/* ══════════ EGGFOLIO — folha única para todas as páginas ══════════ */
:root{
  --black:#000000;
  --yellow:#f3e600;
  --dim:#8a8330;
  --line:rgba(243,230,0,.26);
  --line-soft:rgba(243,230,0,.13);
  --pad:clamp(16px,3.2vw,44px);
  --glow:0 0 4px rgba(243,230,0,.45);
  --glow-hard:0 0 6px rgba(243,230,0,.75);
  --box-glow:0 0 10px rgba(243,230,0,.14), inset 0 0 14px rgba(243,230,0,.05);
  --head-h:59px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  background:var(--black);color:var(--yellow);
  font-family:'IBM Plex Mono',ui-monospace,monospace;
  overflow-x:hidden;-webkit-font-smoothing:antialiased;
  text-shadow:var(--glow);
}
::selection{background:var(--yellow);color:#000;text-shadow:none}
img{display:block;max-width:100%}

/* ══════════ CURSOR ══════════ */
@media (hover:hover) and (pointer:fine){
  *{cursor:none !important}
  /* Hidden until it has been placed, so it never flashes at screen centre */
  #cur{position:fixed;top:0;left:0;z-index:10000;pointer-events:none;
    transform:translate(-50%,-50%);will-change:transform;
    opacity:0;transition:opacity .12s}
  #cur.ready{opacity:1}
  #cur .br{position:absolute;width:9px;height:9px;border:1.5px solid var(--yellow);
    filter:drop-shadow(0 0 1px #000) drop-shadow(0 0 5px rgba(243,230,0,.9));
    transition:transform .16s cubic-bezier(.3,1.4,.4,1)}
  #cur .br.a{top:-15px;left:-15px;border-right:0;border-bottom:0}
  #cur .br.b{top:-15px;right:-15px;border-left:0;border-bottom:0}
  #cur .br.c{bottom:-15px;left:-15px;border-right:0;border-top:0}
  #cur .br.d{bottom:-15px;right:-15px;border-left:0;border-top:0}
  #cur .dot{position:absolute;top:-1.5px;left:-1.5px;width:3px;height:3px;background:var(--yellow);
    filter:drop-shadow(0 0 1px #000) drop-shadow(0 0 6px rgba(243,230,0,1))}
  #cur .hl,#cur .vl{position:absolute;background:rgba(243,230,0,.55);filter:drop-shadow(0 0 1px #000)}
  #cur .hl{top:-.5px;left:-11px;width:22px;height:1px}
  #cur .vl{left:-.5px;top:-11px;height:22px;width:1px}
  #cur.hot .br.a{transform:translate(-7px,-7px)}
  #cur.hot .br.b{transform:translate(7px,-7px)}
  #cur.hot .br.c{transform:translate(-7px,7px)}
  #cur.hot .br.d{transform:translate(7px,7px)}
  #cur.hot .dot{background:#fff}
  #curlabel{position:absolute;left:24px;top:14px;font-size:8px;letter-spacing:.16em;
    white-space:nowrap;color:var(--yellow);opacity:0;transition:opacity .15s}
  #cur.hot #curlabel{opacity:.9}
}
@media (hover:hover) and (pointer:fine){
  /* class selectors outrank the bare * rule above */
  body.native-cursor,body.native-cursor *{cursor:auto !important}
  body.native-cursor #cur{opacity:0 !important}
  #cur{transition:opacity .12s}
}
@media not all and (hover:hover){#cur{display:none}}

/* ══════════ CRT ══════════ */
.crt{position:fixed;inset:0;pointer-events:none;z-index:9200;
  box-shadow:inset 2px 0 22px rgba(255,0,80,.05), inset -2px 0 22px rgba(0,200,255,.05);
  background:
    /* Vignette. It used to reach rgba(0,0,0,.92) at the edges, which is where
       the header links and the footer live — they were being dimmed almost to
       black. Now it starts later and never gets past a quarter opacity: still
       a curved-glass falloff, but the corners stay readable. */
    radial-gradient(ellipse at center, transparent 62%, rgba(0,0,0,.10) 88%, rgba(0,0,0,.24) 100%),
    radial-gradient(ellipse at 50% 45%, rgba(243,230,0,.045) 0%, rgba(243,230,0,0) 62%),
    repeating-linear-gradient(to bottom,
      rgba(0,0,0,.42) 0px, rgba(0,0,0,.42) 1px, rgba(0,0,0,0) 1px, rgba(0,0,0,0) 3px);
}
.crt-sweep{position:fixed;left:0;right:0;top:0;height:22vh;pointer-events:none;z-index:9203;
  will-change:transform;
  background:linear-gradient(to bottom,rgba(243,230,0,0),rgba(243,230,0,.055),rgba(255,255,255,.03),rgba(243,230,0,0));
  animation:sweep 7s linear infinite}
@keyframes sweep{0%{transform:translate3d(0,-25vh,0)}100%{transform:translate3d(0,105vh,0)}}
.grain{position:fixed;inset:-6%;pointer-events:none;z-index:9204;opacity:.13;will-change:transform;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  animation:grain 620ms steps(5) infinite}
@keyframes grain{0%{transform:translate3d(0,0,0)}20%{transform:translate3d(-2%,1.5%,0)}
  40%{transform:translate3d(1.5%,-2%,0)}60%{transform:translate3d(-1.5%,-1.5%,0)}
  80%{transform:translate3d(2%,1%,0)}100%{transform:translate3d(-1%,2%,0)}}
.flicker{position:fixed;inset:0;pointer-events:none;z-index:9205;
  background:rgba(243,230,0,.055);opacity:0;animation:fl 5.5s steps(1) infinite}
@keyframes fl{0%,90%{opacity:0}90.4%{opacity:.9}90.8%{opacity:0}92%{opacity:.5}
  92.4%{opacity:0}96%{opacity:1}96.3%{opacity:0}97.6%{opacity:.6}98%{opacity:0}}

body.lite .grain,body.lite .crt-sweep,body.lite .flicker{display:none}
body.lite{text-shadow:none}
body.lite .eggfolio{text-shadow:0 0 10px rgba(243,230,0,.5)}
body.lite .ln .p,body.lite .ln .s,body.lite .ln .ok,
body.lite .brand,body.lite .welcome,body.lite h1{text-shadow:0 0 4px rgba(243,230,0,.5)}
@media (prefers-reduced-motion:reduce){
  .grain,.crt-sweep,.flicker{display:none}
  html{scroll-behavior:auto}
}

/* ══════════ BOOT / TRANSIÇÃO ENTRE PÁGINAS ══════════ */
/* The blackout now ships in the HTML, which means a broken script would
   leave a black page forever. This lifts it after 12s no matter what —
   JavaScript normally beats it there by ten. */
#boot{position:fixed;inset:0;z-index:9500;background:#000;
  display:flex;align-items:center;justify-content:center;flex-direction:column;gap:14px;
  animation:bootFailsafe 1s linear 12s forwards}
@keyframes bootFailsafe{to{opacity:0;visibility:hidden}}
#boot.done{opacity:0;visibility:hidden;transition:opacity .3s ease,visibility 0s .3s}
#boot.out{opacity:1;visibility:visible;transition:opacity .16s ease}
#boot .bar{width:min(340px,60vw);height:2px;background:rgba(243,230,0,.18);overflow:hidden}
#boot .bar i{display:block;height:100%;width:0;background:var(--yellow);
  box-shadow:var(--glow-hard);transition:width .18s}
#boot .log{font-size:11px;letter-spacing:.14em;color:var(--dim);height:1.2em}

/* ══════════ COMUNS ══════════ */
.mono-label{font-size:clamp(9px,.72vw,11px);letter-spacing:.22em;text-transform:uppercase;color:var(--dim)}
.tick{color:var(--yellow);text-shadow:var(--glow-hard)}
.btn{font-family:inherit;font-size:clamp(10px,.88vw,12px);letter-spacing:.2em;text-transform:uppercase;
  color:var(--yellow);background:transparent;border:1px solid var(--line);
  padding:13px 26px;text-decoration:none;position:relative;overflow:hidden;display:inline-block;
  box-shadow:var(--box-glow);transition:color .18s,border-color .18s,box-shadow .18s}
.btn span{position:relative;z-index:2}
.btn::before{content:"";position:absolute;inset:0;background:var(--yellow);
  transform:scaleX(0);transform-origin:left;transition:transform .22s cubic-bezier(.7,0,.2,1)}
.btn:hover{color:#000;border-color:var(--yellow);text-shadow:none;box-shadow:0 0 22px rgba(243,230,0,.45)}
.btn:hover::before{transform:scaleX(1)}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  border-bottom:1px solid var(--line);padding-bottom:12px;margin-bottom:clamp(22px,3.5vw,40px);
  box-shadow:0 1px 10px rgba(243,230,0,.10)}
.sec-head h2{font-size:clamp(13px,1.3vw,17px);font-weight:600;letter-spacing:.24em;text-transform:uppercase}

/* ══════════ HEADER ══════════ */
header{position:fixed;top:0;left:0;right:0;z-index:8000;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:18px var(--pad);border-bottom:1px solid var(--line);
  box-shadow:0 1px 12px rgba(243,230,0,.10);
  background:linear-gradient(to bottom,#000 0%,rgba(0,0,0,.96) 62%,rgba(0,0,0,.82) 100%)}
.brand{font-size:clamp(15px,1.5vw,19px);font-weight:700;letter-spacing:.04em;
  color:var(--yellow);text-decoration:none;text-shadow:var(--glow-hard)}
.role{font-size:clamp(9px,.75vw,11px);letter-spacing:.2em;text-transform:uppercase;
  color:var(--dim);text-align:center;white-space:nowrap}
nav{display:flex;gap:22px;justify-content:flex-end}
nav a{font-size:clamp(10px,.85vw,12px);letter-spacing:.18em;text-transform:uppercase;
  color:var(--yellow);text-decoration:none;position:relative;padding-bottom:3px;opacity:.8;transition:opacity .18s}
nav a::after{content:"";position:absolute;left:0;bottom:0;width:0;height:1px;background:var(--yellow);
  box-shadow:var(--glow);transition:width .22s ease}
nav a:hover,nav a.on{opacity:1;text-shadow:var(--glow-hard)}
nav a:hover::after,nav a.on::after{width:100%}

/* ══════════ HERO (home) ══════════ */
#hero{position:relative;height:100svh;min-height:560px;display:grid;place-items:center;overflow:hidden}
#head{position:absolute;inset:0;width:100%;height:100%;z-index:1}
.hero-type{position:relative;z-index:3;text-align:center;pointer-events:none;width:100%}
.welcome{font-size:clamp(11px,1.5vw,20px);letter-spacing:.5em;text-transform:uppercase;
  color:var(--yellow);opacity:.9;margin-left:.5em;text-shadow:var(--glow-hard)}
.eggfolio{font-size:clamp(58px,15.5vw,250px);font-weight:700;line-height:.86;letter-spacing:-.02em;
  color:var(--yellow);margin-top:.06em;
  text-shadow:0 0 6px rgba(243,230,0,.7),0 0 34px rgba(243,230,0,.30)}
.hero-cta{position:absolute;left:0;right:0;bottom:clamp(74px,11vh,120px);z-index:5;
  display:flex;gap:14px;justify-content:center;flex-wrap:wrap;padding:0 var(--pad)}
.hud{position:absolute;inset:0;z-index:4;pointer-events:none}
.hud .corner{position:absolute;width:16px;height:16px;border:1px solid var(--line);
  box-shadow:0 0 8px rgba(243,230,0,.2)}
.hud .tl{top:calc(var(--pad) + 46px);left:var(--pad);border-right:0;border-bottom:0}
.hud .tr{top:calc(var(--pad) + 46px);right:var(--pad);border-left:0;border-bottom:0}
.hud .bl{bottom:var(--pad);left:var(--pad);border-right:0;border-top:0}
.hud .br2{bottom:var(--pad);right:var(--pad);border-left:0;border-top:0}
.hud .tag{position:absolute;font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim)}
.hud .t-left{bottom:var(--pad);left:calc(var(--pad) + 28px)}
.hud .t-right{bottom:var(--pad);right:calc(var(--pad) + 28px);text-align:right}
.ruler{position:absolute;left:var(--pad);right:var(--pad);display:flex;justify-content:space-between;
  font-size:8px;letter-spacing:.1em;color:rgba(243,230,0,.34)}
.ruler.top{top:calc(var(--pad) + 30px)}
.scroll-hint{position:absolute;left:50%;transform:translateX(-50%);bottom:calc(var(--pad) + 26px);
  z-index:5;font-size:9px;letter-spacing:.28em;color:var(--dim);animation:pulse 2.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:1}}

/* ══════════ STREAMS ══════════ */
.stream{position:absolute;z-index:2;pointer-events:none;contain:content;
  display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden;
  top:21vh;height:50vh;width:min(23vw,290px);
  font-size:10px;line-height:1.8;letter-spacing:.055em;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 93%,transparent 100%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 93%,transparent 100%)}
.stream.left{left:var(--pad)}
.stream.right{right:var(--pad)}
.ln{white-space:pre;min-height:1.8em}
.ln .p {color:var(--yellow);font-weight:600;text-shadow:var(--glow-hard)}
.ln .c {color:rgba(243,230,0,.88)}
.ln .k {color:var(--dim)}
.ln .s {color:var(--yellow);text-shadow:var(--glow)}
.ln .m {color:rgba(243,230,0,.34);font-style:italic}
.ln .ok{color:var(--yellow);text-shadow:var(--glow-hard)}
.ln .n {color:rgba(243,230,0,.62)}
.ln .rule{color:rgba(243,230,0,.16)}
.ln.active::after{content:"▋";color:var(--yellow);text-shadow:var(--glow-hard);
  animation:blink .8s steps(1) infinite}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
@media(max-width:1180px){.stream{display:none}}

/* ══════════ GALERIA DA HOME ══════════ */
#work{position:relative;z-index:2;padding:clamp(60px,9vh,120px) var(--pad) clamp(50px,8vh,100px)}
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(14px,1.8vw,26px)}
.card{position:relative;aspect-ratio:16/9;overflow:hidden;border:1px solid var(--line);
  display:block;text-decoration:none;background:#080800;box-shadow:var(--box-glow);contain:paint}
/* Covers keep their colour now. A light contrast and saturation lift is all
   they get, so they read as artwork instead of a texture. */
.card .thumb{position:absolute;inset:0;background-size:cover;background-position:center;
  filter:contrast(1.05) saturate(1.08) brightness(.94);
  transition:filter .35s,transform .5s cubic-bezier(.2,.6,.2,1)}
.card:hover .thumb{transform:scale(1.03);filter:contrast(1.02) saturate(1.14) brightness(1)}

/* DISPLACEMENT — a second copy of the same image, revealed only through thin
   horizontal bands and nudged sideways by a pixel or two. The illusion of a
   drifting signal, done with one transform: no pixels are ever recomputed,
   so it animates on the GPU and costs nothing per frame. */
.card .thumb .shift{position:absolute;inset:0;display:block;background:inherit;
  -webkit-mask-image:repeating-linear-gradient(to bottom,#000 0 2px,transparent 2px 7px);
          mask-image:repeating-linear-gradient(to bottom,#000 0 2px,transparent 2px 7px);
  opacity:.6;will-change:transform;animation:drift 9s ease-in-out infinite}
@keyframes drift{
  0%,100%{transform:translate3d(0,0,0)}
  20%{transform:translate3d(1.5px,0,0)}
  45%{transform:translate3d(-2px,0,0)}
  70%{transform:translate3d(1px,0,0)}
}

/* ══════════ CRT LAYERS, shared by covers and project media ══════════
   Scanlines are static so they paint once. The dither is a real 4x4 Bayer
   matrix tiled at 4px; inset:-4px keeps its edge off-screen while it drifts. */
.fx{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:repeating-linear-gradient(to bottom,
    rgba(0,0,0,.34) 0 1px, rgba(0,0,0,0) 1px 3px)}
.dither{position:absolute;inset:-4px;z-index:1;pointer-events:none;
  opacity:.28;mix-blend-mode:overlay;background-size:4px 4px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'><rect x='0' y='0' width='1' height='1' fill='%23000' fill-opacity='1'/><rect x='2' y='0' width='1' height='1' fill='%23000' fill-opacity='0.75'/><rect x='3' y='0' width='1' height='1' fill='%23fff' fill-opacity='0.25'/><rect x='0' y='1' width='1' height='1' fill='%23fff' fill-opacity='0.5'/><rect x='1' y='1' width='1' height='1' fill='%23000' fill-opacity='0.5'/><rect x='2' y='1' width='1' height='1' fill='%23fff' fill-opacity='0.75'/><rect x='3' y='1' width='1' height='1' fill='%23000' fill-opacity='0.25'/><rect x='0' y='2' width='1' height='1' fill='%23000' fill-opacity='0.625'/><rect x='1' y='2' width='1' height='1' fill='%23fff' fill-opacity='0.375'/><rect x='2' y='2' width='1' height='1' fill='%23000' fill-opacity='0.875'/><rect x='3' y='2' width='1' height='1' fill='%23fff' fill-opacity='0.125'/><rect x='0' y='3' width='1' height='1' fill='%23fff' fill-opacity='0.875'/><rect x='1' y='3' width='1' height='1' fill='%23000' fill-opacity='0.125'/><rect x='2' y='3' width='1' height='1' fill='%23fff' fill-opacity='0.625'/><rect x='3' y='3' width='1' height='1' fill='%23000' fill-opacity='0.375'/></svg>");
  will-change:transform;animation:dither 2.8s steps(4,end) infinite}
@keyframes dither{
  0%{transform:translate3d(0,0,0)}
  25%{transform:translate3d(-1px,1px,0)}
  50%{transform:translate3d(1px,1px,0)}
  75%{transform:translate3d(1px,-1px,0)}
  100%{transform:translate3d(0,0,0)}
}
/* home covers keep the yellow bleed and pull the dither back on hover */
.card .fx{box-shadow:inset 0 0 44px rgba(243,230,0,.07)}
.card:hover .dither{opacity:.16}

/* Project media is the work itself, so the treatment steps back: softer
   scanlines, half the dither, and a brightness lift that answers the yellow
   cast the page-wide CRT tint lays over everything. */
.mbox .fx{background:repeating-linear-gradient(to bottom,
    rgba(0,0,0,.18) 0 1px, rgba(0,0,0,0) 1px 4px)}
.mbox .dither{opacity:.13}
.mbox img,.mbox iframe{filter:brightness(1.12) saturate(1.06) contrast(1.02)}

/* the light mode and the reduced-motion setting stop both loops */
body.lite .card .shift,body.lite .card .dither{animation:none}
@media (prefers-reduced-motion:reduce){
  .card .shift,.card .dither{animation:none}
}
.card .idx{position:absolute;top:12px;left:14px;z-index:3;font-size:10px;letter-spacing:.2em;color:var(--yellow)}
.card .veil{position:absolute;inset:0;z-index:2;background:var(--yellow);
  clip-path:inset(0 0 100% 0);transition:clip-path .26s cubic-bezier(.75,0,.15,1)}
.card:hover .veil{clip-path:inset(0 0 0 0)}
.card .meta{position:absolute;z-index:3;left:0;right:0;bottom:0;padding:clamp(16px,2vw,30px);
  color:#000;text-shadow:none;opacity:0;transform:translateY(8px);
  transition:opacity .18s ease .1s,transform .26s ease .06s}
.card:hover .meta{opacity:1;transform:translateY(0)}
.card:hover .idx{color:#000;text-shadow:none}
.card .meta h3{font-size:clamp(17px,2.3vw,34px);font-weight:700;letter-spacing:-.01em;line-height:1}
.card .meta p{font-size:clamp(9px,.85vw,12px);letter-spacing:.18em;text-transform:uppercase;margin-top:8px;opacity:.72}
.card .cbr{position:absolute;z-index:3;width:10px;height:10px;border:1px solid rgba(243,230,0,.55);transition:opacity .2s}
.card:hover .cbr{opacity:0}
.card .cbr.a{top:8px;right:8px;border-left:0;border-bottom:0}
.card .cbr.b{bottom:8px;left:8px;border-right:0;border-top:0}

/* ══════════ PÁGINA INTERNA (projeto / about) ══════════ */
.page{padding:calc(var(--head-h) + clamp(34px,6vh,72px)) var(--pad) clamp(50px,8vh,90px)}
.page-head{border-bottom:1px solid var(--line);padding-bottom:clamp(14px,2vw,22px);
  margin-bottom:clamp(26px,4vw,52px);box-shadow:0 1px 10px rgba(243,230,0,.10)}
.page-head .crumb{font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);margin-bottom:10px}
.page-head h1{font-size:clamp(34px,7vw,110px);font-weight:700;line-height:.92;letter-spacing:-.02em;
  text-shadow:0 0 6px rgba(243,230,0,.6),0 0 30px rgba(243,230,0,.22)}

/* layout 1/4 + 3/4 */
.proj{display:grid;grid-template-columns:minmax(210px,1fr) 3fr;gap:clamp(22px,3.4vw,56px);align-items:start}
/* The sticky offset is set from JS — see fitSticky() in project.html. A column
   that fits on screen pins under the header; a taller one gets a negative
   offset, which parks its last line just above the bottom edge instead. */
.proj-info{position:sticky;top:calc(var(--head-h) + 26px);display:flex;flex-direction:column;gap:22px}
.field{border-top:1px solid var(--line-soft);padding-top:9px}
.field dt{font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);margin-bottom:5px}
.field dd{font-size:12px;line-height:1.6}
.field dd .li{display:block}
.field.desc dd{font-size:12.5px;line-height:1.75;opacity:.9}
.field.desc dd p+p{margin-top:.85em}
.credits{width:100%;border-collapse:collapse;font-size:11px}
.credits td{padding:3px 0;vertical-align:top}
.credits td:first-child{color:var(--dim);width:44%;letter-spacing:.06em;padding-right:10px}

/* galeria de mídia do projeto */
.proj-media{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(12px,1.5vw,22px)}
.proj-media .m{grid-column:span 2}
.proj-media .m.half{grid-column:span 1}
.mbox{position:relative;width:100%;border:1px solid var(--line);background:#070700;
  box-shadow:var(--box-glow);overflow:hidden;display:grid;place-items:center}
.mbox .ph{font-size:10px;letter-spacing:.24em;color:rgba(243,230,0,.4)}
.mbox .cbr{position:absolute;z-index:2;width:10px;height:10px;border:1px solid rgba(243,230,0,.4)}
.mbox .cbr.a{top:8px;left:8px;border-right:0;border-bottom:0}
.mbox .cbr.b{bottom:8px;right:8px;border-left:0;border-top:0}
.mbox iframe,.mbox img{position:absolute;inset:0;width:100%;height:100%;border:0;object-fit:cover}

/* "Original": the image sets its own height instead of being cropped to a box */
.mbox.auto{display:block;aspect-ratio:auto}
.mbox.auto img{position:static;width:100%;height:auto;object-fit:contain}

/* ══════════ AUDIO PLAYER ══════════ */
.player{position:relative;border:1px solid var(--line);background:#070700;
  box-shadow:var(--box-glow);padding:13px 15px 11px}
.player .cbr{position:absolute;width:9px;height:9px;border:1px solid rgba(243,230,0,.45)}
.player .cbr.a{top:7px;left:7px;border-right:0;border-bottom:0}
.player .cbr.b{bottom:7px;right:7px;border-left:0;border-top:0}
.ptop{display:flex;align-items:center;gap:13px;margin-bottom:9px}
.pplay{font:inherit;font-size:12px;line-height:1;width:32px;height:32px;flex:none;cursor:pointer;
  background:transparent;color:var(--yellow);border:1px solid var(--line);
  box-shadow:var(--box-glow);transition:background .15s,color .15s}
.pplay:hover{background:var(--yellow);color:#000;text-shadow:none}
.pmeta{flex:1;min-width:0}
.pmeta b{display:block;font-size:12.5px;font-weight:600;letter-spacing:.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pmeta span{display:block;font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--dim);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ptime{font-size:10.5px;letter-spacing:.12em;color:var(--dim);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.pwave{display:block;width:100%;height:44px;cursor:ew-resize;touch-action:none}
@media(max-width:600px){
  .pwave{height:34px}
  .pmeta span{display:none}
}

/* outros projetos — 3 colunas, sem hover */
.others{margin-top:clamp(56px,9vh,120px)}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(12px,1.6vw,24px)}
.mini{text-decoration:none;color:inherit;display:block}
.mini .t{position:relative;aspect-ratio:16/9;border:1px solid var(--line-soft);overflow:hidden;
  background-size:cover;background-position:center;
  filter:saturate(.85) brightness(.68);transition:filter .25s,border-color .25s}
.mini:hover .t{filter:saturate(1.05) brightness(.95);border-color:var(--line)}
.mini h4{font-size:12px;font-weight:600;letter-spacing:.02em;margin-top:10px}
.mini p{font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);margin-top:3px}

/* ══════════ ABOUT ══════════ */
.about{display:grid;grid-template-columns:minmax(240px,1fr) 1.7fr;gap:clamp(24px,4vw,64px);align-items:start}
.photo{position:relative;aspect-ratio:3/4;border:1px solid var(--line);background:#070700;
  box-shadow:var(--box-glow);overflow:hidden;display:grid;place-items:center}
.photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:contrast(1.05) saturate(1.08) brightness(.94)}
.photo .cbr{z-index:2}
.photo .ph{font-size:10px;letter-spacing:.24em;color:rgba(243,230,0,.4)}
.photo .cbr{position:absolute;width:12px;height:12px;border:1px solid rgba(243,230,0,.45)}
.photo .cbr.a{top:8px;left:8px;border-right:0;border-bottom:0}
.photo .cbr.b{bottom:8px;right:8px;border-left:0;border-top:0}
.bio h2{font-size:clamp(15px,1.8vw,22px);font-weight:600;letter-spacing:.05em;
  color:var(--yellow);margin-bottom:clamp(16px,2vw,26px)}
.bio p{font-size:13.5px;line-height:1.85;opacity:.92;max-width:62ch}
.bio p+p{margin-top:1.1em}

.list{margin-top:clamp(48px,7vh,96px)}
/* A fixed last column. With `auto` each row was its own grid, so a longer
   date pushed that row's middle column somewhere else than its neighbours. */
.row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr) 136px;gap:16px;align-items:baseline;
  padding:15px 0;border-bottom:1px solid var(--line-soft);transition:background .2s}
.row:hover{background:rgba(243,230,0,.035)}
.row .a{font-size:14px;font-weight:600;letter-spacing:.01em}
.row .b{font-size:11.5px;color:rgba(243,230,0,.7);letter-spacing:.05em}
.row .c{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);white-space:nowrap}

/* ══════════ FOOTER ══════════ */
footer{position:relative;z-index:2;border-top:1px solid var(--line);padding:26px var(--pad);
  box-shadow:0 -1px 12px rgba(243,230,0,.10);
  display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
.social{display:flex;gap:10px}
.social a{width:34px;height:34px;display:grid;place-items:center;border:1px solid var(--line);
  color:var(--yellow);box-shadow:var(--box-glow);transition:background .18s,color .18s,box-shadow .18s}
.social a:hover{background:var(--yellow);color:#000;box-shadow:0 0 20px rgba(243,230,0,.5)}
.social svg{width:15px;height:15px;fill:currentColor;filter:drop-shadow(0 0 4px rgba(243,230,0,.5))}
.social a:hover svg{filter:none}
.foot-right{display:flex;align-items:center;gap:12px}
.top-btn{width:34px;height:34px;display:grid;place-items:center;border:1px solid var(--line);
  color:var(--yellow);text-decoration:none;box-shadow:var(--box-glow);transition:background .18s,color .18s}
.top-btn:hover{background:var(--yellow);color:#000;text-shadow:none}

/* ══════════ RESPONSIVO ══════════ */
@media(max-width:980px){
  .proj{grid-template-columns:1fr}
  .proj-info{position:static}
  .about{grid-template-columns:1fr}
  .photo{max-width:340px}
  .grid3{grid-template-columns:repeat(2,1fr)}
  .proj-media{grid-template-columns:1fr}
  .proj-media .m.half{grid-column:span 2}
}
@media(max-width:760px){
  header{grid-template-columns:1fr auto;row-gap:8px}
  .role{grid-column:1/-1;order:3;text-align:left}
  .grid{grid-template-columns:1fr}
  .grid3{grid-template-columns:1fr}
  .hud .ruler,.hud .tag{display:none}
  .row{grid-template-columns:1fr;gap:3px}
  footer{justify-content:center;flex-direction:column}
}

/* ══════════ SCROLL REVEAL ══════════
   The hidden state only exists once JavaScript has marked an element, so a
   failed script leaves a readable page rather than an empty one. Transform
   and opacity only: the compositor does all of it. */
[data-reveal]{opacity:0;transform:translate3d(0,15px,0);
  transition:opacity .55s ease, transform .55s cubic-bezier(.2,.75,.2,1);
  will-change:opacity,transform}
[data-reveal].seen{opacity:1;transform:none}
[data-reveal].seen{will-change:auto}
body.lite [data-reveal]{opacity:1;transform:none;transition:none}
/* If initReveals() never runs, nothing would ever un-hide these. The class is
   added the moment the observer starts, which switches this failsafe off. */
body:not(.reveals-on) [data-reveal]{animation:revealFailsafe .5s linear 6s forwards}
@keyframes revealFailsafe{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  [data-reveal]{opacity:1;transform:none;transition:none}
}

/* ══════════ BREACH — leaving a page ══════════
   Bands sweep down over the blackout while the log types. Transform and
   opacity, so the whole thing runs off the main thread. */
#boot.out::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(to bottom,
    rgba(243,230,0,.11) 0 2px, rgba(243,230,0,0) 2px 9px);
  animation:breach .4s linear both;will-change:transform,opacity}
@keyframes breach{
  0%{opacity:0;transform:translate3d(0,-16px,0)}
  25%{opacity:1}
  100%{opacity:.22;transform:translate3d(0,16px,0)}
}
#boot.out .log{animation:jolt .4s steps(3) both}
@keyframes jolt{
  0%{transform:translate3d(0,0,0)}
  33%{transform:translate3d(-3px,0,0)}
  66%{transform:translate3d(2px,0,0)}
  100%{transform:translate3d(0,0,0)}
}
