/* ═══════════════════════════════════════════════════════════════════
   BoostU — "Night-Shift Dispatch Console"
   See BRIEF.md for the design system and why it looks like this.

   Ground #0A0C12 · panel #12151E · ink #EDEAE3 · violet #937CFF (live only)
   amber #F5A524 (DOT signage) · paper #F4F1EA (the dawn chapter)

   Type: IBM Plex Sans (display) / IBM Plex Mono (data) / Golos Text (body)
   All three verified to carry U+0400–045F — UZ and RU are primary languages.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --ground:#0A0C12; --panel:#12151E; --panel2:#171B26;
  --line:#232838;   --line2:#2E3446;
  --ink:#EDEAE3;    --ink2:#B9BDC9;  --muted:#7A8091;
  --violet:#937CFF; --violet2:#6B4EE6;
  --amber:#F5A524;
  --paper:#F4F1EA;  --paper-ink:#16131F;

  --fd:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --fm:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
  --fb:'Golos Text','IBM Plex Sans',system-ui,sans-serif;

  --e-out:cubic-bezier(.16,1,.3,1);
  --e-snap:cubic-bezier(.77,0,.175,1);

  --wrap:1280px;
  --gut:clamp(1.1rem,4vw,3.5rem);
  --sp:clamp(4.5rem,9vw,8.5rem);
  --top:88px;
  --rail:46px;              /* gutter the module journey line is routed down */
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:var(--fb); font-size:clamp(15px,.55vw + 13.4px,17px);
  line-height:1.65; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
a{color:inherit}
::selection{background:var(--violet);color:#0A0C12}

/* ── the trace ──
   The cursor pulls three strands behind it, everywhere on the page. It sits
   above the content so it is visible over panels rather than only in the gaps,
   which means legibility is the whole design constraint: it never intercepts a
   click, and it only ever *lightens* the dark ground — screen blending leaves
   near-white text untouched because the text is already brighter than anything
   the trace draws. Under the fixed chrome, so it never paints over the status
   bar or the dock. */
.trace{
  position:fixed;inset:0;z-index:900;pointer-events:none;
  mix-blend-mode:screen;contain:strict
}
/* the dawn chapter inverts the problem: on paper the ground is brighter than
   the ink, so the trace has to darken instead of lighten to stay visible —
   and multiplying can only push the dark text further from the page, never
   closer to it */
.trace.on-paper{mix-blend-mode:multiply}

/* only ever created on file:// with no server answering — the "you opened the
   file, not the site" card. Amber: it is signage, not an error state. */
.file-note{
  position:fixed;left:1.2rem;bottom:1.2rem;z-index:1300;max-width:min(92vw,460px);
  background:var(--panel);border:1px solid var(--line2);border-left:3px solid var(--amber);
  color:var(--ink);font-size:.72rem;line-height:1.6;letter-spacing:.02em;
  padding:.85rem 1rem;border-radius:3px;box-shadow:0 8px 30px rgba(0,0,0,.5)
}

/* grain — warmth and depth on a near-black ground */
body::after{
  content:''; position:fixed; inset:0; z-index:9999; pointer-events:none; opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

::-webkit-scrollbar{width:11px}
::-webkit-scrollbar-track{background:#080a0f}
::-webkit-scrollbar-thumb{background:#262c3c;border:3px solid #080a0f;border-radius:99px}
::-webkit-scrollbar-thumb:hover{background:#3a4256}

:focus-visible{outline:2px solid var(--violet);outline-offset:3px}

/* ─────────── type primitives ─────────── */
.mono{font-family:var(--fm);font-variant-numeric:tabular-nums lining-nums}
.num{font-variant-numeric:tabular-nums lining-nums}

h1,h2,h3,h4{font-family:var(--fd);font-weight:600;margin:0;text-wrap:balance}
h1{letter-spacing:-.035em;line-height:.98}
h2{font-size:clamp(1.85rem,3.6vw,3.35rem);letter-spacing:-.03em;line-height:1.04}
h3{font-size:clamp(1.05rem,1.15vw,1.3rem);letter-spacing:-.015em;line-height:1.25}
h4{font-size:.98rem;letter-spacing:-.01em}
p{margin:0}

.eyebrow{
  font-size:.7rem;text-transform:uppercase;letter-spacing:.16em;
  color:var(--violet);margin:0 0 .85rem
}
.lead{font-size:clamp(1rem,.85vw + .78rem,1.16rem);color:var(--ink2);max-width:60ch;line-height:1.6}
.src{font-size:.72rem;color:var(--muted);letter-spacing:.02em;line-height:1.6}
.src a{color:var(--ink2);text-underline-offset:3px}

.wrap{max-width:var(--wrap);margin:0 auto;padding-inline:var(--gut)}

/* ─────────── buttons ─────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font-family:var(--fd);font-size:.82rem;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;text-decoration:none;
  padding:.95rem 1.5rem;border:1px solid transparent;border-radius:2px;
  cursor:pointer;position:relative;overflow:hidden;
  transition:background .35s var(--e-out),color .35s var(--e-out),border-color .35s var(--e-out),transform .5s var(--e-out);
}
.btn-lg{padding:1.15rem 2rem;font-size:.86rem}
.btn-p{background:var(--violet);color:#0B0714;border-color:var(--violet)}
.btn-p:hover{background:#a893ff;border-color:#a893ff}
.btn-g{border-color:var(--line2);color:var(--ink);background:transparent}
.btn-g:hover{border-color:var(--ink);background:rgba(237,234,227,.05)}

/* ─────────── the live pip ─────────── */
.pip{
  width:7px;height:7px;border-radius:50%;background:var(--muted);flex:none;
  box-shadow:0 0 0 0 currentColor;
}
.pip-live{background:#4ADE80;animation:pulse 2.6s var(--e-out) infinite}
.pip-violet{background:var(--violet)}
.pip-amber{background:var(--amber)}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(74,222,128,.5)}
  70%{box-shadow:0 0 0 7px rgba(74,222,128,0)}
  100%{box-shadow:0 0 0 0 rgba(74,222,128,0)}
}
.shift.off .pip{background:var(--muted);animation:none}

/* ═══════════════════ BOOT ═══════════════════ */
.boot{
  position:fixed;inset:0;z-index:9000;background:var(--ground);
  display:grid;place-items:center;
  transition:opacity .6s var(--e-out),visibility .6s;
}
.boot.done{opacity:0;visibility:hidden}
.boot-in{text-align:center;width:min(320px,80vw)}
.boot-logo{width:150px;margin:0 auto 1.9rem;opacity:0;animation:bootIn .7s var(--e-out) .1s forwards}
.boot-bar{height:2px;background:var(--line);overflow:hidden;margin-bottom:1.1rem}
.boot-bar i{display:block;height:100%;width:0;background:var(--violet);animation:bootBar 1.15s var(--e-snap) .25s forwards}
.boot-l1,.boot-l2{font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;opacity:0}
.boot-l1{color:var(--ink);animation:bootIn .5s var(--e-out) .45s forwards;margin-bottom:.3rem}
.boot-l2{color:var(--muted);animation:bootIn .5s var(--e-out) .65s forwards}
@keyframes bootIn{to{opacity:1}}
@keyframes bootBar{to{width:100%}}

/* ═══════════════════ PROGRESS ═══════════════════ */
.prog{position:fixed;top:0;left:0;right:0;height:2px;z-index:1200;background:transparent}
.prog i{display:block;height:100%;width:0;background:var(--violet)}

/* ═══════════════════ OPS BAR ═══════════════════ */
.ops{
  position:fixed;top:0;left:0;right:0;z-index:1100;
  /* No backdrop blur: a fixed bar over a scrolling page makes the compositor
     re-blur its whole strip on every scrolled frame, at device resolution.
     A denser ground reads the same against this page's near-black chapters. */
  background:rgba(10,12,18,.94);
  border-bottom:1px solid var(--line);
}
.ops-in{
  max-width:var(--wrap);margin:0 auto;padding:0 var(--gut);height:58px;
  display:flex;align-items:center;gap:1.5rem;
}
.brand{flex:none;display:block}
.brand img{width:104px}

.ops-clocks{display:flex;align-items:center;gap:.85rem;margin-inline:auto}
.clk{display:flex;flex-direction:column;line-height:1.1}
.clk-k{font-size:.58rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted)}
.clk-t{font-size:.94rem;font-weight:500;color:var(--ink)}
.clk-gap{display:flex;gap:3px;align-items:center;padding-top:.5rem}
.clk-gap span{width:3px;height:3px;border-radius:50%;background:var(--line2)}
.shift{display:flex;align-items:center;gap:.5rem;margin-left:.6rem;padding-left:.95rem;border-left:1px solid var(--line)}
.shift-t{font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;color:var(--ink2);white-space:nowrap}

.ops-r{display:flex;align-items:center;gap:.85rem;flex:none}
.lang{display:flex;border:1px solid var(--line);border-radius:2px;overflow:hidden}
.lang button{
  background:transparent;border:0;color:var(--muted);cursor:pointer;
  font-family:var(--fm);font-size:.68rem;letter-spacing:.08em;padding:.42rem .58rem;
  transition:background .25s,color .25s;
}
.lang button:hover{color:var(--ink)}
.lang button[aria-current="true"]{background:var(--ink);color:var(--ground)}
.ops-r .btn{padding:.7rem 1.05rem;font-size:.72rem}

.menu-b{display:none;width:40px;height:36px;background:transparent;border:1px solid var(--line);border-radius:2px;cursor:pointer;position:relative}
.menu-b span{position:absolute;left:11px;right:11px;height:1.5px;background:var(--ink);transition:transform .35s var(--e-out),opacity .2s}
.menu-b span:nth-child(1){top:12px}.menu-b span:nth-child(2){top:17px}.menu-b span:nth-child(3){top:22px}
.menu-b[aria-expanded="true"] span:nth-child(1){transform:translateY(5px) rotate(45deg)}
.menu-b[aria-expanded="true"] span:nth-child(2){opacity:0}
.menu-b[aria-expanded="true"] span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}

/* ─────────── ticker ─────────── */
.tick{display:flex;align-items:center;height:29px;border-top:1px solid var(--line);overflow:hidden}
.tick-k{
  flex:none;font-size:.6rem;text-transform:uppercase;letter-spacing:.13em;
  color:var(--ground);background:var(--amber);padding:.32rem .7rem;height:100%;
  display:flex;align-items:center;
}
.tick-vp{flex:1;overflow:hidden;position:relative;height:100%}
.tick-row{
  position:absolute;top:0;left:0;height:100%;display:flex;align-items:center;gap:2.2rem;
  white-space:nowrap;font-size:.68rem;letter-spacing:.05em;color:var(--ink2);
  animation:tickRun 46s linear infinite;
}
.tick-row b{color:var(--ink);font-weight:500}
.tick-row .up{color:#4ADE80}
.tick-row .dn{color:#F87171}
@keyframes tickRun{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ─────────── mobile sheet ─────────── */
.sheet{
  position:fixed;inset:var(--top) 0 0;z-index:1050;background:var(--ground);
  transform:translateY(-100%);transition:transform .55s var(--e-snap);
  overflow-y:auto;visibility:hidden;
}
.sheet.open{transform:translateY(0);visibility:visible}
.sheet-in{padding:2rem var(--gut) 3rem;display:flex;flex-direction:column}
.sheet-in a{
  font-family:var(--fd);font-size:1.4rem;font-weight:600;letter-spacing:-.02em;
  text-decoration:none;padding:.72rem 0;border-bottom:1px solid var(--line);
}

/* ─────────── desktop dock ─────────── */
.dock{
  position:fixed;bottom:1.4rem;left:50%;transform:translateX(-50%);z-index:1000;
  display:flex;gap:.15rem;padding:.4rem;
  background:rgba(18,21,30,.96);  /* was backdrop-blur; see .ops */
  border:1px solid var(--line);border-radius:3px;
  opacity:0;pointer-events:none;transition:opacity .5s var(--e-out);
}
.dock.show{opacity:1;pointer-events:auto}
.dock a{
  font-family:var(--fm);font-size:.65rem;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);text-decoration:none;padding:.45rem .72rem;border-radius:2px;
  white-space:nowrap;transition:color .25s,background .25s;
}
.dock a:hover{color:var(--ink)}
.dock a.cur{color:var(--ground);background:var(--violet)}

/* ═══════════════════ SECTIONS ═══════════════════ */
.sec{padding:var(--sp) 0;position:relative;scroll-margin-top:var(--top)}
/* Eighteen sections is a lot of page to style, lay out and paint when only
   two are ever in view. content-visibility lets the browser skip all of it
   until a section approaches the viewport — the biggest single saving this
   page has on modest hardware. #course is exempt: the journey rail is drawn
   from measured row positions, and a skipped section measures as its
   placeholder, not as itself. The intrinsic-size keeps the scrollbar and
   anchor jumps honest; `auto` pins it to the real height once rendered. */
.sec:not(#course){content-visibility:auto;contain-intrinsic-size:auto 900px}
.sec-alt{background:#0C0E16}
.sub-h{
  font-size:.7rem;text-transform:uppercase;letter-spacing:.15em;color:var(--muted);
  font-weight:400;margin:0 0 1.4rem;padding-bottom:.7rem;border-bottom:1px solid var(--line)
}

.sec-h{
  display:grid;grid-template-columns:78px minmax(0,1fr) minmax(0,.85fr);
  gap:clamp(1.5rem,3vw,3.5rem);align-items:start;margin-bottom:clamp(2.6rem,5vw,4.5rem);
}
.mm{
  font-size:.66rem;letter-spacing:.1em;color:var(--amber);
  padding-top:.45rem;border-top:1px solid var(--amber);display:block
}
.sec-h-l{min-width:0}
.sec-h .lead{padding-top:.35rem}

/* hazard divider */
.hazard{
  height:12px;
  background:repeating-linear-gradient(45deg,var(--amber) 0 12px,#0A0C12 12px 24px);
  opacity:.42;
}

/* ═══════════════════ HERO ═══════════════════ */
.hero{position:relative;padding-top:calc(var(--top) + clamp(1.8rem,4vw,3.4rem));overflow:hidden}
.hero-grid{
  position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:76px 76px;opacity:.32;
  mask-image:radial-gradient(115% 78% at 30% 10%,#000 0%,transparent 72%);
}
.hero-wrap{
  position:relative;display:grid;
  grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
  gap:clamp(2rem,4vw,4.5rem);align-items:start;
}
.hero-l{min-width:0}
.kicker{
  display:flex;align-items:center;gap:.6rem;font-size:.68rem;
  text-transform:uppercase;letter-spacing:.17em;color:var(--ink2);margin:0 0 1.5rem
}
.kicker-pip{width:5px;height:5px;background:var(--amber);flex:none}
.hero-top{position:relative}

/* ═══════════════════ THE TAPE ═══════════════════
   A headline that behaves like ticker tape: one line, full bleed, running past
   both edges, pulled along by the page's own scroll. It is deliberately NOT
   self-animating — an <h1> that slides away on its own takes the offer with it,
   and auto-motion over 5s needs a stop control to be accessible. Tying it to
   scroll means the reader drives it, and at rest the promise sits exactly where
   a normal headline would. */
.tape{overflow:hidden;margin-bottom:clamp(1.4rem,2.6vw,2.2rem)}
/* the type is set on the tape, not on the segments: JS shrinks it to fit the
   offer on screen, and one declaration has to move all of it. The duplicate is
   a <span> rather than an <h1>, so the h1 element rules are restated here —
   otherwise the two copies measure differently and the loop visibly jumps. */
.tape-in{
  display:flex;align-items:baseline;width:max-content;white-space:nowrap;
  font-family:var(--fd);font-weight:600;letter-spacing:-.035em;line-height:.98;
  font-size:clamp(2.4rem,5.2vw,4.4rem);
  padding-left:var(--tape-pad,var(--gut));
  transform:translate3d(var(--tx,0px),0,0);will-change:transform
}
/* scoped, because .h1 is declared below this block and would otherwise win the
   font-size at equal specificity and pin the tape back to the CSS clamp */
.tape-in .tape-seg{margin:0;flex:none;font:inherit;letter-spacing:inherit}
/* the continuation is quieter than the offer — same voice, lower register */
.tape-seg.tape-x{color:var(--muted)}
/* the second pass has to lay out exactly like the first, so it is the same kind
   of row. Left as a plain span, the block-level glyphs inside it stack and the
   tape grows to five lines tall. */
.tape-dup{display:flex;align-items:baseline;flex:none}
/* the glyphs are punctuation, so they are spaced like it: tighter than a word
   gap on both sides and sized off the line they sit on */
.tg{flex:none;display:block;margin:0 .42em;transform:translateY(.06em)}
.tg-arc{width:1.85em;height:.66em}
.tg-night{width:.62em;height:.62em}
.tg-chev{width:1.05em;height:.6em}
.tg .s{fill:none;stroke:var(--amber);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.tg .d{fill:var(--amber)}
.tg .rim{fill:none;stroke:var(--line2);stroke-width:2.4}
.tg .dark{fill:var(--ink2)}

/* the fallback size; on the tape, JS overrides it to fit the offer on screen */
.h1{font-size:clamp(2.4rem,5.2vw,4.4rem);margin:0 0 1.3rem}
.h1 em{font-style:normal;color:var(--violet)}
.hero-badge{
  display:inline-block;font-size:.66rem;text-transform:uppercase;letter-spacing:.12em;
  color:var(--ink2);border:1px solid var(--line2);padding:.42rem .8rem;border-radius:2px;margin-bottom:1.5rem
}
.hero-sub{margin-bottom:1.8rem;max-width:50ch;font-size:clamp(.98rem,.6vw + .82rem,1.08rem)}
.hero-cta{display:flex;flex-wrap:wrap;gap:.75rem;margin-bottom:2rem}
.hero-note{
  font-size:.79rem;color:var(--muted);max-width:46ch;line-height:1.6;
  padding-top:1.3rem;border-top:1px solid var(--line)
}

/* ─────────── console panel ─────────── */
.pnl{background:var(--panel);border:1px solid var(--line);border-radius:3px;position:relative}
.pnl::before{
  content:'';position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(237,234,227,.13),transparent)
}
.pnl-h{
  display:flex;align-items:center;gap:.6rem;padding:.72rem .95rem;
  border-bottom:1px solid var(--line);
  font-size:.66rem;text-transform:uppercase;letter-spacing:.12em;color:var(--ink2)
}
.pnl-h-r{margin-left:auto;color:var(--muted);font-size:.62rem;letter-spacing:.09em}
.pnl-b{padding:1.15rem}
.pnl-f{border-top:1px solid var(--line);padding:.95rem}

.hero-pnl{overflow:hidden}
.hb{display:flex;flex-direction:column}
.hb-r{
  display:grid;grid-template-columns:1fr auto auto;gap:.9rem;align-items:center;
  padding:.62rem .95rem;border-bottom:1px solid rgba(35,40,56,.62);
  font-family:var(--fm);font-size:.72rem;
  opacity:0;transform:translateX(-12px);
}
.hb-r.in{opacity:1;transform:none;transition:opacity .5s var(--e-out),transform .5s var(--e-out)}
.hb-l{color:var(--ink);letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hb-m{color:var(--muted);font-variant-numeric:tabular-nums}
.hb-v{color:var(--amber);font-variant-numeric:tabular-nums;font-weight:500}
.hb-v.hi{color:#4ADE80}

.snap{display:grid;grid-template-columns:1fr 1fr;gap:.85rem 1.2rem}
.snap div{display:flex;flex-direction:column;gap:.15rem}
.snap-k{font-size:.58rem;text-transform:uppercase;letter-spacing:.13em;color:var(--muted)}
.snap b{font-family:var(--fd);font-size:1.02rem;font-weight:600;color:var(--ink)}

/* ─────────── the night side ─────────── */
.globe{
  position:relative;height:clamp(300px,34vw,500px);margin-top:clamp(2rem,4vw,3.5rem);
  overflow:hidden;
}
/* The WebGL globe layers over the static SVG rather than replacing it, so a
   failed import or a lost context falls back to something already painted. */
/* Faded in by globe.js on its first rendered frame, not on a timer: a blind
   animation reaches opacity 1 whether or not the canvas has anything in it,
   and pairs with the hidden fallback below to show a black band. */
.gl-canvas{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  opacity:0;transition:opacity 1.2s var(--e-out);
  /* a sideways drag turns the earth, a vertical one still scrolls the page —
     the strip is full-bleed, so swallowing vertical touch would trap the reader */
  touch-action:pan-y
}
/* `animation:none` is load-bearing: .gl-fb fades in under `glFbIn ... both`,
   and a filling animation outranks a normal declaration in the cascade, so
   without dropping it here the opacity:0 below never applies and the static
   SVG stays composited under the canvas for the life of the page. */
.globe.is3d>.gl-fb{opacity:0;animation:none;transition:opacity .6s var(--e-out)}
/* the earth can be picked up and turned, so say so with the standard grip.
   Only once WebGL is up: the static fallback has nothing to respond with. */
.globe.is3d{cursor:grab}
.globe.is3d.is-drag{cursor:grabbing}
/* the press starts on the canvas but the hand often ends up over the copy;
   without this the drag paints a text selection across the hero */
.gl-dragging,.gl-dragging *{user-select:none;-webkit-user-select:none}
.gl-dragging{cursor:grabbing}
.gl-fb{
  position:absolute;inset:0;width:100%;height:100%;
  animation:glFbIn 1s var(--e-out) both
}
@keyframes glFbIn{from{opacity:0}to{opacity:1}}

/* city labels ride the projected marker positions, so they are placed by JS
   and only styled here */
.gl-labels{position:absolute;inset:0;pointer-events:none;z-index:2}
.gl-label{
  position:absolute;top:0;left:0;white-space:nowrap;
  font-size:.58rem;text-transform:uppercase;letter-spacing:.16em;color:var(--ink2);
  padding:.28rem .5rem;background:rgba(10,12,18,.78);border:1px solid var(--line)
}
/* the earth is fully round, so the sides of a wide strip want softening */
.globe::before,.globe::after{
  content:'';position:absolute;top:0;bottom:0;width:clamp(40px,9vw,170px);
  z-index:1;pointer-events:none
}
.globe::before{left:0;background:linear-gradient(90deg,var(--ground),transparent)}
.globe::after{right:0;background:linear-gradient(270deg,var(--ground),transparent)}
.scroll-cue{
  position:absolute;bottom:1.2rem;right:var(--gut);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:.5rem;
  font-size:.6rem;text-transform:uppercase;letter-spacing:.16em;color:var(--muted);
  text-decoration:none
}
.scroll-cue svg{width:11px;animation:cue 2.2s var(--e-out) infinite}
@keyframes cue{0%,100%{transform:translateY(0);opacity:.5}50%{transform:translateY(5px);opacity:1}}

/* ═══════════════════ ODOMETER ═══════════════════ */
.odo-strip{
  display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);
  margin-bottom:clamp(3rem,6vw,5rem)
}
.odo-i{background:var(--ground);padding:clamp(1.1rem,2vw,1.8rem)}
.odo{
  display:flex;font-family:var(--fm);font-weight:500;
  font-size:clamp(2.4rem,5vw,4.2rem);line-height:1;color:var(--ink);
  letter-spacing:-.03em;margin-bottom:.7rem
}
.odo-w{height:1em;overflow:hidden}
.odo-s{
  display:flex;flex-direction:column;
  transform:translateY(0);transition:transform 1.5s var(--e-out)
}
.odo-s span{height:1em;display:flex;align-items:center}
.odo-tx{display:flex;flex-direction:column;gap:.1rem}
.odo-tx b{font-family:var(--fd);font-size:.84rem;font-weight:600;color:var(--ink)}
.odo-tx span{font-size:.74rem;color:var(--muted)}

/* ═══════════════════ DOORS (trailer-door cards) ═══════════════════ */
.doors{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.door{
  background:var(--panel);padding:clamp(1.3rem,2.2vw,2rem);position:relative;
  transition:background .45s var(--e-out);
  /* ribbed trailer-door texture */
  background-image:repeating-linear-gradient(90deg,rgba(237,234,227,.018) 0 1px,transparent 1px 22px);
}
.door:hover{background-color:var(--panel2)}
.door-n{
  display:block;font-size:.64rem;letter-spacing:.14em;color:var(--amber);margin-bottom:1.5rem
}
.door h3{margin-bottom:.6rem}
.door p{font-size:.87rem;color:var(--ink2);line-height:1.62}
.doors-3{grid-template-columns:repeat(3,1fr)}

/* ═══════════════════ MARKET ═══════════════════ */
.keys{
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(1.2rem,2.5vw,2.5rem);
  margin-bottom:clamp(2.5rem,5vw,4rem)
}
.key{border-top:1px solid var(--line2);padding-top:1.1rem}
.key-n{
  display:block;font-size:clamp(1.6rem,3vw,2.5rem);font-weight:500;
  color:var(--violet);letter-spacing:-.03em;line-height:1;margin-bottom:.7rem
}
.key p{font-size:.81rem;color:var(--ink2);line-height:1.55}

.mkt-c{display:grid;grid-template-columns:1fr 1fr;gap:1.4rem;margin-bottom:1.6rem}
.mkt-card .pnl-b p{font-size:.88rem;color:var(--ink2);line-height:1.68}

/* ═══════════════════ MAP ═══════════════════ */
.map-wrap{display:grid;grid-template-columns:minmax(0,1fr) 210px;gap:clamp(1.4rem,2.5vw,2.4rem);align-items:start;margin-bottom:clamp(2.8rem,5vw,4.2rem)}
.map-pnl{overflow:hidden}
.map-holder{padding:clamp(.8rem,2vw,1.6rem);position:relative}
.map-holder svg{width:100%;height:auto;overflow:visible}
.dot{fill:var(--line2);opacity:0;transition:opacity .5s var(--e-out),fill .5s}
.dot.on{opacity:1}
.lane{
  fill:none;stroke:var(--violet);stroke-width:1.5;stroke-linecap:round;
  stroke-dasharray:5 5;opacity:.85
}
.lane-bg{fill:none;stroke:var(--violet);stroke-width:4;opacity:.09;stroke-linecap:round}
.city{opacity:0;transform-box:fill-box;transform-origin:center}
.city.on{animation:pop .55s var(--e-out) forwards}
@keyframes pop{from{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}
.city circle{fill:var(--amber)}
.city text{
  fill:var(--ink2);font-family:var(--fm);font-size:9.5px;letter-spacing:.06em;
  text-transform:uppercase
}
.city.hub circle{fill:var(--violet)}
.city.hub text{fill:var(--ink);font-weight:500}
.hub-ring{fill:none;stroke:var(--violet);stroke-width:1.2;opacity:.5;transform-box:fill-box;transform-origin:center;animation:ring 3.2s var(--e-out) infinite}
@keyframes ring{0%{transform:scale(.5);opacity:.7}100%{transform:scale(2.6);opacity:0}}

.map-legend{
  display:flex;flex-wrap:wrap;gap:1.2rem;padding:.8rem .95rem;
  border-top:1px solid var(--line);font-size:.63rem;text-transform:uppercase;
  letter-spacing:.1em;color:var(--muted)
}
.map-legend span{display:flex;align-items:center;gap:.45rem}
.lg{width:9px;height:9px;flex:none;border-radius:50%}
.lg-hub{background:var(--violet)}
.lg-city{background:var(--amber)}
.lg-lane{border-radius:0;height:2px;width:16px;background:repeating-linear-gradient(90deg,var(--violet) 0 4px,transparent 4px 8px)}

.map-side{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line)}
.mstat{background:var(--panel);padding:1rem 1.1rem}
.mstat b{
  display:block;font-size:1.8rem;font-weight:500;color:var(--ink);
  letter-spacing:-.03em;line-height:1;margin-bottom:.35rem
}
.mstat span{font-size:.7rem;color:var(--muted);line-height:1.4;display:block}

/* DOT plates */
.plates{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;margin-bottom:1.6rem}
.plate{
  background:var(--panel);border:1px solid var(--line2);border-radius:3px;
  padding:.85rem .95rem;transition:border-color .4s var(--e-out),transform .4s var(--e-out)
}
.plate:hover{border-color:var(--amber);transform:translateY(-2px)}
.plate-n{
  font-family:var(--fd);font-size:.9rem;font-weight:600;color:var(--ink);
  margin-bottom:.15rem;line-height:1.2
}
.plate-c{font-size:.7rem;color:var(--muted);margin-bottom:.7rem}
.plate-d{
  display:flex;gap:.9rem;padding-top:.65rem;border-top:1px dashed var(--line2);
  font-family:var(--fm);font-size:.64rem;letter-spacing:.04em
}
.plate-d div{display:flex;flex-direction:column;gap:.1rem}
.plate-d i{font-style:normal;color:var(--muted);font-size:.56rem;letter-spacing:.1em;text-transform:uppercase}
.plate-d b{color:var(--amber);font-weight:500;font-variant-numeric:tabular-nums}
.map-foot{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}

/* ═══════════════════ LOAD BOARD ═══════════════════ */
.sec-board{background:#0C0E16}
.lb{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:clamp(1.2rem,2.2vw,2rem);align-items:start;margin-bottom:1.4rem}
.lb-pnl{overflow:hidden}
.lb-scroll{overflow-x:auto}
.lb-t{width:100%;border-collapse:collapse;min-width:640px}
.lb-t th{
  text-align:left;font-size:.6rem;font-weight:400;text-transform:uppercase;
  letter-spacing:.13em;color:var(--muted);padding:.7rem .85rem;
  border-bottom:1px solid var(--line);white-space:nowrap
}
.lb-t th.num{text-align:right}
.lb-t td{padding:.72rem .85rem;border-bottom:1px solid rgba(35,40,56,.6);font-size:.79rem}
.lb-t tbody tr{
  cursor:pointer;transition:background .3s var(--e-out);
  opacity:0;transform:translateY(9px)
}
.lb-t tbody tr.in{opacity:1;transform:none;transition:opacity .5s var(--e-out),transform .5s var(--e-out),background .3s}
.lb-t tbody tr:hover{background:rgba(147,124,255,.055)}
.lb-t tbody tr.sel{background:rgba(147,124,255,.1)}
.lb-t tbody tr.sel td:first-child{box-shadow:inset 2px 0 0 var(--violet)}
.lb-lane{font-family:var(--fm);color:var(--ink);white-space:nowrap}
.lb-lane em{font-style:normal;color:var(--muted)}
.lb-eq{font-family:var(--fm);font-size:.68rem;color:var(--ink2);white-space:nowrap}
.lb-t td.num{text-align:right;font-family:var(--fm);font-variant-numeric:tabular-nums;white-space:nowrap}
.lb-rate{color:var(--ink);font-weight:500}
.lb-rpm{font-weight:500}
.lb-rpm.g{color:#4ADE80}.lb-rpm.t{color:var(--amber)}.lb-rpm.b{color:#F87171}
.lb-age{color:var(--muted);font-size:.7rem}
.lb-bk{
  font-family:var(--fm);font-size:.6rem;text-transform:uppercase;letter-spacing:.1em;
  background:transparent;border:1px solid var(--line2);color:var(--ink2);
  padding:.34rem .6rem;border-radius:2px;cursor:pointer;white-space:nowrap;
  transition:all .3s var(--e-out)
}
.lb-bk:hover{border-color:var(--violet);color:var(--violet)}
tr.booked .lb-bk{background:var(--violet);border-color:var(--violet);color:#0B0714;pointer-events:none}
tr.booked{opacity:.55}

.lb-out{position:sticky;top:calc(var(--top) + 1rem)}
.lb-out-b{padding:1.15rem}
.lb-hint{font-size:.7rem;text-transform:uppercase;letter-spacing:.11em;color:var(--muted);text-align:center;padding:2.5rem 0}
.ro-lane{font-family:var(--fd);font-size:1.12rem;font-weight:600;letter-spacing:-.015em;margin-bottom:.2rem}
.ro-eq{font-family:var(--fm);font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);margin-bottom:1.15rem}
.ro-rows{display:flex;flex-direction:column;gap:0;margin-bottom:1.15rem}
.ro-r{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;padding:.5rem 0;border-bottom:1px solid rgba(35,40,56,.6)}
.ro-r span{font-size:.76rem;color:var(--muted)}
.ro-r b{font-family:var(--fm);font-size:.86rem;font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums}
.ro-r.net{border-bottom:0;padding-top:.8rem;margin-top:.3rem;border-top:1px solid var(--line2)}
.ro-r.net span{color:var(--ink2);font-size:.8rem}
.ro-r.net b{font-size:1.25rem;color:var(--violet)}
.ro-v{padding:.85rem .95rem;border-radius:2px;border-left:2px solid}
.ro-v b{display:block;font-family:var(--fd);font-size:.88rem;margin-bottom:.25rem}
.ro-v p{font-size:.78rem;color:var(--ink2);line-height:1.55}
.ro-v.g{background:rgba(74,222,128,.07);border-color:#4ADE80}
.ro-v.g b{color:#4ADE80}
.ro-v.t{background:rgba(245,165,36,.07);border-color:var(--amber)}
.ro-v.t b{color:var(--amber)}
.ro-v.b{background:rgba(248,113,113,.07);border-color:#F87171}
.ro-v.b b{color:#F87171}
.lb-notes{display:flex;flex-direction:column;gap:.4rem;max-width:78ch}

/* ═══════════════════ HOURS / DIAL ═══════════════════ */
.hours-g{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1fr);gap:clamp(2rem,4vw,4rem);align-items:center}
.dial-wrap{display:flex;justify-content:center}
.dial{width:min(340px,80vw)}
.dial svg{width:100%;height:auto}
.d-ring{fill:none;stroke:var(--line);stroke-width:1}
.d-night{fill:none;stroke:#1E2440;stroke-width:16}
.d-open{fill:none;stroke:var(--amber);stroke-width:16;opacity:.9}
.d-hand{stroke:var(--violet);stroke-width:2;stroke-linecap:round}
.d-hub{fill:var(--violet)}
.d-tk{stroke:var(--line2);stroke-width:1}
.d-lbl{fill:var(--muted);font-family:var(--fm);font-size:9px;letter-spacing:.08em}
/* text-anchor is load-bearing, not cosmetic: these three are placed on the
   dial's centre line (x=150) and SVG anchors text at its start by default, so
   without this they hang off the centre to the right — far enough that the
   Cincinnati line crosses the ring and runs into the 06 label. The hour labels
   escaped this only because they set text-anchor inline. */
.d-c1,.d-c2{text-anchor:middle}
.d-c1{fill:var(--ink);font-family:var(--fm);font-size:20px;font-weight:500}
.d-c2{fill:var(--muted);font-family:var(--fm);font-size:8.5px;letter-spacing:.14em;text-transform:uppercase}
.hours-n{display:flex;flex-direction:column;gap:1.35rem}
.hn b{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.13em;color:var(--amber);margin-bottom:.45rem}
.hn p{font-size:.89rem;color:var(--ink2);line-height:1.65}

/* ═══════════════════ COURSE ═══════════════════ */
.facts{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line);margin-bottom:clamp(3rem,6vw,4.5rem)}
.fact{background:var(--panel);padding:clamp(1.1rem,2vw,1.6rem);display:flex;flex-direction:column;gap:.4rem}
.fact b{font-family:var(--fd);font-size:1.12rem;font-weight:600;letter-spacing:-.02em}
.fact span{font-size:.79rem;color:var(--muted);line-height:1.5}
.mods-h{display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;flex-wrap:wrap;margin-bottom:1.4rem}
.mods-h .sub-h{margin:0;border:0;padding:0}

/* ── the journey rail ──
   A routed connector down a gutter of its own, so it never crosses the module
   numbers. The heading takes the same indent, otherwise the list reads as
   nudged sideways rather than as a column with a rail beside it. */
.mods-w{display:grid;grid-template-columns:var(--rail) minmax(0,1fr)}
.mods-h{padding-left:var(--rail)}
.jrn{position:relative}
.jrn svg{position:absolute;top:0;left:0;display:block;overflow:visible}
/* the full route, always visible: the drawn line is progress against a known
   distance, which is the whole point of showing it */
.jrn-t{fill:none;stroke:var(--line);stroke-width:1.5}
.jrn-p{
  fill:none;stroke:var(--amber);stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:1;stroke-dashoffset:1        /* pathLength=1, so 1 == undrawn */
}
.jrn-n{fill:var(--ground);stroke:var(--line);stroke-width:1.5;transition:fill .35s var(--e-out),stroke .35s var(--e-out)}
.jrn-n.on{fill:var(--amber);stroke:var(--amber)}

.mods{border-top:1px solid var(--line)}
.mod{border-bottom:1px solid var(--line)}
.mod-b{
  width:100%;background:transparent;border:0;cursor:pointer;color:inherit;
  display:grid;grid-template-columns:52px minmax(0,1fr) auto;gap:1.2rem;align-items:center;
  padding:1.15rem .3rem;text-align:left;font:inherit;
  transition:background .3s
}
.mod-b:hover{background:rgba(237,234,227,.022)}
.mod-n{font-family:var(--fm);font-size:.72rem;color:var(--amber);letter-spacing:.06em}
.mod-t{font-family:var(--fd);font-size:clamp(1rem,1.3vw,1.2rem);font-weight:600;letter-spacing:-.015em}
.mod-r{display:flex;align-items:center;gap:.9rem}
.mod-c{font-family:var(--fm);font-size:.66rem;color:var(--muted);font-variant-numeric:tabular-nums}
.mod-x{width:11px;height:11px;position:relative;flex:none}
.mod-x::before,.mod-x::after{content:'';position:absolute;background:var(--ink2);transition:transform .4s var(--e-out)}
.mod-x::before{top:5px;left:0;right:0;height:1.5px}
.mod-x::after{left:5px;top:0;bottom:0;width:1.5px}
.mod-b[aria-expanded="true"] .mod-x::after{transform:scaleY(0)}
.mod-p{overflow:hidden;height:0;transition:height .5s var(--e-out)}
.mod-in{padding:0 .3rem 1.5rem 52px}
.mod-in ul{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:.5rem 1.6rem;list-style:none;margin:0;padding:0}
.mod-in li{
  font-size:.83rem;color:var(--ink2);padding-left:1.1rem;position:relative;line-height:1.5
}
.mod-in li::before{content:'';position:absolute;left:0;top:.62em;width:5px;height:1px;background:var(--amber)}

/* ═══════════════════ STEPS / VS ═══════════════════ */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.2rem,2.5vw,2.2rem);margin-bottom:clamp(2.2rem,4vw,3.2rem);counter-reset:s}
.step{border-top:2px solid var(--violet);padding-top:1.3rem}
.step-n{display:block;font-size:.65rem;letter-spacing:.13em;color:var(--violet);margin-bottom:.9rem;text-transform:uppercase}
.step h3{margin-bottom:.55rem}
.step p{font-size:.86rem;color:var(--ink2);line-height:1.62}
.vs{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line)}
.vs-c{background:var(--panel);padding:clamp(1.2rem,2.2vw,1.8rem)}
.vs-c span{display:block;font-family:var(--fm);font-size:.64rem;text-transform:uppercase;letter-spacing:.13em;margin-bottom:.7rem}
.vs-c p{font-size:.92rem;line-height:1.55}
.vs-old span{color:var(--muted)}
.vs-old p{color:var(--muted)}
.vs-new{background:var(--panel2)}
.vs-new span{color:var(--violet)}
.vs-new p{color:var(--ink)}

/* ═══════════════════ RACK (platforms) ═══════════════════ */
.rack{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.rk{background:var(--panel);padding:clamp(1.1rem,2vw,1.6rem);display:flex;gap:1rem;transition:background .4s var(--e-out)}
.rk:hover{background:var(--panel2)}
.rk-i{font-size:.64rem;color:var(--amber);letter-spacing:.1em;flex:none;padding-top:.2rem}
.rk h4{margin-bottom:.35rem}
.rk p{font-size:.81rem;color:var(--ink2);line-height:1.55}

/* ═══════════════════ WEEK ═══════════════════ */
.week{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:var(--line);border:1px solid var(--line);margin-bottom:1rem}
.wd{background:var(--panel);padding:1rem .7rem;min-height:118px;display:flex;flex-direction:column;gap:.6rem}
.wd-k{font-family:var(--fm);font-size:.62rem;text-transform:uppercase;letter-spacing:.11em;color:var(--muted)}
.wd-v{font-family:var(--fd);font-size:.83rem;font-weight:600;line-height:1.3;letter-spacing:-.01em}
.wd.hl{background:var(--panel2)}
.wd.hl .wd-v{color:var(--violet)}
.wd.hl .wd-k{color:var(--ink2)}

/* ═══════════════════ TWO / BLK ═══════════════════ */
.two{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.2rem,2.2vw,2rem);margin-top:clamp(2.2rem,4vw,3.2rem)}
.blk .pnl-b h3{margin-bottom:.7rem}
.blk .pnl-b>p{font-size:.87rem;color:var(--ink2);line-height:1.65;margin-bottom:1.2rem}
.dl{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.55rem}
.dl li{font-size:.83rem;color:var(--ink2);padding-left:1rem;position:relative;line-height:1.5}
.dl li::before{content:'';position:absolute;left:0;top:.6em;width:5px;height:5px;background:var(--violet)}
.dl b{color:var(--ink);font-weight:600}
.ticks{list-style:none;margin:1.2rem 0 0;padding:1.2rem 0 0;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:.5rem}
.ticks li{font-size:.82rem;color:var(--ink2);padding-left:1.15rem;position:relative;line-height:1.5}
.ticks li::before{
  content:'';position:absolute;left:0;top:.42em;width:6px;height:3px;
  border-left:1.5px solid var(--amber);border-bottom:1.5px solid var(--amber);
  transform:rotate(-45deg)
}

/* ═══════════════════ GATES (exams) ═══════════════════ */
.gates{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.2rem,2.5vw,2.2rem)}
.gate{border:1px solid var(--line);border-radius:3px;padding:clamp(1.3rem,2.2vw,1.9rem);background:var(--panel);position:relative;overflow:hidden}
.gate::after{content:'';position:absolute;top:0;left:0;width:100%;height:2px;background:var(--violet);transform:scaleX(0);transform-origin:left;transition:transform .7s var(--e-out)}
.gate.in::after{transform:scaleX(1)}
.gate-n{
  display:inline-block;font-family:var(--fm);font-size:1.5rem;font-weight:500;
  color:var(--violet);letter-spacing:-.02em;margin-bottom:1.1rem
}
.gate h3{margin-bottom:1rem}
.gate ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem}
.gate li{font-size:.84rem;color:var(--ink2);line-height:1.55;padding-left:1rem;position:relative}
.gate li::before{content:'';position:absolute;left:0;top:.65em;width:5px;height:1px;background:var(--amber)}

/* ═══════════════════ CAREER ═══════════════════ */
.trio{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.2rem,2.2vw,2rem);margin-bottom:clamp(3rem,5vw,4.5rem)}
.trio .pnl-b h3{margin-bottom:.6rem}
.trio .pnl-b p{font-size:.86rem;color:var(--ink2);line-height:1.62}
.exp{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line);margin-bottom:clamp(2.2rem,4vw,3.2rem)}
.ex{background:var(--panel);padding:1.2rem;display:flex;gap:.85rem}
.ex>span{font-family:var(--fm);font-size:.62rem;color:var(--amber);letter-spacing:.1em;flex:none;padding-top:.25rem}
.ex b{display:block;font-family:var(--fd);font-size:.9rem;font-weight:600;margin-bottom:.35rem;letter-spacing:-.01em}
.ex p{font-size:.79rem;color:var(--ink2);line-height:1.55}
.dir-cta{display:flex;justify-content:space-between;align-items:center;gap:2rem;flex-wrap:wrap;padding-top:clamp(1.5rem,3vw,2.2rem);border-top:1px solid var(--line)}
.dir-cta p{font-size:.9rem;color:var(--ink2);max-width:52ch}

/* ═══════════════════ CALCULATOR ═══════════════════ */
.calc{
  display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1fr);
  gap:clamp(1.5rem,3vw,2.8rem);
  border:1px solid var(--line);background:var(--panel);border-radius:3px;
  padding:clamp(1.3rem,2.6vw,2.2rem);margin-bottom:1.2rem
}
.calc-ctl{grid-column:1/-1;display:flex;justify-content:space-between;gap:2rem;flex-wrap:wrap;align-items:flex-end;padding-bottom:1.5rem;border-bottom:1px solid var(--line)}
.tracks{flex:1 1 100%;display:flex;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:2px}
.tracks button{
  flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:.4rem;
  background:var(--panel);border:0;color:var(--muted);cursor:pointer;text-align:left;
  padding:.85rem 1.1rem .9rem;transition:color .3s var(--e-out),background .3s var(--e-out)
}
/* the role name carries the weight — the line under it is what the role does */
.trk-n{
  font-family:var(--fd);font-size:.94rem;font-weight:600;letter-spacing:-.01em;
  color:var(--ink);transition:color .3s var(--e-out)
}
.trk-d{
  font-family:var(--fm);font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;
  line-height:1.5;color:inherit
}
.tracks button:hover{color:var(--ink2)}
.tracks button[aria-selected="true"]{background:var(--violet);color:#241645}
.tracks button[aria-selected="true"] .trk-n{color:#0B0714}
.lvl{min-width:230px;flex:1;max-width:340px}
.lvl label{display:flex;gap:.5rem;font-size:.64rem;text-transform:uppercase;letter-spacing:.13em;color:var(--muted);margin-bottom:.7rem}
.lvl label b{color:var(--amber)}
.lvl input[type=range]{
  -webkit-appearance:none;appearance:none;width:100%;height:2px;background:var(--line2);
  outline:none;margin:.5rem 0
}
.lvl input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;width:16px;height:16px;border-radius:50%;
  background:var(--violet);cursor:pointer;border:3px solid var(--ground)
}
.lvl input[type=range]::-moz-range-thumb{
  width:16px;height:16px;border-radius:50%;background:var(--violet);
  cursor:pointer;border:3px solid var(--ground)
}
.lvl-ticks{display:flex;justify-content:space-between;font-size:.6rem;color:var(--muted)}

.calc-out{display:flex;flex-direction:column;gap:1.2rem}
.gauge-wrap{display:flex;justify-content:center}
.gauge{width:min(300px,72vw)}
.gauge svg{width:100%;height:auto}
.g-track{fill:none;stroke:var(--line);stroke-width:9;stroke-linecap:round}
.g-fill{fill:none;stroke:var(--violet);stroke-width:9;stroke-linecap:round}
/* the pointer rides the rim instead of sweeping through the read-out */
.g-tick{stroke:var(--amber);stroke-width:2;stroke-linecap:round}
.g-bead{fill:var(--amber);stroke:var(--ground);stroke-width:2.5}
.g-v{fill:var(--ink);font-family:var(--fm);font-weight:500;text-anchor:middle;letter-spacing:-.01em}
.g-k{fill:var(--muted);font-family:var(--fm);font-size:8.5px;letter-spacing:.14em;text-anchor:middle;text-transform:uppercase}
.g-t{fill:var(--muted);font-family:var(--fm);font-size:8.5px;letter-spacing:.08em;text-anchor:middle}
.calc-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(105px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.cm{background:var(--panel);padding:.85rem}
.cm i{display:block;font-style:normal;font-family:var(--fm);font-size:.58rem;text-transform:uppercase;letter-spacing:.12em;color:var(--muted);margin-bottom:.3rem}
.cm b{font-family:var(--fd);font-size:1rem;font-weight:600}
.calc-skills h4{font-size:.66rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);font-weight:400;margin-bottom:1.1rem;padding-bottom:.7rem;border-bottom:1px solid var(--line)}
.cs-g{margin-bottom:1.2rem}
.cs-g>b{display:block;font-family:var(--fm);font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;color:var(--amber);margin-bottom:.6rem}
.cs-g ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.4rem}
.cs-g li{
  font-size:.74rem;color:var(--ink2);border:1px solid var(--line2);
  padding:.28rem .55rem;border-radius:2px
}

/* ═══════════════════ FAQ ═══════════════════ */
.faq{border-top:1px solid var(--line);max-width:100%}
.fq{border-bottom:1px solid var(--line)}
.fq-b{
  width:100%;background:transparent;border:0;cursor:pointer;color:inherit;font:inherit;
  display:flex;gap:1.2rem;align-items:flex-start;text-align:left;padding:1.25rem .3rem;
  transition:background .3s
}
.fq-b:hover{background:rgba(237,234,227,.022)}
.fq-n{font-family:var(--fm);font-size:.68rem;color:var(--amber);flex:none;padding-top:.32rem;letter-spacing:.06em}
.fq-q{font-family:var(--fd);font-size:clamp(.96rem,1.15vw,1.1rem);font-weight:600;letter-spacing:-.015em;flex:1;line-height:1.4}
.fq-x{width:11px;height:11px;position:relative;flex:none;margin-top:.35rem}
.fq-x::before,.fq-x::after{content:'';position:absolute;background:var(--ink2);transition:transform .4s var(--e-out)}
.fq-x::before{top:5px;left:0;right:0;height:1.5px}
.fq-x::after{left:5px;top:0;bottom:0;width:1.5px}
.fq-b[aria-expanded="true"] .fq-x::after{transform:scaleY(0)}
.fq-p{overflow:hidden;height:0;transition:height .5s var(--e-out)}
.fq-in{padding:0 2.5rem 1.5rem calc(.3rem + 1.2rem + 2.2rem)}
.fq-in p{font-size:.9rem;color:var(--ink2);line-height:1.7;max-width:70ch}

/* ═══════════════════ DAWN GATE ═══════════════════ */
.dawn-gate{position:relative;height:clamp(160px,20vw,240px);overflow:hidden;background:linear-gradient(180deg,#0C0E16 0%,#241D2E 42%,#6B5570 70%,#C9A98B 88%,var(--paper) 100%)}
.dg-sun{
  position:absolute;left:50%;bottom:12%;width:min(420px,70vw);aspect-ratio:1;
  transform:translateX(-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(245,165,36,.55) 0%,rgba(245,165,36,.14) 45%,transparent 68%)
}
.dg-road{
  position:absolute;bottom:0;left:0;right:0;height:22%;
  background:linear-gradient(180deg,rgba(20,22,29,.5),transparent);
}

/* ═══════════════════ DAWN CHAPTER ═══════════════════ */
.dawn{
  --ground:var(--paper); --panel:#FFFFFF; --panel2:#EBE7DD;
  --line:#DDD7C9; --line2:#C6BFAE;
  --ink:var(--paper-ink); --ink2:#4A4458; --muted:#6E6880;
  background:var(--paper);color:var(--paper-ink)
}
.dawn .eyebrow{color:var(--violet2)}
.dawn .mm{color:#9A6B12;border-color:#9A6B12}
.dawn .pnl::before{background:none}
.dawn .btn-p{background:var(--violet2);border-color:var(--violet2);color:#fff}
.dawn .btn-p:hover{background:#5a3fd0;border-color:#5a3fd0}
.dawn .btn-g{border-color:var(--line2);color:var(--paper-ink)}
.dawn .btn-g:hover{border-color:var(--paper-ink);background:rgba(22,19,31,.04)}
.dawn ::selection{background:var(--violet2);color:#fff}

/* gallery */
.gal{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(.6rem,1.2vw,1rem);margin-bottom:clamp(2.5rem,5vw,4rem)}
.gf{margin:0;overflow:hidden;border-radius:2px;background:#EBE7DD}
.gf img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--e-out);aspect-ratio:4/3}
.gf:hover img{transform:scale(1.045)}
.gf-lg{grid-column:span 2;grid-row:span 2}
.gf-lg img{aspect-ratio:auto;height:100%;min-height:100%}
.env-l{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(2,1fr);gap:0 clamp(2rem,4vw,4rem)
}
.env-l li{
  font-size:.9rem;color:var(--ink2);line-height:1.6;padding:.95rem 0 .95rem 1.6rem;
  border-bottom:1px solid var(--line);position:relative
}
.env-l li::before{content:'';position:absolute;left:0;top:1.35em;width:8px;height:1px;background:var(--violet2)}

/* ═══════════════════ FORM ═══════════════════ */
.sec-form{background:#EFEBE1}
/* The wide-left split was sized for a six-field form. What sits here now is a
   button and two lines, so the columns are even and the short side is centred
   against the price card rather than stranded at the top of a tall row. */
.form-g{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(1.8rem,3.5vw,3.5rem);align-items:center}
/* The form is gone; what is left is the one instruction that matters and the
   channel it points at. Sized to sit level with the price card beside it. */
.apply{display:flex;flex-direction:column;align-items:flex-start;gap:1.15rem}
.apply .btn{margin-top:.2rem}
.apply-alt{font-size:.8rem;color:var(--muted);letter-spacing:.02em}
.apply-alt a{color:var(--paper-ink);border-bottom:1px solid var(--line2);padding-bottom:1px}
.apply-alt a:hover{border-color:var(--violet2)}

/* ── the application form ──
   Revealed by JS only when /api/health confirms the server can deliver to
   Telegram; [hidden] is the resting state. Field chrome matches the dawn
   cards: white ground, warm hairlines, 2px radius. */
.af{display:flex;flex-direction:column;gap:1.05rem;width:100%;max-width:460px;margin-bottom:1.4rem}
.af[hidden]{display:none}
.af-f{display:flex;flex-direction:column;gap:.45rem}
.af-f>span{font-size:.62rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted)}
.af input[type=text],.af input[type=tel]{
  font-family:var(--fb);font-size:.95rem;color:var(--paper-ink);background:#fff;
  border:1px solid var(--line2);border-radius:2px;padding:.7rem .85rem;outline:none;
  transition:border-color .18s var(--e-out)
}
.af input[type=text]:focus,.af input[type=tel]:focus{border-color:var(--violet2)}
.af-tracks{display:flex;gap:.4rem;flex-wrap:wrap}
.af-tracks label{cursor:pointer}
.af-tracks input{position:absolute;opacity:0;pointer-events:none}
.af-tracks span{
  display:block;font-family:var(--fm);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;
  padding:.5rem .75rem;border:1px solid var(--line2);border-radius:2px;color:var(--ink2);
  transition:border-color .18s var(--e-out),color .18s var(--e-out)
}
.af-tracks input:checked+span{border-color:var(--violet2);color:var(--violet2);background:rgba(107,78,230,.05)}
.af-tracks input:focus-visible+span{outline:2px solid var(--violet2);outline-offset:1px}
.af .btn{align-self:flex-start}
.af-status{font-size:.74rem;min-height:1.1em;letter-spacing:.03em}
.af-status.ok{color:#1E7A46}
.af-status.err{color:#A8321E}
.form-side{display:flex;flex-direction:column;gap:1.2rem}
.price{background:#fff;border:1px solid var(--line);border-radius:3px;padding:clamp(1.3rem,2.2vw,1.8rem)}
.price>p:first-child{font-size:.64rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);margin-bottom:.9rem}
.price-v{display:block;font-family:var(--fm);font-size:clamp(1.9rem,3.4vw,2.7rem);font-weight:500;letter-spacing:-.035em;line-height:1;color:var(--paper-ink);font-variant-numeric:tabular-nums}
.price>span{display:block;font-size:.7rem;text-transform:uppercase;letter-spacing:.12em;color:var(--muted);margin-top:.5rem}
.price-d{font-size:.84rem;color:var(--ink2);line-height:1.6;margin-top:1.1rem;padding-top:1.1rem;border-top:1px solid var(--line)}
.grn{border-left:2px solid var(--violet2);padding:.3rem 0 .3rem 1.1rem}
.grn b{display:block;font-family:var(--fd);font-size:.95rem;font-weight:600;margin-bottom:.4rem}
.grn p{font-size:.84rem;color:var(--ink2);line-height:1.6}

/* ═══════════════════ CONTACT / FOOTER ═══════════════════ */
.sec-contact{padding-bottom:clamp(3rem,6vw,5rem)}
.ct{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.ct-i{background:#fff;padding:1.3rem}
.ct-i span{display:block;font-size:.6rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);margin-bottom:.6rem}
.ct-i p{font-size:.95rem;line-height:1.5}
/* the map link is a second line under the address, not a peer of it */
.ct-map{margin-top:.5rem;font-size:.78rem}
.ct-map a{color:var(--muted)}
.ct-i a{text-decoration:none;border-bottom:1px solid var(--line2);transition:border-color .3s}
.ct-i a:hover{border-color:var(--violet2)}

/* The dock floats ~4.2rem deep over the viewport bottom (1.4rem offset + its
   own height). At full scroll that band lands on the footer row, so the footer
   reserves it — the extra padding is clearance for a fixed element, not
   rhythm, which is why it is added on top of the normal padding rather than
   replacing it. Undone at ≤1024px where the dock does not exist. */
.ftr{border-top:1px solid var(--line);padding:clamp(2.2rem,4vw,3.2rem) 0 calc(clamp(2.2rem,4vw,3.2rem) + 5rem)}
.ftr-in{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:clamp(1.2rem,3vw,2.5rem);align-items:center}
.ftr-logo{width:100px}
.ftr-tag{font-size:.8rem;color:var(--ink2)}
.ftr-l{display:flex;gap:1.4rem}
.ftr-l a{font-size:.78rem;text-decoration:none;border-bottom:1px solid var(--line2)}
.ftr-r{font-size:.68rem;color:var(--muted);letter-spacing:.04em}

/* ═══════════════════ REVEALS ═══════════════════ */
[data-rv]{--d:0ms}
[data-rv="fade"]{opacity:0;transform:translateY(14px);transition:opacity .75s var(--e-out) var(--d),transform .75s var(--e-out) var(--d)}
[data-rv="fade"].in{opacity:1;transform:none}
[data-rv="clip"]{clip-path:inset(0 0 100% 0);transition:clip-path 1s var(--e-out) var(--d)}
[data-rv="clip"].in{clip-path:inset(0 0 -6% 0)}
[data-rv="rows"]>*{opacity:0;transform:translateY(18px);transition:opacity .7s var(--e-out),transform .7s var(--e-out)}
[data-rv="rows"].in>*{opacity:1;transform:none}

/* ═══════════════════ RESPONSIVE ═══════════════════ */
@media (max-width:1180px){
  .doors,.doors-3,.rack,.steps,.gates,.trio{grid-template-columns:repeat(2,1fr)}
  .exp,.plates{grid-template-columns:repeat(2,1fr)}
  .hero-wrap{grid-template-columns:1fr;gap:2.5rem}
  .hero-r{max-width:520px}
  .map-wrap{grid-template-columns:1fr}
  .map-side{flex-direction:row;flex-wrap:wrap}
  .map-side .mstat{flex:1 1 140px}
  .lb{grid-template-columns:1fr}
  .lb-out{position:static}
  .ops-clocks{display:none}
}
@media (max-width:1024px){
  .dock{display:none}
  .ftr{padding-bottom:clamp(2.2rem,4vw,3.2rem)}   /* no dock, no clearance */
  .calc{grid-template-columns:1fr}
  .hours-g{grid-template-columns:1fr;gap:2.5rem}
  .form-g{grid-template-columns:1fr}
  .gal{grid-template-columns:repeat(2,1fr)}
  .gf-lg{grid-column:span 2;grid-row:auto}
  .gf-lg img{aspect-ratio:16/9}
  .ct,.keys,.odo-strip,.facts{grid-template-columns:repeat(2,1fr)}
  .ftr-in{grid-template-columns:1fr 1fr;gap:1.5rem}
}
@media (max-width:860px){
  :root{--top:88px}
  .menu-b{display:block}
  .ops-r .btn{display:none}
  .sec-h{grid-template-columns:1fr;gap:1rem}
  .mm{display:inline-block}
  .sec-h .lead{padding-top:0}
  .week{grid-template-columns:repeat(2,1fr)}
  .mkt-c,.two,.vs{grid-template-columns:1fr}
  .env-l{grid-template-columns:1fr}
  .mod-b{grid-template-columns:40px minmax(0,1fr) auto;gap:.8rem}
  .mod-in{padding-left:40px}
  /* the rail narrows rather than disappearing: it is the one thing tying the
     ten modules together, and a narrow screen is where that ordering helps most */
  :root{--rail:26px}
}
@media (max-width:640px){
  .doors,.doors-3,.rack,.steps,.gates,.trio,.exp,.plates,.ct,.keys,.odo-strip,.facts{grid-template-columns:1fr}
  .gal{grid-template-columns:1fr}
  .ftr-in{grid-template-columns:1fr}
  .h1{font-size:clamp(2.1rem,9vw,3rem)}
  .lb-t{min-width:560px}
  .scroll-cue{display:none}
  .mod-c{display:none}
  /* On a phone the tape would clip the offer itself, and the offer is the one
     thing that must survive. Below this width the headline is just a headline:
     it wraps, the continuation is dropped, and nothing travels. */
  .tape{overflow:visible}
  .tape-in{display:block;width:auto;white-space:normal;padding-left:0;transform:none}
  .tape-x,.tape-dup,.tape-in>.tg{display:none}
  .fq-in{padding-left:.3rem;padding-right:0}
  .tick-k{display:none}
  /* three roles side by side stops being readable here — stack them */
  .tracks{flex-direction:column}
}

/* ═══════════════════ REDUCED MOTION ═══════════════════
   Every motion device above reduces to its finished state. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important
  }
  [data-rv]{opacity:1!important;transform:none!important;clip-path:none!important}
  [data-rv="rows"]>*{opacity:1!important;transform:none!important}
  .hb-r,.lb-t tbody tr{opacity:1!important;transform:none!important}
  .dot{opacity:1!important}
  .city{opacity:1!important}
  /* the journey line's finished state is the whole route drawn */
  .jrn-p{stroke-dashoffset:0!important}
  .jrn-n{fill:var(--amber)!important;stroke:var(--amber)!important}
  /* the tape stops travelling and rests at its opening clause — the headline */
  .tape-in{transform:none!important}
  .hub-ring{display:none}
  .boot{display:none}
  .gate::after{transform:scaleX(1)!important}
}
