/* Postmello — marketing + legal site.
 *
 * One palette across all three surfaces (this site, the letter page, the
 * letter email): warm paper, mailbox red, bee honey. The old site ran a
 * saturated sky-blue gradient with white text and heavy drop shadows, which
 * fought the logo and dated the page; the logo is the only saturated thing
 * here now, and everything else gets out of its way.
 */

:root {
  /* ---- Ink ----
     Four steps, and the rule that governs them: **use whitespace to make this
     page quiet, never faint text.** Secondary copy used to sit at --ink-soft
     on a warm ground and looked elegant at reading distance while being hard
     to skim on a laptop, which is how a pricing section ended up invisible.
     Everything a visitor needs to understand is now --ink or --ink-soft;
     --ink-faint is for material nobody has to read. */
  --ink: #29211b;        /* headlines and anything primary */
  /* The mark sits a hair warmer and lighter than the headline ink. At Rubik 600
     across eight uppercase letters the wordmark carries more mass than any
     heading on the page, and at full --ink it read as the heaviest thing in the
     header rather than as a logo the page is printed under. */
  --ink-mark: #2c231d;   /* the wordmark, and only the wordmark */
  --ink-mid: #453b32;    /* ledes and the hero sentence — one step off black */
  --ink-soft: #62564c;   /* normal body, notes, nav links */
  --ink-faint: #918478;  /* TERTIARY ONLY: copyright, dates, separators */

  /* ---- Paper ----
     Three surfaces for the whole site, not a colour per section: the canvas,
     a barely-different second sheet, and one warm card. The accent colour IS
     the paper — the desks, stamps, stickers and bee bring every other colour
     on the page, and a standard web accent would only compete with them. */
  --paper: #faf7f2;      /* writing paper: the canvas */
  --paper-alt: #f7f2ea;  /* a second sheet — a tonal hair, not a band */
  /* Manila — the kraft-envelope material, and the one place the page's paper
     gets real chroma. The old #f1e8de darkened the ground without warming it
     (chroma ~7%), and darker-without-warmer is the recipe for grey; Patrick
     called it twice, 2026-08-16. Deeper (#eee0c4) read as a highlighted
     callout, paler (#f3e7d0) stayed timid. Soft ink on this passes AA. */
  --paper-card: #f4e8cc; /* manila card stock: the one emphasised block */
  --card: #fdfbf8;       /* very light card: secondary information blocks */
  --line: #ddd4ca;
  --line-card: #ddd4ca;
  --navy: #2f4358;   /* link-hover underlines + focus rings (was --red #c8402f, retired 2026-08-18: red read as alarm/error on a quiet paper page) */
  --honey: #e9a227;
  --sky: #8fc3ee;

  /* Every surface carries the same seamless grain tile at 128px (the PNG is
     256px, so it lands 1:1 on a 2x screen). ~3.5% mean alpha: enough that the
     page reads as paper on a second look, not enough to touch legibility. */
  --grain: url("assets/paper-grain.png");
  --grain-size: 128px;

  /* ---- Faces ----
     THREE roles, and the rule is one line: **Rubik is the mark, Nunito is the
     voice, DM Mono is the apparatus.**

     --font-mark is Rubik Bold, and it is reserved for the wordmark — the header
     and the footer sign-off, nowhere else. That reservation is the whole point:
     a face used in one place reads as a logo, and the same face sprinkled over
     headings reads as a font choice. In sentences the product is always
     "Postmello"; only the mark is set POSTMELLO.

     --font-voice is Nunito and carries everything anyone reads as a sentence,
     from the hero down to the legal pages. It has the warmth of the app's own
     rounded lettering without tipping into a children's-book face, and unlike
     the old ui-rounded stack it is the SAME face for every visitor — the site
     used to render in SF Pro Rounded on Apple hardware and Segoe UI everywhere
     else, which is two different brands.

     --font-apparatus is DM Mono, for the postal furniture — eyebrows, plan
     names, the badge, the footer group labels. In THIS subject a monospace
     reads as franking and address labels rather than as code. Never set a
     paragraph in it. DM Mono ships 300/400/500 only, so apparatus text is
     weight 500 and never 600: asking for 600 gets a synthesised bold.

     These now come from Google Fonts (Patrick, 2026-08-15), so the site takes
     an external stylesheet where it previously took none. Every stack keeps its
     old system fallback, in that order, so a blocked or slow CDN degrades to
     what the site looked like yesterday rather than to Times New Roman. */
  --font-mark: "Rubik", ui-rounded, "SF Pro Rounded", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-voice: "Nunito", ui-rounded, "SF Pro Rounded", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-apparatus: "DM Mono", ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  /* ---- Scales ----
     Until now this file had a palette and two lengths; every section then
     hard-coded its own margin and its own clamp(), which is why anything new
     bolted on looked bolted on. These are the three scales the page is built
     from, and nothing outside them should appear below. */

  /* Type. Ratio ~1.25, clamped so the top of the scale only arrives when
     there is width for it. Both ends are pinned deliberately: the low end is
     the phone reading size and the high end is the desktop one, so a clamp
     that only sets a maximum ends up phone-sized on a phone by accident.

     Rebuilt for Nunito (2026-08-15) and a step heavier and larger throughout.
     Nunito's x-height runs smaller than SF Pro Rounded's, so the old scale read
     a size down once the face changed; body copy also moves 17 → 19px, on the
     principle that **the page should be quiet because of whitespace, never
     because the text is small or faint.** */
  --fs-display: clamp(2.7rem, 5.2vw, 4.9rem);   /* 43 → 78px */
  --fs-section: clamp(2.15rem, 3.7vw, 3.4rem);  /* 34 → 54px */
  --fs-sub:     clamp(1.65rem, 2.4vw, 2.2rem);  /* 26 → 35px, subheadings */
  --fs-hero:    clamp(1.18rem, 1.55vw, 1.38rem);/* 19 → 22px */
  --fs-lede:    clamp(1.18rem, 1.4vw, 1.3rem);  /* 19 → 21px */
  --fs-body:    clamp(1.06rem, 0.95vw, 1.19rem);/* 17 → 19px */
  --fs-small:   1rem;                           /* 16px */
  --fs-micro:   0.85rem;                        /* 13.6px, DM Mono only */

  /* Space. Doubling-ish; --space-section is the page's vertical heartbeat and
     every band uses it, so the rhythm is set in one place. It runs to ~148px
     on a desktop: the sections are big pictures with a line of type over them,
     and at the old 104px they crowded into a scroll of panels. */
  --s-1: 6px;
  --s-2: 12px;
  --s-3: 20px;
  --s-4: 32px;
  --s-5: 52px;
  --s-6: 84px;
  --space-section: clamp(76px, 10vw, 148px);

  /* Measure. Prose stays near 65 characters; the hero and the collection grid
     get the page-wide one, which is what makes a desk nearly half the content
     width instead of a third of it. */
  --maxw: 720px;
  --maxw-wide: 940px;
  --maxw-page: 1200px;
  --maxw-read: 650px;
  --gutter: 22px;

  /* Cards are rare here and never SaaS cards: 12px is the ceiling, and nothing
     that uses it carries a drop shadow. --radius-media is for photographs,
     where a slightly larger corner reads as an object rather than a bleed. */
  --radius: 12px;
  --radius-media: 14px;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  position: relative;
  font-family: var(--font-voice);
  color: var(--ink);
  line-height: 1.55;
  /* Nunito's regular is light on a warm ground; 450 is the weight at which body
     copy reads as ink rather than as grey. */
  font-weight: 450;
  font-size: var(--fs-body);
  background-color: var(--paper);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
/* The grain goes OVER the whole document rather than under it, and that is the
   difference between "the background has a texture" and "the site is printed
   on paper". It also fixes something a background-only grain broke: the hero
   JPEG has the device flattened onto a flat sheet of --paper, so against a
   textured page its surround appeared as a bare rectangle. Over the top,
   everything — page, photographs, tinted blocks — takes the same tooth.
   Absolute, not fixed: paper does not slide under the words as you scroll. */
body::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image: var(--grain);
  background-size: var(--grain-size);
}

/* Links are ink with a rule under them, not red text.
   Red is the mailbox — the one saturated thing in the logo and the art — and
   as a link colour it was the loudest element on a page whose whole system
   says the accent is the paper. Underlined ink is what a printed page does:
   the link is marked, not coloured. The rule sits at a third strength so it
   reads as a mark rather than a border, and it takes the mailbox red on
   hover, which is the one place that colour still earns its keep.

   The standing underline is kept for links INSIDE PROSE, deliberately, against
   the "no underline by default" rule that governs the chrome. In a paragraph an
   unmarked link is indistinguishable from bold text, and the Privacy Policy and
   the blog are mostly paragraph. Navigation, footer and the editorial links —
   which sit alone, where nothing can be confused with them — carry no rule
   until hover. */
a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(41, 33, 27, 0.32);
  text-underline-offset: 0.17em;
  transition: text-decoration-color 120ms ease;
}
a:hover { text-decoration-color: var(--navy); }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }

/* ---------- Header ---------- */
.site-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 22px;
  max-width: var(--maxw);
  margin: 0 auto;
}
/* The landing page is built on the 1200px measure, so its header has to be
   too — at the 720px doc width the mark sat 200px inboard of the headline
   beneath it, which reads as two pages stacked. The legal pages keep the
   narrow one, where it lines up with the 720px card. */
.site-head--wide { max-width: var(--maxw-page); }
.site-head img {
  /* The mark is a cut-out mailbox, not a rounded app tile — it carries its own
     silhouette, so no border-radius, and it can run bigger than the 34px tile
     did without crowding the wordmark. */
  width: 46px; height: 46px;
}
/* THE MARK. Rubik Bold, all caps, positive tracking — the one place on the site
   that face appears, alongside the footer sign-off. Written "Postmello" in the
   markup and uppercased here, so screen readers and copy-paste get the name the
   way it is spoken while the header shows the logo.

   It used to be the body face at 1.05rem with negative tracking, which is to
   say: an icon followed by ordinary site text. */
.site-head .name {
  font-family: var(--font-mark);
  /* 600, not 700 (2026-08-15). Rubik's Bold at 27px uppercase was a heavier
     object than the H1 underneath it; Semibold keeps the authority and gives
     the counters back. Tracking eased 0.045 → 0.025em to match: the wider
     letterspacing was compensating for the weight. */
  font-weight: 600;
  font-size: clamp(1.35rem, 2vw, 1.72rem);   /* 22 → 27.5px */
  text-transform: uppercase;
  letter-spacing: 0.025em;
  color: var(--ink-mark);
  line-height: 1;
}
/* The wordmark is a link on every page but the home page, and it must not
   pick up the prose underline — it is a logo. */
.site-head > a { text-decoration: none; }
.site-head nav { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.site-head .dot { color: var(--ink-faint); }
.site-head nav a {
  color: var(--ink-soft);
  font-weight: 550;
  font-size: 1.06rem;   /* 17px */
  text-decoration: none;
}
.site-head nav a:hover { color: var(--ink); text-decoration: none; }

/* ---------- Hero ---------- */
/* Two columns, and the product takes the larger one. The hero used to be a
   centred headline with the mascot beside it, and the actual app appeared
   below the fold as a separate figure — so the first screen of a page about a
   writing desk showed everything except the desk. Words left, desk right, and
   the visitor knows what this is before reading a line.
   43/57 rather than half and half: the text column lands near 480px, which is
   a comfortable measure for three short blocks, and every pixel it gives up
   goes to the screenshot. */
.hero {
  max-width: var(--maxw-page);
  margin: 0 auto;
  /* Almost nothing below: the next section brings its own --space-section, and
     stacking both left ~290px of empty paper under the device. */
  padding: clamp(20px, 3vw, 48px) var(--gutter) clamp(8px, 1.6vw, 24px);
  display: grid;
  grid-template-columns: minmax(0, 43fr) minmax(0, 57fr);
  align-items: center;
  gap: clamp(28px, 4vw, 56px);
}
/* One column below 900px, text first — which is already the source order, so
   nothing has to be reordered and the reading order stays the visual one. */
@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: clamp(24px, 5vw, 40px);
    max-width: var(--maxw);
  }
}
/* On a phone the hero fills the first screen, so the claims below always begin
   on the second one. Without this the fold landed mid-block and screen one
   ended on the first claim's OBJECT with its heading just underneath the edge -
   a stack of paper and a pen floating at the bottom of the page, captionless,
   reading as a stray image rather than the top of an argument.
   svh, not vh: vh is the tall-chrome height on mobile Safari, which is exactly
   the case where the overshoot would reintroduce the problem. The 90px is the
   site header above it; the hero starts below the header, so the header's
   height has to come out or the hero pushes a screenful too far. */
@media (max-width: 620px) {
  .hero { min-height: calc(100svh - 90px); align-content: center; }
}
.hero h1 {
  /* Balance beats a hard <br>: the headline keeps even lines at every width
     instead of stranding one word. */
  text-wrap: balance;
  font-size: var(--fs-display);
  margin: 0 0 var(--s-3);
  color: var(--ink);
  font-weight: 800;
  /* Nunito goes loose at display size; -0.025em is what pulls "A quiet place"
     back into one word-shape instead of five letters and four gaps. */
  letter-spacing: -0.025em;
  line-height: 1.02;
}
.hero .tagline {
  font-size: var(--fs-hero);
  color: var(--ink-mid);
  max-width: var(--maxw-read);
  margin: 0 0 var(--s-4);
  font-weight: 500;
  line-height: 1.5;
  text-wrap: pretty;
}

/* The device is Apple's own iPad Air 13" (M4) product bezel, composited into
   the image itself rather than drawn in CSS. The bezel's screen hole is exactly
   2732x2048 — the native resolution of the simulator capture — so the shot
   lands 1:1 with no resampling. The surround is flattened onto --paper, so the
   JPEG's edge is invisible against the page and no alpha channel ships. Which
   also means NO border, radius or shadow here: the bezel already is the frame,
   and its drop shadow is baked into Apple's asset. */
.hero-shot {
  margin: 0;
}
.hero-shot > img {
  width: 100%;
  height: auto;
  display: block;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  /* DM Mono ships 300/400/500 — 600 would be a synthesised bold. */
  font-weight: 500;
  padding: 10px 20px;
  border-radius: 999px;
  font-family: var(--font-apparatus);
  font-size: var(--fs-micro);
  /* No text-transform here, unlike the other apparatus text: it would render
     Apple's "iPad" as "IPAD". */
  letter-spacing: 0.05em;
}

/* ---------- Steps ---------- */
/* Bezel-free on purpose: the hero shot has already said "iPad", and repeating
   the frame three more times spends ~15% of each image on chrome the reader no
   longer needs. Matches .shot's 940px so the row's outer edges line up with the
   hero above it.
   auto-fit rather than a fixed 3 columns: at 300px a panel is still legible,
   below that the row folds to two and then one on its own.

   Now a child of .feature, which owns the vertical rhythm and the gutter — the
   row used to be its own top-level section and carried its own margins, which
   is how the page ended up with two different section spacings. */
.steps {
  max-width: var(--maxw-page);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s-4);
}
.steps figure {
  margin: 0;
}
/* A hairline and a small radius, no shadow. Without the bezel these are bare
   crops, and cream-on-cream needs *some* edge or the paper in the shot bleeds
   into the paper of the page; a shadow would be the heavier way to say it. */
.steps img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 10px;
  border: 1px solid var(--line);
}
/* Captions carry the sequence, so they are labels rather than footnotes: full
   --ink, 600, and tightened tracking at size. At 0.95rem/--ink-mid they read as
   image credits and the row lost its "paper, writing, stamp" reading. */
/* Labels, not captions: at 16px they were image credits under three big
   pictures, and this row IS the section's copy. */
.steps figcaption {
  margin-top: 14px;
  text-align: center;
  color: var(--ink);
  font-size: clamp(1.2rem, 1.5vw, 1.32rem);
  font-weight: 700;
  letter-spacing: -0.018em;
}

/* ---------- Feature bands ---------- */
/* Three sections of equal weight, each: a big heading, one line of lede, and
   one large piece of supporting art. Stacked and centred rather than the
   alternating left/right zigzag every SaaS page uses — the art here is
   landscape screenshots of a desk, and a half-width column would shrink the
   very craft the section exists to show.

   Bands alternate ground (paper / paper-deep / paper) so the three separate
   without any card, rule or number. They are not a sequence, so they are not
   numbered: order carries priority, not steps. */
.feature {
  padding: var(--space-section) var(--gutter);
}
/* The last section is typographic and the footer that follows brings its own
   air, so the full section padding underneath it opened a hole big enough to
   read as a missing block. */
main > .feature:last-child { padding-bottom: var(--s-5); }
/* A different sheet of paper, not a coloured band. --paper-alt is three units
   off the canvas — at the old --paper-deep these read as two full-width
   rectangles of another colour, which is the one thing the page's own
   background is not allowed to do. The hairline at each edge is what makes the
   change legible: a paper edge rather than a block. */
.feature--band {
  background-color: var(--paper-alt);
  border-block: 1px solid var(--line);
}
.feature-head {
  max-width: var(--maxw-wide);
  margin: 0 auto var(--s-6);
  text-align: center;
}
/* A heading with nothing under it (the letter-making and business-model
   sections are now a heading plus their art) needs less air beneath it than a
   heading with a sentence — otherwise the h2 floats between two voids. */
.feature-head:has(> h2:only-child) { margin-bottom: var(--s-5); }
/* Rules either side of the heading were tried and cut (Patrick, 2026-08-13:
   "the blue dividers are a strange choice and look weird"). The alternating
   band grounds already separate the sections, so the heading needs no device
   of its own — which leaves the type to do it, at full size. */
.feature h2 {
  margin: 0 0 var(--s-3);
  font-size: var(--fs-section);
  font-weight: 780;
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--ink);
  /* On the h2, not on its span: balancing is a block-level operation and had
     no effect on an inline child, which is why the left-aligned calm heading
     broke as "…without keeping / up." */
  text-wrap: balance;
}
.feature .lede {
  /* Two limits, and the tighter one wins: 58ch keeps the measure readable at
     small sizes, --maxw-read caps it at ~650px once the type is large enough
     that 58 characters would run wider than that. */
  max-width: min(58ch, var(--maxw-read));
  margin: 0 auto;
  font-size: var(--fs-lede);
  line-height: 1.55;
  color: var(--ink-mid);
  text-wrap: pretty;
}
/* The one flat claim left on the page: "No ads · No subscription required to
   write letters", under the three plan columns. Full --ink and 600 against the
   lede's --ink-mid — it is the sentence a reader should leave the section
   with, and it earns that by weight rather than by being a badge or a callout
   box. */
.feature .claim {
  max-width: min(52ch, var(--maxw-read));
  margin: var(--s-5) auto 0;
  font-size: clamp(1rem, 1.3vw, 1.12rem);
  font-weight: 600;
  line-height: 1.5;
  color: var(--ink);
  text-align: center;
  text-wrap: balance;
}

/* ---------- The circle of drawers ---------- */
/* Five drawers, each cut from a different desk, scattered instead of lined up.
   A straight row is what the single cropped strip already was, and it read as
   one thing repeated; broken apart, with each drawer tipped a degree or two and
   sitting at its own height, they read as five people. The tilts are fixed
   values rather than random so the arrangement is the same every load — this is
   a composition, not a shuffle. */
.circle {
  max-width: var(--maxw-wide);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--s-4) var(--s-3);
}
.circle img {
  /* Sized so all five fit one line at the wide measure: 5 x 168 + 4 x 20 = 920.
     At 186 they broke 4 + 1, and a single orphaned drawer reads as a mistake
     rather than as a scatter. */
  width: clamp(132px, 16vw, 168px);
  height: auto;
  display: block;
  filter: drop-shadow(-3px 6px 10px rgba(42, 33, 24, 0.16));
}
.circle img:nth-child(1) { transform: rotate(-2.5deg) translateY(4px); }
.circle img:nth-child(2) { transform: rotate(1.5deg)  translateY(-8px); }
.circle img:nth-child(3) { transform: rotate(-1deg)   translateY(6px); }
.circle img:nth-child(4) { transform: rotate(2deg)    translateY(-5px); }
.circle img:nth-child(5) { transform: rotate(-1.5deg) translateY(3px); }

/* The struck-through `.absences` list (photos / video / GIFs / threads /
   typing dots / read receipts) and the `.uses` list of relationships both
   lived here. Both are gone, for the same reason: they defined the product by
   enumeration, in the apparatus face, at the two moments the page most needed
   to sound like a person. Their content survives as prose — one bold line in
   the quiet section, one lede in the contacts section.

   Nothing on this page animates, so the only motion to answer for is the
   drawers' fixed tilts and the smooth scroll. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .circle img { transform: none; }
}

/* ---------- The worlds ---------- */
/* Two across, each nearly half the 1200px content measure — about 580px, or
   roughly double what a three-across row gave them. This was a carousel first
   (one visible, three hidden behind a swipe) and then a three-up row, and both
   made the desks read as variants of one product. At 580px you can see the
   mailbox, the plate, the paper on the desk: six places rather than six
   thumbnails, which is the only reason this section exists.

   Fixed 2 columns rather than auto-fit: with six items auto-fit can settle on
   a count that strands an orphan on the last row. */
.collections {
  max-width: var(--maxw-page);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-5) var(--s-4);
}
.collections figure {
  margin: 0;
  /* The plate name reads before the picture, the way a place is labelled on a
     map. figcaption is legal as the first child of a figure, so this needs no
     ordering trick and the DOM order is the reading order. */
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
/* No border. These are the most colourful things on the site and they carry
   their own edges — a hairline round each one turned six places into six
   cards. The radius stays so they read as objects rather than as bleeds. */
.collections img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-media);
}
/* Understated (2026-08-15). These were mono, uppercase and letterspaced — set
   like brass nameplates, on the theory that a collection name is taxonomy. Six
   of them across the most colourful block on the site, and the labels were
   performing as hard as the pictures. Fairy Glen, Seaside Post and Ember Peak
   are imaginative enough on their own; the name only has to say which desk you
   are looking at. Nunito, sentence case, full ink. */
.collections figcaption {
  text-align: center;
  font-size: clamp(1.12rem, 1.3vw, 1.25rem);   /* 18 → 20px */
  font-weight: 680;
  letter-spacing: -0.008em;
  color: var(--ink);
}

/* On a phone the same grid would make each world a ~150px card, which is the
   thumbnail problem the section was rebuilt to escape. So the grid becomes one
   large world at a time on a scroll-snap rail, with the next one showing at
   the edge so it is obvious there are more.

   CSS scroll-snap, not a JS carousel: native momentum, no autoplay, no dots,
   nothing to pause for reduced motion. The rail is full-bleed (negative
   margins cancel the section gutter) so a world can reach the screen edge, and
   scroll-padding keeps the snapped item off it. */
@media (max-width: 760px) {
  .collections {
    display: flex;
    gap: var(--s-3);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline-start: var(--gutter);
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    /* Room for the peeking neighbour's shadow-free edge, and for the caption
       of the snapped one; without it the rail clips at the figure box. */
    padding-bottom: var(--s-1);
    scrollbar-width: none;
  }
  .collections::-webkit-scrollbar { display: none; }
  .collections figure {
    /* 78%, not 100%: the remaining fifth of the screen shows the start of the
       next desk, which is what tells a thumb there is anything to swipe. */
    flex: 0 0 78%;
    scroll-snap-align: start;
  }
}
/* The rail is a scrollable region, so it has to be reachable by keyboard —
   Safari does not focus scroll containers on its own, hence tabindex in the
   markup and a visible ring here. */
.collections:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 8px;
  border-radius: var(--radius-media);
}

/* ---------- The editorial interlude ---------- */
/* Two ideas, one section, sitting between the calm section and the
   collections. Compact on purpose — this is an interlude, not a third pillar,
   so it runs at roughly three-quarters of the page's section rhythm and its
   headings are a size below every other h2 on the page.

   Editorial, not promotional: no cards, no shadows, no illustrations, no
   buttons. One hairline between the columns is the entire apparatus. */
.editorial-section { padding-block: calc(var(--space-section) * 0.72); }
.editorial {
  max-width: var(--maxw-page);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(40px, 6vw, 96px);
}
.editorial-col + .editorial-col {
  border-left: 1px solid var(--line);
  padding-left: clamp(40px, 6vw, 96px);
  /* The gap already separates them; the rule needs the same space on both
     sides of itself or it reads as attached to the second column. */
  margin-left: calc(-1 * clamp(40px, 6vw, 96px) / 2);
}
/* Eyebrows are dark, not decorative grey. They label the two ideas, and a
   label nobody can read is just texture. */
.eyebrow {
  margin: 0 0 var(--s-3);
  font-family: var(--font-apparatus);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-mid);
}
.editorial h2 {
  margin: 0 0 var(--s-3);
  font-size: clamp(1.68rem, 2.5vw, 2.25rem);   /* 27 → 36px */
  font-weight: 750;
  line-height: 1.16;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}
.editorial p:not(.eyebrow) {
  margin: 0 0 var(--s-4);
  max-width: 46ch;
  font-size: var(--fs-lede);
  line-height: 1.62;
  color: var(--ink-soft);
}
/* No rule until you reach for it. These sit alone under a paragraph with
   nothing around them to be confused with, so the standing underline was
   decoration; the arrow already says "this goes somewhere". On hover the rule
   arrives and the arrow steps 3px in the direction it points. */
.editorial-link {
  display: inline-block;
  font-size: 1.09rem;
  font-weight: 650;
  color: var(--ink);
  text-decoration: none;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.22em;
}
.editorial-link:hover {
  text-decoration: underline;
  text-decoration-color: var(--navy);
}
.editorial-link span {
  display: inline-block;
  transition: transform 140ms ease;
}
.editorial-link:hover span { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .editorial-link span { transition: none; }
  .editorial-link:hover span { transform: none; }
}
@media (max-width: 760px) {
  .editorial {
    grid-template-columns: 1fr;
    gap: var(--s-5);
    max-width: var(--maxw-read);
  }
  /* Stacked, the vertical rule becomes a horizontal one between the two. */
  .editorial-col + .editorial-col {
    border-left: 0;
    border-top: 1px solid var(--line);
    padding-left: 0;
    padding-top: var(--s-5);
    margin-left: 0;
  }
}

/* ---------- The stationery spread ---------- */
/* Six desks say where you sit; this says what you can make there, which is the
   half of a collection the desk shots cannot show. It sits INSIDE the
   collections section, after the grid, rather than becoming a seventh section
   of its own — it is evidence for a claim already made, not a new argument.

   ONE collection, whole — every piece of Fairy Glen, nothing sampled. The
   earlier build took the prettiest piece from each of six packs, which showed
   the catalog's range but left the desk grid's real question unanswered: what
   do you get if you pick one? A pack shown complete answers it, and the
   sentence underneath does the work of saying the others match.

   Laid out in CSS rather than baked into a single JPEG for two reasons: any
   piece can be swapped for a better one without a re-render, and a phone can
   get a different arrangement instead of the same picture at a third the size.

   Percentage geometry inside an aspect-ratio box, so the whole composition
   scales as one object: at 1200px or 780px every overlap lands identically.
   The angles are fixed values — this is a composition, not a shuffle. */
/* A note on the grid, not a heading for what follows — so it sits close under
   the desks and well clear of the subheading beneath it. */
.collections-note {
  max-width: var(--maxw-read);
  margin: var(--s-5) auto 0;
  text-align: center;
  font-size: var(--fs-lede);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: balance;
}

/* A subheading, deliberately a third the size of the section h2 above it: the
   spread is a flourish inside the collections section, not another argument. */
.stationery-head {
  max-width: var(--maxw-page);
  /* s-3 below, matching the h2-to-lede gap in .feature-head; the lede now
     carries the s-5 the head used to hold against the spread. */
  margin: var(--s-6) auto var(--s-3);
  text-align: center;
  font-size: var(--fs-sub);
  font-weight: 720;
  letter-spacing: -0.02em;
  color: var(--ink);
}
/* The intent line under the subheading — same voice as a .feature .lede
   (measure, size, --ink-mid) so it reads as the head's sentence, not as a
   caption for the spread; the spread's own title is .stationery-caption. */
.stationery-lede {
  max-width: min(58ch, var(--maxw-read));
  margin: 0 auto var(--s-5);
  text-align: center;
  font-size: var(--fs-lede);
  line-height: 1.55;
  color: var(--ink-mid);
  text-wrap: pretty;
}
.stationery {
  position: relative;
  max-width: var(--maxw-page);
  margin: 0 auto;
  aspect-ratio: 1200 / 580;
}
.stationery img {
  position: absolute;
  display: block;
  height: auto;
}
/* Papers: opaque rectangles, so they need their own soft shadow to sit on the
   page and a hairline to keep cream-on-cream from bleeding into the ground. */
.st-paper {
  width: 21%;
  border-radius: 3px;
  border: 1px solid var(--line);
  box-shadow: -4px 8px 16px rgba(42, 33, 24, 0.13);
}
/* Nine sheets across the full width at a 9.6% step, so each one shows a little
   under half of itself and the fan still reaches both edges.

   Tops ALTERNATE high/low, and that is load-bearing rather than decorative.
   Every paper in a fan has its right side covered by the next one. A sheet
   sitting HIGH gets a LOW neighbour, so its TOP-right stays clear; a sheet
   sitting LOW gets a HIGH one, so its BOTTOM-right does. Papers carrying their
   art along the top (wisteria, dewdrops, firefly night) are therefore at the
   odd positions, and papers carrying it along the bottom (lily pond, sparkle
   trail, glen meadow, fairy ring) at the even ones. The fairy door is the one
   sheet with its art on the RIGHT, so it goes last where nothing covers it.
   Reorder these and the art disappears under the neighbouring sheet.

   Two things are layered on top of the alternation. A sweep, so the tilt runs
   from -5° at the left edge to +5° at the right instead of jittering about
   zero — that is what makes nine sheets read as one fan opening rather than a
   staircase. And an arc, so the pair of tops dips a little toward the middle:
   with both tops flat the fan looked ruled off along a horizon. */
/* Three of the nine are the PORTRAIT cut of the same design — the app ships
   both ways round for every paper, and the art is re-composed rather than
   rotated (wisteria arches over the top and down both sides, the bluebells run
   the full left edge). Saying that in the caption would be a claim the picture
   cannot back; turning three sheets says it without a word.

   Width is the landscape height — 21% × 3/4 = 15.75% — because it is the same
   sheet turned, not a smaller one. The fan's total span is unchanged: it
   depends only on the step and the LAST sheet's width, so any of 1–8 can turn
   freely. All three sit at ODD positions, which is forced: a portrait sheet is
   43.4% of the box tall against a landscape's 32.6%, and one placed LOW would
   reach into the props band. */
.st-paper--portrait { width: 15.75%; }
.st-paper--1 { left: 1%;    top: 2%;    transform: rotate(-5deg);   z-index: 1; }  /* wisteria: arch, TOP + both sides */
.st-paper--2 { left: 10.6%; top: 11%;   transform: rotate(-3.5deg); z-index: 2; }  /* lily pond: BOTTOM */
.st-paper--3 { left: 20.2%; top: 3.5%;  transform: rotate(-2.5deg); z-index: 3; }  /* dewdrops: TOP left */
.st-paper--4 { left: 29.8%; top: 12.5%; transform: rotate(-1deg);   z-index: 4; }  /* sparkle: BOTTOM left */
.st-paper--5 { left: 39.4%; top: 4.5%;  transform: rotate(0deg);    z-index: 5; }  /* bluebells: LEFT edge */
.st-paper--6 { left: 49%;   top: 12.5%; transform: rotate(1deg);    z-index: 6; }  /* glen meadow: BOTTOM band */
.st-paper--7 { left: 58.6%; top: 3.5%;  transform: rotate(2.5deg);  z-index: 7; }  /* firefly night: full bleed */
.st-paper--8 { left: 68.2%; top: 11%;   transform: rotate(3.5deg);  z-index: 8; }  /* fairy ring: BOTTOM centre */
.st-paper--9 { left: 77.8%; top: 2%;    transform: rotate(5deg);    z-index: 9; }  /* fairy door: RIGHT edge */

/* The compressed fan, bottom left. A 4.4% step against a 17% width shows only
   a quarter of each envelope — which is right, because these are colour fields
   with one small motif, and what a tight fan has to carry is the chord: deep
   purple, lilac, pink, sage, blue, cream. The rotation sweeps -7° to +3° about
   the bottom-left corner so the six splay from a common hinge like a hand of
   cards, rather than six rectangles each tilted on its own centre. */
.st-envelope {
  width: 18%;
  top: 57%;
  transform-origin: 0% 100%;
  filter: drop-shadow(-3px 6px 11px rgba(42, 33, 24, 0.16));
}
.st-envelope--1 { left: 1.5%;  transform: rotate(-7deg); z-index: 11; }  /* twilight: deep purple */
.st-envelope--2 { left: 6.1%;  transform: rotate(-5deg); z-index: 12; }  /* sparkle: lilac */
.st-envelope--3 { left: 10.7%; transform: rotate(-3deg); z-index: 13; }  /* petals: pink */
.st-envelope--4 { left: 15.3%; transform: rotate(-1deg); z-index: 14; }  /* bluebell: sage */
.st-envelope--5 { left: 19.9%; transform: rotate(1deg);  z-index: 15; }  /* moon: blue, motif ↘ */
.st-envelope--6 { left: 24.5%; transform: rotate(3deg);  z-index: 16; }  /* toadstool: cream, motif ↘ */

/* Stamps and stickers sit above everything — they are the loose things set
   down on top of the rest. */
.st-stamp, .st-sticker {
  z-index: 20;
  filter: drop-shadow(-2px 4px 7px rgba(42, 33, 24, 0.20));
}
/* Five in two staggered rows, just right of the envelope fan. Level, six
   identical squares are the product row this section exists to avoid. */
.st-stamp { width: 7.6%; }
.st-stamp--1 { left: 45.5%; top: 53%;   transform: rotate(-7deg); }
.st-stamp--3 { left: 53.7%; top: 50.5%; transform: rotate(3deg); }
.st-stamp--4 { left: 61.9%; top: 54%;   transform: rotate(-4deg); }
.st-stamp--5 { left: 49.6%; top: 71%;   transform: rotate(5deg); }
.st-stamp--6 { left: 57.8%; top: 73.5%; transform: rotate(6deg); }
/* The sixth is AFFIXED to the top envelope, not laid on top of it. The top
   envelope is the one piece here with a large plain face, and left bare it
   reads as a blank cream rectangle under a fan of blank cream paper; stamped,
   it is a letter about to be posted, which is the only thing in the picture
   doing anything.

   Two things make it read as stuck on rather than resting there:

   1. It sits where the APP puts a stamp, at the app's size. EnvelopeMetrics
      (Buzzybox/UI/Components/EnvelopeVisual.swift) states all three as
      fractions of the envelope WIDTH — side 0.157, top inset 0.071, trailing
      inset 0.099 — so at this envelope (18% of 1200 = 216px wide, 154.35 tall
      at the art's 343/480):
        side  = 216 × 0.157             = 33.91px → 2.83% of the composition
        left  = 294 + 216 − 21.38 − 33.91 = 454.70px → 37.89%
        top   = 330.6 + 15.34          = 345.94px → 59.64%
      That is a third the size of the loose stamps beside it, and it should be:
      those are catalog pieces at catalog size, this one is at letter scale.
      Retuning either fraction in the app means recomputing these.

   2. It shares the envelope's rotation ABOUT THE ENVELOPE'S OWN PIVOT, so the
      two turn as one object. The envelope rotates 3° around its bottom-left
      corner, at (294, 484.95) in this 1200×580 space; putting that same point
      in the stamp's coordinates gives an origin of (−160.70, +139.01) from its
      top-left, which as a fraction of its own 33.91px box is −473.9% / 409.9%.
      Percentages rather than px so it survives the composition scaling. Rotate
      the stamp about its own centre instead and it sits at a jaunty angle to
      the envelope, which is a sticker's behaviour, not a stamp's. */
.st-stamp--2 {
  width: 2.826%;
  left: 37.892%;
  top: 59.644%;
  transform-origin: -473.9% 409.9%;
  transform: rotate(3deg);
  filter: drop-shadow(-1px 1px 2px rgba(42, 33, 24, 0.22));
}

/* Sized ONE BY ONE rather than to a shared width. The wand is 95×180 and the
   flying letter 180×138; at a single width the wand looms over everything and
   the letter reads as a speck. These widths equalise AREA instead, which is
   what the eye takes for "the same size". Three heights rather than two, so
   ten of them settle into a cloud instead of resolving into rows. */
/* One of them sits ON the last sheet of the fan, at the foot of the paper
   nothing else covers. Without it the two bands are two exhibits with a rule
   of empty page between them; with it, a sticker has been put on a letter,
   which is what stickers are for. */
.st-sticker--1  { width: 7.2%; left: 82.5%; top: 27%;   transform: rotate(-8deg); }  /* butterfly, on the fairy-door sheet */
.st-sticker--2  { width: 6.4%; left: 70.5%; top: 50%; transform: rotate(5deg); }   /* toadstool house */
.st-sticker--3  { width: 4.7%; left: 78.5%; top: 47%; transform: rotate(-6deg); }  /* wand */
.st-sticker--4  { width: 7.2%; left: 85.5%; top: 52%; transform: rotate(7deg); }   /* flower crown */
.st-sticker--6  { width: 5.6%; left: 69.5%; top: 66%; transform: rotate(6deg); }   /* bluebell */
.st-sticker--7  { width: 6.7%; left: 77.5%; top: 63%; transform: rotate(-4deg); }  /* fairy door */
.st-sticker--8  { width: 5.6%; left: 86.5%; top: 67%; transform: rotate(8deg); }   /* lantern */
.st-sticker--9  { width: 7.5%; left: 72%;   top: 80%; transform: rotate(-7deg); }  /* wings */
.st-sticker--10 { width: 7.7%; left: 81%;   top: 83%; transform: rotate(4deg); }   /* flying letter */
.st-sticker--5  { width: 6.3%; left: 90.5%; top: 78%; transform: rotate(-5deg); }  /* moon */

/* Was .stationery-note, a sentence that inventoried the spread and then
   generalised it to every collection. Both jobs went (2026-08-18): nobody
   reads piece-counts off a marketing page, the picture shows more variety
   than the numbers claimed, and the six desk pictures further up already
   demonstrate that every collection is built the same way.
   What is left is the collection's NAME, set as a title for the spread — the
   same monospace-and-caps treatment the collection labels wear in the plans
   panel, so the two places a collection is named on this page look related. */
.stationery-caption {
  margin: var(--s-3) auto 0;
  text-align: center;
  font-family: var(--font-apparatus);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mid);
}

/* The wrappers exist only for the phone; on the composition every piece is
   absolutely positioned against .stationery, so these collapse to nothing. */
.st-group { margin: 0; }

/* On a phone the single coordinate space would put a 7.6%-wide stamp at 26px,
   which is a speck. It is dropped for four bands in normal flow — papers,
   envelopes, stamps, stickers — each group wrapping inside its own row and
   keeping the character it has above: papers and envelopes still shingle, the
   loose pieces still scatter.

   The overlap is symmetric negative margins (`0 -5.5%`, not `-11% 0 0`), which
   matters: a one-sided negative margin shortens the flex line without moving
   the last item, so a centred row hangs 11% off the right edge. Halved on both
   sides, every row centres on its true visual span.

   Thirty-one pieces laid out with no overlap at all ran this block past 900px
   down a phone, and the brief for this section is that it must not make the
   page substantially longer. Small and complete beats large and truncated —
   it is a spread, not a gallery. */
@media (max-width: 760px) {
  .stationery {
    aspect-ratio: auto;
    display: block;
  }
  .stationery img {
    position: static;
    top: auto; left: auto; right: auto;
    transform-origin: center;
  }
  .st-group {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-end;
    margin-bottom: var(--s-3);
    /* Absorbs the outer half of the first and last item's negative margins,
       which a centred flex line otherwise hangs over the container edge. */
    padding: 0 3%;
  }
  .st-group--stickers { margin-bottom: 0; }
  /* Three sheets to a row. The turned ones keep the relationship they have
     above — same sheet, so their width is the others' height — and that mixing
     is what sets the overlap: with two widths in play the flex line has to
     wrap at three whichever way the row is made up. Three landscapes take
     3 × (38 − 6) = 96% and still fit; the loosest possible four, two turned
     and two not, take 2 × 22.5 + 2 × 32 = 109% and cannot. At the −5.5% this
     started on, a mixed four fit and the rows came out 4/4/1 with the outer
     sheets hanging off both edges. */
  .stationery .st-paper    { width: 38%; margin: 0 -3% var(--s-2); }
  .stationery .st-paper--portrait { width: 28.5%; }
  /* Tighter than the papers — the envelopes are a stack, not a fan. */
  .stationery .st-envelope { width: 34%; margin: 0 -4% var(--s-2); }
  /* Six stamps across one row. At this size a stamp is 50px and 50px of
     overlap is most of the stamp, so these separate instead. */
  .stationery .st-stamp    { width: 15%; margin: 0 0.5% var(--s-2); }
  /* Widths carried over from the composition, doubled — same equal-area
     reasoning, and five to a row. */
  .stationery .st-sticker  { margin: 0 1% var(--s-2); }
  .st-sticker--1  { width: 14.4%; }
  .st-sticker--2  { width: 12.8%; }
  .st-sticker--3  { width: 9.4%; }
  .st-sticker--4  { width: 14.4%; }
  .st-sticker--5  { width: 12.6%; }
  .st-sticker--6  { width: 11.2%; }
  .st-sticker--7  { width: 13.4%; }
  .st-sticker--8  { width: 11.2%; }
  .st-sticker--9  { width: 15%; }
  .st-sticker--10 { width: 15.4%; }
}

/* ---------- The four claims under the hero ---------- */
/* Typographic, not boxed: this sits between the hero and the first picture
   grid, and a row of cards there would read as a second navigation.
   FOUR columns wide, TWO in the middle, one on a phone — stepped explicitly
   rather than with auto-fit, which at some widths leaves three across and one
   orphaned underneath. Two-by-two is the honest middle: four narrow columns
   below ~1000px would set every sentence to five lines.
   The headings sit BELOW the section headings further down the page on
   purpose — these are quick claims, not sections, and if they competed with
   "See where the page takes you" the page would read as beginning twice. */
.pillars {
  max-width: var(--maxw-page);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3vw, 40px);
}
/* The claim art. REAL DESK OBJECTS, not glyphs - the same instinct as the plan
   charms and the collection props: show the object. An icon set would be the
   one vocabulary on this page the product does not already own.

   Bottom-aligned inside a fixed-height box, so four objects of four different
   aspect ratios stand on one ground line instead of floating at four heights.
   Height, not width, is the shared dimension - the row would otherwise size
   itself off the widest thing in it (the drawers) and shrink the bee to a bead.

   No CSS drop-shadow here, unlike .plan-desks: these props carry their own
   baked contact shadows (the app's, and the ones composited into the two
   groups), and a second shadow on top reads as a sticker peeling off.

   The size is the whole argument for keeping this block. Its comment in the
   markup says all four claims should land before a reader scrolls, and that
   pictures start immediately below in "See where the page takes you". At this
   height the art costs the block one object-height, once; at 120px+ it
   becomes a second feature row and steals that section's entrance. */
.pillars .pillar-art {
  /* The gap is bigger than the block's other vertical steps on purpose. These
     are objects with their own baked contact shadows, not glyphs, and set at
     --s-2 each one looked like it was resting ON its heading. */
  margin: 0 0 var(--s-3);
  height: clamp(72px, 6.6vw, 88px);
  display: flex;
  align-items: flex-end;
  /* Centred over the column, even where the type below is left-aligned
     (Patrick, 2026-08-19). The four objects are 56px to 203px wide, so
     left-aligning them shares an edge with the type but leaves the row itself
     ragged - four things starting together and ending nowhere. Centred, the
     row reads as four objects on a shelf, which is what it is; the type keeps
     its own alignment underneath and the two systems stop competing. */
  justify-content: center;
}
.pillars .pillar-art img {
  max-height: 100%;
  max-width: 100%;
  width: auto;
  height: auto;
}
/* The whole claim centres, not just its object (Patrick, 2026-08-19). Centred
   art over left-aligned type measured as a 15-36px disagreement per column -
   the art sat on the column's centre while each heading, being left-aligned and
   shorter than its column, had its optical centre well to the left. The art was
   not off; it was the only thing that was ON. Centring the words is what makes
   the column read as one object with a caption, and it matches what the phone
   layout has always done. */
.pillars li { text-align: center; }
.pillars h2 {
  margin: 0 0 var(--s-2);
  font-size: clamp(1.14rem, 1.5vw, 1.32rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}
.pillars p {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--ink-soft);
}
@media (max-width: 1000px) {
  .pillars { grid-template-columns: repeat(2, 1fr); gap: var(--s-5) var(--s-4); }
}
@media (max-width: 620px) {
  .pillars {
    grid-template-columns: 1fr;
    max-width: 420px;
    gap: var(--s-5);
    text-align: center;
  }
  /* Already centred; the single column just needs more air under the object,
     because here the heading sits directly beneath it with no neighbouring
     column to give the eye a horizontal rhythm instead. */
  .pillars .pillar-art { margin-bottom: var(--s-4); }
}

/* ---------- The plans: free core, optional additions ---------- */
/* Three equal columns, restored 2026-08-16 (Patrick) after two intermediate
   shapes. The history matters because it says what each build got wrong: the
   FIRST three-column build presented the offerings as equals in light type —
   a thing you had to study to learn that one was free — so it became a wide
   free block, the words "Add more", then a pair, which told the story with
   layout but read as a bespoke diagram. Three columns in a row is the more
   universal shape: one glance says there are exactly three things and none of
   them is hidden. The fix for the original failure now lives in the PAPER,
   not the layout — the free column is the filled warm sheet, the additions
   are outlined near-white, so the one you get is the substantial one even
   though the three footprints match.

   Contrast was the other old failure: eyebrows at --ink-soft/13px and notes
   at the same colour vanished at laptop distance on a warm ground. Eyebrows
   are bigger and --ink-mid now, notes are --ink-mid rather than --ink-soft,
   and the middle line is the biggest thing in every block. */
/* ROW ALIGNMENT (2026-08-18, Patrick: the spec's table has vertical alignment
   and "you're breaking that a little bit" — correctly).
   Three cards read as a comparison only if the comparable things sit on the
   same line. They did not: Membership's founding note pushed its feature list
   down one row, and Plus's headline wraps to two lines, so from that point
   down nothing in the three cards agreed.
   Subgrid fixes it properly. .plans owns seven rows — eyebrow, desks, price,
   founding note, and three feature lines — and every card, its dd, and its
   feature list adopt those same tracks. Each row is then as tall as the
   tallest content across all three cards, so a wrap in one card moves the
   same line in the others and the table holds.
   The alternative was hand-tuned min-heights, which is the same idea written
   as numbers that go stale the first time a word changes. */
.plans {
  /* Was 980px, while the page's own widest rhythm is 1200 and the desk grid
     and stationery spread both use it. Narrow cards were the root of the
     white-space problem: at a third of 980 minus padding, every second
     feature line wrapped, and a shared row that has to fit a wrapped line in
     one card opens a gap in the other two. Widening does more for the block
     than any spacing tweak could. */
  max-width: var(--maxw-page);
  margin: 0 auto;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* FOUR shared tracks, not seven (2026-08-18). Only the COMPARABLE rows are
     worth locking together — eyebrow, charms, desk count, price — because
     those are what a reader scans across. The feature lists underneath differ
     in length by design (Plus has two lines where the others have three), and
     forcing them onto shared tracks reserved an empty row in whichever card
     was shorter. That reserved emptiness is the "weird vertical white space":
     alignment applied to things that were never meant to line up.
     The lists now flow at their natural height inside one final track. */
  grid-template-rows: repeat(4, auto) auto;
  column-gap: var(--s-3);
  /* Doubles as the cards' internal line spacing, so it is a leading value,
     not a gutter. */
  row-gap: 6px;
}
.plan { display: grid; grid-row: span 5; grid-template-rows: subgrid; }
.plan > dt { grid-row: 1; }
.plan > dd { grid-row: 2 / span 4; display: grid; grid-template-rows: subgrid; }
/* Explicit rows, so every card puts the same thing on the same line whatever
   its own content does. (There used to be a sixth row here for the founding
   annotation; it left the card entirely on 2026-08-18.) */
.plan > dd > .plan-desks { grid-row: 1; }
.plan > dd > strong { grid-row: 2; }
.plan > dd > .plan-price { grid-row: 3; margin-top: 2px; }
/* Plain flow, deliberately: see the note on .plans about what alignment is
   worth locking and what it is not. */
.plan > dd > .plan-list { grid-row: 4; }
/* COLOUR AND EMPHASIS — third revision (2026-08-18, spec §8).
   History, because each round was a correction of the last and the reasoning
   still binds. Round one gave the two PAID blocks hue and left free in bare
   kraft, so the column the page wants you to take became the dullest thing in
   the row; the lesson taken was "never let the free column lose". Round two
   over-applied it: free became the only block with chroma — manila fill,
   honey border, a "Start here" tag — sitting in the exact slot a pricing
   table gives its recommended plan.
   That is what this round fixes. A stronger free card reads as SELECTED, and
   telling a visitor the free plan is the recommended one is the wrong signal
   on a page whose job is to explain a subscription. So all three cards are
   the same paper and the same border, and the single permitted emphasis goes
   to Membership as the primary paid option: one step of border strength, no
   fill change, no badge.
   "Never let the free column lose" is still honoured — by position, and by a
   section heading that says the first desk is free before you reach any card.
   Everything still refused: no buy buttons, no ticks, no shadows. */
.plan {
  position: relative;
  text-align: left;
  background-color: #f5efe4;
  border: 1px solid #dccfbe;
  border-radius: var(--radius-media);
  padding: var(--s-4) var(--s-4) calc(var(--s-4) - 4px);
}
.plan--membership {
  border-color: #c9b79c;
}
/* Prices (2026-08-17, Patrick: a plan view without prices reads less serious
   and less real). One line per block, between the desk count and the terms.
   The desk count stays the LARGEST line — this section's story is still what
   you get, with what it costs one step below.

   Superseded (evening, 2026-08-17): the strike rule and the Plus "+" went
   with the annual model's first cut. THEN (same night, third cut + Patrick's
   call to bring the strike back): under "everyone subscribes" the struck
   figure is the genuine post-founding regular price — the SAME rule the
   morning strike stood on — so the `s` rule returned. The founding-note
   explainer did NOT return ("that join while Postmello is new" read as if
   nobody was on it); the Family terms line carries "Early price, yours to
   keep" instead, and prices are written from the app repo's pricing.json
   (scripts/apply-pricing.py). */
.plan-price {
  margin: 0;
  font-size: clamp(1.02rem, 1.25vw, 1.16rem);
  font-weight: 700;
  color: var(--ink);
}
.plan-price s {
  font-weight: 500;
  color: var(--ink-faint);
}
/* Honey at full strength on manila, with ink dark enough to pass AA rather
   than the white a SaaS badge would use — white on honey is a button, and a
   button is what this section does not have. */
.plan-tag {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  font-family: var(--font-apparatus);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4a3208;
  background-color: rgba(233, 162, 39, 0.42);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}
/* Plan names are taxonomy, so they keep the monospace — the page's small
   accent vocabulary, used for collection names and plan names and nothing
   else. 14px semibold: an eyebrow that can still be read. */
.plans dt {
  font-family: var(--font-apparatus);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mid);
  margin-bottom: var(--s-2);
}
.plans dd {
  margin: 0;
}
.plans dd strong {
  font-size: clamp(1.2rem, 1.7vw, 1.45rem);
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.plans dd span {
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink-soft);
}
/* (The old .plan--row rule lived here. Collections stopped being a member of
   the plans list on 2026-08-18 — it is its own <section> now, styled under
   "Collections panel" below — so the rule and the long comment justifying its
   full-width span went with the markup they described.) */
/* The desk charms. The real Mint Modern charm the app draws on a desk, not a
   glyph — the same instinct as the collection props below: show the object.
   They do NOT overlap. Overlapping was tried first, to buy size — and it
   failed in a way worth recording: this charm is a wide, flat desk with a
   continuous top edge, so any overlap at all fuses the row into one long
   bench and the count becomes unreadable. Since the count is the entire
   reason the charms are here, separation wins over size.
   Six therefore sets the size: a third of 980px, minus padding, minus the
   "+", divided six ways. Small, but a desk still reads as a desk, and the
   exact number is in words directly underneath.
   Plus stops at six and adds a "+" — twelve would be a crowd. */
.plan-desks {
  margin: 0 0 var(--s-1);
  display: flex;
  align-items: flex-end;
  gap: 3px;
  min-height: 22px;
}
.plan-desks img {
  height: 20px;
  width: auto;
  filter: drop-shadow(0 1px 2px rgba(60, 42, 20, 0.26));
}
.plan-desks-more {
  margin-left: 2px;
  font-family: var(--font-apparatus);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink-mid);
  line-height: 20px;
}
/* The Catalog book, inline with the line it labels rather than up in the
   charm row: it is not a desk, and putting it there would have read as one
   more thing you get N of.
   AFTER the words, not before (Patrick, 2026-08-18). Leading it indented the
   text past the left edge every other feature line starts on, so the one line
   with an icon was the one line out of alignment — in a block whose whole
   argument is that the rows line up. Trailing, it decorates the line without
   moving it. */
.plan-book {
  height: 19px;
  width: auto;
  margin-left: 7px;
  vertical-align: -4px;
  filter: drop-shadow(0 1px 2px rgba(60, 42, 20, 0.22));
}

/* Feature lines. A stack of short facts, not a paragraph: three cards side by
   side are read by COMPARING rows, and prose defeats that — the eye cannot
   line up "unlimited letters and contacts, kept forever" against "choose 3
   collections every year" when both are sentences. No bullet glyphs; the
   left edge and the spacing do the listing, which keeps the block typographic
   rather than administrative. */
.plan-list {
  list-style: none;
  /* The one deliberate gap in the stack: features are a group, and they need
     to read as separate from the price block above them. */
  margin: var(--s-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.plan-list li {
  font-size: var(--fs-body);
  line-height: 1.45;
  color: var(--ink-soft);
}
/* The one line that is the reason to buy the tier gets full ink. One per card,
   never two — the moment everything is emphasised, nothing is.
   font-size:inherit is load-bearing: `.plans dd strong` sizes the card
   HEADLINE, and without this reset it caught these too, so the feature line
   rendered at headline size and Plus appeared to have two headlines. */
.plan-list li strong {
  font-size: inherit;
  font-weight: 600;
  color: var(--ink);
}
/* (The in-card founding annotation lived here. It went on 2026-08-18: even
   at micro size it was one more thing between the price and the benefits, and
   the promise it stood in for now sits once, quietly, beneath the whole
   pricing block as .plan-founding-note. The struck price is left to speak for
   itself, which it does — a crossed-out number beside a lower one needs no
   caption.) */
/* The promise, once, under everything. Small and secondary on purpose: it
   preserves the value of the offer without making it the centrepiece. */
.plan-founding-note {
  max-width: 880px;
  margin: var(--s-4) auto 0;
  font-size: var(--fs-small);
  font-style: italic;
  color: var(--ink-soft);
  text-align: center;
}

/* ---------- Collections panel ---------- */
/* Not a plan, so not in the plans grid and not shaped like a card. 40/60: the
   copy needs only enough width to keep its lines short, and the art is the
   argument — a collection is a whole world, and eight of them on one shelf
   says that faster than the sentence above them does. */
.collections-panel {
  max-width: var(--maxw-page);
  margin: var(--s-4) auto 0;
  display: grid;
  grid-template-columns: 40% 1fr;
  gap: var(--s-4);
  align-items: center;
  background-color: #eee8f3;
  border: 1px solid #d9cee4;
  border-radius: var(--radius-media);
  padding: var(--s-4);
}
.collections-panel-eyebrow {
  margin: 0 0 var(--s-2);
  font-family: var(--font-apparatus);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mid);
}
.collections-panel h3 {
  margin: 0;
  font-size: clamp(1.2rem, 1.7vw, 1.45rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
}
/* Two sentences, not a list of facts (2026-08-18). The facts version had
   "additional collections from $0.99" standing alone, which reads as an offer
   open to anyone; joining the clauses into one sentence that OPENS with
   "Available with Membership" makes the price conditional on the thing before
   it, which is the truth. The sentence that used to sit above these, listing
   what a collection contains, went earlier: the pictures say it better. */
.collections-avail,
.collections-keep {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink-soft);
}
.collections-avail strong { font-weight: 700; color: var(--ink); }
/* The permanence line is the only place on the page that distinguishes a
   purchase from a subscription, so it carries full ink on its own. */
.collections-keep {
  margin-top: var(--s-2);
  font-weight: 600;
  color: var(--ink);
}
/* $0.99 prominent by instruction, and for a reason: it is the figure that
   stops an annual subscription reading as the start of an expensive stream.
   One step up in size is enough — a badge would oversell a number whose whole
   job is to look small. */
.collections-price {
  font-size: clamp(1.02rem, 1.25vw, 1.16rem);
}

/* The shelf. Transparent cutouts on the panel's own lilac — no cards, no
   frames: these are objects on a surface, the same grammar the desks use. */
.collections-props {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3) var(--s-2);
}
.collections-props li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
.collections-props img {
  width: auto;
  max-width: 100%;
  height: 74px;
  object-fit: contain;
  filter: drop-shadow(0 4px 8px rgba(60, 42, 20, 0.14));
}
.collections-props span {
  font-family: var(--font-apparatus);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--ink-mid);
}
/* Phone: the panel stacks and the shelf halves its columns. The art stays —
   it is the most persuasive thing in the section and the first thing a
   responsive pass would be tempted to drop. */
@media (max-width: 760px) {
  .collections-panel {
    grid-template-columns: 1fr;
    max-width: 420px;
    gap: var(--s-3);
  }
  .collections-props { grid-template-columns: repeat(2, 1fr); }
  .collections-props img { height: 84px; }
}
/* Reassurance. Not a headline, but it was nearly invisible at --fs-small in
   --ink-soft, and it is the sentence that answers "so what is the catch". Full
   --ink at 600, and no strip behind it — a fourth tinted block below three
   tinted blocks would just look like a plan with no name. */
.reassurance {
  max-width: 880px;
  margin: var(--s-5) auto 0;
  font-size: clamp(1.06rem, 1.2vw, 1.12rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink);
  text-align: center;
}
/* The reason under the claim (2026-08-18). One step down in size and colour,
   because the pair is an assertion and its explanation and they must not read
   as two competing sentences — a reader who takes only the first line has
   already got the point. Narrower than .reassurance on purpose: it is a
   sentence rather than a slogan, and 880px would run it to a single
   uncomfortably wide line on a desktop. */
.reassurance-why {
  max-width: 620px;
  margin: var(--s-2) auto 0;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink-soft);
  text-align: center;
}
/* One column on a phone: three abreast at 340px gives each block eleven
   characters a line. Stacked, the filled sheet leads and the two outlined
   ones follow — the same story the row tells, read downward. */
@media (max-width: 760px) {
  .plans {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    max-width: 420px;
    row-gap: var(--s-3);
  }
  /* Subgrid OFF when the cards stack. Row alignment is a comparison device
     and there is nothing to compare against once each card is alone on the
     screen — worse, three cards each spanning seven shared rows would either
     collide or inherit a 6px leading meant for a table. Back to plain blocks
     with their own rhythm. */
  .plan,
  .plan > dd {
    display: block;
    grid-row: auto;
    grid-template-rows: none;
  }
  .plan-desks { margin-bottom: var(--s-2); }
  .reassurance, .reassurance-why { max-width: 420px; }
}

/* ---------- Blog ---------- */
/* Articles sit on the paper itself rather than in the white card the legal
   pages use: those are documents to be consulted, these are meant to be read,
   and a 680px measure on the open page is the difference. Same palette, same
   faces, same grain — the blog is the site in long form, not a second site. */
/* --maxw, not a bespoke 680: with the gutter this puts the text edge exactly
   under the wordmark in the header, which a 680px box missed by 20px. */
.post, .blog-index {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(24px, 4vw, 48px) var(--gutter) var(--s-6);
}
/* The blog is more editorial than the rest of the site but it is NOT a second
   brand: no serif, same three voices, same paper. An article title runs close
   to the homepage hero because on that page it IS the hero. */
.post h1, .blog-index h1 {
  margin: var(--s-3) 0 var(--s-3);
  font-size: clamp(2.25rem, 3.8vw, 3.9rem);   /* 36 → 62px */
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-wrap: balance;
}
/* The article's own subtitle, carried down from the piece rather than written
   for the web: it states the argument before the first paragraph starts. */
.post-deck {
  margin: 0 0 var(--s-3);
  font-size: clamp(1.3rem, 1.9vw, 1.6rem);   /* 21 → 26px */
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--ink-mid);
  text-wrap: balance;
}
/* The byline takes the apparatus face — lower case, not the uppercase the
   eyebrows use. A typewritten credit under a headline is exactly the register
   this brand is in, and it separates the attribution from the prose without a
   rule or a colour. */
.post-meta {
  margin: 0 0 var(--s-5);
  font-family: var(--font-apparatus);
  font-size: 0.94rem;   /* 15px */
  font-weight: 500;
  color: var(--ink-soft);
}
/* A line the author set on its own and put in bold — a beat in the argument,
   not a heading. Given air either side and full ink, so it lands as one. */
.post-beat {
  margin: var(--s-4) 0 !important;
  font-size: 1.28rem !important;
  line-height: 1.45;
  color: var(--ink) !important;
}
.post-beat strong { font-weight: 600; }
.post p, .blog-index > p {
  font-size: 1.19rem;   /* 19px */
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0 0 var(--s-3);
}
.post h2 {
  margin: var(--s-6) 0 var(--s-3);
  font-size: clamp(1.6rem, 2.3vw, 2.3rem);   /* 26 → 37px */
  font-weight: 750;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ink);
}
/* A subsection inside a section — "Replying on the letter itself". Close to
   body size and set in the ink of a heading: it has to be a step DOWN from the
   h2 above it, or the article grows a second layer of section breaks. */
.post h3 {
  margin: var(--s-5) 0 var(--s-3);
  font-size: 1.24rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.post strong { color: var(--ink); font-weight: 600; }
/* The one pull-quote device: a hairline and a size, no italics and no quote
   marks — the same reasoning that took the italics off the footer tagline. */
.post blockquote {
  margin: var(--s-5) 0;
  padding-left: var(--s-4);
  border-left: 2px solid var(--line);
  font-size: 1.32rem;
  line-height: 1.45;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.post ul { margin: 0 0 var(--s-3); padding-left: 1.15rem; }
.post li {
  font-size: 1.19rem;
  line-height: 1.6;
  color: var(--ink-soft);
  margin-bottom: var(--s-2);
}
.post-end {
  margin-top: var(--s-6);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-small);
  color: var(--ink-soft);
}

/* The index. Entries, not cards: a title, a sentence and a byline, separated
   by the same hairline the rest of the site uses for structure. */
.blog-intro { margin-bottom: var(--s-5) !important; }
.post-list { list-style: none; margin: 0; padding: 0; }
.post-list li {
  padding: var(--s-5) 0;
  border-top: 1px solid var(--line);
}
.post-list li:last-child { border-bottom: 1px solid var(--line); }
/* Blog-card headings sit at the editorial scale, a clear step under an article
   title but well above the deck beneath them. */
.post-list h2 {
  margin: 0 0 var(--s-2);
  font-size: clamp(1.62rem, 2.3vw, 2.1rem);   /* 26 → 34px */
  font-weight: 720;
  line-height: 1.18;
  letter-spacing: -0.02em;
}
.post-list h2 a { color: var(--ink); }
.post-list h2 a { text-decoration: none; }
.post-list h2 a:hover { text-decoration: underline; text-decoration-color: var(--navy); }
.post-list p {
  margin: 0 0 var(--s-2);
  font-size: var(--fs-lede);
  line-height: 1.6;
  color: var(--ink-soft);
}
/* The subtitle repeated on the index, so the list says what each piece argues
   rather than only what it is called. */
.post-list-deck {
  font-size: clamp(1.15rem, 1.5vw, 1.28rem) !important;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-mid) !important;
  letter-spacing: -0.012em;
}
.post-list .post-meta { margin: 0 0 var(--s-3); font-size: 0.92rem; }
/* Whole-entry hover, so the target is the block and not just the six words of
   the title. */
.post-list li:hover h2 a { text-decoration: underline; text-decoration-color: var(--navy); }
/* The current page in the nav is stated, not styled loudly. */
.site-head nav a[aria-current="page"] { color: var(--ink); font-weight: 650; }

/* ---------- Cards / doc pages ---------- */
.card,
.doc {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 36px 32px;
  margin: 0 auto 32px;
  max-width: var(--maxw);
}
.doc h1 { margin-top: 0; font-size: 2.1rem; font-weight: 780; letter-spacing: -0.02em; line-height: 1.14; }
.doc h2 { font-size: 1.28rem; font-weight: 720; margin-top: 34px; color: var(--ink); letter-spacing: -0.012em; }
/* The Help page's questions. They were <h2 style="font-size:1.1rem"> — a
   heading level lied about in an inline style, five times, so a screen reader
   heard five sibling sections where there is one list of questions. Same size
   they rendered at before. */
.doc h3 { font-size: 1.16rem; font-weight: 700; margin-top: 30px; color: var(--ink); letter-spacing: -0.01em; }
.doc p, .doc li { color: var(--ink-soft); line-height: 1.6; }
/* A date is genuinely tertiary — one of the few things --ink-faint is for. */
.doc .updated { color: var(--ink-faint); font-family: var(--font-apparatus); font-size: 0.85rem; margin-top: -8px; }
.doc ul { padding-left: 20px; }
.doc li { margin-bottom: 6px; }
/* Back links are navigation, so no standing rule under them; they take one on
   hover like the nav does. */
.back {
  color: var(--ink-soft);
  font-weight: 550;
  text-decoration: none;
}
.back:hover { color: var(--ink); text-decoration: underline; text-decoration-color: var(--navy); }
.doc a.back { display: inline-block; margin-bottom: 18px; font-weight: 650; }

.contact-box {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px 20px;
  margin-top: 18px;
}

/* ---------- Footer ---------- */
footer {
  text-align: center;
  /* Less above than a section break: the plans block that precedes it is
     typographic and already surrounded by air, so the full 84px on top of the
     section's own padding read as a hole. */
  padding: var(--s-4) 22px 44px;
  color: var(--ink-faint);
  border-top: 1px solid var(--line);
  max-width: var(--maxw);
  margin: 0 auto;
}
footer a { color: var(--ink-soft); font-weight: 550; font-size: 1rem; margin: 0 8px; text-decoration: none; }
footer a:hover { color: var(--ink); text-decoration: underline; text-decoration-color: var(--navy); }
footer .dot { color: var(--ink-faint); }
footer .fine { display: block; margin-top: 10px; font-size: 0.875rem; font-weight: 450; color: var(--ink-faint); }

/* The one sign-off on the page, and it happens once. The page used to end
   three times over — a bolded claim under the plans, a gap, a centred
   name-and-tagline block, then the links — so it kept looking finished and
   then continuing. Name, tagline, links and copyright are one tight block now.

   "Letters at your own pace." replaces "One letter at a time." It names the
   distinction (letters rather than messages, and no clock) where the old line
   was gentle but unownable, and it holds for a grandparent as well as a
   nine-year-old. */
footer .signoff {
  margin: 0 0 var(--s-3);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* The mark again, and the only other place Rubik is allowed. Same treatment as
   the header at a size down: uppercased here, "Postmello" in the markup. */
footer .signoff-name {
  font-family: var(--font-mark);
  font-weight: 600;
  font-size: 1.32rem;   /* 21px */
  text-transform: uppercase;
  letter-spacing: 0.025em;
  color: var(--ink-mark);
  line-height: 1.15;
}
/* Not italic. Italics made the tagline read as a quotation or a decorative
   aside; upright, at nearly body size, it reads as brand copy — which is what
   it is. */
footer .signoff-line {
  font-size: 1.12rem;   /* 18px */
  font-weight: 500;
  color: var(--ink-mid);
}

/* Three labelled groups instead of one run of four links (2026-08-15).
   Blog · Help · Privacy Policy · Terms in a single row gave a legal page and a
   blog post the same weight and left nowhere to put an address, so a visitor
   looking for "how does this work for kids" or "who do I write to" had to guess
   which link hid it. Grouping says which is which in three words.

   Deliberately NOT a corporate footer: no Company, no Careers, no Partners, no
   social row, and nothing here that does not exist. Three groups, one line of
   labels, same quiet centre as before. */
footer .foot-groups {
  display: flex;
  justify-content: center;
  gap: clamp(var(--s-4), 7vw, var(--s-6));
  text-align: left;
  margin-bottom: var(--s-3);
}
.foot-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* The group labels are furniture, not links, so they take the apparatus face —
   the same reasoning as the plate names and the badge. Small and faint is right
   HERE (contra the whitespace-not-faint-text rule): nobody needs to read the
   word "Trust", it only has to separate the columns for someone scanning. */
.foot-label {
  margin: 0 0 2px;
  font-family: var(--font-apparatus);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* Stacked, so the horizontal margin that separates inline footer links would
   only push each column off its own label. */
footer .foot-group a {
  margin: 0;
  font-size: 0.98rem;
}

@media (max-width: 560px) {
  /* One centred column each, in the same order. Two-up wrapping put Contact
     under Explore and left a hole where Trust should have been. */
  footer .foot-groups {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--s-3);
  }
}

@media (max-width: 520px) {
  .doc, .card { padding: 26px 20px; }
  .site-head nav { gap: 14px; }
}
