0.29.1原版
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
# Color System Guide
|
||||
|
||||
This document explains the color system used in the Memos application, built with OKLCH color space for better perceptual uniformity and accessibility.
|
||||
|
||||
## Overview
|
||||
|
||||
The color system supports both light and dark themes automatically through CSS custom properties. All colors are defined using OKLCH (Oklab LCH) color space, which provides better perceptual uniformity than traditional RGB/HSL.
|
||||
|
||||
## Color Categories
|
||||
|
||||
### 🎨 Primary Brand Colors
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| ---------------------- | ------------- | --------------- | ------------------------------ |
|
||||
| `--primary` | Golden yellow | Brighter golden | Main brand color, primary CTAs |
|
||||
| `--primary-foreground` | White | White | Text on primary backgrounds |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Call-to-action buttons
|
||||
- Active navigation items
|
||||
- Important links and highlights
|
||||
- Brand elements
|
||||
|
||||
```css
|
||||
/* Example usage */
|
||||
.cta-button {
|
||||
background: var(--primary);
|
||||
color: var(--primary-foreground);
|
||||
}
|
||||
```
|
||||
|
||||
### 🔘 Secondary Colors
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| ------------------------ | ----------- | --------------- | ----------------------------- |
|
||||
| `--secondary` | Light gray | Very light gray | Supporting actions |
|
||||
| `--secondary-foreground` | Dark gray | Dark gray | Text on secondary backgrounds |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Secondary buttons
|
||||
- Less important actions
|
||||
- Alternative navigation items
|
||||
- Subtle highlights
|
||||
|
||||
### 📄 Background & Surface Colors
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| ---------------------- | ----------- | ----------- | --------------------------- |
|
||||
| `--background` | Near white | Dark gray | Main page background |
|
||||
| `--card` | Near white | Dark gray | Card/container backgrounds |
|
||||
| `--card-foreground` | Very dark | Near white | Text on card backgrounds |
|
||||
| `--popover` | Pure white | Darker gray | Overlay backgrounds |
|
||||
| `--popover-foreground` | Dark gray | Light gray | Text on overlay backgrounds |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Page backgrounds (`--background`)
|
||||
- Content cards and panels (`--card`)
|
||||
- Tooltips, dropdowns, modals (`--popover`)
|
||||
|
||||
### ✏️ Text & Content Colors
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| -------------------- | ----------- | ------------ | ------------------------ |
|
||||
| `--foreground` | Dark gray | Light gray | Primary text color |
|
||||
| `--muted` | Light gray | Very dark | Subtle background areas |
|
||||
| `--muted-foreground` | Medium gray | Medium light | Secondary text, captions |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Main body text (`--foreground`)
|
||||
- Helper text, placeholders (`--muted-foreground`)
|
||||
- Disabled text states
|
||||
- Subtle background sections (`--muted`)
|
||||
|
||||
### 🎯 Interactive Elements
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| --------------------- | ------------ | ----------- | ---------------------------- |
|
||||
| `--accent` | Light gray | Very dark | Hover states, selected items |
|
||||
| `--accent-foreground` | Dark gray | Light gray | Text on accent backgrounds |
|
||||
| `--border` | Medium light | Medium dark | Dividers, input borders |
|
||||
| `--input` | Medium light | Medium dark | Form input backgrounds |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Hover states (`--accent`)
|
||||
- Form field borders (`--border`)
|
||||
- Input field backgrounds (`--input`)
|
||||
|
||||
### ⚠️ Feedback Colors
|
||||
|
||||
| Variable | Light Theme | Dark Theme | Usage |
|
||||
| -------------------------- | ----------- | ---------- | ------------------------------- |
|
||||
| `--destructive` | Very dark | Red | Error states, dangerous actions |
|
||||
| `--destructive-foreground` | White | White | Text on destructive backgrounds |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Error messages
|
||||
- Delete buttons
|
||||
- Warning alerts
|
||||
- Validation failures
|
||||
|
||||
### 📊 Data Visualization
|
||||
|
||||
| Variable | Purpose |
|
||||
| ----------- | --------------------------------------- |
|
||||
| `--chart-1` | Primary data series (golden) |
|
||||
| `--chart-2` | Secondary data series (purple) |
|
||||
| `--chart-3` | Tertiary data series (light) |
|
||||
| `--chart-4` | Quaternary data series (purple variant) |
|
||||
| `--chart-5` | Quinary data series (golden variant) |
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Charts and graphs
|
||||
- Data visualization
|
||||
- Progress indicators
|
||||
- Statistical displays
|
||||
|
||||
### 🔧 Sidebar System
|
||||
|
||||
| Variable | Usage |
|
||||
| ------------------------------ | ---------------------------- |
|
||||
| `--sidebar` | Sidebar background |
|
||||
| `--sidebar-foreground` | Sidebar text |
|
||||
| `--sidebar-primary` | Active sidebar items |
|
||||
| `--sidebar-primary-foreground` | Text on active sidebar items |
|
||||
| `--sidebar-accent` | Sidebar hover states |
|
||||
| `--sidebar-accent-foreground` | Text on sidebar hover states |
|
||||
| `--sidebar-border` | Sidebar dividers |
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do's
|
||||
|
||||
1. **Always pair colors correctly:**
|
||||
|
||||
```css
|
||||
/* Correct */
|
||||
background: var(--primary);
|
||||
color: var(--primary-foreground);
|
||||
```
|
||||
|
||||
2. **Use semantic meaning:**
|
||||
- Primary = main actions
|
||||
- Secondary = supporting actions
|
||||
- Destructive = dangerous/delete actions
|
||||
- Muted = less important content
|
||||
|
||||
3. **Respect the design system:**
|
||||
- Use existing color tokens instead of custom colors
|
||||
- Maintain consistency across components
|
||||
|
||||
### ❌ Don'ts
|
||||
|
||||
1. **Don't mix incompatible pairs:**
|
||||
|
||||
```css
|
||||
/* Incorrect - poor contrast */
|
||||
background: var(--primary);
|
||||
color: var(--foreground);
|
||||
```
|
||||
|
||||
2. **Don't use colors outside their intended purpose:**
|
||||
- Don't use destructive colors for positive actions
|
||||
- Don't use primary colors for secondary elements
|
||||
|
||||
3. **Don't hardcode color values:**
|
||||
|
||||
```css
|
||||
/* Bad */
|
||||
color: #333333;
|
||||
|
||||
/* Good */
|
||||
color: var(--foreground);
|
||||
```
|
||||
|
||||
## Theme Switching
|
||||
|
||||
The color system automatically adapts between light and dark themes when the `.dark` class is applied to a parent element (typically `<html>` or `<body>`):
|
||||
|
||||
```javascript
|
||||
// Toggle dark mode
|
||||
document.documentElement.classList.toggle("dark");
|
||||
```
|
||||
|
||||
## Accessibility
|
||||
|
||||
- All color pairs meet WCAG contrast requirements
|
||||
- Color is never the only means of conveying information
|
||||
|
||||
## Implementation Examples
|
||||
|
||||
### Button Variants
|
||||
|
||||
```css
|
||||
/* Primary button */
|
||||
.btn-primary {
|
||||
background: var(--primary);
|
||||
color: var(--primary-foreground);
|
||||
border: 1px solid var(--primary);
|
||||
}
|
||||
|
||||
/* Secondary button */
|
||||
.btn-secondary {
|
||||
background: var(--secondary);
|
||||
color: var(--secondary-foreground);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Destructive button */
|
||||
.btn-destructive {
|
||||
background: var(--destructive);
|
||||
color: var(--destructive-foreground);
|
||||
border: 1px solid var(--destructive);
|
||||
}
|
||||
```
|
||||
|
||||
### Form Elements
|
||||
|
||||
```css
|
||||
/* Input field */
|
||||
.input {
|
||||
background: var(--input);
|
||||
color: var(--foreground);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
```
|
||||
|
||||
### Cards and Containers
|
||||
|
||||
```css
|
||||
/* Content card */
|
||||
.card {
|
||||
background: var(--card);
|
||||
color: var(--card-foreground);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Popover/Modal */
|
||||
.popover {
|
||||
background: var(--popover);
|
||||
color: var(--popover-foreground);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
```
|
||||
|
||||
## Color Testing
|
||||
|
||||
To ensure proper contrast and accessibility:
|
||||
|
||||
1. Test both light and dark themes
|
||||
2. Verify readability at different zoom levels
|
||||
3. Check with colorblind simulation tools
|
||||
4. Validate WCAG contrast ratios
|
||||
|
||||
## Z-Index Hierarchy
|
||||
|
||||
The application uses a structured z-index hierarchy to ensure proper layering of UI components:
|
||||
|
||||
| Component Type | Z-Index | Usage |
|
||||
| ----------------- | -------- | ------------------------------------- |
|
||||
| **Base Content** | `z-0` | Normal page content |
|
||||
| **Overlays** | `z-50` | Dialog/Sheet backgrounds |
|
||||
| **Modal Content** | `z-50` | Dialog/Sheet content |
|
||||
| **Dropdowns** | `z-[60]` | Select, DropdownMenu, Popover content |
|
||||
| **Tooltips** | `z-[70]` | Tooltip content (highest priority) |
|
||||
|
||||
### Rules
|
||||
|
||||
1. **Dialog/Sheet**: Use `z-50` for both overlay and content
|
||||
2. **Interactive Elements**: Use `z-[60]` for dropdowns inside dialogs
|
||||
3. **Tooltips**: Use `z-[70]` to appear above all other elements
|
||||
4. **Always test**: Ensure Select/DropdownMenu works inside Dialog/Sheet
|
||||
|
||||
### Example
|
||||
|
||||
```tsx
|
||||
// ✅ Correct: Select inside Dialog will appear above dialog content
|
||||
<Dialog>
|
||||
<DialogContent>
|
||||
<Select>
|
||||
<SelectContent className="z-[60]">
|
||||
{" "}
|
||||
{/* Higher than dialog */}
|
||||
<SelectItem>Option 1</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
_This color system is designed to provide a consistent, accessible, and beautiful user experience across all themes and components._
|
||||
@@ -0,0 +1,43 @@
|
||||
:root {
|
||||
/* Surfaces - soft graphite layers for comfortable long-form reading */
|
||||
--background: oklch(0.24 0.008 255);
|
||||
--foreground: oklch(0.9 0.006 255);
|
||||
|
||||
--card: oklch(0.275 0.009 255);
|
||||
--card-foreground: oklch(0.9 0.006 255);
|
||||
|
||||
/* Popovers float above cards without becoming high-glare panels */
|
||||
--popover: oklch(0.32 0.01 255);
|
||||
--popover-foreground: oklch(0.92 0.006 255);
|
||||
|
||||
/* Primary - readable blue for selected items, links, and focused controls */
|
||||
--primary: oklch(0.62 0.11 250);
|
||||
--primary-foreground: oklch(0.98 0.004 255);
|
||||
|
||||
/* Secondary - elevated surface for secondary buttons */
|
||||
--secondary: oklch(0.33 0.011 255);
|
||||
--secondary-foreground: oklch(0.88 0.006 255);
|
||||
|
||||
/* Muted - inline backgrounds for code, skeletons, metadata, and panels */
|
||||
--muted: oklch(0.35 0.011 255);
|
||||
--muted-foreground: oklch(0.72 0.007 255);
|
||||
|
||||
/* Accent - hover states with a little more color than muted surfaces */
|
||||
--accent: oklch(0.39 0.018 250);
|
||||
--accent-foreground: oklch(0.94 0.006 255);
|
||||
|
||||
/* Destructive - visible on dark surfaces without overpowering the palette */
|
||||
--destructive: oklch(0.64 0.18 24);
|
||||
--destructive-foreground: oklch(0.98 0.004 255);
|
||||
|
||||
/* Borders - --border for layout dividers, --input for form field borders */
|
||||
--border: oklch(0.38 0.01 255);
|
||||
--input: oklch(0.42 0.011 255);
|
||||
--ring: oklch(0.58 0.095 250);
|
||||
|
||||
/* Sidebar - anchored but no longer near-black */
|
||||
--sidebar: oklch(0.21 0.009 255);
|
||||
--sidebar-foreground: oklch(0.76 0.007 255);
|
||||
--sidebar-accent: oklch(0.31 0.015 250);
|
||||
--sidebar-accent-foreground: oklch(0.9 0.006 255);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
:root {
|
||||
--background: oklch(0.9818 0.0054 95.0986);
|
||||
--foreground: oklch(0.2438 0.0269 95.7226);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.1908 0.002 106.5859);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.2671 0.0196 98.939);
|
||||
--primary: oklch(0.45 0.08 250);
|
||||
--primary-foreground: oklch(0.9818 0.0054 95.0986);
|
||||
--secondary: oklch(0.9245 0.0138 92.9892);
|
||||
--secondary-foreground: oklch(0.4334 0.0177 98.6048);
|
||||
--muted: oklch(0.9341 0.0153 90.239);
|
||||
--muted-foreground: oklch(0.5559 0.0075 97.4233);
|
||||
--accent: oklch(0.9245 0.0138 92.9892);
|
||||
--accent-foreground: oklch(0.2671 0.0196 98.939);
|
||||
--destructive: oklch(0.5 0.12 25);
|
||||
--destructive-foreground: oklch(1 0 0);
|
||||
--border: oklch(0.8847 0.0069 97.3627);
|
||||
--input: oklch(0.7621 0.0156 98.3528);
|
||||
--ring: oklch(0.45 0.08 250);
|
||||
--sidebar: oklch(0.9663 0.008 98.8792);
|
||||
--sidebar-foreground: oklch(0.359 0.0051 106.6524);
|
||||
--sidebar-accent: oklch(0.9245 0.0138 92.9892);
|
||||
--sidebar-accent-foreground: oklch(0.325 0 0);
|
||||
--font-sans:
|
||||
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--radius: 0.5rem;
|
||||
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
|
||||
--shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
|
||||
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
|
||||
--shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
|
||||
--shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
|
||||
--shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
|
||||
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
|
||||
}
|
||||
|
||||
/* Tailwind v4 token mappings — compiled once at build time, shared by all themes.
|
||||
Dynamic theme files only need to override :root variables; this block covers all of them. */
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
|
||||
--font-sans: var(--font-sans);
|
||||
--font-mono: var(--font-mono);
|
||||
--font-serif: var(--font-serif);
|
||||
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
|
||||
--shadow-xs: var(--shadow-xs);
|
||||
--shadow-sm: var(--shadow-sm);
|
||||
--shadow: var(--shadow);
|
||||
--shadow-md: var(--shadow-md);
|
||||
--shadow-lg: var(--shadow-lg);
|
||||
--shadow-xl: var(--shadow-xl);
|
||||
--shadow-2xl: var(--shadow-2xl);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
:root {
|
||||
--background: oklch(0.95 0.015 75);
|
||||
--foreground: oklch(0.25 0.02 65);
|
||||
--card: oklch(0.98 0.008 80);
|
||||
--card-foreground: oklch(0.22 0.015 68);
|
||||
--popover: oklch(0.98 0.008 80);
|
||||
--popover-foreground: oklch(0.25 0.02 65);
|
||||
--primary: oklch(0.45 0.08 45);
|
||||
--primary-foreground: oklch(0.98 0.008 80);
|
||||
--secondary: oklch(0.92 0.025 70);
|
||||
--secondary-foreground: oklch(0.35 0.03 60);
|
||||
--muted: oklch(0.9 0.025 75);
|
||||
--muted-foreground: oklch(0.5 0.02 68);
|
||||
--accent: oklch(0.88 0.035 55);
|
||||
--accent-foreground: oklch(0.25 0.02 65);
|
||||
--destructive: oklch(0.48 0.15 25);
|
||||
--destructive-foreground: oklch(0.98 0.008 80);
|
||||
--border: oklch(0.85 0.025 72);
|
||||
--input: oklch(0.8 0.03 75);
|
||||
--ring: oklch(0.45 0.08 45);
|
||||
--sidebar: oklch(0.9647 0.0118 83.7892);
|
||||
--sidebar-foreground: oklch(0.2941 0.0196 67.6524);
|
||||
--sidebar-accent: oklch(0.9412 0.0196 78.9456);
|
||||
--sidebar-accent-foreground: oklch(0.2647 0.0157 71.2341);
|
||||
--shadow-xs: 0 1px 3px 0px hsl(34 12% 15% / 0.04);
|
||||
--shadow-sm: 0 1px 3px 0px hsl(34 12% 15% / 0.08), 0 1px 2px -1px hsl(34 12% 15% / 0.08);
|
||||
--shadow: 0 1px 3px 0px hsl(34 12% 15% / 0.08), 0 1px 2px -1px hsl(34 12% 15% / 0.08);
|
||||
--shadow-md: 0 1px 3px 0px hsl(34 12% 15% / 0.08), 0 2px 4px -1px hsl(34 12% 15% / 0.08);
|
||||
--shadow-lg: 0 1px 3px 0px hsl(34 12% 15% / 0.08), 0 4px 6px -1px hsl(34 12% 15% / 0.08);
|
||||
--shadow-xl: 0 1px 3px 0px hsl(34 12% 15% / 0.08), 0 8px 10px -1px hsl(34 12% 15% / 0.08);
|
||||
--shadow-2xl: 0 1px 3px 0px hsl(34 12% 15% / 0.18);
|
||||
}
|
||||
Reference in New Issue
Block a user