mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 21:32:18 +00:00
Maintainer-voice sweep across `src/`. ~190 references to the maintainer by first name in code comments and JSDoc neutralised to "the maintainer", "the live tenant", "users", or "the user" depending on context. Three sed passes covering ~50 distinct patterns (`Marc reported`, `Marc wants`, `Marc kept`, `Marc rolled back`, etc.). Test fixtures (`displayName: "Marc B."`, `username: "marc"`, `<HeroStrip userName="Marc">`) kept as opaque test data per the brief. CHANGELOG normalisation. The v1.4.14 + v1.4.15 entries paired a German bullet with its English translation by historical design — the in-app copy is English-default and the user docs are English, so the mixed-language style was a holdover from the early-marathon notes. A one-off node script extracted the `_..._` English paragraph from each bilingual bullet and rewrote the entry as that text. ~44 bullets reduced; one Docs bullet that lost a leading word in the regex fixed by hand. CLAUDE.md → CONTRIBUTING-AI.md rename so the filename is no longer AI-vendor-specific. `CONTRIBUTING.md` reference updated. `AGENTS.md` stays in place for multi-agent compatibility (the conventions doc is shared with Codex / Cursor / etc.). Wave-4 state wrap. STATE.md now records C1–C5 + D + D2 as complete; v1421-backlog.md grew a "Closed in v1.4.22" header listing the 20 items the marathon landed; `.planning/phase-W4-report.md` documents the per-commit decisions, test deltas, and the 23 items deferred to v1.4.23 with reasoning. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
305 lines
9.2 KiB
CSS
305 lines
9.2 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
@import "shadcn/tailwind.css";
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
|
|
@theme inline {
|
|
--color-background: var(--background);
|
|
--color-foreground: var(--foreground);
|
|
--font-sans: var(--font-sans);
|
|
--font-mono: var(--font-mono);
|
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
--color-sidebar-border: var(--sidebar-border);
|
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
--color-sidebar-accent: var(--sidebar-accent);
|
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
--color-sidebar-primary: var(--sidebar-primary);
|
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
--color-sidebar: var(--sidebar);
|
|
--color-chart-5: var(--chart-5);
|
|
--color-chart-4: var(--chart-4);
|
|
--color-chart-3: var(--chart-3);
|
|
--color-chart-2: var(--chart-2);
|
|
--color-chart-1: var(--chart-1);
|
|
--color-ring: var(--ring);
|
|
--color-input: var(--input);
|
|
--color-border: var(--border);
|
|
--color-destructive: var(--destructive);
|
|
--color-accent-foreground: var(--accent-foreground);
|
|
--color-accent: var(--accent);
|
|
--color-muted-foreground: var(--muted-foreground);
|
|
--color-muted: var(--muted);
|
|
--color-secondary-foreground: var(--secondary-foreground);
|
|
--color-secondary: var(--secondary);
|
|
--color-primary-foreground: var(--primary-foreground);
|
|
--color-primary: var(--primary);
|
|
--color-popover-foreground: var(--popover-foreground);
|
|
--color-popover: var(--popover);
|
|
--color-card-foreground: var(--card-foreground);
|
|
--color-card: var(--card);
|
|
--radius-sm: calc(var(--radius) - 4px);
|
|
--radius-md: calc(var(--radius) - 2px);
|
|
--radius-lg: var(--radius);
|
|
--radius-xl: calc(var(--radius) + 4px);
|
|
--radius-2xl: calc(var(--radius) + 8px);
|
|
--radius-3xl: calc(var(--radius) + 12px);
|
|
--radius-4xl: calc(var(--radius) + 16px);
|
|
|
|
/* Dracula semantic colors for charts */
|
|
--color-dracula-purple: var(--dracula-purple);
|
|
--color-dracula-pink: var(--dracula-pink);
|
|
--color-dracula-green: var(--dracula-green);
|
|
--color-dracula-cyan: var(--dracula-cyan);
|
|
--color-dracula-orange: var(--dracula-orange);
|
|
--color-dracula-red: var(--dracula-red);
|
|
--color-dracula-yellow: var(--dracula-yellow);
|
|
--color-dracula-lavender: var(--dracula-lavender);
|
|
|
|
/*
|
|
* Semantic feedback tokens — aliases over the Dracula palette so badges,
|
|
* banners, and status pills can stop hard-coding `text-dracula-green` /
|
|
* `bg-dracula-orange/15` and ask for the *meaning* instead. Each is a
|
|
* straight alias of the existing colour at the time of introduction so
|
|
* the visual stays pixel-identical to v1.4.6 — what changes is intent.
|
|
* - success → dracula-green (positive outcome, e.g. published)
|
|
* - warning → dracula-orange (caution / non-blocking attention)
|
|
* - info → dracula-cyan (neutral informational note)
|
|
*/
|
|
--color-success: var(--success);
|
|
--color-warning: var(--warning);
|
|
--color-info: var(--info);
|
|
}
|
|
|
|
/*
|
|
* Dracula Theme
|
|
* Based on https://draculatheme.com/contribute
|
|
* Mapped to shadcn/ui CSS variable system
|
|
*/
|
|
|
|
/* ── Dracula palette (shared) ────────────────────── */
|
|
:root {
|
|
--dracula-bg: #282a36;
|
|
--dracula-current: #44475a;
|
|
--dracula-fg: #f8f8f2;
|
|
--dracula-comment: #9aa3b3;
|
|
--dracula-cyan: #8be9fd;
|
|
--dracula-green: #50fa7b;
|
|
--dracula-orange: #ffb86c;
|
|
--dracula-pink: #ff79c6;
|
|
--dracula-purple: #bd93f9;
|
|
--dracula-red: #ff5555;
|
|
--dracula-yellow: #f1fa8c;
|
|
--dracula-lavender: #d6acff;
|
|
|
|
/*
|
|
* Semantic feedback tokens (see @theme `--color-success` / `--color-warning`
|
|
* / `--color-info` re-exports). Aliased over the Dracula palette so existing
|
|
* dark-mode visuals stay identical; light mode (Alucard) below provides the
|
|
* higher-contrast counterpart so AA contrast lands on the white card.
|
|
*/
|
|
--success: var(--dracula-green);
|
|
--warning: var(--dracula-orange);
|
|
--info: var(--dracula-cyan);
|
|
|
|
--radius: 0.625rem;
|
|
}
|
|
|
|
/* ── Dark mode (default) ─────────────────────────── */
|
|
:root.dark {
|
|
--background: #282a36;
|
|
--foreground: #f8f8f2;
|
|
--card: #1e1f29;
|
|
--card-foreground: #f8f8f2;
|
|
--popover: #1e1f29;
|
|
--popover-foreground: #f8f8f2;
|
|
--primary: #bd93f9;
|
|
--primary-foreground: #282a36;
|
|
--secondary: #44475a;
|
|
--secondary-foreground: #f8f8f2;
|
|
--muted: #44475a;
|
|
--muted-foreground: #9aa3b3;
|
|
--accent: #44475a;
|
|
--accent-foreground: #f8f8f2;
|
|
--destructive: #ff5555;
|
|
--border: #44475a;
|
|
--input: #44475a;
|
|
--ring: #bd93f9;
|
|
--chart-1: #bd93f9;
|
|
--chart-2: #50fa7b;
|
|
--chart-3: #ff79c6;
|
|
--chart-4: #8be9fd;
|
|
--chart-5: #ffb86c;
|
|
--sidebar: #1e1f29;
|
|
--sidebar-foreground: #f8f8f2;
|
|
--sidebar-primary: #bd93f9;
|
|
--sidebar-primary-foreground: #f8f8f2;
|
|
--sidebar-accent: #44475a;
|
|
--sidebar-accent-foreground: #f8f8f2;
|
|
--sidebar-border: #44475a;
|
|
--sidebar-ring: #bd93f9;
|
|
|
|
color-scheme: dark;
|
|
}
|
|
|
|
/* ── Light mode (Alucard — official Dracula light) ── */
|
|
:root.light {
|
|
--background: #f5f5f5;
|
|
--foreground: #1f1f1f;
|
|
--card: #ffffff;
|
|
--card-foreground: #1f1f1f;
|
|
--popover: #ffffff;
|
|
--popover-foreground: #1f1f1f;
|
|
--primary: #644ac9;
|
|
--primary-foreground: #ffffff;
|
|
--secondary: #dcdeef;
|
|
--secondary-foreground: #1f1f1f;
|
|
--muted: #dcdeef;
|
|
--muted-foreground: #5b6273;
|
|
--accent: #dcdeef;
|
|
--accent-foreground: #1f1f1f;
|
|
--destructive: #cb3a2a;
|
|
/*
|
|
* Alucard light-mode overrides for the semantic tokens — straight Dracula
|
|
* green/orange/cyan would fail AA contrast on a white card. These match the
|
|
* darker palette already used for `--destructive`/`--chart-*` in light mode.
|
|
*/
|
|
--success: #14720a;
|
|
--warning: #a34d14;
|
|
--info: #036a96;
|
|
--border: #cfcfde;
|
|
--input: #cfcfde;
|
|
--ring: #644ac9;
|
|
--chart-1: #644ac9;
|
|
--chart-2: #14720a;
|
|
--chart-3: #a3134d;
|
|
--chart-4: #036a96;
|
|
--chart-5: #a34d14;
|
|
--sidebar: #ffffff;
|
|
--sidebar-foreground: #1f1f1f;
|
|
--sidebar-primary: #644ac9;
|
|
--sidebar-primary-foreground: #ffffff;
|
|
--sidebar-accent: #dcdeef;
|
|
--sidebar-accent-foreground: #1f1f1f;
|
|
--sidebar-border: #cfcfde;
|
|
--sidebar-ring: #644ac9;
|
|
|
|
color-scheme: light;
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border outline-ring/50;
|
|
}
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
}
|
|
p {
|
|
color: var(--foreground);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* `.no-scrollbar` — keeps a container scrollable but hides the visible
|
|
* bar. Used by the mobile section strips in `<AdminShell>` and
|
|
* `<SettingsShell>` so 13 admin / 10 settings entries can swipe
|
|
* horizontally without painting an always-on scrollbar at the top of
|
|
* every admin/settings page (a recurring maintainer complaint — most
|
|
* recently mistaken for a `/admin/api-tokens` table scrollbar in
|
|
* v1.4.16/17 because the strip sits right above the api-tokens card).
|
|
*
|
|
* Standard `scrollbar-width: none` (Firefox) + `::-webkit-scrollbar`
|
|
* (Chromium/WebKit) covers every browser HealthLog targets. Touch
|
|
* scrolling, keyboard arrow scrolling, and `Tab` focus traversal all
|
|
* keep working — this is a purely cosmetic suppression, not an
|
|
* `overflow: hidden`.
|
|
*/
|
|
.no-scrollbar {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
.no-scrollbar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* ── Insight card animations ─────────────────────── */
|
|
@keyframes insight-fade-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.animate-insight-in {
|
|
animation: insight-fade-in 0.4s ease-out forwards;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.animate-insight-in {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/* ── v1.4.20 phase B1 — Insights redesign hero strip ─────────────── */
|
|
|
|
/*
|
|
* `.hero-gradient` — purple → pink linear gradient at low opacity, for
|
|
* the new <HeroStrip> band on /insights. Sits above `var(--card)` so
|
|
* the band reads as a richer surface than the card it overlays.
|
|
*
|
|
* Matches the design handoff (`prototype/artboard-fullpage.jsx →
|
|
* BriefingHero` background) — purple/pink at ~12% opacity over the
|
|
* card colour, with a subtle border-tint to anchor it on the dark bg.
|
|
*/
|
|
.hero-gradient {
|
|
background: linear-gradient(
|
|
135deg,
|
|
color-mix(in srgb, var(--dracula-purple) 18%, var(--card)) 0%,
|
|
color-mix(in srgb, var(--dracula-pink) 12%, var(--card)) 100%
|
|
);
|
|
border: 1px solid color-mix(in srgb, var(--dracula-purple) 24%, transparent);
|
|
}
|
|
|
|
/*
|
|
* `.glow-purple` — soft purple aura behind the hero card, painted via
|
|
* `box-shadow` so it stays GPU-cheap and respects the existing card
|
|
* border radius without an extra wrapper element.
|
|
*/
|
|
.glow-purple {
|
|
box-shadow:
|
|
0 0 0 1px color-mix(in srgb, var(--dracula-purple) 16%, transparent),
|
|
0 18px 48px -28px color-mix(in srgb, var(--dracula-purple) 50%, transparent);
|
|
}
|
|
|
|
/*
|
|
* `pulseDot` keyframes — the "live, refreshed N min ago" green dot in
|
|
* the hero meta row. Used as `.pulse-dot { animation: pulseDot ... }`.
|
|
* Reduced-motion users get a static dot via the prefers-reduced-motion
|
|
* guard below.
|
|
*/
|
|
@keyframes pulseDot {
|
|
0%,
|
|
100% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 0.5;
|
|
transform: scale(0.85);
|
|
}
|
|
}
|
|
|
|
.pulse-dot {
|
|
animation: pulseDot 1.8s ease-in-out infinite;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.pulse-dot {
|
|
animation: none;
|
|
}
|
|
}
|