Browse documents

Skeuomorphism — Component Recipes

The exact class recipes applied (Phase 1) and planned (later phases), so any component can be brought into the material system consistently. All classes reference tokens from 01_tokens.md.

Shipped (Phase 1)

Card — raised panel

// components/ui/card.tsx
'sheen rounded-lg border border-border/70 bg-surface text-foreground shadow-raised'

Top sheen + layered ambient shadow + softened hairline border. Every <Card> (KPI tiles, consoles, widgets) inherits this.

Button — tactile

// base
'... transition-[transform,box-shadow,background-color,color,border-color] duration-150 ease-out
 active:translate-y-px disabled:shadow-none disabled:translate-y-0 ...'

// variants
primary:     'sheen bg-primary text-primary-foreground shadow-raised
              hover:-translate-y-px hover:shadow-raised-hover hover:bg-primary/95 active:shadow-pressed'
secondary:   'sheen bg-surface-sunken text-foreground shadow-raised
              hover:-translate-y-px hover:shadow-raised-hover active:shadow-pressed'
outline:     'sheen border border-border bg-surface text-foreground shadow-raised
              hover:-translate-y-px hover:shadow-raised-hover hover:bg-surface-sunken active:shadow-pressed'
destructive: 'sheen bg-danger text-danger-foreground shadow-raised
              hover:-translate-y-px hover:shadow-raised-hover hover:bg-danger/95 active:shadow-pressed'
ghost:       'text-foreground hover:bg-surface-sunken active:translate-y-0'   // stays flat

Lifts on hover, presses in on :active; disabled buttons flatten.

Input / Select / Textarea — recessed well

'... bg-surface-sunken shadow-well transition-[background-color,box-shadow,border-color]
 focus-visible:bg-surface focus-visible:shadow-none focus-visible:ring-2 focus-visible:ring-ring ...'

Carved into the surface at rest; flattens to a plain field with a crisp ring on focus.


Planned recipes (later phases)

Glass chrome (Phase 2 / 5)

'glass shadow-floating'                 // overlays, top bar, command palette
active:   'bg-surface-sunken shadow-well text-foreground'   // pushed in
inactive: 'text-foreground-muted hover:bg-surface hover:shadow-raised hover:-translate-y-px'

Meter / progress bar — carved track + raised fill (Phase 3)

track: 'bg-surface-sunken shadow-well rounded-full'
fill:  'sheen bg-primary shadow-raised rounded-full'

Toggle switch — physical rocker (Phase 4)

track-off: 'bg-surface-sunken shadow-well'
track-on:  'sheen bg-success shadow-raised'
knob:      'sheen bg-surface shadow-raised rounded-full transition-transform'

Widget frame — lift on drag (Phase 6)

resting: 'sheen bg-surface shadow-raised'
dragging:'sheen bg-surface shadow-floating scale-[1.02]'

Migration checklist (per component)

  1. Replace shadow-sm / shadow with the right token (shadow-raised for content, shadow-well for inputs, shadow-floating for overlays).
  2. Add .sheen to raised surfaces only.
  3. For interactive controls, add hover:-translate-y-px hover:shadow-raised-hover + active:translate-y-px active:shadow-pressed and set the transition to include transform,box-shadow.
  4. Soften heavy 1px borders to border-border/70 where a shadow now carries the edge.
  5. Verify light and dark, and prefers-reduced-motion.
  6. tsc + screenshot via ego lite.