/* Atlas Wild Experiences — the landing-page blocks. LAYOUT ONLY, same rule as the rest.
 *
 * These five components exist only on the home page and the journeys page, and
 * they are what stops the site reading as a template: a full-bleed hero, the
 * live seat ticker, the logbook, display figures with their sources, and a
 * pull-quote at display size.
 *
 * Not one raw colour below. build.py fails the build if that stops being true.
 */

/* ── full-bleed hero ────────────────────────────────────────────────────── */
.hero-full {
  position: relative;
  min-height: 78vh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--awe-black);
}
/* The photograph fills the section; everything else sits on top of it. Every
   hero is a stack of slides (one, or several that crossfade); the active one is
   opaque and on top, the rest wait at zero opacity. A single-image hero is just
   the one-slide case, so this one rule covers both. */
.hero-full > picture,
.hero-full > picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero-slides { position: absolute; inset: 0; }
.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1200ms var(--ease-standard);
}
.hero-slide.is-active { opacity: 1; }
.hero-slide picture,
.hero-slide picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero-dots {
  position: absolute;
  z-index: 3;
  left: var(--container-gutter-phone);
  bottom: var(--space-4);
  display: flex;
  gap: var(--space-2);
}
.hero-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  border: 1px solid color-mix(in oklab, var(--awe-cream), transparent 45%);
  background: color-mix(in oklab, var(--awe-black), transparent 45%);
  transition: background var(--motion-fast) var(--ease-standard),
              border-color var(--motion-fast) var(--ease-standard);
}
.hero-dot.is-active { background: var(--accent); border-color: var(--accent); }
.hero-dot:focus-visible { outline: none; box-shadow: var(--focus-ring); }
/* On a crossfade hero the dots carry the wayfinding, so the scroll cue would
   just crowd the same corner — drop it there. */
.hero-carousel .hero-cue { display: none; }
@media (prefers-reduced-motion: reduce) { .hero-slide { transition: none; } }
/* Two scrims, not one. A single flat overlay greys the whole photograph out;
   a vertical gradient plus a left-weighted one darkens only where type goes. */
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top,
      var(--awe-black) 0%,
      color-mix(in oklab, var(--awe-black), transparent 22%) 34%,
      transparent 72%),
    linear-gradient(to right,
      color-mix(in oklab, var(--awe-black), transparent 30%) 0%,
      transparent 62%);
}
.hero-copy {
  position: relative;
  width: 100%;
  padding-block: var(--space-12) var(--space-12);
}
.hero-full h1 {
  font-size: clamp(var(--text-3xl), 6.4vw, 84px);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  max-width: 15ch;
  margin-block: 0 var(--space-6);
  /* The type sits on a photograph, so it carries its own shadow rather than
     relying on the scrim being dark enough at every crop. */
  text-shadow: 0 2px 40px var(--awe-black);
}
.hero-full .lede {
  font-size: var(--text-lg);
  max-width: 52ch;
  color: var(--fg);
  text-shadow: 0 1px 24px var(--awe-black);
}
.hero-cap {
  position: absolute;
  right: var(--container-gutter-phone);
  bottom: var(--space-4);
  margin: 0;
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-data);
  text-transform: uppercase;
  color: var(--muted);
}
.hero-cue {
  position: absolute;
  left: 50%;
  bottom: var(--space-4);
  width: 1px;
  height: 34px;
  background: linear-gradient(var(--accent), transparent);
}

@media (min-width: 768px) {
  .hero-full { min-height: 88vh; }
  .hero-cap { right: var(--container-gutter-tablet); }
  .hero-dots { left: var(--container-gutter-tablet); }
}
@media (min-width: 1040px) {
  .hero-cap { right: var(--container-gutter-desktop); }
  .hero-dots { left: var(--container-gutter-desktop); }
}
/* The hero's motion is the crossfade between slides (see .hero-slide), so the
   old load-time "settle" zoom is gone: applied to the active slide it re-fired
   on every crossfade and fought the fade, and it briefly held the first frame
   at zero opacity. A single, slow dissolve is the quieter choice. */

/* ── the live seat ticker ───────────────────────────────────────────────── */
/* A ticker runs edge to edge or it is just a list in a box. This escapes the
   page's text column without needing a second class in the markup. */
.wrap:has(> .ticker) {
  max-width: none;
  padding-inline: 0;
}
.ticker {
  display: flex;
  align-items: stretch;
  border-block: var(--awe-rule);
  background: var(--surface);
}
.ticker-label {
  flex: none;
  display: flex;
  align-items: center;
  padding-inline: var(--space-5);
  border-right: var(--awe-rule);
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  background: var(--bg);
}
/* display:flex, and it is load-bearing. The script appends a CLONE of the
   track as a sibling so the marquee loops without a seam; in a block
   formatting context the clone lands underneath and the ticker renders as two
   stacked copies of the same list. */
.ticker-view { overflow: hidden; flex: 1 1 auto; display: flex; }
.ticker-track {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding-block: var(--space-4);
  padding-inline: var(--space-5) 0;
  white-space: nowrap;
  flex: none;
}
.tk {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-data);
  font-feature-settings: var(--awe-figures);
  font-size: var(--text-sm);
  letter-spacing: var(--awe-tracking-data);
  color: var(--fg-2);
  text-decoration: none;
  border: 0;                      /* not prose — the base link rule would rule
                                     a line under every departure */
}
.tk:hover { color: var(--fg); }
/* Availability, encoded in SHAPE first and colour second.
 *
 * The brand palette is entirely warm and has no red: on some grounds `danger`
 * derives to the same rust as the accent, and `warn` is a step of lightness
 * away from it (see the note in derive_tokens.py). Four states cannot be told
 * apart by hue here — and would not be distinguishable to a red-green
 * colour-blind reader in any palette. So the dot fills, then gains a ring,
 * then hollows out, and each row still prints its own seat count in words.
 */
.tk-dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--muted);
  box-shadow: none;
}
.tk-dot[data-status="open"]    { background: var(--success); }
.tk-dot[data-status="filling"] { background: var(--warn); }
/* Last places: filled AND ringed — two channels, not one. */
.tk-dot[data-status="last"] {
  background: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--danger), transparent 62%);
}
/* Sold out: hollow, and the whole row drops back. */
.tk-dot[data-status="closed"] {
  background: transparent;
  border: 1.5px solid var(--muted);
}
.tk:has(.tk-dot[data-status="closed"]) { color: var(--muted); }

@media (prefers-reduced-motion: no-preference) {
  /* Only once the data has arrived — a marquee scrolling a "loading" row is
     motion that means nothing. */
  .ticker.is-live .ticker-track {
    animation: tick 46s linear infinite;
  }
  .ticker.is-live:hover .ticker-track,
  .ticker.is-live:focus-within .ticker-track { animation-play-state: paused; }
  @keyframes tick {
    from { transform: translateX(0); }
    to   { transform: translateX(-100%); }
  }
}
@media (prefers-reduced-motion: reduce) {
  .ticker-view { overflow-x: auto; }
  .ticker-track { animation: none; }
}

/* ── display figures ────────────────────────────────────────────────────── */
.figs {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.fig { border-top: 2px solid var(--accent); padding-top: var(--space-5); }
.fig-n {
  font-family: var(--font-display);
  font-size: clamp(var(--text-3xl), 5vw, 68px);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
}
.fig-l { margin-top: var(--space-3); color: var(--fg-2); max-width: 30ch; }
.fig-s {
  margin-top: var(--space-3);
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-data);
  color: var(--muted);
}
/* Only the first figure gets the accent rule — four accent lines is four
   emphases, which is none. */
.fig:not(:first-child) { border-top-color: var(--border); }

/* ── pull-quote ─────────────────────────────────────────────────────────── */
.pull { margin: 0; }
.pull p {
  font-family: var(--font-display);
  font-size: clamp(var(--text-2xl), 4.4vw, 56px);
  line-height: 1.14;
  letter-spacing: var(--tracking-display);
  margin: 0;
  /* Measured in `em`, so the cap scales WITH the type. `ch` was tried first
     and gave a column three words wide. `ch` is the width of the ZERO, and
     both display faces this brand has used have a narrow one, so 26ch at 56px
     is far less than 26 characters of real text. Verified at 1280px: three
     lines. */
  max-width: 15em;
}
.pull cite {
  display: block;
  margin-top: var(--space-6);
  font-family: var(--font-data);
  font-size: var(--text-xs);
  font-style: normal;
  letter-spacing: var(--awe-tracking-data);
  text-transform: uppercase;
  color: var(--muted);
}

/* ── image cards ────────────────────────────────────────────────────────── */
.icards {
  display: grid;
  gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.icard {
  display: block;
  text-decoration: none;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.icard-media { aspect-ratio: 4 / 3; overflow: hidden; }
.icard-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--motion-base) var(--ease-standard);
}
.icard:hover .icard-media img { transform: scale(1.03); }
.icard:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.icard-body { padding: var(--space-5); }
.icard-body h3 { margin-block: 0 var(--space-2); font-size: var(--text-xl); }
.icard-body p { margin: 0; color: var(--fg-2); font-size: var(--text-base); }
.icard-meta {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-data);
  text-transform: uppercase;
  color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .icard-media img { transition: none; }
  .icard:hover .icard-media img { transform: none; }
}

/* ── the logbook ────────────────────────────────────────────────────────── */
.logbook table { min-width: 640px; }
.logbook .lb-d {
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-data);
  color: var(--muted);
  white-space: nowrap;
}
.logbook .lb-p {
  font-family: var(--font-data);
  font-size: var(--text-xs);
  letter-spacing: var(--awe-tracking-data);
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.logbook .lb-s { color: var(--fg); font-size: var(--text-base); }
.logbook .lb-n { color: var(--fg-2); }
