Some checks failed
Master CI / yarn_install_and_build (push) Has been cancelled
- Complete Unraid WebGUI inventory (~100 pages documented) - Unraid GraphQL API research and documentation - Homarr architecture documentation - Orchis GTK theme design tokens (TypeScript) - Project README with implementation plan Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1330 lines
39 KiB
TypeScript
1330 lines
39 KiB
TypeScript
/**
|
|
* Orchis GTK Theme - Complete Design Token System
|
|
* ================================================
|
|
* Extracted from: https://github.com/vinceliuice/Orchis-theme
|
|
* Based on Google Material Design with custom Orchis adaptations
|
|
*
|
|
* This file provides a complete CSS/design token system for a Next.js
|
|
* web application, faithfully representing the Orchis GTK theme.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// 1. COLOR PALETTES - ALL VARIANTS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* --- MATERIAL DESIGN BASE PALETTE ---
|
|
* Orchis uses the standard Material Design 2014 color palette as its foundation.
|
|
* Each color has shades from 50 (lightest) to 900 (darkest) plus accent variants.
|
|
*/
|
|
export const materialPalette = {
|
|
red: {
|
|
50: "#FFEBEE", 100: "#FFCDD2", 200: "#EF9A9A", 300: "#E57373",
|
|
400: "#EF5350", 500: "#F44336", 600: "#E53935", 700: "#D32F2F",
|
|
800: "#C62828", 900: "#B71C1C",
|
|
a100: "#FF8A80", a200: "#FF5252", a400: "#FF1744", a700: "#D50000",
|
|
},
|
|
pink: {
|
|
50: "#FCE4EC", 100: "#F8BBD0", 200: "#F48FB1", 300: "#F06292",
|
|
400: "#EC407A", 500: "#E91E63", 600: "#D81B60", 700: "#C2185B",
|
|
800: "#AD1457", 900: "#880E4F",
|
|
a100: "#FF80AB", a200: "#FF4081", a400: "#F50057", a700: "#C51162",
|
|
},
|
|
purple: {
|
|
50: "#F3E5F5", 100: "#E1BEE7", 200: "#CE93D8", 300: "#BA68C8",
|
|
400: "#AB47BC", 500: "#9C27B0", 600: "#8E24AA", 700: "#7B1FA2",
|
|
800: "#6A1B9A", 900: "#4A148C",
|
|
a100: "#EA80FC", a200: "#E040FB", a400: "#D500F9", a700: "#AA00FF",
|
|
},
|
|
deepPurple: {
|
|
50: "#EDE7F6", 100: "#D1C4E9", 200: "#B39DDB", 300: "#9575CD",
|
|
400: "#7E57C2", 500: "#673AB7", 600: "#5E35B1", 700: "#512DA8",
|
|
800: "#4527A0", 900: "#311B92",
|
|
a100: "#B388FF", a200: "#7C4DFF", a400: "#651FFF", a700: "#6200EA",
|
|
},
|
|
indigo: {
|
|
50: "#E8EAF6", 100: "#C5CAE9", 200: "#9FA8DA", 300: "#7986CB",
|
|
400: "#5C6BC0", 500: "#3F51B5", 600: "#3949AB", 700: "#303F9F",
|
|
800: "#283593", 900: "#1A237E",
|
|
a100: "#8C9EFF", a200: "#536DFE", a400: "#3D5AFE", a700: "#304FFE",
|
|
},
|
|
blue: {
|
|
50: "#E3F2FD", 100: "#BBDEFB", 200: "#90CAF9", 300: "#64B5F6",
|
|
400: "#42A5F5", 500: "#2196F3", 600: "#1E88E5", 700: "#1976D2",
|
|
800: "#1565C0", 900: "#0D47A1",
|
|
a100: "#82B1FF", a200: "#448AFF", a400: "#2979FF", a700: "#2962FF",
|
|
},
|
|
teal: {
|
|
50: "#E0F2F1", 100: "#B2DFDB", 200: "#80CBC4", 300: "#4DB6AC",
|
|
400: "#26A69A", 500: "#009688", 600: "#00897B", 700: "#00796B",
|
|
800: "#00695C", 900: "#004D40",
|
|
a100: "#A7FFEB", a200: "#64FFDA", a400: "#1DE9B6", a700: "#00BFA5",
|
|
},
|
|
green: {
|
|
50: "#E8F5E9", 100: "#C8E6C9", 200: "#A5D6A7", 300: "#81C784",
|
|
400: "#66BB6A", 500: "#4CAF50", 600: "#43A047", 700: "#388E3C",
|
|
800: "#2E7D32", 900: "#1B5E20",
|
|
a100: "#B9F6CA", a200: "#69F0AE", a400: "#00E676", a700: "#00C853",
|
|
},
|
|
yellow: {
|
|
50: "#FFFDE7", 100: "#FFF9C4", 200: "#FFF59D", 300: "#FFF176",
|
|
400: "#FFEE58", 500: "#FFEB3B", 600: "#FDD835", 700: "#FBC02D",
|
|
800: "#F9A825", 900: "#F57F17",
|
|
a100: "#FFFF8D", a200: "#FFFF00", a400: "#FFEA00", a700: "#FFD600",
|
|
},
|
|
orange: {
|
|
50: "#FFF3E0", 100: "#FFE0B2", 200: "#FFCC80", 300: "#FFB74D",
|
|
400: "#FFA726", 500: "#FF9800", 600: "#FB8C00", 700: "#F57C00",
|
|
800: "#EF6C00", 900: "#E65100",
|
|
a100: "#FFD180", a200: "#FFAB40", a400: "#FF9100", a700: "#FF6D00",
|
|
},
|
|
grey: {
|
|
50: "#FAFAFA", 100: "#F5F5F5", 200: "#EEEEEE", 300: "#E0E0E0",
|
|
400: "#BDBDBD", 500: "#9E9E9E", 600: "#757575", 700: "#616161",
|
|
800: "#424242", 900: "#212121",
|
|
},
|
|
blueGrey: {
|
|
50: "#ECEFF1", 100: "#CFD8DC", 200: "#B0BEC5", 300: "#90A4AE",
|
|
400: "#78909C", 500: "#607D8B", 600: "#546E7A", 700: "#455A64",
|
|
800: "#37474F", 900: "#263238",
|
|
},
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- ORCHIS CUSTOM GREY SCALE ---
|
|
* Orchis defines a more granular grey scale (050 through 950) than
|
|
* standard Material Design. These are used for backgrounds and surfaces.
|
|
*/
|
|
export const orchisGrey = {
|
|
"050": "#FAFAFA",
|
|
"100": "#F2F2F2",
|
|
"150": "#EEEEEE",
|
|
"200": "#DDDDDD",
|
|
"250": "#CCCCCC",
|
|
"300": "#BFBFBF",
|
|
"350": "#A0A0A0",
|
|
"400": "#9E9E9E",
|
|
"450": "#868686",
|
|
"500": "#727272",
|
|
"550": "#555555",
|
|
"600": "#464646",
|
|
"650": "#3C3C3C",
|
|
"700": "#2C2C2C",
|
|
"750": "#242424",
|
|
"800": "#212121",
|
|
"850": "#121212",
|
|
"900": "#0F0F0F",
|
|
"950": "#030303",
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- ACCENT COLOR VARIANTS ---
|
|
* Each accent has a "light" variant (used on dark backgrounds)
|
|
* and a "dark" variant (used on light backgrounds).
|
|
*
|
|
* The DEFAULT theme color is Blue (default).
|
|
*/
|
|
export const accentColors = {
|
|
default: { // Blue
|
|
light: "#3281EA", // used on dark backgrounds
|
|
dark: "#1A73E8", // used on light backgrounds
|
|
},
|
|
purple: {
|
|
light: "#BA68C8",
|
|
dark: "#AB47BC",
|
|
},
|
|
pink: {
|
|
light: "#F06292",
|
|
dark: "#EC407A",
|
|
},
|
|
red: {
|
|
light: "#F44336",
|
|
dark: "#E53935",
|
|
},
|
|
orange: {
|
|
light: "#FB8C00",
|
|
dark: "#F57C00",
|
|
},
|
|
yellow: {
|
|
light: "#FBC02D",
|
|
dark: "#FFD600",
|
|
},
|
|
green: {
|
|
light: "#66BB6A",
|
|
dark: "#4CAF50",
|
|
},
|
|
teal: {
|
|
light: "#4DB6AC",
|
|
dark: "#009688",
|
|
},
|
|
grey: {
|
|
light: "#DDDDDD", // $grey-200 for dark mode
|
|
dark: "#464646", // $grey-600 for light mode
|
|
},
|
|
} as const;
|
|
|
|
/** Success/sea green used for checkmarks and success states */
|
|
export const successColors = {
|
|
light: "#81C995",
|
|
dark: "#0F9D58",
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- THEME TOKENS: LIGHT MODE ---
|
|
* Resolved color values for the light color scheme.
|
|
* Primary defaults to Blue accent ($blue-dark = #1A73E8).
|
|
*/
|
|
export const lightTheme = {
|
|
// Primary accent (default = blue)
|
|
primary: "#1A73E8",
|
|
|
|
// Backgrounds
|
|
background: "#F2F2F2", // grey-100 = background(c)
|
|
surface: "#FFFFFF", // white = background(a) => surface
|
|
base: "#FFFFFF", // white = background(a) => base
|
|
baseAlt: "#FAFAFA", // grey-050 = background(b) => base-alt
|
|
|
|
// Text on background
|
|
text: {
|
|
primary: "rgba(0, 0, 0, 0.87)",
|
|
secondary: "rgba(0, 0, 0, 0.6)",
|
|
disabled: "rgba(0, 0, 0, 0.38)",
|
|
secondaryDisabled: "rgba(0, 0, 0, 0.26)",
|
|
},
|
|
|
|
// Text on primary (white text on blue bg)
|
|
onPrimary: {
|
|
primary: "#FFFFFF",
|
|
secondary: "rgba(255, 255, 255, 0.7)",
|
|
disabled: "rgba(255, 255, 255, 0.5)",
|
|
},
|
|
|
|
// Semantic colors
|
|
warning: "#FFD600", // $yellow-dark
|
|
error: "#E53935", // $red-dark
|
|
success: "#0F9D58", // $sea-dark
|
|
link: "#1A73E8", // same as primary
|
|
linkVisited: "#AB47BC", // $purple-dark
|
|
|
|
// Borders and dividers
|
|
border: "rgba(0, 0, 0, 0.12)",
|
|
solidBorder: "#E2E2E2", // darken($background, 8%)
|
|
divider: "rgba(0, 0, 0, 0.12)",
|
|
frame: "rgba(0, 0, 0, 0.1)",
|
|
|
|
// Overlay states (used on currentColor)
|
|
overlay: {
|
|
normal: "rgba(0, 0, 0, 0.05)", // 5% opacity
|
|
hover: "rgba(0, 0, 0, 0.08)", // 8% opacity
|
|
focus: "rgba(0, 0, 0, 0.08)", // 8% opacity
|
|
focusHover: "rgba(0, 0, 0, 0.16)", // 16% opacity
|
|
active: "rgba(0, 0, 0, 0.12)", // 12% opacity
|
|
checked: "rgba(0, 0, 0, 0.10)", // 10% opacity
|
|
selected: "rgba(0, 0, 0, 0.06)", // 6% opacity
|
|
},
|
|
|
|
// Track (for sliders, switches)
|
|
track: "rgba(0, 0, 0, 0.26)",
|
|
trackDisabled: "rgba(0, 0, 0, 0.15)",
|
|
|
|
// Fill (subtle backgrounds)
|
|
fill: "rgba(0, 0, 0, 0.04)",
|
|
secondaryFill: "rgba(0, 0, 0, 0.08)",
|
|
|
|
// Tooltip
|
|
tooltip: "rgba(0, 0, 0, 0.9)", // dark tooltip on light
|
|
|
|
// Panel/titlebar
|
|
titlebar: "#FFFFFF", // background(a) when topbar=light
|
|
titlebarBackdrop: "#FAFAFA",
|
|
|
|
// Window buttons (macOS style)
|
|
buttonClose: "#fd5f51",
|
|
buttonMaximize: "#38c76a",
|
|
buttonMinimize: "#fdbe04",
|
|
|
|
// Popover/menu
|
|
popover: "#FFFFFF",
|
|
|
|
// Sidebar
|
|
sidebar: "#FAFAFA", // $base-alt
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- THEME TOKENS: DARK MODE ---
|
|
* Resolved color values for the dark color scheme.
|
|
* Primary defaults to Blue accent ($blue-light = #3281EA).
|
|
*/
|
|
export const darkTheme = {
|
|
// Primary accent (default = blue)
|
|
primary: "#3281EA",
|
|
|
|
// Backgrounds
|
|
background: "#212121", // grey-800 = background(e)
|
|
surface: "#3C3C3C", // grey-650 = background(h) => surface
|
|
base: "#2C2C2C", // grey-700 = background(g) => base
|
|
baseAlt: "#242424", // grey-750 = background(f) => base-alt
|
|
|
|
// Text on dark background
|
|
text: {
|
|
primary: "#FFFFFF",
|
|
secondary: "rgba(255, 255, 255, 0.7)",
|
|
disabled: "rgba(255, 255, 255, 0.5)",
|
|
secondaryDisabled: "rgba(255, 255, 255, 0.3)",
|
|
},
|
|
|
|
// Text on primary (white text on blue bg)
|
|
onPrimary: {
|
|
primary: "#FFFFFF",
|
|
secondary: "rgba(255, 255, 255, 0.7)",
|
|
disabled: "rgba(255, 255, 255, 0.5)",
|
|
},
|
|
|
|
// Semantic colors
|
|
warning: "#FBC02D", // $yellow-light
|
|
error: "#F44336", // $red-light
|
|
success: "#81C995", // $sea-light
|
|
link: "#3281EA", // same as primary
|
|
linkVisited: "#BA68C8", // $purple-light
|
|
|
|
// Borders and dividers
|
|
border: "rgba(255, 255, 255, 0.12)",
|
|
solidBorder: "#3D3D3D", // lighten($background, 12%)
|
|
divider: "rgba(255, 255, 255, 0.12)",
|
|
frame: "rgba(0, 0, 0, 0.25)",
|
|
|
|
// Overlay states
|
|
overlay: {
|
|
normal: "rgba(255, 255, 255, 0.05)",
|
|
hover: "rgba(255, 255, 255, 0.08)",
|
|
focus: "rgba(255, 255, 255, 0.08)",
|
|
focusHover: "rgba(255, 255, 255, 0.16)",
|
|
active: "rgba(255, 255, 255, 0.12)",
|
|
checked: "rgba(255, 255, 255, 0.10)",
|
|
selected: "rgba(255, 255, 255, 0.06)",
|
|
},
|
|
|
|
// Track
|
|
track: "rgba(255, 255, 255, 0.3)",
|
|
trackDisabled: "rgba(255, 255, 255, 0.15)",
|
|
|
|
// Fill
|
|
fill: "rgba(255, 255, 255, 0.04)",
|
|
secondaryFill: "rgba(255, 255, 255, 0.08)",
|
|
|
|
// Tooltip
|
|
tooltip: "rgba(0, 0, 0, 0.9)",
|
|
|
|
// Panel/titlebar (dark topbar)
|
|
titlebar: "#2C2C2C", // background(g)
|
|
titlebarBackdrop: "#3C3C3C",
|
|
|
|
// Window buttons
|
|
buttonClose: "#fd5f51",
|
|
buttonMaximize: "#38c76a",
|
|
buttonMinimize: "#fdbe04",
|
|
|
|
// Popover/menu
|
|
popover: "#212121", // background(e)
|
|
|
|
// Sidebar
|
|
sidebar: "#242424", // $base-alt
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- BLACK VARIANT (tweaks: --black) ---
|
|
* Full black backgrounds for OLED-friendly dark mode.
|
|
*/
|
|
export const blackVariant = {
|
|
background: "#000000", // $black
|
|
surface: "#121212", // grey-850
|
|
base: "#0F0F0F", // grey-900
|
|
baseAlt: "#030303", // grey-950
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- NORD COLOR SCHEME VARIANT ---
|
|
* Activated with: --tweaks nord
|
|
*/
|
|
export const nordPalette = {
|
|
nord0: "#2e3440", nord1: "#3b4252", nord2: "#434c5e", nord3: "#4c566a",
|
|
nord4: "#d8dee9", nord5: "#e5e9f0", nord6: "#eceff4",
|
|
nord7: "#8fbcbb", nord8: "#88c0d0", nord9: "#81a1c1", nord10: "#5e81ac",
|
|
nord11: "#bf616a", nord12: "#d08770", nord13: "#ebcb8b", nord14: "#a3be8c",
|
|
nord15: "#b48ead",
|
|
} as const;
|
|
|
|
export const nordAccents = {
|
|
default: { light: "#89a3c2", dark: "#5e81ac" },
|
|
purple: { light: "#c89dbf", dark: "#b57daa" },
|
|
pink: { light: "#dc98b1", dark: "#cd7092" },
|
|
red: { light: "#d4878f", dark: "#c35b65" },
|
|
orange: { light: "#dca493", dark: "#d08770" },
|
|
yellow: { light: "#eac985", dark: "#e4b558" },
|
|
green: { light: "#a0c082", dark: "#82ac5d" },
|
|
teal: { light: "#83b9b8", dark: "#63a6a5" },
|
|
grey: { light: "#d9dce3", dark: "#3a4150" },
|
|
} as const;
|
|
|
|
export const nordGrey = {
|
|
"050": "#f8fafc", "100": "#f0f1f4", "150": "#eaecf0", "200": "#d9dce3",
|
|
"250": "#c4c9d4", "300": "#b5bcc9", "350": "#929cb0", "400": "#8e99ae",
|
|
"450": "#74819a", "500": "#616d85", "550": "#464f62", "600": "#3a4150",
|
|
"650": "#333a47", "700": "#242932", "750": "#1e222a", "800": "#1c1f26",
|
|
"850": "#0f1115", "900": "#0d0e11", "950": "#020203",
|
|
} as const;
|
|
|
|
|
|
/**
|
|
* --- DRACULA COLOR SCHEME VARIANT ---
|
|
* Activated with: --tweaks dracula
|
|
*/
|
|
export const draculaAccents = {
|
|
default: { light: "#6272a4", dark: "#5d70ac" },
|
|
purple: { light: "#bd93f9", dark: "#a679ec" },
|
|
pink: { light: "#ff79c6", dark: "#f04cab" },
|
|
red: { light: "#ff5555", dark: "#f44d4d" },
|
|
orange: { light: "#ffb86c", dark: "#f8a854" },
|
|
yellow: { light: "#f1fa8c", dark: "#e8f467" },
|
|
green: { light: "#50fa7b", dark: "#4be772" },
|
|
teal: { light: "#50fae9", dark: "#20eed9" },
|
|
grey: { light: "#d9dae3", dark: "#3c3f51" },
|
|
} as const;
|
|
|
|
export const draculaGrey = {
|
|
"050": "#f9f9fb", "100": "#f0f1f4", "150": "#ebecf1", "200": "#d9dae3",
|
|
"250": "#c4c7d4", "300": "#b5b8c9", "350": "#9397af", "400": "#8f94ad",
|
|
"450": "#757a99", "500": "#626784", "550": "#474b61", "600": "#3c3f51",
|
|
"650": "#343746", "700": "#242632", "750": "#1f2029", "800": "#1c1e26",
|
|
"850": "#0f1015", "900": "#0d0d11", "950": "#020203",
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 2. TYPOGRAPHY
|
|
// ============================================================================
|
|
|
|
export const typography = {
|
|
/** Primary font stack - Orchis prefers M+ 1c and Roboto */
|
|
fontFamily: '"M+ 1c", Roboto, Cantarell, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
|
|
/** For large headings, Roboto is preferred first */
|
|
largeFontFamily: 'Roboto, "M+ 1c", Cantarell, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
|
|
/** Root font size */
|
|
rootFontSize: "14px",
|
|
rootFontSizeCompact: "13px",
|
|
|
|
/** Subheading font size */
|
|
subheadingSize: "16px",
|
|
subheadingSizeCompact: "15px",
|
|
|
|
/**
|
|
* Typography scale (from GTK4 type classes)
|
|
* Maps to CSS utility classes
|
|
*/
|
|
scale: {
|
|
largeTitle: { weight: 300, size: "24pt" }, // .large-title
|
|
title1: { weight: 800, size: "20pt" }, // .title-1
|
|
title2: { weight: 800, size: "15pt" }, // .title-2
|
|
title3: { weight: 700, size: "15pt" }, // .title-3
|
|
title4: { weight: 700, size: "13pt" }, // .title-4
|
|
heading: { weight: 700, size: "11pt" }, // .heading
|
|
body: { weight: 400, size: "11pt" }, // .body
|
|
caption: { weight: 400, size: "9pt" }, // .caption
|
|
captionHeading: { weight: 700, size: "9pt" }, // .caption-heading
|
|
},
|
|
|
|
/** Button text weight */
|
|
buttonWeight: 500,
|
|
|
|
/** Tab text weight */
|
|
tabWeight: 500,
|
|
|
|
/** Sidebar selected item weight */
|
|
sidebarSelectedWeight: 500,
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 3. BORDER RADIUS / SHAPE LANGUAGE
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Orchis uses a **rounded** design language by default.
|
|
* $default_corner = 12px (configurable via --round flag from 2px to 15px).
|
|
*
|
|
* All other radii are derived from this base value.
|
|
*/
|
|
export const borderRadius = {
|
|
/** Default corner radius (12px) */
|
|
default: 12,
|
|
|
|
/** Window radius: $default_corner + $space-size = 12 + 6 = 18px */
|
|
window: 18,
|
|
|
|
/** Standard corner radius (for buttons, entries, etc.): same as default = 12px
|
|
* In compact mode: max(0, $default_corner - 2px) = 10px */
|
|
corner: 12,
|
|
cornerCompact: 10,
|
|
|
|
/** Material radius: $default_corner / 2 + 4 = 10px */
|
|
material: 10,
|
|
|
|
/** Menu/popover radius: $default_corner / 4 + $space-size + 2 = 3 + 6 + 2 = 11px */
|
|
menu: 11,
|
|
|
|
/** Popup radius: $default_corner + $space-size * 2 - 4 = 12 + 12 - 4 = 20px */
|
|
popup: 20,
|
|
|
|
/** Menu item radius: $default_corner / 4 + 2 = 5px */
|
|
menuItem: 5,
|
|
|
|
/** Card/boxed list radius: $corner-radius - 1px = 11px */
|
|
card: 11,
|
|
|
|
/** Circular/pill radius (for pills, circular buttons) */
|
|
circular: 9999,
|
|
|
|
/** Tooltip radius: $corner-radius / 2 = 6px */
|
|
tooltip: 6,
|
|
|
|
/** Toolbar button radius: $corner-radius / 2 = 6px */
|
|
toolbarButton: 6,
|
|
|
|
/** Panel corner radius (gnome-shell): 0 */
|
|
panel: 0,
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 4. SPACING SYSTEM
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Orchis uses a base spacing unit of 6px (4px in compact mode).
|
|
* Margin is 4px (2px in compact).
|
|
* Sizes scale consistently based on these units.
|
|
*/
|
|
export const spacing = {
|
|
/** Base spacing unit: 6px */
|
|
space: 6,
|
|
spaceCompact: 4,
|
|
|
|
/** Base margin: 4px */
|
|
margin: 4,
|
|
marginCompact: 2,
|
|
|
|
/** Component sizes */
|
|
small: 24, // 24px (compact: 22px) - small buttons, icons
|
|
smallCompact: 22,
|
|
medium: 36, // 36px (compact: 32px) - buttons, entries, tabs
|
|
mediumCompact: 32,
|
|
large: 48, // 48px (compact: 40px) - large buttons, headers
|
|
largeCompact: 40,
|
|
|
|
/** Menu item height: 28px (compact: 24px) */
|
|
menuItem: 28,
|
|
menuItemCompact: 24,
|
|
|
|
/** Bar size (progress bars, level bars): 6px */
|
|
bar: 6,
|
|
|
|
/** Icon sizes */
|
|
iconBase: 16,
|
|
iconMedium: 24, // 16 * 1.5
|
|
iconLarge: 32, // 16 * 2
|
|
|
|
/** Derived spacing values frequently used */
|
|
xs: 2, // half margin
|
|
sm: 4, // margin
|
|
md: 6, // space
|
|
lg: 12, // space * 2
|
|
xl: 18, // space * 3
|
|
xxl: 24, // space * 4
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 5. COMPONENT STYLING PATTERNS
|
|
// ============================================================================
|
|
|
|
// --- 5.1 BUTTONS ---
|
|
|
|
export const button = {
|
|
/** Standard button */
|
|
standard: {
|
|
minHeight: 24,
|
|
minWidth: 24,
|
|
// padding: (medium-size - 24) / 2 = (36-24)/2 = 6px
|
|
padding: "6px",
|
|
borderRadius: 12, // $corner-radius
|
|
fontWeight: 500,
|
|
transition: "all 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
},
|
|
|
|
/** States for standard button (light mode) */
|
|
states: {
|
|
normal: {
|
|
background: "rgba(0, 0, 0, 0.05)", // currentColor at 5%
|
|
color: "rgba(0, 0, 0, 0.87)", // $text primary
|
|
boxShadow: "inset 0 0 0 2px transparent",
|
|
},
|
|
hover: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
},
|
|
focus: {
|
|
boxShadow: "inset 0 0 0 2px rgba(0, 0, 0, 0.08)",
|
|
},
|
|
active: {
|
|
// Ripple animation plays
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
},
|
|
disabled: {
|
|
background: "rgba(0, 0, 0, 0.05)",
|
|
color: "rgba(0, 0, 0, 0.38)",
|
|
},
|
|
checked: {
|
|
// PRIMARY colored button
|
|
background: "#1A73E8", // $primary
|
|
color: "#FFFFFF", // $primary-text
|
|
},
|
|
},
|
|
|
|
/** Flat/text button */
|
|
flat: {
|
|
normal: {
|
|
background: "transparent",
|
|
color: "rgba(0, 0, 0, 0.6)", // $text-secondary
|
|
},
|
|
hover: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
active: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
disabled: {
|
|
background: "transparent",
|
|
color: "rgba(0, 0, 0, 0.26)",
|
|
},
|
|
checked: {
|
|
background: "rgba(0, 0, 0, 0.10)",
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
},
|
|
|
|
/** Suggested action (primary CTA) - uses primary color */
|
|
suggested: {
|
|
background: "#1A73E8",
|
|
color: "#FFFFFF",
|
|
},
|
|
|
|
/** Destructive action */
|
|
destructive: {
|
|
background: "#E53935",
|
|
color: "#FFFFFF",
|
|
},
|
|
|
|
/** Pill button (for dialog actions) */
|
|
pill: {
|
|
borderRadius: 9999,
|
|
padding: "6px 32px",
|
|
},
|
|
|
|
/** Circular button */
|
|
circular: {
|
|
borderRadius: 9999,
|
|
minWidth: 24,
|
|
minHeight: 24,
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.2 CARDS / PANELS ---
|
|
|
|
export const card = {
|
|
borderRadius: 12, // $corner-radius (same as default)
|
|
border: "1px solid", // $divider color
|
|
// light: "rgba(0,0,0,0.12)", dark: "rgba(255,255,255,0.12)"
|
|
boxShadow: "none",
|
|
backgroundClip: "padding-box",
|
|
// light bg: $base = #FFFFFF, dark bg: $base = #2C2C2C
|
|
// color: $text-secondary
|
|
|
|
/** Boxed list (grouped card rows) */
|
|
boxedList: {
|
|
borderRadius: 11, // $corner-radius - 1px
|
|
rowBorderBottom: "1px solid", // $divider
|
|
transition: "200ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.3 NAVIGATION / SIDEBAR ---
|
|
|
|
export const sidebar = {
|
|
// background: $base-alt (light: #FAFAFA, dark: #242424)
|
|
borderRight: "1px solid", // $divider
|
|
padding: "6px 0", // $space-size vertical only
|
|
|
|
row: {
|
|
minHeight: 36, // $medium-size
|
|
padding: "0 9px", // 0 $space-size * 1.5
|
|
// Navigation sidebar rows have special pill-shaped right side
|
|
borderRadius: "0 9999px 9999px 0", // 0 $circular 0 $circular
|
|
margin: "0 6px 0 0",
|
|
|
|
selected: {
|
|
// background: overlay-checked = 10% currentColor
|
|
color: "#1A73E8", // $primary
|
|
},
|
|
},
|
|
|
|
stackSidebar: {
|
|
rowPadding: "6px 9px",
|
|
rowRadius: 6, // $corner-radius / 2
|
|
rowSelectedWeight: 500,
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.4 HEADERBAR / NAVIGATION BAR ---
|
|
|
|
export const headerbar = {
|
|
// Light mode: background = #FFFFFF, dark mode: background = #2C2C2C
|
|
// Topbar can be independently dark even in light mode
|
|
minHeight: 48, // $large-size
|
|
padding: "0 6px",
|
|
borderSpacing: 6,
|
|
|
|
/** Compact headerbar */
|
|
compact: {
|
|
minHeight: 40,
|
|
padding: "0 4px",
|
|
borderSpacing: 4,
|
|
},
|
|
|
|
buttonStyle: {
|
|
// headerbar buttons are flat by default
|
|
color: "inherit", // uses titlebar text colors
|
|
fontWeight: 500,
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.5 INPUT FIELDS ---
|
|
|
|
export const input = {
|
|
minHeight: 36, // $medium-size
|
|
padding: "0 8px", // 0 ($space-size + 2px)
|
|
borderRadius: 12, // $corner-radius
|
|
borderSpacing: 6,
|
|
|
|
states: {
|
|
normal: {
|
|
background: "rgba(0, 0, 0, 0.05)", // currentColor 5%
|
|
outline: "0 solid transparent",
|
|
outlineOffset: "4px",
|
|
},
|
|
hover: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
outline: "2px solid rgba(0, 0, 0, 0.08)",
|
|
outlineOffset: "-2px",
|
|
},
|
|
focus: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
outline: "2px solid rgba(0, 0, 0, 0.26)", // $track color
|
|
outlineOffset: "-2px",
|
|
},
|
|
checked: {
|
|
// When actively typing (focus + content)
|
|
outline: "2px solid #1A73E8", // $primary
|
|
outlineOffset: "-2px",
|
|
},
|
|
disabled: {
|
|
background: "rgba(0, 0, 0, 0.05)",
|
|
color: "rgba(0, 0, 0, 0.38)",
|
|
},
|
|
error: {
|
|
outline: "2px solid #E53935", // $error
|
|
},
|
|
warning: {
|
|
outline: "2px solid #FFD600", // $warning
|
|
},
|
|
success: {
|
|
outline: "2px solid #0F9D58", // $success
|
|
},
|
|
},
|
|
|
|
/** Flat entry (no background) */
|
|
flat: {
|
|
minHeight: "auto",
|
|
padding: "2px",
|
|
borderRadius: 0,
|
|
background: "transparent",
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.6 DROPDOWNS / COMBOBOX ---
|
|
// Orchis treats dropdowns as button + popover combinations
|
|
|
|
export const dropdown = {
|
|
// Inherits button styling for the trigger
|
|
trigger: {
|
|
minHeight: 24,
|
|
borderRadius: 12,
|
|
fontWeight: 500,
|
|
},
|
|
// Menu uses popover styling
|
|
menu: {
|
|
borderRadius: 11, // $menu-radius
|
|
boxShadow: "0 3px 3px -1px rgba(0,0,0,0.2), 0 6px 6px 0 rgba(0,0,0,0.14), 0 1px 11px 0 rgba(0,0,0,0.12)", // $shadow-z6
|
|
padding: 6,
|
|
},
|
|
menuItem: {
|
|
minHeight: 22, // $menuitem-size - $space-size
|
|
minWidth: 56, // $menuitem-size * 2
|
|
padding: "3px 9px", // $space-size/2 $space-size*1.5
|
|
borderRadius: 5, // $menuitem-radius
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.7 TOGGLES / SWITCHES ---
|
|
|
|
export const toggle = {
|
|
// GTK switch is a sliding toggle
|
|
margin: "6px 0",
|
|
padding: "0 2px",
|
|
border: "5px solid transparent",
|
|
borderRadius: 9999, // $circular-radius
|
|
transition: "all 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
|
|
// Track
|
|
track: {
|
|
unchecked: "rgba(0, 0, 0, 0.26)", // $track (light mode)
|
|
checked: "rgba(26, 115, 232, 0.5)", // color-mix($primary 50%)
|
|
disabled: { opacity: 0.5 },
|
|
},
|
|
|
|
// Slider/thumb
|
|
slider: {
|
|
width: 20,
|
|
height: 20,
|
|
margin: "-3px -2px",
|
|
borderRadius: 9999,
|
|
backgroundColor: "#FFFFFF", // $surface (light)
|
|
boxShadow: "0 2px 2px -2px rgba(0,0,0,0.3), 0 1px 2px -1px rgba(0,0,0,0.24), 0 1px 2px -1px rgba(0,0,0,0.17)", // $shadow-z1
|
|
},
|
|
|
|
// Checked slider
|
|
sliderChecked: {
|
|
backgroundColor: "#1A73E8", // $primary
|
|
},
|
|
|
|
// Hover ring
|
|
hoverRing: "0 0 0 10px rgba(0, 0, 0, 0.08)",
|
|
focusRing: "0 0 0 10px rgba(0, 0, 0, 0.08)",
|
|
} as const;
|
|
|
|
|
|
// --- 5.8 TABLES / TREE VIEWS ---
|
|
|
|
export const table = {
|
|
background: "#FFFFFF", // $base
|
|
headerBackground: "#FFFFFF", // $base
|
|
headerColor: "rgba(0, 0, 0, 0.6)", // $text-secondary
|
|
headerPadding: "2px 6px",
|
|
headerBorder: "1px solid rgba(0, 0, 0, 0.12)", // $divider
|
|
headerFontWeight: "normal",
|
|
|
|
row: {
|
|
padding: "2px",
|
|
color: "rgba(0, 0, 0, 0.6)",
|
|
borderBottom: "1px solid rgba(0, 0, 0, 0.12)",
|
|
},
|
|
|
|
/** Row hover (activatable rows) */
|
|
rowHover: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
|
|
/** Row active (with ripple animation) */
|
|
rowActive: {
|
|
background: "rgba(0, 0, 0, 0.08)",
|
|
},
|
|
|
|
/** Row selected */
|
|
rowSelected: {
|
|
background: "rgba(0, 0, 0, 0.06)", // $overlay-selected
|
|
},
|
|
|
|
/** Progress bar in treeview */
|
|
progressBar: "6px solid #1A73E8", // $bar-size solid $primary
|
|
progressTrough: "6px solid rgba(0, 0, 0, 0.15)",
|
|
} as const;
|
|
|
|
|
|
// --- 5.9 TABS / NOTEBOOK ---
|
|
|
|
export const tabs = {
|
|
tab: {
|
|
minHeight: 24, // $small-size
|
|
minWidth: 24,
|
|
padding: "6px 12px", // $space-size $space-size*2
|
|
fontWeight: 500,
|
|
transition: "all 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
},
|
|
|
|
states: {
|
|
normal: {
|
|
borderColor: "transparent",
|
|
background: "transparent",
|
|
color: "rgba(0, 0, 0, 0.6)", // $text-secondary
|
|
},
|
|
hover: {
|
|
background: "#E2E2E2", // $solid-border (light)
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
disabled: {
|
|
color: "rgba(0, 0, 0, 0.26)",
|
|
},
|
|
checked: {
|
|
background: "#FFFFFF", // $base
|
|
borderColor: "#E2E2E2", // $solid-border
|
|
color: "rgba(0, 0, 0, 0.87)",
|
|
},
|
|
},
|
|
|
|
/** Notebook container */
|
|
notebook: {
|
|
background: "#FFFFFF", // $base
|
|
frameRadius: 12, // $corner-radius
|
|
},
|
|
|
|
/** Stack switcher (segmented control style) */
|
|
stackSwitcher: {
|
|
borderRadius: 9999, // $circular-radius
|
|
background: "rgba(0, 0, 0, 0.05)", // $overlay-normal
|
|
buttonRadius: 9999,
|
|
// Checked: background = $primary, color = white
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.10 DIALOGS / MODALS ---
|
|
|
|
export const dialog = {
|
|
background: "#3C3C3C", // $surface (or $surface in current mode)
|
|
borderRadius: 18, // $window-radius
|
|
boxShadow: "0 8px 6px -5px rgba(0,0,0,0.2), 0 16px 16px 2px rgba(0,0,0,0.14), 0 6px 18px 5px rgba(0,0,0,0.12)", // $shadow-z16
|
|
borderSpacing: 10,
|
|
|
|
/** Message dialog specific */
|
|
messageDialog: {
|
|
actionPadding: 6,
|
|
actionButtonRadius: 9999, // $circular-radius (pill shaped)
|
|
actionButtonStyle: "flat", // flat buttons in dialogs
|
|
// Non-disabled buttons colored with $primary
|
|
// Destructive buttons colored with $destructive
|
|
},
|
|
|
|
/** About dialog */
|
|
aboutDialog: {
|
|
iconSize: 128,
|
|
scrolledWindowRadius: 12, // $window-radius - $space-size
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.11 PROGRESS BARS ---
|
|
|
|
export const progressBar = {
|
|
/** Bar height: $bar-size = 6px */
|
|
height: 6,
|
|
borderRadius: 12, // $corner-radius
|
|
|
|
/** Trough (background track) */
|
|
trough: {
|
|
background: "rgba(0, 0, 0, 0.15)", // $track-disabled (light)
|
|
},
|
|
|
|
/** Progress (filled portion) */
|
|
progress: {
|
|
background: "#1A73E8", // $primary
|
|
},
|
|
|
|
/** Level bar */
|
|
levelBar: {
|
|
low: "#FFD600", // $warning
|
|
high: "#1A73E8", // $primary
|
|
full: "#0F9D58", // $success
|
|
empty: "rgba(0, 0, 0, 0.15)",
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.12 TOOLTIPS ---
|
|
|
|
export const tooltipStyle = {
|
|
// Light mode: dark tooltip (darken(background(h), 3%) at 0.9 opacity)
|
|
// Dark mode: dark tooltip
|
|
background: "rgba(0, 0, 0, 0.9)", // $tooltip (light mode default)
|
|
color: "#FFFFFF",
|
|
borderRadius: 6, // $corner-radius / 2
|
|
padding: "6px 12px", // $space-size $space-size*2
|
|
boxShadow: "0 2px 2px -1px rgba(0,0,0,0.2), 0 4px 4px 0 rgba(0,0,0,0.14), 0 1px 6px 0 rgba(0,0,0,0.12)", // $shadow-z4
|
|
margin: "2px 6px 8px 6px",
|
|
} as const;
|
|
|
|
|
|
// --- 5.13 SCROLLBARS ---
|
|
|
|
export const scrollbar = {
|
|
background: "#FFFFFF", // $base
|
|
borderWidth: 1,
|
|
borderColor: "rgba(0, 0, 0, 0.12)",
|
|
|
|
slider: {
|
|
minWidth: 8,
|
|
minHeight: 8,
|
|
border: "4px solid transparent",
|
|
borderRadius: 9999,
|
|
backgroundClip: "padding-box",
|
|
|
|
normal: "rgba(0, 0, 0, 0.26)", // $text-secondary-disabled
|
|
hover: "rgba(0, 0, 0, 0.38)", // $text-disabled
|
|
active: "rgba(0, 0, 0, 0.6)", // $text-secondary
|
|
disabled: "rgba(0, 0, 0, 0.26)",
|
|
},
|
|
|
|
/** Overlay scrollbar (thin) */
|
|
overlay: {
|
|
sliderWidth: 4,
|
|
sliderHeight: 4,
|
|
margin: 3,
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.14 POPOVERS / MENUS ---
|
|
|
|
export const popover = {
|
|
borderRadius: 11, // $menu-radius
|
|
boxShadow: "0 3px 3px -1px rgba(0,0,0,0.2), 0 6px 6px 0 rgba(0,0,0,0.14), 0 1px 11px 0 rgba(0,0,0,0.12)", // $shadow-z6
|
|
padding: 6, // $space-size
|
|
border: "none",
|
|
// Light: background = $surface = #FFFFFF
|
|
// Dark: background = $surface = #3C3C3C
|
|
|
|
/** Menu item styling */
|
|
menuItem: {
|
|
minHeight: 22, // $menuitem-size - $space-size
|
|
minWidth: 56,
|
|
padding: "3px 9px",
|
|
borderRadius: 5, // $menuitem-radius
|
|
transition: "background-color 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
},
|
|
|
|
/** Separator */
|
|
separator: {
|
|
margin: "3px 0", // $space-size/2 0
|
|
background: "rgba(0, 0, 0, 0.12)",
|
|
},
|
|
|
|
/** Backdrop state */
|
|
backdrop: {
|
|
boxShadow: "0 3px 2px -3px rgba(0,0,0,0.3), 0 2px 2px -1px rgba(0,0,0,0.24), 0 1px 3px 0 rgba(0,0,0,0.12)", // $shadow-z2
|
|
},
|
|
} as const;
|
|
|
|
|
|
// --- 5.15 CALENDAR ---
|
|
|
|
export const calendar = {
|
|
borderRadius: 12,
|
|
border: "1px solid rgba(0, 0, 0, 0.12)",
|
|
headerBorderBottom: "1px solid rgba(0, 0, 0, 0.12)",
|
|
headerPadding: 3,
|
|
gridMargin: 3,
|
|
dayPadding: 9, // $space-size * 1.5
|
|
todayHighlight: "#1A73E8", // primary color
|
|
selectedBorder: 9999, // circular for selected days
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 6. SHADOW / ELEVATION SYSTEM
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Based on Material Design elevation system.
|
|
* Values from material-components-web with Orchis adjustments.
|
|
*/
|
|
export const shadows = {
|
|
/** z1 - Subtle elevation (cards at rest, buttons) */
|
|
z1: "0 2px 2px -2px rgba(0,0,0,0.3), 0 1px 2px -1px rgba(0,0,0,0.24), 0 1px 2px -1px rgba(0,0,0,0.17)",
|
|
|
|
/** z2 - Low elevation (search bars, app bars) */
|
|
z2: "0 3px 2px -3px rgba(0,0,0,0.3), 0 2px 2px -1px rgba(0,0,0,0.24), 0 1px 3px 0 rgba(0,0,0,0.12)",
|
|
|
|
/** z3 - Medium elevation (cards on hover, FAB at rest) */
|
|
z3: "0 3px 3px -2px rgba(0,0,0,0.2), 0 3px 3px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12)",
|
|
|
|
/** z4 - Medium-high elevation (menus, tooltips, backdrops) */
|
|
z4: "0 2px 2px -1px rgba(0,0,0,0.2), 0 4px 4px 0 rgba(0,0,0,0.14), 0 1px 6px 0 rgba(0,0,0,0.12)",
|
|
|
|
/** z6 - High elevation (popovers, dropdown menus) */
|
|
z6: "0 3px 3px -1px rgba(0,0,0,0.2), 0 6px 6px 0 rgba(0,0,0,0.14), 0 1px 11px 0 rgba(0,0,0,0.12)",
|
|
|
|
/** z8 - Higher elevation (bottom sheets, side sheets) */
|
|
z8: "0 5px 5px -3px rgba(0,0,0,0.2), 0 8px 8px 1px rgba(0,0,0,0.14), 0 3px 9px 2px rgba(0,0,0,0.12)",
|
|
|
|
/** z12 - Very high elevation (FAB pressed) */
|
|
z12: "0 7px 7px -4px rgba(0,0,0,0.2), 0 12px 12px 2px rgba(0,0,0,0.14), 0 5px 13px 4px rgba(0,0,0,0.12)",
|
|
|
|
/** z16 - Window elevation (dialogs, modal windows) */
|
|
z16: "0 8px 6px -5px rgba(0,0,0,0.2), 0 16px 16px 2px rgba(0,0,0,0.14), 0 6px 18px 5px rgba(0,0,0,0.12)",
|
|
|
|
/** z24 - Maximum elevation (full-screen dialogs) */
|
|
z24: "0 11px 11px -7px rgba(0,0,0,0.2), 0 24px 24px 3px rgba(0,0,0,0.14), 0 9px 28px 8px rgba(0,0,0,0.12)",
|
|
|
|
/** Text shadow */
|
|
text: "0 1px 1px rgba(0,0,0,0.2), 0 1px 2px rgba(0,0,0,0.14), 0 1px 3px rgba(0,0,0,0.12)",
|
|
|
|
/** Gnome Shell simplified shadows */
|
|
shell: {
|
|
z1: "0 1px 2px rgba(0,0,0,0.25)",
|
|
z2: "0 3px 3px rgba(0,0,0,0.32)",
|
|
z3: "0 3px 8px rgba(0,0,0,0.2)",
|
|
z4: "0 6px 10px rgba(0,0,0,0.32)",
|
|
z5: "0 10px 15px rgba(0,0,0,0.45)",
|
|
z6: "0 12px 20px rgba(0,0,0,0.6)",
|
|
},
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 7. ANIMATION / TRANSITION PATTERNS
|
|
// ============================================================================
|
|
|
|
export const animation = {
|
|
/** Durations */
|
|
duration: {
|
|
shortest: "75ms", // $duration - micro interactions
|
|
shorter: "100ms", // $shorter-duration
|
|
short: "150ms", // $longer-duration
|
|
rippleFadeIn: "225ms", // $ripple-fade-in-duration
|
|
rippleFadeOut: "300ms", // $ripple-fade-out-duration
|
|
rippleOpacity: "1200ms", // $ripple-fade-out-opacity-duration
|
|
},
|
|
|
|
/** Timing functions (Material Design standard) */
|
|
easing: {
|
|
/** Standard easing - for most transitions */
|
|
standard: "cubic-bezier(0.4, 0.0, 0.2, 1)",
|
|
/** Decelerate - for elements entering the screen */
|
|
decelerate: "cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
/** Accelerate - for elements leaving the screen */
|
|
accelerate: "cubic-bezier(0.4, 0.0, 1, 1)",
|
|
/** Sharp - for elements that may return to screen */
|
|
sharp: "cubic-bezier(0.4, 0.0, 0.6, 1)",
|
|
},
|
|
|
|
/** Predefined transition shorthands */
|
|
transition: {
|
|
default: "all 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
shadow: "box-shadow 75ms cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
},
|
|
|
|
/** Ripple effect (Material Design signature interaction) */
|
|
ripple: {
|
|
/**
|
|
* CSS keyframes for ripple effect:
|
|
* @keyframes ripple {
|
|
* from { background-image: radial-gradient(circle farthest-corner at center, rgba(0,0,0,0.10) 30%, transparent 0%); }
|
|
* to { background-image: radial-gradient(circle farthest-corner at center, rgba(0,0,0,0.10) 100%, transparent 0%); }
|
|
* }
|
|
*/
|
|
duration: "225ms",
|
|
easing: "cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
// The ripple circle starts at 30% and expands to 100%
|
|
overlayColor: "rgba(0, 0, 0, 0.10)", // $overlay-checked
|
|
},
|
|
|
|
/** Spinner animation: rotate 1 full turn, linear, infinite */
|
|
spinner: {
|
|
animation: "spin 1s linear infinite",
|
|
},
|
|
|
|
/** Needs-attention pulse */
|
|
needsAttention: {
|
|
// Radial gradient pulse from 0% to 95% with primary color
|
|
},
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// 8. ICON STYLE PREFERENCES
|
|
// ============================================================================
|
|
|
|
export const icons = {
|
|
/** Orchis uses symbolic (monochrome outline) icons in the GNOME style */
|
|
style: "symbolic", // Monochrome, outline-based icons
|
|
|
|
/** Base icon size */
|
|
baseSize: 16, // $base-icon-size
|
|
mediumSize: 24, // $base-icon-size * 1.5
|
|
largeSize: 32, // $base-icon-size * 2
|
|
|
|
/** Icon color follows text color (currentColor) */
|
|
color: "currentColor",
|
|
|
|
/** Check/radio icon size */
|
|
checkRadioSize: 24,
|
|
|
|
/** The Orchis icon set uses:
|
|
* - Papirus icons (recommended companion)
|
|
* - Symbolic SVG icons for UI elements
|
|
* - Material Design inspired icon shapes
|
|
* - Rounded/soft stroke style
|
|
*/
|
|
recommendation: "Use Material Symbols (Rounded variant) or Phosphor Icons for web",
|
|
} as const;
|
|
|
|
|
|
// ============================================================================
|
|
// CSS CUSTOM PROPERTIES (ready for :root injection)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Generate CSS custom properties for a Next.js application.
|
|
* Usage: inject these into your global CSS or a ThemeProvider.
|
|
*/
|
|
export function generateCSSVariables(mode: "light" | "dark" = "light", accent: keyof typeof accentColors = "default"): string {
|
|
const theme = mode === "light" ? lightTheme : darkTheme;
|
|
const accentColor = mode === "light" ? accentColors[accent].dark : accentColors[accent].light;
|
|
|
|
return `
|
|
:root {
|
|
/* ---- Primary / Accent ---- */
|
|
--orchis-primary: ${accentColor};
|
|
--orchis-on-primary: ${theme.onPrimary.primary};
|
|
--orchis-on-primary-secondary: ${theme.onPrimary.secondary};
|
|
|
|
/* ---- Backgrounds ---- */
|
|
--orchis-background: ${theme.background};
|
|
--orchis-surface: ${theme.surface};
|
|
--orchis-base: ${theme.base};
|
|
--orchis-base-alt: ${theme.baseAlt};
|
|
|
|
/* ---- Text ---- */
|
|
--orchis-text: ${theme.text.primary};
|
|
--orchis-text-secondary: ${theme.text.secondary};
|
|
--orchis-text-disabled: ${theme.text.disabled};
|
|
|
|
/* ---- Semantic ---- */
|
|
--orchis-error: ${theme.error};
|
|
--orchis-warning: ${theme.warning};
|
|
--orchis-success: ${theme.success};
|
|
--orchis-link: ${accentColor};
|
|
--orchis-link-visited: ${theme.linkVisited};
|
|
--orchis-destructive: ${theme.error};
|
|
|
|
/* ---- Borders ---- */
|
|
--orchis-border: ${theme.border};
|
|
--orchis-border-solid: ${theme.solidBorder};
|
|
--orchis-divider: ${theme.divider};
|
|
|
|
/* ---- Overlay States ---- */
|
|
--orchis-overlay-hover: ${theme.overlay.hover};
|
|
--orchis-overlay-focus: ${theme.overlay.focus};
|
|
--orchis-overlay-active: ${theme.overlay.active};
|
|
--orchis-overlay-checked: ${theme.overlay.checked};
|
|
--orchis-overlay-selected: ${theme.overlay.selected};
|
|
|
|
/* ---- Track / Fill ---- */
|
|
--orchis-track: ${theme.track};
|
|
--orchis-track-disabled: ${theme.trackDisabled};
|
|
--orchis-fill: ${theme.fill};
|
|
--orchis-secondary-fill: ${theme.secondaryFill};
|
|
|
|
/* ---- Tooltip ---- */
|
|
--orchis-tooltip-bg: ${theme.tooltip};
|
|
|
|
/* ---- Titlebar ---- */
|
|
--orchis-titlebar: ${theme.titlebar};
|
|
--orchis-titlebar-backdrop: ${theme.titlebarBackdrop};
|
|
--orchis-sidebar: ${theme.sidebar};
|
|
|
|
/* ---- Window Buttons ---- */
|
|
--orchis-btn-close: ${theme.buttonClose};
|
|
--orchis-btn-maximize: ${theme.buttonMaximize};
|
|
--orchis-btn-minimize: ${theme.buttonMinimize};
|
|
|
|
/* ---- Typography ---- */
|
|
--orchis-font-family: ${typography.fontFamily};
|
|
--orchis-font-size: ${typography.rootFontSize};
|
|
--orchis-font-weight-button: ${typography.buttonWeight};
|
|
|
|
/* ---- Spacing ---- */
|
|
--orchis-space: ${spacing.space}px;
|
|
--orchis-space-xs: ${spacing.xs}px;
|
|
--orchis-space-sm: ${spacing.sm}px;
|
|
--orchis-space-md: ${spacing.md}px;
|
|
--orchis-space-lg: ${spacing.lg}px;
|
|
--orchis-space-xl: ${spacing.xl}px;
|
|
--orchis-space-xxl: ${spacing.xxl}px;
|
|
|
|
/* ---- Border Radius ---- */
|
|
--orchis-radius: ${borderRadius.default}px;
|
|
--orchis-radius-window: ${borderRadius.window}px;
|
|
--orchis-radius-corner: ${borderRadius.corner}px;
|
|
--orchis-radius-menu: ${borderRadius.menu}px;
|
|
--orchis-radius-card: ${borderRadius.card}px;
|
|
--orchis-radius-tooltip: ${borderRadius.tooltip}px;
|
|
--orchis-radius-menuitem: ${borderRadius.menuItem}px;
|
|
--orchis-radius-circular: ${borderRadius.circular}px;
|
|
|
|
/* ---- Shadows ---- */
|
|
--orchis-shadow-z1: ${shadows.z1};
|
|
--orchis-shadow-z2: ${shadows.z2};
|
|
--orchis-shadow-z3: ${shadows.z3};
|
|
--orchis-shadow-z4: ${shadows.z4};
|
|
--orchis-shadow-z6: ${shadows.z6};
|
|
--orchis-shadow-z8: ${shadows.z8};
|
|
--orchis-shadow-z12: ${shadows.z12};
|
|
--orchis-shadow-z16: ${shadows.z16};
|
|
--orchis-shadow-z24: ${shadows.z24};
|
|
|
|
/* ---- Transitions ---- */
|
|
--orchis-duration: ${animation.duration.shortest};
|
|
--orchis-duration-short: ${animation.duration.short};
|
|
--orchis-duration-ripple: ${animation.duration.rippleFadeIn};
|
|
--orchis-ease: ${animation.easing.standard};
|
|
--orchis-ease-out: ${animation.easing.decelerate};
|
|
--orchis-ease-in: ${animation.easing.accelerate};
|
|
--orchis-transition: ${animation.transition.default};
|
|
|
|
/* ---- Component Sizes ---- */
|
|
--orchis-size-small: ${spacing.small}px;
|
|
--orchis-size-medium: ${spacing.medium}px;
|
|
--orchis-size-large: ${spacing.large}px;
|
|
--orchis-icon-size: ${icons.baseSize}px;
|
|
--orchis-icon-size-md: ${icons.mediumSize}px;
|
|
--orchis-icon-size-lg: ${icons.largeSize}px;
|
|
--orchis-bar-size: ${spacing.bar}px;
|
|
}
|
|
`.trim();
|
|
}
|