WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

ATB-52: CSS Token Extraction — Design#

Status: Approved, ready for implementation Linear: ATB-52 Date: 2026-03-02


Context#

The web UI uses a neobrutal aesthetic with a CSS custom property token system. Most of theme.css already references var(--token) exclusively. Two sections were added separately (moderation UI, structure management UI) and were never aligned with the token schema. This design covers the full extraction.

tokensToCss() and neobrutal-light.ts already exist. The work is: fix the remaining hardcoded values, add one missing token, convert presets to JSON, and add the dark preset.


Audit: Hardcoded Values Remaining#

Moderation UI (theme.css lines 751–821)#

Hardcoded value Replace with
var(--space-2) var(--space-sm) (8px = 0.5rem)
var(--space-4) var(--space-md) (16px = 1rem)
var(--space-6) var(--space-lg) (24px = 1.5rem)
1px solid var(--color-border) var(--border-width) solid var(--color-border)
2px solid currentColor var(--border-width) solid currentColor
border-radius: 0 var(--radius)
font-weight: 700 var(--font-weight-bold)
0.25rem 0.6rem (mod-btn padding) var(--space-xs) var(--space-sm)
0.75rem (mod-btn font-size) var(--font-size-xs) ← new token
1.25rem (dialog title font-size) var(--font-size-lg) (20px = 1.25rem)
6px 6px 0 var(--color-shadow) var(--card-shadow)
color: #fff (hover text) var(--color-surface)
var(--color-danger, #d00) var(--color-danger) (remove fallback)
var(--color-text-muted, #666) var(--color-text-muted) (remove fallback)
3px solid var(--color-border) var(--border-width) solid var(--color-border)

Structure UI (theme.css lines 1003–1154)#

Hardcoded value Replace with
var(--space-6, 1.5rem) var(--space-lg) (remove fallback)
var(--radius, 0.5rem) var(--radius) (remove fallback)
var(--radius, 0.375rem) var(--radius) (remove fallback)
var(--font-size-xl, 2rem) var(--font-size-xl) (remove fallback)

Token Schema Addition#

One new token added to complete the type scale:

Token neobrutal-light neobrutal-dark Description
font-size-xs 12px 12px Extra-small text (mod buttons, badges)

Preset Files#

Format#

Convert from TypeScript to JSON. resolveJsonModule: true is already set in tsconfig.base.json — no config changes needed. Import in base.tsx changes to:

import neobrutalLight from "../styles/presets/neobrutal-light.json" assert { type: "json" };

Or, since moduleResolution: bundler is set, the assert clause may not be required — verify during implementation.

neobrutal-light.json (converted from existing TS, adds font-size-xs)#

{
  "color-bg": "#f5f0e8",
  "color-surface": "#ffffff",
  "color-text": "#1a1a1a",
  "color-text-muted": "#555555",
  "color-primary": "#ff5c00",
  "color-primary-hover": "#e04f00",
  "color-secondary": "#3a86ff",
  "color-border": "#1a1a1a",
  "color-shadow": "#1a1a1a",
  "color-success": "#2ec44a",
  "color-warning": "#ffbe0b",
  "color-danger": "#ff006e",
  "color-code-bg": "#1a1a1a",
  "color-code-text": "#f5f0e8",
  "font-body": "'Space Grotesk', system-ui, sans-serif",
  "font-heading": "'Space Grotesk', system-ui, sans-serif",
  "font-mono": "'JetBrains Mono', ui-monospace, monospace",
  "font-size-base": "16px",
  "font-size-sm": "14px",
  "font-size-xs": "12px",
  "font-size-lg": "20px",
  "font-size-xl": "28px",
  "font-size-2xl": "36px",
  "font-weight-normal": "400",
  "font-weight-bold": "700",
  "line-height-body": "1.6",
  "line-height-heading": "1.2",
  "space-xs": "4px",
  "space-sm": "8px",
  "space-md": "16px",
  "space-lg": "24px",
  "space-xl": "40px",
  "radius": "0px",
  "border-width": "2px",
  "shadow-offset": "2px",
  "content-width": "100%",
  "button-radius": "0px",
  "button-shadow": "2px 2px 0 var(--color-shadow)",
  "card-radius": "0px",
  "card-shadow": "4px 4px 0 var(--color-shadow)",
  "btn-press-hover": "1px",
  "btn-press-active": "2px",
  "input-radius": "0px",
  "input-border": "2px solid var(--color-border)",
  "nav-height": "64px"
}

neobrutal-dark.json (new)#

Same structural/typography/spacing tokens. Color tokens that differ:

Token Value
color-bg #1a1a1a
color-surface #2d2d2d
color-text #f5f0e8
color-text-muted #a0a0a0
color-primary-hover #ff7a2a (lightened for dark bg)
color-border #f5f0e8 (inverted from light)
color-shadow #000000
color-code-bg #111111

All other tokens (primary, secondary, success, warning, danger, all typography, all spacing, all component) are identical to neobrutal-light.


File Changes#

File Action
public/static/css/theme.css Fix ~15 hardcoded values in mod UI + structure UI
src/styles/presets/neobrutal-light.ts Delete
src/styles/presets/neobrutal-light.json Create (converted from TS, adds font-size-xs)
src/styles/presets/neobrutal-dark.json Create (dark color tokens, same structure)
src/layouts/base.tsx Update import to JSON
src/lib/theme.ts No changes
src/lib/__tests__/theme.test.ts No changes

Acceptance Criteria (from ATB-52)#

  • theme.css contains zero hardcoded color values, font stacks, spacing values, or font sizes — all use var(--token)
  • No fallback values in var() calls (fallbacks are hardcoded values in disguise)
  • tokensToCss() utility exists and is tested (already satisfied)
  • neobrutal-light.json and neobrutal-dark.json ship with complete token sets
  • --font-size-xs added to both presets
  • base.tsx imports from JSON and the forum renders identically to before
  • All existing views render correctly after the refactor