feat: skin engine + Twenty CRM theme for iistwin
- Add client/src/themes/ with tokens, built-in skins (iistwin, twenty, omegaprom) - Add ThemeProvider with data-skin/data-theme and runtime CSS for custom skins - Add npm run skins:generate script for build-time CSS generation - Add organization_skins table, migration and CRUD API - Add activeSkinId to organizations and expose it in /api/auth/me - Add skin switcher in /profile and admin skin editor in /settings/appearance - Adapt index.css hardcoded colors to skin tokens - Update AGENTS.md and Obsidian notes
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');
|
||||
@import './themes/styles/generated-skins.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/*
|
||||
* Fallback переменные для случая, когда data-skin/data-theme ещё не применены
|
||||
* (например, во время гидратации). Основные значения берутся из generated-skins.css.
|
||||
*/
|
||||
:root {
|
||||
/* Light Theme - Ultra Minimal */
|
||||
--background: hsl(0 0% 100%);
|
||||
--foreground: hsl(220 10% 15%);
|
||||
--card: hsl(0 0% 100%);
|
||||
@@ -26,21 +31,18 @@
|
||||
--border: hsl(220 5% 90%);
|
||||
--input: hsl(0 0% 100%);
|
||||
--ring: hsl(220 10% 15%);
|
||||
|
||||
/* Status colors - muted */
|
||||
|
||||
--status-done: hsl(142 50% 45%);
|
||||
--status-progress: hsl(45 90% 50%);
|
||||
--status-overdue: hsl(0 70% 55%);
|
||||
--status-paused: hsl(220 5% 60%);
|
||||
|
||||
/* Chart colors */
|
||||
|
||||
--chart-1: hsl(220 10% 25%);
|
||||
--chart-2: hsl(142 50% 45%);
|
||||
--chart-3: hsl(45 90% 50%);
|
||||
--chart-4: hsl(200 70% 50%);
|
||||
--chart-5: hsl(0 70% 55%);
|
||||
|
||||
/* Sidebar - clean */
|
||||
|
||||
--sidebar: hsl(0 0% 100%);
|
||||
--sidebar-foreground: hsl(220 10% 15%);
|
||||
--sidebar-primary: hsl(220 10% 15%);
|
||||
@@ -49,15 +51,12 @@
|
||||
--sidebar-accent-foreground: hsl(220 10% 15%);
|
||||
--sidebar-border: hsl(220 5% 92%);
|
||||
--sidebar-ring: hsl(220 10% 15%);
|
||||
|
||||
/* Typography */
|
||||
|
||||
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
--font-mono: "SF Mono", "Monaco", "Inconsolata", monospace;
|
||||
|
||||
/* Minimal radius */
|
||||
--font-mono: "DM Mono", "SF Mono", "Monaco", "Inconsolata", monospace;
|
||||
|
||||
--radius: 0.25rem;
|
||||
|
||||
/* No shadows */
|
||||
|
||||
--shadow-2xs: none;
|
||||
--shadow-xs: none;
|
||||
--shadow-sm: none;
|
||||
@@ -66,19 +65,17 @@
|
||||
--shadow-lg: 0 1px 3px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 2px 4px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-2xl: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
|
||||
|
||||
|
||||
--tracking-normal: -0.01em;
|
||||
--spacing: 0.25rem;
|
||||
|
||||
/* Finance elevation system */
|
||||
--elevate-1: rgba(0,0,0,.03);
|
||||
--elevate-2: rgba(0,0,0,.08);
|
||||
--elevate-1: rgba(0, 0, 0, 0.03);
|
||||
--elevate-2: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--elevate-1: rgba(255,255,255,.03);
|
||||
--elevate-2: rgba(255,255,255,.08);
|
||||
/* Dark Theme - Ultra Minimal */
|
||||
--elevate-1: rgba(255, 255, 255, 0.03);
|
||||
--elevate-2: rgba(255, 255, 255, 0.08);
|
||||
--background: hsl(220 10% 8%);
|
||||
--foreground: hsl(220 5% 92%);
|
||||
--card: hsl(220 10% 10%);
|
||||
@@ -98,21 +95,18 @@
|
||||
--border: hsl(220 10% 18%);
|
||||
--input: hsl(220 10% 12%);
|
||||
--ring: hsl(0 0% 100%);
|
||||
|
||||
/* Status colors - brighter for dark mode */
|
||||
|
||||
--status-done: hsl(142 50% 55%);
|
||||
--status-progress: hsl(45 90% 55%);
|
||||
--status-overdue: hsl(0 70% 60%);
|
||||
--status-paused: hsl(220 5% 55%);
|
||||
|
||||
/* Chart colors - brighter */
|
||||
|
||||
--chart-1: hsl(220 5% 70%);
|
||||
--chart-2: hsl(142 50% 55%);
|
||||
--chart-3: hsl(45 90% 55%);
|
||||
--chart-4: hsl(200 70% 55%);
|
||||
--chart-5: hsl(0 70% 60%);
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
--sidebar: hsl(220 10% 8%);
|
||||
--sidebar-foreground: hsl(220 5% 92%);
|
||||
--sidebar-primary: hsl(0 0% 100%);
|
||||
@@ -121,26 +115,13 @@
|
||||
--sidebar-accent-foreground: hsl(220 5% 92%);
|
||||
--sidebar-border: hsl(220 10% 16%);
|
||||
--sidebar-ring: hsl(0 0% 100%);
|
||||
|
||||
/* Typography */
|
||||
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
--font-mono: "SF Mono", "Monaco", "Inconsolata", monospace;
|
||||
|
||||
/* Minimal radius */
|
||||
|
||||
--radius: 0.25rem;
|
||||
|
||||
/* Subtle shadows for dark mode */
|
||||
--shadow-2xs: none;
|
||||
--shadow-xs: none;
|
||||
--shadow-sm: none;
|
||||
--shadow: none;
|
||||
|
||||
--shadow-md: 0 1px 2px 0 rgba(0, 0, 0, 0.15);
|
||||
--shadow-lg: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
|
||||
--shadow-xl: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
|
||||
--shadow-2xl: 0 8px 10px -2px rgba(0, 0, 0, 0.25);
|
||||
|
||||
--spacing: 0.25rem;
|
||||
--tracking-normal: -0.01em;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
@@ -249,15 +230,18 @@
|
||||
}
|
||||
|
||||
.status-badge-done {
|
||||
@apply bg-green-50 text-green-700 dark:bg-green-900/30 dark:text-green-400;
|
||||
background-color: color-mix(in srgb, var(--status-done) 12%, transparent);
|
||||
color: var(--status-done);
|
||||
}
|
||||
|
||||
|
||||
.status-badge-progress {
|
||||
@apply bg-yellow-50 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400;
|
||||
background-color: color-mix(in srgb, var(--status-progress) 12%, transparent);
|
||||
color: var(--status-progress);
|
||||
}
|
||||
|
||||
|
||||
.status-badge-overdue {
|
||||
@apply bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400;
|
||||
background-color: color-mix(in srgb, var(--status-overdue) 12%, transparent);
|
||||
color: var(--status-overdue);
|
||||
}
|
||||
|
||||
/* Nav item */
|
||||
@@ -392,13 +376,8 @@
|
||||
|
||||
/* jspreadsheet formula cell highlight */
|
||||
td.formula-highlight {
|
||||
background-color: rgba(34, 34, 34, 0.1) !important;
|
||||
border: 1px solid hsl(220 10% 40%) !important;
|
||||
}
|
||||
|
||||
.dark td.formula-highlight {
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
border: 1px solid hsl(220 5% 60%) !important;
|
||||
background-color: var(--tw-background-transparent-secondary) !important;
|
||||
border: 1px solid var(--tw-border-strong) !important;
|
||||
}
|
||||
|
||||
/* Mobile bottom navigation safe area */
|
||||
@@ -423,20 +402,12 @@ td.formula-highlight {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: hsl(220 5% 80%);
|
||||
background: var(--tw-border-strong);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb {
|
||||
background: hsl(220 10% 25%);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(220 5% 70%);
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(220 10% 35%);
|
||||
background: var(--tw-font-extra-light);
|
||||
}
|
||||
|
||||
/* Focus visible — removed per user request */
|
||||
@@ -451,9 +422,5 @@ td.formula-highlight {
|
||||
|
||||
/* Selection */
|
||||
::selection {
|
||||
background-color: hsla(220, 10%, 15%, 0.15);
|
||||
}
|
||||
|
||||
.dark ::selection {
|
||||
background-color: hsla(0, 0%, 100%, 0.15);
|
||||
background-color: var(--tw-background-transparent-secondary);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user