# Stylesheet Redesign Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace `l4d2web/static/css/*` (~1,436 LOC, 196 component classes) with a tiered design system: two-tier tokens, `@layer`-ordered cascade, budgeted component classes, five high-leverage macros, an in-app style guide, and the "system is closed" workflow rule enforced via `AGENTS.md`. **Architecture:** Pure custom CSS (no framework base). Single entry stylesheet `main.css` declares `@layer reset, tokens, elements, layout, components, widgets, utilities;` and `@import`s the rest. Tokens split into `primitives.css` (raw palette) + `semantic.css` (role aliases + dark-mode branch). Component classes are CSS-only by default; macros under `templates/ui/` exist only for five composites where markup correctness is load-bearing (`field`, `modal`, `tabs`, `confirm_form`, `badge_state`). A new public route `/styleguide` is the canonical reference contributors and agents read before producing new UI. **Tech Stack:** Plain CSS using modern features (`@layer`, `color-mix()`, custom properties). Jinja macros for the five composites. Flask blueprint for `/styleguide`. No Sass, no PostCSS, no bundler. **Spec:** `docs/superpowers/specs/2026-05-17-stylesheet-redesign-design.md` --- ## File structure | Action | Path | Contents | |---|---|---| | Create | `l4d2web/static/css/main.css` | Entry. Declares `@layer` order + `@import`s | | Create | `l4d2web/static/css/reset.css` | Modern reset (~30 LOC) | | Create | `l4d2web/static/css/tokens/primitives.css` | Raw palette: grays, blue, red/green/amber, spacing, type scale, radii, shadows, motion, fonts | | Create | `l4d2web/static/css/tokens/semantic.css` | Aliases: `--color-*`, `--space-*`, plus `[data-theme="dark"]` branch | | Create | `l4d2web/static/css/elements.css` | Bare HTML defaults: `body`, `h1-h6`, `a`, `code`, `kbd`, `pre`, `hr`, form elements, tables | | Rewrite | `l4d2web/static/css/layout.css` | `.container`, `.stack`, `.stack-h`, section spacing | | Create | `l4d2web/static/css/components/button.css` | `.btn` + variants/sizes + states | | Create | `l4d2web/static/css/components/field.css` | `.field` + label / hint / error | | Create | `l4d2web/static/css/components/table.css` | `.table` | | Create | `l4d2web/static/css/components/panel.css` | `.panel` + heading / body / footer | | Create | `l4d2web/static/css/components/modal.css` | `.modal` (styles ``) + header / body / footer / close / `.modal-wide` | | Create | `l4d2web/static/css/components/tabs.css` | `.tabs` + `.tab[aria-selected]` + `.tab-panel` | | Create | `l4d2web/static/css/components/badge.css` | `.badge` + semantic + `.state-*` | | Create | `l4d2web/static/css/components/nav.css` | `.site-header`, `.primary-nav`, `.account-nav`, `.brand` | | Create | `l4d2web/static/css/components/dropdown.css` | ` styling is already done in elements.css; this layer exists as a hook for any custom dropdown markup we add later. Keep minimal until a real custom-dropdown widget is needed. */ .dropdown { position: relative; display: inline-block; } .dropdown > select { width: 100%; } ``` - [ ] **Step 5: Verify in browser** Open a page with a modal (e.g. `/servers/1` then click any action that opens one). Open `server_detail.html` and click between the tab buttons — the active one should show a primary-colored underline. Fields in forms (e.g. profile page) should display label / input / hint stacking cleanly. - [ ] **Step 6: Commit** ```bash git add l4d2web/l4d2web/static/css/components/modal.css \ l4d2web/l4d2web/static/css/components/tabs.css \ l4d2web/l4d2web/static/css/components/field.css \ l4d2web/l4d2web/static/css/components/dropdown.css git commit -m "feat(stylesheet): composite components — modal, tabs, field, dropdown" ``` --- ## Task 5: Macros — five high-leverage primitives **Files:** - Create: `l4d2web/templates/ui/_field.html` - Create: `l4d2web/templates/ui/_modal.html` - Create: `l4d2web/templates/ui/_tabs.html` - Create: `l4d2web/templates/ui/_confirm_form.html` - Create: `l4d2web/templates/ui/_badge.html` These are import-only files. No template uses them yet — adoption happens organically as templates are touched. This commit only adds the API surface. - [ ] **Step 1: Create `templates/ui/` directory** ```bash mkdir -p l4d2web/l4d2web/templates/ui ``` - [ ] **Step 2: Write `ui/_field.html`** `l4d2web/l4d2web/templates/ui/_field.html`: ```jinja {# Form field with label, optional hint, optional error. Owns the