---
name: Terra Firma
version: "1.0"
slug: terra-firma
tier: premium
price: 29
type: Ceramic Studio Portfolio
axis: "4 — Extreme density, ultra-minimal (scroll-as-dial)"
theme: light-craft-stillpage
gesture: "Scroll-as-dial — the page never scrolls. The wheel turns the work: each input swaps the single centered piece in place (crossfade, soft blur, 0.985 scale settle). All views mutate in the same fixed viewport."
colors:
  chalk:      "#F2EDE4"
  chalk-deep: "#EAE3D6"
  ink:        "#2E2620"
  terracotta: "#C4572E"
  greige:     "#8A7A6A"
fonts:
  display: "Young Serif"
  body:    "Karla"
spacing:
  s1: "0.5rem"
  s2: "1rem"
  s3: "1.5rem"
  s4: "2rem"
  s5: "3rem"
  s6: "5rem"
  s7: "8rem"
radius: "2px"
type-scale:
  hero:    "clamp(2rem, 5vw, 3.4rem)"
  section: "clamp(1.5rem, 2.8vw, 2.1rem)"
  cartel:  "clamp(1.6rem, 3.4vw, 2.4rem)"
  body:    "0.92rem / 1.6"
  eyebrow: "0.7rem / ls .22em"
full-kit: "https://www.stacklift.design/kit/terra-firma"
---

# Terra Firma — Design System

## §1 Identity

Terra Firma is an ultra-minimal portfolio kit for a ceramic studio, built on one radical rupture: **the page never scrolls**. `html, body { overflow: hidden }` — permanently. The scroll wheel is repurposed as a dial that turns the work: one piece at a time, centered, with generous silence around it. Terra firma — firm ground: nothing under your feet ever moves; only the object mutates.

The palette is raw clay in daylight: `--chalk` (#F2EDE4) is the universal background, `--ink` (#2E2620) a warm raw-umber for text, `--greige` (#8A7A6A) for captions and secondary voice. The single accent is `--terracotta` (#C4572E), burnt terracotta — reserved for the active rail marker, the counter numeral, eyebrows, the DS trigger and hover states.

Typography pairs Young Serif — a generous, almost hand-modelled serif, used sparingly and never bold — with Karla for everything else. The display face appears only where an object would: piece names, view headings, the brand.

## §2 The Signature Gesture — Scroll-as-dial

The document cannot scroll. All wheel input is intercepted and accumulated; past a threshold, it advances the dial:

```js
var WHEEL_THRESHOLD = 90;   // wheel delta to accumulate before a step
var TURN_LOCK = 780;        // ms lock during a turn — matches --turn + settle
```

Pieces are absolutely stacked in one `.dial-stack`. The active one is visible; a step crossfades to its neighbour **in place**:

```css
.piece{
  opacity:0; transform:scale(.985); filter:blur(10px);
  transition:opacity var(--turn) var(--ease-earth),
             transform var(--turn) var(--ease-earth),
             filter var(--turn) var(--ease-earth);
}
.piece.is-active{ opacity:1; transform:scale(1); filter:blur(0); }
```

`--turn` (0.72s) is the single knob that tunes the whole feel. The dial **loops** (piece 7 → piece 1). Arrow keys, vertical swipe and the progress rail drive the same `goTo()` — one function, one grammar. The caption (`.cartel-item`) follows with a faster, smaller rise (0.5s, translateY 8px).

## §3 Views Mutate, Nothing Slides

Works, Studio and Contact are `.view` layers absolutely stacked in the same fixed stage. Switching views reuses the exact grammar of the dial — opacity + blur crossfade, no translation, no sliding panel:

```css
.view{ opacity:0; visibility:hidden; filter:blur(6px); }
.view.is-active{ opacity:1; visibility:visible; filter:blur(0); }
```

The Design System overlay is the **only surface allowed to scroll** — it is documentation, not the site. It slides from the bottom (`translateY(100%)` → `0`), closes on Escape, and restores focus.

## §4 Colour & Type Rules

1. `--chalk` is the only page background. Never white, never a card grid.
2. `--terracotta` is the sole accent: counter numeral, active rail marker, eyebrows, `.btn-ds`, hovers, focus underlines. Never large surfaces.
3. `--ink` doubles as the Design System overlay background — the one dark room in the house.
4. Young Serif is never bolded, never uppercased, never letter-spaced. It is the clay; leave it alone.
5. Karla carries UI text: eyebrows 600 / ls .22em / uppercase; body 300–400; menu 500 / ls .14em / uppercase.
6. Photography: single object on warm chalk seamless, soft daylight from the left, gentle right-hand shadow. The image background must sit within ±4% of `--chalk`.

## §5 Components

- **Dial** — `.dial-stack` + `.piece` stack, `4:5`, `height:min(58vh,60svh)`. One active piece, crossfade in place.
- **Cartel** — `.cartel-item`: Young Serif name + greige meta line with roman numeral in terracotta.
- **Progress rail** — `.rail`: one thin dash per piece; active dash thickens to 3px terracotta. Click to jump.
- **Counter** — `.counter`: tabular numerals, `01 / 07`, current number in terracotta, `aria-live="polite"`.
- **Hint** — `.hint`: `↻ scroll`, nudging glyph; fades permanently after the first turn.
- **Pastilles** — `.badge--ink` (`</> · 0 dependencies`) + `.badge--signal` (outlined terracotta, `↻ scroll-as-dial`).
- **Views** — `.view` stacked layers; menu buttons carry `data-view` and `.is-current` state.
- **Contact form** — underline-only fields, terracotta focus, `.btn` ink → terracotta on hover.
- **Design System overlay** — `.ds`: slide-up, ink background, internal scroll. Palette swatches, type rows, component demos.
- **Inert links** — `.is-soon` (opacity .4, `pointer-events:none`, `aria-disabled`). Never a dead `href="#"`.

## §6 Agent Instructions

1. Never allow the document to scroll. New content means a new view or a new dial position — never a longer page.
2. All motion is opacity/blur/scale in place. Nothing translates across the screen; nothing slides in from an edge (sole exception: the DS overlay).
3. One dominant gesture: the dial. Do not add parallax, reveals, marquees or hover theatrics around it.
4. `--terracotta` only in the small places listed in §4. If an element is bigger than a button, it is not terracotta.
5. Wheel handling must accumulate deltas (`WHEEL_THRESHOLD`) and lock during a turn (`TURN_LOCK`); never step per-event — trackpads fire dozens.
6. Keep captions to one line: numeral · year · material · dimension.
7. Respect `prefers-reduced-motion`: swaps become fast opacity fades, blur and scale removed, hint glyph static.
8. Never use Inter. Never use #000000. Young Serif display, Karla body — nothing else.

> 💡 Full implementation available — this `design.md` ships with a complete HTML/CSS kit: the scroll-as-dial system, stacked views, rail, cartel and DS overlay, ready to use.
> → [www.stacklift.design/kit/terra-firma](https://www.stacklift.design/kit/terra-firma)
