/* ===========================================================================
   PORTFOLEO — SUPPORTING-PAGE LAYER
   ---------------------------------------------------------------------------
   Shared chrome and page furniture for every marketing/legal/docs page that is
   NOT the home page: /pricing /security /docs /changelog /terms /privacy
   /refund.

   Load order (unchanged, and non-negotiable):
       /fonts/fonts.css -> /css/tokens.css -> /css/base.css
       -> /css/components.css -> /css/pages.css

   RULES THIS FILE OBEYS
     * Consumes design tokens only. Zero raw hex, zero raw px colour, zero
       magic numbers that are not already a token. (Two exceptions, both
       geometry, both commented at the point of use.)
     * Declares no `:root` block — tokens.css is the only token surface, and
       tests/test_design_tokens_sync.py asserts that.
     * References no external host: every url() is a site-root path or a data
       URI, and there is no @import of anything.
     * No emoji.
     * Nothing here requires JavaScript. Every supporting page ships with an
       empty script budget, which is what lets the CSP stay tight and what
       makes the "THIRD-PARTY REQUESTS: 0" claim on /security checkable.

   WHY A SEPARATE FILE FROM `site.css`
     SPEC-DESIGN-SYSTEM.md s9.3 assigns `site.css` to the home page rebuild
     (the hero, the tape, the cold-open). That work is owned by a different
     package. Splitting the shared page furniture out means the two can land in
     either order without either one clobbering the other. `index.html` may
     link this file too — everything in it is page-agnostic.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. SHARED CHROME — TOPBAR
   components.css `.topbar` is itself the flex row and stays transparent until
   `html[data-scrolled]` is stamped by the home page's scroll handler. A
   document page has no cold open to reveal and ships no JS, so it opts into
   the resolved state permanently with `.topbar--solid`.
   --------------------------------------------------------------------------- */
.topbar--solid {
  background: color-mix(in srgb, var(--s-000) 92%, transparent);
  backdrop-filter: var(--blur-chrome);
  box-shadow: inset 0 -1px 0 0 var(--ln-200);
}
.topbar > .wrap {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  width: 100%;
  min-width: 0;
}
.topbar .wordmark { flex: 0 0 auto; }
.topbar nav { flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.topbar nav::-webkit-scrollbar { display: none; }
.topbar nav a[aria-current="page"] { color: var(--t-100); }
.topbar nav a[aria-current="page"]::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 2px;
  background: var(--ac);
}
.topbar .btn { flex: 0 0 auto; }

@media (max-width: 720px) {
  .topbar > .wrap { gap: var(--sp-3); }
  .topbar nav { gap: var(--sp-3); font-size: 13px; }
  .topbar .topbar-cta { display: none; }
}


/* ---------------------------------------------------------------------------
   2. SHARED CHROME — FOOTER
   --------------------------------------------------------------------------- */
.site-footer .foot-grid {
  display: grid;
  gap: var(--sp-6);
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  padding-bottom: var(--sp-6);
}
.site-footer .foot-col h2 {
  font: var(--ti-micro);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
  color: var(--t-300);
  margin-bottom: var(--sp-2);
}
.site-footer .foot-col ul { list-style: none; display: grid; gap: 6px; }
/* WCAG 2.2 SC 2.5.8. Footer link columns are standalone targets and measured
   15px tall on all eight supporting pages — index.html carries its own 26px
   floor in its inline style, so only the shared layer was missing it, and the
   footer is exactly where mobile mis-taps happen because the links sit
   closest together.                                                          */
.site-footer .foot-col a { color: var(--t-200); display: inline-flex; align-items: center; min-height: 24px; }
.site-footer .foot-col a:hover { color: var(--t-100); }
.site-footer .foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-6);
  justify-content: space-between;
  padding-top: var(--sp-4);
  box-shadow: inset 0 1px 0 0 var(--ln-100);
  color: var(--t-300);
}
.site-footer .foot-legal p { max-width: 92ch; }


/* ---------------------------------------------------------------------------
   3. PAGE SKELETON
   --------------------------------------------------------------------------- */
.page {
  padding-block: var(--sp-16) var(--sp-24);
}
.page-head { max-width: 76ch; }
.page-head .eyebrow { display: block; margin-bottom: var(--sp-3); }
.page-head h1 { max-width: 22ch; }
.page-head .lead {
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-body-size);
  line-height: var(--td-body-lh);
  letter-spacing: var(--td-body-track);
  color: var(--t-200);
  margin-top: var(--sp-5);
  max-width: 68ch;
}
.page-head .meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-5);
  font: var(--ti-micro);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
  color: var(--t-300);
}
.page-head .meta b { color: var(--t-200); font-weight: 700; }

.sec { margin-top: var(--section-y); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.sec--tight { margin-top: var(--sp-12); }
.sec > h2 {
  font-size: var(--td-3-size);
  font-variation-settings: "wght" var(--td-3-wght), "wdth" var(--td-3-wdth);
  letter-spacing: var(--td-3-track);
  line-height: var(--td-3-lh);
  padding-bottom: var(--sp-2);
  box-shadow: inset 0 -1px 0 0 var(--ln-300);
  margin-bottom: var(--sp-5);
}
.sec > h2 .n {
  font: var(--ti-nano);
  letter-spacing: var(--ti-nano-track);
  color: var(--ac);
  margin-right: var(--sp-3);
  vertical-align: middle;
}
.sec > h3 {
  margin-top: var(--sp-8);
  margin-bottom: var(--sp-2);
}
.sec > h4 { margin-top: var(--sp-6); margin-bottom: var(--sp-2); }


/* ---------------------------------------------------------------------------
   4. PROSE
   `.doc` and `.legal` are already routed to the sans plane by base.css s2.
   This adds the block rhythm and the list/table treatment those pages need.
   --------------------------------------------------------------------------- */
.doc,
.legal { max-width: 78ch; }
.doc--wide { max-width: none; }
.doc > * + *,
.legal > * + * { margin-top: var(--sp-4); }
.doc ul, .doc ol,
.legal ul, .legal ol { padding-left: var(--sp-5); display: grid; gap: 6px; }
.doc li, .legal li { color: var(--t-200); }
.doc li::marker, .legal li::marker { color: var(--t-400); }
.doc strong, .legal strong { color: var(--t-100); font-variation-settings: "wght" 600, "wdth" 100; }
.doc code, .legal code,
.doc kbd, .legal kbd {
  font: var(--ti-sm);
  color: var(--t-100);
  background: var(--s-200);
  border: var(--bw-hair) solid var(--ln-300);
  border-radius: var(--r-1);
  padding: 1px 5px;
}
.doc h3 + p, .legal h3 + p { margin-top: var(--sp-2); }

.mono-note {
  font: var(--ti-xs);
  color: var(--t-300);
  letter-spacing: var(--ti-xs-track);
}


/* ---------------------------------------------------------------------------
   5. CALLOUTS
   Four kinds, mapped to the semantic tokens. The DRAFT banner is `warn` and
   is deliberately the loudest object on the legal pages.
   --------------------------------------------------------------------------- */
.callout {
  border: var(--bw-hair) solid var(--ln-300);
  border-left-width: 2px;
  border-radius: var(--r-1);
  background: var(--s-100);
  padding: var(--sp-4) var(--sp-5);
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-200);
}
.callout > * + * { margin-top: var(--sp-2); }
.callout .k {
  display: block;
  font: var(--ti-micro);
  font-family: var(--f-mono);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
  color: var(--t-300);
  margin-bottom: var(--sp-2);
}
.callout--warn { border-left-color: var(--warn); background: var(--warn-a10); }
.callout--warn .k { color: var(--warn); }
.callout--down { border-left-color: var(--down); background: var(--down-a10); }
.callout--down .k { color: var(--down); }
.callout--info { border-left-color: var(--info); background: var(--info-a10); }
.callout--info .k { color: var(--info); }
.callout--ac   { border-left-color: var(--ac); background: var(--ac-a08); }
.callout--ac .k { color: var(--ac); }


/* ---------------------------------------------------------------------------
   6. MARKETING TABLES
   The product data table (`.dt`) is a 24px metronome on a pure-black well and
   is the wrong object for a comparison grid that wraps. `.mtbl` is the prose
   table: same hairlines, same no-zebra rule, but it breathes and it scrolls
   inside its own container so the page body never scrolls horizontally.
   --------------------------------------------------------------------------- */
.tbl-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: var(--bw-hair) solid var(--ln-200);
  border-radius: var(--r-1);
  background: var(--s-100);
}
.mtbl { width: 100%; min-width: 520px; font: var(--ti-md); color: var(--t-200); }
.mtbl caption {
  caption-side: bottom;
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  font: var(--ti-xs);
  color: var(--t-300);
  box-shadow: inset 0 1px 0 0 var(--ln-100);
}
.mtbl th {
  background: var(--s-150);
  color: var(--t-200);
  font: var(--ti-nano);
  letter-spacing: var(--ti-nano-track);
  text-transform: uppercase;
  padding: var(--sp-2) var(--sp-4);
  white-space: nowrap;
  box-shadow: inset 0 -1px 0 0 var(--ln-300);
}
.mtbl td {
  padding: var(--sp-2) var(--sp-4);
  vertical-align: top;
  box-shadow: inset 0 1px 0 0 var(--ln-100);
}
.mtbl tbody tr:first-child td { box-shadow: none; }
.mtbl td:first-child { color: var(--t-100); }
.mtbl .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mtbl th.num { text-align: right; }
.mtbl tr.is-us td { background: var(--ac-a08); }
.mtbl tr.is-us td:first-child { box-shadow: inset 2px 0 0 0 var(--ac), inset 0 1px 0 0 var(--ln-100); }
.mtbl tbody tr:hover td { background: var(--s-200); }
.mtbl tbody tr.is-us:hover td { background: var(--ac-a14); }
.mtbl .sub { display: block; font: var(--ti-xs); color: var(--t-300); margin-top: 2px; white-space: normal; }


/* ---------------------------------------------------------------------------
   7. PRICING — THE LADDER
   --------------------------------------------------------------------------- */
.pricing-ctl { position: relative; }
.plans {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  align-items: stretch;
}
.plan {
  display: flex;
  flex-direction: column;
  background: var(--g-card);
  border: var(--bw-hair) solid var(--ln-200);
  border-radius: var(--r-4);
  padding: var(--sp-6);
  min-width: 0;
}
.plan--featured { background: var(--g-card-pos); box-shadow: inset 0 0 0 1px var(--ac-a24); }
.plan--reserve { background: none; border-style: dashed; }
.plan .p-name {
  font: var(--ti-nano);
  letter-spacing: var(--ti-nano-track);
  text-transform: uppercase;
  color: var(--t-300);
}
.plan--featured .p-name { color: var(--ac); }
.plan .p-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--sp-3);
}
.plan .p-amt {
  font-family: var(--f-mono);
  font-size: var(--ti-3xl-size);
  line-height: var(--ti-3xl-lh);
  font-weight: 600;
  letter-spacing: var(--ti-3xl-track);
  color: var(--t-100);
  font-variant-numeric: tabular-nums;
}
.plan .p-per { font: var(--ti-xs); color: var(--t-300); }
.plan .p-sub {
  margin-top: var(--sp-2);
  min-height: 32px;
  font: var(--ti-xs);
  color: var(--t-300);
}
.plan .p-sub b { color: var(--up); font-weight: 500; }
.plan .p-what {
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-200);
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  box-shadow: inset 0 1px 0 0 var(--ln-200);
}
.plan .p-list {
  list-style: none;
  display: grid;
  gap: 6px;
  margin-top: var(--sp-4);
  font: var(--ti-sm);
  color: var(--t-200);
}
.plan .p-list li { display: grid; grid-template-columns: 1fr auto; gap: var(--sp-3); align-items: baseline; }
.plan .p-list .v { color: var(--t-100); font-variant-numeric: tabular-nums; text-align: right; }
/* --t-300, not --t-400. These cells render "0", "Off", "Unsigned", "Blocked on
   licence" — they are the LIMIT ITSELF, i.e. the most commercially loaded
   values on the pricing page, and tokens.css states as a hard rule that
   --t-400 may never render information (it measured 3.73:1 here, under AA).
   --t-300 is 4.86:1 on the card surface and still reads as "this one is off". */
.plan .p-list .v[data-off="1"] { color: var(--t-300); }
.plan .p-foot { margin-top: auto; padding-top: var(--sp-5); }
.plan .p-foot .btn { width: 100%; justify-content: center; }
.plan .p-seats {
  margin-top: var(--sp-3);
  font: var(--ti-micro);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
  color: var(--t-300);
  text-align: center;
}

/* The annual/monthly switch. Pure CSS: two radios, sibling selectors, no JS.
   Both price spans are in the DOM so a screen reader can reach either, and
   the hidden one is display:none rather than opacity so it is not announced
   twice. */
.billing {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-5);
  flex-wrap: wrap;
}
.billing .seg {
  display: inline-flex;
  border: var(--bw-hair) solid var(--ln-300);
  border-radius: var(--r-pill);
  padding: 2px;
  background: var(--s-100);
}
.billing .seg label {
  font: var(--ti-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--t-300);
  padding: 5px 14px;
  border-radius: var(--r-pill);
  cursor: pointer;
  user-select: none;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.billing .seg label:hover { color: var(--t-100); }
.billing .hint { font: var(--ti-xs); color: var(--t-300); }

#bill-yr:checked ~ .billing .seg label[for="bill-yr"],
#bill-mo:checked ~ .billing .seg label[for="bill-mo"] { background: var(--ac); color: var(--on-ac); }
#bill-yr:focus-visible ~ .billing .seg label[for="bill-yr"],
#bill-mo:focus-visible ~ .billing .seg label[for="bill-mo"] { box-shadow: var(--sh-focus-ring); }

.p-yr, .p-mo { display: none; }
#bill-yr:checked ~ .plans .p-yr { display: revert; }
#bill-mo:checked ~ .plans .p-mo { display: revert; }
.p-price .p-yr,
.p-price .p-mo { display: none; }
#bill-yr:checked ~ .plans .p-price .p-yr,
#bill-mo:checked ~ .plans .p-price .p-mo { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }

.savechip {
  font: var(--ti-micro);
  letter-spacing: .08em;
  color: var(--up);
  border: var(--bw-hair) solid var(--up-a45);
  background: var(--up-a10);
  border-radius: var(--r-1);
  padding: 2px 5px;
  white-space: nowrap;
}


/* ---------------------------------------------------------------------------
   8. THE LEDGER — shipped vs building
   --------------------------------------------------------------------------- */
.ledger { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.ledger .col {
  border: var(--bw-hair) solid var(--ln-200);
  border-radius: var(--r-1);
  background: var(--s-100);
  padding: var(--sp-5);
  min-width: 0;
}
.ledger .col h3 {
  font: var(--ti-nano);
  letter-spacing: var(--ti-nano-track);
  text-transform: uppercase;
  color: var(--t-300);
  margin-bottom: var(--sp-3);
}
.ledger .col--now h3 { color: var(--up); }
.ledger .col--next h3 { color: var(--warn); }
.ledger ul { list-style: none; display: grid; gap: 6px; font: var(--ti-sm); color: var(--t-200); }
.ledger li { display: flex; gap: var(--sp-2); align-items: baseline; }
.ledger li .cmd-badge { flex: 0 0 auto; }
.ledger .col .mono-note { margin-top: var(--sp-3); }


/* ---------------------------------------------------------------------------
   9. FAQ — native <details>, no JS, keyboard-operable for free
   --------------------------------------------------------------------------- */
.faq { border: var(--bw-hair) solid var(--ln-200); border-radius: var(--r-1); background: var(--s-100); }
.faq details + details { box-shadow: inset 0 1px 0 0 var(--ln-100); }
.faq summary {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  cursor: pointer;
  list-style: none;
  font-family: var(--f-sans);
  font-variation-settings: "wght" 500, "wdth" 100;
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-100);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before {
  content: "+";
  font: var(--ti-md);
  color: var(--ac);
  width: 1ch;
  flex: 0 0 auto;
}
.faq details[open] > summary::before { content: "\2212"; }  /* U+2212 MINUS SIGN */
.faq summary:hover { background: var(--s-200); }
.faq .a {
  padding: 0 var(--sp-5) var(--sp-5) calc(var(--sp-5) + 1ch + var(--sp-3));
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-200);
  max-width: 76ch;
}
.faq .a > * + * { margin-top: var(--sp-3); }


/* ---------------------------------------------------------------------------
   10. KEY / VALUE BLOCKS  (security facts, sub-processor rows, doc metadata)
   --------------------------------------------------------------------------- */
.kv { display: grid; gap: 0; border: var(--bw-hair) solid var(--ln-200); border-radius: var(--r-1); }
.kv > div {
  display: grid;
  grid-template-columns: minmax(120px, 200px) 1fr;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  box-shadow: inset 0 1px 0 0 var(--ln-100);
}
.kv > div:first-child { box-shadow: none; }
.kv dt {
  font: var(--ti-micro);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
  color: var(--t-300);
  padding-top: 3px;
}
.kv dd {
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-200);
  min-width: 0;
}
.kv dd code { word-break: break-word; }
@media (max-width: 620px) {
  .kv > div { grid-template-columns: 1fr; gap: var(--sp-1); }
}


/* ---------------------------------------------------------------------------
   11. ARCHITECTURE DIAGRAM  (pure CSS + text, no image, no external asset)
   --------------------------------------------------------------------------- */
.flow { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.flow .node {
  border: var(--bw-hair) solid var(--ln-300);
  border-radius: var(--r-1);
  background: var(--s-100);
  padding: var(--sp-4);
  min-width: 0;
}
.flow .node h3,
.flow .node h4 {
  font: var(--ti-nano);
  letter-spacing: var(--ti-nano-track);
  text-transform: uppercase;
  color: var(--t-200);
  margin-bottom: var(--sp-2);
}
.flow .node ul { list-style: none; display: grid; gap: 4px; font: var(--ti-xs); color: var(--t-300); }
.flow .node li::before { content: "\2013\00a0"; color: var(--t-400); }   /* U+2013 EN DASH */
.flow .node--never { border-color: var(--down-a45); background: var(--down-a10); }
.flow .node--never h4 { color: var(--down); }
.flow .node--local { border-color: var(--up-a45); background: var(--up-a10); }
.flow .node--local h4 { color: var(--up); }


/* ---------------------------------------------------------------------------
   12. DOCS INDEX
   --------------------------------------------------------------------------- */
.cards {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.cards a.card { display: block; min-width: 0; }
.cards a.card:hover { background: var(--s-200); text-decoration: none; }
.cards .card .c-body { color: var(--t-300); }

.toc {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: var(--bw-hair) solid var(--ln-200);
  border-radius: var(--r-1);
  background: var(--s-100);
  font: var(--ti-micro);
  letter-spacing: var(--ti-micro-track);
  text-transform: uppercase;
}
/* WCAG 2.2 SC 2.5.8 — a table-of-contents link is a STANDALONE target, so the
   inline-in-a-sentence exception does not apply and the 24px minimum does.
   9px uppercase text gives a 12px box; the padding is what makes it tappable.
   The negative margin keeps the visual row rhythm the padding would otherwise
   loosen, so this costs nothing but reach.                                    */
.toc a {
  color: var(--t-300);
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  margin-block: -6px;
}
.toc a:hover { color: var(--ac); text-decoration: none; }

.taglist { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }


/* ---------------------------------------------------------------------------
   13. CHANGELOG
   --------------------------------------------------------------------------- */
.log { display: grid; gap: var(--sp-8); }
.log .entry {
  display: grid;
  grid-template-columns: 148px 1fr;
  gap: var(--sp-6);
  padding-top: var(--sp-6);
  box-shadow: inset 0 1px 0 0 var(--ln-200);
}
.log .entry:first-child { box-shadow: none; padding-top: 0; }
.log .when { font: var(--ti-sm); color: var(--t-300); font-variant-numeric: tabular-nums; }
.log .when .ver { display: block; color: var(--ac); font: var(--ti-micro); letter-spacing: var(--ti-micro-track); margin-top: 4px; }
.log .what { min-width: 0; }
.log .what h3 { margin-bottom: var(--sp-3); }
.log .what ul { list-style: none; display: grid; gap: var(--sp-2); font: var(--ti-md); color: var(--t-200); }
.log .what li { display: grid; grid-template-columns: 84px 1fr; gap: var(--sp-3); align-items: baseline; }
.log .what li > .badge { justify-self: start; }
@media (max-width: 720px) {
  .log .entry { grid-template-columns: 1fr; gap: var(--sp-3); }
  .log .what li { grid-template-columns: 1fr; gap: 2px; }
}


/* ---------------------------------------------------------------------------
   14. FINE PRINT / SIGNATURE BLOCK
   --------------------------------------------------------------------------- */
.fineprint {
  font: var(--ti-xs);
  color: var(--t-300);
  max-width: 88ch;
}
.fineprint sup { color: var(--ac); }
.placeholder {
  font-family: var(--f-mono);
  font-size: var(--ti-sm-size);
  color: var(--warn);
  background: var(--warn-a10);
  border: var(--bw-hair) dashed var(--warn-a45);
  border-radius: var(--r-1);
  padding: 0 5px;
  /* NOT `white-space: nowrap`. The longest chip on /terms is 30+ characters of
     mono, and nowrap pushed that page's document width to 498px at a 375px
     viewport — a 123px horizontal scroll on every phone. The chip may wrap;
     what it may not do is break inside a word, so the two-value form keeps the
     token intact and only breaks at the spaces the label already has.        */
  overflow-wrap: break-word;
}


/* ---------------------------------------------------------------------------
   15. PRINT — a legal page must print cleanly; base.css already flips the
   palette, this restores the page rhythm on paper.
   --------------------------------------------------------------------------- */
@media print {
  .topbar,
  .toc,
  .site-footer .foot-grid { display: none !important; }
  .page { padding-block: 0; }
  .sec { margin-top: 18pt; break-inside: auto; }
  .sec > h2 { break-after: avoid; }
  .faq details { display: block; }
  .faq details > .a { display: block !important; }
  .callout { break-inside: avoid; }
  .tbl-wrap { overflow: visible; }
  .mtbl { min-width: 0; }
}


/* ---------------------------------------------------------------------------
   16. SIGN-IN — a single centred card, no chrome, no nav
   Its own block because it is the only page on the site that is not a
   document: it has one job and any second element on it is a distraction.
   --------------------------------------------------------------------------- */
.signin-page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
  background: var(--g-desktop);
}
.signin-box {
  width: min(460px, 100%);
  background: var(--g-card);
  border: var(--bw-hair) solid var(--ln-200);
  border-radius: var(--r-4);
  box-shadow: var(--sh-raised);
  padding: var(--sp-10) var(--sp-8) var(--sp-8);
}
.signin-box .wordmark { font-size: 17px; }
.signin-sub { display: block; margin: var(--sp-2) 0 var(--sp-6); }
.signin-copy { max-width: none; margin-top: var(--sp-5); }
.signin-copy p { font-size: var(--td-small-size); line-height: var(--td-small-lh); }
.signin-cta { width: 100%; margin-top: var(--sp-6); }
.signin-foot {
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  box-shadow: inset 0 1px 0 0 var(--ln-200);
  font: var(--ti-xs);
  color: var(--t-300);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: baseline;
}
.signin-foot a { color: var(--t-300); }
.signin-foot a:hover { color: var(--t-100); }
/* The separator is a text node, so --t-400 (documented NON-TEXT ONLY, measured
   3.86:1 here) is the wrong token even for a middot. --t-300 with the dot
   inert to assistive tech is both accessible and quieter.                    */
.signin-foot .sep { color: var(--t-300); }
