diff --git a/src/app/styles/app.css b/src/app/styles/app.css index 60e21a4..adb7fe0 100644 --- a/src/app/styles/app.css +++ b/src/app/styles/app.css @@ -265,6 +265,21 @@ } } +@layer utilities { + /* 21× border-black/5 dark:border-white/10 → single token */ + .border-subtle { + @apply border-black/5 dark:border-white/10; + } + /* Secondary text pair */ + .text-secondary { + @apply text-neutral-500 dark:text-neutral-400; + } + /* Standard focus ring */ + .focus-ring { + @apply focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2; + } +} + /* Global utility - useful across your app */ @media (prefers-reduced-motion: reduce) { * { diff --git a/src/entities/Breadcrumb/ui/BreadcrumbHeader/BreadcrumbHeader.svelte b/src/entities/Breadcrumb/ui/BreadcrumbHeader/BreadcrumbHeader.svelte index 6eed8c5..f419995 100644 --- a/src/entities/Breadcrumb/ui/BreadcrumbHeader/BreadcrumbHeader.svelte +++ b/src/entities/Breadcrumb/ui/BreadcrumbHeader/BreadcrumbHeader.svelte @@ -44,7 +44,7 @@ function createButtonText(item: BreadcrumbItem) { flex items-center justify-between z-40 bg-surface/90 dark:bg-dark-bg/90 backdrop-blur-md - border-b border-black/5 dark:border-white/10 + border-b border-subtle " >
diff --git a/src/features/DisplayFont/ui/FontSampler/FontSampler.svelte b/src/features/DisplayFont/ui/FontSampler/FontSampler.svelte index 3b51dd0..15e8e79 100644 --- a/src/features/DisplayFont/ui/FontSampler/FontSampler.svelte +++ b/src/features/DisplayFont/ui/FontSampler/FontSampler.svelte @@ -59,7 +59,7 @@ const stats = $derived([ group relative w-full h-full bg-paper dark:bg-dark-card - border border-black/5 dark:border-white/10 + border border-subtle hover:border-brand dark:hover:border-brand hover:shadow-brand/10 hover:shadow-[5px_5px_0px_0px] @@ -76,7 +76,7 @@ const stats = $derived([ class=" flex items-center justify-between px-4 sm:px-5 md:px-6 py-3 sm:py-4 - border-b border-black/5 dark:border-white/10 + border-b border-subtle bg-paper dark:bg-dark-card " > @@ -145,7 +145,7 @@ const stats = $derived([
-
+
{#each stats as stat, i} {stat.label}:{stat.value} diff --git a/src/features/SetupFont/ui/TypographyMenu/TypographyMenu.svelte b/src/features/SetupFont/ui/TypographyMenu/TypographyMenu.svelte index 856d7d8..45540f2 100644 --- a/src/features/SetupFont/ui/TypographyMenu/TypographyMenu.svelte +++ b/src/features/SetupFont/ui/TypographyMenu/TypographyMenu.svelte @@ -79,7 +79,7 @@ $effect(() => { 'transition-colors duration-150', 'hover:bg-white/50 dark:hover:bg-white/5', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/30', - isOpen && 'bg-paper dark:bg-dark-card border-black/5 dark:border-white/10 shadow-sm', + isOpen && 'bg-paper dark:bg-dark-card border-subtle shadow-sm', className, )} > @@ -96,7 +96,7 @@ $effect(() => { class={cn( 'z-50 w-72', 'bg-surface dark:bg-dark-card', - 'border border-black/5 dark:border-white/10', + 'border border-subtle', 'shadow-[0_20px_40px_-10px_rgba(0,0,0,0.15)]', 'rounded-none p-4', 'data-[state=open]:animate-in data-[state=closed]:animate-out', @@ -109,7 +109,7 @@ $effect(() => { escapeKeydownBehavior="close" > -
+
{ class={cn( 'flex items-center gap-1 md:gap-2 p-1.5 md:p-2', 'bg-surface/95 dark:bg-dark-bg/95 backdrop-blur-xl', - 'border border-black/5 dark:border-white/10', + 'border border-subtle', 'shadow-[0_20px_40px_-10px_rgba(0,0,0,0.1)]', 'rounded-none ring-1 ring-black/5 dark:ring-white/5', )} > -
+
= { ), ghost: cn( 'bg-transparent', - 'text-neutral-500 dark:text-neutral-400', + 'text-secondary', 'border border-transparent', 'hover:bg-transparent dark:hover:bg-transparent', 'hover:text-brand dark:hover:text-brand', @@ -121,7 +121,7 @@ const variantStyles: Record = { ), icon: cn( 'bg-surface dark:bg-dark-bg', - 'text-neutral-500 dark:text-neutral-400', + 'text-secondary', 'border border-transparent', 'hover:bg-paper dark:hover:bg-paper', 'hover:text-brand', @@ -172,7 +172,7 @@ const activeStyles: Partial> = { 'bg-paper dark:bg-dark-card border-black/10 dark:border-white/10 shadow-sm text-neutral-900 dark:text-neutral-100', ghost: 'bg-transparent dark:bg-transparent text-brand dark:text-brand', outline: 'bg-surface dark:bg-paper border-brand', - icon: 'bg-paper dark:bg-paper text-brand border-black/5 dark:border-white/10', + icon: 'bg-paper dark:bg-paper text-brand border-subtle', }; const classes = $derived(cn( @@ -184,7 +184,7 @@ const classes = $derived(cn( 'select-none', 'outline-none', 'cursor-pointer', - 'focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2', + 'focus-ring', 'focus-visible:ring-offset-surface dark:focus-visible:ring-offset-dark-bg', 'disabled:cursor-not-allowed disabled:pointer-events-none', // Variant diff --git a/src/shared/ui/Button/ButtonGroup.svelte b/src/shared/ui/Button/ButtonGroup.svelte index fd06816..3e1881f 100644 --- a/src/shared/ui/Button/ButtonGroup.svelte +++ b/src/shared/ui/Button/ButtonGroup.svelte @@ -26,7 +26,7 @@ let { children, class: className, ...rest }: Props = $props(); class={cn( 'flex items-center gap-1 p-1', 'bg-surface dark:bg-dark-bg', - 'border border-black/5 dark:border-white/10', + 'border border-subtle', 'rounded-none', 'transition-colors duration-500', className, diff --git a/src/shared/ui/ComboControl/ComboControl.svelte b/src/shared/ui/ComboControl/ComboControl.svelte index 5750544..32d2276 100644 --- a/src/shared/ui/ComboControl/ComboControl.svelte +++ b/src/shared/ui/ComboControl/ComboControl.svelte @@ -93,9 +93,7 @@ const displayLabel = $derived(label ?? controlLabel ?? ''); step={control.step} orientation="horizontal" /> - + {formattedValue()}
@@ -129,7 +127,7 @@ const displayLabel = $derived(label ?? controlLabel ?? ''); 'border border-transparent', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/30', open - ? 'bg-paper dark:bg-dark-card shadow-sm border-black/5 dark:border-white/10' + ? 'bg-paper dark:bg-dark-card shadow-sm border-subtle' : 'hover:bg-paper/50 dark:hover:bg-dark-card/50', )} aria-label={controlLabel} @@ -157,7 +155,7 @@ const displayLabel = $derived(label ?? controlLabel ?? ''); diff --git a/src/shared/ui/ControlGroup/ControlGroup.svelte b/src/shared/ui/ControlGroup/ControlGroup.svelte index bfcde08..abe45b7 100644 --- a/src/shared/ui/ControlGroup/ControlGroup.svelte +++ b/src/shared/ui/ControlGroup/ControlGroup.svelte @@ -24,7 +24,7 @@ interface Props { const { label, children, class: className }: Props = $props(); -
+
{label}
diff --git a/src/shared/ui/Input/Input.svelte b/src/shared/ui/Input/Input.svelte index dd6db7d..c65b185 100644 --- a/src/shared/ui/Input/Input.svelte +++ b/src/shared/ui/Input/Input.svelte @@ -9,6 +9,10 @@ import type { Snippet } from 'svelte'; import { cubicOut } from 'svelte/easing'; import type { HTMLInputAttributes } from 'svelte/elements'; import { scale } from 'svelte/transition'; +import { + inputSizeConfig, + inputVariantConfig, +} from './config'; import type { InputSize, InputVariant, @@ -80,36 +84,11 @@ let { ...rest }: Props = $props(); -const sizeConfig: Record = { - sm: { input: 'px-3 py-1.5', text: 'text-sm', height: 'h-8', clearIcon: 12 }, - md: { input: 'px-4 py-2', text: 'text-base', height: 'h-10', clearIcon: 14 }, - lg: { input: 'px-4 py-3', text: 'text-lg md:text-xl', height: 'h-12', clearIcon: 16 }, - xl: { input: 'px-4 py-3', text: 'text-xl md:text-2xl', height: 'h-14', clearIcon: 18 }, -}; - -const variantConfig: Record = { - default: { - base: 'bg-paper dark:bg-paper border border-black/5 dark:border-white/10', - focus: 'focus:border-brand focus:ring-1 focus:ring-brand/20', - error: 'border-brand ring-1 ring-brand/20', - }, - underline: { - base: 'bg-transparent border-0 border-b border-neutral-300 dark:border-neutral-700', - focus: 'focus:border-brand', - error: 'border-brand', - }, - filled: { - base: 'bg-surface dark:bg-paper border border-transparent', - focus: 'focus:border-brand focus:ring-1 focus:ring-brand/20', - error: 'border-brand ring-1 ring-brand/20', - }, -}; - const hasValue = $derived(value !== undefined && value !== ''); const showClear = $derived(showClearButton && hasValue && !!onclear); const hasRightSlot = $derived(!!rightIcon || showClearButton); -const cfg = $derived(sizeConfig[size]); -const styles = $derived(variantConfig[variant]); +const cfg = $derived(inputSizeConfig[size]); +const styles = $derived(inputVariantConfig[variant]); const inputClasses = $derived(cn( 'font-primary rounded-none outline-none transition-all duration-200', @@ -170,7 +149,7 @@ const inputClasses = $derived(cn( {helperText} diff --git a/src/shared/ui/Input/config.ts b/src/shared/ui/Input/config.ts new file mode 100644 index 0000000..30964fe --- /dev/null +++ b/src/shared/ui/Input/config.ts @@ -0,0 +1,31 @@ +import type { + InputSize, + InputVariant, +} from './types'; + +/** Size-specific layout classes: padding, text size, height, and clear-icon pixel size. */ +export const inputSizeConfig: Record = { + sm: { input: 'px-3 py-1.5', text: 'text-sm', height: 'h-8', clearIcon: 12 }, + md: { input: 'px-4 py-2', text: 'text-base', height: 'h-10', clearIcon: 14 }, + lg: { input: 'px-4 py-3', text: 'text-lg md:text-xl', height: 'h-12', clearIcon: 16 }, + xl: { input: 'px-4 py-3', text: 'text-xl md:text-2xl', height: 'h-14', clearIcon: 18 }, +}; + +/** Variant-specific classes: base background/border, focus ring, and error state. */ +export const inputVariantConfig: Record = { + default: { + base: 'bg-paper dark:bg-paper border border-subtle', + focus: 'focus:border-brand focus:ring-1 focus:ring-brand/20', + error: 'border-brand ring-1 ring-brand/20', + }, + underline: { + base: 'bg-transparent border-0 border-b border-neutral-300 dark:border-neutral-700', + focus: 'focus:border-brand', + error: 'border-brand', + }, + filled: { + base: 'bg-surface dark:bg-paper border border-transparent', + focus: 'focus:border-brand focus:ring-1 focus:ring-brand/20', + error: 'border-brand ring-1 ring-brand/20', + }, +}; diff --git a/src/shared/ui/SidebarContainer/SidebarContainer.svelte b/src/shared/ui/SidebarContainer/SidebarContainer.svelte index e83c8d2..15932e2 100644 --- a/src/shared/ui/SidebarContainer/SidebarContainer.svelte +++ b/src/shared/ui/SidebarContainer/SidebarContainer.svelte @@ -84,7 +84,7 @@ function close() { 'overflow-hidden', 'will-change-[width]', 'transition-[width] duration-300 ease-out', - 'border-r border-black/5 dark:border-white/10', + 'border-r border-subtle', 'bg-surface dark:bg-dark-bg', isOpen ? 'w-80 opacity-100' : 'w-0 opacity-0', 'transition-[width,opacity] duration-300 ease-out', diff --git a/src/shared/ui/Slider/Slider.svelte b/src/shared/ui/Slider/Slider.svelte index 1b481bc..ce43c28 100644 --- a/src/shared/ui/Slider/Slider.svelte +++ b/src/shared/ui/Slider/Slider.svelte @@ -70,7 +70,7 @@ let { const isVertical = $derived(orientation === 'vertical'); const labelClasses = `font-mono text-[0.625rem] tabular-nums shrink-0 - text-neutral-500 dark:text-neutral-400 + text-secondary group-hover:text-neutral-700 dark:group-hover:text-neutral-300 transition-colors`; diff --git a/src/widgets/ComparisonView/ui/FontList/FontList.svelte b/src/widgets/ComparisonView/ui/FontList/FontList.svelte index cdbc293..7f67562 100644 --- a/src/widgets/ComparisonView/ui/FontList/FontList.svelte +++ b/src/widgets/ComparisonView/ui/FontList/FontList.svelte @@ -71,7 +71,7 @@ $effect(() => {
-
+
diff --git a/src/widgets/ComparisonView/ui/Header/Header.svelte b/src/widgets/ComparisonView/ui/Header/Header.svelte index 70f2fcc..3b2d98e 100644 --- a/src/widgets/ComparisonView/ui/Header/Header.svelte +++ b/src/widgets/ComparisonView/ui/Header/Header.svelte @@ -53,7 +53,7 @@ const fontBName = $derived(comparisonStore.fontB?.name ?? ''); 'flex items-center justify-between', 'px-4 md:px-8 py-4 md:py-6', 'h-16 md:h-20 z-20', - 'border-b border-black/5 dark:border-white/10', + 'border-b border-subtle', 'bg-surface dark:bg-dark-bg', className, )} diff --git a/src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte b/src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte index 85b52f9..22da262 100644 --- a/src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte +++ b/src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte @@ -44,7 +44,7 @@ let { 'flex flex-col h-full', 'w-80', 'bg-surface dark:bg-dark-bg', - 'border-r border-black/5 dark:border-white/10', + 'border-r border-subtle', 'transition-colors duration-500', className, )} @@ -53,7 +53,7 @@ let {
@@ -100,7 +100,7 @@ let { class=" shrink-0 p-6 bg-surface dark:bg-dark-bg - border-t border-black/5 dark:border-white/10 + border-t border-subtle z-10 " >