/* ============================================================
   Sulaymon Ruziboev — portfolio
   Light-futurist system: white canvas, glass surfaces,
   violet→cyan accent used only as light.
   ============================================================ */

/* ── fonts ─────────────────────────────────────────────────────
   Self-hosted. Loading these from Google costs two extra DNS+TLS
   handshakes AND serialises them — the font files can't start until
   the stylesheet from a *different* host has arrived. Served from
   our own origin they reuse the connection already open for the HTML.

   Both are variable fonts, so one file per family covers 400–600
   rather than one file per weight. Latin subset only.
   ───────────────────────────────────────────────────────────── */
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url('../assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ── tokens ────────────────────────────────────────────────── */
:root{
  --bg:            #f4f4f7;
  --bg-deep:       #ececf2;
  --surface:       #ffffff;
  --ink:           #0b0b12;
  --ink-soft:      #3a3a48;
  --muted:         #82828f;
  --line:          rgba(11,11,18,.10);
  --line-soft:     rgba(11,11,18,.06);

  --accent:        #6a3bff;
  --accent-2:      #00c2ff;
  --accent-3:      #ff4d9d;
  --grad:          linear-gradient(115deg, var(--accent) 0%, #7d5cff 35%, var(--accent-2) 100%);

  --glass:         rgba(255,255,255,.58);
  --glass-strong:  rgba(255,255,255,.78);
  --glass-line:    rgba(255,255,255,.85);
  --shadow-sm:     0 2px 10px rgba(20,18,40,.05);
  --shadow:        0 18px 50px -18px rgba(30,22,80,.22), 0 2px 8px rgba(20,18,40,.05);
  --shadow-lg:     0 40px 90px -30px rgba(40,25,110,.30), 0 4px 14px rgba(20,18,40,.06);

  --r-sm: 12px;  --r: 20px;  --r-lg: 30px;  --r-pill: 999px;

  --pad: clamp(20px, 5vw, 80px);
  --maxw: 1440px;

  --font-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Inter", "Segoe UI", system-ui, sans-serif;

  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease:     cubic-bezier(.4,0,.2,1);
}

/* ── reset ─────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }
html{
  -webkit-text-size-adjust:100%; scroll-behavior:smooth;
  /* Kill the grey/blue flash mobile browsers paint over anything tappable.
     This is the touch highlight only — :focus-visible below is untouched, so
     keyboard users keep their focus ring. */
  -webkit-tap-highlight-color:transparent;
}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
body.is-locked{ overflow:hidden; }
img{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
h1,h2,h3,p,ul,ol,figure{ margin:0; }
ul,ol{ padding:0; list-style:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
::selection{ background:var(--accent); color:#fff; }

.skip{
  position:fixed; top:-100px; left:16px; z-index:200;
  background:var(--ink); color:#fff; padding:12px 18px; border-radius:var(--r-sm);
}
.skip:focus-visible{ top:16px; }
:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:6px; }

/* ── ambient page texture ──────────────────────────────────── */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(80% 55% at 50% -10%, rgba(122,80,255,.16), transparent 70%),
    radial-gradient(60% 45% at 100% 15%, rgba(0,194,255,.12), transparent 70%),
    radial-gradient(55% 45% at 0% 40%, rgba(255,77,157,.07), transparent 70%);
}
.fx-grain{
  position:fixed; inset:0; z-index:300; pointer-events:none; opacity:.30;
  mix-blend-mode:multiply;
  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='.85' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='180' height='180' filter='url(%23n)' opacity='.42'/></svg>");
}
.fx-grain::after{
  content:""; position:absolute; inset:0;
  box-shadow:inset 0 0 220px rgba(30,20,70,.10);
}

/* ── glass primitives ──────────────────────────────────────── */
.glass{
  position:relative;
  background:var(--glass);
  backdrop-filter:blur(26px) saturate(180%);
  -webkit-backdrop-filter:blur(26px) saturate(180%);
  border:1px solid var(--glass-line);
  box-shadow:var(--shadow);
}
.glass::after{           /* specular top edge */
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:linear-gradient(160deg, rgba(255,255,255,.85), rgba(255,255,255,0) 42%);
  opacity:.75;
}

/* ── typography ────────────────────────────────────────────── */
.display{
  font-family:var(--font-display);
  font-weight:500;
  font-size:clamp(3.2rem, 10.5vw, 10.5rem);
  line-height:.88;
  letter-spacing:-.045em;
  margin:.18em 0 .32em;
}
.display--sm{ font-size:clamp(2.6rem, 8vw, 7.5rem); }
/* line-height is .88, so the em box is shorter than the glyphs. The reveal
   mask (overflow:hidden) would otherwise shear descenders off "p", "y", "g" —
   pad the clip box out, then pull the extra space back with a negative margin
   so the lines keep their tight optical rhythm. */
.display .line{ display:block; overflow:hidden; padding-bottom:.24em; margin-bottom:-.18em; }
.display .line > span{ display:block; white-space:nowrap; }
.line--ghost{
  color:transparent;
  -webkit-text-stroke:1.5px rgba(11,11,18,.42);
  paint-order:stroke fill;
}
.h2{
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(2.1rem, 5.2vw, 4.4rem);
  line-height:1.02; letter-spacing:-.035em;
}
.h2 em{
  font-style:normal;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.label{
  font-family:var(--font-display);
  font-size:.72rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--muted);
}
.eyebrow{
  display:inline-flex; align-items:center; gap:10px;
  font-size:.78rem; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-soft);
  padding:8px 16px; border-radius:var(--r-pill);
  background:var(--glass-strong); border:1px solid var(--glass-line);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  box-shadow:var(--shadow-sm);
}
.eyebrow .dot{
  width:7px; height:7px; border-radius:50%; background:#22c55e;
  box-shadow:0 0 0 0 rgba(34,197,94,.55); animation:pulse 2.4s infinite;
}
@keyframes pulse{
  70%{ box-shadow:0 0 0 9px rgba(34,197,94,0); }
  100%{ box-shadow:0 0 0 0 rgba(34,197,94,0); }
}

/* ── buttons ───────────────────────────────────────────────── */
.btn{
  --bg-btn:var(--surface);
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  gap:8px; padding:16px 30px; border-radius:var(--r-pill);
  font-family:var(--font-display); font-size:.95rem; font-weight:500; letter-spacing:-.01em;
  white-space:nowrap; overflow:hidden;
  transition:transform .5s var(--ease-out), box-shadow .5s var(--ease-out), color .35s;
  will-change:transform;
}
.btn span{ position:relative; z-index:2; }
.btn--solid{ background:var(--ink); color:#fff; box-shadow:var(--shadow); }
.btn--solid::before{
  content:""; position:absolute; inset:0; z-index:1; background:var(--grad);
  opacity:0; transition:opacity .45s var(--ease);
}
.btn--solid:hover::before{ opacity:1; }
.btn--ghost{
  background:var(--glass-strong); border:1px solid var(--glass-line); color:var(--ink);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); box-shadow:var(--shadow-sm);
}
.btn--ghost:hover{ box-shadow:var(--shadow); }
.btn--pill{
  background:var(--glass-strong); border:1px solid var(--glass-line);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  padding:13px 28px; box-shadow:var(--shadow-sm);
}
.btn--pill:hover{ background:var(--ink); color:#fff; }
.btn:hover{ transform:translateY(-2px); }

/* ── custom cursor ─────────────────────────────────────────── */
.cursor{ display:none; }
@media (hover:hover) and (pointer:fine){
  .cursor{
    display:block; position:fixed; top:0; left:0; z-index:400; pointer-events:none;
    mix-blend-mode:multiply;
  }
  .cursor__ring,.cursor__dot{
    position:absolute; border-radius:50%; transform:translate(-50%,-50%);
    will-change:transform, width, height;
  }
  .cursor__ring{
    width:36px; height:36px; border:1px solid rgba(106,59,255,.55);
    transition:width .35s var(--ease-out), height .35s var(--ease-out), background .35s;
  }
  .cursor__dot{ width:5px; height:5px; background:var(--accent); }
  .cursor.is-hot .cursor__ring{ width:70px; height:70px; background:rgba(106,59,255,.09); }
}

/* ── loader ────────────────────────────────────────────────── */
.loader{
  position:fixed; inset:0; z-index:500;
  display:grid; place-items:center; background:var(--bg);
  transition:opacity .7s var(--ease), visibility .7s;
}
.loader.is-done{ opacity:0; visibility:hidden; }
.loader__inner{ display:grid; justify-items:center; gap:22px; width:min(260px,60vw); }
.loader__mark{
  font-size:2rem; background:var(--grad);
  -webkit-background-clip:text; background-clip:text; color:transparent;
  animation:spin 3s linear infinite;
}
@keyframes spin{ to{ transform:rotate(360deg); } }
.loader__bar{ width:100%; height:2px; background:var(--line); overflow:hidden; border-radius:2px; }
.loader__bar span{ display:block; height:100%; width:0; background:var(--grad); }
.loader__pct{ font-family:var(--font-display); font-size:.78rem; letter-spacing:.2em; color:var(--muted); }

/* ── nav ───────────────────────────────────────────────────── */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:120;
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; padding:22px var(--pad);
  transition:transform .55s var(--ease-out), padding .4s var(--ease);
}
.nav.is-hidden{ transform:translateY(-130%); }
.nav.is-stuck{ padding-top:14px; padding-bottom:14px; }
.nav__logo{ display:inline-flex; align-items:center; gap:10px; font-family:var(--font-display); font-weight:600; letter-spacing:-.02em; }
.nav__mark{
  display:grid; place-items:center; width:34px; height:34px; border-radius:11px;
  background:var(--ink); overflow:hidden;   /* the logo is a dark square; the box is its fallback */
  transition:transform .6s var(--ease-out);
}
.nav__mark img{ width:100%; height:100%; object-fit:cover; display:block; }
.nav__logo:hover .nav__mark{ transform:scale(1.06); }
.nav__links{
  display:flex; gap:6px; padding:7px; border-radius:var(--r-pill);
}
.nav__links a{
  position:relative; z-index:1; padding:9px 20px; border-radius:var(--r-pill);
  font-size:.9rem; color:var(--ink-soft); transition:color .3s;
}
.nav__links a:hover{ color:var(--ink); }
.nav__links a.is-active{ color:#fff; }
.nav__links a.is-active::before{
  content:""; position:absolute; inset:0; z-index:-1; border-radius:var(--r-pill);
  background:var(--ink);
}
.nav__actions{ display:flex; align-items:center; gap:10px; }
.nav__git{
  display:grid; place-items:center; width:52px; height:52px; border-radius:50%;
  background:var(--glass-strong); border:1px solid var(--glass-line); color:var(--ink);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); box-shadow:var(--shadow-sm);
  transition:transform .5s var(--ease-out), background .35s var(--ease), color .35s, box-shadow .5s var(--ease-out);
}
.nav__git svg{ width:23px; height:23px; display:block; }
.nav__git:hover{ background:var(--ink); color:#fff; transform:translateY(-2px); box-shadow:var(--shadow); }
.nav__burger{ display:none; width:44px; height:44px; place-items:center; }
.nav__burger span{ display:block; width:22px; height:1.5px; background:var(--ink); transition:transform .4s var(--ease-out), opacity .3s; }
.nav__burger span+span{ margin-top:6px; }
.nav__burger[aria-expanded="true"] span:first-child{ transform:translateY(3.75px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child{ transform:translateY(-3.75px) rotate(-45deg); }

.mobile-menu{
  position:fixed; inset:0; z-index:110;
  display:grid; align-content:center; justify-items:center; gap:8px;
  background:rgba(244,244,247,.86);
  backdrop-filter:blur(28px); -webkit-backdrop-filter:blur(28px);
  opacity:0; visibility:hidden; transition:opacity .45s var(--ease), visibility .45s;
}
.mobile-menu.is-open{ opacity:1; visibility:visible; }
.mobile-menu a{
  font-family:var(--font-display); font-size:clamp(2rem,9vw,3rem);
  letter-spacing:-.03em; opacity:0; transform:translateY(18px);
  transition:opacity .5s var(--ease-out), transform .5s var(--ease-out);
}
.mobile-menu.is-open a{ opacity:1; transform:none; }
.mobile-menu.is-open a:nth-child(2){ transition-delay:.05s }
.mobile-menu.is-open a:nth-child(3){ transition-delay:.1s }
.mobile-menu.is-open a:nth-child(4){ transition-delay:.15s }
.mobile-menu.is-open a:nth-child(5){ transition-delay:.2s }
.mobile-menu.is-open a:nth-child(6){ transition-delay:.25s }

/* ══ HERO ═════════════════════════════════════════════════ */
.hero{
  position:relative; z-index:1;
  min-height:100svh; padding:clamp(120px,16vh,190px) var(--pad) 70px;
  display:flex; align-items:center; overflow:hidden;
  /* the hero is a drag surface — never let a drag turn into a text selection */
  -webkit-user-select:none; user-select:none;
}
.hero__aura{ position:absolute; inset:0; pointer-events:none; }
.aura{ position:absolute; border-radius:50%; filter:blur(80px); opacity:.55; }
.aura--a{ width:46vw; height:46vw; left:22%; top:-8%;  background:radial-gradient(circle, rgba(122,80,255,.42), transparent 68%); }
.aura--b{ width:38vw; height:38vw; right:4%; top:22%;  background:radial-gradient(circle, rgba(0,194,255,.36), transparent 68%); }
.aura--c{ width:34vw; height:34vw; left:2%;  bottom:-6%; background:radial-gradient(circle, rgba(255,77,157,.26), transparent 68%); }

.hero__canvas,
.hero__fallback{
  position:absolute; left:50%; top:52%;
  width:min(78vh, 62vw); height:min(78vh, 62vw);
  transform:translate(-50%,-50%);
  pointer-events:none;
}
.hero__fallback{
  display:none; border-radius:50%;
  background:conic-gradient(from 210deg, rgba(122,80,255,.55), rgba(0,194,255,.5), rgba(255,77,157,.4), rgba(122,80,255,.55));
  filter:blur(38px); opacity:.6;
}
.no-webgl .hero__canvas{ display:none; }
.no-webgl .hero__fallback{ display:block; }

/* ── draggable orb + elastic reveal window ─────────────────
   The blob is a clip window onto a photo that sits under the page's
   own background. At rest it reads as the glass badge; dragged, it
   stretches open and uncovers the image.                            */
.hero__reveal{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  opacity:0; transition:opacity .9s var(--ease);
}
.hero__reveal.is-ready{ opacity:1; }
.reveal__svg{ position:absolute; inset:0; width:100%; height:100%; overflow:visible; }
.reveal__orb{
  position:absolute; left:0; top:0;
  width:clamp(52px,6vw,74px); aspect-ratio:1; border-radius:50%;
  background:var(--grad);
  box-shadow:0 12px 34px -8px rgba(106,59,255,.6), inset 0 -6px 16px rgba(255,255,255,.5);
  pointer-events:auto; cursor:grab; touch-action:none;
  will-change:transform;
  -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
  display:grid; place-items:center;
}
/* rides along with the orb, since it lives inside it */
.reveal__orb span{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(8px, .62vw, 10px);
  letter-spacing:.07em; text-transform:uppercase;
  line-height:1.15; text-align:center; color:#fff;
  text-shadow:0 1px 4px rgba(40,20,90,.5);
  pointer-events:none; -webkit-user-select:none; user-select:none;
}
/* while the orb is held the pointer can travel outside the hero, so the
   guard has to be global for the duration of the drag */
html.orb-drag, html.orb-drag *{
  -webkit-user-select:none !important; user-select:none !important;
  cursor:grabbing !important;
}
.reveal__orb:active,
.reveal__orb.is-dragging{ cursor:grabbing; }
/* the blob draws the ring itself once the effect is live, and the badge
   becomes a bare text label so it can't swallow pointer events on the orb */
html.blob-on .hero__badge{
  background:none; border-color:transparent;
  backdrop-filter:none; -webkit-backdrop-filter:none;
  pointer-events:none;
}
html.blob-on .badge__orb{ display:none; }
/* The grid's own box covers the whole hero and sits above the reveal layer,
   so it would swallow every pointerdown meant for the orb. Make the container
   transparent to the pointer and hand it back to the real controls. */
html.blob-on .hero__grid{ pointer-events:none; }
html.blob-on .hero__grid a,
html.blob-on .hero__grid button{ pointer-events:auto; }
html.blob-on .hero__badge p{ transition:opacity .25s linear; }

.hero__grid{
  position:relative; z-index:3;
  width:100%; max-width:var(--maxw); margin-inline:auto;
  display:grid; gap:clamp(28px,5vw,60px);
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  grid-template-areas:
    "head  badge"
    "note  stat";
  align-items:start;
}
.hero__head{ grid-area:head; container-type:inline-size; }
/* Size the hero headline from its own COLUMN, not the viewport, so the
   longest line ("Beyond the") can never wrap however the grid resolves. */
@supports (container-type: inline-size){
  .hero .display{ font-size:clamp(2.4rem, 16.5cqw, 9.5rem); }
}
.hero__badge{ grid-area:badge; justify-self:end; }
.hero__note{ grid-area:note; align-self:end; }
.hero__stat{ grid-area:stat; justify-self:end; align-self:end; }

.hero__actions{ display:flex; flex-wrap:wrap; gap:14px; }

/* circular badge */
.glass-ring{
  width:clamp(150px,17vw,206px); aspect-ratio:1; border-radius:50%;
  display:grid; place-items:center; gap:10px; text-align:center;
  border:1px solid rgba(11,11,18,.12);
  background:rgba(255,255,255,.30);
  backdrop-filter:blur(10px) saturate(150%); -webkit-backdrop-filter:blur(10px) saturate(150%);
}
.glass-ring p{ font-size:.86rem; color:var(--ink-soft); line-height:1.35; grid-row:2; }
.badge__orb{
  grid-row:1; width:clamp(52px,6vw,74px); aspect-ratio:1; border-radius:50%;
  background:var(--grad);
  box-shadow:0 12px 34px -8px rgba(106,59,255,.6), inset 0 -6px 16px rgba(255,255,255,.5);
  animation:bob 6s ease-in-out infinite;
}
@keyframes bob{ 50%{ transform:translateY(-8px); } }

/* rotating caption */
.hero__note{ display:flex; align-items:center; gap:20px; max-width:400px; }
.hero__note p{ font-size:.95rem; color:var(--ink-soft); }
.spinner{ position:relative; flex:0 0 auto; width:112px; height:112px; }
.spinner svg{ width:100%; height:100%; animation:spin 22s linear infinite; }
.spinner text{
  font-family:var(--font-display); font-size:11.5px; letter-spacing:.14em;
  fill:var(--ink-soft); text-transform:uppercase;
}
.spinner__core{
  position:absolute; inset:0; margin:auto; width:16px; height:16px; border-radius:50%;
  background:var(--grad); box-shadow:0 0 22px rgba(106,59,255,.55);
}

/* stat card */
.hero__stat{
  display:block; position:relative; width:min(340px,100%);
  padding:26px 28px 30px; border-radius:var(--r-lg);
  transition:transform .6s var(--ease-out), box-shadow .6s var(--ease-out);
}
.hero__stat:hover{ transform:translateY(-5px); box-shadow:var(--shadow-lg); }
.hero__stat > *{ position:relative; z-index:2; }
.stat__avatars{ display:flex; margin-bottom:16px; }
.stat__avatars span{
  width:34px; height:34px; border-radius:50%; border:2px solid #fff;
  margin-left:calc(var(--i) * -10px);
  background:var(--grad); filter:hue-rotate(calc(var(--i) * 55deg));
  box-shadow:var(--shadow-sm);
}
.stat__num{
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.9rem,3.4vw,2.7rem); line-height:1; letter-spacing:-.04em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
  margin-bottom:10px;
}
.hero__stat p{ font-size:.88rem; color:var(--muted); max-width:26ch; }
.hero__stat .stat__arrow{           /* qualified: must beat `.hero__stat > *` */
  position:absolute; right:24px; bottom:26px; font-size:1.25rem; color:var(--ink);
  transition:transform .5s var(--ease-out);
}
.hero__stat:hover .stat__arrow{ transform:translate(4px,-4px); }

.hero__scroll{
  position:absolute; left:50%; bottom:26px; transform:translateX(-50%);
  display:flex; align-items:center; gap:10px;
  font-size:.7rem; letter-spacing:.24em; text-transform:uppercase; color:var(--muted);
}
.hero__scroll span{
  width:1px; height:34px;
  background:linear-gradient(var(--muted), transparent);
  animation:drop 2s var(--ease) infinite;
}
@keyframes drop{ 0%{ transform:scaleY(0); transform-origin:top } 50%{ transform:scaleY(1); transform-origin:top } 51%{ transform-origin:bottom } 100%{ transform:scaleY(0); transform-origin:bottom } }

/* ══ MARQUEE ══════════════════════════════════════════════ */
.marquee{
  position:relative; z-index:1;
  padding:26px 0; border-block:1px solid var(--line-soft);
  background:rgba(255,255,255,.42);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
}
.marquee__track{ display:flex; width:max-content; will-change:transform; }
.marquee__set{ display:flex; align-items:center; gap:38px; padding-right:38px; }
.marquee__set span{
  font-family:var(--font-display); font-size:clamp(1.1rem,2.2vw,1.7rem);
  letter-spacing:-.03em; color:var(--ink-soft); white-space:nowrap;
}
.marquee__set i{ font-style:normal; color:var(--accent); opacity:.55; font-size:.8rem; }

/* ══ sections ═════════════════════════════════════════════ */
.sec-head{
  max-width:var(--maxw); margin:0 auto clamp(40px,6vw,80px);
  padding-inline:var(--pad); display:grid; gap:20px;
}
section{ position:relative; z-index:1; }

/* ── ABOUT ───────────────────────────────────────────────── */
/* same vertical rhythm as .work / .caps — this section used to run a larger
   clamp on both sides, which read as a hole above Selected Work */
.about{ padding:clamp(60px,9vh,110px) var(--pad) clamp(90px,13vh,150px); }
.about__sticky{ max-width:1100px; margin-inline:auto; display:grid; gap:clamp(36px,6vw,64px); }
.about__text{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.5rem,3.6vw,3.1rem); line-height:1.22; letter-spacing:-.03em;
}
.about__text .w{ color:rgba(11,11,18,.16); transition:color .3s linear; }
.about__text .w.is-lit{ color:var(--ink); }
.about__meta{
  display:grid; gap:28px; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  padding-top:clamp(24px,4vw,44px); border-top:1px solid var(--line);
}
.about__meta div{ display:grid; gap:4px; }
.about__meta b{
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(2rem,4.4vw,3.2rem); line-height:1; letter-spacing:-.04em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* direct child only — the counter is a <span> too, nested inside the <b>,
   and an unscoped rule here shrank it to caption size */
.about__meta div > span{ font-size:.86rem; color:var(--muted); }

/* ── WORK ────────────────────────────────────────────────── */
.work{ padding:clamp(60px,9vh,110px) 0 clamp(90px,13vh,150px); }
/* Two columns that pack independently. A grid would tie the cards into rows,
   so one tall card left a hole beside every shorter neighbour — and an odd
   card count left a big one mid-list. Columns just flow. */
.work__list{
  max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad);
  column-count:2; column-gap:clamp(24px,3.2vw,44px);
}
.card{
  display:block;                      /* an <article>: the whole-card link is an overlay */
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  background:var(--surface); box-shadow:var(--shadow);
  transform-style:preserve-3d; will-change:transform;
  transition:box-shadow .6s var(--ease-out);
  break-inside:avoid;                 /* never split a card across the columns */
  margin-bottom:clamp(24px,3.2vw,44px);
}
/* No stagger any more: `nth-child(even)` stopped meaning "the right-hand one"
   once the cards flowed into columns instead of rows. */
.card:hover{ box-shadow:var(--shadow-lg); }
.card__media{ position:relative; aspect-ratio:4/3; overflow:hidden; background:var(--bg-deep); }
.card__media::before{                 /* gradient fallback if the photo fails */
  content:""; position:absolute; inset:0;
  background:conic-gradient(from 160deg, #7a50ff, #00c2ff, #ff4d9d, #7a50ff);
  filter:saturate(.85);
}
.card__media img{
  position:relative; width:100%; height:100%; object-fit:cover;
  transform:scale(1.06); transition:transform 1.1s var(--ease-out), filter .7s;
  filter:saturate(.75) contrast(1.03);
}
.card:hover .card__media img{ transform:scale(1.13); filter:saturate(1.05) contrast(1.05); }
.card__sheen{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  background:linear-gradient(115deg, rgba(255,255,255,0) 38%, rgba(255,255,255,.55) 50%, rgba(255,255,255,0) 62%);
  transform:translateX(-120%); transition:transform 1s var(--ease-out);
}
.card:hover .card__sheen{ transform:translateX(120%); }
/* the whole card is one link, stretched under the body so the repo button —
   which sits above it — stays independently clickable */
.card__link{ position:absolute; inset:0; z-index:2; border-radius:inherit; }
.card__body{
  position:relative; margin:-58px 16px 16px; padding:26px 26px 30px;
  border-radius:var(--r); z-index:3;
  pointer-events:none;                /* clicks fall through to .card__link … */
}
.card__body a{ pointer-events:auto; } /* … except the repo button itself */
.card__body > *{ position:relative; z-index:2; }
.card__idx{
  font-family:var(--font-display); font-size:.74rem; letter-spacing:.2em; color:var(--muted);
}
.card__body h3{
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.15rem,2vw,1.6rem); letter-spacing:-.03em; line-height:1.15;
  margin:8px 0 10px; padding-right:36px;
}
.card__body p{ font-size:.92rem; color:var(--ink-soft); max-width:46ch; }
.card__body p + p{ margin-top:11px; }
/* provenance line — sits under the title, before the description */
.card__body .card__built{
  display:flex; gap:8px; align-items:baseline;
  margin:-4px 0 12px; font-size:.78rem; line-height:1.45;
  letter-spacing:.01em; color:var(--ink-soft); max-width:46ch;
}
.card__built b{ color:var(--accent); font-weight:500; white-space:nowrap; }
.tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:16px; }
.tags li{
  font-size:.74rem; letter-spacing:.04em; color:var(--ink-soft);
  padding:6px 12px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:rgba(255,255,255,.6);
}
/* status chip — reads as a state, not a technology */
.tags li.is-status{
  color:var(--accent); font-weight:500;
  border-color:rgba(106,59,255,.35); background:rgba(106,59,255,.08);
}
.card__body .card__go{              /* qualified: must beat `.card__body > *` */
  position:absolute; top:26px; right:26px; z-index:3;
  display:grid; place-items:center; width:36px; height:36px; border-radius:50%;
  background:var(--ink); color:#fff; font-size:.9rem;
  transition:transform .5s var(--ease-out), background .4s;
}
.card:hover .card__go{ transform:translate(3px,-3px); background:var(--accent); }

/* repo button — reads "GitHub", flips to "Open ↗" under the cursor */
.card__body .card__repo{
  position:relative; z-index:4; margin-top:20px;
  display:inline-flex; align-items:center; gap:9px;
  padding:10px 18px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:rgba(255,255,255,.72);
  font-family:var(--font-display); font-size:.82rem; font-weight:500; color:var(--ink);
  box-shadow:var(--shadow-sm);
  transition:transform .45s var(--ease-out), background .35s var(--ease), color .35s, border-color .35s, box-shadow .45s var(--ease-out);
}
.card__repo svg{ width:16px; height:16px; display:block; flex:none; }
.card__repo-label{ display:grid; overflow:hidden; }
.card__repo-label b,
.card__repo-label i{
  grid-area:1/1; font-weight:inherit; font-style:normal; white-space:nowrap;
  transition:transform .4s var(--ease-out), opacity .3s var(--ease);
}
.card__repo-label i{ transform:translateY(105%); opacity:0; }
.card__repo:hover,
.card__repo:focus-visible{
  background:var(--ink); border-color:var(--ink); color:#fff;
  transform:translateY(-2px); box-shadow:var(--shadow);
}
.card__repo:hover .card__repo-label b,
.card__repo:focus-visible .card__repo-label b{ transform:translateY(-105%); opacity:0; }
.card__repo:hover .card__repo-label i,
.card__repo:focus-visible .card__repo-label i{ transform:translateY(0); opacity:1; }

/* source-on-request note — stands in for a repo button */
.card__body .card__note{
  margin-top:20px; display:flex; gap:9px; align-items:flex-start;
  padding:12px 16px; border-radius:var(--r);
  border:1px dashed rgba(106,59,255,.32); background:rgba(106,59,255,.06);
  font-size:.8rem; line-height:1.5; color:var(--ink-soft); max-width:46ch;
}
.card__note span{ color:var(--accent); line-height:1.45; }

/* ── CAPABILITIES ────────────────────────────────────────── */
.caps{ padding:clamp(60px,9vh,110px) 0 clamp(90px,13vh,150px); }
.caps__grid{
  max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad);
  display:grid; gap:clamp(16px,2vw,24px);
  grid-template-columns:repeat(auto-fit,minmax(255px,1fr));
}
.cap{
  padding:32px 28px 36px; border-radius:var(--r-lg);
  transition:transform .6s var(--ease-out), box-shadow .6s var(--ease-out);
}
.cap > *{ position:relative; z-index:2; }
.cap:hover{ transform:translateY(-6px); box-shadow:var(--shadow-lg); }
.cap__ico{
  display:grid; place-items:center; width:52px; height:52px; margin-bottom:22px;
  border-radius:16px; font-size:1.2rem; color:#fff; background:var(--ink);
  transition:background .45s, transform .6s var(--ease-out);
}
.cap:hover .cap__ico{ background:var(--grad); transform:rotate(-8deg) scale(1.06); }
.cap h3{
  font-family:var(--font-display); font-weight:500; font-size:1.22rem;
  letter-spacing:-.025em; margin-bottom:10px;
}
.cap p{ font-size:.92rem; color:var(--ink-soft); }

/* ── TOOLKIT ─────────────────────────────────────────────── */
/* One tone quieter than Capabilities: same glass card, but the icon stays a
   flat outline and the weight sits in the chips, so a long tool list doesn't
   out-shout the four things I can actually build. */
.kit{ padding:clamp(60px,9vh,110px) 0 clamp(90px,13vh,150px); }
.sec-lede{
  font-size:1rem; line-height:1.6; color:var(--ink-soft); max-width:52ch;
}
.kit__grid{
  max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad);
  display:grid; gap:clamp(16px,2vw,24px); align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
}
.kit__card{
  padding:28px 26px 30px; border-radius:var(--r-lg);
  transition:transform .6s var(--ease-out), box-shadow .6s var(--ease-out);
}
.kit__card > *{ position:relative; z-index:2; }
.kit__card:hover{ transform:translateY(-6px); box-shadow:var(--shadow-lg); }
.kit__ico{
  display:grid; place-items:center; width:40px; height:40px; margin-bottom:18px;
  border-radius:13px; font-size:.95rem; color:var(--accent);
  border:1px solid rgba(106,59,255,.28); background:rgba(106,59,255,.07);
  transition:background .45s, color .45s, transform .6s var(--ease-out);
}
.kit__card:hover .kit__ico{
  background:var(--ink); border-color:var(--ink); color:#fff; transform:rotate(-8deg);
}
.kit__card h3{
  font-family:var(--font-display); font-weight:500; font-size:1.08rem;
  letter-spacing:-.025em; margin-bottom:8px;
}
.kit__card p{ font-size:.87rem; line-height:1.55; color:var(--ink-soft); }
.kit__list{
  display:flex; flex-wrap:wrap; gap:7px;
  margin-top:18px; padding-top:18px; border-top:1px solid var(--line);
}
.kit__list li{
  font-size:.76rem; letter-spacing:.01em; color:var(--ink);
  padding:6px 12px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:rgba(255,255,255,.62);
  transition:border-color .35s var(--ease), background .35s var(--ease);
}
.kit__card:hover .kit__list li{ border-color:rgba(106,59,255,.26); background:rgba(255,255,255,.85); }
/* Seven cards never fill a four-wide row. Above the width where the fourth
   column appears, the motion card — the one with the longest list — takes the
   spare slot so the second row reads as a decision, not a gap. */
@media (min-width:1376px){
  .kit__card:nth-child(6){ grid-column:span 2; }
}

/* ── EXPERIENCE ──────────────────────────────────────────── */
.exp{ padding:clamp(60px,9vh,110px) 0 clamp(48px,6vh,72px); }
.exp__list{ max-width:1100px; margin-inline:auto; padding-inline:var(--pad); }
.exp__item{
  position:relative; display:grid; gap:6px 40px;
  grid-template-columns:minmax(120px,190px) 1fr;
  padding:30px 0; border-top:1px solid var(--line);
  transition:padding-left .55s var(--ease-out);
}
.exp__item:last-child{ border-bottom:1px solid var(--line); }
.exp__item::before{
  content:""; position:absolute; left:0; top:-1px; height:1px; width:0;
  background:var(--grad); transition:width .7s var(--ease-out);
}
.exp__item:hover{ padding-left:16px; }
.exp__item:hover::before{ width:100%; }
.exp__year{ font-family:var(--font-display); font-size:.86rem; letter-spacing:.06em; color:var(--muted); padding-top:5px; }
/* version tag sits above the year, like a release number */
.exp__year b{
  display:block; margin-bottom:3px;
  font-weight:500; font-size:1.2rem; letter-spacing:-.02em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.exp__item h3{ font-family:var(--font-display); font-weight:500; font-size:clamp(1.15rem,2.2vw,1.6rem); letter-spacing:-.03em; margin-bottom:6px; }
.exp__item p{ font-size:.94rem; color:var(--ink-soft); max-width:60ch; }

/* ── CONTACT ─────────────────────────────────────────────── */
.contact{
  position:relative; overflow:hidden; text-align:center;
  padding:clamp(56px,7vh,86px) var(--pad) clamp(70px,10vh,120px);
}
/* NOTE: parent-qualified so it outranks the `.contact > *{position:relative}`
   rule below — otherwise the aura drops into flow and adds ~900px of dead space. */
.contact .contact__aura{
  position:absolute; left:50%; top:40%; transform:translate(-50%,-50%);
  width:min(900px,120vw); aspect-ratio:1; border-radius:50%; filter:blur(90px); opacity:.5;
  background:radial-gradient(circle, rgba(122,80,255,.42), rgba(0,194,255,.22) 45%, transparent 70%);
}
.contact > *{ position:relative; z-index:2; }
.contact .display{ margin:.12em 0 .34em; }
.contact .line{ text-align:center; }
.contact__mail{
  display:inline-block; font-family:var(--font-display);
  font-size:clamp(1.05rem,2.6vw,1.9rem); letter-spacing:-.02em;
  padding-bottom:6px; background-image:linear-gradient(var(--ink),var(--ink));
  background-size:100% 1px; background-position:0 100%; background-repeat:no-repeat;
  transition:background-size .6s var(--ease-out), color .4s;
}
.contact__mail:hover{ background-size:0% 1px; color:var(--accent); }
.contact__socials{
  display:flex; flex-wrap:wrap; justify-content:center; gap:10px;
  margin-top:clamp(34px,5vw,56px);
}
.contact__socials a{
  display:inline-block; padding:12px 24px; border-radius:var(--r-pill);
  font-size:.9rem; background:var(--glass-strong); border:1px solid var(--glass-line);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  transition:transform .5s var(--ease-out), background .4s, color .4s;
}
.contact__socials a:hover{ transform:translateY(-3px); background:var(--ink); color:#fff; }

/* ── FOOTER ──────────────────────────────────────────────── */
.foot{
  position:relative; z-index:1;
  display:flex; flex-wrap:wrap; gap:14px; justify-content:space-between; align-items:center;
  max-width:var(--maxw); margin-inline:auto;
  padding:30px var(--pad) 40px; border-top:1px solid var(--line);
  font-size:.84rem; color:var(--muted);
}
.foot a:hover{ color:var(--ink); }

/* ── reveal base state (JS adds the motion) ──────────────── */
[data-reveal]{ opacity:0; transform:translateY(26px); }
.no-js [data-reveal]{ opacity:1; transform:none; }

/* ══ RESPONSIVE ═══════════════════════════════════════════ */
@media (max-width:1080px){
  .hero__grid{
    grid-template-columns:1fr;
    grid-template-areas:"head" "stat" "note" "badge";
    gap:36px;
  }
  .hero__badge{ justify-self:start; }
  .hero__stat{ justify-self:start; }
  .hero__canvas,.hero__fallback{ top:38%; width:min(60vh,88vw); height:min(60vh,88vw); opacity:.85; }
  .work__list{ column-count:1; }
}
@media (max-width:820px){
  .nav__links, .nav__cta{ display:none; }
  .nav__burger{ display:grid; }
  /* the pill nav is gone here, so the bar itself carries the glass —
     otherwise the logo and burger float unreadably over the page */
  .nav{
    background:rgba(255,255,255,.60);
    backdrop-filter:blur(22px) saturate(180%);
    -webkit-backdrop-filter:blur(22px) saturate(180%);
    border-bottom:1px solid rgba(255,255,255,.72);
    box-shadow:0 8px 26px -14px rgba(30,22,80,.20);
  }
  /* the open menu is its own glass sheet — don't stack two */
  body.is-locked .nav{
    background:transparent; border-bottom-color:transparent; box-shadow:none;
    backdrop-filter:none; -webkit-backdrop-filter:none;
  }
  .exp__item{ grid-template-columns:1fr; gap:10px; }
  .hero{ min-height:auto; padding-top:130px; }
  .hero__scroll{ display:none; }
  /* The orb is only meaningful when you can drag it, and you can't here —
     blob.js bails at this same breakpoint. Hiding the badge too, otherwise
     the static CSS fallback just takes its place and looks identical. */
  .hero__badge{ display:none; }
  .hero__note{ flex-direction:column; align-items:flex-start; }
  .card__body{ margin:-40px 12px 12px; padding:22px; }
}
@media (max-width:520px){
  .line--ghost{ -webkit-text-stroke-width:1px; }
  .btn{ padding:14px 24px; font-size:.9rem; }
  .hero__actions{ width:100%; }
  .hero__actions .btn{ flex:1 1 auto; }
}

/* ══ ACCESSIBILITY ════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  [data-reveal]{ opacity:1 !important; transform:none !important; }
  .about__text .w{ color:var(--ink) !important; }
  .cursor{ display:none !important; }
}
