@import url("../font/fonts.css");

/* ============================================================================
   EINSTEIN TOURS AND TRAVEL - design system
   ----------------------------------------------------------------------------
   Palette, type and shape are taken from the company logo rather than invented:
   the navy of the wordmark, the olive of the crescent, the amber of the sun,
   and the serif of "EINSTEIN". The page ground is warm savanna sand, not black.

   Shape: one radius scale, applied everywhere. Nothing is square.
   Type:  Bodoni Moda for display, Figtree for everything else, Ephesis for
          single accented words only.
   ========================================================================== */

:root {
  color-scheme: light;

  /* Ground. Warm savanna sand through to dusk. */
  --ground:      #f7f2e7;
  --ground-rise: #efe7d6;
  --ground-deep: #e6dbc4;
  --ground-veil: #dccfb2;

  /* Ink. The teal-green of the silhouettes inside the badge. */
  --ink:      #1b4442;
  --ink-mute: #3d6360;
  --ink-far:  #4b6d6a;

  /* Accent. The rust of the arched lettering. Warm against the teal ink. */
  --accent:      #8a4520;
  --accent-deep: #6b3416;
  --on-accent:   #f9f5ec;

  /* Sage, from the badge disc. Tinted surfaces only. */
  --sage: #d9e9c7;

  /* One job only: the hairline under a section heading and the price. */
  --amber: #a25c16;

  --rule:      rgb(27 68 66 / 0.18);
  --rule-soft: rgb(27 68 66 / 0.09);
  --scrim:     rgb(27 68 66 / 0.55);

  /* Type */
  --face-display: "Bodoni Moda", Georgia, serif;
  --face-text:    "Figtree", Arial, Helvetica, system-ui, sans-serif;
  --face-script:  "Ephesis", "Bodoni Moda", cursive;
  --face-data:    "Figtree", Arial, sans-serif;

  --step--1: clamp(0.78rem, 0.755rem + 0.13vw, 0.865rem);
  --step-0:  clamp(0.98rem, 0.93rem + 0.24vw, 1.12rem);
  --step-1:  clamp(1.2rem, 1.05rem + 0.7vw, 1.62rem);
  --step-2:  clamp(1.6rem, 1.2rem + 1.9vw, 2.75rem);
  --step-3:  clamp(2.1rem, 1.32rem + 3.5vw, 4.4rem);
  --step-4:  clamp(2.9rem, 1.3rem + 7vw, 7.2rem);
  --step-5:  clamp(3.4rem, 0.6rem + 12vw, 12rem);

  /* Space */
  --pad:    clamp(1.25rem, 5vw, 7rem);
  --gutter: clamp(0.75rem, 1.5vw, 2rem);
  --bay:    clamp(6rem, 12vh + 5vw, 15rem);
  --bay-sm: clamp(3.5rem, 6vh + 3vw, 7rem);

  /* Shape. One scale, used everywhere. */
  --r-img:   22px;
  --r-box:   18px;
  --r-field: 12px;
  --r-pill:  999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io:  cubic-bezier(0.72, 0, 0.28, 1);
  --dur-s: 0.28s;
  --dur-m: 0.62s;
  --dur-l: 1.05s;

  /* Layers */
  --z-base: 0; --z-sticky: 20; --z-rail: 30; --z-nav: 40; --z-veil: 50; --z-grain: 60;
}

/* Dusk. Deep navy from the wordmark, never black. */
/* Deliberately not wired to prefers-color-scheme: the warm ground is the brand,
   so dusk is opt-in from the footer toggle rather than automatic. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="dark-never"] {
    color-scheme: dark;
    --ground:      #131b33;
    --ground-rise: #1b2542;
    --ground-deep: #0e1428;
    --ground-veil: #24304f;
    --ink:      #f4efe2;
    --ink-mute: #c3bdae;
    --ink-far:  #9d9a8e;
    --accent:      #9dc264;
    --accent-deep: #7ea247;
    --on-accent:   #131b33;
    --amber: #e0a33f;
    --rule:      rgb(244 239 226 / 0.18);
    --rule-soft: rgb(244 239 226 / 0.09);
    --scrim:     rgb(10 14 28 / 0.6);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --ground:      #102a29;
  --ground-rise: #173937;
  --ground-deep: #0a1f1e;
  --ground-veil: #204b48;
  --ink:      #f4efe2;
  --ink-mute: #bfcdc2;
  --ink-far:  #96a89d;
  --accent:      #e08d52;
  --accent-deep: #c4713a;
  --on-accent:   #102a29;
  --sage: #d9e9c7;
  --amber: #e0a33f;
  --rule:      rgb(244 239 226 / 0.2);
  --rule-soft: rgb(244 239 226 / 0.1);
  --scrim:     rgb(8 26 25 / 0.6);
}

/* --- 2. Reset ------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor jumps clear the fixed masthead. */
  scroll-padding-top: 6rem;
}

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--face-text);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
img { height: auto; background: var(--ground-rise); border-radius: var(--r-img); }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

::selection { background: var(--accent); color: var(--on-accent); }

/* --- 3. Type ------------------------------------------------------------- */

.display {
  font-family: var(--face-display);
  font-weight: 500;
  line-height: 1.0;
  letter-spacing: -0.012em;
  font-variation-settings: "opsz" 72;
  text-wrap: balance;
}

/* Calligraphic accent. One or two words in a headline, never a whole line. */
.script {
  font-family: var(--face-script);
  font-weight: 400;
  font-size: 1.18em;
  line-height: 0.78;
  letter-spacing: 0;
  color: var(--accent);
  padding-inline: 0.04em;
  padding-bottom: 0.16em;
  display: inline-block;
  vertical-align: baseline;
}

.display--xl { font-size: var(--step-5); line-height: 0.94; letter-spacing: -0.022em; }
.display--l  { font-size: var(--step-4); line-height: 0.98; letter-spacing: -0.018em; }
.display--m  { font-size: var(--step-3); line-height: 1.04; }
.display--s  { font-size: var(--step-2); line-height: 1.12; letter-spacing: -0.008em; }

.display em {
  font-style: italic;
  font-weight: 400;
  line-height: 1.15;
  padding-bottom: 0.08em;
  display: inline-block;
}

.lede {
  font-size: var(--step-1);
  line-height: 1.42;
  font-weight: 330;
  color: var(--ink-mute);
  max-width: 34ch;
  text-wrap: pretty;
}

.body { max-width: 62ch; color: var(--ink-mute); text-wrap: pretty; }
.body + .body { margin-top: 1.1em; }
.body strong { color: var(--ink); font-weight: 520; }

/* Reserved for real measured data: coordinates, day numbers, prices, durations. */
.data {
  font-family: var(--face-data);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-far);
}

.marker {
  font-family: var(--face-text);
  font-size: clamp(0.62rem, 0.58rem + 0.16vw, 0.72rem);
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-weight: 400;
  color: var(--accent);
}

/* --- 4. The Drift Grid --------------------------------------------------- */
/* 14 columns. Blocks take irregular spans and are allowed to run off-edge.
   Placement is authored inline with --from / --span so each composition can be
   genuinely asymmetric; every block collapses to one column under 860px.      */

.shell { padding-inline: var(--pad); }

.drift {
  display: grid;
  grid-template-columns: repeat(14, minmax(0, 1fr));
  column-gap: var(--gutter);
}

.place {
  grid-column: var(--from, 1) / span var(--span, 14);
  grid-row: var(--row, auto);
  min-width: 0;
}

@media (max-width: 860px) {
  .place { grid-column: 1 / -1; grid-row: auto; }
  .drift { row-gap: var(--bay-sm); }
}

.bay { padding-block: var(--bay); }
.bay--tight { padding-block: var(--bay-sm); }

.rule { border: 0; border-top: 1px solid var(--rule); }

/* --- 5. Grain ------------------------------------------------------------ */
/* Fixed and non-scrolling so the GPU never repaints it during scroll. */

.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.02;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- 6. Masthead --------------------------------------------------------- */

.masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-nav);
  height: 68px;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 3rem);
  padding-inline: var(--pad);
  transition: background var(--dur-m) var(--ease-out),
              border-color var(--dur-m) var(--ease-out),
              transform var(--dur-m) var(--ease-out);
  border-bottom: 1px solid transparent;
}

.masthead::before {
  content: "";
  position: absolute;
  inset: 0 0 -3.5rem 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgb(7 10 9 / 0.88) 12%, rgb(7 10 9 / 0.45) 55%, transparent);
  opacity: 0;
  transition: opacity var(--dur-m) var(--ease-out);
}

.masthead[data-settled="false"]::before { opacity: 1; }

/* While the bar sits over the hero photograph its labels are forced light.
   This is keyed to an explicit data-settled="false" rather than to the absence
   of "true", so that with no JavaScript the bar falls back to ink on sand. */
.masthead[data-settled="false"] .wordmark,
.masthead[data-settled="false"] .mast-toggle { color: #f4efe2; }
/* :not(.act) matters. The CTA is an <a> inside .mast-nav, and without the
   exclusion this rule would repaint its label light over the teal fill. */
.masthead[data-settled="false"] .mast-nav :is(.mast-list > li > a, .menu-trigger) { color: #e4ded0; }
.masthead[data-settled="false"] .mast-nav :is(.mast-list > li > a, .menu-trigger):hover,
.masthead[data-settled="false"] .mast-nav :is(.mast-list > li > a, .menu-trigger)[aria-current="page"] { color: #fff; }

.masthead,
.masthead[data-settled="true"] {
  background: color-mix(in oklab, var(--ground) 82%, transparent);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--rule);
}

/* Over the hero photograph the bar drops its fill and leans on the scrim above.
   Declared after the solid default so the no-script case stays solid. */
.masthead[data-settled="false"] {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}

.masthead[data-hidden="true"] { transform: translateY(-100%); }

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--face-display);
  font-size: 1.06rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.wordmark img {
  width: auto;
  height: 46px;
  object-fit: contain;
  background: none;
  border-radius: 0;
  flex: none;
}

.wordmark b { font-weight: 600; }

.wordmark span {
  font-family: var(--face-text);
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  font-weight: 600;
  color: var(--ink-far);
  text-transform: uppercase;
}

@media (max-width: 620px) { .wordmark span { display: none; } }

.mast-nav { display: flex; align-items: center; gap: clamp(0.75rem, 1.6vw, 1.9rem); margin-left: auto; }

/* Every rule here excludes .act. The call to action is also an <a> inside
   .mast-nav, and a bare `.mast-nav a` selector outranks `.act`, which would
   repaint its label --ink-mute over the accent fill at a 1.1:1 contrast ratio. */
.mast-nav :is(.mast-list > li > a, .menu-trigger) {
  font-size: 0.83rem;
  font-weight: 420;
  letter-spacing: -0.005em;
  color: var(--ink-mute);
  white-space: nowrap;
  position: relative;
  padding-block: 0.35rem;
  transition: color var(--dur-s) var(--ease-out);
}

.mast-nav :is(.mast-list > li > a, .menu-trigger)::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur-m) var(--ease-out);
}

.mast-nav :is(.mast-list > li > a, .menu-trigger):hover,
.mast-nav :is(.mast-list > li > a, .menu-trigger)[aria-current="page"] { color: var(--ink); }

.mast-nav :is(.mast-list > li > a, .menu-trigger):hover::after,
.mast-nav :is(.mast-list > li > a, .menu-trigger)[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }

@media (max-width: 1080px) { .mast-nav { display: none; } }

.mast-toggle {
  display: none;
  margin-left: auto;
  width: 34px; height: 34px;
  position: relative;
  color: var(--ink);
}

.mast-toggle i {
  position: absolute;
  left: 6px;
  width: 22px; height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-m) var(--ease-out), opacity var(--dur-s) linear;
}

.mast-toggle i:nth-child(1) { top: 13px; }
.mast-toggle i:nth-child(2) { top: 20px; }
.mast-toggle[aria-expanded="true"] i:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
.mast-toggle[aria-expanded="true"] i:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

@media (max-width: 1080px) { .mast-toggle { display: block; } }

/* Full-bleed drawer, staggered items. */
.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-veil);
  background: var(--ground-deep);
  padding: 6rem var(--pad) 2rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.2rem;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.8s var(--ease-io);
  visibility: hidden;
}

.drawer[data-open="true"] { clip-path: inset(0 0 0 0); visibility: visible; }

/* The nav is a grid so every entry, link or row, occupies its own line.
   Inline anchors ran together as one line of text. */
.drawer nav { display: grid; align-content: center; }

.drawer a {
  display: block;
  font-family: var(--face-display);
  font-size: clamp(2rem, 9vw, 3.4rem);
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 1.14;
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.5s var(--ease-out), transform 0.6s var(--ease-out);
  transition-delay: calc(var(--i) * 55ms);
}

.drawer[data-open="true"] a { opacity: 1; transform: none; }

.drawer-foot {
  margin-top: auto;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 2rem;
}


/* --- 6b. Nav dropdowns --------------------------------------------------- */

.mast-list {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.6vw, 1.9rem);
  list-style: none;
}

.has-menu { position: relative; }

.menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
  cursor: pointer;
  font-family: inherit;
}

.menu-trigger svg {
  width: 9px; height: 6px;
  flex: none;
  transition: transform var(--dur-m) var(--ease-out);
}

.has-menu[data-open="true"] .menu-trigger svg { transform: rotate(180deg); }

.submenu {
  position: absolute;
  top: 100%;
  left: -0.9rem;
  min-width: 14.5rem;
  margin-top: 0.55rem;
  padding: 0.5rem;
  list-style: none;
  background: var(--ground);
  border-radius: var(--r-box);
  box-shadow: 0 18px 44px rgb(27 37 69 / 0.18), inset 0 0 0 1px var(--rule);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--dur-s) var(--ease-out),
              transform var(--dur-m) var(--ease-out),
              visibility 0s linear var(--dur-s);
}

/* An invisible bridge across the gap, so the pointer can travel from the
   trigger to the panel without the menu closing under it. */
.submenu::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: -0.7rem;
  height: 0.7rem;
}

.has-menu[data-open="true"] > .submenu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.submenu a {
  display: block;
  padding: 0.6rem 0.85rem;
  border-radius: var(--r-field);
  font-size: 0.86rem;
  font-weight: 450;
  color: var(--ink-mute);
  white-space: nowrap;
  transition: background var(--dur-s) var(--ease-out), color var(--dur-s) var(--ease-out);
}

.submenu a:hover, .submenu a:focus-visible { background: var(--ground-rise); color: var(--ink); }

.submenu li:first-child a {
  color: var(--ink);
  font-weight: 600;
}

.submenu li:first-child { margin-bottom: 0.3rem; padding-bottom: 0.35rem; border-bottom: 1px solid var(--rule-soft); }

/* Sub-links inside the mobile drawer */
.drawer-row { display: flex; align-items: center; gap: 0.6rem; }

.drawer-row > a { flex: 1 1 auto; min-width: 0; }

.drawer-expand {
  flex: none;
  width: 2.6rem; height: 2.6rem;
  display: grid;
  place-items: center;
  color: var(--ink-mute);
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--rule);
  transition: color var(--dur-s) var(--ease-out), background var(--dur-s) var(--ease-out);
}

.drawer-expand svg { width: 13px; height: 8px; transition: transform var(--dur-m) var(--ease-out); }
.drawer-expand[aria-expanded="true"] { color: var(--on-accent); background: var(--accent); box-shadow: none; }
.drawer-expand[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Collapsed by default. Height is animated via a grid row so the panel can size
   itself to its content without a hard-coded max-height. */
.drawer-sub {
  display: grid;
  grid-template-rows: 0fr;
  margin-left: 1.1rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--rule);
  transition: grid-template-rows var(--dur-m) var(--ease-io),
              margin-bottom var(--dur-m) var(--ease-io);
}

.drawer-sub > div { overflow: hidden; min-height: 0; display: grid; gap: 0.1rem; }

.drawer-sub[data-open="true"] { grid-template-rows: 1fr; margin-bottom: 0.7rem; }

.drawer-sub a {
  display: block;
  font-family: var(--face-text);
  font-size: clamp(0.95rem, 3.4vw, 1.15rem);
  font-weight: 450;
  letter-spacing: 0;
  line-height: 1.9;
  color: var(--ink-mute);
  opacity: 1;
  transform: none;
  transition: color var(--dur-s) var(--ease-out);
}

.drawer-sub a:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .submenu { transition: opacity 0.001ms, visibility 0.001ms; transform: none; }
  .menu-trigger svg, .drawer-expand svg, .drawer-sub { transition: none; }
}

/* --- 7. Expedition rail -------------------------------------------------- */
/* Real wayfinding: section index plus scroll position. Not decoration. */

.rail {
  position: fixed;
  left: max(0.9rem, calc(var(--pad) * 0.32));
  top: 50%;
  translate: 0 -50%;
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  opacity: 0;
  transition: opacity var(--dur-m) var(--ease-out);
}

.rail[data-visible="true"] { opacity: 1; }

.rail button {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink-far);
  transition: color var(--dur-s) var(--ease-out);
}

.rail button i {
  display: block;
  width: 15px; height: 1px;
  background: currentColor;
  transition: width var(--dur-m) var(--ease-out), background var(--dur-s) var(--ease-out);
}

.rail button b {
  font-family: var(--face-data);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0;
  translate: -6px 0;
  transition: opacity var(--dur-s) var(--ease-out), translate var(--dur-m) var(--ease-out);
  white-space: nowrap;
}

.rail button:hover, .rail button[aria-current="true"] { color: var(--ink); }
.rail button:hover i, .rail button[aria-current="true"] i { width: 30px; background: var(--accent); }
.rail button:hover b, .rail button[aria-current="true"] b { opacity: 1; translate: 0 0; }

@media (max-width: 1180px) { .rail { display: none; } }

/* --- 8. Controls --------------------------------------------------------- */

.act {
  --fill: var(--accent);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 1rem 1.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  border-radius: var(--r-pill);
  letter-spacing: 0.005em;
  white-space: nowrap;              /* a CTA never wraps */
  isolation: isolate;
  overflow: hidden;
  background: var(--fill);
  color: var(--on-accent);
  transition: transform var(--dur-s) var(--ease-out);
  will-change: transform;
}

/* Magnetic pull. The JS writes --mx/--my; nothing re-renders. */
.act--magnetic { translate: calc(var(--mx, 0) * 1px) calc(var(--my, 0) * 1px); }

.act::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: -1;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--dur-m) var(--ease-io);
}

.act:hover::before { transform: scaleY(1); }
.act:hover { color: var(--ground); }
.act:active { transform: scale(0.975); }

.act--ghost {
  background: transparent;
  color: var(--ink);
  /* A stroke keeps this readable over photography, where a fill would not. A
     13% hairline disappears against a photograph, so this one is its own value
     rather than --rule, and the hero adds a scrim behind it. */
  box-shadow: inset 0 0 0 1px rgb(233 237 231 / 0.42);
}

.hero .act--ghost {
  color: #e9ede7;
  background: rgb(7 10 9 / 0.32);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: inset 0 0 0 1px rgb(233 237 231 / 0.55);
}

.hero .act--ghost:hover { color: var(--ground-deep); background: transparent; }

:root[data-theme="light"] .act--ghost,
:root:not([data-theme="dark"]) .act--ghost { box-shadow: inset 0 0 0 1px rgb(19 26 23 / 0.42); }

.act--ghost::before { background: var(--ink); }
.act--ghost:hover { color: var(--ground); }

.act svg { width: 15px; height: 15px; flex: none; }

/* A text link that behaves like an instrument switch. */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.85rem;
  font-weight: 480;
  color: var(--ink);
  padding-block: 0.3rem;
}

.switch i {
  display: block;
  width: 26px; height: 1px;
  background: var(--accent);
  transition: width var(--dur-m) var(--ease-out);
}

.switch:hover i { width: 46px; }

/* --- 9. Plates (imagery) ------------------------------------------------- */

.plate {
  position: relative;
  overflow: hidden;
  background: var(--ground-rise);
  border-radius: var(--r-img);
}

.plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  will-change: transform;
}

.plate--tall  { aspect-ratio: 3 / 4; }
.plate--port  { aspect-ratio: 4 / 5; }
.plate--sq    { aspect-ratio: 1 / 1; }
.plate--land  { aspect-ratio: 4 / 3; }
.plate--wide  { aspect-ratio: 16 / 9; }
.plate--pano  { aspect-ratio: 21 / 9; }

/* Shutter reveal: the image is uncovered rather than faded in. */
.js .plate[data-shutter] img {
  clip-path: inset(0 0 100% 0);
  transform: scale(1.14);
}

.plate[data-shutter].is-open img {
  clip-path: inset(0 0 0 0);
  transform: scale(1);
  transition: clip-path 1.15s var(--ease-io), transform 1.5s var(--ease-out);
}

/* --- 10. Hero ------------------------------------------------------------ */

.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: flex-end;
  padding: 0 var(--pad) clamp(2.5rem, 7vh, 5rem);
  overflow: hidden;
}

.hero-bed {
  position: absolute;
  inset: -8% -4% -14% -4%;
  z-index: -2;
  will-change: transform;
}

.hero-bed img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }

.hero-veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, var(--ground) 2%, rgb(7 10 9 / 0.55) 38%, rgb(7 10 9 / 0.12) 72%),
    linear-gradient(to right, rgb(7 10 9 / 0.72), transparent 62%);
}

:root[data-theme="light"] .hero-veil,
:root:not([data-theme="dark"]) .hero-veil {
  background:
    linear-gradient(to top, var(--ground) 2%, rgb(7 10 9 / 0.5) 40%, rgb(7 10 9 / 0.15) 74%),
    linear-gradient(to right, rgb(7 10 9 / 0.66), transparent 62%);
}

/* The hero always reads on dark photography, in either page theme. */
.hero, .hero .lede { color: #e9ede7; }
.hero .lede { color: #c3ccc4; }

.hero-title {
  position: relative;
  /* Capped below --step-4 so the two lines of the opening headline never break
     to three at any desktop width. */
  font-size: clamp(2.5rem, 6.1vw, 6.2rem);
}

/* A plate that runs off the right edge of the viewport. */
.hero-drift {
  position: absolute;
  right: calc(var(--pad) * -0.5);
  bottom: 18vh;
  width: clamp(150px, 17vw, 290px);
  z-index: 1;
  will-change: transform;
}

@media (max-width: 1024px) { .hero-drift { display: none; } }

/* --- 11. Line reveal ----------------------------------------------------- */
/* Each line sits in its own overflow window and rises like a shutter. */

.rise { display: block; overflow: hidden; padding-bottom: 0.08em; }

.js .rise > * {
  display: block;
  transform: translateY(105%);
  transition: transform 1.05s var(--ease-io);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.is-risen .rise > *, .rise.is-risen > * { transform: none; }

.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.75s var(--ease-out), transform 0.95s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}

[data-reveal].is-in { opacity: 1; transform: none; }

/* --- 12. Atlas (horizontal country pan) ---------------------------------- */

.atlas { position: relative; overflow: hidden; }

.atlas-track {
  display: flex;
  align-items: stretch;
  height: 100dvh;
  will-change: transform;
}

.atlas-card {
  position: relative;
  border-radius: var(--r-img);
  flex: none;
  width: clamp(280px, 46vw, 720px);
  margin-right: var(--gutter);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(1.5rem, 3vw, 3rem);
  color: #e9ede7;
}

.atlas-card:first-child { margin-left: var(--pad); }
.atlas-card:last-child { margin-right: var(--pad); }

/* Alternating heights break the row into a rhythm rather than a shelf. */
.atlas-card:nth-child(odd)  { align-self: flex-start; height: 78%; margin-top: 11dvh; }
.atlas-card:nth-child(even) { align-self: flex-end;   height: 64%; margin-bottom: 14dvh; }

.atlas-card img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: -2;
  border-radius: inherit;
  transform: scale(1.06);
  transition: transform 1.1s var(--ease-out), filter 0.6s var(--ease-out);
  filter: saturate(0.82) brightness(0.78);
}

.atlas-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: -1;
  background: linear-gradient(to top, rgb(7 10 9 / 0.88) 4%, rgb(7 10 9 / 0.3) 46%, transparent 78%);
}

.atlas-card:hover img, .atlas-card:focus-visible img { transform: scale(1); filter: saturate(1) brightness(0.92); }

.atlas-index {
  font-family: var(--face-data);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  color: var(--accent);
  margin-bottom: auto;
}

.atlas-name {
  font-family: var(--face-display);
  font-size: clamp(2rem, 5vw, 4rem);
  font-weight: 500;
  letter-spacing: -0.04em;
  line-height: 0.92;
}

.atlas-meta {
  margin-top: 0.9rem;
  font-size: 0.86rem;
  color: #b9c2ba;
  max-width: 32ch;
}

/* Under 860px the pan is replaced by a vertical stack; no hijack on touch. */
@media (max-width: 860px) {
  .atlas-track { display: grid; height: auto; gap: var(--bay-sm); padding-inline: var(--pad); }
  .atlas-card {
    width: auto; height: auto; min-height: 62dvh;
    margin: 0 !important; align-self: stretch !important;
  }
}

/* --- 13. Dossiers (journey stack) ---------------------------------------- */

.dossier {
  position: relative;
  display: grid;
  grid-template-columns: repeat(14, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: center;
  padding-block: clamp(2rem, 4vw, 3.5rem);
  border-top: 1px solid var(--rule);
  transition: opacity var(--dur-m) var(--ease-out);
}

.dossier[hidden] { display: none; }

.dossier-no { grid-column: 1 / span 1; align-self: start; padding-top: 0.4rem; }

.dossier-plate { grid-column: 2 / span 4; }
.dossier-plate .plate { aspect-ratio: 5 / 4; }

.dossier-body { grid-column: 7 / span 5; }
.dossier-side { grid-column: 13 / span 2; text-align: right; align-self: start; padding-top: 0.4rem; }

.dossier-title {
  font-family: var(--face-display);
  font-size: var(--step-2);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.02;
  transition: color var(--dur-s) var(--ease-out);
}

.dossier a:hover .dossier-title { color: var(--accent); }
.dossier a:hover .plate img { transform: scale(1.05); }
.dossier .plate img { transition: transform 1.1s var(--ease-out); }

.dossier-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.4rem;
  margin-top: 1.1rem;
}

@media (max-width: 860px) {
  .dossier { grid-template-columns: 1fr; row-gap: 1.2rem; }
  .dossier-no, .dossier-plate, .dossier-body, .dossier-side {
    grid-column: 1 / -1; text-align: left; padding-top: 0;
  }
  .dossier-plate .plate { aspect-ratio: 16 / 10; }
}

/* Filter set */
.sieve { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.sieve button {
  padding: 0.55rem 1.15rem;
  border-radius: var(--r-pill);
  font-size: 0.78rem;
  font-weight: 450;
  color: var(--ink-mute);
  box-shadow: inset 0 0 0 1px var(--rule);
  transition: color var(--dur-s) var(--ease-out), box-shadow var(--dur-s) var(--ease-out),
              background var(--dur-s) var(--ease-out);
}

.sieve button:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink-far); }

.sieve button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* --- 14. Sticky narrative ------------------------------------------------ */

.saga { position: relative; }

.saga-pin {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.saga-frame { position: absolute; inset: 0; }

/* All four frames are stacked in the same box. Without absolute positioning
   they lay out one under another and only the first is ever on screen, which
   is why every panel after the first showed bare ground. */
.saga-frame img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 0;
  opacity: 0;
  transform: scale(1.08);
  transition: opacity 1.1s var(--ease-out), transform 2s var(--ease-out);
}

.saga-frame img.is-live { opacity: 1; transform: scale(1); }

.saga-panel {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  padding-inline: var(--pad);
  pointer-events: none;
}

/* The card sits on unpredictable photography, so it carries its own opaque
   ground rather than relying on the image behind it. Ink is the page ink, so
   the panel reads the same in either theme. */
.saga-card {
  max-width: 30rem;
  border-radius: var(--r-box);
  background: color-mix(in oklab, var(--ground) 94%, transparent);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  box-shadow: 0 24px 60px rgb(27 37 69 / 0.22), inset 0 0 0 1px var(--rule-soft);
  padding: clamp(1.6rem, 3vw, 2.6rem);
  color: var(--ink);
  pointer-events: auto;
}

.saga-card .display { color: var(--ink); }
.saga-card .body { color: var(--ink-mute); }
.saga-card .switch { color: var(--ink); }

/* Where transparency is reduced, fall back to a solid panel. */
@media (prefers-reduced-transparency: reduce) {
  .saga-card { background: var(--ground); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

.saga-panel:nth-child(even) { justify-content: flex-end; }

@media (max-width: 860px) {
  .saga-panel { justify-content: flex-start !important; align-items: flex-end; padding-bottom: 12vh; }
  .saga-card { max-width: none; }
}

/* --- 15. Ledger (stepped list, replaces a bulleted run) ------------------- */

.ledger { display: grid; gap: 1px; background: var(--rule); border-radius: var(--r-box); overflow: hidden; }

.ledger > li {
  background: var(--ground);
  padding: clamp(1.1rem, 2vw, 1.8rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.45rem;
  transition: background var(--dur-m) var(--ease-out);
}

.ledger > li:hover { background: var(--ground-rise); }

@media (min-width: 861px) {
  .ledger--2 { grid-template-columns: 1fr 1fr; }
  .ledger--3 { grid-template-columns: repeat(3, 1fr); }
}

/* --- 16. Form ------------------------------------------------------------ */

.field { display: grid; gap: 0.5rem; }

.field label {
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.field .hint { font-size: 0.75rem; color: var(--ink-far); }

.field input, .field textarea, .field select {
  width: 100%;
  padding: 0.9rem 1.1rem;
  border-radius: var(--r-field);
  background: var(--ground-rise);
  color: var(--ink);
  border: 1px solid var(--rule);
  transition: border-color var(--dur-s) var(--ease-out), background var(--dur-s) var(--ease-out);
  font-size: 0.92rem;
}

.field textarea { min-height: 8rem; resize: vertical; }

/* Placeholders must clear AA against --ground-rise, so they use --ink-far. */
.field ::placeholder { color: var(--ink-far); opacity: 1; }

.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--ink-far); }

.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--ground);
}

.field .err {
  font-size: 0.76rem;
  color: #ff9a8a;
  display: none;
}

:root[data-theme="light"] .field .err,
:root:not([data-theme="dark"]) .field .err { color: #a12d16; }

.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea,
.field[data-invalid="true"] select { border-color: #ff9a8a; }

.field[data-invalid="true"] .err { display: block; }

.chipset { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.chipset label {
  position: relative;
  padding: 0.58rem 1.15rem;
  border-radius: var(--r-pill);
  font-size: 0.8rem;
  font-weight: 430;
  color: var(--ink-mute);
  box-shadow: inset 0 0 0 1px var(--rule);
  cursor: pointer;
  transition: color var(--dur-s) var(--ease-out), background var(--dur-s) var(--ease-out),
              box-shadow var(--dur-s) var(--ease-out);
}

.chipset input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.chipset label:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink-far); }

.chipset label:has(input:checked) {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.chipset label:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Submit states */
.act[data-busy="true"] { pointer-events: none; opacity: 0.72; }

.act[data-busy="true"] .act-label::after {
  content: "";
  display: inline-block;
  width: 0.6em;
  text-align: left;
  animation: dots 1.2s steps(4, end) infinite;
}

@keyframes dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }

.form-note {
  padding: 1rem 1.2rem;
  border-radius: var(--r-field);
  box-shadow: inset 0 0 0 1px var(--rule);
  background: var(--ground-rise);
  font-size: 0.86rem;
}

.form-note[data-tone="bad"] { box-shadow: inset 0 0 0 1px #ff9a8a; }
.form-note[data-tone="good"] { box-shadow: inset 0 0 0 1px var(--accent); }

/* --- 17. Footer ---------------------------------------------------------- */

.foot { border-top: 1px solid var(--rule); padding-block: var(--bay-sm) 2.5rem; }
.foot a:hover { color: var(--accent); }

.foot-heads {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-family: var(--face-text);
  font-weight: 600;
  color: var(--ink-mute);
  margin-bottom: 1.1rem;
}

.foot-list { display: grid; gap: 0.45rem; font-size: 0.88rem; color: var(--ink-mute); }

.theme-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--face-data);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-far);
  padding: 0.4rem 0;
}

.theme-switch:hover { color: var(--ink); }

.theme-switch i {
  width: 26px; height: 13px; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px currentColor;
  position: relative;
}

.theme-switch i::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  transition: transform var(--dur-m) var(--ease-out);
}

:root[data-theme="light"] .theme-switch i::after { transform: translateX(13px); }

/* --- 18. Utilities ------------------------------------------------------- */

.stack   { display: grid; align-content: start; }
.stack-1 { gap: 0.5rem; }  .stack-2 { gap: 1rem; }
.stack-3 { gap: 1.6rem; }  .stack-4 { gap: 2.6rem; }
.stack-5 { gap: clamp(2.6rem, 5vw, 4.5rem); }

.row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.mute { color: var(--ink-mute); }
.far  { color: var(--ink-far); }
.tint { color: var(--accent); }
.pull-up { margin-top: clamp(-9rem, -7vw, -2rem); }

.skip {
  position: absolute;
  border-radius: var(--r-pill);
  left: -9999px;
  z-index: var(--z-grain);
  padding: 0.8rem 1.2rem;
  background: var(--accent);
  color: var(--on-accent);
}

.skip:focus { left: var(--pad); top: 0.75rem; }

.sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- 18b. Entrance ------------------------------------------------------- */
/* Runs once on load, before any scroll happens, so the page arrives rather
   than simply appearing. Everything is transform and opacity. */

.js body { opacity: 0; }
.js body.ready { opacity: 1; transition: opacity 0.5s var(--ease-out); }

.js .masthead { transform: translateY(-100%); }
.js body.ready .masthead { transform: none; transition: transform 0.9s var(--ease-out) 0.1s; }

.js .hero-bed { transform: scale(1.12); }
.js body.ready .hero-bed { transform: scale(1); transition: transform 1.8s var(--ease-out); }

.js .hero-drift { opacity: 0; transform: translateY(40px) scale(0.94); }
.js body.ready .hero-drift {
  opacity: 1; transform: none;
  transition: opacity 0.9s var(--ease-out) 0.55s, transform 1.2s var(--ease-out) 0.55s;
}

@media (prefers-reduced-motion: reduce) {
  .js body, .js body.ready { opacity: 1; }
  .js .masthead, .js .hero-bed, .js .hero-drift { transform: none; opacity: 1; }
}

/* --- 19. Page transitions ------------------------------------------------ */
/* Cross-document view transitions. Browsers without support simply navigate. */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: vt-out 0.32s var(--ease-io) both; }
::view-transition-new(root) { animation: vt-in 0.52s var(--ease-out) both; }

@keyframes vt-out { to { opacity: 0; transform: translateY(-14px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(20px); } }

/* --- 20. Reduced motion -------------------------------------------------- */
/* Everything above collapses to a static, fully legible page. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .rise > * { transform: none !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .plate[data-shutter] img { clip-path: none !important; transform: none !important; }
  .saga-frame img { opacity: 1; transform: none; }
  .saga-frame img:not(.is-live) { opacity: 0; }
  .act--magnetic { translate: none !important; }
  .hero-bed, .hero-drift { transform: none !important; }
  @view-transition { navigation: none; }
}
