# Spacing, radii & surfaces

> The 4px step, the radius scale, borders, shadows, glass and focus states.

Both apps use Tailwind's 4px step. Controls are 32px (`space-8`, small), 36px (`space-9`, default) or 40px (`space-10`, large) tall; fields pad 12px (`space-3`) inline; buttons 16px (`space-4`); cards pad and gap 24px (`space-6`). Settings sections use `crew-settings-gap` (24px; 16px at compact density). Compact density — a personal Appearance setting — only tightens table cell padding (6px block) and settings spacing; never shrink controls for it.

Max is a sidebar app (see [**Sidebar**](/design/components/sidebar.md)): a 16rem sidebar from `md` (768px) up that collapses to 3rem icons or hides (⌘/Ctrl+B), beside an inset content panel with 8px margins and `radius-xl` corners. The header is 56px (64px from `sm`) with the search trigger and ⌘K hint; `main` pads 16px × 24px and centres at 80rem (`max-w-7xl`) on wide screens. Page headers are an `h1` in `max-title` (24px bold, tight) over a 14px `muted-foreground` line, in a row that wraps its actions: `flex flex-wrap items-center justify-between gap-3`. Many sections sit in the glass shell `glass-panel border border-glass rounded-3xl px-6 py-6`. On phones a 56px bottom tab bar holds four destinations plus **More**; it is 3.5rem plus the safe-area inset, and anything anchored to the bottom adds `--app-bottom-inset` so nothing hides behind it. Below `lg`, views show one column at a time, filters move into a bottom sheet and the main create action floats as a **+** button. Crew OS's public hero centres in a `max-w-3xl` column; the sections below it run full-bleed.

## Radii

`--radius` is 10px in both apps. Buttons, inputs and textareas use `radius-md` (8px); cards `radius-xl` (14px); settings sections and toggles `r-lg` (12px); popovers and menus `radius-lg` (10px); small chips `radius-sm` (6px). Pills (`r-full`) are for switches, hero CTAs, the hero badge and avatars. The logo itself is square-cornered — don't round it.

## Borders, shadows and glass

Elevation is carried by surface steps and hairlines first, shadow second. `shadow-xs` sits under outline buttons and fields; `shadow-sm` under cards. Both apps have a **glass** layer for surfaces floating over imagery, video or gradient grounds: translucent white fill, `backdrop-glass*` blur-and-saturate, a translucent white hairline, and `shadow-glass-panel` or `shadow-glass-card`. Use glass only over something worth seeing through; on a plain ground use `card`. Respect `prefers-reduced-transparency` by dropping the backdrop filter.

The **Glass button finish** (Appearance setting) adds a frosted inset highlight to default buttons without changing their colour or size.

## Focus and states

Every interactive element shows a focus ring built from `ring`: primitives draw a 3px `ring` halo plus a `ring` border (`focus-visible` only); the switch and native selects draw a 2px `ring` outline offset by 2px. In Crew OS `ring` is a mid grey (4.5:1 light, 7.8:1 dark) so it shows next to a black button; in Max it follows `primary`. Hover drops a fill to 90% opacity (`primary`, `destructive`) or 80% (`secondary`), or lays `accent` under ghost and outline controls. Disabled is 50% opacity with no pointer events. Invalid is `aria-invalid` → `destructive` border and a faint `destructive` halo, with the message below the field.

## Spacing scale

Both apps use Tailwind v4's 4px step (--spacing: 0.25rem); these are the steps the shared components use.

| Token | Value | Usage |
|---|---|---|
| `space-1` | 4px | Tightest gap: icon-to-text in badges, stacked helper lines. |
| `space-1.5` | 6px | Small Button icon gap (gap-1.5); description offset under settings titles. |
| `space-2` | 8px | Button icon gap, CardHeader row gap, Textarea vertical padding, label-to-field gap. |
| `space-3` | 12px | Input/Textarea horizontal padding; small Button padding; gap between inline controls. |
| `space-4` | 16px | Default Button horizontal padding; compact settings gap; settings header gap. |
| `space-5` | 20px | Appearance toggle row inline padding. |
| `space-6` | 24px | Card padding and inner gap (px-6 py-6 gap-6); large Button padding. |
| `crew-settings-gap` | 24px | Settings section padding and field gap, comfortable density (16px when data-density is compact). |
| `space-8` | 32px | Small Button and icon-button height (h-8); appearance preview padding. |
| `space-9` | 36px | Default Button and Input height (h-9). |
| `space-10` | 40px | Large Button height (h-10). |

## Radius scale

Both apps set --radius: 0.625rem and derive sm/md/xl from it; values below are those calc() results.

| Token | Value | Usage |
|---|---|---|
| `radius` | 10px | The base radius both apps set; `radius-lg` equals it. |
| `radius-sm` | 6px | calc(radius - 4px): small chips, inner elements. |
| `radius-md` | 8px | calc(radius - 2px): Button, Input, Textarea (rounded-md). |
| `radius-lg` | 10px | Popovers, menus, sheets. |
| `r-lg` | 12px | Settings sections, appearance toggles and previews (0.75rem). |
| `radius-xl` | 14px | calc(radius + 4px): Card (rounded-xl). |
| `r-full` | 9999px | Pills: Switch track and thumb, hero CTAs, the hero badge, avatars. |

## Shadows

| Token | Value | Usage |
|---|---|---|
| `shadow-xs` | `0 1px 2px 0 rgba(0, 0, 0, 0.05)` | Outline Button, Input, Textarea. |
| `shadow-sm` | `0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)` | Card. |
| `shadow-glass-panel` | crew-light: `0 8px 32px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.6)`; crew-dark: `0 8px 32px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08)`; max-light: `0 8px 32px 0 rgba(31, 38, 135, 0.07), inset 0 1px 1px 0 rgba(255, 255, 255, 0.9)`; max-dark: `0 8px 32px 0 rgba(0, 0, 0, 0.4), inset 0 1px 1px 0 rgba(255, 255, 255, 0.08)` | `.glass-panel`: floating panels over imagery or gradient grounds, with `backdrop-glass-panel`. |
| `shadow-glass-card` | crew-light: `0 4px 24px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03)`; crew-dark: `0 4px 24px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.15)`; max-light: `0 4px 24px 0 rgba(31, 38, 135, 0.05), inset 0 1px 1px 0 rgba(255, 255, 255, 0.95)`; max-dark: `0 4px 24px 0 rgba(0, 0, 0, 0.3), inset 0 1px 1px 0 rgba(255, 255, 255, 0.06)` | `.glass-card`: cards on gradient or image grounds, with `backdrop-glass`. |

## Glass (backdrop)

| Token | Value | Usage |
|---|---|---|
| `backdrop-glass` | `blur(16px) saturate(180%)` | `.glass` and `.glass-card`. |
| `backdrop-glass-subtle` | `blur(12px) saturate(160%)` | `.glass-subtle`: light frosting behind small chips and bars. |
| `backdrop-glass-panel` | `blur(20px) saturate(180%)` | `.glass-panel`. |
| `backdrop-glass-strong` | `blur(24px) saturate(200%)` | `.glass-strong`: dialogs and menus over busy grounds. |
| `backdrop-glass-button` | `blur(12px) saturate(140%)` | `.glass-button` and the Glass button finish: surface-only, keeps the CTA's own colour. |
| `backdrop-glass-input` | `blur(8px)` | `.glass-input`. |
