---
version: alpha
name: Vue
description: "Approachable authority — Inter's clean precision anchors a calm white-to-slate canvas where a single signature green (`#42b883`) earns every pixel of attention it occupies across CTAs, links, and hover states."

colors:
  # Surface / canvas
  background: "#ffffff"
  surface: "#f9f9f9"              # --vt-c-bg-soft; slightly warm off-white for code/aside areas
  surface-elevated: "#f1f1f1"     # --vt-c-bg-mute; deeper mute for dividers and raised states

  # Ink / text
  ink: "#213547"                  # dominant dark text, rgb(33,53,71) — navy-slate, not pure black
  ink-secondary: "#3c3c3c"        # rgba(60,60,60,0.7) flattened over white — mid-charcoal for nav placeholders
  ink-muted: "#476582"            # --vt-c-text-light-code; code annotations and secondary UI text
  ink-on-dark: "#ffffff"          # white text over primary button background

  # Brand accent — the signature Vue green
  primary: "#42b883"              # --vt-c-brand; the unmistakable Vue green
  primary-light: "#42d392"        # --vt-c-brand-light; lighter green for hover shifts
  primary-dark: "#33a06f"         # --vt-c-brand-highlight; deeper green for pressed states and focus rings
  on-primary: "#ffffff"           # white text on green

  # Interactive states
  link-hover: "#3a9a75"           # rgb(58,154,117) from interactive delta — nav link hover color
  focus-ring: "#42b883"           # green focus ring matching brand accent

  # Docsearch accents (third-party but brand-adjacent)
  search-accent: "#5468ff"        # --docsearch-primary-color; algolia blue, stays contained to search UI
  search-muted: "#969faf"         # --docsearch-muted-color; subtle placeholder text in search

  # Borders
  border: "#3c3c3c"               # rgba(60,60,60,0.12) flattened — section dividers, hairlines
  border-strong: "#3c3c3c"        # rgba(60,60,60,0.29) flattened — toggle borders, stronger outlines

  # Shadow tints
  shadow-soft: "#000000"          # rgba(0,0,0,0.08) droplet — subtle elevation for flyout panels

typography:
  display-hero:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 76px
    fontWeight: 900
    lineHeight: 1.25
    letterSpacing: -1.5px
  display:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 48px
    fontWeight: 700
    lineHeight: 1.25
    letterSpacing: -0.5px
  heading-section:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 28px
    fontWeight: 600
    lineHeight: 1.3
    letterSpacing: -0.25px
  heading-sub:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 20px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: -0.4px
  body-large:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 22px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: 0.2px
  body:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: 0.2px
  body-medium:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 16px
    fontWeight: 500
    lineHeight: 1.5
    letterSpacing: 0.2px
  nav-link:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.67
    letterSpacing: 0.2px
  button-ui:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 16px
    fontWeight: 600
    lineHeight: 1.5
    letterSpacing: 0px
  code:
    fontFamily: "'Rubik', -apple-system, monospace"
    fontSize: 15px
    fontWeight: 400
    lineHeight: 1.6
    letterSpacing: 0.2px
  caption:
    fontFamily: "'Inter var experimental', 'Inter var', Inter, -apple-system, system-ui, 'Segoe UI', Roboto, sans-serif"
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.83
    letterSpacing: 0px

spacing:
  xs: 4px
  sm: 8px
  md: 12px
  lg: 24px
  xl: 32px
  2xl: 48px
  3xl: 96px

rounded:
  none: 0px
  xs: 2px
  sm: 4px
  md: 8px
  pill: 9999px

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.md}"
    padding: 8px 16px
  button-primary-hover:
    backgroundColor: "{colors.primary-dark}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.md}"
    padding: 8px 16px
  button-secondary:
    backgroundColor: "{colors.surface-elevated}"
    textColor: "{colors.ink-muted}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.md}"
    padding: 8px 18px
  button-secondary-hover:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.button-ui}"
    rounded: "{rounded.md}"
    padding: 8px 18px
  card:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.md}"
    padding: 24px
    border: "1px solid {colors.border}"
  input:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.pill}"
    padding: 6px 28px
  input-focus:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.pill}"
    padding: 6px 28px
    outline: "2px solid {colors.focus-ring}"
  badge:
    backgroundColor: "{colors.surface-elevated}"
    textColor: "{colors.ink-muted}"
    typography: "{typography.caption}"
    rounded: "{rounded.xs}"
    padding: 2px 6px
  nav-bar:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.nav-link}"
    padding: 0px 24px
    border: "1px solid {colors.border}"
  code-block:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink-muted}"
    typography: "{typography.code}"
    rounded: "{rounded.md}"
    padding: 16px 24px
---

# Vue Design System

## Overview

Vue's website is a study in deliberate restraint. Against a clean white canvas (`{colors.background}`), a dark navy-slate text (`{colors.ink}`) carries the page with an authority that doesn't shout — it simply states. The design vocabulary is minimal by intention: one font family (Inter, deployed as a variable font with optical-size tuning from 76px down to 11px), one primary brand color, and a spare palette of surface tints. The result is a developer documentation site that feels less like a marketing page and more like a well-kept technical manual — trustworthy, readable, unfussy.

The signature Vue green (`{colors.primary}`) operates as a single-frequency signal. It appears on the primary "Get Started" CTA, powers the color-shift hover state on every navigation link, and marks inline hyperlinks in documentation. Because it never bleeds into surface fills or decorative background treatments, each green occurrence reads with the clarity of a single musical note played in a quiet room. There is also a gradient moment — a diagonal from `#42d392` (light green) through `#647eff` (periwinkle blue) — reserved for the hero wordmark or section dividers, adding dimensionality without competing with the clean white canvas.

Typography is the quiet hero. Inter's variable font technology enables weight-900 display headlines at 76px with tight −1.5px tracking, then softens gracefully through 600-weight section headers and 400-weight body copy at 16px — all within a single font file. The only deviation is Rubik, a geometric sans used for code inline snippets, adding just enough roundness to distinguish code from prose without a heavy monospace weight. This economy — two typefaces where most sites deploy five — signals confidence and focus.

**Key Characteristics:**
- White (`{colors.background}`) canvas with no competing surface colors at macro scale
- Single brand accent `{colors.primary}` (#42b883) — the Vue green applied to CTAs, links, and all hover shifts
- `{colors.ink}` (#213547) navy-slate primary text — slightly warmer than pure black, cooler than charcoal
- Inter variable font used site-wide with weight spanning 400–900 across the type scale
- Hero display at 76px, weight 900, tracking −1.5px — the maximum expression of Inter's variable range
- Rubik as the code-prose companion face — round, friendly, visually distinct from the Inter UI
- Minimal border radius: `{rounded.xs}` (2px) for inline tokens, `{rounded.md}` (8px) for feature cards, pill for search
- `rgba(0,0,0,0.1)` + `rgba(0,0,0,0.08)` dual-layer flyout shadow (flattened to `{colors.shadow-soft}`) for panel elevation
- 0.25s ease transition dominant across nav and interactive elements; 0.5s for opacity fades
- Precise breakpoint ladder from 370px to 1600px — twenty distinct media query points

## Colors

### Canvas & Surfaces
- **White** (`{colors.background}`): The default page canvas. Clean, literal white — no warm or cool tint.
- **Off-White** (`{colors.surface}`): `--vt-c-bg-soft`; used for code blocks, asides, and secondary panels. Barely distinguishable from white at first glance, but establishes quiet hierarchy.
- **Muted Surface** (`{colors.surface-elevated}`): `--vt-c-bg-mute`; the lightest interactive surface, used for secondary buttons and active states in toggles.

### Ink & Text
- **Navy Slate** (`{colors.ink}`): Primary text. rgb(33, 53, 71) — a cool dark slate that reads softer than #111 but carries firm authority.
- **Mid Charcoal** (`{colors.ink-secondary}`): Secondary placeholder and nav text, derived from rgba(60,60,60,0.7) flattened over white.
- **Code Slate** (`{colors.ink-muted}`): `--vt-c-text-light-code`; used in code annotations, subdued UI text, and secondary button labels.

### Brand Accent
- **Vue Green** (`{colors.primary}`): The brand's iconic green. `--vt-c-brand`. Applied exclusively to primary CTAs, navigation hover states, and inline links in documentation. Held in reserve — never used as a fill on large surfaces.
- **Green Light** (`{colors.primary-light}`): `--vt-c-brand-light`; a brighter, higher-saturation variant used in the hero gradient and link hover flashes.
- **Green Highlight** (`{colors.primary-dark}`): `--vt-c-brand-highlight`; the deeper, more saturated tone for pressed states, focus rings, and documentation link accents.

### Borders & Shadows
- **Hairline** (`{colors.border}`): Derived from rgba(60,60,60,0.12) over white — extremely light dividers for nav bottom borders and section separators.
- **Border Strong** (`{colors.border-strong}`): rgba(60,60,60,0.29) flattened — toggle outlines and component edges that need more presence.
- **Shadow Soft** (`{colors.shadow-soft}`): The black base for `rgba(0,0,0,0.08–0.10)` flyout shadows. Dual-layer pattern creates natural depth on dropdown panels.

## Typography

### Font Families
- **Primary**: `Inter var experimental` (self-hosted variable font), with full system-ui fallback chain. Variable font technology allows seamless weight 400 → 900 in a single file.
- **Code Companion**: `Rubik` (loaded via secondary bundle) — used for inline code snippets. Geometric round structure differentiates code from prose without a full monospace register.

### Hierarchy

| Token | Use |
|---|---|
| `display-hero` | Inter weight 900, 76px, −1.5px tracking — the hero headline, maximum weight expression |
| `display` | Inter weight 700, 48px — major section announcements |
| `heading-section` | Inter weight 600, 28px — section openers in docs and marketing |
| `heading-sub` | Inter weight 600, 20px, −0.4px — subsection headers with slightly tighter tracking |
| `body-large` | Inter weight 400, 22px — lead copy, hero subheadlines |
| `body` | Inter weight 400, 16px — standard documentation and marketing body text |
| `body-medium` | Inter weight 500, 16px — navigation labels, active link states |
| `nav-link` | Inter weight 500, 14px — compact header navigation links |
| `button-ui` | Inter weight 600, 16px — CTA button labels |
| `code` | Rubik weight 400, 15px — inline code and short code snippets |
| `caption` | Inter weight 500, 12px — version badges, footnote annotations |

### Principles
- **Variable font as single source of truth**: All display, heading, and body roles draw from the same Inter variable file. No font switches between UI and editorial contexts.
- **Weight as the only hierarchy lever**: The system doesn't use color or size alone to establish hierarchy — weight moves from 900 (hero) → 600 (heading) → 500 (nav/medium) → 400 (body). Clean and legible at every step.
- **Rubik for code prose distinction**: Inline code in Rubik at 15px visually signals "this is a technical token" without the jarring density of a full monospace face.
- **Tight tracking only at display sizes**: −1.5px at hero (76px), −0.5px at display (48px), −0.4px at heading-sub (20px). Body text runs at standard +0.2px openness for comfortable documentation reading.

## Layout

### Spacing System
The spacing scale is based on an 8px grid with practical deviations at small sizes (4px, 6px) for tight inline UI components. Base rhythm is 24px for component padding and vertical gaps; 96px for major section breaks.

Vue documentation pages use generous inline spacing: 28px horizontal padding on the search pill, 24px on nav containers. This breathing room at small components carries the "approachable" voice into even the most utilitarian UI.

### Grid & Container
- Max content width: approximately 1440px (breakpoint at 1440–1441px)
- Marketing sections: centered, up to 1280px effective content width
- Documentation layout: left sidebar (table of contents) + main content + optional right sidebar
- Hero: centered single-column content stack, text-align center with green CTA button

### Whitespace Philosophy
- **Generous section rhythm**: 96px vertical gaps at section level let the spare typography breathe.
- **Compact component interiors**: Buttons, nav items, and badges use tight padding — the wide spacing happens between blocks, not inside them.
- **No decorative dividers**: Section separation is achieved through spacing. Borders appear only on nav bottom edges and as hairlines in interactive components.

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| Flat (Level 0) | No shadow, no border | Main page canvas, running text sections |
| Hairline (Level 1) | `border-bottom: 1px solid {colors.border}` | Navigation bar, section separators |
| Card (Level 2) | `border: 1px solid {colors.border}` | Feature tiles, documentation cards |
| Flyout (Level 3) | `box-shadow: rgba(0,0,0,0.1) 0 12px 32px, rgba(0,0,0,0.08) 0 2px 6px` | Dropdown menus, search panel, mobile nav overlay |
| Focus Ring | `outline: 2px solid {colors.focus-ring}` | All keyboard-focused interactive elements |

**Shadow Philosophy**: Vue's shadow vocabulary is deliberately minimal — most surfaces are flat or border-defined. The dual-layer flyout shadow (12px blur outer + 2px blur inner) is reserved for panels that need to visually detach from the page: dropdown menus, the search modal, and the mobile navigation overlay. This restraint keeps the clean white canvas intact at all times and ensures shadow never competes with the green accent color.

## Shapes

The complete radius scale is declared in the `rounded:` token block above.

| Token | Value | Use |
|---|---|---|
| `none` | 0px | Hard-edged code blocks in some doc contexts |
| `xs` | 2px | Inline code spans, anchor highlights |
| `sm` | 4px | Small badges, toggle switch corners |
| `md` | 8px | Feature cards, dropdown panels, button corners |
| `pill` | 9999px | Search input — the single prominent rounding gesture |

The radius philosophy is measured restraint. Eight pixels is the workhorse — big enough to feel friendly on feature cards, modest enough not to look bubbly. The pill shape is confined to the search bar, echoing the same decision Svelte makes: search is the one affordance that gets a rounded signal because it visually communicates "type here." Everything else — buttons, cards, panels — stays at `{rounded.md}` or below.

## Components

The complete component spec lives in the `components:` token block above. Reference component tokens directly (`{components.button-primary}`, `{components.card}`, etc.).

### Button Variants

- **`button-primary`** — Vue green fill (`{colors.primary}`), white text, 8px radius, compact 8px 16px padding. Used for "Get Started" and primary documentation CTAs. The green earns its impact because it appears here and almost nowhere else.
- **`button-primary-hover`** — Deepens to `{colors.primary-dark}` on hover, staying within the green family.
- **`button-secondary`** — Muted surface fill (`{colors.surface-elevated}`), slate text (`{colors.ink-muted}`). Used for secondary page actions and framework-picker controls. No border — relies on the fill delta from the page background.
- **`button-secondary-hover`** — Lightens back toward `{colors.surface}` on hover, creating a subtle lift.

### Cards

- **`card`** — Off-white surface (`{colors.surface}`), 1px border, 8px radius, 24px padding. Feature tiles and documentation cards. No shadow — border is the sole elevation signal at this level.

### Inputs

- **`input`** — Pill-shaped search input. Off-white fill, generous 28px horizontal padding for the icon indent. Default state is borderless; focus adds a 2px Vue green outline (`{colors.focus-ring}`).
- **`input-focus`** — Adds `2px solid {colors.focus-ring}` (Vue green), maintaining all other values.

### Code Blocks

- **`code-block`** — Off-white surface, Rubik 15px, slate-blue text (`{colors.ink-muted}`), 8px radius, generous 16px 24px padding. Used for documentation code examples and inline terminal strings.

### Badges

- **`badge`** — Muted surface, xs radius, caption-size Inter, in slate-blue. Used for version numbers ("v3.4") and doc-type labels.

### Navigation

- Sticky transparent header with `1px` bottom border in `{colors.border}`.
- Links in Inter weight 500 at 14px, ink-secondary color by default. Hover shifts to `{colors.link-hover}` (Vue green family) via `color-shift` pattern over 0.25s ease.
- Right-aligned: search button (pill shape, ink-secondary text) + dark-mode toggle (circular, 50% radius).

## Do's and Don'ts

### Do
- Use `{colors.primary}` exclusively for primary CTAs and link states — its impact relies on scarcity. A page with five green elements is as signal-less as a page with none.
- Apply Inter weight 900 at hero sizes (76px+) with −1.5px tracking. This is the maximum expression of the variable font range — don't flatten it to 700.
- Use Rubik at 15px for inline code text. The geometric softness distinguishes code from prose without harsh monospace contrast.
- Keep border-radius at `{rounded.md}` (8px) for interactive components; reserve `{rounded.pill}` for search-type inputs only.
- Use the dual-layer shadow pattern only for panels that truly detach: dropdowns, search modals, mobile drawers.
- Keep body copy at `{colors.ink}` (#213547) — the navy-slate warmth is characteristic; don't substitute pure black or mid-gray.
- Let `{colors.ink-muted}` (#476582) carry secondary roles: code annotations, subdued labels, secondary button labels.
- Reference `{colors.primary-dark}` for focus ring and pressed state, not the lighter `{colors.primary-light}`.

### Don't
- Don't use Vue green as a surface fill for cards, sections, or decorative backgrounds. It belongs on interactive elements and text, not areas.
- Don't introduce additional typefaces. The Inter + Rubik pairing is the complete vocabulary — no serifs, no additional sans families.
- Don't apply pill radius to buttons — it belongs to the search input only. Buttons are `{rounded.md}` (8px).
- Don't add decorative section dividers or horizontal rules between marketing blocks. Spacing is the divider.
- Don't use the hero gradient (green-to-periwinkle) for more than one decorative element per view. It's a signature moment, not a recurring pattern.
- Don't weight-stage heading hierarchy with sizes alone — Inter's variable weight capability means weight, not size, is the primary hierarchy signal.
- Don't substitute generic `sans-serif` for Inter in component contexts. The self-hosted variable font stack (`Inter var experimental`) has specific optical tuning that generic fallbacks don't replicate.
- Don't add colored backgrounds to feature sections. The system's contrast comes from typography weight against a plain white canvas.

---

## Responsive Behavior

### Breakpoints
| Name | Width | Key Changes |
|---|---|---|
| Mobile XS | <370px | Minimal single-column, reduced hero font size |
| Mobile | 370–480px | Standard mobile stack, nav collapses |
| Mobile Large | 480–640px | Two-up feature grids begin |
| Tablet Small | 640–768px | Three-column feature layouts at smaller sizes |
| Tablet | 768–960px | Documentation layout with sidebar hints |
| Desktop Small | 960–1280px | Full three-column docs; marketing layout complete |
| Desktop | 1280–1440px | Content capped at max-width; generous margins |
| Large Desktop | >1440px | Centered layout; wide negative space |

### Touch Targets
- Primary buttons: minimum 40px height with 8px 16px padding
- Navigation links: 14px text with sufficient vertical padding for comfortable thumb tap
- Search pill: full-width on mobile with pill shape and focus ring preserved
- Dark-mode/settings toggles: 36px+ circular hit area at 50% radius

### Collapsing Strategy
- Hero display: 76px → 48px → 36px tablet → 28px mobile (weight stays at 900)
- Navigation: horizontal compact links → hamburger overlay on tablet/mobile
- Documentation layout: three-column → two-column (no right sidebar) → single column
- Feature card grid: 3-column → 2-column → single stack
- Section gaps: `{spacing.3xl}` (96px) → `{spacing.2xl}` (48px) on mobile
- Code blocks: horizontal scroll rather than wrapping

### Image Behavior
- Vue logo SVG scales as a block-level inline element
- Hero illustrations and gradient fills maintain aspect ratio
- Documentation screenshots scale with `max-width: 100%` and `height: auto`

---

## Agent Prompt Guide

### Quick Color Reference
- Background: `{colors.background}`
- Primary text: `{colors.ink}`
- Secondary text: `{colors.ink-secondary}`
- Code / subdued: `{colors.ink-muted}`
- Brand accent (CTAs, links): `{colors.primary}`
- Link hover: `{colors.link-hover}`
- Border (hairline): `{colors.border}`
- Focus ring: `{colors.focus-ring}`

### Example Component Prompts

- "Create a Vue-style hero section on white (`{colors.background}`). Headline: Inter weight 900, 76px, line-height 1.25, tracking −1.5px, color `{colors.ink}`. Subhead: Inter weight 400, 22px, line-height 1.5, color `{colors.ink-secondary}`. Primary CTA button: background `{colors.primary}`, text white, padding 8px 16px, 8px radius, Inter weight 600, 16px. On hover: background `{colors.primary-dark}`."
- "Build a documentation feature card: background `{colors.surface}`, 1px solid border `{colors.border}`, 8px radius, 24px padding. Title in Inter weight 600, 20px, color `{colors.ink}`. Body in Inter weight 400, 16px, color `{colors.ink-secondary}`, line-height 1.5. No shadow."
- "Design a navigation bar: white background, 1px solid bottom border `{colors.border}`. Links in Inter weight 500, 14px, color `{colors.ink-secondary}`. On hover: color shifts to `{colors.link-hover}` over 0.25s ease. Right-aligned search pill button and dark-mode toggle."
- "Create a search input: background `{colors.surface}`, pill shape (border-radius 9999px), padding 6px 28px left (icon indent). Text in Inter weight 400, 16px, color `{colors.ink}`. On focus: `outline: 2px solid {colors.focus-ring}` (Vue green). Transition outline 0.2s ease."
- "Build an inline code span: background `{colors.surface}`, 2px radius, padding 2px 6px. Text in Rubik weight 400, 15px, color `{colors.ink-muted}`. Used for variable names and terminal strings in documentation prose."
- "Design a version badge: background `{colors.surface-elevated}`, 2px radius, padding 2px 6px. Text in Inter weight 500, 12px, color `{colors.ink-muted}`. Example content: 'v3.4.21'."

### Iteration Guide

1. Start with white (`{colors.background}`) — Vue never uses a tinted or dark marketing canvas. The white is the discipline.
2. Apply `{colors.primary}` to exactly one CTA per view and to link states. Green earns power from restraint.
3. All display text in Inter variable font, weight 900 at hero size. Don't step down to 700 for the hero — use the full variable range.
4. Body and UI copy at Inter 400 or 500. Rubik at 15px only for inline code fragments — nothing else.
5. Buttons are `{rounded.md}` (8px); search is `{rounded.pill}`. Don't blur this boundary.
6. Section backgrounds stay white. Elevation comes from 1px borders on cards, not fills or shadows.
7. For panels that truly detach (dropdowns, modals), use the dual-layer shadow: `rgba(0,0,0,0.1) 0 12px 32px, rgba(0,0,0,0.08) 0 2px 6px`.

---

## Attribution

Independent design analysis from [Design Swatches](https://designmd.santiagoalonso.com) by [Santiago Alonso](https://santiagoalonso.com). Based on publicly observable interface patterns. Not affiliated with or endorsed by Vue. Brand names and trademarks belong to their respective owners.
