/* Kristi Marie Creative — the emerald PAPER ground
   ================================================
   Direction: the 2026 KM Brands emerald system, paper ground. Chosen
   2026-08-27 off dev_sandbox/incoming/kmc-emerald-2026/compare.html, where
   velvet and paper were held side by side. KMC is paper. Kristi Marie Events
   took velvet; that fork is written down in the two standalone systems:

     KMC Design System (standalone) v1-20260827.html   ← this page's rules
     KME Design System (standalone) v0-20260827.html

   WHY THIS FILE EXISTS, AND WHY IT IS SO SHORT
   --------------------------------------------
   tokens.css / base.css already speak the KM Brands grammar: white-adjacent
   ground, colour as STROKE never as area, outlined containers, the 16x1
   eyebrow tick, the 44x2 mark, the forward bloom. Honey Pulse was a palette
   worn over that grammar. Emerald is another one. So this is not a rewrite —
   it RE-POINTS the existing token names at emerald values and then carries
   only the handful of deltas a token cannot express (the display face, the
   display face and its weight floor, square corners, the one velvet panel).

   base.css and home.css contain ZERO hardcoded colour between them. That is
   the whole reason a palette swap is a hundred lines instead of a thousand.

   ⚠️ SCOPE, AND IT IS MOVING. Everything is under `body.em`. The migration
   began with the homepage on 2026-08-27 and runs page by page; a page is on
   this ground the moment its markup carries `class="em"` AND it links this
   file, and not before. Both halves are required, which is why the check in
   build/verify/system.mjs asserts the class and the computed --ink together
   rather than trusting either alone.

   ⚠️ THE LEDGER IS build/verify/system.mjs, NOT THIS COMMENT. A list of
   migrated pages written here would be a second source of truth and it would
   go stale the first time someone migrated a page without reading this far
   down. MIGRATED in that file is asserted on every run, so it cannot.

   For the duration, an unmigrated page still fetches Playfair from Google
   while a migrated one fetches nothing external at all, so EB Garamond and
   Poppins are served twice across a mixed session. That is a cache miss, not
   a bug, and it disappears with the last migrated page.

   Load order matters: tokens.css, base.css, emerald.css, home.css.
   ============================================================ */

/* ---------- 1 · the faces, local ----------
   Lifted from the same house bundle the standalone systems embed. No
   fonts.googleapis.com, no fonts.gstatic.com, no preconnect: this page has
   no external request of any kind.

   ⚠️ THE DISPLAY FACE IS NOTO SERIF DISPLAY, NOT BODONI MODA — Darrell,
   2026-08-27, chosen off compare.html's face picker: "the font style I like
   in the compare.html is the Noto Serif". The design system document still
   says Bodoni and has not been updated; when the two disagree, this is the
   decision and that is the stale artefact. EB Garamond, Poppins and Hurricane
   are unchanged.

   It is the same weight axis Bodoni ran on — 500 display, 600 in the 20–28px
   band — so nothing in §3 moves. What DID change is why those numbers exist:
   see the note there.

   ⚠️ Noto Serif Display and EB Garamond are VARIABLE files — two weights share
   one binary on purpose. Do not "fix" the duplicate src by deleting a rule. */
@font-face { font-family: 'Noto Serif Display'; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/assets/fonts/noto-serif-display-normal-400.woff2") format('woff2'); }
@font-face { font-family: 'Noto Serif Display'; font-style: italic; font-weight: 400 700; font-display: swap; src: url("/assets/fonts/noto-serif-display-italic-400.woff2") format('woff2'); }
@font-face { font-family: 'EB Garamond'; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/eb-garamond-normal-400.woff2") format('woff2'); }
@font-face { font-family: 'EB Garamond'; font-style: normal; font-weight: 500; font-display: swap; src: url("/assets/fonts/eb-garamond-normal-400.woff2") format('woff2'); }
@font-face { font-family: 'EB Garamond'; font-style: italic; font-weight: 400; font-display: swap; src: url("/assets/fonts/eb-garamond-italic-400.woff2") format('woff2'); }
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/poppins-normal-400.woff2") format('woff2'); }
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 500; font-display: swap; src: url("/assets/fonts/poppins-normal-500.woff2") format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/ibm-plex-mono-normal-400.woff2") format('woff2'); }
/* ---------- the sisters' own faces ----------
 * Bodoni Moda is Kristi Marie Events' display face; Playfair Display is
 * Fleur's. They are here for ONE element each — the business name in the
 * family directory — because a reader who clicks through should already
 * recognise where she is landing, and the typeface is the strongest signal
 * available. Darrell, 2026-08-30.
 *
 * ⚠️ SELF-HOSTED, NOT LINKED, AND THAT IS NOT OPTIONAL. system.mjs asserts
 * "makes no external request" on every page. A Google Fonts <link> would fail
 * that check on the home page and break the rule it is enforcing — the whole
 * emerald ground serves its own faces. Latin subset only, same as the eight
 * above, fetched from the same source.
 *
 * ⚠️ PLAYFAIR DISPLAY IS ALSO tokens.css's `--serif` FALLBACK, from before the
 * emerald migration, where it has never had an @font-face and so has always
 * resolved to Georgia. It stays harmless because emerald.css redefines
 * --serif on body.em and every page carries that class — but if a page ever
 * ships without `body.em`, its serif silently becomes Playfair rather than
 * Georgia. Worth knowing before that looks like a mystery.
 *
 * ⚠️ NOT PRELOADED, deliberately. Both are far below the fold; preloading
 * would spend first-paint budget on a name nobody has scrolled to. */
@font-face { font-family: 'Bodoni Moda'; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/assets/fonts/bodoni-moda-normal-var.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Playfair Display'; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/assets/fonts/playfair-display-normal-var.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

@font-face { font-family: 'Hurricane'; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/hurricane-latin-400.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

/* ---------- 2 · the remap ----------
   Same token NAMES, emerald values. Every rule in base.css and home.css that
   reads var(--ink) / var(--amber) / var(--wash) picks these up and needs no
   edit. The names keep their honey-era spelling on purpose: renaming them
   would touch six stylesheets and the verify suite for no behavioural gain,
   and the next palette would only rename them again. Read them as ROLES.

   Every pair below is computed, not eyeballed. Figures are against the ground
   the text actually sits on. */
body.em {
  /* grounds — paper IS the ground now, not a white-adjacent tint */
  --ground:    #FFFFFF;
  --paper:     #FFFFFF;
  /* ⚠️ THE HOUSE VALUES. The 2026-08-29 tuning packet retunes both of these,
     AND IT IS SCOPED TO TWO PAGES — see the top of rentals.css, which is the
     only file that overrides them and is loaded only by /rentals and
     /rentals/design.
     ⚠️ THEY WERE GLOBAL FOR ONE DEPLOY AND THAT WAS THE BUG. The packet moves
     shared tokens as its mechanism, so applying it here changed every page
     that reads them: home.css reads the three 16 times and base.css 9 more,
     and base.css is the shared shell, so the nav, footer and buttons moved on
     surfaces nobody had reviewed. The packet's own §4 says so — "home.css,
     pages.css, base.css and the shop read the same three tokens changed in §1
     and were never previewed against them." Darrell approved the packet for
     the canvas and the wall; the bleed was a recorded side effect, not a
     decision. Scoping it is not a colour move, it is the packet applying
     where it was previewed.
     ⚠️ SO A NEW RULE THAT WANTS THE PACKET'S VALUES BELONGS IN rentals.css,
     NOT HERE. Moving either line back to the packet value re-breaks four
     pages, and it will look like a one-line tidy-up when it happens. */
  --rule-line: #E2DDD5;  /* quiet hairlines. 1.35:1 on paper, and meant to be */
  --wash:      #E7EEE9;  /* emerald mist — row hover, chip fill. The one tint. */

  /* text-safe */
  --ink:        #0A0908;  /* 19.9:1 on paper */
  /* Deep sage. Darrell, 2026-08-29, replacing the taupe #766555 this page
     inherited from Honey Pulse — the one warm value left in a cool palette,
     and the reason secondary copy read brown against the emerald. It is the
     most-spent colour in the house: 90 uses across six stylesheets, 41 of
     them in the design canvas alone.
     ⚠️ IT SITS ON PAPER, AND ONLY ON PAPER — 5.99:1, up from the taupe's
     5.58:1. This line first said the mist wash was the binding ground, which
     it inherited from the comment it replaced ("4.7:1 on the mist wash") and
     then stated more strongly. Measured across all six pages, nothing painted
     on the wash is --muted: it is ink #0A0908 or evergreen #0A3D2B every
     time. A comment already in the file is not evidence; it is a claim with
     the same provenance as any other.

     ⚠️ THE WASH FIGURE HERE DEPENDS ON WHICH PAGE YOU ARE ON, which is why it
     is no longer stated as one number. On the house wash #E7EEE9 muted is
     5.08:1 and clears AA. On the two rentals pages, where the tuning packet
     takes the wash to #4C9A74, it is 1.76:1 — unreadable. So "putting muted
     on the wash is a free move", which this comment used to say flatly, is
     true on four pages and false on two.
     ⚠️ DO NOT PAINT --muted ON --wash IN rentals.css OR design.css. Anywhere
     else it is fine. The old wording was an instruction rather than a note,
     and the only thing between it and unreadable text was that nothing paints
     muted on wash today.
     Still true everywhere: 5.31:1 on the plate #F3F1EC. */
  --muted:      #5A6660;
  --amber-deep: #0A3D2B;  /* ROLE: accent text. Evergreen — 12.2:1 on paper */

  /* the emerald ramp — --amber is the STROKE role, --honey the WASH role */
  --honey: #E7EEE9;  /* mist: fills that sit under ink type */
  /* 7.7:1 on paper. The packet takes this to #45705C (5.64:1) on the two
     rentals pages only; see the head of rentals.css. */
  --amber: #0E5F41;  /* emerald: strokes, seeds, underline draws, marks. 7.7:1 */

  /* names the emerald system uses that Honey Pulse had no equivalent for */
  --emerald:     #0E5F41;
  --emerald-mid: #45705C;
  --emerald-lit: #4C9A74;  /* the stroke's velvet voice — dark grounds only */
  --evergreen:   #0A3D2B;
  --silk:        #0B221B;  /* blackened emerald — the topbar band */
  --velvet:      #0A0908;  /* the one panel */
  --velvet-text: #F4F1EA;  /* 17.6:1 on velvet */
  --velvet-soft: #CFC9BE;  /* 12.1:1 on velvet */
  --gilt:        #B8860B;  /* fills, focus rings, seed halos. NEVER type on paper */
  --gilt-deep:   #8A6D15;  /* gilt as type on paper — 4.9:1 */
  --champagne:   #E8CD82;  /* gilt as type on a dark ground — 12.8:1 on velvet */
  --plate:       #F3F1EC;  /* the one sanctioned light fill, behind a loading image */
  --stone:       #D6D6D3;
  --greige:      #A29B91;

  /* faces */
  --serif:  "Noto Serif Display", Georgia, "Times New Roman", serif;
  --text:   "EB Garamond", Georgia, "Times New Roman", serif;
  --sans:   "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:   "IBM Plex Mono", ui-monospace, monospace;
  --script: "Hurricane", "Snell Roundhand", cursive;

  /* rhythm — the system's container, the page's own tuned section step.
     ⚠️ --sec-pad STAYS AT 6.5rem. The system quotes 128px between sections;
     this page reaches that already, because most sections are .sec--tight
     (padding-top 0) so one section's bottom padding IS the gap. Setting 8rem
     here made every .sec--tight → .sec boundary 256px and the page fell
     apart into islands. The container and gutter do move: 1320/36 is the
     house measure and the line lengths were tuned inside a 1280 that was
     never a considered number. */
  --maxw:    82.5rem;  /* 1320px */
  --gut:     2.25rem;  /* 36px */
  --sec-pad: 6.5rem;

  /* ⚠️ SOFTENED CORNERS, WHOLE HOUSE. Darrell, 2026-08-29: every card, image,
     container and outlined box takes a slight round, and it carries across the
     whole site rather than living on one section.

     ⚠️ THIS OVERRIDES THE KMC DESIGN SYSTEM, WHICH SPECIFIES --rad: 0, AND IT
     IS A DECISION RATHER THAN A DRIFT. It was made looking at the shipped
     pages, which is the authority the system's own governance defers to. The
     radius rule in build/verify/system.mjs was rewritten in the same commit —
     it asserts the HOUSE SCALE now rather than zero, so a stray 16px blob or a
     999px pill still fails. A rule that merely stopped being enforced would
     have been the worse outcome; the constraint is the same shape, at a
     different number.

     Slight is the whole point: 3px on a 400px card is a softened edge, not a
     rounded one. Do not add a border-radius declaration below — these three
     tokens exist so this stays one edit rather than forty, and that is what
     made this change possible at all. */
  --radius-sm: 2px;   /* chips, small marks, swatches */
  --radius:    3px;   /* buttons, cards, tiles, images — the default */
  --radius-lg: 4px;   /* the hero plate; a large surface wants a touch more */
}

body.em { background: var(--ground); }

/* ---------- the tint the operating system uses on our behalf ----------
 * ⚠️ UNSET UNTIL 2026-09-03, WHICH MEANT EVERY NATIVE CONTROL WORE THE OS's
 * BLUE. Darrell, on a phone: "can we change the shade of the selector circles
 * on mobile to a lighter shade of green — right now it's a light blue."
 *
 * That blue is the platform accent, and it is what the browser reaches for
 * whenever a control is drawn by the system rather than by us: the selected
 * day in a date picker, the radio circles Android puts in a <select> dialog,
 * a range thumb, a checkbox we have not hand-styled. There is exactly one
 * standard lever for it and this is it.
 *
 * ⚠️ HOUSE-WIDE, NOT ON THE FORM, because the controls are house-wide — the
 * date field on /contact, the number fields on the canvas, the search on
 * /rentals. A tint set on one card would leave the rest blue and nobody would
 * be able to say why.
 *
 * ⚠️ --emerald-lit RATHER THAN --amber OR --evergreen, AND THE GROUND IS THE
 * REASON. This colour is composited by the OS onto ITS dialog, which may be
 * white on one phone and near-black on another, and we are told which. Both
 * have to work: emerald-lit is 3.33:1 on white and 5.86:1 on velvet, so it
 * clears the 3:1 that non-text UI is held to either way. Evergreen would
 * disappear on a dark dialog; emerald is marginal on a light one. It is also
 * the lighter green Darrell asked for.
 *
 * ⚠️ IT REACHES AS FAR AS THE PLATFORM LETS IT AND NO FURTHER. accent-color
 * tints what the OS draws; it does not restyle it. An iOS date wheel takes the
 * system tint for its selection and ignores this, which is the same wall the
 * dropdown LIST hits in pages.css. Setting it is right, and it is not a
 * promise that every blue pixel on every device turns green. */
body.em { accent-color: var(--emerald-lit); }

/* ---------- 3 · the display face ----------
   ⚠️ TWO RULES, BOTH LOAD-BEARING, AND THE REASON CHANGED WITH THE FACE.
   Under Bodoni these numbers existed because a didone's hairlines stop being
   thin and start being absent below 500 / 20px. Noto Serif Display is not a
   didone — it is the most legible of the seven candidates and it would
   survive 400. The weights stay at 500 / 600 anyway, because they are what
   compare.html's picker runs it at and therefore what Darrell chose it at:
   the face is a little sturdier and a little quieter than Bodoni, and the
   weight is what keeps the headlines feeling drawn rather than typed.

   base.css sets h1,h2,h3 to 400 for Playfair, which was drawn for it.

   Tracking still flips sign: Playfair was pulled in at -0.012em, this face is
   set open at +0.01em, which is the system's --track-display. */
body.em h1, body.em h2, body.em h3 {
  font-weight: 500;
  letter-spacing: 0.01em;
}
/* everything in the 20–28px band, the step the system calls d3.
   ⚠️ SERIF HEADINGS ONLY. .foot-col-title is an h2 by tag but a 12px Poppins
   label by design — it was in this list for one revision and that asked
   Poppins for a 600 this page does not load, which is the faux-bold that
   smears a tracked uppercase label. Check the FACE, not the tag. */
/* ⚠️ .toc h3 CAME OUT OF THIS LIST 2026-08-29, and the comment above is why
   it should have come out in the same edit that changed it. The trio's heading
   became a Poppins label when the section took the Outline/Trio treatment, and
   it sat here asking for a 600 this page does not ship — the identical
   faux-bold the .foot-col-title note describes, on identically tracked
   uppercase, one revision later. checkFaces caught it. Its weight is set with
   the rest of its type in home.css now, next to the face that has to support
   it, which is the only place the two can be checked against each other. */
body.em .svc h3,
body.em .col-item h3 { font-weight: 600; }

/* The one italic per headline. The system asks for exactly one, and it is the
   only place accent text appears in a heading. */
body.em h1 em, body.em h2 em, body.em h3 em {
  font-style: italic;
  color: var(--amber-deep);
}

/* ⚠️ THE MASTHEAD'S SIZE AND MEASURE MOVED TO home.css ON 2026-08-27, with
   the split composition. They belong there now: the headline is sized against
   a 536px copy COLUMN, not against the page, and this file cannot see the
   column. Overriding from here is what broke it once already — home.css said
   48px/20ch, this file said 68px/19ch and won on specificity, and the
   headline set on four lines with 146px of column to spare. */
body.em .flourish { margin-top: 0.75rem; }

/* ---------- 3b · THE DISPLAY SCALE ----------
   ⚠️ THIS IS THE FIX FOR "THE FONTS DON'T MATCH", and the fonts were never
   the problem — the binaries are byte-identical to the mockup's.

   The mockup has ONE display scale, three steps, used everywhere: d1/d2/d3.
   This page had grown SEVEN ad-hoc clamps, one per section, every one of them
   smaller than the step it was standing in for — the masthead at 48px against
   the system's 68, section heads at 42 against 46, the showroom at 36. No
   single rule was wrong and the sum of them was a different typeface voice:
   a display face that is never allowed to get large stops being a display
   face at all.

   So the scale is named here once and the sections stop having opinions.
   Values are the system's own (tokens/typography.css in the mockup), not
   re-derived: d1 clamp(40px, 4.8vw, 68px), d2 clamp(30px, 3.6vw, 46px),
   d3 22px at 600.

   ⚠️ NO max-width ON d1. At 45/55 the masthead headline sets on three lines
   with the italic starting mid-line, and that is the composition Darrell
   picked — not an overflow to be clamped away. Constraining it to 20ch is
   what produced the tidy, small, two-line version that did not look like the
   mockup. */
body.em .masthead h1 {
  font-size: clamp(40px, 4.8vw, 68px);
  line-height: 1.02;
  max-width: none;
}
body.em .sec-head h2,
body.em .spread h2,
body.em .featured-head h2,
body.em .pull-body h2,
body.em .cta h2 {
  font-size: clamp(30px, 3.6vw, 46px);
  line-height: 1.08;
  max-width: none;
}
/* d3 — the 20–28px band, where the display face runs 600.
   .toc h3 is absent for the same reason it left the weight rule above: it is
   a 15px tracked label now, not a 22px display heading. */
body.em .svc h3,
body.em .col-item h3 { font-size: 1.375rem; line-height: 1.16; }

/* ⚠️ THE SECOND VOICE IS SMALL AND ROMAN, NOT BIG AND ITALIC. The masthead
   line was a serif italic at up to 28px with its own amber tick — a second
   display voice competing with the headline above it. In the system it is
   .lede: 20px, EB Garamond roman, secondary colour, one line under the rule.
   The headline is the voice; this is the caption that lets it be. */
body.em .standfirst {
  font-family: var(--text);
  font-style: normal;
  font-size: 1.25rem;
  line-height: 1.45;
  color: var(--muted);
  max-width: 34ch;
}

/* ---------- 3c · the section rhythm ----------
   The system's step is 128px between sections and 96px for a tight one, and
   it is padding-TOP only — a section that pads both ends doubles up against
   its neighbour, which is why this page read looser than the mockup while
   using a smaller number. Scoped to body.em: the other five pages keep the
   Honey Pulse rhythm until each is migrated. */
body.em .sec { padding: 8rem 0 0; }
body.em .sec--tight { padding-top: 6rem; }

/* ⚠️ THE SHOWROOM HEADLINE COMES OUT OF FULL ITALIC. home.css sets
   .pull h2 { font-style: italic } — a Honey Pulse choice, and a good one for
   Playfair. Here it breaks the house's most recognisable typographic tic:
   exactly ONE italic per headline. A fully italic line makes the whole
   headline the accent, which leaves the <em> inside it with nothing to say.
   The <em> carries it now, like every other heading on the page. */
body.em .pull h2 { font-style: normal; }

/* The masthead's second voice and the section full-stop are both serif
   italic. At 22–32px they clear the floor; they carry 500 so the italic
   hairlines survive at the small end. */
body.em .standfirst,
body.em .kicker { font-weight: 500; }

/* ---------- 4 · controls ----------
   ⚠️ THE BLOOM CANNOT FLOOD DARK, AND IT DOES NOT HAVE TO.

   base.css is emphatic that the button label stays INK through the whole
   bloom, because a colour that has to flip mid-fill fails somewhere in the
   middle. That held on honey (#ffd061) because the fill was lighter than the
   label. Emerald is not: ink on #0E5F41 measures 2.59:1, and champagne on the
   white the fill has not reached yet is 1.5:1. Every timing fix moves the
   failure window; none of them closes it. Measured, not argued — the suite
   samples eight frames of the real transition.

   So the seed floods MIST instead of emerald. Ink is 19.9:1 on the paper and
   15.0:1 on the fill, so no frame of the bloom can fail, and the button keeps
   the forward bloom — which is the KM Brands control and the thing that would
   have been quietly lost by making every button solid.

   The seed sits a step deeper than --wash on purpose. At #E7EEE9 the resting
   11px dot is within a hair of the paper and reads as a smudge rather than a
   mark; at #D3E4DA it is a soft green bullet, and the flooded fill is still
   15:1 under the label.

   Colour arrives as stroke: the emerald is in the BORDER, all the way through.

   A filled weight is not defined here. The system sanctions one — bloom =
   outlined, ember = filled — and the velvet panel's CTA below is that ember.
   A second filled variant with nothing to wear it would be dead CSS. */
/* The back reveal floods SILK and carries a mist label on it. Both halves are
   measured as a pair: --amber-deep on paper at rest, and #D3E4DA on --silk
   inside the fill. The label is drawn twice and clipped with the fill rather
   than recoloured, so neither pair is ever blended into the other and there
   is no mid-transition frame to fail. Change one of these and re-measure both. */
body.em {
  --btn-fill:    var(--silk);
  --btn-on-fill: #D3E4DA;
}

/* ⚠️ POPPINS SHIPS 400 AND 500 HERE, NOT 600. base.css asks .text-link for
   600 because the honey pages request it from Google. Ask a face for a
   weight it does not have and the browser synthesises one — which on a
   tracked uppercase label smears the counters. Pin it. */
body.em .text-link,
body.em .col-go { font-weight: 500; }

/* Focus is gilt: 3.25:1 against paper, which is the threshold for a
   non-text indicator, and it is the one colour on the page that appears
   nowhere else at rest. */
body.em :focus-visible { outline-color: var(--gilt); }

/* ---------- 5 · chrome ----------
   The topbar is silk rather than ink — a band of the same family as the
   velvet panel, so the page opens and closes on the same dark note.

   ⚠️ THE TOPBAR IS NOT THE VELVET PANEL, so this page still spends its one
   dark block exactly once. Chrome and content count separately: the band is
   40px of furniture that every page wears, the panel is a section of the
   page's argument. The standalone KMC system does the same thing — silk
   topbar, one velvet block — which is where to check if this is ever
   questioned. What is NOT allowed is a second dark SECTION. */
body.em .topbar { background: var(--silk); color: var(--velvet-text); }
body.em .topbar b { color: var(--champagne); }

/* The nav rule is a hairline, not an ink border. On paper the structural
   ink frame is reserved for things that are actually framed. */
body.em .nav { border-bottom: 1px solid var(--rule-line); }
body.em .site-footer { border-top: 1px solid var(--ink); }

/* ---------- 6 · the plate ----------
   --plate is the system's one permitted light fill and it exists for exactly
   this: the box behind an image that has not arrived. */
body.em .plate { background: var(--plate); }

/* ---------- 7 · the steps come off the ink ----------
   ⚠️ ONE VELVET PANEL PER PAGE, AND IT IS THE FINALE.

   On Honey Pulse the three funnel steps were solid ink cards, and that was
   defensible: "colour as stroke, never as area" was a rule about the accent
   ramp, not about black. The emerald system counts differently — a dark
   block is THE moment, singular, and the closing CTA is the better place to
   spend it. So the steps become what everything else on this page is: an
   outlined container on paper.

   The badge inverts back with them — it was a cream ring on ink, it is an
   emerald ring on paper again. */
body.em .steps li {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--rule-line);
}
body.em .steps li:hover { border-color: var(--amber); }
body.em .step-num {
  border: 1.5px solid var(--amber);
  color: var(--amber-deep);
}

/* ---------- 8 · the one velvet panel ----------
   The closing CTA. Noir ground, cream type, an emerald-lit hairline for the
   accent italic, and the single gilt event on the page sitting on it.

   ⚠️ CONTAINED, NOT FULL-BLEED — changed 2026-08-27 with the compare.html
   layout. Full-bleed velvet under a paper page reads as a different site's
   footer arriving early; a panel inside the measure reads as a card the page
   is handing you. The composition (the 1.25/.75 split, the padding) is in
   home.css; only the ground and the gilt are here.

   ⚠️ Count them. If a second dark block ever lands on this page, one of the
   two is wrong — and it is not this one. The topbar is chrome, not the panel;
   see §5. */
/* ⚠️ SILK, NOT VELVET — Darrell, 2026-08-28, and the system sanctions both:
   "--silk #0B221B and --velvet #0A0908 are the two grounds the single panel
   may take." Silk is blackened emerald and it is the reason this reads as a
   dark GREEN block rather than a black one. Measured, because "does it still
   look green" was the actual question: velvet is hue 30 at 11% saturation,
   which is a neutral near-black that happens to round warm; silk is hue 162
   at 51%, and 23 points more green than red per channel.
   ⚠️ Every text pair on this panel was computed against VELVET and silk is
   LIGHTER, so each one had to be re-checked rather than assumed. Measured on
   silk: velvet-text 14.79:1, velvet-soft 10.13:1, champagne 10.71:1,
   emerald-lit 4.91:1. All four still clear, and the last one is the floor —
   it is the accent italic, it is the only pair under 5, and it is what goes
   first if this ground is ever lightened again. Re-run the four before you
   touch it. */
/* ⚠️ ONE GROUND, TWO COMPOSITIONS, AND THEY ARE NAMED APART ON PURPOSE.
   `.cta` is the homepage's enquiry panel (a 1.25/.75 split carrying two
   fields and the gilt control; composition in home.css). `.close` is the
   content pages' finale (headline, one line of copy, one gilt button;
   composition in pages.css). They are the SAME dark block wearing the same
   ground, so the ground is written once, here, for both.

   Naming them apart is the lesson from the two winks base.css used to record
   (both gone now, the second on 2026-08-30): when
   one class carried two compositions in two stylesheets that are never loaded
   together, nothing in the codebase could say which page a rule was for, and
   the only thing stopping them colliding was a link tag. Now a grep for
   `.close` finds the content pages and a grep for `.cta` finds home. */
body.em .cta,
body.em .close,
body.em .page-hero {
  background: var(--silk);
  color: var(--velvet-text);
  border: 1px solid rgba(244, 241, 234, .16);
}
body.em .cta h2, body.em .close h2, body.em .page-hero h1 { color: var(--velvet-text); }
body.em .cta h2 em, body.em .close h2 em, body.em .page-hero h1 em { color: var(--emerald-lit); }
body.em .cta p, body.em .close p, body.em .page-hero p { color: var(--velvet-soft); }
body.em .cta .eyebrow, body.em .close .eyebrow, body.em .page-hero .eyebrow { color: var(--velvet-soft); }
body.em .cta .eyebrow::before,
body.em .close .eyebrow::before,
body.em .page-hero .eyebrow::before { background: var(--emerald-lit); }
/* the 2026 addition: a gilt hairline under a velvet-panel headline.
   ⚠️ left-aligned now, not centred — the panel is a two-column spread and a
   centred rule in a left-set column points at nothing. */
body.em .cta .gilt-hair,
body.em .close .gilt-hair,
body.em .page-hero .gilt-hair {
  height: 1px; width: 100%; max-width: 22rem;
  background: var(--gilt); opacity: .55; border: 0;
  margin: 1.75rem 0 0;
}

/* ---------- 8a · surfaces that take the house corner ----------
   Darrell, 2026-08-29: the softened edge carries across the whole site, not
   one section. The three radius tokens do most of it for free — every control,
   input, product card and swatch already read them — and this block is only
   the surfaces that clip or paint without ever having declared a radius,
   because they had no reason to when the answer was always zero.

   ⚠️ WHAT IS DELIBERATELY LEFT SQUARE, AND WHY. The topbar, the nav, the
   footer, the canvas shell and the page ground are FULL BLEED. A radius on a
   band that runs the whole viewport does not soften anything; it cuts four
   notches out of the corners and shows the page behind them. The divider-only
   containers (.toc, .faq-list, .sis-grid) are left alone for the
   opposite reason: their "outline" is a border-top, so a radius there is a
   declaration that paints nothing and later reads as an oversight.

   ⚠️ overflow: hidden IS LOAD-BEARING, NOT TIDINESS. A rounded box with a
   square photograph inside it is a square photograph — the corner shows on the
   image and the round shows on the border, half a pixel apart, which reads as
   a rendering bug rather than a style. Anything holding an image to its own
   edge has to clip. */
body.em .cta,
body.em .close,
body.em .page-hero,
body.em .svc::before,
body.em .pull,
body.em .pull-claim,
body.em .page-media,
body.em .cat,
body.em .surface { border-radius: var(--radius); }

body.em .cat,
body.em .page-media,
body.em .it { overflow: hidden; }

/* ---------- 8b · the gilt control ----------
   Gold is an event, and this is the event: one per page, on the velvet panel,
   and nowhere else. Champagne label on noir is 12.8:1.

   ⚠️ IT RUNS THE EMBER, NOT THE BLOOM. A gilt seed flooding this button would
   put champagne on gilt for the length of the fill — 2.09:1, measured — and
   no timing closes that window. The ember is a glow around a label that never
   changes its ground, so there is no frame to fail. Bloom = outlined, ember =
   filled: the same rule the mist bloom in §4 obeys from the other side. */
body.em .btn--gilt {
  background: transparent;
  color: var(--champagne);
  border-color: var(--gilt);
  transition: box-shadow .45s ease, border-color .35s ease, transform .3s var(--ease-out);
}
body.em .btn--gilt::before { content: none; }
body.em .btn--gilt:hover,
body.em .btn--gilt:focus-visible {
  box-shadow: 0 0 0 1px rgba(232,205,130,.7), 0 6px 24px rgba(184,134,11,.45),
              0 0 72px rgba(184,134,11,.34), inset 0 0 20px rgba(184,134,11,.22);
  border-color: rgba(232,205,130,.9);
  transform: translateY(-2px);
}
body.em .btn--gilt:active { transform: translateY(1px); }
body.em .cta :focus-visible,
body.em .close :focus-visible { outline-color: var(--champagne); }

/* ⚠️ A TEXT LINK ON THE DARK PANEL, AND WHY IT IS NOT CHAMPAGNE.
   .text-link inherits --amber-deep, which on this ground is evergreen on
   silk at 1.36:1. Unreadable, and invisible to a contrast sweep that only
   samples buttons — so it is fixed here rather than left to be noticed.

   Champagne is the obvious replacement and is the wrong one. Gold is an
   event and the system permits ONE per page; the panel already spends it on
   the ember. A champagne link beside that ember is a second gold thing, and
   build/verify/system.mjs counts it as exactly that and fails the page. The
   check is right and the instinct was wrong.

   So the link reads as text and the accent rides the underline: cream at
   14.79:1 with an emerald-lit draw. The hierarchy is clearer for it — the
   ember is the action, the link is a way past. */
body.em .cta .text-link,
body.em .close .text-link { color: var(--velvet-text); }
body.em .cta .text-link::after,
body.em .close .text-link::after { background: var(--emerald-lit); }

/* ---------- 8c · the pieces the split layout added ----------
   The display face is never set at 400 on screen and never below 20px (§3).
   These are display type by ROLE but not by TAG, so the h1/h2/h3 rule cannot
   reach them and they have to say it themselves. */
body.em .pull-quote { font-family: var(--serif); font-weight: 500; letter-spacing: .01em; }
/* Poppins ships 400 and 500 here and nothing else — see §4's note on
   .text-link. A tracked uppercase label asking for 600 gets a synthesised
   weight that fills its own counters. */
body.em .col-kind,
body.em .col-go,
body.em .chip-label { font-weight: 500; }
/* the small button inside the staircase's first step */
/* ⚠️ 1.75rem OF LEFT PADDING IS THE SEED CLEARANCE, not a taste call. The
   bloom seed sits at left:19px and is 11px across, so it spans to 24.5px; a
   26px label wore the dot on its first letter. Same scar base.css records
   against .wishlist-btn. */
/* The 1.75rem of left padding here was seed clearance for the bloom. The bloom
   is gone, so the label starts at 8px like every other button, and the right
   padding carries the same 28px of reserved travel. */
body.em .btn--sm { font-size: var(--label-md); padding: .8125rem 36px .8125rem 8px; }

/* ---------- 9 · the flourish ----------
   Hurricane, 1–3 words, decoration and never copy. Optional by the system's
   own rules; it is here because the masthead earns one.

   ⚠️ A LOWERCASE `s` IS ONLY SAFE AT THE START OF A WORD. Hurricane's `s`
   loops back over whatever precedes it, so any `s` with a letter in front of
   it sets as an x.

   This rule read "NO `st` PAIR, EVER" until 2026-08-30 and that was WRONG in
   the dangerous direction — it described the one example that produced it
   ("tastefully curated" reads "taxtefully curated") and would have waved
   through every other break. Rendered in the real face while choosing this
   line, all four of these came back broken and only one is an `st`:

       tastefully -> taxtefully      (s after `a`)
       cohesive   -> cohexive        (s after `e`)
       as         -> ax              (s after `a`)
       lines      -> linex           (s after `e`)

   And these set correctly, because the `s` opens the word:

       sight, set

   ⚠️ SO "no st" IS NOT THE TEST, AND CHECKING A CANDIDATE AGAINST IT PASSES
   BROKEN LINES. "one cohesive room" contains no `st` and is unusable. Set any
   candidate in the face and look at it; the letter is the only proof. */
body.em .flourish {
  font-family: var(--script);
  font-size: clamp(2rem, 3.4vw, 2.875rem);
  line-height: 1;
  color: var(--emerald-mid);
  margin-top: 0.5rem;
}

@media (max-width: 900px) {
  body.em { --sec-pad: 4.75rem; --gut: 1.375rem; }
}
