Alterna entre tema claro e escuro com persistência em localStorage, sincronização entre abas, detecção de preferência do sistema e atalho de teclado — zero configuração.
Controla qual tema (claro/escuro) a página usa, lembrando a escolha entre visitas e respeitando a preferência do sistema operacional na primeira vez. Quando nenhum botão próprio existe na página, injeta automaticamente um FAB colado na borda direita da tela, com um botão de sol e um de lua — sem opção "sistema", só as duas escolhas reais.
Detecta a preferência salva no localStorage; sem nada salvo, usa prefers-color-scheme do sistema. Se nenhuma página tiver um botão real com sw-day, injeta um FAB colado na borda direita, centralizado verticalmente — um par de botões empilhados (sol/lua), cada um define o tema direto ao clicar, e o botão do tema atual fica destacado na cor primária. Atalho Ctrl+Shift+D alterna a qualquer momento.
<!-- Qualquer elemento com sw-day vira um toggle -->
<button sw-day class="sw-btn sw-btn-pil">
<i class="sw-daytg-ico"></i> <!-- ícone ☀️/🌙 auto-injetado -->
Alternar tema
</button>
<!-- Só ícone: deixe vazio — sw-day.js injeta o ícone e o aria-label sozinho -->
<button sw-day class="sw-btn sw-btn-rnd"></button>
/* Variáveis semânticas gerenciadas automaticamente pelo SW.Day */
html[sw-theme="light"] {
--surface: var(--sw-neu-1);
--text: var(--sw-neu-12);
--border: var(--sw-neu-4);
}
Logo trocando de arquivo
A logo real da barra lateral desta doc — clique no botão de tema (rodapé da barra lateral ou topo, no mobile) e veja o arquivo mudar de verdade.
Fundo trocando de cor
O fundo deste cartão está preso ao tema — não é imagem, é a propriedade CSS background sendo trocada em tempo real pelo módulo.
<!-- Troca o src da imagem conforme o tema -->
<img src="logo-dark.png"
sw-day-img-light="logo-light.png"
sw-day-img-dark="logo-dark.png">
<!-- Troca a cor (ou "url(...)" para uma imagem) de fundo do elemento -->
<div sw-day-bg-light="#fef3c7"
sw-day-bg-dark="#0d131d">
</div>
No tema claro: Sans-Serif. No tema escuro: Mono (JetBrains). Alterne o tema com o botão na lateral →
<!-- Troca a família de fonte ao mudar de tema -->
<h1 sw-day-font-light="var(--sw-f-san)"
sw-day-font-dark="var(--sw-f-mon)">
Título Dinâmico
</h1>
Fluxo de decisão
localStorage tem sw-theme salvo?
prefers-color-scheme do sistema
dark
Recursos automáticos
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;">
<div>
<p style="font-size:.8rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);margin-bottom:.75rem;">Fluxo de decisão</p>
<div style="background:var(--surface);border:1px solid var(--border);border-radius:0.5rem;padding:1.25rem;display:flex;flex-direction:column;gap:.75rem;">
<div style="display:flex;align-items:center;gap:.75rem;font-size:.9rem;">
<span style="width:2rem;height:2rem;border-radius:50%;background:var(--color-primary);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;flex-shrink:0;">1</span>
<span><code>localStorage</code> tem <code>sw-theme</code> salvo?</span>
</div>
<div style="display:flex;align-items:center;gap:.75rem;font-size:.9rem;">
<span style="width:2rem;height:2rem;border-radius:50%;background:var(--surface-active);color:var(--text-muted);display:inline-flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;flex-shrink:0;">2</span>
<span>Se não → <code>prefers-color-scheme</code> do sistema</span>
</div>
<div style="display:flex;align-items:center;gap:.75rem;font-size:.9rem;">
<span style="width:2rem;height:2rem;border-radius:50%;background:var(--surface-active);color:var(--text-muted);display:inline-flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;flex-shrink:0;">3</span>
<span>Se não → padrão <code>dark</code></span>
</div>
</div>
</div>
<div>
<p style="font-size:.8rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);margin-bottom:.75rem;">Recursos automáticos</p>
<div style="background:var(--surface);border:1px solid var(--border);border-radius:0.5rem;padding:1.25rem;display:flex;flex-direction:column;gap:.6rem;font-size:.88rem;">
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Persiste entre sessões (localStorage)</div>
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Sincroniza entre abas abertas</div>
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Respeita prefers-color-scheme</div>
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Atalho Ctrl+Shift+D</div>
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Evento sw:theme:change</div>
<div style="display:flex;align-items:center;gap:.5rem;"><i class="swi-check" style="color:#22c55e;"></i> Ícone ☀️/🌙 auto-injetado</div>
</div>
</div>
</div>
Controle programático completo via SW.Day:
// Setar tema
SW.Day.set('dark');
SW.Day.set('light');
// Toggle (dark → light → dark)
SW.Day.toggle();
// Ler tema atual
console.log(SW.Day.theme); // 'dark' | 'light'
// Escutar mudança de tema
document.documentElement.addEventListener('sw:theme:change', (e) => {
console.log('Tema:', e.detail.theme);
// atualizar gráficos, ícones, etc.
});
// Exemplo real: sincronizar Chart.js com o tema
document.documentElement.addEventListener('sw:theme:change', ({ detail }) => {
const isDark = detail.theme === 'dark';
myChart.options.scales.x.grid.color = isDark ? '#333' : '#ddd';
myChart.update();
});
sw-daysw-day-demosw-day como exemplo — não impede o FAB padrão de aparecersw-day-lock="dark|light" (no <html>)sw-day-no-fab (no <html>)sw-day-img-{tema}sw-day-bg-{tema}sw-day-font-{tema}Nenhum.
sw:theme:changeSW.Day.toggle()SW.Day.set(tema, persistir?)SW.Day.themelocalStorage pra lembrar a escolha entre visitas (sem ele, ainda funciona, só não persiste).<head> antes de qualquer CSS: <script>try{var t=localStorage.getItem('sw-theme');if(t)document.documentElement.setAttribute('sw-theme',t)}catch(e){}</script>Nenhuma.