Section 15 · Integration

Vuetify.

VirtuProbe's app is Vue 3 + Vuetify. Vuetify gives us components for free, but its defaults feel like a vendor demo. This is how we make it look like us.

Theme

Define a single dark theme that mirrors our tokens. Light theme is not on the roadmap — the product runs at 02:00 in a hoodie.

vuetify.config.tsimport { createVuetify } from "vuetify";

export const vuetify = createVuetify({
  theme: {
    defaultTheme: "virtuprobe",
    themes: {
      virtuprobe: {
        dark: true,
        colors: {
          background: "#0b0f0d",    // --vp-color-bg
          surface:    "#11161a",    // --vp-color-bg-2
          primary:    "#b0f75a",    // --vp-color-neon
          secondary:  "#7e8a87",    // --vp-color-fg-dim
          error:      "#ff6b6b",
          info:       "#78b4ff",
          success:    "#b0f75a",
          warning:    "#ffc864",
          "on-primary": "#06140d",    // dark label on neon
          "on-surface": "#e8efe9",
          "on-background": "#e8efe9",
        },
        variables: {
          "border-color": "#2a3338",
          "high-emphasis-opacity": 1,
          "medium-emphasis-opacity": 0.78,
          "disabled-opacity": 0.42,
        }
      }
    }
  },
  defaults: {
    VBtn:   { rounded: "md", flat: true, height: 36 },
    VTextField: { variant: "outlined", density: "comfortable", hideDetails: "auto" },
    VSelect:    { variant: "outlined", density: "comfortable" },
    VCard:  { rounded: "md", flat: true },
    VTabs:  { sliderColor: "primary", density: "comfortable" },
  }
});

Component overrides

Vuetify's defaults will feel close-but-wrong. Add this stylesheet last, after Vuetify's own styles, to bring it home.

vuetify-overrides.css/* 1. Inputs use our bg-2 surface, not Vuetify's translucent grey */
.v-field--variant-outlined .v-field__overlay { background: var(--vp-color-bg-2); opacity: 1; }
.v-field--variant-outlined .v-field__outline__start,
.v-field--variant-outlined .v-field__outline__end,
.v-field--variant-outlined .v-field__outline__notch::before,
.v-field--variant-outlined .v-field__outline__notch::after {
  border-color: var(--vp-color-line-2);
}
.v-field--focused .v-field__outline { color: var(--vp-color-neon); }

/* 2. Mono input where the content is structural */
.v-text-field.is-mono .v-field__input { font-family: var(--vp-font-mono); font-weight: 500; }

/* 3. Buttons — kill Vuetify's elevation on primary, add our glow */
.v-btn.v-btn--variant-flat.bg-primary {
  box-shadow: 0 0 0 1px var(--vp-color-neon), 0 6px 20px -6px var(--vp-color-neon-glow);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

/* 4. Tabs — underline only, kill the hover ripple background */
.v-tab { text-transform: none; letter-spacing: 0.02em; min-width: 0; }
.v-tab--selected { color: var(--vp-color-fg); font-weight: 600; }

/* 5. Cards — flat, our line-2 border */
.v-card { background: var(--vp-color-bg-2); border: 1px solid var(--vp-color-line-2); }

/* 6. Tables — strip Vuetify's stripes, use our line tokens */
.v-data-table { background: transparent; }
.v-data-table__th { background: var(--vp-color-bg-3); font: 600 10.5px/1 var(--vp-font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--vp-color-fg-mute); }
.v-data-table__td { font: 500 12.5px var(--vp-font-mono); }
.v-data-table__tr:hover { background: var(--vp-color-bg-2); }

What we still build by hand

Vuetify covers ~70%. The remaining 30% is the surface that is the product:

key-value rowsgrid + checkbox + 2 inputs · custom · see Inputs
code editorCodeMirror · themed to our palette
protocol tagsour component · don't use VChip
status badgesours · VChip's pill shape is wrong for us
empty statescustom · Vuetify has no opinion here
command palettecustom · Vuetify's autocomplete is too form-shaped

Don't