# BlogBat design system

This is the canonical context for BlogBat surfaces. Read `.agents/brand.md` before changing them.

## Overview

BlogBat uses a bold night story. Its system lives in `apps/web/src/app/globals.css` and `packages/ui`.
Keep product styling separate from tenant themes. Owners control their fonts, colors, logos, and layouts.

## Colors

| Role | Light value | Dark value | Use |
| --- | --- | --- | --- |
| `--background` | `oklch(0.99 0.004 285)` | `oklch(0.16 0.025 285)` | Page canvas |
| `--foreground` | `oklch(0.17 0.02 285)` | `oklch(0.96 0.006 285)` | Primary text and ink borders |
| `--card` | `oklch(1 0.003 285)` | `oklch(0.21 0.03 285)` | Persistent panels |
| `--primary` | `oklch(0.55 0.23 285)` | `oklch(0.68 0.2 285)` | Main actions and violet highlights |
| `--secondary` | `oklch(0.96 0.02 285)` | `oklch(0.28 0.04 285)` | Secondary actions |
| `--muted` | `oklch(0.965 0.008 285)` | `oklch(0.27 0.025 285)` | Quiet surfaces |
| `--accent` | `oklch(0.96 0.04 75)` | `oklch(0.32 0.05 75)` | Warm dusk emphasis |
| `--border` | `oklch(0.92 0.01 285)` | `oklch(0.98 0.02 285 / 14%)` | Light dividers |
| `--ring` | `oklch(0.55 0.23 285)` | `oklch(0.68 0.2 285)` | Keyboard focus |
| `--link` | `oklch(0.55 0.23 285)` | `oklch(0.74 0.18 285)` | Text links |

The brand pack uses `#6D4AFF`; product components use semantic `--primary`.
Use status tokens only for their named meaning.
Apply tenant colors through the public-theme layer, never global product variables.

## Typography

Geist Sans is the product face. Geist Mono handles technical values.
Anton is the display face for short marketing statements, not paragraphs or controls.

- Use `font-sans` for product navigation, forms, settings, and body copy.
- Use `font-display` for selected marketing headlines and marquees.
- Use `font-mono` for code, commands, counts, and structured values.
- Keep headings short and preserve a clear document hierarchy.
- Keep body text readable with normal sentence casing and measured line lengths.
Tenant fonts belong to tenant content, not product defaults.

## Layout

Marketing uses `max-w-6xl`, `px-4`, and `sm:px-6`.

- Start with one column and add grids at named breakpoints.
- Keep the primary action near the related message.
- Use calmer spacing and density inside product workflows.
- Preserve touch targets and readable gutters on small screens.

Marketing can use full-width bands. Dashboards follow existing sidebar and content-shell patterns.

## Elevation & Depth

| Token | Value | Use |
| --- | --- | --- |
| `--shadow-subtle` | `rgba(0, 0, 0, 0.04) 0 1px 2px` | Small controls and quiet emphasis |
| `--shadow-keystone` | Two compact low-opacity layers | Cards and lifted sticker states |
| `--shadow-floating` | One outline plus a broad `0 8px 24px -4px` layer | Floating panels |

Marketing pairs shadows with a two-pixel border. Sticker controls move on hover and press.

Use surface and border hierarchy first. Reserve `--shadow-floating` for elevated content.

## Shapes

Tailwind radius roles derive from `--radius: 0.625rem`.

| Role | Formula |
| --- | --- |
| `sm` | `calc(var(--radius) - 4px)` |
| `md` | `calc(var(--radius) - 2px)` |
| `lg` | `var(--radius)` |
| `xl` | `calc(var(--radius) + 4px)` |
| `2xl` | `calc(var(--radius) + 8px)` |
| `3xl` | `calc(var(--radius) + 12px)` |
| `4xl` | `calc(var(--radius) + 16px)` |

Use the base radius for buttons and cards; use pills for badges, status, and short selectors.

Reuse the shared `BAT_PATH_D`; do not approximate its silhouette.

## Components

Prefer primitives from `packages/ui` before building a local variant.

### Buttons

The shared button uses a two-pixel ink border, a compact shadow, and physical press feedback.

- Use `default` for the primary action.
- Use `secondary` or `outline` for supporting actions.
- Use `ghost` for low-emphasis navigation.
- Preserve disabled, focus-visible, hover, and active states.

### Cards and floating panels

Cards pair their semantic colors with the base radius, border, and keystone shadow.
Use `--popover` for transient content. Keep routine dashboard panels quieter than marketing cards.

### Forms and feedback

- Give every field a visible label or accessible name.
- Use `--input` for field boundaries and `--ring` for keyboard focus.
- Place validation beside the affected control.
- Do not rely on color alone to communicate a result.

### Brand and motion

Reuse `BatMark` inline and approved files from `apps/web/public/brand/` in marketing.

Tie motion to meaning or feedback. Honor `prefers-reduced-motion` without hiding content or actions.

## Do's and Don'ts

### Do

- Read `.agents/brand.md` before changing product identity.
- Use semantic tokens and shared primitives.
- Keep product and tenant theme values separate.
- Test keyboard focus, contrast, narrow layouts, and reduced motion.

### Don't

- Do not hardcode `#6D4AFF` inside product components.
- Do not redraw or distort the bat mark.
- Do not use display type for long copy or controls.
- Do not ship motion without an equivalent reduced-motion state.
