/* =============================================================
   v12.css — v1.2 CANDIDATE, THE SQUARING-OFF  (Jul 2026)
   Section 09 of /design-guide. The de-generic refresh: dialled-down
   heading weight, mono retired from label roles, every decorative
   radius removed. Decisions settled 30 Jul 2026; NOT yet promoted.

   HOW TO OPT A PAGE IN — two lines, no markup edits:
     <link rel="stylesheet" href="../assets/css/v12.css">   (LAST in head)
     <body data-v12>

   Load it last so the scoped rules outrank page-inline CSS. It lives in
   assets/css/ rather than design-guide/ on purpose: design-guide.css also
   carries page-inline COPIES of shipped components (.cmp-*, .radar-block,
   .path-card…) so the guide can render them live, and pulling that file
   into a real page would fight that page's own definitions. This file
   contains the scope and nothing else.

   SCOPE: everything below is gated behind [data-v12]. Put the
   attribute on <body> to convert a whole page, or on any wrapper
   to convert a single blade. Nothing here touches a page that
   does not opt in — this is CANDIDATE, not shipped.

   The radius purge works because site.css consumes --radius-*
   TOKENS rather than literals. Overriding the tokens on the scope
   squares buttons, cards, chips, tables, panels, inputs and every
   component that inherits them in one declaration. Only the named
   exceptions below climb back out.
   ============================================================= */

/* -- R1 . Type: weight down, mono out of label roles ----------- */

/* R1b DECIDED: option M2. Montserrat takes every label role (list below);
   mono survives ONLY as data, and that mono becomes IBM Plex Mono.
   The swap is one token: after the label sweep, anything still resolving
   --font-mono is BY DEFINITION a data role, so redefining the token here
   converts code/pre/.mono, the whole .receipt, and the numeric columns in
   one line, with nothing else to chase.
   ^^ SUPERSEDED — see R1b FINAL below. */

/* R1b FINAL: option M1c — "no mono, except code" (type lab, 30 Jul 2026).
   Montserrat does everything, INCLUDING the data surfaces M2 had kept on a
   mono: proof pills, spec tables, metric lines, the receipt. The single
   exception is literal code, which keeps a monospace face because code is
   the one place where character-cell alignment is semantic rather than
   decorative.

   Two options died on the way here, both usefully:
   · M2 (Plex for all data) — the type lab showed Montserrat holding those
     surfaces unaided, and one family used well is a stronger anti-generic
     position than any mono choice.
   · M1 as originally written (code via the platform stack, no webfont at
     all) — code turns out to appear on REAL pages, not just this guide:
     the LayerZero brief and product page, the Pod brief, a blog post and a
     whitepaper. That earns a real face rather than whatever the reader's
     OS happens to ship.

   Two tokens, and they now mean different things:
     --font-mono  → Montserrat. Kept as a token rather than deleted, so the
                    hundreds of existing var(--font-mono) call sites resolve
                    correctly without touching a single one of them.
     --font-code  → IBM Plex Mono, applied ONLY to code/pre/.mono below. */
[data-v12]{
  --font-mono:var(--font-sans);
  --font-code:'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
}
[data-v12] code,[data-v12] pre,[data-v12] .mono{font-family:var(--font-code)}

/* SVG labels. Redefining --font-mono catches every CSS call site, but an SVG
   font-family PRESENTATION ATTRIBUTE is markup, not CSS, so the token cannot
   reach it — and the radar chart on /comparisons hard-codes "JetBrains Mono"
   on two of its labels. CSS beats a presentation attribute, so one rule ends
   it. SVG text is never code, so M1c applies with no exception to carve. */
[data-v12] svg text{font-family:var(--font-sans)}

/* NAME COLLISION, and it matters: <td class="mono"> in the brief tier is a
   NUMERIC DATA CELL that merely shares a class name with the inline code
   marker. It is not code, so it takes Montserrat with its digits held on
   the grid. Worth renaming to td.num at promotion. */
[data-v12] td.mono{font-family:var(--font-sans);font-variant-numeric:tabular-nums}

/* The data surfaces that just lost their monospace keep their digits
   aligned — the one job mono was genuinely doing for them. */
[data-v12] .pf,[data-v12] .receipt,[data-v12] .receipt .rc-row,
[data-v12] .fc-metric,[data-v12] .spec,
[data-v12] .cl-v,[data-v12] .ev-v,[data-v12] .stat .v,
[data-v12] .mc-value,[data-v12] .proof-card .pm,[data-v12] .pb-num{
  font-variant-numeric:tabular-nums;
}

/* R1 FINAL (30 Jul 2026). The weight drop and the tracking pull are ONE
   change, not two — approved together and not separable. Dropping weight
   alone slackens a headline; the tighter tracking is what keeps it set.
   Anyone tempted to take the 600/500 weights without the tracking should
   read row 3 of the type lab's 2c: weight-only is the worst of the four.

   TRACKING FOLLOWS RENDERED SIZE, NOT TAG NAME. A 38px masthead and a 20px
   card heading are both h2-ish in markup and want completely different
   tracking, so the display-scale headings are named explicitly below.

   And the scope must NEVER LOOSEN what a page already tightened. Caught on
   the AI Foundry brief: brief.css sets .mh-title and .af-sec h2 to -.03em,
   but the generic element rules here tie those selectors on specificity and
   win on load order — so the two largest headings on the page were being
   dropped to 600/500 AND relaxed to -.025/-.02em at the same time. That is
   the one combination the whole R1 argument is against. */
[data-v12] .display,[data-v12] h1.display,[data-v12] h1{font-weight:600;letter-spacing:-.03em}
[data-v12] h2,[data-v12] h3,[data-v12] h4{font-weight:500}
[data-v12] h2{letter-spacing:-.02em}
[data-v12] h3{letter-spacing:-.01em}
/* h4 JOINED THE LIST on the site-wide rollout (31 Jul 2026). R1 originally
   named h1–h3 only, because the three test pages have no h4 — the tag turns up
   first in the FOOTER, i.e. on every page, and then on the homepage flywheel
   and the newsletter block. Leaving it out produced the one thing R1 exists to
   prevent: a 16px card heading sitting at 700 directly under a 29px section
   heading at 500. Two carve-outs, both of which are LABELS wearing an h4:
   .foot-cols h4 and .compat h4 are 11–12px uppercase eyebrows, and labels are
   600 everywhere else in this file. */
[data-v12] .foot-cols h4,[data-v12] .compat h4{font-weight:600}
/* Display-scale headlines (30px+): these carry the full -.03em, whether they
   are tagged h1 or h2. .mh-title and .hero h1 already shipped at -.03em —
   these rules keep them there rather than relaxing them. */
[data-v12] .mh-title,[data-v12] .hero h1,
[data-v12] .section-lead h2,[data-v12] .af-sec h2,[data-v12] .th-head h2,
[data-v12] .cta-panel h2,[data-v12] .cta-band h2{
  letter-spacing:-.03em;
}
/* Numerals keep their mass. The proof is the one thing that should
   still shout after the headings stop. */
[data-v12] .mc-value,[data-v12] .proof-card .pm,[data-v12] .pb-num,
[data-v12] .cl-v,[data-v12] .ev-v,[data-v12] .stat .v,[data-v12] .rc-row .v{font-weight:700}

/* -- R1c . THE WEIGHT SWEEP ------------------------------------ */
/* The R1 rules above are ELEMENT selectors ([data-v12] h2 = 0,1,1), so any
   shared-CSS rule that sets a heading weight from TWO classes outranks them
   and the heading silently keeps its v1.1 mass. Exactly the R2b problem in
   another dimension — and the reason the audit has to cover weight too, not
   just radius.

   Note this whole layer is load-order-dependent: a one-class-plus-element
   selector (.af-sec h2, .prose h2, .sc-copy h3, .uc h3, .hero h1) TIES with
   [data-v12] h2 at 0,1,1 and only loses because v12.css is linked last.
   That is why "link it LAST" is a hard requirement, not a style note.

   Found by eye on the AI Foundry brief — "The all-in-one control panel for
   enterprise GenAI." was still landing at 700. Audited across all three
   converted pages afterwards; this is the only offender, everything else
   heavy is either a numeral (correct, R1 keeps those at 700) or inside a
   film (correct, R9 — the pin covers type as well as geometry). */
[data-v12] .claim-ledger .cl-claim{font-weight:500}
/* Second offender, found by the 31 Jul site-wide audit: .leader-card .name
   scores 0,2,0 and held all six leadership portraits' names at 700 while the
   section heading above them sat at 500. Same shape of bug as .cl-claim, same
   fix. Both are now caught mechanically — the weight audit is no longer a
   by-eye check. */
[data-v12] .leader-card .name{font-weight:500}
/* NOT a bug, and worth recording so nobody "fixes" it: /gaia sets an inline
   font-weight:600 on a 13px uppercase h3. That is a LABEL wearing a heading
   tag — the same case as .foot-cols h4 — and 600 is what labels take
   everywhere in this file. Inline styles are also the one thing a scoped
   sheet cannot reach without !important, which is not worth spending here. */

/* Label roles leave JetBrains Mono for Montserrat. Mono survives only as
   DATA: code/pre, the receipt value column, numeric table columns. */
[data-v12] .section-eyebrow,[data-v12] .eyebrow,[data-v12] .eyebrow-pill,
[data-v12] .chip,[data-v12] .art-tag,[data-v12] .news-tag,
[data-v12] .mc-label,[data-v12] .mc-src,[data-v12] .mc-ring-sub,
[data-v12] .cl-k,[data-v12] .cl-src,[data-v12] .ev-k,
[data-v12] .rf-k,[data-v12] .qr-k,[data-v12] .rung .rl,
[data-v12] .gf-head .t,[data-v12] .gf-head .m,[data-v12] .gf-row .p,
[data-v12] .pb-src,[data-v12] .fs-node .k,[data-v12] .rc-title,
[data-v12] .path-metric .pm-label,[data-v12] .path-bar-row .who,
[data-v12] .cmp-toolbar .cmp-note,[data-v12] .cmp-seg button,
[data-v12] .cmp-bar-line .who,[data-v12] .cmp-metric .cl,
[data-v12] .quote-card .q-tag,[data-v12] .radar-note,
[data-v12] .stat .src,[data-v12] .firsts-label{
  font-family:var(--font-sans);
  font-variant-numeric:tabular-nums;
}
/* brief.css label roles — the second half of the M2 sweep, applied once
   Plex was actually installed and it became visible how much of the brief
   tier was still resolving --font-mono. The triage test is the one stated
   in §09 R1b: DOES IT MEASURE SOMETHING? If it names, enumerates or
   navigates, it is a label and it moves to Montserrat.

   Enumerators (.ix capability index, .gn stepper numbers, .sn-no section
   nav) are the interesting case: they are digits, and digits want column
   alignment — but they do not MEASURE, they order. Montserrat plus the
   tabular-nums already set above keeps them aligned, so they move too.

   What deliberately stays on Plex after this: .pf proof pills, td.mono
   numeric cells, .receipt, and code/pre. Every one of those reports a
   number with a unit. That is the whole surface area of mono in v1.2. */
[data-v12] .crumbs,[data-v12] .crumbs a,[data-v12] .crumbs .sep,[data-v12] .crumbs .here,
[data-v12] .sn-link .sn-no,[data-v12] .mh-meta .pill,[data-v12] .opt-tag,
[data-v12] .brief-cols .bh,[data-v12] .brief-cols .x,
[data-v12] .af-layer .ltag,[data-v12] .af-layer .lsub,
[data-v12] .capledger .ix,[data-v12] .gstep .gn,
[data-v12] .fs-edge .lbl,[data-v12] .evidence .ev-basis .lbl,
[data-v12] .tag-pill,[data-v12] .uc .who,[data-v12] .engage-rail .el{
  font-family:var(--font-sans);
  font-variant-numeric:tabular-nums;
}

/* Remaining label roles surfaced by the same pass on /comparisons.
   .vs-head "Typical platform" · .vs-attr .k "Hardware" · the bottom-line
   and callout labels — all name a thing, none measure one. .mock-kpi .k is
   a fake-UI caption, same call. */
[data-v12] .vs-card .vs-head,[data-v12] .vs-attr .k,[data-v12] .mock-kpi .k,
[data-v12] .quad-bottomline .label,[data-v12] .dd-callout .label{
  font-family:var(--font-sans);
  font-variant-numeric:tabular-nums;
}

/* Product-overview pages (products/*.html, page-inline classes).
   .kf-ix is a key-feature enumerator, .fc-tag names a card — both labels.
   Their siblings .fc-metric ("0.70ms p50 · 300+ probes") and .l
   ("15.97% / 14.92%") stay on Plex: those measure. */
[data-v12] .kf-ix,[data-v12] .fc-tag{
  font-family:var(--font-sans);
  font-variant-numeric:tabular-nums;
}

/* Label roles carrying DIGITS, surfaced by the 31 Jul site-wide rollout. The
   --font-mono token already resolves to Montserrat for all of them (R1b), so
   the only thing left to say is tabular-nums — otherwise the homepage story
   numerals and the CSP tier chips lose their column when the face changes. */
[data-v12] .story-num,[data-v12] .story-kick,[data-v12] .pfc-tag,
[data-v12] .os-num,[data-v12] .os-chip,[data-v12] .os-card-eyebrow,
[data-v12] .vl-chip,[data-v12] .lc-pill,[data-v12] .t-chip,
[data-v12] .rung3 .rn,[data-v12] .pm-layer .pm-num,[data-v12] .pm-chip{
  font-variant-numeric:tabular-nums;
}

/* Montserrat uppercase runs wider than JetBrains at equal tracking:
   pull the tracking in a notch, give half a pixel of size back. */
[data-v12] .section-eyebrow,[data-v12] .eyebrow,[data-v12] .eyebrow-pill{
  font-size:11.5px;letter-spacing:.15em;font-weight:600;
}

/* E2 . The square tick: the eyebrow's replacement signature. DECIDED.
   S1 was carried by the FONT. Once the font goes, a mark carries it.
   8px solid square in currentColor, echoing the Grid motif. */
[data-v12] .section-eyebrow{gap:10px}
[data-v12] .section-eyebrow::before{
  content:"";flex:none;width:8px;height:8px;background:currentColor;
}
/* The brief tier and the product-overview pages do NOT use .section-eyebrow —
   they use .af-eyebrow (brief.css). Found by converting bud-ai-foundry.html,
   which has ten of them and zero .section-eyebrow, so E2 was invisible on all
   twelve briefs. Same treatment, one carve-out: where the eyebrow already
   carries a structural section number (.sec-no — sanctioned by adjudication 8),
   the NUMBER is the mark. Doubling up gives "■ 01 · CAPABILITIES", which is
   clutter, so the tick stands down. .pc-eyebrow is a promo-CARD kicker, not a
   section eyebrow, and deliberately gets neither. */
[data-v12] .af-eyebrow{font-family:var(--font-sans);font-size:11.5px;letter-spacing:.15em;font-weight:600;gap:10px}
[data-v12] .af-eyebrow .sec-no{font-family:var(--font-sans)}
[data-v12] .af-eyebrow:not(:has(.sec-no))::before{
  content:"";flex:none;width:8px;height:8px;background:currentColor;
}

/* E1 . The rule tick: NOT ADOPTED. Kept only as an escape hatch if a
   single page needs the quieter mark; do not reach for it by default. */
[data-v12].tick-rule .section-eyebrow::before,
[data-v12] .tick-rule .section-eyebrow::before{width:16px;height:2px}

/* -- R2 . Geometry: the radius purge --------------------------- */
[data-v12]{
  --radius-xs:0;--radius-sm:0;--radius-md:0;--radius-lg:0;
  --radius-xl:0;--radius-2xl:0;--radius-pill:0;
}
/* Bars and tracks are hard-coded 4px in site.css / this file. */
[data-v12] .track,[data-v12] .track .fill{border-radius:0}

/* EXCEPTIONS. Round survives only where it carries meaning.
   1. The light editorial CARDS (blog index, newsroom, whitepapers) are
      explicitly out of scope: their paper-on-dark inversion IS the signature.
   2. Circular controls and status dots. A round dot reads as a state;
      a round card reads as a template. */
[data-v12] .news-card{border-radius:14px}
[data-v12] .news-featured{border-radius:20px}
[data-v12] .news-tag{border-radius:999px}
[data-v12] .story-nav{border-radius:50%}
[data-v12] .art-dot,
[data-v12] .mock-head .dots i,[data-v12] .todo-block .todo-tag::before{border-radius:999px}
/* .bp-doc LEFT THIS LIST on the site-wide rollout (31 Jul 2026). It was here
   as a light editorial card — the blog post used to be a floating white SHEET
   on the dark page, and the sheet was the signature. The Document Band rework
   dissolved it: .bp-doc now carries typography only, on a full-width
   .section[data-theme="light"] band with no background and no frame of its own.
   A 20px radius on an element with nothing to round is dead code, and its
   interior (R2c below) is page components on a site page, not paper. */

/* …but NOT the eyebrow-pill's bullet. That one is a BRAND MARK, not a status
   indicator — it opens a label, it never reports a state — so it squares, and
   it squares into the same mark as the E2 tick. Two devices doing the same job
   should not be different shapes. Sized down from the tick's 8px because it
   sits inside a bordered pill and must not compete with the caps beside it.
   The accent glow stays: it is what makes the mark read as lit rather than
   printed, and it is the one thing carrying over from the round version.
   The distinction to hold: a mark that OPENS something is square (logo,
   eyebrow tick, pill bullet). A dot that REPORTS something stays round. */
[data-v12] .eyebrow-pill .dot{width:6px;height:6px;border-radius:0}

/* R9 DECIDED: films and hero carousels STAY THEIR OWN SURFACE.
   A film is an artifact ON the page, not a region OF it — like a photograph
   or a video, it is entitled to its own frame. It is also the least generic
   surface on the site, so it has the least to gain from the refresh.

   This is not a preference dressed as a rule; it is what the code already
   does. The film and carousel stylesheets are built almost entirely on
   LITERAL radii, not tokens, so the purge cannot reach them:
     film.css 57 literals / 0 tokens · gaia-film 23/0 · novaria-film 19/0
     home-hero-carousel 14/0 · nvh 10/0 · os-film-stack 7/0
     overview-films.css: no radius at all — the 10 overview films are inert
   The one exception is gaia-hero-carousel.css, which uses 10 radius TOKENS
   and would therefore HALF-square: a few tiles going hard while the rest of
   the frame stays round. That is the one outcome worse than either system.

   So the film roots restore the v1.1 radii for their whole subtree. Same
   mechanism as the purge, pointed the other way. If films are converted
   later it is a deliberate hand sweep of ~130 literal declarations across
   eight stylesheets — a separate piece of work, not a side effect. */
[data-v12] .film-blade,[data-v12] .hc-blade,[data-v12] .nvh-blade,
[data-v12] .gah-blade,[data-v12] .sf-stage,[data-v12] .osfilm,
[data-v12] .pf-stage, /* pod film frame: sole token consumer in an otherwise
                         literal-radius film — would half-square without the pin */
/* THE OVERVIEW-FILM STAGES. Added 31 Jul 2026, and this one was a live
   half-square sitting on eight shipped pages, not a hypothetical.
   The ten overview films are each wrapped in a .motif-stage whose frame is
   declared INLINE as border-radius:var(--radius-2xl) — a token — while every
   tile, pill and panel inside them is a literal. So the purge reached the
   FRAME and nothing else: a hard-cornered film box with 9-16px rounded
   contents, which is precisely the outcome adjudication 11 calls worse than
   either system. It slipped through the 30 Jul product-tier rollout because
   the two pages anyone looked at closely, bud-sentry and bud-pod, route their
   film through .sf-stage and .pf-stage and were therefore already pinned.
   The other eight had no pin at all.
   Pinned BY ATTRIBUTE rather than by .motif-stage, deliberately: .motif-stage
   is also the ordinary gridfield section wrapper — four of them on the Agent
   page alone — and those are page content that must stay square. The
   data-*-film hook is what actually marks a stage as a film. */
[data-v12] [data-ag-film],[data-v12] [data-cf-film],[data-v12] [data-ff-film],
[data-v12] [data-lz-film],[data-v12] [data-mf-film],[data-v12] [data-pod-film],
[data-v12] [data-sf-film],[data-v12] [data-hc-film]{
  --radius-xs:4px;--radius-sm:6px;--radius-md:8px;--radius-lg:12px;
  --radius-xl:14px;--radius-2xl:20px;--radius-pill:999px;
}
/* …with one carve-out. .ov-grid is the film's STATIC FALLBACK — what a reader
   actually sees INSTEAD of the film below 980px. That is content, not chrome,
   so it re-purges. Found on products/bud-sentry.html, where the pin was
   otherwise leaving six 14px cards and six 8px icon badges rounded on mobile,
   which is the only breakpoint at which anyone sees them. */
[data-v12] .ov-grid{
  --radius-xs:0;--radius-sm:0;--radius-md:0;--radius-lg:0;
  --radius-xl:0;--radius-2xl:0;--radius-pill:0;
}
[data-v12] .ov-card:hover{transform:none;background:var(--surface-elev)}

/* -- R2b . THE LITERAL SWEEP ----------------------------------- */
/* The token purge above does the bulk of the work, but it can only reach
   CSS that consumes --radius-*. Any layer that hard-codes a radius has to
   be swept by hand, and the sweep is DISCOVERED BY TESTING, not guessed:
   convert a page, then audit for surviving radii. Each block below is
   named by its source file so it stays auditable.

   Half-squaring is the one outcome worse than either system (adjudication
   11), so a page may not be signed off until its audit comes back clean.

   AUDIT SNIPPET — paste in the console on any converted page. It ignores
   status dots (<=14px) and circular controls, and prints what is left.
   NOTE 31 Jul: it now scans `body *`, not `main *`. Scanning main missed the
   nav mega menu — .pm-layer / .pm-chip sat rounded on every converted page for
   a day (see R2c) — and the footer, which is where h4 first appears:
     document.querySelectorAll('body *').forEach(e=>{const b=e.getBoundingClientRect(),
       r=getComputedStyle(e).borderTopLeftRadius; if(r==='0px')return;
       if(b.width<=14&&b.height<=14)return;
       if((r==='50%'||parseFloat(r)>=b.width/2-.5)&&Math.abs(b.width-b.height)<2&&b.width<=48)return;
       console.log(e.className,r)});

   STATUS
     site.css / comparisons.css — token-driven, nothing to sweep.
       /comparisons audited 30 Jul 2026: clean.
     brief.css — 15 literal radii, swept below. Affects all 12 briefs.
     film + carousel css — deliberately NOT swept, see R9 pin. */

/* brief.css — the brief tier (product-briefs/*.html) */
[data-v12] .eyebrow-pill,
[data-v12] .mh-meta .pill,
[data-v12] .opt-tag,
[data-v12] .chip-stat,
[data-v12] .af-stack .af-layer,
[data-v12] .flank,
[data-v12] .gstep .gi,
[data-v12] .plane,
[data-v12] .tag-pill,
[data-v12] .usp,
[data-v12] .uc .ucb,
[data-v12] .promo-card .icon-badge,
[data-v12] .pc-flag{border-radius:0}
/* …but not this one: a circular control. (brief.css re-declares the
   eyebrow-pill dot at 999px too; the square-bullet rule in R2 outranks it
   by specificity, so nothing to re-state here.) */
[data-v12] .th-screen .play-badge{border-radius:999px}

/* Page-inline styles, brief tier — bespoke per-page classes surfaced by the
   30 Jul full-tier rollout audit (each selector names the briefs declaring it):
     .note-vio   violet note card — sentry, agent, cache, layerzero, mcp, pod, sentinel
     .own-tag    "this layer" pipeline-row tag — sentry, cache, sentinel
     .sig        signature pill — cache
     .tier/.ti   value-tier rows — layerzero
     .perim      perimeter stat band — mcp-foundry
     .dl-node/.dl-pipe/.fstep  DiLoCo pipeline + flow steps — model-foundry
     .status-pill  roadmap status chip — sentinel (it LABELS a state in caps,
                   it is not a dot; C1 treatment, same call as .pc-flag) */
[data-v12] .note-vio,[data-v12] .own-tag,[data-v12] .sig,
[data-v12] .tier,[data-v12] .tier .ti,[data-v12] .perim,
[data-v12] .dl-node,[data-v12] .dl-pipe,[data-v12] .flow .fstep,
[data-v12] .status-pill{border-radius:0}
/* Kept round: .term-bar .t-dot (model-foundry) — 10px terminal-chrome dots,
   circular controls per the R2 exception. The Pod page's .pf- and .pfd-
   literals are its overview film — R9, films keep their own surface.
   (Those two prefixes were written here as a glob with a slash between them,
   which closed this comment early and made the CSS parser swallow the whole
   next rule. It cost the R3 button rule silently, and then the R2c mega-menu
   rule below. No asterisk-slash inside a comment, ever.) */


/* -- R2c . THE SITE-WIDE SWEEP (31 Jul 2026) ------------------- */
/* Everything below was surfaced by converting the remaining 60-odd pages —
   the platform tier, /partners, /about, /company/news, the homepage and
   /blog — and auditing each one. It is the same discovery loop as R2b, just
   over the rest of the site, and it confirms the R8 lesson exactly: the token
   purge did the easy 90% on every page, and the work was all in the seams.
   Grouped by SOURCE FILE so each block stays auditable.

   The single most expensive find is first, and it was hiding in plain sight
   on all three original test pages. */

/* site.css — GLOBAL CHROME. .pm-layer and .pm-chip are the Products mega
   menu, which renders on EVERY page including the three signed off on 30 Jul.
   They survived because the R2b audit snippet scans `main *`, and the mega
   lives in <header>. §09 already said to check the mega menu by eye; nobody
   did. The snippet in R2b has been widened to `body *` — see the note there. */
[data-v12] .pm-layer,[data-v12] .pm-chip,
[data-v12] .nav-item > a.nav-current::after{border-radius:0}

/* site.css — decorative marks and motif tiles. Same call as the eyebrow-pill
   bullet in R2: a mark that OPENS something squares. That now includes list
   bullets, which is a harmonisation rather than a change — the blog document
   has set square electric bullets since it was written, and .prose was the
   last place on the site still opening a list with a circle. */
[data-v12] .pm-feats li::before,
[data-v12] .prose ul li::before,
[data-v12] .tool-mess i,[data-v12] .os-grid i,[data-v12] .frag-tile{border-radius:0}

/* os-stack.css — the <bud-os-stack> component, now only on /novaria (Stack
   placement was dropped from the nine product pages on 30 Jul, which is why
   the product-tier rollout never saw this file). Six literals; .os-step is a
   circular CONTROL and keeps its radius, .os-sec-head's leading dot opens a
   label so it squares with the other marks. */
[data-v12] .os-layer,[data-v12] .os-chip,[data-v12] .os-card,
[data-v12] .os-cap,[data-v12] .os-sec-head::before{border-radius:0}

/* partners.css + the partner pages' inline styles. /partners/csp.html is the
   densest page-inline surface on the site — 18 literal declarations, more than
   brief.css carries for the whole brief tier. .ba-knob (slider handle) and
   .os-step above are the only controls in this block; .rung3 .rn and .story-num
   are numeral BADGES, not controls, and square like .promo-card .icon-badge. */
[data-v12] .vladder-rung,[data-v12] .vl-chip,[data-v12] .vl-stat,
[data-v12] .rung3 .rn,[data-v12] .t-chip,[data-v12] .si-client,
[data-v12] .receipt-band,[data-v12] .pull-band,[data-v12] .line-card,
[data-v12] .lc-pill,[data-v12] .alt-wrap,[data-v12] .sup-card,
[data-v12] .stat6,[data-v12] .lmap-row,[data-v12] .cross-strip,
[data-v12] .diff-card,[data-v12] .mfig,[data-v12] .sens-card,
[data-v12] .ba4,[data-v12] .pf-card,[data-v12] .sov-stat,
[data-v12] .commit-strip,[data-v12] .gov-row,
[data-v12] .path-bar-row .track,[data-v12] .path-bar-row .track .fill{border-radius:0}

/* index.html page-inline — the homepage's own components. .fwc-btn (32px
   circular) and .pfc-card::after (a radial glow, not a shape) are the two
   things here that stay round; .fwc-dot is a 26x6 progress PILL, which is the
   exact shape R2 exists to retire. .story-num is the numeral badge above. */
[data-v12] .fwc-dot,[data-v12] .story-sw,[data-v12] .story-num,
[data-v12] .story-stat,[data-v12] .story-reason,
[data-v12] .pfc-tag,[data-v12] .pfc-arrow,[data-v12] .pfc-tab,
[data-v12] .pfc-facts li::before{border-radius:0}

/* gaia/index.html page-inline. .tline is a progress track — same treatment as
   site.css's .track in R2 — and .tline .mk riding it is a circular marker that
   reports a position, so it stays. */
[data-v12] .gs-panel li::before,[data-v12] .tline,
[data-v12] .tline .fill,[data-v12] .chartkey i{border-radius:0}

/* blog.css — THE DOCUMENT BAND INTERIOR. This is the one judgement call in
   the sweep rather than a mechanical find, so the reasoning is on the record:
   the R2 exception protects light editorial CARDS, and until the Document Band
   rework the blog post WAS one — a floating white sheet whose rounded frame
   was the signature. It is now a full-width light band, structurally identical
   to any other .section[data-theme="light"] on the site, which squares. Its
   callouts, phase blocks, figure frames and takeaway panels are therefore page
   components on a site page, and holding them at 10px while the band around
   them goes hard is precisely the half-squaring adjudication 11 forbids.
   The document's own bullets have been square since it was drawn, which is
   what settled it: half of this vocabulary had already made the move.

   Round survives on the two author avatars (.bp-byline .ba, .bp-foot .ph) —
   circular portraits, the same call as any status dot — and on the .news-card
   related-posts grid below the article, which is a card and stays exempt.

   THE LITERAL LIST THAT WAS HERE IS GONE (31 Jul, second pass). The blog
   document was rebuilt from the Claude Design editorial handoff into
   assets/blog-body.css, and that file was written TOKEN-DRIVEN from the first
   line — every radius in it is var(--radius-*), so the R2 purge above reaches
   the whole document with nothing left to sweep. This is what §07's "radius is
   a token, never a literal" buys: a brand-new 500-line stylesheet that cost
   the scope zero maintenance. Only .blog-chip survives here, because the index
   filter bar still lives in blog.css. */
[data-v12] .blog-chip{border-radius:0}

/* -- R3 . Buttons ---------------------------------------------- */
/* DECIDED: square only. The primary keeps its glow — it is the
   one-primary-per-view marker. B2 below is NOT ADOPTED; it survives as a
   per-page escape hatch if the glow ever reads soft against hard corners. */
[data-v12].btn-hard .btn-primary,[data-v12] .btn-hard .btn-primary{
  box-shadow:inset 0 -2px 0 rgba(255,255,255,.28);
}

/* -- R4 . Chips and labels: four replacements for the oval ------ */
/* C1 . Square outline: the direct swap, categorical colour still reads. */
.chip-sq{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-sans);font-size:10.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;line-height:1;
  padding:6px 10px;border-radius:0;
  border:1px solid var(--cat-border,var(--border-strong));
  color:var(--cat,var(--fg2));background:transparent;
}
/* C2 . Solid stamp: filled block, contrasting text. MAX ONE PER VIEW. */
.chip-solid{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-sans);font-size:10.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;line-height:1;
  padding:6px 11px;border-radius:0;border:1px solid transparent;
  background:var(--cat,var(--accent));color:#fff;
}
.chip-solid.on-light{background:var(--fg1);color:var(--bud-midnight)}
/* C3 . Rule label: no box at all. The most editorial, the least
   component-shaped. Default for metadata that is not colour-coded. */
.chip-rule{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--font-sans);font-size:10.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;line-height:1;
  color:var(--cat,var(--fg3));padding:0;border:0;background:none;
}
.chip-rule::before{content:"";flex:none;width:14px;height:2px;background:currentColor}
/* C4 . Edge-tick tag: square, hairline, one thick colour edge.
   Keeps the --cat contract for news / blog category coding. */
.chip-tick{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font-sans);font-size:10.5px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;line-height:1;
  padding:6px 11px 6px 9px;border-radius:0;
  border:1px solid var(--border);border-left:3px solid var(--cat,var(--accent));
  color:var(--cat,var(--fg2));background:var(--cat-fill,transparent);
}

/* Under the scope the shipped chips adopt C1; --cat tags adopt C4. */
[data-v12] .chip{border-radius:0;padding:6px 10px;letter-spacing:.1em}
[data-v12] .art-tag{
  border-radius:0;padding:6px 11px 6px 9px;
  border:1px solid var(--border);border-left:3px solid var(--cat,var(--accent));
}
[data-v12] .filter-chip,[data-v12] .tag-pill,[data-v12] .cmp-chip{border-radius:0}

/* -- R5 . Cards: four square replacements ---------------------- */
/* K1 . Square hairline: the conservative swap. */
.card-sq{
  background:var(--surface);border:1px solid var(--border);border-radius:0;
  padding:24px;transition:border-color var(--duration-md) var(--ease-out-expo),
                          background var(--duration-md) var(--ease-out-expo);
}
.card-sq:hover{border-color:var(--border-strong);background:var(--surface-elev)}
.card-sq h3{font-size:18px;margin:0 0 8px}
.card-sq p{font-size:14px;color:var(--fg2);margin:0;line-height:1.55}

/* K2 . Edge-accent: square plus one THICK structural accent, full-bleed to
   the card edge. Left by default, .top for the metric variant. Replaces
   the 2px hairline top-stripe on .metric-card. */
.card-edge{
  background:var(--surface);border:1px solid var(--border);border-radius:0;
  border-left:4px solid var(--cat,var(--accent));padding:24px 24px 24px 22px;
  transition:border-color var(--duration-md) var(--ease-out-expo),
             background var(--duration-md) var(--ease-out-expo);
}
.card-edge:hover{background:var(--surface-elev)}
.card-edge.top{border-left:1px solid var(--border);border-top:4px solid var(--cat,var(--accent));padding:22px 24px 24px}
.card-edge h3{font-size:18px;margin:0 0 8px}
.card-edge p{font-size:14px;color:var(--fg2);margin:0;line-height:1.55}

/* K3 . Void block: solid Midnight Purple, NO border. Contrast comes from
   the value step, not a hairline. Requires a #120E1C page; on a
   Midnight-Purple section use K1 or K2 instead. */
.card-void{
  background:var(--bud-midnight-purple);border:0;border-radius:0;padding:26px;
  box-shadow:inset 3px 0 0 transparent;
  transition:box-shadow var(--duration-md) var(--ease-out-expo),
             background var(--duration-md) var(--ease-out-expo);
}
.card-void:hover{box-shadow:inset 3px 0 0 var(--cat,var(--accent))}
.card-void h3{font-size:18px;margin:0 0 8px;color:var(--fg1)}
.card-void p{font-size:14px;color:var(--fg2);margin:0;line-height:1.55}

/* K4 . Grid-motif card: the gridfield recipe at card scale.
   MAX ONE PER GRID. The lead card in a set, never the whole set. */
.card-motif{
  position:relative;border-radius:0;border:1px solid var(--border-strong);
  background:var(--motif-bg);overflow:hidden;isolation:isolate;
}
.card-motif>bud-grid{position:absolute;inset:0}
.card-motif .cm-clear{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(120deg,rgba(10,7,18,.96) 0%,rgba(10,7,18,.88) 58%,rgba(10,7,18,.42) 100%);
}
.card-motif .cm-in{position:relative;z-index:2;padding:26px}
.card-motif h3{font-size:18px;margin:0 0 8px}
.card-motif p{font-size:14px;color:var(--fg2);margin:0;line-height:1.55}

/* DECIDED: the hover LIFT retires alongside the radius. A card that rises
   and drops a shadow belongs to the same generic vocabulary as the pill and
   the 14px corner. A border / background step replaces it — and on K3, an
   accent edge arriving on the left. */
[data-v12] .card-hover:hover,[data-v12] .proof-card:hover,
[data-v12] .metric-card:hover,[data-v12] .rung:hover,
[data-v12] .path-card:hover,[data-v12] .pillar:hover,
[data-v12] .story:hover{transform:none}
/* …but the background step is a DARK-card move. Four card variants carry the
   light treatment (near-white #F7F5FC plate, #111 body) — .news-card on the
   blog and newsroom, .rs-card on /research, .cs-card on /case-studies,
   .wp-card on /whitepapers — so --surface-elev (#252134) paints near-black
   under near-black text and the card stops being readable on hover. All four
   keep the border-only hover their own page or stylesheet gives them
   (border-color:--accent plus --shadow-3).
   These are every light card in the repo today; add any new one here too. */
[data-v12] .card-hover:not(.news-card):not(.rs-card):not(.cs-card):not(.wp-card):hover,
[data-v12] .proof-card:hover,
[data-v12] .metric-card:hover{background:var(--surface-elev)}
/* Border-only hover on the news/blog cards — and a PRONOUNCED one, since the
   edge is now carrying the whole signal. A 1px accent hairline was too quiet
   on its own, so it doubles to a 2px edge and throws a soft accent halo.
   Both arrive as box-shadow rings stacked IN FRONT of the card's own
   elevation, which is why the elevation token comes last: a real 2px border
   would shift every card in the grid by a pixel on hover. */
[data-v12] .news-card:hover{
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent),0 0 0 6px rgba(140,51,239,.18),var(--shadow-3);
}
[data-v12] .news-featured:hover{
  box-shadow:0 0 0 1px var(--accent),0 0 0 6px rgba(140,51,239,.18),var(--shadow-4);
}
/* metric-card's 2px top hairline becomes a 4px structural edge (K2 top). */
[data-v12] .metric-card{border-top:4px solid var(--accent)}

/* -- R6 . Tables ----------------------------------------------- */
/* Square arrives from the token purge; the head goes solid so the table
   reads as a ruled document rather than a tinted card. */
[data-v12] .tbl-wrap{border-radius:0}
[data-v12] table.tbl thead th{
  background:var(--bud-midnight-purple);color:var(--fg2);
  font-family:var(--font-sans);letter-spacing:.12em;
  border-bottom:1px solid var(--border-strong);
}
[data-v12] table.tbl td{font-variant-numeric:tabular-nums}


/* Guide-only demo helpers for section 09 live in design-guide/design-guide.css. */
