# Goldstones Family Farm — build notes

Decisions taken during the build that were not in the brief. Read this before
changing anything that looks arbitrary — most of it is load-bearing.

---

## 1. Values invented during the build

The brief's §0 token block arrived empty, with an instruction to stop rather than
invent. The palette and type pairing were settled in a prior identity round, so those
are ratified, not invented. **The following were not in that ratified set and were
created during the build.** Each needs a yes or a correction.

| Value | Where it came from | Used for | Risk |
|---|---|---|---|
| `#7D5510` amber-deep | Darkened from ratified amber `#C68A2E` to clear AA at 16px on cream. The original fails at 3.1:1. | All accent text, links, eyebrows on cream | Low — it is the same hue, only legible |
| `#E0B156` amber-light | Lightened from the same amber for use on moss and navy | Accents on dark grounds | Low |
| `#F7F2E8` cream-alt, `#FBF8F0` surface, `#EDE6D6` rule-soft | Interpolated between ratified cream and white to give sections and cards separation | Alternating bands, card grounds, dividers | **Medium — these are new mid-tones, exactly what §0 warns about.** They now appear on every page |
| `#36422E` moss-deep, `#6B7A57` moss-mid, `#A7B292` moss-light, `#E4E7DA` moss-tint | Ladder built around ratified moss `#4C5A3C` | Headings, dark panels, chips, empty images | Medium — four new values from one |
| `#A0442C` / `#F6E7E1` / `#8A3A22` error family | No error colour existed in §0. Chosen as a desaturated brick that sits in the palette rather than a system red | Form errors, full-availability chip | **Medium — a whole semantic colour invented** |
| `#7C5A43` umber, `#5A4030` umber-deep | Warm neutral for the collection-only badge and link hover | Product card, links | Low |
| `#8A836F` / `#DDD5C4` disabled pair | No disabled treatment specified | Disabled controls | Low |
| Bitter (serif) | Brief asked for "a simple, clean serif or slab" without naming one | Pull quotes, eyebrows, numerals, prices | Low — swappable in one token |

**If any of these are wrong, they are cheap to change now and expensive later** — the
mid-tones in particular are referenced by nearly every component.

## 2. Components created at page level

None. Every element on the Home template is drawn from Blocks 2 and 3.

The two post-freeze components (match price panel, scrollable date picker) were added
back into the component system and re-exported, per the brief's rule, rather than being
built at page level. They are flagged in `INVENTORY.md`.

## 3. Decisions the brief left open

**The Stay register.** Held the farm voice and let the specification sell, as the brief
recommended. The barns are described as "two barn conversions, each sleeping ten" with
facts carried in the key-facts row — no "luxury", no "retreat", no thread count. The
Cottages.com price point is not mentioned on the site.

**Fishing capacity.** Resolved by the farm: real, so the chip is always visible. It is
also **per lake, not per day**, because a match takes a whole lake out of use — a single
combined number would mislead. Peg counts per lake are deliberately not shown, since the
split of 23 pegs between the two lakes is unconfirmed.

## 4. Things the photographs corrected

**The holiday lets are the curved-roof Dutch Barns, not the farmhouse.** The pointed-gable
brick building with the tall chimney is the historic farmhouse. Early work had these
conflated. The farmhouse became the parent-brand device; the barns belong to Stay.

**The two barns are semi-detached under one roof.** The brief's "hard case" is worse than
stated: the exterior is genuinely one building, so any card leading with it produces a
duplication bug. Resolved by leading with **interiors**, which differ markedly — the Dutch
Barn is blue-and-white with the wood burner as its centre; the Hayloft is wool, oak and
stone. Each card carries a three-image cluster rather than one photograph.

**One cottage fact was inferred — now superseded by a sourced one.** The differentiator in
the key-facts row (freestanding bath vs walk-in shower room) was read off the photographs.
It was correctly marked provisional, but it should not be used.

**Use instead: The Hayloft has a ground-floor wet room.** This comes from the property's
own Cottages.com listing, so it is sourced rather than inferred. It is also the better
differentiator on the merits — for a group of ten it is an accessibility fact that changes
who can book, not a bathroom-fittings preference.

The correction is recorded here and in `tokens.json` under `confirmed.cottageDifferentiator`.
**The exported HTML has deliberately not been hand-edited** — exports are ground truth from
Design, and editing them by hand breaks the design-diff contract. Apply the change when the
cottage card becomes an Astro component, or re-export from Design if you want the HTML to
match.

Still unconfirmed: whether The Dutch Barn has a corresponding distinguishing feature. If
not, the slot can carry "Ask us which suits your group" — the design does not depend on a
symmetrical pair.

## 5. Accessibility decisions

**Text over photography is always cream.** Amber letterforms at 14px/600 over sky sit
almost exactly on the 4.5:1 threshold and flip either side of it as the scrim changes.
Amber is carried on a short rule beside the eyebrow instead. This is why the scrim could
then be *lightened* to 0.84 — legibility no longer depends on it, so the photograph
comes back.

**The 44px floor binds on controls, not inline links.** Buttons, basket, steppers,
calendar cells and icon buttons all hold 44×44. Inline navigation links are 19px text
with generous spacing. Flag if you want it binding everywhere.

**The date picker scrolls rather than shrinks.** Seven 44px columns need 320px; a 375px
phone offers 279px inside the card. Shrinking the cells breaks the target size; a hard
floor clipped Sunday entirely. It now scrolls horizontally with a 320px track floor.
This is the one component where the brief's grid and its touch-target rule genuinely
conflict, and the target won.

**Never colour alone.** Closed dates are struck through as well as greyed. Match days
carry a dot as well as a tint. Availability chips carry a dot and a word.

**Secondary text was darkened to clear moss-tint.** `--gs-muted` began as #6E685B, which
gives 4.41:1 on moss-tint — under AA. Since moss-tint is the ground for basket panels,
seasonal bands and key-fact pills, the token was darkened to #5F5A4C rather than patched
per instance. Verified pairings are listed in `tokens.json` under
`photography.checkedPairings`; do not lighten it back.

## 5a. Derived-family corrections (post-handover)

Two checks on the invented families, judged in context rather than in isolation.

**The three creams were three tokens doing two jobs.** `cream-alt #F7F2E8` and
`surface #FBF8F0` differ by four to eight points per channel — invisible at arm's length,
and worse than invisible in the one place it mattered: a card on an alternating section had
effectively no colour separation from its ground and relied entirely on its shadow.
`--gs-cream-alt` is now **retired as an alias of `--gs-surface`** (same value, kept only so
existing references resolve). Alternating sections use surface; cards on them lift with
their border. Two surfaces, one divider. `rule-soft #EDE6D6` stays — it is never a surface,
only a 1px divider, so judging it as one was the wrong test.

**The error family went muddy against amber.** `#A0442C` and amber `#C68A2E` were both warm
mid-tones about twenty degrees apart in hue with near-identical lightness, so in the
availability chip row — the one component where moss, amber and red sit side by side — red
read as a darker amber rather than as a stop. Deepened and shifted redder:

| Token | Was | Now |
|---|---|---|
| `--gs-error` | #A0442C | **#93301F** |
| `--gs-error-bg` | #F6E7E1 | **#F7E4DE** |
| `--gs-error-fg` | #8A3A22 | **#7E2C1A** (9.1:1 on errorBg) |

The division of labour is now legible: amber is provisional and near-limit, red is only ever
a stop. `Colour Check.dc.html` shows both comparisons before and after.

## 6. Layout rules worth keeping

**Every `minmax()` floor is wrapped in `min(<len>, 100%)`.** A bare floor cannot shrink,
so it overflows instead. This caused repeated failures across three blocks; it is now
uniform. Do not add a bare `minmax(300px, 1fr)`.

**Section padding is fluid** — `clamp(20px, 5vw, 64px)`. A fixed 64px consumed 34% of a
375px viewport, which is what made grids overflow in the first place.

**Aspect-ratio and min-height do not mix on grid children.** `aspect-ratio: 1` turns a
44px min-height into a 44px min-*width* that `1fr` cannot shrink below. Set one or the
other.

## 7. Copy status

All copy in the export is real, in the farm's voice, and free of lorem. But it is
**written, not approved** — treat it as a well-argued first draft. The exceptions are the
confirmed facts listed in `tokens.json` under `confirmed`, and the provisional values
under `provisional`, which are marked in the UI and must be filled before launch.

Lake names — "Top lake" and "Bottom lake" — are placeholders. If the lakes have real
names, they need correcting in the day-ticket component and the sold-out fallback.
