---
version: "alpha"
name: "Framebrick Blocks — Default"
description: "Default, a sample theme of Framebrick Blocks: shadcn/ui neutral, Geist, 0.625rem radius — how every block ships."
colors:
  background: "#FFFFFF"
  foreground: "#0A0A0A"
  card: "#FFFFFF"
  card-foreground: "#0A0A0A"
  popover: "#FFFFFF"
  popover-foreground: "#0A0A0A"
  primary: "#171717"
  primary-foreground: "#FAFAFA"
  secondary: "#F5F5F5"
  secondary-foreground: "#171717"
  muted: "#F5F5F5"
  muted-foreground: "#737373"
  accent: "#F5F5F5"
  accent-foreground: "#171717"
  destructive: "#E7000B"
  border: "#E5E5E5"
  input: "#E5E5E5"
  ring: "#A1A1A1"
  background-dark: "#0A0A0A"
  foreground-dark: "#FAFAFA"
  card-dark: "#171717"
  card-foreground-dark: "#FAFAFA"
  popover-dark: "#171717"
  popover-foreground-dark: "#FAFAFA"
  primary-dark: "#E5E5E5"
  primary-foreground-dark: "#171717"
  secondary-dark: "#262626"
  secondary-foreground-dark: "#FAFAFA"
  muted-dark: "#262626"
  muted-foreground-dark: "#A1A1A1"
  accent-dark: "#262626"
  accent-foreground-dark: "#FAFAFA"
  destructive-dark: "#FF6467"
  border-dark: "rgba(255, 255, 255, 0.1)"
  input-dark: "rgba(255, 255, 255, 0.15)"
  ring-dark: "#737373"
  on-primary: "{colors.primary-foreground}"
  on-secondary: "{colors.secondary-foreground}"
  surface: "{colors.card}"
  on-surface: "{colors.card-foreground}"
  on-surface-variant: "{colors.muted-foreground}"
  neutral: "{colors.background}"
  outline: "{colors.border}"
  error: "{colors.destructive}"
typography:
  display:
    fontFamily: "Geist"
    fontSize: "72px"
    fontWeight: 600
    lineHeight: 1.05
    letterSpacing: "-0.025em"
  h1:
    fontFamily: "Geist"
    fontSize: "60px"
    fontWeight: 600
    lineHeight: 1.1
    letterSpacing: "-0.025em"
  h2:
    fontFamily: "Geist"
    fontSize: "48px"
    fontWeight: 600
    lineHeight: 1.15
    letterSpacing: "-0.025em"
  h3:
    fontFamily: "Geist"
    fontSize: "24px"
    fontWeight: 600
    lineHeight: 1.3
    letterSpacing: "-0.025em"
  lead:
    fontFamily: "Geist"
    fontSize: "20px"
    fontWeight: 400
    lineHeight: 1.6
  body:
    fontFamily: "Geist"
    fontSize: "16px"
    fontWeight: 400
    lineHeight: 1.5
  small:
    fontFamily: "Geist"
    fontSize: "14px"
    fontWeight: 400
    lineHeight: 1.43
  label:
    fontFamily: "Geist"
    fontSize: "14px"
    fontWeight: 500
    lineHeight: 1.43
  caption:
    fontFamily: "Geist"
    fontSize: "12px"
    fontWeight: 400
    lineHeight: 1.33
rounded:
  sm: "6px"
  md: "8px"
  lg: "10px"
  xl: "14px"
  full: "9999px"
spacing:
  section-y: "128px"
  section-y-phone: "64px"
  gutter: "40px"
  gutter-phone: "20px"
  container: "1280px"
components:
  button:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: "8px 16px"
    height: "36px"
  button-small:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: "0px 12px"
    height: "32px"
  button-large:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: "0px 24px"
    height: "40px"
  button-outline:
    backgroundColor: "{colors.background}"
    textColor: "{colors.foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: "8px 16px"
    height: "36px"
  button-outline-hover:
    backgroundColor: "{colors.accent}"
    textColor: "{colors.accent-foreground}"
  button-secondary:
    backgroundColor: "{colors.secondary}"
    textColor: "{colors.secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: "8px 16px"
    height: "36px"
  card:
    backgroundColor: "{colors.muted}"
    textColor: "{colors.foreground}"
    rounded: "{rounded.xl}"
    padding: "20px"
  card-raised:
    backgroundColor: "{colors.card}"
    textColor: "{colors.card-foreground}"
    rounded: "{rounded.xl}"
    padding: "20px"
  chip:
    backgroundColor: "{colors.muted}"
    textColor: "{colors.foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.md}"
    padding: "4px 8px"
  icon-square:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    rounded: "{rounded.md}"
    size: "36px"
  input:
    backgroundColor: "{colors.background}"
    textColor: "{colors.foreground}"
    typography: "{typography.body}"
    rounded: "{rounded.lg}"
    padding: "4px 10px"
    height: "32px"
  tint:
    backgroundColor: "{colors.accent}"
    textColor: "{colors.accent-foreground}"
    rounded: "{rounded.lg}"
---

# Framebrick Blocks — Default

> The design tokens and style rules of this project's theme, made with Framebrick Blocks (https://framebrick.co/blocks): shadcn/ui and Tailwind CSS v4 sections that read their look from `app/globals.css`. Read it before you build or change a page, so new work matches the sections already here. The front matter holds the exact values; the sections below say where and how to use them. Format: [DESIGN.md](https://github.com/google-labs-code/design.md), spec version `alpha`.

## Overview

Default, a sample theme of Framebrick Blocks: shadcn/ui neutral, Geist, 0.625rem radius — how every block ships.

Every colour, size and corner is a CSS variable in `app/globals.css` — the shadcn/ui variables (`--background`, `--primary`, `--muted-foreground`…), `--radius`, and the Framebrick block tokens (`--text-display`, `--text-h1`, `--text-h2`, `--text-h3`, `--text-lead`, `--section-y`, `--gutter`, `--container`). Use them through Tailwind's classes (`bg-primary`, `text-muted-foreground`, `rounded-xl`, `text-h2`, `py-(--section-y)`, `px-(--gutter)`, `max-w-(--container)`), never as literal values: the theme can then change in one file, and dark mode follows the `.dark` class.

## Colors

Token names are the shadcn variables, so `bg-<name>` and `text-<name>` are the classes to write. Light mode is the token set; `-dark` tokens are the same variable under `.dark`.

| Token | Light | Dark | Use |
|---|---|---|---|
| `background` | #FFFFFF | #0A0A0A | The page and every section that has no tone of its own. |
| `foreground` | #0A0A0A | #FAFAFA | Text on the page: headings, body text, icons. |
| `card` | #FFFFFF | #171717 | Cards that stand apart from a muted band: testimonial and story cards. |
| `card-foreground` | #0A0A0A | #FAFAFA | Text on a card. |
| `popover` | #FFFFFF | #171717 | Menus and dialogs. |
| `popover-foreground` | #0A0A0A | #FAFAFA | Text in a menu or dialog. |
| `primary` | #171717 | #E5E5E5 | The accent: filled buttons, the chosen tab, a progress bar, the current item, icon squares. |
| `primary-foreground` | #FAFAFA | #171717 | Text and icons on primary. |
| `secondary` | #F5F5F5 | #262626 | Secondary buttons and quiet fills. |
| `secondary-foreground` | #171717 | #FAFAFA | Text on secondary. |
| `muted` | #F5F5F5 | #262626 | Cards, chips and panels inside a section (the blocks' most common surface). |
| `muted-foreground` | #737373 | #A1A1A1 | Secondary text on the page and on cards: leads, descriptions, meta, labels. |
| `accent` | #F5F5F5 | #262626 | Hover fills of ghost and outline buttons and menu items; a tint of the primary colour. |
| `accent-foreground` | #171717 | #FAFAFA | Text on accent. |
| `destructive` | #E7000B | #FF6467 | Errors: a failed form send, a required field's mark. |
| `border` | #E5E5E5 | rgba(255, 255, 255, 0.1) | Hairlines between rows, card and field borders, dividers. |
| `input` | #E5E5E5 | rgba(255, 255, 255, 0.15) | Form field borders. |
| `ring` | #A1A1A1 | #737373 | Focus rings. |

Semantic names in the front matter point at these: `on-primary` → `primary-foreground`, `on-secondary` → `secondary-foreground`, `surface` → `card`, `on-surface` → `card-foreground`, `on-surface-variant` → `muted-foreground`, `neutral` → `background`, `outline` → `border`, `error` → `destructive`.

## Typography

**Geist** for everything (`font-sans`; `font-heading` points at the same font), loaded with `next/font` in `app/layout.tsx`.

The heading sizes are fluid (`clamp()`): they grow with the window from the phone size to the desktop size, which the front matter gives. Headings are `font-heading font-semibold tracking-tight` with `text-balance`; body text wraps with `text-pretty`.

| Token | Size (phone → desktop) | Line height | Weight | Class | Use |
|---|---|---|---|---|---|
| `display` | 40px → 72px | 1.05 | 600 | `text-display` | The largest heading: a hero's title (`text-display`). |
| `h1` | 36px → 60px | 1.1 | 600 | `text-h1` | A page's title (`text-h1`), and the big figures. |
| `h2` | 30px → 48px | 1.15 | 600 | `text-h2` | A section's title (`text-h2`), the h2 of every block. |
| `h3` | 20px → 24px | 1.3 | 600 | `text-h3` | Card, row and panel titles; a lead set large (`text-h3`). |
| `lead` | 17px → 20px | 1.6 | 400 | `text-lead` | The text under a hero's or a section's title (`text-lead`). |
| `body` | 16px | 1.5 | 400 | `text-base` | Paragraphs, list items, form fields. |
| `small` | 14px | 1.43 | 400 | `text-sm` | Card text, meta, captions under photos, footer links. |
| `label` | 14px | 1.43 | 500 | `text-sm font-medium` | Button labels, labels above headings, form labels, menu links. |
| `caption` | 12px | 1.33 | 400 | `text-xs` | Chips, tags, the smallest notes. |

## Layout

Every section is a full-width `<section>` that sets its own vertical padding and container, so sections stack in any order with no margin between them:

```html
<section class="py-(--section-y)">
  <div class="mx-auto max-w-(--container) px-(--gutter)">…</div>
</section>
```

| Token | Phone → desktop | Use |
|---|---|---|
| `section-y` | 64px → 128px | Vertical padding of every section (`py-(--section-y)`); a tight band uses half. |
| `gutter` | 20px → 40px | Side padding of every section, the header and the footer (`px-(--gutter)`). |
| `container` | 1280px | The widest content, centred (`mx-auto max-w-(--container)`). |

Breakpoints are Tailwind's: `md` from 768px and `lg` from 1024px. Grids go from one column on phones to two from 768px and three or four from 1024px; parts of a section sit 24–48px apart (`gap-6` to `gap-12`), cards in a grid 10–32px apart.

## Elevation & Depth

The theme is flat. Depth comes from fills, not shadows: `muted` cards on the `background` page, `card` for a raised surface, `primary` for the one thing to act on, a dark tone (`.dark` on a section) for a band that stands apart, and photos under a black cover (50–75%) wherever white text sits on them. The only shadows are shadcn's on outlined buttons (`shadow-xs`) and on menus and dialogs.

## Shapes

Corners come from `--radius` (10px): `rounded-sm` 6px, `rounded-md` 8px, `rounded-lg` 10px, `rounded-xl` 14px; `rounded-full` for avatars, dots and round icon buttons.

- **`md`:** buttons, chips, tags, icon squares.
- **`lg`:** form fields, small panels, photos inside a card.
- **`xl`:** cards, photos, video frames, the panels of a section.
- **`full`:** portraits, round arrow buttons, dots, the play button.

## Motion

The motion is in the Framebrick UI components the blocks use (`components/ui/`: Spring, Flip and Sweep Button, Scroll Reveal, Text Appear, Marquee, Slideshow, the accordions…), measured from the templates they come from. Use them as they are:

- Don't change a component's springs, durations or easings; choose what its props offer (`trigger`, `delay`, `amount`, `spring` on Scroll Reveal; `speed` and `pauseOnHover` on Marquee; `interval` on Slideshow).
- A block rises into view once (Scroll Reveal, `trigger="enter"`); headings rise word by word (Text Appear). Don't animate on every scroll, and don't add motion of your own to a block that has none.
- A filled button or chip hovers to 95% of its fill (`hover:bg-primary/95`), never a lighter step: the label must keep 4.5:1 on it in every theme, so check a coloured theme, not only the default.
- Respect reduced motion: the components already stop or settle at once when `prefers-reduced-motion` is set; anything new must do the same.

## Components

Component tokens use the exact sizes of the blocks' own parts. A suffix (`-hover`) lists only what changes.

- **`button`** — a filled button (Framebrick UI's Spring, Flip or Sweep Button, shadcn's Button): `bg-primary text-primary-foreground`, `h-9 px-4`, `rounded-md`, `text-sm font-medium`. Its hover fades the fill to 95% (`hover:bg-primary/95`); the label rolls or the arrow turns, the colours stay.
- **`button-small`** / **`button-large`** — `h-8 px-3` and `h-10 px-6`, the same colours.
- **`button-outline`** — the second button beside a filled one: `border bg-background`, `shadow-xs`; its hover takes `accent` (**`button-outline-hover`**).
- **`button-secondary`** — a quiet button on a coloured band.
- **`card`** — the blocks' usual card: `rounded-xl bg-muted p-5` (20px), secondary text in `text-foreground/65` (65% of the foreground reads better than `muted-foreground` on `muted`).
- **`card-raised`** — a card that stands out from a muted band: `bg-card` with a 1px `ring-border`.
- **`chip`** — a small label on a card or a photo: `rounded-md bg-muted px-2 py-1 text-xs`.
- **`icon-square`** — a 36px `primary` square holding a 20px line icon in `primary-foreground`.
- **`input`** — shadcn's Input: `h-8 rounded-lg border border-input bg-transparent px-2.5`, 16px text (14px from 768px); focus draws a 3px `ring` at 50%.
- **`tint`** — a soft panel in the primary colour's tint: `bg-accent text-accent-foreground`.

## Do's and Don'ts

- Do use the theme's variables through their classes (`bg-primary`, `text-muted-foreground`, `rounded-xl`, `text-h2`); never write a colour, a font size or a radius as a literal value.
- Do give a new section `py-(--section-y)` and a `mx-auto max-w-(--container) px-(--gutter)` container, and no outer margin.
- Do give each section one `h2` (the page has one `h1`, in its hero), and set headings in `font-heading font-semibold tracking-tight`.
- Do keep `primary` for what the visitor should act on: one filled button per group, the second one outlined.
- Do use `text-foreground/65` for secondary text on `muted`, `text-muted-foreground` on `background` and `card`.
- Do check both modes: every colour has a `.dark` value, and a section can take `.dark` on its own.
- Don't add shadows, gradients or colours of your own; the palette above is the whole palette.
- Don't put type-scale classes (`text-h2`) and a text colour in the same `cn()` call: tailwind-merge reads both as colours and drops one. Keep the type classes in a plain string.
- Don't mix fonts beyond the ones named above.

## Source

The Default sample theme of Framebrick Blocks (https://framebrick.co/blocks, any block's preview with ?theme=default), generated from its CSS variables: shadcn/ui's defaults and the block tokens of the blocks' own stylesheet, with the theme's values over them. Body text is Geist in every sample theme.
