/* ============================================================
   THE CONDUIT — Stoned Monkey Theory
   The interface for every main page of stonedmonkeytheory.com.

   Faithful to smt-conduit.html: a fixed, non-scrolling cinematic
   experience. The page's content lives in the holo CARDS, grouped
   into SECTORS you travel between via chips / the star map. The
   only things that scroll are the chat dock and the card cluster,
   exactly as in the prototype.

   Sectors are server-rendered into the DOM (not injected by JS) so
   every word stays crawlable.
   ============================================================ */

:root{
  --void:#0D0906;
  --panel:#1C130B;
  --amber:#FFC46B;
  --copper:#D2793A;
  --ember:#FF6A3D;
  --ghost:#F4E9DB;
  --dim:rgba(244,233,219,.55);
  --hair:rgba(210,121,58,.25);
  --glass:rgba(28,19,11,.55);

  --font-display:'Unbounded','Space Grotesk',system-ui,sans-serif;
  --font-body:'Space Grotesk',system-ui,-apple-system,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace;
}

*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden;background:var(--void)}
body{
  font-family:var(--font-body);color:var(--ghost);
  -webkit-font-smoothing:antialiased;
}
@media (pointer:fine){
  body.conduit,body.conduit a,body.conduit button,body.conduit .hoverable{cursor:none}
}
/* ---------- no-JS / WebGL-failure fallback ----------
   Everything the Conduit reveals with a class (.show / .revealed / .on) is
   opacity:0 by default. Without JS those classes never land, so the page would
   render as a black void even though the copy is right there in the DOM.
   This unwinds the whole experience into a plain, readable, scrollable document. */
html.no-js,html.no-js body{overflow:auto;height:auto}
.no-js canvas#gl,.no-js .ignition,.no-js .cursor,.no-js .cursor-ring,
.no-js .bar,.no-js .constellation,.no-js .enter-btn,.no-js .skip,
.no-js .grain,.no-js .vignette{display:none}

.no-js .intro{position:static;inset:auto;min-height:0;padding:120px 24px 40px}
.no-js .eyebrow,.no-js .sub{opacity:1;transform:none}

.no-js .journey{position:static;inset:auto;opacity:1;visibility:hidden;pointer-events:auto}
.no-js .journey{visibility:visible}
.no-js .ghost-label{display:none}
.no-js .dock{position:static}
.no-js .chat-window,.no-js .chips{display:none}

.no-js .cluster{position:static;width:min(760px,calc(100vw - 48px));margin:0 auto 80px;
  max-height:none;overflow:visible;transform:none;perspective:none}
.no-js .sector{display:block !important}
.no-js .holo{opacity:1;transform:none}
.no-js .title .l{opacity:1;filter:none;transform:none}

canvas#gl{position:fixed;inset:0;display:block;z-index:0}

/* ---------- film grain + vignette ---------- */
.vignette{position:fixed;inset:0;pointer-events:none;z-index:3;
  background:radial-gradient(ellipse at 50% 45%,transparent 40%,rgba(6,4,2,.55) 95%)}
.grain{position:fixed;inset:-100%;pointer-events:none;z-index:4;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  animation:grain 7s steps(10) infinite}
@keyframes grain{0%{transform:translate(0,0)}20%{transform:translate(-4%,3%)}40%{transform:translate(3%,-5%)}
  60%{transform:translate(-3%,-2%)}80%{transform:translate(4%,4%)}100%{transform:translate(0,0)}}

/* ---------- letterbox bars ---------- */
.bar{position:fixed;left:0;right:0;height:8vh;background:#020101;z-index:60;pointer-events:none;
  transition:transform 1s cubic-bezier(.7,0,.2,1)}
.bar.top{top:0;transform:translateY(-101%)}
.bar.bot{bottom:0;transform:translateY(101%)}
body.cine .bar.top,body.cine .bar.bot{transform:translateY(0)}

/* ---------- ignition ---------- */
.ignition{position:fixed;inset:0;background:#020101;z-index:80;pointer-events:none;
  transition:opacity 2s ease}
.ignition.off{opacity:0}

/* ---------- cursor ---------- */
.cursor,.cursor-ring{position:fixed;top:0;left:0;pointer-events:none;z-index:200;border-radius:50%;
  transform:translate(-50%,-50%);mix-blend-mode:screen;will-change:transform}
.cursor{width:6px;height:6px;background:var(--amber);
  box-shadow:0 0 12px var(--amber),0 0 30px rgba(255,196,107,.5)}
.cursor-ring{width:34px;height:34px;border:1px solid rgba(255,196,107,.45);
  transition:width .25s,height .25s,border-color .25s}
body.hovering .cursor-ring{width:56px;height:56px;border-color:var(--ember)}
@media (pointer:coarse){.cursor,.cursor-ring{display:none}}

/* ---------- veil / flash ---------- */
.veil{position:fixed;inset:0;z-index:90;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,transparent 0%,rgba(255,196,107,.12) 35%,rgba(210,121,58,.28) 50%,rgba(255,106,61,.12) 65%,transparent 100%);
  background-size:300% 100%;background-position:120% 0}
.veil.sweep{animation:sweep .9s cubic-bezier(.7,0,.2,1)}
@keyframes sweep{0%{opacity:0;background-position:120% 0}25%{opacity:1}75%{opacity:1}
  100%{opacity:0;background-position:-120% 0}}
.flash{position:fixed;inset:0;z-index:89;pointer-events:none;opacity:0;
  background:radial-gradient(circle at 50% 50%,rgba(210,121,58,.25),transparent 60%)}
.flash.on{animation:flash .8s ease-out}
@keyframes flash{0%{opacity:0}15%{opacity:1}100%{opacity:0}}

/* ============================================================
   HUD
   ============================================================ */
/* z-index 50 puts the HUD above BOTH the intro (40) and the journey (30).
   At 20 it was underneath the intro's full-screen layer, so the logo and the
   Contact link were visible but unclickable until you entered the journey —
   the intro was quietly eating the clicks. Contact has to work from anywhere. */
.hud{position:fixed;z-index:50;font-family:var(--font-mono);font-size:10px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--dim);
  opacity:0;transition:opacity 1.2s .3s}
body.booted .hud{opacity:1}

.hud-tl{top:26px;left:32px;display:flex;align-items:center;gap:14px;text-decoration:none}
.logo-mark{width:30px;height:30px;position:relative;flex:none}
.logo-mark::before,.logo-mark::after{content:"";position:absolute;inset:0;
  border:1px solid var(--amber);border-radius:6px;transform:rotate(45deg)}
.logo-mark::after{border-color:var(--ember);animation:spinmark 9s linear infinite}
@keyframes spinmark{to{transform:rotate(405deg)}}
.logo-word{font-family:var(--font-display);font-weight:700;font-size:13px;
  letter-spacing:.3em;color:var(--ghost)}

.hud-tr{top:30px;right:32px;display:flex;gap:22px;align-items:center;list-style:none}
.hud-link{color:var(--dim);text-decoration:none;transition:color .3s;position:relative;
  padding:4px 0;font-family:var(--font-mono);font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;white-space:nowrap;background:none;border:none}
.hud-link::after{content:"";position:absolute;left:0;bottom:0;height:1px;width:0;
  background:linear-gradient(90deg,var(--amber),var(--ember));transition:width .35s}
.hud-link:hover,.hud-link[aria-current="page"]{color:var(--ghost)}
.hud-link:hover::after,.hud-link[aria-current="page"]::after{width:100%}

.hud-bl{bottom:24px;left:32px;display:flex;flex-direction:column;gap:4px}
.hud-br{bottom:24px;right:32px;text-align:right}
.telemetry{color:rgba(255,196,107,.6)}
.blink{animation:blink 1.4s steps(2) infinite}
@keyframes blink{50%{opacity:.15}}

/* Skip intro — bottom centre, NOT top-right. It used to sit at top:26px/right:32px,
   directly on top of the Contact link, and at z-index 85 it won: for the first
   few seconds of every visit, clicking Contact hit "Skip Intro" instead. */
.skip{position:fixed;bottom:30px;left:50%;transform:translateX(-50%);z-index:85;
  font-family:var(--font-mono);font-size:10px;
  letter-spacing:.3em;text-transform:uppercase;color:var(--dim);background:none;border:none;
  padding:10px 16px;transition:color .3s,opacity .6s,visibility .6s}
.skip:hover{color:var(--amber)}
.skip.gone{opacity:0;visibility:hidden;pointer-events:none}

/* ============================================================
   CONSTELLATION — the sector star map
   ============================================================ */
.constellation{position:fixed;right:30px;top:50%;transform:translateY(-50%);z-index:22;
  display:flex;flex-direction:column;align-items:center;opacity:0;transition:opacity 1s;
  pointer-events:none}
body.journeying .constellation{opacity:1;pointer-events:auto}
.c-node{width:11px;height:11px;position:relative;transform:rotate(45deg);
  border:1px solid rgba(244,233,219,.3);background:rgba(28,19,11,.6);transition:all .5s;padding:0}
.c-node:hover{border-color:var(--amber)}
.c-node.lit{border-color:var(--amber);background:var(--amber);
  box-shadow:0 0 12px var(--amber),0 0 26px rgba(255,196,107,.5)}
.c-node .c-tip{position:absolute;right:26px;top:50%;transform:translateY(-50%) rotate(-45deg);
  transform-origin:right center;font-family:var(--font-mono);font-size:9px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--dim);white-space:nowrap;opacity:0;transition:opacity .3s;
  pointer-events:none}
.c-node:hover .c-tip{opacity:1}
.c-link{width:1px;height:26px;background:rgba(244,233,219,.14);position:relative;overflow:hidden}
.c-link i{position:absolute;inset:0;background:linear-gradient(var(--amber),var(--ember));
  transform:scaleY(0);transform-origin:top;transition:transform .8s .2s cubic-bezier(.2,.8,.2,1)}
.c-link.lit i{transform:scaleY(1)}
.c-label{margin-top:14px;font-family:var(--font-mono);font-size:8px;letter-spacing:.25em;
  color:var(--dim);writing-mode:vertical-rl;text-transform:uppercase}
.constellation.complete .c-node.lit{animation:nodepulse 2s ease-in-out infinite}
@keyframes nodepulse{50%{box-shadow:0 0 18px var(--amber),0 0 44px rgba(255,106,61,.7)}}

/* ============================================================
   INTRO
   ============================================================ */
.intro{position:fixed;inset:0;z-index:40;display:flex;flex-direction:column;align-items:center;
  justify-content:center;text-align:center;padding:0 24px;
  transition:opacity 1.1s ease,visibility 1.1s}
/* legibility scrim — the particle core sits directly behind the intro copy and
   washes it out. A soft radial darkening keeps the field visible but the words
   readable. Sits behind the text, above the canvas. */
.intro::before{content:"";position:absolute;left:50%;top:50%;
  width:min(1100px,130vw);height:min(720px,110vh);transform:translate(-50%,-50%);
  background:radial-gradient(ellipse at center,rgba(6,4,2,.78) 0%,rgba(6,4,2,.55) 45%,transparent 72%);
  pointer-events:none;z-index:-1}
.intro > *{position:relative;z-index:1}
.intro.gone{opacity:0;visibility:hidden;pointer-events:none}

.eyebrow{font-family:var(--font-mono);font-size:11px;letter-spacing:.5em;text-transform:uppercase;
  color:var(--amber);opacity:0;transition:opacity 1.2s,transform 1.2s;transform:translateY(20px)}

.title{font-family:var(--font-display);font-weight:700;font-size:clamp(30px,6.6vw,86px);
  line-height:1.04;margin:22px 0 26px;max-width:15ch;
  filter:drop-shadow(0 0 34px rgba(210,121,58,.35))}
/* .w keeps a word intact — inline-block letters would otherwise wrap mid-word */
.title .w{display:inline-block;white-space:nowrap}
.title .l{display:inline-block;opacity:0;filter:blur(14px);
  transform:translateY(40px) scale(1.5) rotate(4deg);
  background:linear-gradient(115deg,var(--ghost) 20%,var(--amber) 45%,var(--copper) 62%,var(--ember) 85%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  transition:opacity .9s cubic-bezier(.2,.8,.2,1),filter .9s,transform .9s cubic-bezier(.2,.8,.2,1)}
.title .l.in{opacity:1;filter:blur(0);transform:none}

.sub{max-width:580px;font-weight:300;font-size:clamp(14px,1.6vw,17px);line-height:1.75;
  color:var(--dim);opacity:0;transition:opacity 1.2s,transform 1.2s;transform:translateY(20px)}

.enter-btn{margin-top:44px;position:relative;padding:16px 46px;background:transparent;
  text-decoration:none;
  border:1px solid var(--hair);border-radius:999px;color:var(--ghost);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.32em;text-transform:uppercase;
  overflow:hidden;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .4s,box-shadow .4s,opacity 1.2s,transform 1.2s;
  opacity:0;transform:translateY(20px)}
.enter-btn::before{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(255,196,107,.15),rgba(255,106,61,.15));
  transform:translateX(-101%);transition:transform .5s cubic-bezier(.65,0,.25,1)}
.enter-btn:hover{border-color:rgba(255,196,107,.7);
  box-shadow:0 0 30px rgba(255,196,107,.25),inset 0 0 20px rgba(255,196,107,.08)}
.enter-btn:hover::before{transform:translateX(0)}
.enter-btn span{position:relative}

.intro.revealed .eyebrow,.intro.revealed .sub,.intro.revealed .enter-btn{opacity:1;transform:none}

/* ============================================================
   JOURNEY
   ============================================================ */
.journey{position:fixed;inset:0;z-index:30;pointer-events:none;opacity:0;visibility:hidden;
  transition:opacity .9s .4s,visibility .9s .4s}
.journey.live{opacity:1;visibility:visible}

/* chat dock */
.dock{position:absolute;left:32px;bottom:76px;width:min(410px,calc(100vw - 48px));
  pointer-events:auto;display:flex;flex-direction:column;gap:14px}
.chat-window{display:flex;flex-direction:column;gap:12px;max-height:44vh;overflow-y:auto;
  padding-right:6px;scrollbar-width:thin;scrollbar-color:rgba(210,121,58,.4) transparent}
.chat-window::-webkit-scrollbar{width:3px}
.chat-window::-webkit-scrollbar-thumb{background:rgba(210,121,58,.4)}

.msg{max-width:92%;padding:14px 18px;border-radius:16px;font-size:14px;line-height:1.65;
  font-weight:300;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  opacity:0;transform:translateY(14px);animation:msgin .6s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes msgin{to{opacity:1;transform:none}}
.msg.ai{align-self:flex-start;background:var(--glass);border:1px solid var(--hair);
  border-top-left-radius:4px;
  box-shadow:0 8px 32px rgba(13,9,6,.5),inset 0 1px 0 rgba(244,233,219,.06)}
.msg.ai .who{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-family:var(--font-mono);
  font-size:9px;letter-spacing:.25em;text-transform:uppercase;color:var(--amber)}
.msg.ai .who i{width:6px;height:6px;border-radius:50%;background:var(--amber);
  box-shadow:0 0 8px var(--amber);animation:blink 1.6s infinite}
.msg.user{align-self:flex-end;
  background:linear-gradient(135deg,rgba(210,121,58,.22),rgba(255,106,61,.16));
  border:1px solid rgba(255,106,61,.3);border-top-right-radius:4px}
.caret{display:inline-block;width:7px;height:14px;background:var(--amber);vertical-align:-2px;
  animation:blink .8s steps(2) infinite}

/* topic chips */
.chips{display:flex;flex-wrap:wrap;gap:9px;pointer-events:auto}
.chip{padding:10px 18px;border-radius:999px;border:1px solid var(--hair);
  background:rgba(28,19,11,.45);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  color:var(--ghost);font-family:var(--font-body);font-size:12.5px;font-weight:400;
  letter-spacing:.04em;transition:all .35s cubic-bezier(.2,.8,.2,1);position:relative;
  overflow:hidden;opacity:0;transform:translateY(10px) scale(.96);animation:msgin .5s forwards}
.chip:nth-child(2){animation-delay:.06s}.chip:nth-child(3){animation-delay:.12s}
.chip:nth-child(4){animation-delay:.18s}.chip:nth-child(5){animation-delay:.24s}
.chip:nth-child(6){animation-delay:.3s}
.chip:hover{border-color:var(--amber);
  box-shadow:0 0 22px rgba(255,196,107,.28),inset 0 0 12px rgba(255,196,107,.08);
  transform:translateY(-2px)}
.chip.active{border-color:var(--ember);
  background:linear-gradient(135deg,rgba(210,121,58,.25),rgba(255,106,61,.2));
  box-shadow:0 0 24px rgba(255,106,61,.3)}

/* ============================================================
   HOLO CARD CLUSTER — where the page's content lives
   ============================================================ */
.cluster{position:absolute;right:6vw;top:50%;width:min(460px,44vw);pointer-events:auto;
  transform-style:preserve-3d;perspective:1200px;
  max-height:74vh;overflow-y:auto;padding-right:4px;
  scrollbar-width:thin;scrollbar-color:rgba(210,121,58,.4) transparent}
.cluster::-webkit-scrollbar{width:3px}
.cluster::-webkit-scrollbar-thumb{background:rgba(210,121,58,.4)}

/* one sector visible at a time — all sectors stay in the DOM for crawlers */
.sector{display:none}
.sector.on{display:block}

.holo{position:relative;border-radius:20px;padding:26px 28px;margin-bottom:18px;
  background:linear-gradient(160deg,rgba(28,19,11,.72),rgba(28,19,11,.4));
  border:1px solid var(--hair);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  box-shadow:0 20px 60px rgba(8,5,2,.6),inset 0 1px 0 rgba(244,233,219,.08);
  opacity:0;transform:translateX(60px) rotateY(-8deg);
  transition:opacity .7s cubic-bezier(.2,.8,.2,1),transform .7s cubic-bezier(.2,.8,.2,1)}
.holo::before{content:"";position:absolute;inset:0;border-radius:20px;padding:1px;
  pointer-events:none;
  background:linear-gradient(135deg,rgba(255,196,107,.5),transparent 30%,transparent 70%,rgba(255,106,61,.5));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;opacity:.7}
.holo::after{content:"";position:absolute;top:0;left:8%;right:8%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,196,107,.8),transparent)}
.sector.show .holo{opacity:1;transform:translateX(0) rotateY(0)}
.sector.show .holo:nth-child(1){transition-delay:.1s}
.sector.show .holo:nth-child(2){transition-delay:.24s}
.sector.show .holo:nth-child(3){transition-delay:.38s}
.sector.show .holo:nth-child(4){transition-delay:.52s}
.sector.show .holo:nth-child(5){transition-delay:.66s}

.holo .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.3em;text-transform:uppercase;
  color:var(--amber);display:flex;align-items:center;gap:10px;margin-bottom:12px}
.holo .tag::before{content:"";width:22px;height:1px;background:var(--amber);
  box-shadow:0 0 6px var(--amber);flex:none}
.holo h2,.holo h3{font-family:var(--font-display);font-weight:500;font-size:19px;
  letter-spacing:.02em;margin-bottom:10px;line-height:1.35;
  background:linear-gradient(100deg,var(--ghost),rgba(210,121,58,.9));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.holo p{font-size:13.5px;font-weight:300;line-height:1.7;color:var(--dim)}
.holo p + p{margin-top:10px}

.holo ul{list-style:none;margin-top:12px}
.holo li{font-size:13px;font-weight:300;color:var(--dim);padding:5px 0 5px 20px;position:relative}
.holo li::before{content:"\25C7";position:absolute;left:0;color:var(--ember);font-size:10px;top:8px}
.holo li strong{color:var(--ghost);font-weight:500}

.holo .stats{display:flex;gap:26px;margin-top:16px;flex-wrap:wrap}
.holo .stat b{display:block;font-family:var(--font-display);font-weight:500;font-size:24px;
  color:var(--amber);text-shadow:0 0 18px rgba(255,196,107,.45)}
.holo .stat i{font-style:normal;font-family:var(--font-mono);font-size:9px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--dim)}

.holo .cta{display:inline-block;margin-top:16px;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.25em;text-transform:uppercase;color:var(--amber);text-decoration:none;
  border-bottom:1px solid rgba(255,196,107,.4);padding-bottom:3px;transition:all .3s}
.holo .cta:hover{color:var(--ember);border-color:var(--ember);
  text-shadow:0 0 14px rgba(255,106,61,.6)}

/* numbered process steps inside a card */
.holo ol{list-style:none;margin-top:12px;counter-reset:s}
.holo ol li{padding-left:30px}
.holo ol li::before{counter-increment:s;content:"0" counter(s);font-family:var(--font-mono);
  font-size:9px;letter-spacing:.1em;color:var(--amber);top:7px}

/* ============================================================
   FORM (contact card)
   ============================================================ */
.holo .form{margin-top:18px}
.holo .form .field{margin-bottom:14px}
.holo .form label{display:block;margin-bottom:6px;font-family:var(--font-mono);font-size:9px;
  letter-spacing:.25em;text-transform:uppercase;color:var(--amber)}
.holo .form input,.holo .form textarea{width:100%;padding:10px 12px;border-radius:10px;
  background:rgba(13,9,6,.55);border:1px solid var(--hair);color:var(--ghost);
  font-family:var(--font-body);font-size:13px;font-weight:300;line-height:1.6}
.holo .form input::placeholder,.holo .form textarea::placeholder{color:rgba(244,233,219,.35)}
.holo .form input:focus,.holo .form textarea:focus{outline:none;border-color:var(--amber)}
.holo .form textarea{resize:vertical}
.holo .form button,.holo button.cta{background:none;border:none;cursor:pointer;
  border-bottom:1px solid rgba(255,196,107,.4)}
.holo .form button[disabled]{opacity:.5;cursor:default}
.form-success{display:none}
.form-success.on{display:block}
.is-hidden{display:none}

/* ghost display type behind the cluster */
.ghost-label{position:absolute;right:4vw;top:12vh;font-family:var(--font-display);font-weight:700;
  font-size:clamp(40px,7vw,110px);letter-spacing:.02em;color:transparent;
  -webkit-text-stroke:1px rgba(210,121,58,.16);pointer-events:none;white-space:nowrap;
  opacity:0;transform:translateX(40px);transition:all 1s .2s cubic-bezier(.2,.8,.2,1)}
.ghost-label.show{opacity:1;transform:none}

/* ============================================================
   THE FORGE — drive-mode UI (easter egg)

   Type DRIVE and the field pours itself into a machine you can drive around
   a Sydney made of the same light. These styles only ever bite while
   body.driving is set; the markup is created by conduit-drive.js, which is
   itself only fetched once somebody finds the egg.
   ============================================================ */
.drive-hints{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);z-index:23;
  font-family:var(--font-mono);font-size:9px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--dim);white-space:nowrap;opacity:0;transition:opacity .8s;pointer-events:none}
.drive-hints i{font-style:normal;color:var(--amber)}
body.driving .drive-hints{opacity:1}

/* the journey is the whole left/right composition — while you are driving,
   the city IS the content, so it stands down entirely */
body.driving .cluster,body.driving .ghost-label,body.driving .dock{display:none}

/* drive panel — the sector you just drove through, read from its own cards */
.drive-panel{position:fixed;top:76px;right:32px;z-index:26;width:min(340px,30vw);
  padding:20px 22px;border-radius:14px;
  background:linear-gradient(165deg,rgba(20,13,8,.92),rgba(20,13,8,.78));
  border:1px solid rgba(210,121,58,.3);border-left:2px solid var(--amber);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  box-shadow:0 16px 50px rgba(6,4,2,.7);
  opacity:0;transform:translateX(24px);pointer-events:none;
  transition:opacity .55s cubic-bezier(.2,.8,.2,1),transform .55s cubic-bezier(.2,.8,.2,1)}
body.driving .drive-panel.show{opacity:1;transform:none;pointer-events:auto}
.drive-panel .dp-eyebrow{font-family:var(--font-mono);font-size:8.5px;letter-spacing:.4em;
  text-transform:uppercase;color:var(--amber);margin-bottom:8px}
.drive-panel h4{font-family:var(--font-display);font-weight:500;font-size:19px;letter-spacing:.03em;
  color:var(--ghost);margin-bottom:4px}
.drive-panel .dp-line{font-size:11.5px;font-weight:300;color:var(--dim);letter-spacing:.03em;
  margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid rgba(210,121,58,.18)}
.drive-panel ul{list-style:none}
.drive-panel li{font-size:12.5px;font-weight:300;line-height:1.55;color:rgba(244,233,219,.8);
  padding:4px 0 4px 16px;position:relative}
.drive-panel li::before{content:"—";position:absolute;left:0;color:var(--copper)}
.drive-panel .dp-stats{display:flex;gap:20px;margin-top:12px;padding-top:12px;
  border-top:1px solid rgba(210,121,58,.18)}
.drive-panel .dp-stats b{display:block;font-family:var(--font-display);font-weight:500;
  font-size:18px;color:var(--amber)}
.drive-panel .dp-stats i{font-style:normal;font-family:var(--font-mono);font-size:8px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.drive-panel .dp-foot{margin-top:14px;font-family:var(--font-mono);font-size:8.5px;
  letter-spacing:.24em;text-transform:uppercase;color:var(--dim)}
.drive-panel .dp-foot i{font-style:normal;color:var(--amber)}

/* touch pad — a phone has no keyboard to type EXIT into, so it gets a button */
.touch-ctl{position:fixed;right:16px;bottom:calc(env(safe-area-inset-bottom,0px) + 20px);z-index:26;
  display:none;grid-template-columns:repeat(3,56px);grid-template-rows:repeat(3,56px);gap:8px}
body.driving.coarse .touch-ctl{display:grid}
.touch-ctl button{border-radius:14px;border:1px solid var(--hair);background:rgba(28,19,11,.6);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  color:var(--amber);font-size:18px;font-family:var(--font-mono);cursor:pointer;
  user-select:none;-webkit-user-select:none;touch-action:none}
.touch-ctl button:active{border-color:var(--amber);background:rgba(210,121,58,.3)}
.touch-ctl .tf-btn{grid-column:3;grid-row:1}
.touch-ctl .fwd-btn{grid-column:2;grid-row:1}
.touch-ctl .left-btn{grid-column:1;grid-row:2}
.touch-ctl .back-btn{grid-column:2;grid-row:2}
.touch-ctl .right-btn{grid-column:3;grid-row:2}
.touch-ctl .exit-btn{grid-column:1/4;grid-row:3;font-size:10px;letter-spacing:.24em;
  border-color:rgba(255,106,61,.45);color:var(--ember)}

/* ============================================================
   THE ARENA — easter egg #2 (type MECH)

   A lit colosseum where two war-frames duel — local AI, or PvP over the
   arena relay. These styles only bite while body.arena is set; the HUD
   markup is created by conduit-arena.js, itself only fetched once somebody
   types the word. Ember/amber accent, matching the forge.
   ============================================================ */
/* while a duel is live the arena IS the content — the journey stands down */
body.arena .cluster,body.arena .ghost-label,body.arena .dock,
body.arena .drive-hints,body.arena .drive-panel{display:none !important}

.arena-hud{position:fixed;top:78px;left:50%;transform:translateX(-50%);z-index:28;
  display:none;align-items:center;gap:22px;font-family:var(--font-mono);font-size:9px;
  letter-spacing:.25em;text-transform:uppercase;pointer-events:none}
body.arena .arena-hud{display:flex}
.arena-hud .hp{width:min(220px,26vw)}
.arena-hud .hp .name{margin-bottom:6px;color:var(--dim)}
.arena-hud .hp.you .name{color:var(--amber);text-align:right}
.arena-hud .hp.foe .name{color:#FF6A6A}
.arena-hud .bar{height:5px;background:rgba(244,233,219,.1);border:1px solid rgba(244,233,219,.15);
  border-radius:3px;overflow:hidden}
.arena-hud .bar i{display:block;height:100%;transform-origin:left;transition:transform .25s}
.arena-hud .hp.you .bar i{background:linear-gradient(90deg,var(--copper),var(--amber));
  transform-origin:right;box-shadow:0 0 10px rgba(255,196,107,.5)}
.arena-hud .hp.foe .bar i{background:linear-gradient(90deg,#FF3B30,#FF7A6A);
  box-shadow:0 0 10px rgba(255,59,48,.5)}
.arena-hud .vs{font-family:var(--font-display);font-weight:700;font-size:15px;color:transparent;
  -webkit-text-stroke:1px rgba(255,106,61,.8)}
.arena-hints{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);z-index:28;display:none;
  font-family:var(--font-mono);font-size:9px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--dim);white-space:nowrap;pointer-events:none}
body.arena .arena-hints{display:block}
.arena-hints i{font-style:normal;color:var(--amber)}
body.arena .cursor{background:#FF6A3D;box-shadow:0 0 10px #FF6A3D,0 0 24px rgba(255,106,61,.6)}
body.arena .cursor-ring{border-color:rgba(255,106,61,.85);
  box-shadow:inset 0 0 8px rgba(255,106,61,.25)}

/* ============================================================
   RESPONSIVE — phones & small tablets (≤900px)

   The desktop Conduit is a two-column composition: the chat dock
   floating bottom-left, the holo cards floating right, both inside a
   fixed frame that never scrolls. That composition has nowhere to go
   on a phone, so here the Conduit UNWINDS:

     .journey becomes the scroll container, and its two halves stack —
     guide + chips first, then the card stack at full width and full
     natural height.

   The particle field stays fixed behind it and the HUD stays fixed
   above it, so the page still feels like the Conduit — but the cards
   are read as a normal vertical scroll instead of through a letterbox.

   (Before this, .cluster was pinned to a 38vh slot while holding a
   ~930px stack of cards, and .dock — bottom:60px, but ~350px tall once
   the guide text and chips wrapped — rendered straight over the top of
   it. The cards were both clipped and covered.)
   ============================================================ */
@media (max-width:900px){

  /* ---------- the journey is now the scroller ---------- */
  .journey{
    height:100vh;height:100dvh;          /* dvh: survives the iOS URL bar */
    pointer-events:auto;                 /* it has to receive the touch scroll */
    overflow-y:auto;overflow-x:hidden;   /* -x:hidden or the card entrance transform adds a sideways scroll */
    -webkit-overflow-scrolling:touch;overscroll-behavior:contain;
    display:flex;flex-direction:column;gap:22px;
    /* clear the fixed HUD (logo row + constellation) and the notch */
    padding:calc(env(safe-area-inset-top,0px) + 124px)
            calc(env(safe-area-inset-right,0px) + 16px)
            calc(env(safe-area-inset-bottom,0px) + 48px)
            calc(env(safe-area-inset-left,0px) + 16px);
  }

  /* guide + chips read first, the cards they summon read second.
     (.cluster precedes .dock in the DOM, so order: flips them.) */
  .dock{
    position:static;inset:auto;width:min(100%,620px);margin-inline:auto;
    order:1;gap:12px;
  }
  .cluster{
    position:static;inset:auto;width:min(100%,620px);margin-inline:auto;
    order:2;
    max-height:none;overflow:visible;padding-right:0;
    /* JS writes an inline 3D transform on desktop; !important beats it
       if the viewport is resized down into this breakpoint */
    transform:none !important;perspective:none;transform-style:flat;
  }

  /* the chat is a log — cap it and let it keep auto-scrolling to the
     newest line, so the chips and cards never get pushed off-screen.
     The mask softens the top edge so older lines fade out of the cap
     instead of being sliced in half. */
  .chat-window{max-height:30vh;max-height:30dvh;
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 34px);
    mask-image:linear-gradient(180deg,transparent,#000 34px)}
  .msg{max-width:100%;font-size:14.5px}

  /* ---------- cards: full width, full height, bigger type ---------- */
  .holo{padding:22px 20px;margin-bottom:14px;
    /* no translateX/rotateY on mobile — it would push a sideways scroll */
    transform:translateY(22px)}
  .holo h2,.holo h3{font-size:20px}
  .holo p{font-size:15px;line-height:1.72}      /* 13.5px is too small to read on a phone */
  .holo li{font-size:14.5px;line-height:1.6}
  .holo .stats{gap:20px}
  .holo .cta{font-size:11px;padding:6px 0;display:inline-block}

  /* 16px inputs — anything smaller and iOS zooms the page on focus */
  .holo .form input,.holo .form textarea{font-size:16px;padding:12px 14px}
  .holo .form button,.holo button.cta{min-height:44px}

  /* ---------- HUD sits above the scrolling cards ---------- */
  .hud,.constellation{z-index:50}
  .hud-bl,.hud-br{display:none}

  /* A scrim so cards scrolling under the HUD stay legible. It has to stay
     fully opaque past the constellation row (which ends ~88px down) or the
     card text shows through between the diamonds — hence the 72% mask stop. */
  body.conduit::before{
    content:"";position:fixed;top:0;left:0;right:0;z-index:45;pointer-events:none;
    height:calc(env(safe-area-inset-top,0px) + 124px);
    background:linear-gradient(180deg,rgba(13,9,6,.97),rgba(13,9,6,.9) 62%,transparent);
    -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
    -webkit-mask-image:linear-gradient(180deg,#000 72%,transparent);
    mask-image:linear-gradient(180deg,#000 72%,transparent);
  }

  .hud-tl{top:calc(env(safe-area-inset-top,0px) + 14px);
    left:calc(env(safe-area-inset-left,0px) + 16px)}

  /* Contact is the only HUD link, so it just sits top-right with a real
     touch target — no scrolling strip needed to fit it. */
  .hud-tr{
    top:calc(env(safe-area-inset-top,0px) + 12px);
    right:calc(env(safe-area-inset-right,0px) + 14px);
    left:auto;
  }
  .hud-link{display:flex;align-items:center;min-height:44px;padding:0 6px}
  .hud-link::after{bottom:8px;left:6px;right:6px}
  .hud-link:hover::after,.hud-link[aria-current="page"]::after{width:calc(100% - 12px)}

  /* ---------- constellation: a row, with real touch targets ---------- */
  .constellation{right:auto;left:50%;flex-direction:row;
    top:calc(env(safe-area-inset-top,0px) + 66px);transform:translateX(-50%)}
  .c-node{width:12px;height:12px}
  /* 44px tap target that costs no layout height — the row stays slim */
  .c-node::after{content:"";position:absolute;inset:-16px}
  .c-link{width:32px;height:1px}
  .c-link i{transform:scaleX(0);transform-origin:left;
    background:linear-gradient(90deg,var(--amber),var(--ember))}
  .c-link.lit i{transform:scaleX(1)}
  .c-label,.c-node .c-tip{display:none}

  /* decorative, and on a phone it both overflows the viewport and
     collides with the constellation row */
  .ghost-label{display:none}

  /* ---------- intro ---------- */
  .intro{
    height:100vh;height:100dvh;overflow-y:auto;
    justify-content:center;justify-content:safe center;  /* never clip the top when it overflows */
    padding:calc(env(safe-area-inset-top,0px) + 88px) 22px
            calc(env(safe-area-inset-bottom,0px) + 96px);
  }
  .title{max-width:none}
  .sub{max-width:34rem}
  .enter-btn{min-height:52px;display:inline-flex;align-items:center;justify-content:center;
    padding:16px 38px;width:min(100%,340px)}

  /* already bottom-centre; just clear the home bar and give it a real target */
  .skip{bottom:calc(env(safe-area-inset-bottom,0px) + 18px);min-height:44px}

  /* ---------- chips ---------- */
  .chips{gap:10px}
  .chip{min-height:44px;display:inline-flex;align-items:center;padding:10px 16px;font-size:13px}

  .bar{height:5vh}

  /* ---------- drive mode on a phone ----------
     .journey is the scroll container up here, which means it covers the whole
     viewport and takes pointer events. Left up, it would swallow every touch
     meant for the city and hide it completely — so while driving it stands
     down entirely and the canvas gets the screen. */
  body.driving .journey{display:none}
  body.driving::before{display:none}          /* and the HUD scrim with it */
  .drive-hints{display:none}                  /* no keyboard to hint at */
  .drive-panel{left:calc(env(safe-area-inset-left,0px) + 12px);
    right:calc(env(safe-area-inset-right,0px) + 12px);
    top:calc(env(safe-area-inset-top,0px) + 104px);width:auto}
}

/* Landscape phones: ~390px of height, and the intro has to fit in it. */
@media (max-height:520px) and (orientation:landscape){
  .intro{padding-top:calc(env(safe-area-inset-top,0px) + 56px);
    padding-bottom:calc(env(safe-area-inset-bottom,0px) + 56px)}
  .title{font-size:clamp(24px,5vw,40px);margin:10px 0 12px}
  .eyebrow{font-size:10px;letter-spacing:.36em}
  .sub{font-size:13px;line-height:1.6}
  .enter-btn{margin-top:18px;min-height:46px;padding:12px 30px}
  .journey{padding-top:calc(env(safe-area-inset-top,0px) + 104px)}
  .chat-window{max-height:40vh;max-height:40dvh}
  .constellation{top:calc(env(safe-area-inset-top,0px) + 54px)}
  body.conduit::before{height:calc(env(safe-area-inset-top,0px) + 104px)}
  .bar{display:none}   /* letterboxing a 390px-tall viewport leaves nothing to read */
}

@media (prefers-reduced-motion:reduce){
  .grain,.logo-mark::after{animation:none}
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .title .l{opacity:1;filter:none;transform:none}
  .holo{opacity:1;transform:none}
}
:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:4px}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* page-to-page transition: fade the conduit out under the veil sweep */
body.departing .intro,body.departing .journey,body.departing .constellation{
  opacity:0;transition:opacity .55s ease}

/* ============================================================
   ERROR PAGES — the intro layer, no journey
   ============================================================ */
.err-actions{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;margin-top:44px;
  opacity:0;transform:translateY(20px);transition:opacity 1.2s,transform 1.2s}
.err-actions .enter-btn{margin-top:0;opacity:1;transform:none}
.intro.revealed .err-actions{opacity:1;transform:none}

.err-links{display:flex;gap:22px;flex-wrap:wrap;justify-content:center;margin-top:40px;
  opacity:0;transition:opacity 1.2s .3s}
.intro.revealed .err-links{opacity:1}
.err-links a{color:var(--dim);text-decoration:none;font-family:var(--font-mono);font-size:10px;
  letter-spacing:.18em;text-transform:uppercase;position:relative;padding-bottom:4px;
  transition:color .3s}
.err-links a::after{content:"";position:absolute;left:0;bottom:0;height:1px;width:0;
  background:linear-gradient(90deg,var(--amber),var(--ember));transition:width .35s}
.err-links a:hover{color:var(--ghost)}
.err-links a:hover::after{width:100%}

/* the error code, ghosted behind the message like the sector labels */
.err-code{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:-1;
  font-family:var(--font-display);font-weight:700;font-size:clamp(160px,34vw,420px);
  line-height:1;color:transparent;-webkit-text-stroke:1px rgba(210,121,58,.12);
  pointer-events:none;user-select:none;white-space:nowrap;
  opacity:0;transition:opacity 1.6s .4s}
body.booted .err-code{opacity:1}

@media (max-width:900px){
  .err-actions{flex-direction:column;width:100%}
  .err-actions .enter-btn{width:100%;text-align:center}
  .err-links{gap:14px;font-size:9px}
}
