/* ============================================================================
   palettes.css — GENERATED by docs/make-palette.py. Do not hand-edit the
   numbers; edit the JSON or the script and re-run. Safe to tweak by hand once
   you accept it stops being reproducible.

   Each block is a PRESET: put data-palette="name" on <body> and the whole
   site changes. Default (no attribute) is untouched.

   ⚠️ --accent is the only token here that lands on TEXT, so it is darkened
   until it clears 4.5:1 on that palette's own paper. The --fig-* colours are
   figure colours — canvas and SVG only, never type.
   ========================================================================= */

body[data-palette="wilsons"]{
  --paper:      #F0F6F9;
  --ink:        #060503;
  --accent:     #D4200C;
  --fig-r1:     #E7230E;
  --fig-r2:     #704A28;
  --fig-r3:     #AA1C14;
  --fig-lit:    #E7230E;
  --fig-warm:   #704A28;
}

body[data-palette="strelitzia"]{
  --paper:      #E5DDD1;
  --ink:        #211A1E;
  --accent:     #8A4D00;
  --fig-r1:     #FE8F01;
  --fig-r2:     #C45611;
  --fig-r3:     #803309;
  --fig-lit:    #FE8F01;
  --fig-warm:   #C45611;
}

body[data-palette="navy"]{
  /* ⚠️ PAPEL MAIS ESCURO PEDE TINTA SUAVE MAIS ESCURA — e é isto que dá espaço
     ao fundo. Em #E5DDD1 o `--ink-soft` padrão (alpha .60) dá 4.64:1 no papel
     LIMPO: 0,14 acima do piso, ou seja, sem folga nenhuma para uma camada de
     fundo. Medido por diferença contra uma captura sem o campo, o fundo a 11%
     de opacidade escurecia o papel até 4.32:1 — abaixo. Com alpha .66 o mesmo
     fundo dá 5.17:1 e o papel limpo 5.63:1. O ajuste é do token, não da
     opacidade: quem mudou foi o papel. */
  --ink-soft:   rgba(20,11,8,.66);
  --ink-faint:  rgba(20,11,8,.66);
  --paper:      #F4F3F8;   /* 2026-09-09: papel do esquema ultramarine; era #E5DDD1 (strelitzia) */
  --ink:        #211A1E;
  --accent:     #1B2A6B;
  /* ⚠️ O PAR ESCURO EXISTE PARA UMA SECÇÃO SÓ (§14: "one intentional dark /
     inverted section"). Não é um tema — é a inversão de Art & Exploration, e
     é o que faz WALK parecer outra intenção e não um terceiro passo de R&D.
     Derivado da paleta: o quase-preto é o `--ink` levado para o azul, e o
     texto é o papel arrefecido. Medido: #EDECE6 sobre #141317 dá 14.9:1. */
  --paper-dark:      #141317;
  --paper-band:      #BAC1E2;   /* 2026-09-11: o fundo do R&D — #9AA6D6 (--fig-r3) a 65% sobre o papel */
  --paper-dark-text: #EDECE6;
  --rule:            rgba(20,11,8,.16);
  --fig-r1:     #1B2A6B;
  --fig-r2:     #4C5FA8;
  --fig-r3:     #9AA6D6;
  --fig-lit:    #1B2A6B;
  --fig-warm:   #4C5FA8;
}

/* ⚠️ A MARGEM DE CONTRASTE MUDA COM O PAPEL, ENTÃO A OPACIDADE TAMBÉM.
   O papel #E5DDD1 é mais escuro que o #F7F7FA original, então o mesmo fundo a
   .07 leva --ink-soft de 4.62:1 para 4.53:1 — passa, mas sem folga. Medido na
   página, não estimado. A .05 volta a haver margem. */
/* ============================================================================
   O FUNDO SE MOVE, E NÃO CUSTA NADA.

   A geometria do molde é assada uma vez e usada como MÁSCARA; a cor vem de um
   gradiente CSS que desliza por baixo dela. Isso reproduz exatamente a "paleta
   dinâmica" do gerador na sua forma mais barata: lá, `rampBy: diagonal` indexa
   a rampa por posição, o que É um gradiente linear atravessando a placa, e a
   `deriva` o desloca devagar. Aqui o compositor faz as duas coisas.

   ⚠️ POR QUE NÃO A SIMULAÇÃO AO VIVO. Medido: 42 ms por passo na resolução que
   esta composição pede. A 15fps isso é seis vezes um segundo de CPU por
   segundo — não roda, e forçar prenderia um núcleo por algo que ninguém está
   olhando. Esta versão gasta zero CPU: máscara e gradiente vivem no compositor.

   ⚠️ O GRADIENTE É REPETIDO e a animação anda exatamente 200% em 180s, então o
   laço fecha sem emenda. Um gradiente não repetido bate na borda e a cor salta.
   ========================================================================= */
/* ⚠️ ESTE BLOCO ERA O EXPERIMENTO DO GRADIENTE CSS E FICOU AQUI DEPOIS DE
   DEIXAR DE SER USADO — e foi ele que fez a página parecer vazia.
   Duas coisas se somavam: (1) a base do #field era um gradiente animado a 6%
   de opacidade, e não a imagem assada, portanto o fallback era invisível; e
   (2) `.is-live` limpava só o `background-image`, deixando a `mask-image` do
   `mold-mask.webp` aplicada — o canvas VIVO estava a ser recortado pela
   silhueta de um molde assado antigo. Nenhum dos dois dava erro de consola:
   só desapareciam.
   A base é a imagem assada, sem máscara. O canvas vivo cobre-a. */
body[data-palette="navy"] #field{
  opacity:.14;
  transition:opacity 1.2s ease;
  background-image:url(../assets/mold-bg-navy.webp);
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
  -webkit-mask-image:none; mask-image:none;
  animation:none;
}
@media (max-width:760px){ body[data-palette="navy"] #field{opacity:.10} }

/* ============================================================================
   ONDE O MOVIMENTO PODE SER VISTO: O PLATE DO HERO.

   ⚠️ MEDIÇÃO, NÃO PREFERÊNCIA. O gradiente animado no #field funciona — mas na
   opacidade que o piso de contraste permite (.06) a diferença entre duas fases
   da animação é de **0,5 em 255 por pixel**. O mecanismo estava certo e o
   resultado era invisível. Um fundo de página inteira que respeita 4.5:1 não
   pode carregar movimento visível; não há ajuste que resolva isso, é a mesma
   restrição vista de dois lados.

   O plate já é uma figura mascarada com gradiente, a 30%, e fica AO LADO do
   texto e não atrás dele. Aqui o mesmo mecanismo custa o mesmo (zero: máscara e
   gradiente no compositor) e se vê.
   ========================================================================= */
body[data-palette="navy"] .plate{
  /* 2026-09-09: era a rampa strelitzia (laranjas); com o esquema ultramarine no fundo, um
     plate laranja durante o aquecimento era a única coisa fora da paleta. */
  background-image:repeating-linear-gradient(155deg, #1B2A6B 0%, #4C5FA8 33%, #9AA6D6 66%, #1B2A6B 100%);
  background-size:220% 220%;
  background-position:0% 50%;
  opacity:.34;
  animation:plateDrift 140s linear infinite;
}
@keyframes plateDrift{ from{background-position:0% 50%} to{background-position:220% 50%} }
@media (prefers-reduced-motion:reduce){
  body[data-palette="navy"] .plate{animation:none}
}

/* ---------------------------------------------------- o fundo vivo
   O #field já é um <canvas> no HTML; até agora servia só de superfície para o
   `background-image` assado. Agora o motor desenha nele. A imagem continua ali
   por baixo e sai de cena quando o canvas tem o que mostrar — é o fallback para
   sem-JS, reduced-motion e ponteiro grosso.

   ⚠️ Aqui `width:100%;height:100%` estão declarados, então o canvas estica.
   Foi a lição da versão anterior: um <canvas> é elemento SUBSTITUÍDO e
   `top:0;bottom:0` sozinho não o estica — a altura intrínseca vence. */
/* ⚠️ A OPACIDADE VIVA É OUTRA. A imagem assada tem de ficar em 5% porque não
   consegue sair de baixo do texto; o canvas vivo apaga-se sozinho nas zonas de
   texto, então pode subir a um nível em que o movimento se vê. */
/* ⚠️ OPACIDADE 1: O CANVAS É A PÁGINA, COMO NO LAB.
   Houve aqui uma varredura de opacidade × máscara à procura do ponto em que o
   fundo se via e o texto ainda passava em 4.5:1. A resposta certa era outra
   pergunta: o Vitor quer o desenho do lab, tal e qual, e resolve a legibilidade
   escolhendo as cores. Então isto é 1 e não há máscara nenhuma.
   ⚠️ Consequência assumida: o contraste do texto passa a depender inteiramente
   das cores da paleta, não desta camada. Se um dia voltar a haver texto por
   cima de tinta escura, é a paleta que muda, não a opacidade. */
body[data-palette="navy"] #field.is-live{
  background-image:none;
  -webkit-mask-image:none; mask-image:none;   /* nada recorta o canvas vivo */
  animation:none;
  opacity:1;
}
/* Abaixo de 760px o `field-live.js` nem arranca (bateria); manda a imagem assada. */
@media (max-width:760px){ body[data-palette="navy"] #field.is-live{opacity:1} }

/* ============================================================================
   O AQUECIMENTO NÃO PODE MOSTRAR O FALLBACK (2026-09-13).

   Relatado como "a animação começa de forma bugada". Não era a animação: era
   ESTA imagem assada. Durante os segundos de aquecimento ela ocupa a tela
   inteira em `background-size:cover` — esticada, desfocada e cortada — e
   depois desaparece de golpe quando o canvas fica pronto. Medido: `is-live`
   só chegava entre os 6 s e os 10 s numa janela de 1700×975.

   A imagem é um bom fallback para quem NÃO vai ter animação nenhuma. É um mau
   cartaz de abertura para quem vai. Então: enquanto o motor está a caminho
   (`starting` ou `live`), o papel fica limpo e o desenho entra em fade.

   ⚠️ O `:not(.is-live)` NÃO É DECORATIVO. Sem ele esta regra é mais específica
   que `body[data-palette="navy"] #field.is-live` (1,2,2 contra 1,2,1) e
   ganhava-lhe: o canvas vivo ficaria em `opacity:0` para sempre — trocaria um
   fundo feio por nenhum fundo.

   ⚠️ CONTINUA A HAVER IMAGEM em todos os casos em que não vai haver desenho:
   sem JavaScript (o atributo nunca chega a ser escrito), `reduced-motion`,
   `small-screen`, e `fallback` — o estado que o field-live.js escreve quando
   desiste de aquecer. Nenhum visitante fica com a página vazia.
   ========================================================================= */
html[data-field="starting"] body[data-palette="navy"] #field:not(.is-live),
html[data-field="live"]     body[data-palette="navy"] #field:not(.is-live){
  background-image:none;
  opacity:0;
}
.plate.is-replaced,
body[data-palette="navy"] .plate.is-replaced{opacity:0;transition:opacity 1.4s ease}

/* ============================================================================
   VERSÕES DO FUNDO (2026-09-14) — ver js/field-live.js, "VERSÕES DO FUNDO".
   `html[data-fundo=…]` é escrito por um script no <head> de cada página.
   Especificidade (0,2,2): ganha ao bloco navy (0,1,1) sem !important.
   ========================================================================= */
html[data-fundo="areia"]   body[data-palette="navy"]{ --paper:#F6F2EA; --paper-band:#E4D8C6; }
html[data-fundo="grafite"] body[data-palette="navy"]{ --paper:#F5F5F4; --paper-band:#DCDCDF; }
html[data-fundo="salvia"]  body[data-palette="navy"]{ --paper:#F3F5F0; --paper-band:#D3DDCB; }

/* As escuras invertem a página inteira: o papel fica escuro e a "tinta" clara.
   A banda do mapa e a secção Walk ganham um tom próprio para continuarem a ler
   como secções. A imagem assada (azul claro) não serve de fallback aqui. */
html[data-fundo="noite"] body[data-palette="navy"]{
  --paper:#141619; --ink:#EDE7DC; --ink-soft:rgba(237,231,220,.74); --ink-faint:rgba(237,231,220,.74);
  --ink-ghost:rgba(237,231,220,.30); --rule:rgba(237,231,220,.16); --hairline:rgba(237,231,220,.22);
  --accent:#C6A472; --paper-band:#1C1F25; --paper-dark:#0B0C0E; --paper-dark-text:#EDE7DC;
}
html[data-fundo="noite-azul"] body[data-palette="navy"]{
  --paper:#0D1224; --ink:#E8EAF4; --ink-soft:rgba(232,234,244,.74); --ink-faint:rgba(232,234,244,.74);
  --ink-ghost:rgba(232,234,244,.30); --rule:rgba(232,234,244,.16); --hairline:rgba(232,234,244,.22);
  --accent:#9AA6D6; --paper-band:#141B33; --paper-dark:#070A15; --paper-dark-text:#E8EAF4;
}
html[data-fundo="brasa"] body[data-palette="navy"]{
  --paper:#17110E; --ink:#F2E8DA; --ink-soft:rgba(242,232,218,.74); --ink-faint:rgba(242,232,218,.74);
  --ink-ghost:rgba(242,232,218,.30); --rule:rgba(242,232,218,.16); --hairline:rgba(242,232,218,.22);
  --accent:#E0A060; --paper-band:#201814; --paper-dark:#0C0907; --paper-dark-text:#F2E8DA;
}
html[data-fundo="noite"] body[data-palette="navy"] #field,
html[data-fundo="noite-azul"] body[data-palette="navy"] #field,
html[data-fundo="brasa"] body[data-palette="navy"] #field{ background-image:none; }

/* Versões tiradas das gramáticas fotográficas (strelitzia, wilsons). Não editar à mão. */
/* fundos-foto:start — gerado por docs/make-fundos-foto.py */
html[data-fundo="strelitzia"] body[data-palette="navy"]{
  --paper:#F9F3E9; --ink:#191517; --ink-soft:rgba(25,21,23,0.66); --ink-faint:rgba(25,21,23,0.66);
  --ink-ghost:rgba(25,21,23,.30); --rule:rgba(25,21,23,.16); --hairline:rgba(25,21,23,.22);
  --accent:#A45B01; --paper-band:#F7D2C1; --paper-dark:#191517; --paper-dark-text:#F9F3E9;
}
html[data-fundo="strelitzia"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="strelitzia-noite"] body[data-palette="navy"]{
  --paper:#120E10; --ink:#EDE7DD; --ink-soft:rgba(237,231,221,0.74); --ink-faint:rgba(237,231,221,0.74);
  --ink-ghost:rgba(237,231,221,.30); --rule:rgba(237,231,221,.16); --hairline:rgba(237,231,221,.22);
  --accent:#FE8F01; --paper-band:#3F1F15; --paper-dark:#0A0809; --paper-dark-text:#EDE7DD;
}
html[data-fundo="strelitzia-noite"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="wilsons"] body[data-palette="navy"]{
  --paper:#100F0D; --ink:#E4E9EB; --ink-soft:rgba(228,233,235,0.74); --ink-faint:rgba(228,233,235,0.74);
  --ink-ghost:rgba(228,233,235,.30); --rule:rgba(228,233,235,.16); --hairline:rgba(228,233,235,.22);
  --accent:#EF2E19; --paper-band:#460C08; --paper-dark:#090807; --paper-dark-text:#E4E9EB;
}
html[data-fundo="wilsons"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="wilsons-claro"] body[data-palette="navy"]{
  --paper:#F0F4F7; --ink:#171614; --ink-soft:rgba(23,22,20,0.66); --ink-faint:rgba(23,22,20,0.66);
  --ink-ghost:rgba(23,22,20,.30); --rule:rgba(23,22,20,.16); --hairline:rgba(23,22,20,.22);
  --accent:#D51601; --paper-band:#F5E6E4; --paper-dark:#171614; --paper-dark-text:#F0F4F7;
}
html[data-fundo="wilsons-claro"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="strelitzia-ambar"] body[data-palette="navy"]{
  --paper:#120E10; --ink:#EDE7DD; --ink-soft:rgba(237,231,221,0.74); --ink-faint:rgba(237,231,221,0.74);
  --ink-ghost:rgba(237,231,221,.30); --rule:rgba(237,231,221,.16); --hairline:rgba(237,231,221,.22);
  --accent:#FE8F01; --paper-band:#3C220C; --paper-dark:#0A0809; --paper-dark-text:#EDE7DD;
}
html[data-fundo="strelitzia-ambar"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="strelitzia-cinza"] body[data-palette="navy"]{
  --paper:#F9F3E9; --ink:#191517; --ink-soft:rgba(25,21,23,0.66); --ink-faint:rgba(25,21,23,0.66);
  --ink-ghost:rgba(25,21,23,.30); --rule:rgba(25,21,23,.16); --hairline:rgba(25,21,23,.22);
  --accent:#A45B01; --paper-band:#E3DAD0; --paper-dark:#191517; --paper-dark-text:#F9F3E9;
}
html[data-fundo="strelitzia-cinza"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="strelitzia-nodal"] body[data-palette="navy"]{
  --paper:#F9F3E9; --ink:#191517; --ink-soft:rgba(25,21,23,0.66); --ink-faint:rgba(25,21,23,0.66);
  --ink-ghost:rgba(25,21,23,.30); --rule:rgba(25,21,23,.16); --hairline:rgba(25,21,23,.22);
  --accent:#A45B01; --paper-band:#F7D2C1; --paper-dark:#191517; --paper-dark-text:#F9F3E9;
}
html[data-fundo="strelitzia-nodal"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="wilsons-petroleo"] body[data-palette="navy"]{
  --paper:#100F0D; --ink:#E4E9EB; --ink-soft:rgba(228,233,235,0.74); --ink-faint:rgba(228,233,235,0.74);
  --ink-ghost:rgba(228,233,235,.30); --rule:rgba(228,233,235,.16); --hairline:rgba(228,233,235,.22);
  --accent:#EF2E19; --paper-band:#252A2B; --paper-dark:#090807; --paper-dark-text:#E4E9EB;
}
html[data-fundo="wilsons-petroleo"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="wilsons-nodal"] body[data-palette="navy"]{
  --paper:#100F0D; --ink:#E4E9EB; --ink-soft:rgba(228,233,235,0.74); --ink-faint:rgba(228,233,235,0.74);
  --ink-ghost:rgba(228,233,235,.30); --rule:rgba(228,233,235,.16); --hairline:rgba(228,233,235,.22);
  --accent:#EF2E19; --paper-band:#460C08; --paper-dark:#090807; --paper-dark-text:#E4E9EB;
}
html[data-fundo="wilsons-nodal"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="flor-na-noite"] body[data-palette="navy"]{
  --paper:#100F0D; --ink:#E4E9EB; --ink-soft:rgba(228,233,235,0.74); --ink-faint:rgba(228,233,235,0.74);
  --ink-ghost:rgba(228,233,235,.30); --rule:rgba(228,233,235,.16); --hairline:rgba(228,233,235,.22);
  --accent:#FE8F01; --paper-band:#3B230A; --paper-dark:#090807; --paper-dark-text:#E4E9EB;
}
html[data-fundo="flor-na-noite"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop"] body[data-palette="navy"]{
  --paper:#0E0F14; --ink:#E2EAE3; --ink-soft:rgba(226,234,227,0.74); --ink-faint:rgba(226,234,227,0.74);
  --ink-ghost:rgba(226,234,227,.30); --rule:rgba(226,234,227,.16); --hairline:rgba(226,234,227,.22);
  --accent:#04BACE; --paper-band:#0C292F; --paper-dark:#08080B; --paper-dark-text:#E2EAE3;
}
html[data-fundo="bop"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop-ciano"] body[data-palette="navy"]{
  --paper:#0E0F14; --ink:#E2EAE3; --ink-soft:rgba(226,234,227,0.74); --ink-faint:rgba(226,234,227,0.74);
  --ink-ghost:rgba(226,234,227,.30); --rule:rgba(226,234,227,.16); --hairline:rgba(226,234,227,.22);
  --accent:#04BACE; --paper-band:#092A2F; --paper-dark:#08080B; --paper-dark-text:#E2EAE3;
}
html[data-fundo="bop-ciano"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop-acido"] body[data-palette="navy"]{
  --paper:#0E0F14; --ink:#E2EAE3; --ink-soft:rgba(226,234,227,0.74); --ink-faint:rgba(226,234,227,0.74);
  --ink-ghost:rgba(226,234,227,.30); --rule:rgba(226,234,227,.16); --hairline:rgba(226,234,227,.22);
  --accent:#04BACE; --paper-band:#282A0E; --paper-dark:#08080B; --paper-dark-text:#E2EAE3;
}
html[data-fundo="bop-acido"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop-nodal"] body[data-palette="navy"]{
  --paper:#0E0F14; --ink:#E2EAE3; --ink-soft:rgba(226,234,227,0.74); --ink-faint:rgba(226,234,227,0.74);
  --ink-ghost:rgba(226,234,227,.30); --rule:rgba(226,234,227,.16); --hairline:rgba(226,234,227,.22);
  --accent:#04BACE; --paper-band:#0C292F; --paper-dark:#08080B; --paper-dark-text:#E2EAE3;
}
html[data-fundo="bop-nodal"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop-claro"] body[data-palette="navy"]{
  --paper:#EEF6EF; --ink:#15161B; --ink-soft:rgba(21,22,27,0.66); --ink-faint:rgba(21,22,27,0.66);
  --ink-ghost:rgba(21,22,27,.30); --rule:rgba(21,22,27,.16); --hairline:rgba(21,22,27,.22);
  --accent:#037785; --paper-band:#9DE4E8; --paper-dark:#15161B; --paper-dark-text:#EEF6EF;
}
html[data-fundo="bop-claro"] body[data-palette="navy"] #field{ background-image:none; }
html[data-fundo="bop-neon"] body[data-palette="navy"]{
  --paper:#0E0F14; --ink:#E2EAE3; --ink-soft:rgba(226,234,227,0.74); --ink-faint:rgba(226,234,227,0.74);
  --ink-ghost:rgba(226,234,227,.30); --rule:rgba(226,234,227,.16); --hairline:rgba(226,234,227,.22);
  --accent:#04BACE; --paper-band:#0F3B41; --paper-dark:#08080B; --paper-dark-text:#E2EAE3;
}
html[data-fundo="bop-neon"] body[data-palette="navy"] #field{ background-image:none; }
/* fundos-foto:end */
