---
prompt-id: "04"
name: Composite components — Modal, Drawer, Popover, Tabs, Accordion, Combobox, etc.
status: live
mcp: none
model: Sonnet 4.6
environment: Claude.ai or Claude Code
inputs:
  - output/tokens.css
  - output/components/foundation.css
  - specs/governance.spec.md
  - specs/<archetype>.spec.md
outputs:
  - output/components/composite.css
chains: [3, 9]
prereqs: ["03"]
documented-in: Ch06 — Composite Components
---

# Prompt 04 — Composite components

Generates the composite component set — components that compose foundation primitives.
Every variant, every interactive state, and every accessibility annotation in place.

---

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
META-HEADER — run before generating any CSS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

STEP -2 — DETECT ENVIRONMENT
Check whether you have file-write access (Claude Code / IDE) or
are in a chat session (Claude.ai).
  Claude Code: outputs will be saved automatically to
               output/components/composite.css
  Claude.ai:   at save points, provide copy-paste instructions
               with the exact filename and target path.

STEP -1 — CONTEXT CHECK
Verify the following files exist and read them before proceeding:
  output/tokens.css                   → REQUIRED
  output/components/foundation.css    → REQUIRED — composite
                                          components build on top
                                          of foundation class names
  specs/governance.spec.md            → REQUIRED
  specs/<archetype>.spec.md           → REQUIRED
  output/chain-state.md               → read if present

If tokens.css or foundation.css is missing, stop and ask
before generating any CSS.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MAIN PROMPT BODY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PROMPT 04 — COMPOSITE COMPONENT CSS

YOUR ROLE
You are a design-system CSS engineer extending the foundation
set. You translate tokens.css + foundation.css + both specs into
composite.css — components that combine two or more foundation
primitives. You reference foundation class names as expected
child elements (not as wrappers). Zero hardcoded values: every
colour, spacing, and radius must reference a token.

COMPOSITE MEANS: built from foundation pieces
A composite component contains and orchestrates foundation
components. Modal contains Button + optional Form. Combobox
contains Input + Badge + Popover. Your CSS scopes child rules
relative to the composite root — no global overrides.

THE COMPOSITE COMPONENT SET
Generate CSS for these components in this order:

  1. Modal (overlay + panel, contains Dialog shell)
  2. Drawer (slide-in panel — left/right/bottom)
  3. Popover (anchored floating panel)
  4. Tooltip (short-form popover, no interactive content)
  5. Tabs (tab bar + panel)
  6. Accordion (expand/collapse sections)
  7. Combobox (Input + dropdown list + Badge for multi-select)
  8. Date picker (Input + calendar grid)
  9. Toast / Snackbar (timed notification, queued)
  10. Pagination (page nav control)
  11. Stepper (multi-step flow indicator)
  12. Command palette (Cmd+K interface — search + results list)

For EACH component generate:
  — Base class (resting state)
  — All variants defined in the archetype spec COMPONENTS section
  — All interactive states including keyboard navigation states
    (:focus-visible, [aria-expanded], [aria-selected],
    [aria-checked], [data-state="open/closed"])
  — Transition / animation — fade, slide, scale — but always
    wrap in @media (prefers-reduced-motion: no-preference) {}
    so users who prefer reduced motion get instant transitions

MODAL — SPECIFIC RULES
  — Overlay: position:fixed inset:0 z-index token (--z-modal)
  — Panel: centred, max-width from governance COMPONENTS,
    max-height 90vh, overflow-y:auto
  — Use foundation Dialog panel class as the inner shell
  — Enter/exit: fade overlay + scale-from-95 panel
  — Sizes: sm (400px), md (600px), lg (800px) — use tokens

DRAWER — SPECIFIC RULES
  — Slide-in from left, right, or bottom (variant classes)
  — Overlay same as modal; panel edge-to-edge on its axis
  — Width (left/right): from governance spec or 320px token
  — Height (bottom): 50vh default, resizable via drag handle
    (annotate drag handle as a CSS-only hook)

POPOVER — SPECIFIC RULES
  — position:absolute or position:fixed depending on context
  — Arrow pointer via CSS clip-path or border-trick
  — Placement variants: top, bottom, left, right + auto-flip
    (annotate auto-flip as JS responsibility)
  — z-index: --z-popover token (below modal, above page)
  — Max-width 320px; overflow-y:auto for tall content

TOOLTIP — SPECIFIC RULES
  — Same anchor mechanic as popover but no interactive content
  — Delay: 400ms show, 100ms hide — annotate as CSS transitions
  — Max-width 200px, --font-size-sm, padding-tight
  — WCAG: tooltip content duplicates aria-label on trigger
    (annotate: requires role="tooltip" + id on tooltip element)

TABS — SPECIFIC RULES
  — Tab list: horizontal strip of tab buttons (role="tablist")
  — Active tab: --color-primary underline 2px (token-driven)
  — Disabled tab: --color-text-disabled, pointer-events:none
  — Panel: role="tabpanel", padding from governance
  — Vertical variant: tabs on left side, panel fills right

ACCORDION — SPECIFIC RULES
  — Trigger: full-width button with chevron icon right-aligned
  — Chevron rotates 180deg on open (CSS transform)
  — Panel: max-height transition for smooth expand
    (use @media prefers-reduced-motion wrapper)
  — Nested accordion: indent 16px (one --spacing step)

COMBOBOX — SPECIFIC RULES
  — Input triggers dropdown on focus / typing
  — Dropdown: Popover shell containing option list
  — Option hover/focus: --color-surface-hover background
  — Selected option: --color-primary-subtle + checkmark icon
  — Multi-select: selected items render as Badge pills inside
    the Input field
  — Empty state: "No results" message using Empty state styles

DATE PICKER — SPECIFIC RULES
  — Text input triggers Popover containing calendar grid
  — Calendar: 7-column grid, Mon–Sun headers
  — Today: --color-primary-subtle ring
  — Selected: --color-cta-bg background, --color-cta-text text
  — Range selection: --color-primary-subtle between start/end
  — Disabled dates: --color-text-disabled, line-through

TOAST / SNACKBAR — SPECIFIC RULES
  — Fixed position: bottom-right (default), bottom-centre (mobile)
  — Stack multiple: gap-2 using spacing token
  — Variants: info, success, warning, error (reuse Alert palette)
  — Auto-dismiss: progress bar animation, 4s default
    (annotate: JS sets --toast-progress-duration custom property)
  — Manual dismiss button: inherits Alert dismissible pattern

PAGINATION — SPECIFIC RULES
  — Prev / Next chevron buttons + numbered page buttons
  — Active page: --color-cta-bg + --color-cta-text
  — Ellipsis: ... for large page ranges (CSS content: "…")
  — Compact variant: Prev / [n of n] / Next only

STEPPER — SPECIFIC RULES
  — Horizontal row of step circles with connecting lines
  — States: completed (checkmark, --color-success),
    active (--color-primary ring), upcoming (--color-border)
  — Vertical variant for narrow containers
  — Step label below each circle, wraps to two lines max

COMMAND PALETTE — SPECIFIC RULES
  — Full-viewport overlay (same z-index layer as modal)
  — Search input at top, prominent, auto-focused
  — Results list below: icon + label + keyboard shortcut right
  — Category separators between result groups
  — Active result: --color-surface-hover background
  — Matches Lattice archetype most naturally; apply the
    monospace/terminal aesthetic when Lattice is active

ARCHETYPE-SPECIFIC OVERRIDES
  Harbor:    drawers use dark surface; popover arrow teal-tinted
  Sentinel:  hard edges on all overlays (border-radius:0 or
             --radius-sm); all elevation via border, not shadow
  Current:   drawer height 60vh min; tabs full-width on mobile;
             44px min-height on all tab triggers
  Lattice:   command palette priority component; compact density;
             monospace option labels
  Meridian:  generous popover padding; accordion panels use
             --font-size-md body; stepper vertical preferred

OUTPUT FORMAT
  /* ── 04 COMPOSITE COMPONENTS ──────────────────────────────── */
  /* ── Modal ──────────────────────────────────────────────────── */
  ...
  /* ── Drawer ─────────────────────────────────────────────────── */
  ...

One continuous CSS file. No HTML, no JS, no @import.
All tokens must exist in tokens.css. Flag gaps in a comment
block at the top.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
META-FOOTER — after generating CSS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SAVE INSTRUCTION
Save as: output/components/composite.css

CHAIN-STATE LOG
Append to output/chain-state.md:

  ## Prompt 04 — Composite components
  Date: <today>
  Archetype: <confirmed archetype>
  Components generated: Modal, Drawer, Popover, Tooltip, Tabs,
    Accordion, Combobox, Date picker, Toast, Pagination,
    Stepper, Command palette
  Output: output/components/composite.css
  Token gaps flagged: <count or "none">

HANDOFF
  "Composite components done. Next → Prompt 05 — Pattern
   components (hero, data-table pattern, sidebar layout, etc.).
   Paste governance spec + archetype spec + both CSS files
   before running Prompt 05."
```
