/* ============================================================================
   BayRoster — the yard-record visual system (ADR-003 + ADR-004, task T-011)
   ============================================================================

   JOB
     One stylesheet, one light theme. The page is a warm cream working paper.
     On top of it sit two things and only two things:

       1. CANVAS  — full-bleed deep Field Navy sections (`.canvas`). These are
          staging, not chrome: a navy field carrying a texture, used to lift a
          paper object off the page.
       2. PAPER   — crafted objects that look like cut card stock sitting on
          that canvas: sheets, plates, tickets, tags, stamps.

   INVARIANTS (break one and the family resemblance goes with it)
     - Canvas, paper, ink and status colours are FIXED BRAND HEX VALUES, not
       theme-relative shades. There is no dark mode, no toggle, and no
       prefers-color-scheme branch; a canvas section must never shift colour
       because something upstream re-themed a token.
     - Every paper object shares one formula: a 1px flat border in a paper/ink
       colour, a HARD 0-blur offset drop shadow (a solid object casting a
       hard-edged shadow, never soft ambient UI glow), a fraction-of-a-degree
       rotation, and `border-radius: 2px`. Two pixels, not twelve — these are
       printed material, not app chrome.
     - `.plate-notch` is the signature mark: two pseudo-elements each drawing
       two sides of a corner bracket. Built as offset borders, deliberately
       NOT clip-path, so it never clips the parent's shadow or overflow.
     - Mono (IBM Plex Mono) is for FIELD REFERENCE AND STATUS MARKS ONLY —
       unit ids, record numbers, dates, dollars, document ids, status chips.
       Never prose, never headings, and specifically NOT `.eyebrow`, which is
       body sans on purpose.
     - The status trio (paid / due / open) is reserved. It marks unit status
       and is reused as a decorative numbering rhythm on ledger rows. It is
       never a section background, and the Kiln Rust accent is never a status
       colour. The two palettes stay separate even though both run warm.
     - No symmetric card grids anywhere. Lists are numbered ledgers.
     - Rotation is a desktop-only affordance. At <=900px every paper object
       goes `transform: none` and absolutely-positioned objects become normal
       flow, because a tilted card in a vertical stack reads as a mistake.

   FAILURE BEHAVIOUR
     Artwork slots (`.slot`) draw a plain CSS placeholder when their generated
     image has not landed. Nothing here renders a broken image; see
     `includes/artwork.php` and `_warroom/RESEARCH/artwork-slots.md`.

   ORACLE
     `python tools/audit-php-syntax.py "*.php" "includes/*.php"` for the pages,
     and the rendered browser at 375 / 768 / 1280 for this file:
     `document.documentElement.scrollWidth === clientWidth` on every page at
     every width is the pass condition that this stylesheet can fail.
   ========================================================================== */

@font-face {
    font-family: "Bitter";
    src: url("../assets/fonts/Bitter-wght.ttf") format("truetype");
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
}

@font-face {
    font-family: "Source Sans 3";
    src: url("../assets/fonts/SourceSans3-wght.ttf") format("truetype");
    font-style: normal;
    font-weight: 200 900;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Mono";
    src: url("../assets/fonts/IBMPlexMono-Regular.ttf") format("truetype");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

:root {
    color-scheme: light;

    /* --- Working-paper ground (ADR-003 tokens; assets/brand-tokens.css is
       the upstream contract, the literals here are the fallback so the site
       still renders correctly if that file is unavailable) --- */
    --paper: var(--warm-cream, #f4ead7);
    --ink: var(--field-navy, #1e3342);
    --clay: var(--kiln-rust, #8b452b);
    --olive: var(--tally-olive, #465331);
    --stone: var(--memo-tan, #c9b28b);
    --register-paper: #f7f5ef;
    --register: #284759;
    --stamp: #91462d;
    --white: #fffefa;
    --paper-deep: #eadcc2;
    --paper-soft: #faf3e6;
    --line: rgba(30, 51, 66, 0.2);
    --shadow: 0 1.2rem 2.8rem rgba(30, 51, 66, 0.14);

    /* --- FIXED CANVAS AND PAPER CONSTANTS ---------------------------------
       Deliberately literal hex, never `var(--theme-something)`. A canvas
       section is a brand constant: it reads the same regardless of what any
       future retheme does to the tokens above. Same reasoning PineRoster
       records for its fixed pine tones. */
    --canvas-deep: #16283a;   /* deepest field navy — hero stage, kind track */
    --canvas: #1e3342;        /* Field Navy — the standard canvas */
    --canvas-mid: #23394b;    /* one step up, for a canvas that follows one */
    --sheet: #f4ead7;         /* Warm Cream — every paper object */
    --sheet-bright: #fbf6ea;  /* the brighter sheet, for text on canvas */
    --sheet-ink: #172934;     /* ink printed on a sheet */
    --sheet-edge: #c7bca6;    /* the cut edge of a sheet */
    /* Muted ink for the small mono reference lines printed on a sheet.
       Verified at 5.1:1 on Warm Cream; the earlier #6d7268 measured 4.14
       and failed AA for normal-size text. */
    --paper-muted: #5f6459;
    --mark: #8b452b;          /* Kiln Rust — marks on PAPER */
    --mark-canvas: #c9b28b;   /* Memo Tan — the same marks on NAVY */
    --cast: rgba(11, 22, 32, 0.4);   /* hard offset shadow on canvas */
    --cast-paper: rgba(30, 51, 66, 0.18); /* hard offset shadow on paper */

    /* --- FIXED STATUS TRIO ------------------------------------------------
       Mirrors what the software itself shows for a space: paid, due soon,
       open. Used (a) as unit status on the yard stage and (b) as a purely
       decorative numbering rhythm down ledger rows — a row marked "due" does
       not mean that row is overdue, it means the list is cycling the same
       three tones the product uses. White ink on all three: lowest pair is
       due at 5.4:1, so the set clears AA as a set. */
    --status-paid: #465331;
    --status-due: #9c5a1e;
    --status-open: #284759;
    --status-ink: #ffffff;

    --font-display: "Bitter", Rockwell, Georgia, serif;
    --font-body: "Source Sans 3", "Trebuchet MS", Arial, sans-serif;
    --font-mono: "IBM Plex Mono", Consolas, monospace;

    --max: 1180px;
    --space-xs: 0.45rem;
    --space-sm: 0.8rem;
    --space-md: 1.35rem;
    --space-lg: 2.1rem;
    --space-xl: 3.4rem;
    --space-2xl: 5.6rem;
    --space-3xl: 8rem;

    /* Narrative rhythm: canvas sections breathe more than an inner-page
       `.section` does. Viewport-responsive, layered on top of --space-*. */
    --canvas-rhythm: clamp(4.5rem, 9vw, 8.5rem);

    /* Contextual accent for the notch bracket and other small marks. Canvas
       sections override it; everything else inherits the paper value. */
    --notch-ink: var(--mark);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    overflow-x: clip;
    background: var(--paper);
}

body {
    margin: 0;
    overflow-x: hidden;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 1.08rem;
    font-weight: 450;
    line-height: 1.62;
    text-rendering: optimizeLegibility;
}

/* `height: auto` is load-bearing, not tidiness. An <img> carries width/height
   ATTRIBUTES so the browser can reserve the right box before the bytes arrive,
   and those attributes are presentational hints: a component that sets only
   `width` in CSS leaves the height hint standing, so the picture renders at
   its container's width by the attribute's height in px — stretched. That is
   exactly what happened to the three feature captures (a 1200x800 capture
   rendered 321x800 at 375px, T-021). Releasing the height here means no
   component can reintroduce that bug by forgetting one line, and the
   attributes go on doing their real job: holding the aspect ratio. */
img,
svg {
    display: block;
    max-width: 100%;
    height: auto;
}

a {
    color: var(--link-ink, var(--clay));
    /* Email addresses and URLs in the legal pages and the footer are single
       unbreakable tokens; without this they hang off the right edge at
       silhouette widths. */
    overflow-wrap: break-word;
    text-decoration-thickness: 0.08em;
    text-underline-offset: 0.2em;
}

a:hover,
a:focus-visible {
    color: var(--link-ink-hover, var(--ink));
}

.canvas,
.page-hero,
.pricing-hero,
.about-hero,
.error-hero,
.closing-band,
footer {
    --link-ink-hover: var(--sheet-bright);
}

:focus-visible {
    outline: 3px solid var(--clay);
    outline-offset: 4px;
}

::selection {
    background: var(--clay);
    color: var(--paper);
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
figure,
blockquote {
    margin-top: 0;
}

/* ---------------------------------------------------------------------------
   INK INHERITANCE — read this before adding any colour rule.

   Text colour is driven by three inherited custom properties, never by
   descendant selectors like `.canvas p`. A canvas section sets the cream
   trio; a paper object sets the ink trio; inheritance does the scoping.

   This exists because the selector approach failed twice in review. A rule
   like `.canvas p { color: cream }` (0,1,1) silently out-specifies
   `.yard-stamp { color: navy }` (0,1,0), so a cream stamp on a cream field
   rendered as an empty white box — invisible, and invisible to a contrast
   probe that never thought to sample it. Fixing that by hand means writing
   `.canvas .yard-stamp`, then `.canvas .paper p`, then
   `.page-hero .price-ticket p`, and so on for every object x every ground:
   a combinatorial set that is never finished and fails silently when missed.

   With variables there is nothing to enumerate. Put a paper object anywhere,
   on any ground, and its text is correct because it declares its own ink.
   ADD NEW OBJECTS BY SETTING THE TRIO, NOT BY WRITING A DESCENDANT SELECTOR.
   ------------------------------------------------------------------------ */
p,
li {
    color: var(--prose-ink, inherit);
}

h1,
h2,
h3,
h4 {
    color: var(--heading-ink, var(--ink));
}

/* Headings are capped in real characters, not percentages — a ch cap reads
   about 20% narrower than it looks, so these are tuned per component below
   rather than trusted globally. `text-wrap: balance` handles the rest. */
h1,
.hero-title {
    max-width: 15ch;
    margin-bottom: var(--space-md);
    font-family: var(--font-display);
    font-size: clamp(2.7rem, 6vw, 5.4rem);
    font-weight: 850;
    letter-spacing: -0.042em;
    line-height: 0.95;
    text-wrap: balance;
}

h2 {
    max-width: 20ch;
    margin-bottom: var(--space-md);
    font-family: var(--font-display);
    font-size: clamp(1.95rem, 3.6vw, 3.1rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.04;
    text-wrap: balance;
}

h3 {
    max-width: 26ch;
    margin-bottom: var(--space-sm);
    font-family: var(--font-display);
    font-size: clamp(1.28rem, 2vw, 1.72rem);
    font-weight: 750;
    line-height: 1.16;
    text-wrap: balance;
}

h4 {
    font-family: var(--font-display);
    font-weight: 750;
}

p,
li {
    max-width: 68ch;
}

strong {
    font-weight: 750;
}

/* ---------------------------------------------------------------------------
   Mono is a reference mark, not a typeface choice.
   Everything in this selector list is a field record: a document id, a record
   number, a date, a dollar figure, a status word. Prose and headings never
   join this list. `.eyebrow` is NOT here — see below.
   ------------------------------------------------------------------------ */
code,
.mono,
.register-index,
.record-index,
.chapter-index,
.document-meta,
.price-label,
.yard-stamp,
.plate-label,
.plate-link,
.record-reference,
.yard-tag,
.trust-rail,
.unit-tag,
.record-stamp,
.kind-mark,
.route-mark,
.index-num {
    font-family: var(--font-mono);
    font-size: 0.83rem;
    font-weight: 400;
    letter-spacing: 0.045em;
    line-height: 1.45;
    text-transform: uppercase;
}

/* Eyebrow labels are body sans with a square bullet — the second of the two
   label conventions. Mixing them is what makes a page look machine-made. */
.eyebrow,
.hero-kicker {
    display: block;
    max-width: 44ch;
    margin-bottom: var(--space-md);
    color: var(--label-ink, var(--olive));
    font-family: var(--font-body);
    font-size: 0.79rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    line-height: 1.5;
    text-transform: uppercase;
}

.eyebrow::before,
.hero-kicker::before {
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    margin-right: 0.6em;
    background: var(--mark);
    content: "";
    vertical-align: 0.05em;
}

.container {
    width: min(100% - 2.5rem, var(--max));
    margin-inline: auto;
}

.container--wide {
    width: min(100% - 2.5rem, 1420px);
}

.sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.text-center {
    text-align: center;
}

.mt-md {
    margin-top: var(--space-md);
}

.mt-lg {
    margin-top: var(--space-lg);
}

/* ===========================================================================
   1. CANVAS STAGING
   A canvas is a full-bleed deep-navy section. It is always textured — a flat
   navy band with centred white text and a button is the exact generic shape
   this system exists to avoid — and it always carries at least one paper
   object. `isolation: isolate` gives each canvas its own stacking context so
   negative-z texture layers can never escape into a neighbour.
   ======================================================================== */
.canvas {
    position: relative;
    z-index: 0;
    padding-block: var(--canvas-rhythm);
    overflow: hidden;
    background: var(--canvas);
    color: var(--sheet-bright);
    isolation: isolate;
    --notch-ink: var(--mark-canvas);
}

.canvas--deep {
    background: var(--canvas-deep);
}

.canvas--mid {
    background: var(--canvas-mid);
}

/* The canvas ink trio. Anything nested inside inherits it; a paper object
   nested inside overrides it by declaring its own. No descendant selectors. */
.canvas,
.page-hero,
.pricing-hero,
.about-hero,
.error-hero,
.closing-band,
.package-panel--private,
.manifest-sheet,
footer {
    --prose-ink: rgba(251, 246, 234, 0.84);
    --heading-ink: var(--sheet-bright);
    --label-ink: var(--stone);
    --link-ink: var(--stone);
    --btn-outline-ink: var(--sheet-bright);
    --btn-outline-edge: rgba(244, 234, 215, 0.62);
    --btn-outline-flip: var(--canvas-deep);
}

.canvas .eyebrow::before,
.canvas .hero-kicker::before {
    background: var(--mark-canvas);
}

/* Texture A — graph paper. Always a 1px line, always a fixed pixel grid,
   always under 5% opacity. Used on the header hairline, the invite, and the
   inner-page mastheads so it reads as a recurring signature. */
.canvas--graph {
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.042) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.042) 1px, transparent 1px);
    background-size: 46px 46px;
}

/* Texture B — the ruled-radial dot field, rotated off-axis so the pattern
   never resolves into a visible grid. */
.canvas--dots::before {
    position: absolute;
    z-index: -1;
    inset: -22%;
    background: repeating-radial-gradient(ellipse at 12% 58%, transparent 0 26px, rgba(201, 178, 139, 0.55) 27px 28px, transparent 29px 46px);
    content: "";
    opacity: 0.14;
    transform: rotate(-7deg);
}

/* Texture C — a giant near-invisible mono reference string bleeding off the
   corner. Supply the string with `data-ghost` on the section. */
.canvas--ghost::after {
    position: absolute;
    z-index: -1;
    right: -0.25em;
    bottom: -0.34em;
    color: rgba(255, 255, 255, 0.035);
    content: attr(data-ghost);
    font-family: var(--font-mono);
    font-size: clamp(4.5rem, 15vw, 13rem);
    line-height: 1;
    pointer-events: none;
    white-space: nowrap;
}

/* Texture D — bay-door rhythm. Vertical bands at low contrast, the storage
   equivalent of a graph grid. Doubles as the hero stage's provisional art. */
.canvas--bays {
    background-image:
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 74px),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.028) 0 1px, transparent 1px 120px);
}

/* ===========================================================================
   2. PAPER OBJECTS
   One formula, several species. Border + hard 0-blur cast shadow + micro
   rotation + 2px radius. The rotation direction and the shadow direction
   always agree: the shadow falls toward the bottom-right, the sheet tilts a
   fraction of a degree, and no two adjacent objects tilt the same way.
   ======================================================================== */
.paper {
    position: relative;
    background: var(--sheet);
    color: var(--sheet-ink);
    border: 1px solid var(--sheet-edge);
    border-radius: 2px;
    box-shadow: 16px 20px 0 var(--cast), 0 14px 34px rgba(11, 22, 32, 0.28);
}

/* The paper ink trio. Every paper species declares it, so a sheet reads
   correctly on navy, on cream, or anywhere else it is ever moved to. */
.paper,
.yard-record,
.register-plate,
.proof-figure,
.price-ticket,
.owner-register,
.vacant-bay,
.contact-form-sheet,
.package-panel--public,
.card,
.paper-note,
.contact-info,
.faq-item,
.unit-tag,
.yard-stamp {
    --prose-ink: #3b4c56;
    --heading-ink: var(--sheet-ink);
    --label-ink: var(--olive);
    --link-ink: var(--mark);
    --btn-outline-ink: var(--ink);
    --btn-outline-edge: var(--ink);
    --btn-outline-flip: var(--paper);
}

/* A unit tag is a cream pill: its own text is ink, whatever it sits on. */
.unit-tag {
    --link-ink: var(--canvas-deep);
}

.paper .eyebrow::before,
.paper .hero-kicker::before {
    background: var(--mark);
}

/* A paper object resting on the page itself rather than on navy gets a
   lighter cast — a sheet on a desk, not a sheet held over a dark field. */
.paper--on-paper {
    box-shadow: 14px 17px 0 var(--cast-paper), 0 10px 26px rgba(30, 51, 66, 0.1);
}

/* --- The signature mark ----------------------------------------------------
   Corner brackets drawn as two pseudo-elements, each painting two sides of a
   corner. Offset borders, NOT clip-path: clip-path would cut off the parent's
   own cast shadow, which is the whole point of the object. */
.plate-notch {
    position: relative;
}

.plate-notch::before,
.plate-notch::after {
    position: absolute;
    width: 15px;
    height: 15px;
    content: "";
    pointer-events: none;
}

.plate-notch::before {
    top: -1px;
    left: -1px;
    border-top: 2px solid var(--notch-ink);
    border-left: 2px solid var(--notch-ink);
}

.plate-notch::after {
    right: -1px;
    bottom: -1px;
    border-right: 2px solid var(--notch-ink);
    border-bottom: 2px solid var(--notch-ink);
}

/* --- Yard stamp: a small filing reference, floating free of any card ------ */
.yard-stamp {
    display: inline-block;
    padding: 0.32rem 0.6rem;
    background: var(--sheet);
    color: var(--canvas-deep);
    border: 1px solid rgba(30, 51, 66, 0.55);
    box-shadow: 3px 3px 0 rgba(11, 22, 32, 0.22);
    font-size: 0.67rem;
    font-weight: 400;
    letter-spacing: 0.11em;
}

/* --- Register plate: a real software capture framed as a mounted card ----- */
.register-plate {
    display: block;
    margin: 0;
    padding: 0.62rem;
    background: #fffdf6;
    color: var(--sheet-ink);
    border: 1px solid #9aa093;
    border-radius: 2px;
    box-shadow: 13px 15px 0 var(--cast), 0 12px 30px rgba(11, 22, 32, 0.22);
    text-decoration: none;
}

.register-plate img {
    width: 100%;
    height: auto;
}

.plate-label,
.plate-link {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.4rem 0.8rem;
    color: #5a6158;
    font-size: 0.63rem;
    font-weight: 400;
    letter-spacing: 0.07em;
}

.plate-label {
    margin: 0.1rem 0 0.55rem;
}

.plate-link {
    margin: 0.55rem 0 0.1rem;
    color: var(--mark);
    font-family: var(--font-body);
    font-size: 0.86rem;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
}

a.register-plate:hover .plate-link,
a.register-plate:focus-visible .plate-link {
    color: var(--canvas);
}

/* --- Unit tag: a pinned status marker on the yard stage ------------------- */
.unit-tags {
    position: absolute;
    z-index: 5;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    pointer-events: none;
}

.unit-tag {
    position: absolute;
    top: var(--tag-y, 20%);
    left: var(--tag-x, 60%);
    pointer-events: auto;
}

.unit-tag a {
    display: inline-grid;
    grid-template-columns: auto auto;
    align-items: stretch;
    background: var(--sheet);
    color: var(--canvas-deep);
    border: 2px solid var(--canvas-deep);
    border-radius: 999px;
    box-shadow: 5px 6px 0 rgba(11, 22, 32, 0.3);
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.07em;
    overflow: hidden;
    text-decoration: none;
    text-transform: uppercase;
    animation: unit-tag-signal 7s ease-in-out infinite;
}

.unit-tag a > span {
    padding: 0.28rem 0.5rem 0.24rem 0.62rem;
}

.unit-tag a > strong {
    padding: 0.28rem 0.62rem 0.24rem 0.5rem;
    color: var(--status-ink);
    font-weight: 700;
}

.unit-tag--paid a > strong {
    background: var(--status-paid);
}

.unit-tag--due a > strong {
    background: var(--status-due);
}

.unit-tag--open a > strong {
    background: var(--status-open);
}

/* NO PIN STEM. There was one — a dashed leader dropping from each tag onto
   the stage art — and it was removed deliberately.

   The stage art is `object-fit: cover`, so it crops and shifts as the stage's
   aspect ratio changes, while the tags are placed at fixed percentages of the
   stage box. The two are NOT in the same positioning context: a leader aimed
   at a spot on the photo at one width aims somewhere else at another. Worse,
   the photograph is a general yard scene with no unit B-04 in it, so the stem
   asserted a correspondence that never existed at any width.

   A pointer must be baked into the thing it points at, share a positioning
   context with it, or not exist. This one qualifies for none of those, so it
   does not exist. The tag still carries the whole meaning: unit id + status. */

.unit-tag:nth-child(2) a {
    animation-delay: 2.2s;
}

.unit-tag:nth-child(3) a {
    animation-delay: 4.4s;
}

@keyframes unit-tag-signal {
    0%, 88%, 100% {
        box-shadow: 5px 6px 0 rgba(11, 22, 32, 0.3);
    }

    94% {
        box-shadow: 5px 6px 0 rgba(11, 22, 32, 0.3), 0 0 0 6px rgba(244, 234, 215, 0.14);
    }
}

/* --- Yard record: ruled paper with a clip and a margin rule --------------- */
.yard-record {
    position: relative;
    padding: clamp(1.9rem, 3.4vw, 2.9rem) clamp(1.3rem, 3vw, 2.4rem) clamp(1.9rem, 3.4vw, 2.9rem) clamp(1.3rem, 3vw, 2.4rem);
    background-color: var(--sheet);
    background-image: repeating-linear-gradient(0deg, transparent 0 37px, rgba(40, 71, 89, 0.2) 38px, transparent 39px);
    color: var(--sheet-ink);
    border: 1px solid var(--sheet-edge);
    border-radius: 2px;
    box-shadow: 16px 20px 0 var(--cast), 0 14px 34px rgba(11, 22, 32, 0.26);
}

.yard-record--on-paper {
    box-shadow: 14px 17px 0 var(--cast-paper), 0 10px 26px rgba(30, 51, 66, 0.1);
}

.yard-record::before {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 3.4rem;
    border-left: 2px solid rgba(139, 69, 43, 0.24);
    content: "";
}

.yard-record > * {
    position: relative;
    padding-left: 2.4rem;
}

.yard-record h3 {
    margin-top: var(--space-lg);
    color: var(--sheet-ink);
    font-size: 1.16rem;
}

.yard-record h3:first-of-type {
    margin-top: 0;
}

.yard-record p {
    color: #3b4c56;
    font-size: 0.99rem;
}

.record-clip {
    position: absolute;
    z-index: 2;
    top: -1.25rem;
    left: 50%;
    width: 5.4rem;
    height: 2rem;
    padding: 0;
    background: var(--mark);
    border-radius: 2px;
    box-shadow: 0 3px 8px rgba(11, 22, 32, 0.24);
    transform: translateX(-50%) rotate(-2deg);
}

.record-reference {
    margin-bottom: var(--space-lg);
    color: var(--paper-muted);
    font-size: 0.64rem;
    letter-spacing: 0.1em;
}

/* --- Register stamp: the inline YES/NO mark ------------------------------- */
.record-stamp {
    display: inline-block;
    min-width: 3.1rem;
    margin-right: 0.5rem;
    padding: 0.08rem 0.36rem;
    color: var(--status-paid);
    border: 2px solid var(--status-paid);
    font-size: 0.7rem;
    font-weight: 700;
    text-align: center;
    transform: rotate(-4deg);
}

.record-stamp--no {
    color: #6b6a63;
    border-color: #6b6a63;
    transform: rotate(3deg);
}

.record-signoff {
    margin-top: var(--space-lg);
    margin-bottom: 0;
    color: var(--mark);
    font-family: var(--font-display);
    font-size: 1.18rem;
    font-weight: 750;
}

/* --- Yard tag: the two-line translucent chip under a masthead heading ----- */
.yard-tag {
    display: inline-grid;
    max-width: 28rem;
    margin-top: var(--space-md);
    padding: 0.55rem 0.85rem;
    background: rgba(244, 234, 215, 0.08);
    color: var(--stone);
    border: 1px solid rgba(255, 255, 255, 0.36);
    border-radius: 2px;
    font-size: 0.66rem;
    letter-spacing: 0.09em;
}

.yard-tag b {
    color: var(--sheet-bright);
    font-weight: 700;
}

.yard-tag span {
    color: rgba(244, 234, 215, 0.72);
    letter-spacing: 0.05em;
    text-transform: none;
}

/* --- Artwork slots -------------------------------------------------------
   A slot container always paints a plain provisional field. When the art
   lands, `.slot-art` covers it. Nothing here can render a broken image. */
/* The provisional field is its OWN layer, not the slot's background.
   It used to be `.slot { background: ... }` cleared by `.slot:has(.slot-art)`,
   which also wiped any background the component itself wanted — a filled
   `.kind-figure` silently lost its cream mount. A slot is a container; what
   it looks like when empty is a separate concern from how it is styled when
   full, so the placeholder gets its own layer to switch off.
   NOTE: this makes ::before the slot's own; do not combine .slot with
   .plate-notch, which also owns ::before and ::after. */
.slot {
    position: relative;
    overflow: hidden;
}

.slot::before {
    position: absolute;
    z-index: 0;
    inset: 0;
    background-color: var(--canvas-deep);
    background-image:
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 68px),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 110px);
    content: "";
}

.slot--paper::before {
    background-color: var(--paper-deep);
    background-image:
        repeating-linear-gradient(90deg, rgba(30, 51, 66, 0.07) 0 2px, transparent 2px 68px),
        repeating-linear-gradient(0deg, rgba(30, 51, 66, 0.05) 0 1px, transparent 1px 110px);
}

.slot-art {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Once real art occupies a slot the provisional field switches itself off.
   This matters for art with transparency: a cut-out mark must not sit on a
   placeholder texture. Browsers without :has() simply keep the field behind
   the (usually opaque) art, which is harmless. */
.slot:has(.slot-art)::before {
    display: none;
}

.slot-art {
    position: relative;
    z-index: 1;
}

/* ===========================================================================
   3. HEADER, BREADCRUMBS, BUTTONS
   The header stays cream. It is the anchor that keeps this a light-theme site
   with navy staging inside it, rather than a dark site.
   ======================================================================== */
header {
    position: sticky;
    z-index: 1000;
    top: 0;
    background: rgba(244, 234, 215, 0.97);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 0.35rem 1.4rem rgba(30, 51, 66, 0.05);
    backdrop-filter: blur(14px);
}

header::after {
    position: absolute;
    right: 0;
    bottom: -4px;
    left: 0;
    height: 4px;
    background: var(--canvas);
    content: "";
    transform: scaleX(0.34);
    transform-origin: left;
}

/* `min-height` is a floor, not the height. The bar takes its size from
   whatever is tallest inside it plus this padding, so growing the logo grows
   the header instead of jamming the artwork against the rule — one number to
   change, not a height to keep in sync with a width somewhere else. */
header > .container {
    display: flex;
    min-height: 92px;
    align-items: center;
    justify-content: space-between;
    padding-block: 0.75rem;
    gap: var(--space-lg);
}

/* LOGO SIZE (owner directive, 2026-08-06: "400px wide on desktop, and about
   as wide as possible on a phone to make it fit the top bar").
   The width lives on the link and the image simply fills it, so there is a
   single number per breakpoint rather than two that can drift apart. 400px is
   the cap; below roughly 1250px the viewport unit takes over so the lockup
   gives ground to the nav instead of crowding it — at the 900px nav
   breakpoint that leaves it near 290px, which clears the seven-item nav with
   room to spare. `min-width: 0` lets it shrink if a longer nav ever arrives;
   without it a replaced element's intrinsic width would pin the flex item. */
.logo {
    flex: 0 1 auto;
    width: clamp(200px, 32vw, 400px);
    min-width: 0;
    text-decoration: none;
}

.site-logo {
    width: 100%;
    height: auto;
}

header nav ul {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

header nav a {
    display: block;
    padding: 0.72rem 0.75rem 0.58rem;
    border-bottom: 3px solid transparent;
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 0.96rem;
    font-weight: 700;
    text-decoration: none;
}

header nav a:hover,
header nav a:focus-visible,
header nav a.active,
header nav a[aria-current="page"] {
    color: var(--clay);
    border-bottom-color: var(--clay);
}

.header-controls {
    display: none;
}

.mobile-nav-toggle {
    width: 46px;
    height: 46px;
    padding: 0;
    border: 2px solid var(--ink);
    border-radius: 0;
    background: transparent;
    color: var(--ink);
    font-size: 1.35rem;
}

.breadcrumbs {
    background: var(--paper-deep);
    border-bottom: 1px solid var(--line);
}

.breadcrumbs .container,
.breadcrumb {
    display: flex;
    min-height: 42px;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.55rem;
    margin-block: 0;
    padding-block: 0.55rem;
    color: var(--olive);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    list-style: none;
    text-transform: uppercase;
}

.breadcrumbs a {
    color: var(--olive);
}

.cta-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
}

.btn,
button.btn {
    display: inline-flex;
    max-width: 100%;
    min-height: 48px;
    overflow-wrap: anywhere;
    align-items: center;
    justify-content: center;
    padding: 0.78rem 1.22rem;
    border: 2px solid var(--ink);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    color: var(--ink);
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 0.98rem;
    font-weight: 750;
    line-height: 1;
    text-align: center;
    text-decoration: none;
    transition: transform 160ms ease, background-color 160ms ease, color 160ms ease;
}

.btn:hover,
.btn:focus-visible {
    color: var(--paper);
    background: var(--ink);
    transform: translate(-2px, -2px);
}

/* Never pale text on the rust fill: the button ink stays the cream sheet on
   a solid clay field, which is the one high-contrast pairing that holds. */
.btn-primary {
    border-color: var(--clay);
    background: var(--clay);
    color: var(--paper);
}

.btn-primary:hover,
.btn-primary:focus-visible {
    border-color: var(--ink);
    background: var(--ink);
}

.btn-secondary {
    border-color: var(--olive);
    background: var(--olive);
    color: var(--paper);
}

/* An outline button takes its ink from whatever it is standing on. The
   descendant-selector version of this put cream-on-cream "Ask a Question"
   inside the closing card — a paper object on a canvas — because
   `.canvas .btn-outline` reached straight through the sheet. Same trio, same
   reason as the text colours above. */
.btn-outline {
    color: var(--btn-outline-ink, var(--ink));
    border-color: var(--btn-outline-edge, var(--ink));
}

.btn-outline:hover,
.btn-outline:focus-visible {
    background: var(--btn-outline-ink, var(--ink));
    color: var(--btn-outline-flip, var(--paper));
    border-color: var(--btn-outline-ink, var(--ink));
}

.btn-block {
    width: 100%;
}

/* Buttons standing on a canvas need a cream outline, not an ink one. */
/* ===========================================================================
   4. HOMEPAGE — SECTION 01: the yard stage
   Shape: an open canvas with paper objects scattered across it at absolute
   positions. Nothing else on the site uses this shape.
   ======================================================================== */
.home-yard {
    padding-block: 0;
    background: var(--canvas-deep);
}

.yard-stage {
    position: relative;
    max-width: 1680px;
    min-height: clamp(660px, 60vw, 850px);
    margin: 0 auto;
    isolation: isolate;
    overflow: hidden;
    background-color: var(--canvas-deep);
    border-inline: 1px solid rgba(201, 178, 139, 0.3);
}

.yard-art {
    position: absolute;
    z-index: -2;
    inset: 0;
}

.yard-art .slot {
    width: 100%;
    height: 100%;
}

/* Two-axis darkening wash so pale text stays legible over whatever art
   eventually lands here. */
.yard-stage::before {
    position: absolute;
    z-index: -1;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(15, 26, 36, 0.72) 0%, rgba(15, 26, 36, 0.18) 52%, rgba(15, 26, 36, 0.4) 100%),
        linear-gradient(0deg, rgba(15, 26, 36, 0.5) 0%, rgba(15, 26, 36, 0) 42%);
    content: "";
}

/* A thin inset frame — the stage reads as a mounted print, not a background */
.yard-stage::after {
    position: absolute;
    z-index: 0;
    inset: 16px;
    border: 1px solid rgba(201, 178, 139, 0.34);
    border-radius: 2px;
    content: "";
    pointer-events: none;
}

.yard-stamp--stage {
    position: absolute;
    z-index: 6;
    top: 1.8rem;
    left: 2.1rem;
}

.manifest-sheet {
    position: absolute;
    z-index: 4;
    top: 10%;
    left: 3.4%;
    width: min(47%, 620px);
    padding: clamp(1.6rem, 2.6vw, 2.6rem);
    background: rgba(22, 40, 58, 0.965);
    color: var(--sheet-bright);
    border: 1px solid rgba(244, 234, 215, 0.46);
    border-radius: 2px;
    box-shadow: 18px 22px 0 rgba(11, 22, 32, 0.34), 0 16px 40px rgba(6, 14, 22, 0.44);
    transform: rotate(-0.35deg);
}

.manifest-sheet h1 {
    max-width: 13ch;
    color: var(--sheet-bright);
    font-size: clamp(2.3rem, 3.4vw, 3.2rem);
}

.manifest-sheet .tagline {
    max-width: 44ch;
    margin-bottom: var(--space-lg);
    color: rgba(251, 246, 234, 0.85);
    font-size: clamp(1.02rem, 1.3vw, 1.16rem);
    line-height: 1.55;
}

.manifest-sheet .eyebrow {
    color: var(--stone);
}

.manifest-sheet .eyebrow::before {
    background: var(--mark-canvas);
}

.manifest-note {
    max-width: 46ch;
    margin: var(--space-md) 0 0;
    padding-top: var(--space-sm);
    border-top: 1px solid rgba(244, 234, 215, 0.22);
    color: rgba(251, 246, 234, 0.7);
    font-size: 0.88rem;
    line-height: 1.5;
}

.register-plate--stage {
    position: absolute;
    z-index: 3;
    right: 3%;
    bottom: 7.5%;
    width: min(43%, 540px);
    transform: rotate(1.1deg);
}

.yard-key {
    position: absolute;
    z-index: 4;
    bottom: 7.5%;
    left: 3.4%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    margin: 0;
    color: rgba(251, 246, 234, 0.9);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

.yard-key span {
    display: inline-flex;
    align-items: center;
    gap: 0.42rem;
}

.yard-key i {
    display: inline-block;
    width: 0.78rem;
    height: 0.78rem;
    border: 1px solid rgba(11, 22, 32, 0.5);
}

.yard-key-dot--paid {
    background: var(--status-paid);
}

.yard-key-dot--due {
    background: var(--status-due);
}

.yard-key-dot--open {
    background: var(--status-open);
}

/* The buying-model rail beneath the stage. */
.trust-rail {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem clamp(1.5rem, 5vw, 4.5rem);
    max-width: 1680px;
    margin: 0 auto;
    padding: 1.15rem var(--space-md);
    background: var(--canvas);
    border-top: 1px solid rgba(201, 178, 139, 0.24);
    color: rgba(251, 246, 234, 0.86);
    font-size: 0.72rem;
    letter-spacing: 0.09em;
}

.trust-rail span {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
}

.trust-rail b {
    color: var(--mark-canvas);
    font-weight: 700;
}

/* ===========================================================================
   HOMEPAGE — SECTION 02: the yard walk
   Shape: a short intro block, then three numbered stops threaded by a
   hand-drawn diagonal route line. The stops are staggered downward so the
   line passes through all three markers; the geometry is tuned to the
   container width and redrawn (not scaled) at the stacking breakpoint.
   ======================================================================== */
.home-walk {
    position: relative;
    padding-block: var(--canvas-rhythm);
    overflow: hidden;
    background-color: var(--paper);
    background-image:
        linear-gradient(rgba(30, 51, 66, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(30, 51, 66, 0.05) 1px, transparent 1px);
    background-size: 46px 46px;
}

.walk-intro {
    max-width: 62ch;
    margin-bottom: clamp(3rem, 6vw, 5rem);
}

.walk-intro h2 {
    max-width: 21ch;
}

.walk-intro > p:last-child {
    max-width: 46ch;
    padding-left: var(--space-md);
    border-left: 4px solid var(--mark);
    font-size: 1.14rem;
    line-height: 1.55;
}

.walk-route {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--walk-gap);
    --walk-gap: clamp(1.4rem, 3vw, 3.2rem);
}

/* THE ROUTE LINE — a pointer, so its geometry has to hold at EVERY width,
   not just the one it was tuned at.

   Horizontal: each stop's marker is 1.3rem wide at `left: 0`, so its centre
   sits 0.65rem into that column. With three equal columns the third marker's
   centre is one column-width short of the track's right edge — hence the
   `right` calc, exact at any width because the gap is a variable.

   Vertical: the stagger is a PERCENTAGE, not a fixed 2rem. That is the whole
   trick. Percentage margins resolve against the containing block's width, so
   the drop between markers scales with the track exactly as the horizontal
   span does — which keeps their RATIO, and therefore the required angle,
   constant. A fixed 2rem stagger with a fixed rotation only agreed at one
   width: at 900px the line missed the outer markers by about 8px, more than
   the marker's own radius, so it visibly connected nothing.

   The arithmetic that matters: tan(4.6deg) = TOTAL drop / full span, so the
   per-step drop is half the total. Getting that backwards doubles the stagger
   and the line misses both outer markers by ~33px while still passing exactly
   through the middle one — which looks plausible in a screenshot and is
   caught only by measuring the line against each marker. `routecheck` in the
   handoff does exactly that, at five widths.

   With the ratio pinned, one fixed 4.6deg rotation is correct everywhere in
   the band where the diagonal is used (900px up). Residual drift from the
   gap's clamp is under 2px at 1600px, well inside the 10px marker. */
.walk-route::before {
    position: absolute;
    z-index: 0;
    top: 1.5rem;
    right: calc((100% - 2 * var(--walk-gap)) / 3 - 0.65rem);
    left: 0.65rem;
    margin-top: 2.77%;
    border-top: 3px dashed rgba(30, 51, 66, 0.32);
    content: "";
    transform: rotate(4.6deg);
}

.walk-stop {
    position: relative;
    z-index: 1;
    padding-top: 3.6rem;
}

/* Percentages of the grid area's width, so the drop tracks the track. */
.walk-stop:nth-child(2) {
    margin-top: 8.88%;
}

.walk-stop:nth-child(3) {
    margin-top: 17.76%;
}

.walk-stop::before {
    position: absolute;
    top: 0.85rem;
    left: 0;
    width: 1.3rem;
    height: 1.3rem;
    background: var(--paper);
    border: 3px solid var(--canvas);
    border-radius: 999px;
    content: "";
}

.walk-stop .index-num {
    display: block;
    margin-bottom: var(--space-sm);
    color: var(--mark);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
}

.walk-stop h3 {
    max-width: 19ch;
}

.walk-stop p {
    max-width: 40ch;
    font-size: 1rem;
}

/* ===========================================================================
   HOMEPAGE — SECTION 03: the scope ledger
   Shape: an asymmetric two-up. Prose and a question list sit directly on the
   canvas; the scope contract sits on a tilted ruled sheet beside it.
   ======================================================================== */
.ledger-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.54fr) minmax(0, 0.46fr);
    gap: clamp(2.4rem, 6vw, 6rem);
    align-items: start;
}

.ledger-intro h2 {
    max-width: 17ch;
}

.ledger-intro > p {
    max-width: 48ch;
}

.ledger-questions {
    max-width: 44ch;
    margin: var(--space-lg) 0 0;
    padding: 0;
    list-style: none;
}

.ledger-questions li {
    position: relative;
    padding: 0.62rem 0 0.62rem 1.7rem;
    border-bottom: 1px solid rgba(244, 234, 215, 0.18);
    font-size: 1.02rem;
}

.ledger-questions li::before {
    position: absolute;
    top: 0.62rem;
    left: 0;
    color: var(--mark-canvas);
    content: "?";
    font-family: var(--font-mono);
    font-size: 0.95rem;
}

.ledger-sheet {
    transform: rotate(1.1deg);
}

/* ===========================================================================
   HOMEPAGE — SECTION 04: one property, two sides
   Shape: a narrow mono index column above two unequal full-bleed panels, one
   cream and one navy, whose content hugs the seam between them. A literal
   spatial split rather than a bullet list.
   ======================================================================== */
.home-package {
    padding-block: var(--canvas-rhythm);
    background: var(--canvas);
}

.package-heading {
    display: grid;
    grid-template-columns: 10rem minmax(0, 1fr);
    gap: clamp(1.2rem, 3vw, 2.6rem);
    margin-bottom: clamp(2.4rem, 5vw, 4rem);
}

.package-index {
    padding-top: 0.5rem;
    border-top: 2px solid var(--mark-canvas);
    color: var(--stone);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.package-heading h2 {
    max-width: 24ch;
}

.package-heading p {
    max-width: 60ch;
    margin-bottom: 0;
}

.package-panels {
    display: grid;
    grid-template-columns: minmax(0, 0.44fr) minmax(0, 0.56fr);
}

.package-panel {
    padding-block: clamp(2.2rem, 4vw, 3.6rem);
}

.package-panel--public {
    display: flex;
    justify-content: flex-end;
    background: var(--sheet);
    color: var(--sheet-ink);
}

.package-panel--private {
    background: var(--canvas-deep);
}

.package-panel-inner {
    width: min(100%, 34rem);
    padding-inline: clamp(1.25rem, 3vw, 2.6rem);
}

.package-panel--public h3,
.package-panel--public li {
    color: var(--sheet-ink);
}

.package-panel--public .eyebrow {
    color: var(--olive);
}

.package-panel--public .eyebrow::before {
    background: var(--mark);
}

.package-panel ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.package-panel li {
    position: relative;
    padding: 0.5rem 0 0.5rem 1.5rem;
    font-size: 0.99rem;
}

.package-panel li + li {
    border-top: 1px solid rgba(30, 51, 66, 0.14);
}

.package-panel--private li + li {
    border-top-color: rgba(244, 234, 215, 0.14);
}

.package-panel li::before {
    position: absolute;
    top: 0.5rem;
    left: 0;
    content: "\2013";
    font-family: var(--font-mono);
}

.package-panel--public li::before {
    color: var(--mark);
}

.package-panel--private li::before {
    color: var(--mark-canvas);
}

.package-panel .register-plate {
    margin-top: var(--space-lg);
    transform: rotate(-0.8deg);
}

.package-action {
    margin-top: clamp(2rem, 4vw, 3.2rem);
}

/* ===========================================================================
   HOMEPAGE — SECTION 05: verified money
   Shape: one large capture mounted as a plate, with a numbered decision
   register running beside it on ruled ledger paper. Only section that pairs
   a single dominant object with a short ruled decision list.
   ======================================================================== */
.home-money {
    position: relative;
    padding-block: var(--canvas-rhythm);
    background-color: var(--paper-soft);
    background-image: repeating-linear-gradient(0deg, transparent 0 37px, rgba(40, 71, 89, 0.09) 38px, transparent 39px);
}

.money-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.55fr) minmax(0, 0.45fr);
    gap: clamp(2.2rem, 5vw, 5rem);
    align-items: start;
    margin-top: clamp(2rem, 4vw, 3.2rem);
}

.money-intro h2 {
    max-width: 18ch;
}

.money-intro > p {
    max-width: 54ch;
}

.register-plate--money {
    transform: rotate(-0.9deg);
}

.decision-register {
    margin: 0;
    padding: 0;
    border-top: 2px solid var(--canvas);
    counter-reset: decision;
    list-style: none;
}

.decision-register li {
    position: relative;
    max-width: none;
    padding: var(--space-md) 0 var(--space-md) 3.6rem;
    border-bottom: 1px solid var(--line);
    counter-increment: decision;
}

.decision-register li::before {
    position: absolute;
    top: var(--space-md);
    left: 0;
    display: grid;
    width: 2.4rem;
    height: 2.4rem;
    align-items: center;
    justify-items: center;
    background: var(--status-paid);
    color: var(--status-ink);
    border-radius: 3px;
    content: counter(decision, decimal-leading-zero);
    font-family: var(--font-mono);
    font-size: 0.76rem;
}

.decision-register li:nth-child(2)::before {
    background: var(--status-due);
}

.decision-register li:nth-child(3)::before {
    background: var(--status-open);
}

.decision-register h3 {
    margin-bottom: 0.2rem;
    font-size: 1.14rem;
}

.decision-register p {
    margin-bottom: 0;
    font-size: 0.99rem;
}

/* ===========================================================================
   HOMEPAGE — SECTION 06: what the roster holds
   Shape: a borderless track under a dashed rule, diamond markers, and a giant
   ghost abbreviation printed behind each column's copy. No boxes, no cards.
   ======================================================================== */
.home-kinds {
    --track-rule: rgba(244, 234, 215, 0.32);
}

.kind-heading {
    max-width: 60ch;
    margin-bottom: clamp(2.6rem, 5vw, 4rem);
}

.kind-heading h2 {
    max-width: 22ch;
}

.kind-track {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.6rem, 3.5vw, 3.4rem);
    border-top: 2px dashed var(--track-rule, rgba(30, 51, 66, 0.28));
}

.kind-track article {
    position: relative;
    padding-top: 2.8rem;
}

.kind-track article::before {
    position: absolute;
    top: -0.62rem;
    left: 0;
    width: 1.15rem;
    height: 1.15rem;
    background: var(--notch-ink);
    content: "";
    transform: rotate(45deg);
}

/* DELIBERATE CONTRAST EXCEPTION. This watermark measures ~1.3:1 and is meant
   to: it is a texture, not text. It carries `aria-hidden="true"`, and the
   same word is stated at full contrast by the <h3> directly beneath it, so no
   information depends on reading it. Raising it to AA would turn a watermark
   into a second headline. `.error-code` is the same case. */
.kind-abbr {
    position: absolute;
    z-index: 0;
    top: 1.1rem;
    right: 0;
    margin: 0;
    color: rgba(251, 246, 234, 0.1);
    font-family: var(--font-display);
    font-size: clamp(3.2rem, 6.6vw, 6.2rem);
    font-weight: 850;
    letter-spacing: -0.05em;
    line-height: 0.85;
    pointer-events: none;
}

/* ARTWORK SLOT holder: a square plate at the head of each column, framed and
   pinned like a photograph rather than sized like an icon. Square on purpose —
   the delivered art is 1254x1254 with its subject centred, so any wider ratio
   would crop the subject out. Each plate is tilted and dropped a different
   amount so three of them in a row read as pinned prints, not a card grid. */
.kind-figure {
    width: 100%;
    margin-bottom: var(--space-lg);
    padding: 0.5rem;
    aspect-ratio: 1;
    background: #fffdf6;
    border: 1px solid #9aa093;
    border-radius: 2px;
    box-shadow: 12px 14px 0 var(--cast), 0 12px 30px rgba(11, 22, 32, 0.24);
}

.kind-track article:nth-child(1) .kind-figure {
    transform: rotate(-0.9deg);
}

.kind-track article:nth-child(2) .kind-figure {
    margin-top: 1.6rem;
    transform: rotate(0.7deg);
}

.kind-track article:nth-child(3) .kind-figure {
    margin-top: 0.7rem;
    transform: rotate(-0.5deg);
}

.kind-track h3,
.kind-track p,
.kind-figure {
    position: relative;
    z-index: 1;
}

.kind-track p {
    max-width: 36ch;
    font-size: 1rem;
}

.kind-mark {
    display: block;
    margin-bottom: var(--space-sm);
    color: var(--stone);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
}

/* ===========================================================================
   HOMEPAGE — SECTION 07: the route
   Shape: the one conventional shape on the page — four round plates on a
   horizontal rule. Used deliberately: clarity beats novelty when explaining
   how a sale actually proceeds.
   ======================================================================== */
.home-route {
    padding-block: var(--canvas-rhythm);
    background: var(--paper-deep);
    border-block: 1px solid var(--line);
}

.route-heading {
    margin-bottom: clamp(2.4rem, 5vw, 3.6rem);
}

.route-track {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(1.2rem, 2.6vw, 2.4rem);
}

.route-track::before {
    position: absolute;
    top: 1.5rem;
    right: 1.6rem;
    left: 1.6rem;
    border-top: 2px solid rgba(30, 51, 66, 0.26);
    content: "";
}

.route-step {
    position: relative;
    z-index: 1;
}

.route-mark {
    display: grid;
    width: 3rem;
    height: 3rem;
    align-items: center;
    justify-items: center;
    margin-bottom: var(--space-md);
    background: var(--canvas);
    color: var(--sheet);
    border-radius: 999px;
    font-size: 0.8rem;
}

.route-step h3 {
    max-width: 17ch;
    font-size: 1.16rem;
}

.route-step p {
    max-width: 34ch;
    margin-bottom: 0;
    font-size: 0.98rem;
}

/* ===========================================================================
   HOMEPAGE — SECTION 08: the invite
   Shape: one tilted cream note on a graph-paper canvas, notched at the
   corners to bookend the hero. Lowest copy density on the page.
   ======================================================================== */
.invite-note {
    display: grid;
    grid-template-columns: 5.5rem minmax(0, 1fr);
    gap: clamp(1.2rem, 3vw, 2.6rem) clamp(1.4rem, 3vw, 2.8rem);
    align-items: start;
    padding: clamp(1.8rem, 4vw, 3.4rem);
    transform: rotate(-0.4deg);
}

.invite-mark {
    margin: 0;
    color: var(--mark);
    font-family: var(--font-display);
    font-size: 4.4rem;
    font-weight: 800;
    line-height: 0.8;
}

/* ARTWORK SLOT: once `invite-mark` art lands the glyph is replaced by a mark
   of the same footprint, so the card's grid does not move. No frame here —
   the delivered mark carries transparency and is meant to sit on the sheet. */
.invite-mark.slot {
    width: 5.5rem;
    aspect-ratio: 1;
    border-radius: 2px;
}

.invite-mark .slot-art {
    object-fit: contain;
}

.invite-note h2 {
    max-width: 18ch;
}

.invite-note p {
    max-width: 56ch;
}

.invite-note .cta-buttons {
    grid-column: 2;
}

/* ===========================================================================
   5. INNER-PAGE MASTHEADS
   Every inner page opens on the same navy canvas so the family register is
   established before a word is read. `.page-hero-grid` stays layout-only, so
   it can be reused mid-page on a cream section without dragging the canvas
   colours with it.
   ======================================================================== */
.page-hero,
.pricing-hero,
.about-hero,
.error-hero {
    position: relative;
    z-index: 0;
    padding-block: clamp(3.4rem, 7vw, 6rem);
    overflow: hidden;
    background-color: var(--canvas);
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.042) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.042) 1px, transparent 1px);
    background-size: 46px 46px;
    color: var(--sheet-bright);
    isolation: isolate;
    --notch-ink: var(--mark-canvas);
}

.page-hero::before,
.pricing-hero::before,
.about-hero::before,
.error-hero::before {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 10px;
    background: var(--mark);
    content: "";
}

/* ARTWORK SLOT holder: a decorative band pinned to the top-right corner of
   every inner-page masthead. Sits behind the copy, is `aria-hidden`, and fades
   out toward the text so a landed illustration can never reduce contrast.
   Until the art arrives the .slot placeholder paints a plain bay-door field.

   BAND, NOT COLUMN (T-021). The holder is as tall as the masthead, which is
   right for the empty placeholder but wrong for the art: the delivered
   illustration is 1440x480 (3:1, registered in artwork-slots.md), and
   stretching it to fill a 512x605 box on pricing or a 512x1491 one on
   features — that page keeps a tall proof plate inside the hero — made
   `object-fit: cover` blow it up 1.3x to 3.1x and keep a vertical sliver of
   the middle. The bay doors and dock it is composed around fell outside the
   crop, and what survived was upscaled past its own detail. So the ART sizes
   itself to its own ratio at the top of the holder (see `.slot-art` below)
   while the holder keeps its full height for the placeholder. */
.masthead-band {
    position: absolute;
    z-index: -1;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(78%, 620px);
    opacity: 0.42;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 55%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 55%);
    pointer-events: none;
}

/* `height: auto` overrides the slot default (`height: 100%`), so the band art
   renders at its own ratio, uncropped and never upscaled, pinned to the top
   of the holder. The holder carries the horizontal fade and the image carries
   the vertical one: one single-axis mask each, so the two never have to be
   composited, and the picture dissolves into the canvas instead of ending on
   a ruled line partway down the masthead. */
.masthead-band .slot-art {
    height: auto;
    -webkit-mask-image: linear-gradient(180deg, #000 58%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 58%, transparent 100%);
}

.page-hero .hero-kicker::before,
.pricing-hero .hero-kicker::before,
.about-hero .hero-kicker::before {
    background: var(--mark-canvas);
}

.hero .tagline,
.page-hero .tagline,
.hero-lede {
    max-width: 56ch;
    font-size: clamp(1.14rem, 2.2vw, 1.48rem);
    font-weight: 500;
    line-height: 1.42;
}

.page-hero-grid {
    display: grid;
    grid-template-columns: minmax(11rem, 0.3fr) minmax(0, 0.7fr);
    gap: clamp(1.6rem, 6vw, 6rem);
    align-items: end;
}

/* NAMING CONSTRAINT: `includes/header.php` puts `page-<slug>` on <body>, so
   any class literally named `page-<something>` risks matching the body
   element itself and inheriting to the whole document. This label used to be
   `.page-index` and did exactly that on /index.php, turning every page into
   uppercase mono. `.page-500` is the one deliberate body hook. Do not
   introduce new `page-*` component classes. */
.record-index,
.register-index {
    color: var(--label-ink, var(--olive));
}

.record-index {
    align-self: stretch;
    padding-top: 0.45rem;
    border-top: 2px solid var(--label-ink, var(--olive));
    font-size: 0.74rem;
    letter-spacing: 0.09em;
}

.page-hero .record-index {
    border-top-color: var(--mark-canvas);
}

/* Ordinary light section rhythm (inner pages). */
.section,
.working-section {
    position: relative;
    padding-block: var(--space-2xl);
    background: var(--paper);
}

.section-alt {
    background: var(--paper-deep);
    border-block: 1px solid var(--line);
}

.section-title {
    max-width: 18ch;
}

.section-subtitle {
    max-width: 62ch;
    margin-bottom: var(--space-xl);
    color: var(--olive);
    font-size: 1.18rem;
}

/* The closing band is a canvas: every page ends on navy carrying one paper
   object, which is what makes the site feel bound rather than stacked. */
.closing-band {
    position: relative;
    z-index: 0;
    padding-block: var(--canvas-rhythm);
    overflow: hidden;
    background-color: var(--canvas);
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.042) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.042) 1px, transparent 1px);
    background-size: 46px 46px;
    color: var(--sheet-bright);
    isolation: isolate;
    --notch-ink: var(--mark-canvas);
}

.closing-band .container {
    display: grid;
    grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
    gap: clamp(1.6rem, 5vw, 4.5rem);
    align-items: start;
}

.closing-band h2,
.closing-band h3 {
    max-width: 17ch;
}

.working-split,
.grid-2 {
    display: grid;
    grid-template-columns: minmax(14rem, 0.36fr) minmax(0, 0.64fr);
    gap: clamp(2rem, 6vw, 5.5rem);
    align-items: start;
}

.section-rail {
    position: sticky;
    top: 128px;
    padding-top: 0.7rem;
    padding-left: var(--space-md);
    border-top: 2px solid var(--canvas);
    border-left: 5px solid var(--canvas);
}

.section-rail h2 {
    max-width: 15ch;
}

.section-rail p {
    max-width: 34ch;
}

.section-rail p:last-child {
    margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
   The manifest index: what a symmetric feature-card grid becomes here.
   `.grid-3` is NOT a grid — it is a numbered single-column ledger whose row
   marks cycle the fixed status trio as a purely decorative rhythm. The number
   comes from a CSS counter so any page can drop rows in without hand-keeping
   a parallel list of numerals.
   ------------------------------------------------------------------------ */
.grid-3 {
    display: block;
    border-top: 2px solid var(--canvas);
    counter-reset: manifest;
}

.grid-3 > .card,
.route-row {
    position: relative;
    display: block;
    margin: 0;
    padding: var(--space-lg) 0 var(--space-lg) 4.9rem;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    counter-increment: manifest;
}

.grid-3 > .card::before,
.route-row::before {
    position: absolute;
    top: var(--space-lg);
    left: 0;
    display: grid;
    width: 3.3rem;
    height: 3.3rem;
    align-items: center;
    justify-items: center;
    background: var(--status-paid);
    color: var(--status-ink);
    border-radius: 3px;
    content: counter(manifest, decimal-leading-zero);
    font-family: var(--font-mono);
    font-size: 0.86rem;
}

.grid-3 > .card:nth-child(3n + 2)::before,
.route-row:nth-child(3n + 2)::before {
    background: var(--status-due);
}

.grid-3 > .card:nth-child(3n)::before,
.route-row:nth-child(3n)::before {
    background: var(--status-open);
}

.route-list {
    border-top: 2px solid var(--canvas);
    counter-reset: manifest;
}

.grid-3 > .card h3,
.route-row h3 {
    max-width: 30ch;
    margin-bottom: 0.3rem;
}

.grid-3 > .card p,
.route-row p {
    margin-bottom: 0;
}

.canvas .grid-3,
.canvas .route-list {
    border-top-color: var(--mark-canvas);
}

.canvas .grid-3 > .card,
.canvas .route-row {
    border-bottom-color: rgba(244, 234, 215, 0.18);
}

/* Plain paper notes and standalone cards keep the property-sheet language:
   1px border, restrained shadow, a ruled left edge. No glassmorphism, no
   gradient blobs, no soft floating card grid. */
.card,
.paper-note,
.contact-info,
.faq-item {
    padding: clamp(1.25rem, 3vw, 2.2rem);
    border: 1px solid var(--line);
    border-left: 6px solid var(--canvas);
    border-radius: 2px;
    background: var(--paper-soft);
    box-shadow: none;
}

.card + .card,
.faq-item + .faq-item {
    margin-top: var(--space-md);
}

.card ul,
.paper-note ul {
    padding-left: 1.2rem;
}

.card li + li,
.paper-note li + li {
    margin-top: 0.65rem;
}

.process-steps {
    border-top: 2px solid var(--canvas);
}

.process-step {
    display: grid;
    grid-template-columns: 5rem minmax(0, 1fr);
    gap: var(--space-lg);
    padding-block: var(--space-lg);
    border-bottom: 1px solid var(--line);
}

.process-number {
    color: var(--mark);
    font-family: var(--font-mono);
    font-size: 1.8rem;
}

.process-content h3 {
    margin-bottom: var(--space-xs);
}

/* Every product capture on the site is a register plate: a real screenshot
   framed as a mounted card, with a mono reference line underneath. Real
   software pictures are the trust device; framing them as objects is what
   keeps them from reading as stock hero art. */
.proof-figure {
    margin: 0;
    padding: 0.62rem;
    background: #fffdf6;
    border: 1px solid #9aa093;
    border-radius: 2px;
    box-shadow: 13px 15px 0 var(--cast-paper), 0 12px 30px rgba(30, 51, 66, 0.1);
    transform: rotate(-0.5deg);
}

.section-alt .proof-figure,
.canvas .proof-figure,
.page-hero .proof-figure,
.pricing-hero .proof-figure,
.about-hero .proof-figure {
    box-shadow: 13px 15px 0 var(--cast), 0 12px 30px rgba(11, 22, 32, 0.2);
}

/* A plate always keeps paper ink, whatever it is standing on. */
.proof-figure figcaption,
.canvas .proof-figure figcaption,
.page-hero .proof-figure figcaption {
    color: #5a6158;
}

.proof-figure img {
    width: 100%;
}

/* ---------------------------------------------------------------------------
   PLATE WINDOW — framing a raw capture as a deliberate photograph.

   Two of the raw Anytown captures in `assets/source/` were taken mid-scroll:
   they carry a browser scrollbar down the right edge and begin and end part
   way through a panel. Shown whole, the plate reads as an accidentally-sized
   scroll box rather than a picture of the software.

   `assets/` belongs to another bench, so the capture cannot be re-cropped.
   This window crops in CSS instead: give it a rect in SOURCE PIXELS and it
   shows exactly that region, fluidly, at any container width.

     --sw  source image width          --cx --cy  crop origin
     --cw --ch  crop size

   The percentage maths: `left` and `width` resolve against the window's
   width, `top` against its height — and because the window's aspect-ratio is
   --cw/--ch, `top: -100% * cy/ch` lands the same scaled offset as
   `left: -100% * cx/cw`. That is what keeps the crop exact at every width
   without a single media query.

   Rects are derived by measuring the source file, and each one is chosen so
   the visible region starts and ends on a whole element and excludes the
   baked-in scrollbar. Re-derive if the capture is ever replaced.
   ------------------------------------------------------------------------ */
.plate-window {
    position: relative;
    overflow: hidden;
    aspect-ratio: var(--cw) / var(--ch);
}

.plate-window img {
    position: absolute;
    top: calc(-100% * var(--cy) / var(--ch));
    left: calc(-100% * var(--cx) / var(--cw));
    width: calc(100% * var(--sw) / var(--cw));
    max-width: none;
    height: auto;
}

/* Anytown overview: whole app from its title bar down. Only the scrollbar
   column is trimmed; the top of the window is the natural framing. */
.plate-window--overview {
    --sw: 1265;
    --cx: 0;
    --cy: 0;
    --cw: 1240;
    --ch: 700;
}

/* Anytown building: the complete "Building A - 18 numbered units" panel,
   heading through footer ruler. Excludes the sliced panels above and below
   and the scrollbar. */
.plate-window--building {
    --sw: 1265;
    --cx: 60;
    --cy: 100;
    --cw: 1120;
    --ch: 500;
}

/* Anytown harbor: the complete "Harbor Dock - 8 boat slips" panel. */
.plate-window--harbor {
    --sw: 1265;
    --cx: 60;
    --cy: 105;
    --cw: 1120;
    --ch: 555;
}

.proof-figure figcaption,
.proof-caption {
    margin-top: 0.6rem;
    color: #5a6158;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

/* ===========================================================================
   6. FEATURES PAGE — the feature record
   ======================================================================== */
.feature-hero-proof {
    margin-top: var(--space-xl);
    margin-left: clamp(0rem, 13vw, 10rem);
    transform: rotate(0.9deg);
}

.feature-sequence {
    border-top: 2px solid var(--canvas);
    counter-reset: chapter;
}

.feature-chapter {
    display: grid;
    grid-template-columns: 7.5rem minmax(14rem, 0.4fr) minmax(0, 0.6fr);
    gap: clamp(1.3rem, 4vw, 3.2rem);
    padding-block: var(--space-2xl);
    border-bottom: 1px solid var(--line);
}

.chapter-index {
    color: var(--mark);
    font-size: 0.8rem;
    letter-spacing: 0.09em;
}

.feature-chapter:nth-child(even) .chapter-copy {
    order: 3;
}

.feature-chapter:nth-child(even) .proof-figure {
    order: 2;
    transform: rotate(0.7deg);
}

.feature-chapter .proof-figure {
    align-self: center;
}

.feature-chapter h2 {
    max-width: 18ch;
}

/* The limits list is a ruled ledger of exclusions, not a grid of boxes.
   Every row is marked with an en dash — the "deliberately left out" glyph. */
.honest-limits .grid-2 {
    display: block;
    border-top: 2px solid var(--canvas);
}

.honest-limits .faq-item {
    position: relative;
    margin: 0;
    padding: var(--space-lg) 0 var(--space-lg) 3rem;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    background: transparent;
}

.honest-limits .faq-item::before {
    position: absolute;
    top: var(--space-lg);
    left: 0;
    color: var(--mark);
    content: "\2013";
    font-family: var(--font-mono);
    font-size: 1.3rem;
}

.honest-limits .faq-item h3 {
    margin-bottom: 0.3rem;
}

.honest-limits .faq-item p {
    margin-bottom: 0;
}

/* ===========================================================================
   7. PRICING — the yard estimate
   One document, not three tiers. The price itself sits on a plate stamped
   DRAFT, because the number is genuinely provisional until the owner
   confirms it and the page must not pretend otherwise.
   ======================================================================== */
.pricing-hero-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.58fr) minmax(16rem, 0.42fr);
    gap: clamp(2rem, 6vw, 5.5rem);
    align-items: center;
}

.price-ticket {
    position: relative;
    padding: clamp(1.5rem, 3.4vw, 2.6rem);
    background: var(--sheet);
    color: var(--sheet-ink);
    border: 1px solid var(--sheet-edge);
    border-radius: 2px;
    box-shadow: 16px 20px 0 var(--cast), 0 14px 34px rgba(11, 22, 32, 0.28);
    transform: rotate(1deg);
}

/* PSEUDO-ELEMENT OWNERSHIP: `.plate-notch` owns ::before AND ::after on
   whatever carries it. The price ticket used to carry a "DRAFT" stamp written
   as `.price-ticket::after`, which meant the notch's 15px corner bracket and
   the stamp were the SAME box — the word was crushed into a 15px square with
   the letters spilling past the card edge. It looked like a rendering fault
   because it was one. Anything that needs a mark of its own on a notched
   object gets a REAL element, never a pseudo-element. Check this before
   adding ::before/::after to a .plate-notch element.

   That stamp element and the 2.6rem bottom margin that reserved room for it
   are gone with the pricing decision of 2026-08-06 (T-016): $60 is a stated
   price, so there is nothing left on the ticket to mark as provisional.
   `.price-ticket p:last-child` below now closes the card. */

.price-label {
    color: var(--paper-muted);
    font-size: 0.66rem;
    letter-spacing: 0.1em;
}

.price-amount {
    margin: 0.2rem 0;
    color: var(--canvas);
    font-family: var(--font-display);
    font-size: clamp(3.6rem, 8vw, 6.2rem);
    font-weight: 850;
    letter-spacing: -0.06em;
    line-height: 0.9;
}

.price-ticket p {
    max-width: 30ch;
    color: #3b4c56;
}

.price-ticket p:last-child {
    margin-bottom: 0;
    font-size: 0.95rem;
}

/* The cost register: a ruled document, not a comparison table. */
.pricing-register {
    width: 100%;
    border-collapse: collapse;
    background: transparent;
    border-top: 2px solid var(--canvas);
}

.pricing-register caption {
    padding: 0 0 var(--space-md);
    color: var(--olive);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.09em;
    text-align: left;
    text-transform: uppercase;
}

.pricing-register th,
.pricing-register td {
    padding: 1.15rem 1rem 1.15rem 0;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
}

.pricing-register th {
    width: 26%;
    color: var(--canvas);
    font-family: var(--font-display);
    font-size: 1.06rem;
    font-weight: 750;
    text-transform: none;
}

.pricing-register td:last-child {
    width: 24%;
    padding-right: 0;
    color: var(--mark);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.03em;
}

/* ===========================================================================
   8. FAQ — the field index
   Numbered index rows on a flat divider rule. Not a stack of identical
   rounded accordion cards.
   ======================================================================== */
.faq-register {
    margin: 0;
    padding: 0;
    background: transparent;
    border-top: 2px solid var(--canvas);
    counter-reset: faq;
    list-style: none;
}

.faq-register > li {
    display: grid;
    grid-template-columns: 4.4rem minmax(13rem, 0.36fr) minmax(0, 0.64fr);
    gap: clamp(1rem, 3vw, 2.6rem);
    max-width: none;
    padding-block: var(--space-lg);
    border-bottom: 1px solid var(--line);
    counter-increment: faq;
}

.faq-register > li::before {
    color: var(--mark);
    content: "Q" counter(faq, decimal-leading-zero);
    font-family: var(--font-mono);
    font-size: 0.86rem;
    letter-spacing: 0.06em;
}

.faq-register h2,
.faq-register h3 {
    max-width: 24ch;
    margin-bottom: 0;
    font-size: clamp(1.18rem, 2vw, 1.5rem);
}

.faq-register p {
    margin-bottom: 0;
}

/* The masthead's ghost count, bleeding off the corner of the index heading. */
.index-masthead {
    position: relative;
    overflow: hidden;
}

.index-masthead::after {
    position: absolute;
    z-index: 0;
    right: -0.1em;
    bottom: -0.34em;
    color: rgba(30, 51, 66, 0.07);
    content: attr(data-count);
    font-family: var(--font-display);
    font-size: clamp(5rem, 15vw, 12rem);
    font-weight: 850;
    line-height: 0.8;
    pointer-events: none;
}

.index-masthead > * {
    position: relative;
    z-index: 1;
}

/* On a navy masthead the ghost count inverts to a cream tint. */
.page-hero .index-masthead::after,
.canvas .index-masthead::after {
    color: rgba(251, 246, 234, 0.09);
}

/* The pricing register document is wider than a note, so its ruled margin
   sits further in and its rows keep the table's own padding. */
.yard-record--wide > * {
    padding-left: 1.5rem;
}

.yard-record--wide::before {
    left: 2.4rem;
}

.yard-record--wide .pricing-register th,
.yard-record--wide .pricing-register td {
    background: transparent;
}

/* ===========================================================================
   9. ABOUT / CONTACT / LEGAL / ERRORS
   ======================================================================== */
.about-hero-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.56fr) minmax(16rem, 0.44fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: end;
}

.owner-register {
    position: relative;
    padding: clamp(1.6rem, 3.4vw, 2.8rem);
    background: var(--sheet);
    color: var(--sheet-ink);
    border: 1px solid var(--sheet-edge);
    border-radius: 2px;
    box-shadow: 16px 20px 0 var(--cast), 0 14px 34px rgba(11, 22, 32, 0.28);
    transform: rotate(-0.8deg);
}

.owner-register p {
    margin: 0;
    color: var(--canvas);
    font-family: var(--font-display);
    font-size: clamp(2rem, 4.4vw, 3.4rem);
    font-weight: 850;
    letter-spacing: -0.04em;
    line-height: 1;
    text-transform: uppercase;
}

.owner-register span {
    display: block;
    margin-bottom: var(--space-md);
    color: var(--paper-muted);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.contact-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.62fr) minmax(15rem, 0.38fr);
    gap: clamp(2rem, 6vw, 5rem);
    align-items: start;
}

.contact-form-sheet {
    padding: clamp(1.4rem, 4vw, 3rem);
    background: var(--paper-soft);
    border: 1px solid var(--sheet-edge);
    border-top: 8px solid var(--mark);
    border-radius: 2px;
    box-shadow: 14px 17px 0 var(--cast-paper), 0 10px 26px rgba(30, 51, 66, 0.1);
}

.contact-rail {
    border-top: 2px solid var(--canvas);
}

.contact-rail .contact-info {
    margin: 0;
    padding: var(--space-lg) 0;
    border-width: 0 0 1px;
    background: transparent;
}

form {
    width: 100%;
}

.form-group {
    margin-bottom: var(--space-md);
}

label {
    display: block;
    margin-bottom: 0.4rem;
    color: var(--olive);
    font-family: var(--font-mono);
    font-size: 0.74rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

input,
textarea,
select {
    width: 100%;
    padding: 0.84rem 0.9rem;
    border: 1px solid var(--stone);
    border-bottom: 3px solid var(--ink);
    border-radius: 0;
    background: var(--white);
    color: var(--ink);
    font: inherit;
}

input:focus,
textarea:focus,
select:focus {
    border-bottom-color: var(--clay);
    outline: 2px solid transparent;
}

textarea {
    min-height: 10rem;
    resize: vertical;
}

.form-helper {
    color: var(--olive);
    font-size: 0.9rem;
}

.alert {
    margin-bottom: var(--space-lg);
    padding: var(--space-md) var(--space-lg);
    border-left: 8px solid var(--olive);
    background: var(--paper-soft);
}

.alert-error {
    border-left-color: var(--clay);
}

.legal-layout {
    display: grid;
    grid-template-columns: minmax(12rem, 0.28fr) minmax(0, 0.72fr);
    gap: clamp(2rem, 6vw, 5.5rem);
    align-items: start;
}

.document-meta {
    position: sticky;
    top: 130px;
    padding: var(--space-lg);
    background: var(--canvas);
    color: var(--sheet-bright);
    border-left: 8px solid var(--mark);
    border-radius: 2px;
    font-size: 0.74rem;
    letter-spacing: 0.06em;
}

.document-meta p,
.document-meta a {
    color: var(--sheet-bright);
}

.legal-copy {
    padding-left: clamp(1.2rem, 4vw, 3rem);
    border-left: 6px solid var(--canvas);
}

.legal-copy h1 {
    max-width: 20ch;
    margin-bottom: var(--space-xl);
}

.legal-copy h2 {
    max-width: 26ch;
    margin-top: var(--space-xl);
    padding-top: var(--space-md);
    border-top: 1px solid var(--line);
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    text-transform: none;
}

.error-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.44fr) minmax(15rem, 0.56fr);
    gap: clamp(1.6rem, 5vw, 4rem);
    align-items: center;
}

/* Scoped past `.error-hero p`, which would otherwise win on specificity and
   render this watermark at full brightness against the paper object. */
.error-hero .error-code {
    margin: 0;
    color: rgba(244, 234, 215, 0.17);
    font-family: var(--font-display);
    font-size: clamp(7rem, 22vw, 17rem);
    font-weight: 850;
    letter-spacing: -0.08em;
    line-height: 0.74;
}

/* The vacant bay: the error page's paper object. A cream sheet with an open
   rolled door drawn along its bottom edge. */
.vacant-bay {
    position: relative;
    padding: clamp(1.5rem, 4vw, 2.8rem);
    background: var(--sheet);
    color: var(--sheet-ink);
    border: 1px solid var(--sheet-edge);
    border-radius: 2px;
    box-shadow: 16px 20px 0 var(--cast), 0 14px 34px rgba(11, 22, 32, 0.28);
    transform: rotate(-0.5deg);
}

.vacant-bay h1 {
    max-width: 100%;
    color: var(--canvas);
    font-size: clamp(2.2rem, 4.6vw, 3.6rem);
    line-height: 0.98;
    overflow-wrap: anywhere;
}

.vacant-bay p {
    color: #3b4c56;
}

.vacant-bay .register-index {
    color: var(--paper-muted);
}

.vacant-bay::after {
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: 42%;
    height: 10px;
    background: var(--mark);
    content: "";
}

.page-500 .vacant-bay {
    border-style: dashed;
    border-width: 2px;
}

.error-route-list {
    margin: 0;
    padding: 0;
    border-top: 2px solid var(--canvas);
    list-style: none;
}

.error-route-list li {
    display: grid;
    grid-template-columns: 7rem minmax(0, 1fr);
    gap: var(--space-lg);
    max-width: none;
    padding: var(--space-lg) 0;
    border-bottom: 1px solid var(--line);
}

.error-route-list .mono {
    color: var(--mark);
    font-size: 0.74rem;
}

.error-route-list a {
    font-family: var(--font-display);
    font-size: 1.28rem;
    font-weight: 750;
}

/* ===========================================================================
   10. FOOTER
   Navy, to bookend the hero stage and close the page on the same canvas it
   opened on.
   ======================================================================== */
footer {
    position: relative;
    z-index: 0;
    padding: var(--space-2xl) 0 var(--space-lg);
    overflow: hidden;
    background-color: var(--canvas-deep);
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
    background-size: 46px 46px;
    color: rgba(251, 246, 234, 0.84);
    border-top: 10px solid var(--mark);
}

.footer-mast {
    display: grid;
    grid-template-columns: minmax(14rem, 0.38fr) minmax(0, 0.62fr);
    gap: var(--space-lg) var(--space-xl);
    align-items: end;
    margin-bottom: var(--space-xl);
}

.footer-mast .register-index {
    color: var(--stone);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
}

.footer-name {
    margin: 0;
    color: var(--sheet-bright);
    font-family: var(--font-display);
    font-size: clamp(2.4rem, 6vw, 5rem);
    font-weight: 850;
    letter-spacing: -0.05em;
    line-height: 0.88;
}

.footer-tagline {
    grid-column: 2;
    max-width: 42ch;
    color: rgba(251, 246, 234, 0.8);
    font-size: 1.1rem;
}

.footer-register {
    border-top: 2px solid var(--mark-canvas);
}

.footer-register-row {
    display: grid;
    grid-template-columns: minmax(9rem, 0.24fr) minmax(0, 0.5fr) minmax(7rem, 0.26fr);
    gap: var(--space-md) var(--space-lg);
    padding-block: var(--space-md);
    border-bottom: 1px solid rgba(244, 234, 215, 0.16);
}

.footer-register-row p,
.footer-register-row ul {
    max-width: 46ch;
    margin-bottom: 0;
}

.footer-register-row ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.4rem;
    padding: 0;
    list-style: none;
}

footer a {
    color: var(--stone);
}

footer a:hover,
footer a:focus-visible {
    color: var(--sheet-bright);
}

.footer-heading {
    color: rgba(251, 246, 234, 0.7);
    font-family: var(--font-mono);
    font-size: 0.74rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.footer-heading span {
    margin-right: 0.8rem;
    color: var(--mark-canvas);
}

.footer-social {
    display: flex;
    gap: 0.65rem;
}

.social-link {
    display: inline-flex;
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(244, 234, 215, 0.45);
}

.social-icon {
    width: 17px;
    height: 17px;
    filter: invert(1) sepia(0.2) saturate(0.4) brightness(1.15);
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-sm) var(--space-lg);
    padding-top: var(--space-lg);
    color: rgba(251, 246, 234, 0.66);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.footer-bottom p {
    margin: 0;
}

.back-to-top {
    position: fixed;
    z-index: 900;
    right: 1.2rem;
    bottom: 1.2rem;
    width: 46px;
    height: 46px;
    border: 2px solid var(--ink);
    border-radius: 0;
    background: var(--paper);
    color: var(--ink);
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transform: translateY(12px);
    transition: opacity 160ms ease, transform 160ms ease;
}

.back-to-top.visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

/* ===========================================================================
   11. RESPONSIVE
   Two governing tiers. 1080px takes the yard stage out of absolute
   positioning; 900px collapses every narrative grid straight to one column
   and strips every rotation. Below that, 620px steps type down and 400px
   handles the narrowest phones.

   The rule that matters: rotation is only ever applied to objects scattered
   across an open canvas. Stacked in a single column, a tilted card reads as
   a bug, so the tilt goes rather than shrinking the object in place.
   ======================================================================== */
@media (max-width: 1080px) {
    .yard-stage {
        display: flex;
        min-height: 0;
        flex-direction: column;
        gap: var(--space-lg);
        padding: 4.6rem clamp(1.25rem, 3vw, 2.2rem) clamp(2rem, 4vw, 3rem);
    }

    /* ART DIRECTION (T-021). Stacked, the stage is a tall column, and a
       full-bleed backdrop asked `object-fit: cover` to fit a 3:2 landscape
       photograph into a 373x1130 box at 375px. What survived was a vertical
       sliver — a fence post, a slice of corrugated wall, gravel — and a
       reader could no longer tell it was a storage property, which is the
       entire job of that picture. Distorting or zooming it would trade one
       defect for a worse one, so the composition changes instead: below this
       breakpoint the photo stops being a backdrop and becomes a landscape
       plate at the head of the column, at its own ratio. The building of bay
       doors, the trailer and the covered bay are all in frame, at 1:1 pixels
       or smaller. The stage falls back to the flat navy canvas every other
       deep section already uses. */
    .yard-art {
        position: relative;
        z-index: 0;
        inset: auto;
        width: min(100%, 720px);
        margin-inline: auto;
    }

    /* The registered ratio for this slot, so the empty placeholder is a band
       too; the landed art is 1536x1024 and fills it exactly. */
    .yard-art .slot {
        height: auto;
        aspect-ratio: 3 / 2;
    }

    .yard-art .slot-art {
        height: auto;
    }

    /* The wash exists to keep pale text legible over the backdrop. With the
       photo out from behind the copy it has nothing left to protect, and over
       flat navy it would only smear a gradient across the stage. */
    .yard-stage::before {
        display: none;
    }

    .manifest-sheet,
    .register-plate--stage,
    .yard-key {
        position: relative;
        inset: auto;
        width: min(100%, 720px);
        margin-inline: auto;
        transform: none;
    }

    .unit-tags {
        position: relative;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 0.6rem 0.9rem;
        inset: auto;
    }

    .unit-tag {
        position: static;
    }

    .yard-key {
        justify-content: center;
    }

    .yard-stamp--stage {
        top: 1.3rem;
        left: 1.3rem;
    }
}

@media (max-width: 900px) {
    :root {
        --space-2xl: 4.5rem;
        --space-3xl: 6rem;
        --canvas-rhythm: clamp(3.4rem, 8vw, 5rem);
    }

    header > .container {
        min-height: 78px;
    }

    /* Below the nav breakpoint the bar is logo + hamburger and nothing else,
       so the logo asks for its cap and lets flex shrink it to exactly the
       space the toggle and the gap leave over. The layout does that
       arithmetic at every width — including 320 — instead of a table of
       hand-tuned sizes per phone. The cap keeps a tablet-width bar from
       turning a 4.77:1 lockup into a 140px-tall header. */
    .logo {
        width: min(340px, 100%);
    }

    .header-controls {
        display: block;
    }

    .mobile-nav-toggle {
        display: block;
    }

    header nav {
        position: absolute;
        top: 100%;
        right: 0;
        left: 0;
        display: none;
        padding: 0.75rem 1.25rem 1.25rem;
        background: var(--paper);
        border-bottom: 5px solid var(--canvas);
        box-shadow: var(--shadow);
    }

    header nav.active {
        display: block;
    }

    header nav ul {
        display: block;
    }

    header nav a {
        padding: 0.9rem 0;
        border-bottom: 1px solid var(--line);
    }

    /* Narrative grids go straight to one column — no intermediate 2-up state
       that would turn three different shapes into the same pair of boxes. */
    .working-split,
    .grid-2,
    .page-hero-grid,
    .pricing-hero-layout,
    .about-hero-layout,
    .contact-layout,
    .legal-layout,
    .error-layout,
    .footer-mast,
    .ledger-layout,
    .money-layout,
    .package-heading,
    .package-panels,
    .closing-band .container,
    .walk-route,
    .kind-track,
    .route-track {
        /* minmax(0, 1fr), not 1fr: a bare `1fr` track is minmax(auto, 1fr),
           so one wide child (a long address, an input's intrinsic width) can
           push the track past the container and hang a few pixels off the
           right edge. This is the fix for that class of bug sitewide. */
        grid-template-columns: minmax(0, 1fr);
    }

    .route-track {
        gap: 0;
    }

    /* Every paper object stops tilting once it is stacked. */
    .ledger-sheet,
    .invite-note,
    .price-ticket,
    .owner-register,
    .vacant-bay,
    .proof-figure,
    .feature-hero-proof,
    .feature-chapter:nth-child(even) .proof-figure,
    .register-plate--money,
    .package-panel .register-plate,
    .kind-track article:nth-child(1) .kind-figure,
    .kind-track article:nth-child(2) .kind-figure,
    .kind-track article:nth-child(3) .kind-figure {
        transform: none;
    }

    .kind-track article:nth-child(2) .kind-figure,
    .kind-track article:nth-child(3) .kind-figure {
        margin-top: 0;
    }

    .kind-figure {
        width: min(100%, 17rem);
    }

    /* Route geometry is redrawn, not scaled: the diagonal becomes a vertical
       left rail, and the same move is applied to the kind track and the
       route track so mobile reads as one system rather than three unrelated
       components crammed into a column. */
    .walk-route::before {
        top: 1.5rem;
        right: auto;
        bottom: 1.5rem;
        left: 0.62rem;
        border-top: 0;
        border-left: 3px dashed rgba(30, 51, 66, 0.32);
        transform: none;
    }

    .walk-stop {
        padding-top: 0;
        padding-left: 2.8rem;
    }

    .walk-stop:nth-child(2),
    .walk-stop:nth-child(3) {
        margin-top: 0;
    }

    .walk-stop::before {
        top: 0.35rem;
    }

    .kind-track {
        border-top: 0;
        border-left: 2px dashed var(--track-rule, rgba(30, 51, 66, 0.28));
    }

    .kind-track article {
        padding-top: 0;
        padding-left: 2rem;
    }

    .kind-track article::before {
        top: 0.6rem;
        left: -0.62rem;
    }

    .route-track::before {
        top: 1.5rem;
        right: auto;
        bottom: 1.5rem;
        left: 1.5rem;
        border-top: 0;
        border-left: 2px solid rgba(30, 51, 66, 0.26);
    }

    /* Three children in a two-column grid put the paragraph back in column 1
       — a 3rem-wide column, which rendered the body copy one word per line.
       Pin the text to column 2 so the badge keeps its own lane. */
    .route-step {
        display: grid;
        grid-template-columns: 3rem minmax(0, 1fr);
        gap: 0 var(--space-md);
        padding-block: var(--space-md);
    }

    .route-step h3,
    .route-step p {
        grid-column: 2;
    }

    .route-step h3 {
        margin-bottom: 0.3rem;
    }

    .route-mark {
        margin-bottom: 0;
    }

    .invite-note {
        grid-template-columns: 1fr;
    }

    .invite-note .cta-buttons {
        grid-column: 1;
    }

    .invite-mark {
        font-size: 3rem;
    }

    .package-panel--public {
        justify-content: flex-start;
    }

    .package-panel-inner {
        width: 100%;
        max-width: none;
    }

    .section-rail,
    .document-meta {
        position: static;
    }

    .feature-chapter {
        grid-template-columns: 4rem minmax(0, 1fr);
    }

    .feature-chapter .chapter-copy,
    .feature-chapter:nth-child(even) .chapter-copy {
        grid-column: 2;
        order: initial;
    }

    .feature-chapter .proof-figure,
    .feature-chapter:nth-child(even) .proof-figure {
        grid-column: 1 / -1;
        order: initial;
    }

    .feature-hero-proof {
        margin-left: 0;
    }

    .error-code {
        font-size: clamp(5rem, 20vw, 9rem);
    }

    .footer-tagline {
        grid-column: 1;
    }

    .footer-register-row {
        grid-template-columns: minmax(8rem, 0.3fr) minmax(0, 0.7fr);
    }

    .footer-register-row > :nth-child(3) {
        grid-column: 2;
    }
}

@media (max-width: 620px) {
    body {
        font-size: 1rem;
    }

    .container,
    .container--wide {
        width: min(100% - 2rem, var(--max));
    }

    .section,
    .working-section,
    .page-hero,
    .pricing-hero,
    .about-hero,
    .error-hero {
        padding-block: 3rem;
    }

    h1,
    h2,
    h3,
    .hero-title,
    .footer-name,
    .price-amount,
    .owner-register p {
        overflow-wrap: anywhere;
    }

    h1,
    .hero-title {
        font-size: clamp(2.05rem, 11vw, 3.4rem);
    }

    .manifest-sheet h1 {
        font-size: clamp(2rem, 10vw, 2.8rem);
    }

    .yard-stage {
        padding-top: 4rem;
    }

    .manifest-sheet,
    .yard-record,
    .invite-note,
    .price-ticket,
    .owner-register,
    .vacant-bay {
        box-shadow: 8px 10px 0 var(--cast), 0 8px 20px rgba(11, 22, 32, 0.22);
    }

    .proof-figure,
    .register-plate {
        box-shadow: 7px 8px 0 var(--cast-paper), 0 8px 18px rgba(30, 51, 66, 0.1);
    }

    .yard-record > * {
        padding-left: 1.4rem;
    }

    .yard-record::before {
        left: 1.9rem;
    }

    .grid-3 > .card,
    .route-row {
        padding-left: 3.6rem;
    }

    .grid-3 > .card::before,
    .route-row::before {
        width: 2.6rem;
        height: 2.6rem;
        font-size: 0.74rem;
    }

    .decision-register li {
        padding-left: 3.1rem;
    }

    .decision-register li::before {
        width: 2.2rem;
        height: 2.2rem;
    }

    .process-step,
    .error-route-list li {
        grid-template-columns: 1fr;
        gap: var(--space-sm);
    }

    .feature-chapter {
        grid-template-columns: 1fr;
        gap: var(--space-md);
        padding-block: var(--space-xl);
    }

    .feature-chapter .chapter-copy,
    .feature-chapter:nth-child(even) .chapter-copy,
    .feature-chapter .proof-figure,
    .feature-chapter:nth-child(even) .proof-figure {
        grid-column: 1;
    }

    .faq-register > li {
        grid-template-columns: 3.2rem minmax(0, 1fr);
        gap: var(--space-sm) var(--space-md);
    }

    .faq-register p {
        grid-column: 2;
    }

    .pricing-register,
    .pricing-register tbody,
    .pricing-register tr,
    .pricing-register th,
    .pricing-register td {
        display: block;
        width: 100%;
    }

    .pricing-register tr {
        padding-block: var(--space-md);
        border-bottom: 1px solid var(--line);
    }

    .pricing-register th,
    .pricing-register td {
        padding: 0.3rem 0;
        border: 0;
    }

    .footer-register-row,
    .footer-register-row > :nth-child(3) {
        grid-template-columns: 1fr;
        grid-column: 1;
    }

    .footer-bottom {
        display: block;
    }

    .footer-bottom p + p {
        margin-top: 0.65rem;
    }

    .cta-buttons .btn {
        width: 100%;
        max-width: 100%;
        white-space: normal;
    }
}

@media (max-width: 400px) {
    /* Tighter than --space-lg so the lockup gets the width back, but still a
       real gap: the logo and the toggle must not read as one control. */
    header > .container {
        gap: 0.75rem;
    }

    .mobile-nav-toggle {
        width: 42px;
        height: 42px;
    }

    .invite-mark {
        display: none;
    }

    .trust-rail {
        justify-content: flex-start;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }
}

@media print {
    header,
    footer,
    .breadcrumbs,
    .back-to-top,
    .cta-buttons {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
        font-size: 11pt;
    }

    .canvas,
    .page-hero,
    .pricing-hero,
    .about-hero,
    .error-hero,
    .closing-band {
        background: #fff !important;
        color: #000 !important;
    }

    .section,
    .working-section,
    .hero,
    .page-hero {
        padding-block: 1rem;
    }
}
