/* ==========================================================
   Luke Anderson · Portfolio
   Editorial typography. Internet-native energy. Skill-first.
   No frameworks. ~25kb minified.
   ========================================================== */

/* ---------- Reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body,h1,h2,h3,h4,p,ul,ol,figure,blockquote,dl,dd,pre{margin:0}
ul,ol{padding:0;list-style:none}
img,svg{display:block;max-width:100%}
button,input,textarea,select{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer;padding:0}
a{color:inherit;text-decoration:none}
kbd{
  font-family:var(--mono);font-size:.78em;
  padding:1px 6px;border-radius:5px;
  border:1px solid var(--rule-2);
  background:var(--surface);color:var(--text);
  letter-spacing:.04em;
}

/* ---------- Tokens ---------- */
:root{
  --bg:        #0a0908;
  --bg-2:      #100e0c;
  --surface:   #161311;
  --surface-2: #1f1b18;
  --rule:      rgba(245,241,234,0.08);
  --rule-2:    rgba(245,241,234,0.18);
  --text:      #f3eee5;
  --text-2:    #c9c2b6;
  --text-3:    #8a857d;

  --terra:   #f97316;
  --pink:    #ec4899;
  --blue:    #3b82f6;
  --lime:    #84cc16;
  --amber:   #f59e0b;
  --violet:  #a78bfa;
  --accent:  var(--terra);

  --max:       1180px;
  --gutter:    clamp(20px, 4vw, 48px);
  --pad-y:     clamp(80px, 12vw, 140px);

  --serif:     'Instrument Serif', 'Iowan Old Style', 'Times New Roman', Georgia, serif;
  --sans:      ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --mono:      'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --ease:      cubic-bezier(.22,.61,.36,1);
  --ease-out:  cubic-bezier(.16,1,.3,1);
  --t-fast:    .25s var(--ease);
  --t-med:     .45s var(--ease);
  --t-slow:    .8s var(--ease-out);
}

:root[data-theme="light"]{
  --bg:        #f7f4ee;
  --bg-2:      #f0ebe1;
  --surface:   #ebe5d8;
  --surface-2: #e3dccd;
  --rule:      rgba(20,17,14,0.10);
  --rule-2:    rgba(20,17,14,0.20);
  --text:      #14110e;
  --text-2:    #4a443d;
  --text-3:    #756e64;
  --terra:   #c2410c;
  --pink:    #be185d;
  --blue:    #1d4ed8;
  --lime:    #4d7c0f;
  --amber:   #b45309;
  --violet:  #6d28d9;
}

/* ---------- Base ---------- */
html,body{background:var(--bg);color:var(--text)}
body{
  font-family:var(--sans);
  font-size:16px;line-height:1.6;
  font-feature-settings:'ss01','cv11','kern';
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  min-height:100svh;
  transition:background .35s var(--ease), color .35s var(--ease);
}
::selection{background:var(--accent);color:var(--bg)}

/* Subtle warm grain */
body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.16;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .35 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode:overlay;
}
:root[data-theme="light"] body::before{opacity:.08;mix-blend-mode:multiply}

.skip-link{
  position:fixed;top:-40px;left:12px;padding:8px 12px;border-radius:6px;
  background:var(--text);color:var(--bg);z-index:200;
}
.skip-link:focus{top:12px}

/* ---------- Typography ---------- */
.kicker{
  display:inline-flex;align-items:baseline;gap:10px;
  font-family:var(--mono);font-size:11px;font-weight:500;
  color:var(--text-2);text-transform:uppercase;letter-spacing:.16em;
}
.k-num{
  color:var(--accent);font-weight:500;
}
.eyebrow{
  display:inline-flex;align-items:center;flex-wrap:wrap;gap:14px;
  font-family:var(--mono);font-size:11px;
  color:var(--text-3);text-transform:uppercase;letter-spacing:.16em;
  margin-bottom:34px;
}
.eyebrow .ey-num{color:var(--accent)}
.eyebrow .sep{
  width:18px;height:1px;background:var(--rule-2);
}

.display{
  font-family:var(--serif);font-weight:400;
  letter-spacing:-.025em;line-height:.94;color:var(--text);
}
.display em{font-style:italic;color:var(--accent)}

/* ---------- NAV ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:1000;
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  padding:14px var(--gutter);gap:18px;
  transition:background .35s var(--ease), border-color .35s var(--ease), padding .35s var(--ease);
  /* IMPORTANT: z-index:1000 puts the nav above scene-pin's sticky stacking
     context, so the search button stays clickable while a scene is pinned. */
}

/* Entrance: a subtle hairline rule sweeps across the top first,
   then each cluster of nav items drops down with a staggered delay.
   Runs only once on page load. */
.nav::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg, transparent, var(--accent), transparent);
  transform-origin:center;
  animation: nav-rule-in 1.1s cubic-bezier(.7,0,.2,1) both;
}
@keyframes nav-rule-in{
  from{transform:scaleX(0);opacity:0}
  60%{opacity:.7}
  to{transform:scaleX(1);opacity:.35}
}

.nav-brand,
.palette-trigger,
.nav-end{
  animation: nav-item-drop .8s cubic-bezier(.22,.8,.25,1) both;
}
.nav-brand     { animation-delay: .25s; }
.palette-trigger{ animation-delay: .40s; }
.nav-end       { animation-delay: .55s; }
@keyframes nav-item-drop{
  from{opacity:0;transform:translateY(-18px);filter:blur(2px)}
  to{opacity:1;transform:translateY(0);filter:blur(0)}
}

/* Compact when scrolled — slightly tighter padding, gives the bar a "focus" feel */
.nav.scrolled{
  padding-top:10px;padding-bottom:10px;
}

@media (prefers-reduced-motion: reduce){
  .nav-brand,.palette-trigger,.nav-end{animation:none}
  .nav::after{animation:none;opacity:.35;transform:none}
}
.nav.scrolled{
  background:color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter:saturate(140%) blur(14px);
  -webkit-backdrop-filter:saturate(140%) blur(14px);
  border-bottom:1px solid var(--rule);
}
.nav-brand{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--serif);font-size:18px;letter-spacing:-.01em;
}
.brand-mark{
  width:10px;height:10px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent);
  animation:pulse 2.4s var(--ease) infinite;
}
@keyframes pulse{
  50%{box-shadow:0 0 0 6px color-mix(in srgb, var(--accent) 0%, transparent)}
}

.palette-trigger{
  justify-self:center;
  display:inline-flex;align-items:center;gap:10px;
  padding:7px 14px 7px 12px;border-radius:999px;
  font-size:13px;color:var(--text-3);
  background:var(--surface);border:1px solid var(--rule);
  transition:all var(--t-fast);
  max-width:360px;width:100%;
}
.palette-trigger svg{flex-shrink:0;color:var(--text-3)}
.palette-trigger span{flex:1;text-align:left}
.palette-trigger kbd{margin-left:auto}
.palette-trigger:hover{
  border-color:var(--accent);color:var(--text);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--accent) 12%, transparent);
}
/* When the palette is open, hide the nav trigger so there aren't two
   search bars visible at once. The trigger fades out via opacity so
   the layout doesn't shift. */
body.palette-open .palette-trigger{
  opacity:0;
  pointer-events:none;
  visibility:hidden;
  transition:opacity .15s ease;
}

.nav-end{display:flex;align-items:center;gap:8px;justify-content:flex-end}
.nav-status{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:11px;color:var(--text-3);
  letter-spacing:.06em;
  padding:4px 10px;border-radius:999px;
  border:1px solid var(--rule);
}
.nav-loc{color:var(--text-3)}
.nav-btn{
  width:34px;height:34px;display:grid;place-items:center;
  color:var(--text-2);border-radius:50%;
  transition:color var(--t-fast), background var(--t-fast);
}
.nav-btn:hover{color:var(--text);background:var(--rule)}
.ic-moon{display:none}
.ic-sun{display:block}
:root[data-theme="light"] .ic-sun{display:none}
:root[data-theme="light"] .ic-moon{display:block}

.dot{width:6px;height:6px;border-radius:50%;background:var(--text-3);display:inline-block}
.dot.live{background:var(--lime)}

@media(max-width:760px){
  .nav{grid-template-columns:auto 1fr auto}
  .palette-trigger span{display:none}
  .palette-trigger{padding:7px 10px}
  .nav-status{display:none}
}

/* ---------- HERO ---------- */
.hero{
  min-height:100svh;
  max-width:var(--max);margin:0 auto;
  padding:140px var(--gutter) 100px;
  display:grid;grid-template-columns:1.4fr 1fr;
  gap:48px;align-content:center;
  position:relative;
}
@media(max-height:700px) and (min-width:980px){
  .hero{min-height:auto;padding-top:120px;padding-bottom:120px}
}
.hero-grid{align-self:center}
.hero-title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(64px, 11vw, 156px);
  line-height:.92;letter-spacing:-.03em;color:var(--text);
}
.hero-title .verb{
  display:inline-block;color:var(--accent);font-style:italic;
  position:relative;
  min-width:.5em;
  /* The element height shouldn't collapse during typewriter when textContent is empty */
}
.hero-title .verb::after{
  /* Invisible character that holds the line height when verb is empty mid-typewriter */
  content:".";
  visibility:hidden;
  position:absolute;
}
.hero-title em{font-style:italic;color:var(--accent)}
.cursor-blink{
  display:inline-block;color:var(--accent);font-weight:300;
  animation:blink 1.1s steps(2) infinite;
  margin-left:-.05em;font-style:normal;
}
@keyframes blink{50%{opacity:0}}

.hero-sub{
  margin-top:32px;max-width:55ch;
  font-size:clamp(15px, 1.4vw, 17px);line-height:1.65;color:var(--text-2);
}
.hero-sub b{font-weight:600;color:var(--text)}

.hero-cta{
  display:flex;flex-wrap:wrap;gap:12px;margin-top:36px;
}

/* Buttons */
.btn{
  position:relative;display:inline-flex;align-items:center;gap:8px;
  padding:11px 16px;border-radius:999px;font-size:14px;font-weight:500;
  border:1px solid var(--rule-2);transition:all var(--t-fast);
  will-change:transform;
}
.btn kbd{
  background:color-mix(in srgb, var(--text) 12%, transparent);
  border-color:transparent;color:inherit;font-size:11px;
}
.btn-primary{
  background:var(--accent);color:var(--bg);border-color:var(--accent);
}
.btn-primary:hover{
  filter:brightness(1.06);
  box-shadow:0 6px 20px color-mix(in srgb, var(--accent) 35%, transparent);
}
.btn-primary kbd{background:rgba(0,0,0,.18);color:inherit}
.btn-ghost{color:var(--text);background:transparent}
.btn-ghost:hover{background:var(--surface);border-color:var(--rule-2)}

.magnetic{transition:transform .15s var(--ease-out)}

/* Hero card: 3D-tilting interactive panel */
.hero-card{
  align-self:center;
  font-family:var(--mono);font-size:12px;
  border:1px solid var(--rule);background:var(--surface);
  border-radius:14px;overflow:hidden;
  box-shadow:0 30px 60px -30px rgba(0,0,0,.4);
  position:relative;
  transform-style:preserve-3d;
  transform:perspective(900px) rotateX(0) rotateY(0);
  transition:transform .45s cubic-bezier(.2,.8,.2,1), box-shadow .35s ease;
  will-change:transform;
  --mx:50%;--my:50%;
}
.hero-card:hover{
  box-shadow:0 40px 80px -30px rgba(0,0,0,.55);
}
.hero-card::before{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:linear-gradient(135deg, var(--terra), var(--pink), var(--blue));
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:.35;pointer-events:none;
  transition:opacity .35s ease;
  z-index:3;
}
.hero-card:hover::before{opacity:.85}

/* Cursor-tracked radial glow */
.hc-glow{
  position:absolute;inset:0;border-radius:inherit;
  background:radial-gradient(
    420px circle at var(--mx) var(--my),
    color-mix(in srgb, var(--accent) 18%, transparent),
    transparent 55%
  );
  opacity:0;
  transition:opacity .3s ease;
  pointer-events:none;
  z-index:1;
  mix-blend-mode:screen;
}
:root[data-theme="light"] .hc-glow{mix-blend-mode:multiply}
.hero-card:hover .hc-glow{opacity:1}

/* Diagonal shine sweep that tracks cursor X */
.hc-shine{
  position:absolute;inset:0;border-radius:inherit;
  background:linear-gradient(
    105deg,
    transparent 30%,
    color-mix(in srgb, var(--accent) 10%, transparent) calc(var(--mx) - 5%),
    color-mix(in srgb, var(--accent) 22%, transparent) var(--mx),
    color-mix(in srgb, var(--accent) 10%, transparent) calc(var(--mx) + 5%),
    transparent 70%
  );
  opacity:0;
  transition:opacity .35s ease;
  pointer-events:none;
  z-index:2;
  mix-blend-mode:overlay;
}
.hero-card:hover .hc-shine{opacity:.6}

.hc-inner{position:relative;z-index:4;transform:translateZ(20px)}

/* Rows are buttons */
button.hc-row{
  /* button reset */
  border:0;background:transparent;color:inherit;cursor:pointer;
  font:inherit;text-align:left;
  /* layout */
  width:100%;
  display:grid;grid-template-columns:90px 1fr auto;gap:14px;
  padding:12px 16px;border-bottom:1px solid var(--rule);
  align-items:center;
  position:relative;
  transition:background .25s ease, padding-left .3s cubic-bezier(.2,.8,.2,1);
}
button.hc-row:hover{
  background:color-mix(in srgb, var(--accent) 8%, transparent);
  padding-left:22px;
}
button.hc-row:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:-2px;
}
.hc-k{color:var(--text-3);text-transform:uppercase;letter-spacing:.1em;font-size:10px;transition:color .25s}
button.hc-row:hover .hc-k{color:var(--accent)}
.hc-v{color:var(--text);display:inline-flex;align-items:center;gap:8px;font-size:13px}
.hc-rotate{font-style:normal;transition:opacity .3s ease}
.hc-rotate.swap{opacity:0}
.hc-arrow{
  font-family:var(--serif);font-size:15px;font-style:italic;
  color:var(--text-3);
  opacity:0;
  transform:translateX(-6px);
  transition:opacity .25s ease, transform .3s cubic-bezier(.2,.8,.2,1), color .25s;
}
button.hc-row:hover .hc-arrow{
  opacity:1;
  transform:translateX(0);
  color:var(--accent);
}
.hc-foot{
  padding:10px 16px;color:var(--text-3);font-size:11px;
  background:var(--bg-2);
}

/* On touch / reduced motion, drop the parallax + shine */
@media(hover:none),(pointer:coarse){
  .hero-card{transform:none !important}
  .hc-glow,.hc-shine{display:none}
  button.hc-row:hover{padding-left:16px}
}
@media(prefers-reduced-motion:reduce){
  .hero-card{transform:none !important;transition:none !important}
  .hc-glow,.hc-shine{display:none}
}

@media(max-width:980px){
  .hero{
    grid-template-columns:1fr;gap:32px;
    min-height:auto;padding:110px var(--gutter) 90px;
  }
  .hero-card{order:1;align-self:start;width:100%;max-width:420px}
  .hero-title{font-size:clamp(54px, 13vw, 96px)}
}
@media(max-width:560px){
  .hero{padding:100px 20px 80px}
  .hero-title{font-size:clamp(42px, 14vw, 72px)}
  .hero-sub{font-size:15px}
  .hero-cta{gap:8px}
  .btn{padding:9px 12px;font-size:13px}
  .marquee-track{font-size:11px;gap:18px}
}

/* ---------- Marquee ---------- */
.marquee{
  position:absolute;left:0;right:0;bottom:24px;
  overflow:hidden;
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  pointer-events:auto;
}
@media(max-width:980px){
  .marquee{position:relative;bottom:auto;grid-column:1/-1;margin-top:8px}
}
.marquee-track{
  display:inline-flex;align-items:center;gap:24px;white-space:nowrap;
  animation:marquee 40s linear infinite;
  font-family:var(--mono);font-size:12px;color:var(--text-3);
  text-transform:uppercase;letter-spacing:.18em;
}
.marquee-track span{padding:0 4px}
.m-dot{width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.6;flex-shrink:0}
@keyframes marquee{to{transform:translateX(-50%)}}
.marquee:hover .marquee-track{animation-play-state:paused}

/* ---------- Block (general section frame) ---------- */
.block{
  max-width:var(--max);margin:0 auto;
  padding:var(--pad-y) var(--gutter);
  border-top:1px solid var(--rule);
  position:relative;
}
.block-head{
  display:flex;justify-content:space-between;align-items:baseline;
  margin-bottom:42px;gap:20px;flex-wrap:wrap;
}
.block-meta{
  font-family:var(--mono);font-size:11px;color:var(--text-3);
  text-transform:uppercase;letter-spacing:.16em;
}

/* ---------- Capabilities ---------- */
.cap-grid{
  display:grid;gap:16px;
  grid-template-columns:repeat(4, 1fr);
}
@media(max-width:980px){.cap-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.cap-grid{grid-template-columns:1fr}}

.cap{
  --cap-c: var(--terra);
  position:relative;text-align:left;
  padding:24px;border-radius:16px;
  background:var(--surface);border:1px solid var(--rule);
  transition:transform var(--t-fast), border-color var(--t-fast), background var(--t-fast);
  overflow:hidden;isolation:isolate;
  cursor:pointer;
}
.cap[data-accent="pink"]{--cap-c:var(--pink)}
.cap[data-accent="blue"]{--cap-c:var(--blue)}
.cap[data-accent="lime"]{--cap-c:var(--lime)}
.cap[data-accent="amber"]{--cap-c:var(--amber)}
.cap[data-accent="violet"]{--cap-c:var(--violet)}
.cap[data-accent="terra"]{--cap-c:var(--terra)}
.cap::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(circle at var(--mx,50%) var(--my,0%), color-mix(in srgb, var(--cap-c) 20%, transparent), transparent 50%);
  opacity:0;transition:opacity var(--t-fast);z-index:-1;
}
.cap:hover{
  border-color:var(--cap-c);
  transform:translateY(-3px);
  background:var(--surface-2);
}
.cap:hover::before{opacity:1}
.cap-num{
  position:absolute;top:18px;right:20px;
  font-family:var(--mono);font-size:11px;color:var(--text-3);letter-spacing:.1em;
}
.cap-glyph{
  width:38px;height:38px;color:var(--cap-c);
  margin-bottom:18px;
  transition:transform var(--t-med);
}
.cap:hover .cap-glyph{transform:rotate(-6deg) scale(1.1)}
.cap h3{
  font-family:var(--serif);font-weight:400;
  font-size:23px;letter-spacing:-.01em;margin-bottom:6px;color:var(--text);
}
.cap p{font-size:13.5px;color:var(--text-2);line-height:1.55;margin-bottom:14px}
.cap-tag{
  display:inline-block;font-family:var(--mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.14em;
  padding:4px 8px;border-radius:5px;
  background:color-mix(in srgb, var(--cap-c) 15%, transparent);
  color:var(--cap-c);
  border:1px solid color-mix(in srgb, var(--cap-c) 35%, transparent);
}

/* ---------- Lab Stack (4 tiles, expandable) ---------- */
.lab-stack{
  display:grid;
  grid-template-columns:1fr 1fr 1fr 1fr;
  gap:14px;
  transition:
    grid-template-columns .65s cubic-bezier(.7,0,.2,1),
    gap .65s cubic-bezier(.7,0,.2,1);
}
.lab-stack[data-active]{gap:0}
.lab-stack[data-active="0"]{grid-template-columns:1fr 0fr 0fr 0fr}
.lab-stack[data-active="1"]{grid-template-columns:0fr 1fr 0fr 0fr}
.lab-stack[data-active="2"]{grid-template-columns:0fr 0fr 1fr 0fr}
.lab-stack[data-active="3"]{grid-template-columns:0fr 0fr 0fr 1fr}

.lab-card{
  --tone: var(--terra);
  position:relative;
  aspect-ratio:1;
  min-width:0;
  border-radius:18px;
  overflow:hidden;
  background:var(--surface);
  border:1px solid var(--rule);
  cursor:pointer;
  -webkit-tap-highlight-color:color-mix(in srgb, var(--tone) 18%, transparent);
  transition:
    transform .55s cubic-bezier(.7,0,.2,1),
    border-color .55s cubic-bezier(.7,0,.2,1),
    opacity .35s cubic-bezier(.7,0,.2,1),
    background .55s cubic-bezier(.7,0,.2,1);
  isolation:isolate;
}
.lab-card[data-tone="terra"]{--tone:var(--terra)}
.lab-card[data-tone="pink"]{--tone:var(--pink)}
.lab-card[data-tone="blue"]{--tone:var(--blue)}
.lab-card[data-tone="lime"]{--tone:var(--lime)}

.lab-card::before{
  content:"";
  position:absolute;inset:0;border-radius:inherit;
  background:radial-gradient(circle at 30% 0%, color-mix(in srgb, var(--tone) 18%, transparent), transparent 60%);
  opacity:.85;z-index:0;transition:opacity .3s ease;
  pointer-events:none;
}
.lab-card:hover{
  border-color:color-mix(in srgb, var(--tone) 55%, var(--rule));
  transform:translateY(-3px);
}
/* Suppress the hover lift once a tile is active. A transform on the
   lab-card would create a containing block for the playground's
   position:fixed fullscreen, breaking it. */
.lab-stack[data-active] .lab-card:hover,
.lab-card.active:hover,
.lab-card:has(.pg.pg-fullscreen):hover{transform:none}
.lab-card:hover::before{opacity:1}
.lab-card:hover .lab-glyph{transform:rotate(-6deg) scale(1.06)}
.lab-card:focus-visible{outline:2px solid var(--tone);outline-offset:2px}
.lab-card:focus{outline:none}

/* Cover */
.lab-cover{
  position:absolute;inset:0;
  display:flex;flex-direction:column;
  justify-content:space-between;
  padding:20px;z-index:1;
  transition:opacity .25s ease;
}
.lab-glyph{
  color:var(--tone);
  transition:transform .35s cubic-bezier(.34,1.56,.64,1);
  width:fit-content;
}
.lab-cover-foot h3{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(20px, 2.2vw, 26px);
  letter-spacing:-.01em;color:var(--text);margin-bottom:4px;
}
.lab-cover-foot p{
  font-family:var(--mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.16em;
  color:var(--text-3);
}
.lab-open{
  display:inline-flex;align-items:center;gap:4px;
  margin-top:14px;font-family:var(--mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.16em;
  color:var(--tone);
}
.lab-open em{font-style:normal;transition:transform .25s ease;display:inline-block}
.lab-card:hover .lab-open em{transform:translate(2px, -2px)}

/* Expanded view */
.lab-expanded{
  position:absolute;inset:0;
  padding:24px;
  overflow:auto;
  opacity:0;
  pointer-events:none;
  transition:opacity .3s ease;
  z-index:2;
}
.lab-bar{
  display:flex;justify-content:space-between;align-items:flex-start;
  margin-bottom:14px;padding-bottom:18px;
  border-bottom:1px solid var(--rule);
}
.lab-bar-eye{
  display:block;font-family:var(--mono);font-size:10.5px;
  color:var(--text-3);text-transform:uppercase;letter-spacing:.18em;
  margin-bottom:6px;
}
.lab-bar h3{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(28px, 3.4vw, 40px);
  line-height:1;letter-spacing:-.015em;color:var(--text);
}
.lab-back{
  display:inline-flex;align-items:center;gap:8px;
  padding:8px 14px;border-radius:8px;
  background:transparent;border:1px solid var(--rule-2);
  color:var(--text-2);
  font-family:var(--mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.14em;
  transition:all var(--t-fast);
  flex-shrink:0;
}
.lab-back:hover{
  border-color:var(--tone, var(--accent));
  color:var(--tone, var(--accent));
}

/* Active state: card expands and shows expanded view */
.lab-stack[data-active] .lab-card{aspect-ratio:auto}
.lab-stack[data-active] .lab-card.active{
  cursor:default;
  min-height:min(720px, 80vh);
  border-color:color-mix(in srgb, var(--tone) 35%, var(--rule-2));
}
.lab-stack[data-active] .lab-card.active::before{opacity:.45}
.lab-stack[data-active] .lab-card.active .lab-cover{
  opacity:0;pointer-events:none;
}
.lab-stack[data-active] .lab-card.active .lab-expanded{
  opacity:1;pointer-events:auto;
  transition-delay:.3s;
}

/* Inactive cards when something is active: gracefully fade out */
.lab-stack[data-active] .lab-card:not(.active){
  opacity:0;pointer-events:none;
  border-width:0;
  transform:none;
}
.lab-stack[data-active] .lab-card:not(.active)::before{opacity:0}

/* Mobile: stack tiles vertically, hide siblings when one is active.
   Switch the expanded view to natural flow so its content sizes the card. */
@media(max-width:780px){
  .lab-stack{grid-template-columns:1fr}
  .lab-stack[data-active="0"],
  .lab-stack[data-active="1"],
  .lab-stack[data-active="2"],
  .lab-stack[data-active="3"]{grid-template-columns:1fr}

  .lab-card{aspect-ratio:1.7 / 1}

  .lab-stack[data-active] .lab-card:not(.active){display:none}

  .lab-stack[data-active] .lab-card.active{
    aspect-ratio:auto;
    min-height:0;
    overflow:visible;
  }
  /* Cover is removed so it doesn't reserve any layout space */
  .lab-stack[data-active] .lab-card.active .lab-cover{display:none}
  /* Expanded view goes into natural flow so card height = content height */
  .lab-stack[data-active] .lab-card.active .lab-expanded{
    position:static;
    inset:auto;
    opacity:1;
    pointer-events:auto;
    overflow:visible;
    transition:none;
  }

  .lab-bar h3{font-size:24px}
  .lab-expanded{padding:18px}
}

.tool{margin-bottom:40px}
.tool:last-child{margin-bottom:0}
.tool-head{margin-bottom:20px}
.tool-title{
  font-family:var(--serif);font-weight:400;font-size:32px;letter-spacing:-.015em;
  display:inline-flex;align-items:baseline;gap:10px;color:var(--text);
}
.tool-emoji{
  font-style:normal;color:var(--accent);font-family:var(--mono);
  font-size:.7em;
}
.tool-blurb{
  margin-top:6px;font-size:14.5px;color:var(--text-2);max-width:62ch;
}
.tool-blurb kbd{font-size:11px;padding:1px 5px}
.tool-actions{
  margin-top:14px;display:flex;flex-wrap:wrap;gap:8px;
}
.chip{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;
  padding:6px 12px;border-radius:999px;
  background:var(--surface);color:var(--text-2);border:1px solid var(--rule);
  transition:all var(--t-fast);
}
.chip:hover{color:var(--text);border-color:var(--accent);background:var(--surface-2)}
.chip-ghost{color:var(--text-3)}

/* Live HTML/CSS playground */
.pg{
  display:grid;grid-template-columns:var(--pg-split, 1fr 1fr);gap:0;
  border-radius:14px;overflow:hidden;
  border:1px solid var(--rule);background:var(--bg-2);
  min-height:380px;
  transition:grid-template-columns .35s var(--ease);
}
.pg-pane{display:flex;flex-direction:column;background:var(--surface);min-width:0}
.pg-pane-code{border-right:1px solid var(--rule)}
.pg-tab{
  display:flex;align-items:center;gap:8px;
  padding:8px 10px 8px 14px;font-family:var(--mono);font-size:11.5px;
  color:var(--text-3);background:var(--bg-2);
  border-bottom:1px solid var(--rule);
  letter-spacing:.04em;flex-shrink:0;
}
.pg-dot{
  width:8px;height:8px;border-radius:50%;
  background:var(--accent);flex-shrink:0;
  box-shadow:0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent);
  animation:pulse 2.4s var(--ease) infinite;
}
.pg-tab-name{flex:1}
.pg-live{
  margin-left:auto;display:inline-flex;align-items:center;gap:6px;
  color:var(--text-2);
}

/* Custom playground controls (NOT macOS, theme-matched) */
.pg-controls{display:flex;align-items:center;gap:4px;margin-left:auto}
.pg-btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 8px;border-radius:6px;
  background:transparent;border:1px solid transparent;
  color:var(--text-3);font-family:var(--mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.12em;
  transition:all var(--t-fast);cursor:pointer;
}
.pg-btn:hover{color:var(--accent);background:color-mix(in srgb, var(--accent) 10%, transparent)}
.pg-btn-major{
  border-color:var(--rule-2);padding-right:10px;
}
.pg-btn-major:hover{border-color:var(--accent)}
.pg-btn-label{font-size:10px;font-weight:500}
.pg-btn.active{
  background:var(--accent);color:var(--bg);border-color:var(--accent);
}
@media(max-width:560px){.pg-btn-label{display:none}.pg-btn-major{padding:5px 8px}}

#pg-input{
  flex:1;padding:14px 16px;font-family:var(--mono);font-size:13px;
  line-height:1.55;color:var(--text);background:transparent;
  border:0;outline:0;resize:none;tab-size:2;
  min-height:320px;
}
#pg-input::selection{background:color-mix(in srgb, var(--accent) 35%, transparent)}
#pg-output{
  flex:1;border:0;background:#fff;width:100%;min-height:320px;
}
:root[data-theme="dark"] #pg-output{background:#0a0908}

/* Playground sizing modes */
.pg.pg-grow{--pg-split: 2.2fr 1fr}
.pg.pg-shrink{--pg-split: 1fr 2.2fr}

/* Fullscreen state: keep .pg in place in the DOM (so the iframe never reloads),
   just lift it visually with position:fixed. Use :has() to neutralise ancestor
   overflow:hidden and isolation, otherwise the lab tile would clip it. */
.pg.pg-fullscreen{
  position:fixed;
  top:24px;left:24px;right:24px;bottom:24px;
  width:auto;height:auto;
  min-height:0;
  margin:0;
  z-index:200;
  border-radius:14px;
  border-color:var(--rule-2);
  background:var(--bg);
  box-shadow:0 30px 80px rgba(0,0,0,.55);
  animation:pgPop .35s cubic-bezier(.7,0,.2,1);
}
@keyframes pgPop{
  from{opacity:0;transform:scale(.96)}
}
.pg.pg-fullscreen #pg-input,
.pg.pg-fullscreen #pg-output{min-height:0;height:100%}
.pg.pg-fullscreen .pg-pane{height:100%;min-height:0}

/* When the playground is fullscreen, neutralise every ancestor that would
   otherwise clip or trap it. :has() is supported across all modern browsers. */
.lab-card:has(.pg.pg-fullscreen){
  overflow:visible !important;
  isolation:auto !important;
  z-index:200;
}
.lab-expanded:has(.pg.pg-fullscreen){
  overflow:visible !important;
}
.lab-stack:has(.pg.pg-fullscreen){
  overflow:visible !important;
}

/* Dim + blur backdrop when fullscreen, drawn via a pseudo-element on <main>
   so it sits above the page content but under the .pg (z-index:200). */
main:has(.pg.pg-fullscreen)::after{
  content:"";
  position:fixed;inset:0;z-index:150;
  background:color-mix(in srgb, var(--bg) 75%, transparent);
  backdrop-filter:blur(8px) saturate(140%);
  -webkit-backdrop-filter:blur(8px) saturate(140%);
  animation:bdIn .25s ease;
  pointer-events:none;
}
@keyframes bdIn{from{opacity:0}}

@media(max-width:760px){
  .pg{grid-template-columns:1fr;--pg-split:1fr}
  .pg-pane-code{border-right:0;border-bottom:1px solid var(--rule)}
  .pg.pg-grow,.pg.pg-shrink{--pg-split:1fr}
  /* The shrink/grow/expand buttons are useless on a single-column mobile
     layout; the lab tile already takes the screen. Hide them. */
  .pg-controls{display:none}
  /* Smaller inset on mobile when fullscreen */
  .pg.pg-fullscreen{top:12px;left:12px;right:12px;bottom:12px}
}

/* Drum pads */
.pads{
  display:grid;grid-template-columns:repeat(8,1fr);gap:10px;
}
@media(max-width:760px){.pads{grid-template-columns:repeat(4,1fr)}}

.pad{
  --c-1: 250 90% 65%;
  --c-2: 280 80% 65%;
  --c-3: 320 80% 60%;
  --c-4: 0 80% 60%;
  --c-5: 30 90% 55%;
  --c-6: 60 90% 50%;
  --c-7: 150 80% 45%;
  --c-8: 200 80% 55%;
  position:relative;aspect-ratio:1;border-radius:14px;
  background:hsl(var(--c-1) / .15);
  border:1px solid hsl(var(--c-1) / .35);
  color:hsl(var(--c-1));
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-family:var(--mono);transition:all .12s var(--ease);
  overflow:hidden;
}
.pad[style*="--c:1"]{background:hsl(var(--c-1) / .15);border-color:hsl(var(--c-1) / .35);color:hsl(var(--c-1))}
.pad[style*="--c:2"]{background:hsl(var(--c-2) / .15);border-color:hsl(var(--c-2) / .35);color:hsl(var(--c-2))}
.pad[style*="--c:3"]{background:hsl(var(--c-3) / .15);border-color:hsl(var(--c-3) / .35);color:hsl(var(--c-3))}
.pad[style*="--c:4"]{background:hsl(var(--c-4) / .15);border-color:hsl(var(--c-4) / .35);color:hsl(var(--c-4))}
.pad[style*="--c:5"]{background:hsl(var(--c-5) / .15);border-color:hsl(var(--c-5) / .35);color:hsl(var(--c-5))}
.pad[style*="--c:6"]{background:hsl(var(--c-6) / .15);border-color:hsl(var(--c-6) / .35);color:hsl(var(--c-6))}
.pad[style*="--c:7"]{background:hsl(var(--c-7) / .15);border-color:hsl(var(--c-7) / .35);color:hsl(var(--c-7))}
.pad[style*="--c:8"]{background:hsl(var(--c-8) / .15);border-color:hsl(var(--c-8) / .35);color:hsl(var(--c-8))}

.pad span{font-size:11px;opacity:.7;letter-spacing:.1em}
.pad b{font-size:18px;font-weight:500;font-family:var(--serif);font-style:italic;font-weight:400;letter-spacing:-.01em;margin-top:2px}
.pad:hover{transform:translateY(-2px);filter:brightness(1.15)}
.pad.hit{
  transform:scale(.94);
  box-shadow:0 0 0 4px currentColor, 0 0 32px currentColor;
  filter:brightness(1.5);
}

/* Light mode pads: stronger contrast, deeper colours */
:root[data-theme="light"] .pad{
  background:hsl(var(--c-1) / .14);
  border:1.5px solid hsl(var(--c-1) / .55);
  color:hsl(var(--c-1) 70% 35%);
}
:root[data-theme="light"] .pad[style*="--c:1"]{background:hsl(var(--c-1) / .14);border-color:hsl(var(--c-1) / .55);color:hsl(var(--c-1) 70% 38%)}
:root[data-theme="light"] .pad[style*="--c:2"]{background:hsl(var(--c-2) / .14);border-color:hsl(var(--c-2) / .55);color:hsl(var(--c-2) 70% 38%)}
:root[data-theme="light"] .pad[style*="--c:3"]{background:hsl(var(--c-3) / .14);border-color:hsl(var(--c-3) / .55);color:hsl(var(--c-3) 70% 38%)}
:root[data-theme="light"] .pad[style*="--c:4"]{background:hsl(var(--c-4) / .14);border-color:hsl(var(--c-4) / .55);color:hsl(var(--c-4) 70% 42%)}
:root[data-theme="light"] .pad[style*="--c:5"]{background:hsl(var(--c-5) / .14);border-color:hsl(var(--c-5) / .55);color:hsl(var(--c-5) 70% 38%)}
:root[data-theme="light"] .pad[style*="--c:6"]{background:hsl(var(--c-6) / .18);border-color:hsl(var(--c-6) 70% 40% / .65);color:hsl(var(--c-6) 70% 30%)}
:root[data-theme="light"] .pad[style*="--c:7"]{background:hsl(var(--c-7) / .14);border-color:hsl(var(--c-7) / .55);color:hsl(var(--c-7) 70% 30%)}
:root[data-theme="light"] .pad[style*="--c:8"]{background:hsl(var(--c-8) / .14);border-color:hsl(var(--c-8) / .55);color:hsl(var(--c-8) 70% 38%)}
:root[data-theme="light"] .pad.hit{filter:brightness(.85) saturate(1.3)}

/* ---------- Gradient Lab ---------- */
.grad{
  display:grid;grid-template-columns:1.1fr 1fr;gap:18px;
  border:1px solid var(--rule);border-radius:14px;
  background:var(--surface);overflow:hidden;
}
.grad-canvas{
  min-height:340px;
  background:linear-gradient(135deg,#f97316,#ec4899,#3b82f6);
  border-right:1px solid var(--rule);
  position:relative;
}
.grad-canvas::after{
  content:"";position:absolute;inset:0;
  box-shadow:inset 0 0 60px rgba(0,0,0,.15);
}
.grad-controls{
  display:flex;flex-direction:column;gap:18px;padding:22px;
  font-family:var(--mono);
}
.grad-row{display:flex;flex-direction:column;gap:14px}
.grad-row-sliders{gap:18px}
.grad-color{
  display:grid;grid-template-columns:80px 36px 1fr;gap:12px;align-items:center;
  cursor:pointer;
}
.grad-label{
  font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.16em;
}
.grad-color input[type="color"]{
  appearance:none;-webkit-appearance:none;
  width:36px;height:36px;border:1px solid var(--rule-2);border-radius:8px;
  padding:0;background:transparent;cursor:pointer;
}
.grad-color input[type="color"]::-webkit-color-swatch-wrapper{padding:3px}
.grad-color input[type="color"]::-webkit-color-swatch{border:0;border-radius:5px}
.grad-color input[type="color"]::-moz-color-swatch{border:0;border-radius:5px}
.grad-hex{font-size:12px;color:var(--text-2)}
.grad-slider{display:flex;flex-direction:column;gap:8px}
.grad-slider .grad-label{display:flex;justify-content:space-between}
.grad-slider output{color:var(--accent)}
.grad-slider input[type="range"]{
  appearance:none;-webkit-appearance:none;
  width:100%;height:4px;border-radius:2px;
  background:linear-gradient(90deg, var(--accent), var(--rule-2));
  outline:none;
}
.grad-slider input[type="range"]::-webkit-slider-thumb{
  appearance:none;-webkit-appearance:none;
  width:16px;height:16px;border-radius:50%;
  background:var(--accent);cursor:pointer;
  border:2px solid var(--bg);box-shadow:0 0 0 1px var(--accent);
}
.grad-slider input[type="range"]::-moz-range-thumb{
  width:16px;height:16px;border-radius:50%;border:2px solid var(--bg);
  background:var(--accent);cursor:pointer;box-shadow:0 0 0 1px var(--accent);
}
.grad-types{display:flex;gap:6px}
.grad-types .grad-type[aria-pressed="true"]{
  background:var(--accent);color:var(--bg);border-color:var(--accent);
}
.grad-output{
  margin-top:auto;display:flex;flex-direction:column;gap:10px;
  padding:14px;border-radius:10px;
  background:var(--bg-2);border:1px solid var(--rule);
}
#grad-code{
  font-size:11.5px;line-height:1.5;color:var(--text);
  word-break:break-all;
}
@media(max-width:760px){
  .grad{grid-template-columns:1fr}
  .grad-canvas{min-height:200px;border-right:0;border-bottom:1px solid var(--rule)}
}

/* ---------- Game of Life ---------- */
#life-canvas{
  width:100%;height:auto;
  border:1px solid var(--rule);border-radius:12px;
  background:var(--bg-2);
  display:block;cursor:crosshair;
  image-rendering:pixelated;
  aspect-ratio: 4 / 1.6;
}


/* ---------- Work ---------- */
.work-list{display:flex;flex-direction:column}
.work-item{
  display:grid;grid-template-columns:200px 1fr;gap:48px;
  padding:32px 0;border-top:1px solid var(--rule);
  align-items:start;position:relative;
  transition:padding var(--t-fast);
}
.work-item:last-child{border-bottom:1px solid var(--rule)}
.work-item::before{
  content:"";position:absolute;inset:0;left:-16px;right:-16px;
  background:var(--surface);opacity:0;border-radius:8px;
  transition:opacity var(--t-fast);z-index:-1;
}
.work-item:hover{padding-left:8px}
.work-item:hover::before{opacity:.7}

.work-meta{display:flex;flex-direction:column;gap:6px;padding-top:6px}
.work-date{font-family:var(--mono);font-size:13px;color:var(--text);letter-spacing:.02em}
.work-tag{font-family:var(--mono);font-size:11px;color:var(--text-3);text-transform:uppercase;letter-spacing:.16em}

.work-title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(22px, 2.4vw, 30px);
  line-height:1.25;letter-spacing:-.01em;
  margin-bottom:10px;color:var(--text);
}
.work-co{display:block;font-size:.62em;color:var(--text-3);margin-top:4px;letter-spacing:0}
.work-co em{font-style:italic;color:var(--text-2)}
.work-body p{font-size:15px;line-height:1.65;color:var(--text-2);max-width:60ch}

@media(max-width:760px){
  .work-item{grid-template-columns:1fr;gap:12px}
  .work-meta{flex-direction:row;gap:14px;align-items:baseline}
}

/* ---------- About ---------- */
.about-grid{display:grid;grid-template-columns:200px 1fr;gap:48px}
.prose-lead{
  font-family:var(--serif);
  font-size:clamp(28px, 3.2vw, 40px);line-height:1.3;
  letter-spacing:-.015em;margin-bottom:26px;color:var(--text);
}
.about-right p{margin-bottom:14px;color:var(--text-2);font-size:16px;line-height:1.7;max-width:64ch}
.about-right em{font-style:italic;color:var(--text)}
.link{color:var(--text);border-bottom:1px solid var(--accent);transition:all var(--t-fast);padding:0 1px}
.link:hover{background:var(--accent);color:var(--bg)}

@media(max-width:760px){.about-grid{grid-template-columns:1fr;gap:14px}}

/* ---------- Education ---------- */
.edu-list{display:flex;flex-direction:column}
.edu-list li{
  display:grid;grid-template-columns:200px 1fr;gap:48px;
  padding:22px 0;border-top:1px solid var(--rule);align-items:baseline;
}
.edu-list li:last-child{border-bottom:1px solid var(--rule)}
.edu-date{font-family:var(--mono);font-size:12px;color:var(--text-3);letter-spacing:.04em}
.edu-list h4{font-family:var(--serif);font-weight:400;font-size:clamp(20px,2vw,24px);margin-bottom:6px;color:var(--text);letter-spacing:-.005em}
.edu-list p{font-size:14.5px;color:var(--text-2);line-height:1.6}
@media(max-width:760px){.edu-list li{grid-template-columns:1fr;gap:6px}}

/* ---------- Contact ---------- */
.contact{padding-bottom:120px}
.contact-inner{max-width:780px;margin:0 auto}
.contact-display{
  font-size:clamp(64px, 12vw, 168px);
  margin-top:14px;margin-bottom:24px;
}
.contact-lede{font-family:var(--serif);font-size:clamp(22px,2.4vw,28px);color:var(--text-2);line-height:1.45;max-width:42ch;margin-bottom:42px}
.contact-rows{display:flex;flex-direction:column;border-top:1px solid var(--rule)}
.contact-row{
  display:grid;grid-template-columns:140px 1fr auto;
  align-items:baseline;gap:24px;
  padding:22px 0;border-bottom:1px solid var(--rule);
  transition:padding var(--t-fast);position:relative;
}
.contact-row::before{
  content:"";position:absolute;left:0;right:0;top:0;bottom:0;
  border-bottom:1px solid var(--text);transform:scaleX(0);
  transform-origin:left;transition:transform var(--t-med);
}
.contact-row:hover::before{transform:scaleX(1)}
.contact-row:hover{padding-left:8px}
.contact-label{font-family:var(--mono);font-size:11px;color:var(--text-3);text-transform:uppercase;letter-spacing:.16em}
.contact-value{font-family:var(--serif);font-size:clamp(22px,2.6vw,32px);letter-spacing:-.01em;color:var(--text);line-height:1.2}
.contact-arrow{font-family:var(--serif);font-size:24px;color:var(--accent)}
@media(max-width:600px){.contact-row{grid-template-columns:1fr;gap:6px}.contact-arrow{display:none}}

/* ---------- Footer ---------- */
.footer{
  max-width:var(--max);margin:0 auto;
  padding:30px var(--gutter) 60px;
  border-top:1px solid var(--rule);
  display:flex;justify-content:space-between;align-items:center;
  gap:20px;flex-wrap:wrap;
  font-size:13px;color:var(--text-3);
}
.foot-l, .foot-r{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.foot-sep{opacity:.5}

/* ---------- Mobile / Resize Polish ---------- */
@media(max-width:560px){
  .block{padding:64px var(--gutter)}
  .block-head{margin-bottom:30px}
  .work-item{padding:24px 0;gap:8px}
  .work-item:hover{padding-left:0}
  .work-item:hover::before{left:-8px;right:-8px}
  .cap{padding:20px}
  .cap h3{font-size:21px}
  .tool-title{font-size:26px}
  .tool{margin-bottom:32px}
  .pads{gap:6px}
  .pad{border-radius:10px}
  .pad b{font-size:15px}
  #life-canvas{aspect-ratio:1.2 / 1}
  .palette-window{margin:0 12px;width:calc(100vw - 24px)}
  .palette-foot{font-size:10px;flex-wrap:wrap;gap:8px}
  .palette-search input{font-size:14px}
  .footer{padding:24px var(--gutter) 40px;font-size:12px}
  .contact-display{font-size:clamp(54px, 18vw, 96px)}
}

/* Avoid horizontal overflow when zoomed.
   IMPORTANT: use `clip` not `hidden` — `hidden` makes html/body scroll
   containers, which silently breaks `position: sticky` on any descendant
   (the pin-scrub scenes need viewport-anchored sticky). */
html,body{max-width:100%;overflow-x:clip}

/* ---------- Reveal (fallback for old browsers) ---------- */
[data-reveal]{
  opacity:0;transform:translateY(20px);
  transition:opacity .8s var(--ease-out), transform .8s var(--ease-out);
}
[data-reveal].in-view{opacity:1;transform:none}

/* ==========================================================
   Scroll-driven animations (Chrome/Edge 115+, Safari 26+, Firefox 142+)
   Layered on top of [data-reveal]. The browser interpolates each element's
   own animation between its entry into view and its position 'cover N%' through.
   ========================================================== */
@supports (animation-timeline: view()) {

  /* Cancel the old transition reveal so the scroll animation takes over */
  [data-reveal]{ transition:none; opacity:1; transform:none; }

  /* ---- Section headings: name, kicker, meta slide in as the section enters ---- */
  .block-head{
    animation: head-rise linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 28%;
  }
  @keyframes head-rise{
    from { opacity:0; transform: translateY(40px); filter: blur(4px); }
    60%  { filter: blur(0); }
    to   { opacity:1; transform: translateY(0); filter: blur(0); }
  }

  /* Capability cards are now driven by the .scene-cap pin-scrub (see below).
     The view-timeline rule is intentionally removed. */

  /* ---- Lab tiles: cascade from below ---- */
  .lab-stack .lab-card{
    animation: tile-rise linear both;
    animation-timeline: view();
  }
  .lab-stack .lab-card:nth-child(1){ animation-range: entry 0% cover 28%; }
  .lab-stack .lab-card:nth-child(2){ animation-range: entry 6% cover 34%; }
  .lab-stack .lab-card:nth-child(3){ animation-range: entry 12% cover 40%; }
  .lab-stack .lab-card:nth-child(4){ animation-range: entry 18% cover 46%; }
  @keyframes tile-rise{
    from { opacity:0; transform: translateY(80px) scale(.96); }
    to   { opacity:1; transform: translateY(0) scale(1); }
  }

  /* ---- Work items: meta slides from left, body fades from below ---- */
  .work-item{
    animation: work-row-in linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 30%;
  }
  @keyframes work-row-in{
    from { opacity:0; transform: translateY(40px); }
    to   { opacity:1; transform: translateY(0); }
  }
  .work-item .work-meta{
    animation: meta-slide linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 35%;
  }
  @keyframes meta-slide{
    from { opacity:0; transform: translateX(-30px); }
    to   { opacity:1; transform: translateX(0); }
  }
  .work-item .work-body{
    animation: body-slide linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 40%;
  }
  @keyframes body-slide{
    from { opacity:0; transform: translateX(30px); filter: blur(2px); }
    to   { opacity:1; transform: translateX(0); filter: blur(0); }
  }

  /* ---- Education rows: simple cascade ---- */
  .edu-list li{
    animation: edu-in linear both;
    animation-timeline: view();
  }
  .edu-list li:nth-child(1){ animation-range: entry 0% cover 30%; }
  .edu-list li:nth-child(2){ animation-range: entry 8% cover 38%; }
  .edu-list li:nth-child(3){ animation-range: entry 16% cover 46%; }
  @keyframes edu-in{
    from { opacity:0; transform: translateY(40px); }
    to   { opacity:1; transform: translateY(0); }
  }

  /* Contact display + rows are now driven by .scene-contact pin-scrub (see below) */

  /* ---- Hero parallax: scale and fade as the hero leaves the viewport ---- */
  .hero-title{
    animation: hero-out linear both;
    animation-timeline: view(block);
    animation-range: exit 0% exit 100%;
  }
  @keyframes hero-out{
    from { transform: translateY(0) scale(1);    opacity:1; }
    to   { transform: translateY(-30px) scale(.92); opacity:.4; }
  }
  .hero-sub{
    animation: hero-sub-out linear both;
    animation-timeline: view(block);
    animation-range: exit 20% exit 100%;
  }
  @keyframes hero-sub-out{
    from { opacity:.85; }
    to   { opacity:0; transform: translateY(-20px); }
  }

  /* ---- Marquee: slight scroll-driven scale (subtle depth) ---- */
  .marquee{
    animation: marquee-fade linear both;
    animation-timeline: view(block);
    animation-range: exit 50% exit 100%;
  }
  @keyframes marquee-fade{
    from { opacity:1; }
    to   { opacity:0; }
  }

  /* ---- About prose lead: dramatic entrance ---- */
  .prose-lead{
    animation: lead-in linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 35%;
  }
  @keyframes lead-in{
    from { opacity:0; transform: translateY(30px); filter:blur(3px); }
    to   { opacity:1; transform: translateY(0); filter:blur(0); }
  }

  /* ---- Stack / Tools group cascade ---- */
  .stack-col{
    animation: stack-in linear both;
    animation-timeline: view();
  }
  .stack-col:nth-child(1){ animation-range: entry 0% cover 30%; }
  .stack-col:nth-child(2){ animation-range: entry 8% cover 38%; }
  .stack-col:nth-child(3){ animation-range: entry 16% cover 46%; }
  .stack-col:nth-child(4){ animation-range: entry 24% cover 54%; }
  @keyframes stack-in{
    from { opacity:0; transform: translateY(40px); }
    to   { opacity:1; transform: translateY(0); }
  }
}

/* ==========================================================
   PIN-SCRUB SCENES (Apple-style, JS-driven)
   The section is taller than the viewport with a sticky inner pin.
   As the user scrolls, JS computes progress (0-1) through the
   sticky-engaged region and inline-styles each animated child.
   The setup CSS only kicks in when JS adds `body.has-scrub`; that way
   mobile/touch/reduced-motion users get the natural single-column
   layout with no animations.
   ========================================================== */

.scene{
  position:relative;
  border-top:1px solid var(--rule);
}
.scene-pin{
  /* Default: not pinned. Acts like a normal section wrapper. */
  padding:var(--pad-y) 0;
}
.scene-stage{
  width:100%;
  max-width:var(--max);
  margin:0 auto;
  padding:0 var(--gutter);
}

/* When JS is in charge of the scrub */
body.has-scrub .scene-cap     { height:230vh; }
body.has-scrub .scene-lab     { height:200vh; }
body.has-scrub .scene-contact { height:200vh; }
body.has-scrub .scene-pin{
  position:sticky;top:0;
  height:100svh;
  padding:0;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  z-index:1;
}

/* Pre-hide the animated children so they don't flash before JS computes */
body.has-scrub .scene-cap .block-head,
body.has-scrub .scene-cap .cap-grid .cap,
body.has-scrub .scene-lab .block-head,
body.has-scrub .scene-lab .lab-stack .lab-card,
body.has-scrub .scene-contact .kicker,
body.has-scrub .scene-contact .contact-display,
body.has-scrub .scene-contact .contact-lede,
body.has-scrub .scene-contact .contact-row{
  opacity:0;
  will-change:opacity,transform,filter;
}
body.has-scrub .scene-cap .block-head        { transform:translateY(30px) }
body.has-scrub .scene-cap .cap-grid .cap     { transform:translateY(60px) scale(.92); filter:blur(4px) }
body.has-scrub .scene-lab .block-head        { transform:translateY(30px) }
/* Each Lab tile flies in from a different corner — set per-tile in JS via tx/ty.
   IMPORTANT: override the base .lab-card transition. The default has
   `transition: transform .55s` which smooths every JS scroll update, causing
   the card to lag 0.55s behind scroll and never reach its target while moving. */
body.has-scrub .scene-lab .lab-stack .lab-card{
  transform:translate(0,0) scale(.85);
  transition:
    background .25s ease,
    border-color .25s ease;
}

/* When a Lab tile is opened (active), drop the pin entirely so the tile's
   expanded layout can take over the section naturally. The JS scrubber
   notices the active state and clears its inline styles in tandem. */
body.has-scrub .scene-lab:has(.lab-stack[data-active]){
  height:auto;
}
body.has-scrub .scene-lab:has(.lab-stack[data-active]) .scene-pin{
  position:static;
  height:auto;
  overflow:visible;
  display:block;
  padding:var(--pad-y) 0;
}
body.has-scrub .scene-lab:has(.lab-stack[data-active]) .block-head,
body.has-scrub .scene-lab:has(.lab-stack[data-active]) .lab-stack .lab-card{
  opacity:1;
  transform:none;
  filter:none;
}
body.has-scrub .scene-contact .kicker        { transform:translateY(20px) }
body.has-scrub .scene-contact .contact-display{ transform:translateY(60px) scale(.92); filter:blur(6px) }
body.has-scrub .scene-contact .contact-lede  { transform:translateY(20px) }
body.has-scrub .scene-contact .contact-row   { transform:translateX(60px) }

/* ---- Word-by-word reveals (JS splits the text) ---- */
[data-words] .word{
  display:inline-block;
  opacity:0;
  transform:translateY(18px);
  transition:
    opacity .55s cubic-bezier(.2,.65,.2,1),
    transform .55s cubic-bezier(.2,.65,.2,1);
  transition-delay: calc(var(--i, 0) * 35ms);
  will-change: opacity, transform;
}
[data-words] .word em,
[data-words] .word b,
[data-words] .word strong{display:inline-block}
[data-words].words-in .word{
  opacity:1;
  transform:translateY(0);
}

@media (prefers-reduced-motion: reduce){
  [data-words] .word{transition:none;opacity:1;transform:none}
}

/* ---------- Command Palette ---------- */
.palette{
  position:fixed;inset:0;z-index:100;
  display:grid;align-items:start;justify-items:center;
  padding-top:14vh;
  background:color-mix(in srgb, var(--bg) 60%, transparent);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  animation:palFade .25s var(--ease);
}
.palette[hidden]{display:none}
@keyframes palFade{from{opacity:0;backdrop-filter:blur(0)}}

.palette-window{
  width:min(640px, 92vw);
  background:var(--surface);
  border:1px solid var(--rule-2);
  border-radius:14px;overflow:hidden;
  box-shadow:0 30px 80px rgba(0,0,0,.45), 0 0 0 1px rgba(0,0,0,.1);
  animation:palWin .35s var(--ease-out);
  position:relative;
}
@keyframes palWin{from{opacity:0;transform:translateY(20px) scale(.97)}}

.palette-search{
  display:flex;align-items:center;gap:12px;
  padding:18px 18px;border-bottom:1px solid var(--rule);
  position:relative;
}
.palette-search::before{
  content:"";position:absolute;left:18px;right:18px;top:0;height:1px;
  background:linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity:.6;
}
.palette-search svg{color:var(--text-3);flex-shrink:0}
.palette-search input{
  flex:1;background:transparent;border:0;outline:0;
  font-size:16px;color:var(--text);
  font-family:var(--sans);
}
.palette-search input::placeholder{color:var(--text-3)}

.palette-list{
  max-height:50vh;overflow-y:auto;
  padding:8px;
  scrollbar-width:thin;scrollbar-color:var(--rule-2) transparent;
}
.palette-cat{
  font-family:var(--mono);font-size:10.5px;color:var(--text-3);
  text-transform:uppercase;letter-spacing:.16em;
  padding:10px 10px 6px;
}
.palette-item{
  display:flex;align-items:center;gap:14px;
  padding:10px 12px;border-radius:8px;cursor:pointer;
  transition:background var(--t-fast);
  font-size:14px;
}
.palette-item.active, .palette-item:hover{background:var(--surface-2)}
.palette-item.active{box-shadow:inset 0 0 0 1px var(--accent)}
.palette-icon{
  width:28px;height:28px;display:grid;place-items:center;
  border-radius:8px;background:var(--bg-2);
  color:var(--accent);font-size:13px;flex-shrink:0;
}
.palette-label{flex:1;color:var(--text)}
.palette-hint{font-family:var(--mono);font-size:11px;color:var(--text-3)}

.palette-foot{
  display:flex;align-items:center;gap:14px;
  padding:10px 16px;
  border-top:1px solid var(--rule);background:var(--bg-2);
  font-family:var(--mono);font-size:11px;color:var(--text-3);
}
.palette-foot kbd{margin-right:4px}
.palette-foot-spacer{flex:1}
.palette-foot-brand{color:var(--text-2)}

/* Palette draggable / minimised / maximised */
.palette.dragged{align-items:start;justify-items:start;padding:0;background:transparent}
.palette.dragged .palette-window{position:fixed}

/* ==========================================================
   WORKSHOP — fullscreen hacker takeover
   Triggered by typing the password into the ⌘K palette. A black
   circle expands from the search bar, the page fades behind it,
   and a terminal-styled workspace types itself in.
   ========================================================== */

/* The portal: expanding circle that wipes the screen */
.ws-portal{
  position:fixed;inset:0;z-index:140;
  pointer-events:none;
  --ox:50%;--oy:50%;
  clip-path:circle(0 at var(--ox) var(--oy));
  -webkit-clip-path:circle(0 at var(--ox) var(--oy));
}
.ws-portal-bg{
  position:absolute;inset:0;
  background:
    radial-gradient(circle at 30% 20%, rgba(34,197,94,.06), transparent 60%),
    radial-gradient(circle at 70% 80%, rgba(249,115,22,.05), transparent 60%),
    #050605;
}
.ws-portal.opening{
  pointer-events:auto;
  transition:clip-path .9s cubic-bezier(.6,.04,.4,1);
  clip-path:circle(200% at var(--ox) var(--oy));
  -webkit-clip-path:circle(200% at var(--ox) var(--oy));
}
.ws-portal.closing{
  pointer-events:none;
  transition:clip-path .55s cubic-bezier(.5,.05,.5,1);
  clip-path:circle(0 at var(--ox) var(--oy));
  -webkit-clip-path:circle(0 at var(--ox) var(--oy));
}

/* The workshop itself: fullscreen terminal */
.workshop{
  position:fixed;inset:0;z-index:145;
  background:#050605;
  color:#c8e6c8;
  font-family:var(--mono);
  display:flex;flex-direction:column;
  overflow:hidden;
  opacity:0;
  transition:opacity .35s ease;
}
.workshop[hidden]{display:none}
.workshop.visible{opacity:1}

/* Scanlines overlay for CRT effect */
.ws-scanlines{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  background-image:repeating-linear-gradient(
    0deg,
    rgba(0,0,0,0) 0px,
    rgba(0,0,0,0) 2px,
    rgba(0,0,0,.18) 3px,
    rgba(0,0,0,.18) 4px
  );
  opacity:.45;
  mix-blend-mode:multiply;
}
/* Subtle film grain */
.ws-grain{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .35 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity:.08;
  mix-blend-mode:overlay;
}

/* Top bar: status line */
.ws-top{
  position:relative;z-index:5;
  display:flex;justify-content:space-between;align-items:center;
  padding:14px 24px;
  border-bottom:1px solid rgba(200,230,200,.12);
  background:rgba(0,0,0,.4);
  font-size:11px;letter-spacing:.06em;
}
.ws-top-l{display:flex;align-items:center;gap:10px;color:#7a9d7a;flex-wrap:wrap}
.ws-prompt{color:#22c55e;font-weight:500}
.ws-sep{color:#3a4f3a}
.ws-id{color:#c8e6c8}
.ws-sync{
  display:inline-flex;align-items:center;gap:7px;
  font-weight:500;
  padding:3px 10px;border-radius:99px;
  background:rgba(34,197,94,.08);
  border:1px solid rgba(34,197,94,.25);
  color:#86efac;
  font-size:11px;
  text-transform:uppercase;letter-spacing:.08em;
}
.ws-sync-dot{
  width:7px;height:7px;border-radius:50%;
  background:#fbbf24;
  box-shadow:0 0 8px currentColor;
  animation:wsDotPulse 1.4s ease-in-out infinite;
  flex-shrink:0;
}
.ws-sync.online{
  background:rgba(34,197,94,.12);
  border-color:rgba(34,197,94,.45);
  color:#bbf7d0;
}
.ws-sync.online .ws-sync-dot{background:#22c55e}
.ws-sync.offline{
  background:rgba(239,68,68,.12);
  border-color:rgba(239,68,68,.45);
  color:#fca5a5;
}
.ws-sync.offline .ws-sync-dot{background:#ef4444;animation:none}
.ws-sync.saving{
  background:rgba(251,191,36,.12);
  border-color:rgba(251,191,36,.45);
  color:#fde68a;
}
.ws-sync.saving .ws-sync-dot{background:#fbbf24;animation:wsDotPulse .8s ease-in-out infinite}
@keyframes wsDotPulse{50%{opacity:.4}}

.ws-top-r{display:flex;align-items:center;gap:10px}
.ws-top-r kbd{
  font-family:var(--mono);font-size:9px;
  background:rgba(200,230,200,.08);
  border:1px solid rgba(200,230,200,.18);
  color:#7a9d7a;padding:2px 6px;border-radius:3px;
}
.ws-close{
  background:transparent;border:1px solid rgba(200,230,200,.18);
  color:#c8e6c8;font-family:var(--mono);font-size:11px;
  padding:5px 12px;border-radius:4px;cursor:pointer;
  text-transform:uppercase;letter-spacing:.14em;
  transition:all .15s ease;
}
.ws-close:hover{background:rgba(239,68,68,.15);border-color:#ef4444;color:#fca5a5}

/* Boot sequence */
.ws-boot{
  position:relative;z-index:5;
  padding:18px 24px;
  font-size:12px;line-height:1.7;color:#7a9d7a;
  border-bottom:1px solid rgba(200,230,200,.08);
  min-height:0;
  max-height:0;
  overflow:hidden;
  transition:max-height .5s ease;
  background:rgba(0,0,0,.3);
}
.workshop.booting .ws-boot{max-height:180px;padding-top:14px;padding-bottom:14px}
.workshop.booted .ws-boot{max-height:0;padding-top:0;padding-bottom:0;border-bottom-width:0}
.ws-boot-line{display:block;animation:wsBootFade .2s ease}
.ws-boot-line .ok{color:#22c55e}
.ws-boot-line .acc{color:#fb923c}
.ws-boot-line .blip{
  display:inline-block;width:6px;height:11px;
  background:#22c55e;margin-left:4px;vertical-align:middle;
  animation:wsBlink 1s steps(2) infinite;
}
@keyframes wsBlink{50%{opacity:0}}
@keyframes wsBootFade{from{opacity:0;transform:translateX(-4px)}}

/* Stage (main content) */
.ws-stage{
  position:relative;z-index:5;
  flex:1;overflow-y:auto;
  padding:32px 24px;
  opacity:0;transform:translateY(8px);
  transition:opacity .55s ease .4s, transform .55s ease .4s;
}
.workshop.booted .ws-stage{opacity:1;transform:none}

.ws-hello{margin-bottom:32px;max-width:720px}
.ws-eye{
  display:inline-block;font-family:var(--mono);font-size:10.5px;
  color:#22c55e;text-transform:uppercase;letter-spacing:.2em;
  margin-bottom:10px;
  padding:3px 8px;
  border:1px solid rgba(34,197,94,.4);border-radius:3px;
  background:rgba(34,197,94,.08);
}
.ws-title{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(36px, 4.5vw, 56px);letter-spacing:-.02em;line-height:1;
  color:#e8f5e8;margin-bottom:14px;
}
.ws-title em{font-style:italic;color:#fb923c}
.ws-sub{
  font-family:var(--mono);font-size:13px;color:#7a9d7a;
  max-width:60ch;line-height:1.65;
}

/* Grid: panes */
.ws-grid{
  display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:18px;
  max-width:1400px;
}
@media(max-width:1100px){
  .ws-grid{grid-template-columns:1fr 1fr}
  .ws-notes{grid-column:1 / -1}
}
@media(max-width:680px){
  .ws-grid{grid-template-columns:1fr}
  .ws-notes{grid-column:auto}
}

.ws-pane{
  display:flex;flex-direction:column;gap:14px;
  padding:18px;border-radius:6px;
  background:rgba(20,30,20,.4);
  border:1px solid rgba(200,230,200,.12);
  min-height:300px;
  position:relative;
  transition:border-color .25s ease;
}
.ws-pane:hover{border-color:rgba(34,197,94,.35)}
.ws-pane::before{
  content:"";position:absolute;top:0;left:0;width:24px;height:1px;
  background:#22c55e;
  box-shadow:0 0 8px #22c55e;
}
.ws-pane-head{
  display:flex;justify-content:space-between;align-items:baseline;
}
.ws-pane h4{
  font-family:var(--mono);font-weight:500;font-size:12px;
  letter-spacing:.1em;color:#c8e6c8;text-transform:uppercase;
}
.ws-status{
  font-family:var(--mono);font-size:10px;color:#7a9d7a;
  text-transform:uppercase;letter-spacing:.14em;
}

/* Notes */
#ws-notes-input{
  flex:1;padding:14px 16px;border-radius:4px;
  background:rgba(0,0,0,.45);border:1px solid rgba(200,230,200,.1);
  color:#c8e6c8;font-family:var(--mono);font-size:13px;
  line-height:1.6;outline:none;resize:none;tab-size:2;
  caret-color:#22c55e;
  transition:border-color .2s;
}
#ws-notes-input:focus{border-color:#22c55e}
#ws-notes-input::placeholder{color:#3a4f3a}

/* Todo + Habit form (terminal-style) */
.ws-todo-form,.ws-habit-form{
  display:flex;align-items:center;gap:8px;
  padding:10px 12px;border-radius:4px;
  background:rgba(0,0,0,.45);border:1px solid rgba(200,230,200,.1);
}
.ws-todo-prompt{color:#22c55e;font-weight:500;flex-shrink:0}
.ws-todo-form input,.ws-habit-form input{
  flex:1;background:transparent;border:0;outline:0;
  color:#c8e6c8;font-family:var(--mono);font-size:13px;
}
.ws-todo-form input::placeholder,.ws-habit-form input::placeholder{color:#3a4f3a}

.ws-todo-list,.ws-habit-list{
  display:flex;flex-direction:column;gap:3px;
  flex:1;overflow-y:auto;max-height:300px;
  font-family:var(--mono);font-size:13px;
}
.ws-todo-list li,.ws-habit-list li{
  display:flex;align-items:center;gap:10px;
  padding:8px 10px;border-radius:3px;
  border:1px solid transparent;
  transition:all .15s ease;
}
.ws-todo-list li:hover,.ws-habit-list li:hover{
  background:rgba(34,197,94,.06);
  border-color:rgba(34,197,94,.18);
}
.ws-todo-list li.done{opacity:.4}
.ws-todo-list li.done .ws-todo-text{text-decoration:line-through;color:#7a9d7a}
.ws-check{
  width:14px;height:14px;border-radius:2px;
  border:1.5px solid rgba(200,230,200,.25);
  cursor:pointer;flex-shrink:0;display:grid;place-items:center;
  background:transparent;color:#050605;
  transition:all .15s ease;
}
.ws-check:hover{border-color:#22c55e}
.ws-todo-list li.done .ws-check,
.ws-habit-list li.done-today .ws-check{
  background:#22c55e;border-color:#22c55e;
  box-shadow:0 0 6px rgba(34,197,94,.5);
}
.ws-check svg{display:block;opacity:0;transition:opacity .15s}
.ws-todo-list li.done .ws-check svg,
.ws-habit-list li.done-today .ws-check svg{opacity:1}
.ws-todo-text{flex:1;color:#c8e6c8}
.ws-del{
  background:transparent;border:0;color:#5a6a5a;cursor:pointer;
  font-size:14px;padding:0 6px;line-height:1;opacity:0;
  transition:opacity .15s, color .15s;
}
.ws-todo-list li:hover .ws-del,.ws-habit-list li:hover .ws-del,.ws-bm-list li:hover .ws-del{opacity:1}
.ws-del:hover{color:#ef4444}

/* Pomodoro */
.ws-pomo-time{
  font-family:var(--serif);font-size:64px;text-align:center;
  letter-spacing:-.02em;color:#e8f5e8;
  font-feature-settings:'tnum';margin:auto 0;
  text-shadow:0 0 18px rgba(232,245,232,.15);
}
.ws-pomo-actions{display:flex;justify-content:center;gap:6px}
.ws-pomo-progress{
  height:3px;border-radius:0;background:rgba(0,0,0,.4);
  overflow:hidden;margin-top:4px;
}
.ws-pomo-progress i{
  display:block;height:100%;width:0;
  background:#fb923c;
  box-shadow:0 0 8px #fb923c;
  transition:width .9s linear, background .25s;
}
.ws-pomo.break .ws-pomo-progress i{background:#22c55e;box-shadow:0 0 8px #22c55e}
.ws-pomo.break .ws-pomo-time{color:#86efac}

/* Buttons */
.ws-btn{
  font-family:var(--mono);font-size:11px;letter-spacing:.06em;
  padding:7px 14px;border-radius:3px;
  background:rgba(34,197,94,.12);
  border:1px solid rgba(34,197,94,.35);
  color:#86efac;cursor:pointer;
  transition:all .15s ease;
  text-transform:uppercase;
}
.ws-btn:hover{background:rgba(34,197,94,.22);border-color:#22c55e;color:#bbf7d0}
.ws-btn-ghost{
  background:transparent;border-color:rgba(200,230,200,.15);color:#7a9d7a;
}
.ws-btn-ghost:hover{border-color:rgba(200,230,200,.35);color:#c8e6c8;background:rgba(200,230,200,.04)}

/* Bookmarks */
.ws-bm-form{
  display:grid;grid-template-columns:1fr 1.4fr auto;gap:6px;
}
.ws-bm-form input{
  padding:9px 11px;border-radius:3px;
  background:rgba(0,0,0,.45);border:1px solid rgba(200,230,200,.1);
  color:#c8e6c8;font-family:var(--mono);font-size:12px;
  outline:none;transition:border-color .2s;
}
.ws-bm-form input::placeholder{color:#3a4f3a}
.ws-bm-form input:focus{border-color:#22c55e}
.ws-bm-list{
  display:flex;flex-direction:column;gap:3px;
  flex:1;overflow-y:auto;max-height:300px;
  font-family:var(--mono);font-size:12.5px;
}
.ws-bm-list li{
  display:flex;align-items:center;gap:10px;
  padding:8px 10px;border-radius:3px;
  border:1px solid transparent;
  transition:all .15s ease;
}
.ws-bm-list li:hover{background:rgba(34,197,94,.06);border-color:rgba(34,197,94,.18)}
.ws-bm-list a{
  flex:1;color:#c8e6c8;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:color .15s;
}
.ws-bm-list a:hover{color:#86efac;text-decoration:underline}
.ws-bm-list .ws-bm-host{color:#7a9d7a;font-size:10.5px}

/* Habit streak indicator */
.ws-habit-list li{position:relative}
.ws-habit-list .ws-habit-streak{
  font-size:10.5px;color:#7a9d7a;
  padding:2px 7px;border-radius:2px;
  background:rgba(0,0,0,.3);border:1px solid rgba(200,230,200,.08);
}
.ws-habit-list li.done-today .ws-habit-streak{color:#fb923c;border-color:rgba(251,146,60,.35)}

/* Footer */
.ws-foot{
  position:relative;z-index:5;
  display:flex;justify-content:space-between;align-items:center;
  padding:8px 24px;
  border-top:1px solid rgba(200,230,200,.08);
  background:rgba(0,0,0,.4);
  font-size:10.5px;color:#5a6a5a;
  text-transform:uppercase;letter-spacing:.14em;
}

/* Custom scrollbar inside the workshop only */
.workshop ::-webkit-scrollbar{width:8px;height:8px}
.workshop ::-webkit-scrollbar-track{background:transparent}
.workshop ::-webkit-scrollbar-thumb{background:rgba(34,197,94,.2);border-radius:0}
.workshop ::-webkit-scrollbar-thumb:hover{background:rgba(34,197,94,.4)}

/* Selection */
.workshop ::selection{background:rgba(34,197,94,.35);color:#e8f5e8}

@media(prefers-reduced-motion:reduce){
  .ws-portal,.workshop,.ws-stage,.ws-boot{transition:none !important}
  .workshop{opacity:1}
  .workshop.booted .ws-stage{opacity:1;transform:none}
}

/* ---------- Toast ---------- */
.toast{
  position:fixed;left:50%;bottom:90px;transform:translate(-50%, 30px);
  padding:12px 20px;border-radius:10px;
  background:var(--text);color:var(--bg);
  z-index:90;opacity:0;transition:.3s var(--ease);
  font-size:14px;font-weight:500;
  box-shadow:0 16px 40px rgba(0,0,0,.25);
}
.toast.show{opacity:1;transform:translate(-50%, 0)}

/* ---------- Reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    transition-duration:.001ms !important;
    animation-timeline:none !important;
  }
  html{scroll-behavior:auto}
  .marquee-track{animation:none}
  .verb{animation:none !important}
  /* Force final state for scroll-driven reveals so users still see content */
  [data-reveal],.block-head,.cap-grid .cap,.cap-glyph,
  .lab-stack .lab-card,.work-item,.work-meta,.work-body,
  .edu-list li,.contact-display,.contact-row,
  .hero-title,.hero-sub,.marquee,.prose-lead,.stack-col,
  [data-words] .word{
    opacity:1 !important;transform:none !important;filter:none !important;
  }
}

/* ---------- Print ---------- */
@media print{
  .nav,.footer,.palette,.toast,.hero-cta,.brand-mark,.marquee,.tool-actions,.pads,.pg{display:none !important}
  body{background:#fff;color:#000}
  body::before{display:none}
  .block{padding:30px 20px;border-color:#ccc}
  .display,.hero-title,.work-title,.contact-value,.cap h3,.tool-title{color:#000 !important}
  .display em,.hero-title em,.tool-emoji,.cap-glyph{color:#444}
  .hero{min-height:auto;padding:20px}
  .lab{display:none}
}
