From a60b4fe9611e0c24e2f8fad1eea9f05159440634 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Wed, 19 Aug 2026 23:35:41 +0000 Subject: [PATCH 1/3] feat(configurator): hide the preview on tool screens, give them full width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the lifecycle/reference tools — Changes, Presets, Install & export, Reference — the live preview sat there showing an irrelevant Color gallery over half the screen while the operation (export CSS, browse classes, review overrides) got a cramped 360px column. These screens now hide the preview entirely and let the panel take the full width (the CSS output, class catalogue and change list all benefit). The mobile Controls/Preview fold bar is hidden there too, since there's nothing to fold to. Accessibility deliberately keeps its preview — the contrast checker reads the rendered colours from the iframe. check, lint, 285 unit tests and shell e2e pass; screenshot + e2e verified the full-width tool layout and that token/Accessibility screens still show the preview. --- configurator/src/App.svelte | 65 ++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/configurator/src/App.svelte b/configurator/src/App.svelte index d8308f17..a3cd0b23 100644 --- a/configurator/src/App.svelte +++ b/configurator/src/App.svelte @@ -67,6 +67,16 @@ let previewMotion = $state<"normal" | "slow" | "none">("normal"); let previewTemplate = $state("color"); + // Lifecycle / reference tools have no live visual sample, so the preview used + // to sit there showing an irrelevant Color gallery over half the screen. + // For these the preview is hidden and the panel takes the full width instead. + // (Accessibility keeps the preview — its contrast checker reads the rendered + // colours from the iframe.) + const FULLWIDTH_DOMAINS = new Set(["changes", "themes", "setup", "cheatsheet"]); + let hidePreview = $derived(FULLWIDTH_DOMAINS.has(domain)); + // A tool screen has nothing to fold to, so keep the mobile view on controls. + $effect(() => { if (hidePreview) untrack(() => { mobileView = "controls"; }); }); + // Derived let overridesCount = $derived(Object.keys(overrides).length); let domainBadges = $derived(overridesByDomain(overrides)); @@ -317,11 +327,14 @@ -
- {@render foldToggleButton("controls", SlidersHorizontal, "Controls")} - {@render foldToggleButton("preview", Eye, "Preview")} -
+ visible without scrolling and doesn't compete with the status bar. + Hidden on tool screens, which have no preview to fold to. --> + {#if !hidePreview} +
+ {@render foldToggleButton("controls", SlidersHorizontal, "Controls")} + {@render foldToggleButton("preview", Eye, "Preview")} +
+ {/if}
@@ -334,10 +347,12 @@ />
- -
+ +
@@ -373,20 +388,24 @@
- -
- { previewTheme = t; }} - onWidthChange={(w) => { previewWidth = w; }} - onMotionChange={(m) => { previewMotion = m; }} - onTemplateChange={(t) => { previewTemplate = t; }} - /> -
+ + {#if !hidePreview} +
+ { previewTheme = t; }} + onWidthChange={(w) => { previewWidth = w; }} + onMotionChange={(m) => { previewMotion = m; }} + onTemplateChange={(t) => { previewTemplate = t; }} + /> +
+ {/if}
From 41101cb688aa09bfe08c8be55831c1532a7c9012 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Wed, 19 Aug 2026 23:44:48 +0000 Subject: [PATCH 2/3] feat(configurator): inline detached-scale notices for radius, border-width & motion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Type and Spacing panels already warn when concrete per-step overrides shadow their generated scale (making the scale knob inert). Radius, border-width and motion had the same failure mode with no warning — the audit flagged this gap. Reuse the existing ScaleShadowNotice, fed by tokenModel.scaleShadows(): - Shape: a notice above the Radius section (pinned --sf-radius-* steps) and in the Border widths section (pinned --sf-border-width-* steps). - Motion: a notice in the Durations section (absolute --sf-duration-* values that override the global --sf-motion-scale). Each offers "Clear them and use the scale" to restore the generated ladder. No new logic — the generalised detection already shipped in tokenModel (and the Changes panel); this surfaces it inline where the knobs live. check, lint, 285 unit tests and shell e2e pass; screenshot + e2e verified the radius and motion notices and that clearing restores the scale. Note: the broader migration of every panel SliderRow to the explicit Inherit/Value/Expression editor remains a separate follow-up — the generic All-tokens/Changes editor already uses ValueField, and SliderRow already supports a variable/raw escape hatch. --- .../src/components/panels/BordersPanel.svelte | 11 +++++++++++ configurator/src/components/panels/MotionPanel.svelte | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/configurator/src/components/panels/BordersPanel.svelte b/configurator/src/components/panels/BordersPanel.svelte index 52c8bbb9..d7b3e6ec 100644 --- a/configurator/src/components/panels/BordersPanel.svelte +++ b/configurator/src/components/panels/BordersPanel.svelte @@ -5,6 +5,8 @@ import ColorInput from '../inputs/ColorInput.svelte'; import Section from '../inputs/Section.svelte'; import { SPACE_SCALE, RADIUS_SCALE, BORDER_WIDTH_SCALE, type VarOption } from '../../lib/variableScales'; + import ScaleShadowNotice from '../inputs/ScaleShadowNotice.svelte'; + import { scaleShadows } from '../../lib/tokenModel'; let { overrides, onSet, onReset }: { overrides: Record; @@ -56,6 +58,13 @@ let dividerColor = $derived(overrides["--sf-divider-color"] ?? ""); let mediaRadius = $derived(parseNum(overrides["--sf-media-radius"]?.replace("rem",""), 0)); + // Fixed per-step overrides that shadow the radius / border-width scale knobs + // (the same detached-scale state the Type & Spacing panels already warn about; + // generalised here via tokenModel.scaleShadows). + let radiusShadow = $derived(scaleShadows(overrides).find((s) => s.family.id === "radius")?.shadowedSteps ?? []); + let borderShadow = $derived(scaleShadows(overrides).find((s) => s.family.id === "border-width")?.shadowedSteps ?? []); + const clearSteps = (steps: string[]) => steps.forEach(onReset); + function getStyleCurrent(tokenName: string, defaultVal: string): string { return overrides[tokenName] ?? defaultVal; } @@ -98,6 +107,7 @@
+ clearSteps(borderShadow)} />
Radius
+ clearSteps(radiusShadow)} />
diff --git a/configurator/src/components/panels/MotionPanel.svelte b/configurator/src/components/panels/MotionPanel.svelte index a8577fdc..efbdd3c5 100644 --- a/configurator/src/components/panels/MotionPanel.svelte +++ b/configurator/src/components/panels/MotionPanel.svelte @@ -4,6 +4,8 @@ import SliderRow from '../inputs/SliderRow.svelte'; import Toggle from '../inputs/Toggle.svelte'; import Section from '../inputs/Section.svelte'; + import ScaleShadowNotice from '../inputs/ScaleShadowNotice.svelte'; + import { scaleShadows } from '../../lib/tokenModel'; import { themeState } from '../../lib/theme.svelte'; //
@@ -422,6 +422,7 @@ onNavigate={(d, token) => { domain = d; if (token) { focusNonce += 1; focusRequest = { token, nonce: focusNonce }; } + else focusRequest = null; // On mobile, deep-linking into a token means we want the controls side. mobileView = "controls"; }} diff --git a/configurator/src/components/CommandPalette.svelte b/configurator/src/components/CommandPalette.svelte index 708a5ac1..bbd9c555 100644 --- a/configurator/src/components/CommandPalette.svelte +++ b/configurator/src/components/CommandPalette.svelte @@ -102,7 +102,7 @@
No matches for "{query}"
{:else} {#each results as r, i (r.kind === "nav" ? `nav:${r.id}` : `tok:${r.token.name}`)} - {#if i === 0} + {#if i === 0 && navCount > 0}
Go to
{/if} {#if r.kind === "token" && i === navCount}