diff --git a/configurator/src/App.svelte b/configurator/src/App.svelte index 888f8b1c..1acb57b4 100644 --- a/configurator/src/App.svelte +++ b/configurator/src/App.svelte @@ -1,6 +1,7 @@ - -
-
{label}
-
- {#each presets as p (p.id)} - - {/each} -
-
diff --git a/configurator/src/components/panels/BordersPanel.svelte b/configurator/src/components/panels/BordersPanel.svelte index 292efcb9..67be49da 100644 --- a/configurator/src/components/panels/BordersPanel.svelte +++ b/configurator/src/components/panels/BordersPanel.svelte @@ -1,16 +1,13 @@
@@ -34,7 +76,7 @@ {#if overridesCount > 0} You have {overridesCount} active override{overridesCount !== 1 ? "s" : ""}. {:else} - Start by picking a theme preset below, or dive into any domain. + Pick any domain below to get started. {/if}

{#if overridesCount > 0} @@ -47,57 +89,99 @@ {/if}
- +
-
Theme presets
-
- {#each THEME_PRESETS.slice(0, 6) as theme (theme.id)} +
Token domains
+
+ {#each TOKEN_DOMAINS as d (d.id)} + {@const count = domainCount(d.id)} + {@const DomainIcon = d.icon} {/each}
-
- +
-
Token domains
+
Tools
- {#each DOMAIN_CARDS as d (d.id)} - {@const domainOverrides = Object.keys(overrides).filter((k) => k.includes(d.id.slice(0, 5))).length} - {@const DomainIcon = d.icon} + {#each TOOLS as t (t.id)} + {@const ToolIcon = t.icon} {/each}
+ + +
+
+
Saved themes
+ +
+ +
+ { if (e.key === "Enter") handleQuickSave(); }} + class="flex-1 min-w-0 bg-white/5 border border-white/10 rounded-lg px-2 py-1.5 text-[11px] text-slate-200 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500" + /> + +
+ + {#if savedThemes.length === 0} +

No saved themes yet. Configure tokens, then save.

+ {:else} +
+ {#each savedThemes.slice(0, 6) as theme (theme.id)} + + {/each} +
+ {/if} +
diff --git a/configurator/src/components/panels/MacrosPanel.svelte b/configurator/src/components/panels/MacrosPanel.svelte index c656af51..62203918 100644 --- a/configurator/src/components/panels/MacrosPanel.svelte +++ b/configurator/src/components/panels/MacrosPanel.svelte @@ -35,13 +35,13 @@ // Prose spacing knobs. Defaults reference space tokens — the numbers below are // the approximate resolved rem values, used only as the slider's idle position. const PROSE_SPACE = [ - { label: "Heading gap", token: "--sf-prose-heading-gap", def: 0.75, max: 3 }, - { label: "List gap", token: "--sf-prose-list-gap", def: 0.5, max: 2 }, - { label: "Block margin", token: "--sf-prose-block-margin", def: 1, max: 4 }, - { label: "Media margin", token: "--sf-prose-media-margin", def: 1, max: 4 }, - { label: "Figure margin", token: "--sf-prose-figure-margin", def: 1.5, max: 4 }, - { label: "Blockquote padding",token: "--sf-prose-blockquote-padding",def: 1, max: 3 }, - { label: "HR margin", token: "--sf-prose-hr-margin", def: 1.5, max: 4 }, + { label: "Heading gap", token: "--sf-prose-heading-gap", def: 0.75, max: 3, raw: "var(--sf-space-s)" }, + { label: "List gap", token: "--sf-prose-list-gap", def: 0.5, max: 2, raw: "var(--sf-space-xs)" }, + { label: "Block margin", token: "--sf-prose-block-margin", def: 1, max: 4, raw: "var(--sf-space-m)" }, + { label: "Media margin", token: "--sf-prose-media-margin", def: 1, max: 4, raw: "var(--sf-space-m)" }, + { label: "Figure margin", token: "--sf-prose-figure-margin", def: 1.5, max: 4, raw: "var(--sf-space-l)" }, + { label: "Blockquote padding",token: "--sf-prose-blockquote-padding",def: 1, max: 3, raw: "var(--sf-space-m)" }, + { label: "HR margin", token: "--sf-prose-hr-margin", def: 1.5, max: 4, raw: "var(--sf-space-l)" }, ]; let showFlow = $state(false); @@ -94,6 +94,9 @@ overridden={"--sf-flow-space" in overrides} onChange={(v) => onSet("--sf-flow-space", `${v}rem`)} onReset={() => onReset("--sf-flow-space")} + rawDefault="var(--sf-content-gap)" + currentRaw={overrides["--sf-flow-space"]} + onRawSet={(v) => onSet("--sf-flow-space", v)} />
{#each [0, 1, 2] as i (i)} @@ -191,6 +194,9 @@ overridden={"--sf-scroll-shadow-size" in overrides} onChange={(v) => onSet("--sf-scroll-shadow-size", `${v}rem`)} onReset={() => onReset("--sf-scroll-shadow-size")} + rawDefault="2rem" + currentRaw={overrides["--sf-scroll-shadow-size"]} + onRawSet={(v) => onSet("--sf-scroll-shadow-size", v)} />
onSet(t.token, `${v}rem`)} onReset={() => onReset(t.token)} + rawDefault={t.raw} + currentRaw={overrides[t.token]} + onRawSet={(v) => onSet(t.token, v)} /> {/each} onSet("--sf-prose-media-radius", `${v}px`)} onReset={() => onReset("--sf-prose-media-radius")} + rawDefault="var(--sf-radius-m)" + currentRaw={overrides["--sf-prose-media-radius"]} + onRawSet={(v) => onSet("--sf-prose-media-radius", v)} />
Marker color
diff --git a/configurator/src/components/panels/MotionPanel.svelte b/configurator/src/components/panels/MotionPanel.svelte index ccdffd5a..b24297da 100644 --- a/configurator/src/components/panels/MotionPanel.svelte +++ b/configurator/src/components/panels/MotionPanel.svelte @@ -19,54 +19,59 @@ ]; const EASINGS = [ - { label: "Linear", token: "--sf-ease-linear", value: "linear", preview: "M0,40 L40,0" }, - { label: "Ease out", token: "--sf-ease-out", value: "cubic-bezier(0.25, 0, 0.15, 1)", preview: "M0,40 C8,40 28,0 40,0" }, - { label: "Ease in", token: "--sf-ease-in", value: "cubic-bezier(0.5, 0, 0.75, 0.25)", preview: "M0,40 C12,40 32,32 40,0" }, - { label: "Ease in-out",token: "--sf-ease-in-out", value: "cubic-bezier(0.4, 0, 0.2, 1)", preview: "M0,40 C8,40 32,0 40,0" }, - { label: "Spring", token: "--sf-ease-spring", value: "linear(0, 0.5, 1.1, 0.95, 1.02, 1)", preview: "M0,40 C10,20 20,-4 28,-2 S38,2 40,0" }, + { label: "Linear", token: "--sf-ease-linear", value: "linear", preview: "M0,40 L40,0" }, + { label: "Ease out", token: "--sf-ease-out", value: "cubic-bezier(0.25, 0, 0.15, 1)", preview: "M0,40 C8,40 28,0 40,0" }, + { label: "Ease in", token: "--sf-ease-in", value: "cubic-bezier(0.5, 0, 0.75, 0.25)", preview: "M0,40 C12,40 32,32 40,0" }, + { label: "Ease in-out",token: "--sf-ease-in-out", value: "cubic-bezier(0.4, 0, 0.2, 1)", preview: "M0,40 C8,40 32,0 40,0" }, + { label: "Spring", token: "--sf-ease-spring", value: "linear(0, 0.5, 1.1, 0.95, 1.02, 1)", preview: "M0,40 C10,20 20,-4 28,-2 S38,2 40,0" }, { label: "Bounce", token: "--sf-ease-bounce", value: "linear(0, 0.35 18%, 1 32%, 0.86 42%, 1.02 56%, 0.98 72%, 1)", preview: "M0,40 L12,16 L20,0 L26,6 L32,-1 L36,1 L40,0" }, - { label: "Elastic", token: "--sf-ease-elastic", value: "linear(0, 0.3, 1.2, 0.9, 1.05, 1)", preview: "M0,40 C8,40 16,-10 24,-2 S36,2 40,0" }, - { label: "Overshoot", token: "--sf-ease-overshoot", value: "cubic-bezier(0.34, 1.56, 0.64, 1)", preview: "M0,40 C8,40 20,-10 40,0" }, + { label: "Elastic", token: "--sf-ease-elastic", value: "linear(0, 0.3, 1.2, 0.9, 1.05, 1)", preview: "M0,40 C8,40 16,-10 24,-2 S36,2 40,0" }, + { label: "Overshoot", token: "--sf-ease-overshoot", value: "linear(0, 0.6 30%, 1.08 55%, 0.98 75%, 1)", preview: "M0,40 C8,40 20,-10 40,0" }, ]; - // animation-delay-N base is 75ms * N; stagger base is 75ms const STAGGER_TOKENS = ["--sf-animation-delay-1","--sf-animation-delay-2","--sf-animation-delay-3","--sf-animation-delay-4","--sf-animation-delay-5"]; const knobs = KNOBS_BY_DOMAIN["motion"] ?? []; - let scale = $derived(parseFloat(overrides["--sf-motion-scale"] ?? "1")); + let scale = $derived((() => { const v = parseFloat(overrides["--sf-motion-scale"] ?? "1"); return isFinite(v) ? v : 1; })()); let motionDisabled = $derived(overrides["--sf-motion-scale"] === "0"); - let themeTransition = $derived(parseFloat(overrides["--sf-theme-transition-duration"]?.replace("ms","") ?? String(300 * scale))); + let themeTransition = $derived((() => { const v = parseFloat(overrides["--sf-theme-transition-duration"]?.replace("ms","") ?? String(300 * scale)); return isFinite(v) ? v : Math.round(300 * scale); })()); let staggerBase = $derived(() => { const raw = overrides[STAGGER_TOKENS[0]]; if (raw) return parseFloat(raw.replace("ms","")); return 75 * scale; }); - // Animation demo state + // Animation demo — user picks which easing + duration to feel. let animating = $state(false); let animOffsetX = $state(0); + let demoEase = $state("--sf-ease-out"); + let demoDuration = $state("--sf-duration-normal"); - let showGlobalScale = $state(false); - let showThemeTransition = $state(false); - let showDurationOverrides = $state(false); - let showStaggerBase = $state(false); - let showEasingCurves = $state(false); - let showAnimationDemo = $state(false); - let showDurationPreview = $state(false); - let showScrollTimeline = $state(false); + let showDurations = $state(false); + let showEasing = $state(false); + let showStagger = $state(false); + let showAdvanced = $state(false); function getDuration(token: string, base: number): number { const raw = overrides[token]; - if (raw) return parseFloat(raw); + if (raw) { + const parsed = parseFloat(raw); + if (isFinite(parsed)) return parsed; + } return Math.round(base * scale); } + function easeValue(token: string): string { + return overrides[token] ?? EASINGS.find((e) => e.token === token)?.value ?? "ease"; + } + function playDemo() { if (animating) return; + const base = DURATIONS.find((d) => d.token === demoDuration)?.base ?? 250; + const dur = getDuration(demoDuration, base); animating = true; animOffsetX = 180; - const dur = getDuration("--sf-duration-normal", 250); setTimeout(() => { animOffsetX = 0; setTimeout(() => { animating = false; }, dur); @@ -75,9 +80,7 @@ function setStaggerBase(baseMs: number) { const patch: Record = {}; - for (let i = 1; i <= 5; i++) { - patch[`--sf-animation-delay-${i}`] = `${Math.round(baseMs * i)}ms`; - } + for (let i = 1; i <= 5; i++) patch[`--sf-animation-delay-${i}`] = `${Math.round(baseMs * i)}ms`; onBulkChange(patch); } @@ -114,71 +117,66 @@ {#if motionDisabled}
-

Motion is disabled — duration sliders have no effect while scale is 0.

+

Motion is disabled — duration & easing have no effect while scale is 0.

{/if} - -
- - {#if showGlobalScale} -
- {#each knobs as k (k.name)} - val === null ? onReset(name) : onSet(name, val)} - /> - {/each} -
- {/if} -
- -
- - +
- - {#if showThemeTransition} - onSet("--sf-theme-transition-duration", `${v}ms`)} - onReset={() => onReset("--sf-theme-transition-duration")} - /> - {/if} +
Live preview
+
+
+
d.token === demoDuration)?.base ?? 250)}ms ${easeValue(demoEase)}`} + >
+
+
+ + + +
+
- -
+ +
- {#if showDurationOverrides} + {#if showDurations}

- Set absolute ms values to override the fluid scale calculation. + Named duration tokens. Drag to set an absolute ms value, overriding the global scale. {#if motionDisabled} (No effect while motion is disabled.){/if}

{#each DURATIONS as d (d.token)} @@ -195,22 +193,94 @@ onReset={() => onReset(d.token)} /> {/each} + +
+ {#each DURATIONS as d (d.label)} + {@const actual = getDuration(d.token, d.base)} +
+ {d.label} +
+
+
+ {actual}ms +
+ {/each} +
+ {/if} +
+ +
+ + +
+ + {#if showEasing} +

+ Edit the named easing tokens. Accepts any CSS timing function — + cubic-bezier(…) or + linear(…). Use “Live preview” above to feel a curve. +

+
+ {#each EASINGS as e (e.token)} + {@const isOverridden = e.token in overrides} +
+
+ + + +
+
+ {e.label} +
+ + {#if isOverridden} + + {/if} +
+
+ { + const v = (ev.target as HTMLInputElement).value.trim(); + v ? onSet(e.token, v) : onReset(e.token); + }} + class="w-full bg-white/5 border border-white/10 rounded px-1.5 py-1 text-[9px] font-mono text-slate-300 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500" + /> +
+
+
+ {/each} +
{/if}
- +
- {#if showStaggerBase} + {#if showStagger}

One slider sets all five stagger delays (delay-1 through delay-5 are multiples of this base).

@@ -229,7 +299,6 @@ onReset={resetStagger} />
-
{#each [1,2,3,4,5] as n (n)} {@const delayMs = Math.round(staggerBase() * n)} @@ -247,146 +316,65 @@
- -
+ +
- {#if showEasingCurves} -

- Customize the named easing tokens used throughout the design system. -

-
- {#each EASINGS as e (e.token)} - {@const isOverridden = e.token in overrides} -
-
- {e.label} - {#if isOverridden} - - {/if} -
- - - -
{e.token.replace("--sf-ease-", "")}
-
+ {#if showAdvanced} + +
+ {#each knobs as k (k.name)} + val === null ? onReset(name) : onSet(name, val)} + /> {/each}
- {/if} -
- -
- - -
- - {#if showAnimationDemo} -
-
-
-
- -
- {/if} -
-
- - -
- - {#if showScrollTimeline} -

- Default animation-range for scroll-driven animations using the .sf-scroll-timeline utility. -

- {#each [ - { label: "Range start", token: "--sf-scroll-timeline-range-start", placeholder: "entry 0%" }, - { label: "Range end", token: "--sf-scroll-timeline-range-end", placeholder: "cover 30%" }, - ] as r (r.token)} -
-
{r.label}
- { - const v = (e.target as HTMLInputElement).value.trim(); - v ? onSet(r.token, v) : onReset(r.token); - }} - class="flex-1 min-w-0 bg-white/5 border border-white/10 rounded px-1.5 py-1 text-[9px] font-mono text-slate-300 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500" - /> - {#if r.token in overrides} - - {/if} -
- {/each} - {/if} -
- -
+ + onSet("--sf-theme-transition-duration", `${v}ms`)} + onReset={() => onReset("--sf-theme-transition-duration")} + /> - -
- - {#if showDurationPreview} -
- {#each DURATIONS as d (d.label)} - {@const actual = getDuration(d.token, d.base)} -
- {d.label} -
-
-
- {actual}ms + +
+

+ Default animation-range for scroll-driven animations using the + .sf-scroll-timeline utility. +

+ {#each [ + { label: "Range start", token: "--sf-scroll-timeline-range-start", placeholder: "entry 0%" }, + { label: "Range end", token: "--sf-scroll-timeline-range-end", placeholder: "cover 30%" }, + ] as r (r.token)} +
+
{r.label}
+ { + const v = (e.target as HTMLInputElement).value.trim(); + v ? onSet(r.token, v) : onReset(r.token); + }} + class="flex-1 min-w-0 bg-white/5 border border-white/10 rounded px-1.5 py-1 text-[9px] font-mono text-slate-300 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500" + /> + {#if r.token in overrides} + + {/if}
{/each}
{/if} -
+
diff --git a/configurator/src/components/panels/ShadowsPanel.svelte b/configurator/src/components/panels/ShadowsPanel.svelte index 0f3da6ad..145d62bf 100644 --- a/configurator/src/components/panels/ShadowsPanel.svelte +++ b/configurator/src/components/panels/ShadowsPanel.svelte @@ -1,75 +1,54 @@
- - + +
+ {#each SHADOW_STEPS as step, i (step)} +
+
+ {step} +
+ {/each} +
- -
- - {#if showShadowAppearance} -
- {#each knobs as k (k.name)} - val === null ? onReset(name) : onSet(name, val)} - /> - {/each} -
- - onSet("--sf-shadow-lightness", String(v))} - onReset={() => onReset("--sf-shadow-lightness")} - /> - {/if} -
+ + onSet("--sf-shadow-lightness", String(v))} + onReset={() => onReset("--sf-shadow-lightness")} + />
@@ -148,33 +127,42 @@

Which brand color radiates the glow. Defaults to primary.

{/if} + + +
+
+
+ {#if glowDisabled} +

Glow disabled.

+ {/if} {/if}
- -
+ +
- {#if showElevationPreview} -
- {#each SHADOW_STEPS as step, i (step)} -
-
- {step} -
+ {#if showAdvanced} +
+ {#each knobs as k (k.name)} + val === null ? onReset(name) : onSet(name, val)} + /> {/each}
{/if} -
+
diff --git a/configurator/src/components/panels/SpacingPanel.svelte b/configurator/src/components/panels/SpacingPanel.svelte index 8a2945f1..6c0c226b 100644 --- a/configurator/src/components/panels/SpacingPanel.svelte +++ b/configurator/src/components/panels/SpacingPanel.svelte @@ -5,12 +5,11 @@ import SliderRow from '../inputs/SliderRow.svelte'; import ClampField from '../inputs/ClampField.svelte'; - let { overrides, onSet, onReset, onBulkChange }: { + let { overrides, onSet, onReset }: { tokens: SlashedToken[]; overrides: Record; onSet: (name: string, value: string) => void; onReset: (name: string) => void; - onBulkChange: (patch: Record) => void; } = $props(); const RATIO_PRESETS = [ @@ -21,12 +20,6 @@ { label: "Golden — 1.618", value: 1.618 }, ]; - const DENSITY_PRESETS = [ - { label: "Compact", desc: "Tight UI, data-heavy", patch: { "--sf-space-scale": "0.75", "--sf-section-scale": "0.7", "--sf-space-base-min": "0.75", "--sf-space-base-max": "1.25" } }, - { label: "Comfortable", desc: "Balanced — default", patch: { "--sf-space-scale": null as null, "--sf-section-scale": null as null, "--sf-space-base-min": null as null, "--sf-space-base-max": null as null } }, - { label: "Spacious", desc: "Generous, editorial", patch: { "--sf-space-scale": "1.3", "--sf-section-scale": "1.4", "--sf-space-base-min": "1.25", "--sf-space-base-max": "2.75" } }, - ]; - const SPACE_STEPS = ["2xs", "xs", "s", "m", "l", "xl", "2xl", "3xl", "4xl"]; const knobs = KNOBS_BY_DOMAIN["spacing"] ?? []; @@ -48,20 +41,35 @@ let vwMin = $derived(num("--sf-fluid-min-vw", 22.5)); let vwMax = $derived(num("--sf-fluid-max-vw", 90)); - let activeDensity = $derived(DENSITY_PRESETS.find((d) => - Object.entries(d.patch).every(([k, v]) => - v === null ? !(k in overrides) : overrides[k] === v - ) - )); - let showLayoutGap = $state(false); - let showDensityPresets = $state(false); let showModularScale = $state(false); - let showSpacePreview = $state(false); + let showAdvanced = $state(false);
+ +
+
Space scale preview
+
+ {#each SPACE_STEPS as step, i (step)} + {@const midBase = (baseMin + baseMax) / 2} + {@const ratio = (ratioMin + ratioMax) / 2} + {@const offset = i - 4} + {@const rawRem = offset >= 0 ? midBase * Math.pow(ratio, offset) : midBase / Math.pow(ratio, -offset)} + {@const scaled = rawRem * spaceScale} + {@const barWidth = Math.min(scaled * 28, 240)} +
+ {step} +
+ {scaled.toFixed(2)}rem +
+ {/each} +
+
+ +
+
- -
- - {#if showDensityPresets} -
- {#each DENSITY_PRESETS as d (d.label)} - - {/each} -
- {/if} -
- -
-
- -
+ +
- {#if showSpacePreview} -
- {#each SPACE_STEPS as step, i (step)} - {@const midBase = (baseMin + baseMax) / 2} - {@const ratio = (ratioMin + ratioMax) / 2} - {@const offset = i - 4} - {@const rawRem = offset >= 0 ? midBase * Math.pow(ratio, offset) : midBase / Math.pow(ratio, -offset)} - {@const scaled = rawRem * spaceScale} - {@const barWidth = Math.min(scaled * 28, 240)} -
- {step} -
- {scaled.toFixed(2)}rem -
+ {#if showAdvanced} +
+ {#each knobs as k (k.name)} + val === null ? onReset(name) : onSet(name, val)} + /> {/each}
{/if} diff --git a/configurator/src/components/panels/ThemesPanel.svelte b/configurator/src/components/panels/ThemesPanel.svelte index ae9c4548..8c3e5971 100644 --- a/configurator/src/components/panels/ThemesPanel.svelte +++ b/configurator/src/components/panels/ThemesPanel.svelte @@ -1,71 +1,139 @@
-
Theme presets
+
Themes

- Apply a curated set of overrides with one click. Existing overrides outside the theme's scope are preserved. + Save your current configuration as a named theme, then re-apply it any time. + Themes are stored in this browser.

-
- {#each THEME_PRESETS as theme (theme.id)} - {@const tokenCount = Object.keys(theme.overrides).length} -
-
- {theme.icon} -
-
{theme.name}
-
{theme.blurb}
-
- {#if theme.tags} - {#each theme.tags as tag (tag)} - {tag} - {/each} - {/if} - {#if tokenCount > 0} - {tokenCount} overrides - {/if} -
-
- -
+ +
+
Save current
+
+ { if (e.key === "Enter") handleSave(); }} + class="flex-1 min-w-0 bg-white/5 border border-white/10 rounded-lg px-2 py-1.5 text-[11px] text-slate-200 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500" + /> + +
+

+ {#if overridesCount === 0} + No active overrides yet — adjust some tokens first. + {:else} + Captures all {overridesCount} active override{overridesCount === 1 ? "" : "s"}. + {/if} +

+
- {#if tokenCount > 0} -
- {#each Object.entries(theme.overrides).slice(0, 5) as [k, v] (k)} -
- {#if k.includes("color") || k.includes("source")} -
+ +
+ {#if themes.length === 0} +
+

No saved themes yet.

+

Configure your tokens, then save them above.

+
+ {:else} + {#each themes as theme (theme.id)} + {@const tokenCount = Object.keys(theme.overrides).length} +
+
+ {theme.icon} +
+
+ {theme.name} + {#if activeId === theme.id} + {/if} - {k.replace("--sf-", "")}
- {/each} - {#if tokenCount > 5} - +{tokenCount - 5} more - {/if} +
{tokenCount} override{tokenCount === 1 ? "" : "s"}
+
+
+ + +
- {/if} -
- {/each} + + {#if tokenCount > 0} +
+ {#each Object.entries(theme.overrides).slice(0, 5) as [k, v] (k)} +
+ {#if k.includes("color") || k.includes("source")} +
+ {/if} + {k.replace("--sf-", "")} +
+ {/each} + {#if tokenCount > 5} + +{tokenCount - 5} more + {/if} +
+ {/if} +
+ {/each} + {/if}
+ + + {#if overridesCount > 0} + + {/if}
diff --git a/configurator/src/components/panels/TypographyPanel.svelte b/configurator/src/components/panels/TypographyPanel.svelte index 8d1fe2da..81870107 100644 --- a/configurator/src/components/panels/TypographyPanel.svelte +++ b/configurator/src/components/panels/TypographyPanel.svelte @@ -66,7 +66,7 @@ { label: "normal", value: "normal" }, ]; - const WEIGHT_OPTIONS = ["300","400","500","600","700","800"]; + const WEIGHT_OPTIONS = ["100","200","300","400","500","600","700","800","900"]; const WEIGHT_DEFAULTS: Record = { "--sf-font-weight-body": "400", "--sf-font-weight-heading": "600", @@ -166,6 +166,7 @@ let showBodyText = $state(false); let showDisplayType = $state(false); let showModularScale = $state(false); + let showScaleAdvanced = $state(false); let showScalePreview = $state(false); let showAdvancedType = $state(false); let showLineLengths = $state(false); @@ -195,7 +196,7 @@ const link = document.createElement("link"); link.id = id; link.rel = "stylesheet"; - link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fontName)}:wght@300;400;500;600;700&display=swap`; + link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fontName)}:wght@100;200;300;400;500;600;700;800;900&display=swap`; document.head.appendChild(link); } } @@ -759,17 +760,6 @@ onRatioMaxChange={(v) => onSet("--sf-text-ratio-max", String(v))} /> - -
- {#each knobs as k (k.name)} - val === null ? onReset(name) : onSet(name, val)} - /> - {/each} -
-
Line height scale
@@ -818,6 +808,29 @@ {/each}
+ + +
+ + {#if showScaleAdvanced} +
+ {#each knobs as k (k.name)} + val === null ? onReset(name) : onSet(name, val)} + /> + {/each} +
+ {/if} +
{/if}
diff --git a/configurator/src/components/shell/PreviewPanel.svelte b/configurator/src/components/shell/PreviewPanel.svelte index 5ff4aa24..378c0bb1 100644 --- a/configurator/src/components/shell/PreviewPanel.svelte +++ b/configurator/src/components/shell/PreviewPanel.svelte @@ -30,8 +30,6 @@ const TEMPLATES: { id: PreviewTemplate; label: string }[] = [ { id: "marketing", label: "Marketing" }, - { id: "docs", label: "Docs" }, - { id: "dashboard", label: "Dashboard" }, { id: "components", label: "Components" }, { id: "stylescape", label: "Stylescape" }, ]; @@ -240,59 +238,6 @@
`; - const DOCS_BODY = ` -
- -
-

Introduction

-

SLASHED is a CSS design-token framework built around ~840 custom properties.

-
npm install slashed
-
-
`; - - const DASHBOARD_BODY = ` -
- -
-
-
-
Revenue
-
$48.2k
-
↑ 12% vs last month
-
-
-
Users
-
12,431
-
↑ 8% vs last month
-
-
-
Conversions
-
3.6%
-
→ Flat
-
-
-
Tickets open
-
24
-
↑ 3 since yesterday
-
-
-
-
`; - const COMPONENTS_BODY = `

Component showcase

@@ -473,8 +418,6 @@ const BODIES: Record = { marketing: MARKETING_BODY, - docs: DOCS_BODY, - dashboard: DASHBOARD_BODY, components: COMPONENTS_BODY, stylescape: STYLESCAPE_BODY, }; @@ -616,13 +559,13 @@ ${BODIES[template]}
-
+
-
+
{#each TEMPLATES as t (t.id)}
-
+