MÓDULO 3.2

🎨 House style dark premium

Paleta, tipografia, camada de fundo e escala de vídeo — o sistema visual que torna cada cena inconfundível.

6
Tópicos
22
Minutos
Avançado
Nível
Referência
Tipo
DARK --bg #0D1321 --bg2 #1D2D44 --bg3 #3E5C76 --fg #F0EBD8 --muted #748CAB --accent ÚNICO #FFC300 --accent2 #FCA311 --code #2EC4B6 UM accent. Sempre. FUNDO TEXTO BORDAS
1

🎨 A Paleta

Oito variáveis CSS. Uma por papel. Zero improvisação.

O house style não é uma lista de cores bonitas — é um sistema com papel definido para cada tom. Fundo de noite (#0D1321), painéis ligeiramente mais claros, borda sutil, texto creme quente, muted para hierarquia, e âmbar como accent único dominante. O ciano (#2EC4B6) é reservado exclusivamente para código e valores técnicos.

--bg
#0D1321
--bg2
#1D2D44
--bg3 / borda
#3E5C76
--fg
#F0EBD8
--muted
#748CAB
--accent ★
#FFC300
--accent2
#FCA311
--code
#2EC4B6
:root do composition-template.mjs
:root {
  --bg:      #0D1321;   /* azul-noite – NUNCA preto puro */
  --bg2:     #1D2D44;   /* painéis e cards */
  --bg3:     #3E5C76;   /* bordas e divisores */
  --fg:      #F0EBD8;   /* texto creme quente */
  --muted:   #748CAB;   /* secundário / hierarquia */
  --accent:  #FFC300;   /* âmbar — destaque ÚNICO */
  --accent2: #FCA311;   /* âmbar quente p/ gradientes */
  --code:    #2EC4B6;   /* verde-água — só código/valores */
}
✓ FAZER
  • Usar #0D1321 como fundo em todas as cenas
  • Âmbar só para o accent dominante (CTAs, destaques)
  • Ciano só para código, URLs e valores técnicos
  • Fundo idêntico em todas as cenas do vídeo
✗ NÃO FAZER
  • Usar #000000 como fundo (parece vídeo de YouTuber noob)
  • Misturar dois accents na mesma cena (verde + âmbar)
  • Usar ciano para texto decorativo
  • Mudar a paleta de cena para cena
🎨
8 variáveis
papéis fixos
1 accent
âmbar dominante
ciano = código
só técnico
🌙
fundo fixo
consistência total
2

🔤 Tipografia

Três fontes. Três papéis. Nenhuma ambiguidade.

O sistema usa Sora para headlines (peso 700–800, escala vídeo 72–172px em 16:9), Inter para corpo e interface (28–42px), e JetBrains Mono para código, URLs e labels técnicos. As três fontes têm .woff2 locais — o gerador nunca faz request para CDN em runtime.

Sora 800 · headline 64–172px
House style
dark premium.
Inter 400 · corpo 28–42px
O corpo usa Inter em peso regular ou medium.
Legível em tela grande, sem distração.
JetBrains Mono · código e URLs
node build-index.mjs --vertical
🌐 inema.club
Conceito principal — Por que fontes locais?

Durante a renderização com Chrome headless, a página não pode fazer requests externos. Se a fonte vier de CDN, o Chrome renderiza com fallback — e o vídeo some no render. O script fetch-fonts.mjs baixa as .woff2 (subset latin) e gera assets/fonts/fonts.css com @font-face local antes de qualquer renderização.

@font-face gerado por fetch-fonts.mjs
@font-face{font-family:'Sora';font-style:normal;font-weight:700;
  font-display:block;src:url('./fonts/Sora-700.woff2') format('woff2');}
@font-face{font-family:'Sora';font-style:normal;font-weight:800;
  font-display:block;src:url('./fonts/Sora-800.woff2') format('woff2');}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;
  font-display:block;src:url('./fonts/Inter-400.woff2') format('woff2');}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;
  font-display:block;src:url('./fonts/JetBrainsMono-400.woff2') format('woff2');}
/* subset: latin — cobre PT-BR: á à â ã é ê í ó ô õ ú ç */
Fluxo: fontes locais no pipeline
1
node fetch-fonts.mjs — baixa .woff2, gera fonts.css
2
build-index.mjs — injeta readFileSync("fonts.css") no HTML
3
Chrome headless carrega HTML — fontes já inline, zero CDN
Frame renderizado com Sora perfeita — sem fallback
Sora
700–800 · títulos
Inter
400–700 · corpo
Mono
JetBrains · código
📦
.woff2 local
nunca CDN
3

🌌 Camada de Fundo Persistente

O fundo que respira — sempre presente, nunca competindo.

Cada cena tem uma camada de fundo persistente marcada com data-layout-ignore. Ela nunca é reposicionada pelo layout engine. Contém quatro elementos: glow radial âmbar respirando, ghost text gigante driftando, grid hairline e grão (ruído SVG). Juntos criam profundidade sem distrair.

⚠ Atenção: data-layout-ignore

O atributo data-layout-ignore sinaliza ao gerador que esse elemento fica em position:absolute; z-index:-1 e não entra no flow do layout. Sem ele, o ghost text ou o glow deslocam o conteúdo real da cena.

HTML — camada persistente (composition-template.mjs)
<!-- FUNDO PERSISTENTE — data-layout-ignore -->
<div data-layout-ignore class="bg-layer">
  <!-- glow radial âmbar respirando -->
  <div class="glow-amber"></div>
  <!-- ghost text gigante driftando -->
  <div class="ghost-text">DARK</div>
  <!-- grid hairline -->
  <svg class="grid-lines" ...></svg>
  <!-- grão (SVG feTurbulence) -->
  <canvas class="grain"></canvas>
</div>
CSS — camada e animações ambiente
.bg-layer {
  position: absolute; inset: 0; z-index: -1; overflow: hidden;
}
.glow-amber {
  position: absolute; top: 40%; left: 50%;
  transform: translate(-50%, -50%);
  width: 60%; height: 40%;
  background: radial-gradient(ellipse, #FFC300 0%, transparent 70%);
  opacity: 0.06;
  animation: breathe 4s ease-in-out infinite;
}
.ghost-text {
  position: absolute; font-family: 'Sora', sans-serif;
  font-size: 172px; font-weight: 800;
  color: #F0EBD8; opacity: 0.035;
  animation: drift 8s ease-in-out infinite;
}
@keyframes breathe {
  0%,100% { opacity:.04; transform: translate(-50%,-50%) scale(1); }
  50%     { opacity:.08; transform: translate(-50%,-50%) scale(1.08); }
}
@keyframes drift {
  0%   { transform: translateX(0px) translateY(0px); }
  33%  { transform: translateX(12px) translateY(-6px); }
  66%  { transform: translateX(-8px) translateY(4px); }
  100% { transform: translateX(0px) translateY(0px); }
}
💡 Tip — Opacidade dos decorativos

Decorativos devem ficar entre 12–25% de opacidade. Abaixo de 12% some na compressão H.264. Acima de 25% compete com o conteúdo e parece amador. O ghost text fica em ~3.5% (quase invisível, só sensação de profundidade).

🌅
glow âmbar
radial respirando
DARK
ghost text
3.5% · drifting
grid hairline
profundidade
grão
textura premium
4

💾 Fontes Locais .woff2

Subset latin. @font-face local. Zero CDN em render.

O script fetch-fonts.mjs usa o User-Agent do Chrome 131 para simular browser, faz request à API do Google Fonts, filtra apenas o subset latin (unicode-range U+0000-00FF cobre todo PT-BR: á à â ã é ê í ó ô õ ú ç), baixa os .woff2 e gera assets/fonts/fonts.css.

📊 Arquivos gerados por fetch-fonts.mjs
Sora
Sora-700.woff2
Sora-800.woff2
~18KB cada
Inter
Inter-400.woff2
Inter-500.woff2
Inter-600.woff2
Inter-700.woff2
~14KB cada
JetBrains Mono
JetBrainsMono-400.woff2
JetBrainsMono-600.woff2
JetBrainsMono-700.woff2
~22KB cada
✓ FAZER
  • Rodar node fetch-fonts.mjs uma vez por projeto
  • Usar font-display:block (sem flash)
  • Commitar assets/fonts/ no repositório
  • Verificar subset latin com unicode-range
✗ NÃO FAZER
  • Link para Google Fonts CDN no HTML de cena
  • Usar font-display:swap (causa flash no render)
  • Baixar todos os subsets (aumenta tamanho sem ganho PT-BR)
  • Ignorar o .gitignore — fonts devem ser commitadas
.woff2
formato ideal
🇧🇷
subset latin
cobre PT-BR
font-display:block
sem flash
📁
assets/fonts/
local sempre
5

🎬 Escala de Vídeo, Não Web

8–10 elementos por cena. Headlines em 64–172px. Movimento ambiente em tudo.

O maior erro ao criar vídeos com HTML é usar escala web. Em 1920×1080 com zoom 1:1, texto de 16px some. O house style define headline mínima de 64px, corpo 28–42px, e decorativos com 12–25% de opacidade para criar camadas sem poluir. 8–10 elementos por cena é o limite — mais que isso cria caos visual na compressão.

Escala de tipografia por contexto
16:9 · 1920×1080
headline: 72–172px
corpo: 28–40px
caption: 32–36px
kicker: 20–28px
9:16 · 1080×1920
headline: 104–118px
corpo: 36–42px
caption: 38–44px
kicker: 24–32px
Decorativos
opacidade: 12–25%
bordas: 2–4px
ghost text: ~3.5%
glow: 4–8%
💡 Tip — Movimento ambiente

Toda decoração tem motion ambiente: entradas 0.4–0.6s, eases variados, combinando transform + opacity, stagger de 0.08–0.14s entre elementos. A regra é: se é decorativo, ele respira. Se é conteúdo, ele aparece uma vez e para.

Anatomia de uma cena (8–10 elementos)
z:-1 Camada fundo: glow + ghost + grid + grain (data-layout-ignore)
z:1 Kicker/label: fonte 20–28px, âmbar ou muted, 0.8s de entrada
z:1 Headline: Sora 800, 72–172px, branco-creme, entrada 0.4s ease-out
z:1 Regra âmbar: 2–3px de altura, 0% → 100% de largura, 0.6s ease
z:1 Subhead: Inter 400, 28–36px, muted, stagger 0.12s após headline
z:2 Caption no rodapé: Inter 600, fundo translúcido #0D1321CC
z:2 Barra de progresso âmbar: 2px altura no rodapé, scaleX(progress)
8–10
elementos/cena
máximo
172px
headline max
16:9
0.4s
entrada rápida
ease-out
25%
decorativo max
opacidade
6

🏁 A CTA INEMA.CLUB

A última cena. A assinatura padrão. Não remover jamais.

A scene9 (última cena de todo vídeo HyperFrames) é a CTA INEMA.CLUB: texto "CONTINUA EM" em muted, INEMA em creme (--fg), .CLUB em âmbar com drop-shadow glow, e 🌐 inema.club em JetBrains Mono. É a assinatura do canal — todos os vídeos terminam igual.

CONTINUA EM
INEMA.CLUB
🌐 inema.club
scene9() — composition-template.mjs (não remover)
function scene9() {
  return `
    <div class="cta-wrap">
      <div class="cta-pre">CONTINUA EM</div>
      <div class="cta-brand">
        <span class="cta-inema">INEMA</span>
        <span class="cta-club">.CLUB</span>
      </div>
      <div class="cta-url">🌐 inema.club</div>
    </div>`;
}

/* CSS correspondente */
.cta-pre  { font-family:'Inter'; color:var(--muted); letter-spacing:.2em; }
.cta-brand{ font-family:'Sora'; font-weight:800; font-size:clamp(72px,8vw,120px); }
.cta-inema{ color:var(--fg); }                /* INEMA — creme */
.cta-club { color:var(--accent);              /* .CLUB — âmbar */
             filter:drop-shadow(0 0 16px #FFC300aa); }
.cta-url  { font-family:'JetBrains Mono'; color:var(--code); } /* 🌐 inema.club */
💡 Tip — Narração da CTA

A narração padrão da scene9 é: "Isso é conteúdo do INEMA ponto CLUB. Acesse: inema ponto club." — gerada com pf_dora --speed 0.98. Duração típica: ~3.84s. LEAD: 0.5s, TAIL: 0.9s.

✓ FAZER
  • Manter scene9 como última cena de todo vídeo
  • INEMA em --fg (creme), .CLUB em --accent (âmbar)
  • Drop-shadow glow no .CLUB
  • URL em JetBrains Mono + ciano
✗ NÃO FAZER
  • Remover ou pular a scene9
  • Mudar a cor de .CLUB para outra cor da trilha
  • Usar fonte diferente na CTA
  • Omitir o 🌐 na URL
INEMA
--fg creme
.CLUB
--accent + glow
🌐 inema.club
JetBrains Mono
🏁
scene9
sempre a última

📋 Resumo do Módulo 3.2

O que você aprendeu
  • A paleta de 8 variáveis CSS com papéis fixos
  • âmbar como accent ÚNICO dominante (#FFC300)
  • Três fontes: Sora / Inter / JetBrains Mono com papéis distintos
  • Por que .woff2 local e nunca CDN em render
  • Camada de fundo persistente com data-layout-ignore
  • Escala de vídeo: 64–172px headlines, 8–10 elementos/cena
  • CTA INEMA.CLUB: INEMA creme + .CLUB âmbar + glow + 🌐
Referências do módulo
  • 📄 references/house-style.md
  • 📄 scripts/composition-template.mjs
  • 📄 scripts/fetch-fonts.mjs
  • 🔑 Regra âmbar: 1 accent. Fundo idêntico. NUNCA CDN.
Próximo módulo:
⚙️
3.3 — O gerador build-index.mjs
Como o gerador transforma HTML em frames e frames em MP4.