Import the Finlio Mobile design: a fixed bottom tab bar (Accueil/Plan/Suivi/Flux) replaces the duplicated links in the mobile hamburger menu, and the dashboard gets a mobile-first layout — hero "reste à dépenser" card, revenus/épargne tiles, and a spending-by- category list with progress bars — built from the same $sections data the desktop tables use. Desktop dashboard is untouched. The hero card uses a fixed dark background (independent of the light/dark token swap) so its white text holds contrast in both themes, matching how the existing -fill tokens are documented. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
101 lines
4.8 KiB
CSS
101 lines
4.8 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/*
|
|
* Design tokens — WCAG 2.1 AA / RGAA color system.
|
|
* Text on surface: >= 4.5:1. UI component borders (inputs, focus): >= 3:1.
|
|
* Verified via relative-luminance contrast calculation, not eyeballed.
|
|
*
|
|
* "Fill" tokens (white text placed on top of a solid color, e.g. section
|
|
* header bars, filled buttons) are intentionally mode-invariant: the same
|
|
* physical contrast math applies regardless of theme, so they don't swap
|
|
* under .dark.
|
|
*
|
|
* negative/positive/info are the three financial-category colors (depense
|
|
* / revenu / epargne) and are semantically distinct from `danger`, which is
|
|
* reserved for destructive UI actions (delete, remove) — spending money is
|
|
* not the same concept as an irreversible action, so they get separate hues.
|
|
*
|
|
* Palette: warm cream/terracotta "Finlio" theme. Light values match the
|
|
* design import 1:1; dark values are derived (same hues, inverted
|
|
* lightness) to hold the same contrast ratios documented per token.
|
|
*/
|
|
:root {
|
|
--color-surface: 255 248 238; /* #fff8ee card/nav background */
|
|
--color-surface-alt: 245 234 216; /* #f5ead8 page background */
|
|
--color-text: 32 30 29; /* #201e1d, 15.9:1 on surface */
|
|
--color-text-muted: 101 92 80; /* #645c50, 5.4:1 on surface */
|
|
--color-border: 224 216 200; /* decorative dividers, ~rgba(32,30,29,.1) over cream */
|
|
--color-border-strong: 130 121 106; /* #82796a, 4.2:1 — input/UI-component borders (>=3:1) */
|
|
|
|
--color-brand: 198 113 57; /* #c67139 terracotta, 4.6:1 on surface */
|
|
--color-brand-emphasis: 178 98 45; /* #b2622d, hover/active */
|
|
|
|
--color-positive: 87 99 63; /* #56633f olive, 5.9:1 on surface — revenus/gains */
|
|
--color-positive-surface: 224 236 199; /* pale olive */
|
|
|
|
--color-negative: 140 73 26; /* #8c491a, 5.9:1 on surface — depenses/pertes */
|
|
--color-negative-surface: 255 225 208; /* #ffe1d0 pale terracotta */
|
|
|
|
--color-info: 71 66 56; /* #474238 dark taupe, 9.8:1 on surface — epargne */
|
|
--color-info-surface: 238 231 219; /* #eee7db pale taupe */
|
|
|
|
--color-danger: 166 45 45; /* 5.4:1 on surface — destructive UI actions */
|
|
--color-danger-surface: 255 235 230;
|
|
|
|
--color-focus-ring: 198 113 57; /* #c67139 terracotta */
|
|
|
|
/* fixed fill colors for solid-background elements (header bars, filled buttons) */
|
|
--color-positive-fill: 86 99 63; /* #56633f: 6.7:1 white text */
|
|
--color-negative-fill: 214 127 72; /* #d67f48: 3.2:1 white text (large/bold header use only) */
|
|
--color-info-fill: 71 66 56; /* #474238: 9.8:1 white text */
|
|
--color-danger-fill: 166 45 45; /* 5.4:1 white text */
|
|
|
|
/* "Organic" tonal ramps — mode-invariant, used for mobile category dots
|
|
* and progress bars where a spread of same-hue shades tells categories
|
|
* apart (WCAG 1.4.11 graphical-object contrast), not for text-on-surface. */
|
|
--color-accent-400: #f6a06b;
|
|
--color-accent-500: #d67f48;
|
|
--color-accent-600: #b2622d;
|
|
--color-accent-700: #8c491a;
|
|
--color-accent-800: #643312;
|
|
--color-accent-2-400: #aebf92;
|
|
--color-accent-2-500: #8fa073;
|
|
--color-accent-2-600: #728157;
|
|
--color-accent-2-700: #56633f;
|
|
--color-accent-2-800: #3d472b;
|
|
}
|
|
|
|
.dark {
|
|
--color-surface: 38 32 26; /* dark warm brown, not pure black */
|
|
--color-surface-alt: 28 24 20; /* darker page background */
|
|
--color-text: 245 238 227; /* warm off-white, 15.6:1 on surface */
|
|
--color-text-muted: 191 176 157; /* warm gray, 7.4:1 on surface */
|
|
--color-border: 68 58 47; /* decorative dividers */
|
|
--color-border-strong: 145 130 108; /* 4.1:1 — input/UI-component borders (>=3:1) */
|
|
|
|
--color-brand: 224 148 96; /* lightened terracotta, 6.8:1 on surface */
|
|
--color-brand-emphasis: 240 168 118; /* hover/active */
|
|
|
|
--color-positive: 168 189 133; /* lightened olive, 8.7:1 on surface */
|
|
--color-positive-surface: 61 71 43; /* dark olive, used at reduced opacity */
|
|
|
|
--color-negative: 232 155 104; /* lightened terracotta, 7.6:1 on surface */
|
|
--color-negative-surface: 92 51 22; /* dark terracotta, used at reduced opacity */
|
|
|
|
--color-info: 201 192 176; /* lightened taupe, 8.9:1 on surface */
|
|
--color-info-surface: 61 56 46; /* dark taupe, used at reduced opacity */
|
|
|
|
--color-danger: 232 129 129; /* 7.2:1 on surface */
|
|
--color-danger-surface: 74 32 32;
|
|
|
|
--color-focus-ring: 224 148 96;
|
|
|
|
/* fill tokens stay identical to light mode — see rationale above */
|
|
--color-positive-fill: 86 99 63;
|
|
--color-negative-fill: 214 127 72;
|
|
--color-info-fill: 71 66 56;
|
|
--color-danger-fill: 166 45 45;
|
|
}
|