MyKindlebox/mykindlebox/client/src/index.css

203 lines
7.2 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
/* Theme palettes. The Tailwind color tokens (tailwind.config.js) resolve to
these CSS variables, so setting `data-theme` on <html> re-themes the whole
app. `:root` is the default (Classic Cream) palette, also used when no/an
unknown data-theme is set. Each named theme overrides the same ten tokens.
Keep this list in sync with the registry in src/lib/theme.js. */
:root,
[data-theme='classic'] {
--color-surface: #f7f3ec;
--color-surface-raised: #ffffff;
--color-surface-sunken: #ede8de;
--color-border: #d4c9b4;
--color-text-primary: #1c1a16;
--color-text-secondary: #6b6354;
--color-accent: #4a6741;
--color-accent-hover: #3a5233;
--color-accent-warm: #c47d2e;
--color-danger: #b34040;
}
/* Dashboard stat-tile tokens. Defined once here on :root so EVERY theme
inherits them (theme blocks below don't redefine them), and they resolve
through the per-theme color tokens — so by default the eight tiles all read
as a plain raised surface, exactly like the rest of the app. The vibrant
`carnival` theme below overrides each tile with its own color. The tile
foreground vars let the colored variant flip to light text without touching
the global text tokens. Dashboard.jsx references these as literal
`bg-[var(--stat-N)]` classes (Tailwind only generates classes it can see as
complete strings, so the per-tile names are spelled out, not built up). */
:root {
/* Text on accent-warm fills (the For Sale badge, "Check" flags). The warm
oranges are too light for white text in the light themes, so this is the
theme's dark ink everywhere — on Midnight that's the surface color. */
--color-on-accent-warm: var(--color-text-primary);
--stat-fg: var(--color-text-primary);
--stat-fg-muted: var(--color-text-secondary);
--stat-1: var(--color-surface-raised);
--stat-2: var(--color-surface-raised);
--stat-3: var(--color-surface-raised);
--stat-4: var(--color-surface-raised);
--stat-5: var(--color-surface-raised);
--stat-6: var(--color-surface-raised);
--stat-7: var(--color-surface-raised);
--stat-8: var(--color-surface-raised);
--stat-1-hover: var(--color-surface-sunken);
--stat-2-hover: var(--color-surface-sunken);
--stat-3-hover: var(--color-surface-sunken);
--stat-4-hover: var(--color-surface-sunken);
--stat-5-hover: var(--color-surface-sunken);
--stat-6-hover: var(--color-surface-sunken);
--stat-7-hover: var(--color-surface-sunken);
--stat-8-hover: var(--color-surface-sunken);
}
/* Dark theme: accent-hover is *lighter* than accent (the opposite of the light
themes), since a darker hover would disappear against dark surfaces. */
[data-theme='midnight'] {
--color-surface: #1a1d1a;
--color-surface-raised: #242823;
--color-surface-sunken: #151814;
--color-border: #3a3f38;
--color-text-primary: #ece8e0;
--color-text-secondary: #a8a294;
--color-accent: #7fa56e;
--color-accent-hover: #94b884;
--color-accent-warm: #d9954a;
--color-danger: #d46a6a;
--color-on-accent-warm: var(--color-surface);
}
[data-theme='ocean'] {
--color-surface: #f0f5f8;
--color-surface-raised: #ffffff;
--color-surface-sunken: #e1eaf0;
--color-border: #c2d3de;
--color-text-primary: #14222b;
--color-text-secondary: #516a79;
--color-accent: #2e6e8e;
--color-accent-hover: #245870;
--color-accent-warm: #e0913b;
--color-danger: #c0504d;
}
[data-theme='berry'] {
--color-surface: #f8f2f6;
--color-surface-raised: #ffffff;
--color-surface-sunken: #efe2ea;
--color-border: #dcc6d3;
--color-text-primary: #2a1a26;
--color-text-secondary: #7a6070;
--color-accent: #9b3b6e;
--color-accent-hover: #7e2d58;
--color-accent-warm: #c9762e;
--color-danger: #c0392b;
}
[data-theme='sunset'] {
--color-surface: #fbf3ec;
--color-surface-raised: #ffffff;
--color-surface-sunken: #f4e6da;
--color-border: #e6cdb8;
--color-text-primary: #2a1c14;
--color-text-secondary: #7a604d;
--color-accent: #b84a26;
--color-accent-hover: #9a3d1c;
--color-accent-warm: #e0913b;
--color-danger: #b33a3a;
}
/* Carnival: the deliberately loud theme. A clean light base lets the
multi-colored dashboard tiles (overridden below) pop. The stat tiles flip to
white text via --stat-fg. */
[data-theme='carnival'] {
--color-surface: #faf7fd;
--color-surface-raised: #ffffff;
--color-surface-sunken: #f0eaf7;
--color-border: #e2d9ec;
--color-text-primary: #1b1228;
--color-text-secondary: #6a5c7c;
--color-accent: #7c3aed;
--color-accent-hover: #6d28d9;
--color-accent-warm: #ea580c;
--color-danger: #e11d48;
--stat-fg: #ffffff;
--stat-fg-muted: rgba(255, 255, 255, 0.82);
--stat-1: #7c3aed; /* herd — violet */
--stat-2: #2563eb; /* bucks — blue */
--stat-3: #db2777; /* does — pink */
--stat-4: #ea580c; /* kits — orange */
--stat-5: #059669; /* for sale — green*/
--stat-6: #d97706; /* on hold — amber */
--stat-7: #0891b2; /* sold — cyan */
--stat-8: #475569; /* archived — slate*/
--stat-1-hover: #6d28d9;
--stat-2-hover: #1d4ed8;
--stat-3-hover: #be185d;
--stat-4-hover: #c2410c;
--stat-5-hover: #047857;
--stat-6-hover: #b45309;
--stat-7-hover: #0e7490;
--stat-8-hover: #334155;
}
/* Theme-aware form controls. Inputs/textareas/selects across the app don't set
their own background or text color, so without this they fall back to the
browser default (white background, near-black text) — fine on the light
themes (where it matches `surface-raised`) but unreadable on the dark
Midnight theme, which renders a glaring white box with washed-out placeholder
text. Tying the controls to the theme tokens keeps them legible everywhere
without touching each component. */
@layer base {
input:not([type='checkbox']):not([type='radio']):not([type='file']):not([type='range']):not([type='color']),
textarea,
select {
background-color: var(--color-surface-raised);
color: var(--color-text-primary);
}
/* iOS Safari zooms the page when focusing a control whose font-size is under
16px, which is jarring in the installed PWA. Most controls use text-sm, so
bump them to 16px on small screens only; desktop keeps the denser size. */
@media (max-width: 767px) {
input:not([type='checkbox']):not([type='radio']):not([type='file']):not([type='range']):not([type='color']),
textarea,
select {
font-size: 16px;
}
}
input::placeholder,
textarea::placeholder {
color: var(--color-text-secondary);
opacity: 1;
}
}
/* `!important` is deliberate: several inputs/buttons already set
`focus:outline-none` (paired with their own `focus:ring-2`) which would
otherwise win on specificity over a plain `:focus-visible` rule and leave
keyboard focus invisible on exactly the elements that most need it. This
guarantees every focusable element gets a visible accent-colored ring on
keyboard focus, app-wide, without auditing each component individually. */
:focus-visible {
outline: 2px solid theme('colors.accent') !important;
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}