mirror of
https://github.com/temetro/temetro.git
synced 2026-08-28 19:37:33 +00:00
Migrate UI to COSS components + COSS neutral theme; add i18next
Components: - Replace components/ui primitives with COSS equivalents from the @coss/* shadcn registry. Add menu/preview-card/group; remove the superseded dropdown-menu, hover-card, button-group; keep carousel (no COSS equivalent). - Migrate live call sites to canonical COSS APIs preserving layout/behavior: sidebar menus (nav-user, team-switcher, nav-notifications), chat-input radio menu, patient dialogs/cards, auth forms (FieldGroup -> flex column), settings. - ai-elements: migrate the live conversation/message with behavior parity (Tooltip via render, Group/GroupText); repoint dormant files (hover-card -> preview-card, dropdown-menu -> menu, button-group -> group, InputGroupButton -> Button). Residual pre-existing Base UI type drift stays behind ignoreBuildErrors. Theme: - Adopt COSS default neutral tokens in globals.css with light + dark palettes. - Add next-themes (defaultTheme=dark, enableSystem) and drop the forced dark class. Align font variables to the COSS contract (--font-sans/-heading/-mono). Make scrollbars theme-aware. i18n: - Add i18next + react-i18next (lib/i18n/config.ts, locales/en/translation.json, components/i18n-provider.tsx mounted in layout). Convert auth forms, sidebar nav, and settings tabs to useTranslation() as the reference pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+85
-58
@@ -8,8 +8,8 @@
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-heading: var(--font-sans);
|
||||
--font-mono: var(--font-mono);
|
||||
--font-heading: var(--font-heading);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
@@ -46,83 +46,110 @@
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
--color-warning: var(--warning);
|
||||
--color-success-foreground: var(--success-foreground);
|
||||
--color-success: var(--success);
|
||||
--color-info-foreground: var(--info-foreground);
|
||||
--color-info: var(--info);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--animate-skeleton: skeleton 2s -1s infinite linear;
|
||||
@keyframes skeleton {
|
||||
to {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.488 0.243 264.376);
|
||||
--primary-foreground: oklch(0.97 0.014 254.604);
|
||||
--secondary: oklch(0.967 0.001 286.375);
|
||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--card: var(--color-white);
|
||||
--card-foreground: var(--color-neutral-800);
|
||||
--popover: var(--color-white);
|
||||
--popover-foreground: var(--color-neutral-800);
|
||||
--primary: var(--color-neutral-800);
|
||||
--primary-foreground: var(--color-neutral-50);
|
||||
--secondary: --alpha(var(--color-black) / 4%);
|
||||
--secondary-foreground: var(--color-neutral-800);
|
||||
--muted: --alpha(var(--color-black) / 4%);
|
||||
--muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-black));
|
||||
--accent: --alpha(var(--color-black) / 4%);
|
||||
--accent-foreground: var(--color-neutral-800);
|
||||
--destructive: var(--color-red-500);
|
||||
--border: --alpha(var(--color-black) / 8%);
|
||||
--input: --alpha(var(--color-black) / 10%);
|
||||
--ring: var(--color-neutral-400);
|
||||
--chart-1: oklch(0.809 0.105 251.813);
|
||||
--chart-2: oklch(0.623 0.214 259.815);
|
||||
--chart-3: oklch(0.546 0.245 262.881);
|
||||
--chart-4: oklch(0.488 0.243 264.376);
|
||||
--chart-5: oklch(0.424 0.199 265.638);
|
||||
--radius: 0.875rem;
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.546 0.245 262.881);
|
||||
--sidebar-primary-foreground: oklch(0.97 0.014 254.604);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--sidebar: var(--color-neutral-50);
|
||||
--sidebar-foreground: var(--color-neutral-800);
|
||||
--sidebar-primary: var(--color-neutral-800);
|
||||
--sidebar-primary-foreground: var(--color-neutral-50);
|
||||
--sidebar-accent: --alpha(var(--color-black) / 4%);
|
||||
--sidebar-accent-foreground: var(--color-neutral-800);
|
||||
--sidebar-border: --alpha(var(--color-black) / 8%);
|
||||
--sidebar-ring: var(--color-neutral-400);
|
||||
--background: var(--color-white);
|
||||
--foreground: var(--color-neutral-800);
|
||||
--destructive-foreground: var(--color-red-700);
|
||||
--info: var(--color-blue-500);
|
||||
--info-foreground: var(--color-blue-700);
|
||||
--success: var(--color-emerald-500);
|
||||
--success-foreground: var(--color-emerald-700);
|
||||
--warning: var(--color-amber-500);
|
||||
--warning-foreground: var(--color-amber-700);
|
||||
}
|
||||
|
||||
/* Linear-inspired dark palette: near-black canvas, #5e6ad2 indigo accent, hairline borders. */
|
||||
/* COSS neutral dark palette: near-black canvas, neutral accent, hairline borders. */
|
||||
.dark {
|
||||
--background: oklch(0.172 0.004 277);
|
||||
--foreground: oklch(0.98 0.002 277);
|
||||
--card: oklch(0.193 0.005 277);
|
||||
--card-foreground: oklch(0.98 0.002 277);
|
||||
--popover: oklch(0.193 0.005 277);
|
||||
--popover-foreground: oklch(0.98 0.002 277);
|
||||
--primary: oklch(0.556 0.155 277);
|
||||
--primary-foreground: oklch(0.985 0.001 277);
|
||||
--secondary: oklch(0.225 0.006 277);
|
||||
--secondary-foreground: oklch(0.98 0.002 277);
|
||||
--muted: oklch(0.225 0.006 277);
|
||||
--muted-foreground: oklch(0.652 0.012 268);
|
||||
--accent: oklch(0.245 0.008 277);
|
||||
--accent-foreground: oklch(0.98 0.002 277);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 8%);
|
||||
--input: oklch(1 0 0 / 10%);
|
||||
--ring: oklch(0.556 0.155 277);
|
||||
--background: color-mix(in srgb, var(--color-neutral-950) 95%, var(--color-white));
|
||||
--foreground: var(--color-neutral-100);
|
||||
--card: color-mix(in srgb, var(--background) 98%, var(--color-white));
|
||||
--card-foreground: var(--color-neutral-100);
|
||||
--popover: color-mix(in srgb, var(--background) 98%, var(--color-white));
|
||||
--popover-foreground: var(--color-neutral-100);
|
||||
--primary: var(--color-neutral-100);
|
||||
--primary-foreground: var(--color-neutral-800);
|
||||
--secondary: --alpha(var(--color-white) / 4%);
|
||||
--secondary-foreground: var(--color-neutral-100);
|
||||
--muted: --alpha(var(--color-white) / 4%);
|
||||
--muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-white));
|
||||
--accent: --alpha(var(--color-white) / 4%);
|
||||
--accent-foreground: var(--color-neutral-100);
|
||||
--destructive: color-mix(in srgb, var(--color-red-500) 90%, var(--color-white));
|
||||
--border: --alpha(var(--color-white) / 6%);
|
||||
--input: --alpha(var(--color-white) / 8%);
|
||||
--ring: var(--color-neutral-500);
|
||||
--chart-1: oklch(0.809 0.105 251.813);
|
||||
--chart-2: oklch(0.623 0.214 259.815);
|
||||
--chart-3: oklch(0.546 0.245 262.881);
|
||||
--chart-4: oklch(0.488 0.243 264.376);
|
||||
--chart-5: oklch(0.424 0.199 265.638);
|
||||
--sidebar: oklch(0.138 0.004 277);
|
||||
--sidebar-foreground: oklch(0.98 0.002 277);
|
||||
--sidebar-primary: oklch(0.556 0.155 277);
|
||||
--sidebar-primary-foreground: oklch(0.985 0.001 277);
|
||||
--sidebar-accent: oklch(0.245 0.008 277);
|
||||
--sidebar-accent-foreground: oklch(0.98 0.002 277);
|
||||
--sidebar-border: oklch(1 0 0 / 8%);
|
||||
--sidebar-ring: oklch(0.556 0.155 277);
|
||||
--sidebar: var(--color-neutral-950);
|
||||
--sidebar-foreground: var(--color-neutral-100);
|
||||
--sidebar-primary: var(--color-neutral-100);
|
||||
--sidebar-primary-foreground: var(--color-neutral-800);
|
||||
--sidebar-accent: --alpha(var(--color-white) / 4%);
|
||||
--sidebar-accent-foreground: var(--color-neutral-100);
|
||||
--sidebar-border: --alpha(var(--color-white) / 6%);
|
||||
--sidebar-ring: var(--color-neutral-500);
|
||||
--destructive-foreground: var(--color-red-400);
|
||||
--info: var(--color-blue-500);
|
||||
--info-foreground: var(--color-blue-400);
|
||||
--success: var(--color-emerald-500);
|
||||
--success-foreground: var(--color-emerald-400);
|
||||
--warning: var(--color-amber-500);
|
||||
--warning-foreground: var(--color-amber-400);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: oklch(1 0 0 / 18%) transparent;
|
||||
scrollbar-color: color-mix(in srgb, var(--foreground) 20%, transparent) transparent;
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
@@ -132,11 +159,11 @@
|
||||
background: transparent;
|
||||
}
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: oklch(1 0 0 / 18%);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, transparent);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background-color: oklch(1 0 0 / 28%);
|
||||
background-color: color-mix(in srgb, var(--foreground) 32%, transparent);
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
|
||||
Reference in New Issue
Block a user