This commit is contained in:
parent
9faf66399c
commit
bb065692b0
8 changed files with 92 additions and 132 deletions
|
|
@ -46,7 +46,7 @@ export default function App() {
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto flex max-w-[1500px] flex-col gap-7 p-5 md:p-10">
|
<main className="mx-auto flex max-w-[1500px] flex-col gap-7 p-5 md:p-10">
|
||||||
<div>
|
<div>
|
||||||
<Button variant="outline" onClick={() => setShowOnboarding(true)}>
|
<Button variant="subtleDefault" onClick={() => setShowOnboarding(true)}>
|
||||||
Open onboarding
|
Open onboarding
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@
|
||||||
--ui-density: 1;
|
--ui-density: 1;
|
||||||
--ui-border-width: 1px;
|
--ui-border-width: 1px;
|
||||||
--ui-shadow-strength: 0;
|
--ui-shadow-strength: 0;
|
||||||
--ui-surface-contrast: 0;
|
|
||||||
--ui-font-scale: 1;
|
--ui-font-scale: 1;
|
||||||
--ui-heading-weight: 600;
|
--ui-heading-weight: 600;
|
||||||
--ui-motion: 1;
|
--ui-motion: 1;
|
||||||
|
|
@ -248,11 +247,6 @@
|
||||||
padding: calc(0.625rem * var(--ui-density)) calc(0.75rem * var(--ui-density));
|
padding: calc(0.625rem * var(--ui-density)) calc(0.75rem * var(--ui-density));
|
||||||
}
|
}
|
||||||
[data-slot="card"] {
|
[data-slot="card"] {
|
||||||
background: color-mix(
|
|
||||||
in oklch,
|
|
||||||
var(--card),
|
|
||||||
var(--foreground) calc(var(--ui-surface-contrast) * 1%)
|
|
||||||
);
|
|
||||||
box-shadow: 0 calc(0.4rem * var(--ui-shadow-strength))
|
box-shadow: 0 calc(0.4rem * var(--ui-shadow-strength))
|
||||||
calc(1.8rem * var(--ui-shadow-strength))
|
calc(1.8rem * var(--ui-shadow-strength))
|
||||||
rgb(0 0 0 / calc(0.12 * var(--ui-shadow-strength)));
|
rgb(0 0 0 / calc(0.12 * var(--ui-shadow-strength)));
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,12 @@ export function ThemeSelector({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={cn("flex flex-wrap gap-3", className)}>
|
<div
|
||||||
|
className={cn(
|
||||||
|
"grid w-full grid-cols-[repeat(auto-fit,minmax(5rem,1fr))] gap-3 sm:flex sm:flex-wrap",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
{themes.map((theme) => (
|
{themes.map((theme) => (
|
||||||
<div key={theme.id} className="flex flex-col items-center gap-1.5">
|
<div key={theme.id} className="flex flex-col items-center gap-1.5">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ const DESIGN_NUMBER_FIELDS = [
|
||||||
"density",
|
"density",
|
||||||
"borderWidth",
|
"borderWidth",
|
||||||
"shadowStrength",
|
"shadowStrength",
|
||||||
"surfaceContrast",
|
|
||||||
"fontScale",
|
"fontScale",
|
||||||
"headingWeight",
|
"headingWeight",
|
||||||
"motion",
|
"motion",
|
||||||
|
|
@ -83,7 +82,16 @@ function parseDesign(value: string | null, fallback: ThemeDesign) {
|
||||||
if (!value) return fallback;
|
if (!value) return fallback;
|
||||||
try {
|
try {
|
||||||
const parsed: unknown = JSON.parse(value);
|
const parsed: unknown = JSON.parse(value);
|
||||||
return isThemeDesign(parsed) ? parsed : fallback;
|
if (!isThemeDesign(parsed)) return fallback;
|
||||||
|
return {
|
||||||
|
density: parsed.density,
|
||||||
|
borderWidth: parsed.borderWidth,
|
||||||
|
shadowStrength: parsed.shadowStrength,
|
||||||
|
fontScale: parsed.fontScale,
|
||||||
|
headingWeight: parsed.headingWeight,
|
||||||
|
motion: parsed.motion,
|
||||||
|
fontFamily: parsed.fontFamily,
|
||||||
|
};
|
||||||
} catch {
|
} catch {
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
@ -332,10 +340,6 @@ export function ThemeProvider({
|
||||||
"--ui-shadow-strength",
|
"--ui-shadow-strength",
|
||||||
String(themeDesign.shadowStrength),
|
String(themeDesign.shadowStrength),
|
||||||
);
|
);
|
||||||
root.style.setProperty(
|
|
||||||
"--ui-surface-contrast",
|
|
||||||
String(themeDesign.surfaceContrast),
|
|
||||||
);
|
|
||||||
root.style.setProperty("--ui-font-scale", String(themeDesign.fontScale));
|
root.style.setProperty("--ui-font-scale", String(themeDesign.fontScale));
|
||||||
root.style.setProperty(
|
root.style.setProperty(
|
||||||
"--ui-heading-weight",
|
"--ui-heading-weight",
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
import { useId } from "react";
|
|
||||||
import { Trash } from "lucide-react";
|
|
||||||
|
|
||||||
import { Button } from "../../cmp/button";
|
|
||||||
import { Label } from "../../cmp/label";
|
|
||||||
import { Slider } from "../../cmp/slider";
|
|
||||||
import { useTheme } from "../Provider";
|
|
||||||
import {
|
|
||||||
DEFAULT_BORDER_RADIUS,
|
|
||||||
MAX_BORDER_RADIUS,
|
|
||||||
MIN_BORDER_RADIUS,
|
|
||||||
} from "../utils";
|
|
||||||
|
|
||||||
export function BorderRadiusPicker() {
|
|
||||||
const id = useId();
|
|
||||||
const { themeBorderRadius, setThemeBorderRadius } = useTheme();
|
|
||||||
const updateBorderRadius = (value: number | readonly number[]) => {
|
|
||||||
setThemeBorderRadius(Array.isArray(value) ? (value[0] ?? 0) : value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex w-65 flex-col gap-2">
|
|
||||||
<div className="flex justify-between gap-4">
|
|
||||||
<Label htmlFor={id}>Border radius</Label>
|
|
||||||
<output
|
|
||||||
htmlFor={id}
|
|
||||||
className="font-mono text-xs text-muted-foreground"
|
|
||||||
>
|
|
||||||
{themeBorderRadius.toFixed(3)}rem
|
|
||||||
</output>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<div className="flex flex-1 flex-col justify-start gap-1">
|
|
||||||
<Slider
|
|
||||||
id={id}
|
|
||||||
className="w-full"
|
|
||||||
min={MIN_BORDER_RADIUS}
|
|
||||||
max={MAX_BORDER_RADIUS}
|
|
||||||
step={0.025}
|
|
||||||
value={[themeBorderRadius]}
|
|
||||||
onValueChange={updateBorderRadius}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
className="h-8 w-8"
|
|
||||||
variant="destructive"
|
|
||||||
disabled={themeBorderRadius === DEFAULT_BORDER_RADIUS}
|
|
||||||
onClick={() => updateBorderRadius(DEFAULT_BORDER_RADIUS)}
|
|
||||||
>
|
|
||||||
<Trash />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useId, useState, type ReactNode } from "react";
|
import { useId, useState, type ComponentProps, type ReactNode } from "react";
|
||||||
import { ChevronDown, RotateCcw } from "lucide-react";
|
import { ChevronDown, RotateCcw } from "lucide-react";
|
||||||
|
|
||||||
import { Button } from "../../cmp/button";
|
import { Button } from "../../cmp/button";
|
||||||
|
|
@ -14,8 +14,8 @@ import { Slider } from "../../cmp/slider";
|
||||||
import { ThemeSelector } from "../BaseThemeSelector";
|
import { ThemeSelector } from "../BaseThemeSelector";
|
||||||
import { useTheme } from "../Provider";
|
import { useTheme } from "../Provider";
|
||||||
import type { ThemeDesign, ThemeFontFamily } from "../types";
|
import type { ThemeDesign, ThemeFontFamily } from "../types";
|
||||||
|
import { MAX_BORDER_RADIUS, MIN_BORDER_RADIUS } from "../utils";
|
||||||
import { Base16Picker } from "./Base16Picker";
|
import { Base16Picker } from "./Base16Picker";
|
||||||
import { BorderRadiusPicker } from "./BorderRadiusPicker";
|
|
||||||
import { CustomCssPicker } from "./CustomCssPicker";
|
import { CustomCssPicker } from "./CustomCssPicker";
|
||||||
import { PolarityPicker } from "./PolarityPicker";
|
import { PolarityPicker } from "./PolarityPicker";
|
||||||
import { PrimaryPicker } from "./PrimaryPicker";
|
import { PrimaryPicker } from "./PrimaryPicker";
|
||||||
|
|
@ -30,32 +30,23 @@ function Section({ title, children }: { title: string; children: ReactNode }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DesignSlider({
|
function ThemeSlider({
|
||||||
label,
|
label,
|
||||||
field,
|
value,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
step,
|
step,
|
||||||
|
onValueChange,
|
||||||
format = (value) => String(value),
|
format = (value) => String(value),
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
field: keyof Pick<
|
value: number;
|
||||||
ThemeDesign,
|
|
||||||
| "density"
|
|
||||||
| "borderWidth"
|
|
||||||
| "shadowStrength"
|
|
||||||
| "surfaceContrast"
|
|
||||||
| "fontScale"
|
|
||||||
| "headingWeight"
|
|
||||||
| "motion"
|
|
||||||
>;
|
|
||||||
min: number;
|
min: number;
|
||||||
max: number;
|
max: number;
|
||||||
step: number;
|
step: number;
|
||||||
|
onValueChange: (value: number) => void;
|
||||||
format?: (value: number) => string;
|
format?: (value: number) => string;
|
||||||
}) {
|
}) {
|
||||||
const { themeDesign, setThemeDesign } = useTheme();
|
|
||||||
const value = themeDesign[field];
|
|
||||||
const id = useId();
|
const id = useId();
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-2 text-sm">
|
<div className="grid gap-2 text-sm">
|
||||||
|
|
@ -75,16 +66,39 @@ function DesignSlider({
|
||||||
step={step}
|
step={step}
|
||||||
value={[value]}
|
value={[value]}
|
||||||
onValueChange={(next) =>
|
onValueChange={(next) =>
|
||||||
setThemeDesign((current) => ({
|
onValueChange(Array.isArray(next) ? (next[0] ?? value) : next)
|
||||||
...current,
|
|
||||||
[field]: Array.isArray(next) ? (next[0] ?? value) : next,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DesignSlider({
|
||||||
|
field,
|
||||||
|
...props
|
||||||
|
}: Omit<ComponentProps<typeof ThemeSlider>, "value" | "onValueChange"> & {
|
||||||
|
field: keyof Pick<
|
||||||
|
ThemeDesign,
|
||||||
|
| "density"
|
||||||
|
| "borderWidth"
|
||||||
|
| "shadowStrength"
|
||||||
|
| "fontScale"
|
||||||
|
| "headingWeight"
|
||||||
|
| "motion"
|
||||||
|
>;
|
||||||
|
}) {
|
||||||
|
const { themeDesign, setThemeDesign } = useTheme();
|
||||||
|
return (
|
||||||
|
<ThemeSlider
|
||||||
|
{...props}
|
||||||
|
value={themeDesign[field]}
|
||||||
|
onValueChange={(value) =>
|
||||||
|
setThemeDesign((current) => ({ ...current, [field]: value }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function ThemeCustomizer({
|
export function ThemeCustomizer({
|
||||||
value,
|
value,
|
||||||
onValueChange,
|
onValueChange,
|
||||||
|
|
@ -97,6 +111,8 @@ export function ThemeCustomizer({
|
||||||
const {
|
const {
|
||||||
themeDesign,
|
themeDesign,
|
||||||
setThemeDesign,
|
setThemeDesign,
|
||||||
|
themeBorderRadius,
|
||||||
|
setThemeBorderRadius,
|
||||||
parentTheme,
|
parentTheme,
|
||||||
isThemeCustomized,
|
isThemeCustomized,
|
||||||
resetThemePreset,
|
resetThemePreset,
|
||||||
|
|
@ -113,7 +129,7 @@ export function ThemeCustomizer({
|
||||||
</Section>
|
</Section>
|
||||||
<div className="space-y-7">
|
<div className="space-y-7">
|
||||||
<Section title="Shape and spacing">
|
<Section title="Shape and spacing">
|
||||||
<div className="grid gap-6 md:grid-cols-2">
|
<div className="grid gap-6 xl:grid-cols-2">
|
||||||
<DesignSlider
|
<DesignSlider
|
||||||
label="Density"
|
label="Density"
|
||||||
field="density"
|
field="density"
|
||||||
|
|
@ -130,18 +146,19 @@ export function ThemeCustomizer({
|
||||||
step={0.25}
|
step={0.25}
|
||||||
format={(v) => `${v}px`}
|
format={(v) => `${v}px`}
|
||||||
/>
|
/>
|
||||||
<BorderRadiusPicker />
|
<ThemeSlider
|
||||||
<DesignSlider
|
label="Border radius"
|
||||||
label="Surface contrast"
|
value={themeBorderRadius}
|
||||||
field="surfaceContrast"
|
min={MIN_BORDER_RADIUS}
|
||||||
min={0}
|
max={MAX_BORDER_RADIUS}
|
||||||
max={8}
|
step={0.025}
|
||||||
step={0.5}
|
format={(value) => `${value.toFixed(3)}rem`}
|
||||||
|
onValueChange={setThemeBorderRadius}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
<Section title="Depth and motion">
|
<Section title="Depth and motion">
|
||||||
<div className="grid gap-6 md:grid-cols-2">
|
<div className="grid gap-6 xl:grid-cols-2">
|
||||||
<DesignSlider
|
<DesignSlider
|
||||||
label="Shadow strength"
|
label="Shadow strength"
|
||||||
field="shadowStrength"
|
field="shadowStrength"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ export const DEFAULT_THEME_DESIGN: ThemeDesign = {
|
||||||
density: 1,
|
density: 1,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
shadowStrength: 0,
|
shadowStrength: 0,
|
||||||
surfaceContrast: 0,
|
|
||||||
fontScale: 1,
|
fontScale: 1,
|
||||||
headingWeight: 600,
|
headingWeight: 600,
|
||||||
motion: 1,
|
motion: 1,
|
||||||
|
|
@ -87,14 +86,12 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
--tensamin-edge: var(--primary-foreground-alt);
|
--tensamin-edge: var(--primary-foreground-alt);
|
||||||
}
|
}
|
||||||
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"] {
|
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"] {
|
||||||
background-color: color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt));
|
background-color: color-mix(in oklch, var(--primary) 10%, transparent);
|
||||||
border-top-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 98%, white);
|
border-color: transparent;
|
||||||
border-left-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 89%, black);
|
color: var(--primary-foreground-alt);
|
||||||
border-right-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 89%, black);
|
|
||||||
border-bottom-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 83%, black);
|
|
||||||
}
|
}
|
||||||
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"]:hover {
|
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"]:hover {
|
||||||
background-color: color-mix(in oklch, var(--background) 80%, var(--primary-foreground-alt));
|
background-color: color-mix(in oklch, var(--primary) 20%, transparent);
|
||||||
}
|
}
|
||||||
:root[data-theme="tensamin"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="secondary"] {
|
:root[data-theme="tensamin"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="secondary"] {
|
||||||
--tensamin-edge: var(--secondary);
|
--tensamin-edge: var(--secondary);
|
||||||
|
|
@ -349,22 +346,14 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
:root[data-theme="methanium"] [data-slot="card"] {
|
:root[data-theme="methanium"] [data-slot="card"] {
|
||||||
padding-block: calc(1rem * var(--ui-density));
|
padding-block: calc(1rem * var(--ui-density));
|
||||||
}
|
}
|
||||||
:root[data-theme="methanium"] [data-slot="button"]:where([data-variant="default"], [data-variant="outline"]) {
|
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"] {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
color: var(--primary-foreground);
|
color: var(--primary-foreground);
|
||||||
}
|
|
||||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"] {
|
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"] {
|
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"]:hover {
|
||||||
border-color: var(--input);
|
|
||||||
}
|
|
||||||
:root[data-theme="methanium"] [data-slot="button"]:where([data-variant="default"], [data-variant="outline"]):hover {
|
|
||||||
background-color: #bb6fd6;
|
background-color: #bb6fd6;
|
||||||
}
|
}
|
||||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"]:is(:hover, :focus-visible) {
|
|
||||||
border-color: color-mix(in srgb, var(--input) 75%, var(--foreground) 25%);
|
|
||||||
}
|
|
||||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"] {
|
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"] {
|
||||||
background-color: var(--secondary);
|
background-color: var(--secondary);
|
||||||
border-color: color-mix(in srgb, white 16%, transparent);
|
border-color: color-mix(in srgb, white 16%, transparent);
|
||||||
|
|
@ -373,12 +362,13 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"]:hover {
|
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"]:hover {
|
||||||
background-color: color-mix(in srgb, var(--secondary) 80%, var(--foreground) 20%);
|
background-color: color-mix(in srgb, var(--secondary) 80%, var(--foreground) 20%);
|
||||||
}
|
}
|
||||||
:root[data-theme="methanium"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) {
|
:root[data-theme="methanium"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"], [data-slot="button"][data-variant="outline"]) {
|
||||||
background-color: color-mix(in srgb, var(--input) 55%, var(--background));
|
background-color: color-mix(in srgb, var(--input) 55%, var(--background));
|
||||||
border-color: var(--input);
|
border-color: var(--input);
|
||||||
|
color: var(--foreground);
|
||||||
transition: background-color 100ms ease, border-color 100ms ease;
|
transition: background-color 100ms ease, border-color 100ms ease;
|
||||||
}
|
}
|
||||||
:root[data-theme="methanium"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):not(:disabled):not([data-disabled]):not(:has(:disabled)):hover {
|
:root[data-theme="methanium"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"], [data-slot="button"][data-variant="outline"]):not(:disabled):not([data-disabled]):not(:has(:disabled)):hover {
|
||||||
background-color: color-mix(in srgb, var(--input) 72%, var(--background));
|
background-color: color-mix(in srgb, var(--input) 72%, var(--background));
|
||||||
border-color: color-mix(in srgb, var(--input) 75%, var(--foreground) 25%);
|
border-color: color-mix(in srgb, var(--input) 75%, var(--foreground) 25%);
|
||||||
}`,
|
}`,
|
||||||
|
|
@ -392,6 +382,8 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
design: DEFAULT_THEME_DESIGN,
|
design: DEFAULT_THEME_DESIGN,
|
||||||
},
|
},
|
||||||
css: `:root[data-theme="secret"] {
|
css: `:root[data-theme="secret"] {
|
||||||
|
--secret-border: color-mix(in srgb, #ffe8b4 15%, #24120c 85%);
|
||||||
|
--secret-control: #5e244e;
|
||||||
--background: #2f1b13;
|
--background: #2f1b13;
|
||||||
--foreground: #fffaf2;
|
--foreground: #fffaf2;
|
||||||
--card: #f9b637;
|
--card: #f9b637;
|
||||||
|
|
@ -408,8 +400,8 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
--accent: #fb6c00;
|
--accent: #fb6c00;
|
||||||
--accent-foreground: #24120c;
|
--accent-foreground: #24120c;
|
||||||
--destructive: #e73f1e;
|
--destructive: #e73f1e;
|
||||||
--border: #f9b637;
|
--border: var(--secret-border);
|
||||||
--input: #5e244e;
|
--input: var(--secret-border);
|
||||||
--ring: #fb6c00;
|
--ring: #fb6c00;
|
||||||
--sidebar: #24120c;
|
--sidebar: #24120c;
|
||||||
--sidebar-foreground: #fffaf2;
|
--sidebar-foreground: #fffaf2;
|
||||||
|
|
@ -417,7 +409,7 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
--sidebar-primary-foreground: #24120c;
|
--sidebar-primary-foreground: #24120c;
|
||||||
--sidebar-accent: #aa1c41;
|
--sidebar-accent: #aa1c41;
|
||||||
--sidebar-accent-foreground: #fffaf2;
|
--sidebar-accent-foreground: #fffaf2;
|
||||||
--sidebar-border: #e68457;
|
--sidebar-border: var(--secret-border);
|
||||||
}
|
}
|
||||||
:root.dark[data-theme="secret"] {
|
:root.dark[data-theme="secret"] {
|
||||||
--background: #24120c;
|
--background: #24120c;
|
||||||
|
|
@ -436,8 +428,8 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
--accent: #e73f1e;
|
--accent: #e73f1e;
|
||||||
--accent-foreground: #fffaf2;
|
--accent-foreground: #fffaf2;
|
||||||
--destructive: #e73f1e;
|
--destructive: #e73f1e;
|
||||||
--border: #e68457;
|
--border: var(--secret-border);
|
||||||
--input: #5e244e;
|
--input: var(--secret-border);
|
||||||
--ring: #fb6c00;
|
--ring: #fb6c00;
|
||||||
--sidebar: #24120c;
|
--sidebar: #24120c;
|
||||||
--sidebar-foreground: #ffe8b4;
|
--sidebar-foreground: #ffe8b4;
|
||||||
|
|
@ -445,7 +437,7 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
--sidebar-primary-foreground: #24120c;
|
--sidebar-primary-foreground: #24120c;
|
||||||
--sidebar-accent: #aa1c41;
|
--sidebar-accent: #aa1c41;
|
||||||
--sidebar-accent-foreground: #fffaf2;
|
--sidebar-accent-foreground: #fffaf2;
|
||||||
--sidebar-border: #5e244e;
|
--sidebar-border: var(--secret-border);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] body {
|
:root[data-theme="secret"] body {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
|
|
@ -459,29 +451,33 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%));
|
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%));
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
:root[data-theme="secret"] [data-slot="button"][data-variant="subtleDefault"] {
|
||||||
|
background-image: linear-gradient(to top, rgb(255 232 180 / 12%), rgb(255 232 180 / 2%));
|
||||||
|
color: var(--foreground);
|
||||||
|
}
|
||||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) {
|
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) {
|
||||||
background-color: var(--input);
|
background-color: var(--secret-control);
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):hover {
|
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):hover {
|
||||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%);
|
||||||
border-color: var(--input);
|
border-color: var(--input);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):is(:focus-visible, :focus-within) {
|
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):is(:focus-visible, :focus-within) {
|
||||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%);
|
||||||
border-color: var(--input);
|
border-color: var(--input);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] [data-slot="select-trigger"]:is([data-popup-open], [data-open], [aria-expanded="true"]) {
|
:root[data-theme="secret"] [data-slot="select-trigger"]:is([data-popup-open], [data-open], [aria-expanded="true"]) {
|
||||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
background-color: color-mix(in srgb, var(--secret-control) 84%, #24120c 16%);
|
||||||
border-color: var(--input);
|
border-color: var(--input);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] [data-slot="select-content"] {
|
:root[data-theme="secret"] [data-slot="select-content"] {
|
||||||
background-color: var(--popover);
|
background-color: var(--popover);
|
||||||
border-color: color-mix(in srgb, #ffe8b4 15%, #24120c 85%);
|
border-color: var(--secret-border);
|
||||||
color: var(--popover-foreground);
|
color: var(--popover-foreground);
|
||||||
}
|
}
|
||||||
:root.dark[data-theme="secret"] [data-slot="select-content"] {
|
:root.dark[data-theme="secret"] [data-slot="select-content"] {
|
||||||
border-color: color-mix(in srgb, #ffe8b4 15%, #24120c 85%);
|
border-color: var(--secret-border);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] [data-slot="select-item"]:is(:hover, :focus, [data-highlighted], [data-selected]) {
|
:root[data-theme="secret"] [data-slot="select-item"]:is(:hover, :focus, [data-highlighted], [data-selected]) {
|
||||||
background-color: #24120c;
|
background-color: #24120c;
|
||||||
|
|
@ -490,13 +486,13 @@ export const BUILT_IN_THEMES = defineThemes([
|
||||||
:root[data-theme="secret"] [data-slot="button"][data-variant="default"] {
|
:root[data-theme="secret"] [data-slot="button"][data-variant="default"] {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)), linear-gradient(115deg, #e73f1e 0%, #fb6c00 30%, #ffdd9c 47%, #f9b637 58%, #fb6c00 100%);
|
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)), linear-gradient(115deg, #e73f1e 0%, #fb6c00 30%, #ffdd9c 47%, #f9b637 58%, #fb6c00 100%);
|
||||||
border-color: #e68457;
|
border-color: var(--secret-border);
|
||||||
color: var(--primary-foreground);
|
color: var(--primary-foreground);
|
||||||
text-shadow: 0 1px rgb(255 255 255 / 35%);
|
text-shadow: 0 1px rgb(255 255 255 / 35%);
|
||||||
box-shadow: inset 0 1px rgb(255 255 255 / 45%), 0 0.45rem 1.2rem rgb(36 18 12 / 28%);
|
box-shadow: inset 0 1px rgb(255 255 255 / 45%), 0 0.45rem 1.2rem rgb(36 18 12 / 28%);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] :where([data-slot="card"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"]) {
|
:root[data-theme="secret"] :where([data-slot="card"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"]) {
|
||||||
border-color: color-mix(in oklch, var(--border) 72%, var(--primary));
|
border-color: var(--secret-border);
|
||||||
box-shadow: inset 0 1px color-mix(in oklch, white 8%, transparent), 0 1rem 3rem rgb(97 37 82 / 12%);
|
box-shadow: inset 0 1px color-mix(in oklch, white 8%, transparent), 0 1rem 3rem rgb(97 37 82 / 12%);
|
||||||
}
|
}
|
||||||
:root[data-theme="secret"] [data-slot="card"] {
|
:root[data-theme="secret"] [data-slot="card"] {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ export type ThemeDesign = {
|
||||||
density: number;
|
density: number;
|
||||||
borderWidth: number;
|
borderWidth: number;
|
||||||
shadowStrength: number;
|
shadowStrength: number;
|
||||||
surfaceContrast: number;
|
|
||||||
fontScale: number;
|
fontScale: number;
|
||||||
headingWeight: number;
|
headingWeight: number;
|
||||||
motion: number;
|
motion: number;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue