/* ---------------------------------------------------------------------------
   Styles Framer applied at RUNTIME, not in its stylesheet.

   Framer's React bundle writes a set of inline styles after hydration. Those
   never appear in the server-rendered CSS, so stripping the bundle silently
   drops them — most visibly the glass effect on every nav pill and button.

   Captured from the live site by reading the inline styles Framer's JS wrote
   (https://www.by-fel.com/about, hydrated DOM), then expressed as CSS keyed on
   the framer-v-* variant class that Framer itself uses as the discriminator.

     framer-v-1150kk2  ->  LIGHT
     framer-v-1o68bfv  ->  DARK
     framer-v-1x0lp31  ->  GLASS

   Face e hover ainda são a captura. O frost da variante GLASS foi adensado
   depois (Felipe, 13/09): o blur sozinho não fazia os chips lerem no campo
   claro do hero.
   --------------------------------------------------------------------------- */

/* Os valores do vidro como TOKENS: a nav consome pelas regras de variante
   abaixo, e o badge dos projetos consome o mesmo conjunto (mais abaixo).
   Um lugar só — a receita já divergiu uma vez por estar em dois. */
:root {
  --glass-blur:       blur(90px) saturate(160%);
  --glass-dim:        brightness(0.15);           /* só na GLASS: o tipo branco segura */
  --glass-face:       rgba(32, 32, 32, 0.85);   /* GLASS: o padrão translúcido */
  --glass-face-light: rgba(238, 238, 238, 0.9);   /* LIGHT: para fundo imprevisível */
  --glass-face-hover: rgb(0, 0, 0);
}

.framer-1x0lp31 {
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  /* SEM SOMBRA — regra da casa (Felipe, 26/08): botão nunca carrega sombra.
     O ar declara aqui um inset de 1px a 2% de branco. A 2% ele não pinta
     nada sobre estes fundos, então fica de fora: a regra segue intacta e o
     visual não muda. */
}

/* LIGHT — off-white at 90% */
.framer-1x0lp31.framer-v-1150kk2 {
  background-color: var(--token-a038fa8f-b58d-41a3-a830-15b5abcdd149, var(--glass-face-light));
}

/* DARK — near-black */
.framer-1x0lp31.framer-v-1o68bfv {
  background-color: var(--token-a86c6d9c-06aa-4198-851c-1a6244ec1705, rgb(18, 18, 18));
}

/* GLASS — white at 20%, now with a denser frost.
   ---------------------------------------------------------------------------
   A captura era blur(60px) sobre a face a 20%. Funcionava no preto da about
   e some no cinza do hero: o desfoque de um campo liso continua liso, e o
   tipo branco lava.

   O blur maior amassa mais vizinhança para dentro do chip; o saturate
   devolve cor quando uma foto passa atrás. O brightness é o contraste:
   escurece o que o filtro amostra, então o tipo branco tem chão. Num fundo
   preto a conta é a mesma de antes — brilho de zero é zero, mais os 20%
   de branco. A câmera não leva este dim: o tipo dela é escuro. */
.framer-1x0lp31.framer-v-1x0lp31 {
  background-color: var(--token-46dc26a4-f697-4eca-8ab9-c09e05427c95, var(--glass-face));
  backdrop-filter: var(--glass-blur) var(--glass-dim);
  -webkit-backdrop-filter: var(--glass-blur) var(--glass-dim);
}

/* ---------------------------------------------------------------------------
   Appear animations.

   Framer ships elements at opacity 0 and animates them in from JS. Without the
   bundle they would either stay invisible or pop in with no transition, so the
   initial state is declared here and the runtime releases it on scroll.

   Timing comes from Framer's own bundles:
     duration .8s, ease cubic-bezier(.44,0,.56,1), stagger .1s
   --------------------------------------------------------------------------- */

/* Content is visible by default — deliberately.
 *
 * An earlier version set `opacity: 0` here and let JS reveal it. That is the
 * wrong way round: it hid 26 of 32 marked elements on /about, and any JS
 * failure would have hidden the page's content permanently.
 *
 * Instead the runtime hides only what is genuinely below the fold at load,
 * immediately before animating it. Anything already on screen never moves, and
 * if the script never runs the page simply renders complete and static. */
[data-reveal] {
  will-change: opacity, transform;
}

[data-reveal][data-reveal-armed] {
  opacity: 0;
  transform: translateY(10px);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal][data-reveal-armed] {
    opacity: 1;
    transform: none;
    will-change: auto;
  }
}

/* ---------------------------------------------------------------------------
   "VIEW" badge that follows the cursor over a project row.
   Framer created this element on hover and translated it to the pointer; it is
   89px wide on the live site and disappears when the pointer leaves.
   --------------------------------------------------------------------------- */

.fel-view-badge {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  /* O CRACHÁ É O CONTINENTE; quem tem corpo são as duas partes. Ele perde
     padding, fundo e desfoque — se ficasse com eles, o vão de 2px entre as
     partes seria preenchido pelo próprio crachá e a divisão desapareceria. */
  display: flex;
  gap: 2px;
  padding: 0;
  font-family: var(--font-body, 'Maxeville Regular', sans-serif);
  font-size: 12px;
  /* 1.3 e não 1.2em: 12 × 1,3 = 15,6 de linha, mais os 10 de padding, dão
     os mesmos 25,6px de altura dos chips FEL/WORK/ABOUT. Medido nos dois.
     Com 1.2em davam 24,4 — perto o bastante para ninguém apontar, e longe
     o bastante para as duas peças nunca parecerem a mesma família. */
  line-height: 1.3;
  white-space: nowrap;

  /* O MESMO VIDRO DA NAV — variante GLASS, por decisão do Felipe (28/08):
     "os botoes do nav estao com um bom acabamento, mas esses aqui devem ter
     o mesmo que eles."

     Estava na LIGHT (branco a 90% com tinta escura), que eu tinha escolhido
     porque o badge segue o cursor sobre miniaturas de brilho arbitrário e
     branco a 20% com texto branco pode lavar sobre uma imagem clara. A
     escolha de direção é dele; fica registrado que esse é o ponto a olhar se
     algum dia o rótulo sumir sobre uma capa muito clara. */
  color: #fff;
  box-shadow: none;
  border: 0;
  border-radius: 0;

  opacity: 0;
  transition: opacity 200ms cubic-bezier(.44, 0, .56, 1);
}

/* O vidro mora em cada parte, e o padding é o da nav — 5px 8px, medido
   nela. É isso que faz as duas lerem como irmãs dos chips FEL/WORK/ABOUT e
   não como um rótulo de outro sistema. */
.fel-view-parte {
  padding: 5px 8px;
  background: var(--glass-face);
  backdrop-filter: var(--glass-blur) var(--glass-dim);
  -webkit-backdrop-filter: var(--glass-blur) var(--glass-dim);
}

.fel-view-badge.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .fel-view-badge { display: none; }
}

/* ---------------------------------------------------------------------------
   Pointer image trail over the hero.
   Pure scale + fade — the live site applies matrix(s,0,0,s,0,0) with no
   rotation, ranging roughly 0.32 to 1.40, and clears ~2.5s after the pointer
   stops. Backgrounds come from posters already on the page.
   --------------------------------------------------------------------------- */

.fel-trail-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

.fel-trail-item {
  position: absolute;
  width: 300px;
  aspect-ratio: 4 / 5;
  margin: -187px 0 0 -150px;      /* centre on the pointer */
  background-size: cover;
  background-position: center;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.32);
  transition:
    transform 620ms cubic-bezier(.44, 0, .56, 1),
    opacity 620ms cubic-bezier(.44, 0, .56, 1);
  will-change: transform, opacity;
}

.fel-trail-item.is-in  { opacity: 1; transform: scale(1); }
.fel-trail-item.is-out { opacity: 0; transform: scale(1.4); }

@media (prefers-reduced-motion: reduce) {
  .fel-trail-layer { display: none; }
}

/* ---------------------------------------------------------------------------
   Hover states, measured with build/audit-interactions.mjs against the live
   site. Framer applied these from JS, so stripping its bundle dropped them.

     nav pill (GLASS)  rgba(245,245,245,.2) -> rgb(0,0,0)
     nav pill (DARK)   rgb(18,18,18)        -> rgba(245,245,245,.2)   *
     nav pill (LIGHT)  rgba(238,238,238,.9) -> rgba(245,245,245,.2)   *
       * medido assim, mas opacificado na regra — ver a nota do hover abaixo.
     project row       rgb(0,0,0)           -> rgb(26,26,26)
   --------------------------------------------------------------------------- */

.framer-1x0lp31 {
  transition: background-color 400ms cubic-bezier(.44, 0, .56, 1);
}

.framer-1x0lp31.framer-v-1x0lp31:hover {          /* GLASS -> solid black */
  background-color: rgb(0, 0, 0);
}

/* O HOVER DESTAS DUAS ERA TRANSLÚCIDO, E POR ISSO SUMIA (12/09).
   ---------------------------------------------------------------------------
   "Os botões internos estão ficando brancos, totalmente brancos."

   A captura está certa — o Framer realmente troca a chapa por um véu de 20%
   de branco no hover destas duas variantes. O que a captura não pode carregar
   é a SUPOSIÇÃO embutida nela: ela foi medida com um fundo previsível atrás.
   Um véu não tem cor própria; ele tem a cor do que está atrás. E a tinta do
   chip é fixa.

       DARK   chapa rgb(18,18,18), tinta BRANCA.
              hover → véu. Sobre o preto da página o véu compõe rgb(49,49,49)
              e a tinta branca lê. Sobre um thumbnail claro passando atrás da
              nav fixa, o mesmo véu compõe quase branco — e branco sobre
              branco é o que ele fotografou.
       LIGHT  chapa rgba(238,238,238,.9), tinta PRETA.
              mesma armadilha espelhada, só que ela perdoa: a tinta é escura,
              então clarear não apaga.

   A correção não muda a aparência onde ela já funcionava: cada variante passa
   a receber, OPACA, exatamente a cor que o véu compunha sobre o fundo para o
   qual ela foi desenhada. rgb(49,49,49) é 0,2×245 + 0,8×0; rgb(253,253,253) é
   0,2×245 + 0,8×255. Mesmo pixel sobre o fundo certo, e agora o mesmo pixel
   sobre qualquer fundo.

   É a regra que o chip da câmera já carrega escrita, três arquivos adiante:
   a chapa fica cheia e só a tinta respira, para o contraste mínimo não
   depender do que passa por trás. */
.framer-1x0lp31.framer-v-1o68bfv:hover {          /* DARK  -> cinza opaco */
  background-color: rgb(49, 49, 49);
}
.framer-1x0lp31.framer-v-1150kk2:hover {          /* LIGHT -> quase branco opaco */
  background-color: rgb(253, 253, 253);
}

/* Project rows stay on the page black while hovered. The old #1a1a1a fill
   read as a grey slab once the thumbnails tucked to the centre. isolation
   still keeps each row's z-index tuck from leaking into the next. */
a[data-project-name] {
  isolation: isolate;
}

/* Navigation glass stays at 85% dark tint over both empty and image backgrounds.
   Explicit values bypass exported variant tokens and inline appearance states. */
.framer-1x0lp31.framer-v-1x0lp31 {
  background-color: var(--glass-face) !important;
  backdrop-filter: var(--glass-blur) var(--glass-dim) !important;
  -webkit-backdrop-filter: var(--glass-blur) var(--glass-dim) !important;
  transition: color 400ms cubic-bezier(.44,0,.56,1);
}
.framer-1x0lp31.framer-v-1x0lp31:hover {
  background-color: var(--glass-face-hover) !important;
}
