/* =========================================================================
   Philip Toulinov — portfolio v2
   "the dev-tool" : Geist + Geist Mono, CI-semantic color, hairline craft.
   hand-rolled, no framework. amber = building/running · green = passed.
   ========================================================================= */

:root{
  /* surfaces — warm-ink elevation ladder (never pure black). research-locked. */
  --bg:    #0c0b10;   /* canvas */
  --bg-1:  #121118;   /* faint raise */
  --bg-2:  #14131a;   /* surface · cards */
  --bg-3:  #1d1b24;   /* raised · inputs · hover */
  --card:  linear-gradient(180deg,#15131c,#100e15);

  /* hairlines — warm-white at low alpha (NOT shadows) */
  --line:   rgba(237,232,224,.08);
  --line-2: rgba(237,232,224,.14);

  /* text ramp — never pure white (avoids halation on warm dark) */
  --text:   #ede8e0;
  --text-2: #a9a39a;
  --text-3: #8b857b;   /* muted tone — lifted to clear WCAG AA (4.5:1) at the small sizes it's used */

  /* CI-semantic status colors — one map drives DAG/terminal/dashboard */
  --amber:      #f5b642;   /* accent · building · running · active */
  --amber-soft: #ffd585;
  --green:      #5ee6c0;   /* passed · healthy · deployed · available */
  --cyan:       #5ec8ff;   /* staging env */
  --magenta:    #e878f5;   /* dev env */
  --red:        #f8553f;   /* failed (sparingly) */
  --pending:    #555259;   /* queued · idle */

  --accent:      var(--amber);
  --accent-soft: var(--amber-soft);
  --accent-rgb:  245,182,66;

  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Bricolage Grotesque", "Geist", ui-sans-serif, system-ui, sans-serif;  /* distinctive display voice */
  --mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --term: "JetBrains Mono", var(--mono);   /* terminal only — real-shell glyphs */

  --pad: clamp(1.25rem, 5vw, 6rem);
  --maxw: 1280px;
  --r:  8px;
  --r-lg: 12px;
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --t-hover: .2s;          /* one hover/focus duration across every interactive surface (premium consistency) */
}

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:auto; overflow-x:hidden; }
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--sans); font-weight:400; line-height:1.5;
  font-size:clamp(15px,1.04vw,16.5px);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  font-feature-settings:"ss01","cv01","cv11";
  font-optical-sizing:auto;
  overflow-x:clip;   /* clip (not hidden) so <body> stays out of the scroll-container business — hidden forces overflow-y:auto, which makes body a scroller and breaks every viewport position:sticky (e.g. the #builds scroll-state strip). clip still suppresses horizontal overflow; unsupported engines fall back to hidden. */
}
body.is-loading{ overflow:hidden; height:100vh; }
img,svg,canvas{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
ul,ol{ margin:0; padding:0; list-style:none; }
h1,h2,h3,h4,p{ margin:0; }
button{ font-family:inherit; color:inherit; background:none; border:none; cursor:pointer; }
::selection{ background:var(--accent); color:#15110a; }

.mono{ font-family:var(--mono); font-weight:400; letter-spacing:-.01em; }
.ok{ color:var(--green); }

/* faint film grain */
body::after{
  content:""; position:fixed; inset:0; z-index:9990; pointer-events:none; opacity:.035;
  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='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;
}

/* =====================  CROSS-DOCUMENT VIEW TRANSITIONS (index ↔ projects "deploy handoff")  =====================
   Enables a shared-element morph from a project card into its case study; degrades to plain navigation
   where unsupported, and never fires during the in-page self-test (no cross-doc nav happens there). */
@view-transition{ navigation:auto; }
::view-transition-group(vt-deploy-hero),::view-transition-group(vt-deploy-title){ animation-duration:.5s; animation-timing-function:cubic-bezier(.16,1,.3,1); }

/* =====================  CURSOR-LIT CODE FIELD (varied, scrolls with page)  ===================== */
/* base is near-invisible (clean dark page); the cursor "flashlight" reveals amber code.
   content is one long NON-repeating CI/CD sequence flowing through multi-columns, so every
   region of the page shows DIFFERENT code (no tiled "wall of the same block"). */
.codefield{ position:fixed; top:0; left:0; width:100%; height:100vh; height:100dvh; z-index:0; overflow:hidden; pointer-events:none;
  background:radial-gradient(circle 380px at var(--mx,-900px) var(--my,-900px), rgba(var(--accent-rgb),.028), transparent 60%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 93%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0%,#000 93%,transparent 100%); }
.codefield__grid{ position:absolute; inset:0;
  background-image:
    linear-gradient(rgba(237,232,224,.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(237,232,224,.025) 1px, transparent 1px);
  background-size:54px 54px;
  -webkit-mask-image:radial-gradient(120% 70% at 50% 0%, #000, transparent 70%);
          mask-image:radial-gradient(120% 70% at 50% 0%, #000, transparent 70%); }
.codefield__text{ position:absolute; inset:0; margin:0;
  padding:6.5rem clamp(1rem,3vw,3.5rem) 2rem; font-family:var(--term); font-size:12.5px; line-height:1.7;
  letter-spacing:.01em; white-space:pre-wrap; word-break:break-word;
  columns:340px auto; column-gap:clamp(2rem,4vw,3.6rem); column-fill:auto; }
.codefield__base{ color:var(--text); opacity:.02; }
.codefield__glow{ color:var(--accent); opacity:.27; text-shadow:0 0 12px rgba(var(--accent-rgb),.16);
  -webkit-mask-image:radial-gradient(240px circle at var(--mx,-900px) var(--my,-900px), #000 0%, #000 12%, transparent 68%);
          mask-image:radial-gradient(240px circle at var(--mx,-900px) var(--my,-900px), #000 0%, #000 12%, transparent 68%); }
/* Mobile-only transform-composited flashlight: a translucent amber blob moved via translate3d (GPU
   composite, NO repaint) instead of the desktop --mx/--my mask, which repainted the full-screen
   #codeGlow <pre> + .codefield bg every frame behind the floating cards (the measured lag source).
   Hidden on desktop; enabled + the moving mask layers disabled in the (pointer:coarse) block below. */
.codefield__cfglow{ display:none; position:absolute; top:0; left:0; width:440px; height:440px;
  margin-left:-220px; margin-top:-220px; border-radius:50%; pointer-events:none; will-change:transform;
  transform:translate3d(-900px,-900px,0); contain:strict;
  /* A focused warm LIGHT (not fog): a tight brighter core + a long soft falloff that reaches transparent
     near the rect edge so almost no dead fill is blended each frame (at DPR 3 the rasterised layer is the
     per-frame cost). It lights the static amber code field enabled in the (pointer:coarse) block below. */
  background:radial-gradient(circle,
    rgba(var(--accent-rgb),.20) 0%,
    rgba(var(--accent-rgb),.11) 26%,
    rgba(var(--accent-rgb),.04) 56%,
    transparent 84%); }

/* Readability: the cursor-lit code stays a TEXTURE behind copy. A soft bg-coloured halo
   wraps each glyph so the code never bleeds through the gaps and muddies the text. */
.hero__eyebrow,.hero__lede,.hero__pitch,.hero__status,
.sec__label,.sec__title,.sec__sub,
.about__big,.about__body,.about__facts,
/* Flux sections show the codefield through #fluxRoot — give their *prose* the same dense halo so it
   stays readable over the cursor-lit code (text-only; never touches the codefield). */
#fluxRoot p,#fluxRoot li,#fluxRoot .ct-val,#fluxRoot .fx-stval{
  text-shadow:0 0 3px var(--bg),0 0 7px var(--bg),0 0 13px var(--bg),0 0 20px var(--bg); }
/* Headings (incl. the contact heading's background-clip:text gradient) use a drop-shadow, NOT a
   text-shadow — text-shadow ghosts gradient-filled text (renders only the shadow, no fill). */
#fluxRoot h1,#fluxRoot h2,#fluxRoot h3,#fluxRoot .flux-role{
  filter:drop-shadow(0 1px 4px var(--bg)) drop-shadow(0 0 11px var(--bg)); }

/* =====================  TOOLCHAIN LOGO GRID  ===================== */
.toolchain-wrap{ margin-top:clamp(1.6rem,3.5vw,2.6rem); }
.toolchain__label{ font-size:12px; color:var(--text-3); margin:0 0 .95rem; }
.toolchain{ list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(auto-fill,minmax(102px,1fr)); gap:10px; }
.tool{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:11px;
  padding:18px 8px; border:1px solid var(--line); border-radius:var(--r); background:var(--card);
  transition:border-color var(--t-hover) var(--ease-out), transform var(--t-hover) var(--ease-out), background var(--t-hover) var(--ease-out); }
.tool__ico{ width:30px; height:30px; background:var(--text-3);
  transition:background .25s, transform .3s var(--ease); }
.tool__name{ font-size:11px; color:var(--text-3); letter-spacing:.02em; text-align:center; transition:color .25s; }
.tool:hover,.tool:focus-within{ border-color:color-mix(in srgb, var(--brand) 50%, var(--line));
  transform:translateY(-3px); background:rgba(255,255,255,.035); }
.tool:hover .tool__ico,.tool:active .tool__ico{ background:var(--brand); transform:scale(1.1); }
.tool:hover .tool__name{ color:var(--text); }
/* reveal wave: each logo flashes to its brand colour as the grid scrolls in (so touch sees colour too) */
.tool--lit .tool__ico{ background:var(--brand); transform:scale(1.12); }
.tool--lit .tool__name{ color:var(--text); }
main,.foot{ position:relative; z-index:1; }

/* =====================  CUSTOM CURSOR  ===================== */
/* solid white (no mix-blend-mode:difference — it went muddy/invisible over the now-visible codefield +
   WebGL flux field); a soft shadow keeps it crisp on any busy/bright background. */
.cursor{ position:fixed; top:0; left:0; z-index:9999; pointer-events:none; filter:drop-shadow(0 0 2.5px rgba(0,0,0,.5)); }
.cursor__dot{ position:fixed; width:7px; height:7px; border-radius:50%; background:#f8553f; box-shadow:0 0 6px rgba(248,85,63,.7); transform:translate(-50%,-50%); }
.cursor__ring{ position:fixed; width:34px; height:34px; border-radius:50%; background:transparent; border:1.5px solid #fff;
  transform:translate(-50%,-50%); transition:width .25s var(--ease), height .25s var(--ease), border-color .25s; }
.cursor__label{ position:fixed; transform:translate(-50%,-50%); font-family:var(--mono); font-size:9.5px;
  letter-spacing:.04em; color:#fff; opacity:0; white-space:nowrap; text-transform:lowercase; }
/* grows on hover/label — always a transparent ring with a clear white border (never a filled blob) */
body.cursor-hover .cursor__ring{ width:54px; height:54px; }
body.cursor-label .cursor__ring{ width:66px; height:66px; }
body.cursor-label .cursor__label{ opacity:1; }
@media (hover:hover) and (pointer:fine){ body{ cursor:none; } body a,body button,body input{ cursor:none; } }
/* while the pointer is inside a live-app iframe, hand off to the native cursor (the dot can't track across
   the iframe boundary) so embedded demos always show a real, working pointer instead of a frozen dot */
html.over-iframe .cursor{ opacity:0 !important; }
html.over-iframe, html.over-iframe body, html.over-iframe iframe{ cursor:auto !important; }
@media (hover:none){ .cursor{ display:none; } }

/* =====================  BUILD / SCROLL BAR  ===================== */
.buildbar{ position:fixed; top:0; left:0; width:100%; height:2px; z-index:9000; }
.buildbar > i{ display:block; height:100%; width:0%; background:linear-gradient(90deg,var(--accent),var(--green));
  box-shadow:0 0 12px rgba(var(--accent-rgb),.5); }

/* =====================  PRELOADER  ===================== */
#preloader{ position:fixed; inset:0; z-index:10000; background:var(--bg); display:grid; place-items:center; }
.pre__inner{ width:min(560px,88vw); border:1px solid var(--line-2); border-radius:var(--r-lg);
  background:var(--card); overflow:hidden; box-shadow:0 40px 120px rgba(0,0,0,.6); }
.pre__bar{ display:flex; align-items:center; gap:8px; padding:11px 14px; border-bottom:1px solid var(--line); background:rgba(255,255,255,.02); }
.pre__dot{ width:11px; height:11px; border-radius:50%; background:#2a2733; }
.pre__dot:nth-child(1){ background:#ff5f57; } .pre__dot:nth-child(2){ background:#febc2e; } .pre__dot:nth-child(3){ background:#28c840; }
.pre__path{ margin-left:8px; font-family:var(--mono); font-size:12px; color:var(--text-3); }
.pre__log{ margin:0; padding:20px 18px; font-family:var(--mono); font-size:13px; line-height:1.95;
  color:var(--text-2); min-height:192px; white-space:pre-wrap; }
.pre__log .g{ color:var(--green); } .pre__log .a{ color:var(--accent); } .pre__log .d{ color:var(--text-3); }
.pre__progress{ height:3px; background:rgba(255,255,255,.05); }
.pre__progress > i{ display:block; height:100%; width:0%; background:linear-gradient(90deg,var(--accent),var(--green)); }
.pre__skip{ position:absolute; bottom:26px; right:30px; color:var(--text-3); font-family:var(--mono); font-size:12px; letter-spacing:.04em; padding:6px; }
.pre__skip:hover{ color:var(--text); }

/* =====================  COMMAND PALETTE (⌘K)  ===================== */
.palette{ position:fixed; inset:0; z-index:9500; display:none; }
.palette.open{ display:block; }
.palette__scrim{ position:absolute; inset:0; background:rgba(6,6,9,.55); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.palette__box{ position:absolute; top:14vh; left:50%; transform:translateX(-50%); width:min(620px,92vw);
  background:var(--card); border:1px solid var(--line-2); border-radius:var(--r-lg);
  box-shadow:0 40px 120px rgba(0,0,0,.6); overflow:hidden; }
.palette.open .palette__box{ animation:palettePop .28s var(--ease-out); }
@keyframes palettePop{ from{ opacity:0; transform:translateX(-50%) translateY(-10px) scale(.985); } to{ opacity:1; } }
.palette__top{ display:flex; align-items:center; gap:.7rem; padding:1rem 1.1rem; border-bottom:1px solid var(--line); }
.palette__chev{ color:var(--accent); font-size:1rem; }
.palette__input{ flex:1; background:none; border:none; outline:none; color:var(--text); font-family:var(--sans);
  font-size:1.05rem; }
.palette__input::placeholder{ color:var(--text-3); }
.palette__esc{ font-size:.62rem; color:var(--text-3); border:1px solid var(--line-2); border-radius:5px; padding:.2rem .4rem; }
.palette__list{ max-height:48vh; overflow-y:auto; padding:.45rem; }
.palette__item{ display:flex; align-items:center; gap:.8rem; padding:.7rem .8rem; border-radius:8px; color:var(--text-2); }
.palette__item .pi__ico{ font-family:var(--mono); color:var(--accent); font-size:.85rem; width:1.4rem; text-align:center; }
.palette__item .pi__t{ color:var(--text); }
.palette__item .pi__d{ margin-left:auto; font-family:var(--mono); font-size:.7rem; color:var(--text-3); }
.palette__item.sel,.palette__item:hover{ background:var(--bg-3); color:var(--text); }
.palette__empty{ padding:1.2rem; color:var(--text-3); font-family:var(--mono); font-size:.85rem; }

/* =====================  NAV  ===================== */
.nav{ position:fixed; top:0; left:0; width:100%; z-index:8000;
  display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1rem var(--pad);
  transition:transform .4s var(--ease), background .4s, backdrop-filter .4s, border-color .4s;
  border-bottom:1px solid transparent; }
.nav.scrolled{ background:rgba(10,10,12,.66); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); border-color:var(--line); }
.nav.hide{ transform:translateY(-110%); }
.nav__brand{ display:flex; align-items:center; gap:.6rem; }
.nav__mark{ font-weight:600; font-size:.95rem; color:var(--accent); border:1px solid var(--line-2); border-radius:6px; padding:.2rem .42rem; line-height:1; }
.nav__name{ font-size:1rem; font-weight:500; letter-spacing:-.01em; }
.nav__links{ display:flex; gap:1.7rem; font-size:.8rem; }
.nav__links a{ color:var(--text-2); position:relative; padding:.2rem 0; display:inline-flex; gap:.4rem; align-items:baseline; }
.nav__links a span{ font-size:.62rem; color:var(--accent); }
.nav__links a::after{ content:""; position:absolute; left:0; bottom:-3px; height:1px; width:0; background:var(--text); transition:width var(--t-hover) var(--ease-out); }
.nav__links a:hover{ color:var(--text); } .nav__links a:hover::after{ width:100%; }
.nav__right{ display:flex; align-items:center; gap:.85rem; }
.status{ display:inline-flex; align-items:center; gap:.45rem; font-size:.72rem; color:var(--text-2); }
.status i{ width:7px; height:7px; border-radius:50%; background:var(--green); box-shadow:0 0 0 0 rgba(94,230,192,.6); animation:pulse 2.6s infinite; }
@keyframes pulse{ 0%{box-shadow:0 0 0 0 rgba(94,230,192,.45)} 70%{box-shadow:0 0 0 7px rgba(94,230,192,0)} 100%{box-shadow:0 0 0 0 rgba(94,230,192,0)} }
.kbtn{ display:inline-flex; gap:.18rem; align-items:center; border:1px solid var(--line-2); border-radius:7px; padding:.3rem .42rem; color:var(--text-2); transition:border-color .3s,color .3s; }
.kbtn:hover{ color:var(--text); border-color:var(--text-3); }
.kbtn kbd{ font-family:var(--mono); font-size:.72rem; }
.kbtn__keys{ display:inline-flex; gap:.18rem; align-items:center; }
.kbtn__touch{ display:none; gap:.32rem; align-items:center; font-size:.74rem; letter-spacing:.01em; }
/* on touch / narrow screens the ⌘K glyph is meaningless — show a labelled "Menu" affordance
   (the palette doubles as the mobile nav once the inline links collapse). */
@media (hover:none), (max-width:760px){
  .kbtn__keys{ display:none; }
  .kbtn__touch{ display:inline-flex; }
  .kbtn{ color:var(--text); border-color:var(--text-3); padding:.34rem .6rem; }
}
/* first-visit coach-mark pointing at the menu/palette button (one-time, localStorage-gated) */
.navhint{ position:fixed; z-index:7700; max-width:min(72vw,260px); /* above .termdock (7600) so the genie never pops out behind the minimized terminal */ padding:.5rem .7rem; border-radius:9px;
  background:var(--card,#15140f); border:1px solid var(--text-3); color:var(--text);
  font-family:var(--mono); font-size:.74rem; line-height:1.35; box-shadow:0 10px 30px rgba(0,0,0,.4);
  opacity:0; transform:translateY(-4px); transition:opacity .35s var(--ease-out,ease), transform .35s var(--ease-out,ease); pointer-events:none; }
.navhint.is-in{ opacity:1; transform:translateY(0); pointer-events:auto; }
.navhint__arrow{ position:absolute; top:-6px; width:11px; height:11px; rotate:45deg;
  background:var(--card,#15140f); border-left:1px solid var(--text-3); border-top:1px solid var(--text-3); }
.navhint b{ color:var(--accent,#f5b642); font-weight:600; }
.navhint::after{ content:""; }
.navhint__pulse{ animation:navhintPulse 1.6s var(--ease-out,ease) infinite; }
@keyframes navhintPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(var(--accent-rgb,245,182,66),.0);} 50%{ box-shadow:0 0 0 4px rgba(var(--accent-rgb,245,182,66),.22);} }

/* ---- genie coach-mark: maximize out of the element it points at, softly cycle the
   transit palette for ~5.5s, then minimize back into that element. --gx/--gy are the
   vector (mark-centre → target-centre) set by JS, so it grows from / shrinks into the
   target like a macOS dock genie (a scale+translate approximation, not a literal warp). */
/* iMessage-style bubble: black fill, white outline, big radius + a two-circle tail */
.coach{ background:#0a0a0a; border:1.6px solid rgba(245,182,66,.95); border-radius:22px; color:#fff;
  box-shadow:0 0 0 4px rgba(245,182,66,.12), 0 12px 34px rgba(0,0,0,.6); will-change:transform,opacity; }
.coach b{ font-weight:700; }
.coach .navhint__arrow{ width:15px; height:15px; rotate:0deg; border-radius:50%;
  background:#0a0a0a; border:1.6px solid rgba(245,182,66,.95); box-shadow:none; }
.coach .navhint__arrow::after{ content:""; position:absolute; width:8px; height:8px; border-radius:50%;
  background:#0a0a0a; border:1.6px solid rgba(245,182,66,.95); left:-1px; top:-12px; }
/* informational + non-blocking: never intercept a tap meant for the control it points at
   (a coach that blocks the very thing it says to tap would be broken). Auto-dismisses. */
.coach.is-in{ animation: coachGenieIn .52s cubic-bezier(.2,1.25,.3,1) both, coachBreathe 2.8s ease-in-out .62s infinite; pointer-events:none; }
.coach.is-out{ animation: coachGenieOut .46s cubic-bezier(.5,0,.75,.25) both; pointer-events:none; }
@keyframes coachGenieIn{
  0%{ opacity:0; transform: translate(var(--gx,0), var(--gy,0)) scale(.12); filter:blur(1.5px); }
  55%{ opacity:1; }
  100%{ opacity:1; transform: translate(0,0) scale(1); filter:blur(0); } }
@keyframes coachGenieOut{
  0%{ opacity:1; transform: translate(0,0) scale(1); filter:blur(0); }
  100%{ opacity:0; transform: translate(var(--gx,0), var(--gy,0)) scale(.12); filter:blur(1.5px); } }
/* soft palette cycle on the border + the highlighted words */
@keyframes coachColor{
  0%,100%{ border-color: rgba(245,182,66,.92); }   /* amber  */
  25%{ border-color: rgba(94,230,192,.92); }        /* mint   */
  50%{ border-color: rgba(98,182,255,.92); }        /* cyan   */
  75%{ border-color: rgba(199,146,234,.92); } }     /* violet */
@keyframes coachColorB{
  0%,100%{ color:#f5b642; } 25%{ color:#5ee6c0; } 50%{ color:#62b6ff; } 75%{ color:#c792ea; } }
/* breathe: gently grow + settle back while the bubble is active (after the genie-in) */
@keyframes coachBreathe{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.035); } }
.coach.is-in b{ animation: coachColorB 5.5s linear .12s 1; }

/* =====================  SECTION PRIMITIVES  ===================== */
section{ position:relative; padding:clamp(4.5rem,10vw,9rem) var(--pad); }
.sec__head{ max-width:var(--maxw); margin:0 auto clamp(2.5rem,5vw,4.5rem); }
.sec__label{ color:var(--accent); font-size:.74rem; letter-spacing:.04em; text-transform:lowercase; margin-bottom:1.1rem; }
.sec__title{ font-family:var(--display); font-weight:700; font-size:clamp(1.9rem,4.4vw,3.6rem); line-height:1.04; letter-spacing:-.03em; max-width:18ch; }
/* "DECRYPTED" hover-decode affordance — the scramble itself is the feedback; this just hints it's live */
.decodable{ cursor:pointer; }
.sec__label.decodable:hover,.hero__eyebrow.decodable:hover{ color:var(--amber-soft); }
.sec__sub{ margin-top:.9rem; color:var(--text-2); font-size:1rem; max-width:60ch; }
.sec__sub code,.terminal code{ font-family:var(--mono); color:var(--accent); background:rgba(var(--accent-rgb),.1); padding:.1em .42em; border-radius:5px; font-size:.86em; }

/* =====================  HERO  ===================== */
.hero{ position:relative; min-height:100svh; display:flex; flex-direction:column; justify-content:center;
  padding-top:7rem; padding-bottom:5rem; }
.hero::before{ content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(80% 60% at 78% 8%, rgba(var(--accent-rgb),.10), transparent 60%); }
.hero__wrap{ max-width:var(--maxw); width:100%; margin:0 auto; }
.hero__eyebrow{ color:var(--accent); font-size:clamp(.7rem,1.3vw,.84rem); letter-spacing:.02em; margin-bottom:1.5rem; }
.hero__title{ font-family:var(--display); font-weight:800; font-size:clamp(3.2rem,13vw,10.5rem); line-height:.9; letter-spacing:-.04em; }
.hero__title .word{ font-variation-settings:"wght" 800, "opsz" 96; }
.hero__title .line{ display:block; overflow:hidden; padding:.02em 0; }
.hero__title .word{ display:inline-block; will-change:transform; }
.hero__lede{ margin-top:clamp(1.4rem,3vw,2.2rem); max-width:34ch; font-size:clamp(1.1rem,1.8vw,1.45rem); line-height:1.45; color:var(--text); font-weight:400; }
.hero__lede .hl{ color:var(--accent-soft); }
.hero__status{ margin-top:1.5rem; display:inline-flex; align-items:center; gap:.6rem; font-size:.8rem; color:var(--text-2); flex-wrap:wrap; }
.hero__status .hero__sep{ color:var(--text-3); }
.dot-ok{ width:7px; height:7px; border-radius:50%; background:var(--green); box-shadow:0 0 8px rgba(94,230,192,.7); }
.hero__cta{ margin-top:2.4rem; display:flex; gap:.8rem; flex-wrap:wrap; }

.btn{ display:inline-flex; align-items:center; gap:.55rem; font-size:.92rem; font-weight:500;
  padding:.85rem 1.35rem; border-radius:9px; border:1px solid var(--line-2); transition:background var(--t-hover) var(--ease-out), color var(--t-hover) var(--ease-out), border-color var(--t-hover) var(--ease-out), transform var(--t-hover) var(--ease-out); will-change:transform; }
.btn svg{ transition:transform var(--t-hover) var(--ease-out); }
.btn--primary{ background:var(--accent); color:#15110a; border-color:var(--accent); font-weight:600; }
.btn--primary:hover{ background:var(--accent-soft); } .btn--primary:hover svg{ transform:translateX(3px); }
.btn--ghost{ color:var(--text); } .btn--ghost:hover{ background:rgba(255,255,255,.05); border-color:var(--text-3); }
.btn.mono{ font-size:.84rem; }
/* desktop: a deliberate, BIG cue in the right rail under the side text — 2x bold, pulsing + bouncing */
/* a clear, clickable pill cue — bigger, invites a tap that scrolls to the next section */
.hero__scroll{ display:inline-flex; align-items:center; gap:.55rem; margin-top:1.8rem; text-decoration:none; cursor:pointer;
  font-size:.82rem; font-weight:700; letter-spacing:.22em; text-transform:uppercase; color:var(--accent);
  padding:.72rem 1.25rem; border:1.6px solid rgba(var(--accent-rgb),.55); border-radius:999px;
  background:rgba(var(--accent-rgb),.07); box-shadow:0 6px 20px rgba(0,0,0,.3);
  transition:background .2s, border-color .2s, color .2s;
  animation:heroScrollCue 1.7s var(--ease) infinite; }
.hero__scroll:hover{ color:#fff; background:rgba(var(--accent-rgb),.18); border-color:var(--accent); }
/* a down chevron in place of the old thin drip line */
.hero__scroll i{ width:9px; height:9px; border-right:2.4px solid currentColor; border-bottom:2.4px solid currentColor;
  transform:rotate(45deg); margin-top:-3px; background:none; border-radius:0; }
.hero__scroll i::after{ content:none; }
@keyframes heroScrollCue{ 0%,100%{ transform:translateY(0); opacity:.86; } 50%{ transform:translateY(5px); opacity:1; } }
@keyframes heroScrollCueM{ 0%,100%{ transform:translateX(-50%) translateY(0); opacity:.86; } 50%{ transform:translateX(-50%) translateY(4px); opacity:1; } }
/* mobile: same pill, kept IN-FLOW below the text (never absolutely positioned over it) */
@media (max-width:880px){
  .hero__scroll{ align-self:center; margin-top:1.3rem;
    font-size:.7rem; letter-spacing:.18em; padding:.55rem 1.05rem; color:var(--accent); }
}

/* =====================  PIPELINE DAG  ===================== */
.pipe{ }
.dag{ max-width:var(--maxw); margin:0 auto clamp(2.5rem,5vw,4rem); position:relative; }
.dag__nodes{ display:grid; grid-template-columns:repeat(5,1fr); gap:0; position:relative; }
.dnode{ position:relative; }
.dnode > button{ display:flex; flex-direction:column; align-items:flex-start; gap:.3rem; width:100%; padding:1rem .8rem 1rem 0; text-align:left; }
.dnode__pt{ position:relative; width:15px; height:15px; border-radius:50%; background:var(--bg-2); border:2px solid var(--pending); margin-bottom:.5rem; transition:border-color .45s, background .45s, box-shadow .45s; z-index:2; }
.dnode__name{ font-size:.74rem; letter-spacing:.02em; color:var(--text-2); text-transform:uppercase; }
.dnode__org{ font-size:.92rem; color:var(--text); font-weight:500; }
.dnode__st{ font-size:.68rem; color:var(--text-3); }
/* connector line behind the dots */
.dag__track{ position:absolute; left:7px; right:7px; top:calc(1rem + 7px); height:2px; background:var(--line-2); z-index:1; overflow:hidden; }
.dag__track > i{ position:absolute; left:0; top:0; height:100%; width:0%; background:linear-gradient(90deg,var(--accent),var(--green)); box-shadow:0 0 10px rgba(var(--accent-rgb),.5); transition:width .5s var(--ease); }
.dag__packet{ position:absolute; top:calc(1rem + 4px); width:8px; height:8px; border-radius:50%; background:var(--accent); box-shadow:0 0 10px 2px rgba(var(--accent-rgb),.8); z-index:3; opacity:0; }
/* node states */
.dnode.run .dnode__pt{ border-color:var(--accent); background:var(--accent); box-shadow:0 0 0 5px rgba(var(--accent-rgb),.16); }
.dnode.run .dnode__pt::after{ content:""; position:absolute; inset:-6px; border-radius:50%; border:2px solid var(--accent); border-top-color:transparent; animation:spin .8s linear infinite; }
.dnode.run .dnode__st{ color:var(--accent); }
.dnode.pass .dnode__pt{ border-color:var(--green); background:var(--green); box-shadow:0 0 0 5px rgba(94,230,192,.16); }
.dnode.pass .dnode__st{ color:var(--green); }
.dnode.pass .dnode__st::before{ content:"✓ "; }
.dnode.sel .dnode__org{ color:var(--accent); }
@keyframes spin{ to{ transform:rotate(360deg); } }

/* =====================  STAGES  ===================== */
.stages{ max-width:var(--maxw); margin:0 auto; }
.stage{ display:grid; grid-template-columns:120px 1fr; gap:clamp(1rem,3vw,2.4rem); }
.stage__gut{ position:relative; padding-top:1.7rem; }
.stage__ix{ font-size:.68rem; letter-spacing:.12em; color:var(--text-3); }
.stage.is-pass .stage__ix{ color:var(--green); } .stage.is-live .stage__ix{ color:var(--accent); }
.stage__line{ position:absolute; left:6px; top:3.2rem; bottom:-1.5rem; width:2px; background:var(--line); }
.stage:last-child .stage__line{ display:none; }
.stage__card{ position:relative; background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:clamp(1.4rem,3vw,2.1rem); margin-bottom:1.5rem; transition:border-color .4s, transform .4s var(--ease), box-shadow .4s; }
.stage__card::before{ content:""; position:absolute; left:-1px; top:1.9rem; width:3px; height:0; background:var(--accent); border-radius:3px; transition:height .5s var(--ease); }
.stage.is-live .stage__card::before,.stage.is-pass .stage__card::before{ height:34px; }
.stage.is-pass .stage__card::before{ background:var(--green); }
.stage__card:hover{ border-color:var(--line-2); transform:translateY(-2px); }
.stage__card--flag{ box-shadow:0 0 0 1px rgba(var(--accent-rgb),.08); }
.stage__card--now{ background:linear-gradient(180deg, rgba(var(--accent-rgb),.05), transparent); }
.stage__top{ display:flex; justify-content:space-between; align-items:flex-start; gap:1rem; flex-wrap:wrap; margin-bottom:1.2rem; }
.stage__role{ font-size:clamp(1.25rem,2.3vw,1.7rem); font-weight:600; letter-spacing:-.02em; }
.stage__org{ color:var(--accent-soft); font-size:.98rem; margin-top:.15rem; }
.stage__mode{ color:var(--text-3); }
.stage__meta{ display:flex; flex-direction:column; align-items:flex-end; gap:.5rem; }
.stage__dates{ font-size:.78rem; color:var(--text-2); }
.chip{ font-family:var(--mono); font-size:.66rem; text-transform:lowercase; letter-spacing:.02em; padding:.26rem .6rem; border-radius:20px; border:1px solid var(--line-2); color:var(--text-3); }
.chip.live{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); }
.chip.pass{ color:var(--green); border-color:rgba(94,230,192,.45); }
.chip.pass::before{ content:"✓ "; }
.chip[data-live]{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); }
.stage__points{ display:grid; gap:.85rem; }
.stage__points li{ position:relative; padding-left:1.4rem; color:var(--text-2); font-size:.98rem; line-height:1.55; }
.stage__points li::before{ content:""; position:absolute; left:.1rem; top:.6em; width:6px; height:6px; border:1px solid var(--accent); transform:rotate(45deg); }
.stage__points b{ color:var(--text); font-weight:600; }
.stage__points b[data-count]{ color:var(--accent); font-family:var(--mono); font-weight:500; }
.stage__art{ margin-top:1.4rem; padding-top:1rem; border-top:1px dashed var(--line-2); font-size:.74rem; color:var(--text-3); }
.stage__art a{ color:var(--accent); }
.stage__art a:hover{ color:var(--accent-soft); }

/* =====================  OBSERVABILITY  ===================== */
.obs{ padding-top:0; }
.obs__wrap{ max-width:var(--maxw); margin:0 auto; border:1px solid var(--line); border-radius:var(--r-lg); background:var(--bg-1); padding:clamp(1.5rem,4vw,2.5rem); }
.obs .sec__label{ margin-bottom:1.4rem; }
.obs__grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r); overflow:hidden; }
.tile{ background:var(--bg-2); padding:1.2rem 1.3rem 1.3rem; display:flex; flex-direction:column; gap:.5rem; min-height:150px; }
.tile__k{ font-size:.7rem; color:var(--text-3); letter-spacing:.02em; }
.tile__v{ font-size:clamp(1.8rem,3.4vw,2.6rem); font-weight:600; letter-spacing:-.03em; line-height:1; }
.tile__v b{ font-weight:600; }
.tile__v--mono{ font-family:var(--mono); font-weight:500; font-size:clamp(1.4rem,2.6vw,2rem); }
.tile__spark{ width:100%; height:40px; margin-top:auto; opacity:.9; }
.tile__sub{ font-size:.68rem; color:var(--text-3); }
.tile__v .tdot{ display:inline-block; width:11px; height:11px; border-radius:50%; background:var(--green); margin-right:.55rem; vertical-align:baseline; }
.tile__gauge{ margin-top:auto; height:6px; border-radius:6px; background:var(--bg-3); overflow:hidden; }
.tile__gauge > i{ display:block; height:100%; width:0%; background:linear-gradient(90deg,var(--accent),var(--green)); }

/* =====================  TERMINAL  ===================== */
.terminal{ max-width:960px; margin:0 auto; border:1px solid var(--line-2); border-radius:var(--r-lg);
  background:var(--card); overflow:hidden; box-shadow:0 40px 110px rgba(0,0,0,.5); }
.terminal__bar{ display:flex; align-items:center; gap:8px; padding:11px 15px; border-bottom:1px solid var(--line); background:rgba(255,255,255,.02); }
.terminal__path{ margin-left:8px; font-size:12px; color:var(--text-3); }
.terminal__hint{ margin-left:auto; font-size:11px; color:var(--text-3); } .terminal__hint b{ color:var(--accent); font-weight:500; }
.terminal__scroll{ height:min(60vh,460px); overflow-y:auto; overscroll-behavior:contain; padding:18px clamp(15px,2.5vw,24px) 22px; cursor:text; }
.terminal__scroll::-webkit-scrollbar{ width:9px; }
.terminal__scroll::-webkit-scrollbar-thumb{ background:var(--line-2); border-radius:5px; }
.terminal__body{ font-size:13px; line-height:1.85; color:var(--text-2); }
.terminal__body .row{ display:block; white-space:pre-wrap; overflow-wrap:anywhere; margin:.14em 0; }
.terminal__body .cmd{ color:var(--text); display:block; margin-top:.95em; }
.terminal__body .cmd::before{ content:"$ "; color:var(--green); }
.terminal__body .a{ color:var(--accent); } .terminal__body .g{ color:var(--green); } .terminal__body .d{ color:var(--text-3); } .terminal__body .r{ color:var(--red); }
.terminal__body .c{ color:var(--cyan); } .terminal__body .m{ color:var(--magenta); }
.terminal__body .head{ display:block; color:var(--accent); text-transform:uppercase; letter-spacing:.06em; font-size:10.5px; margin-top:.7em; }
.terminal__body .bar{ color:var(--green); } .terminal__body .bar .e{ color:var(--text-3); }
.terminal__body a{ color:var(--green); text-decoration:underline; text-underline-offset:3px; }
.terminal__body a:hover{ color:var(--accent); }
.terminal__line{ display:flex; align-items:center; gap:.5ch; font-size:13px; margin-top:.5em; }
.terminal__prompt{ color:var(--text); white-space:nowrap; }
.terminal__input{ flex:1; min-width:2ch; background:none; border:none; outline:none; color:var(--text); font-family:var(--mono); font-size:13px; caret-color:var(--accent); padding:0; }
/* the hero input is bare — the .terminal__field pill owns the single amber outline (see below) */
#heroTermInput{ padding:5px 0; }
/* focusing the shell hides the big ASCII name banner for a clearer view of the live terminal */
#heroTerm.is-typing .heroterm__banner{ display:none; }
.term-fallback{ max-width:960px; margin:1rem auto; color:var(--text-2); font-family:var(--mono); font-size:.84rem; line-height:1.8; }
/* terminal uses JetBrains Mono for real-shell glyphs (slashed zero, unambiguous) */
.terminal__body,.terminal__body.mono,.terminal__line,.terminal__line.mono,.terminal__input,.terminal__path,.terminal__path.mono,.terminal__hint,.terminal__hint.mono{ font-family:var(--term); }

/* =====================  ABOUT  ===================== */
.about__grid{ max-width:var(--maxw); margin:0 auto; display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr); gap:clamp(1.6rem,3.6vw,3.2rem); align-items:stretch; }
.about__big{ font-size:clamp(1.5rem,3vw,2.4rem); line-height:1.28; letter-spacing:-.02em; font-weight:400; color:var(--text); }
.about__big b{ font-weight:600; color:var(--text); }
.about__body{ margin-top:1.5rem; color:var(--text-2); font-size:1.05rem; max-width:56ch; }
.about__facts{ border-top:1px solid var(--line); }
.about__facts li{ display:flex; gap:1rem; padding:.8rem 0; border-bottom:1px solid var(--line); font-size:.9rem; color:var(--text); }
.about__facts li span{ color:var(--text-3); min-width:5.5ch; }

/* =====================  CONTACT  ===================== */
.contact__big{ font-family:var(--display); font-weight:800; font-size:clamp(2rem,5vw,4rem); line-height:1; letter-spacing:-.03em; margin:.2rem 0 0; max-width:18ch; }
.contact__big .line{ display:block; overflow:hidden; }
.contact__big span[data-word]{ display:inline-block; will-change:transform; }
.contact__lede{ margin:1.6rem auto 0; color:var(--text-2); max-width:var(--maxw); font-size:1.05rem; }
.contact__links{ margin:clamp(2.5rem,5vw,4rem) auto 0; border-top:1px solid var(--line); max-width:var(--maxw); }
.contact__link{ display:flex; align-items:baseline; gap:1.2rem; padding:1.4rem .3rem; border-bottom:1px solid var(--line); transition:padding var(--t-hover) var(--ease-out), background var(--t-hover) var(--ease-out); }
.contact__link span{ color:var(--text-3); min-width:9ch; font-size:.74rem; text-transform:uppercase; letter-spacing:.06em; }
.contact__link b{ font-weight:600; font-size:clamp(1.2rem,3vw,2.1rem); color:var(--text); letter-spacing:-.02em; transition:color var(--t-hover) var(--ease-out); }
.contact__arrow{ margin-left:auto; font-size:.72rem; color:var(--text-3); opacity:0; transform:translateX(-6px); transition:opacity var(--t-hover) var(--ease-out), transform var(--t-hover) var(--ease-out), color var(--t-hover) var(--ease-out); }
.contact__link:hover{ padding-left:1.2rem; background:linear-gradient(90deg,rgba(var(--accent-rgb),.05),transparent); }
.contact__link:hover b{ color:var(--accent); }
.contact__link:hover .contact__arrow{ opacity:1; transform:translateX(0); color:var(--accent); }

/* commit-a-message form (git-themed, mailto, no backend) */
.commit{ max-width:var(--maxw); margin:clamp(2.5rem,5vw,4rem) auto 0; border:1px solid var(--line-2); border-radius:var(--r-lg);
  background:var(--card); overflow:hidden; box-shadow:0 40px 110px rgba(0,0,0,.45); }
.commit__bar{ display:flex; align-items:center; gap:8px; padding:11px 15px; border-bottom:1px solid var(--line); background:rgba(255,255,255,.02); }
.commit__path{ margin-left:8px; font-size:12px; color:var(--text-3); }
.commit__body{ display:flex; flex-direction:column; gap:.7rem; padding:clamp(1.1rem,2.5vw,1.6rem); }
.commit__row{ display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; }
.commit__kw{ color:var(--green); font-size:13px; white-space:nowrap; }
.commit__body input,.commit__body textarea{ flex:1; min-width:12ch; background:var(--bg); border:1px solid var(--line); border-radius:8px;
  color:var(--text); font-family:var(--term); font-size:13px; padding:.6rem .7rem; outline:none; transition:border-color .2s; resize:vertical; }
.commit__body input:focus,.commit__body textarea:focus{ border-color:rgba(var(--accent-rgb),.5); }
.commit__body input::placeholder,.commit__body textarea::placeholder{ color:var(--text-3); }
.commit__body textarea{ width:100%; line-height:1.6; }
.commit__foot{ display:flex; align-items:center; gap:1rem; flex-wrap:wrap; margin-top:.2rem; }
.commit__hint{ font-size:11px; color:var(--text-3); }
.commit__out{ margin:0; font-size:12.5px; line-height:1.7; color:var(--text-2); white-space:pre-wrap; min-height:0; }
.commit__out:empty{ display:none; }
.commit__out .g{ color:var(--green); } .commit__out .d{ color:var(--text-3); } .commit__out .r{ color:var(--red); } .commit__out .a{ color:var(--accent); }

/* =====================  FOOTER  ===================== */
.foot{ display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap; padding:2rem var(--pad); border-top:1px solid var(--line); color:var(--text-3); font-size:.74rem; }
.foot__build i{ font-style:normal; }

/* =====================  REVEAL INITIAL STATES  ===================== */
.is-loading [data-reveal],.is-loading [data-point]{ opacity:0; }
.no-motion [data-reveal],.no-motion [data-point]{ opacity:1!important; }
.no-motion [data-word]{ transform:none!important; }

/* =====================  ENV THEMES  ===================== */
body[data-env="staging"]{ --accent:var(--cyan); --accent-soft:#a9e0ff; --accent-rgb:94,200,255; }
body[data-env="dev"]{ --accent:var(--magenta); --accent-soft:#f3b6fa; --accent-rgb:232,120,245; }

/* =====================  TERMINAL QUICK-COMMAND CHIPS  ===================== */
.term-chips{ display:flex; flex-wrap:wrap; gap:.4rem; padding:.7rem clamp(15px,2.5vw,24px); border-bottom:1px solid var(--line); background:rgba(255,255,255,.015); }
.term-chips button{ font-family:var(--term); font-size:.7rem; color:var(--text-2); border:1px solid var(--line-2); border-radius:6px; padding:.28rem .55rem; transition:color .2s,border-color .2s,background .2s; }
.term-chips button::before{ content:"$ "; color:var(--text-3); }
.term-chips button:hover{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); background:rgba(var(--accent-rgb),.06); }

/* =====================  KEYBOARD CHEATSHEET (?)  ===================== */
.sheet{ position:fixed; inset:0; z-index:9500; display:none; }
.sheet.open{ display:block; }
.sheet__scrim{ position:absolute; inset:0; background:rgba(6,6,9,.55); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.sheet__box{ position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:min(420px,92vw);
  background:var(--card); border:1px solid var(--line-2); border-radius:var(--r-lg); box-shadow:0 40px 120px rgba(0,0,0,.6); overflow:hidden; }
.sheet.open .sheet__box{ animation:palettePop .28s var(--ease-out); }
.sheet__top{ display:flex; justify-content:space-between; align-items:center; padding:.9rem 1.1rem; border-bottom:1px solid var(--line); color:var(--text-2); font-size:.78rem; }
.sheet__top kbd{ font-size:.62rem; color:var(--text-3); border:1px solid var(--line-2); border-radius:5px; padding:.2rem .4rem; }
.sheet__list{ padding:.6rem; }
.sheet__list li{ display:flex; align-items:center; gap:1rem; padding:.5rem .7rem; font-size:.82rem; color:var(--text-2); }
.sheet__keys{ display:inline-flex; gap:.25rem; min-width:4.6rem; }
.sheet__keys kbd{ font-size:.7rem; color:var(--accent); border:1px solid var(--line-2); border-radius:5px; padding:.12rem .42rem; background:var(--bg-3); }

/* =====================  DAG NODE FLASH (on click-to-jump)  ===================== */
.stage--flash .stage__card{ border-color:rgba(var(--accent-rgb),.55); box-shadow:0 0 0 1px rgba(var(--accent-rgb),.3), 0 0 40px rgba(var(--accent-rgb),.12); }
.dnode__org .sha{ color:var(--accent); font-family:var(--mono); font-size:.72rem; }

/* =====================  STAGE BUILD-LOG MICRO-STREAM  ===================== */
.stage__log{ margin:.55rem 0 0; font-family:var(--term); font-size:11.5px; line-height:1.8; color:var(--text-3); white-space:pre-wrap; }
.stage__log:empty{ display:none; }
.stage__log .g{ color:var(--green); } .stage__log .a{ color:var(--accent); } .stage__log .d{ color:var(--text-3); }

/* =====================  ENV CHIP + VIEW-TRANSITION THEME BLOOM  ===================== */
.env-chip{ display:inline-flex; align-items:center; gap:.4rem; border:1px solid var(--line-2); border-radius:20px; padding:.3rem .62rem; color:var(--accent); font-family:var(--mono); font-size:.66rem; transition:border-color .3s,color .3s; }
.env-chip i{ width:6px; height:6px; border-radius:50%; background:var(--accent); box-shadow:0 0 8px rgba(var(--accent-rgb),.7); }
.env-chip:hover{ border-color:rgba(var(--accent-rgb),.5); }
@media (max-width:860px){ .env-chip{ display:none; } }
::view-transition-old(root),::view-transition-new(root){ animation:none; mix-blend-mode:normal; }
::view-transition-old(root){ z-index:0; } ::view-transition-new(root){ z-index:1; }

/* =====================  COPY BUTTON (optimistic morph)  ===================== */
.copy{ display:inline-flex; align-items:center; gap:.35rem; border:1px solid var(--line-2); border-radius:6px; padding:.22rem .5rem; color:var(--text-2); font-family:var(--mono); font-size:.66rem; transition:color .2s,border-color .2s; }
.copy:hover{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); }
.copy.done{ color:var(--green); border-color:rgba(94,230,192,.5); }
.contact__link .copy{ margin-left:auto; align-self:center; }
.contact__link > a{ flex:none; }
.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; }

/* =====================  REACHABILITY (contact)  ===================== */
.contact__reach{ display:inline-flex; align-items:center; gap:.5rem; margin-top:1.1rem; color:var(--text-2); font-size:.82rem; font-family:var(--mono); }
.dot-idle{ width:7px; height:7px; border-radius:50%; background:var(--amber); box-shadow:0 0 8px rgba(245,182,66,.6); flex:none; }

/* =====================  PULSING PRESENCE DOT  ===================== */
.ping{ position:relative; }
.ping::after{ content:""; position:absolute; inset:0; border-radius:50%; background:inherit; animation:ping 2.6s cubic-bezier(0,0,.2,1) infinite; }
@keyframes ping{ 75%,100%{ transform:scale(2.6); opacity:0; } }

/* =====================  ROLLBACK / RETRO MODE (konami)  ===================== */
body.rollback{ --accent:#ff8c42; --accent-soft:#ffb583; --accent-rgb:255,140,66; }
body.rollback::before{ content:"⟲ rollback mode · git revert HEAD~1 — press ↑↑↓↓←→←→ b a to redo"; position:fixed; left:0; right:0; bottom:0; z-index:9400;
  text-align:center; font-family:var(--mono); font-size:.68rem; letter-spacing:.06em; color:#1a0f06; background:var(--accent); padding:.35rem; }

/* =====================  RESPONSIVE  ===================== */
@media (max-width:1000px){
  .about__grid{ grid-template-columns:1fr; }
  .obs__grid{ grid-template-columns:1fr 1fr; }
}
@media (max-width:760px){
  .nav__links,.nav__name{ display:none; }
  .dag__nodes{ grid-template-columns:1fr; gap:.2rem; }
  .dag__track{ left:7px; right:auto; top:1rem; bottom:1rem; width:2px; height:auto; }
  .dag__track > i{ width:100%!important; height:0%; }
  .dag__packet{ display:none; }
  .dnode > button{ flex-direction:row; align-items:center; gap:.7rem; padding:.6rem 0; }
  .dnode__pt{ margin-bottom:0; }
  .dnode__name{ min-width:5.5rem; }
  .stage{ grid-template-columns:1fr; }
  .stage__gut{ padding-top:0; display:flex; align-items:center; gap:.6rem; }
  .stage__line{ display:none; }
  .stage__top{ flex-direction:column; }
  .stage__meta{ align-items:flex-start; flex-direction:row; gap:.7rem; }
  .obs__grid{ grid-template-columns:1fr; }
  .hero__lede{ max-width:none; }
  .contact__link{ flex-direction:column; gap:.3rem; }
  .contact__arrow{ display:none; }
  .foot{ flex-direction:column; gap:.5rem; }
}

/* =====================  REDUCED MOTION (applied only when the site itself is no-motion)  ===================== */
.no-motion *,.no-motion *::before,.no-motion *::after{ animation-duration:.001ms!important; animation-iteration-count:1!important; transition-duration:.001ms!important; }
.no-motion .hero__scroll i::after,.no-motion .status i,.no-motion .dnode.run .dnode__pt::after{ animation:none; }
.no-motion [data-word]{ transform:none!important; }
.no-motion [data-reveal],.no-motion [data-point]{ opacity:1!important; }

/* =====================  THESIS — pinned kinetic interstitial (hero → pipeline)  ===================== */
.thesis{ position:relative; z-index:1; }
.thesis__pin{ position:relative; height:100vh; display:flex; align-items:center; justify-content:center; overflow:hidden; }
.thesis__beat{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; padding:0 var(--pad); }
.thesis__line{ margin:0; max-width:18ch; text-align:center; text-wrap:balance; font-family:var(--display); font-weight:600; font-size:clamp(2.1rem,6vw,5rem); line-height:1.04; letter-spacing:-.02em; color:var(--text); }
.thesis__line .tw{ display:inline-block; will-change:transform,filter; }
.thesis__am{ color:var(--accent); }
.thesis__arrow{ font-family:var(--mono); font-weight:400; color:var(--text-3); padding:0 .08em; }
.thesis__hud{ position:absolute; left:50%; bottom:clamp(28px,5vh,52px); transform:translateX(-50%); display:flex; flex-direction:column; align-items:center; gap:11px; }
.thesis__bar{ width:120px; height:2px; border-radius:2px; overflow:hidden; background:var(--line-2); }
.thesis__bar > i{ display:block; height:100%; width:0%; background:linear-gradient(90deg,var(--accent),var(--green)); box-shadow:0 0 10px rgba(var(--accent-rgb),.5); }
.thesis__pct{ font-size:10.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--text-3); }
@media (max-width:640px){ .thesis__line{ max-width:13ch; } }
.no-motion .thesis__pin{ height:auto; flex-direction:column; gap:clamp(1.2rem,5vh,3rem); padding:16vh var(--pad); }
.no-motion .thesis__beat{ position:relative; inset:auto; padding:0; }
.no-motion .thesis__hud{ display:none; }

/* =====================  HERO STATUSPAGE  ===================== */
.statuspage{ margin:1.5rem 0 0; max-width:520px; border:1px solid var(--line); border-radius:var(--r-lg); background:linear-gradient(180deg,rgba(255,255,255,.018),transparent); padding:.85rem 1rem; }
.sp__top{ display:flex; align-items:center; justify-content:space-between; gap:1rem; font-size:.72rem; letter-spacing:.02em; }
.sp__hdr{ display:inline-flex; align-items:center; gap:.5rem; color:var(--text-2); }
.sp__dot{ width:7px; height:7px; border-radius:50%; background:var(--green); box-shadow:0 0 9px var(--green); }
.sp__win{ color:var(--text-3); }
.sp__rows{ margin-top:.7rem; display:flex; flex-direction:column; gap:.46rem; }
.sp__row{ display:grid; grid-template-columns:6.2rem 1fr auto; align-items:center; gap:.7rem; }
.sp__name{ font-size:.68rem; color:var(--text-3); letter-spacing:.02em; }
.sp__bars{ display:flex; align-items:flex-end; gap:1.5px; height:16px; }
.sp__bar{ flex:1 1 auto; height:100%; border-radius:1px; background:var(--green); opacity:.45; transform:scaleY(.4); transform-origin:bottom; transition:transform .5s var(--ease), opacity .5s; }
.sp__bar--deg{ background:var(--amber); }
.sp__bars.is-in .sp__bar{ transform:scaleY(1); opacity:.72; }
.sp__pct{ font-size:.66rem; color:var(--text-2); }
.warn{ color:var(--amber); }
@media (max-width:640px){ .sp__row{ grid-template-columns:5rem 1fr auto; } .sp__bars{ height:13px; gap:.5px; } .sp__bar{ min-width:1px; border-radius:.5px; } }

/* =====================  PLAYABLE INCIDENT  ===================== */
.incident{ margin-top:2.2rem; border:1px solid var(--line-2); border-radius:var(--r-lg); overflow:hidden; background:var(--bg-2); }
.incident__bar{ display:flex; align-items:center; gap:.7rem; flex-wrap:wrap; padding:.7rem 1rem; border-bottom:1px solid var(--line); background:linear-gradient(90deg,rgba(248,85,63,.10),transparent); font-size:.74rem; }
.incident__sev{ color:var(--red); font-weight:600; letter-spacing:.02em; }
.incident__svc{ color:var(--text-3); }
.incident__ttl{ color:var(--text); flex:1 1 auto; }
.incident__timer{ color:var(--amber); font-variant-numeric:tabular-nums; }
.incident.is-resolved .incident__bar{ background:linear-gradient(90deg,rgba(94,230,192,.10),transparent); }
.incident.is-resolved .incident__sev{ color:var(--green); }
.incident__log{ margin:0; padding:1rem; min-height:7.5rem; max-height:13rem; overflow:auto; font-size:.76rem; line-height:1.75; white-space:pre-wrap; }
.incident__log span{ display:block; }
.incident__log .cmd{ color:var(--text); }
.incident__log .d{ color:var(--text-3); }
.incident__log .r{ color:var(--red); }
.incident__log .g{ color:var(--green); }
.incident__log .a{ color:var(--amber); }
.incident__steps{ display:flex; flex-wrap:wrap; gap:.5rem; padding:.85rem 1rem; border-top:1px solid var(--line); }
.incident__btn{ font-family:var(--mono); font-size:.74rem; color:var(--text-2); border:1px solid var(--line-2); border-radius:8px; padding:.45rem .9rem; background:var(--bg-3); transition:all .2s var(--ease); }
.incident__btn:not(:disabled):hover{ color:var(--text); border-color:var(--accent); }
.incident__btn:disabled{ opacity:.4; cursor:default; }
.incident__btn.is-next{ border-color:var(--accent); color:var(--accent); animation:incNudge 1.6s var(--ease) infinite; }
.incident__btn.is-active{ color:var(--amber); border-color:var(--amber); }
.incident__btn.is-done{ color:var(--green); border-color:rgba(94,230,192,.4); opacity:1; }
.incident__btn.is-done::before{ content:"✓ "; }
.incident__btn--reset{ margin-left:auto; color:var(--text-3); }
@keyframes incNudge{ 0%,100%{ box-shadow:0 0 0 3px rgba(var(--accent-rgb),.12); } 50%{ box-shadow:0 0 0 5px rgba(var(--accent-rgb),.04); } }
.incident__result{ padding:.8rem 1rem; border-top:1px solid var(--line); font-size:.78rem; color:var(--text-2); }
.incident__result b{ color:var(--green); }

/* =====================  ACCESSIBILITY — focus ring · touch targets · reduced motion  ===================== */
/* visible keyboard focus everywhere (mouse focus stays clean via :focus-visible); placed late on purpose
   so it wins over the inputs' outline:none on keyboard focus */
:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:4px; }
.palette__input:focus-visible,.terminal__input:focus-visible,.commit__body input:focus-visible,.commit__body textarea:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
/* primary controls meet a comfortable tap target on small/touch screens */
@media (max-width:760px){
  .kbtn,.motion-toggle,.term-chips button,.incident__btn{ min-height:44px; display:inline-flex; align-items:center; justify-content:center; }
}
/* =====================  DAG NODE HOVER PREVIEW  ===================== */
.dagpop{ position:absolute; z-index:30; left:0; top:0; transform:translate(-50%,calc(-100% - 14px)); width:min(15rem,72vw); padding:.7rem .85rem; border:1px solid var(--line-2); border-radius:10px; background:var(--bg-3); box-shadow:0 18px 44px rgba(0,0,0,.5); opacity:0; pointer-events:none; transition:opacity .16s var(--ease), transform .16s var(--ease); display:flex; flex-direction:column; gap:.22rem; }
.dagpop.show{ opacity:1; pointer-events:auto; transform:translate(-50%,calc(-100% - 20px)); }
.dagpop::after{ content:""; position:absolute; left:50%; bottom:-6px; width:10px; height:10px; transform:translateX(-50%) rotate(45deg); background:var(--bg-3); border-right:1px solid var(--line-2); border-bottom:1px solid var(--line-2); }
.dagpop__role{ font-family:var(--sans); font-weight:600; font-size:.82rem; color:var(--text); letter-spacing:-.01em; }
.dagpop__org{ font-size:.68rem; color:var(--accent); }
.dagpop__art{ font-size:.66rem; color:var(--text-3); line-height:1.5; margin-top:.15rem; }
.dagpop__st{ font-size:.64rem; color:var(--green); letter-spacing:.04em; margin-top:.1rem; }
.dagpop__logos{ display:flex; gap:.45rem; margin-top:.4rem; }
.dagpop__logos i{ width:15px; height:15px; -webkit-mask-size:contain; mask-size:contain; background:var(--text-3);
  opacity:0; transform:translateY(5px) scale(.8); transition:opacity .3s var(--ease), transform .3s var(--ease), background .3s; }
.dagpop.show .dagpop__logos i{ opacity:1; transform:none; background:var(--lb,var(--text-2)); }
.dagpop.show .dagpop__logos i:nth-child(2){ transition-delay:.05s }
.dagpop.show .dagpop__logos i:nth-child(3){ transition-delay:.10s }
.dagpop.show .dagpop__logos i:nth-child(4){ transition-delay:.15s }
.dagpop.show .dagpop__logos i:nth-child(5){ transition-delay:.20s }

/* =====================  STAGE-CARD TOOL CHIPS (brand logos)  ===================== */
.stage__stack{ display:flex; flex-wrap:wrap; gap:.5rem; margin-top:.85rem; }
.slogo{ display:inline-flex; align-items:center; gap:.42rem; padding:.32rem .62rem .32rem .52rem; border:1px solid var(--line); border-radius:999px; background:var(--bg-3);
  transition:border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease); }
.slogo__ico{ width:15px; height:15px; -webkit-mask-size:contain; mask-size:contain; background:var(--brand);
  transition:transform .3s var(--ease), filter .3s var(--ease); }
.slogo__nm{ font-family:var(--mono); font-size:.7rem; color:var(--text-2); letter-spacing:.01em; }
.slogo:hover{ border-color:color-mix(in srgb, var(--brand) 55%, var(--line)); background:rgba(255,255,255,.045); transform:translateY(-2px); }
.slogo:hover .slogo__ico{ transform:scale(1.14); filter:drop-shadow(0 0 6px var(--brand)); }
.slogo:hover .slogo__nm{ color:var(--text); }
.stage__stack.lit .slogo{ animation:slogoPop .55s var(--ease) both; }
.stage__stack.lit .slogo:nth-child(2){ animation-delay:.06s }
.stage__stack.lit .slogo:nth-child(3){ animation-delay:.12s }
.stage__stack.lit .slogo:nth-child(4){ animation-delay:.18s }
.stage__stack.lit .slogo:nth-child(5){ animation-delay:.24s }
@keyframes slogoPop{ 0%{ opacity:0; transform:translateY(10px) scale(.96) } 60%{ transform:translateY(-1px) scale(1.02) } 100%{ opacity:1; transform:none } }
.no-motion .stage__stack.lit .slogo{ animation:none; }

/* =====================  PRINT — clean single-doc résumé (Ctrl/⌘+P)  ===================== */
@media print{
  @page{ margin:1.4cm; }
  .codefield,.cursor,.buildbar,.palette,.sheet,.nav,.hero__scroll,.term-chips,#bootSeq,
  .hero__cta,.motion-toggle,.kbtn,.status,.dag,.terminal__bar,.terminal__line,.hero__grid,
  .obs__grid .tile__spark,.tile__gauge,.contact__arrow{ display:none!important; }
  html,body{ background:#fff!important; }
  *,*::before,*::after{ color:#111!important; text-shadow:none!important; box-shadow:none!important;
    background:transparent!important; -webkit-text-fill-color:#111!important; }
  body::after{ display:none!important; }
  main,.foot{ z-index:auto; }
  section{ padding:.6rem 0!important; break-inside:avoid; min-height:0!important; }
  .hero{ min-height:0!important; padding-top:0!important; }
  .hero__title{ font-size:2.4rem!important; line-height:1.05!important; }
  .hero__lede{ font-size:1rem!important; max-width:none!important; }
  .sec__title{ font-size:1.3rem!important; }
  .stage{ grid-template-columns:1fr!important; }
  .stage__card,.terminal,.obs__wrap,.tile,.about__facts li{ border-color:#ccc!important; break-inside:avoid; }
  .terminal__scroll{ height:auto!important; overflow:visible!important; }
  a[href^="http"]::after,a[href^="mailto"]::after,a[href^="tel"]::after{ content:" (" attr(href) ")"; font-size:.72em; color:#555!important; }
}

/* =========================================================================
   HERO TERMINAL — the working shell, its ASCII name banner, the pinned dock
   and the expand-overlay. (styled via classes on the terminal itself, never
   `.hero …` descendants — the node is re-parented into the overlay on expand.)
   ========================================================================= */
.hero__term{ display:grid; grid-template-columns:minmax(0,1.62fr) minmax(248px,.96fr); gap:clamp(1.1rem,2.6vw,2.2rem);
  align-items:start; margin-top:clamp(1.4rem,3.4vw,2.4rem); }
.hero__termslot{ min-width:0; }
.heroterm{ max-width:none; width:100%; margin:0; }
/* fit-to-viewport: one bounded flex column so the docked terminal never spills past the fold —
   chrome rows stay fixed, the live scroll absorbs whatever height is left, and it reflows on
   resize/zoom for free (svh + flex). The banner shrinks (below) rather than getting clipped. */
/* applies at ALL widths so the docked terminal never clips on any display size; #heroTermSlot scope =
   docked only (the expanded view is re-parented into .termoverlay, which sizes itself). The
   #heroTermSlot specificity also out-ranks the mobile `min(30vh,230px)` scroll rule below. */
#heroTermSlot .heroterm{ display:flex; flex-direction:column; max-height:min(680px, calc(100svh - 11rem)); }
#heroTermSlot .terminal__bar,
#heroTermSlot .term-chips,
#heroTermSlot .heroterm__banner{ flex:0 0 auto; }
#heroTermSlot .terminal__scroll{ flex:1 1 auto; min-height:0; height:auto; }

/* the name, figlet-rendered, gradient-filled amber→mint (running→passed) with a one-shot compile sweep */
.terminal__body .row.is-banner{ overflow-x:auto; overflow-y:hidden; margin:0 0 .35em; padding-bottom:3px; scrollbar-width:none; }
.terminal__body .row.is-banner::-webkit-scrollbar{ height:0; }
.term-banner{ margin:0; font-family:var(--term); font-size:clamp(5px,min(1.5vw,1.4vh),10.5px); line-height:1.04; letter-spacing:0; white-space:pre;
  background:linear-gradient(112deg,var(--amber) 8%, var(--amber-soft) 34%, var(--green) 92%); background-size:230% 100%;
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; color:transparent;
  filter:drop-shadow(0 0 13px rgba(var(--accent-rgb),.16)); animation:bannerSweep 2.6s var(--ease-out) .15s 1 both; }
@keyframes bannerSweep{ from{ background-position:118% 0; filter:drop-shadow(0 0 4px rgba(var(--accent-rgb),.05)); }
  to{ background-position:0 0; filter:drop-shadow(0 0 13px rgba(var(--accent-rgb),.16)); } }
/* cycling banner: continuously DRIFTING multi-colour gradient ("moving colours") */
.term-banner--flow{ background-size:300% 100%; animation:bannerFlow 7s linear infinite; }
@keyframes bannerFlow{ from{ background-position:0% 50%; } to{ background-position:300% 50%; } }

/* =====================  HEADLINE "COMPILE" REVEAL + SCROLL-THROUGHPUT REACTIVITY  ===================== */
.sec__title .cw{ display:inline-block; }                    /* keep words whole so they wrap as a unit */
.sec__title .cc{ display:inline-block; will-change:transform; }   /* per-char box so transform applies */
.sec__title.is-compiling{ font-variation-settings:'wght' var(--wght,700); }
/* the running monitor node glows hotter + the cycling banner sweep intensifies + quickens with scroll velocity */
.dnode.run .dnode__pt{ box-shadow:0 0 0 calc(5px + var(--throughput,0) * 7px) rgba(var(--accent-rgb), calc(.16 + var(--throughput,0) * .5)); }
.term-banner--flow{ animation-duration:calc(7s - var(--throughput,0) * 4s); filter:drop-shadow(0 0 calc(13px + var(--throughput,0) * 16px) rgba(var(--accent-rgb), calc(.16 + var(--throughput,0) * .42))); }

/* =====================  DEPLOY-FLOW CONNECTORS ( -----> vertical + horizontal )  ===================== */
/* vertical rail threading the sections — the pipeline flows down the page */
.flow-rail{ display:flex; flex-direction:column; align-items:center; gap:7px; max-width:var(--maxw); margin:0 auto; padding:0 var(--pad); color:var(--text-3); pointer-events:none; }
.flow-rail__line{ width:1px; height:clamp(22px,4.5vh,48px); background:linear-gradient(var(--line-2), rgba(var(--accent-rgb),.4)); }
.flow-rail__tip{ font-family:var(--term); font-size:11px; letter-spacing:.16em; text-transform:lowercase; display:flex; align-items:center; gap:.6ch; color:var(--text-3); }
.flow-rail__tip b{ color:var(--accent); font-weight:400; }
/* a glowing deploy "packet" travels down each rail — the pipeline literally flows through */
.flow-rail{ position:relative; }
.flow-rail::after{ content:""; position:absolute; left:50%; top:2%; width:4px; height:4px; margin-left:-2px; border-radius:50%;
  background:var(--accent); box-shadow:0 0 9px 1px rgba(var(--accent-rgb),.8); animation:railPacket 3s var(--ease) infinite; }
@keyframes railPacket{ 0%{ top:2%; opacity:0; } 14%{ opacity:1; } 86%{ opacity:1; } 100%{ top:94%; opacity:0; } }
.no-motion .flow-rail::after{ animation:none; opacity:0; }
/* horizontal arrows inside the shell */
.terminal__body .flow{ color:var(--text-3); letter-spacing:.02em; }
.terminal__body .flow .on{ color:var(--green); } .terminal__body .flow .nx{ color:var(--accent); } .terminal__body .flow .ar{ color:var(--text-3); }

/* embedded per-section shells — a real, contextual terminal in each major section */
.sec-shell{ max-width:960px; margin:clamp(2.6rem,6vw,4.6rem) auto 0; }
.sec-shell__label{ margin:0 0 .8rem; font-size:12px; color:var(--text-3); letter-spacing:.01em; }
.terminal--sec .terminal__scroll{ height:min(40vh,320px); }
/* fun-but-pro rotating caption + blinking block cursor under the banner */
.term-cap{ margin:.5rem 0 .1rem; font-size:clamp(10px,1.1vw,12.5px); letter-spacing:.02em; line-height:1.2;
  opacity:.92; transition:opacity .5s var(--ease-out); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.term-cap__cur{ display:inline-block; font-style:normal; transform:translateY(.5px); animation:capBlink 1.05s steps(1) infinite; }
@keyframes capBlink{ 50%{ opacity:0; } }

/* minimise control — only meaningful (and only shown) when the shell is floating */
.heroterm__min{ display:none; align-items:center; gap:.34rem; margin-left:auto; font-family:var(--term); font-size:11px;
  color:var(--text-3); border:1px solid var(--line-2); border-radius:7px; padding:.24rem .56rem; transition:color .2s,border-color .2s,background .2s; }
.heroterm__min:hover{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); background:rgba(var(--accent-rgb),.06); }
.heroterm.is-floating .heroterm__min{ display:none; }   /* replaced by the JS-built expand/close controls (.heroterm__ctl) */
.heroterm.is-floating .terminal__hint{ display:none; }

/* the hero right rail */
.hero__side{ display:flex; flex-direction:column; gap:1.15rem; padding-top:.15rem; min-width:0; }
.hero__side .hero__lede{ margin:0; max-width:none; font-size:clamp(1rem,1.45vw,1.22rem); line-height:1.5; color:var(--text-2); }
.hero__side .hero__lede .hl{ color:var(--accent-soft); }
.hero__side .statuspage{ margin:0; max-width:none; }

/* ── pinned dock (top-right, below the nav cluster) ─────────────────────── */
.termdock{ position:fixed; top:4.55rem; right:clamp(1rem,5vw,2.2rem); z-index:7600; display:inline-flex; align-items:center; gap:.62rem;
  padding:.5rem .8rem; border:1px solid var(--line-2); border-radius:11px; background:rgba(18,17,24,.82);
  -webkit-backdrop-filter:blur(13px); backdrop-filter:blur(13px); box-shadow:0 16px 42px rgba(0,0,0,.5);
  font-family:var(--term); font-size:.74rem; color:var(--text-2); letter-spacing:-.01em; cursor:pointer;
  opacity:0; transform:translateY(-10px) scale(.96); pointer-events:none;
  transition:opacity .42s var(--ease), transform .42s var(--ease), border-color .25s, color .25s; }
.termdock.is-shown{ opacity:1; transform:none; pointer-events:auto; }
.termdock:hover,.termdock:focus-visible{ color:var(--text); border-color:rgba(var(--accent-rgb),.5); }
.termdock__dots{ display:inline-flex; gap:3.5px; }
.termdock__dots i{ width:7px; height:7px; border-radius:50%; background:var(--line-2); transition:background .25s; }
.termdock__dots i:nth-child(1){ background:rgba(248,85,63,.55); }
.termdock__dots i:nth-child(2){ background:rgba(245,182,66,.55); }
.termdock__dots i:nth-child(3){ background:rgba(94,230,192,.55); }
.termdock:hover .termdock__dots i:nth-child(1){ background:var(--red); }
.termdock:hover .termdock__dots i:nth-child(2){ background:var(--amber); }
.termdock:hover .termdock__dots i:nth-child(3){ background:var(--green); }
.termdock__txt{ white-space:nowrap; }
.termdock__caret{ color:var(--accent); font-size:.95em; transition:transform .3s var(--ease); }
.termdock:hover .termdock__caret{ transform:translate(1px,-1px); }

/* ── backdrop + expand overlay ──────────────────────────────────────────── */
.termbackdrop{ position:fixed; inset:0; z-index:9100; background:rgba(8,7,12,.6);
  -webkit-backdrop-filter:blur(6px) saturate(.85); backdrop-filter:blur(6px) saturate(.85);
  opacity:0; transition:opacity .4s var(--ease); }
.termbackdrop.is-shown{ opacity:1; }
.termoverlay{ position:fixed; inset:0; z-index:9200; display:grid; align-items:start; justify-items:center;
  padding:clamp(1rem,6vh,4.5rem) clamp(1rem,4vw,2rem) clamp(1rem,4vh,2rem); pointer-events:none; }
.termoverlay .heroterm{ pointer-events:auto; width:min(940px,94vw); max-width:none; margin:0;
  display:flex; flex-direction:column; max-height:100%; min-height:0;   /* fit inside the overlay's padding at ANY zoom — internal scroll handles overflow */
  opacity:0; transform:translateY(-24px) scale(.965); transform-origin:top right; will-change:transform,opacity;
  transition:opacity .4s var(--ease-out), transform .48s var(--ease-out), width .35s var(--ease-out), max-height .35s var(--ease-out); box-shadow:0 50px 140px rgba(0,0,0,.62); }
.termoverlay.is-open .heroterm{ opacity:1; transform:none; }

/* ── MINI: a small, NON-modal docked window (dock opens this first; page stays usable) ── */
.termoverlay.is-mini{ pointer-events:none; padding:0; }   /* container passes clicks through to the page */
.termoverlay.is-mini .heroterm{
  position:fixed; right:clamp(.8rem,2vw,1.4rem); bottom:clamp(.8rem,2vw,1.4rem); top:auto; left:auto;
  width:min(300px,84vw); max-height:min(38vh,330px); max-height:min(38dvh,330px);
  transform-origin:bottom right; box-shadow:0 24px 70px rgba(0,0,0,.55); }
.termoverlay.is-mini .heroterm__banner{ display:none; }            /* the big name banner is for the expanded view */
@media (max-width:760px){
  /* compact bottom-right window (was a full-width 64dvh bottom sheet — too large) */
  .termoverlay.is-mini .heroterm{ left:auto; right:.6rem; bottom:.6rem; width:min(280px,80vw); max-height:min(42dvh,300px); }
}
/* terminal window controls (created in JS): expand ⤢ + close × in the bar */
.heroterm__ctl{ display:none; align-items:center; gap:.34rem; margin-left:auto; font-family:var(--term); font-size:11px;
  color:var(--text-2); background:none; border:1px solid var(--line); border-radius:7px; padding:.28rem .5rem; cursor:pointer; }
.heroterm__ctl:hover,.heroterm__ctl:focus-visible{ color:var(--accent); border-color:rgba(var(--accent-rgb),.45); background:rgba(var(--accent-rgb),.06); }
.heroterm.is-floating .heroterm__ctl{ display:inline-flex; }
.heroterm.is-floating .heroterm__ctl + .heroterm__ctl{ margin-left:.4rem; }
/* floating terminal flexes to the viewport: bar/chips/banner keep their size, the scroll body shrinks */
.heroterm.is-floating .terminal__bar,
.heroterm.is-floating .term-chips,
.heroterm.is-floating .heroterm__banner{ flex:0 0 auto; }
.heroterm.is-floating .terminal__scroll{ height:auto; flex:1 1 auto; min-height:64px; }
@media (max-height:430px){ .heroterm.is-floating .heroterm__banner{ display:none; } }
/* The input is the LAST child inside the scroll, so pin it to the bottom of the scroll viewport in
   EVERY hero state — it stays visible (above the keyboard / output) regardless of scroll, no JS race.
   Must be fully OPAQUE so scrolled-up output can't bleed through behind it. */
#heroTerm .terminal__line{ position:sticky; bottom:0; z-index:2; margin:0 calc(-1*clamp(15px,2.5vw,24px));
  padding:.55em clamp(15px,2.5vw,24px) calc(.55em + env(safe-area-inset-bottom));
  background:var(--card); border-top:1px solid var(--line); }
/* the scroll's own bottom padding would leave a strip BELOW the sticky bar where output bleeds through —
   move that breathing room onto the output body so the pinned bar reaches the very bottom edge. */
#heroTerm .terminal__scroll{ padding-bottom:0; }
#heroTerm .terminal__body{ padding-bottom:10px; }
/* "↳ type to take over" coach-mark is redundant (and overlaps) once the keyboard is up — you're typing */
html.kbd-term .coach{ display:none !important; }
/* the input + send button live in ONE constant-amber pill (always reads as "type here"); a single
   outline only — resting amber border, focus brightens that same border + a soft glow (no second ring). */
#heroTerm .terminal__field{ flex:1 1 auto; display:flex; align-items:center; gap:.4ch; min-width:0;
  border:1.5px solid rgba(var(--accent-rgb),.85); border-radius:10px; padding:.18em .25em .18em .7em;
  background:rgba(255,255,255,.015); transition:border-color .2s, box-shadow .2s; }
#heroTerm .terminal__field:focus-within{ border-color:var(--accent); box-shadow:0 0 14px rgba(var(--accent-rgb),.18); }
#heroTerm .terminal__input:focus-visible{ outline:none; }   /* the outline is on the field, not the bare input */
/* send button is light blue (a deliberate, distinct "send" accent against the amber field) */
.terminal__send{ flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; border:1px solid rgba(94,200,255,.45); border-radius:8px; background:none;
  color:#5ec8ff; cursor:pointer; opacity:.7; transition:color .15s, border-color .15s, background .15s, opacity .15s; }
.terminal__send:hover,.terminal__send:focus-visible{ color:#bfe7ff; border-color:#5ec8ff; opacity:1; }
/* fill + flash light-blue only while there's something to send (toggled by JS on real keystrokes, not the demo) */
.terminal__line.has-text .terminal__send{ opacity:1; color:#08121b; background:#5ec8ff; border-color:#5ec8ff;
  animation:sendPulse 1.15s var(--ease) infinite; }
@keyframes sendPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(94,200,255,.55); } 50%{ box-shadow:0 0 0 6px rgba(94,200,255,0); } }
@media (prefers-reduced-motion:reduce){ .terminal__line.has-text .terminal__send{ animation:none; } }
/* "more above" cue: once output is scrolled past its start, fade the top edge so it's clear there's more to scroll up to */
#heroTermScroll.more-up{ -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 26px); mask-image:linear-gradient(to bottom, transparent 0, #000 26px); }
body.term-frozen{ overflow:hidden; }

/* ── responsive ─────────────────────────────────────────────────────────── */
@media (max-width:880px){
  .hero__term{ grid-template-columns:1fr; gap:1.25rem; }
  .heroterm .terminal__scroll{ height:min(30vh,230px); }
  .termdock{ top:3.85rem; }
}
@media (max-width:760px){
  .termdock{ min-height:44px; }
  .termoverlay{ padding:1rem .7rem; align-items:stretch; }
  .heroterm.is-floating .terminal__scroll{ height:min(26vh,200px); }
}

/* pinned ASCII name banner — stays visible while the live tour scrolls below it */
.heroterm__banner{ padding:.95rem clamp(15px,2.5vw,24px) .8rem; border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,rgba(var(--accent-rgb),.045),transparent);
  overflow-x:auto; overflow-y:hidden; scrollbar-width:none; }
.heroterm__banner::-webkit-scrollbar{ height:0; }
/* pin the ASCII art to a constant line-box count: frames carry different leading/trailing blank
   lines, so without this the banner (and thus the whole hero) breathes ~1 line height as frames
   cycle — which shifted the page under scroll-anchoring and drifted the terminal-close position. */
.heroterm__banner .term-banner{ display:inline-block; min-height:15.2em; }

/* =========================================================================
   WHOAMI — the profile as a config file (machine version) + prose (human version)
   ========================================================================= */
.about__read{ display:flex; flex-direction:column; gap:1.05rem; justify-content:center; min-width:0; }
.about__kr{ color:var(--text-3); font-size:.72rem; letter-spacing:.02em; }
.about__read .about__big{ margin:0; }
.about__read .about__body{ margin:0; max-width:48ch; }
.about__statusline{ display:inline-flex; align-items:center; gap:.55rem; margin-top:.3rem; font-size:.8rem; color:var(--text-2); }

.profile{ border:1px solid var(--line-2); border-radius:var(--r-lg); background:var(--card); overflow:hidden;
  box-shadow:0 30px 80px rgba(0,0,0,.42); display:flex; flex-direction:column; }
.profile__bar{ display:flex; align-items:center; gap:8px; padding:11px 15px; border-bottom:1px solid var(--line); background:rgba(255,255,255,.02); }
.profile__path{ margin-left:8px; font-size:12px; color:var(--text-3); }
.profile__lang{ margin-left:auto; font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-3);
  border:1px solid var(--line-2); border-radius:5px; padding:.14rem .44rem; }
.profile__code{ padding:1.05rem 0 1.15rem; font-size:13px; line-height:1.95; color:var(--text); flex:1;
  display:flex; flex-direction:column; justify-content:center; }
.pln{ display:flex; gap:1rem; padding:0 clamp(1rem,2.4vw,1.5rem);
  opacity:0; transform:translateY(7px); transition:opacity .5s var(--ease-out), transform .5s var(--ease-out);
  transition-delay:calc(var(--i) * 45ms); }
.profile.is-in .pln{ opacity:1; transform:none; }
.pln .ln{ width:1.3rem; flex:none; text-align:right; color:var(--text-3); -webkit-user-select:none; user-select:none; }
.pln .lc{ white-space:pre-wrap; overflow-wrap:anywhere; min-width:0; }
.pln .k{ color:var(--accent); }
.pln .p{ color:var(--text-3); }
.pln .c{ color:var(--text-3); }
.pln .g{ color:var(--green); }
.pln--cursor .caret{ color:var(--accent); animation:caretBlink 1.15s steps(1) infinite; }
@keyframes caretBlink{ 50%{ opacity:0; } }
.no-motion .pln{ opacity:1; transform:none; }
@media (max-width:760px){ .about__read .about__body{ max-width:none; } }

/* =========================================================================
   CONTACT — the last deploy (tight headline, links + the commit form side by side)
   ========================================================================= */
.contact__top{ max-width:var(--maxw); margin:1.4rem auto 0; display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.04fr);
  gap:clamp(1.8rem,4vw,3.6rem); align-items:start; }
.contact__intro{ min-width:0; }
.contact__cmd{ font-size:.8rem; color:var(--text-2); margin-bottom:1rem; }
.contact__cmd .a{ color:var(--accent); } .contact__cmd .g{ color:var(--green); }
.contact .contact__lede{ margin:1.1rem 0 0; max-width:42ch; }
.contact__links{ margin:clamp(1.6rem,3vw,2.4rem) 0 0; max-width:none; border-top:1px solid var(--line); }
.contact .commit{ margin:0; max-width:none; }
@media (max-width:1000px){
  .contact__top{ grid-template-columns:1fr; gap:2rem; }
  .contact .contact__lede{ max-width:none; }
}

/* =====================  REVIEW FIXES (2026-06-17)  ===================== */
/* scannable hero pitch line — role · location · open-to (literal pitch, crawlable) */
.hero__pitch{ font-family:var(--mono); font-size:clamp(12px,1.25vw,13.5px); color:var(--text-2); letter-spacing:.02em; line-height:1.5; margin:.5rem 0 0; }

/* the floating terminal pill overlapped section headings on phones — dock it to the
   bottom-right on mobile so it stays usable (opens the mini terminal) without covering headings */
@media (max-width:760px){ .termdock{ top:auto!important; bottom:1rem; right:1rem; } }

/* honor Save-Data / data-saver: kill the GPU-heavy ambient layers and blur */
@media (prefers-reduced-data:reduce){
  .codefield{ display:none!important; }
  *,*::before,*::after{ backdrop-filter:none!important; -webkit-backdrop-filter:none!important; }
}

/* (removed: dead .bd-grid/.bd-card homepage-teaser styles — the Flux build uses #builds/.bd-slide/.bd-tab; no .bd-card markup exists) */

/* =====================  FLUX SECTIONS — RESPONSIVE / PRODUCTION-READY PASS (2026-06-18)  =====================
   The Flux sections (experience / builds / contact / status) were authored with inline 2-column
   grids that external media queries cannot reach. These rules use the elements' existing class/id
   hooks (plus a few added hooks: .ct-grid, .fx-strow, .fx-stval) with !important so they override the
   inline `grid-template-columns` on small screens. Author !important beats a normal inline declaration. */

/* --- Contact: collapse the 2-col (details | terminal) grid. It was crushing the left column to
       ~140px on phones, collapsing every contact value (email/phone/résumé) to width:0. --- */
@media (max-width:820px){
  /* minmax(0,1fr) lets the column shrink below the terminal form's intrinsic min-width */
  .ct-grid{ grid-template-columns:minmax(0,1fr) !important; gap:clamp(28px,6vw,42px) !important; }
  #ctForm input, #ctForm textarea{ width:100%; min-width:0; box-sizing:border-box; }
}
@media (max-width:460px){
  .ct-row{ gap:12px !important; }
  .ct-row > span:first-child{ width:76px !important; font-size:10px !important; }    /* shrink the label column */
  .ct-val{ font-size:15px !important; overflow-wrap:anywhere; }                       /* long email/url wraps instead of clipping */
}

/* --- Experience: stack each detail panel (number/role | bullets) on phones. --- */
@media (max-width:760px){
  .flux-panel{ grid-template-columns:1fr !important; gap:24px !important; }
  .flux-panel ul{ padding-top:0 !important; }
}
/* Timeline station labels are absolutely positioned at 10/30/50/70/90% with white-space:nowrap, so
   they collide into an unreadable strip on phones. Hide the labels (rings + numbers stay; the active
   company is named in the panel below). The buttons carry aria-labels so they stay accessible. */
@media (max-width:620px){
  .flux-lab{ display:none !important; }
}

/* --- Status: the JS-built rows use an inline 140px|1fr|auto grid that overflowed ~320px screens.
       Shrink the label + value columns so the 58-bar sparkline and value stay inside the viewport. --- */
@media (max-width:560px){
  /* minmax(0,1fr) + tighter sparkline so the 58-bar row (230px intrinsic min) collapses to fit */
  .fx-strow{ grid-template-columns:70px minmax(0,1fr) auto !important; gap:10px !important; }
  .fx-strow > span:first-child{ font-size:9.5px !important; line-height:1.25 !important; }
  .fx-stval{ min-width:0 !important; font-size:11.5px !important; }
  .fx-strow > div{ overflow:hidden; gap:1px !important; }        /* sparkline container: clip + tighten gaps */
  .fx-strow > div > span{ min-width:1px !important; }            /* let bars compress below 2px */
}

/* --- Tap targets: lift a couple of interactive controls to the 24px AA minimum. --- */
.ct-copy{ padding:8px 9px; margin:-6px -3px; border-radius:6px; }   /* "copy" hit area was 40x16 */
.bd-tab{ min-height:44px; }

/* --- Skip-to-content link (keyboard a11y): off-screen until focused. --- */
.skip-link{ position:fixed; top:10px; left:10px; z-index:10000; transform:translateY(-160%);
  background:var(--accent,#7c6cff); color:#fff; font-family:var(--mono,monospace); font-size:13px;
  padding:10px 16px; border-radius:8px; text-decoration:none; box-shadow:0 8px 24px rgba(0,0,0,.45);
  transition:transform .18s var(--ease-out, ease); }
.skip-link:focus{ transform:translateY(0); outline:2px solid #fff; outline-offset:2px; }

/* --- Tactile press feedback: a subtle scale on activation across the interactive surface. --- */
.btn:active, .term-chips button:active, .bd-tab:active, .flux-st:active, .ct-copy:active,
#bdPrev:active, #bdNext:active, .nav__links a:active, .kbtn:active{ transform:scale(.97); }
@media (hover:none){ /* keep the press feel snappy on touch */
  .btn, .term-chips button, .bd-tab, .flux-st{ transition:transform .12s var(--ease-out, ease); }
}

/* ═════════════════  PORTED LAB EFFECTS — additive, native, honest-degrade  ═════════════════
   #3 native scroll-state(stuck) · #5 CSS anchor-positioning tooltip + Popover API.
   Both zero-JS and @supports-gated: non-supporting engines fall back to a plain, usable state. */

/* ---- #3 · Builds "pipeline" strip flips building→deployed the moment it sticks (no scroll listener) ---- */
.bd-stuck{ position:sticky; top:clamp(54px,8vh,74px); z-index:6; width:max-content; max-width:100%;
  margin:0 0 clamp(18px,3vw,30px); container-type:scroll-state; }
.bd-stuck__in{ display:inline-flex; align-items:center; gap:.7ch; padding:.46rem .85rem; border-radius:999px;
  font-family:var(--term,'Geist Mono',monospace); font-size:12px; letter-spacing:.03em; color:var(--text-3,#9a9aae);
  background:rgba(12,11,16,.66); -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border:1px solid var(--line,rgba(230,230,255,.1));
  transition:color .35s var(--ease-out,ease), border-color .35s var(--ease-out,ease), background .35s var(--ease-out,ease); }
.bd-stuck__dot{ width:8px; height:8px; border-radius:50%; background:var(--amber,#f5b642); box-shadow:0 0 10px var(--amber,#f5b642);
  transition:background .35s var(--ease-out,ease), box-shadow .35s var(--ease-out,ease); }
.bd-stuck__state{ color:var(--text-3,#9a9aae); transition:color .35s var(--ease-out,ease); }
.bd-stuck__state::after{ content:"building"; }
@supports (container-type:scroll-state){
  @container scroll-state(stuck: top){
    .bd-stuck__in{ color:var(--green,#5ee6c0); border-color:rgba(94,230,192,.42); background:rgba(9,18,16,.74); }
    .bd-stuck__dot{ background:var(--green,#5ee6c0); box-shadow:0 0 12px var(--green,#5ee6c0); }
    .bd-stuck__state{ color:var(--green,#5ee6c0); }
    .bd-stuck__state::after{ content:"deployed ✓"; }
  }
}

/* ---- #5 · Status info: native top-layer Popover tethered with CSS anchor positioning + a hover tooltip ---- */
.fx-infowrap{ position:relative; display:inline-flex; align-items:center; }
.fx-info{ display:inline-grid; place-items:center; width:20px; height:20px; border-radius:50%; cursor:pointer;
  font-family:var(--term,'Geist Mono',monospace); font-size:12px; font-style:italic; line-height:1; color:var(--text-3,#9a9aae);
  background:rgba(124,108,255,.12); border:1px solid rgba(124,108,255,.34); anchor-name:--fxstatusinfo;
  transition:color .2s, border-color .2s, background .2s; }
.fx-info:hover,.fx-info:focus-visible{ color:#cdc6ff; border-color:rgba(124,108,255,.7); background:rgba(124,108,255,.2); outline:none; }
/* anchored hover/focus tooltip (CSS anchor positioning; falls back to inline-flow where unsupported) */
.fx-tip{ font-family:var(--term,'Geist Mono',monospace); font-size:10.5px; color:#06060a; background:#7c6cff;
  padding:3px 7px; border-radius:5px; white-space:nowrap; opacity:0; pointer-events:none; transition:opacity .15s; }
@supports (anchor-name:--a){
  .fx-tip{ position:absolute; position-anchor:--fxstatusinfo; position-area:block-start; margin-bottom:6px;
    justify-self:anchor-center; position-try-fallbacks:flip-block; }
}
.fx-info:hover + .fx-tip, .fx-info:focus-visible + .fx-tip{ opacity:1; }
.fx-pop{ margin:0; border:1px solid rgba(124,108,255,.34); border-radius:10px; padding:14px 16px; max-width:300px;
  background:#12111a; color:#c8c8d4; font-family:var(--sans,'Geist',system-ui,sans-serif); font-size:13px; line-height:1.5;
  box-shadow:0 24px 60px -24px rgba(0,0,0,.8); }
.fx-pop strong{ color:#f2f2f7; } .fx-pop code{ font-family:var(--term,monospace); color:var(--green,#5ee6c0); font-size:12px; }
.fx-pop::backdrop{ background:rgba(6,6,10,.28); }
@supports (anchor-name:--a){
  .fx-pop{ position-anchor:--fxstatusinfo; inset:auto; position-area:block-end span-inline-end; margin-top:8px;
    position-try-fallbacks:flip-block, flip-inline; }
}
@keyframes fxPopIn{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:none; } }
.fx-pop:popover-open{ animation:fxPopIn .22s var(--ease-out,ease); }

/* ---- #6 · CI "security scan" beam panel (raw WebGL upgrades the static gradient fallback below) ---- */
.scanpanel{ position:relative; height:clamp(96px,12vw,150px); margin:0 0 18px; border-radius:10px; overflow:hidden;
  border:1px solid var(--line,rgba(230,230,255,.1));
  background:linear-gradient(100deg, rgba(124,108,255,.05), rgba(94,230,192,.05)); }
.scanpanel canvas{ position:absolute; inset:0; width:100%; height:100%; display:block; }
.scanpanel__lbl{ position:absolute; left:14px; bottom:11px; z-index:2; display:inline-flex; align-items:center; gap:.6ch;
  font-size:11px; letter-spacing:.04em; color:var(--text-3,#9a9aae); pointer-events:none; }
.scanpanel__lbl i{ width:7px; height:7px; border-radius:50%; background:var(--green,#5ee6c0); box-shadow:0 0 8px var(--green,#5ee6c0);
  animation:fxPulse 2.5s ease-out infinite; }

/* =========================================================================
   TOUCH TAP-TARGET HARDENING — coarse pointers only (zero desktop/mouse impact).
   Placed last so it wins the cascade over base component rules of equal specificity.
   ========================================================================= */
@media (pointer:coarse){
  .terminal__line{ min-height:40px; }                                  /* the input row: easy tap-to-focus */
  .terminal__input{ min-height:44px; font-size:16px; }                 /* 44px touch + 16px stops iOS Safari zoom-on-focus */
  .terminal__send{ width:44px; height:44px; }                          /* full touch target on phones */
  #tmLiveOpen,#tmLiveClose{ min-height:44px; display:inline-flex; align-items:center; }  /* live-app dock controls: real touch size */
  #heroTerm .terminal__bar .pre__dot{ position:relative; }             /* dots double as a "jump to builds" button — give them a real hit area */
  #heroTerm .terminal__bar .pre__dot::after{ content:''; position:absolute; inset:-16px -7px; }
  /* the input is bare — the .terminal__field pill owns the single amber outline (no second border) */
  #heroTermInput{ padding:6px 2px; }
  /* keyboard mode (toggled by JS from visualViewport, only while a soft keyboard is open):
     pin the hero terminal into the space above the keyboard so the input is reachable
     without the page auto-scrolling. */
  html.kbd-term, html.kbd-term body{ overflow:hidden !important; }
  html.kbd-term #heroTerm{ position:fixed !important; left:0; right:0; top:0; bottom:auto; z-index:9400; margin:0; max-width:none;
    border-radius:0; display:flex; flex-direction:column;
    transform:none !important; will-change:auto !important; }   /* force over the overlay's relative+will-change, which offsets/contains a fixed element in WebKit */
  html.kbd-term #heroTerm .heroterm__banner,
  html.kbd-term #heroTerm #heroTermChips{ display:none; }
  html.kbd-term #heroTerm .terminal__scroll{ flex:1 1 auto; height:auto !important; min-height:0; }
  .fx-info{ width:30px; height:30px; }                                 /* was 20x20 → meets tap-target min */
  .nav__brand{ min-height:42px; min-width:42px; justify-content:center; }
  .ct-copy{ min-height:40px; display:inline-flex; align-items:center; justify-content:center; }
  .heroterm__ctl{ min-height:36px; }
  .heroterm__ctl--close{ min-width:36px; justify-content:center; }
  .pj-case{ display:inline-flex; align-items:center; min-height:36px; }
}

/* MOBILE PERF: backdrop-blur is the single most expensive GPU op on phones — the V8u deck alone runs
   16 blurred glass cards, which craters the framerate. Drop it on touch devices; panels keep their
   semi-opaque backgrounds (just unfrosted). Measured ~3x FPS recovery on the V8u section. */
@media (pointer:coarse){
  *{ backdrop-filter:none!important; -webkit-backdrop-filter:none!important; }
}

/* MOBILE PERF: the moving flashlight. Desktop drives --mx/--my, which repaints the full-screen
   #codeGlow <pre> mask + the .codefield radial bg every frame — measured as the dominant cost behind
   the floating V8u cards (8fps → 42fps when paused). On touch we instead move a composited blob
   (#cfGlow via translate3d), so kill the two per-frame repaint layers and enable the blob. */
@media (pointer:coarse){
  .codefield{ background:none; }            /* the --mx/--my radial bg no longer animates here */
  .codefield__glow{ display:none; }         /* its moving 240px mask was the full-screen repaint */
  .codefield__cfglow{ display:block; }      /* the transform-composited replacement (GPU, no repaint) */
  /* Give the flashlight something to light: a faint STATIC code field instead of a black void.
     .codefield is position:fixed, so this layer is painted ONCE — zero per-frame cost — and the
     composited blob reads as a warm light gliding over real code (and isn't a dead smudge when paused). */
  .codefield__base{ opacity:.05; }
}

/* MOBILE SMOOTHNESS: the thesis words animate transform (not filter) on touch — filter is forced to
   `none` there, so `will-change:transform,filter` was reserving a filter compositing layer for nothing. */
@media (pointer:coarse){
  .thesis__line .tw{ will-change:transform; }
}

/* ░░ BOOT SEQUENCE ░░ */
#bootSeq{position:fixed;inset:0;z-index:9999;background:#050507;overflow:hidden;
  transition:opacity .45s ease;will-change:opacity;font-family:'Geist Mono',ui-monospace,monospace}
#bootSeq.is-gone{opacity:0;pointer-events:none}
#bsGrid{position:absolute;inset:0;z-index:2;display:block}
#bsShock{position:absolute;left:50%;top:46%;width:14px;height:14px;border-radius:30%;
  transform:translate(-50%,-50%) scale(0);opacity:0;z-index:3;
  border:2px solid rgba(94,230,192,.9);
  box-shadow:0 0 30px rgba(94,230,192,.55),inset 0 0 22px rgba(124,108,255,.5)}
#bsCoreR,#bsCoreB{position:absolute;left:50%;top:46%;width:130px;height:130px;border-radius:50%;
  transform:translate(-50%,-50%);z-index:3;mix-blend-mode:screen;opacity:0}
#bsCoreR{background:radial-gradient(circle,rgba(248,85,63,.25),transparent 62%)}
#bsCoreB{background:radial-gradient(circle,rgba(63,224,208,.3),transparent 62%)}
#bsCore{position:absolute;left:50%;top:46%;width:120px;height:120px;border-radius:26%;
  transform:translate(-50%,-50%) scale(.2);opacity:0;z-index:3;
  background:radial-gradient(circle,#eafff9 0%,#5ee6c0 22%,#7c6cff 48%,transparent 72%);
  box-shadow:0 0 60px 12px rgba(94,230,192,.5)}
#bsCore span{position:absolute;inset:0;display:grid;place-items:center;
  color:rgba(4,16,12,.78);font-size:42px;font-weight:700;line-height:1}
#bsVig{position:absolute;inset:0;z-index:4;pointer-events:none;
  background:radial-gradient(circle at 50% 46%,transparent 14%,rgba(0,0,0,.5) 62%,rgba(0,0,0,.92) 100%)}
#bsGrain{position:absolute;inset:0;z-index:5;pointer-events:none;opacity:.05;mix-blend-mode:overlay;
  background-image:radial-gradient(rgba(255,255,255,.6) .5px,transparent .5px);background-size:3px 3px}
#bsSkip{position:absolute;right:18px;bottom:16px;z-index:6;background:none;border:none;cursor:pointer;
  color:#5b5b6e;font:inherit;font-size:11px;letter-spacing:.04em}
#bsSkip:hover{color:#9a9aae}
#heroTerm{transform-origin:center center}
