diff --git a/DESIGN-SYSTEM.md b/DESIGN-SYSTEM.md index aafd2911..590162f7 100644 --- a/DESIGN-SYSTEM.md +++ b/DESIGN-SYSTEM.md @@ -321,11 +321,31 @@ Color: accent-text ## Shadows -Minimal to none. No decorative shadows. +Shadows communicate **interaction state**, not decoration. Elements earn shadows through user interaction. -- Cards: none (border only) -- Dropdowns/flyouts: `0 4px 12px rgba(0,0,0,0.3)` if needed -- Logo mark: `0 2px 8px rgba(14,165,233,0.25)` (subtle brand glow on logo only) +**Resting state:** No shadows. Elements are flat with 1px borders. + +**Hover state (buttons):** Subtle shadow + lift effect. Element feels like it rises off the surface. +- Primary button hover: `0 2px 8px rgba(34,211,238,0.25)` + `translateY(-1px)` — cyan-tinted shadow +- Ghost button hover: `0 2px 6px rgba(0,0,0,0.2)` + `translateY(-1px)` +- Active/click: shadow shrinks, element "presses down" to `translateY(0)` + +**Active/selected state (tabs, toggles):** The selected item gets an elevation shadow to feel raised above siblings. +- Active tab: `0 2px 8px rgba(0,0,0,0.25)` — class: `tab-active-shadow` + +**Card hover lift (optional):** For cards that should feel interactive (clickable list items, session cards). +- Hover: `0 4px 12px rgba(0,0,0,0.2)` + `translateY(-2px)` — class: `card-lift` +- Active: shadow shrinks to `0 1px 4px rgba(0,0,0,0.15)` + +**Overlays:** Flyouts, dropdowns, modals get elevation shadows to separate from content. +- Drawer/flyout: `4px 0 12px rgba(0,0,0,0.2)` +- Dropdown: `0 4px 12px rgba(0,0,0,0.3)` +- Modal: `0 8px 24px rgba(0,0,0,0.4)` + +**What NOT to do:** +- No shadows on resting cards (border only) +- No permanent decorative shadows +- No colored glow shadows (except primary button cyan tint on hover) --- diff --git a/frontend/src/index.css b/frontend/src/index.css index 8a90e814..60f3190d 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -178,9 +178,15 @@ border-radius: 5px; padding: 9px 16px; font-size: 13px; - transition: filter 150ms ease; + transition: filter 150ms ease, box-shadow 150ms ease, transform 150ms ease; &:hover { filter: brightness(1.1); + box-shadow: 0 2px 8px rgba(34, 211, 238, 0.25); + transform: translateY(-1px); + } + &:active { + box-shadow: 0 1px 2px rgba(34, 211, 238, 0.15); + transform: translateY(0); } } @@ -191,11 +197,38 @@ border-radius: 5px; padding: 9px 16px; font-size: 13px; - transition: background 150ms ease, color 150ms ease, border-color 150ms ease; + transition: background 150ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease; &:hover { background: var(--color-bg-elevated); color: var(--color-text-primary); border-color: var(--color-border-hover); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); + transform: translateY(-1px); + } + &:active { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); + transform: translateY(0); + } +} + +/* ── Interactive shadow patterns ────────────────── */ + +/* Tab/toggle group: active item gets elevation shadow */ +@utility tab-active-shadow { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25); +} + +/* Card hover lift — optional, add to cards that should feel interactive */ +@utility card-lift { + transition: box-shadow 200ms ease, transform 200ms ease, border-color 200ms ease; + &:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + transform: translateY(-2px); + border-color: var(--color-border-hover); + } + &:active { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); + transform: translateY(0); } }