/* ==========================================================================
   REYNSI — cold world / demo tape
   Static build of the Claude Design Canvas export.

   Sizing note: the desktop and mobile exports differ only in numbers, so the
   type/space ramp is expressed as clamp(mobile, calc(...), desktop) linearly
   interpolated between a 390px and a 1440px viewport. Genuine art-direction
   differences (hero framing, watermark placement) live in the single
   @media (max-width: 640px) block at the bottom.

   Accent = #c9b8ff (lavender), the canvas default for accentColor.
   ========================================================================== */

*{box-sizing:border-box;}

body{
  margin:0;
  background:oklch(12% 0.01 250);
}

:root{
  --accent:#c9b8ff;
  --ink:oklch(94% 0.01 250);
  --bg:oklch(12% 0.01 250);
  --bg-alt:oklch(14% 0.012 250);
  --line:oklch(30% 0.02 250 / 0.4);
  /* The export specified Impact, which ships on macOS/Windows but not on
     Android or most Linux. Anton is a near-identical condensed grotesque and
     is loaded as the primary face; Impact and friends stay behind it so
     machines that have it render the original metrics. */
  --display:'Anton',Impact,'Haettenschweiler','Arial Narrow Bold',sans-serif;
  --mono:'JetBrains Mono',monospace;
}

/* --------------------------------------------------------------------------
   Keyframes (lifted verbatim from the export's <helmet>)
   -------------------------------------------------------------------------- */

@keyframes edgeGlitchBase{0%,86%,100%{transform:translate(0,0) skewX(0deg);clip-path:inset(0 0 0 0);}87%{transform:translate(-3px,0) skewX(-2deg);clip-path:inset(0 0 62% 0);}88.5%{transform:translate(4px,1px) skewX(1deg);clip-path:inset(40% 0 0 0);}90%{transform:translate(-2px,-1px) skewX(0deg);clip-path:inset(0 0 0 0);}93%{transform:translate(2px,0);clip-path:inset(20% 0 20% 0);}95%{transform:translate(0,0);clip-path:inset(0 0 0 0);}}
@keyframes edgeGlitchR{0%,86%,100%{transform:translate(0,0);opacity:0;clip-path:inset(0 0 0 0);}87%{transform:translate(7px,-2px);opacity:.85;clip-path:inset(8% 0 45% 0);}88.5%{transform:translate(-5px,1px);opacity:.7;clip-path:inset(55% 0 5% 0);}90%{transform:translate(5px,0);opacity:.8;clip-path:inset(0 0 0 0);}93%{transform:translate(-4px,1px);opacity:.6;}95%{transform:translate(0,0);opacity:0;}}
@keyframes edgeGlitchB{0%,86%,100%{transform:translate(0,0);opacity:0;}87%{transform:translate(-8px,2px);opacity:.75;clip-path:inset(0 0 68% 0);}88.5%{transform:translate(6px,-1px);opacity:.65;clip-path:inset(30% 0 30% 0);}90%{transform:translate(-6px,0);opacity:.75;}93%{transform:translate(4px,-1px);opacity:.55;}95%{transform:translate(0,0);opacity:0;}}
@keyframes tickerScroll{0%{transform:translateX(0);}100%{transform:translateX(-50%);}}
@keyframes menuGlitchRGB{0%,88%,100%{transform:translate(0,0);opacity:0;}89%{transform:translate(-3px,1px);opacity:.7;}91%{transform:translate(3px,-1px);opacity:.6;}93%{transform:translate(-2px,0);opacity:.5;}95%{transform:translate(0,0);opacity:0;}}
@keyframes crtPowerOff{0%{transform:scale(1,1) skewX(0deg) translate(0,0);filter:brightness(1) contrast(1) saturate(1);opacity:1;}8%{transform:scale(1.01,1) skewX(1deg) translate(2px,0);filter:brightness(1.1) contrast(1.05);}16%{transform:scale(0.99,1.02) skewX(-2deg) translate(-3px,1px);filter:brightness(1.3) contrast(1.15);}24%{transform:scale(1.02,0.97) skewX(2deg) translate(3px,-1px);filter:brightness(1.15) contrast(1.1);}34%{transform:scale(1.06,0.85) skewX(-3deg) translate(-2px,2px);filter:brightness(1.7) contrast(1.3) saturate(1.3);}46%{transform:scale(1.16,0.38) skewX(4deg) translate(4px,-2px);filter:brightness(2.6) contrast(1.45) saturate(1.5);}58%{transform:scale(1.28,0.09) skewX(-2deg);filter:brightness(3.4) contrast(1.55);}72%{transform:scale(0.5,0.018) skewX(1deg);filter:brightness(4.8) contrast(1.65);opacity:1;}88%{transform:scale(0.14,0.004);filter:brightness(7.5);opacity:1;}100%{transform:scale(0.02,0.0004);filter:brightness(11);opacity:0;}}
@keyframes introStaticBurst{0%{opacity:0;}8%{opacity:.9;}18%{opacity:.25;}28%{opacity:1;}38%{opacity:.2;}50%{opacity:.9;}62%{opacity:.35;}75%{opacity:1;}88%{opacity:.2;}100%{opacity:0;}}
@keyframes introFlash{0%{opacity:0;}10%{opacity:.5;}22%{opacity:0;}55%{opacity:0;}66%{opacity:1;}80%{opacity:.55;}100%{opacity:0;}}
@keyframes crtRGBRedRefined{0%{opacity:0;transform:translate(0,0);}35%{opacity:.55;transform:translate(-1.2px,0.5px);}65%{opacity:.4;transform:translate(-2px,0.8px);}100%{opacity:0;transform:translate(-0.8px,0.3px);}}
@keyframes crtRGBBlueRefined{0%{opacity:0;transform:translate(0,0);}35%{opacity:.5;transform:translate(1.2px,-0.5px);}65%{opacity:.35;transform:translate(2px,-0.8px);}100%{opacity:0;transform:translate(0.8px,-0.3px);}}
@keyframes scanDrift{0%{background-position-y:0;}100%{background-position-y:600px;}}

/* Equalizer button — the standalone export's keyframes, converted from `height`
   to `transform:scaleY()`. Every value is that keyframe's pixel height over
   that bar's own base height, so the motion is proportionally identical to the
   export and independent of the 0.78 scale-down. Percentages are untouched. */

@keyframes idleBar1{0%,100%{transform:scaleY(1);}50%{transform:scaleY(1.6);}}      /* 10 -> 16 */
@keyframes idleBar2{0%,100%{transform:scaleY(1);}50%{transform:scaleY(0.6);}}      /* 20 -> 12 */
@keyframes idleBar3{0%,100%{transform:scaleY(1);}50%{transform:scaleY(1.5714);}}   /* 14 -> 22 */
@keyframes idleBar4{0%,100%{transform:scaleY(1);}50%{transform:scaleY(0.625);}}    /* 24 -> 15 */
@keyframes idleBar5{0%,100%{transform:scaleY(1);}50%{transform:scaleY(2.25);}}     /* 8 -> 18 */

/* base 10 */
@keyframes activeBar1{0%{transform:scaleY(1);}15%{transform:scaleY(3);}30%{transform:scaleY(0.6);}45%{transform:scaleY(2.6);}60%{transform:scaleY(1.2);}75%{transform:scaleY(2.2);}90%{transform:scaleY(0.8);}100%{transform:scaleY(1);}}
/* base 20 */
@keyframes activeBar2{0%{transform:scaleY(1);}12%{transform:scaleY(0.4);}28%{transform:scaleY(1.6);}42%{transform:scaleY(0.7);}58%{transform:scaleY(1.4);}74%{transform:scaleY(0.5);}88%{transform:scaleY(1.2);}100%{transform:scaleY(1);}}
/* base 14 */
@keyframes activeBar3{0%{transform:scaleY(1);}18%{transform:scaleY(2.2857);}33%{transform:scaleY(0.7143);}48%{transform:scaleY(1.7143);}63%{transform:scaleY(0.4286);}78%{transform:scaleY(2);}92%{transform:scaleY(1);}100%{transform:scaleY(1);}}
/* base 24 */
@keyframes activeBar4{0%{transform:scaleY(1);}14%{transform:scaleY(0.4167);}30%{transform:scaleY(1.25);}46%{transform:scaleY(0.3333);}62%{transform:scaleY(1.0833);}80%{transform:scaleY(0.5);}100%{transform:scaleY(1);}}
/* base 8 */
@keyframes activeBar5{0%{transform:scaleY(1);}16%{transform:scaleY(3.25);}32%{transform:scaleY(1.5);}50%{transform:scaleY(4);}66%{transform:scaleY(1);}82%{transform:scaleY(2.5);}100%{transform:scaleY(1);}}

@keyframes glitchFlash{0%{opacity:0;}10%{opacity:.6;}20%{opacity:0;}35%{opacity:.4;}45%{opacity:0;}100%{opacity:0;}}

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */

.main{
  font-family:var(--display);
  background:var(--bg);
  color:var(--ink);
  position:relative;
  overflow-x:hidden;
  min-height:100vh;
  /* mainStyle: hidden while the intro is up, faded in once entered */
  opacity:0;
  transition:opacity 1.2s ease 0.1s;
}
body[data-entered] .main{opacity:1;}

.scanlines{
  position:fixed;
  inset:0;
  pointer-events:none;
  z-index:5;
  opacity:0.05;
  background:repeating-linear-gradient(0deg,#fff 0px,#fff 1px,transparent 1px,transparent 3px);
  animation:scanDrift 10s linear infinite;
}

.wrap{
  max-width:1000px;
  margin:0 auto;
  position:relative;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.header{
  position:fixed;
  top:0;
  left:0;
  right:0;
  /* Above the menu overlay (50), below the intro (999). The menu has no close
     button: the equalizer is the close control, so it has to stay on top and
     keep animating while the menu is open. Held at all times rather than
     switched on [data-menu-open] — the overlay fades out over .35s, and a
     z-index that dropped on click would flicker the button behind it. */
  z-index:60;
  display:flex;
  justify-content:space-between;
  align-items:center;
  /* The header's height is set by its tallest child, the menu button. The
     vertical ramp is the export's shifted down 3px so the 56x50 equalizer
     lands on exactly the height the old 48x44 mark produced (76 / 77.9 /
     83.9px at 320 / 640 / 1440) — the header must not move. */
  padding:clamp(13px,calc(11.5px + 0.38vw),17px) clamp(20px,calc(15.5px + 1.14vw),32px);
  backdrop-filter:blur(6px);
  background:linear-gradient(oklch(12% 0.01 250 / 0.6),transparent);
}

.header__mark{
  font-family:var(--display);
  font-size:clamp(18px,calc(16.5px + 0.38vw),22px);
  letter-spacing:1px;
  color:var(--ink);
}

/* --------------------------------------------------------------------------
   Equalizer menu button

   Ported from "Reynsi Equalizer Icon (standalone).html", scaled by ~0.78 from
   the export's 72x64 down to 56x50 so it fits the header without changing its
   height (the header's vertical padding is pulled in by 3px to absorb the
   6px the button gained over the old 48x44 mark). Still well over the 48x44
   minimum hit target. Accent is var(--accent), not the export's #a8c8ff, and
   the export's PLAYING/READY/STANDBY label was preview chrome — dropped.

   Scaled:  button 72x64 -> 56x50   box 32x36 -> 25x28   bar 4px -> 3px
            gap 4px -> 3px          base heights [10,20,14,24,8] -> [8,16,11,19,6]
            glitch inset -6px -10px -> -5px -8px
   -------------------------------------------------------------------------- */

.equalizer{
  background:none;
  border:1px solid oklch(40% 0.02 250);
  border-radius:0;
  width:56px;
  height:50px;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  transition:border-color .2s ease;
  padding:0;
}

.equalizer__box{
  position:relative;
  width:25px;
  height:28px;
  display:flex;
  align-items:flex-end;
  justify-content:center;
  gap:3px;
}

/* The export animated `height`, which relayouts five elements every frame,
   forever, on every page load. scaleY from a bottom origin is the same motion
   composited: the bars are already bottom-aligned, so they grow upward exactly
   as before. Animation name and duration ride on custom properties so the
   hover / active / reduced-motion layers can override one axis at a time. */
.equalizer__bar{
  width:3px;
  /* Five 3px bars + four 3px gaps is 27px in a 25px box, so the default
     flex-shrink would quietly sand them down to 2.6px and blur every edge.
     (The export has the same bug: its declared 4px bars render at 3.2px.)
     Pinned to whole pixels; the 1px of overflow per side has nothing to clip
     against and the cluster stays centred. */
  flex-shrink:0;
  display:block;
  background:oklch(85% 0.01 250);
  transform-origin:bottom;
  transition:background .2s ease;
  animation:var(--eq-anim) var(--eq-dur) ease-in-out infinite;
}

.equalizer__bar:nth-child(1){height:8px; --eq-anim:idleBar1;--eq-dur:1.8s;}
.equalizer__bar:nth-child(2){height:16px;--eq-anim:idleBar2;--eq-dur:2.1s;}
.equalizer__bar:nth-child(3){height:11px;--eq-anim:idleBar3;--eq-dur:1.6s;}
.equalizer__bar:nth-child(4){height:19px;--eq-anim:idleBar4;--eq-dur:2.3s;}
.equalizer__bar:nth-child(5){height:6px; --eq-anim:idleBar5;--eq-dur:1.9s;}

.equalizer__glitch{
  position:absolute;
  inset:-5px -8px;
  background:var(--accent);
  mix-blend-mode:screen;
  pointer-events:none;
  opacity:0;
}

/* hover:hover so the lit state can't stick on a touch device after a tap */
@media (hover: hover){
  .equalizer:hover{border-color:var(--accent);}
  .equalizer:hover .equalizer__bar{background:oklch(97% 0.01 250);}
  .equalizer:hover .equalizer__bar:nth-child(1){--eq-dur:1.1s;}
  .equalizer:hover .equalizer__bar:nth-child(2){--eq-dur:1.3s;}
  .equalizer:hover .equalizer__bar:nth-child(3){--eq-dur:1.0s;}
  .equalizer:hover .equalizer__bar:nth-child(4){--eq-dur:1.4s;}
  .equalizer:hover .equalizer__bar:nth-child(5){--eq-dur:1.2s;}
}

/* 800ms burst on press — site.js puts data-active on the button. Must come
   after the hover block: pressing with a mouse is also hovering. */
.equalizer[data-active]{border-color:var(--accent);}
.equalizer[data-active] .equalizer__bar{background:var(--accent);}
.equalizer[data-active] .equalizer__bar:nth-child(1){--eq-anim:activeBar1;--eq-dur:.7s;}
.equalizer[data-active] .equalizer__bar:nth-child(2){--eq-anim:activeBar2;--eq-dur:.7s;}
.equalizer[data-active] .equalizer__bar:nth-child(3){--eq-anim:activeBar3;--eq-dur:.7s;}
.equalizer[data-active] .equalizer__bar:nth-child(4){--eq-anim:activeBar4;--eq-dur:.7s;}
.equalizer[data-active] .equalizer__bar:nth-child(5){--eq-anim:activeBar5;--eq-dur:.7s;}
.equalizer[data-active] .equalizer__glitch{animation:glitchFlash .5s ease-out;}

/* With the menu open the button is the close control, so the pressed look does
   not expire with the 800ms burst — it holds for as long as the menu is up and
   drops back to idle when it closes. Descendant selectors are one step longer
   than the :hover block above so a mouse resting on the button can't pull the
   bars back to hover speed mid-burst. The one-shot glitch flash stays on
   [data-active] alone: it belongs to the press, not to the open state. */
body[data-menu-open] .equalizer{border-color:var(--accent);}
body[data-menu-open] .equalizer .equalizer__bar{background:var(--accent);}
body[data-menu-open] .equalizer .equalizer__bar:nth-child(1){--eq-anim:activeBar1;--eq-dur:.7s;}
body[data-menu-open] .equalizer .equalizer__bar:nth-child(2){--eq-anim:activeBar2;--eq-dur:.7s;}
body[data-menu-open] .equalizer .equalizer__bar:nth-child(3){--eq-anim:activeBar3;--eq-dur:.7s;}
body[data-menu-open] .equalizer .equalizer__bar:nth-child(4){--eq-anim:activeBar4;--eq-dur:.7s;}
body[data-menu-open] .equalizer .equalizer__bar:nth-child(5){--eq-anim:activeBar5;--eq-dur:.7s;}

/* --------------------------------------------------------------------------
   Menu overlay  (menuOverlayStyle)
   -------------------------------------------------------------------------- */

.menu{
  position:fixed;
  inset:0;
  z-index:50;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  padding:0 clamp(20px,calc(18.5px + 0.38vw),24px);
  background:#0a0c10;
  opacity:0;
  transform:scale(1.04);
  pointer-events:none;
  transition:opacity .35s ease, transform .35s ease;
}
body[data-menu-open] .menu{
  opacity:1;
  transform:scale(1);
  pointer-events:auto;
}

.menu__img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center 35%;
  filter:grayscale(1) contrast(1.3) brightness(0.35) saturate(0.8);
}
.menu__tint{
  position:absolute;
  inset:0;
  background:oklch(9% 0.01 250 / 0.55);
}
.menu__scanlines{
  position:absolute;
  inset:0;
  opacity:.06;
  background:repeating-linear-gradient(0deg,#fff 0px,#fff 1px,transparent 1px,transparent 3px);
  pointer-events:none;
}

.menu__inner{
  position:relative;
  z-index:2;
}

.menu__eyebrow{
  font-family:var(--mono);
  font-size:clamp(11px,calc(10.25px + 0.19vw),13px);
  letter-spacing:clamp(3px,calc(2.63px + 0.1vw),4px);
  color:oklch(80% 0.02 250);
  margin-bottom:clamp(22px,calc(21.25px + 0.19vw),24px);
  text-transform:uppercase;
}

.menu__item{
  position:relative;
  margin-bottom:clamp(14px,calc(12.5px + 0.38vw),18px);
}

.menu__link{
  font-family:var(--display);
  color:oklch(97% 0.01 250);
  font-size:clamp(40px,calc(34px + 1.52vw),56px);
  letter-spacing:1px;
  text-decoration:none;
  display:block;
}
.menu__item .menu__link{position:relative;z-index:3;}
.menu__inner > .menu__link{margin-bottom:clamp(14px,calc(12.5px + 0.38vw),18px);}
.menu__inner > .menu__link--last{margin-bottom:clamp(32px,calc(29px + 0.76vw),40px);}

.menu__link-ghost{
  position:absolute;
  top:0;
  left:0;
  right:0;
  font-family:var(--display);
  color:oklch(72% 0.14 25);
  font-size:clamp(40px,calc(34px + 1.52vw),56px);
  letter-spacing:1px;
  mix-blend-mode:screen;
  animation:menuGlitchRGB 6.5s infinite;
}

.menu__social{
  display:flex;
  gap:clamp(16px,calc(14.5px + 0.38vw),20px);
  justify-content:center;
  font-family:var(--mono);
  font-size:clamp(11px,calc(10.25px + 0.19vw),13px);
  letter-spacing:clamp(1.2px,calc(1.09px + 0.03vw),1.5px);
  color:var(--accent);
}
.menu__social a{
  color:var(--accent);
  text-decoration:none;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero{
  position:relative;
  height:100vh;
  min-height:clamp(640px,calc(625px + 3.81vw),680px);
  display:flex;
  align-items:flex-end;
  overflow:hidden;
  clip-path:polygon(0 0,100% 0,100% 94%,0 100%);
}

/* <picture> wrappers: absolutely filled so the img keeps behaving exactly as
   it did before it was wrapped (and stays out of .hero/.menu's flex flow). */
.hero__pic,
.menu__pic{
  position:absolute;
  inset:0;
}

.hero__img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center 42%;
  filter:grayscale(1) contrast(1.25) brightness(0.6) saturate(0.9);
}

.hero__fade{
  position:absolute;
  inset:0;
  background:linear-gradient(to top,oklch(12% 0.01 250) 5%,oklch(12% 0.01 250 / 0.2) 45%,oklch(12% 0.01 250 / 0.55) 100%);
}

.hero__vignette{
  position:absolute;
  inset:0;
  background:linear-gradient(180deg,oklch(30% 0.03 250 / 0.35),transparent 40%);
  mix-blend-mode:multiply;
}

.hero__watermark{
  position:absolute;
  top:22%;
  right:-6%;
  font-family:var(--mono);
  font-size:clamp(140px,26vw,340px);
  font-weight:700;
  color:oklch(94% 0.01 250 / 0.04);
  letter-spacing:-6px;
  pointer-events:none;
  line-height:1;
  z-index:1;
}

.hero__content{
  position:relative;
  z-index:2;
  padding:0 0 72px 40px;
  max-width:1200px;
}

.eyebrow{
  font-family:var(--mono);
  font-size:clamp(11px,calc(10.6px + 0.1vw),12px);
  letter-spacing:clamp(2.5px,calc(2.3px + 0.05vw),3px);
  text-transform:uppercase;
  color:var(--accent);
  margin-bottom:clamp(22px,calc(19.75px + 0.57vw),28px);
}

.eyebrow--hero{
  font-size:clamp(10px,calc(9.25px + 0.19vw),12px);
  letter-spacing:clamp(3px,calc(2.25px + 0.19vw),5px);
  margin-bottom:clamp(14px,calc(12.5px + 0.38vw),18px);
  display:flex;
  align-items:center;
  gap:clamp(8px,calc(7.25px + 0.19vw),10px);
}

.eyebrow__rule{
  width:clamp(22px,calc(19.75px + 0.57vw),28px);
  height:1px;
  background:var(--accent);
  display:inline-block;
}

.wordmark{
  position:relative;
  transform:rotate(-1.5deg);
  margin-left:clamp(-6px,calc(-3.25px - 0.19vw),-4px);
}

.wordmark h1{
  font-family:var(--display);
  font-size:clamp(56px,calc(45px + 10.5vw),196px);
  line-height:0.82;
  margin:0;
  letter-spacing:clamp(-4px,calc(-1.25px - 0.19vw),-2px);
}

.wordmark__base{
  position:relative;
  z-index:3;
  color:oklch(97% 0.01 250);
  animation:edgeGlitchBase 6.5s infinite;
}
.wordmark__r{
  position:absolute;
  top:0;
  left:0;
  z-index:2;
  color:oklch(72% 0.14 25);
  mix-blend-mode:screen;
  animation:edgeGlitchR 6.5s infinite;
}
.wordmark__b{
  position:absolute;
  top:0;
  left:0;
  z-index:2;
  color:oklch(72% 0.14 240);
  mix-blend-mode:screen;
  animation:edgeGlitchB 6.5s infinite;
}

.hero__tagline{
  font-family:var(--mono);
  font-size:clamp(14px,calc(13.25px + 0.19vw),16px);
  color:oklch(78% 0.02 250);
  max-width:clamp(320px,calc(268px + 13.33vw),460px);
  margin:clamp(20px,calc(17.75px + 0.57vw),26px) 0 0;
  line-height:1.6;
}

/* --------------------------------------------------------------------------
   Ticker
   -------------------------------------------------------------------------- */

.ticker{
  height:clamp(64px,calc(43px + 5.33vw),120px);
  background:var(--bg-alt);
  overflow:hidden;
  white-space:nowrap;
  display:flex;
  align-items:center;
  border-bottom:1px solid var(--line);
}

.ticker__track{
  display:inline-flex;
  animation:tickerScroll 22s linear infinite;
}

.ticker__text{
  font-family:var(--display);
  font-size:clamp(22px,calc(13.8px + 2.1vw),44px);
  letter-spacing:clamp(1.5px,calc(1.3px + 0.05vw),2px);
  color:oklch(30% 0.02 250);
  padding-right:clamp(28px,calc(20.5px + 1.9vw),48px);
}

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */

.section{
  position:relative;
  padding:clamp(64px,calc(47px + 4.38vw),110px) clamp(20px,calc(15.5px + 1.14vw),32px) clamp(76px,calc(56px + 5.14vw),130px);
  overflow:hidden;
}

.section--bio{background:var(--bg-alt);}
.section--demos{
  background:var(--bg);
  border-top:1px solid var(--line);
}
.section--contact{
  background:var(--bg-alt);
  border-top:1px solid var(--line);
  padding-top:clamp(68px,calc(48.5px + 4.95vw),120px);
  padding-bottom:clamp(84px,calc(59.5px + 6.29vw),150px);
}

.hatch{
  position:absolute;
  inset:0;
  pointer-events:none;
  opacity:.05;
  background:repeating-linear-gradient(-35deg,oklch(94% 0.01 250) 0px,oklch(94% 0.01 250) 2px,transparent 2px,transparent 26px);
}

.ghost{
  position:absolute;
  font-family:var(--display);
  font-size:clamp(70px,calc(89px + 9.07vw),220px);
  letter-spacing:clamp(-4px,calc(-1.25px - 0.19vw),-2px);
  color:oklch(94% 0.01 250 / 0.035);
  line-height:1;
  pointer-events:none;
  white-space:nowrap;
}
.ghost--bio{top:-8%;right:-14%;transform:rotate(-4deg);}
.ghost--demos{bottom:-6%;left:-10%;transform:rotate(4deg);}
.ghost--contact{bottom:-10%;right:-12%;transform:rotate(-3deg);}

.bio__text{
  font-family:var(--display);
  font-size:clamp(20px,calc(18px + 1.39vw),38px);
  line-height:1.35;
  color:oklch(93% 0.01 250);
  margin:0;
  white-space:pre-line;
  text-wrap:pretty;
  max-width:820px;
}

.section__head{
  display:flex;
  align-items:baseline;
  gap:clamp(12px,calc(10.5px + 0.38vw),16px);
  margin-bottom:clamp(32px,calc(27.5px + 1.14vw),44px);
}
.eyebrow--inline{margin-bottom:0;}
.section__rule{
  flex:1;
  height:1px;
  background:oklch(30% 0.02 250 / 0.5);
}

.section__title{
  font-family:var(--display);
  font-size:clamp(30px,calc(26px + 2.37vw),60px);
  margin:0 0 clamp(28px,calc(23.5px + 1.14vw),40px);
  letter-spacing:-1px;
  color:oklch(96% 0.01 250);
}
.section--contact .eyebrow{margin-bottom:clamp(18px,calc(17.25px + 0.19vw),20px);}
.section--contact .section__title{margin-bottom:clamp(20px,calc(18.5px + 0.38vw),24px);}

/* --------------------------------------------------------------------------
   Embeds
   -------------------------------------------------------------------------- */

.embed{
  background:oklch(16% 0.014 250);
  border-left:3px solid var(--accent);
}
.embed--soundcloud{
  padding:clamp(12px,calc(10.5px + 0.38vw),16px);
  margin-bottom:clamp(18px,calc(15.75px + 0.57vw),24px);
}
.embed--spotify{overflow:hidden;}

.embed__frame{
  border:none;
  display:block;
}
.embed__frame--soundcloud{
  height:clamp(260px,calc(245px + 3.81vw),300px);
}

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */

.contact__frame{
  position:absolute;
  bottom:clamp(-60px,calc(-32.5px - 1.9vw),-40px);
  right:clamp(-40px,calc(-26.25px - 0.95vw),-30px);
  width:clamp(200px,calc(148px + 13.33vw),340px);
  height:clamp(200px,calc(148px + 13.33vw),340px);
  border:1px solid oklch(94% 0.01 250 / 0.06);
  transform:rotate(18deg);
  pointer-events:none;
}

.contact__copy{
  font-family:var(--mono);
  font-size:clamp(14px,calc(13.6px + 0.1vw),15px);
  color:oklch(78% 0.02 250);
  max-width:520px;
  line-height:1.7;
  margin:0 0 clamp(28px,calc(26.5px + 0.38vw),32px);
}

/* bookingLinkStyle */
.booking-link{
  color:var(--accent);
  display:inline-block;
  font-family:var(--mono);
  font-size:clamp(12px,calc(11.6px + 0.1vw),13px);
  letter-spacing:clamp(1.5px,calc(1.3px + 0.05vw),2px);
  text-transform:uppercase;
  text-decoration:none;
  border:1px solid;
  padding:clamp(14px,calc(13.25px + 0.19vw),16px) clamp(28px,calc(26.5px + 0.38vw),32px);
  margin-bottom:clamp(48px,calc(45px + 0.76vw),56px);
}

.pills{
  display:flex;
  gap:clamp(12px,calc(10.5px + 0.38vw),16px);
  flex-wrap:wrap;
}
.pill{
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:clamp(1.2px,calc(1.09px + 0.03vw),1.5px);
  text-transform:uppercase;
  color:var(--ink);
  text-decoration:none;
  border:1px solid oklch(30% 0.02 250 / 0.6);
  padding:12px clamp(18px,calc(17.25px + 0.19vw),20px);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer{
  padding:clamp(24px,calc(21px + 0.76vw),32px) clamp(20px,calc(15.5px + 1.14vw),32px);
  border-top:1px solid var(--line);
  display:flex;
  justify-content:space-between;
  align-items:center;
  font-family:var(--mono);
  font-size:clamp(10px,calc(9.6px + 0.1vw),11px);
  letter-spacing:clamp(1.2px,calc(1.09px + 0.03vw),1.5px);
  color:oklch(60% 0.02 250);
}

/* --------------------------------------------------------------------------
   Intro overlay  (introOverlayStyle + friends)

   Visible when the intro has not been dismissed OR while the CRT collapse is
   running. `data-entered` / `data-transitioning` on <body> replace the React
   `entered` / `transitioning` booleans.
   -------------------------------------------------------------------------- */

.intro{
  position:fixed;
  inset:0;
  z-index:999;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  background:#0a0c10;
  opacity:1;
  pointer-events:auto;
  transition:none;
  padding:0 clamp(20px,calc(18.5px + 0.38vw),24px);
  overflow:hidden;
}
body[data-entered] .intro{
  z-index:-1;
  opacity:0;
  pointer-events:none;
  transition:opacity .15s linear;
}
/* transitioning wins: the overlay stays up through the collapse */
body[data-entered][data-transitioning] .intro{
  z-index:999;
  opacity:1;
  pointer-events:auto;
  transition:none;
}

.intro__static{
  position:absolute;
  inset:0;
  z-index:3;
  pointer-events:none;
  mix-blend-mode:screen;
  background-image:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.9) 0px, rgba(255,255,255,0.9) 1px, transparent 1px, transparent 2px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.35) 0px, transparent 2px);
  opacity:0;
  animation:none;
}
body[data-transitioning] .intro__static{animation:introStaticBurst .8s steps(3,end) forwards;}

.intro__flash{
  position:absolute;
  inset:0;
  z-index:4;
  pointer-events:none;
  background:var(--accent);
  opacity:0;
  animation:none;
}
body[data-transitioning] .intro__flash{animation:introFlash .5s ease-out .35s forwards;}

.intro__scanlines{
  position:absolute;
  inset:0;
  opacity:0.06;
  background:repeating-linear-gradient(0deg,#fff 0px,#fff 1px,transparent 1px,transparent 3px);
  pointer-events:none;
}

.intro__content{
  position:relative;
  z-index:2;
  display:flex;
  flex-direction:column;
  align-items:center;
  transform-origin:center center;
  animation:none;
}
body[data-transitioning] .intro__content{animation:crtPowerOff .85s cubic-bezier(.7,0,.84,0) forwards;}

.intro__eyebrow{
  font-family:var(--mono);
  font-size:clamp(10px,calc(9.25px + 0.19vw),12px);
  letter-spacing:clamp(3px,calc(2.63px + 0.1vw),4px);
  text-transform:uppercase;
  color:oklch(70% 0.02 250);
  margin-bottom:clamp(16px,calc(14.5px + 0.38vw),20px);
}

.intro__wordmark{position:relative;}

.intro__word{
  font-family:var(--display);
  font-size:clamp(44px,calc(24px + 8.71vw),150px);
  margin:0;
  letter-spacing:clamp(-3px,calc(-1.6px - 0.1vw),-2px);
}

.intro__word--base{
  position:relative;
  z-index:3;
  color:oklch(97% 0.01 250);
  animation:edgeGlitchBase 6.5s infinite;
}
body[data-transitioning] .intro__word--base{animation:none;}

.intro__word--r{
  position:absolute;
  top:0;
  left:0;
  z-index:2;
  color:oklch(72% 0.14 25);
  mix-blend-mode:screen;
  animation:edgeGlitchR 6.5s infinite;
}
body[data-transitioning] .intro__word--r{animation:crtRGBRedRefined .85s ease-out forwards;}

.intro__word--b{
  position:absolute;
  top:0;
  left:0;
  z-index:2;
  color:oklch(72% 0.14 240);
  mix-blend-mode:screen;
  animation:edgeGlitchB 6.5s infinite;
}
body[data-transitioning] .intro__word--b{animation:crtRGBBlueRefined .85s ease-out forwards;}

/* enterBtnStyle */
.intro__enter{
  color:var(--accent);
  margin-top:clamp(40px,calc(37px + 0.76vw),48px);
  background:transparent;
  font-family:var(--mono);
  font-size:clamp(12px,calc(11.6px + 0.1vw),13px);
  letter-spacing:clamp(2.5px,calc(2.3px + 0.05vw),3px);
  text-transform:uppercase;
  border:1px solid;
  padding:clamp(14px,calc(13.25px + 0.19vw),16px) clamp(36px,calc(33px + 0.76vw),44px);
  cursor:pointer;
  position:relative;
  z-index:2;
}

/* --------------------------------------------------------------------------
   Art direction — the handful of mobile differences that are NOT a smooth
   ramp: hero framing, the clipped bottom edge and the RS watermark.
   (Mobile's max-width:480px letterbox on the wrapper/header is deliberately
   dropped — it would pillarbox the site on a real phone.)
   -------------------------------------------------------------------------- */

@media (max-width: 640px){
  .hero{clip-path:polygon(0 0,100% 0,100% 96%,0 100%);}
  .hero__img{object-position:center 38%;}
  .hero__fade{
    background:linear-gradient(to top,oklch(12% 0.01 250) 8%,oklch(12% 0.01 250 / 0.2) 45%,oklch(12% 0.01 250 / 0.55) 100%);
  }
  .hero__watermark{
    top:16%;
    right:-14%;
    font-size:clamp(90px,42vw,180px);
    letter-spacing:-4px;
  }
  .hero__content{padding:0 20px 56px;}
  /* mobile export runs the marquee faster; animation-duration can't clamp() */
  .ticker__track{animation-duration:16s;}
}

/* The looping glitch animations are what keep the RGB ghost layers hidden
   (their keyframes start and end at opacity 0), so anything switched off here
   has to be pinned to opacity 0 by hand. */
@media (prefers-reduced-motion: reduce){
  .scanlines,
  .ticker__track,
  .wordmark__base,
  .intro__word--base{animation:none;}

  .wordmark__r,
  .wordmark__b,
  .menu__link-ghost,
  .intro__word--r,
  .intro__word--b{animation:none;opacity:0;}

  /* Equalizer: the bars keep their base heights and drop any residual
     transform. `animation` is declared once on .equalizer__bar (the state
     layers only swap the custom properties), so this single rule is enough
     to stop the idle, hover and active loops. */
  .equalizer__bar{animation:none;transform:none;}
  .equalizer[data-active] .equalizer__glitch{animation:none;opacity:0;}
}
