Tips & Tricks

Como Implementar Modo Escuro com Claude Code

Aprenda a implementar modo escuro usando o Claude Code. Inclui exemplos praticos de codigo e orientacao passo a passo.

Eficientizando a Implementacao de Modo Escuro com Claude Code

O modo escuro ja e uma funcionalidade padrao em aplicacoes web, mas sua implementacao requer muitas consideracoes como design CSS, gerenciamento de estado e persistencia. Com o Claude Code, voce pode implementar com um design consistente em pouco tempo.

Design de Tema com Variaveis CSS

Primeiro, defina os tokens de tema com variaveis CSS.

> Projete temas claro/escuro baseados em variaveis CSS.
> Use nomes de cores semanticos e integre com Tailwind.
/* globals.css */
:root {
  --color-bg-primary: #ffffff;
  --color-bg-secondary: #f8fafc;
  --color-bg-tertiary: #f1f5f9;
  --color-text-primary: #0f172a;
  --color-text-secondary: #475569;
  --color-text-tertiary: #94a3b8;
  --color-border: #e2e8f0;
  --color-border-hover: #cbd5e1;
  --color-accent: #3b82f6;
  --color-accent-hover: #2563eb;
  --color-surface: #ffffff;
  --color-surface-hover: #f8fafc;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
}

[data-theme="dark"] {
  --color-bg-primary: #0f172a;
  --color-bg-secondary: #1e293b;
  --color-bg-tertiary: #334155;
  --color-text-primary: #f1f5f9;
  --color-text-secondary: #cbd5e1;
  --color-text-tertiary: #64748b;
  --color-border: #334155;
  --color-border-hover: #475569;
  --color-accent: #60a5fa;
  --color-accent-hover: #93bbfd;
  --color-surface: #1e293b;
  --color-surface-hover: #334155;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}

Implementacao da Troca de Tema

Criando um hook que suporta tanto a sincronizacao com as configuracoes do sistema quanto a troca manual.

import { useState, useEffect, useCallback } from "react";

type Theme = "light" | "dark" | "system";

export function useTheme() {
  const [theme, setThemeState] = useState<Theme>(() => {
    if (typeof window === "undefined") return "system";
    return (localStorage.getItem("theme") as Theme) || "system";
  });

  const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");

  const applyTheme = useCallback((newTheme: Theme) => {
    const root = document.documentElement;
    let resolved: "light" | "dark";

    if (newTheme === "system") {
      resolved = window.matchMedia("(prefers-color-scheme: dark)").matches
        ? "dark"
        : "light";
    } else {
      resolved = newTheme;
    }

    root.setAttribute("data-theme", resolved);
    setResolvedTheme(resolved);
  }, []);

  const setTheme = useCallback(
    (newTheme: Theme) => {
      setThemeState(newTheme);
      localStorage.setItem("theme", newTheme);
      applyTheme(newTheme);
    },
    [applyTheme]
  );

  useEffect(() => {
    applyTheme(theme);

    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    const handleChange = () => {
      if (theme === "system") applyTheme("system");
    };

    mediaQuery.addEventListener("change", handleChange);
    return () => mediaQuery.removeEventListener("change", handleChange);
  }, [theme, applyTheme]);

  return { theme, setTheme, resolvedTheme };
}

Botao de Troca de Tema

import { useTheme } from "@/hooks/useTheme";

export function ThemeToggle() {
  const { theme, setTheme, resolvedTheme } = useTheme();

  const options: { value: Theme; label: string; icon: string }[] = [
    { value: "light", label: "Claro", icon: "sun" },
    { value: "dark", label: "Escuro", icon: "moon" },
    { value: "system", label: "Sistema", icon: "monitor" },
  ];

  return (
    <div className="flex items-center gap-1 p-1 rounded-lg bg-[var(--color-bg-tertiary)]">
      {options.map((option) => (
        <button
          key={option.value}
          onClick={() => setTheme(option.value)}
          className={`px-3 py-1.5 rounded-md text-sm transition-colors ${
            theme === option.value
              ? "bg-[var(--color-surface)] text-[var(--color-text-primary)] shadow-sm"
              : "text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"
          }`}
          aria-label={option.label}
        >
          {option.label}
        </button>
      ))}
    </div>
  );
}

Prevencao de FOUC (Flash of Unstyled Content)

Script para prevenir o flash momentaneo de troca de tema ao carregar a pagina.

<!-- Colocar dentro do head -->
<script>
  (function () {
    const theme = localStorage.getItem("theme") || "system";
    let resolved = theme;
    if (theme === "system") {
      resolved = window.matchMedia("(prefers-color-scheme: dark)").matches
        ? "dark"
        : "light";
    }
    document.documentElement.setAttribute("data-theme", resolved);
  })();
</script>

Integracao com Tailwind CSS

// tailwind.config.js
module.exports = {
  darkMode: ["selector", '[data-theme="dark"]'],
  theme: {
    extend: {
      colors: {
        bg: {
          primary: "var(--color-bg-primary)",
          secondary: "var(--color-bg-secondary)",
          tertiary: "var(--color-bg-tertiary)",
        },
        text: {
          primary: "var(--color-text-primary)",
          secondary: "var(--color-text-secondary)",
        },
        surface: {
          DEFAULT: "var(--color-surface)",
          hover: "var(--color-surface-hover)",
        },
      },
    },
  },
};

Para integracao com design systems, consulte Construcao de Design System, e para responsividade, consulte Design Responsivo.

Resumo

Com o Claude Code, voce pode concluir a implementacao de modo escuro em pouco tempo de forma consistente, desde o design de variaveis CSS, logica de troca de tema, prevencao de FOUC ate integracao com Tailwind. Basta solicitar “adicione modo escuro” para integrar adequadamente em projetos existentes.

Para mais detalhes, consulte a documentacao oficial do Claude Code.

#Claude Code #dark mode #CSS variables #Tailwind CSS #theming