Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
254 commits
Select commit Hold shift + click to select a range
4ba2c59
fix(docs): make palette editor opt-in and escapable
mikenewbon Jul 4, 2026
f2f8f50
fix(docs): match generated ramps to tailwind's color scale shape
mikenewbon Jul 4, 2026
19bdb2d
feat(docs): channel-curve palette editor with tailwind reverse-fitting
mikenewbon Jul 4, 2026
e3837d5
feat(docs): stream theme updates live while dragging curves
mikenewbon Jul 4, 2026
6135c97
feat(docs): neutral-50 light background baseline + tighter drag trans…
mikenewbon Jul 4, 2026
f14e176
fix(docs): keep dark mode background intact under the neutral-50 base…
mikenewbon Jul 4, 2026
6853b96
feat(docs): shadow/border style controls and neo-brutalist preset
mikenewbon Jul 5, 2026
89c27a2
fix(docs): make bold/hard borders win over variant ring colors
mikenewbon Jul 5, 2026
0a1a740
fix(docs): correct bold-border and hard-shadow semantics
mikenewbon Jul 5, 2026
41babb0
feat(docs): holistic style system, masonry bento, reference brutalist…
mikenewbon Jul 5, 2026
a3076dd
feat(docs): four new presets and a compact settings panel
mikenewbon Jul 5, 2026
c175d14
feat(docs): per-mode neutral shade picker for shadow color
mikenewbon Jul 5, 2026
a0267ff
feat(docs): per-mode shade sliders for borders and background, palett…
mikenewbon Jul 5, 2026
accd314
feat(docs): collapsible layout + presets hydrate the settings panel
mikenewbon Jul 5, 2026
c768509
feat(docs): semantic token shade sections and candy pastel offsets
mikenewbon Jul 5, 2026
8deeb3a
docs: mike takes the content tile
mikenewbon Jul 5, 2026
9ef31ed
refactor(docs): adversarial review fixes across the theme studio
mikenewbon Jul 5, 2026
f9a2eff
feat(docs): default variants, shadow geometry/opacity, accordion groups
mikenewbon Jul 5, 2026
e9c1a40
feat(docs): sidebar polish — mode tabs, single-open groups, ghost sec…
mikenewbon Jul 5, 2026
289b76d
fix(docs): flatten analytics payload to primitives for typecheck
mikenewbon Jul 5, 2026
43e212a
feat(docs): custom palettes, shuffle depth, offset effect slider
mikenewbon Jul 5, 2026
d7841ce
feat(docs): primary shade sliders, primary-ramp shadow/border shades,…
mikenewbon Jul 5, 2026
23f1fae
feat(docs): Cabin and Harbor presets on the studio's own palettes
mikenewbon Jul 5, 2026
2226402
feat(docs): oklch-native palette pipeline — generate, store and expor…
mikenewbon Jul 5, 2026
46f0307
feat(docs): flat ghost shadows, full token slider coverage, font-size…
mikenewbon Jul 5, 2026
573adca
feat(docs): Orchard preset — orange on a sculpted grove neutral, exer…
mikenewbon Jul 5, 2026
4cf1629
feat(docs): semantic palette pickers, Background rename, card-wrapped…
mikenewbon Jul 5, 2026
ae8cccb
feat(docs): inline palette-edit icons and custom curve editing for se…
mikenewbon Jul 5, 2026
1e55e36
fix(docs): update palette and color-parse specs to the oklch-native p…
mikenewbon Jul 5, 2026
a193edd
feat(docs): legend chips on every sidebar section, edit buttons group…
mikenewbon Jul 5, 2026
0096bd1
feat(docs): per-group variant options matching each component's real …
mikenewbon Jul 5, 2026
79975db
feat(docs): preview view tabs with template-faithful Dashboard and Ch…
mikenewbon Jul 5, 2026
8109504
feat(docs): theme importer — parse exported CSS/config back into edit…
mikenewbon Jul 5, 2026
35aeba8
fix(docs): border recoloring no longer repaints semantic outline/subt…
mikenewbon Jul 5, 2026
ae5864b
feat(docs): SaaS and Landing preview views from the real templates
mikenewbon Jul 5, 2026
2f72b57
fix(docs): audit fixes — input-family and overlay treatment coverage,…
mikenewbon Jul 5, 2026
0fe2768
feat(docs): section the palette pickers into Colors and Neutrals
mikenewbon Jul 5, 2026
7abd4da
fix(docs): resolve the mode tab selection after mount — SSR can't kno…
mikenewbon Jul 5, 2026
25bf100
feat(docs): resculpted Harbor preset and refreshed sand ramp
mikenewbon Jul 5, 2026
741f565
feat(docs): rework border controls — Default/None/Custom with a width…
mikenewbon Jul 5, 2026
fbf36f9
feat(docs): frame toggle under custom borders, matched option order, …
mikenewbon Jul 5, 2026
bd6fc63
feat(docs): border width reaches chrome edges, separators and divider…
mikenewbon Jul 5, 2026
971ed0e
feat(docs): studio chrome follows the border width too
mikenewbon Jul 5, 2026
dc8e243
feat(docs): border width sweep — full component coverage live, tailwi…
mikenewbon Jul 6, 2026
002fdf0
feat(docs): --studio-border-width variable scales all hand-rolled pre…
mikenewbon Jul 6, 2026
f853241
feat(docs): neo-brutalist rebuilt on the carbon neutral, art deco ret…
mikenewbon Jul 6, 2026
4e7beae
fix(docs): curve editor — fixed 1:1 axes, window-clamped drags, hue n…
mikenewbon Jul 6, 2026
4ce960d
fix(docs): dashboard panel children keep their height — flex was crus…
mikenewbon Jul 6, 2026
ddedd68
feat(docs): enhance ThemeStudioControls with preset swatches and new …
mikenewbon Jul 6, 2026
ccfdb13
fix(docs): dead semantic help link fataled the prerender; heap headro…
mikenewbon Jul 6, 2026
5a68c91
refactor(docs): drop skin classes and ui injections from studio contr…
mikenewbon Jul 6, 2026
8642837
feat(docs): A11y view — live WCAG contrast matrix; contrast badge ret…
mikenewbon Jul 6, 2026
58d9ff3
refactor(docs): sidebar sections on UCollapsible, clearer shade label…
mikenewbon Jul 6, 2026
1c42cb0
feat(docs): Theme Studio becomes a fullscreen modal; simplified picke…
mikenewbon Jul 6, 2026
2389a71
fix(docs): update ThemeStudioModal color to primary for improved visi…
mikenewbon Jul 6, 2026
e288b6b
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 6, 2026
ece3b31
feat(docs): studio toolbar spans the full modal width above the sidebar
mikenewbon Jul 6, 2026
918243b
feat(docs): settings panel on USidebar — offcanvas collapse, Import/E…
mikenewbon Jul 6, 2026
a0dc9f4
feat(docs): floating sidebar layout restored full-height; studio chro…
mikenewbon Jul 6, 2026
8081226
fix(docs): preview card owns its start margin so it keeps its inset w…
mikenewbon Jul 6, 2026
1a316fe
feat(docs): inner shadow axis — inset treatment across the same surfa…
mikenewbon Jul 6, 2026
633fd8a
feat(docs): inner shadow gets its own color select and shade sliders,…
mikenewbon Jul 6, 2026
bc11eca
fix(docs): restore the sidebar pe-0 / card-owned margin fix that regr…
mikenewbon Jul 6, 2026
2add887
feat(docs): Orchard resculpted — bottom-lit inner shadow on grove 500…
mikenewbon Jul 6, 2026
a072bda
feat(docs): logo and mode buttons move into the sidebar header, tinte…
mikenewbon Jul 6, 2026
f5aa2ef
fix(docs): neo defaults from paste; sidebar dividers, dashboard sideb…
mikenewbon Jul 6, 2026
3d481a9
feat(docs): default border/ring widths compile to the studio width va…
mikenewbon Jul 6, 2026
cbb3580
refactor(docs): unify sidebar and preview card shadow treatments; str…
mikenewbon Jul 6, 2026
a68fd61
refactor(docs): one ThemePickerColorMenu — the studio's sectioned swa…
mikenewbon Jul 6, 2026
a38cba0
feat(docs): Landing and SaaS previews faithful to the real templates …
mikenewbon Jul 6, 2026
1beaa02
fix(docs): landing polish — glass badge per template, pinned solid CT…
mikenewbon Jul 6, 2026
f54a676
feat(docs): ?studio query param — the open studio survives reloads an…
mikenewbon Jul 6, 2026
dc2cb7d
fix(docs): badge blur freed from the entrance animation's backdrop ro…
mikenewbon Jul 6, 2026
5b7c032
feat(docs): curve editor endpoints wear the ramp's 50 and 950 colors
mikenewbon Jul 6, 2026
ad2f3d5
fix(docs): sidebar slot rounding scoped to desktop — the mobile sheet…
mikenewbon Jul 6, 2026
6ed248b
refactor(docs): retire the border-width class machinery — widths ride…
mikenewbon Jul 6, 2026
fab9d64
feat(docs): undo/redo over theme documents — footer buttons plus cmd/…
mikenewbon Jul 6, 2026
3563264
refactor(docs): settings panel regrouped — Scale and Components join …
mikenewbon Jul 6, 2026
b07d353
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 6, 2026
b4fbd3b
fix(docs): type-safe undo snapshot getter — undefined before mount, n…
mikenewbon Jul 6, 2026
403045b
feat(docs): section legends are real buttons — label plus trailing ch…
mikenewbon Jul 6, 2026
fe8cda2
refactor(docs): adversarial review pass — shared components, hot-path…
mikenewbon Jul 6, 2026
3b4848e
refactor(docs): review tail — bento chat on real components, determin…
mikenewbon Jul 6, 2026
6aed6a5
feat(docs): Forest preset — sculpted evergreen and forest neutrals, s…
mikenewbon Jul 6, 2026
ab7c564
feat(docs): Anthropic preset on the real palette — brand clay anchore…
mikenewbon Jul 6, 2026
0f74982
fix(docs): update dark theme background color from neutral-950 to neu…
mikenewbon Jul 6, 2026
e300500
feat(docs): enhance Theme Studio components with size adjustments
mikenewbon Jul 7, 2026
2a4c480
feat(docs): settings panel moves right — close in its header, view dr…
mikenewbon Jul 7, 2026
d199582
feat(docs): sidebar refinement pass — inset panel with tuned padding,…
mikenewbon Jul 7, 2026
f9c5a99
feat(docs): Theme Studio becomes a left-edge drawer with a settings s…
mikenewbon Jul 7, 2026
2b34207
feat(docs): studio drawer from the right — settings strip snaps in, c…
mikenewbon Jul 7, 2026
2123304
feat(docs): Theme Studio returns as the /theme page
mikenewbon Jul 7, 2026
8c0dc2f
feat(docs): studio toolbar with setting popovers, split component def…
mikenewbon Jul 7, 2026
4658982
feat(docs): add UColorModeButton to theme page for improved color mod…
mikenewbon Jul 7, 2026
77dbc39
feat(docs): Marshmallow resculpted — pink-mauve custom neutral, pink-…
mikenewbon Jul 7, 2026
aaa0d5c
feat(docs): Anthropic restyle — cream page under ivory surfaces, blur…
mikenewbon Jul 7, 2026
b31b7b9
feat(docs): remove 'Forest' preset and update 'Marshmallow' with new …
mikenewbon Jul 7, 2026
853ab96
fix(docs): studio fullscreen state can't hide the chrome on other pages
mikenewbon Jul 7, 2026
ecc88fc
feat(docs): studio controls move into the site header on /theme
mikenewbon Jul 9, 2026
7b453d0
feat(docs): bottom toolbar, fullscreen floating bar, header view tabs
mikenewbon Jul 9, 2026
2045a34
refactor(docs): header view tabs move into the navigation menu's list…
mikenewbon Jul 9, 2026
7d6db7c
feat(docs): studio menu nests resources one level down
mikenewbon Jul 9, 2026
de1d29d
feat(docs): studio grid renders the landing playground masonry
mikenewbon Jul 9, 2026
25d257e
fix(docs): fullscreen toolbar gets container max-width and a taller r…
mikenewbon Jul 9, 2026
74fd8d0
fix(docs): adjust studio menu popover width for improved layout
mikenewbon Jul 9, 2026
7e5359b
feat(docs): palette curve editors get a live 2D color field background
mikenewbon Jul 9, 2026
c57e93d
feat(docs): smooth the curve editor color field, drop the grid lines
mikenewbon Jul 9, 2026
6ed2a48
fix(docs): curve editor field columns align fence-post with the plot
mikenewbon Jul 9, 2026
decb68e
fix(docs): playground prompt tile no longer steals focus on load
mikenewbon Jul 9, 2026
7bbe30f
feat(docs): slim theme popover on the header swatch button
mikenewbon Jul 9, 2026
37cdb2e
fix(docs): preset menu names the applied preset across reloads, says …
mikenewbon Jul 9, 2026
d7acb94
feat(docs): shades fold into the Colors popover
mikenewbon Jul 9, 2026
af1bcde
fix(docs): CodeRabbit review pass
mikenewbon Jul 9, 2026
c83fd13
fix(docs): adversarial review pass — history, fullscreen, palette and…
mikenewbon Jul 9, 2026
cc54613
feat(docs): neutral-as-primary, leaner color controls and layered pal…
mikenewbon Jul 10, 2026
f41c925
feat(docs): collapsible studio sections, reworked palette modifiers a…
mikenewbon Jul 10, 2026
0a4e8a8
feat(docs): strict color roles for v4, active fold triggers
mikenewbon Jul 10, 2026
55f32b7
fix(docs): adjust ThemeStudioColorMenu and ThemeStudioSection for imp…
mikenewbon Jul 10, 2026
daef31f
fix(docs): update button variant in ThemeStudioPaletteEditor for impr…
mikenewbon Jul 10, 2026
f9255a1
refactor(docs): consolidate the studio to fewer, stockier components
mikenewbon Jul 10, 2026
05af01c
refactor(docs): enhance theme studio with palette effects and UI impr…
mikenewbon Jul 10, 2026
c762b41
refactor(docs): enhance shadow handling and UI consistency in Theme S…
mikenewbon Jul 10, 2026
cf162ac
feat(docs): typography system — weights, heading treatment and richer…
mikenewbon Jul 10, 2026
eb9aa2a
fix(docs): adjust padding in theme.vue for improved layout consistency
mikenewbon Jul 10, 2026
8f7f28e
feat(docs): enhance ThemeStudioPaletteEditor with swatch tooltips and…
mikenewbon Jul 10, 2026
da6cb0e
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 10, 2026
274d1da
feat(docs): structured borders, richer icon sets and a Bootstrap 5 pr…
mikenewbon Jul 11, 2026
aa34b53
fix(docs): adversarial review pass over the full theme studio PR
mikenewbon Jul 11, 2026
aed4e55
fix(docs): color-mode shortcut lands on ⌘⇧D; CI typecheck fix
mikenewbon Jul 11, 2026
7684316
fix(docs): color-mode shortcut settles on ⌃⇧D
mikenewbon Jul 11, 2026
d8a729b
fix(docs): custom shadow seed visible at 20%, inherit clears the knobs
mikenewbon Jul 11, 2026
c89a698
feat(docs): playground grid rides a virtualized UScrollArea masonry
mikenewbon Jul 11, 2026
a033494
feat(docs): listbox-powered theme pickers
mikenewbon Jul 11, 2026
887d36a
fix(docs): refine theme studio components for improved usability
mikenewbon Jul 11, 2026
87a425d
feat(docs): enhance theme studio components with default values and s…
mikenewbon Jul 11, 2026
da65ac0
feat(docs): enhance Playground and Theme Studio components with new f…
mikenewbon Jul 11, 2026
ff6dba7
feat(docs): update PlaygroundContributors.vue to enhance contributor …
mikenewbon Jul 11, 2026
2bd89a0
feat(docs): enhance theme studio components with reset functionality
mikenewbon Jul 11, 2026
a72ef89
feat(docs): add reset functionality to theme.vue for improved theme m…
mikenewbon Jul 11, 2026
4617d2c
feat(docs): implement enhanced reset functionality across theme studi…
mikenewbon Jul 12, 2026
9a238d0
refactor(docs): engine dedupe, dead-code sweep and white/black shade …
mikenewbon Jul 12, 2026
b7dc498
refactor(docs): shared pickers and a three-way split for theme studio…
mikenewbon Jul 12, 2026
ce574fc
feat(docs): portfolio, changelog, docs and editor previews with a lis…
mikenewbon Jul 12, 2026
fda15c6
feat(docs): update ThemeStudioSection and ThemeStudioViewPortfolio wi…
mikenewbon Jul 12, 2026
876e371
fix(docs): refine header and theme studio components for improved cla…
mikenewbon Jul 12, 2026
69d0ea2
feat(docs): introduce ThemeStudioFontPicker and Google Fonts integration
mikenewbon Jul 14, 2026
0c492db
feat(docs): enhance header and theme studio views with image previews
mikenewbon Jul 14, 2026
35f42c6
feat(docs): refactor theme studio header and introduce new components
mikenewbon Jul 15, 2026
ba18c5b
feat(docs): enhance theme management with style token integration
mikenewbon Jul 15, 2026
328f23f
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 15, 2026
333b360
Merge branch 'v4' into docs/theme-studio-plan
benjamincanac Jul 16, 2026
6adf871
refactor(docs): simplify header and theme management logic
mikenewbon Jul 16, 2026
25c2808
feat(theme-engine): enhance CSS generation for light and dark themes
mikenewbon Jul 17, 2026
405bd59
fix(theme-studio): refine slider step behavior and tooltip functionality
mikenewbon Jul 20, 2026
6127af1
fix(theme-studio): improve slider value clamping and keyboard interac…
mikenewbon Jul 20, 2026
d7968cd
feat(docs/theme): pack-aware icons across the studio, plus fixes
mikenewbon Jul 20, 2026
02a2c02
feat(theme-studio): add fine shade stops (150–850) to palette editor
mikenewbon Jul 20, 2026
04342fb
refactor(theme-studio): update stop terminology and enhance layout
mikenewbon Jul 20, 2026
0d2bce3
refactor(theme-studio): optimize swatch handling and performance
mikenewbon Jul 21, 2026
d7c359e
feat(theme-studio): pinned brand colours, curve accuracy, drag perfor…
mikenewbon Jul 25, 2026
ed71bb6
fix(theme-studio): persist multi-pins and keep endpoints on the curve
mikenewbon Jul 25, 2026
f88a9c1
fix(theme-studio): stop stock ramps crashing the palette editor
mikenewbon Jul 25, 2026
217d9e4
refactor(theme-studio): improve swatch detail handling and animation
mikenewbon Jul 25, 2026
91eb659
feat(theme-studio): 25 and 10 shade intervals in the palette editor
mikenewbon Jul 25, 2026
80ef29d
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 25, 2026
b98649f
fix(theme-studio): specs follow the stopStep API
mikenewbon Jul 25, 2026
2a63b56
fix(theme-studio): apply shadow shade slider in custom mode; trim com…
mikenewbon Jul 25, 2026
1512426
feat(theme-studio): add button and badge variant color specifications
mikenewbon Jul 25, 2026
204e2a8
refactor(theme-studio): collapse shadows into one Custom config
mikenewbon Jul 25, 2026
5c0ff55
feat(theme-studio): press-effect option, themed tabs, reset and stale…
mikenewbon Jul 27, 2026
addd3cb
fix(theme-studio): parse the CSS none keyword in oklch colors
mikenewbon Jul 27, 2026
3a16fb8
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 27, 2026
454582e
refactor(theme-studio): trim comments, rename press/border vars, drop…
mikenewbon Jul 29, 2026
b6a25be
test(theme-studio): drop legacy shadow/border values from specs
mikenewbon Jul 29, 2026
e4baec5
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Jul 29, 2026
b770a34
refactor(theme-studio): keyboard-operable curves, lazy previews, drop…
mikenewbon Jul 29, 2026
ef6760a
refactor(theme-studio): fold compound variants that select the same v…
mikenewbon Jul 29, 2026
21938e3
docs(blog): add a WIP theme studio article
mikenewbon Jul 29, 2026
aeb5b56
refactor(theme-studio): split the presets listbox out of the menu
mikenewbon Aug 1, 2026
0a3476d
fix(theme-studio): header and picker feedback pass
mikenewbon Aug 1, 2026
b661e0b
fix(theme-studio): drop the shuffle die from the header picker
mikenewbon Aug 2, 2026
a89ad23
refactor(theme-studio): one settings panel, type and icons on the too…
mikenewbon Aug 2, 2026
c807089
fix(theme-studio): truncate picker labels, and apply the saved icon pack
mikenewbon Aug 2, 2026
55884e6
fix(theme-studio): apply the saved icon pack to appConfig after hydra…
mikenewbon Aug 2, 2026
eba3087
fix(theme-studio): gate the icon pack at its source; quieter picker t…
mikenewbon Aug 2, 2026
7a8dddf
feat(theme-studio): Options panel with a pack-aware icon, accented tr…
mikenewbon Aug 2, 2026
0ccf22b
refactor(theme-studio): preset button wears its preset; toolbar sheds…
mikenewbon Aug 2, 2026
a2ba282
fix(theme-studio): adjust UContainer class for fullscreen handling
mikenewbon Aug 2, 2026
179d17c
refactor(theme-studio): Defaults groups reuse the static section prim…
mikenewbon Aug 2, 2026
fefea9e
chore: ignore Playwright MCP scratch output
mikenewbon Aug 2, 2026
879bd1e
refactor(theme-studio): one ThemeStudioRow for every settings row
mikenewbon Aug 2, 2026
c5af27e
feat(theme-studio): shade rows become a row variant; sections nest pr…
mikenewbon Aug 2, 2026
40d4c87
refactor(theme-studio): depth drives section behaviour; one spacing s…
mikenewbon Aug 2, 2026
6d0d3ec
refactor(theme-studio): review pass — dedupe, dead code, stale strings
mikenewbon Aug 2, 2026
cce6a87
feat(theme-studio): toolbar owns font and icons, behind form fields
mikenewbon Aug 2, 2026
ef44811
fix(theme-studio): restore the picker size prop; toolbar opens the op…
mikenewbon Aug 2, 2026
ed5f915
refactor(theme-studio): split the die out of the preset menu
mikenewbon Aug 2, 2026
d2ec6e5
feat(theme-studio): even out 8-bit's ramp, and name both custom neutrals
mikenewbon Aug 2, 2026
90744fd
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Aug 2, 2026
3bfe61d
refactor(theme-studio): colors button back to stacked dots and one label
mikenewbon Aug 2, 2026
eb336e2
refactor(theme-studio): enhance ThemeStudioSection for improved layou…
mikenewbon Aug 2, 2026
071872e
fix(theme-studio): shade editors get their own section; scope the fir…
mikenewbon Aug 2, 2026
1c1c4e6
refactor(theme-studio): fold single-consumer wrappers back into their…
mikenewbon Aug 2, 2026
4817b34
refactor(theme-studio): font picker builds on the list picker
mikenewbon Aug 2, 2026
3a42b1b
refactor(theme-studio): shade groups own their dirty/reset
mikenewbon Aug 2, 2026
7a1a636
refactor(theme-studio): shadow, inner shadow and borders share one co…
mikenewbon Aug 2, 2026
390e230
feat(theme-studio): toolbar controls share one field, tooltipped when…
mikenewbon Aug 2, 2026
33e956d
refactor(theme-studio): the page composes, the composables behave
mikenewbon Aug 2, 2026
7520a62
fix(theme-studio): sub-sections stay open, and the closed fold stops …
mikenewbon Aug 2, 2026
f1fd731
fix(theme-studio): the shade fold breathes again when open
mikenewbon Aug 2, 2026
20ea495
fix(theme-studio): shade folds space off the control above them, smoo…
mikenewbon Aug 2, 2026
a317135
fix(theme-studio): folds clip while they animate; colour survives Inh…
mikenewbon Aug 2, 2026
6c23a56
revert(theme-studio): colour stays behind Custom
mikenewbon Aug 2, 2026
c1e91ba
fix(theme-studio): folds collapse all the way down
mikenewbon Aug 2, 2026
067de5f
fix(theme-studio): update UI styles for ThemeStudioRow component
mikenewbon Aug 2, 2026
8566b53
feat(theme-studio): toolbar order, sticky panels, and one less colour
mikenewbon Aug 2, 2026
bf9a32c
feat(theme-studio): white leaves the border colours too
mikenewbon Aug 2, 2026
c25536f
refactor(theme-studio): preset tiles are buttons, not hand-rolled ones
mikenewbon Aug 2, 2026
dd2d5c5
refactor(theme-studio): the theme popover is a card
mikenewbon Aug 2, 2026
f7b5191
style(theme-studio): toolbar buttons go ghost
mikenewbon Aug 2, 2026
6b4584e
refactor(theme-studio): the theme grid is a listbox, and the toolbar …
mikenewbon Aug 2, 2026
ea1e628
fix(theme-studio): the preset swatch styles need their own key
mikenewbon Aug 2, 2026
82870cd
refactor(theme-studio): dirty is a state, and the tile grid keeps onl…
mikenewbon Aug 2, 2026
892dce0
style(theme-studio): the view grid breathes
mikenewbon Aug 2, 2026
21403dc
refactor(theme-studio): improve comments for clarity
mikenewbon Aug 2, 2026
826b170
feat(theme-studio): border colour picks a ramp, the tokens pick their…
mikenewbon Aug 2, 2026
fe1269b
fix(theme-studio): keep the shade group's row type when it has no sli…
mikenewbon Aug 2, 2026
9f4b2f0
fix(theme-studio): the shade group defaults to an empty record, not u…
mikenewbon Aug 2, 2026
88a76ba
feat(theme-studio): enhance theme properties with class bindings
mikenewbon Aug 2, 2026
5a32606
Merge branch 'v4' into docs/theme-studio-plan
mikenewbon Aug 3, 2026
d041311
Merge branch 'v4' into docs/theme-studio-plan
benjamincanac Aug 11, 2026
8c82637
Merge branch 'v4' into docs/theme-studio-plan
benjamincanac Aug 13, 2026
dd7037b
chore: theme studio review cleanup
benjamincanac Aug 13, 2026
068a6d3
refactor(docs): de-brand theme presets
benjamincanac Aug 14, 2026
0297891
feat(docs): rework the header theme popover
benjamincanac Aug 14, 2026
9cc9378
feat(docs): toggle dark mode with the 'd' shortcut
benjamincanac Aug 14, 2026
061f0ec
feat(docs): let the AI chat apply theme presets
benjamincanac Aug 14, 2026
cda6d50
refactor(docs): font and icon toolbar controls become direct selects
benjamincanac Aug 14, 2026
f6afcfd
fix(docs): reset when a persisted preset no longer exists
benjamincanac Aug 14, 2026
d6fd659
feat(docs): extend the radius range to 0.75rem
benjamincanac Aug 14, 2026
ffbc217
refactor(docs): rename the Grid preview to Components
benjamincanac Aug 14, 2026
0673ae6
docs: playground and studio control tweaks
benjamincanac Aug 14, 2026
652d24c
refactor(docs): persist the theme under one key
benjamincanac Aug 15, 2026
649a335
Merge branch 'v4' into pr/6675
benjamincanac Aug 19, 2026
2484d9c
test: remove docs utils
benjamincanac Aug 19, 2026
864bb55
refactor(docs): drop the theme studio's shadow and border axes
benjamincanac Aug 19, 2026
4d53f08
docs(blog): remove article for now
benjamincanac Aug 19, 2026
c3ac5ee
fix(docs): retune the presets' dark-mode borders
benjamincanac Aug 19, 2026
4dd6b45
refactor(docs): rework the theme studio toolbar
benjamincanac Aug 19, 2026
7d5a7f0
Merge branch 'v4' into pr/6675
benjamincanac Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions docs/app/app.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
<script setup lang="ts">
const route = useRoute()

const appConfig = useAppConfig()
const { style, link, color } = useTheme()

const colorMode = useColorMode()

// Bare `d`, site-wide since the color mode button sits in the header on every
// page. defineShortcuts disables single-key bindings while an input or a
// contenteditable is focused, so it never eats a typed 'd'. Reads `.value`,
// not `.preference`, so toggling out of `system` flips away from what's
// currently on screen rather than to it.
defineShortcuts({
d: () => (colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark')
})

const { data: navigation } = await useFetch('/api/navigation.json')

useHead({
Expand Down Expand Up @@ -32,6 +44,8 @@ useFaviconFromTheme()
const { rootNavigation, navigationByFramework } = useNavigation(navigation)

provide('navigation', rootNavigation)

const showLayout = computed(() => !route.path.startsWith('/examples') && route.path !== '/theme')
</script>

<template>
Expand All @@ -40,7 +54,7 @@ provide('navigation', rootNavigation)

<div class="flex">
<div class="flex-1 min-w-0" :class="[route.path.startsWith('/docs/') && 'root']">
<template v-if="!route.path.startsWith('/examples')">
<template v-if="showLayout">
<!-- <Banner /> -->

<Header />
Expand All @@ -50,7 +64,7 @@ provide('navigation', rootNavigation)
<NuxtPage />
</NuxtLayout>

<template v-if="!route.path.startsWith('/examples')">
<template v-if="showLayout">
<Footer />
</template>
</div>
Expand Down
26 changes: 26 additions & 0 deletions docs/app/assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
--container-8xl: 90rem;

--font-sans: 'Public Sans', sans-serif;
/* Tailwind's preflight wires --font-sans and --font-mono itself, nothing
consumes --font-serif. Defaulting it to the body stack keeps the heading
rule below inert until the studio sets a serif of its own. */
--font-serif: var(--font-sans);

--color-green-50: #EFFDF5;
--color-green-100: #D9FBE8;
Expand All @@ -30,6 +34,28 @@
--ui-container: var(--container-8xl);
}

/* The live counterpart of the export's heading rule, until v5 ships
--ui-font-heading. In `base` so `font-mono` on an h1 still wins. */
@layer base {
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-serif);
}
}

/* The theme studio floats its preview on a canvas recessed BEHIND the card,
so the two modes run opposite ways: a step down from white in light, past
--ui-bg in dark. Unlayered, to outrank the bg-default utility the Nuxt root
carries, and pointed at the neutral ramp so a themed palette reaches it. */
body.theme-studio,
body.theme-studio #__nuxt {
background-color: var(--ui-color-neutral-100);
}

.dark body.theme-studio,
.dark body.theme-studio #__nuxt {
background-color: var(--ui-color-neutral-950);
}

html[data-framework="nuxt"] .vue-only,
html[data-framework="vue"] .nuxt-only {
display: none;
Expand Down
2 changes: 1 addition & 1 deletion docs/app/components/VersionMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const items = computed(() => {
variant="subtle"
:trailing-icon="appConfig.ui.icons.chevronDown"
size="xs"
class="-mb-[6px] font-semibold rounded-full truncate"
class="-mb-[6px] font-semibold rounded-xl truncate"
:class="[open && 'bg-primary/15']"
:ui="{
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined].filter(Boolean).join(' ')
Expand Down
16 changes: 15 additions & 1 deletion docs/app/components/chat/Chat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const { open, messages } = useChat()
const { open: searchOpen } = useContentSearch()
const { framework } = useFrameworks()
const { resetTheme, applyThemeSettings, hasCSSChanges, hasConfigChanges } = useTheme()
// A preset is a whole ThemeDoc, so it rides applyDoc (reset, style axis, class
// bundle) rather than the settings channel applyTheme uses.
const { presets, applyPreset } = useThemeStudio()

const hasThemeChanges = computed(() => hasCSSChanges.value || hasConfigChanges.value)

Expand All @@ -32,6 +35,13 @@ function processThemeToolCalls() {
if (name === 'applyTheme' && part.input) {
_themeApplied.add(part.toolCallId)
applyThemeSettings(part.input as DocsChatTools['applyTheme']['input'])
} else if (name === 'applyPreset' && part.input) {
_themeApplied.add(part.toolCallId)
const { preset: id } = part.input as DocsChatTools['applyPreset']['input']
// The model picks from an enum, but a renamed preset in a stale
// conversation would still resolve to nothing.
const preset = presets.find(entry => entry.id === id)
if (preset) applyPreset(preset)
} else if (name === 'resetTheme') {
_themeApplied.add(part.toolCallId)
resetTheme()
Expand Down Expand Up @@ -129,6 +139,9 @@ function getToolMessage(state: ToolState, toolName: string, input: Record<string
'getComponentTheme': `${readVerb} ${upperName(input.componentName || '')} theme`,
'getThemeGuide': `${readVerb} theme guide`,
'applyTheme': `${applyVerb} theme changes`,
// the preset's own name, upperName is for camelCase component ids and
// would render 'nuxt-ui' as 'NuxtUi'
'applyPreset': `${applyVerb} ${presets.find(preset => preset.id === input.preset)?.name ?? input.preset} preset`,
'resetTheme': `${state === 'output-available' ? 'Reset' : 'Resetting'} theme to defaults`
}[toolName] || `${searchVerb} ${toolName}`
}
Expand All @@ -154,6 +167,7 @@ function getToolIcon(part: ToolPart): string {
'getComponentTheme': 'i-lucide-file-text',
'getThemeGuide': 'i-lucide-palette',
'applyTheme': 'i-lucide-palette',
'applyPreset': 'i-lucide-palette',
'resetTheme': 'i-lucide-palette'
}

Expand Down Expand Up @@ -242,7 +256,7 @@ defineShortcuts({
icon="i-lucide-rotate-ccw"
color="neutral"
variant="ghost"
@click="resetTheme"
@click="resetTheme()"
/>
</UTooltip>

Expand Down
2 changes: 1 addition & 1 deletion docs/app/components/content/IconsTheme.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import json5 from 'json5'
import { themeIcons } from '../../utils/theme'
import { themeIcons } from '../../utils/theme/icons'

const { icon: iconSet } = useTheme()

Expand Down
11 changes: 9 additions & 2 deletions docs/app/components/header/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const route = useRoute()
const { desktopLinks } = useHeader()
const { open } = useChat()
const { track } = useAnalytics()
// The Ask-AI button skins to the applied icon pack, like the rest of the
// studio chrome (the theme applies site-wide, so this stays consistent).
const studioIcons = useStudioIcons()

function toggleChat() {
if (!open.value) {
Expand Down Expand Up @@ -39,13 +42,17 @@ function toggleChat() {
<UButton
color="neutral"
variant="ghost"
icon="i-lucide-bot-message-square"
:icon="studioIcons.assistant"
aria-label="Ask AI for help"
@click="toggleChat"
/>
</UTooltip>

<ThemePicker />
<ThemeStudioPicker />

<UTooltip text="Color mode">
<UColorModeButton variant="ghost" />
</UTooltip>

<UTooltip text="Open on GitHub" class="hidden lg:flex">
<UButton
Expand Down
96 changes: 96 additions & 0 deletions docs/app/components/playground/Playground.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<script setup lang="ts">
import {
PlaygroundInput,
PlaygroundCommandPalette,
PlaygroundCalendar,
// PlaygroundButtons,
PlaygroundNotifications,
PlaygroundTransactions,
PlaygroundTransferFunds,
PlaygroundInviteTeam,
PlaygroundAnalytics,
PlaygroundPinInput,
// PlaygroundBadges,
PlaygroundDashboard,
PlaygroundReportBug,
PlaygroundGoal,
PlaygroundSavingsTargets,
// PlaygroundTypography,
PlaygroundShortcuts,
PlaygroundNavigation,
// PlaygroundColorPicker,
PlaygroundEmpty,
PlaygroundAnnouncement,
PlaygroundTabs,
PlaygroundContributors,
PlaygroundAuthForm,
PlaygroundPrompt
} from '#components'

// Live, interactive component showcase, the Theme Studio's grid view, laid
// out as a virtualized masonry (UScrollArea lanes) of content-sized cards à
// la shadcn/HeroUI. Each tile is a self-contained, product-like block
// (header + body + footer action). Overlays are only shown embedded in
// richer examples (command palette, dashboard dropdown, select menus, auth
// form, chat), never as bare triggers.
const tiles = [
{ name: 'input', component: PlaygroundInput },
{ name: 'command-palette', component: PlaygroundCommandPalette },
{ name: 'calendar', component: PlaygroundCalendar },
// { name: 'buttons', component: PlaygroundButtons },
{ name: 'notifications', component: PlaygroundNotifications },
{ name: 'transactions', component: PlaygroundTransactions },
{ name: 'transfer-funds', component: PlaygroundTransferFunds },
{ name: 'invite-team', component: PlaygroundInviteTeam },
{ name: 'analytics', component: PlaygroundAnalytics },
{ name: 'pin-input', component: PlaygroundPinInput },
// { name: 'badges', component: PlaygroundBadges },
{ name: 'dashboard', component: PlaygroundDashboard },
{ name: 'report-bug', component: PlaygroundReportBug },
{ name: 'goal', component: PlaygroundGoal },
{ name: 'savings-targets', component: PlaygroundSavingsTargets },
// { name: 'typography', component: PlaygroundTypography },
{ name: 'shortcuts', component: PlaygroundShortcuts },
{ name: 'navigation', component: PlaygroundNavigation },
// { name: 'color-picker', component: PlaygroundColorPicker },
{ name: 'empty', component: PlaygroundEmpty },
{ name: 'announcement', component: PlaygroundAnnouncement },
{ name: 'tabs', component: PlaygroundTabs },
{ name: 'contributors', component: PlaygroundContributors },
{ name: 'auth-form', component: PlaygroundAuthForm },
{ name: 'prompt', component: PlaygroundPrompt }
]

// Lanes follow the CONTAINER, not the viewport, the preview pane changes
// width with fullscreen. Tile count follows lanes (the old per-breakpoint
// reveal) so narrow layouts aren't one endless column.
const scrollArea = useTemplateRef('scrollArea')
const { width } = useElementSize(computed(() => scrollArea.value?.$el))
const lanes = computed(() => width.value >= 1200 ? 4 : width.value >= 900 ? 3 : width.value >= 600 ? 2 : 1)

const REVEAL_COUNTS = [6, 12, 19, tiles.length] as const
const visibleTiles = computed(() => tiles.slice(0, REVEAL_COUNTS[lanes.value - 1]))
</script>

<template>
<UScrollArea
ref="scrollArea"
:items="visibleTiles"
:virtualize="{
lanes,
gap: 16,
estimateSize: 360,
paddingStart: 24,
paddingEnd: 24,
overscan: 0,
getItemKey: (index: number) => visibleTiles[index]!.name
}"
class="playground-grid h-full px-4 sm:px-6"
>
<template #default="{ item }">
<PlaygroundCard>
<component :is="item.component" />
</PlaygroundCard>
</template>
</UScrollArea>
</template>
39 changes: 39 additions & 0 deletions docs/app/components/playground/PlaygroundAnalytics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script setup lang="ts">
const extra = useStudioExtraIcons()
const bars = [40, 65, 52, 80, 60, 95, 72]
const days = ['M', 'T', 'W', 'T', 'F', 'S', 'S']
</script>

<template>
<div class="p-4 space-y-4">
<div class="flex items-start justify-between">
<div>
<p class="text-sm text-muted">
Visitors
</p>
<p class="text-2xl font-semibold text-highlighted">
418.2K
</p>
</div>
<UBadge color="success" variant="subtle" size="sm" :icon="extra.trendingUp">
+10%
</UBadge>
</div>

<div>
<div class="flex items-end gap-1.5 h-24">
<div
v-for="(bar, index) in bars"
:key="index"
class="flex-1 rounded-t-sm bg-primary/80 transition-colors hover:bg-primary"
:style="{ height: `${bar}%` }"
/>
</div>
<div class="flex gap-1.5 mt-1.5">
<span v-for="(day, index) in days" :key="index" class="flex-1 text-center text-xs text-muted">
{{ day }}
</span>
</div>
</div>
</div>
</template>
33 changes: 33 additions & 0 deletions docs/app/components/playground/PlaygroundAnnouncement.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script setup lang="ts">
const appConfig = useAppConfig()
const toast = useToast()
</script>

<template>
<div>
<div class="p-4 flex items-start gap-3">
<div class="flex items-center justify-center size-9 rounded-lg bg-elevated text-primary shrink-0">
<UIcon name="i-lucide-radar" class="size-5" />
</div>
<div>
<p class="font-semibold text-highlighted">
Observability Plus
</p>
<p class="text-sm text-muted">
A faster, natural-language way to explore your data. Monitoring moves to the Pro plan in 2026.
</p>
</div>
</div>

<div class="flex items-center justify-end gap-2 border-t border-default p-3">
<UButton label="Dismiss" color="neutral" variant="ghost" />
<UButton
label="Learn more"
color="neutral"
variant="subtle"
:trailing-icon="appConfig.ui.icons.arrowRight"
@click="toast.add({ title: 'Observability Plus' })"
/>
</div>
</div>
</template>
Loading
Loading