:root{
  --bg:#050505;
  --panel:#0a0a0a;
  --panel2:#0d0d0d;
  --line:#1a1a1a;
  --line2:#242424;
  --text:#f7f7f7;
  --muted:#8d8d8d;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}

body{
  margin:0;
  background:
    radial-gradient(circle at 50% 0%, rgba(255,255,255,.035), transparent 26rem),
    var(--bg);
  color:var(--text);
  font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
}
a{color:inherit;text-decoration:none}
.wrap{width:min(1120px,calc(100% - 40px));margin:auto}

/* =========================================================
   floating nav
   ========================================================= */
nav{
  position:fixed;left:0;right:0;top:0;z-index:100;
  padding:18px 0;
  pointer-events:none;
  transition:padding .45s cubic-bezier(.16,1,.3,1);
}
nav > .wrap{pointer-events:none}

.nav-bar{
  pointer-events:auto;
  display:flex;align-items:center;gap:18px;
  height:76px;padding:0 12px 0 10px;
  border-radius:22px;
  border:1px solid rgba(255,255,255,.08);
  background:rgba(10,10,10,.62);
  backdrop-filter:blur(22px) saturate(140%);
  -webkit-backdrop-filter:blur(22px) saturate(140%);
  box-shadow:0 18px 40px -26px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.05);
  transition:
    height .45s cubic-bezier(.16,1,.3,1),
    background .45s ease,
    border-color .45s ease,
    box-shadow .45s ease,
    border-radius .45s ease;
}

nav.shrunk{padding:10px 0}
nav.shrunk .nav-bar{
  height:62px;
  background:rgba(8,8,8,.86);
  border-color:rgba(255,255,255,.13);
  box-shadow:0 22px 50px -28px rgba(0,0,0,1), inset 0 1px 0 rgba(255,255,255,.06);
}

.brand{
  display:inline-flex;align-items:center;flex:none;
  padding:4px 6px;border-radius:14px;
  transition:background .3s ease;
}
.brand img{
  width:62px;height:62px;object-fit:contain;display:block;
  transition:
    width .45s cubic-bezier(.16,1,.3,1),
    height .45s cubic-bezier(.16,1,.3,1),
    transform .45s cubic-bezier(.16,1,.3,1),
    filter .3s ease;
}
nav.shrunk .brand img{width:50px;height:50px}
.brand:hover{background:rgba(255,255,255,.05)}
.brand:hover img{transform:scale(1.07) rotate(-2deg);filter:drop-shadow(0 0 12px rgba(255,255,255,.2))}

.links{
  position:relative;
  display:flex;align-items:center;gap:2px;
  margin-left:auto;
  font-size:13.5px;
  padding:5px;
  border-radius:14px;
  background:rgba(255,255,255,.028);
  border:1px solid rgba(255,255,255,.05);
}
.links a{
  position:relative;z-index:2;
  padding:9px 16px;border-radius:10px;
  color:var(--muted);
  letter-spacing:-.005em;
  transition:color .3s ease;
  white-space:nowrap;
}
.links a:hover,.links a[aria-current="page"]{color:var(--text)}
.links a::after{display:none}

/* the highlight that slides under whichever link you're on */
.link-pill{
  position:absolute;z-index:1;top:5px;left:0;
  height:calc(100% - 10px);width:0;
  border-radius:10px;
  background:rgba(255,255,255,.075);
  border:1px solid rgba(255,255,255,.06);
  opacity:0;
  transition:
    transform .5s cubic-bezier(.16,1,.3,1),
    width .5s cubic-bezier(.16,1,.3,1),
    opacity .3s ease;
  pointer-events:none;
}
.links.pill-on .link-pill{opacity:1}

.nav-cta{
  flex:none;
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 16px;border-radius:13px;
  font-size:13px;font-weight:650;letter-spacing:-.01em;
  color:#080808;background:#f4f4f4;
  border:1px solid #f4f4f4;
  transition:transform .4s cubic-bezier(.16,1,.3,1),background .3s ease,box-shadow .4s ease;
}
.nav-cta svg{width:15px;height:15px;transition:transform .4s cubic-bezier(.16,1,.3,1)}
.nav-cta:hover{background:#fff;transform:translateY(-2px);box-shadow:0 10px 24px -12px rgba(255,255,255,.5)}
.nav-cta:hover svg{transform:translateX(4px)}

.nav-burger{
  display:none;
  flex:none;margin-left:auto;
  width:44px;height:40px;
  align-items:center;justify-content:center;
  gap:5px;flex-direction:column;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.08);
  border-radius:12px;cursor:pointer;padding:0;
}
.nav-burger span{
  display:block;width:17px;height:1.5px;background:#e6e6e6;border-radius:2px;
  transition:transform .4s cubic-bezier(.16,1,.3,1),opacity .3s ease;
}
.nav-burger[aria-expanded="true"] span:first-child{transform:translateY(3.25px) rotate(45deg)}
.nav-burger[aria-expanded="true"] span:last-child{transform:translateY(-3.25px) rotate(-45deg)}

/* the fixed bar no longer takes up flow space */
body{padding-top:112px}

@media(max-width:820px){
  body{padding-top:96px}
  nav{padding:12px 0}
  .nav-bar{height:66px;gap:10px}
  .nav-cta{display:none}
  .nav-burger{display:flex}
  .links{
    position:absolute;left:0;right:0;top:calc(100% + 10px);
    flex-direction:column;align-items:stretch;gap:4px;
    padding:10px;border-radius:18px;
    background:rgba(8,8,8,.94);
    backdrop-filter:blur(22px);
    border:1px solid rgba(255,255,255,.09);
    box-shadow:0 24px 50px -26px rgba(0,0,0,1);
    opacity:0;visibility:hidden;
    transform:translateY(-10px) scale(.98);
    transition:opacity .35s ease,transform .45s cubic-bezier(.16,1,.3,1),visibility .35s;
  }
  .links.open{opacity:1;visibility:visible;transform:none}
  .links a{padding:13px 14px;font-size:15px}
  .link-pill{display:none}
}

.hero{
  min-height:76vh;
  display:grid;place-items:center;text-align:center;
  padding:66px 0 54px;
  border-top:0;
}
.hero-logo{
  display:block;
  width:min(780px,92%);
  margin:0 auto 14px;
  padding:18px 24px;
  border-radius:28px;
  transition:transform .28s ease, filter .28s ease, background .28s ease;
}
.hero-logo img{
  width:100%;
  display:block;
  user-select:none;
  -webkit-user-drag:none;
  filter:drop-shadow(0 18px 32px rgba(255,255,255,.04));
}
.hero-logo:hover{
  transform:translateY(-5px) scale(1.012);
  background:rgba(255,255,255,.018);
  filter:drop-shadow(0 18px 38px rgba(255,255,255,.055));
}

.hero p{
  margin:0 auto;
  max-width:650px;
  color:var(--muted);
  font-size:17px;
  line-height:1.7;
}
.hero p strong{color:#dcdcdc;font-weight:600}

.cta{display:flex;gap:16px;justify-content:center;margin-top:30px;flex-wrap:wrap}
/* Buttons are extruded: a solid, un-blurred shadow under the face is the
   side wall of the key. Hover lifts the face and grows the wall, active
   drops the face onto the wall so the key physically bottoms out. */
.btn{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:14px 26px;
  min-height:46px;
  border-radius:14px;
  font-size:14px;font-weight:600;letter-spacing:-.01em;
  border:1px solid var(--line2);
  background:linear-gradient(180deg,#1c1c1c 0%,#111 55%,#0b0b0b 100%);
  color:var(--text);
  transform:translateY(-4px);
  transform-style:preserve-3d;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 4px 0 #050505,
    0 4px 0 1px #1f1f1f,
    0 10px 18px -6px rgba(0,0,0,.75);
  isolation:isolate;
}

/* Specular sweep. It slides via background-position rather than a transform,
   so the key does NOT need overflow:hidden to clip it — and without that clip
   the hit-area pad below stays clickable. */
.btn::before{
  content:'';position:absolute;inset:0;z-index:-1;
  border-radius:inherit;
  background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.14) 48%,transparent 66%);
  background-size:320% 100%;
  background-position:100% 0;
  transition:background-position .7s cubic-bezier(.16,1,.3,1);
}
.btn:hover::before{background-position:0% 0}

/* THE CLICK FIX — the key travels 6px vertically between rest, hover and
   active. If the hit area travelled with it, the pointer would fall off the
   bottom edge on hover, drop the key, re-enter it, and flutter: the button
   runs away from the cursor. This pad is a fixed rectangle covering every
   pose the key can be in, so once you are over the button you stay over it. */
.btn::after{
  content:'';position:absolute;z-index:-2;
  left:-4px;right:-4px;top:-8px;bottom:-12px;
  border-radius:20px;
}

.btn:hover{
  transform:translateY(-7px);
  border-color:#3a3a3a;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.18),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 7px 0 #050505,
    0 7px 0 1px #2b2b2b,
    0 18px 26px -8px rgba(0,0,0,.8);
}

.btn:active{
  transform:translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.08),
    inset 0 2px 6px rgba(0,0,0,.5),
    0 1px 0 #050505,
    0 1px 0 1px #1f1f1f,
    0 3px 8px -4px rgba(0,0,0,.7);
}

.btn:focus-visible{outline:2px solid #6b6b6b;outline-offset:3px}

.btn.primary{
  color:#050505;font-weight:750;
  border-color:#fff;
  background:linear-gradient(180deg,#ffffff 0%,#efefef 55%,#d9d9d9 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.9),
    inset 0 -1px 0 rgba(0,0,0,.18),
    0 4px 0 #6f6f6f,
    0 4px 0 1px #8a8a8a,
    0 10px 20px -6px rgba(255,255,255,.14);
}
.btn.primary::before{
  background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.85) 48%,transparent 66%);
  background-size:320% 100%;
  background-position:100% 0;
}
.btn.primary:hover::before{background-position:0% 0}
.btn.primary:hover{
  border-color:#fff;
  background:linear-gradient(180deg,#ffffff 0%,#f7f7f7 55%,#e6e6e6 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -1px 0 rgba(0,0,0,.18),
    0 7px 0 #6f6f6f,
    0 7px 0 1px #9a9a9a,
    0 18px 30px -8px rgba(255,255,255,.2);
}
.btn.primary:active{
  box-shadow:
    inset 0 2px 6px rgba(0,0,0,.28),
    0 1px 0 #6f6f6f,
    0 1px 0 1px #8a8a8a,
    0 3px 8px -4px rgba(0,0,0,.5);
}

/* the extrusion needs room below the row so the wall isn't clipped */
.cta{padding-bottom:12px}

/* On touch there is no hover pose to chase, and fat-finger targets matter
   more than travel, so the keys sit still and get taller. */
@media(hover:none){
  .btn{transform:none;min-height:50px;padding:15px 26px}
  .btn:hover{transform:none}
  .btn:active{transform:translateY(3px)}
}

section{padding:84px 0;border-top:1px solid var(--line)}
.eyebrow{
  color:var(--muted);
  text-transform:uppercase;
  font-size:11px;
  letter-spacing:.21em;
  margin-bottom:14px;
}
h2{
  font-size:clamp(34px,5vw,60px);
  letter-spacing:-.055em;
  line-height:.98;
  margin:0 0 28px;
}

.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;perspective:1100px}
.card{
  position:relative;
  overflow:hidden;
  background:linear-gradient(180deg,var(--panel2),var(--panel));
  border:1px solid var(--line);
  border-radius:18px;
  padding:22px;
  min-height:215px;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  transition:transform .22s ease,border-color .22s ease,background .22s ease;
}
.card::after{
  content:"";
  position:absolute;inset:auto -20% -55% 10%;
  height:120px;
  background:radial-gradient(circle,rgba(255,255,255,.07),transparent 65%);
  opacity:0;
  transition:opacity .22s ease;
  pointer-events:none;
}
.card:hover{
  border-color:#2b2b2b;
  background:linear-gradient(180deg,#101010,#0a0a0a);
}
.card:hover::after{opacity:1}
.card span{font-size:11px;color:var(--muted);letter-spacing:.1em}
.card h3{font-size:22px;margin:12px 0 8px;letter-spacing:-.035em}
.card p{color:var(--muted);line-height:1.62;margin:0;font-size:14px}

.statline{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:1px;background:var(--line);
  border:1px solid var(--line);
  border-radius:18px;overflow:hidden;margin-top:18px;
}
.stat{background:var(--panel);padding:28px;transition:background .2s ease}
.stat:hover{background:#101010}
.stat strong{font-size:32px;display:block;letter-spacing:-.045em}
.stat small{color:var(--muted)}

footer{padding:38px 0;color:var(--muted);font-size:13px}

@media(max-width:760px){
  .wrap{width:min(100% - 28px,1120px)}
    .brand img{width:62px;height:62px}
  .hero{min-height:66vh;padding-top:40px}
  .hero-logo{width:100%;padding:10px 0}
  .grid,.statline{grid-template-columns:1fr}
  section{padding:60px 0}
}

/* ---------- motion ---------- */
html.js-smooth{scroll-behavior:auto}
.reveal{
  opacity:0;
  translate:0 26px;
  scale:.985;
  filter:blur(6px);
  will-change:opacity,translate,scale,filter;
  transition:
    opacity .9s cubic-bezier(.16,1,.3,1),
    translate 1.05s cubic-bezier(.16,1,.3,1),
    scale 1.05s cubic-bezier(.16,1,.3,1),
    filter .9s cubic-bezier(.16,1,.3,1);
  transition-delay:var(--d,0ms);
}
.reveal.in{opacity:1;translate:none;scale:1;filter:blur(0)}


.scroll-bar{
  position:fixed;left:0;top:0;height:2px;width:100%;
  transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,#4b4b4b,#ffffff);
  z-index:60;pointer-events:none;
}


/* ---------- custom scrollbar ----------
   replaces the default browser bar everywhere, page and panels alike.
   Firefox only gets the two-colour form; WebKit gets the full treatment. */
html{
  scrollbar-width:thin;
  scrollbar-color:#2e2e2e #0a0a0a;
}
*::-webkit-scrollbar{width:11px;height:11px}
*::-webkit-scrollbar-track{
  background:#0a0a0a;
  border-left:1px solid rgba(255,255,255,.05);
}
*::-webkit-scrollbar-thumb{
  border-radius:99px;
  border:3px solid transparent;
  background-clip:content-box;
  background-color:#2b2b2b;
  transition:background-color .25s ease;
}
*::-webkit-scrollbar-thumb:hover{background-color:#454545}
*::-webkit-scrollbar-thumb:active{background-color:#6a6a6a}
*::-webkit-scrollbar-corner{background:#0a0a0a}


.card,.btn,.stat{will-change:transform}
.card{transition:transform .5s cubic-bezier(.16,1,.3,1),border-color .3s ease,background .3s ease}
.btn{transition:transform .32s cubic-bezier(.16,1,.3,1),box-shadow .32s cubic-bezier(.16,1,.3,1),border-color .3s ease,background .3s ease}
.btn:active{transition-duration:.08s}

@media(prefers-reduced-motion:reduce){
  .reveal{opacity:1;translate:none;scale:1;filter:none;transition:none}
}

/* ---------- projects (work page) ---------- */
.page-head{padding:76px 0 10px;border-top:0}
.page-head h1{
  font-size:clamp(40px,7vw,80px);
  letter-spacing:-.06em;line-height:.95;margin:0 0 20px;
}
.page-head p{color:var(--muted);max-width:620px;line-height:1.7;margin:0;font-size:16px}

.projects{
  perspective:1300px;
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(320px,1fr));
  gap:20px;
  margin-top:8px;
}

.project{
  position:relative;
  display:flex;flex-direction:column;
  overflow:hidden;
  background:linear-gradient(180deg,var(--panel2),var(--panel));
  border:1px solid var(--line);
  border-radius:20px;
  transition:transform .5s cubic-bezier(.16,1,.3,1),border-color .35s ease,box-shadow .5s ease;
}
.project:hover{
  border-color:#2e2e2e;
  box-shadow:0 28px 56px -26px rgba(0,0,0,.95);
}

.shot{
  position:relative;
  aspect-ratio:16/10;
  overflow:hidden;
  background:#080808;
  border-bottom:1px solid var(--line);
}
.shot img{
  width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.02);
  filter:saturate(.92);
  transition:transform 1.1s cubic-bezier(.16,1,.3,1),filter .5s ease;
}
.project:hover .shot img{transform:scale(1.08);filter:saturate(1.05)}
.shot::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(5,5,5,.15) 0%,transparent 40%,rgba(5,5,5,.55) 100%);
  pointer-events:none;
}

.status{
  position:absolute;left:14px;top:14px;z-index:2;
  display:inline-flex;align-items:center;gap:7px;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  padding:6px 11px;border-radius:999px;
  background:rgba(5,5,5,.72);
  border:1px solid rgba(255,255,255,.1);
  backdrop-filter:blur(10px);
  color:#e9e9e9;
}
/* signal-bar indicator — three bars metering like a live equalizer */
.dot{
  --sig:var(--muted);
  position:relative;flex:none;
  width:11px;height:10px;border-radius:0;
  background-image:linear-gradient(var(--sig),var(--sig));
  background-repeat:no-repeat;background-position:50% 100%;
  background-size:3px 100%;
  animation:sig-mid 1.15s ease-in-out infinite;
}
.dot::before,.dot::after{
  content:"";position:absolute;bottom:0;
  width:3px;height:40%;background:var(--sig);
}
.dot::before{left:0;animation:sig-a 1.15s ease-in-out infinite}
.dot::after{right:0;animation:sig-b 1.15s ease-in-out infinite}

@keyframes sig-mid{
  0%,100%{background-size:3px 40%}
  50%{background-size:3px 100%}
}
@keyframes sig-a{
  0%,100%{height:100%}
  45%{height:30%}
}
@keyframes sig-b{
  0%,100%{height:55%}
  30%{height:100%}
  65%{height:25%}
}

.status.dev .dot{--sig:#f0b429}
.status.live .dot{--sig:#49d17a}
.status.dead{opacity:.85}
/* discontinued: bars flatline, no motion */
.status.dead .dot,
.status.dead .dot::before,
.status.dead .dot::after{--sig:#6a6a6a;animation:none}
.status.dead .dot{background-size:3px 22%}
.status.dead .dot::before,.status.dead .dot::after{height:22%}

@media (prefers-reduced-motion:reduce){
  .dot,.dot::before,.dot::after{animation:none}
}

.info{
  padding:20px 20px 22px;
  display:flex;flex-direction:column;gap:11px;
  flex:1;
}
.info h3{font-size:21px;margin:0;letter-spacing:-.035em;line-height:1.15}
.info p{color:var(--muted);line-height:1.65;margin:0;font-size:13.5px;flex:1}
.info p.empty{color:#5e5e5e;font-style:italic}

.role-line{
  font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:#dcdcdc;margin:-3px 0 0;
}

.tags{display:flex;flex-wrap:wrap;gap:7px;padding-top:4px;border-top:1px solid var(--line);margin-top:2px}
.tag{
  font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  padding:5px 10px;border-radius:999px;
  border:1px solid var(--line2);color:var(--muted);
  transition:border-color .3s ease,color .3s ease;
}
.project:hover .tag{border-color:#333;color:#a5a5a5}

.work-cta{margin-top:38px}

@media(max-width:760px){
  .projects{grid-template-columns:1fr;gap:16px}
  .page-head{padding-top:52px}
}

/* ---------- cursor-tracking cards ---------- */
.tilt{
  transform-style:preserve-3d;
  /* Two poses stacked in one transform: the RESTING pose (--px/--pz/--pry,
     set per component further down, which is what fans the cards out in
     space) and the LIVE pose (--rx/--ry/--lift/--sc, written by the pointer
     tracking in main.js). Keeping them in separate variables means the
     script never has to know a card is angled. */
  transform:
    perspective(var(--persp,1200px))
    translate3d(var(--px,0px), var(--lift,0px), var(--pz,0px))
    rotateY(var(--pry,0deg))
    rotateX(var(--rx,0deg))
    rotateY(var(--ry,0deg))
    scale(var(--sc,1));
  transition:transform .7s cubic-bezier(.16,1,.3,1);
}
.tilt.tracking{transition:transform .12s linear}

/* the light that follows the pointer across the card */
.tilt::before{
  content:"";
  position:absolute;inset:0;
  border-radius:inherit;
  background:radial-gradient(
    340px circle at var(--mx,50%) var(--my,50%),
    rgba(255,255,255,.11),
    rgba(255,255,255,.03) 38%,
    transparent 62%
  );
  opacity:0;
  transition:opacity .45s ease;
  pointer-events:none;
  z-index:3;
}
.tilt.tracking::before{opacity:1}

/* a rim that lights up on the edge nearest the pointer */
.tilt::after{
  content:"";
  position:absolute;inset:0;
  border-radius:inherit;
  padding:1px;
  background:radial-gradient(
    260px circle at var(--mx,50%) var(--my,50%),
    rgba(255,255,255,.4),
    transparent 70%
  );
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
  opacity:0;
  transition:opacity .45s ease;
  pointer-events:none;
  z-index:4;
}
.tilt.tracking::after{opacity:1}

/* the old .card glow blob would double up with the new one */
.card.tilt::after{inset:0;height:auto;background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),rgba(255,255,255,.4),transparent 70%)}

/* lift the inner content off the surface for real depth */
.tilt > *{transform:translateZ(28px)}
.project.tilt .shot{transform:translateZ(0)}
.project.tilt .info{transform:translateZ(38px)}

@media(prefers-reduced-motion:reduce){
  .tilt,.tilt.tracking{transform:none;transition:none}
  .tilt > *,.project.tilt .info{transform:none}
}

/* =========================================================
   3D scene / atmosphere
   ========================================================= */
.fx{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}

/* perspective floor that drifts toward the viewer */
.fx-grid{
  position:absolute;left:-50%;right:-50%;bottom:-14vh;height:78vh;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size:64px 64px;
  transform:perspective(520px) rotateX(76deg) translateY(var(--gy,0px));
  transform-origin:50% 100%;
  mask-image:linear-gradient(to top, #000 0%, rgba(0,0,0,.35) 38%, transparent 78%);
  -webkit-mask-image:linear-gradient(to top, #000 0%, rgba(0,0,0,.35) 38%, transparent 78%);
  opacity:.85;
}

.fx-orb{
  position:absolute;border-radius:50%;
  filter:blur(90px);
  will-change:transform;
}
.fx-orb-a{
  width:52vw;height:52vw;max-width:720px;max-height:720px;
  left:-8vw;top:-16vh;
  background:radial-gradient(circle,rgba(120,150,255,.16),transparent 68%);
}
.fx-orb-b{
  width:44vw;height:44vw;max-width:620px;max-height:620px;
  right:-10vw;top:34vh;
  background:radial-gradient(circle,rgba(255,255,255,.09),transparent 66%);
}

.fx-noise{
  position:absolute;inset:0;opacity:.028;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* nav keeps its own position:fixed / z-index from the nav block above */
main, footer{position:relative;z-index:2}
main{overflow-x:clip}

/* =========================================================
   page transition curtain
   ========================================================= */
.curtain{
  position:fixed;inset:0;z-index:200;display:flex;pointer-events:none;
}
.curtain span{
  flex:1;background:#050505;
  transform-origin:50% 0;
  transition:transform .62s cubic-bezier(.76,0,.24,1);
  /* runs on its own so a JS failure can never leave the page blacked out */
  animation:curtainUp .62s cubic-bezier(.76,0,.24,1) forwards;
}
@keyframes curtainUp{from{transform:scaleY(1)}to{transform:scaleY(0)}}
.curtain span:nth-child(1){transition-delay:0ms;animation-delay:0ms}
.curtain span:nth-child(2){transition-delay:55ms;animation-delay:55ms}
.curtain span:nth-child(3){transition-delay:110ms;animation-delay:110ms}
.curtain span:nth-child(4){transition-delay:165ms;animation-delay:165ms}
.curtain span:nth-child(5){transition-delay:220ms;animation-delay:220ms}

/* opening: panels retract upward */
.curtain.open span{transform:scaleY(0);transform-origin:50% 0}
/* closing: panels drop back down from the top */
.curtain.close span{animation:none;transform:scaleY(1);transform-origin:50% 100%}
.curtain.close{pointer-events:all}

/* =========================================================
   hero stage
   ========================================================= */
.stage{transform-style:preserve-3d;perspective:1400px}

.hero-badge{
  display:inline-flex;align-items:center;gap:8px;
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#c9c9c9;
  padding:8px 14px;border-radius:999px;
  border:1px solid rgba(255,255,255,.12);
  background:rgba(255,255,255,.035);
  backdrop-filter:blur(10px);
  margin-bottom:26px;
}
.hero-badge .dot{--sig:#49d17a}

.hero-logo{will-change:transform}

.scroll-hint{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  margin-top:56px;
  font-size:10px;letter-spacing:.28em;text-transform:uppercase;color:#5f5f5f;
}
.scroll-hint-line{
  width:1px;height:46px;
  background:linear-gradient(to bottom,rgba(255,255,255,.35),transparent);
  position:relative;overflow:hidden;
}
.scroll-hint-line::after{
  content:"";position:absolute;left:0;top:-46px;width:1px;height:46px;
  background:linear-gradient(to bottom,transparent,#fff);
  animation:drop 2.1s cubic-bezier(.6,0,.4,1) infinite;
}
@keyframes drop{
  0%{transform:translateY(0)}
  70%,100%{transform:translateY(92px)}
}

/* =========================================================
   marquee band
   ========================================================= */
.marquee{
  overflow:hidden;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  background:rgba(255,255,255,.015);
  padding:16px 0;
  transform:rotate(-1.15deg) scale(1.03);
  margin:34px 0;
}
.marquee-track{display:flex;width:max-content;animation:slide 32s linear infinite}
.marquee-track span{
  display:inline-flex;align-items:center;gap:26px;padding-right:26px;
  font-size:clamp(20px,2.6vw,34px);
  letter-spacing:-.035em;
  color:#1f1f1f;
  -webkit-text-stroke:1px #2c2c2c;
  white-space:nowrap;
}
.marquee-track i{font-style:normal;color:#3a3a3a;font-size:.5em;-webkit-text-stroke:0}
@keyframes slide{to{transform:translateX(-50%)}}
.marquee:hover .marquee-track{animation-play-state:paused}

/* =========================================================
   depth on the stat strip
   ========================================================= */
.statline{perspective:1000px}
.stat{transition:background .35s ease,transform .5s cubic-bezier(.16,1,.3,1)}
.stat:hover{transform:translateZ(24px)}

@media(prefers-reduced-motion:reduce){
  .marquee-track{animation:none}
  .scroll-hint-line::after{animation:none}
  .fx-grid{transform:none;opacity:.25}
  .curtain{display:none}
}

/* =========================================================
   testimonials
   ========================================================= */
.section-lead{color:var(--muted);max-width:600px;line-height:1.7;margin:0 0 30px;font-size:15px}

.tgrid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(290px,1fr));
  gap:18px;
  perspective:1400px;
}

.tcard{
  position:relative;
  margin:0;
  padding:26px 24px 22px;
  display:flex;flex-direction:column;gap:18px;
  background:linear-gradient(165deg,#101010,#0a0a0a 55%,#070707);
  border:1px solid var(--line);
  border-radius:20px;
  overflow:hidden;
  transition:border-color .35s ease,box-shadow .5s ease;
}
.tcard:hover{border-color:#2e2e2e;box-shadow:0 30px 60px -30px rgba(0,0,0,.95)}

.quote-mark{
  position:absolute;top:-16px;right:12px;
  font-size:120px;line-height:1;
  color:rgba(255,255,255,.035);
  font-family:Georgia,serif;
  pointer-events:none;
  transition:color .4s ease,transform .6s cubic-bezier(.16,1,.3,1);
}
.tcard:hover .quote-mark{color:rgba(255,255,255,.07);transform:translateY(4px) scale(1.06)}

.tcard blockquote{
  margin:0;
  color:#cfcfcf;
  font-size:14.5px;
  line-height:1.72;
  flex:1;
}

.tcard figcaption{
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
  gap:12px;
  padding-top:16px;
  border-top:1px solid var(--line);
}
.avatar{
  position:relative;overflow:hidden;
  width:38px;height:38px;border-radius:12px;
  display:grid;place-items:center;
  font-size:12px;letter-spacing:.06em;font-weight:700;color:#0a0a0a;
  background:linear-gradient(150deg,#f2f2f2,#b9b9b9);
  flex:none;
  transition:transform .5s cubic-bezier(.16,1,.3,1);
}
/* the photo sits on top of the initials, which stay as the fallback
   if the file is missing (onerror removes the img) */
.avatar img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;display:block;
  border-radius:inherit;
}
.tcard:hover .avatar{transform:translateZ(30px) scale(1.06)}
.who{display:flex;flex-direction:column;min-width:0}
.who strong{font-size:13.5px;letter-spacing:-.01em}
.who small{color:var(--muted);font-size:11px;letter-spacing:.06em}
.stars{font-size:11px;color:#e8c15a;letter-spacing:.1em;white-space:nowrap}

/* =========================================================
   contact panel + channels
   ========================================================= */
.cta-panel{position:relative}

.channels{display:flex;flex-direction:column;gap:14px;perspective:1300px}
.channel{
  position:relative;
  display:grid;
  grid-template-columns:150px 1fr auto;
  align-items:center;
  gap:18px;
  padding:26px 26px;
  border:1px solid var(--line);
  border-radius:18px;
  background:linear-gradient(180deg,var(--panel2),var(--panel));
  overflow:hidden;
  transition:border-color .35s ease,box-shadow .5s ease;
}
.channel:hover{border-color:#2e2e2e;box-shadow:0 24px 48px -26px rgba(0,0,0,.95)}
.ch-label{
  font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);
}
.ch-value{font-size:clamp(19px,2.4vw,26px);letter-spacing:-.035em;font-weight:650}
.ch-note{
  grid-column:2;grid-row:2;
  color:var(--muted);font-size:13px;line-height:1.6;margin-top:-6px;
}
.ch-arrow{
  grid-column:3;grid-row:1 / span 2;
  font-size:20px;color:var(--muted);
  transition:transform .5s cubic-bezier(.16,1,.3,1),color .3s ease;
}
.channel:hover .ch-arrow{transform:translateX(7px);color:var(--text)}

.avail{
  margin-top:26px;padding:22px 24px;
  border:1px solid var(--line);border-radius:16px;
  background:rgba(255,255,255,.015);
  display:flex;flex-direction:column;gap:10px;align-items:flex-start;
}
.avail p{margin:0;color:var(--muted);font-size:13px;line-height:1.6}

@media(max-width:760px){
  .tgrid{grid-template-columns:1fr}
  .channel{grid-template-columns:1fr;gap:6px;padding:22px}
  .ch-note{grid-column:1;grid-row:auto;margin-top:2px}
  .ch-arrow{grid-column:1;grid-row:auto;font-size:18px}
}

/* ---------- channel icons ---------- */
.channel{grid-template-columns:56px 1fr auto}
.ch-icon{
  grid-column:1;grid-row:1 / span 2;
  width:46px;height:46px;border-radius:14px;
  display:grid;place-items:center;
  background:rgba(255,255,255,.045);
  border:1px solid rgba(255,255,255,.08);
  color:#d8d8d8;
  transition:background .4s ease,color .4s ease,border-color .4s ease,transform .5s cubic-bezier(.16,1,.3,1);
}
.ch-icon svg{width:22px;height:22px;display:block}
.channel:hover .ch-icon{transform:translateZ(30px) scale(1.06);border-color:rgba(255,255,255,.16)}
.channel:hover .ch-icon.discord{background:rgba(88,101,242,.18);color:#8b98ff}
.channel:hover .ch-icon.roblox{background:rgba(226,60,60,.16);color:#ff7b7b}
.channel:hover .ch-icon:not(.discord):not(.roblox){background:rgba(255,255,255,.09);color:#fff}

.channel .ch-label{grid-column:2;grid-row:1;align-self:end}
.channel .ch-value{grid-column:2;grid-row:2;align-self:start}
.channel .ch-note{grid-column:2;grid-row:3;margin-top:4px}
.channel .ch-arrow{grid-column:3;grid-row:1 / span 3}

@media(max-width:760px){
  .channel{grid-template-columns:auto 1fr}
  .ch-icon{grid-row:1 / span 3;width:42px;height:42px}
  .channel .ch-label,.channel .ch-value,.channel .ch-note{grid-column:2}
  .channel .ch-arrow{display:none}
}

/* =========================================================
   sneak peeks lightbox
   ========================================================= */
.project{cursor:pointer}
.project:focus-visible{outline:2px solid #6f8dff;outline-offset:4px}

.open-hint{
  display:inline-flex;align-items:center;gap:6px;
  margin-top:2px;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);
  transition:color .35s ease;
}
.open-hint b{transition:transform .45s cubic-bezier(.16,1,.3,1);font-weight:400}
.project:hover .open-hint{color:#f0f0f0}
.project:hover .open-hint b{transform:translateX(5px)}

.sneaks{
  position:fixed;inset:0;z-index:300;
  display:grid;place-items:center;
  padding:24px;
}
.sneaks[hidden]{display:none}

.sneaks-backdrop{
  position:absolute;inset:0;
  background:rgba(3,3,3,.82);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  opacity:0;
  transition:opacity .45s ease;
}
.sneaks.in .sneaks-backdrop{opacity:1}

.sneaks-panel{
  position:relative;
  width:min(1080px,100%);
  max-height:calc(100vh - 48px);
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,#0e0e0e,#080808);
  border:1px solid rgba(255,255,255,.1);
  border-radius:24px;
  overflow:hidden;
  box-shadow:0 50px 100px -40px rgba(0,0,0,1);
  opacity:0;
  transform:perspective(1400px) translateY(28px) rotateX(7deg) scale(.96);
  transform-origin:50% 0;
  transition:
    opacity .5s cubic-bezier(.16,1,.3,1),
    transform .62s cubic-bezier(.16,1,.3,1);
}
.sneaks.in .sneaks-panel{opacity:1;transform:none}

.sneaks-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding:24px 24px 18px;
  border-bottom:1px solid var(--line);
  flex:none;
}
.sneaks-head h3{
  margin:0;font-size:clamp(24px,3.4vw,34px);
  letter-spacing:-.045em;line-height:1.05;
}
.sneaks-head .eyebrow{margin-bottom:8px}

/* same extruded key as .btn — a face sitting on a solid side wall */
.sneaks-close{
  flex:none;
  width:42px;height:42px;
  display:grid;place-items:center;
  border-radius:13px;cursor:pointer;
  color:#d6d6d6;
  background:linear-gradient(180deg,#1c1c1c 0%,#111 55%,#0b0b0b 100%);
  border:1px solid rgba(255,255,255,.1);
  transform:translateY(-3px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 3px 0 #050505,
    0 3px 0 1px #1f1f1f,
    0 8px 16px -6px rgba(0,0,0,.8);
  transition:
    background .3s ease,color .3s ease,
    transform .4s cubic-bezier(.16,1,.3,1),
    box-shadow .4s cubic-bezier(.16,1,.3,1);
}
.sneaks-close svg{width:19px;height:19px}
.sneaks-close:hover{
  color:#fff;
  background:linear-gradient(180deg,#262626 0%,#161616 55%,#0e0e0e 100%);
  transform:translateY(-6px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.18),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 6px 0 #050505,
    0 6px 0 1px #2b2b2b,
    0 14px 22px -8px rgba(0,0,0,.85);
}
.sneaks-close:active{
  transform:translateY(0);
  transition-duration:.08s;
  box-shadow:
    inset 0 2px 6px rgba(0,0,0,.6),
    0 1px 0 #050505,
    0 1px 0 1px #1f1f1f;
}

.sneaks-body{
  padding:22px 24px 34px;
  /* the body is the part that scrolls — min-height:0 is what stops a flex
     child from refusing to shrink, which used to squash the rows into
     each other instead of handing the overflow to the scrollbar */
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
  display:grid;
  align-content:start;
  grid-auto-rows:max-content;
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr));
  gap:22px 16px;
  /* one shared camera, so every tile tilts on the same vanishing point
     instead of each one having its own private perspective */
  perspective:1200px;
  perspective-origin:50% 40%;
}
.sneaks-body::-webkit-scrollbar{width:10px}
.sneaks-body::-webkit-scrollbar-thumb{background:#242424;border-radius:99px;border:3px solid transparent;background-clip:content-box}

.sneak{
  position:relative;
  border:1px solid var(--line);
  border-radius:16px;
  overflow:hidden;
  background:#060606;
  aspect-ratio:1/1;
  transform:translateY(-4px);
  transform-style:preserve-3d;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    0 4px 0 #040404,
    0 4px 0 1px #1a1a1a,
    0 14px 26px -12px rgba(0,0,0,.95);
  transition:
    border-color .35s ease,
    transform .5s cubic-bezier(.16,1,.3,1),
    box-shadow .5s cubic-bezier(.16,1,.3,1);
}
/* lift the slab and tip its top edge away from the viewer */
.sneak:hover{
  border-color:#3a3a3a;
  transform:translateY(-12px) rotateX(7deg) scale(1.015);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    0 9px 0 #040404,
    0 9px 0 1px #2a2a2a,
    0 30px 44px -16px rgba(0,0,0,1);
}
.sneak:active{
  transform:translateY(-1px) rotateX(2deg) scale(1);
  transition-duration:.09s;
  box-shadow:
    inset 0 2px 8px rgba(0,0,0,.6),
    0 1px 0 #040404,
    0 1px 0 1px #1a1a1a;
}
.sneak img,.sneak video{
  width:100%;height:100%;object-fit:cover;display:block;
}
.sneak .badge{
  position:absolute;left:10px;top:10px;
  font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  padding:5px 9px;border-radius:999px;
  background:rgba(5,5,5,.75);border:1px solid rgba(255,255,255,.12);
  backdrop-filter:blur(8px);color:#e4e4e4;
}

.sneaks-empty{
  grid-column:1 / -1;
  padding:52px 20px;
  text-align:center;
  color:#5e5e5e;
  border:1px dashed var(--line2);
  border-radius:16px;
  font-size:14px;line-height:1.7;
}
.sneaks-empty strong{display:block;color:#9a9a9a;font-size:15px;margin-bottom:6px;font-weight:600}

@media(max-width:760px){
  .sneaks{padding:12px}
  .sneaks-panel{max-height:calc(100vh - 24px);border-radius:20px}
  .sneaks-body{grid-template-columns:1fr;padding:18px 16px 22px}
  .sneaks-head{padding:20px 18px 16px}
}

@media(prefers-reduced-motion:reduce){
  .sneaks-panel,.sneaks-backdrop{transition:none}
  .sneaks-panel{transform:none}
}

/* ---------- click-to-play video sneaks ---------- */
.sneak.is-video video{cursor:pointer}

.sneak-play{
  position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);
  width:58px;height:58px;
  display:grid;place-items:center;
  border-radius:50%;cursor:pointer;padding:0;
  color:#0b0b0b;
  background:rgba(245,245,245,.94);
  border:1px solid rgba(255,255,255,.6);
  background:linear-gradient(180deg,#ffffff 0%,#efefef 55%,#dcdcdc 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -2px 0 rgba(0,0,0,.14),
    0 5px 0 #7d7d7d,
    0 14px 30px -10px rgba(0,0,0,.95);
  transition:
    transform .45s cubic-bezier(.16,1,.3,1),
    box-shadow .45s cubic-bezier(.16,1,.3,1),
    background .3s ease,opacity .3s ease;
}
.sneak-play svg{width:24px;height:24px;margin-left:3px}
.sneak:hover .sneak-play{
  transform:translate(-50%,-58%) scale(1.09);
  background:linear-gradient(180deg,#ffffff 0%,#f8f8f8 55%,#e8e8e8 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -2px 0 rgba(0,0,0,.14),
    0 9px 0 #7d7d7d,
    0 22px 38px -12px rgba(0,0,0,1);
}
.sneak-play:active{
  transform:translate(-50%,-50%) scale(1.02);
  transition-duration:.08s;
  box-shadow:
    inset 0 3px 8px rgba(0,0,0,.3),
    0 1px 0 #7d7d7d,
    0 4px 10px -4px rgba(0,0,0,.8);
}

/* a dim wash so the play button reads over bright frames */
.sneak.is-video::after{
  content:"";position:absolute;inset:0;
  background:rgba(4,4,4,.34);
  transition:opacity .35s ease;
  pointer-events:none;
}

/* once it is playing, the button and the wash get out of the way */
.sneak.playing .sneak-play{opacity:0;pointer-events:none;transform:translate(-50%,-50%) scale(.8)}
.sneak.playing::after{opacity:0}
.sneak.playing video{object-fit:contain;background:#000}


/* =========================================================
   depth — the page as a set of panels standing in space
   ---------------------------------------------------------
   Every card already tracks the pointer in 3D (.tilt above). This layer
   gives each one a RESTING pose so a row reads as a fanned deck receding
   from the centre, and puts a solid, un-blurred wall under the panel so
   the slab has visible thickness rather than just a soft drop shadow.
   Hover pulls the panel square-on and forward, out of the fan.
   ========================================================= */

:root{
  --fan-rot:10deg;      /* how hard the outer panels turn away */
  --fan-depth:-70px;    /* how far back they sit */
  --fan-shift:12px;     /* pulled toward the centre so the row stays even */
}

/* ---- the slab: face + side wall ---- */
.tcard,.project,.channel{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.06),
    0 6px 0 -1px #050505,
    0 6px 0 0 rgba(255,255,255,.045),
    0 26px 44px -20px rgba(0,0,0,.95);
  /* transform is repeated here on purpose: this rule sits after .tilt in the
     sheet, so leaving it out would strip the pose transition and make cards
     snap back the instant the pointer leaves. */
  transition:
    transform .7s cubic-bezier(.16,1,.3,1),
    border-color .35s ease,
    box-shadow .6s cubic-bezier(.16,1,.3,1),
    /* the paint order has to hold until the card has finished travelling
       back into the fan, otherwise it drops behind its neighbour while it
       is still in front of them in space */
    z-index 0s linear .7s;
  /* the rows sit flat (no preserve-3d on the grid), so depth ordering is
     decided by z-index, not by translateZ — an angled card overlaps its
     neighbour's cell and would otherwise tear along the seam */
  z-index:1;
  isolation:isolate;
}
.tcard:hover,.project:hover,.channel:hover{
  border-color:#3a3a3a;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.1),
    0 12px 0 -1px #050505,
    0 12px 0 0 rgba(255,255,255,.07),
    0 46px 70px -26px rgba(0,0,0,1);
  /* raised immediately on the way in, released only after the way out */
  z-index:10;
  transition:
    transform .7s cubic-bezier(.16,1,.3,1),
    border-color .35s ease,
    box-shadow .6s cubic-bezier(.16,1,.3,1),
    z-index 0s linear 0s;
}

/* The middle card rests in front of the two fanned ones, so it needs to
   out-rank them even when nothing is hovered. */
.tcard,.project{z-index:3}
.tcard:first-child,.tcard:last-child,
.project:first-child,.project:last-child{z-index:1}

/* ---- testimonials: a three-panel fan ---- */
.tgrid{perspective:1800px}
.tcard:first-child{--pry:calc(var(--fan-rot) * -1);--pz:var(--fan-depth);--px:var(--fan-shift)}
.tcard:last-child {--pry:var(--fan-rot);           --pz:var(--fan-depth);--px:calc(var(--fan-shift) * -1)}
.tcard:hover{--pry:0deg;--pz:70px;--px:0px}

/* ---- work: same fan, a touch flatter so the shots stay readable ---- */
.projects{perspective:1800px}
.project:first-child{--pry:calc(var(--fan-rot) * -.7);--pz:-55px;--px:9px}
.project:last-child {--pry:calc(var(--fan-rot) * .7); --pz:-55px;--px:-9px}
.project:hover{--pry:0deg;--pz:60px;--px:0px}

/* ---- contact: a stack walking away from the viewer ---- */
.channels{perspective:1700px}
.channel:nth-child(2){--pz:-38px;z-index:3}
.channel:nth-child(3){--pz:-76px;z-index:2}
.channel:nth-child(4){--pz:-114px;z-index:1}
/* rows further back must also paint further back — DOM order alone would
   stack each one on top of the row in front of it */
.channel:nth-child(1){z-index:4}
.channel:hover{--pz:55px;--pry:0deg}

/* ---- stats: one extruded bar instead of a flat inset row ---- */
.statline{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.06),
    0 7px 0 -1px #050505,
    0 7px 0 0 rgba(255,255,255,.05),
    0 30px 50px -24px rgba(0,0,0,.95);
  transform:translateY(-5px);
}

/* ---- hero: the logo hangs in front of the page, not on it ---- */
.hero-logo img{
  filter:
    drop-shadow(0 18px 38px rgba(255,255,255,.055))
    drop-shadow(0 40px 60px rgba(0,0,0,.9));
}

/* On a phone the fan turns a readable column into a stack of angled
   slivers, so the resting pose is dropped and only the walls remain. */
@media(max-width:900px){
  .tcard,.project,.channel{--pry:0deg !important;--pz:0px !important;--px:0px !important}
}
@media(prefers-reduced-motion:reduce){
  .tcard,.project,.channel{--pry:0deg !important;--pz:0px !important;--px:0px !important}
}

/* =========================================================
   auth + dashboard
   Same vocabulary as the rest of the site: glass panels on the dark
   ground, extruded keys, the .reveal stagger, the curtain between pages.
   ========================================================= */

.auth-wrap{
  min-height:calc(100vh - 320px);
  display:grid;place-items:center;
  padding:24px 0 70px;
}

.auth-card{
  width:min(430px,100%);
  padding:34px 32px 30px;
  border-radius:24px;
  border:1px solid var(--line2);
  background:linear-gradient(180deg,rgba(16,16,16,.92),rgba(9,9,9,.92));
  backdrop-filter:blur(22px) saturate(140%);
  -webkit-backdrop-filter:blur(22px) saturate(140%);
  box-shadow:
    0 34px 70px -34px rgba(0,0,0,1),
    inset 0 1px 0 rgba(255,255,255,.055);
}
.auth-card .eyebrow{margin-bottom:10px}
.auth-card h1{
  font-size:clamp(28px,4.6vw,38px);
  letter-spacing:-.045em;line-height:1.05;margin:0 0 8px;
}
.auth-card .auth-sub{
  color:var(--muted);font-size:13.5px;line-height:1.65;margin:0 0 26px;
}

/* ---------- fields ---------- */
.field{display:block;margin-bottom:16px}
.field > span{
  display:block;
  font-size:10.5px;letter-spacing:.15em;text-transform:uppercase;
  color:#7d7d7d;margin-bottom:8px;
}
.field .hint{
  display:block;margin-top:7px;
  font-size:11.5px;letter-spacing:0;text-transform:none;color:#5e5e5e;line-height:1.5;
}

.input,
textarea.input{
  width:100%;
  padding:13px 15px;
  font:inherit;font-size:14.5px;
  color:var(--text);
  background:linear-gradient(180deg,#0d0d0d,#080808);
  border:1px solid var(--line2);
  border-radius:13px;
  outline:none;
  transition:border-color .3s ease,box-shadow .3s ease,background .3s ease;
}
.input::placeholder{color:#4a4a4a}
.input:hover{border-color:#313131}
.input:focus{
  border-color:#585858;
  background:linear-gradient(180deg,#101010,#0a0a0a);
  box-shadow:0 0 0 3px rgba(255,255,255,.06);
}
textarea.input{resize:vertical;min-height:104px;line-height:1.6}
.input.bad,.input.bad:focus{
  border-color:#7a2f2f;
  box-shadow:0 0 0 3px rgba(190,60,60,.14);
}

/* password box with the reveal toggle tucked inside it */
.pw{position:relative}
.pw .input{padding-right:50px}
.pw-eye{
  position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:38px;height:38px;
  display:grid;place-items:center;
  background:transparent;border:0;border-radius:10px;
  color:#6e6e6e;cursor:pointer;padding:0;
  transition:color .25s ease,background .25s ease;
}
.pw-eye:hover{color:#d2d2d2;background:rgba(255,255,255,.06)}
.pw-eye svg{width:18px;height:18px}
.pw-eye .eye-off{display:none}
.pw-eye[aria-pressed="true"] .eye-on{display:none}
.pw-eye[aria-pressed="true"] .eye-off{display:block}

/* ---------- notices ---------- */
.notice{
  display:flex;align-items:flex-start;gap:10px;
  padding:12px 14px;margin:0 0 18px;
  border-radius:13px;
  font-size:13px;line-height:1.55;
  border:1px solid var(--line2);
  background:rgba(255,255,255,.03);
  color:#c4c4c4;
}
.notice svg{width:16px;height:16px;flex:none;margin-top:1px}
.notice.err{border-color:#5c2626;background:rgba(150,40,40,.13);color:#f0b6b6}
.notice.ok{border-color:#245a35;background:rgba(40,140,75,.12);color:#a9e6bf}
.notice[hidden]{display:none}

/* the card gives a short shake when the credentials do not match */
@keyframes auth-shake{
  0%,100%{transform:translateX(0)}
  15%{transform:translateX(-8px)}
  32%{transform:translateX(7px)}
  50%{transform:translateX(-5px)}
  68%{transform:translateX(4px)}
  85%{transform:translateX(-2px)}
}
.auth-card.shake{animation:auth-shake .5s cubic-bezier(.36,.07,.19,.97)}
@media(prefers-reduced-motion:reduce){.auth-card.shake{animation:none}}

.auth-actions{margin-top:24px}
.auth-actions .btn{width:100%}
.auth-foot{
  margin:22px 0 0;padding-top:18px;
  border-top:1px solid var(--line);
  font-size:12.5px;color:#5e5e5e;line-height:1.6;
}

/* ---------- dashboard ---------- */
.dash-head{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:20px;flex-wrap:wrap;margin-bottom:8px;
}
.dash-who{
  display:inline-flex;align-items:center;gap:9px;
  font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:#c9c9c9;
  padding:8px 14px;border-radius:999px;
  border:1px solid rgba(255,255,255,.12);
  background:rgba(255,255,255,.035);
  backdrop-filter:blur(10px);
}
.dash-who .dot{--sig:#49d17a}

.dash-grid{
  display:grid;
  grid-template-columns:minmax(0,420px) minmax(0,1fr);
  gap:22px;
  align-items:start;
  margin-top:26px;
}
@media(max-width:900px){
  .dash-grid{grid-template-columns:1fr}
}

.panel{
  padding:26px 24px;
  border-radius:22px;
  border:1px solid var(--line);
  background:linear-gradient(180deg,var(--panel2),var(--panel));
  box-shadow:0 28px 56px -30px rgba(0,0,0,.95);
}
.panel > h2{
  font-size:19px;letter-spacing:-.035em;margin:0 0 4px;line-height:1.2;
}
.panel > .panel-sub{
  color:var(--muted);font-size:13px;line-height:1.6;margin:0 0 22px;
}

/* ---------- image dropzone ---------- */
.drop{
  position:relative;
  display:grid;place-items:center;
  aspect-ratio:16/10;
  border-radius:16px;
  border:1px dashed #2f2f2f;
  background:linear-gradient(180deg,#0b0b0b,#070707);
  cursor:pointer;overflow:hidden;
  text-align:center;
  transition:border-color .3s ease,background .3s ease,transform .3s cubic-bezier(.16,1,.3,1);
}
.drop:hover{border-color:#4a4a4a;background:linear-gradient(180deg,#0e0e0e,#090909)}
.drop.over{border-color:#7c7c7c;border-style:solid;background:rgba(255,255,255,.05);transform:scale(1.008)}
.drop.bad{border-color:#7a2f2f}
.drop input[type=file]{
  position:absolute;inset:0;opacity:0;cursor:pointer;
}
.drop-empty{padding:20px;pointer-events:none}
.drop-empty svg{width:28px;height:28px;color:#4d4d4d;margin-bottom:10px}
.drop-empty strong{display:block;font-size:14px;font-weight:600;margin-bottom:5px}
.drop-empty small{display:block;color:#5e5e5e;font-size:12px;line-height:1.55}
.drop img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;display:block;
}
.drop:not(.has) img{display:none}
.drop.has .drop-empty{display:none}
.drop-swap{
  position:absolute;left:0;right:0;bottom:0;
  padding:26px 14px 11px;
  font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:#e2e2e2;
  background:linear-gradient(transparent,rgba(0,0,0,.85));
  opacity:0;transition:opacity .3s ease;pointer-events:none;
}
.drop.has:hover .drop-swap{opacity:1}
.req{color:#d98b8b;font-weight:600}

.form-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:520px){.form-row{grid-template-columns:1fr}}

select.input{
  appearance:none;-webkit-appearance:none;
  background-image:
    linear-gradient(45deg,transparent 50%,#6e6e6e 50%),
    linear-gradient(135deg,#6e6e6e 50%,transparent 50%),
    linear-gradient(180deg,#0d0d0d,#080808);
  background-position:calc(100% - 19px) 21px,calc(100% - 14px) 21px,0 0;
  background-size:5px 5px,5px 5px,100% 100%;
  background-repeat:no-repeat;
  padding-right:40px;cursor:pointer;
}
select.input option{background:#0d0d0d;color:var(--text)}

.form-actions{
  display:flex;gap:14px;flex-wrap:wrap;
  margin-top:24px;padding:0 0 12px;
}

/* ---------- saved list ---------- */
.saved-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:14px;flex-wrap:wrap;margin-bottom:20px;
}
.saved-head h2{margin:0;font-size:19px;letter-spacing:-.035em}
.count-chip{
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  padding:6px 12px;border-radius:999px;
  border:1px solid var(--line2);color:#8d8d8d;
  background:rgba(255,255,255,.025);
}

.saved{display:flex;flex-direction:column;gap:12px}

.saved-item{
  display:grid;
  grid-template-columns:104px minmax(0,1fr) auto;
  gap:15px;align-items:center;
  padding:12px;
  border-radius:16px;
  border:1px solid var(--line);
  background:linear-gradient(180deg,#0c0c0c,#080808);
  transition:border-color .3s ease,transform .45s cubic-bezier(.16,1,.3,1),box-shadow .45s ease,opacity .3s ease;
}
.saved-item:hover{
  border-color:#2e2e2e;
  transform:translateY(-2px);
  box-shadow:0 18px 34px -22px rgba(0,0,0,.95);
}
.saved-item .thumb{
  width:104px;aspect-ratio:16/10;
  border-radius:11px;overflow:hidden;background:#070707;
  border:1px solid var(--line);
}
.saved-item .thumb img{width:100%;height:100%;object-fit:cover;display:block}
.saved-meta{min-width:0}
.saved-meta strong{
  display:block;font-size:15px;letter-spacing:-.025em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.saved-meta small{
  display:block;color:#6a6a6a;font-size:12px;margin-top:4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.saved-tools{display:flex;gap:7px;flex:none}

/* small square keys — the .btn extrusion at icon scale */
.icon-btn{
  width:38px;height:38px;
  display:grid;place-items:center;
  border-radius:11px;
  border:1px solid var(--line2);
  background:linear-gradient(180deg,#191919,#0d0d0d);
  color:#a5a5a5;cursor:pointer;padding:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 2px 0 #050505;
  transition:transform .3s cubic-bezier(.16,1,.3,1),color .25s ease,border-color .25s ease,box-shadow .3s ease;
}
.icon-btn svg{width:16px;height:16px}
.icon-btn:hover{
  transform:translateY(-2px);color:#f2f2f2;border-color:#3a3a3a;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 4px 0 #050505;
}
.icon-btn:active{transform:translateY(1px);box-shadow:inset 0 2px 5px rgba(0,0,0,.5)}
.icon-btn.danger:hover{color:#ff9c9c;border-color:#6a2b2b}
.icon-btn.good:hover{color:#a6f0bd;border-color:#2f6a45}

/* a review waiting on the admin account */
.saved-item.is-pending{border-color:#5a4a1f;background:rgba(255,199,88,.05)}
.state-chip{
  display:inline-block;margin-left:2px;padding:2px 8px;border-radius:999px;
  border:1px solid #5a4a1f;background:rgba(255,199,88,.12);
  color:#ffd489;font-size:11px;letter-spacing:.02em;vertical-align:middle;
}
.client-box{border-top:1px solid #222;margin-top:8px}
.client-box code{
  padding:1px 6px;border-radius:6px;border:1px solid #2a2a2a;
  background:#141414;color:#cfcfcf;font-size:11.5px;
}

/* an avatar that came from Discord: shown, but not swappable */
.drop.locked{cursor:default;opacity:.92}
.drop.locked input{pointer-events:none}
.drop.locked .drop-swap{display:none}
.icon-btn:focus-visible{outline:2px solid #6b6b6b;outline-offset:2px}

.saved-empty{
  padding:44px 22px;text-align:center;
  border:1px dashed #232323;border-radius:16px;
  color:#5e5e5e;font-size:13.5px;line-height:1.7;
}
.saved-empty strong{display:block;color:#9a9a9a;font-size:15px;margin-bottom:6px}

@media(max-width:520px){
  .saved-item{grid-template-columns:74px minmax(0,1fr);row-gap:11px}
  .saved-item .thumb{width:74px}
  .saved-tools{grid-column:1 / -1;justify-content:flex-end}
}

/* a card that was just added lands instead of appearing */
@keyframes saved-land{
  from{opacity:0;transform:translateY(-10px) scale(.98)}
  to{opacity:1;transform:none}
}
.saved-item.fresh{animation:saved-land .5s cubic-bezier(.16,1,.3,1) both}
.saved-item.going{opacity:0;transform:translateX(28px) scale(.97)}
@media(prefers-reduced-motion:reduce){
  .saved-item.fresh{animation:none}
}

/* a project card that came from the dashboard rather than the markup */
.project.from-store .info p.empty{color:#5e5e5e;font-style:italic}

/* =========================================================
   ticker — a grid with more cards than fit on one row stops
   wrapping and becomes a slow conveyor that loops forever.
   Pointer over it (or keyboard focus in it) holds it still.
   ========================================================= */
.ticker{
  display:block;
  overflow:hidden;
  /* the cards lift and tilt, so the strip needs air above and below
     rather than a hard edge to clip against */
  padding:18px 0 26px;
  margin:-18px 0 -8px;
  /* the ends fade out instead of being cut off, which is what sells the
     strip as continuous rather than as a row that happens to be clipped */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5.5%,#000 94.5%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 5.5%,#000 94.5%,transparent);
}

.ticker-track{
  display:flex;
  align-items:stretch;
  gap:var(--tgap,20px);
  width:max-content;
  will-change:transform;
  animation:ticker-run 60s linear infinite;
}

/* One copy's width — measured in JS and written to --tspan — is exactly
   how far the track travels before the second copy is standing where the
   first one started, which is why the restart cannot be seen. */
@keyframes ticker-run{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(calc(var(--tspan,0px) * -1),0,0)}
}

.ticker.hold .ticker-track,
.ticker:focus-within .ticker-track{
  animation-play-state:paused;
}

/* the cards no longer get their width from grid tracks */
.ticker > .ticker-track > .project{
  flex:0 0 clamp(280px,26vw,360px);
}
.ticker > .ticker-track > .tcard{
  flex:0 0 clamp(270px,24vw,330px);
}

/* The fan pose leans the first and last card of a row outward. In a strip
   that never ends there is no first or last, so it is dropped. */
.ticker > .ticker-track > .project:first-child,
.ticker > .ticker-track > .project:last-child,
.ticker > .ticker-track > .tcard:first-child,
.ticker > .ticker-track > .tcard:last-child{
  --pry:0deg;--pz:0px;--px:0px;
}

/* a clone is scenery: screen readers already read the original */
.ticker-track > [data-clone]{}

@media(max-width:760px){
  .ticker{
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 3%,#000 97%,transparent);
    mask-image:linear-gradient(90deg,transparent,#000 3%,#000 97%,transparent);
  }
  .ticker > .ticker-track > .project{flex:0 0 min(300px,82vw)}
  .ticker > .ticker-track > .tcard{flex:0 0 min(290px,82vw)}
}

@media(prefers-reduced-motion:reduce){
  .ticker-track{animation:none}
}

/* =========================================================
   dashboard tabs — the nav's sliding pill, at section scale
   ========================================================= */
.tabs{
  position:relative;
  display:inline-flex;align-items:center;gap:2px;
  margin-top:26px;
  padding:5px;
  border-radius:15px;
  background:rgba(255,255,255,.028);
  border:1px solid rgba(255,255,255,.05);
}
.tab{
  position:relative;z-index:2;
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 18px;border-radius:11px;
  font:inherit;font-size:13.5px;letter-spacing:-.005em;
  color:var(--muted);
  background:transparent;border:0;cursor:pointer;
  transition:color .3s ease;
  white-space:nowrap;
}
.tab:hover{color:#d6d6d6}
.tab[aria-selected="true"]{color:var(--text)}
.tab:focus-visible{outline:2px solid #6b6b6b;outline-offset:2px}

.tab-n{
  display:inline-grid;place-items:center;
  min-width:20px;height:20px;padding:0 6px;
  border-radius:999px;
  font-size:11px;font-weight:650;
  color:#8d8d8d;
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.06);
  transition:color .3s ease,background .3s ease;
}
.tab[aria-selected="true"] .tab-n{color:#0a0a0a;background:#e8e8e8;border-color:#e8e8e8}

.tab-pill{
  position:absolute;z-index:1;top:5px;left:0;
  height:calc(100% - 10px);width:0;
  border-radius:11px;
  background:rgba(255,255,255,.075);
  border:1px solid rgba(255,255,255,.06);
  opacity:0;
  transition:
    transform .5s cubic-bezier(.16,1,.3,1),
    width .5s cubic-bezier(.16,1,.3,1),
    opacity .3s ease;
  pointer-events:none;
}
.tabs.pill-on .tab-pill{opacity:1}

/* the pane that is not showing is hidden outright, not just faded */
.dash-grid[hidden]{display:none}

/* switching panes should feel like the rest of the site, not a jump cut */
@keyframes pane-in{
  from{opacity:0;transform:translateY(8px)}
  to{opacity:1;transform:none}
}
.dash-grid.pane-in{animation:pane-in .45s cubic-bezier(.16,1,.3,1) both}
@media(prefers-reduced-motion:reduce){.dash-grid.pane-in{animation:none}}

@media(max-width:520px){
  .tabs{display:flex;width:100%}
  .tab{flex:1;justify-content:center;padding:11px 10px}
}

/* =========================================================
   star picker
   ========================================================= */
.stars-pick{display:inline-flex;gap:4px}
.star{
  width:34px;height:34px;
  display:grid;place-items:center;
  font-size:19px;line-height:1;
  color:#3a3a3a;
  background:transparent;border:0;border-radius:9px;
  cursor:pointer;padding:0;
  transition:color .2s ease,transform .28s cubic-bezier(.16,1,.3,1),background .2s ease;
}
.star:hover{background:rgba(255,255,255,.05);transform:translateY(-2px)}
.star.on{color:#f0c94b}
.star:focus-visible{outline:2px solid #6b6b6b;outline-offset:1px}

/* an avatar is round, so its dropzone should be too */
.drop-round{
  aspect-ratio:1/1;
  width:150px;
  border-radius:50%;
  margin:2px auto 0;
}
.drop-round .drop-empty{padding:16px}
.drop-round .drop-empty strong{font-size:12px;line-height:1.35;margin-bottom:4px}
.drop-round .drop-empty small{font-size:10.5px;line-height:1.4}
.drop-round .drop-empty svg{width:24px;height:24px;margin-bottom:6px}
.drop-round .drop-swap{padding:20px 10px 14px;font-size:10px;text-align:center}

/* feedback rows show a round thumb and let the quote wrap to two lines */
.saved-item.is-feedback{grid-template-columns:54px minmax(0,1fr) auto}
.saved-item.is-feedback .thumb{
  width:54px;height:54px;aspect-ratio:1/1;border-radius:50%;
  display:grid;place-items:center;
  font-size:15px;font-weight:650;color:#8d8d8d;
  background:linear-gradient(180deg,#161616,#0d0d0d);
}
.saved-item.is-feedback .thumb img{border-radius:50%}
.saved-item.is-feedback .saved-meta strong{
  white-space:normal;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
  font-size:13.5px;font-weight:500;line-height:1.45;color:#d8d8d8;
}
.saved-item.is-feedback .saved-meta small{margin-top:6px}
.saved-item.is-feedback .saved-meta .rating{color:#f0c94b;letter-spacing:1px}

@media(max-width:520px){
  .saved-item.is-feedback{grid-template-columns:54px minmax(0,1fr)}
}

/* =========================================================
   work page — portfolio grid, filters and the detail panel
   ========================================================= */
.wfilters{margin:0 0 24px}
.wfilters .tab{padding:10px 15px}
.wfilters .tab[hidden]{display:none}

.wgrid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(288px,1fr));
  gap:18px;
}
.wgrid > [hidden]{display:none}
.wgrid[aria-busy="true"]{min-height:180px}

.wcard{
  position:relative;
  display:flex;flex-direction:column;
  overflow:hidden;cursor:pointer;
  background:linear-gradient(180deg,var(--panel2),var(--panel));
  border:1px solid var(--line);
  border-radius:20px;
  transition:transform .5s cubic-bezier(.16,1,.3,1),border-color .35s ease,box-shadow .5s ease;
}
.wcard:hover{
  transform:translateY(-6px);
  border-color:#2e2e2e;
  box-shadow:0 28px 56px -26px rgba(0,0,0,.95);
}
.wcard:focus-visible{outline:2px solid #6b6b6b;outline-offset:3px}

.wshot{
  position:relative;
  aspect-ratio:16/9;
  overflow:hidden;
  background:#080808;
  border-bottom:1px solid var(--line);
}
.wshot img,.wshot video{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.92);
  transform:scale(1.02);
  transition:transform 1.1s cubic-bezier(.16,1,.3,1),filter .5s ease;
}
.wcard:hover .wshot img,.wcard:hover .wshot video{transform:scale(1.06);filter:saturate(1.05)}
.wshot::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(5,5,5,.2) 0%,transparent 42%,rgba(5,5,5,.6) 100%);
}

/* a text-only entry gets a quote slab instead of a still */
.wshot.is-text{
  display:grid;place-items:center;
  background:
    radial-gradient(circle at 30% 20%, rgba(255,255,255,.07), transparent 60%),
    linear-gradient(180deg,#101010,#070707);
}
.wmark{
  font-size:84px;line-height:.6;color:#232323;
  font-family:Georgia,"Times New Roman",serif;
  transition:color .45s ease,transform .6s cubic-bezier(.16,1,.3,1);
}
.wcard:hover .wmark{color:#343434;transform:translateY(-4px)}

.wkind{
  position:absolute;right:13px;top:13px;z-index:2;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  padding:6px 11px;border-radius:999px;
  background:rgba(5,5,5,.72);
  border:1px solid rgba(255,255,255,.1);
  backdrop-filter:blur(10px);
  color:#e9e9e9;
}

.wplay{
  position:absolute;left:50%;top:50%;z-index:2;
  width:44px;height:44px;margin:-22px 0 0 -22px;
  border-radius:50%;
  background:rgba(8,8,8,.68);
  border:1px solid rgba(255,255,255,.18);
  backdrop-filter:blur(8px);
  transition:opacity .35s ease,transform .45s cubic-bezier(.16,1,.3,1);
}
.wplay::after{
  content:"";position:absolute;left:50%;top:50%;
  width:0;height:0;margin:-9px 0 0 -5px;
  border-left:13px solid #f0f0f0;
  border-top:8px solid transparent;
  border-bottom:8px solid transparent;
}
.wcard:hover .wplay{opacity:0;transform:scale(.82)}

.winfo{
  display:flex;flex-direction:column;gap:10px;
  padding:17px 18px 19px;
  flex:1;
}
.wmeta{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);
}
.wmeta span + span::before{content:"·";margin-right:8px;color:#3a3a3a}
.winfo h3{
  margin:0;font-size:17.5px;letter-spacing:-.035em;line-height:1.2;
}
.winfo > p{
  margin:0;flex:1;
  color:var(--muted);font-size:13px;line-height:1.6;
}
.wcard:hover .tag{border-color:#333;color:#a5a5a5}
.wcard:hover .open-hint{color:#f0f0f0}
.wcard:hover .open-hint b{transform:translateX(5px)}

.wempty{
  grid-column:1/-1;
  padding:44px 20px;text-align:center;
  border:1px dashed var(--line2);border-radius:20px;
  color:var(--muted);
}
.wempty strong{display:block;color:#9a9a9a;font-size:15px;margin-bottom:6px}
.wempty span{font-size:13px}

@keyframes wrefade{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.wcard.refade{animation:wrefade .45s cubic-bezier(.16,1,.3,1) both}

/* ---------- detail panel ---------- */
.wpanel{
  position:fixed;inset:0;z-index:300;
  display:grid;place-items:center;
  padding:24px;
}
.wpanel[hidden]{display:none}

.wpanel-backdrop{
  position:absolute;inset:0;
  background:rgba(3,3,3,.82);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  opacity:0;transition:opacity .45s ease;
}
.wpanel.on .wpanel-backdrop{opacity:1}

.wpanel-sheet{
  position:relative;
  width:min(820px,100%);
  max-height:calc(100vh - 48px);
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,#0e0e0e,#080808);
  border:1px solid rgba(255,255,255,.1);
  border-radius:24px;
  overflow:hidden;
  box-shadow:0 50px 100px -40px rgba(0,0,0,1);
  opacity:0;
  transform:perspective(1400px) translateY(28px) rotateX(7deg) scale(.96);
  transform-origin:50% 0;
  transition:
    opacity .5s cubic-bezier(.16,1,.3,1),
    transform .62s cubic-bezier(.16,1,.3,1);
}
.wpanel.on .wpanel-sheet{opacity:1;transform:none}

.wpanel-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding:24px 24px 18px;
  border-bottom:1px solid var(--line);
  flex:none;
}
.wpanel-head h3{
  margin:0;font-size:clamp(22px,3.2vw,32px);
  letter-spacing:-.045em;line-height:1.06;
}
.wpanel-head .eyebrow{margin-bottom:8px}
.wpanel-sub{
  margin-top:9px;
  font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);
}
.wpanel-sub:empty{display:none}

.wpanel-close{
  flex:none;
  width:42px;height:42px;
  display:grid;place-items:center;
  border-radius:13px;cursor:pointer;
  color:#d6d6d6;
  background:linear-gradient(180deg,#1c1c1c 0%,#111 55%,#0b0b0b 100%);
  border:1px solid rgba(255,255,255,.1);
  transition:color .3s ease,border-color .3s ease,transform .3s ease;
}
.wpanel-close:hover{color:#fff;border-color:#3a3a3a;transform:translateY(-2px)}
.wpanel-close svg{width:18px;height:18px}
.wpanel-close:focus-visible{outline:2px solid #6b6b6b;outline-offset:2px}

.wpanel-body{
  padding:22px 24px 26px;
  overflow:auto;
}
.wpanel-media{
  border-radius:16px;overflow:hidden;
  border:1px solid var(--line);
  background:#000;
  margin-bottom:22px;
}
.wpanel-media[hidden]{display:none}
.wpanel-media video,.wpanel-media img{
  width:100%;display:block;max-height:54vh;object-fit:contain;background:#000;
}

.wpanel-text{color:#c6c6c6;font-size:14.5px;line-height:1.75}
.wpanel-text p{margin:0 0 14px}
.wpanel-text .wpanel-lead{color:#ededed;font-size:16px;line-height:1.65}
.wpanel-text h4{
  margin:24px 0 10px;
  font-size:12px;letter-spacing:.15em;text-transform:uppercase;color:#f0f0f0;
}
.wpanel-text .wpanel-empty{color:#5e5e5e;font-style:italic}
.wpanel-text ul{margin:0 0 14px;padding-left:18px}
.wpanel-text li{margin-bottom:7px}

.wpanel-links{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px}
.wpanel-links[hidden]{display:none}

@media(max-width:760px){
  .wgrid{grid-template-columns:1fr;gap:16px}
  .wpanel{padding:12px}
  .wpanel-sheet{max-height:calc(100vh - 24px)}
  .wpanel-head{padding:18px 18px 14px}
  .wpanel-body{padding:18px}
}
