/* ============================================================
   RAYSONS — Through the Foundry  ·  Dark Molten direction
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600&family=Montserrat:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap');

:root{
  /* How much room the fixed navbar occupies. It was never written down, so anything
     top-aligned under it had to guess — and the Foundry hero guessed low, sliding its
     eyebrow badge under the bar at every width but one. Stated once here so nothing
     has to guess again. .nav is 26px padding top and bottom around ~40px of brand. */
  --nav-h:96px;

  /* CHAMPAGNE NOIR — refined warm-luxury accent (the neon orange retired to the
     fire footage only). The "--molten" names are kept so nothing downstream
     breaks; they now hold champagne-gold values, not hot orange. */
  --bg:#0a0807;            /* warm near-black */
  --ink:#f3ecdf;           /* warm bone */
  --ink-dim:#9a9081;
  --ink-faint:#b0a48f;     /* contrast-safe over the bright pour */
  --molten:#c9a24e;        /* accent — champagne gold (was hot orange) */
  --molten-hot:#e6c483;    /* light champagne */
  --molten-deep:#8a6a2e;   /* deep gold (for gradients) */
  --bronze:#a6822e;        /* warm gold for emphasis */
  --bronze-lite:#dcbd82;   /* light champagne for small-text emphasis (contrast-safe) */
  --bronze-deep:#6e561c;
  --iron:#3a342e;
  --line:rgba(244,236,226,.10);
  --line-strong:rgba(244,236,226,.22);
  --serif:"Cormorant",Georgia,"Times New Roman",serif;
  --sans:"Montserrat",-apple-system,BlinkMacSystemFont,sans-serif;
  --mono:"Space Mono",monospace;
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:auto}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--sans);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  cursor:none;
}
a{color:inherit;text-decoration:none}
::selection{background:var(--molten);color:#1a0d04}
/* keyboard focus visibility (a11y) — bronze ring, never removed */
:focus-visible{outline:2px solid var(--bronze-lite);outline-offset:3px;border-radius:3px}

/* ---- WebGL canvas, fixed full-bleed background ---- */
#gl{
  position:fixed;inset:0;width:100vw;height:100vh;
  z-index:0;display:block;
}
/* vignette + grain overlay above canvas, below text */
.atmos{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(120% 90% at 50% 42%, transparent 40%, rgba(0,0,0,.55) 100%);
  mix-blend-mode:multiply;
}
.grain{
  position:fixed;inset:-50%;z-index:2;pointer-events:none;opacity:.05;
  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='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 6s steps(6) infinite;
}
@keyframes grain{
  0%{transform:translate(0,0)}10%{transform:translate(-3%,-2%)}
  30%{transform:translate(2%,-4%)}50%{transform:translate(-2%,3%)}
  70%{transform:translate(3%,2%)}90%{transform:translate(-3%,1%)}
}

/* scroll space drives the journey */
#scroll-space{position:relative;z-index:5;pointer-events:none}

/* ============================================================
   LOADER
   ============================================================ */
/* Re-entry within a session: the film shows its opening title ONCE. On every page after
   the first, the head snippet sets html.reentry from sessionStorage before first paint, and
   the loader is hidden instantly (no fade, no progress ritual) — the page arrives through
   the ember dip nav-transition.js already performs. Each engine's boot reads the same class
   and sets body.entered immediately so the chrome doesn't wait. Covers both loader ids. */
html.reentry #loader,html.reentry #cloader{transition:none!important;opacity:0!important;visibility:hidden!important;pointer-events:none!important}

#loader{
  position:fixed;inset:0;z-index:100;background:#050302;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  transition:opacity 1s ease, visibility 1s;
}
#loader.done{opacity:0;visibility:hidden}
.loader-mark{
  font-family:var(--mono);font-size:12px;letter-spacing:.5em;
  color:var(--ink-dim);text-indent:.5em;margin-bottom:34px;
}
.loader-bar{
  width:min(340px,60vw);height:1px;background:var(--line);position:relative;overflow:hidden;
}
.loader-bar i{
  position:absolute;inset:0;width:0;background:linear-gradient(90deg,var(--molten-deep),var(--molten-hot));
  box-shadow:0 0 18px var(--molten);
}
.loader-foot{
  display:flex;justify-content:space-between;width:min(340px,60vw);margin-top:16px;
  font-family:var(--mono);font-size:11px;letter-spacing:.18em;color:var(--ink-faint);text-transform:uppercase;
}
.loader-pct{color:var(--ink)}

/* ============================================================
   CHROME — nav, hud, cursor
   ============================================================ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:40;
  display:flex;align-items:center;justify-content:space-between;
  padding:26px clamp(20px,4vw,56px);
  mix-blend-mode:difference;
}
/* PHONES: difference-blend is beautiful over film and unreadable over a text list — at the
   foot of a page it was inverting straight through the footer's own headings. A phone has
   no room to scroll the nav out of the way, so on mobile it drops the blend and carries a
   scrim of its own: legible over the pour, over the metal and over type. */
@media(max-width:760px){
  .nav{mix-blend-mode:normal;
    background:linear-gradient(180deg, rgba(7,5,4,.94) 0%, rgba(7,5,4,.66) 58%, transparent 100%)}
}
.nav .brand{display:flex;align-items:center;gap:12px;font-weight:600;letter-spacing:.02em;font-size:15px}
.nav .brand b{font-weight:700}
.nav .brand span{font-family:var(--mono);font-size:10px;letter-spacing:.24em;color:#fff;opacity:.6;border:1px solid rgba(255,255,255,.4);padding:3px 7px;border-radius:2px}
/* the nav logomark. Lives HERE (the shared nav stylesheet) rather than being re-declared
   per page — it was duplicated in index.html, about-cinema.css and foundry.css, so any page
   loading only styles.css rendered the logo at its natural size. */
.brand .brandmark{width:28px;height:28px;display:block;flex:0 0 auto}
.nav-links{display:flex;gap:30px;font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.nav-links a{position:relative;opacity:.85;transition:opacity .3s}
.nav-links a:hover{opacity:1}
.nav-links a::after{content:"";position:absolute;left:0;bottom:-5px;width:0;height:1px;background:currentColor;transition:width .35s ease}
.nav-links a:hover::after{width:100%}
@media(max-width:860px){.nav-links{display:none}}

/* furnace HUD */
.hud{
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--ink-dim);
  text-align:left;line-height:1.9;pointer-events:none;text-transform:uppercase;
}
.hud .row{display:flex;align-items:center;justify-content:flex-start;gap:8px}
.hud .dot{width:6px;height:6px;border-radius:50%;background:var(--molten);box-shadow:0 0 10px var(--molten);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.hud b{color:var(--molten-hot);font-weight:700}
@media(max-width:640px){.hud{display:none}}

/* progress ticker — left */
.prog{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--ink-faint);
  display:flex;align-items:center;gap:12px;pointer-events:none;text-transform:uppercase;
}
.prog .track{width:80px;height:1px;background:var(--line);position:relative}
.prog .track i{position:absolute;left:0;top:0;height:100%;width:0;background:var(--molten);box-shadow:0 0 8px var(--molten)}
.prog .cur{color:var(--ink)}
@media(max-width:640px){.prog .label{display:none}}

/* ── FILM INSTRUMENT CLUSTER (shared) ──────────────────────────────────────────
   The procession HUD (bottom-left: context word + counter) and the progress rail (right
   edge). Overview and Products both run this cockpit; it lived duplicated in each page's
   inline <style> and had already begun to drift (Products' rail fill had lost the .12s
   transition). Consolidated here — the same footer/dock/brandmark pattern — so the
   instrument reads identically on every procession page; only the vocabulary differs
   (Overview = chapter + shot, Products = part NN / 23), set per page in markup/JS.
   :is() unifies the CSS without renaming the classes the engines reference. */
:is(.film-hud,.phud){position:fixed;left:clamp(16px,3vw,40px);bottom:clamp(16px,3vw,30px);z-index:30;
  pointer-events:none;font-family:var(--mono);opacity:0;transition:opacity .6s ease;
  display:flex;flex-direction:column;gap:5px}
:is(.film-hud,.phud).on{opacity:1}
:is(.film-hud .fh-chapter,.phud__k){font-size:11px;letter-spacing:.26em;text-transform:uppercase;
  color:var(--molten-hot);text-shadow:0 1px 12px rgba(7,5,4,.95)}
:is(.film-hud .fh-count,.phud__i){font-size:10px;letter-spacing:.2em;color:var(--ink-faint);
  font-variant-numeric:tabular-nums;text-shadow:0 1px 12px rgba(7,5,4,.95)}
:is(.film-hud .fh-count b,.phud__i b){color:var(--ink);font-weight:500}
:is(.film-rail,.prail){position:fixed;right:clamp(12px,2vw,26px);top:50%;transform:translateY(-50%);z-index:30;
  height:min(46vh,340px);width:2px;background:var(--line);pointer-events:none;opacity:0;
  transition:opacity .6s ease;border-radius:2px}
:is(.film-rail,.prail).on{opacity:1}
:is(.film-rail__fill,.prail__fill){position:absolute;left:0;top:0;width:100%;height:0;border-radius:2px;
  background:linear-gradient(180deg,var(--molten-hot),var(--molten-deep));
  box-shadow:0 0 12px rgba(255,106,26,.5);transition:height .12s linear}
/* chapter markers — Overview only (Products' rack is a continuous 23, so no chapter ticks) */
.film-rail__knob{position:absolute;left:50%;width:7px;height:7px;border-radius:50%;top:0;
  background:var(--molten-hot);box-shadow:0 0 12px var(--molten-hot);
  transform:translate(-50%,-50%);transition:top .12s linear}
.film-rail__tick{position:absolute;left:50%;width:9px;height:1px;background:var(--ink-faint);
  transform:translate(-50%,0);opacity:.5}
@media(max-width:640px){:is(.film-rail,.prail){height:38vh;right:9px}
  :is(.film-hud,.phud){bottom:max(14px,env(safe-area-inset-bottom,14px))}}
@media(prefers-reduced-motion:reduce){:is(.film-rail__fill,.prail__fill),.film-rail__knob{transition:none}}

/* persistent conversion CTA — bottom-centre dock, fades in after the hero */
.cta-dock{position:fixed;left:0;right:0;bottom:clamp(18px,3.4vw,34px);z-index:41;display:flex;justify-content:center;pointer-events:none;
  opacity:0;transform:translateY(16px);transition:opacity .6s ease, transform .6s cubic-bezier(.2,.7,.2,1)}
/* The dock is what fades in past the hero (JS toggles .on); the button inside rides along
   already-revealed. These lived inline in index.html keyed to #ccta, so every other page
   toggled .on against no rule and the button stayed at opacity:0 forever. */
.cta-dock.on{opacity:1;transform:none}
.cta-dock .cta-quote{opacity:1;transform:none}
.cta-quote{
  pointer-events:auto;display:inline-flex;align-items:center;gap:10px;text-decoration:none;
  font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:#1a0d04;background:linear-gradient(180deg,var(--molten-hot),var(--molten));
  padding:13px 24px;border-radius:40px;white-space:nowrap;
  box-shadow:0 8px 30px rgba(201,162,78,.32);
  opacity:0;transform:translateY(16px);
  transition:opacity .6s ease, transform .6s cubic-bezier(.2,.7,.2,1), box-shadow .3s ease;
}
.cta-quote.visible{opacity:1;transform:none}
.cta-quote:hover{box-shadow:0 12px 44px rgba(201,162,78,.6)}
.cta-quote .arrow{transition:transform .3s ease}
.cta-quote:hover .arrow{transform:translateX(5px)}

/* custom cursor */
.cursor{position:fixed;top:0;left:0;z-index:90;pointer-events:none;mix-blend-mode:difference;will-change:transform}
.cursor .ring{position:absolute;width:34px;height:34px;border:1px solid #fff;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s,opacity .25s}
.cursor .dot{position:absolute;width:4px;height:4px;background:#fff;border-radius:50%;transform:translate(-50%,-50%)}
.cursor.hot .ring{width:54px;height:54px}
@media(pointer:coarse){.cursor{display:none}body{cursor:auto}}

/* sound toggle */
.sound{
  display:inline-flex;align-items:center;gap:9px;cursor:none;pointer-events:auto;
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;color:var(--ink-dim);text-transform:uppercase;
  background:rgba(10,7,5,.4);border:1px solid var(--line);padding:7px 13px;border-radius:40px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:color .3s,border-color .3s;
}
/* consolidated bottom-left instrument cluster */
.readout{position:fixed;left:clamp(16px,3vw,40px);bottom:clamp(16px,3vw,34px);z-index:40;
  display:flex;flex-direction:column;align-items:flex-start;gap:13px;pointer-events:none}
@media(max-width:640px){.readout{display:none}}
.sound:hover{color:var(--ink);border-color:var(--line-strong)}
.eq{display:flex;align-items:flex-end;gap:2px;height:11px}
.eq i{width:2px;height:30%;background:currentColor;transition:height .2s}
.sound.on .eq i{animation:eq 1s ease-in-out infinite}
.sound.on .eq i:nth-child(2){animation-delay:.2s}
.sound.on .eq i:nth-child(3){animation-delay:.4s}
.sound.on .eq i:nth-child(4){animation-delay:.1s}
@keyframes eq{0%,100%{height:25%}50%{height:100%}}
@media(max-width:640px){.sound{display:none}}

/* ============================================================
   CHAPTERS
   ============================================================ */
#chapters{position:fixed;inset:0;z-index:10;pointer-events:none}
.chapter{
  position:fixed;inset:0;display:flex;
  padding:max(96px,11vh) clamp(20px,6vw,110px) max(90px,10vh);
  opacity:0;visibility:hidden;
  transition:opacity .7s ease, visibility .7s;
}
.chapter.active{opacity:1;visibility:visible}
.chapter .inner{width:100%;max-width:1320px;margin:auto}

/* reusable type */
.eyebrow{
  font-family:var(--mono);font-size:12px;letter-spacing:.28em;text-transform:uppercase;
  color:var(--molten);display:flex;align-items:center;gap:12px;margin-bottom:26px;
  text-shadow:0 1px 12px rgba(7,5,4,.85);
}
.eyebrow::before{content:"";width:26px;height:1px;background:var(--molten)}
.display{
  font-family:var(--serif);font-weight:600;line-height:1.0;letter-spacing:-.01em;
  font-size:clamp(50px,9vw,150px);text-wrap:balance;
  /* legibility halo — keeps headings readable over the bright molten pour */
  text-shadow:0 2px 30px rgba(7,5,4,.92), 0 0 12px rgba(7,5,4,.7);
}
.display .thin{font-weight:400;color:var(--ink-dim)}
/* accent word: italic Cormorant — the couture move (was a flat orange swap) */
.display em{font-style:italic;font-weight:500;color:var(--molten-hot)}
/* precision beats tint the accent bronze instead of molten (pour→part story) */
.display.cool em{color:var(--bronze-lite)}
.lede{
  font-size:clamp(17px,1.55vw,23px);line-height:1.55;color:#c9beb1;
  max-width:46ch;margin-top:30px;font-weight:400;text-wrap:pretty;
  text-shadow:0 1px 18px rgba(7,5,4,.85);
}
.kicker{font-family:var(--mono);font-size:12px;letter-spacing:.2em;color:var(--ink-faint);text-transform:uppercase;text-shadow:0 1px 12px rgba(7,5,4,.8)}
/* hero value proposition — concrete "what we do" line at the fold (mono, bronze, WCAG 7.8:1) */
.valueprop{font-family:var(--mono);font-size:clamp(11px,1.15vw,13px);letter-spacing:.16em;text-transform:uppercase;
  color:var(--bronze-lite);margin:20px auto 0;text-align:center;max-width:64ch;line-height:1.9;
  text-shadow:0 1px 14px rgba(7,5,4,.9)}
/* legacy / air pull-quote — italic Cormorant, a held breath under the heading */
.pullquote{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ink-dim);
  font-size:clamp(19px,2.2vw,31px);line-height:1.4;max-width:26ch;margin:30px auto 0;text-align:center;text-wrap:balance;
  text-shadow:0 1px 18px rgba(7,5,4,.8)}
.pullquote b{color:var(--bronze-lite);font-weight:500;font-style:normal}

/* staggered reveal of children when active */
.chapter .rise{opacity:0;transform:translateY(28px);transition:opacity .9s cubic-bezier(.2,.7,.2,1),transform .9s cubic-bezier(.2,.7,.2,1)}
.chapter.active .rise{opacity:1;transform:none}
.chapter.active .rise:nth-child(1){transition-delay:.05s}
.chapter.active .rise:nth-child(2){transition-delay:.14s}
.chapter.active .rise:nth-child(3){transition-delay:.23s}
.chapter.active .rise:nth-child(4){transition-delay:.32s}
.chapter.active .rise:nth-child(5){transition-delay:.41s}
.chapter.active .rise:nth-child(6){transition-delay:.5s}

/* layout helpers */
.col-split{display:grid;grid-template-columns:1.1fr .9fr;gap:60px;align-items:end;width:100%}
@media(max-width:900px){.col-split{grid-template-columns:1fr;gap:34px}}

/* hero centred */
.c-center{text-align:center;flex-direction:column;align-items:center;justify-content:center}
.c-center .display{font-size:clamp(52px,10.5vw,168px)}
/* radial scrim behind centred hero text — dims the brightest part of the pour
   right behind the words without darkening the rest of the scene */
.c-center::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 62% 46% at 50% 50%, rgba(7,5,4,.6), rgba(7,5,4,0) 72%);
}

/* stat strip */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-top:1px solid rgba(166,121,46,.5);margin-top:8px}
.stats .s{background:var(--bg);padding:30px 26px}
.stats .s .n{font-family:var(--serif);font-size:clamp(30px,3.6vw,52px);font-weight:500;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stats .s .n b{color:var(--molten-hot);font-weight:500}
.stats .s .l{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);margin-top:8px}
/* tabular figures on the live readouts so counters don't jitter the layout */
.prog .cur,#hud-temp{font-variant-numeric:tabular-nums}
@media(max-width:760px){.stats{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* feature callouts (casting) */
.feat{display:flex;flex-direction:column;gap:18px;max-width:360px}
.feat .f{display:flex;gap:16px;align-items:baseline;padding-bottom:16px;border-bottom:1px solid var(--line)}
.feat .f .i{font-family:var(--mono);font-size:12px;color:var(--bronze-lite);min-width:24px}
.feat .f .t{font-size:16px;color:var(--ink)}
.feat .f .t span{display:block;font-family:var(--mono);font-size:11px;color:var(--ink-faint);margin-top:5px;letter-spacing:.05em}

/* process steps */
.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);width:100%;margin-top:34px}
.steps .st{background:var(--bg);padding:26px 24px;min-height:160px}
.steps .st .num{font-family:var(--mono);font-size:11px;color:var(--molten);letter-spacing:.1em}
.steps .st h4{font-size:18px;font-weight:600;margin:14px 0 10px;letter-spacing:-.01em}
.steps .st p{font-size:13.5px;line-height:1.55;color:var(--ink-dim);font-weight:300}
@media(max-width:900px){.steps{grid-template-columns:1fr 1fr}.steps .st{min-height:0}}
@media(max-width:560px){.steps{grid-template-columns:1fr}}

/* spec list */
.specs{display:grid;grid-template-columns:1fr 1fr;gap:0;width:100%;margin-top:30px;border-top:1px solid rgba(166,121,46,.5)}
.specs .sp{display:flex;justify-content:space-between;align-items:baseline;gap:20px;padding:22px 6px;border-bottom:1px solid var(--line)}
.specs .sp .k{font-size:16px;font-weight:500}
.specs .sp .v{font-family:var(--mono);font-size:12px;color:var(--ink-dim);text-align:right;letter-spacing:.04em;font-variant-numeric:tabular-nums}
.specs .sp .v b{color:var(--bronze-lite);font-weight:700}
@media(max-width:760px){.specs{grid-template-columns:1fr}}

/* customers / sectors chips */
.chips{display:flex;flex-wrap:wrap;gap:10px;margin-top:30px;max-width:760px}
.chips span{font-family:var(--mono);font-size:12px;letter-spacing:.08em;color:var(--ink-dim);border:1px solid var(--line);padding:9px 15px;border-radius:40px;transition:border-color .3s,color .3s}
.chips span:hover{border-color:var(--bronze-lite);color:var(--ink)}

/* customer logo marquee — finale trust crescendo */
.marquee{width:100%;overflow:hidden;margin-top:40px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.marquee-track{display:flex;width:max-content;animation:marq 42s linear infinite;will-change:transform}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee-track span{font-family:var(--mono);font-size:clamp(14px,1.5vw,19px);letter-spacing:.05em;
  color:var(--ink-dim);white-space:nowrap;margin-right:clamp(34px,5vw,64px);transition:color .3s}
.marquee-track span:hover{color:var(--bronze-lite)}
@keyframes marq{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.marquee-track{animation:none;transform:none}}

/* ISO seal + global reach line */
.trust-row{display:flex;align-items:center;justify-content:center;gap:22px;margin-top:34px;flex-wrap:wrap}
.iso-seal{flex:0 0 auto;width:76px;height:76px;border-radius:50%;border:1px solid var(--bronze-deep);
  display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;line-height:1.5;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--bronze-lite);
  box-shadow:inset 0 0 22px rgba(166,121,46,.14)}
.iso-seal b{font-weight:700;font-size:11px;color:var(--bronze-lite)}
.trust-row .kicker{margin-top:0}

/* timeline */
.timeline{display:flex;gap:0;width:100%;margin-top:34px;overflow-x:auto;padding-bottom:8px;pointer-events:auto;scrollbar-width:none}
.timeline::-webkit-scrollbar{display:none}
.timeline .tl{flex:0 0 240px;padding:0 26px 0 0;border-left:1px solid var(--line);padding-left:22px;position:relative}
.timeline .tl::before{content:"";position:absolute;left:-4px;top:6px;width:7px;height:7px;border-radius:50%;background:var(--molten);box-shadow:0 0 10px var(--molten)}
.timeline .tl .yr{font-family:var(--serif);font-size:34px;font-weight:600;color:var(--molten-hot);letter-spacing:-.02em}
.timeline .tl h5{font-size:15px;margin:10px 0 8px;font-weight:600}
.timeline .tl p{font-size:12.5px;line-height:1.5;color:var(--ink-dim);font-weight:300}

/* FAQ */
.faq{width:100%;max-width:880px;margin-top:24px;pointer-events:auto}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{list-style:none;cursor:none;padding:20px 0;display:flex;justify-content:space-between;align-items:center;gap:24px;font-size:clamp(16px,1.7vw,21px);font-weight:500;transition:color .3s}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--molten-hot)}
.faq summary .pl{font-family:var(--mono);color:var(--molten);transition:transform .3s;flex:0 0 auto}
.faq details[open] summary .pl{transform:rotate(45deg)}
.faq .a{font-size:14.5px;line-height:1.65;color:var(--ink-dim);font-weight:300;padding:0 0 22px;max-width:70ch}

/* CTA / enquire */
.mag{
  display:inline-flex;align-items:center;gap:16px;pointer-events:auto;cursor:none;
  font-family:var(--mono);font-size:13px;letter-spacing:.16em;text-transform:uppercase;
  background:var(--molten);color:#180c03;font-weight:700;
  padding:20px 34px;border-radius:46px;margin-top:38px;position:relative;
  transition:transform .25s cubic-bezier(.2,.8,.2,1),box-shadow .3s;
  box-shadow:0 0 0 rgba(201,162,78,0);
  will-change:transform;
}
.mag:hover{box-shadow:0 14px 50px rgba(201,162,78,.45)}
.mag .arrow{transition:transform .3s}
.mag:hover .arrow{transform:translateX(5px)}
.mag.ghost{background:transparent;color:var(--ink);border:1px solid var(--line-strong);box-shadow:none}
.mag.ghost:hover{border-color:var(--molten);box-shadow:none}
.cta-row{display:flex;gap:18px;flex-wrap:wrap;align-items:center}
.contact-grid{display:grid;grid-template-columns:repeat(3,auto);gap:46px;margin-top:46px;font-size:14px;color:var(--ink-dim);line-height:1.7}
.contact-grid .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:9px}
.contact-grid a:hover{color:var(--molten-hot)}
@media(max-width:760px){.contact-grid{grid-template-columns:1fr 1fr;gap:26px}}

/* scroll cue */
.cue{position:fixed;left:50%;bottom:30px;transform:translateX(-50%);z-index:30;
  font-family:var(--mono);font-size:10px;letter-spacing:.3em;color:var(--ink-faint);text-transform:uppercase;
  display:flex;flex-direction:column;align-items:center;gap:12px;transition:opacity .6s}
.cue .line{width:1px;height:42px;background:linear-gradient(var(--molten),transparent);position:relative;overflow:hidden}
.cue .line::after{content:"";position:absolute;top:-50%;left:0;width:100%;height:50%;background:var(--ink);animation:drop 1.8s ease-in-out infinite}
@keyframes drop{0%{top:-50%}100%{top:100%}}
.cue.hide{opacity:0}
/* PHONES — the cue is a fixed 67px stack (label + 12px gap + 42px line) sitting 30px off
   the bottom, so on a short viewport its LABEL lands at roughly y=747 of 844: exactly
   where a hero's last line of copy sits. It was printing over About's "Kolhapur,
   Maharashtra · Since 1987" and over Foundry's assemble prompt. Nothing was reserving
   space for it because it is fixed and out of flow, and it had no mobile rule at all.
   Compacted and dropped closer to the edge so it clears page copy on both. */
@media(max-width:640px){
  .cue{bottom:14px;gap:7px;font-size:9px;letter-spacing:.24em}
  .cue .line{height:26px}
}

/* group company cards (about) */
.groupgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);width:100%;margin-top:34px}
.groupgrid .g{background:var(--bg);padding:24px 22px;min-height:150px;display:flex;flex-direction:column;justify-content:space-between}
.groupgrid .g .tag{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--molten);margin-bottom:18px}
.groupgrid .g h4{font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.15}
.groupgrid .g p{font-size:12px;color:var(--ink-dim);margin-top:8px;font-weight:300;line-height:1.5}
@media(max-width:900px){.groupgrid{grid-template-columns:1fr 1fr}}

.legal{position:fixed;left:0;right:0;bottom:0;z-index:9;text-align:center;padding:14px;font-family:var(--mono);font-size:10px;letter-spacing:.14em;color:var(--ink-faint);opacity:0;transition:opacity .6s;text-transform:uppercase;pointer-events:none}
.legal.show{opacity:1}

/* ---- progress + hud fade out at the trust finale to clear the stage ---- */
.prog,.hud{transition:opacity .6s ease}
.prog.dim,.hud.dim{opacity:0}

/* ---- reduced-motion: kill looping/idle decoration, make reveals instant ---- */
@media (prefers-reduced-motion: reduce){
  .grain{animation:none}
  .cue .line::after{animation:none}
  .hud .dot{animation:none}
  .sound.on .eq i{animation:none}
  .chapter .rise{transition-duration:.001ms}
}

/* ---- WebGL unavailable: degrade to a readable stacked page ---- */
.no-webgl{cursor:auto}
.no-webgl #gl,.no-webgl .atmos,.no-webgl .grain,.no-webgl #loader,
.no-webgl .cue,.no-webgl .hud,.no-webgl .prog,.no-webgl .sound,
.no-webgl .cursor,.no-webgl #scroll-space{display:none}
.no-webgl #chapters{position:static;pointer-events:auto}
.no-webgl .chapter{position:relative;inset:auto;opacity:1;visibility:visible;
  padding:140px clamp(20px,6vw,110px);min-height:auto;border-bottom:1px solid var(--line)}
.no-webgl .chapter .rise{opacity:1;transform:none}

/* ============================================================
   MOBILE ADDITIONS — breakpoints not covered above
   ============================================================ */

/* FAQ: pointer should always be visible on touch devices */
.faq summary{cursor:pointer}

/* group company grid: 4→2→1 */
@media(max-width:480px){.groupgrid{grid-template-columns:1fr}}

/* contact grid in enquire / chapter bottom: 2→1 on small phones */
@media(max-width:480px){.contact-grid{grid-template-columns:1fr;gap:20px}}

/* CTA pill — give extra bottom clearance for iPhone home bar */
@media(max-width:480px){
  .cta-dock{bottom:max(14px,env(safe-area-inset-bottom,14px))}
  .cta-quote{font-size:11px;padding:11px 18px}
}

/* specs 2-col → 1-col on very narrow phones */
@media(max-width:420px){.specs{grid-template-columns:1fr}}

/* steps 2-col → 1-col fallback below 420px */
@media(max-width:420px){.steps{grid-template-columns:1fr}}

/* chips: reduce gap on small screens */
@media(max-width:420px){.chips{gap:8px}.chips span{font-size:11px;padding:7px 12px}}

/* col-split: single column on narrow phones */
@media(max-width:560px){.col-split{grid-template-columns:1fr;gap:24px}}

/* nav hamburger — shared pattern used by all pages */
.nav-burger{display:none;background:none;border:0;width:44px;height:44px;
  cursor:pointer;flex-direction:column;justify-content:center;align-items:center;
  gap:5px;padding:10px;mix-blend-mode:normal;-webkit-tap-highlight-color:transparent}
.nav-burger span{display:block;width:22px;height:1.5px;background:currentColor;
  transition:transform .3s,opacity .3s}
body.nav-open .nav-burger span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
body.nav-open .nav-burger span:nth-child(2){opacity:0}
body.nav-open .nav-burger span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}
@media(max-width:860px){
  .nav-burger{display:flex}
  /* override styles.css display:none on .nav-links at 860px */
  .nav-links{display:flex;position:fixed;inset:0;z-index:39;
    background:rgba(7,5,4,.97);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    flex-direction:column;align-items:center;justify-content:center;
    gap:32px;font-size:18px;letter-spacing:.08em;
    opacity:0;visibility:hidden;
    transition:opacity .4s,visibility .4s;mix-blend-mode:normal;pointer-events:none}
  body.nav-open .nav-links{opacity:1;visibility:visible;pointer-events:auto}
  .nav-links a{padding:12px 28px}   /* ≥44px touch targets in the mobile menu */
}

/* ── EXIT TRANSITIONS — internal nav dips to ember-black + types the destination, so the
   four pages cut like scenes of one film. The dip colour matches the loaders (#050302) so it
   flows straight into the next page's title card. Shared across all pages (nav-transition.js). ── */
/* The curtain RISES like poured metal rather than cross-fading: the body stays ember-black
   (#050302 — still matching the loaders and the finale, so arrival continuity is intact) and
   only its leading edge is molten, so you see a hot line sweep up and the dark fill behind it. */
/* ── ONE FILM ACROSS PAGES ────────────────────────────────────────────────────
   The site is five documents, so every link used to mean: wipe to black (440ms),
   tear the page down, rebuild it, fade the content up from zero. Over a second of
   nothing, which reads as a chapter break rather than a cut.

   Cross-document view transitions remove the gap entirely — the browser holds the
   outgoing page's last painted frame and dissolves it into the incoming one, so
   the film never goes dark. No SPA rewrite, no router, no rebuild of any engine.

   Progressive enhancement: browsers without it (Firefox today) fall through to the
   molten wipe below, exactly as before. nav-transition.js checks for support and
   stands down when the browser can do it natively. */
@view-transition{ navigation:auto }
::view-transition-old(root),
::view-transition-new(root){ animation-duration:.42s; animation-timing-function:cubic-bezier(.2,.7,.2,1) }
/* the incoming page arrives fractionally later so the two overlap rather than swap */
::view-transition-new(root){ animation-delay:.05s }
@media(prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){ animation-duration:.01ms }
}

/* PERSISTENT CHROME — this is what turns a page change into a cut within one film
   rather than a change of film. Anything given a view-transition-name is tracked as
   the SAME element across documents: the browser moves it instead of cross-fading it
   out and a duplicate back in. So the nav and the wordmark simply stay on screen and
   never blink, while only the content beneath them changes — which is exactly how a
   continuous piece behaves. Names must be unique per document, and each of these is. */
@supports (view-transition-name: none){
  .nav,.eq-nav{ view-transition-name:site-nav }
  .nav .brand,.eq-nav .brand{ view-transition-name:site-mark }
  .grain{ view-transition-name:film-grain }        /* the grain never re-seeds mid-cut */
  ::view-transition-group(site-nav),
  ::view-transition-group(site-mark),
  ::view-transition-group(film-grain){ animation-duration:.42s }
  /* the chrome holds still; only the page under it dissolves */
  ::view-transition-old(site-nav),::view-transition-new(site-nav),
  ::view-transition-old(site-mark),::view-transition-new(site-mark),
  ::view-transition-old(film-grain),::view-transition-new(film-grain){ animation:none;opacity:1 }
}

.nav-xfade{position:fixed;inset:0;z-index:9999;pointer-events:none;visibility:hidden;
  background:linear-gradient(0deg,#050302 0%,#050302 90%,#c2300a 96.5%,#ffb24a 100%);
  transform:translateY(101%);
  display:flex;align-items:center;justify-content:center;
  transition:transform .44s cubic-bezier(.7,0,.25,1),visibility .44s}
.nav-xfade.on{transform:translateY(0);visibility:visible;pointer-events:auto}
@media(prefers-reduced-motion:reduce){.nav-xfade{transform:none;opacity:0}
  .nav-xfade.on{opacity:1}}
.nav-xfade__k{font-family:var(--mono);font-size:12px;letter-spacing:.34em;text-transform:uppercase;color:var(--molten);
  opacity:0;transform:translateY(8px);transition:opacity .38s ease .12s,transform .42s cubic-bezier(.2,.7,.2,1) .12s}
.nav-xfade.on .nav-xfade__k{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.nav-xfade{transition:none}.nav-xfade__k{transition:none}}

/* ── SITE FOOTER ───────────────────────────────────────────────────────────────
   Shared by every page. This lived ONLY in about-cinema.css and foundry.css (identical
   copies), so products.html — which loads just this sheet — rendered the footer with no
   styling at all. Same trap as .brandmark: page-specific sheets holding site-wide chrome.
   :is() keeps the legacy class names working without touching their markup. */
:is(.about-footer,.foundry-footer,.site-footer){position:relative;z-index:10;border-top:1px solid var(--line);padding:clamp(48px,8vh,90px) clamp(20px,6vw,110px) 40px;background:#070504}
:is(.about-footer,.foundry-footer,.site-footer) .ft-top{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:18px;padding-bottom:34px;border-bottom:1px solid var(--line);max-width:1280px;margin:0 auto}
:is(.about-footer,.foundry-footer,.site-footer) .ft-logo{font-weight:700;letter-spacing:.02em;font-size:17px}
:is(.about-footer,.foundry-footer,.site-footer) .ft-logo span{color:var(--molten)}
:is(.about-footer,.foundry-footer,.site-footer) .ft-iso{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--bronze-lite);border:1px solid var(--bronze-deep);padding:7px 13px;border-radius:3px}
:is(.about-footer,.foundry-footer,.site-footer) .ft-mid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:34px;padding:34px 0;max-width:1280px;margin:0 auto}
:is(.about-footer,.foundry-footer,.site-footer) .ft-col h4{font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:14px}
:is(.about-footer,.foundry-footer,.site-footer) .ft-col li{list-style:none;font-size:13.5px;color:var(--ink-dim);line-height:2;font-weight:300}
:is(.about-footer,.foundry-footer,.site-footer) .ft-col a:hover{color:var(--molten-hot)}
:is(.about-footer,.foundry-footer,.site-footer) .ft-bot{display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px;padding-top:26px;max-width:1280px;margin:0 auto;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
/* ── THE CHAPTER HANDOFF ───────────────────────────────────────────────────
   The Overview ends like a film — on the object, with "Enter the group story". Every
   other chapter ended on a sitemap. This is that same invitation, so About, Foundry and
   Products close by pointing at what comes next instead of stopping dead. */
:is(.about-footer,.foundry-footer,.site-footer) .ft-next{display:flex;align-items:center;
  justify-content:space-between;gap:18px;max-width:1280px;margin:0 auto;padding:26px 0 2px;
  text-decoration:none;border-top:1px solid var(--line)}
.ft-next__k{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-faint);white-space:nowrap}
.ft-next__t{font-family:var(--serif);font-weight:600;font-size:clamp(21px,3vw,34px);
  letter-spacing:-.01em;color:var(--ink)}
.ft-next__t em{font-style:normal;color:var(--molten-hot);margin-left:12px;display:inline-block;
  transition:transform .4s cubic-bezier(.2,.7,.2,1)}
.ft-next:hover .ft-next__t{color:#fff}
.ft-next:hover .ft-next__t em{transform:translateX(7px)}

/* ── PHONES: a closing frame, not a directory ──────────────────────────────
   Stacked, this footer measured 1019px — 121% of a 390x844 viewport — and it was the
   last thing the visitor saw on three of the five chapters, identical every time. Two of
   its three columns are also redundant on a phone: "Programs" restates the Foundry page,
   "Navigate" restates the burger menu. Contact is the only column carrying something the
   visitor cannot already reach, so on mobile the block closes the chapter instead of
   indexing the site. The extra bottom padding is the Request-a-Quote dock's clearance —
   it was printing over the copyright line. */
@media(max-width:760px){
  :is(.about-footer,.foundry-footer,.site-footer){padding-top:clamp(34px,5vh,56px);padding-bottom:116px}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-top{padding-bottom:24px}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-mid{grid-template-columns:1fr;gap:0;padding:22px 0}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-col:nth-child(-n+2){display:none}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-col li{line-height:1.7;font-size:13px}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-next{padding:20px 0 2px}
  :is(.about-footer,.foundry-footer,.site-footer) .ft-bot{padding-top:20px;gap:4px}
}

/* ══ TOUCH TARGETS ═══════════════════════════════════════════════════════════
   Audited across five pages at phone and tablet widths: no horizontal overflow
   anywhere, but a number of controls were well under the 44px minimum a finger
   needs — the brand mark at 28px tall, footer links at 16px, contact links at 17px.

   Scoped to (pointer:coarse) so DESKTOP LAYOUT IS UNTOUCHED. The visual size of
   everything here is unchanged too: the box grows, the type does not, so nothing
   is redesigned — there is simply more of it to hit. Anchors inside flowing
   paragraphs are deliberately excluded; padding them would break the line
   rhythm of the sentence they sit in.
   ────────────────────────────────────────────────────────────────────────── */
@media(pointer:coarse){
  /* brand + primary nav. Enquire ships its own nav (.eq-nav / #eqBurger) rather than
     the shared one, so it needs naming explicitly or it is the only page left short. */
  .nav .brand,.eq-nav .brand{min-height:44px;display:inline-flex;align-items:center}
  .nav .nav-links a,.eq-nav a{min-height:44px;display:inline-flex;align-items:center}
  .nav-burger,#eqBurger{min-width:44px;min-height:44px}

  /* CTAs — 38px was close but still short of a thumb */
  .cta-dock .cta-quote,.btn--fill,.btn--text,.bracket-next,.finale-next,.eq-submit{
    min-height:44px;display:inline-flex;align-items:center;justify-content:center}

  /* footer link columns: 16px rows are the worst offenders on the whole site */
  :is(.about-footer,.foundry-footer,.site-footer) .ft-col a,
  :is(.about-footer,.foundry-footer,.site-footer) .ft-col li{
    min-height:40px;display:flex;align-items:center}

  /* standalone contact links (email / phone / WhatsApp rows) */
  a[href^="mailto:"],a[href^="tel:"],a[href*="wa.me"]{
    min-height:40px;display:inline-flex;align-items:center}
  /* …but not when they are inside a running sentence */
  p a[href^="mailto:"],p a[href^="tel:"],li a[href^="mailto:"],li a[href^="tel:"]{
    min-height:0;display:inline}
}

/* ══════════════════════════════════════════════════════════════════════════════
   LIGHT THEME  ·  "the cinema stays dark, the documents go light"
   ------------------------------------------------------------------------------
   The film, the WebGL scenes and the pinned canvas beats keep their black: they are
   MEDIA — a lit screen you look at — and their scrims, vignettes and additive fire
   only mean anything on a dark ground. Everything a visitor READS flips to light.

   Mechanically: the root tokens stay dark, and light is applied as ISLANDS on the
   document containers. Those sections are transparent by default (the fixed .stage
   shows through), so painting them gives them a light surface that covers the stage
   while the cinema sections keep letting the dark through. Because the tokens are
   RE-DECLARED on the container, all ~695 var() uses inside inherit light values with
   no per-rule edits.

   State lives on <html data-theme>, never a class — spa.js assigns
   documentElement.className wholesale on every hop and would wipe it (see theme.js).
   ══════════════════════════════════════════════════════════════════════════════ */

/* ---------- the toggle ---------- */
.theme-toggle{margin-left:auto;margin-right:10px;display:inline-flex;align-items:center;
  justify-content:center;width:40px;height:40px;border-radius:50%;border:1px solid var(--line-strong);
  background:transparent;color:var(--ink);cursor:pointer;flex-shrink:0;
  transition:border-color .3s ease,color .3s ease,background .3s ease}
.theme-toggle:hover{border-color:var(--molten);color:var(--molten-hot)}
.theme-toggle svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;display:block}
.theme-toggle .tt-moon{display:none}
[data-theme="light"] .theme-toggle .tt-sun{display:none}
[data-theme="light"] .theme-toggle .tt-moon{display:block}
@media(max-width:760px){.theme-toggle{width:36px;height:36px;margin-right:6px}}

/* ---------- the light surfaces ---------- */
[data-theme="light"] :is(
  .sec, .pillar, .foems, .psectors, .pcat,
  .about-footer, .foundry-footer, .site-footer
){
  --bg:#f4efe6;
  --ink:#16120e;
  --ink-dim:#4c443a;
  --ink-faint:#6d6357;
  /* the accents have to DARKEN to survive on a light ground — champagne gold on bone
     is unreadable. Same hues, taken down until they hold 4.5:1 against the surface. */
  --molten:#8a5a12;
  --molten-hot:#a06713;
  --molten-deep:#5d3d08;
  --bronze:#7a5c14;
  --bronze-lite:#634c11;
  --bronze-deep:#b39a6d;
  --iron:#cdc4b6;
  --line:rgba(22,18,14,.15);
  --line-strong:rgba(22,18,14,.30);
  background:#f4efe6;
  color:var(--ink);
}
/* every text-shadow on this site exists to lift bone type off black; on a light surface
   they read as dirt. 73 of them, killed in one rule rather than 73 edits. */
[data-theme="light"] :is(.sec,.pillar,.foems,.psectors,.pcat,
  .about-footer,.foundry-footer,.site-footer) :is(h1,h2,h3,h4,h5,p,span,a,li,div,em,b,small){
  text-shadow:none}

/* the footer is the page's base — settle it a shade deeper so the closing frame still
   reads as a distinct band rather than merging into the section above it */
[data-theme="light"] :is(.about-footer,.foundry-footer,.site-footer){background:#ece5d9}

/* ---------- components that carry their own dark gradients ---------- */
/* Foundry spec plates + Products cards were warm-on-black; on light they invert to a
   warm tint on bone, keeping the same material language. */
[data-theme="light"] .pillar__plate{background:linear-gradient(160deg, rgba(138,90,18,.09), rgba(255,255,255,.55))}
[data-theme="light"] .pillar__plate::after{background:radial-gradient(80% 60% at 50% 0%, rgba(138,90,18,.10), transparent 70%)}
[data-theme="light"] .pgrid__frame{background:linear-gradient(170deg, rgba(138,90,18,.07), rgba(255,255,255,.6))}
[data-theme="light"] .pgrid__item:hover .pgrid__frame{background:linear-gradient(170deg, rgba(138,90,18,.14), rgba(255,255,255,.6))}
[data-theme="light"] .psector-card{background:linear-gradient(160deg, rgba(138,90,18,.08), rgba(255,255,255,.5))}
[data-theme="light"] .psector-card:hover{background:linear-gradient(160deg, rgba(138,90,18,.15), rgba(255,255,255,.5))}
/* the OEM plates were bone tiles chosen to sit on black — on a light page they vanish,
   so they take a border and a white ground instead */
[data-theme="light"] .foems__logo{background:#fff;border-color:rgba(22,18,14,.16)}
[data-theme="light"] .foems__logo:hover{background:#fff;border-color:var(--molten)}
/* pills, chips and dotted rows */
[data-theme="light"] .pillar__pill:hover{border-color:var(--molten);color:var(--molten-deep)}
[data-theme="light"] .pgrid__tag{border-color:rgba(22,18,14,.18)}

/* ---------- the fixed nav over a light page ---------- */
/* difference-blend inverts against whatever is behind it, so on desktop it adapts to
   light on its own. The mobile scrim does not — it is a hard dark gradient — so it
   flips to a light one. */
@media(max-width:760px){
  [data-theme="light"] .nav{
    background:linear-gradient(180deg, rgba(244,239,230,.96) 0%, rgba(244,239,230,.72) 58%, transparent 100%)}
  [data-theme="light"] .eq-nav{
    background:linear-gradient(180deg, rgba(244,239,230,.96) 0%, rgba(244,239,230,.72) 58%, transparent 100%)}
}
[data-theme="light"] .nav-links a{color:#16120e}
[data-theme="light"] .nav{mix-blend-mode:normal}
[data-theme="light"] .nav .brand,[data-theme="light"] .nav .brand b{color:#16120e}
[data-theme="light"] .nav-burger span{background:#16120e}

/* The dark theme lets .nav ride on mix-blend-mode:difference, which inverts against
   whatever is behind it and therefore needs no scrim. Light mode turns that off (the
   inversion fights the darkened accents), which left the bar sitting bare on top of the
   page — the brand and the links printed straight through the catalogue's product names.
   So in light mode the nav carries its own surface at EVERY width, not just on phones. */
[data-theme="light"] .nav{
  background:linear-gradient(180deg, rgba(244,239,230,.97) 0%, rgba(244,239,230,.88) 62%, rgba(244,239,230,0) 100%);
  backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px)}
[data-theme="light"] .nav .brand span{color:#16120e;opacity:.75;border-color:rgba(22,18,14,.32)}
[data-theme="light"] .theme-toggle{color:#16120e;border-color:rgba(22,18,14,.28)}
[data-theme="light"] .theme-toggle:hover{border-color:var(--molten);color:#8a5a12}
/* the floating dock reads as a warm plate on light rather than a glowing pill */
[data-theme="light"] .cta-quote{color:#16120e}

/* ---------- body copy that was hardcoded for a dark ground ---------- */
/* These are the literals the token system never covered: bone-grey body text (#ccc2b4,
   #c9beb1, #d8cdbe, #b0a48f …) chosen to sit on black. On a light surface they wash out
   to near-invisible — the copy was legible in the screenshot only as a grey ghost. They
   have no token to flip, so the light surfaces restate them explicitly. */
[data-theme="light"] :is(.pillar__body,.specs-sec__lede,.pcat__lede,.foems__meta,
  .mvv .m p,.people .copy p,.fscope__col li,.fprog__d,.pillar__row span){color:#4c443a}
[data-theme="light"] :is(.pillar__note,.pillar__plate-f,.pgrid__tag,.psector-card__count){color:#6d6357}
[data-theme="light"] .pillar__note{opacity:1}
/* headline emphasis: the italic accent is champagne on black — it needs to be the darkened
   gold on light or the second line of every heading disappears */
[data-theme="light"] :is(.pillar__name em,.pcat__title em,.psectors__t em,.foems__t em){color:#8a5a12}
[data-theme="light"] .pillar__peak{color:#8a5a12}
[data-theme="light"] .pillar__peak small{color:#4c443a}
[data-theme="light"] .pillar__plate-k{color:#6d6357}
[data-theme="light"] .pillar__tag,[data-theme="light"] .pcat__num,
[data-theme="light"] .psectors__k,[data-theme="light"] .foems__k{color:#8a5a12}
[data-theme="light"] .pillar__dot{background:#8a5a12;box-shadow:none}

/* ---------- the cinema, made explicit ---------- */
/* These scenes were relying on being TRANSPARENT over a dark fixed stage. That works in
   dark mode but is ambiguous in light: a scrubbed rail or an era card could end up
   reading against a light ground while its type still carried the dark theme's bone
   tokens (About's journey year labels measured 2.1:1). So in light mode the cinema
   paints its own black and restates the dark tokens — it is a screen, and it is now
   unambiguously a screen. */
/* NO BACKGROUND ON THESE. Every one of them sits at z-index:10 over a FIXED full-viewport
   backdrop — .stage on About and Foundry, .pstage on Products, #stage on the Overview —
   and several have a fixed canvas between the two (#journeyGL at z-index:1). Painting the
   SECTION therefore covers whatever is behind it: it blanked About's corridor completely,
   and would have hidden Products' molten pool the same way. The dark ground belongs on the
   fixed backdrops (kept at #0a0807 below); these sections only need the dark TOKENS so
   their copy stays bone over the scene. */
[data-theme="light"] :is(.phero,.pline,.pclose){
  --bg:#0a0807; --ink:#f3ecdf; --ink-dim:#9a9081; --ink-faint:#b0a48f;
  --molten:#c9a24e; --molten-hot:#e6c483; --molten-deep:#8a6a2e;
  --bronze:#a6822e; --bronze-lite:#dcbd82; --bronze-deep:#6e561c;
  --line:rgba(244,236,226,.10); --line-strong:rgba(244,236,226,.22);
  color:#f3ecdf;
}
/* the hero canvases and the fixed stage keep painting themselves; only make sure the
   light page never shows through behind them */
[data-theme="light"] :is(.stage,.pstage){background:#0a0807}

/* ══════════════════════════════════════════════════════════════════════════════
   LIGHT THEME · REVISION — a flat nav, and the journey joins the light
   ══════════════════════════════════════════════════════════════════════════════ */

/* ---------- nav: a surface and an edge, not a fade ---------- */
/* The gradient scrim was doing two jobs badly — it never fully separated the bar from
   the page, and it left a soft smear across the top of every screen. A flat surface with
   a single hairline states the separation outright. */
[data-theme="light"] .nav,
[data-theme="light"] .eq-nav{
  background:#f4efe6;
  border-bottom:1px solid rgba(22,18,14,.16);
  backdrop-filter:none;-webkit-backdrop-filter:none}
@media(max-width:760px){
  [data-theme="light"] .nav,
  [data-theme="light"] .eq-nav{
    background:#f4efe6;
    border-bottom:1px solid rgba(22,18,14,.16)}
}

/* ---------- ABOUT goes light, except the opening film ----------
   The corridor CAN be bone, and the earlier failures were all one misdiagnosis: I kept
   trying to make the canvas transparent so a background could show through it. It never
   needed to be. It needed to CLEAR bone — scene.background, painted by RenderPass — plus a
   bloom threshold lifted above the page so the ground itself does not bloom
   (about-corridor.js). With that, the pillars keep their cast iron and their molten seams
   and simply stand in a bright hall.
   The opening film stays dark: it is video footage shot on black, and no amount of theming
   changes what is inside an mp4. */
[data-theme="light"] :is(.kinetic,.journey,.tl){
  --bg:#f4efe6;
  --ink:#16120e; --ink-dim:#4c443a; --ink-faint:#6d6357;
  --molten:#8a5a12; --molten-hot:#a06713; --molten-deep:#5d3d08;
  --bronze:#7a5c14; --bronze-lite:#634c11; --bronze-deep:#b39a6d;
  --line:rgba(22,18,14,.15); --line-strong:rgba(22,18,14,.30);
  color:#16120e}
[data-theme="light"] :is(.kinetic,.journey,.tl) :is(h1,h2,h3,h4,p,span,a,li,div,em,b,small){text-shadow:none}
/* .journey itself must NOT paint — it is z-index:10 over the FIXED corridor canvas at
   z-index:1, and any background here (bone or black) covers the scene. .tl has no canvas
   over it, so it takes the page colour directly. */
[data-theme="light"] :is(.kinetic,.tl){background:#f4efe6}
[data-theme="light"] body:has(#journeyGL){background:#f4efe6}
[data-theme="light"] body:has(#journeyGL) .stage{background:#f4efe6;--bg:#f4efe6}
[data-theme="light"] body:has(#journeyGL) .stage__glow{background:
  radial-gradient(120% 70% at 50% -8%, rgba(201,162,78,.10), transparent 52%),
  radial-gradient(90% 60% at 50% 116%, rgba(166,121,46,.09), transparent 60%), #f4efe6}
[data-theme="light"] body:has(#journeyGL) .stage__vig{
  background:radial-gradient(125% 100% at 50% 42%, transparent 54%, rgba(22,18,14,.09) 100%)}
[data-theme="light"] body:has(#journeyGL) .stage__embers{opacity:.18}
/* THE OPENING FILM — dark footage, so the section keeps its black frame */
[data-theme="light"] .film{background:#0a0807;
  --bg:#0a0807; --ink:#f3ecdf; --ink-dim:#9a9081; --ink-faint:#b0a48f;
  --molten:#c9a24e; --molten-hot:#e6c483; --bronze-lite:#dcbd82;
  --line:rgba(244,236,226,.10); --line-strong:rgba(244,236,226,.22); color:#f3ecdf}
/* the era-copy scrim: same job, opposite colour, roughly half strength — dark ink needs
   far less backing than bone did, and a heavy wash would hide the pillars behind it */
[data-theme="light"] .journey-gl .journey__glow{
  background:linear-gradient(90deg, rgba(244,239,230,.74) 0%, rgba(244,239,230,.44) 30%, rgba(244,239,230,.10) 52%, transparent 68%)}
[data-theme="light"] .journey-gl .journey__pin::after{
  background:radial-gradient(120% 90% at 50% 50%, transparent 58%, rgba(22,18,14,.07) 100%)}
[data-theme="light"] .journey-gl .journey__items{background:rgba(138,90,18,.13);border-color:rgba(138,90,18,.22)}
[data-theme="light"] .journey-gl .ji{background:rgba(255,255,255,.82)}
[data-theme="light"] .ji{background:#faf6ef}
[data-theme="light"] .ji h4{color:#16120e}
[data-theme="light"] .ji p{color:#4c443a}
[data-theme="light"] .journey__tick{background:rgba(22,18,14,.34)}
[data-theme="light"] .journey__tick b{color:#4c443a}
[data-theme="light"] .journey__rail{background:rgba(22,18,14,.16)}
[data-theme="light"] .journey__rail-knob{background:#8a5a12;box-shadow:0 0 10px rgba(138,90,18,.45)}

/* ---------- the finale, on a light ground ---------- */
/* bracket.js swaps the WebGL clear colour itself (it owns scene.background); these are
   the DOM layers stacked over it. #bracketFx is a vignette built to crush the edges of a
   black frame — on light it inverts to a soft bone falloff so the casting still sits in
   a frame rather than floating on a flat field. */
[data-theme="light"] #bracketGL{background:#efe9df}
[data-theme="light"] #bracketFx{
  background:
    linear-gradient(180deg, rgba(244,239,230,.85) 0%, transparent 20%, transparent 84%, rgba(244,239,230,.6) 100%),
    radial-gradient(120% 92% at 50% 44%, transparent 38%, rgba(214,205,190,.55) 100%),
    radial-gradient(62% 58% at 50% 118%, rgba(160,140,110,.10), transparent 60%)}
[data-theme="light"] :is(#bracketCap .k,#bracketTol .k){color:#8a5a12}
[data-theme="light"] :is(#bracketCap h2,#bracketTol .v){color:#16120e}
[data-theme="light"] #bracketCap h2 em{color:#8a5a12}
[data-theme="light"] :is(#bracketCap p,#bracketHint,#bracketTol .p){color:#4c443a}
[data-theme="light"] :is(#bracketCap,#bracketTol,#bracketHint) :is(h2,p,span){text-shadow:none}
[data-theme="light"] .bracket-next{color:#16120e;background:rgba(255,255,255,.72);
  border-color:rgba(22,18,14,.22)}
[data-theme="light"] .bracket-next span{color:#8a5a12}
[data-theme="light"] body.bracket-on .grain{opacity:.03}


/* ══════════════════════════════════════════════════════════════════════════════
   FOUNDRY — the whole page goes light
   ------------------------------------------------------------------------------
   Foundry can do what About's corridor could not, for one concrete reason: nothing
   here renders through a post-processing composer. The casting (foundry-object.js)
   uses alpha:true with no passes, so it composites over any ground; the heat field
   (foundry-heat.js) is a 2D canvas whose blend mode I control, and it now draws
   'multiply' ochre on light instead of additive fire. That leaves only scrims —
   and a scrim is just a colour.
   ══════════════════════════════════════════════════════════════════════════════ */
[data-theme="light"] body:has(.fheat){background:#f4efe6}
[data-theme="light"] body:has(.fheat) :is(.stage,.stage__glow){background:#f4efe6}
[data-theme="light"] body:has(.fheat) .stage__vig{
  background:radial-gradient(125% 100% at 50% 42%, transparent 54%, rgba(22,18,14,.09) 100%)}
/* the environmental grade walks the process in ink, not in fire */
[data-theme="light"] body:has(.fheat) .stage__grade{mix-blend-mode:multiply;opacity:.22}
[data-theme="light"] body:has(.fheat) .stage__embers{opacity:.18}
[data-theme="light"] body:has(.fheat) .grain{opacity:.028;mix-blend-mode:multiply}

/* the four cinema sections take the document tokens */
[data-theme="light"] :is(.fhero,.furnace,.fchap,.finvite){
  --bg:#f4efe6;
  --ink:#16120e; --ink-dim:#4c443a; --ink-faint:#6d6357;
  --molten:#8a5a12; --molten-hot:#a06713; --molten-deep:#5d3d08;
  --bronze:#7a5c14; --bronze-lite:#634c11; --bronze-deep:#b39a6d;
  --line:rgba(22,18,14,.15); --line-strong:rgba(22,18,14,.30);
  color:#16120e}
[data-theme="light"] :is(.fhero,.furnace,.fchap,.finvite) :is(h1,h2,h3,h4,p,span,a,li,div,em,b,small){text-shadow:none}

/* every scrim on the page was built to darken a black frame — inverted, they lift a
   bone one instead of smearing grey over it */
[data-theme="light"] .fhero__bg::after{background:
  radial-gradient(88% 68% at 50% 46%, transparent 52%, rgba(244,239,230,.55) 100%),
  linear-gradient(180deg, rgba(244,239,230,.62), transparent 26%, transparent 74%, rgba(244,239,230,.5))}
[data-theme="light"] .furnace__grad{background:
  radial-gradient(92% 82% at 50% 60%, transparent 44%, rgba(244,239,230,.5) 100%),
  linear-gradient(180deg, rgba(244,239,230,.72) 0%, transparent 24%, transparent 72%, rgba(244,239,230,.8) 100%)}
[data-theme="light"] .finvite::before{
  background:radial-gradient(90% 80% at 50% 58%, rgba(200,120,30,.13), transparent 68%)}
[data-theme="light"] .fchap__bg{background:
  radial-gradient(120% 90% at 50% 50%, rgba(200,140,60,.07), transparent 70%), #f4efe6}

/* the furnace figures: molten numerals become deep gold on bone, and the burn keeps
   pulsing without the black halo it needed on film */
[data-theme="light"] .furnace__num{color:#8a5a12;text-shadow:0 3px 26px rgba(138,90,18,.20)}
[data-theme="light"] .furnace__num small{color:#4c443a}
[data-theme="light"] .furnace__lbl{color:#4c443a}
[data-theme="light"] .furnace__hud-k{color:#8a5a12}
[data-theme="light"] .furnace__hud-i{color:#6d6357}
@keyframes furnaceBurnLight{0%,100%{text-shadow:0 3px 26px rgba(138,90,18,.20)}
  50%{text-shadow:0 5px 40px rgba(160,103,19,.34)}}
[data-theme="light"] .furnace__fig.on .furnace__num{animation-name:furnaceBurnLight}
/* hero + invitation type */
[data-theme="light"] :is(.fhero__title,.finvite__t){color:#16120e}
[data-theme="light"] :is(.fhero__title em,.finvite__t em,.fchap__title em){color:#8a5a12}
[data-theme="light"] :is(.fhero__sub,.finvite__meta,.finvite__trust){color:#4c443a}
[data-theme="light"] .finvite__b{color:#4c443a}
[data-theme="light"] .finvite__k{color:#8a5a12}
[data-theme="light"] :is(.fchap__title,.fprog__k,.fprog__v,.fscope__l){color:#16120e}
[data-theme="light"] :is(.fchap__lede,.fprog__d,.fscope__col li){color:#4c443a}
[data-theme="light"] :is(.fchap__hud-k,.fscope__g){color:#8a5a12}
[data-theme="light"] .fchap__hud-i{color:#6d6357}
[data-theme="light"] .fobj-hint{color:#6d6357;text-shadow:none}
[data-theme="light"] .eyebrow-badge{color:#8a5a12;border-color:rgba(22,18,14,.24);text-shadow:none}

/* the filled CTA measured 3.25:1 on light — champagne fill with bone text. On a light page
   the fill is the bright element, so the label has to be the dark one. */
[data-theme="light"] .btn--fill{background:#8a5a12;color:#f7f2e8;border-color:#8a5a12}
[data-theme="light"] .btn--fill:hover{background:#6f480d;color:#fff}
[data-theme="light"] .btn--text{color:#16120e}
[data-theme="light"] .btn__arrow,[data-theme="light"] .btn--text .btn__arrow{color:#8a5a12}
[data-theme="light"] .pillar__spec-strip span{color:#4c443a}
[data-theme="light"] .pillar__spec-sep{background:rgba(22,18,14,.24)}

/* ══════════════════════════════════════════════════════════════════════════════
   PRODUCTS — the whole page goes light
   The procession is gone, so the only "cinema" left was the hero and the close —
   both pure type over a fixed gradient stage. Nothing here renders through a
   composer or blends additively, so the page flips cleanly.
   ══════════════════════════════════════════════════════════════════════════════ */
[data-theme="light"] body:has(.pstage){background:#f4efe6}
[data-theme="light"] .pstage{background:#f4efe6}
[data-theme="light"] .pstage__vig{background:
  linear-gradient(180deg, rgba(244,239,230,.7) 0%, transparent 22%, transparent 78%, rgba(244,239,230,.75) 100%),
  radial-gradient(125% 95% at 50% 50%, transparent 52%, rgba(22,18,14,.08) 100%)}
/* the grade walks the sectors in ink rather than fire */
[data-theme="light"] .pstage__grade{mix-blend-mode:multiply;opacity:.20}
[data-theme="light"] body[data-psec="close"] .pstage__grade{opacity:.26}

[data-theme="light"] :is(.phero,.pclose){
  --bg:#f4efe6;
  --ink:#16120e; --ink-dim:#4c443a; --ink-faint:#6d6357;
  --molten:#8a5a12; --molten-hot:#a06713; --molten-deep:#5d3d08;
  --bronze:#7a5c14; --bronze-lite:#634c11; --bronze-deep:#b39a6d;
  --line:rgba(22,18,14,.15); --line-strong:rgba(22,18,14,.30);
  color:#16120e}
[data-theme="light"] :is(.phero,.pclose) :is(h1,h2,p,span,a,em,b,small){text-shadow:none}
[data-theme="light"] :is(.phero__t,.pclose__t){color:#16120e}
[data-theme="light"] :is(.phero__t em,.pclose__t em){color:#8a5a12}
[data-theme="light"] :is(.phero__k,.phero__s){color:#4c443a}
[data-theme="light"] .pclose__b{color:#4c443a}
[data-theme="light"] .pclose__meta{color:#6d6357}

/* The scroll cue is FIXED chrome — it lives outside every light container, so it kept the
   dark theme's bone and measured 2.14:1 on the pages that went light. It cannot simply be
   darkened: on the Overview and About it still sits over the film and the corridor, where
   bone is correct. So it is scoped to the two pages whose ground actually turned light. */
[data-theme="light"] body:has(.fheat) .cue,
[data-theme="light"] body:has(.pstage) .cue{color:#4c443a;text-shadow:none}
[data-theme="light"] body:has(.fheat) .cue span,
[data-theme="light"] body:has(.pstage) .cue span{color:#4c443a}
[data-theme="light"] body:has(.fheat) .cue .line,
[data-theme="light"] body:has(.pstage) .cue .line{background:linear-gradient(rgba(22,18,14,.42),transparent)}
/* the corridor's year read-out is large display type, so 4.13:1 already met the large-text
   bar — taken to the deeper gold anyway so the whole page clears 4.5:1 on one standard */
[data-theme="light"] .journey__hud-year{color:#8a5a12}
[data-theme="light"] .journey__hud-k{color:#6d6357}

/* ---------- no vignettes in light mode ----------
   Every vignette on this site is edge-darkening: it exists to focus a bright subject
   inside a dark frame. On a bone page the same layer just puts grey in the corners and
   makes the page look dirty rather than lit, so they are removed outright rather than
   inverted. The legibility scrims that DO work (the corridor's left-hand wash behind the
   era copy) are kept — those hold text readable, which is a different job. */
[data-theme="light"] :is(.stage__vig,.pstage__vig,.cine-vig){display:none}
[data-theme="light"] .journey-gl .journey__pin::after{background:none}
[data-theme="light"] .fhero__bg::after{background:none}
[data-theme="light"] .furnace__grad{background:none}
[data-theme="light"] .fchap__bg{background:#f4efe6}
[data-theme="light"] #bracketFx{background:none}
[data-theme="light"] .finvite::before{background:none}

/* ---------- the MD / Director portraits, on a light ground ----------
   NO MASK IN LIGHT MODE. The feathered edges exist to blend a photo into black; both
   portraits are already transparent PNG cutouts (colour-type 6), so there is no backdrop
   to hide in the first place. On bone the side fade and the vignette only ate into the
   subjects — a soft grey bite out of a shoulder and a jaw — which is exactly the thing
   that looked wrong. Unmasked, the cutout simply sits on the page. */
[data-theme="light"] :is(.purpose__figure--left,.purpose__figure--right) img{
  -webkit-mask-image:none;mask-image:none;filter:none}
[data-theme="light"] .purpose__figure::before{background:none}
[data-theme="light"] .purpose__figure figcaption b{color:#16120e;text-shadow:none}
[data-theme="light"] .purpose__figure figcaption span{color:#6d6357;text-shadow:none}
/* the caption sat at the figure's bottom edge, which the old mask had already faded to
   nothing — so it read as floating under the portrait. With the mask gone in light mode
   that same position lands squarely on a jacket, so it drops below the cutout instead. */
[data-theme="light"] .purpose__figure figcaption{bottom:-52px}
@media(max-width:900px){[data-theme="light"] .purpose__figure figcaption{bottom:-44px}}

/* ---------- About's glass panels, on a light ground ----------
   When the WebGL corridor is live (body.journey-gl — i.e. always, on desktop) a family of
   panels switches to DARK GLASS so they read against the molten scene behind them:
   .discipline, .certs .c, .client and the .ji era cards, plus gold-tinted containers on
   .discipline-grid / .certs / .clients. Those are hardcoded rgba(10,7,5,…) literals, so
   they ignored the light tokens entirely — the Metallurgy / Quality / Dispatch cards came
   out as dark brown slabs with ink text on them, illegible. On light they become bone
   glass with the same warm tint on the containers. */
[data-theme="light"] :is(.journey-gl .certs .c,.journey-gl .discipline,.journey-gl .client){
  background:rgba(255,255,255,.82);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px)}
[data-theme="light"] .journey-gl .client:hover{background:rgba(255,255,255,.94)}
[data-theme="light"] :is(.journey-gl .discipline-grid,.journey-gl .clients,.journey-gl .certs){
  background:rgba(138,90,18,.13);border-color:rgba(138,90,18,.22)}
/* and the same panels when the corridor is NOT live (mobile / no-WebGL fallback) */
[data-theme="light"] :is(.discipline,.certs .c,.client){background:#faf6ef}
[data-theme="light"] .discipline-grid{border-top-color:rgba(138,90,18,.45)}
[data-theme="light"] :is(.discipline__title,.certs .c h4,.client__name){color:#16120e;text-shadow:none}
[data-theme="light"] :is(.discipline__desc,.certs .c p,.client__meta){color:#4c443a;text-shadow:none}

/* ══════════════════════════════════════════════════════════════════════════════
   AFFORDANCE HINTS
   Every interactive moment on the site now states its gesture in the same voice and
   the same instrument: mono caps, and — where the gesture is SCROLL — the site's own
   falling-dot rail borrowed from .cue, so "scroll" always looks like the same thing
   whether it appears under the scroll cue, the casting or the timeline.
   Each hint retires once the visitor performs the gesture; a hint that stays after
   you have obeyed it reads as an error message.
   ══════════════════════════════════════════════════════════════════════════════ */
:is(.fobj-hint,.journey-hint) i{
  display:inline-block;width:1px;height:15px;margin:0 3px -3px 10px;vertical-align:middle;
  background:linear-gradient(var(--molten),transparent);position:relative;overflow:hidden}
:is(.fobj-hint,.journey-hint) i::after{content:"";position:absolute;top:-50%;left:0;
  width:100%;height:50%;background:var(--ink);animation:drop 1.8s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){:is(.fobj-hint,.journey-hint) i::after{animation:none;top:25%}}

/* the journey timeline is grabbable (.journey__scrub) and said so nowhere — the only
   interaction on the site with no instruction at all. It sits under the rail it describes. */
.journey-hint{position:absolute;left:clamp(20px,6vw,110px);bottom:clamp(18px,3.4vh,34px);z-index:5;
  font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-faint);pointer-events:none;white-space:nowrap;
  text-shadow:0 1px 12px rgba(7,5,4,.9);transition:opacity .7s ease}
.journey-hint.gone{opacity:0}
[data-theme="light"] .journey-hint{color:#6d6357;text-shadow:none}
@media(max-width:760px){.journey-hint{font-size:9px;letter-spacing:.14em;
  left:50%;transform:translateX(-50%);bottom:clamp(12px,2.4vh,22px)}}

/* ============================================================
   FOUNDRY'S HERO STILL — cold arrivals only.

   images/casting-hero.png holds the Foundry hero while the 150 KB live casting
   downloads, so a slow first visit never lands on an empty stage. But it is a
   DIFFERENT image from the live object — a finished part, at another angle — and
   on an in-session hop it sat at full opacity for about a second before being
   replaced. Coming from About you watched a static casting appear, hold, then cut
   to a different one. That was "the old thing in between".

   On a hop the model is already cached and arrives almost at once, so there is
   nothing left to cover. html.reentry means we have been somewhere already this
   session (spa.js asserts it on every hop), so the still stays out of the way and
   the hero belongs to the live object from its first frame.

   This lives in styles.css DELIBERATELY. foundry.css is still in flight during the
   hop, and a rule cannot hide anything until its own stylesheet has landed — in
   foundry.css this same rule left a 300ms flash of the still. styles.css is already
   parsed on every page, so it applies the instant the new body is swapped in.
   ============================================================ */
html.reentry .fhero__object{opacity:0}
/* unless there will BE no live object — reduced motion, or no WebGL, where the still
   is the design rather than a placeholder. foundry-object.js sets .fobj-none there. */
html.reentry.fobj-none .fhero__object{opacity:1}
