---
version: 1
name: Loom site · Selvedge
description: "The Loom marketing site is cloth on a loom. Unbleached cotton ground (#f3eee3), loom-black ink (#17140f), and four dyed threads that carry the product's four verbs: indigo (#1e2a78) for See, madder (#b02a1e) for Shape, saffron (#e9a21b) for Govern, teal (#0b6b66) for Run. Display type is Archivo stretched to its widest (wdth 125) at 800-900, set large and tight; text is Archivo at normal width. Martian Mono appears only where a figure, a code name or a band label is measured. Whole sections are flat colour-block fields that end in a woven selvedge edge. Health is shown as woven swatches whose weave loosens as the score drops (bands 90, 75, 60), never by colour alone."

colors:
  cotton: "#f3eee3"        # page ground
  surface: "#fbf8f1"       # raised panels, inputs
  surface-2: "#ebe4d6"     # quiet band, table stripes
  ink: "#17140f"           # text, the loom frame
  ink-2: "#4a443a"         # secondary text (8.4:1 on cotton)
  line: "#d9d0bf"          # the only rule colour, used inside data (tables, transcripts)
  indigo: "#1e2a78"        # See · Product · links
  madder: "#b02a1e"        # Shape · Solutions · loose threads
  saffron: "#e9a21b"       # Govern · Demos · actions (inset bar) · taking shape
  teal: "#0b6b66"          # Run · Resources · holding together
  ai: "#6b3fc2"            # marks agent output only
  # dark mode (prefers-color-scheme: dark)
  dark-cotton: "#13110d"
  dark-surface: "#1d1a15"
  dark-ink: "#f3eee3"
  dark-ink-2: "#c4b9a6"
  dark-indigo-ink: "#aab4ff"
  dark-madder-ink: "#ff9a8c"
  dark-teal-ink: "#72d3c9"

bands:
  tightly-woven: { from: 90, colour: indigo }
  holding-together: { from: 75, colour: teal }
  taking-shape: { from: 60, colour: saffron }
  loose-threads: { from: 0, colour: madder }

typography:
  display: { family: "Archivo", width: 125, weight: 900, size: "clamp(2.75rem, 7.2vw, 6rem)", leading: 0.9, tracking: "-0.02em" }
  h2: { family: "Archivo", width: 125, weight: 850, size: "clamp(2rem, 4.4vw, 3.5rem)", leading: 0.95, tracking: "-0.015em" }
  h3: { family: "Archivo", width: 112, weight: 800, size: "clamp(1.25rem, 2vw, 1.6rem)", leading: 1.1 }
  lede: { family: "Archivo", width: 100, weight: 400, size: "clamp(1.125rem, 1.6vw, 1.35rem)", leading: 1.45 }
  body: { family: "Archivo", width: 100, weight: 400, size: "1.0625rem", leading: 1.6 }
  figure: { family: "Martian Mono", weight: 500, size: "0.8125rem", tracking: "0.02em" }
  label: { family: "Martian Mono", weight: 600, size: "0.75rem", tracking: "0.08em", case: "upper" }

spacing: { unit: 8px, gutter: "16px phone · 40px desktop", section: "clamp(72px, 10vw, 160px)", measure: "68ch" }
radius: { all: 2px, round: "only health dots and the knot marker" }
motion: { shuttle: "cubic-bezier(.2,.7,.1,1)", out-expo: "cubic-bezier(.16,1,.3,1)", fast: 160ms, base: 320ms, weave: 420ms }
---

# Loom site · Selvedge

## Overview

The site is a loom. Every page is a length of cloth: it starts at the **fell**, a saturated field where the
newest weft is beaten in (the page hero), and ends at the **selvedge**, the woven edge that stops cloth
from fraying (the footer). Between them, sections are either cotton ground with ink type, or whole
colour-block fields in one of the four threads. The product's idea, *Loom weaves See, Shape, Govern and
Run into one system*, is shown literally: four threads that keep the same colour on every page.

Modes (impeccable): the landing and solution pages **persuade**; product, demo and resource pages
**read**; demos inside them **operate**. Ambition on the landing shows as scale and woven motion; on deep
pages it shows as precision.

Taste settings (design-taste-frontend dials, 1–10):

| Surface | Variance | Motion | Density |
|---|---|---|---|
| Landing `/` | 8 | 6 | 4 |
| Hubs and solutions | 6 | 4 | 5 |
| Product, demo, resource, company, articles | 5 | 3 | 6 |
| `/explore/` (review only) | 9 | 7 | 4 |

## Colours

### Threads (the four verbs)

| Thread | Verb | Section of the site | Field text | Use as text on cotton |
|---|---|---|---|---|
| Indigo `#1e2a78` | See | Product | cotton | yes (12:1) |
| Madder `#b02a1e` | Shape | Solutions | cotton | yes (6:1) |
| Saffron `#e9a21b` | Govern | Demos | ink | **never** (2:1); use ink with a saffron mark |
| Teal `#0b6b66` | Run | Resources | cotton | yes (6:1) |
| Ink `#17140f` | – | Company | cotton | – |

A page takes the colour of its section for its fell. A product page takes the colour of its verb
(See indigo, Shape madder, Govern saffron, Run teal; Loom Base, Agents and Security indigo).
Violet `#6b3fc2` marks agent output and nothing else.

### Ground and ink

Cotton `#f3eee3` is the ground; surface `#fbf8f1` raises a panel by one step in tone, never by a shadow.
Ink `#17140f` is text and the loom frame (6px rules that frame fields and the header).
Secondary text is ink-2 `#4a443a`. On a field, secondary text is the field's own tint, never grey.

### Dark mode

Dark follows `prefers-color-scheme`. The ground becomes dyed-black cotton `#13110d`, ink becomes cotton.
Fields keep their dye (indigo, madder, teal darken slightly; saffron stays and keeps ink text).
Thread colours used as text switch to their light inks (indigo `#aab4ff`, madder `#ff9a8c`, teal `#72d3c9`).

### Health bands

| Band | Score | Thread | Weave |
|---|---|---|---|
| Tightly woven | 90–100 | indigo | plain weave, no gaps |
| Holding together | 75–89 | teal | a few dropped picks (6%) |
| Taking shape | 60–74 | saffron | open weave with floats (20%) |
| Loose threads | 0–59 | madder | broken threads (38%) |

Colour and weave density always change together, so a band reads in greyscale and to colour-blind
readers. Every swatch carries its band name in text nearby. Sample data is labelled *Sample data* in
the same view.

## Typography

One family, Archivo (OFL), self-hosted as one variable file (`fonts/archivo-var.woff2`, weight 400–900,
width 88–125, Latin subset). Martian Mono (OFL, `fonts/martian-mono-var.woff2`) for figures, code names,
band labels and the breadcrumb trail. No other faces. Japanese falls back to the system's Hiragino /
Noto Sans JP / Yu Gothic, with no faux italics and no negative tracking.

- **Display** (one per page, the `h1`): width 125, weight 900, `clamp(2.75rem, 7.2vw, 6rem)`, leading .9,
  tracking -.02em. At most three lines on a phone, two on desktop.
- **h2**: width 125, weight 850, leading .95. **h3**: width 112, weight 800.
- **Lede**: one sentence or two under the headline, 18–22px.
- **Body**: 17px, leading 1.6, measure 68ch, full ink.
- **Figures and labels**: Martian Mono 12–13px. Uppercase only for band names and field keys
  (`DRIFT`, `TOKEN COVERAGE`), letter-spaced .08em.
- Emphasis comes from width and weight, never from italics or a second colour in a headline.

## Layout

- Frame: max content width 1320px; outer gutters 16px (phone) and 40px (≥ 900px). Equal on both sides.
- 12-column grid at ≥ 900px; text blocks span 7 columns, the visual takes the rest.
- Section rhythm `clamp(72px, 10vw, 160px)`; more space above a heading than below it.
- **The fell** (page hero): a full-bleed colour field, breadcrumb, `h1`, lede, actions, then the
  selvedge edge (a three-row checker of cotton on the field colour, 18px tall).
- **Fields**: flat colour, no gradient, no texture other than the selvedge edge and woven swatches.
- No horizontal scroll at 320px. Wide tables and code scroll inside their own region.

## Elevation and depth

Depth is a step in tone (cotton → surface) or a 6px ink frame. Shadows appear only on what floats:
the open mega-menu and the mobile drawer (`0 24px 48px -24px rgb(23 20 15 / .45)`).

## Shapes

Corners are 2px everywhere. Round shapes are reserved for health dots and the knot that marks the
current item. Threads are 4–12px wide bars with 3px rounded ends.

## Components

### Header and mega-menu
Cotton bar, wordmark left (pixel distaff mark + "Loom" at width 125), five disclosure buttons (Product,
Solutions, Demos, Resources, Company), one action ("Free health check"). Each panel opens below the bar
on surface, framed by a 6px ink top rule; each column is hung from a thread in its section colour.
Keyboard: Tab reaches each button, Enter/Space opens, Escape closes and returns focus, focus leaving
the panel closes it. Below 1000px the bar shows a Menu button that opens a full-height drawer with the
same groups as accordions. Built on `<details>`, so both work without scripting.

### Buttons
- **Primary**: ink on cotton fields, cotton on colour fields, with a 6px saffron inset bar on the left
  (the shuttle). 48px tall, weight 700 at width 112.
- **Ghost**: transparent, 2px border in currentColor.
- Press: scale .97 for 120ms. Hover: the saffron bar widens from 6px to 10px.

### Status badges (claims)
Every capability claim on the site shows its status from `docs/product/claims.json`:
working (teal), partial (saffron bar), in development / planned / concept / commitment (outlined).
Wording comes from the register; the overclaim gate fails the build otherwise.

### Woven swatch
SVG grid of over/under cells in a band's two shades; gap rate by band. Used for the band meter, the
cloth health map and the thread under hub rows.

### Index rows (hubs, related pages, roles)
Full-width rows: a thread bar in the row's colour, title at h3 size, one sentence, an arrow. Hover pulls
the thread 8px to the right. Never a grid of identical cards.

### Persona switcher
On solution pages: a row of six links (Designers … CEOs) under the fell; the current one is a cotton
tab on the field with a madder knot.

### Footer (the selvedge)
Ink field with a woven edge at the top, the sitemap in five columns, the small print (working name,
trust, security, accessibility, fonts under OFL).

## Motion

One authored moment per page, then quiet.
- **Landing**: the living loom (threads weave a component while the hero is pinned for one screen of
  scroll), then the drift diagram and the cloth map each animate once when they enter.
- **Entrances**: the parts of a section arrive in reading order (heading, text, figure), 70ms apart,
  rising 20px from an already-visible state, `out-expo` 600ms. Only below the fold, once.
- **Feedback**: buttons press (scale .97), rows pull their thread, swatches lift their outline.
- Transform, opacity and clip-path only. No bounce. Everything is off under
  `prefers-reduced-motion: reduce`: canvases draw one finished frame, pins are removed, content stays.

## Voice and content

The voice guide is `apps/showcase/site-content/voice.md` (written by the content owner). The site's
rules on top of it: British spelling; plain words; every claim has a status; concepts say *Concept*;
sample data says *Sample data*; real output says where it came from and when.

### Content authoring contract
The generator is `scripts/site/` (`pages.ts` orchestrates; `content.ts`, `markdown.ts`, `landing.ts`,
`templates.ts`, `visuals.ts`, `diagrams.ts`, `explore.ts`); `scripts/build-site.ts` writes `dist-site/`.
- Pages are Markdown files in `apps/showcase/site-content/` (owned by the content writer; its voice
  guide is `site-content/voice.md`). `apps/showcase/site-placeholder/` holds copy only until a file of
  the same name lands there (today: the AI-draft `landing.ja.md` and `company/accessibility.md`).
- Front matter: `title` (the `<title>`), `description`, `slug` (URL), `section`, `claims`, `statusLabels`,
  optional `related` and `colour`. The first `# Heading` is the page's `h1`; the first paragraph is the lede.
- Placeholders on their own line: `[[demo:mini-audit|audit-explorer|agent-replay|autonomy|layers|before-after]]`,
  `[[diagram:living-loom|drift|four-threads|cloth-health|agent-loop|pr-flow|contribution-flow|contract-to-component|records-in-repo|value|system-of-systems|architecture|base-coverage|bands|token-flip]]`.
  A `Shows:` line after a placeholder is a note for the builder and is not published.
- Status: `[[status:<working|partial|concept|commitment>|<claim id>]]` renders a badge. The overclaim gate
  (in `markdown.ts`, and `tests/unit/site-claims.test.ts`) fails the build when the label disagrees with
  `docs/product/claims.json`, or when a working or partial label names a claim the register lacks.
- Directives: `Primary action:` / `Secondary action:` / `Action:` (buttons), `Link:` (arrow link),
  `Small print:`, `Source:`, `Vision line:`, `Data:`, `Status:`, `Email line:`; a label resolves through
  the navigation, then the table in `markdown.ts`, or explicitly with `→ /path`.
- `landing.md`: `# ` is the hero headline; `## ` sections map to problem, idea, proof, roles and call
  to action by `{#id}`, their words, or position. On the landing a demo placeholder renders as a teaser
  that links to `/demos/<id>/`; the advanced demos live there and on the persona and product pages.
- `demos/index.md`: each `## ` section that holds a `[[demo:…]]` becomes its own page `/demos/<id>/`.
- `nav.json`: `sections[]` with `id`, `label`, `description`, `slug`, `items[]` (`label`, `slug`,
  `description`, `status`) → the mega-menu, the drawer, hubs, breadcrumbs, the persona switcher, related
  pages and the footer. `/demos#id` links become `/demos/<id>/`; old `.html` URLs are rewritten and
  redirected (`_redirects`).

### Landing decisions (October 2026)
- Hero: the living loom, variant "button". Problem: the drift diagram, plays once then a slider.
  Idea: the four bands (See indigo, Shape madder, Govern saffron, Run teal), each a full-bleed field.
  Proof: the facts, beside the before → after token flip and two demo teasers. Roles: index rows.
  Call to action: a saffron field. The alternatives are on `/explore/` (noindex).
- Owner decision: on the landing, "Book a conversation" is the primary action and the health check is
  secondary, in the hero and in the final call to action.
- No Yara or Ahua on the landing.

## Do's and don'ts

### Do
- Set the headline big and wide; let one field of colour carry each section.
- Show real output with its date and source; label sample data where it is shown.
- Keep the thread colours meaning the same thing on every page.
- Give every interactive visual a static, readable version without scripting.

### Don't
- No eyebrow labels above headings, no section numbers, no icon-topped card grids.
- No gradients, glass, glows or shadows on things at rest.
- No saffron text on cotton. No grey text on a colour field.
- No stock photos, emoji or decorative blobs. Pictures are woven, drawn from the product, or real
  interface fragments.
- Never say "Working" without a claim in the register.

## Responsive behaviour

| Breakpoint | Change |
|---|---|
| ≥ 1200px | full composition, mega-menu, 12 columns |
| 1000–1199px | visuals shrink to 5 columns |
| 600–999px | drawer menu, one column with visuals under text |
| < 600px | 16px gutters, display at 2.75rem, fields full-bleed |
| 320px | checked: no horizontal scroll |

Touch targets are at least 44 × 44px. Hover effects are scoped to `(hover: hover)`.

## Iteration guide

1. Change a token here first, then in `css/site.css` (`:root` and its dark twin).
2. New page: add a Markdown file; the generator picks the template from its section.
3. New visual: a static SVG in `scripts/site/visuals.ts` and an enhancer in `site/visuals/`, wired by
   `data-visual`.
4. Run `npm run site:build && npm run test:site` (axe at 1440 and 390, light and dark; keyboard;
   reduced motion; 320px; performance budget).

## Known gaps

- Deep pages are English only (the footer says so); the landing has an AI-draft Japanese version with
  a review banner. On the Japanese landing, the labels inside the drift diagram and the token flip are
  still English.
- The Open Graph image is one static card for every page (`og/loom.png`, source `scripts/site/og-card.html`).
- Martian Mono labels (breadcrumbs, band names, figure keys) follow the Selvedge reference screens; the
  taste skill's house rule against monospace labels was set aside because the brief pins Selvedge.
