/* Hero component — the crossfading slideshow hero, the standalone interior hero, the
   progress segments, caption card and scroll cue. Moved verbatim from global.css. */

/* hero — asymmetric editorial split, not a full-bleed photo with
     centered text (the generic travel-site pattern). A paper-toned
     content column carries the masthead, headline and CTAs; the image
     bleeds to the right edge and is captioned like a field photograph,
     not a decorative backdrop. */
/* Locks the hero to exactly one screen: header floats over the top
     (doesn't consume flex space), and .hero fills the rest — so the
     two always sum to 100dvh regardless of how much text is in the
     overlay. dvh (not vh) so mobile browser chrome doesn't cause a
     scroll gap. */
.hero-screen{position:relative;height:100vh;height:100dvh;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;margin-bottom:-2px;}

/* padding:0 overrides the generic section{padding:120px 0} rule below —
     .hero is a <section> too, and without this reset that padding quietly
     eats into the box .hero-overlay sizes against (height:100%), which is
     what was throwing the text's vertical position off on interior pages. */
/* Background is a fixed dark gradient rather than var(--border) —
     the hero always carries white overlay text and a dark bottom
     scrim regardless of site theme, so in light mode the old light
     tan --border showed through as a near-white "flash" for the
     ~1s before the photo finishes loading and fading in. A dark
     placeholder matches the eventual scrim tone instead, so that
     loading moment reads as a moody fade-up rather than a blank page. */
.hero{position:relative;flex:1;overflow:hidden;background:linear-gradient(160deg,#3a352c,#1c1a15);padding:0;}

/* Slides stack and crossfade full-bleed behind the type — only the
     .active slide is visible, and only its image runs the slow zoom,
     so switching slides never jumps or restarts the others. A soft
     custom easing curve (rather than linear/ease) on the crossfade
     itself is what makes the transition read as smooth rather than a
     mechanical swap. */
.hero-slide{position:absolute;top:-100px;left:0;right:0;height:calc(100% + 200px);opacity:0;transition:opacity 1.4s cubic-bezier(.45,0,.2,1);}

.hero-slide.active{opacity:1;z-index:1;}

/* Base transform matches the zoom's END value (1.06), not the
     start (1). Each slide only shows its zoom animation while
     .active; the instant a slide loses .active, "heroZoom" is
     removed and the browser falls back to this base transform. If
     that base were scale(1), every outgoing slide would snap
     backwards the moment the next slide takes over — a visible jerk
     underneath the crossfade, since both slides briefly overlap
     during the 1.4s opacity transition. Basing it on 1.06 instead
     means the fallback matches exactly where the zoom just left off. */
.hero-slide img{width:100%;height:100%;object-fit:cover;transform:scale(1.06);}

.hero-slide.active img{animation:heroZoom 6.5s linear forwards;}

@keyframes heroZoom{from{transform:scale(1);}to{transform:scale(1.06);}}

/* Single-direction scrim, bottom only — legibility for the overlay
     type without tinting the whole photo (the brand's "no gradients"
     rule is about decorative color gradients, not a functional legibility
     scrim, which every photo-led editorial hero uses). */
.hero-scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg, rgba(20,18,15,.14) 0%, rgba(20,18,15,.22) 28%, rgba(20,18,15,.8) 100%);}

/* Film grain — a flat, clean photo reads as generic stock/digital;
     a faint texture over it reads as documentary/shot-on-film, which
     fits the brand's "field notebook" identity better. Kept very
     subtle (opacity .05) so it's texture, not noise. */
.hero-grain{position:absolute;inset:0;z-index:1;opacity:.05;pointer-events:none;mix-blend-mode:overlay;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}

/* Top-anchored, not bottom-anchored: every hero (homepage and every
     interior page) starts its kicker at the exact same padding-top
     below the fixed header, regardless of how much text follows.
     Previously this used justify-content:flex-end, which meant the
     starting position of the whole block drifted from page to page
     depending on how many lines the heading/sub wrapped to — a 1-line
     vs 2-line h1 shifted the kicker by however many extra pixels that
     line added. Anchoring from the top with a fixed offset keeps that
     first line level everywhere; whatever follows (sub, CTAs) simply
     flows down from there. 120px matches the same below-header offset
     used by .archive-hero-overlay and .article-hero elsewhere. */
.hero-overlay{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;justify-content:flex-start;padding-top:200px;padding-bottom:64px;}

/* Slide progress — a row of thin segments (one per slide, "stories"
     style) paired with a numeral counter, sitting just above the
     kicker so it's always safely clear of the fixed header regardless
     of viewport. Each segment fills over the slide's dwell time; a
     segment for a slide already shown snaps to fully filled, so the
     whole row reads at a glance as "how far through the run we are" —
     the numeral is the same information again, spelled out. */
.hero-progress-row{display:flex;align-items:center;gap:18px;margin-bottom:28px;}

.hero-progress{display:flex;gap:8px;}

.progress-seg{width:34px;height:3px;border-radius:2px;background:rgba(255,255,255,.28);border:none;padding:0;cursor:pointer;position:relative;overflow:hidden;}

.progress-seg .fill{position:absolute;inset:0;width:0;background:#FFFFFF;border-radius:2px;}

.progress-seg.active .fill{animation:progressFill 6.5s linear forwards;}

.progress-seg.done .fill{width:100%;}

@keyframes progressFill{from{width:0;}to{width:100%;}}

/* Numeral counter — current slide in bold, total in a dimmed
     tone, with a quick fade+lift whenever the number changes so it
     never just pops. */
.hero-slide-count{display:flex;align-items:baseline;font-family:var(--sans);font-weight:700;font-size:13px;letter-spacing:.06em;color:#FFFFFF;}

.hero-slide-count .count-current{display:inline-block;min-width:2ch;transition:opacity .3s ease, transform .3s ease;}

.hero-slide-count.is-changing .count-current{opacity:0;transform:translateY(-6px);}

.hero-slide-count .count-sep{margin:0 3px;opacity:.45;}

.hero-slide-count .count-total{opacity:.45;}

.hero-kicker{display:flex;align-items:center;gap:10px;font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#FFFFFF;margin-bottom:20px;}

.hero-kicker .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex-shrink:0;}

.hero h1{font-family:var(--sans);font-weight:700;font-size:clamp(40px,7vw,84px);line-height:1.02;letter-spacing:-0.02em;color:#FFFFFF;margin-bottom:20px;max-width:14ch;}

.hero-sub{font-family:var(--serif);font-size:17px;line-height:1.55;max-width:36ch;color:rgba(255,255,255,.82);margin-bottom:36px;}

.hero-ctas{display:flex;gap:16px;flex-wrap:wrap;}

.scroll-cue{position:absolute;left:50%;bottom:28px;transform:translateX(-50%);z-index:4;width:38px;height:38px;border-radius:50%;background:var(--surface);border:1px solid var(--border);color:var(--heading);display:flex;align-items:center;justify-content:center;cursor:pointer;}

.scroll-cue:hover{background:var(--accent);border-color:var(--accent);color:var(--surface);}

/* Caption card — sits bottom-right, well clear of the fixed header,
     so it never needs to guess the header's height. Reads like a
     field-photograph credit: which dispatch this frame is from. Text
     fades and lifts slightly on each change instead of swapping
     instantly (see initHeroSlider in main.js, which toggles
     .is-changing before/after updating the text). */
.hero-caption{position:absolute;right:0;bottom:0;z-index:3;background:var(--bg-translucent);padding:14px 20px;max-width:240px;min-height:92px;display:flex;flex-direction:column;justify-content:center;border-top:1px solid rgba(255,255,255,.3);border-left:1px solid rgba(255,255,255,.3);}

.hero-caption .cap-label,
  .hero-caption .cap-place{transition:opacity .3s ease, transform .3s ease;}

.hero-caption.is-changing .cap-label,
  .hero-caption.is-changing .cap-place{opacity:0;transform:translateY(6px);}

.hero-caption .cap-label{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);font-weight:600;margin-bottom:4px;}

.hero-caption .cap-place{font-family:var(--sans);font-weight:700;font-size:14.5px;color:var(--heading);}

a.cap-link{display:block;}

/* Reduced motion: the slideshow itself already stops auto-advancing
     (see initHeroSlider in main.js), but a visitor can still click a
     progress segment to jump slides manually — so the crossfade stays
     (it's how the new photo appears at all), just without the zoom,
     fill-sweep or text-lift flourishes layered on top of it. */
@media (prefers-reduced-motion: reduce){
.hero-slide.active img{animation:none;}
.progress-seg.active .fill{animation:none;width:100%;}
.hero-slide-count .count-current,
    .hero-caption .cap-label,
    .hero-caption .cap-place{transition:none;}
}

/* .hero-standalone — a full-height, no-CTA hero for interior pages
     (no .hero-screen wrapper). A single static image with scrim,
     grain and scroll-cue, matching the homepage's 100dvh. */
.hero-standalone{height:100vh;height:100dvh;min-height:100vh;min-height:100dvh;flex:none;}

@media (max-width:980px){
/* Mobile hero: still one full screen (100dvh via .hero-screen).
       Centered vertically rather than pinned to the bottom — the
       caption box sits absolutely at the very bottom of .hero and its
       height varies (some place names wrap to two lines), so a fixed
       bottom padding kept catching up short. Centering plus a bottom
       reserve is robust to that instead of chasing an exact number. */
.hero-overlay{justify-content:center;align-items:center;text-align:center;padding-top:0;padding-bottom:90px;padding-left:24px;padding-right:24px;}
.hero-progress-row{justify-content:center;margin-bottom:24px;}
/* Same rule as the section eyebrow: the dot is a leading marker in the left track
   and never takes part in centring the text. */
.hero-kicker{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:0;text-align:center;}
.hero-kicker .dot{justify-self:end;margin-right:10px;}
.hero h1{max-width:none;}
.hero-sub{max-width:32ch;}
.hero-ctas{justify-content:center;}
.scroll-cue{display:none;}
.hero-caption{display:none;}
/* Interior-page hero stays full-screen at tablet width too. */
.hero-standalone{height:100vh;height:100dvh;min-height:100vh;min-height:100dvh;}
}

@media (max-width:560px){
.hero h1{font-size:clamp(30px,9vw,38px);}
.hero-sub{display:none;}
/* keep the mobile hero content budget tight and guaranteed-to-fit */
.hero-overlay{padding-bottom:70px;}
/* Interior-page hero stays full-screen on mobile too. */
.hero-standalone{height:100vh;height:100dvh;min-height:100vh;min-height:100dvh;}
}

@media (max-width:980px){
.wrap, .header-inner{padding-left:24px;padding-right:24px;}
}

/* ===== Home hero — slide indicator placement =====
   Added block; the base indicator rules earlier in this file are
   unchanged. Desktop: a vertical stack pinned to the right edge,
   vertically centred. Tablet & mobile (≤980px): the original
   horizontal segments + counter, centred at the bottom of the hero
   with a small margin. The row is taken out of the text flow, so the
   overlay's spacing is adjusted by the row's old height to keep the
   headline exactly where it was. */
.hero-progress-row{position:absolute;z-index:3;margin-bottom:0;}

@keyframes progressFillV{from{height:0;}to{height:100%;}}

@media (min-width:981px){
.hero-overlay:has(> .hero-progress-row){padding-top:243px;}
.hero-progress-row{right:48px;top:50%;transform:translateY(-50%);flex-direction:column;align-items:center;gap:16px;}
.hero-progress{flex-direction:column;gap:8px;}
/* 15px-wide hit area, 3px visible track (background-clip) */
.progress-seg{width:15px;height:34px;padding:0 6px;background-clip:content-box;border-radius:0;}
.progress-seg .fill{left:6px;right:6px;width:auto;height:0;}
.progress-seg.active .fill{animation:progressFillV 6.5s linear forwards;}
.progress-seg.done .fill{width:auto;height:100%;}
}

@media (min-width:981px) and (prefers-reduced-motion: reduce){
.progress-seg.active .fill{animation:none;width:auto;height:100%;}
}

@media (max-width:980px){
.hero-overlay:has(> .hero-progress-row){padding-bottom:51px;}
.hero-progress-row{left:0;right:0;bottom:28px;justify-content:center;}
}

@media (max-width:560px){
.hero-overlay:has(> .hero-progress-row){padding-bottom:31px;}
}

/* ===== Home hero — smoothness =====
   Added block. .is-paused (toggled by initHeroSlider in main.js) freezes
   the zoom and progress-fill animations in step with the slide timer
   (tab hidden, hero scrolled out of view, cursor on the caption).
   will-change promotes the cross-fading slides and the zooming photo to
   their own compositor layers so both animate on the GPU instead of
   repainting the full-bleed photo every frame. */
.hero.is-paused .hero-slide.active img,
.hero.is-paused .progress-seg.active .fill{animation-play-state:paused;}

.hero-slide{will-change:opacity;}

.hero-slide.active img{will-change:transform;backface-visibility:hidden;}
