ui phase 0

This commit is contained in:
hamid
2026-07-17 14:00:22 +03:30
parent 9051bb3e18
commit f1cba6cf74
139 changed files with 1242 additions and 667 deletions
+130 -8
View File
@@ -1,23 +1,57 @@
/*
* Balinyaar brand color tokens — source of truth for all colors.
*
* Palette extracted from the seed-deck proposal (balinyaar.html):
* Brand identity (construction + rationale): .claude/skills/frontend-designer/SKILL.md.
* #1d4a40 deep teal / forest-green → brand primary
* #d98c6a terracotta → brand accent (secondary)
* #f3efe9 soft cream → text-on-dark / glyph fill
* #faf9f5 cream → page surface
*
* MUI sets data-mui-color-scheme="dark" on <html> when dark mode is active
* (colorSchemeSelector: 'data' in createTheme). The same attribute drives
* every custom CSS rule in this file. You never need to read or write
* this attribute manually — MUI's useColorScheme() does it for you.
* (colorSchemeSelector: 'data-mui-color-scheme' in createTheme). The same
* attribute drives every custom CSS rule in this file. You never need to
* read or write this attribute manually — MUI's useColorScheme() does it for
* you at runtime.
*
* No-flash boot (no JS): when a returning visitor's `color-scheme` cookie is
* present, the server stamps the attribute directly and the explicit
* `[data-mui-color-scheme]` blocks below apply immediately — zero flash. On a
* cookie-less FIRST visit the server renders <html> WITHOUT the attribute
* (see lib/cookies/server.ts getThemeMode()), so the `@media
* (prefers-color-scheme: dark)` block below — scoped to the attribute being
* absent — paints the OS-preferred scheme immediately, with no script. Once
* MUI hydrates (ThemeProvider defaultMode="system") it resolves the same
* media query and stamps the attribute itself; the values already match, so
* there is nothing to visibly flip. The dark values therefore appear twice
* below (the media-query fallback + the explicit attribute block) — keep
* both in sync when changing a dark-scheme value.
*
* Usage in custom CSS outside MUI:
* color: var(--bal-primary); ← resolves to the active scheme value
* background: var(--bal-bg-default);
*
* Sync rule: any color added/changed here also lands in colors.ts (LIGHT_PALETTE/
* DARK_PALETTE) when it's palette-level (success/error/warning/info, primary,
* secondary…). Non-palette tokens (elevation, radius, motion, focus, rating,
* trust, money-emphasis) are define-only here — colors.ts never needs them.
*/
/* ── Light scheme (default) ────────────────────────────────────────────── */
/* ── Scheme-independent tokens (radius scale, motion) ──────────────────── */
:root {
/* Radius scale — controls / cards / dialogs. shape.borderRadius (theme.ts)
mirrors --bal-radius-md; never invent a radius per component. */
--bal-radius-sm: 4px;
--bal-radius-md: 10px;
--bal-radius-lg: 16px;
/* Motion — durations + easing, consumed by the phase-12 motion pass */
--bal-motion-fast: 120ms;
--bal-motion-base: 200ms;
--bal-motion-slow: 300ms;
--bal-easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
}
/* ── Light scheme — the unconditional default ──────────────────────────── */
:root,
[data-mui-color-scheme='light'] {
/* Primary — deep teal */
@@ -56,16 +90,86 @@
--bal-warning-contrast: #f3efe9;
--bal-info: #1d4a40;
--bal-info-contrast: #f3efe9;
/* Elevation — teal-tinted shadow steps (replaces MUI's grey default stack).
Consumed by theme.ts's `shadows` array + the MuiPaper/MuiDialog overrides. */
--bal-shadow-1: 0 1px 2px rgba(29, 74, 64, 0.06), 0 1px 1px rgba(29, 74, 64, 0.04);
--bal-shadow-2: 0 4px 12px rgba(29, 74, 64, 0.10), 0 2px 4px rgba(29, 74, 64, 0.06);
--bal-shadow-3: 0 12px 32px rgba(29, 74, 64, 0.14), 0 4px 8px rgba(29, 74, 64, 0.08);
/* Focus ring — global :focus-visible treatment (MuiCssBaseline, theme.ts) */
--bal-focus-ring: #1d4a40;
/* Rating stars — RatingInput's star fill/empty (retires the muddy --bal-warning use) */
--bal-rating: #c8971e;
--bal-rating-empty: rgba(29, 74, 64, 0.20);
/* Trust — a distinct identity for verified marks, separate from primary/success */
--bal-trust: #2b6ca8;
--bal-trust-soft: rgba(43, 108, 168, 0.12);
/* Money emphasis — AA-contrast-safe money-text color (terracotta itself fails
AA at small sizes on white: #d98c6a ≈ 2:1). Never use --bal-secondary for
small money text; use this instead. */
--bal-money-emphasis: #8a4a2f;
}
/* ── Dark scheme ────────────────────────────────────────────────────────── */
/* ── Dark scheme — OS-preference fallback for the cookie-less first visit ── */
@media (prefers-color-scheme: dark) {
:root:not([data-mui-color-scheme]) {
--bal-primary: #6fc0ac;
--bal-primary-light: #8fd2c1;
--bal-primary-dark: #3f8a78;
--bal-primary-contrast: #06120f;
--bal-primary-soft: rgba(111, 192, 172, 0.16);
--bal-secondary: #e6a98a;
--bal-secondary-light: #f0bfa3;
--bal-secondary-dark: #d98c6a;
--bal-secondary-contrast: #2a1a12;
--bal-secondary-soft: rgba(230, 169, 138, 0.18);
--bal-bg-default: #0f1c19;
--bal-bg-paper: #16302a;
--bal-text-primary: #f3efe9;
--bal-text-secondary: #9fb0a9;
--bal-divider: rgba(243, 239, 233, 0.14);
--bal-success: #257659;
--bal-success-contrast: #f3efe9;
--bal-error: #b5402f;
--bal-error-contrast: #f3efe9;
--bal-warning: #97701f;
--bal-warning-contrast: #f3efe9;
--bal-info: #2f6b5e;
--bal-info-contrast: #f3efe9;
--bal-shadow-1: 0 1px 2px rgba(6, 18, 15, 0.24), 0 1px 1px rgba(6, 18, 15, 0.16);
--bal-shadow-2: 0 4px 12px rgba(6, 18, 15, 0.32), 0 2px 4px rgba(6, 18, 15, 0.20);
--bal-shadow-3: 0 12px 32px rgba(6, 18, 15, 0.40), 0 4px 8px rgba(6, 18, 15, 0.24);
--bal-focus-ring: #6fc0ac;
--bal-rating: #e0b542;
--bal-rating-empty: rgba(243, 239, 233, 0.20);
--bal-trust: #7fb8e6;
--bal-trust-soft: rgba(127, 184, 230, 0.18);
--bal-money-emphasis: #f0bfa3;
}
}
/* ── Dark scheme — explicit (cookie present, or after MUI hydrates/toggles).
Keep every value identical to the @media block above. ──────────────── */
[data-mui-color-scheme='dark'] {
/* Primary — lifted teal (readable on dark surfaces) */
--bal-primary: #6fc0ac;
--bal-primary-light: #8fd2c1;
--bal-primary-dark: #3f8a78;
--bal-primary-contrast: #06120f;
/* Soft primary tint — selected chips, subtle info panels */
--bal-primary-soft: rgba(111, 192, 172, 0.16);
/* Secondary — warm terracotta-light */
@@ -73,7 +177,6 @@
--bal-secondary-light: #f0bfa3;
--bal-secondary-dark: #d98c6a;
--bal-secondary-contrast: #2a1a12;
/* Soft terracotta tint — the "نمای پرستار" nurse-view chip + EVV/financial affordances */
--bal-secondary-soft: rgba(230, 169, 138, 0.18);
/* Surfaces — deep teal */
@@ -96,4 +199,23 @@
--bal-warning-contrast: #f3efe9;
--bal-info: #2f6b5e;
--bal-info-contrast: #f3efe9;
/* Elevation — black-teal shadow steps (deeper + darker than light scheme) */
--bal-shadow-1: 0 1px 2px rgba(6, 18, 15, 0.24), 0 1px 1px rgba(6, 18, 15, 0.16);
--bal-shadow-2: 0 4px 12px rgba(6, 18, 15, 0.32), 0 2px 4px rgba(6, 18, 15, 0.20);
--bal-shadow-3: 0 12px 32px rgba(6, 18, 15, 0.40), 0 4px 8px rgba(6, 18, 15, 0.24);
/* Focus ring */
--bal-focus-ring: #6fc0ac;
/* Rating stars */
--bal-rating: #e0b542;
--bal-rating-empty: rgba(243, 239, 233, 0.20);
/* Trust */
--bal-trust: #7fb8e6;
--bal-trust-soft: rgba(127, 184, 230, 0.18);
/* Money emphasis — lifted warm tone, readable on dark surfaces */
--bal-money-emphasis: #f0bfa3;
}