Skip to content

Token Adoption & Vuetify Color Cleanup — Implementation Plan

For agentic workers: REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Eliminate all hardcoded Vuetify color props and hex accent colors so every theme (dark/light/cavai) renders correctly without manual color overrides.

Architecture: Remove all color="primary" Vuetify props and hardcoded blue hex values. Replace with CSS classes that reference --accent-primary and other semantic tokens. Extend _vuetify-reset.scss to cover remaining Vuetify color leakage. Tune Cavai theme surface tokens.

Tech Stack: CSS custom properties, SCSS, Vue 2 templates


Chunk 1: Vuetify Primary Color Removal

Task 1: Remove Vuetify runtime theme override in PageBase

Files:

  • Modify: src/components/layout/PageBase.vue:621

  • [ ] Step 1: Remove the hardcoded Vuetify theme override

Delete this line from the mounted() hook:

typescript
this.$vuetify.theme.themes.light.primary = '#0C9CCC'
  • [ ] Step 2: Verify app loads without errors

Run: npm run dev, open browser, confirm no console errors related to Vuetify theme.

  • [ ] Step 3: Commit
bash
git add src/components/layout/PageBase.vue
git commit -m "remove hardcoded Vuetify primary color override"

Task 2: Add Vuetify primary button/progress/icon resets to _vuetify-reset.scss

Files:

  • Modify: src/styles/_vuetify-reset.scss (append after line 170)

  • [ ] Step 1: Add primary color resets

Append to _vuetify-reset.scss:

scss
// Primary color resets — replace Vuetify's internal primary with token
.theme--light.v-btn.primary,
.theme--light .v-btn.primary {
  background-color: var(--accent-primary) !important;
  border-color: var(--accent-primary) !important;
  color: var(--primitive-white) !important;
}

.theme--light.v-btn.primary--text,
.theme--light .v-btn.primary--text,
.theme--light .v-btn.v-btn--text.primary--text {
  color: var(--accent-primary) !important;
  background-color: transparent !important;
}

// Progress indicators using primary
.theme--light .v-progress-circular .v-progress-circular__overlay {
  stroke: var(--accent-primary);
}
.theme--light .v-progress-linear .v-progress-linear__determinate,
.theme--light .v-progress-linear .v-progress-linear__indeterminate .long,
.theme--light .v-progress-linear .v-progress-linear__indeterminate .short {
  background-color: var(--accent-primary) !important;
}

// Warning chip resets — use token instead of Vuetify amber
.theme--light.v-chip.warning {
  background-color: var(--accent-warning) !important;
  color: var(--primitive-white) !important;
}
  • [ ] Step 2: Verify buttons and progress indicators use accent color

Open any page with a primary button (e.g. creative listing "New creative" button). Toggle through dark/light/cavai themes — button should change accent color.

  • [ ] Step 3: Commit
bash
git add src/styles/_vuetify-reset.scss
git commit -m "add Vuetify primary/warning color resets to use theme tokens"

Task 3: Remove color="primary" from ErrorDialog

Files:

  • Modify: src/components/dialogs/ErrorDialog.vue:22

  • [ ] Step 1: Remove color prop, add CSS class

Change:

html
<v-btn
  class="modal_buttons"
  large
  raised
  color="primary"
  @click="$emit('dismissError')"
>

To:

html
<v-btn
  class="modal_buttons btn-primary"
  large
  raised
  @click="$emit('dismissError')"
>
  • [ ] Step 2: Commit
bash
git add src/components/dialogs/ErrorDialog.vue
git commit -m "remove color=primary from ErrorDialog button"

Task 4: Remove color="primary" from DatePicker

Files:

  • Modify: src/components/common/DatePicker.vue:31,38

  • [ ] Step 1: Remove both color="primary" props

Remove color="primary" from both v-btn elements (lines 31 and 38). The buttons will pick up the reset styles from _vuetify-reset.scss.

  • [ ] Step 2: Commit
bash
git add src/components/common/DatePicker.vue
git commit -m "remove color=primary from DatePicker buttons"

Task 5: Remove color="primary" from ImageCropper

Files:

  • Modify: src/pages/UserSettings/ImageCropper.vue:35,52,70,87,105

  • [ ] Step 1: Remove all five color="primary" props from Icon components

Each <Icon color="primary" ...> becomes <Icon ...> (5 instances). Add a CSS rule in the component's scoped style:

scss
.image-cropper .v-icon {
  color: var(--accent-primary);
}
  • [ ] Step 2: Commit
bash
git add src/pages/UserSettings/ImageCropper.vue
git commit -m "remove color=primary from ImageCropper icons, use token"

Task 6: Remove color="primary" from UserSettings/Index

Files:

  • Modify: src/pages/UserSettings/Index.vue:37

  • [ ] Step 1: Remove color="primary" from progress circular

Remove color="primary" from the v-progress-circular. The reset in _vuetify-reset.scss will handle the color.

  • [ ] Step 2: Commit
bash
git add src/pages/UserSettings/Index.vue
git commit -m "remove color=primary from UserSettings progress indicator"

Task 7: Remove color="primary" and color="warning" from BulkDeliveryExportDialog

Files:

  • Modify: src/pages/CreativeGroups/components/BulkDeliveryExportDialog.vue

  • [ ] Step 1: Remove all color="primary" props (7 instances)

Remove color="primary" from lines 41, 116, 155, 192, 225, 300, 342. For v-btn elements, the reset covers them. For v-progress-circular (line 41), same.

  • [ ] Step 2: Remove color="warning" text-color="white" from chips (3 instances)

Remove color="warning" text-color="white" from lines 105, 181, 263. The chip reset in _vuetify-reset.scss handles warning color.

  • [ ] Step 3: Commit
bash
git add src/pages/CreativeGroups/components/BulkDeliveryExportDialog.vue
git commit -m "remove Vuetify color props from BulkDeliveryExportDialog"

Task 8: Remove color="primary" from MainTable

Files:

  • Modify: src/components/common/MainTable.vue:227

  • [ ] Step 1: Remove color="primary" from v-icon

Change:

html
<v-icon
  color="primary"
  size="19"
  dark
  v-bind="attrs"
  v-on="on"
>

To:

html
<v-icon
  size="19"
  v-bind="attrs"
  v-on="on"
  class="icon-accent"
>

Add to component styles:

scss
.icon-accent {
  color: var(--accent-primary) !important;
}
  • [ ] Step 2: Commit
bash
git add src/components/common/MainTable.vue
git commit -m "remove color=primary from MainTable icon, use token"

Chunk 2: Hardcoded Hex Colors in CSS/JS

Task 9: Replace hardcoded blues in _pages.scss SVG illustrations

Files:

  • Modify: src/styles/_pages.scss:197,237,289,335,346,382,439,449

  • [ ] Step 1: Replace all 8 instances of #0e9cca with accent-primary token

Replace every fill: #0e9cca; and stroke: #0e9cca; with:

scss
fill: var(--accent-primary);
// and
stroke: var(--accent-primary);
  • [ ] Step 2: Verify dashboard cards show correct accent color per theme

  • [ ] Step 3: Commit

bash
git add src/styles/_pages.scss
git commit -m "replace hardcoded blue in dashboard SVGs with accent-primary token"

Task 10: Replace hardcoded blue in _components-forms.scss calendar icon

Files:

  • Modify: src/styles/_components-forms.scss:141

  • [ ] Step 1: Replace #0b84c2 in calendar SVG background

The calendar-svg-background() SCSS function generates an inline SVG. CSS custom properties don't work inside url() data URIs.

Approach: Use a filter or override the focused state with a separate rule that sets color via currentColor or --accent-primary on the icon element itself. If the SCSS function can't accept a variable, add a class-based override:

scss
.datepicker-wrapper .v-input--is-focused .v-input__prepend-outer .v-icon {
  color: var(--accent-primary);
}
  • [ ] Step 2: Commit
bash
git add src/styles/_components-forms.scss
git commit -m "replace hardcoded blue in datepicker focus state with token"

Task 11: Replace hardcoded blue in BuildProgress gradient

Files:

  • Modify: src/pages/Chatbots/components/BuildProgress.vue:181

  • [ ] Step 1: Replace hardcoded gradient with token-aware version

Change:

scss
&.blue {
  background: linear-gradient(90deg, #c5e8f9 0%, #1c9bcc 87.5%, #0d4c66 100%);
}

To:

scss
&.blue {
  background: linear-gradient(90deg, var(--accent-primary-subtle) 0%, var(--accent-primary) 87.5%, var(--surface-sunken) 100%);
}
  • [ ] Step 2: Commit
bash
git add src/pages/Chatbots/components/BuildProgress.vue
git commit -m "replace hardcoded blue gradient in BuildProgress with tokens"

Files:

  • Modify: src/pages/Chatbots/components/CavaiFlow/CavaiFlow.vue:4034

  • [ ] Step 1: Replace hardcoded link colors with scale tokens

Change:

typescript
color: fromOperator.includes('answer') ? '#0588BF' : '#FF5E6E',

To:

typescript
color: fromOperator.includes('answer') ? 'var(--scale-alpha-50)' : 'var(--scale-bravo-65)',

Note: These are scale (categorical) colors, not accent colors — they distinguish operator types, not brand identity. Using scale tokens is correct here.

  • [ ] Step 2: Verify flow editor link colors render correctly

Check that the color value is consumed as a CSS property. If it's used as a JS canvas color, CSS variables won't work and we need to read the computed style. Investigate before committing.

  • [ ] Step 3: Commit
bash
git add src/pages/Chatbots/components/CavaiFlow/CavaiFlow.vue
git commit -m "replace hardcoded flow link colors with scale tokens"

Chunk 3: Cavai Theme Tuning

Task 13: Tune Cavai theme surface tokens

Files:

  • Modify: src/styles/theme.css (the [data-theme="cavai"] block)

  • [ ] Step 1: Adjust surface-overlay and surface-raised to be warmer

Change:

css
--surface-raised:  #faf7f5;
--surface-overlay: #ffffff;

To:

css
--surface-raised:  #f9f3ee;
--surface-overlay: #fdf9f6;

This ensures panels and dialogs have a warm tint instead of stark white against the beige base.

  • [ ] Step 2: Toggle through all themes and verify visual consistency

Check: dashboard, builder, dialogs, tables, flow editor in all three themes.

  • [ ] Step 3: Commit
bash
git add src/styles/theme.css
git commit -m "tune Cavai theme surface tokens to warmer tones"

Task 14: Fix OptionInputField hardcoded white

Files:

  • Modify: src/pages/Chatbots/components/OptionRow/OptionInputField.vue:20

  • [ ] Step 1: Replace colors.white with CSS variable reference

Change:

typescript
backgroundColor: inputFocused ? colors.white : colors.grey95

To:

typescript
backgroundColor: inputFocused ? 'var(--surface-overlay)' : 'var(--surface-raised)'
  • [ ] Step 2: Commit
bash
git add src/pages/Chatbots/components/OptionRow/OptionInputField.vue
git commit -m "replace hardcoded white in OptionInputField with surface token"

Chunk 4: Final Verification

Task 15: Full visual QA pass

  • [ ] Step 1: Dark theme — navigate through: dashboard, creative listing, builder (visuals + flow + delivery), reports, user settings. Screenshot any issues.

  • [ ] Step 2: Light theme — same flow.

  • [ ] Step 3: Cavai theme — same flow. Pay special attention to: accent colors on buttons, progress indicators, focus rings, flow editor links, dashboard illustrations.

  • [ ] Step 4: Fix any remaining issues found during QA

  • [ ] Step 5: Final commit with any fixes

bash
git commit -m "fix visual issues found during token adoption QA"

Internal documentation