Skip to content

Styles Consolidation Analysis

Decisions (2026-03-19):

  1. The worktree’s globals.css (Arda orange palette) replaces the main clone’s version (blue-slate default).
  2. tokens.css is kept as a separate file, updated to the Arda orange palette, and becomes the single source of truth for token values.
  3. globals.css is refactored to @import tokens.css instead of redeclaring the same variables.
  4. Legacy sidebar CSS from the main clone (.sidebar-menu-button-hover, [data-active='true'] styles) is dropped — the canary sidebar organism replaces it.
  5. sonner.tsx and the next-themes dependency are dropped — unused dead code; next-themes is Next.js-specific and doesn’t belong in a Vite/Storybook project.
FileContent
src/styles/globals.cssFull theme: Tailwind imports, two :root blocks (hex + oklch, blue-slate palette), @theme inline, scrollbar styles, legacy sidebar CSS
src/styles/tokens.cssMinimal token-only file (oklch, blue-slate palette). Docstring says it’s the published entrypoint for external consumers
src/styles/canary/globals.cssOne-line import: @import url("../globals.css")
src/styles/canary/tokens.cssOne-line import: @import url("../tokens.css")
FileContent
src/styles/globals.cssFull theme: Tailwind imports, single :root (oklch, Arda orange), Geist Mono font, control height tokens, orange state ramp, dark mode, sidebar-inset override, touch media queries
src/styles/tokens.cssUnchanged from main clone (blue-slate, stale)
src/styles/canary/globals.cssOne-line import: @import url("../globals.css")
src/styles/canary/tokens.cssOne-line import: @import url("../tokens.css")

preview.ts imports src/styles/globals.css only. Neither tokens.css nor canary/globals.css is imported at runtime by any component or story file.

TokenMain CloneWorktree
--primaryoklch(0.208 0.042 265.755) (dark blue/slate)oklch(0.637 0.222 29) (Arda orange)
--ringoklch(0.704 0.04 256.788) (blue)oklch(0.637 0.222 29) (orange)
--sidebar-primaryoklch(0.208 0.042 265.755) (blue)#fc5a29 (Arda orange)
--background/--foregroundBlue-tinted neutrals (hue ~265)Pure neutrals (hue 0)

The main clone uses the default shadcn slate palette. The worktree has been rebranded to Arda orange with pure neutrals. The worktree palette is correct.

  • Orange state ramp: --primary-hover, --primary-active, --primary-muted (light + dark modes)
  • Geist Mono font import and --font-geist-mono variable
  • Control height tokens: --control-height-xs/sm/md/lg with responsive media queries for touch devices
  • @theme inline additions: --color-primary-hover, --color-primary-active, --color-primary-muted
  • Dark mode sidebar-inset override: Forces light-mode tokens inside [data-slot='sidebar-inset'] when parent is .dark
  • --base-border-strong: #d4d4d4
  • --destructive-foreground: defined (main clone omits it)
  • Legacy sidebar hover CSS: .sidebar-menu-button-hover, [data-active='true'] ring styles, .add-company-button — pre-canary sidebar styles replaced by the canary sidebar organism. Drop.
  • Duplicate :root block: Two :root blocks (lines 12-90 hex/hsl, lines 134-167 oklch) — merge artifact. Drop in favor of worktree’s single clean block.

tokens.css (45 lines) contains only core semantic tokens — the same oklch values that also appear in the second :root block of the main clone’s globals.css. It is a strict subset. Currently uses the blue-slate palette (stale).

The docstring declares it as a lightweight published entrypoint for external consumers:

@import '@arda-cards/design-system/styles/tokens.css';

External consumers (e.g., arda-frontend-app) can import just the tokens without pulling in Tailwind directives, font imports, scrollbar styles, or base layer rules.

Zero. No component, story, or preview file imports tokens.css or canary/tokens.css. The only consumer is documentation referencing the published package entrypoint.

OptionArchitectural clarityMaintenance simplicityExternal consumer impact
Keep + invert dependencyHigh — clear separation of concernsHigh — one place to edit tokensPreserved
Subsume into globals.cssLower — consumers must import full themeModerate — one less file, but heavier importBreaking — lightweight entrypoint gone
Keep as-is (parallel)Low — duplicate :root declarationsLow — guaranteed driftPreserved but fragile
src/styles/
tokens.css ← Single source of truth for token values (updated to Arda orange)
globals.css ← @import tokens.css + Tailwind + fonts + utilities + media queries
ag-theme-arda.css ← AG Grid theme (unchanged)
canary/
tokens.css ← @import url("../tokens.css") (unchanged proxy)
globals.css ← @import url("../globals.css") (unchanged proxy)
ag-theme-arda.css ← AG Grid canary theme (unchanged)

Contains only :root and .dark blocks with CSS custom properties:

  • Core semantic tokens (background, foreground, primary, secondary, muted, accent, destructive, card, popover, border, input, ring)
  • Orange state ramp (primary-hover, primary-active, primary-muted)
  • Chart colors
  • Sidebar tokens
  • Destructive foreground
  • Border radius
  • Font family variables
  • Control height tokens
  • @import url('./tokens.css') (no redeclared token values)
  • Google Fonts import (Geist, Geist Mono)
  • Tailwind directives (@import 'tailwindcss', @tailwind base/components/utilities)
  • @custom-variant dark
  • @layer base, theme-override declaration
  • @theme inline block (maps CSS vars to Tailwind theme)
  • @layer base reset (border-border, bg-background text-foreground)
  • Sidebar-inset dark mode override
  • Touch device / small screen media queries (control height bumps)
  • Autofill fix
  • Scrollbar utilities
  • Iframe scrollbar hide
  • Figma design spacing tokens (--spacing-1 through --spacing-6)
  • Figma design color tokens (--base-*, --form-*, --selection-*, --sidebar-gradient-*, etc.)
  • Main clone’s duplicate :root block (hex/hsl values superseded by oklch)
  • Legacy sidebar CSS (.sidebar-menu-button-hover, [data-active='true'], .add-company-button)
  • src/components/ui/sonner.tsx and the next-themes npm dependency (see below)

next-themes is a Next.js-specific library for managing light/dark/system theme state. It provides a ThemeProvider context and a useTheme() hook that returns the current theme string.

next-themes (npm package)
└─ src/components/ui/sonner.tsx (only consumer)
└─ nothing imports this file

Single consumer: Only src/components/ui/sonner.tsx imports next-themes. The component reads useTheme() to pass the current theme to the Sonner toast library so toasts match the app theme.

Nobody imports sonner.tsx: All existing toast usage imports directly from the sonner package (import { toast, Toaster } from 'sonner'), not from @/components/ui/sonner. The themed Toaster wrapper was scaffolded by the shadcn CLI but never wired in.

Drop the file src/components/ui/sonner.tsx and the next-themes npm package. The wrapper file is dead code (nobody imports it) and next-themes is its sole consumer. The sonner npm package itself is kept as a devDependency — it’s used directly by use-case stories and canary-refactor components via import { toast, Toaster } from 'sonner' (not through the wrapper). See dependencies.md for the full package disposition.