Skip to main content
Design SystemAudit & Drift

Audit & Drift

Mechanically-scanned CSS drift metrics (hardcoded radii, raw z-index, duplicate token values) plus hand-verified bugs and consolidation findings.

A standing audit of CSS-system drift in BuilderStudio-main. The metrics below are scanned mechanically from source by the generator (so they stay accurate and refreshable); the findings are hand-verified judgement calls. Most were fixed by the CSS token sweep on main; this page tracks what was done and what remains.

SourceBuilderStudio-mainCommit6fd4036fcDate2026-05-29Branchmain
How to read this
Metrics are computed over all 186 CSS files at the snapshot commit (comments stripped, so commented-out CSS is excluded). Findings were each verified by hand. After the sweep the generated scan reports 0 undefined vars and 0 dead keyframes.
  • 11
    Findings resolved
  • 1
    Findings open
  • 1
    By design
  • 19
    Pill radii (50% only)
  • 35
    Hardcoded radii
  • 80
    Raw z-index (by contract)
  • 18
    Hardcoded shadows
  • 12
    Dup token values

Open

Still actionable — not yet addressed.

  • DriftOpenHardcoded box-shadows bypass the shadow tokens
    components/canvas/sidebars/CanvasAssetsList.module.css + ~18 sites

    About 18 hardcoded box-shadows use literal rgba() instead of the --ui-shadow-* tokens. Some (e.g. CanvasAssetsList’s `0 1px 2px rgb(0 0 0 / 8–12%)`) closely match --ui-shadow-soft; others are genuinely context-specific depth.

By design

Investigated and intentionally left as-is (a contract or constraint makes the “drift” correct).

  • DriftBy designSplit z-index system: tokens for primitives, literals for canvas
    repo-wide

    Portaled UI primitives (Tooltip/Toast/Select) use the --ui-z-* tokens; canvas overlays and node chrome use raw z-index integers.

    By design: Intentional, not drift. scripts/validate-canvas-layer-contract.ts deliberately pins canvas selectors (.sheet=35, .toolbar=36, .promptHud=37, .root/.quickZoomDock=40, …) to LITERAL z-index values so the stacking order is statically verifiable. A --canvas-z-* token scale was tried during the sweep and reverted because it broke that contract. Leave canvas z-index as literals.

Resolved by the token sweep

Fixed on BuilderStudio-main main. Kept here for history; each notes how and where it was addressed.

  • BugResolved`var(--ui-shadow-md)` is never defined
    components/canvas/nodes/EasyConnectNode/EasyConnectNode.module.css

    `box-shadow: var(--ui-shadow-md)` was used with no fallback, but tokens.css only defines --ui-shadow-panel / -popover / -tooltip / -toast / -soft. There was no -md, so the shadow silently resolved to nothing and the node rendered with no elevation.

    Fix: Changed to var(--ui-shadow-soft) — CSS token sweep (main @ d84f8332c). This is the one intentional visual change in the sweep (the node now shows its intended elevation).

  • BugResolved`.input` border color is set then immediately overridden
    components/canvas/nodes/base/properties/properties.module.css

    `.input` declared `border: 1px solid rgb(115 115 115 / 0.5)` then a later `border-color: rgb(0 0 0 / 0.12)` that overrode the color, so the 115-grey never rendered.

    Fix: Collapsed to a single `border: 1px solid rgb(0 0 0 / 0.12)` (the value that actually rendered) — CSS token sweep (main @ d84f8332c). Pixel-identical.

  • WarningResolvedDead `@keyframes loading-bar-slide` + misleading comment
    styles/animations.css

    The keyframe had zero consumers anywhere in the repo. Its comment claimed it was "used by CanvasLoadingScreen", but that component uses its own keyframes (rootReveal, loaderLogoEnter, textEnter).

    Fix: Deleted the keyframe and the stale comment — CSS token sweep (main @ d84f8332c). The generated dead-keyframes scan is now 0.

  • WarningResolvedglobals.css comment says `.animate-*` (plural)
    app/globals.css

    The comment implied multiple animation utility classes live in animations.css, but exactly one exists (.animate-canvas-card-exit).

    Fix: Comment corrected to name the single class — CSS token sweep (main @ d84f8332c).

  • WarningResolvedNode-param dropdown z-index (1200) sat above toasts (1100)
    components/canvas/nodes/base/ModelParamsEditor/ModelParamsEditor.module.css + workspace-settings/DatePicker.module.css

    `.paramSelectContent` hard-set z-index:1200 on a portaled Select dropdown. The Select primitive uses var(--ui-z-overlay)=1000 and toasts are --ui-z-toast=1100, so a node-param (and the date-picker) dropdown rendered on top of toasts.

    Fix: Both dropdowns now use var(--ui-z-overlay) so toasts sit above them — CSS token sweep (main @ d84f8332c).

  • WarningResolved`.secondaryToolbarButton` declared as two adjacent blocks
    components/canvas/overlays/CanvasFloatingToolbar.module.css

    Two back-to-back rule blocks for the same selector (both set `border: 0`; the second added height/place-items/gap/radius/padding). Harmless but read as an incomplete refactor.

    Fix: Merged into one block (and deduped a doubled :focus selector) — CSS token sweep (main @ d84f8332c).

  • DriftResolved8 `--node-property-*` theming hooks were never set
    components/canvas/nodes/base/properties/properties.module.css

    Eight custom properties (--node-property-label-font-size, -help-font-size, -section-gap, -description-line-clamp, etc.) were read only with fallbacks and never assigned in any CSS or TS — dead indirection. Contrast with --bs-select-* and --canvas-viewport-* which ARE set at runtime (see cleared list).

    Fix: All 8 reads inlined to their fallback values — CSS token sweep (main @ d84f8332c). Pixel-identical.

  • DriftResolvedThree identical scroll-thumb tokens implied a state change that never happened
    components/canvas/nodes/base/PromptInput/PromptInput.module.css

    --tone-scroll-thumb, -hover and -focus were byte-identical (rgba(0,0,0,0.2)) yet wired to 3 call sites (default / :hover / :focus) as if the thumb changed color on interaction — it did not.

    Fix: Collapsed to one --tone-scroll-thumb token; the 3 call sites point at it — CSS token sweep (main @ d84f8332c). Pixel-identical.

  • DriftResolvedNo pill/full radius token
    styles/tokens.css + repo-wide

    There was no --ui-radius-full token, so full/pill radius was hardcoded as 999px / 9999px (and 50% circles) across the codebase.

    Fix: Added --ui-radius-full (and --ui-radius-2xs for 2px); ~120 border-radius literals tokenized (999px/9999px→full, 2px/0.125rem→2xs, plus exact-match px→token), pixel-identical — CSS token sweep (main @ d84f8332c). The pill-scan dropped 76→19; the remaining 19 are intentional 50% circles left as a documented idiom.

  • DriftResolvedDuplicate-value tokens under many names
    styles/tokens.css

    Pure white was defined under 6+ token names; #111827 under 3; plus error-shell ≡ error-bg/border, auth-text-muted ≡ public-text-muted, the node-header colour pair, and text-caption ≡ ui-text-xs.

    Fix: Duplicates redefined as var() aliases of a canonical token (white→--color-background, fg→--color-foreground, error-shell→base, auth-text-muted→public, node-header icon→label, text-caption→--ui-text-xs) — CSS token sweep (main @ d84f8332c). One source of truth; zero visual change. (Genuinely-distinct values like --text-micro / --text-node-label were left alone.)

  • DriftResolvedTwo overlapping type scales
    styles/tokens.css

    --ui-text-xs/sm/md/lg coexisted with --text-caption/micro/node-label/label, with --text-caption byte-identical to --ui-text-xs.

    Fix: The overlapping --text-caption is now an alias of --ui-text-xs (and --text-label was already an alias of --ui-text-md) — CSS token sweep (main @ d84f8332c). --text-micro (10px) and --text-node-label (9px) are unique canvas values with no scale-A equivalent, so they stay as-is by design.

Cleared (false positives)

Suspected issues that were investigated and found to be fine — recorded so they don't get re-raised (a few were subagent or stale-snapshot false positives).

  • Cleared`--radius-full` "broken references"
    repo-wide

    An earlier pass suspected ~11 broken var(--radius-full) refs. Verified: --radius-full existed nowhere and was referenced nowhere. A stale-snapshot artifact, not a real token. (Note: the sweep later ADDED a real --ui-radius-full token — different name, deliberate.)

  • Cleared`--ui-selection-bg` drift
    app/globals.css

    Suspected the ::selection rule hardcoded the color instead of using the token. Verified: it correctly uses var(--ui-selection-bg). Not a bug.

  • Cleared`--port-color` undefined
    components/canvas/nodes/base/NodeHandles/NodeHandles.module.css

    Flagged by a pure-CSS scan as used-but-undefined. Verified: it is injected at runtime via inline style in PortHandle.tsx (getPortAccentColor). Correct pattern; allowlisted in the drift scan.

  • Cleared`--canvas-viewport-floating-chrome-gap` (badge-position gap)
    components/canvas/nodes/base/badge-position.module.css

    Looked like a never-set fallback var. Verified: viewportTransform.ts builds a CSS-vars map that sets it, zoom-reactively (test asserts it computes to 32px / 2px). Live, not dead.

  • Cleared`--bs-select-*` "dead hooks"
    components/ui/primitives/Select.module.css

    The Select primitive consumes ~20 --bs-select-* vars, all with sensible token fallbacks; node modules override a subset and -trigger-width is JS-measured. This is the correct themeable-contract pattern (the model the now-removed --node-property-* hooks should have followed).

  • ClearedCanvasSidebarSheet "font-size used as border-radius" bug
    components/canvas/sidebars/CanvasSidebarSheet.module.css

    A subagent reported `border-radius: var(--text-micro)` at line 145. Verified false: line 145 is `justify-content: center;` and no border-radius uses a font token anywhere in that file. A hallucinated finding — recorded here so it is not re-raised.

Hardcoded border-radius

35 non-pill hardcoded radius values remain (1 exact-match a radius token; 34 are off-scale and left as documented literals). Plus 19 pill radii — all now the intentional 50% circle idiom after 999px/9999px were tokenized to --ui-radius-full. By value:

  • 7px
    11
  • 5px
    4
  • 14px
    3
  • 0.625rem
    3
  • 0
    3
  • 9px
    3
  • 10px
    2
  • 1.5px
    1
  • 0.5rem--ui-radius-sm
    1
  • 3px
    1
  • 18px
    1
  • 1px
    1
  • 15px
    1

Raw z-index values

80 raw z-index integers across 27 distinct values. Canvas chrome keeps literals on purpose — validate-canvas-layer-contract.ts pins them for static stacking verification (see the “by design” finding).

  • 9999
    1
  • 1000
    1
  • 120
    2
  • 100
    1
  • 60
    2
  • 50
    5
  • 40
    5
  • 39
    1
  • 37
    2
  • 36
    1
  • 35
    1
  • 34
    1
  • 30
    3
  • 28
    1
  • 20
    4
  • 18
    2
  • 15
    1
  • 14
    2
  • 10
    4
  • 8
    1
  • 5
    1
  • 3
    1
  • 2
    3
  • 1
    23
  • 0
    8
  • -1
    2
  • -2
    1

Duplicate token values

12 literal values are each defined under more than one token name. After the sweep most colour duplicates are var() aliases of a canonical token; the remainder are cross-category coincidences (e.g. a spacing value equal to a radius value) that are not real duplication.

ValueDefined under these token names
0.5rem--ui-radius-sm--ui-space-2--node-drag-header-height
0.75rem--ui-radius-md--ui-space-3--ui-text-sm
1.25rem--ui-radius-xl--ui-space-5--node-header-icon-size
rgba(255, 255, 255, 1)--ui-surface-0--ui-surface-node--ui-surface-tab-active
rgba(243, 244, 246, 1)--ui-surface-2--ui-border-subtle--ui-surface-subtle-hover
#f3f3f3--canvas-chrome-surface-subtle--canvas-chrome-row-active--canvas-chrome-row-hover
0.25rem--ui-radius-xxs--ui-space-1
1rem--ui-radius-lg--ui-space-4
3rem--ui-space-12--task-control-height
rgba(249, 250, 251, 1)--ui-surface-1--ui-surface-subtle
260px--canvas-sidebar-primary-width--canvas-sidebar-secondary-width
rgba(229, 231, 235, 1)--ui-border-soft--ui-border-subtle-hover

Was this page helpful?