# Pico CSS — Gotchas & Notes ## [role=button] clobbers --pico-color Pico's stylesheet includes this rule: ```css [role=button], [type=button], button, ... { --pico-color: var(--pico-primary-inverse); ... } ``` In light mode, `--pico-primary-inverse` is `#fff`. This means **any element with `role="button"` will have white text by default**, regardless of its background. Children inherit this, making text invisible on white/light card backgrounds. **Fix:** On the element itself, reset the variable and set an explicit color: ```css .your-element { --pico-color: initial; color: var(--pico-contrast); /* #181c25 light / #dfe3eb dark — always legible */ } ``` **Alternative:** Remove `role="button"` and use `tabindex="0"` + keyboard handlers only, avoiding the Pico button rule entirely. Only do this if button semantics aren't needed for accessibility. ## Plain/ghost buttons disappear on hover in light/Dan mode Pico's button hover rule sets **both** CSS custom properties **and** computed values: ```css button:is(:hover,:active,:focus) { --pico-background-color: var(--pico-primary-hover-background); --pico-border-color: var(--pico-primary-hover-border); --pico-color: var(--pico-primary-inverse); /* #fff in light mode */ } ``` If your button has a transparent or white background — e.g. a ghost/plain-style button — the text becomes invisible because `--pico-primary-inverse` is `#fff` in light mode. **Important:** Overriding only `color: ... !important` is **not enough**, because Pico sets `--pico-color` as a CSS variable that other rules may read. You must override all three custom properties *and* the corresponding computed properties simultaneously. **Symptom:** ghost button text vanishes on hover in light or Dan mode (background goes blue, text goes white). Works fine in dark mode because the dark background makes white text readable. **Fix:** Override all Pico button hover variables explicitly: ```css .my-ghost-button:not(:disabled):hover { --pico-color: var(--pico-contrast) !important; /* near-black in light, near-white in dark */ --pico-background-color: transparent !important; --pico-border-color: var(--pico-contrast) !important; color: var(--pico-contrast) !important; background: transparent !important; border-color: var(--pico-contrast) !important; } ``` Use `--pico-contrast` (not `--pico-color`) as the hover text color — it's `#181c25` in light mode and `#dfe3eb` in dark mode, so it's always legible against the page background regardless of theme. ## Palette overrides must be scoped to light mode Pico defines its palette twice: once for light (`:root:not([data-theme=dark])`) and once for dark (`@media (prefers-color-scheme: dark)` + `[data-theme=dark]`). If you override Pico vars at bare `:root`, you'll clobber the dark mode values. **Wrong:** ```css :root { --pico-color: #2C2C2C; /* kills dark mode */ } ``` **Correct:** ```css @media (prefers-color-scheme: light) { :root:not([data-theme]) { --pico-color: #2C2C2C; } } [data-theme=light] { --pico-color: #2C2C2C; } ``` ## Theme toggling pattern Set `data-theme="light"` or `data-theme="dark"` on ``. Pico reads this attribute for its palette selectors. Persist to `localStorage`. Read OS preference (`prefers-color-scheme`) on first visit when no stored value exists. ## --pico-card-background-color in light mode In light mode, Pico sets: ``` --pico-card-background-color: var(--pico-background-color) → #fff ``` If you want custom card backgrounds, override `--pico-card-background-color` directly (scoped to light mode only — see above). ## CSS variables that Pico does NOT define - `--color-label` (app-defined) — must be set for both light and dark explicitly - Any `--shadow-*` vars — define at `:root` (theme-neutral)