diff --git a/web/mobile/scripts/generate-shadcn-tokens.ts b/web/mobile/scripts/generate-shadcn-tokens.ts index 7a610e3e4b..2e69e67452 100644 --- a/web/mobile/scripts/generate-shadcn-tokens.ts +++ b/web/mobile/scripts/generate-shadcn-tokens.ts @@ -11,10 +11,12 @@ * * Run (from web/mobile): pnpm generate:tokens */ -import {readFileSync, writeFileSync} from "fs" +import {readdirSync, readFileSync, writeFileSync} from "fs" import {dirname, resolve} from "path" import {fileURLToPath} from "url" +import {controlScale} from "../../oss/src/styles/theme/controlScale" +import {shadcnTokens} from "../../oss/src/styles/theme/shadcnTokens" import {palette, type ColorValue} from "../../oss/src/styles/theme/palette" const HERE = dirname(fileURLToPath(import.meta.url)) // web/mobile/scripts @@ -67,17 +69,197 @@ const VARS: Record = { ring: [color(p.accent.primary.light), color(p.accent.primary.dark)], } +// ── @agenta/ui control tokens ──────────────────────────────────────────────── +// The shared components in @agenta/ui speak the palette-derived vocabulary the desktop +// generates (btn-*, error-*, disabled-*). Same palette.ts, same values — only the names +// differ from the shadcn roles above, so both live in one generated file. +const UI_VARS: Record = { + "btn-primary-hover": [color(p.button.primaryHover.light), color(p.button.primaryHover.dark)], + "btn-primary-active": [color(p.button.primaryActive.light), color(p.button.primaryActive.dark)], + "btn-primary-fg": [color(p.button.primaryText.light), color(p.button.primaryText.dark)], + "btn-default-bg": [color(p.button.defaultBg.light), color(p.button.defaultBg.dark)], + "btn-default-hover-bg": [ + color(p.button.defaultHoverBg.light), + color(p.button.defaultHoverBg.dark), + ], + "btn-default-active-bg": [ + color(p.button.defaultActiveBg.light), + color(p.button.defaultActiveBg.dark), + ], + "btn-text-hover-bg": [color(p.button.textHoverBg.light), color(p.button.textHoverBg.dark)], + "btn-text-active-bg": [color(p.button.textActiveBg.light), color(p.button.textActiveBg.dark)], + "btn-link": [color(p.button.link.light), color(p.button.link.dark)], + "btn-link-hover": [color(p.button.linkHover.light), color(p.button.linkHover.dark)], + "btn-link-active": [color(p.button.linkActive.light), color(p.button.linkActive.dark)], + error: [color(p.semantic.error.light), color(p.semantic.error.dark)], + "error-hover": [color(p.semantic.errorHover.light), color(p.semantic.errorHover.dark)], + "error-active": [color(p.semantic.errorActive.light), color(p.semantic.errorActive.dark)], + disabled: [color(p.text.disabled.light), color(p.text.disabled.dark)], + "focus-ring": [color(p.semantic.primaryBorder.light), color(p.semantic.primaryBorder.dark)], + "disabled-bg": [ + color(p.surface.containerDisabled.light), + color(p.surface.containerDisabled.dark), + ], +} + +// ── Control geometry ───────────────────────────────────────────────────────── +// Straight from the shared controlScale module (web/oss/src/styles/theme/controlScale.ts) — +// the same object oss spreads into its Tailwind v3 theme. Emitted into Tailwind v4's own +// namespaces so a shared component renders at identical dimensions in both apps, and a retune +// there reaches mobile through this generator instead of a hand-copied pixel list. + +const geometry = (): string => { + const out: string[] = [] + const push = (ns: string, table: Record) => { + for (const [name, value] of Object.entries(table)) { + // fontSize entries are [size, {lineHeight}] tuples; the rest are plain strings. + const size = Array.isArray(value) ? (value[0] as string) : (value as string) + out.push(` --${ns}-${name}: ${size};`) + } + } + push("height", controlScale.height) + push("width", controlScale.width) + push("spacing", controlScale.spacing) + push("radius", controlScale.borderRadius) + push("text", controlScale.fontSize) + return out.join("\n") +} + +// ── @agenta/ui colour surface ──────────────────────────────────────────────── +// The shared components speak the desktop's palette-derived `--ag-*` vocabulary. Rather than +// curating a per-component list, mirror the layer itself: read the generated variables, keep +// the ones @agenta/ui references, and expose each under Tailwind v4's colour namespace. +// +// Source is theme-variables.css, not palette.ts, because many values are antd-algorithm output +// (derived fills, preset tag ramps) that palette.ts cannot reproduce on its own. Both files come +// from the same generator run, so this stays one source of truth. +const AG_CSS = resolve(HERE, "../../oss/src/styles/theme-variables.css") + +/** + * Flatten the shared contract into utility-name → variable-name. + * + * Tailwind nests families (`{primary: {DEFAULT, hover}}` → `primary`, `primary-hover`), so the + * same flattening the v3 config gets for free has to happen explicitly here. + */ +const flattenTokens = ( + node: unknown, + prefix = "", + out: Record = {}, +): Record => { + if (typeof node === "string") { + const m = node.match(/^var\(--ag-([A-Za-z0-9-]+)\)$/) + if (m && prefix) out[prefix] = m[1] + return out + } + if (node && typeof node === "object") { + for (const [key, value] of Object.entries(node as Record)) { + const name = key === "DEFAULT" ? prefix : prefix ? `${prefix}-${key}` : key + flattenTokens(value, name, out) + } + } + return out +} + +const TOKEN_TO_VAR = flattenTokens(shadcnTokens) + +/** + * Utility names the shared components actually reference. Scanned rather than enumerated so a + * new component cannot silently render unstyled: whatever it uses, the bridge emits. + */ +const usedNames = (): string[] => { + const dir = resolve(HERE, "../../packages/agenta-ui/src") + const names = new Set() + const walk = (d: string) => { + for (const entry of readdirSync(d, {withFileTypes: true})) { + const full = resolve(d, entry.name) + if (entry.isDirectory()) walk(full) + else if (/\.tsx?$/.test(entry.name)) { + for (const m of readFileSync(full, "utf8").matchAll( + /\b(?:bg|text|border|ring|fill|stroke|outline|from|to|via|decoration|shadow|divide|accent|caret|placeholder)-([a-zA-Z][a-zA-Z0-9-]*)/g, + )) { + names.add(m[1]) + } + } + } + } + walk(dir) + return [...names] +} + +const parseAgVars = (): {light: Record; dark: Record} => { + const css = readFileSync(AG_CSS, "utf8") + const grab = (selector: string): Record => { + const start = css.indexOf(`${selector} {`) + if (start < 0) throw new Error(`${selector} block missing from theme-variables.css`) + const body = css.slice(start, css.indexOf("\n}", start)) + const out: Record = {} + for (const line of body.split("\n")) { + const m = line.match(/^\s*--ag-([A-Za-z0-9-]+):\s*(.+);\s*$/) + if (m) out[m[1]] = m[2].trim() + } + return out + } + return {light: grab(":root"), dark: grab(".dark")} +} + +/** Which `--ag-*` names the shared components reference, read from their own source. */ +const usedAgNames = (): string[] => { + const dir = resolve(HERE, "../../packages/agenta-ui/src") + const names = new Set() + const walk = (d: string) => { + for (const entry of readdirSync(d, {withFileTypes: true})) { + const full = resolve(d, entry.name) + if (entry.isDirectory()) walk(full) + else if (/\.tsx?$/.test(entry.name)) { + const src = readFileSync(full, "utf8") + for (const m of src.matchAll( + /\b(?:bg|text|border|ring|fill|stroke|outline|from|to|via|decoration|shadow)-([a-zA-Z][a-zA-Z0-9-]*)/g, + )) { + names.add(m[1]) + } + } + } + } + walk(dir) + return [...names] +} + const block = (selector: string, side: 0 | 1) => - `${selector} {\n${Object.entries(VARS) + `${selector} {\n${Object.entries({...VARS, ...UI_VARS}) .map(([name, pair]) => ` --${name}: ${pair[side]};`) .join("\n")}\n}\n` +// Colour surface: `--name` per theme, plus the v4 namespace mapping. Only names that resolve to +// a real variable are emitted — an unmapped utility would silently generate nothing anyway. +const ag = parseAgVars() +// The contract wins where it renames a token; anything else the package references maps to the +// variable of the same name. +const agResolved = [...new Set([...Object.keys(TOKEN_TO_VAR), ...usedNames()])] + .map((name) => ({name, varName: TOKEN_TO_VAR[name] ?? name})) + .filter(({varName}) => ag.light[varName] !== undefined) + +const agBlock = (side: "light" | "dark") => + agResolved.map(({name, varName}) => ` --${name}: ${ag[side][varName]};`).join("\n") + +const agTheme = () => agResolved.map(({name}) => ` --color-${name}: var(--${name});`).join("\n") + const css = `/* GENERATED by scripts/generate-shadcn-tokens.ts — DO NOT EDIT. * Source of truth: web/oss/src/styles/theme/palette.ts * Regenerate: pnpm --filter @agenta/mobile generate:tokens */ +:root { +${agBlock("light")} +} +.dark { +${agBlock("dark")} +} ${block(":root", 0)} -${block(".dark", 1)}` +${block(".dark", 1)} +@theme { +${agTheme()} +${geometry()} +} +` // --check: drift guard — fail (without writing) if the committed file is stale. if (process.argv.includes("--check")) { diff --git a/web/mobile/src/styles/globals.css b/web/mobile/src/styles/globals.css index bd4b0c3861..5b53fde32a 100644 --- a/web/mobile/src/styles/globals.css +++ b/web/mobile/src/styles/globals.css @@ -43,6 +43,28 @@ --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); + + /* ── @agenta/ui control tokens ───────────────────────────────────────── + * Colours come from the generated palette layer; the geometry mirrors + * `controlScale` in web/oss/tailwind.config.ts (a fixed px scale, not palette-derived), + * so a shared component renders at identical dimensions in both apps. */ + --color-btn-primary-hover: var(--btn-primary-hover); + --color-btn-primary-active: var(--btn-primary-active); + --color-btn-primary-fg: var(--btn-primary-fg); + --color-btn-default-bg: var(--btn-default-bg); + --color-btn-default-hover-bg: var(--btn-default-hover-bg); + --color-btn-default-active-bg: var(--btn-default-active-bg); + --color-btn-text-hover-bg: var(--btn-text-hover-bg); + --color-btn-text-active-bg: var(--btn-text-active-bg); + --color-btn-link: var(--btn-link); + --color-btn-link-hover: var(--btn-link-hover); + --color-btn-link-active: var(--btn-link-active); + --color-error: var(--error); + --color-error-hover: var(--error-hover); + --color-error-active: var(--error-active); + --color-disabled-bg: var(--disabled-bg); + --color-disabled: var(--disabled); + --color-focus-ring: var(--focus-ring); } @layer base { diff --git a/web/mobile/src/styles/theme.generated.css b/web/mobile/src/styles/theme.generated.css index 700f8de8a6..a76059d96e 100644 --- a/web/mobile/src/styles/theme.generated.css +++ b/web/mobile/src/styles/theme.generated.css @@ -2,6 +2,292 @@ * Source of truth: web/oss/src/styles/theme/palette.ts * Regenerate: pnpm --filter @agenta/mobile generate:tokens */ +:root { + --background: #ffffff; + --foreground: #1c2c3d; + --border: #bdc7d1; + --input: #bdc7d1; + --ring: #1c2c3d; + --focus-ring: #d6dee6; + --primary: #1c2c3d; + --primary-hover: #394857; + --primary-foreground: #ffffff; + --secondary: rgba(5, 23, 41, 0.06); + --secondary-foreground: #1c2c3d; + --muted: rgba(5, 23, 41, 0.04); + --muted-foreground: #586673; + --accent: rgba(5, 23, 41, 0.06); + --accent-foreground: #1c2c3d; + --destructive: #d61010; + --destructive-foreground: #ffffff; + --popover: #ffffff; + --popover-foreground: #1c2c3d; + --card: #ffffff; + --card-foreground: #1c2c3d; + --placeholder: #bdc7d1; + --disabled: #bdc7d1; + --disabled-bg: rgba(5, 23, 41, 0.04); + --disabled-border: #d9d9d9; + --success: #389e0d; + --success-bg: #f6ffed; + --success-border: #b7eb8f; + --warning: #faad14; + --warning-bg: #fffbe6; + --warning-border: #ffe58f; + --error: #d61010; + --error-bg: #fbe7e7; + --error-border: #ef9f9f; + --error-hover: #de4040; + --error-active: #ab0d0d; + --info: #1c2c3d; + --info-bg: #f5f7fa; + --info-border: #d6dee6; + --draft: #d48806; + --draft-bg: #fffbe6; + --draft-border: #ffe58f; + --tag-blue: #0958d9; + --tag-blue-bg: #e6f4ff; + --tag-green: #237804; + --tag-green-bg: #f6ffed; + --tag-orange: #ad4e00; + --tag-orange-bg: #fff7e6; + --tag-red: #cf1322; + --tag-red-bg: #fff1f0; + --tag-purple: #531dab; + --tag-purple-bg: #f9f0ff; + --tag-pink: #c41d7f; + --tag-pink-bg: #fff0f6; + --tag-yellow: #876800; + --tag-yellow-bg: #feffe6; + --tag-volcano: #ad2102; + --tag-volcano-bg: #fff2e8; + --tag-geekblue: #1d39c4; + --tag-geekblue-bg: #f0f5ff; + --tag-lime: #3f6600; + --tag-lime-bg: #fcffe6; + --tag-cyan: #006d75; + --tag-cyan-bg: #e6fffb; + --tag-magenta: #c41d7f; + --tag-magenta-bg: #fff0f6; + --tag-gold: #874d00; + --tag-gold-bg: #fffbe6; + --btn-primary-fg: #ffffff; + --btn-primary-hover: #394857; + --btn-primary-active: #051729; + --btn-default-bg: #ffffff; + --btn-default-hover-bg: #ffffff; + --btn-default-active-bg: #ffffff; + --btn-text-hover-bg: rgba(5, 23, 41, 0.06); + --btn-text-active-bg: rgba(5, 23, 41, 0.15); + --btn-link: #1c2c3d; + --btn-link-hover: #394857; + --btn-link-active: #051729; + --empty-shadow: #f5f5f7; + --empty-sheet: #f5f5f7; + --empty-flap: #aeb8c2; + --empty-front: #dce0e6; + --empty-hole: #ffffff; + --chip: rgba(5, 23, 41, 0.02); + --fill: rgba(5, 23, 41, 0.15); + --fill-secondary: rgba(5, 23, 41, 0.06); + --fill-tertiary: rgba(5, 23, 41, 0.04); + --fill-quaternary: rgba(5, 23, 41, 0.02); + --zinc-1: #f5f7fa; + --zinc-2: #eaeff5; + --gray-200: #e5e7eb; + --gray-600: #4b5563; + --gray-500: #6b7280; + --neutral-200: #e5e5e5; + --gray-400: #9ca3af; + --colorTextDescription: #758391; + --colorSuccess: #389e0d; + --controlItemBgActive: #f5f7fa; + --colorPrimary: #1c2c3d; + --colorText: #1c2c3d; + --gray-900: #111827; + --gray-50: #f9fafb; + --gray-100: #f3f4f6; + --zinc-6: #758391; + --colorFillTertiary: rgba(5, 23, 41, 0.04); + --colorTextTertiary: #758391; + --colorTextSecondary: #586673; + --colorBgElevated: #ffffff; + --colorFillQuaternary: rgba(5, 23, 41, 0.02); + --colorBorderSecondary: #eaeff5; + --colorBorder: #bdc7d1; + --colorError: #d61010; + --colorInfo: #1c2c3d; + --colorBgContainer: #ffffff; + --colorIcon: #758391; + --colorTextHeading: #1c2c3d; + --colorBgMask: rgba(5, 23, 41, 0.45); + --colorIconHover: #1c2c3d; + --colorWarning: #faad14; + --colorTextPlaceholder: #bdc7d1; + --colorTextLightSolid: #ffffff; + --colorBgContainerDisabled: rgba(5, 23, 41, 0.04); + --colorWhite: #ffffff; + --colorTextDisabled: #bdc7d1; + --colorSplit: rgba(5, 23, 41, 0.06); + --colorFill: rgba(5, 23, 41, 0.15); + --colorTextQuaternary: #bdc7d1; + --colorBgLayout: #ffffff; + --colorTextLabel: #586673; + --colorFillSecondary: rgba(5, 23, 41, 0.06); + --colorPrimaryBorder: #d6dee6; + --colorPrimaryBorderHover: #97a4b0; + --colorBgSpotlight: rgba(5, 23, 41, 0.9); + --gray-700: #374151; + --gray-300: #d1d5db; + --zinc-9: #1c2c3d; + --zinc-7: #586673; + --zinc-4: #bdc7d1; + --zinc-3: #d6dee6; + --zinc-5: #97a4b0; +} +.dark { + --background: #141414; + --foreground: rgba(255, 255, 255, 0.85); + --border: #424242; + --input: #424242; + --ring: #d1d151; + --focus-ring: #57572a; + --primary: #d1d151; + --primary-hover: #e8e47e; + --primary-foreground: #ffffff; + --secondary: rgba(255, 255, 255, 0.12); + --secondary-foreground: rgba(255, 255, 255, 0.85); + --muted: rgba(255, 255, 255, 0.08); + --muted-foreground: rgba(255, 255, 255, 0.65); + --accent: rgba(255, 255, 255, 0.12); + --accent-foreground: rgba(255, 255, 255, 0.85); + --destructive: #dc4446; + --destructive-foreground: #ffffff; + --popover: #242424; + --popover-foreground: rgba(255, 255, 255, 0.85); + --card: #141414; + --card-foreground: rgba(255, 255, 255, 0.85); + --placeholder: rgba(255, 255, 255, 0.38); + --disabled: rgba(255, 255, 255, 0.25); + --disabled-bg: rgba(255, 255, 255, 0.08); + --disabled-border: #424242; + --success: #49aa19; + --success-bg: #162312; + --success-border: #274916; + --warning: #d89614; + --warning-bg: #2b2111; + --warning-border: #594214; + --error: #dc4446; + --error-bg: #2c1618; + --error-border: #5b2526; + --error-hover: #e86e6b; + --error-active: #ad393a; + --info: #1668dc; + --info-bg: #111a2c; + --info-border: #15325b; + --draft: undefined; + --draft-bg: var(--ag-colorBgElevated); + --draft-border: var(--ag-colorBgElevated); + --tag-blue: #3c89e8; + --tag-blue-bg: #111a2c; + --tag-green: #6abe39; + --tag-green-bg: #162312; + --tag-orange: #e89a3c; + --tag-orange-bg: #2b1d11; + --tag-red: #e84749; + --tag-red-bg: #2a1215; + --tag-purple: #ab7ae0; + --tag-purple-bg: #1a1325; + --tag-pink: #e0529c; + --tag-pink-bg: #291321; + --tag-yellow: #e8d639; + --tag-yellow-bg: #2b2611; + --tag-volcano: #e87040; + --tag-volcano-bg: #2b1611; + --tag-geekblue: #7f9ef3; + --tag-geekblue-bg: #131629; + --tag-lime: #a9d134; + --tag-lime-bg: #1f2611; + --tag-cyan: #33bcb7; + --tag-cyan-bg: #112123; + --tag-magenta: #e0529c; + --tag-magenta-bg: #291321; + --tag-gold: #e8b339; + --tag-gold-bg: #2b2111; + --btn-primary-fg: #141414; + --btn-primary-hover: #e8e47e; + --btn-primary-active: #a4a443; + --btn-default-bg: transparent; + --btn-default-hover-bg: rgba(255, 255, 255, 0.04); + --btn-default-active-bg: rgba(255, 255, 255, 0.08); + --btn-text-hover-bg: rgba(255, 255, 255, 0.08); + --btn-text-active-bg: rgba(255, 255, 255, 0.18); + --btn-link: #4e90dc; + --btn-link-hover: #79b8ff; + --btn-link-active: #3b8eea; + --empty-shadow: #a6a6a8; + --empty-sheet: #a6a6a8; + --empty-flap: #787f85; + --empty-front: #96999d; + --empty-hole: #adadad; + --chip: #272727; + --fill: rgba(255, 255, 255, 0.18); + --fill-secondary: rgba(255, 255, 255, 0.12); + --fill-tertiary: rgba(255, 255, 255, 0.08); + --fill-quaternary: rgba(255, 255, 255, 0.04); + --zinc-1: #242424; + --zinc-2: #2a2a2a; + --gray-200: #2a2a2a; + --gray-600: rgba(255, 255, 255, 0.55); + --gray-500: #8c8c8c; + --neutral-200: #2a2a2a; + --gray-400: #5c5c5c; + --colorTextDescription: rgba(255, 255, 255, 0.45); + --colorSuccess: #49aa19; + --controlItemBgActive: #57572a; + --colorPrimary: #d1d151; + --colorText: rgba(255, 255, 255, 0.85); + --gray-900: rgba(255, 255, 255, 0.85); + --gray-50: #1a1a1a; + --gray-100: #242424; + --zinc-6: rgba(255, 255, 255, 0.45); + --colorFillTertiary: rgba(255, 255, 255, 0.08); + --colorTextTertiary: rgba(255, 255, 255, 0.45); + --colorTextSecondary: rgba(255, 255, 255, 0.65); + --colorBgElevated: #242424; + --colorFillQuaternary: rgba(255, 255, 255, 0.04); + --colorBorderSecondary: #303030; + --colorBorder: #424242; + --colorError: #dc4446; + --colorInfo: #1668dc; + --colorBgContainer: #141414; + --colorIcon: rgba(255, 255, 255, 0.45); + --colorTextHeading: rgba(255, 255, 255, 0.85); + --colorBgMask: rgba(0, 0, 0, 0.45); + --colorIconHover: rgba(255, 255, 255, 0.85); + --colorWarning: #d89614; + --colorTextPlaceholder: rgba(255, 255, 255, 0.38); + --colorTextLightSolid: #ffffff; + --colorBgContainerDisabled: rgba(255, 255, 255, 0.08); + --colorWhite: #ffffff; + --colorTextDisabled: rgba(255, 255, 255, 0.25); + --colorSplit: rgba(253, 253, 253, 0.12); + --colorFill: rgba(255, 255, 255, 0.18); + --colorTextQuaternary: rgba(255, 255, 255, 0.25); + --colorBgLayout: #000000; + --colorTextLabel: rgba(255, 255, 255, 0.65); + --colorFillSecondary: rgba(255, 255, 255, 0.12); + --colorPrimaryBorder: #57572a; + --colorPrimaryBorderHover: #787834; + --colorBgSpotlight: #424242; + --gray-700: rgba(255, 255, 255, 0.65); + --gray-300: #383838; + --zinc-9: rgba(255, 255, 255, 0.85); + --zinc-7: rgba(255, 255, 255, 0.65); + --zinc-4: #424242; + --zinc-3: #383838; + --zinc-5: #5c5c5c; +} :root { --background: #ffffff; --foreground: #1c2c3d; @@ -23,6 +309,23 @@ --border: #eaeff5; --input: #bdc7d1; --ring: #1c2c3d; + --btn-primary-hover: #394857; + --btn-primary-active: #051729; + --btn-primary-fg: #ffffff; + --btn-default-bg: #ffffff; + --btn-default-hover-bg: #ffffff; + --btn-default-active-bg: #ffffff; + --btn-text-hover-bg: rgba(5, 23, 41, 0.06); + --btn-text-active-bg: rgba(5, 23, 41, 0.15); + --btn-link: #1c2c3d; + --btn-link-hover: #394857; + --btn-link-active: #051729; + --error: #d61010; + --error-hover: #de4040; + --error-active: #ab0d0d; + --disabled: #bdc7d1; + --focus-ring: #d6dee6; + --disabled-bg: rgba(5, 23, 41, 0.04); } .dark { @@ -46,4 +349,208 @@ --border: #303030; --input: #424242; --ring: #f2f25c; + --btn-primary-hover: #e8e47e; + --btn-primary-active: #a4a443; + --btn-primary-fg: #141414; + --btn-default-bg: transparent; + --btn-default-hover-bg: rgba(255, 255, 255, 0.04); + --btn-default-active-bg: rgba(255, 255, 255, 0.08); + --btn-text-hover-bg: rgba(255, 255, 255, 0.08); + --btn-text-active-bg: rgba(255, 255, 255, 0.18); + --btn-link: #4e90dc; + --btn-link-hover: #79b8ff; + --btn-link-active: #3b8eea; + --error: #ff4d4f; + --error-hover: #e86e6b; + --error-active: #ad393a; + --disabled: rgba(255, 255, 255, 0.25); + --focus-ring: #57572a; + --disabled-bg: rgba(255, 255, 255, 0.08); +} + +@theme { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-focus-ring: var(--focus-ring); + --color-primary: var(--primary); + --color-primary-hover: var(--primary-hover); + --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-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-placeholder: var(--placeholder); + --color-disabled: var(--disabled); + --color-disabled-bg: var(--disabled-bg); + --color-disabled-border: var(--disabled-border); + --color-success: var(--success); + --color-success-bg: var(--success-bg); + --color-success-border: var(--success-border); + --color-warning: var(--warning); + --color-warning-bg: var(--warning-bg); + --color-warning-border: var(--warning-border); + --color-error: var(--error); + --color-error-bg: var(--error-bg); + --color-error-border: var(--error-border); + --color-error-hover: var(--error-hover); + --color-error-active: var(--error-active); + --color-info: var(--info); + --color-info-bg: var(--info-bg); + --color-info-border: var(--info-border); + --color-draft: var(--draft); + --color-draft-bg: var(--draft-bg); + --color-draft-border: var(--draft-border); + --color-tag-blue: var(--tag-blue); + --color-tag-blue-bg: var(--tag-blue-bg); + --color-tag-green: var(--tag-green); + --color-tag-green-bg: var(--tag-green-bg); + --color-tag-orange: var(--tag-orange); + --color-tag-orange-bg: var(--tag-orange-bg); + --color-tag-red: var(--tag-red); + --color-tag-red-bg: var(--tag-red-bg); + --color-tag-purple: var(--tag-purple); + --color-tag-purple-bg: var(--tag-purple-bg); + --color-tag-pink: var(--tag-pink); + --color-tag-pink-bg: var(--tag-pink-bg); + --color-tag-yellow: var(--tag-yellow); + --color-tag-yellow-bg: var(--tag-yellow-bg); + --color-tag-volcano: var(--tag-volcano); + --color-tag-volcano-bg: var(--tag-volcano-bg); + --color-tag-geekblue: var(--tag-geekblue); + --color-tag-geekblue-bg: var(--tag-geekblue-bg); + --color-tag-lime: var(--tag-lime); + --color-tag-lime-bg: var(--tag-lime-bg); + --color-tag-cyan: var(--tag-cyan); + --color-tag-cyan-bg: var(--tag-cyan-bg); + --color-tag-magenta: var(--tag-magenta); + --color-tag-magenta-bg: var(--tag-magenta-bg); + --color-tag-gold: var(--tag-gold); + --color-tag-gold-bg: var(--tag-gold-bg); + --color-btn-primary-fg: var(--btn-primary-fg); + --color-btn-primary-hover: var(--btn-primary-hover); + --color-btn-primary-active: var(--btn-primary-active); + --color-btn-default-bg: var(--btn-default-bg); + --color-btn-default-hover-bg: var(--btn-default-hover-bg); + --color-btn-default-active-bg: var(--btn-default-active-bg); + --color-btn-text-hover-bg: var(--btn-text-hover-bg); + --color-btn-text-active-bg: var(--btn-text-active-bg); + --color-btn-link: var(--btn-link); + --color-btn-link-hover: var(--btn-link-hover); + --color-btn-link-active: var(--btn-link-active); + --color-empty-shadow: var(--empty-shadow); + --color-empty-sheet: var(--empty-sheet); + --color-empty-flap: var(--empty-flap); + --color-empty-front: var(--empty-front); + --color-empty-hole: var(--empty-hole); + --color-chip: var(--chip); + --color-fill: var(--fill); + --color-fill-secondary: var(--fill-secondary); + --color-fill-tertiary: var(--fill-tertiary); + --color-fill-quaternary: var(--fill-quaternary); + --color-zinc-1: var(--zinc-1); + --color-zinc-2: var(--zinc-2); + --color-gray-200: var(--gray-200); + --color-gray-600: var(--gray-600); + --color-gray-500: var(--gray-500); + --color-neutral-200: var(--neutral-200); + --color-gray-400: var(--gray-400); + --color-colorTextDescription: var(--colorTextDescription); + --color-colorSuccess: var(--colorSuccess); + --color-controlItemBgActive: var(--controlItemBgActive); + --color-colorPrimary: var(--colorPrimary); + --color-colorText: var(--colorText); + --color-gray-900: var(--gray-900); + --color-gray-50: var(--gray-50); + --color-gray-100: var(--gray-100); + --color-zinc-6: var(--zinc-6); + --color-colorFillTertiary: var(--colorFillTertiary); + --color-colorTextTertiary: var(--colorTextTertiary); + --color-colorTextSecondary: var(--colorTextSecondary); + --color-colorBgElevated: var(--colorBgElevated); + --color-colorFillQuaternary: var(--colorFillQuaternary); + --color-colorBorderSecondary: var(--colorBorderSecondary); + --color-colorBorder: var(--colorBorder); + --color-colorError: var(--colorError); + --color-colorInfo: var(--colorInfo); + --color-colorBgContainer: var(--colorBgContainer); + --color-colorIcon: var(--colorIcon); + --color-colorTextHeading: var(--colorTextHeading); + --color-colorBgMask: var(--colorBgMask); + --color-colorIconHover: var(--colorIconHover); + --color-colorWarning: var(--colorWarning); + --color-colorTextPlaceholder: var(--colorTextPlaceholder); + --color-colorTextLightSolid: var(--colorTextLightSolid); + --color-colorBgContainerDisabled: var(--colorBgContainerDisabled); + --color-colorWhite: var(--colorWhite); + --color-colorTextDisabled: var(--colorTextDisabled); + --color-colorSplit: var(--colorSplit); + --color-colorFill: var(--colorFill); + --color-colorTextQuaternary: var(--colorTextQuaternary); + --color-colorBgLayout: var(--colorBgLayout); + --color-colorTextLabel: var(--colorTextLabel); + --color-colorFillSecondary: var(--colorFillSecondary); + --color-colorPrimaryBorder: var(--colorPrimaryBorder); + --color-colorPrimaryBorderHover: var(--colorPrimaryBorderHover); + --color-colorBgSpotlight: var(--colorBgSpotlight); + --color-gray-700: var(--gray-700); + --color-gray-300: var(--gray-300); + --color-zinc-9: var(--zinc-9); + --color-zinc-7: var(--zinc-7); + --color-zinc-4: var(--zinc-4); + --color-zinc-3: var(--zinc-3); + --color-zinc-5: var(--zinc-5); + --height-control-sm: 24px; + --height-control: 28px; + --height-control-lg: 34px; + --height-switch: 22px; + --height-switch-sm: 16px; + --height-switch-thumb: 18px; + --height-switch-thumb-sm: 12px; + --height-control-check: 16px; + --height-control-dot: 8px; + --height-control-check-dash: 7px; + --width-control-sm: 24px; + --width-control: 28px; + --width-control-lg: 34px; + --width-switch: 44px; + --width-switch-sm: 28px; + --width-switch-thumb: 18px; + --width-switch-thumb-sm: 12px; + --width-control-check: 16px; + --width-control-dot: 8px; + --width-control-check-dash: 7px; + --spacing-btn-sm: 7px; + --spacing-btn: 15px; + --spacing-btn-lg: 15px; + --spacing-input-sm: 7px; + --spacing-input: 11px; + --spacing-input-lg: 11px; + --spacing-input-y-sm: 0px; + --spacing-input-y: 4px; + --spacing-input-y-lg: 7px; + --spacing-input-y-ghost-sm: 1px; + --spacing-input-y-ghost: 5px; + --spacing-input-y-ghost-lg: 8px; + --radius-control-sm: 6px; + --radius-control: 8px; + --radius-control-lg: 10px; + --radius-control-round: 50%; + --text-btn-sm: 12px; + --text-btn-md: 12px; + --text-btn-lg: 14px; + --text-field-sm: 10px; + --text-field-md: 12px; + --text-field-lg: 14px; + --text-badge-md: 12px; }