/* ============================================================
   portfolio — preto e branco, recortes em halftone, HUD em mono.
   As cores saem de --bg / --fg; "inverter" só troca as duas.
   ============================================================ */

:root{
  --bg:#000;
  --fg:#fff;
  --mute:#8a8a8a;
  --f:"Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:"VT323",ui-monospace,Menlo,Consolas,monospace;
  --ease:cubic-bezier(.16,1,.3,1);
  --gutter:clamp(1rem,3.5vw,3rem);
  --mx:0; --my:0;                 /* posição do ponteiro, -1..1 (main.js) */
}
body.is-invert{ --bg:#fff; --fg:#000; --mute:#6f6f6f }

*,*::before,*::after{ box-sizing:border-box }
html{ scroll-behavior:smooth; -webkit-text-size-adjust:100% }
body{
  margin:0; background:var(--bg); color:var(--fg);
  font-family:var(--f); line-height:1.5;
  overflow-x:hidden; -webkit-font-smoothing:antialiased;
  transition:background-color .35s, color .35s;
}
body.is-booting{ overflow:hidden }
a{ color:inherit }
button{ font:inherit; color:inherit; background:none; border:0; padding:0; cursor:pointer }
::selection{ background:var(--fg); color:var(--bg) }
:focus-visible{ outline:2px solid currentColor; outline-offset:4px }

/* ---- camadas: recortes (1) < tracking (2) < texto e PSP (3) ---- */
.sec{
  position:relative; height:100svh; min-height:520px; overflow:hidden;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:var(--gutter);
}
.el{
  position:absolute; z-index:1; pointer-events:none;
  left:calc(var(--x)*1%); top:calc(var(--y)*1%);
  width:calc(var(--w)*1vmin); height:calc(var(--w)*1vmin);
  transform:translate(-50%,-50%)
            translate(calc(var(--mx)*var(--d,1)*14px),calc(var(--my)*var(--d,1)*14px));
  will-change:transform;
}
.trk{ position:fixed; inset:0; width:100%; height:100%; z-index:2; pointer-events:none }
.lay{ position:relative; z-index:3 }

/* os recortes são pontos brancos sobre transparente: invertido, viram pretos */
body.is-invert .el, body.is-invert .cut{ filter:invert(1) }

/* entrada de cada seção */
.sec .lay{ opacity:0; transform:translateY(18px); transition:opacity .9s var(--ease), transform .9s var(--ease) }
.sec.is-in .lay{ opacity:1; transform:none }

/* ---- boot ---- */
.boot{
  position:fixed; inset:0; z-index:100; background:var(--bg);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1.1rem;
  transition:opacity .6s var(--ease), visibility .6s;
}
.boot.is-done{ opacity:0; visibility:hidden }
.boot__tag{
  margin:0; font-weight:700; font-size:clamp(3rem,13vw,7rem); line-height:1;
  letter-spacing:-.06em; transform:scaleY(1.45);
}
.boot__bar{ width:min(60vw,15rem); height:1px; background:var(--mute); margin-top:1.4rem }
.boot__bar span{ display:block; height:100%; width:0; background:var(--fg) }
.boot__pct{ font-family:var(--mono); font-size:1.1rem; letter-spacing:.18em; color:var(--mute) }

/* ---- controles fixos ---- */
.ctl{ position:fixed; right:var(--gutter); bottom:var(--gutter); z-index:10 }
/* idioma e inverter: mesmo visual dos botões ← → ↗ da tela do PSP (.keys),
   mas nas cores do tema, para funcionar também com "inverter" ligado */
.ctl{
  display:flex; gap:.3rem; padding:.3rem;
  border-radius:999px; border:1px solid color-mix(in srgb, var(--fg) 22%, transparent);
  background:color-mix(in srgb, var(--bg) 58%, transparent);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  color:var(--fg); transition:background-color .35s, border-color .35s, color .35s;
}
.ctl__b{
  width:40px; height:40px; display:grid; place-items:center; border-radius:50%;
  color:var(--fg); transition:background-color .2s, color .2s, transform .15s var(--ease);
}
.ctl__b:hover{ background:var(--fg); color:var(--bg) }
.ctl__b:focus-visible{ outline:2px solid var(--fg); outline-offset:2px }
.ctl__b:active{ transform:scale(.88) }
.ctl__b svg{ display:block }
/* inverter: círculo meio cheio; ligado, gira e a metade cheia troca de lado */
.ctl__inv svg{ width:20px; height:20px; transition:transform .45s var(--ease) }
.ctl__inv svg circle{ fill:none; stroke:currentColor; stroke-width:2 }
.ctl__inv svg path{ fill:currentColor }
.ctl__inv[aria-pressed="true"] svg{ transform:rotate(180deg) }
/* idioma: bandeira em preto e branco (js/i18n.js) */
.flag{ height:14px; width:auto; fill:currentColor }
/* bandeira + sigla: o botão vira uma pílula em vez de círculo, mesma altura */
.ctl__lang{ width:auto; padding:0 .85rem 0 .8rem; border-radius:999px; display:flex; align-items:center; gap:.5rem }
.ctl__code{ font-family:var(--mono); font-size:1.15rem; letter-spacing:.06em; line-height:1; margin-top:-.1rem }
.flag__o{ fill:none; stroke:currentColor; stroke-width:1 }

/* ---- linha de título com recorte no meio (capa e contato) ---- */
.line{
  margin:0; display:flex; align-items:center; justify-content:center; gap:.08em;
  font-style:italic; font-weight:400; font-size:clamp(1.9rem,6.4vw,5.2rem);
  line-height:1; letter-spacing:-.02em; white-space:nowrap;
}
.cut{
  flex:none; width:clamp(7rem,27vmin,17rem); height:clamp(7rem,27vmin,17rem);
  transform:translate(calc(var(--mx)*-10px),calc(var(--my)*-10px));
}
.role{ margin:1.6rem 0 0; font-family:var(--mono); font-size:1.15rem; letter-spacing:.1em; color:var(--mute); text-align:center }

/* seta "tem mais pra baixo": pontos desenhados por js/cue.js, que define tamanho e posição */
.cue{ position:absolute; z-index:3; left:50%; bottom:var(--gutter); display:block; color:var(--fg); -webkit-tap-highlight-color:transparent }
.cue canvas{ display:block }
.cue:focus-visible{ outline-offset:-14px; border-radius:12px }
.cue.is-gone{ visibility:hidden; pointer-events:none }

/* ---- capa + máquina: uma tela só ----
   Estados (main.js, em #hero): is-name → is-dock → is-psp → is-info.
   Paisagem: nome à esquerda · PSP no meio · descrição à direita. */
.brand{
  position:absolute; z-index:3; left:50%; top:50%;
  display:flex; flex-direction:column; align-items:center;
  /* --bx/--by/--bs vêm do main.js quando o nome "estaciona" */
  transform:translate(-50%,-50%) translate(var(--bx,0px),var(--by,0px)) scale(var(--bs,1));
  transition:transform 1.6s var(--ease);
  will-change:transform;
}
.brand .line{ font-size:clamp(1.9rem,6.4vw,5.2rem) }

/* entrada do nome: as palavras abrem por um recorte e saem do desfoque,
   o disquete gira e cresce no meio delas */
.brand__w{
  display:inline-block;
  clip-path:inset(0 100% 0 0); filter:blur(14px); opacity:0;
  transform:translateX(.35em); letter-spacing:.25em;
  transition:clip-path 1.1s var(--ease), filter 1.1s var(--ease), opacity .8s var(--ease),
             transform 1.2s var(--ease), letter-spacing 1.4s var(--ease);
}
.brand__w--b{ clip-path:inset(0 0 0 100%); transform:translateX(-.35em); transition-delay:.12s }
.brand__cut{
  opacity:0; filter:blur(10px);
  transform:scale(.35) rotate(-28deg);
  transition:opacity .9s var(--ease), filter 1.1s var(--ease), transform 1.5s var(--ease);
}
.brand .role{ opacity:0; transform:translateY(10px); transition:opacity 1s var(--ease) .55s, transform 1s var(--ease) .55s }

.is-name .brand__w{ clip-path:inset(0 0 0 0); filter:none; opacity:1; transform:none; letter-spacing:-.02em }
.is-name .brand__cut{ opacity:1; filter:none; transform:translate(calc(var(--mx)*-10px),calc(var(--my)*-10px)) }
.is-name .brand .role{ opacity:1; transform:none }

/* recorte que só aparece junto com o PSP */
.el--late{ opacity:0; transition:opacity 2s var(--ease) }
.is-psp .el--late{ opacity:1 }

.machine__stage{
  position:absolute; z-index:3; top:0; bottom:0; left:25%; width:48%;
  touch-action:pan-y;
  opacity:0; transform:scale(.94); filter:blur(6px);
  transition:opacity 1.5s var(--ease), transform 2s var(--ease), filter 1.5s var(--ease);
  pointer-events:none;
}
.is-psp .machine__stage{ opacity:1; transform:none; filter:none; pointer-events:auto }
#pspCanvas{ display:block; width:100%; height:100%; filter:contrast(1.08) }
.machine__loading{ position:absolute; inset:0; display:grid; place-items:center; font-family:var(--mono); color:var(--mute); text-align:center; padding:var(--gutter); pointer-events:none }
.machine__loading.is-off{ display:none }
.machine__flat{ position:absolute; left:50%; top:50%; width:92%; transform:translate(-50%,-50%); border:1px solid var(--mute) }
.spin{ width:26px; height:26px; border:1px solid var(--mute); border-top-color:var(--fg); border-radius:50%; animation:spin .9s linear infinite }
@keyframes spin{ to{ transform:rotate(360deg) } }

/* a descrição do projeto, ao lado do PSP */
.info{
  position:absolute; z-index:4; right:var(--gutter); top:50%;
  width:min(23vw,21rem); max-height:calc(100% - 2*var(--gutter));
  transform:translateY(-50%);
  display:flex; flex-direction:column; gap:1.4rem;
}
.info__in{ display:flex; flex-direction:column; gap:.7rem; overflow:auto; transition:opacity .22s, transform .22s var(--ease) }
.info.is-swap .info__in{ opacity:0; transform:translateY(6px) }
.info__in > *, .info__dl > div{
  opacity:0; transform:translateX(16px);
  transition:opacity .8s var(--ease), transform .9s var(--ease);
  transition-delay:calc(var(--i,0)*90ms);
}
.is-info .info__in > *, .is-info .info__dl > div{ opacity:1; transform:none }

.info__count{ font-family:var(--mono); line-height:.8; white-space:nowrap }
.info__count b{ font-weight:400; font-size:3.2rem }
.info__count i{ font-style:normal; font-size:1.1rem; color:var(--mute); margin-left:.2rem }
.info__title{ margin:0; font-weight:400; font-style:italic; font-size:clamp(1.3rem,2vw,1.8rem); line-height:1.1; letter-spacing:-.01em; overflow-wrap:anywhere }
.info__sub{ margin:0; font-size:.98rem; line-height:1.45 }
.info__dl{ margin:.3rem 0 0; display:flex; flex-direction:column; gap:.8rem }
.info__dl > div{ border-top:1px solid color-mix(in srgb, var(--fg) 22%, transparent); padding-top:.55rem }
.info__dl dt{ font-family:var(--mono); font-size:1rem; letter-spacing:.12em; text-transform:uppercase; color:var(--mute); line-height:1 }
.info__dl dd{ margin:.35rem 0 0; font-size:.92rem; line-height:1.5 }
.info__dl > div[hidden]{ display:none }
.info__meta{ margin:0; font-family:var(--mono); font-size:1rem; color:var(--mute); letter-spacing:.04em }

/* anterior / próximo / abrir: presos no canto inferior direito da tela do PSP
   (psp.js move o bloco a cada quadro) e visíveis só com o cursor em cima do PSP.
   Somem com um pequeno atraso, para dar tempo de levar o mouse até eles. */
.keys{
  position:absolute; z-index:5; left:0; top:0;
  translate:-12px -12px;          /* um respiro para dentro da tela */
  display:flex; gap:.3rem; padding:.3rem;
  border-radius:999px; border:1px solid rgba(255,255,255,.22);
  background:rgba(0,0,0,.58); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  color:#fff;                     /* fica sobre a tela do PSP, que é sempre escura */
  opacity:0; pointer-events:none;                 /* escondido, mas o Tab ainda chega neles */
  transition:opacity .25s var(--ease) .4s;
  will-change:transform;
}
.is-info .keys.is-placed.is-on, .is-info .keys.is-placed:hover, .is-info .keys.is-placed:has(:focus-visible){
  opacity:1; pointer-events:auto;
  transition:opacity .2s var(--ease);
}
/* toque: não existe "cursor em cima", então os botões ficam sempre à mostra */
@media (hover:none){ .is-info .keys.is-placed{ opacity:1; pointer-events:auto } }
@media (max-width:640px){
  .keys{ gap:.1rem; padding:.15rem; translate:-7px -7px }
  .keys button, .keys a{ width:30px; height:30px; font-size:1.05rem }
  .keys svg{ width:15px; height:15px }
}
.keys button, .keys a{
  width:40px; height:40px; display:grid; place-items:center; border-radius:50%;
  font-family:var(--mono); font-size:1.35rem; line-height:1; text-decoration:none;
  color:#fff; transition:background-color .2s, color .2s, transform .15s var(--ease);
}
.keys button:hover, .keys a:hover{ background:#fff; color:#000 }
.keys button:focus-visible, .keys a:focus-visible{ outline:2px solid #fff; outline-offset:2px }
.keys button:active, .keys a:active{ transform:scale(.88) }
.keys svg{ width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round }
.keys a[aria-disabled="true"]{ opacity:.3; cursor:default }               /* sem link: fica no lugar, sem ação */
.keys a[aria-disabled="true"]:hover{ background:none; color:#fff }
/* som: mesmo bloco, sozinho, no canto superior direito da tela do PSP */
.keys--snd{ translate:-12px 12px }
@media (max-width:640px){ .keys--snd{ translate:-7px 7px } }
.keys--snd .snd__off{ display:none }
.keys--snd button[aria-pressed="true"] .snd__on{ display:none }
.keys--snd button[aria-pressed="true"] .snd__off{ display:block }
.keys--snd button[aria-pressed="true"]{ opacity:.6 }

/* o "dedo" no PSP: anel que abre onde a pessoa tocou (psp.js) */
/* anel de toque em halftone (desenhado por psp.js, quadro a quadro) */
.poke{ position:absolute; z-index:4; pointer-events:none }

.stage .cue{ opacity:0; transition:opacity 1s var(--ease) .6s }
.stage.is-info .cue{ opacity:1 }

/* ---- sobre ----
   Esquerda: galeria num plano em perspectiva (perto à esquerda, longe à direita).
   Direita: cartão com o texto. */
.about{ justify-content:center }
.about{ --wrap:82rem; --me:0px }
.about__wrap{
  width:min(100%,var(--wrap)); height:100%; margin:0 auto; padding-right:var(--me);
  display:grid; grid-template-columns:minmax(0,1.45fr) minmax(0,1fr); gap:clamp(1.5rem,4vw,4rem); align-items:center;
}

.gallery{
  --gap:clamp(.5rem,1vw,.9rem);
  --room:3.2rem;                  /* folga em cima e embaixo para o quadro em destaque "saltar" sem ser cortado */
  --h:min(64vh,38rem);            /* altura das três fileiras (o título fica em cima) */
  position:relative; height:calc(var(--h) + 2 * var(--room)); margin-block:calc(-1 * var(--room));
  perspective:1100px; perspective-origin:30% 50%;
  /* encosta na borda esquerda da tela, mesmo com a grade centralizada */
  margin-left:calc(-1 * var(--gutter) - max(0px, (100vw - var(--wrap) - 2 * var(--gutter)) / 2));
  /* os desenhos surgem e somem nas pontas, sem corte seco. A máscara fica aqui e não no
     plano: no plano ela achataria o 3D e o quadro em destaque não conseguiria vir para a frente */
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 76%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 7%, #000 76%, transparent);
}
/* ---- título da galeria ----
   Surge quando a seção entra na tela: o rótulo em mono com cursor piscando,
   as palavras subindo de um recorte e saindo do desfoque, e um fio que se desenha. */
.art{ position:relative; min-width:0; display:flex; flex-direction:column }
.art__h{ position:relative; z-index:3; margin:0; pointer-events:none }
.art__k{
  margin:0 0 .55rem; display:flex; align-items:center; gap:.4rem;
  font-family:var(--mono); font-size:1.05rem; letter-spacing:.14em; text-transform:uppercase; color:var(--mute);
  opacity:0; transform:translateX(-10px); transition:opacity .8s var(--ease) .1s, transform .9s var(--ease) .1s;
}
.art__k i{ display:inline-block; width:.5em; height:1em; background:currentColor; animation:caret 1.1s steps(1) infinite }
@keyframes caret{ 50%{ opacity:0 } }
.art__t{
  margin:0; font-weight:400; font-style:italic; font-size:clamp(1.8rem,3.4vw,3.2rem);
  line-height:1; letter-spacing:-.02em;
}
.art__w{
  display:inline-block; clip-path:inset(0 0 100% 0); filter:blur(10px); opacity:0;
  transform:translateY(.45em);
  transition:clip-path 1s var(--ease), filter 1.1s var(--ease), opacity .8s var(--ease), transform 1.1s var(--ease);
  transition-delay:calc(.25s + var(--i) * .14s);
}
.art__w:last-child{ color:color-mix(in srgb, var(--fg) 62%, transparent) }
.art__s{
  position:relative; margin:.8rem 0 0; padding-top:.6rem; max-width:max-content;
  font-family:var(--mono); font-size:1.05rem; letter-spacing:.06em; color:var(--mute);
  opacity:0; transition:opacity 1s var(--ease) .75s;
}
.art__s::before{                 /* o fio que se desenha da esquerda para a direita */
  content:""; position:absolute; left:0; top:0; width:100%; height:1px;
  background:color-mix(in srgb, var(--fg) 35%, transparent);
  transform:scaleX(0); transform-origin:left; transition:transform 1.3s var(--ease) .6s;
}
.about.is-in .art__k{ opacity:1; transform:none }
.about.is-in .art__w{ clip-path:inset(-.2em 0 -.2em 0); filter:none; opacity:1; transform:none }
.about.is-in .art__s{ opacity:1 }
.about.is-in .art__s::before{ transform:scaleX(1) }

/* ---- retrato ao lado do cartão ----
   A arte (tools/portrait.py) já sai sem fundo e com as bordas desfeitas em halftone;
   aqui ela só ganha uma máscara macia extra e entra devagar, saindo do desfoque. */
.me{
  position:absolute; z-index:1; margin:0; pointer-events:none;
  left:calc(100% + clamp(.5rem,1.5vw,1.5rem)); top:50%; width:var(--me-w,0px);
  transform:translateY(-50%);
}
.me img{
  display:block; width:100%; height:auto;
  -webkit-mask-image:radial-gradient(78% 66% at 50% 48%, #000 70%, transparent 100%);
          mask-image:radial-gradient(78% 66% at 50% 48%, #000 70%, transparent 100%);
  opacity:0; filter:blur(12px); transform:translateY(14px) scale(.97);
  transition:opacity 1.4s var(--ease) .5s, filter 1.6s var(--ease) .5s, transform 1.6s var(--ease) .5s;
}
.about.is-in .me img{ opacity:1; filter:none; transform:translate(calc(var(--mx)*-6px),calc(var(--my)*-6px)) }
/* tema claro: em vez de inverter (o rosto viraria negativo), troca para a versão
   feita para fundo branco (tools/portrait.py ... light), com pontos escuros.
   As duas ficam empilhadas e cruzam suave ao trocar o tema. */
.me .me__light{ position:absolute; left:0; top:0 }
body:not(.is-invert) .about.is-in .me .me__light,
body.is-invert .about.is-in .me img:not(.me__light){ opacity:0 }
/* depois da entrada (main.js põe .is-set), a troca de tema é rápida e sem atraso */
.me.is-set img{ transition:opacity .45s var(--ease), filter 1.6s var(--ease), transform .8s var(--ease) }
/* telas largas: o retrato ganha uma coluna própria à direita do cartão */
@media (min-width:1180px){
  .about{ --wrap:104rem; --me-w:clamp(11rem,15vw,20rem); --me:calc(var(--me-w) + clamp(.5rem,1.5vw,1.5rem)) }
  .about__wrap{ grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) }
}
/* telas bem largas (≥1600px): tudo cresce junto com a largura para ocupar o espaço,
   mas devagar. --u vale 0 em 1600px e ~9.6px em 2560px; cada medida soma um pouco dele
   e para num teto, para não exagerar em monitores maiores ainda. */
@media (min-width:1600px){
  .about{
    --u:calc((100vw - 1600px) / 100);
    --wrap:min(calc(104rem + var(--u) * 90), 170rem);
    --me-w:min(calc(20rem + var(--u) * 10), 30rem);
  }
  .about__wrap{ gap:min(calc(4rem + var(--u) * 2), 7rem) }
  .gallery{ --h:min(66vh, calc(38rem + var(--u) * 14), 56rem) }
  .about .art__t{ font-size:min(calc(3.2rem + var(--u) * 1.4), 4.6rem) }
  .about .art__k, .about .art__s{ font-size:min(calc(1.05rem + var(--u) * .3), 1.35rem) }
  .about .card{ padding:min(calc(2.4rem + var(--u) * 1.2), 3.6rem); gap:min(calc(.85rem + var(--u) * .5), 1.4rem); border-radius:min(calc(22px + var(--u) * .6), 30px) }
  .about .card__h{ font-size:min(calc(2.8rem + var(--u) * 1.2), 3.8rem) }
  .about .card__lead{ font-size:min(calc(1.22rem + var(--u) * .6), 1.65rem) }
  .about .card__bio p{ font-size:min(calc(.96rem + var(--u) * .4), 1.25rem) }
  .about .card__built{ font-size:min(calc(.92rem + var(--u) * .38), 1.2rem) }
  .about .card__now{ font-size:min(calc(1.02rem + var(--u) * .35), 1.3rem) }
  .about .card__links{ gap:min(calc(.5rem + var(--u) * .2), .8rem) }
  .about .card__links a{ min-height:min(calc(40px + var(--u) * .8), 52px); padding:0 min(calc(.95rem + var(--u) * .3), 1.3rem); font-size:min(calc(1.08rem + var(--u) * .35), 1.38rem) }
}
/* abaixo disso não sobra coluna: o retrato vira um "adesivo" no canto do cartão */
@media (max-width:1179px){
  /* só a cabeça, na altura do título "sobre mim", cruzando a borda de cima do cartão */
  .me{ --s:clamp(5.2rem,10vw,6.6rem); left:auto; right:clamp(.8rem,2.4vw,1.6rem); top:calc(var(--s) * -.42); width:var(--s); transform:none }
  .me img{
    aspect-ratio:1/1.05; object-fit:cover; object-position:50% 34%;
    -webkit-mask-image:radial-gradient(50% 50% at 50% 50%, #000 58%, transparent 100%);
            mask-image:radial-gradient(50% 50% at 50% 50%, #000 58%, transparent 100%);
  }
}

.gallery__plane{
  position:absolute; top:var(--room); bottom:var(--room); left:-4%; width:175%;
  display:flex; flex-direction:column; gap:var(--gap);
  transform:rotateY(28deg); transform-origin:left center;
  transform-style:preserve-3d;    /* fileiras e quadros vivem no mesmo espaço 3D */
}
/* as fileiras andam por js/gallery.js (dá para parar, arrastar e arremessar) */
.gallery__row{
  flex:1; min-height:0; display:flex; gap:var(--gap); width:max-content;
  will-change:transform; touch-action:pan-y; cursor:grab; transform-style:preserve-3d;
  -webkit-user-select:none; user-select:none;
}
.gallery__row.is-drag, .gallery__row.is-drag .gallery__tile{ cursor:grabbing }

/* .gallery__tile é a área de hover/clique: fica sempre no lugar do quadro e nunca se mexe.
   .gallery__art (dentro dele, sem pointer-events) é o que aparece e o que salta no destaque. */
.gallery__tile{
  position:relative; flex:none; height:100%; aspect-ratio:1; display:block;
  padding:0; border:0; margin:0; font:inherit; color:inherit; background:none; cursor:zoom-in;
  transform-style:preserve-3d;    /* deixa o salto da camada de dentro acontecer no espaço 3D da galeria */
  outline:none; -webkit-tap-highlight-color:transparent;
}
.gallery__art{
  display:block; width:100%; height:100%; pointer-events:none;
  overflow:hidden; border-radius:10px; background:color-mix(in srgb, var(--fg) 8%, transparent);
  transition:transform .45s var(--ease), box-shadow .45s var(--ease);
}
.gallery__tile:focus-visible .gallery__art{ outline:2px solid var(--fg); outline-offset:3px }
.gallery__art img{
  display:block; width:100%; height:100%; object-fit:cover; object-position:50% 30%;
  filter:grayscale(1) contrast(1.05); pointer-events:none;
  transition:filter .45s var(--ease);
}
/* o quadro debaixo do mouse sai do plano em direção a quem olha (translateZ dentro da
   perspectiva, com um pequeno "quique"); por estar mais perto, fica por cima das outras fileiras.
   Os vizinhos da mesma fileira apagam um pouco. */
.gallery__tile.is-front .gallery__art{
  transform:translateZ(90px) scale(1.2);
  transition:transform .55s cubic-bezier(.34,1.56,.64,1), box-shadow .45s var(--ease);
  box-shadow:0 26px 60px rgba(0,0,0,.75), 0 0 0 1.5px color-mix(in srgb, var(--fg) 70%, transparent);
}
.gallery__tile.is-front img{ filter:grayscale(.8) brightness(1.08) contrast(1.1) }
.gallery__row.is-hover .gallery__tile:not(.is-front) img{ filter:grayscale(1) brightness(.55) }

/* ---- tela cheia (js/gallery.js) ---- */
html.is-lb{ overflow:hidden }
.lb{
  position:fixed; inset:0; width:100%; height:100%; max-width:none; max-height:none;
  margin:0; padding:0; border:0; color:var(--fg);
  background:color-mix(in srgb, var(--bg) 93%, transparent);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
.lb::backdrop{ background:transparent }
.lb[open]{ display:grid; grid-template-rows:minmax(0,1fr) auto; animation:lb-fade .3s var(--ease) }
.lb__stage{ min-height:0; display:grid; place-items:center; padding:clamp(3.5rem,8vh,5rem) clamp(4.5rem,9vw,7rem) 1rem }
.lb__stage img{
  max-width:100%; max-height:100%; object-fit:contain; display:block;
  border-radius:10px; box-shadow:0 30px 80px rgba(0,0,0,.6);
  touch-action:pan-y; cursor:grab; -webkit-user-select:none; user-select:none;
}
.lb__stage img.is-in{ animation:lb-in .45s var(--ease) }
.lb__stage img.is-r{ animation:lb-r .4s var(--ease) }
.lb__stage img.is-l{ animation:lb-l .4s var(--ease) }
.lb__bar{
  display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:.6rem 1.4rem;
  padding:0 var(--gutter) clamp(1.2rem,4vh,2rem); text-align:center;
}
.lb__cap{ font-size:.95rem; color:color-mix(in srgb, var(--fg) 80%, transparent); max-width:40rem }
.lb__n{ font-family:var(--mono); font-size:1.05rem; color:var(--mute); letter-spacing:.06em }
.lb__link{
  min-height:38px; display:inline-flex; align-items:center; padding:0 .95rem;
  border:1px solid color-mix(in srgb, var(--fg) 30%, transparent); border-radius:999px;
  font-family:var(--mono); font-size:1.02rem; letter-spacing:.04em; text-decoration:none;
  transition:background-color .2s, color .2s;
}
.lb__link::after{ content:" ↗"; white-space:pre }
.lb__link:hover, .lb__link:focus-visible{ background:var(--fg); color:var(--bg) }
.lb__link[hidden]{ display:none }
.lb__b{
  position:absolute; width:48px; height:48px; display:grid; place-items:center;
  border:1px solid color-mix(in srgb, var(--fg) 28%, transparent); border-radius:50%;
  font-family:var(--mono); font-size:1.35rem; line-height:1;
  background:color-mix(in srgb, var(--bg) 60%, transparent);
  transition:background-color .2s, color .2s, transform .15s var(--ease);
}
.lb__b:hover{ background:var(--fg); color:var(--bg) }
.lb__b:focus-visible{ outline:2px solid var(--fg); outline-offset:3px }
.lb__b:active{ transform:scale(.9) }
.lb__prev{ left:clamp(.8rem,2.5vw,2rem); top:50%; margin-top:-24px }
.lb__next{ right:clamp(.8rem,2.5vw,2rem); top:50%; margin-top:-24px }
.lb__close{ right:clamp(.8rem,2.5vw,2rem); top:clamp(.8rem,2.5vw,2rem) }
@keyframes lb-fade{ from{ opacity:0 } to{ opacity:1 } }
@keyframes lb-in{ from{ opacity:0; transform:scale(.92) } to{ opacity:1; transform:none } }
@keyframes lb-r{ from{ opacity:0; transform:translateX(40px) } to{ opacity:1; transform:none } }
@keyframes lb-l{ from{ opacity:0; transform:translateX(-40px) } to{ opacity:1; transform:none } }

/* celular: imagem quase de ponta a ponta; ← → descem para perto do polegar */
@media (max-width:640px){
  .lb__stage{ padding:4rem .8rem .6rem }
  .lb__prev, .lb__next{ top:auto; bottom:clamp(1.2rem,4vh,2rem); margin-top:0 }
  .lb__bar{ padding-inline:4.6rem }
}

/* o cartão */
.card{
  position:relative; z-index:2;
  padding:clamp(1.4rem,2.6vw,2.4rem); border-radius:22px;
  border:1px solid color-mix(in srgb, var(--fg) 26%, transparent);
  background:color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  display:flex; flex-direction:column; gap:.85rem;
}
.card__h{ margin:0; font-family:var(--mono); font-weight:400; font-size:clamp(2rem,3.6vw,2.8rem); letter-spacing:.08em; line-height:.9 }
.card__lead{ margin:0; font-size:clamp(1.04rem,1.3vw,1.22rem); line-height:1.4 }
.card__bio p{ margin:0 0 .55rem; font-size:.96rem; line-height:1.55; color:color-mix(in srgb, var(--fg) 82%, transparent) }
.card__bio p:last-child{ margin:0 }
.card__built{ list-style:none; margin:0; padding:.8rem 0 0; border-top:1px solid color-mix(in srgb, var(--fg) 18%, transparent); display:flex; flex-direction:column; gap:.3rem; font-size:.92rem; line-height:1.4 }
.card__built li::before{ content:"▸ "; color:var(--mute) }
.card__now{ margin:0; font-family:var(--mono); font-size:1.02rem; letter-spacing:.03em; color:var(--mute); line-height:1.3 }
.card__links{ display:flex; flex-wrap:wrap; gap:.5rem }
.card__links a{
  min-height:40px; display:inline-flex; align-items:center; padding:0 .95rem;
  border:1px solid color-mix(in srgb, var(--fg) 30%, transparent); border-radius:999px;
  font-family:var(--mono); font-size:1.08rem; letter-spacing:.04em; text-decoration:none;
  transition:background-color .2s, color .2s, border-color .2s;
}
.card__links a::after{ content:" ↗"; white-space:pre }
.card__links a:hover, .card__links a:focus-visible{ background:var(--fg); color:var(--bg); border-color:var(--fg) }

/* telas largas mas baixas (notebook): cartão mais compacto para caber na altura */
@media (min-width:901px) and (max-height:800px){
  .card{ padding:1.3rem 1.5rem; gap:.65rem; border-radius:18px }
  .card__h{ font-size:2rem }
  .card__lead{ font-size:1.02rem }
  .card__bio p{ font-size:.9rem; line-height:1.45; margin-bottom:.4rem }
  .card__built{ font-size:.85rem; padding-top:.6rem; gap:.2rem }
  .card__now{ font-size:.95rem }
  .card__links a{ min-height:36px; font-size:1rem }
  .gallery{ --h:68vh }
}

/* telas estreitas: galeria em cima (menos inclinada), cartão embaixo */
@media (max-width:900px){
  .about{ height:auto; min-height:100svh; padding-block:calc(var(--gutter) + 1rem) calc(var(--gutter) + 4rem) }
  .about__wrap{ grid-template-columns:minmax(0,1fr); height:auto; gap:1.6rem }
  .gallery{
    --h:min(46vh,24rem); --room:2.4rem; margin-inline:calc(var(--gutter) * -1);
    /* aqui a perspectiva deixa os quadros da ponta mais altos que a caixa da galeria:
       além das pontas, também somem em cima e embaixo, em vez de cortar reto */
    -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 76%, transparent),
                       linear-gradient(180deg, transparent, #000 var(--room), #000 calc(100% - var(--room)), transparent);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(90deg, transparent, #000 7%, #000 76%, transparent),
                       linear-gradient(180deg, transparent, #000 var(--room), #000 calc(100% - var(--room)), transparent);
            mask-composite:intersect;
  }
  .card{ -webkit-backdrop-filter:none; backdrop-filter:none }
  .gallery__plane{ transform:rotateY(20deg); left:-2%; width:130% }
}

@media (prefers-reduced-motion:reduce){
  .art__k, .art__w, .art__s, .art__s::before, .me img{ transition:opacity .4s !important; filter:none !important; transform:none !important; clip-path:none !important }
  .art__k i, .kick i{ animation:none }
  .hubs__t, .hub{ transform:none !important; transition:opacity .4s, background-color .25s, color .25s !important }
  .lb[open], .lb__stage img{ animation:none !important }
  .gallery__art, .gallery__art img{ transition:none }
}

/* ---- contato ---- */
.contact{ justify-content:center }
/* última seção: altura do conteúdo (não da tela), para não abrir um vão depois do "sobre";
   guarda espaço embaixo para os créditos (.foot) */
.contact{ height:auto; min-height:0; padding-top:clamp(2.5rem,7vh,4.5rem); padding-bottom:calc(var(--gutter) + 3.6rem) }
/* recortes extras dos lados: os el--side somem em telas estreitas (ficariam atrás dos cartões),
   os el--wide só entram quando sobra margem dos lados (telas largas) */
.contact .el--wide{ display:none }
@media (min-width:1500px){ .contact .el--wide{ display:block } }
@media (max-width:900px){ .contact .el--side{ display:none } }
.contact__wrap{
  position:relative; z-index:3; width:min(100%,72rem);
  display:flex; flex-direction:column; align-items:center; gap:clamp(1.6rem,4.5vh,3.2rem);
}
.contact__head{ display:flex; flex-direction:column; align-items:center; text-align:center }
.contact .line{ font-size:clamp(2rem,5.6vw,4.6rem) }
.contact .cut{ width:clamp(5.5rem,17vmin,10.5rem); height:clamp(5.5rem,17vmin,10.5rem) }
.kick{
  margin:0 0 .4rem; display:flex; align-items:center; gap:.4rem;
  font-family:var(--mono); font-size:1.05rem; letter-spacing:.14em; text-transform:uppercase; color:var(--mute);
}
.kick i{ display:inline-block; width:.5em; height:1em; background:currentColor; animation:caret 1.1s steps(1) infinite }
.contact__note{ margin:.6rem 0 0; max-width:34rem; font-size:clamp(.98rem,1.2vw,1.12rem); color:color-mix(in srgb, var(--fg) 78%, transparent) }

/* e-mail: o contato principal, com botão de copiar */
.mail{
  margin-top:1.1rem; display:flex; align-items:stretch;
  border:1px solid color-mix(in srgb, var(--fg) 30%, transparent); border-radius:999px; overflow:hidden;
}
.mail__a, .mail__copy{
  min-height:44px; display:inline-flex; align-items:center; gap:.55rem; padding:0 1.05rem;
  font-family:var(--mono); font-size:1.12rem; letter-spacing:.04em; text-decoration:none;
  transition:background-color .2s, color .2s;
}
.mail__a svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linejoin:round; stroke-linecap:round }
.mail__copy{ border-left:1px solid color-mix(in srgb, var(--fg) 30%, transparent); color:var(--mute); min-width:7.2em; justify-content:center }
.mail__a:hover, .mail__a:focus-visible, .mail__copy:hover, .mail__copy:focus-visible{ background:var(--fg); color:var(--bg); outline:none }
.mail__copy.is-ok{ color:var(--fg) }

/* links: três grupos lado a lado, cada um com dois cartões */
.hubs{ width:100%; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(.8rem,2vw,1.6rem) }
.hubs__g{ display:flex; flex-direction:column; gap:.55rem; min-width:0 }
.hubs__t{
  margin:0 0 .15rem; padding-bottom:.45rem; border-bottom:1px solid color-mix(in srgb, var(--fg) 16%, transparent);
  font-family:var(--mono); font-size:1rem; letter-spacing:.12em; text-transform:uppercase; color:var(--mute);
}
.hubs__t b{ font-weight:400; color:var(--fg); margin-right:.35em }
.hub{
  position:relative; display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:.85rem;
  min-height:64px; padding:.7rem .95rem; border-radius:14px; text-decoration:none;
  border:1px solid color-mix(in srgb, var(--fg) 20%, transparent);
  background:color-mix(in srgb, var(--bg) 70%, transparent);
  transition:background-color .25s, color .25s, border-color .25s, transform .35s var(--ease);
}
.hub__i{ width:26px; height:26px; fill:currentColor; flex:none }
.hub__tx{ display:flex; flex-direction:column; min-width:0; line-height:1.2 }
.hub__tx b{ font-weight:500; font-size:1.02rem }
.hub__tx small{ font-family:var(--mono); font-size:.98rem; letter-spacing:.03em; color:var(--mute); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.hub__n{ font-size:.8rem; color:color-mix(in srgb, var(--fg) 55%, transparent); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.hub__ar{ font-style:normal; font-family:var(--mono); font-size:1.2rem; color:var(--mute); transition:transform .35s var(--ease), color .25s }
.hub:hover, .hub:focus-visible{ background:var(--fg); color:var(--bg); border-color:var(--fg); transform:translateY(-2px); outline:none }
.hub:hover small, .hub:hover .hub__n, .hub:hover .hub__ar,
.hub:focus-visible small, .hub:focus-visible .hub__n, .hub:focus-visible .hub__ar{ color:color-mix(in srgb, var(--bg) 70%, transparent) }
.hub:hover .hub__ar, .hub:focus-visible .hub__ar{ transform:translate(2px,-2px) }

/* entrada: títulos e cartões em cascata */
.hubs__t, .hub{ opacity:0; transform:translateY(14px); transition:opacity .7s var(--ease), transform .8s var(--ease), background-color .25s, color .25s, border-color .25s }
.contact.is-in .hubs__t, .contact.is-in .hub{ opacity:1; transform:none; transition-delay:calc(.35s + var(--i) * .07s), calc(.35s + var(--i) * .07s), 0s, 0s, 0s }
.contact.is-in .hub:hover, .contact.is-in .hub:focus-visible{ transform:translateY(-2px); transition-delay:0s }

/* ---- créditos no fim da página: centralizados, pequenos, apagados ----
   Surgem devagar só quando o rodapé entra na tela (main.js põe .is-seen). */
.foot{
  position:absolute; left:0; right:0; bottom:var(--gutter); z-index:3;
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:.35rem 1rem;
  padding:0 10rem; text-align:center;
  font-family:var(--mono); font-size:.9rem; letter-spacing:.04em; line-height:1.3;
  color:var(--mute); opacity:0; transform:translateY(6px);
  transition:opacity 1.2s var(--ease), transform 1.2s var(--ease);
}
.foot.is-seen{ opacity:.7; transform:none }
.foot:hover, .foot:focus-within{ opacity:1 }
.foot__i{ margin:0 }
.foot__i span{ opacity:.75 }
.foot a{ color:inherit; text-decoration:none; border-bottom:1px solid color-mix(in srgb, var(--mute) 45%, transparent); transition:color .2s, border-color .2s }
.foot a:hover, .foot a:focus-visible{ color:var(--fg); border-color:var(--fg) }
.foot__sep{ width:3px; height:3px; border-radius:50%; background:currentColor; opacity:.6 }

/* ---- contato em telas estreitas: grupos um embaixo do outro, cartões em duas colunas ---- */
@media (max-width:900px){
  .contact{ height:auto; min-height:100svh; padding-block:calc(var(--gutter) + 2rem) calc(var(--gutter) + 58px + 4.5rem) }
  .hubs{ grid-template-columns:minmax(0,1fr); gap:1.2rem }
  .hubs__g{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.55rem }
  .hubs__t{ grid-column:1 / -1 }
  .hub{ grid-template-columns:auto minmax(0,1fr); gap:.6rem; padding:.65rem .75rem }
  .hub__ar{ display:none }
  /* estreito: um crédito por linha, acima dos botões de idioma/inverter (que ficam no canto) */
  .foot{ flex-direction:column; gap:.3rem; padding:0 var(--gutter); bottom:calc(var(--gutter) + 58px); font-size:.82rem }
  .foot__sep{ display:none }
}
@media (max-width:420px){ .hub__n{ display:none } .mail__a, .mail__copy{ font-size:1rem; padding:0 .8rem } }

/* ---- retrato: o título empilha em volta do recorte ---- */
@media (max-aspect-ratio:4/5){
  .line{ flex-direction:column; font-size:clamp(2.6rem,15vw,5rem); gap:0 }
  .cut{ width:44vmin; height:44vmin; margin:-.5rem 0 }
  .contact .line{ flex-direction:row; font-size:clamp(2rem,11vw,3.4rem); gap:.04em }
  .contact .cut{ width:clamp(4.5rem,22vmin,7rem); height:clamp(4.5rem,22vmin,7rem); margin:0 }
  /* capa em retrato: nome no topo, PSP no meio, descrição embaixo */
  .brand .line{ flex-direction:row; font-size:clamp(1.6rem,9vw,3.4rem); gap:.04em }
  .brand .cut{ width:30vmin; height:30vmin; margin:0 }
  .machine__stage{ left:0; width:100%; top:13%; bottom:auto; height:36% }
  .info{ left:var(--gutter); right:var(--gutter); top:auto; bottom:var(--gutter); width:auto; max-height:49%; transform:none; gap:.8rem }
  .info__in{ gap:.45rem }
  .info__count b{ font-size:2.4rem }
  .info__dl{ gap:.5rem }
  .info__dl dd, .info__sub{ font-size:.88rem; line-height:1.4 }
  .stage .cue{ display:none }
  .stage .el--late{ top:30%; width:78vmin; height:78vmin }       /* a flor fica atrás do PSP, não do texto */
  .stage .el:not(.el--late){ opacity:.35 }                         /* estrelas mais discretas atrás da descrição */
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto }
  .sec .lay{ transform:none; transition:opacity .3s }
  .spin{ animation:none }
  .poke{ display:none }
  .brand, .brand__w, .brand__cut, .brand .role, .machine__stage, .el--late,
  .info__in, .info__in > *, .info__dl > div{ transition:opacity .4s !important; filter:none !important }
  .el, .cut{ transform:translate(-50%,-50%) }
  .cut{ transform:none }
}

/* ============================================================
   03 · MODELAGEM 3D — cabeça | texto | soldado
   ============================================================ */
.m3d{ height:auto; min-height:100vh; padding-block:clamp(1rem,3vh,3rem); overflow-x:clip }
.m3d__wrap{
  width:min(100%,178vh); display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,.85fr) minmax(0,1.35fr);
  gap:clamp(1.2rem,3vw,3.5rem); align-items:center;
}
.m3d__t{ margin:0; font-weight:400; font-style:italic; font-size:clamp(1.8rem,5.4vh,4.6rem); line-height:1; letter-spacing:-.02em }
.m3d__t span:last-child{ color:color-mix(in srgb, var(--fg) 62%, transparent) }
.m3d__lead{ margin:1rem 0 0; max-width:27em; font-size:clamp(1rem,2.1vh,1.6rem); line-height:1.45 }
.m3d__list{ list-style:none; margin:1.1rem 0 0; padding:0; max-width:31em; font-size:clamp(.92rem,1.85vh,1.4rem); display:grid; gap:.5em }
.m3d__list li{
  position:relative; padding-left:1.1em; line-height:1.4;
  color:color-mix(in srgb, var(--fg) 80%, transparent);
}
.m3d__list li::before{ content:""; position:absolute; left:0; top:.55em; width:.42rem; height:.42rem; border-radius:50%; background:currentColor }
.m3d__meta{
  position:relative; margin:1.2rem 0 0; padding-top:.6rem; max-width:max-content;
  font-family:var(--mono); font-size:1.05rem; letter-spacing:.06em; color:var(--mute);
}
.m3d__meta::before{ content:""; position:absolute; left:0; top:0; width:100%; height:1px; background:color-mix(in srgb, var(--fg) 35%, transparent) }

.m3d__wrap figure{ margin:0; position:relative }
.m3d__wrap canvas{ display:block; width:100%; opacity:0; transition:opacity 1.1s var(--ease) }
.m3d__wrap canvas.is-on{ opacity:1 }
.m3d__wrap figcaption{
  padding-top:.5rem; font-family:var(--mono); font-size:.92rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--mute); white-space:nowrap; line-height:1.1; text-align:center;
}
.m3d__head{ justify-self:start; width:min(122%,92vh); margin-right:-22% }
.m3d__head figcaption{ position:absolute; left:0; right:0; bottom:9%; padding:0 }
.m3d__hero{ justify-self:center; height:88vh; aspect-ratio:456/400; margin-inline:-40%; left:-2.5rem }
.m3d__h{ position:relative; z-index:2 }
.m3d__hero canvas{ height:100%; cursor:grab; touch-action:pan-y; outline:none }
.m3d__hero canvas.is-held{ cursor:grabbing }
.m3d__hero canvas:focus-visible{ outline:1px dashed color-mix(in srgb, var(--fg) 55%, transparent); outline-offset:4px }
.m3d__hero figcaption{ display:flex; justify-content:center; gap:.7rem; color:var(--fg) }
.m3d__hint{ color:var(--mute) }

@media (max-width:900px){
  .m3d__wrap{ grid-template-columns:minmax(0,.8fr) minmax(0,1fr); gap:1.4rem 1rem }
  .m3d__h{ grid-column:1 / -1; grid-row:1 }
  .m3d{ min-height:0 }
  .m3d__head{ grid-column:1 / -1; justify-self:center; width:min(100%,26rem); margin-right:0 }
  .m3d__hero{ grid-column:1 / -1; height:auto; width:118%; margin-inline:-9%; left:0 }
  .m3d__wrap figcaption{ font-size:.8rem }
  .m3d__hero figcaption{ flex-direction:column; gap:.2rem; align-items:center }
}
