Commit Graph

94 Commits

Author SHA1 Message Date
Benjamin Canac 2484d9cf40 test: remove docs utils 2026-08-19 16:43:57 +02:00
Benjamin Canac 649a335247 Merge branch 'v4' into pr/6675 2026-08-19 16:04:17 +02:00
Benjamin Canac ccd48940fd test(components): fix path expectations on windows 2026-08-17 11:02:02 +02:00
Benjamin Canac 652d24c05d refactor(docs): persist the theme under one key
Every setting owned a localStorage key, sixteen of them, and two of those
were derived caches of the others. Restores could interleave, so the derived
stores each needed a self-heal to reconcile, and eight FOUC scripts each
re-read their own key and re-derived a slice of useTheme's style tags.

One key writes atomically, so those states cannot disagree. The style class
bundle and the custom-palette ramps are rebuilt from their source on load
instead of stored, which removes two of the three heals outright. Reads and
writes both live in the plugin, so no composable touches localStorage.

The nine keys the shipped picker wrote migrate once per browser.

Also groups the theme utils under utils/theme/, with the 646-line theme.ts
split by concern and theme-engine moved to utils/theme/engine.
2026-08-15 22:48:58 +02:00
Benjamin Canac 0fabbe5bc4 fix(theme): keep variants when replacing slot classes in app config (#6824) 2026-08-14 16:33:52 +02:00
Benjamin Canac 8c82637540 Merge branch 'v4' into docs/theme-studio-plan 2026-08-13 15:17:58 +02:00
Benjamin Canac 3a568b5e58 feat(vue): support experimental.componentDetection (#6731) 2026-08-13 11:54:43 +02:00
Benjamin Canac d041311968 Merge branch 'v4' into docs/theme-studio-plan 2026-08-11 17:39:21 +02:00
Benjamin Canac 3e89ea791b fix(theme): blank top-level base in applyUnstyled (#6825) 2026-08-11 14:53:34 +02:00
Mike Newbon 826b170422 feat(theme-studio): border colour picks a ramp, the tokens pick their stops
The border select and the token shades were painting different things: the
select emitted one --ui-border-color for every component ring, while the four
border tokens rode the neutral ramp no matter what it said. They are one
control now — the select names the ramp, each token owns its stop, and rings
follow the default token.

That collapses the option lists everywhere. A shade source names a ramp, so
the stops below it can express what Black, White, Inverted and a fixed Primary
used to be. All three treatments read Neutral / Primary, with Inherit only
where it still means something. A value a saved theme holds but the picker no
longer lists stays selectable rather than blanking the trigger.

Also: the landing hero's shimmer follows --ui-primary instead of ramp stops,
so black-as-primary no longer leaves it on the last palette; ?view= keeps the
preview across a reload; and the view grid folds into the switcher that was
its only caller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DBnE22R8HET4djqk1v5F41
2026-08-02 19:45:26 +02:00
Mike Newbon 21403dc7f3 refactor(theme-studio): improve comments for clarity
Updated comments across various components to enhance clarity and readability. Changes include rephrasing for better understanding and consistency in style. This refactor aims to make the codebase more maintainable and easier for future developers to navigate.
2026-08-02 19:20:34 +02:00
Mike Newbon 90744fd4dd Merge branch 'v4' into docs/theme-studio-plan 2026-08-02 14:36:14 +02:00
Benjamin Canac 4200e80c03 perf(components): memoize tv slot invocations with simple args (#6737) 2026-07-31 16:41:07 +02:00
Mike Newbon ef6760a060 refactor(theme-studio): fold compound variants that select the same variants
Successive treatments (a frame's ring, then a border colour) emitted one
compound entry each for the same variant, so an exported app.config.ts
listed 'solid' and 'soft' twice and leaned on tailwind-merge to resolve
them at runtime. Folding them at composition time renders identically and
shrinks the exports: 8-bit 656 -> 592 lines, neo-brutalist 693 -> 629,
marshmallow 289 -> 229.

The two tests that pinned the old shape now assert the invariant (one
entry per selector, colour last so it wins the merge) instead of exact
class strings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-29 22:51:59 +02:00
Mike Newbon b770a3401d refactor(theme-studio): keyboard-operable curves, lazy previews, drop dead code
The curve editor was pointer-only — its four handles are now focusable
role=slider elements: arrows nudge, shift takes a 10x step, home/end jump
to the window edges, and a run of keypresses commits once like a drag does.

Also: the nine non-default preview views load as async chunks instead of
bundling ~3.5k lines into the /theme route; the shade-slider logic that was
duplicated verbatim across ColorSection and TokenShades moves to
useTokenShades(); the theme-studio-dragging class and its timeout are gone
(no CSS ever defined it); and the color-parse test asserts idempotence
rather than byte-equality with tailwind's palette, which a patch bump breaks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-29 22:37:46 +02:00
Mike Newbon e4baec5283 Merge branch 'v4' into docs/theme-studio-plan 2026-07-29 22:08:06 +02:00
Mike Newbon b6a25be8d2 test(theme-studio): drop legacy shadow/border values from specs
vue-tsc (which CI runs over test/, unlike nuxi typecheck) caught the
literals the vocabulary removal left behind.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-29 21:37:13 +02:00
Mike Newbon 454582e012 refactor(theme-studio): trim comments, rename press/border vars, drop legacy vocabulary
Comment pass across the studio and engine (~800 comment lines removed,
keeping the one-line whys). Renames for readability: the press-effect
shadows are --ui-shadow-press/-half/-color (were hard/final-hard), the
inner color-mix is --ui-inner-shadow-mix, and the border recolor variable
is --ui-border-color (was frame-color). Shadow inherit is now spelled by
absence and the legacy 'none'/'soft'/'hard'/'bold'/'frame' values are gone
along with the localStorage migrations — the studio is unshipped, so
there is no persisted state to translate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-29 21:33:31 +02:00
renovate[bot] 282759e7c6 chore(deps): update nuxt framework (#6751)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2026-07-28 14:20:11 +02:00
Mike Newbon addd3cb417 fix(theme-studio): parse the CSS none keyword in oklch colors
tailwindcss 4.3.3 (already on v4, so PR merge runs resolve it) emits
CSS Color 4 missing components for achromatic stops — zinc-50 is now
oklch(98.5% 0 none) — which parseColor's numeric-only regex rejected,
crashing the zinc round-trip in CI. none reads as 0 for chroma/hue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 18:33:42 +02:00
Mike Newbon 5c0ff5516e feat(theme-studio): press-effect option, themed tabs, reset and staleness fixes
- Optional button press choreography (shadowPress) with a Style-panel
  switch; off for Marshmallow — soft blurred configs keep buttons still
- Pill tabs ride the theme: full-size drop shadow (matching buttons),
  inner shadow, and a border ring under any active border treatment;
  frame no longer double-outlines the indicator
- Strip the ramp shadow from the switch thumb under Custom
- Orchard/Marshmallow gain 1px custom borders; 1px widths now export
  (and so round-trip) explicitly
- Two-stage toolbar reset unjammed: font fingerprints treat explicit
  stock values as absent, and emptied style tags clear via a :root {}
  sentinel (unhead skips empty innerHTML patches)
- Recompute the persisted style-ui bundle on load so fragment changes
  shipped in code reach existing sessions
- Prune dead legacy shadow vars (final-soft, hard-lg/sm), keeping
  import tolerance for old exports

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 18:13:07 +02:00
Mike Newbon 204e2a80c1 refactor(theme-studio): collapse shadows into one Custom config
Replace the parallel soft/hard shadow machinery with a single studio-driven
Custom config (offset/blur/spread + opacity + colour), scaled per Tailwind
size by geometry with uniform alpha so the opacity slider reads true.

- Inherit leaves native Tailwind shadows untouched; Custom drives a gated
  --shadow-* ramp and None strips it, so content (prose images) now follows
  the theme. Exports emit the ramp as @theme tokens for the same reach.
- soft/hard fold into 'custom' (tolerated as legacy aliases, migrated on
  load). Presets migrated; bold ones set explicit opacity.
- Components: cards/alerts move up to shadow-lg; the button keeps its
  bespoke press-effect; overlays ride the ramp.
- Controls lead with the primary sliders; colour + shade sliders fold out
  last behind a toggle. Border shades relocate from Colors→Neutral into the
  Borders section via a shared ThemeStudioTokenShades component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 23:54:00 +02:00
Mike Newbon b98649fda4 fix(theme-studio): specs follow the stopStep API
The density model replaced `fineStops: boolean` with `stopStep: ShadeStep`
and dropped SHADES_FINE, but the specs kept calling the old signature.
Booleans coerce at runtime so the tests still passed; only vue-tsc caught
it, failing CI after lint went green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 13:13:13 +02:00
Mike Newbon f88a9c139d fix(theme-studio): stop stock ramps crashing the palette editor
paletteShades sampled the fine stop set against tailwind's JS colors, but a
stock ramp has no midpoints (150…850) — those lookups are undefined, and
parseColor threw on .trim() before the filter could drop them. The throw blew
up seedFromCurrent's watcher, so opening the editor on a default (stock) colour
failed and later applies stopped landing. Skip absent shades, and make
parseColor treat any non-string as unparseable rather than throwing.

Also fixes the contrastRatio test now that it returns number | null.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 03:41:17 +02:00
Mike Newbon ed71bb6237 fix(theme-studio): persist multi-pins and keep endpoints on the curve
Pin persistence was silently failing for every pin after the first: setPin
rebuilds the array from a deeply-reactive ref, so kept elements came back as
Vue proxies that toRaw() doesn't unwrap, and structuredClone threw
DataCloneError inside applyReactive — aborting the apply before it saved. A
plainPins() helper rebuilds each pin from its scalar fields so persistence
can't throw.

The curve editor's endpoint handles were drawn at the raw bézier control, so
a pin near the edge (or on it) pulled the corrected line away while the handle
stayed put — visibly detached. Endpoints now sit on the corrected curve; a
pinned endpoint is locked (the pin owns it) and dragging an unpinned one backs
out the RBF pull so it still tracks the pointer.

Also folds in the PR review batch:
- pin RBF: spacing-adaptive sigma + hue chain-unwrap (no white collapse / long
  hue arc), with regression tests
- self-heal no longer re-fires the primary setter every load
- resetSection preserves curves for untouched custom palettes
- external-sync guard compares pins and stop density, not just curves
- paletteShades samples fine stops; reactive per-seed hue window
- contrastRatio returns null instead of fabricating black
- midpoint tokens promote through parseUiColorRef
- SSR FOUC scripts and import/export parser hardened
- font name re-validated at the <style> sink

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 03:34:22 +02:00
Mike Newbon d7c359e79e feat(theme-studio): pinned brand colours, curve accuracy, drag performance
Pins:
- Lock stops to an exact OKLCH; the ramp bends through them via a localized
  RBF correction, so you can pin a brand colour and edit around it. Editable
  hex/rgb/oklch readouts, multi-pin, markers on the strip and curve.
- The curve editor draws the pin-corrected curve so the line rides through
  pinned stops and shows their pull on neighbours; every dot sits on the value
  its colour actually resolves to.

Performance (live curve drags):
- CSSOM fast path during a drag — write ramp vars straight to :root, skipping
  the stylesheet reparse, reactive re-inject and per-frame localStorage write;
  the reactive path reconciles once on release.
- content-visibility on off-screen grid tiles so a theme change only restyles
  what's visible (~60% fewer elements on the component wall).
- Colour field rendered on a canvas (small bitmap scaled with bilinear
  smoothing) instead of 24 SVG gradients behind a Gaussian blur — that filter
  was re-rasterised on every restyle (~7ms per apply).

Fixes:
- Undo/redo restores the palette editor's curves/pins (composite snapshot;
  proxy-safe clone) instead of leaving stale curves that clobber on the next edit.
- The editor now follows a preset's custom palette (e.g. 8-bit, Marshmallow
  neutrals) rather than resetting to blank grey defaults.
- No white flash between presets (reset skips the imperative <style> clear when
  a re-apply follows in the same tick).
- Dragging a curve endpoint carries its handle; stop picker moved to the
  Modifiers row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 02:15:33 +02:00
Mike Newbon 02a2c026e2 feat(theme-studio): add fine shade stops (150–850) to palette editor
Add an opt-in 19-stop ramp (the eight 100-step midpoints alongside
Tailwind's standard 11) selectable per custom palette via a dropdown in
the gradient square, and expose the midpoints to the token shade sliders.

Value-based stop positioning keeps the standard 11 byte-identical whether
fine or not. Midpoint tokens reference --color-custom-<ramp>-<mid>
directly (defined by @theme static) since the runtime plugin only emits
--ui-color-* for the standard stops — referencing those for a midpoint
dangled and rendered transparent.

Guard the transitions between modes: narrowing 19→11, clearing, or
switching to a stock ramp snaps any orphaned midpoint token back to the
nearest standard stop; seeding infers fine stops from a source palette's
midpoint keys so an imported fine ramp keeps them on edit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 21:21:37 +02:00
Mike Newbon 25c2808530 feat(theme-engine): enhance CSS generation for light and dark themes
- Introduced logic to restate library dark defaults for tokens overridden in light only, ensuring proper rendering in dark mode.
- Updated the import process to remove dark defaults that match light overrides, preventing unnecessary token growth during round-trips.
- Added tests to verify the correct behavior of CSS generation and token handling for light and dark themes.

These changes improve the consistency and efficiency of theme management, particularly in handling token overrides across different modes.
2026-07-17 18:22:45 +02:00
Benjamin Canac 333b3602a5 Merge branch 'v4' into docs/theme-studio-plan 2026-07-16 14:23:17 +02:00
Benjamin Canac 2a172ef187 fix(CommandPalette): always escape search highlight to prevent XSS (#6741) 2026-07-16 12:48:05 +02:00
Mike Newbon 9a238d000c refactor(docs): engine dedupe, dead-code sweep and white/black shade ladder
deriveStyle rides canonicalTokenShades; unused resolveToken(s)/createThemeDoc/
extends/curve/meta removed; SHADE_LADDER adds literal white/black slider ends
with honest resting defaults; shadow color select's Default merges into a
tagged Neutral shade, normalized in section fingerprints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 03:35:46 +02:00
Mike Newbon aed4e552b9 fix(docs): color-mode shortcut lands on ⌘⇧D; CI typecheck fix
macOS ships its Search-with-Google Service on ⌘⇧L, so pages never
receive that chord (verified with a capture listener — Meta and Shift
arrive, L never does). Bare Shift+D is a screen-reader landmark key.
⌘⇧D is a modifier chord pages can intercept (VS Code web proves it) and
only shadows Chrome's non-reserved bookmark-all-tabs.

The new import spec used property access on an untyped slots object —
the root vue-tsc pass in CI rejects it; compare with toEqual instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:02:21 +02:00
Mike Newbon aa34b532bf fix(docs): adversarial review pass over the full theme studio PR
Bugs:
- bootstrap ramps: all six 950 stops were copies of the 50 stop (regex
  slip during hex→oklch conversion); real shade-color(90%) values restored
- bootstrap palettes renamed bs-* — plain blue/gray shadowed the tailwind
  ramps app-wide (header preset apply recolored every text-blue-* in docs)
  and broke curve-editor seeding; light secondary now the true $gray-600
- shuffle() now applies the neutral white-literal remaps selectPalette
  uses — a shuffled tinted neutral exported a white-background theme
- resetTheme takes { track: false } so preset/import/shuffle/undo no
  longer pollute the Theme Reset analytics metric
- import: legacy ring-N scrubber gated on detection (ate user classes on
  config-only pastes; broke width-1 frame round-trips); non-custom-property
  declarations and nested at-rule blocks now land in `skipped` instead of
  importing as tokens; parseColor rejects truncated/alpha hex that fed NaN
  through the curve fitter
- ai.post.ts advertised sand/sage/ash neutrals that don't exist
- heading line-height defaults unified on 1.25 (slider claimed 1.5 while
  the page rendered ~1.25); AI ui.icons payloads skipped on the live path
- pinned swatch state reset on palette switch; curve editor drags only on
  the primary button; swatch details are a popover (keyboard-reachable
  copy/pin, pin survives outside clicks); Shift+D → ⌘⇧L (Notion
  convention, WCAG 2.1.4-safe); keep-panels scoped behind a prop so the
  header preset menu keeps stock modal dismiss
- Custom shadow opens seeded to the stock shadow-lg look (y6 blur12 @10%)

Bloat & noise:
- ThemeStudioControls: dead hydrationKey remount machinery removed;
  typography rows and shadow sections deduped through config arrays
  (~170 lines); five dead utility classes; orphaned docblocks rehomed
- 16 no-op preset token lines deleted; new tests forbid tokens equal to
  library defaults and 950 stops lighter than 50
- keepPanels shared from utils/theme.ts; plugin imports the storage-key
  constants; black-as-primary FOUC script gets tagPriority
- THEME_STUDIO_PLAN.md removed from the PR

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 16:54:28 +02:00
Mike Newbon da6cb0e9ad Merge branch 'v4' into docs/theme-studio-plan 2026-07-10 21:55:11 +02:00
Mike Newbon cf162ac981 feat(docs): typography system — weights, heading treatment and richer pickers
- ThemeDoc.font grows tailwind weight-step overrides (normal/medium/
  semibold/bold — live variables components dereference, so they restyle
  the whole UI), base uppercase/italic/tracking/leading, and a prose
  heading treatment (font, weight, italic, underline, case, tracking,
  leading) emitted as body and h1–h6 rules; import parses it all back,
  round-trip tested
- Preview rides one nuxt-ui-font-prefs channel (state, storage, FOUC
  script, plugin restore); Google Fonts links cover both families at
  300–800 (also the Comic Neue thinness fix)
- The Font panel becomes a type editor: live specimen atop the fold,
  Base and Headings rows with font selects previewing their own faces,
  and grouped icon toolbars — face [B I(U)], case [AB], rhythm [↔ ↕] —
  with sliders tucked in popovers; Icons fold leads with a 20-icon
  spread of the selected set; text size returns to Scale
- Comic Neue joins the font list

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:12:22 +02:00
Mike Newbon c762b41292 refactor(docs): enhance shadow handling and UI consistency in Theme Studio
- Updated shadow style options to include 'Inherit' and 'flat', improving clarity in shadow management.
- Refined inner shadow handling to streamline options and ensure consistent behavior across components.
- Removed unused local storage references for palette management, simplifying state handling.
- Adjusted UI elements in ThemeStudioControls for better interaction feedback and visual consistency.

These changes improve the overall user experience and maintainability of the theme studio.
2026-07-10 19:32:08 +02:00
Mike Newbon 0a4e8a81b7 feat(docs): strict color roles for v4, active fold triggers
- The pickers separate strictly per the module's v4 shade recipes:
  primary and semantic aliases offer only chromatic ramps, neutral only
  gray ramps — the neutral-as-primary path (picker row, alias redirect,
  mirror recipe, FOUC restore, import fold-back) comes out, parked for
  v5 where the variant redirect becomes possible
- Fold triggers light up while open (subtle active variant) across
  sections, token groups and the modifiers panel; the General panel's
  button/card/input default sections start collapsed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 17:27:09 +02:00
Mike Newbon f41c925f04 feat(docs): collapsible studio sections, reworked palette modifiers and toolbar polish
- Every settings section folds behind a ghost trigger button with a
  LEADING chevron (the disclosure cue that tells folds from selects);
  help links and the edit/shades toggles sit beside it as their own
  buttons — stopped clicks, with actions forcing a collapsed section
  open. Semantic regains its help link, closed by default
- Palette modifiers drop the preset dropdown for an always-there fold:
  an eye-labelled strength row plus the photo-editing quartet
  (lightness, contrast about the ramp midpoint, saturation as scale
  with an additive floor so grays respond, hue), all idempotent from
  the fitted base, with a reset beside the trigger
- Swatch clicks always really select: an active custom palette is
  cleared (curves, params, remaps) instead of silently reseeding, so
  the menu names the choice instead of a stale Custom
- Grid tiles become real UCards, inheriting panel default variants and
  style treatments; SIZE_SUPPORT widens to every xs–xl component (tabs,
  toggles, sliders, menus, calendar, field/form groups) with a
  round-trip test
- Toolbar: history/reset move to the right cluster, fullscreen caps the
  row, the color-mode switch caps the left cluster; slider readouts
  truncate with a title fallback and shave leading zeros; studio-wide
  text-xs/gap alignment; shade-slider fills keep a hairline inset ring
  so they never vanish into the panel background

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 17:21:42 +02:00
Mike Newbon cc54613a7a feat(docs): neutral-as-primary, leaner color controls and layered palette modifiers
- Primary offers a single full-width Neutral option mapping to the neutral
  ALIAS (#6608 semantics): the primary scale mirrors whatever neutral
  resolves to, live, with FOUC restore, export recipe and import round-trip
- Drop the docs-only ramps (sand/sage/ash/cocoa/marine) from main.css, the
  pickers and the engine; restore tailwind v4's own extra neutrals
  (taupe/mauve/mist/olive) — CSS-variable resolved, they're not in the
  tailwindcss/colors JS export
- Colors panel: shared ThemeStudioColorSection renders every alias (header
  row hosts the edit + adjust-shades toggles), semantic rows sit under one
  header, neutral's shade groups fold individually (closed by default)
- Palette modifiers: chroma presets gain a flat offset so gray ramps
  respond, plus a Custom mode layering lightness/contrast/saturation/
  chroma-offset/hue sliders over the fitted base
- Shade sliders keep a hairline inset ring so fills matching the panel
  background stay visible
- Toolbar buttons move to the default size (header picker stays sm);
  shared slider rows collapse into ThemeStudioSliderRow

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 16:12:40 +02:00
Mike Newbon c83fd13d17 fix(docs): adversarial review pass — history, fullscreen, palette and import hardening
History: undo/redo move the baseline synchronously (a second click
inside the debounce window dropped a state and duplicated redo
entries); align() invalidates the stacks when the theme changed while
no watcher was mounted; unmount flushes the pending capture instead of
dropping it.

Fullscreen: Esc leaves defineShortcuts (whose unconditional
preventDefault stopped every Reka layer on the page from closing) for
a plain listener that defers to visible dismissable layers — one press
closes the popover, the next exits. The toolbar reveal is proximity-
driven instead of an invisible click-eating overlay, and pins open
while any of its panels is open (their content portals to body, so
hover/focus-within alone retracted the bar under its own popovers).

Palette: the hue window stretches at seed to cover seam-crossing fits
(grabbing an out-of-window handle snapped the color); pointercancel no
longer throws through releasePointerCapture and strands the dragging
class; generatePalette clamps lightness (gamut clamp only searches
chroma); fitCurve survives empty input.

Engine: import puts style variables it cannot express back into the
token channel instead of silently destroying them (with a regression
test); picking Default on a per-group variant under an app-wide
variant now explodes the app-wide value into the other groups so it
actually wins; shadeSlider tolerates single-mode shade objects;
resetTheme clears the in-memory palette params it already cleared from
storage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 22:19:23 +02:00
Mike Newbon 8c0dc2f908 feat(docs): studio toolbar with setting popovers, split component defaults with color axis, UI-hiding fullscreen
The settings panel dissolves into one toolbar: presets, per-group
popovers (Colors/General/Style/Shades — ThemeStudioControls renders one
group per instance now), view picker, fullscreen, import/export and
history actions. Component defaults split into Button/Card/Input
sections, buttons and inputs gain a default-color axis (emitted as
defaultVariants.color, extracted group-wise on import, round-trip
tested), and Size joins Scale. Fullscreen hides all chrome — site
header included via shared state — with a peek-on-hover exit and Esc.
Icon-only import gets a tooltip; colors keep the grouped Semantic
section with ghost edit pencils.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:40:40 +02:00
Benjamin Canac dcf7cbc091 feat(unplugin): pre-bundle used icons into the Vue/Vite build (#6635)
Co-authored-by: Typed SIGTERM <145281501+typed-sigterm@users.noreply.github.com>
2026-07-07 15:26:58 +02:00
Mike Newbon 6ed248b597 refactor(docs): retire the border-width class machinery — widths ride the default-width variables everywhere
ringFragments and its five width maps (~200 lines), the frame width
enumeration, the widthAsVariables export/import split and every
var-length border/ring class in the preview markup are gone: the docs
build compiles --default-border-width/--default-ring-width onto the
studio variable, so live preview and exports use the same mechanism.
Legacy pastes get their width tokens scrubbed and frame literals
renormalized so old exports still import cleanly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:51:38 +02:00
Mike Newbon f5aa2efeb5 fix(docs): neo defaults from paste; sidebar dividers, dashboard sidebar edge and accordion frame follow border width
The dashboard sidebar's edge lives in its side variant, which tv applies
after config slot appends — only a compound override lands on top.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:35:53 +02:00
Mike Newbon 633fd8aaaa feat(docs): inner shadow gets its own color select and shade sliders, inheriting the drop color by default
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 18:42:15 +02:00
Mike Newbon 1a316fe796 feat(docs): inner shadow axis — inset treatment across the same surfaces, own geometry and opacity
Drop shadow section renamed to match. Studio chrome: Reset joins
Import/Export in the sidebar footer, mode picks are light/dark/system
buttons, the sidebar ring follows the theme border width, and the
collapsible help icons get their sizing back.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 18:32:39 +02:00
Mike Newbon 1c42cb0b30 feat(docs): Theme Studio becomes a fullscreen modal; simplified picker popover; hard shadows dedupe against stock classes
The /theme page is gone — the studio opens as a fullscreen modal from the
header popover, which slims down to presets + shuffle, primary/background
dropdowns, radius, color mode and the copy/export shortcuts.

Hard shadows now ride composed --ui-shadow-hard* variables via
shadow-(--var) utilities: tailwind-merge couldn't parse the old
shadow-[calc(...)] literals as shadows, so stock shadow-sm/lg classes on
overlays (popover, tooltip, dropdown) survived the merge and won on CSS
order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:44:29 +02:00
Mike Newbon 8642837b8f feat(docs): A11y view — live WCAG contrast matrix; contrast badge retired from the palette editor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:54:27 +02:00
Mike Newbon dc8e243459 feat(docs): border width sweep — full component coverage live, tailwind default-width variables in exports
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 02:01:19 +02:00
Mike Newbon bd6fc633fd feat(docs): border width reaches chrome edges, separators and dividers; frame covers tabs, chat bubbles and switches
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 01:41:39 +02:00