# Marrenne Development Build Specification — Part 1: Visual and UI

**Marrenne, Inc. Internal working document. Vendor-agnostic. Hand this to any development team.**
**Prepared:** July 23, 2026. Territory: The Weighted Page.
**Marrenne is the platform name. Internal working document, not for external distribution.**

---

## 0. How to use this document (read first)

This is a build specification, not a brand book. It exists so that a developer can build any Marrenne surface correctly without making a single branding decision and without asking a question. Every value is exact. Where you would normally choose, the choice is already made below.

**Three rules govern everything:**

1. **Do not invent a value.** Every color, size, weight, radius, and spacing value you need is in `tokens.css` / `tokens.json`. If you need one that is not there, stop and ask. Do not pick "close enough."
2. **Do not improvise a pattern.** Every component and state is specified in Section 6. Every image state is specified in Section 7. If a screen seems to need something not described here, stop and ask before building it.
3. **When unsure, choose the narrower reading and ask.** A five-minute question is cheaper than a rebuilt screen.

**Companion files in this folder (wire these directly, do not retype values):**

- `tokens.css` — all design tokens as CSS custom properties. Import once, globally.
- `tokens.json` — the same tokens for programmatic use (native, design tooling).
- `fonts.css` — `@font-face` for every licensed font, web and native, by exact file.
- `assets_index.md` — the exact wordmark and seal file to use in each context.
- `Marrenne_Build_Spec_02_Copy_System.md` — all UI copy, voice rules, and the locked string glossary (exact spelling and casing of every label). **You must read Part 2 before writing or entering any user-facing text.**

**Precedence.** If anything anywhere seems to disagree with this document, treat this document plus `tokens.css` as current, and route the conflict to the founder before building against either version. Do not guess.

---

## 1. The one-paragraph brief for a developer

Marrenne reads as one printed publication across admin and consumer, never as a dashboard or a generic app. Warmth comes from ink density, paper, and depth, never from hue, filters, or rounded friendly shapes. The ground is warm paper (`--vellum`), never stark white. Type is the structure. There is one fixed central axis and composition comes to rest. If a screen ends up looking like a typical SaaS dashboard (white background, blue focus rings, grey spinners, candy-colored status chips, product-grid cards, drop shadows, bouncy animation), it is wrong, regardless of whether it "works."

---

## 2. Global setup

1. Import `fonts.css` and `tokens.css` globally, once, before any component styles.
2. Set the document base: `background: var(--vellum); color: var(--ink); font-family: var(--sans);`
3. Default body text is Söhne (`--sans`) at 14px, weight 400, line-height 1.5. Serif (Canela) is used only for the roles named in Section 3. Never set body copy in a system serif or a system sans.
4. All focus states use the ring tokens in Section 5.4. Remove the browser default focus outline only after replacing it with the token ring, never leave elements with no visible focus.

---

## 3. Typography (the rule that has broken twice, read carefully)

Two families only: **Canela** (serif spine, three optical cuts) and **Söhne** (grotesk, all interface). Never substitute one for the other. Never use a system font for either.

### 3.1 The type scale (exact)

| Role | Family / weight | Size | Line height | Letter-spacing | Case |
|---|---|---|---|---|---|
| Masthead wordmark | Canela Display (asset file) | 18px app bar / 15px sidebar | — | 0.34em (baked into asset) | UPPER |
| Hero / brand display | Canela Display, 400 | 36–48px | 1.1 | normal | sentence |
| Page title / H1 | **Canela Deck Regular, 400** | 30px | 1.15 | normal | sentence |
| Section head / H2 | **Canela Deck Light, 300** | 22px | 1.2 | normal | sentence |
| Card / list-item / activity title (nested) | **Canela Text Light, 300** | 16–17px | 1.3 | normal | sentence |
| Editorial / house-voice body | **Canela Text Light, 300** | 16–17px | 1.55 | normal | sentence |
| Ledger figure (counts that carry meaning) | Canela Display, 400 | 34px stat / 17px cell | — | normal | — |
| Editorial eyebrow | Söhne Halbfett, 600 | 11px | — | 0.30em | UPPER |
| Functional body | Söhne Buch, 400 | 14px | 1.5 | normal | sentence |
| Field label / column head | Söhne Halbfett, 600 | 11px | — | 0.16em | UPPER |
| Control label (on ink) | Söhne Kräftig, 500 | 13px | — | 0.03em | UPPER |
| Any text typed into a field, input, or note | Söhne, 400 | inherit | — | normal | as typed |

### 3.2 Which face, decided per element (do not deviate)

This is the table that keeps breaking. Check every text element against it before assigning a face.

| If the element is… | Use | Never |
|---|---|---|
| The masthead / logo wordmark | Canela Display asset | live font, Deck |
| The one true title of the current screen (H1) | Canela Deck **Regular** | Display, Text |
| A structural section head within the screen (H2) | Canela Deck **Light** | Deck Regular, Display |
| A stat or ledger figure (a meaningful count) | Canela Display, 400 | Text, Deck, Söhne |
| Editorial / house-voice / empty-state / welcome line | Canela Text **Light** | Deck, Display, Söhne |
| A card title, list-row name, activity name, outfit/gap label, wardrobe item name | Canela Text **Light** | **Deck, Display** |
| Any text inside a form field, input, or note | Söhne | any Canela cut |
| Buttons, tabs, nav, field labels, table cells, functional captions | Söhne | any Canela cut |

**Test before assigning Deck to anything:** is this literally the title of the screen the user is on, or a named structural section within it? If it sits inside a card, a row, a list item, or a field, the answer is no. Default to Canela Text Light or Söhne and ask before promoting anything to Deck.

**Weight is not interchangeable.** H1 is Deck Regular (400). H2 is Deck Light (300). All Canela Text is Light (300). Canela Text Regular (400) is licensed but has no active role; do not assign it.

### 3.3 Casing (this is a spec, not a preference)

Titles and headings are **sentence case**, not Title Case and not ALL CAPS, unless the row in 3.1 says UPPER. Season, collection, and brand names entered as content follow the casing rules in Part 2, Section 6 (for example "New York Fashion Week 2028," never "New york fashion week 2028"). Eyebrows, field labels, and control labels are UPPER per the scale. Nothing else is uppercased.

---

## 4. Color

Use the tokens. Do not hand-enter hex values. Full list and contrast data: `tokens.json` and MAR-31.

### 4.1 The warmth guard (mechanical, a reviewer can check each)

Take the warm material choice every time. Any one of these fails the guard:

1. A white (`#FFFFFF`) or pure-grey ground anywhere, outside the single logged white MVP exception (Section 8).
2. A blue or system-default focus ring.
3. A grey shimmer or spinner for loading.
4. A saturated or "candy" status color.
5. Bounce, spring, or looping motion.
6. A filled, duotone, gradient, or celestial (star / moon / orbit) icon.
7. Structural grey set as pure grey or pure black instead of `--slate` / `--ink`.

### 4.2 Accents

Aged red (`--red`) is punctuation only: light grounds only, **one instance per view maximum**, never a fill, never on a dark ground. Bronze (`--bronze`) is imagery and dark grounds only, never small text.

### 4.3 Status (the pill component only, never an icon or colored dot)

| Status | Text | Background | Treatment |
|---|---|---|---|
| Active | `--green` #3F5B49 | `--green-bg` #E3E7DE | filled tint pill |
| Inactive | `--neutral` #635F56 | `--neutral-bg` #E8E4D6 | filled tint pill |
| Invited / Pending | `--slate` #5A626C | transparent | plain ink outline pill |
| Negative (Declined / Error) | `--red` #7D332C | light ground only | label text, never a fill, never on dark |

No new saturated status colors enter the system.

---

## 5. Layout, structure, and interaction

### 5.1 Spacing
4px base scale, tokens `--space-1` … `--space-8` plus half steps. Never use an off-scale pixel value for margin or padding.

### 5.2 Radii
`--radius-control: 2px` on buttons, fields, pills, chips, pager cells. `--radius-plate: 0` (square) on plates, tables, cards, panels. `--radius-round: 50%` on avatars, the seal, and the FAB only. Nothing else is rounded.

### 5.3 Rules (borders)
Four weights only: `--rule-structural` (1px ink, structural and plate mount), `--rule-thead` (2px ink, table head only), `--rule-interior` (1px hairline), `--rule-row` (1px hairline-2, table rows). No other border styles, no dashed or double borders.

### 5.4 Focus (accessibility requirement)
`--focus-ring` 2px ink on light grounds, offset 2px onto the ground; `--focus-ring-tint` 2px slate on recessed/tinted fields; `--focus-ring-dark` 2px ivory on dark grounds. Never the default blue system ring. Every interactive element has a visible focus state.

### 5.5 Loading
A warm skeleton in `--skeleton-ground` (optionally a slow `--skeleton-sheen`), or the static seal for full-view loads. Never a cold-grey shimmer, never a spinner.

### 5.6 Motion
One easing curve, `--ease-settle`, decelerating to rest with no overshoot. Durations `--dur-1`…`--dur-4` only. Meaning is carried in exactly two places: a panel settling to rest, and a plate resolving from its dark ground. No bounce, spring, looping, or celestial motion anywhere else. Full `prefers-reduced-motion` support (see `tokens.css`).

### 5.7 Icons
1.6px stroke line set, round terminals, sizes `--icon-sm/md/lg/xl` (15/17/19/21px). The seal replaces the star everywhere; the star is retired. No filled candy icons, no celestial glyphs, no generic SaaS icon set.

---

## 6. Components (build each with its full state set)

Every interactive component must implement every state listed. States not listed do not get invented.

### 6.1 Primary button (on ink)
Ground `--ink`; label Söhne Kräftig 500, 13px, 0.03em, UPPER, color `--ink-hi`; radius `--radius-control` (2px); height 40px; horizontal padding `--space-4`.
- Hover: ground `--ink-hover`.
- Pressed: ground `--ink-press`.
- Focus: `--focus-ring` (2px ink) offset 2px; on dark grounds use `--focus-ring-dark`.
- Disabled: reduce to `--slate` ground with `--slate-soft` label, no hover.

### 6.2 Secondary button
Transparent ground; 1px ink border (`--rule-structural`); label Söhne 13px ink; radius 2px; height 40px.
- Hover: fill `--vellum-2`.
- Pressed: fill `--hairline`.
- Focus: `--focus-ring`.
- Disabled: hairline border with `--slate-soft` label.
- The label is a plain verb ("Add a photo"), never house-voice language.

### 6.3 Text field / input
Ground `--vellum-2` (recessed); border `--rule-interior`; text Söhne 400, ink; radius 2px; label above in the Field label style (Söhne Halbfett 600, 11px, 0.16em, UPPER, `--slate`).
- Focus: `--focus-ring-tint` (2px slate) offset 2px.
- Error: label text and helper in `--red` (light ground only); border stays hairline, never a red fill.
- Disabled: `--slate-soft` text.
- Placeholder text is `--slate-soft` (exempt from AA), never used to carry required information.
- Text the user types is always Söhne, never any Canela cut.

### 6.4 Status pill
Per Section 4.3. Pill only; never a bare colored dot or an icon. Radius 2px. Padding `--space-1` / `--space-2`.

### 6.5 Tabs and nav
Söhne labels; active tab marked by an ink underline or ink label weight, never a colored background or pill. Inactive tab-bar glyphs may use `--slate-soft`. Focus ring on keyboard focus.

### 6.6 Table
Head rule `--rule-thead` (2px ink); row rule `--rule-row` (1px hairline-2); column heads in the Field label style. Square corners. Cell text Söhne. Ledger figures that carry meaning are Canela Display; incidental numerals (pagination, phone) stay Söhne.

### 6.7 Plate (the image unit) — see Section 7.

### 6.8 Progress / completion panel
Recessed panel: `--vellum-2` ground, `--rule-interior` border, `--space-3h`/`--space-4` padding. A label row in Söhne ink, with the completion figure at the right in **Canela Display 400, `--red`** (a legitimate single aged-red instance). Below, a 3px track (`--track-bg` #E0DACA) with an ink fill.

### 6.9 Empty state — see Section 7.B.

### 6.10 Avatar, seal, FAB
The only round elements (`--radius-round`). The seal follows the ground rules in `assets_index.md`.

---

## 7. Imagery: exactly two states, never a third

This broke on the first build (a bordered grey placeholder box with a centered "+ ADD A PHOTO" button). That pattern is banned. There are two image states and only two.

### 7.A The plate (a real image, or a frame an image will load into)
1. **Mount:** a single full-strength ink rule (`--rule-structural`, 1px `--ink`) enclosing the plate. Square corners. No drop shadow.
2. **Mat:** a mandatory band of vellum between the rule and the image: 12px consumer (`--space-3`), 8px admin (`--space-2`). Never zero. A full-bleed image inside the rule is not a plate.
3. **Well:** the floor is the dark ground `--ground-dk` (#26221C). If an "add a photo" control must live here before an image exists, it is a plain **secondary button** (Section 6.2) placed inside the well, never a separate light box floating outside the plate.
4. **Caption (beneath the mount, outside the rule):** line 1 a Canela Text Light house-voice title (ink); line 2 a Söhne functional label, UPPER, 0.26em, `--slate` (never slate-soft).
5. **Edit / clear controls never sit on the image.** They live in the caption area beneath the plate. The only thing allowed on the well is an optional in-well status chip (bordered vellum, never a colored fill).

### 7.B The empty state (no data at all, not just a missing photo)
No box. No border. No button rectangle. The whole treatment is: the seal (ink-ruled, dot colored per `assets_index.md`), the vellum ground, and one line of house voice in Canela Text Light, centered on the axis. Nothing else. (Locked example lines are in Part 2.)

### 7.C The banned third pattern
Do not build a soft-bordered placeholder rectangle with a centered call-to-action button inside it. If a screen needs "add a photo" and you are unsure whether it is case A or case B, stop and ask.

### 7.D Imagery by subject (brief)
Runway is one held look, never a lookbook grid. Inventory is the kept object glowing against depth, never a cutout on white. The client faces her world, never posed against product. A house is shown as an artist at parity, never subordinated under the Marrenne mark or dressed with the seal over its own mark.

---

## 8. The one live scoped exception (white ground)

For the interim MVP swap only, the wordmark and seal ship on a **white** background (`#FFFFFF`) using the white-ground asset files, to fit the current build surface. This is a deliberate, time-boxed exception to the warmth guard, approved for that release only. It does not change the guard and does not license white grounds anywhere else. The correct ground everywhere is vellum `#F5F2E8`. Do not extend the white exception to a new surface without asking.

---

## 9. Screen and route mapping

Apply the same token and component set to every surface. For any screen not listed, follow the rule at the bottom, do not improvise.

| Surface | Ground | Title face | Notable components |
|---|---|---|---|
| Consumer home / Seasons index | vellum | H1 Canela Deck Regular; season card names Canela Text Light | plate grid (odd-weighted, not a balanced product grid), search field, sort control |
| Season → Brands | vellum; masthead band per Section 8 | Masthead wordmark asset; brand group heads H2 Canela Deck Light | plate cards, "View All" secondary buttons, wishlist heart icon (line icon) |
| Inquiries | vellum | H1 Canela Deck Regular | empty state per 7.B, message list |
| Wardrobe | vellum | H1 Canela Deck Regular | empty state per 7.B, wardrobe item titles Canela Text Light |
| Recommendations | vellum | H1 Canela Deck Regular | empty state per 7.B |
| Admin (all) | vellum / panel | sidebar wordmark 15px; H1/H2 as above | tables, status pills, plate section (contact-sheet grid), progress panel |

**Rule for any new screen:** ground is vellum; the one true screen title is Canela Deck Regular; any structural section head is Canela Deck Light; every nested name is Canela Text Light; all controls and labels are Söhne; images follow Section 7; colors and spacing come from the tokens. If that does not fully specify the screen, ask before building.

---

## 10. Decisions already made — do not deviate (the improvisation stop-list)

These are the exact places builds have gone wrong. Each is decided. Do not re-decide.

1. **Ground is vellum `#F5F2E8`, not white and not black.** The only white allowed is the logged MVP wordmark/seal exception (Section 8). A black masthead band is not specified; a masthead sits on vellum or uses the dark-ground assets, not an invented black bar.
2. **Focus ring is ink/slate/ivory per Section 5.4, never blue.**
3. **Loading is a warm skeleton or the static seal, never a spinner or grey shimmer.**
4. **Status is a pill, never a colored dot or icon; only the four status colors exist.**
5. **Nested titles are Canela Text Light, never Deck, never Display.**
6. **H2 is Deck Light, H1 is Deck Regular; the two are not interchangeable.**
7. **Images are plate or empty state only; the placeholder box with a centered button is banned.**
8. **Edit/clear controls never sit on an image.**
9. **The seal replaces the star; no star, no celestial glyphs anywhere.**
10. **Copy casing, spelling, and every label come from Part 2. Do not casually capitalize, pluralize, or reword a label.** ("Recommendations," not "Recommendation"; "New York Fashion Week 2028," not "New york fashion week 2028.")
11. **No em dashes, US spelling, no exclamation points in brand-voice copy** (Part 2).
12. **Use the supplied wordmark/seal asset files; never re-space, recolor, or set letter-spacing on top of them.**

---

## 11. Acceptance checklist (run before every delivery)

The build passes only if every line is true. If any line fails, the build has drifted.

- [ ] `tokens.css` and `fonts.css` are imported globally; no hard-coded hex, px font sizes, or font names outside the tokens.
- [ ] No white or pure-grey ground anywhere except the logged MVP wordmark/seal surface.
- [ ] Every serif element matches the face-per-element table (3.2), including weights (H1 Deck Regular, H2 Deck Light, all Canela Text Light).
- [ ] Body, labels, buttons, tabs, table cells, and all typed input are Söhne.
- [ ] Focus rings are the token rings, never blue; every interactive element has a visible focus.
- [ ] Loading is a warm skeleton or the static seal; no spinner, no grey shimmer.
- [ ] Status appears only as the pill component with the four defined colors.
- [ ] Aged red appears at most once per view, on light grounds, never as a fill, never on dark.
- [ ] Every image is a plate (mount + mat + well + caption) or an empty state (seal + vellum + one line); no placeholder box; no control on the image.
- [ ] Icons are 1.6px line icons; the seal is used, the star is absent.
- [ ] Motion uses only `--ease-settle` and the four durations; no bounce/spring/loop; reduced-motion honored.
- [ ] All labels and copy match Part 2's string glossary exactly (spelling, casing, plural forms).
- [ ] Wordmark and seal use the correct asset file per `assets_index.md`; no CSS letter-spacing on the asset.

---

Marrenne, Inc. · Development Build Specification, Part 1 · internal working document, not for external distribution.
