Dark mode fatta bene con CSS custom properties
Il dark mode non è solo invertire i colori. È ripensare l'intera gerarchia visiva per un contesto di luce ambientale diverso.
La struttura base è semplice: definisci tutte le variabili colore sulla root, poi sovrascrivile in [data-theme='dark']. I componenti non cambiano mai — usano sempre le stesse variabili. Questo è il vantaggio del semantic token system: swap il tema, tutto si aggiorna. Nessun componente sa in quale tema si trova.
L'errore comune è usare lo stesso valore di contrasto in dark e light mode. In dark mode, i colori luminosi su sfondo scuro si percepiscono come più brillanti di quanto siano. Un testo verde #00ff66 su nero sembra fluorescente. In produzione uso versioni leggermente desaturate e meno luminose dei colori accent per il dark mode, anche se in light mode uso valori più saturi.
prefers-color-scheme è il punto di partenza, non il punto di arrivo. Gli utenti devono poter overridare la preferenza di sistema. Salvo la scelta in localStorage e la riapplico all'avvio. Il primo render deve evitare il flash: leggo localStorage in uno script inline nel <head>, prima che React si idrata. Questo è l'unico posto nel mio stack dove uso uno script inline — vale la pena per eliminare il flash del tema sbagliato.