/* The marketing site's shared shell.
 *
 * `index.html` still carries its own copy of all of this inline, because
 * it was a one-page site and had nowhere to share it with. This file is
 * what the pages added on 2026-08-31 wear, and it is where the shell
 * should end up living for the home page too — that extraction is a
 * follow-up, not something to do in the same change that adds three
 * pages.
 *
 * The `:root` block below is generated. `npm run tokens` stamps it from
 * src/lib/tokens.ts into every file that carries one, and
 * test/tokens.test.mjs fails if any of them has drifted. Do not hand-edit
 * a value here; edit tokens.ts and re-run.
 *
 * Self-hosted faces, same as the home page: the marketing pages hand
 * nothing to a third party, and a font request is a request.
 */

@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('/fonts/inter-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url('/fonts/inter-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('/fonts/inter-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url('/fonts/inter-latin-700-normal.woff2') format('woff2')}
/* The mono family ships all seven weights IBM Plex Mono has, 100 through
   700. The site itself still sets mono at 400 and 500; the rest are here
   because this stylesheet is what `.design-sync/extract-styles.mjs` hands
   to the design system, and only a declared face gets copied into the
   bundle. An undeclared weight is not a weight the design agent can pick,
   and a weight it picks without a face is one the browser synthesizes.
   Declaring a face costs nothing until something asks for it — the files
   are fetched on use, not on load.
   All seven are @fontsource/ibm-plex-mono 5.3.0, latin subset, normal
   style — one family, one release. The 400 was briefly the exception; see
   the note in site/legal.css for why it no longer is. */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:100;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-100-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:200;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-200-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:300;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-300-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url('/fonts/ibm-plex-mono-latin-700-normal.woff2') format('woff2')}

/* Generated from src/lib/tokens.ts — run `npm run tokens` after changing it. */
:root{
  --ink:#12263F;--paper:#FFFFFF;--panel:#EFF4FA;--tint:#EAF2FD;--card:#FFFFFF;
  --rule:#0B63CE;--rule-hover:#094FA6;--mark:#CFE3FA;--on-ink:#9DB4D0;
  --body:#4A5568;--meta:#647085;--border:#DCE4EE;--border-mid:#C3D8EF;
  --band-body:#BCD8F8;--hero-edge:#D2E2F6;
  --verified:#1B6046;--caution:#A9660A;--caution-wash:#FAF0DC;--caution-bg:#FAF0DC;
  --ok:#C9DDF4;--ok-line:#AFCCEC;--legacy:#0B63CE;--legacy-line:#094FA6;
  --ink-soft:#4A5568;--rule-hair:#DCE4EE;--seal:#0B63CE;--seal-wash:#EFF4FA;
  --text-heading:var(--ink);--text-body:var(--body);--text-meta:var(--meta);--text-on-ink:var(--on-ink);
  --text-link:var(--rule);--text-link-hover:var(--rule-hover);--accent:var(--rule);--focus-ring:var(--rule);
  --surface-page:var(--paper);--surface-panel:var(--panel);--surface-card:var(--card);--surface-inverse:var(--ink);
  --border-hairline:var(--border);--border-strong:var(--border-mid);
  --radius:5px;--radius-card:8px;--radius-pill:999px;
  --rule-weight:4px;--rule-weight-caution:5px;
  --frame-marketing:680px;--frame-marketing-wide:1040px;--frame-legal-wide:820px;
  --frame-record:680px;--frame-app:32rem;--frame-app-md:44rem;--frame-app-lg:60rem;
  --measure-read:46rem;--measure-prose:38rem;--measure-legal:72ch;
  --gutter:30px;--gutter-phone:20px;--gutter-wide:40px;--tap-min:44px;
  --space-1:4px;--space-2:8px;--space-3:14px;--space-4:18px;--space-5:22px;
  --space-6:26px;--space-7:32px;--space-8:44px;--space-9:64px;
  --font-weight-regular:400;--font-weight-semibold:600;--font-weight-bold:700;
  --size-label:11px;--size-fine:13px;--size-small:14px;--size-body-record:15px;
  --size-body:16px;--size-body-wide:18px;--size-lede:17px;--size-h3:17px;
  --size-h2-app:20px;--size-h2-app-wide:22px;--size-record-name:24px;
  --size-h2:25px;--size-band:27px;--size-h1:32px;--size-amount:36px;
  --line-tight:1.15;--line-heading:1.3;--line-body:1.6;--line-record:1.7;
  --track-h1:-1.2px;--track-h2:-.5px;--track-h2-app:-.4px;--track-label:.06em;
  --transition-colour:120ms;
  --sans:Inter,system-ui,-apple-system,'Segoe UI',sans-serif;
  --sans-short:Inter,system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--body);
  font-family:var(--sans);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
@media (min-width:768px){body{font-size:18px}}
img{max-width:100%;height:auto}
a{color:var(--rule);text-decoration:underline;text-underline-offset:2px}
a:hover{color:var(--rule-hover)}
:focus-visible{outline:2px solid var(--rule);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important;animation:none!important}}

.frame{max-width:1200px;margin:0 auto;padding:0 40px}
@media (max-width:760px){.frame{padding:0 20px}}
/* Equal top and bottom. It was 40/44, and the last element in a section
   also kept its own bottom margin — a trailing <p> made the gap 59px
   against 41px at the top, which reads as a section that has slumped.
   The margin is dropped here rather than per page: every section on
   the site ends with something, and none of them want the extra. */
section{padding:40px 0}
section > .frame > *:last-child{margin-bottom:0}
.g-paper{background:var(--paper);border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.g-panel{background:var(--panel);border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
/* The third ground: the accent band, centered, white on --rule. It is the
   loudest thing a page can do and pages use it once, for the sentence they
   most want read.
   It was defined in index.html and again in pricing.html, byte-identical,
   and in NEITHER case here — so /record, which carries a `.band` section
   and links only this sheet, has been rendering it as plain dark text on
   plain white since the section was added. Nothing failed; the class just
   resolved to nothing, which is the quiet way this goes wrong. Promoted
   2026-09-02. `.bandgrid` and `.band .count` stay local to index.html:
   they are that page's own two-column layout, not part of the band.
   The centering needs the auto margins as much as the text-align — `p` is
   capped at 70ch above, so without them the text centers inside a box
   still sitting hard left. */
/* Roomier than the sections above it, because it is the last thing on
   every page that carries one and it was set tighter than the prose it
   follows. */
.band{background:var(--rule);padding:56px 0 60px}
.band .frame{text-align:center}
.band h2{color:#fff}
.band p{margin:0 auto;color:#fff;font-size:16px}
/* `.actions` is a flex row, so `text-align:center` on the frame above does
   nothing to it: the button sat at the left edge of a centred 70ch
   paragraph, which is neither centred nor aligned to anything. */
.band .actions{justify-content:center;margin-top:22px}
/* The band is `--rule` and so is `.btn`, so the call to action was a blue
   button on a blue ground -- white text and no button at all. Inverted
   here rather than by putting `.btn.sec` in the markup of all six pages
   that carry a band, so a seventh cannot be added without it. */
.band .btn{background:var(--paper);color:var(--rule)}
.band .btn:hover{background:var(--panel);color:var(--rule)}

/* Nav, grown from four links to seven on 2026-08-31. One line at every
   width down to 320px; two rows below 620px. Never sticky — a page a
   person is reading should not have a bar following them down it. */
/* `.sitenav`, not `nav`. The footer's link groups are `<nav>` landmarks
   too -- they have to be, or the grouping exists only for the eye -- and
   a bare element selector here painted each of them a white box on the
   ink ground. Third time an unscoped element selector has reached
   something new on this site; the others were `details` and `summary`. */
/* Sticky since 2026-09-07, at the owner's request. Nothing about the bar's
   contents or layout changed; only how it sits.

   `sticky`, not `fixed`: the bar keeps its place in flow, so the hero
   still starts below it and no page needed a compensating top margin.

   It stays a positioned element, which matters -- `.navmenu .panel` is
   absolutely positioned and resolves against this box. Swapping
   `relative` for `sticky` keeps that containing block intact.

   z-index 40 clears both things that could cover it: `.mega` at 30 (its
   own child) and `.totop` at 20. The bar opens the mega panel, so it has
   to paint above everything the page can scroll underneath it. */
.sitenav{background:var(--paper);border-bottom:1px solid var(--border);
  position:sticky;top:0;z-index:40}

/* In-page links land below the bar rather than behind it.
   Every `#anchor` on the site scrolls the target to the viewport top,
   which a sticky bar would then cover.

   The bar measures 77px on every page at both widths. 88 is that plus a
   little air, because an anchor landing flush against the bar reads as
   clipped even when it is not. */
html{scroll-padding-top:88px}
.sitenav .frame{display:flex;align-items:center;justify-content:space-between;
  padding-top:16px;padding-bottom:16px;gap:14px}
/* Pulled left so the mark's own edge lines up with the frame, not its
   bounding box -- the lockup carries transparent padding, so aligning the
   box left the logo looking indented against everything below it
   (Design, 2026-08-31). */
.brand{display:inline-flex;flex:0 0 auto;margin-left:-16px}
/* ...but only while the frame has a 40px gutter to spend. Below 760px the
   gutter is 20px, and -16px of it leaves the mark 4px from the screen edge.
   The DC is a single desktop artboard and cannot express this, which is
   exactly the boundary STYLE.md draws: Design owns desktop composition, the
   repo owns every other width. */
@media (max-width:760px){.brand{margin-left:0}}
.logo{height:34px;width:auto;display:block}
/* 24px left the lockup reading as an afterthought beside a 44px Menu
   button. 30px still clears the button plus both gutters at 320px, the
   narrowest width this nav is built for. */
@media (max-width:620px){.logo{height:30px}}
.navlinks{display:flex;flex-wrap:wrap;gap:6px 16px;align-items:center}
/* 500, and the face is hosted for it. With only 400/600/700 available a
   `font-weight:500` snaps to 400 under CSS font matching, so the
   declaration would have read as a change and rendered as none. */
/* `>` and not a descendant selector. Since the plate moved inside
   `.navlinks` (option 1b), a bare `.navlinks a` also claimed every link in
   the panel — including the promoted button, whose white label it repainted
   `--body` on `--rule` blue. These three rules are for the bar's own plain
   links only. */
.navlinks > a{font-size:15px;font-weight:500;color:var(--body);text-decoration:none;padding:8px 10px;
  border-radius:var(--radius);transition:background 120ms,color 120ms;
  min-height:var(--tap-min);display:inline-flex;align-items:center}
.navlinks > a:hover{background:var(--panel);color:var(--ink)}
.navlinks > a[aria-current="page"]{color:var(--ink);font-weight:600}

/* ── The grouped panels ────────────────────────────────────────────
 *
 * Built on <details>, so the bar works with scripting off: a summary is
 * focusable and operable from the keyboard for free, and the panel opens
 * on click. `site/nav.js` adds hover, Escape and closing the others, and
 * the nav is correct before it runs.
 *
 * The panel is positioned against `.sitenav`, which is already
 * `position:relative`, rather than against the summary — so it hangs off
 * the bar's own bottom edge on one line rather than from wherever the
 * word happens to sit.
 */
.navgroup{position:static}
.navgroup > summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;
  gap:6px;min-height:var(--tap-min);padding:8px 10px;border-radius:var(--radius);
  font-size:15px;font-weight:500;color:var(--body);white-space:nowrap;
  transition:background 120ms,color 120ms}
.navgroup > summary::-webkit-details-marker{display:none}
.navgroup > summary:hover,.navgroup[open] > summary{background:var(--panel);color:var(--ink)}
.navgroup > summary:focus-visible{outline:2px solid var(--rule);outline-offset:2px}
/* The group you are inside reads like a current link, because the link
   that would say so is in a closed panel. */
.navgroup[data-here] > summary{color:var(--ink);font-weight:600}

.navgroup .chev{width:8px;height:8px;border-right:1.6px solid currentColor;
  border-bottom:1.6px solid currentColor;transform:translateY(-2px) rotate(45deg);
  transition:transform 120ms}
.navgroup[open] .chev{transform:translateY(1px) rotate(-135deg)}

/* One plate for all three triggers — Design's option 1b, 2026-09-01.
   The `<details>` are empty triggers; the plate is their sibling, shown
   when any of them is open. `:has()` is what makes three triggers drive
   one panel without three copies in the DOM and without needing nav.js
   for the panel to appear at all. */
.navlinks > .mega{display:none;position:absolute;left:0;right:0;top:100%;z-index:30;
  background:var(--paper);border-bottom:1px solid var(--border);
  box-shadow:0 10px 24px rgba(18,38,63,.08)}
.navlinks:has(.navgroup[open]) > .mega{display:block}
/* Three equal reading columns and the promoted task, on the shared
   1120px frame — so the plate's first link sits on the wordmark's edge.
   Hairlines between the groups, not boxes: the columns are one plate. */
/* The bar's own frame — 1200/40, matching `.frame` — not
   `--frame-marketing-wide` (1040), which was the first attempt and set the
   plate 80px inside the wordmark. Design's note is specific about this:
   the panel's first link sits on the wordmark's edge. */
.mega .megainner{max-width:1200px;margin:0 auto;
  padding:26px var(--gutter-wide) 30px;display:grid;gap:0 20px;
  grid-template-columns:1fr 1fr 1fr 300px;align-items:start}
.mega .megacol{padding-right:20px;border-right:1px solid var(--border)}
.mega .megacol:nth-of-type(3){border-right:0}
.mega .megaeyebrow{margin:0 0 10px;padding-left:14px;font-family:var(--sans);
  font-size:var(--size-label);font-weight:700;letter-spacing:var(--track-label);
  text-transform:uppercase;color:var(--meta)}
/* The whole block is one target — label and description together — which
   is what makes a panel this size comfortable to hit.

   `:not(.btn)` on every rule in this group, because the fourth column ends
   in a button and these were reaching it. `.mega a:hover` is (0,2,1) and
   `.btn:hover` is (0,2,0), so the panel's pale hover won the background
   and the button's own `color:#fff` kept the text: white on #EFF4FA,
   about 1.05:1, which is what the owner saw. The layout rules were
   landing on it too — `display:block` over the button's `inline-flex`,
   and 10px/14px over its 11px/20px.

   Excluding rather than overriding: an override would have left the
   button still inheriting a link's box and needing a second rule the next
   time this group grew. A button in this panel is not one of its links. */
.mega a:not(.btn){display:block;padding:10px 14px 11px;border-radius:var(--radius);
  text-decoration:none;transition:background 120ms}
.mega a b{display:block;font-size:16px;font-weight:600;color:var(--ink);
  line-height:1.3}
.mega a span{display:block;margin-top:3px;font-size:14px;line-height:1.45;
  color:var(--meta)}
.mega a:not(.btn):hover{background:var(--panel)}
.mega a:not(.btn):hover span{color:var(--body)}
.mega a:not(.btn)[aria-current="page"]{background:var(--panel)}
.mega a:not(.btn)[aria-current="page"] b{color:var(--rule)}

/* The fourth column is a task, not a destination — the one question a
   visitor has before any other. `--tint` rather than `--panel` so it
   reads as promoted next to three columns of plain paper. */
.mega .megacta{background:var(--tint);border:1px solid var(--border-mid);
  border-radius:var(--radius-card);padding:18px 20px 20px}
.mega .ctaeyebrow{margin:0 0 8px;font-family:var(--sans);font-size:var(--size-label);
  font-weight:700;letter-spacing:var(--track-label);text-transform:uppercase;
  color:var(--rule)}
.mega .ctahead{margin:0 0 6px;font-size:16px;font-weight:600;color:var(--ink);
  line-height:1.3}
.mega .ctabody{margin:0 0 14px;font-size:14px;line-height:1.45;color:var(--meta)}
.mega .megacta .btn{margin:0}

/* Below the frame the promoted card drops under the three groups rather
   than squeezing them; the hairline that separated it goes with it. */
@media (max-width:1120px){
  .mega .megainner{grid-template-columns:1fr 1fr 1fr;gap:0 20px}
  .mega .megacol{padding-right:20px}
  .mega .megacta{grid-column:1 / -1;margin-top:18px}
}
@media (prefers-reduced-motion:reduce){.navgroup .chev{transition:none}}
/* Solid, in the accent. This is the one button in the bar and it is the
   way back in for somebody who already bought: they return to
   wearabledocs.com, the address they were sold at, and the app lives on a
   host they were only ever emailed.
   It was briefly an outlined pill -- my error when this file was
   extracted from the home page's inline styles, and it took over the
   moment that page stopped declaring its own. Restored from
   2bd8575^:site/index.html rather than redrawn. */
.signin{display:inline-flex;align-items:center;min-height:var(--tap-min);
  padding:7px 16px;background:var(--rule);color:#fff;border-radius:var(--radius);
  font-size:14px;font-weight:600;text-decoration:none;white-space:nowrap;
  transition:background var(--transition-colour) ease}
.signin:hover{background:var(--rule-hover);color:#fff}
@media (max-width:620px){
  .sitenav .frame{flex-wrap:wrap;row-gap:8px;justify-content:flex-start}
  .navlinks{gap:4px 10px}
  .navlinks a{font-size:14px;padding:8px}
}

h1{margin:0 0 14px;font-size:32px;line-height:1.12;font-weight:700;letter-spacing:-1.2px;
  color:var(--ink);text-wrap:balance;max-width:20ch}
@media (min-width:768px){h1{font-size:44px}}
h2{margin:0 0 10px;font-size:25px;line-height:var(--line-heading);font-weight:600;letter-spacing:-.5px;
  color:var(--ink);text-wrap:balance}
h3{margin:0 0 8px;font-size:17px;font-weight:600;letter-spacing:-.2px;color:var(--ink)}
p{margin:0 0 14px;max-width:70ch}
/* Emphasis is weight, never slant — the house rule, and now actually the
   house rule. It had been declared in exactly one place, the inline
   <style> in site/index.html, so the home page rendered <em> as bold ink
   and every other page fell through to the browser's italic. /record
   hit this and mirrored it locally as `.step p em`, leaving a note that
   whether the other pages were a bug or a choice was the owner's call.
   Called on 2026-09-02: a bug. Promoted here, where one rule covers every
   page that links this sheet, and the design system's own header stops
   claiming something only the home page did. */
em{font-style:normal;font-weight:600;color:var(--ink)}
/* Same story as `em`, one step worse: `mark` was declared only on the home
   page too, and marketing.css carries no `mark` element rule at all — the
   `.mark` in here is the seal badge's SVG, unrelated despite the name. A
   <mark> on any other page rendered as the browser's default yellow, which
   is why the design system's header had to stop mentioning it. Declared
   here so it means the tint everywhere, and so it can be offered again. */
mark{background:var(--mark);color:var(--ink);padding:1px 3px;border-radius:0}
.eyebrow{margin:0 0 12px;font-family:var(--sans);font-size:var(--size-label);font-weight:700;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--rule)}
/* The "last updated" stamp. Same treatment as the one in legal.css, so a
   page carrying a date looks the same whichever family it belongs to —
   the eyebrow's shape in the meta gray rather than the accent, because it
   is provenance and not a kicker. Added when /engraving and /sms moved
   onto this sheet: /sms in particular has to keep showing a date, since
   that is the page carriers read for opt-in compliance. */
.updated{margin:0 0 4px;font-family:var(--sans);font-size:var(--size-label);font-weight:700;
  line-height:1.4;letter-spacing:var(--track-label);text-transform:uppercase;color:var(--meta)}
.sub{margin:0 0 24px;font-size:15px;color:var(--meta);max-width:70ch}
.lede{font-size:18px;line-height:1.55;color:var(--body);max-width:60ch}
.lede em{font-style:normal;font-weight:600;color:var(--ink)}

/* Plain lists. This sheet had no `ul`/`ol`/`li` rule at all, so a bare list
   on a marketing page fell to the browser's 40px indent and zero item
   spacing while `p` here is on a 14px rhythm — the two never sat together.
   It went unnoticed because nearly every content list on these pages is
   classed (`.pair`, `.flow`, `.states`, `.onscreen`). The nav and footer
   lists reset list-style, margin and padding themselves, so they are
   unaffected by this. */
ul,ol{margin:0 0 14px;padding-left:1.15rem;max-width:70ch}
li{margin:0 0 10px}
li:last-child{margin-bottom:0}

/* A definition list done as `<li><b>term</b> explanation`, two up on wide
   screens and stacked below 860px.
   This lived in TWO page-local <style> blocks — medical-legal.html and
   states.html — under the same name and with different numbers: 20px vs
   18px above, 16px vs 14px of item padding, 1.6 vs 1.55 line height, 6px
   vs 4px under the term. One class, two renderings, and nothing to catch
   it because both pages verified by grep. Promoted here on 2026-09-02 with
   the roomier of the two sets, which is also the one that matches the
   /record body rhythm. Add a third user by using the class, not by copying
   it into a third <style> block. */
.pair{list-style:none;padding:0;margin:20px 0 0;max-width:none;
  display:grid;grid-template-columns:1fr 1fr;gap:0 40px}
.pair li{max-width:62ch;margin:0;padding:16px 0;border-top:1px solid var(--border);
  font-size:16px;line-height:1.6}
.pair li b{display:block;color:var(--ink);margin-bottom:6px}
@media (max-width:860px){.pair{grid-template-columns:1fr}}

.hero{background:var(--tint);border-bottom:1px solid var(--hero-edge);padding:44px 0 40px}

.btn{display:inline-flex;align-items:center;justify-content:center;min-height:46px;
  padding:11px 20px;background:var(--rule);color:#fff;text-decoration:none;
  font-weight:600;font-size:16px;border:0;border-radius:var(--radius);cursor:pointer;
  transition:background 120ms}
.btn:hover{background:var(--rule-hover);color:#fff}
.btn.sec{background:#fff;color:var(--rule);border:1px solid var(--border-mid)}
.btn.sec:hover{background:var(--panel)}

/* A row of actions: a primary button beside a quieter one or a text link.
 *
 * These lived in index.html's own <style> until 2026-09-01, which meant
 * `class="actions"` got no layout at all on any other page — /record and
 * /pricing both carried it and both rendered their buttons jammed against
 * the block above with no gap. Silently unstyled markup is exactly what a
 * shared vocabulary is supposed to prevent, so the reusable part lives
 * here now and the design system's claim is true on every page.
 *
 * What deliberately did NOT move: the hero's `padding-bottom`, which is
 * keyed to viewport HEIGHT (max-height 860/760) to fit the hero on one
 * phone screen. That is hero furniture, not part of this idiom, and it
 * stays in index.html. Spacing above a row is the page's business too. */
.actions{display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.link-action{display:inline-flex;align-items:center;min-height:44px;color:var(--rule);
  text-decoration:none;font-size:16px;border-bottom:2px solid var(--rule);
  padding-bottom:2px;transition:color 120ms,border-color 120ms,background 120ms}
.link-action:hover{color:var(--rule-hover);border-bottom-color:var(--rule-hover)}
/* On a phone the two controls stop being a row: side by side at 390px each
   would be too narrow to read, so they stack and fill the measure, and the
   text link takes a button's box so both targets are the same size. */
@media (max-width:619.98px){
  .actions{flex-direction:column;align-items:stretch;gap:12px}
  .actions .btn{width:100%;align-self:stretch}
  .actions .link-action{width:100%;justify-content:center;min-height:46px;
    padding:11px 20px;background:var(--paper);border:1px solid var(--border-mid);
    border-radius:var(--radius)}
  .actions .link-action:hover{background:var(--panel);border-color:var(--border-mid)}
}

/* `blockquote` shares the statute treatment. There was no blockquote rule
   in either stylesheet, so /sms — where the blockquotes are the exact
   opt-in wording and the exact message text, the things a carrier reads
   the page to check — rendered them as a browser-default indent,
   indistinguishable from the prose quoting them. The element is kept
   rather than swapped for `<div class="statute">`: it is the semantically
   right tag for reproduced wording, and a reviewer reading the markup
   should find it. Both invoke one treatment, so they cannot drift.
   Note this ground is --panel, so a quote inside a `.g-panel` section
   disappears. Put quoting sections on `.g-paper`. */
.statute,blockquote{background:var(--panel);border-left:4px solid var(--rule);padding:20px 24px 22px;
  border-radius:0 var(--radius) var(--radius) 0}
blockquote{margin:0 0 14px;font-size:16px;line-height:1.55;letter-spacing:-.1px;
  color:var(--ink);max-width:none}
.statute p{margin:0;font-size:16px;line-height:1.55;letter-spacing:-.1px;color:var(--ink);max-width:none}
.statute p+p{margin-top:12px}
.statute .cite{margin-top:12px;font-family:var(--sans);font-size:var(--size-label);font-weight:700;letter-spacing:var(--track-label);
  text-transform:uppercase;color:var(--meta)}

/* The footer, in columns.
 *
 * Eleven links in a single row was right for a one-page site and became a
 * wall at seven pages. Grouped by what the reader is doing, with the
 * inverse wordmark: `logo-white.png`, cropped to the same 459x85 ink box
 * as the colour mark, so the two take identical `height:` values.
 *
 * The column titles are real headings inside real `<nav>` landmarks — the
 * groups have to exist for a screen reader too, or they are decoration.
 */
footer{background:var(--ink);color:var(--on-ink);padding:44px 0 36px}
footer a{color:#fff;text-decoration:none}
footer a:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
.fgrid{display:grid;grid-template-columns:1.6fr repeat(4,1fr);gap:32px 34px;align-items:start}
.fbrand img{height:30px;width:auto;display:block;margin-bottom:14px}
.fbrand p{margin:0;font-size:14px;line-height:1.6;color:var(--on-ink);max-width:34ch}
/* The column titles sit above their links, so they have to outrank them.
   At 11px they were smaller than the 13px links and the hierarchy read
   backwards -- a label under-set beneath the list it names. */
/* Inter, not the mono, from 2026-08-31. The tracking came down from .6px
   with it: a monospace at that size needs the letters opened up and a
   proportional face does not -- carrying the same spacing across would
   have made these read as spaced-out capitals rather than as titles. */
.fcol h2{margin:0 0 10px;font-family:var(--sans);font-size:14px;font-weight:600;
  letter-spacing:.2px;text-transform:uppercase;color:#fff}
.fcol ul{list-style:none;margin:0;padding:0;display:grid;gap:0}
/* Tight by default, 44px where a finger is involved.
   `min-height: var(--tap-min)` on every link made each row 44px tall and
   the columns read as a list of buttons rather than a list of links.
   STYLE.md's floor is about *tap* targets, so it is applied on coarse
   pointers -- phones and tablets -- and the desktop rows close up. */
/* Weights declared rather than inherited. Both were arriving at 600 on the
   home page and 400 elsewhere; stating them here settles it. (The original
   note here added that the mono only declared its 400, so 600 titles were
   synthesized. That constraint is gone -- all seven mono weights ship as of
   2026-09-02 -- but the titles are Inter now and the rule stands on its own
   reason: an inherited weight that differs by page is not a weight.) */
.fcol a{padding:3px 0;font-size:12px;font-weight:400;line-height:1.6;
  display:flex;align-items:center}
@media (pointer:coarse){
  .fcol a{min-height:var(--tap-min);padding:6px 0}
}
.fbase{margin-top:38px;padding-top:22px;border-top:1px solid rgba(255,255,255,.14);
  display:grid;gap:8px}
/* 11px, and it stays 11px on a phone — the one place in the footer that
   does not step up at 620px. It is the quietest line on the site by
   intent. */
footer small{display:block;max-width:80ch;font-size:11px;line-height:1.6;color:var(--on-ink)}
@media (max-width:1040px){.fgrid{grid-template-columns:1fr 1fr 1fr}
  .fbrand{grid-column:1 / -1;max-width:none}}
/* Two columns all the way down to 320px rather than one. Four groups of
   three stacked single-file made the footer 1,116px tall on a phone,
   which is a scroll of its own after the page it is closing. */
/* The phone footer carries the desktop's language -- brand block, uppercase
   titles over their links, hairline base -- at a scale that suits a hand.
 *
 * The reason it needed its own sizes: on a coarse pointer every link becomes
 * a 44px row (STYLE.md's tap floor, and not negotiable), and 13px text
 * sitting in a 44px row reads as small type adrift in a large gap. Growing
 * the type fills the row that accessibility already bought, so the lists
 * read as groups rather than as loose lines. Titles move with them, staying
 * a step above the links -- the same relationship desktop has, and the one
 * the note above this block is about.
 *
 * The row gap goes up too: at 26px the space between "Price" and "HELP"
 * matched the space between links, so the four groups ran together into one
 * column of text. */
@media (max-width:620px){.fgrid{grid-template-columns:1fr 1fr;gap:34px 20px}
  .fbrand img{height:36px;margin-bottom:16px}
  .fbrand p{font-size:15px}
  .fcol h2{font-size:15px;margin-bottom:6px}
  /* 14px, not 15px: at 15px "Engraving requirements" wraps to two lines in a
     165px column and that group alone grows a row, tipping the 2x2 grid out
     of alignment. The longest label is what sets this. */
  .fcol a{font-size:14px}}

@media print{
  nav,footer,.btn{display:none}
  body{background:#fff;color:#000;font-size:11pt}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:9pt}
}

/* The menu, below 980px.
 *
 * Seven links stopped fitting the moment the site became more than one
 * page, and wrapping them to two rows made the bar taller than the thing
 * it sits above. So below 980px they collapse behind a button -- measured
 * rather than picked: at 900px the row was already touching the logo.
 *
 * **No JavaScript.** `<details>` is a disclosure with a real button, a
 * real focus ring and keyboard behaviour the browser already implements,
 * and the site still loads exactly one script -- Turnstile, for the
 * contact form. A menu is not a reason to load a second.
 *
 * Two lists rather than one that morphs, which is what the app does for
 * the same reason: a closed `<details>` hides its own content, and
 * forcing that back open at desktop widths depends on details of the UA
 * stylesheet that have changed more than once. Two structures, one
 * shown at a time, and a test asserts they carry the same links.
 */
.sitenav .navmenu{display:none;border:0;padding:0;margin:0}
.navmenu > summary{list-style:none;cursor:pointer;display:flex;align-items:center;
  gap:10px;min-height:var(--tap-min);padding:8px 12px;border:1px solid var(--border-mid);
  border-radius:var(--radius);color:var(--body);font-size:15px;font-weight:600}
.navmenu > summary::-webkit-details-marker{display:none}
.navmenu > summary:focus-visible{outline:2px solid var(--rule);outline-offset:2px}
/* Two bars and a box-shadow standing in for the third, so the whole
   glyph is one element that can rotate into a cross when it opens. */
.navmenu .glyph{flex:0 0 auto;width:20px;height:14px;position:relative}
.navmenu .glyph::before,.navmenu .glyph::after{content:"";position:absolute;left:0;right:0;
  height:2px;background:var(--ink);transition:transform 120ms,top 120ms,bottom 120ms}
.navmenu .glyph::before{top:0;box-shadow:0 6px 0 var(--ink)}
.navmenu .glyph::after{bottom:0}
.navmenu[open] .glyph::before{top:6px;transform:rotate(45deg);box-shadow:none}
.navmenu[open] .glyph::after{bottom:6px;transform:rotate(-45deg)}
.navmenu .panel{position:absolute;left:0;right:0;top:100%;z-index:20;
  background:var(--paper);border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);box-shadow:0 10px 24px rgba(18,38,63,.08)}
.navmenu .panel ul{list-style:none;margin:0;padding:6px 0 10px}
.navmenu .panel a{display:block;padding:13px 40px;font-size:16px;color:var(--body);
  text-decoration:none;border-left:3px solid transparent;min-height:var(--tap-min)}
.navmenu .panel a:hover{background:var(--panel);color:var(--ink)}
.navmenu .panel a[aria-current="page"]{color:var(--ink);font-weight:600;border-left-color:var(--rule)}
.navmenu .panel .sep{margin:6px 0 0;padding-top:10px;border-top:1px solid var(--border)}
/* The phone menu carries the same groups as the bar, but as headings —
   it is already inside a disclosure, and nesting a second one would make
   every link two taps away. */
.navmenu .panel .grp > h2{margin:14px 0 2px;padding:0 40px;font-family:var(--sans);
  font-size:var(--size-label);font-weight:700;letter-spacing:var(--track-label);text-transform:uppercase;
  color:var(--meta)}
.navmenu .panel .grp ul{padding:0}
@media (max-width:760px){.navmenu .panel .grp > h2{padding:0 20px}}
@media (max-width:980px){
  /* `nav .navlinks`, not `.navlinks`. A media query adds no specificity,
     so the bare class here ties with any `.navlinks{display:flex}` a host
     page declares -- and loses to it on source order, because this
     stylesheet is linked before the page's own <style>. That is exactly
     what happened on the home page: the links and the button both showed
     at 390px. The descendant selector wins the tie honestly. */
  .sitenav .navlinks{display:none}
  .sitenav .navmenu{display:block}
  .sitenav .frame{flex-wrap:nowrap;justify-content:space-between}
  /* The pill duplicates the menu's last item at this width and costs the
     row the space the button needs. */
  .sitenav > .frame > .signin{display:none}
}
@media (max-width:760px){.navmenu .panel a{padding-left:20px;padding-right:20px}}

/* Sections that moved off the home page, 2026-08-31.
 *
 * `/how`, `/faq` and `/contact` were three sections of one very long
 * page — 6,034px of an 11,913px phone scroll between them. They are
 * pages now, and their styles live here rather than in each page's own
 * <style>, and because a site stylesheet is where a site's sections
 * belong.
 *
 * The seven steps stack in one column at every width (2026-08-31). They are
 * a sequence, so one column reads top to bottom the way the numbers do;
 * three across made the reader scan in rows instead. `.faq` is still the
 * grid that narrows at the breakpoints below.
 */
.steps { list-style: none; padding: 0px; margin: 0px; display: grid; grid-template-columns: 1fr; gap: 0px; }
.steps li { counter-increment: s 1; position: relative; padding: 20px 24px 22px; border-top: 1px solid var(--border-mid); }
.steps li:first-child { border-top: 0px; }
.steps .n { font-family: var(--sans); font-size: var(--size-label); color: var(--rule); display: block; margin-bottom: 8px; }
.steps span { color: var(--body); font-size: 16px; line-height: var(--line-body); display: block; }

.faq { display: grid; grid-template-columns: 1fr 1fr; gap: 0px 26px; }

.contact { display: grid; grid-template-columns: minmax(0px, 0.9fr) minmax(0px, 1.1fr); gap: 0px 64px; align-items: start; }
.contact .kv { margin: 0px; font-size: 16px; }
.contact .kv div { padding: 12px 0px; border-top: 1px solid var(--border-mid); }
.contact .kv dt { font-family: var(--sans); font-size: var(--size-label); font-weight: 700; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--meta); margin: 0px 0px 4px; }
.contact .kv dd { margin: 0px; color: var(--ink); }
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form label { display: block; }
.form label.wide { grid-column: 1 / -1; }
.form span { display: block; font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.form input, .form select, .form textarea { width: 100%; padding: 0.8rem 0.9rem; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; font-family: var(--sans); font-size: 16px; border: 1px solid var(--border-mid); border-radius: var(--radius); background: var(--paper); color: var(--ink); min-height: 48px; }
.form textarea { min-height: 140px; resize: vertical; line-height: 1.55; }
.form .send { grid-column: 1 / -1; display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.form .send .btn { align-self: auto; }
.form .send small { font-size: 13px; color: var(--meta); max-width: 42ch; line-height: 1.5; }

@media (max-width: 1180px) {
  .contact { grid-template-columns: 1fr; gap: 28px; }
}

@media (max-width: 760px) {
  .form { grid-template-columns: 1fr; }
}

/* Scoped to the FAQ on 2026-08-31. These were bare element selectors
   from when the only <details> on the page was a question, and the day
   the nav grew a menu they put a hairline and 28px of padding around
   the button. A page can have more than one kind of disclosure. */
.faq details { border-top: 1px solid var(--border-mid); padding: 14px 0px; }
.faq summary { cursor: pointer; font-size: 17px; font-weight: 600; color: var(--ink); list-style: none; min-height: 44px; display: flex; align-items: center; }
.faq summary::-webkit-details-marker { display: none; }
.faq details p { margin: 6px 0px 0px; font-size: 15px; line-height: var(--line-body); }

.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

@media (max-width:1180px){.faq{grid-template-columns:1fr 1fr}}
@media (max-width:760px){.faq{grid-template-columns:1fr}}

/* Back to top. The nav scrolls away and the page is long, so this is the way
   back to it.

   NO JAVASCRIPT: the page ships zero <script> tags and this does not change
   that. It is an ordinary anchor to #top on the nav, so it works with
   scripting off, and it is a real link — middle-click, keyboard and
   right-click all behave the way a link should.

   Showing it only after scrolling is the one part that normally needs JS.
   Done here with a scroll-driven animation instead, wrapped in @supports:
   where that is unsupported the button is simply always there, which is the
   correct thing to degrade to. Under reduced motion it is always there too,
   and the jump is instant rather than smooth. */
html{scroll-behavior:smooth}

.totop{position:fixed;right:24px;bottom:24px;z-index:20;
  width:48px;height:48px;                     /* --tap-min is 44; this clears it */
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--radius-pill);
  background:var(--rule);color:var(--paper);
  border:1px solid rgba(255,255,255,.18);
  box-shadow:0 2px 4px rgba(18,38,63,.16),0 8px 20px rgba(18,38,63,.18);
  transition:background var(--transition-colour) ease,transform var(--transition-colour) ease}
.totop:hover{background:var(--rule-hover);color:var(--paper)}
.totop:active{transform:translateY(1px)}
.totop:focus-visible{outline:2px solid var(--rule);outline-offset:3px}

@supports (animation-timeline: scroll()){
  .totop{animation:totop-in linear both;animation-timeline:scroll(root block);
    animation-range:120px 420px}
  @keyframes totop-in{
    from{opacity:0;visibility:hidden}
    to{opacity:1;visibility:visible}
  }
}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .totop{animation:none;opacity:1;visibility:visible}
}
@media(max-width:620px){.totop{right:16px;bottom:16px}}

/* The Let's Seal badge.
 *
 * Their usage rules, followed rather than paraphrased:
 *
 *   "Always make the badge open the live verdict."
 *   "Don't present the badge as proof on its own. A copied image is not
 *    a seal."
 *   "Don't imply notarization or that identity was verified. A seal
 *    proves integrity + time, not who."
 *   Trust Blue #2563eb, clear space >= half the mark's height, paired
 *   with the fingerprint or a /d/<hash> link.
 *
 * So this is never a bare graphic. It is a link to a real proof page,
 * carrying the root it belongs to, and the copy beside it says what a
 * seal proves and what it does not.
 *
 * **#2563eb is not in our palette and is not meant to be.** It is
 * somebody else's brand mark, held to their colour on purpose, the same
 * way a payment mark or an app-store badge is. Do not "fix" it to
 * --rule; a badge repainted in the host's accent is a badge that no
 * longer means anything. It is the only hard-coded colour in this file.
 */
.sealbadge{display:flex;gap:18px;align-items:flex-start;
  padding:20px 22px;background:var(--paper);
  border:1px solid var(--border-mid);border-radius:var(--radius-card)}
.sealbadge .mark{flex:0 0 auto;width:44px;height:44px;margin:11px}  /* clear space = half */
.sealbadge .body{min-width:0}
.sealbadge b{display:block;font-size:16px;color:var(--ink);margin-bottom:4px}
.sealbadge p{margin:0 0 10px;font-size:15px;line-height:var(--line-body);color:var(--body);max-width:56ch}
.sealbadge .hash{display:block;font-family:var(--mono);font-size:12px;color:var(--meta);
  overflow-wrap:anywhere;margin-bottom:10px}
/* The anchor's state, as a fact beside the hash rather than a clause in
   the sentence — the same shape the holder's own history page uses. It
   reads `--meta` while the transaction is still confirming and `--verified`
   once a block holds it, so the badge changes weight when the claim gets
   stronger rather than changing its wording. */
.sealbadge .anchor{display:block;margin:2px 0 10px;font-family:var(--sans);
  font-size:12px;color:var(--verified)}
.sealbadge .anchor.waiting{color:var(--meta)}
.sealbadge a.verify{font-size:15px;font-weight:600}
.sealbadge .pending{font-size:15px;color:var(--meta)}
@media (max-width:560px){.sealbadge{flex-direction:column;gap:10px}
  .sealbadge .mark{margin:0 0 4px}}

/* ── The comparison table ─────────────────────────────────────────
 *
 * Shared, since 2026-09-01. It lived in site/index.html's inline
 * <style> until a second copy of the table went onto /pricing and the
 * markup arrived there unstyled. Two copies of the CSS would have been
 * a second thing to keep in step, so it moved here and the markup is
 * generated by scripts/sync-compare.mjs. Neither half is duplicated now.
 */
.cmp-wrap { overflow-x: auto; margin: 22px 0 0; }
.cmp { border-collapse: collapse; width: 100%; min-width: 680px; font-size: 15px; }
.cmp th, .cmp td { padding: 14px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--border); }
.cmp thead th { font-family: var(--sans); font-size: var(--size-label); font-weight: 700;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--meta);
  border-bottom: 1px solid var(--border-mid); }
.cmp tbody th { width: 36%; font-weight: 600; color: var(--ink); }
.cmp .note { display: block; margin-top: 3px; font-size: 13px; font-weight: 400;
  line-height: 1.45; color: var(--meta); }
.cmp .us { background: var(--panel); }
.cmp thead .us { color: var(--ink); font-weight: 600;
  border-top: var(--rule-weight) solid var(--rule); }
.cmp .mark-y, .cmp .mark-n { display: inline-flex; align-items: center;
  justify-content: center; width: 30px; height: 30px; margin-right: 9px;
  border-radius: var(--radius); color: #fff; font-size: 19px; font-weight: 700;
  line-height: 1; vertical-align: -9px; }
.cmp .mark-y { background: #15A34A; }
.cmp .mark-n { background: #DC2626; }
.cmp .cost { color: var(--ink); font-weight: 600; }
.cmp .cost .note { font-weight: 400; }
.cmp-cue { display: none; }
.cmp { min-width: 620px; }
.cmp th, .cmp td { padding: 12px 14px; }
.cmp tbody th { width: 34%; }
.cmp-cue { display: block; margin: 14px 0 0; font-family: var(--sans);
    font-size: var(--size-label);font-weight:700; letter-spacing: var(--track-label); text-transform: uppercase;
    color: var(--meta); }
@media (max-width: 760px) {
  .cmp { min-width: 620px; }
  .cmp th, .cmp td { padding: 12px 14px; }
  .cmp tbody th { width: 34%; }
  .cmp-cue { display: block; margin: 14px 0 0; font-family: var(--sans);
    font-size: var(--size-label);font-weight:700; letter-spacing: var(--track-label); text-transform: uppercase;
    color: var(--meta); }}
