Appearance
Theme Polish & UI Fixes — 2026-03-28
Comprehensive changelog for all uncommitted changes. Covers theme tokenization, visual polish, accessibility fixes, and animation preset persistence.
Token System & Theming (theme.css)
New Tokens
--accent-revert/--accent-revert-subtle— added to all 5 themes. Used for template/preset "modified" indicators and revert actions. Distinct from--accent-warning(unsaved changes) in both meaning and color.- Dark themes get dedicated values (not aliased to
--branding-purple) for better contrast:- Dark:
#C084FC/#2d2440 - Nord:
#B48EAD/#3a3050 - Mocha:
#DDB6FE/#302548
- Dark:
- Light/Cavai:
var(--branding-purple)/var(--brand-purple-bg)
- Dark themes get dedicated values (not aliased to
--code-editor-bg— softened for light themes:oklch(30% 0.015 270)(light),oklch(30% 0.015 310)(cavai). Was too dark against light surfaces.
Token Adjustments
- Branding color scale tweaks across themes for better distinctiveness
- Code editor syntax highlighting updated in both CodeMirror (
theme-cavai-html.css) and Ace (theme-cavai-theme.js) themes
Accessibility & Contrast Fixes
Critical: Invisible Text
- RadioButton.vue — label color was
var(--border-subtle)→ changed tovar(--text-secondary). This caused near-invisible workspace dropdown text in light/cavai themes. - AddBlockTool / BlockButton — icon color used hardcoded
colors.grey85from legacy constants → removed, now inheritsvar(--text-primary)via CSS. Icons were invisible on light themes.
Shortcuts Dialog (ShortcutsDialog.vue, ShortcutCategory.vue, OsTypeToggle.vue)
- Card background:
var(--surface-raised) !important - Title:
var(--text-primary) - Close button:
var(--text-muted), hover →var(--text-primary) <kbd>elements: bg--surface-sunken, border--border-default, text--text-secondary- Table rows: transparent bg,
--surface-hoveron hover - Description text:
--text-primary(was--text-secondary) - OsTypeToggle: Aggressive Vuetify deep overrides to eliminate white backgrounds on Mac/Windows toggle buttons. Required overriding
.v-btn-toggle,.v-btn,.v-btn::before, and.v-iconat multiple levels with!important.
Visual Polish
AddBlockTool (AddBlockTool.vue, BlockButton.vue)
- Container shifted 2px left (
left: calc(#{$size-30} - 2px)) to cover the "Add block" button behind it - Container bg:
--surface-raised, border:--border-default - Block buttons: bg
--surface-active, separator borders between items - Label:
--surface-raisedbg with--text-primarytext - Removed legacy
colorsmixin and hardcoded color references
Code Editor (CodeMirrorEditor.vue)
- Horizontal alignment:
margin: $size-8 0(was$size-8all sides — misaligned with content above) - Added resize grip indicator: 3 diagonal stripes using
--border-strongvia CSS gradient, positioned bottom-right - Border:
1px solid var(--border-subtle), rounded with$border-radius-kilo
Template Revert (TemplateButton.vue)
- Modified dot: repositioned from right to left (
left: -1px; top: -1px), shrunk from 7×7 to 5×5px - Dot color:
var(--accent-revert)(was--accent-warning) - Revert button: bg
--accent-revert-subtle, text--accent-revert, border removed, rounded top corners ($border-radius-milli) - Triangle arrow pseudo-element: matches
--accent-revert-subtle
Animation Preset Revert (AnimationEffectList.vue)
- Unified with template revert styling:
- Dot:
left: -1px; top: -1px; 5×5px(wasleft: 3px; top: 3px; 3×3px) - Dot color:
var(--accent-revert)(was--accent-warning) - Revert button:
--accent-revert-subtlebg /--accent-reverttext (was--surface-raised/--text-secondary) - Border removed, rounded top with
$border-radius-milli - Triangle arrow updated to
--accent-revert-subtle
- Dot:
Configuration Panel (ConfigurationPanel.vue)
- Removed "Select a block to edit" empty state text (misleading — a base block is always default-selected, text was just a loading flash)
- Kept Bubbles mascot peek with
[data-theme="cavai"]scoping
HtmlSection
- Added
::v-deep .v-btn .v-icon { color: var(--text-secondary) !important; }for info tooltip icon consistency
Flow Editor
Branded Operator Borders (OperatorBase.vue)
- Changed branded operator outline from
solidtodashed:outline: 2px dashed ${resolvedColor} - First/starting operator retains
solidoutline via CSS class
Bug Fix: Animation Preset Revert Persistence
The revert preset button in animations didn't work after navigating away and back — the selected preset name was lost on component destroy.
Root cause: AnimationConfigCard didn't pass lastPreset prop to AnimationEffectList or listen for update:lastPreset. The value only lived in component local data().
Fix (4 files):
types.ts— addedlastPreset?: stringtoAnimationConfigtypedefaults.ts— addedlastPreset: ''toanimationDefaults()AnimationConfigCard.vue— wired:last-presetand@update:lastPresetthrough toAnimationEffectListconfigurationLogic.ts— added'update:lastPreset'listener that persists toanimation.lastPresetin block data
Broader Token Migration (from prior sessions, included in diff)
~71 files touched total. Key patterns applied across the codebase:
- Replaced all hardcoded hex colors with semantic tokens
- Replaced
colors.grey*/colors.*legacy constant usage with CSS custom properties - Added Vuetify deep overrides (
::v-deepwith!important) where framework inlines colors - Ensured all 5 themes render correctly (dark, light, cavai, nord, mocha)
Files touched (grouped by area)
Common components: Card, CardSection, ColorPicker, Dropdown, InputField, InputSelect, RadioButton, TextArea, ToggleSwitch, TooltipWrapper
Shortcuts: OsTypeToggle, ShortcutCategory, ShortcutsDialog
Creative Wizard: CreativeTypeIcon, SizePreset, TemplateRow
Builder Visuals — Blocks: AddBlockTool, BlockActionsMenu, BlockButton, BlockPanel
Builder Visuals — Configuration: ConfigurationPanel, AnimationConfigCard, AnimationEffectList, AnimationEffectRow, BoxShadowSection, CodeMirrorEditor, CustomCSSEditor, DelaySection, DurationSection, FilterSection, FontSizeSection, HtmlSection, IterationsSection, MarginSection, MultiPostfixInput, OverrideIndicator, PlaybackSection, PositionSection, RotationSection, SlideSection, SlideSectionsPagination, TabNavigation, TemplateButton, CustomBorderRadius
Builder Visuals — Configs: HtmlConfiguration, SliderConfiguration
Builder Visuals — Other: FormatSelector, PreviewFormatSelector, PreviewPanel
Flow editor: NodeLabel, brandingToolbarConstants, OperatorBase
Option rows: OptionRow, OptionInputField, OverrideControls
Builder Delivery: ImpressionPixelOptions, TagCode, VastOptions, VpaidOptions
Global styles: _components-builder.scss, _vuetify-reset.scss, theme.css
Code editors: theme-cavai-html.css, theme-cavai-theme.js
Mixins/logic: configurationLogic.ts
Types/defaults: types.ts, defaults.ts
Tokenization Rule
All component colors MUST use semantic tokens from theme.css. Never hardcode hex values or use legacy colors.* constants for themed UI. The only exception is primitives used in :root definitions.