/* ═══ FROZEN Sunday 2026-09-06 12:00 for the parallel build. Deadline Tuesday 2026-09-08.
   Only Terminal A edits this file. Gaps found while building pages go to _ref/GAPS.md,
   one line each, and are worked through in batches. See _ref/PARALLEL-BUILD.md. ═══ */
/* ═════════════════════════════════════════════════════════════════════════════
   BRUTOR 2026 - THE MASTER STYLESHEET.  v6 - 2026-09-04
   One sheet for every page and every component. Pages link it; the WordPress header and
   footer snippets use the same classes. Nothing page-specific belongs here.

   THIS FILE IS THE SPECIFICATION. There is no separate web brand book: the brand book is the
   brand book, and this is the stylesheet that implements it. Every rule lives beside the code it
   governs - colour ramps, line weights, textures, icons, bullets, numbers, eyebrows, spacing.
   If a value is not in here it does not exist, and nothing in here was invented: it is either a
   documented Tandem value or a ruling of Veronika's, and each is marked as such.

   SOURCES, in order of authority
     1. Veronika's rulings.
     2. Tandem's design sheets: Web Design and Assets > 00-SPECS > "Web style guidelines
        from Tandem" (Brand, Button, Card, Colors, Header, Header & Footer, Icons,
        Navigation, Page Layout, Patterns & Textures, Schematics, Typography).
     3. The Home Screen 3rd-iteration frame.
   Every Tandem sheet has been read into this file. Where a ruling differs from a sheet, the
   ruling is what is coded and the sheet's own value is named beside it.

   IF A STYLE DOES NOT EXIST YET, SAY SO. A page that needs something this sheet has no style
   for - a complicated workflow, a schematic that is more than boxes and lines, a chart - is not
   a licence to improvise. Name what is missing, agree a style, add it here, then build. The style
   supports the message; it is never invented under deadline.

   HOW TO READ IT. This is a finished system, not a list of differences from anything. Every
   value below stands on its own. Where a value came from a Tandem sheet it is marked (Tandem);
   where it came from a decision taken during the build it is marked (ruling), with the sheet's
   own figure named beside it so nothing is lost. Both kinds are equally binding.

   CONTENTS
     0  knobs and tokens - the page frame, the colour ramps, radii, shadows, rhythm
     1  base and the page frame - .page, .wrap, the tractor-feed edges
     2  type - the ladder, eyebrows, emphasis, numbers
     3  buttons - variants, sizes, states
     4  sections and grounds - the four textures, dividers, the grid
     5  strap and header - cells, chevrons, mega menus, mobile navigation
     6  hero and stats
     7  cards and rows - light, dark, bone, blog, video, tags
     8  schematics - the frame, the information cards, connectors
     9  CTA and footer
    10  forms - fields, choices, toggles
    11  content elements - pills, tables, callouts, figures, quotes, prose
    12  motion and scroll reveal
    13  utilities

   PAGE FRAME KNOBS (section 0)
     --page-max    none = content spans the window (current ruling); 1400px = a centred page
     --page-pad    page edge to content edge: where the logo starts and Book Demo ends
     --margin-bg   ground outside the page when --page-max is set
     --margin-rule border on the page's left/right edges (none | 1px solid ...)
   Set these once (WordPress: Additional CSS) and every page follows.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ═════════════════════════════════════════════════════════════════════════════
   THE CONTRACT IS ENFORCED (Veronika 2026-09-07: "run all pages, new or existing, through it and it
   will result in a perfect page every time"). scripts/audit-page.py renders a page in a real browser
   and measures EVERY element against this sheet: the content column (a frame's shadow ends on the
   edge, never past it), the one frame rule, the type ladder, the palette, buttons, section grounds
   and rhythm, images (never upscaled, illustrations 8:5, alt text), hygiene (one h1, no inline
   styles, no em dashes, no text arrows). scripts/deploy-page.sh runs it after every push and a
   violation is a failed deploy. When a value here changes, the audit's number changes in the same
   commit. A page is never fixed by hand: the sheet or the fragment is.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────── 0. KNOBS + TOKENS ───────────────────────── */
:root{
  /* page frame */
  --page-max: none;
  --page-pad: 48px;
  --page-bg: #FFFFFF;       /* RULING 2026-09-08: the page ground is WHITE, carrying the squared grid; bone is for a card or a band, not the page */
  --margin-bg: #F3EFE7;      /* RULING 2026-09-08: BONE. The sheet is white, the ground it lies on is Bone Deep - that contrast is what makes it read as a sheet. */
  --margin-rule: none;

  /* rhythm */
  --strap-h: 36px;   /* was 50. RULING 2026-09-08: the top menu is 30% shorter (147px -> 103px) */
  --header-h: 66px;  /* was 96. Same ruling: the bar carries the reduction with the strap */
  --section-y: 120px;        /* Tandem's own section padding. Was 64 - that condensing was reversed 2026-09-04 */
  --section-y-tight: 64px;   /* for a section that is solid text or a list: .sec--tight */
  --gutter: 24px;

  /* ── COLOUR. TWO SOURCES, AND THEY AGREE ────────────────────────────────────
     The web Colors sheet is the working palette for the site: use its ramps freely, they are
     tints of these same colours, and any step is the base at that opacity (rgba(6,22,53,.6) is
     Ink Navy 60%). The Brand Book (Marketing Stuff > Branding > Brutor Final Brand Book.pdf,
     p7 primary, p8 supporting) holds the ABSOLUTE values, so "our brand azure" or "our brand
     orange" always means the figure below, never a ramp step. Verified: the two sources give
     identical hexes at 100% for all six primaries.
     There is ONE azure and ONE orange. Azure Ink and Orange Deep are supporting values with
     their own jobs; neither is ever "the azure" or "the orange".
     What each primary is FOR, in the book's own words (p7):
       Ink Navy  structure: headers, dark surfaces, charts, the mark
       Azure     the signal: links, actions, the full stop. Never means success.
       Bone      the warm light ground: marketing, documents, decks
       White     the product surface: interface, cards, forms
       Orange    energy: illustration, graphics, AND TEXT ON DARK GROUNDS
       Plum      depth: editorial, covers, section markers. Never in product. */
  --ink-black:#131927;      /* Grey 100 - headline black, warmer than Ink Navy */
  --ink:#061635;        --ink-80:rgba(6,22,53,.8);  --ink-60:rgba(6,22,53,.6);  --ink-10:rgba(6,22,53,.1);
  --azure:#1BB5E8;      --azure-40:rgba(27,181,232,.4); --azure-10:rgba(27,181,232,.1);
  --orange:#FF6D00;     --orange-10:rgba(255,109,0,.1);
  --plum:#6E2A56;

  /* SUPPORTING VALUES (Brand Book p8) - secondary colours used in pairings. None of these is
     ever "the azure" or "the orange"; each has its own job. */
  --ink-slate:#1C2B45;   --azure-ink:#0A5A78;   --sky:#7ADCF8;
  --orange-deep:#B84E00; --orange-tint:#FFE2CC;
  --plum-deep:#3D162F;   --plum-mid:#A84B82;    --mauve:#C79BB6;
  --bone:#FCFAF6;       --bone-deep:#F3EFE7;        --white:#fff;
  --grey:#4D5461;       --grey-100:#131927;         --grey-30:#E5E7EA;   /* Grey ramp 70 / 100 / 30 */
  --grey-80:#394050;                                         /* Grey 80 - field fill on a dark ground */
  --navy-soft:#1D2C48;            /* Ink Navy 90% */
  --footer-bg:#000000;            /* brand black (Black 100%) */
  --divider-dark:rgba(252,250,246,.15);   /* lines on dark grounds (CTA to footer, footer copyright row) */
  --menu-card:#E6E8EB;            /* Ink Navy 10% - mega-menu CTA card (Tandem Header sheet) */
  --disabled-bg:#D2D5DB; --disabled-fg:#9EA2AE;     /* Grey 40 / Grey 50 - Button sheet, disabled */
  --disabled-bg-dark:#4D5461; --disabled-fg-dark:#6D717F;   /* Grey 70 / Grey 60 - disabled on a dark ground */
  /* semantic (Tandem 500 steps). RULING: green only for ticks, red only for a failure cross.
     Never a section ground, never a brand accent. */
  --success:#43B75D; --danger:#EE443F; --warning:#FFAA00; --info:#0095FF;

  /* type */
  /* RULING 2026-09-06 (Veronika): the sans is FIGTREE, everywhere, replacing Inter. It overrides the
     Brand Book's "Inter" and reverses the 2026-09-01 "we keep our font" ruling now that it has been
     judged next to the logo: Figtree is geometric with round bowls and a straight-sided A - the same
     skeleton as the wordmark - was drawn for product interfaces, carries a true 900, and is the face
     every Tandem screen was composed in, so the built site now matches the signed-off designs.
     Archivo was tried the same morning and rejected (squared, too wide, fought the logo): a candidate
     is judged NEXT TO THE LOGO first, against competitors second.
     Google Fonts: Figtree 400;600;700;900 - loaded by the theme (brutor-fonts) and by the page <head>
     in the same line as IBM Plex Mono, which is unchanged. */
  --sans:'Figtree',Inter,system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;

  /* hard offsets — the signature. Azure on buttons and on boxes that sit on navy; black on light boxes */
  --shadow-azure: 6px 6px 0 var(--azure);
  --shadow-ink:   6px 6px 0 var(--ink);
  --shadow-w: 6px;           /* the offset's width: the column reserves it on the right (.wrap) */
  --line-w: 1px;             /* RULING 2026-09-07: every separator line INSIDE a component (stats, header cells, rows, tables) is 1px, the header cell weight. Colour is the component's own. */
  --radius: 6px;             /* buttons, chips */
  --radius-box: 8px;         /* cards, panels, schematic frames */
  --grid-cols: 12;           /* Page Layout sheet: 12 columns, 24px gutter */
  --schematic-max: 1160px;   /* Schematics sheet: full-width illustration */
}

/* ───────────────────────── 1. BASE ───────────────────────── */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--margin-bg);color:var(--ink);font:400 15px/24px var(--sans);-webkit-font-smoothing:antialiased}
img,svg,video{display:block;max-width:100%}
a{color:inherit}
p{margin:0}

/* the page frame: everything (header, sections, footer) lives inside .page */
/* CLASS COLLISION, and it is a landmine: WordPress puts its own `page` class on <body> for every
   page post type, so a bare `.page` rule lands on the BODY as well as on our wrapper. That is what
   painted the grid across the whole viewport and turned the margins white on 2026-09-08. Every rule
   that gives .page a ground writes `.page:not(body)`. Never a bare .page for anything that paints. */
.page:not(body){position:relative;max-width:var(--page-max);margin:0 auto;background:var(--page-bg);border-left:var(--margin-rule);border-right:var(--margin-rule)}
.page:not(body)::before{content:"";position:absolute;top:0;bottom:0;left:var(--tex-inset);right:var(--tex-inset);
  background:url(assets/tex/grid-white.svg) 0 0/232px 153px repeat;opacity:.12;pointer-events:none;z-index:0}
/* the squared texture is the PAGE's, so a section without its own ground still has it (2026-09-08).
   IT STOPS AT THE PERFORATED EDGES, like every other ground in this sheet (see section 3, TYPE OVER
   TEXTURE, rule 2): the margins are not part of the sheet the content is written on, so no pattern
   may ever cross the vertical dashed rules. Inset with --edge-w, never a hard-coded number. */
.page:not(body)>*{position:relative;z-index:1}
/* THE HEADER OUTRANKS THE PAGE. Both <header> and <main> are children of .page and both take
   z-index 1 from the rule above; <main> comes later in the DOM, so it painted ON TOP, and the
   mega-menu panel (z-index 50) was trapped inside the header's stacking context and rendered
   BEHIND the page content on every canvas page. Any element that opens over the page belongs
   to the header, so the header sits above main, full stop. Audit check 14 proves it. */
.page:not(body)>header.hd,.page:not(body)>.strap{z-index:10}
/* the content column: from the logo's left edge to the Book Demo's right edge
   (plus the tractor-feed edge strips when .page--edges is on) */
:root{--edge-w:0px;--tex-inset:0px}
.page{--content-pad:calc(var(--page-pad) + var(--edge-w))}   /* computed on .page so .page--edges' --edge-w is seen */
/* COLUMN RULING 2026-09-07 ("overruns beyond vertical edges", flagged repeatedly): the content column
   ends where a frame's HARD SHADOW ends, not where its border ends. The right pad reserves the 6px
   offset so a card, figure, illustration or button on the column's right edge never crosses it. */
.wrap{padding:0 calc(var(--content-pad) + var(--shadow-w)) 0 var(--content-pad)}
@media (max-width:760px){:root{--page-pad:20px}}

/* ─── THE BACKGROUND OF THE SITE. Decided 2026-09-04, absolute values, do not re-derive ───
   margins   left and right of the page: #E6E8EB (warm neutral, low chroma)
   holes     #E6E8EB - the same value, so a hole reads as punched through the sheet to the
             ground behind it. Radius 4.5, pitch 40, no rim.
   line      1px dashed in a mid slate at 50%. One value that reads on a light band and on a
             navy one, so the pattern never has to change tone.
   holes     a real SVG circle (crisp edges), filled with the ground colour at 55% and ringed
             with the same slate hairline. Because the fill is translucent, a hole picks up
             whatever band it crosses: warm over the hero, quietly lifted over navy. That is how
             one unbroken pattern can run the whole page without ever needing a dark variant.
   continuity ONE pattern from the top menu to the bottom menu. It is drawn once on <main>, never
             per band, so a circle is never clipped where two bands meet. A section divider stops
             at the perforation rather than crossing it.
   placing   holes 20px in from the page edge (--hole-x), line 44px in (--line-x): both sit out
             near the edge, with the line close to the holes rather than out by the content.
   size      hole radius 6, pitch 30 (--hole-r, --hole-pitch): bigger and closer together.
   divider   a section divider never runs over a hole - the strips paint above it, so the hole
             interrupts the dashed line rather than the line crossing the hole.
   over dark both the holes and the line drop to rgba(252,250,246,.07), the same faint tone
             as the divider between the CTA band and the footer, so nothing shouts on navy.
   extent    from the bottom of the top menu to the top of the bottom menu, and no further.
             The header and the footer never carry the perforation.
   Only the header bar is plain white. Every white SECTION carries the dashed grid pattern,
   which is what lets a white card lift off it.

   tractor-feed edges (continuous-stationery sprocket holes) on BOTH sides of the page.
   Turn on with <div class="page page--edges">. Each band (hero, stats, sections, CTA — not the
   header, not the footer) draws its own strip in an ::after: faint bone holes with a near-invisible
   rim and a whisper dashed line; on dark bands holes and line share the footer-divider tone.
   Rulings 2026-09-03 (v6 of the perforation). */
/* framed page: a centred sheet on the Bone Deep ground. Site-wide this is done by setting
   --page-max in :root; the class lets one page be shown framed while the choice is open.
   1400px is Tandem's page width, which after the 80px strips and 48px padding leaves a
   1144px content column - within a hair of the sheet's own 1160. No border on the page edge:
   the perforation is the edge treatment, and a hard line beside the dashed one shouts. */
.page--framed{--page-max:1400px;--margin-rule:none}
/* a canvas page is framed exactly like the signed-off homepage. The locked header opens
   `.page.page--edges` without page--framed, and the header is not to be edited, so the
   theme's body class carries the same two values instead. Byte-identical result. */
.brutor-canvas .page{--page-max:1400px;--margin-rule:none}

/* ── THE TEXTURES RULE (2026-09-08, hers, and it supersedes the older wording) ─────────────
   A TEXTURE TOUCHES THE VERTICAL DASHED LINES. It ends exactly on them: no fuzz, no feather,
   no gap, and never a pixel past them into the margins. The dashed rules are the edge of the
   sheet the content is printed on, so the paper runs up to the tear and stops dead.
   Every ground uses --tex-inset, which is the dashed line's own offset, so nothing hard-codes
   a number and the whole page tracks one value. Audit check 11 measures it on the rendered
   page and fails the deploy if any pattern stops short of the line or crosses it.
   (Feathering is still right UNDER CONTENT - that is .halo, and unrelated to this edge.) */
.page--edges{--edge-w:80px;--tex-inset:var(--line-x);--page-max:1400px}
/* THE SITE WIDTH (ruling restated 2026-09-09, and it was the emergency): a page with the
   perforated edges is a SHEET, so it is 1400px wide and centred on the Bone Deep ground.
   --page-max was still `none` from the full-bleed era, which is why the live site ran the
   whole width of the window. The strap, the header, <main> and the footer are all inside
   .page, so this one value sizes every one of them, and the perforation still runs only
   from the bottom of the top menu to the top of the bottom menu, because it is drawn on
   <main> and never on the chrome. */
:root{--edge-line-w:1px;--edge-line-c:rgba(120,130,150,.5);--hole-r:6px;--hole-pitch:30px;
      --hole-x:20px;      /* centre of the holes, measured in from the page edge */
      --line-x:44px}      /* the dashed line, measured in from the page edge */
/* ONE continuous run of holes, drawn once on <main>, which spans exactly from the bottom of the
   top menu to the top of the bottom menu. Drawing it per band was the bug: the pattern restarted
   at every band edge, so a circle got clipped wherever two bands met. Now the phase never breaks.
   The holes are a real SVG circle, not a radial-gradient, so the edge antialiases cleanly. */
.page--edges>main{position:relative}
.page--edges>main::before,.page--edges>main::after{
  content:"";position:absolute;top:0;bottom:0;width:var(--edge-w);z-index:3;pointer-events:none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='30'%3E%3Ccircle cx='20' cy='15' r='6' fill='%23ECEAE6' fill-opacity='.55' stroke='%23788296' stroke-opacity='.45' stroke-width='1'/%3E%3C/svg%3E"),
    repeating-linear-gradient(180deg,var(--edge-line-c) 0 6px,transparent 6px 12px);
  background-size:var(--edge-w) var(--hole-pitch),var(--edge-line-w) 100%;
  background-repeat:repeat-y,no-repeat}
.page--edges main::before{left:0;background-position:left 0 top 0,left var(--line-x) top 0}
.page--edges main::after{right:0;transform:scaleX(-1);background-position:left 0 top 0,left var(--line-x) top 0}
/* a divider stops at the perforation, so no horizontal line ever crosses a circle */
.page--edges>main>.rule{margin:0 var(--edge-w)}
@media (max-width:900px){.page--edges{--edge-w:0px;--tex-inset:0px}.page--edges>main>*::after{display:none}}

/* ───────────────────────── 2. TYPE ───────────────────────── */
/* ── THE HEADLINE MEASURE (ruling 2026-09-08) ───────────────────────────────────────────────
   AN H2 NEVER RUNS MORE THAN TWO THIRDS OF THE PAGE WIDTH, and neither does the standfirst
   under it. A headline that runs the full column reads as a paragraph in bold; stopping it at
   two thirds is what makes it a headline and leaves the right third as breathing room.
   Applied with .w2-3 on the heading and on its standfirst. GOING FORWARD ONLY: the existing
   homepage sections keep the width they have until she says otherwise (her instruction, same
   day), so this is deliberately a class and not a blanket h2 rule. */
.w2-3{max-width:66.66%}
@media (max-width:900px){.w2-3{max-width:none}}

/* HEADLINE COLOUR - ruling 2026-09-04: a headline may be BLACK, ORANGE or AZURE and nothing
   else, each at 100%, never a percentage or a tint. When an existing page is restyled its
   heading colours are left exactly as they are; only the size and the underline are adopted. */
h1,h2,h3,h4{margin:0;font-family:var(--sans);font-weight:900;letter-spacing:-.01em;color:var(--ink-black)}
/* ON A DARK GROUND EVERYTHING FLIPS. A heading, a card title, body text and a link all take Bone;
   the headline black never reaches a navy band or a navy card. */
.on-dark h1,.on-dark h2,.on-dark h3,.on-dark h4,
.bg-navy h1,.bg-navy h2,.bg-navy h3,.bg-navy h4,
.stats h1,.stats h2,.stats h3,.stats h4,
.card--navy h1,.card--navy h2,.card--navy h3,.card--navy h4,
footer.foot h1,footer.foot h2,footer.foot h3,footer.foot h4{color:var(--bone)}
/* Tandem Typography sheet with the Inter-Black ruling applied to every H:
   H1 40/52 - H2 28/42 - H3 20/28 - H4 20/28 - Body Large 17/24 - Body 15/24 - Caption 12/16
   - Eyebrow 11 - Tags 12/16 - Display 64/64 (Brand Book; absent from the sheet).
   Body comes in two weights on the sheet: B1 Regular and B2 Black. */
.h64{font-size:64px;line-height:64px}   /* Display, Brand Book */
.h56{font-size:56px;line-height:64px}   /* hero H1 - ruling 2026-09-04: one step above the section heads */
.h48{font-size:48px;line-height:56px}   /* hero H1 when the position line must hold on two lines (2026-09-07) */
.h40{font-size:40px;line-height:52px}   /* section H2 */
.h28{font-size:28px;line-height:42px}
.h20{font-size:20px;line-height:28px}
.h18{font-size:18px;line-height:26px}   /* a card title that has to hold a long question (2026-09-07) */
.h17{font-size:17px;line-height:24px}
.lead{font:400 17px/24px var(--sans)}       /* B1 Body Large */
.lead--loose{line-height:27px}
.lead--narrow{max-width:56ch}   /* a standfirst under a masthead; was an inline style until 2026-09-06 */
.lead-b{font:900 17px/24px var(--sans)}     /* B2 Body Large */
.p15{font:400 15px/24px var(--sans)}        /* B1 Body small */
.p15-b{font:900 15px/24px var(--sans)}      /* B2 Body small */
.cap12{font:500 12px/16px var(--sans)}      /* C1 Caption */
.tag{display:inline-block;font:500 12px/16px var(--sans);padding:2px 8px;border:1px solid var(--ink);border-radius:var(--radius);background:transparent}   /* the pill rule at tag size */
.dim{color:var(--ink-80)}
/* a paragraph belongs to the heading above it: close under the head, clear of the next block */
h2 + p,h3 + p,h4 + p,.h40 + p,.h28 + p,.h20 + p,.h17 + p{margin-top:8px}
.mono12{font:500 12px/16px var(--mono)}

/* RULING 2026-09-05: NO EYEBROW ABOVE AN H1. A page title stands on its own; the little
   /label/ over it just pushes the headline down and says nothing the headline does not.
   Eyebrows still belong above an H2 inside the page. If a particular page needs one over its
   H1, Veronika asks for it - it is never the default. */
h1 + .eyebrow,.eyebrow + h1{margin-top:0}
.sec--titled .eyebrow:first-child{display:none}

/* PAGE MASTHEAD - the H1 of a section-front like the blog. Twice the working H1, because the
   page has one job and its name is the whole top of it. Display size, from the Brand Book.

   RULING 2026-09-05: a masthead carries the signature marks and NOT the orange bar.
     .dot  the full stop in "Brutor.AI" is the signature azure, exactly as in the wordmark
     .u-o  the page's own word is underlined in the signature orange
   The orange underline here is deliberate and overrides the light-ground default of azure:
   this is the wordmark's own pairing - azure dot, orange stress - not body emphasis. Never
   put .h-rule on a masthead as well; the bar and the underline are two marks doing one job. */
.h-masthead{font-size:64px;line-height:68px;letter-spacing:-.02em}
/* a masthead section breathes differently from a content section: the title comes UP toward
   the nav, because it is the page's name and belongs to the top of the page, and the standfirst
   drops AWAY from it, because at 64px the headline needs air under it before prose starts. */
/* SECTION FRONT - a page like the blog whose job is to list things. It is ONE section, not
   several: the title, the featured item and the list are the same thing, so there is no
   divider between them and no change of ground. Ruling 2026-09-05. */
.sec.sec--masthead{padding-top:56px}   /* .sec is defined later in the file, so this needs the extra class to win */
.h-masthead + .lead{margin-top:26px}

/* ── TYPE OVER TEXTURE: two rules that hold for every textured ground ─────────
   1. ANY block of type sitting on a texture needs a .halo under it. Ruled lines through a
      headline make it look like a scan, and a line crossing the gap between two cards reads
      as a mistake rather than as paper. Halo the whole block - heading, standfirst, cards,
      controls - never one element at a time: separate halos leave a seam wherever their
      falloffs meet, and that seam moves every time the content reflows.
   2. A texture STOPS AT THE PERFORATED EDGES. It is the paper the content is written on, and
      the margins are not part of that sheet. Every ground does this with
      `.page--edges <ground>::before{left:var(--tex-inset);right:var(--tex-inset)}` so it tracks the
      margin width rather than hard-coding it. */

/* HALO - a white field that holds the ruling back from the type and from the cards sitting on
   it. Ruled lines running through a 64px headline make it look like a scan, and a blue line
   crossing the gap between two cards reads as a mistake rather than as paper.

   ONE halo covers the masthead, the featured card and the search together, rather than three
   separate ones. Veronika asked for halos that touch so no stray line shows between them, and
   a single field is the only way to guarantee that - three overlapping gradients leave a seam
   wherever their falloffs meet, and the seam moves whenever the content reflows.

   It is a solid white rectangle with a FEATHERED MASK on all four sides, not a radial
   gradient. A radial fades from the middle outward, so it is palest exactly where the text is
   widest; the mask keeps the centre fully opaque and only softens the last few percent at the
   edges. It must never end on a hard edge or it reads as a white card. */
.halo{--pull:52px;position:relative;padding:44px var(--pull) 48px;margin:-44px calc(var(--pull) * -1) 0}
.halo::before{content:"";position:absolute;inset:0;background:var(--white);pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 93%,transparent 100%),
    linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 93%,transparent 100%),
    linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
  -webkit-mask-composite:source-in;mask-composite:intersect}
.halo > *{position:relative}          /* the content sits on the field, not under it */
/* THE SAME FEATHER, ON A PICTURE. A picture that should sit ON the paper rather than be pasted
   onto it takes .pic--soft instead of a frame: no border, no shadow, its own edges softened with
   the mask .halo uses. Use it whenever a picture would otherwise need a frame only to stop its
   hard edge landing on a texture. A framed picture and a feathered one are the only two options;
   a hard-edged unframed picture on a ground is neither. (2026-09-08) */
/* A PICTURE'S HAIRLINE. A picture that must show its own edge - a document cover, a page of
   print - takes a 1px black hairline and NOTHING else: no offset shadow, no radius. The FRAME
   LAW governs boxes that HOLD content; a picture that IS the content shows its own edge instead,
   and a 6px shadow under it reads as a box. So a picture has exactly three treatments and no
   fourth: framed (.frame et al.), feathered (.pic--soft), or hairlined (.pic--hairline).
   Audit check 2 knows all three. (2026-09-08) */
.pic--hairline{border:1px solid var(--ink-black);border-radius:0;box-shadow:none;background:transparent}
.pic--soft{border:0;box-shadow:none;border-radius:0;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 5%,#000 95%,transparent 100%),
    linear-gradient(90deg,transparent 0,#000 4%,#000 96%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 5%,#000 95%,transparent 100%),
    linear-gradient(90deg,transparent 0,#000 4%,#000 96%,transparent 100%);
  -webkit-mask-composite:source-in;mask-composite:intersect}
@media (max-width:900px){.halo{--pull:var(--page-pad)}}   /* stacked, the pull can never exceed the column's own padding */
@media (max-width:760px){.halo{padding:28px var(--pull) 32px;margin:-28px calc(var(--pull) * -1) 0}}

/* .type-halo is the old single-block version, kept because other pages may still call it */
.type-halo{padding:34px 44px 30px;margin:-34px -44px 0;
  background:radial-gradient(115% 135% at 26% 46%,
    rgba(255,255,255,.98) 0 42%, rgba(255,255,255,.82) 60%, rgba(255,255,255,0) 78%)}
@media (max-width:760px){.type-halo{padding:24px 20px;margin:-24px -20px 0}}
.h-masthead .dot{color:var(--azure)}
.h-masthead .u-o{text-decoration:underline;text-decoration-color:var(--orange);
  text-decoration-thickness:5px;text-underline-offset:8px;text-decoration-skip-ink:none}
@media (max-width:760px){
  .h-masthead{font-size:40px;line-height:46px}
  .h-masthead .u-o{text-decoration-thickness:3px;text-underline-offset:5px}}
.mono14{font:500 14px/16px var(--mono)}
/* NUMBERS. Two kinds, and the kind decides the font.
   A number that IS the point - a headline statistic - is Inter Black in Azure, at headline size.
   A number that LABELS or MEASURES something - an index, a count, a price, a date, a version,
   a citation - is IBM Plex Mono in Azure Ink, tracked, small. That is what the design file does:
   "21%" is Inter Black Azure 40/52, while "01" and "Deloitte | State of AI 2026" are mono.
   No number is ever Inter Regular. Weight and tracking come from the Platform design, where
   every mono label is 800 with 1 to 1.6px of tracking, never lighter. */
.n-stat{font:900 40px/52px var(--sans);color:var(--azure)}          /* the headline figure */
.n-idx{font:800 11px/16px var(--mono);letter-spacing:.11em;color:var(--azure-ink)}   /* 01, 02 - Platform design */
.n-data{font:800 12px/16px var(--mono);letter-spacing:.13em;color:var(--azure-ink)}  /* counts, prices, versions */
.n-src{font:800 12px/16px var(--mono);letter-spacing:.13em;color:var(--ink-80)}     /* a citation under a figure */
.on-dark .n-idx,.on-dark .n-data{color:var(--azure)}
.on-dark .n-src{color:var(--bone)}
.num{color:var(--azure-ink)}
@media (max-width:1100px){.h56{font-size:44px;line-height:52px}}
@media (max-width:760px){.h56{font-size:34px;line-height:42px}.h40{font-size:30px;line-height:38px}.h28{font-size:24px;line-height:32px}}

/* eyebrow: mono bold 11/14, tracked caps, plum; azure on navy */
/* the eyebrow is written /lower case inside slashes/ - never transformed to capitals */
.eyebrow{display:block;font:700 11px/14px var(--mono);letter-spacing:.12em;text-transform:none;color:var(--plum);margin:0 0 6px}
.on-dark .eyebrow{color:var(--azure)}

/* HEADLINE EMPHASIS - the rule, so every heading is marked up the same way.
     Every section heading carries emphasis, and it falls on the phrase that carries the point,
     which is almost always the second line.
     .u  azure-ink underline = we are NAMING something: a category, a product, a term we define
         ("AI control plane", "Brutor under the hood", "you shape it").
     .o  orange = we are ASSERTING something: the payoff, the consequence, the punch
         ("governed, costed, and proven", "can't govern", "Day 201").
     At most one of each in a heading, never the same words in both, never a whole heading in
     colour. A heading with no emphasis is a heading whose point has not been decided yet. */
/* .o = the emphasised phrase. Azure on a light ground, Orange on a dark one, per the book. */
.o{color:var(--azure)}
.on-dark .o,.bg-navy .o,.stats .o,.cta .o,footer.foot .o{color:var(--orange)}
/* EMPHASIS IS FOR H1 AND H2 ONLY. No H3, no H4, no body, no caption ever takes a colour.
   A heading gets at most one orange phrase and one underlined phrase, never the same words.
   The underline is bright Azure on a light ground and Orange on a dark one - the flip your
   deck already uses. Azure Ink was tried and reads navy, which is why it looked wrong. */
.u{text-decoration:underline;text-decoration-color:var(--azure);text-decoration-thickness:3px;text-underline-offset:6px}
.on-dark{color:var(--bone)}
.on-dark .u{text-decoration-color:var(--orange)}   /* the underline follows the same rule */
h3 .o,h4 .o,p .o,.p15 .o,.lead .o{color:inherit}          /* emphasis below H2 is switched off */

/* HEADING RULE - a short orange bar under a heading. Tandem's own card templates use it
   ("Course Name", "Event Name") and it is approved as-is (Veronika 2026-09-05). It does not
   contend with the headline-colour ruling: this is orange as a GRAPHIC MARK, not orange type,
   so it is allowed on a light ground where an orange word would not be.
   It replaces the .u underline on that heading - never both on the same words. */
.h-rule::after{content:"";display:block;width:64px;height:4px;background:var(--orange);
  margin-top:14px}
.h-rule--wide::after{width:104px}
.on-dark .h-rule::after,.bg-navy .h-rule::after{background:var(--orange)}   /* unchanged: it is a mark, not text */
.h-rule--azure::after{background:var(--azure)}   /* when the heading already carries an orange word */

/* ───────────────────────── 3. BUTTONS ─────────────────────────
   SPEC, from the node tree ("Button" frames) and the Button sheet:
     size 150x48 (219x48 when the label is long) - radius 6 - padding 20 across / 14 down
     border 1px #061635 - hard offset = a duplicate frame at +6,+6 filled #1BB5E8
     fills  primary #FF6D00 / secondary #FFFFFF / on-navy #FCFAF6 / on-light #061635
     on-light border #061635; a navy button placed ON a navy band takes a #1BB5E8 border
     disabled Grey 40 #D2D5DB fill with Grey 50 #9EA2AE text and border
   Tandem Button sheet. Every button: 1px Ink border, 6px radius, azure hard offset.
   States    default = full offset - hover = shifts 2px into it - press = flat, no offset -
             disabled = grey, no offset, not clickable.
   Variants  primary (orange) - secondary (white) - on-dark (bone, for navy grounds) -
             on-light (navy, for light grounds) - text button (azure, arrow).
   Sizes     L 17/24 (default) - M 14/16 - S 12/16 - Tiny 10/12.
   The sheet draws an arrow-tr inside the on-dark / on-light buttons; ours carries one only
   where the page asks for it: <svg class="ic"><use href="#i-tr"/></svg> inside the button. */
.btn{display:inline-flex;align-items:center;gap:8px;height:48px;padding:0 20px;border-radius:var(--radius);border:1px solid var(--ink);
  font:600 17px/24px var(--sans);color:var(--ink);text-decoration:none;box-shadow:var(--shadow-azure);transition:transform .12s,box-shadow .12s;white-space:nowrap}
.btn:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--azure)}
.btn:active{transform:translate(6px,6px);box-shadow:none}
.btn--primary{background:var(--orange)}
.btn--secondary{background:var(--white)}
.btn--bone{background:var(--bone)}
.btn--on-dark{background:var(--bone)}                                    /* sits on a navy ground */
.btn--navy,.btn--on-light{background:var(--ink);color:var(--bone);border-color:var(--ink)}
.btn--md{height:40px;padding:0 16px;font-size:14px;line-height:16px;box-shadow:4px 4px 0 var(--azure)}
.btn--sm{height:32px;padding:0 12px;font-size:12px;line-height:16px;box-shadow:3px 3px 0 var(--azure)}
.btn--tiny{height:26px;padding:0 10px;font-size:10px;line-height:12px;box-shadow:2px 2px 0 var(--azure)}
.btn[disabled],.btn[aria-disabled="true"],.btn--disabled{background:var(--disabled-bg);color:var(--disabled-fg);
  border-color:var(--disabled-fg);box-shadow:none;pointer-events:none}
.on-dark .btn[disabled],.on-dark .btn--disabled{background:var(--disabled-bg-dark);color:var(--disabled-fg-dark);border-color:var(--disabled-fg-dark)}
.btn .ic{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
/* ══════════════════════════════════════════════════════════════════════════════════════════
   THE BUTTON SPEC. Transcribed from Tandem's own sheet:
   "Web Design and Assets/00-SPECS/Web style guidelines from Tandem/Button.png" (read 2026-09-09).
   THIS IS THE WHOLE TRUTH ABOUT BUTTONS. Five kinds, four states, and the arrow belongs to
   three of the five. Nothing else is a button.

     KIND                     fill          type    arrow   our class
     1 Primary                Orange        Ink     NO      .btn--primary
     2 Secondary              White         Ink     NO      .btn--secondary  (.btn--bone)
     3 Button against DARK    Bone          Ink     YES     .btn--on-dark + .btn--go
     4 Button against LIGHT   Ink Navy      Bone    YES     .btn--navy  (.btn--on-light)
     5 Text button            none          Azure   YES     .tbtn

   WHY 1 AND 2 HAVE NO ARROW, which I got wrong on 2026-09-08 by making the arrow universal:
   they are the CONVERSION pair, Download Free Trial and Book Demo. The arrow means "this takes
   you onward"; a conversion button is the end of the journey. Kinds 3, 4 and 5 are navigation,
   so they carry it. Add .btn--go to force the arrow onto a kind that has none by default (a bone
   button used as navigation on a dark band); add .btn--noarrow to take it off kind 4.

   STATES, all four from the sheet:
     Default   1px ink border, radius 6, 6px azure offset shadow
     Hover     the button moves 2px toward the shadow, which shortens to 3px
     Press     the button moves the full 6px and the shadow disappears
     Disabled  grey fill, grey type, grey border, no shadow, no pointer events
               (the sheet only draws Disabled for kinds 3, 4 and 5)

   THE ARROW IS NEVER A TEXT CHARACTER. Tandem's own page shipped `<span>&#8599;</span>`, and
   Figtree has no glyph at U+2197, so every one of those buttons rendered a tofu box. The arrow
   is either the #i-tr SVG symbol in the markup or the mask below. Audit check 7 enforces the
   whole of this: the right kinds carry it, the wrong kinds do not, and no button contains a
   text arrow. ══════════════════════════════════════════════════════════════════════════════ */
a.btn--navy:not(.btn--noarrow):not(:has(.ic))::after,
a.btn--on-light:not(.btn--noarrow):not(:has(.ic))::after,
a.btn--go:not(:has(.ic))::after{content:"";width:20px;height:20px;flex:none;
  background:currentColor;-webkit-mask:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%2019L19%206M6.52%206H19v12.48'/></svg>") center/contain no-repeat;mask:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%2019L19%206M6.52%206H19v12.48'/></svg>") center/contain no-repeat}
.btn--noarrow .ic{display:none}
/* a text arrow inside a button is always a mistake: hide it and let the rule above draw the real
   one. Kept as markup rather than deleted, so nothing is lost from a carried-over page. */
.btn .ar,.tbtn .ar{font-size:0;line-height:0}
.btn .ar::after,.tbtn .ar::after{content:"";display:inline-block;width:20px;height:20px;
  background:currentColor;-webkit-mask:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%2019L19%206M6.52%206H19v12.48'/></svg>") center/contain no-repeat;mask:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%2019L19%206M6.52%206H19v12.48'/></svg>") center/contain no-repeat}
.btn--primary .ar,.btn--secondary .ar,.btn--bone .ar{display:none}
.btns{display:flex;flex-wrap:wrap;gap:14px}
/* text button: azure with an arrow-tr; ink-azure on hover; grey when disabled */
.tbtn{display:inline-flex;align-items:center;gap:6px;font:600 17px/24px var(--sans);color:var(--azure);text-decoration:none}
.tbtn .ic{width:24px;height:24px;stroke:var(--azure);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.tbtn:hover{color:var(--azure-ink)}
.tbtn:hover .ic{stroke:var(--azure-ink)}
.tbtn--ul{text-decoration:underline;text-underline-offset:4px}
.tbtn--disabled{color:var(--disabled-fg);pointer-events:none}
.tbtn--disabled .ic{stroke:var(--disabled-fg)}

/* ───────────────────────── 4. SECTIONS + GROUNDS ───────────────────────── */
/* ── THE SECTION PADDING RULE (2026-09-08) ────────────────────────────────────────────────
   A SECTION'S VERTICAL PADDING MAY NEVER EXCEED HALF ITS CONTENT HEIGHT. 120px above and below
   is right for a section carrying a heading block and a grid; on a short section it is most of
   what you see, and the band reads as empty paper. There are only two values, and the content
   picks which: .sec (120) for a full band, .sec--tight (64) for a short one. Audit check 13
   measures both on the rendered page and fails the deploy when the padding wins.
   The other half of this fault is a grid `gap` shorthand leaking into the ROW gap: a two-column
   block that wants 56px between its columns does NOT want 56px under its eyebrow. Set
   column-gap and row-gap separately, never the shorthand. */
.sec{padding:var(--section-y) 0}
.sec--tight{padding:var(--section-y-tight) 0}   /* solid text / bullet lists get less air */
/* RULE (Veronika 2026-09-07): AN H2 IS ALWAYS ABOVE THE CONTENT OF ITS SECTION. A heading never
   sits in a column beside a picture, a list or a figure: it opens the section, full width, and
   everything else follows underneath. .head is that opener; put it first inside .wrap. */
.head{display:grid;gap:14px;margin-bottom:40px}
.ans>div>.head,.ans>.head{display:none}   /* a heading inside a two-column block is a mistake; it belongs above */
.head h2{max-width:760px}
.head h2.full{max-width:none}

/* SPEC, from the node tree: hero 1400x675 with the video half filled #FF6D00 at 10%;
   stats band 1400x208 fill #061635 with 3px #1BB5E8 separators, padding 120 across / 24 down;
   bone sections fill #F3EFE7 at 50%; content column 1160 inside a 1400 page, 120 margins.
   Grounds - Tandem Patterns & Textures sheet, with the no-tint ruling applied.
   hero        Orange 10% fill + "square crumpled paper" at 60%          (as the sheet says)
   white       dashed grid tile - sheet: unscaled at 30%; RULING: half size, 12%
   bone        RULING: plain Bone. Sheet: Bone 50% + "fuzzy lines" texture on top
   navy        flat Ink Navy for stat/quote bands
   navyline    CTA + footer ground: navy with a 5% line texture, from the sheet's
               "Ending CTA pattern" (its SVG ships with white margins, so it is drawn in CSS)
   Textures always tile, never stretch: background-repeat, never cover. */
.bg-grid,.bg-bone,.bg-lined,.bg-stripes,.bg-navy,.bg-navyline,.stats{position:relative}
.bg-grid>*,.bg-bone>*,.bg-lined>*,.bg-stripes>*,.bg-navy>*,.bg-navyline>*,.stats>*{position:relative}
.bg-grid{background:var(--white)}   /* NEVER plain white: the grid below is part of it. Plain white is the header bar only */
.bg-grid::before{content:"";position:absolute;inset:0;background:url(assets/tex/grid-white.svg) 0 0/232px 153px repeat;opacity:.12;pointer-events:none}
/* RULING 2026-09-04: the alternating section is WHITE with its own texture, not a bone tint.
   Two whites told apart by pattern rather than by colour, which removes the warm cast entirely
   and cuts the number of light tones on the page. Grid for one, fuzzy lines for the other. */
.bg-bone{background:var(--white)}
.bg-bone::before{content:"";position:absolute;inset:0;background:url(assets/tex/fuzzy.png) 0 0/420px auto repeat;opacity:.5;pointer-events:none}

/* LINED GROUND - Veronika's own paper, made in Canva 2026-09-05, replacing the synthetic
   ruling built from the grid. Real paper wins: the lines are unevenly spaced, some fade out
   and some run heavier, which is exactly what stops it reading as a printed screen pattern.

   `lined-paper.png` is cut from the 1678 x 2675 source sheet by `_ref/cut-lined-paper.py`:
   the white margin is trimmed so the lines run edge to edge and the sides tile invisibly, and
   the top and bottom are cut at the MIDPOINT OF A GAP so the half-gap at the bottom plus the
   half-gap at the top adds up to a normal line spacing when it wraps. Measured seam gap is
   69px against a median pitch of 70.5 and natural variation of 62-71 - inside the noise.
   If the source is ever replaced, re-run that script rather than cropping by hand.

   SIZE: `651px auto` puts the ruling at about a 28px pitch, which is roughly the 8mm of a
   school exercise book. `auto` keeps the aspect exactly - never give both axes, or the lines
   go soft. The FILE is stored at exactly twice that width, so the browser only ever halves it:
   an exact 2x downscale stays crisp, where the 2.516x it was doing before smeared every line.
   Resample in Pillow if the display width ever changes - do not just move this number.
   OPACITY is the faintness knob and the only thing to touch when it looks wrong. The paper's
   own ink sits at about luminance 228 on white, so multiplied it lands at 255-27*opacity:
   .9 = delta 24, which read too strong; .45 = delta 12, which is where azure-at-12% vanished;
   .65 = delta ~17.5, between the two.
   MULTIPLY: the source is ink on white paper, not a transparency. Multiplying drops its white
   away and leaves only the ink, so the ground underneath stays our white rather than the
   photograph's warm one. Opacity is the faintness knob; the ink is pale to begin with. */
/* STRIPES (Veronika 2026-09-07): the "double blue thicker lines print paper" texture from the web
   textures folder, one blue+grey period cut as a tile (assets/tex/printer-stripes.png, two stripe periods cut from her 3556px source, seam matched to 0.7 of a grey level), tiled down
   the page at the page width, MUTED to 35% and multiplied so the bone shows through. Content sits on
   a .halo (the white field from the blog index) so text and cards stand out against it. */
.bg-stripes{background:var(--white)}
.bg-stripes::before{content:"";position:absolute;inset:0;background:url(assets/tex/printer-stripes.png) center top/100% auto repeat-y;
  opacity:.35;mix-blend-mode:multiply;pointer-events:none}
.page--edges .bg-stripes::before{left:var(--tex-inset);right:var(--tex-inset)}
.bg-lined{background:var(--white)}
.bg-lined::before{content:"";position:absolute;top:0;bottom:0;left:0;right:0;pointer-events:none;
  background:url(assets/tex/lined-paper.png) 0 0/651px auto repeat;
  mix-blend-mode:multiply;opacity:.65}
/* the ruling stops at the vertical edge line on each side - it is the paper the CONTENT is
   written on, and the perforated margins are not part of that sheet. */
.page--edges .bg-lined::before{left:var(--tex-inset);right:var(--tex-inset)}
/* THE TEXTURES RULE, applied to every ground there is. Adding a new ground means adding it here
   too; audit check 11 fails the deploy otherwise. */
.page--edges .bg-grid::before,.page--edges .bg-bone::before{left:var(--tex-inset);right:var(--tex-inset)}


.bg-navy{background:var(--ink);color:var(--bone)}
/* the paper reaches the dark bands too, at a weight you feel rather than see (Tandem's
   crumpled-paper background, downsampled and screened back) */
.bg-navy::before,.bg-navyline::before,.stats::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:url(assets/tex/paper-dark.png) 0 0/900px auto repeat;opacity:.07;mix-blend-mode:screen}
/* NO EXCEPTIONS: a dark band's colour runs full bleed, but its paper layer is still a pattern, so
   it stops at the perforated edges like every other one. Audit check 11 enforces this. */
.page--edges .bg-navy::before,.page--edges .bg-navyline::before,.page--edges .stats::before{left:var(--tex-inset);right:var(--tex-inset)}
.bg-navyline{background:var(--ink) repeating-linear-gradient(0deg,rgba(255,255,255,.05) 0 1px,transparent 1px 4px);color:var(--bone)}   /* CTA ground: Ink Navy + grid */
/* ── THE DASHED RULE, named and specified (2026-09-08) ────────────────────────────────────
   ONE dash pattern, used in two orientations, and it is the only dash on a page:
     dash 6px  ·  gap 6px  ·  thickness 1px (--edge-line-w)  ·  colour rgba(120,130,150,.5)
     (--edge-line-c, a grey that reads on white and on bone without becoming a black line)
   HORIZONTAL, as a SECTION DIVIDER: <hr class="rule"> between two bands. It stops at the
     perforation (`.page--edges>main>.rule{margin:0 var(--edge-w)}`), so no horizontal line
     ever crosses a sprocket hole, and it is NEVER placed next to a dark section, where the
     change of ground is already the divider.
   VERTICAL, as the PAGE EDGE: the same 6/6 dash running down both margins, 44px in from the
     page edge (--line-x), beside the sprocket holes at 20px (--hole-x, r6, pitch 30px).
   Solid variant: .rule--solid, 1px --ink-black, for a divider INSIDE a column (the white
   paper page uses it above the meta lines). Solid means "inside a block", dashed means
   "between blocks".
   NOT to be confused with the SCHEMATIC dash, which is a different spec and lives in the
   drawing law: stroke-dasharray 3 2, 1px, orange or azure, inside a figure only. */
.rule{border:0;height:var(--edge-line-w);margin:0;background:repeating-linear-gradient(90deg,var(--edge-line-c) 0 6px,transparent 6px 12px)}
.rule--solid{background:var(--ink-black)}   /* a divider INSIDE a column: 1px black, no dashes (2026-09-08) */   /* section divider = same dashed dark-bone line as the page edges; never next to a dark section */

.grid{display:grid;gap:var(--gutter)}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}
.grid-5{grid-template-columns:repeat(5,1fr)}
@media (max-width:1100px){.grid-4,.grid-5{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){.grid-3{grid-template-columns:1fr}}
@media (max-width:600px){.grid-2,.grid-4,.grid-5{grid-template-columns:1fr}}

/* ██ LOCKED 2026-09-05 - DO NOT EDIT ████████████████████████████████████████████
   Signed off by Veronika. Change nothing in this section unless she asks for the header or
   the footer BY NAME. Not while "tidying", not while fixing a page that sits under them, not
   because a value here looks inconsistent with a newer rule elsewhere - a page problem is a
   page problem, and every page on the site inherits from here.
   The markup that goes with it is equally locked, staged at:
     wpcode-snippets/staged/01-site-wide-header-2026.php   (replaces WPCode 1512 at the flip)
     wpcode-snippets/staged/02-site-wide-footer-2026.php   (replaces WPCode 1513 at the flip)
   ████████████████████████████████████████████████████████████████████████████ */
/* ───────────────────────── 5. STRAP + HEADER ─────────────────────────
   SPEC, from the node tree:
     strap   1400x72, fill #1BB5E8 at 40%, 1px #061635 stroke   (ours is 50 tall by ruling)
     header  1400x66, fill #FFFFFF, 1px #061635, shadow #19213D 0,1 blur 4
               (Tandem drew 96; RULING 2026-09-08, approved: 30% shorter, strap 36 + bar 66 = 103)
     logo cell 240x96 - nav cell 159x96, fill #FCFAF6, 1px #061635, padding 12
     Book Demo cell 205x96, padding 24/12; the button itself 150x48
     chevron 24x24, stroke #061635 1.5px            (ours is Azure by ruling) */
.strap{background:var(--azure-40);height:var(--strap-h);display:flex;align-items:center;justify-content:center;padding:0 var(--gutter)}
.strap a{display:inline-flex;align-items:center;gap:12px;font:900 13px/18px var(--sans);text-decoration:none}
.strap .ic{width:22px;height:22px;stroke:var(--orange);fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}   /* RULING 2026-09-08: the strap's arrow is the signature orange, and drawn heavier than a body arrow so it carries at 13px */

.hd{background:var(--white);border-bottom:1px solid var(--ink);box-shadow:0 1px 4px rgba(25,33,61,.25);position:sticky;top:0;z-index:40}
.hd .bar{display:flex;align-items:stretch;height:var(--header-h)}
.hd .logo{flex:none;display:flex;align-items:center;padding:0 20px 0 var(--page-pad);border-right:1px solid var(--ink)}
.hd .logo img{width:126px;height:auto}   /* 2026-09-08: proportional to the shorter bar */
.hd nav{display:flex;flex:1}
.hd nav>ul{display:flex;flex:1;margin:0;padding:0;list-style:none}
.hd nav .links{margin:0;padding:0;list-style:none}
.hd nav .item{flex:1 1 159px;display:flex;position:relative;border-right:1px solid var(--ink)}
.hd nav .item:last-child{border-right:0}
.hd nav .item>a{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:8px 10px;background:var(--white);
  font:600 13px/16px var(--sans);text-decoration:none;white-space:nowrap}
.hd nav .item>a:hover,.hd nav .item:hover>a,.hd nav .item:focus-within>a,.hd nav .item.open>a{color:var(--azure)}
.hd nav .item:hover .ic,.hd nav .item:focus-within .ic,.hd nav .item.open .ic{transform:rotate(180deg)}   /* active item azure, chevron flips up */
.hd nav .ic{width:20px;height:20px;stroke:var(--azure);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}   /* chevrons azure */
/* mega menus (Tandem Header sheet): panel under the item's cell — mono eyebrow + link list left,
   grey CTA card right (framed zoom + caption + Get Started button). Veronika: azure bullet per link,
   CTA = zoom on the AI Systems Assurance white paper. Opens on hover / keyboard focus; the top item clicks through. */
.hd nav .drop{display:none;position:absolute;top:calc(100% + 16px);left:0;width:640px;padding:20px 24px 24px;background:var(--white);
  border:1px solid var(--ink);border-radius:var(--radius-box);box-shadow:var(--shadow-ink);z-index:50;
  grid-template-columns:1fr 290px;gap:24px;cursor:default}
.hd nav .drop::before{content:"";position:absolute;left:0;right:0;top:-17px;height:17px}   /* keeps the panel open while the pointer crosses the gap */
.hd nav .item:hover .drop,.hd nav .item:focus-within .drop,.hd nav .item.open .drop{display:grid}
.hd nav .item:nth-last-child(-n+3) .drop{left:auto;right:0}                                  /* panels near the right edge open leftwards */
.hd nav .drop .eyebrow{color:var(--grey);margin:0 0 14px}
.hd nav .drop .links a{display:flex;align-items:center;gap:12px;padding:8px 0 8px 12px;font:400 15px/24px var(--sans);color:var(--ink);text-decoration:none;white-space:nowrap}
.hd nav .drop .links a::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:var(--azure)}
.hd nav .drop .links a:hover{color:var(--azure)}
.hd nav .drop .promo{background:var(--menu-card);border-radius:var(--radius-box);padding:16px}
.hd nav .drop .promo .frame{background:var(--white);border-radius:6px;padding:8px;margin-bottom:14px}
.hd nav .drop .promo .frame img{width:100%;height:auto;border-radius:4px;border:1px solid rgba(6,22,53,.12)}
.hd nav .drop .promo p{font:400 15px/22px var(--sans);color:var(--ink);margin:0 0 14px}
.hd nav .drop .promo .btn{height:40px;padding:0 16px;font-size:15px;box-shadow:4px 4px 0 var(--azure)}
.hd .cta{flex:none;display:flex;align-items:center;padding:0 var(--page-pad) 0 20px;border-left:1px solid var(--ink)}
.hd .cta .btn{height:40px;padding:0 16px;font-size:15px;box-shadow:4px 4px 0 var(--azure)}   /* was 48/20/17; 2026-09-08 the shorter bar takes the sheet's own medium button */
/* ── mobile navigation ──────────────────────────────────────────────────────
   No design exists from Tandem, so it is built from the system: the same cells, the same ink
   rules, the same azure bullets. No JavaScript - a hidden checkbox drives it, so it works in a
   WordPress snippet with nothing else loaded. Sub-menus sit open under their parent; the
   mega-menu promo card is dropped on small screens. */
.navtoggle{position:absolute;opacity:0;pointer-events:none}
.burger{display:none;flex:none;align-items:center;justify-content:center;width:56px;align-self:stretch;
  border-left:1px solid var(--ink);cursor:pointer;background:var(--bone)}
.burger span,.burger span::before,.burger span::after{display:block;width:22px;height:2px;background:var(--ink);content:"";transition:transform var(--t),opacity var(--t)}
.burger span{position:relative}
.burger span::before{position:absolute;top:-7px}
.burger span::after{position:absolute;top:7px}
.navtoggle:checked ~ .bar .burger span{background:transparent}
.navtoggle:checked ~ .bar .burger span::before{transform:translateY(7px) rotate(45deg)}
.navtoggle:checked ~ .bar .burger span::after{transform:translateY(-7px) rotate(-45deg)}

@media (max-width:1100px){
  .hd nav>ul{flex-direction:column;width:100%}
  .hd .bar{position:relative}
  .hd .logo{border-right:0}
  .hd .cta{margin-left:auto;border-left:1px solid var(--ink)}
  .burger{display:flex}
  .hd nav{display:none;position:absolute;left:0;right:0;top:100%;flex-direction:column;
    background:var(--white);border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);
    max-height:calc(100vh - var(--header-h));overflow:auto;z-index:60}
  .navtoggle:checked ~ .bar nav{display:flex}
  .hd nav .item{flex:none;display:block;border-right:0;border-top:1px solid var(--ink)}
  .hd nav .item:first-child{border-top:0}
  .hd nav .item>a{justify-content:flex-start;padding:16px var(--page-pad);font-size:17px;background:var(--white)}
  .hd nav .item .ic{display:none}
  .hd nav .drop{display:block;position:static;width:auto;padding:0 0 12px;border:0;border-radius:0;
    box-shadow:none;background:transparent}
  .hd nav .drop::before{display:none}
  .hd nav .drop .eyebrow,.hd nav .drop .promo{display:none}
  .hd nav .drop .links a{padding:10px var(--page-pad) 10px calc(var(--page-pad) + 12px);font-size:15px}
}
@media (max-width:760px){
  .hd .logo{padding:0 16px 0 var(--page-pad)}
  .hd .logo img{width:112px}
  .hd .cta{padding:0 var(--page-pad) 0 12px}
  .hd .cta .btn{height:40px;padding:0 14px;font-size:14px}
  .burger{width:48px}
  .strap a{font-size:13px;line-height:18px}
  .strap{height:auto;min-height:var(--strap-h);padding:8px var(--page-pad)}
}
@media (max-width:420px){
  .hd .logo img{width:96px}
  .hd .cta .btn{padding:0 10px;font-size:13px}
}

/* ───────────────────────── 6. HERO + STATS ───────────────────────── */
/* RULING 2026-09-06 (Veronika): the split stays; the Orange 10% tint and the paper texture come
   OFF the hero "for now". The hero sits on whatever ground its section has, like everything
   else. The Tandem hero recipe (orange 10% + crumpled paper at 60%) is kept in the comment of
   section 4 for when it comes back. */
/* RULING 2026-09-06: the laptop column is 30% wider than the copy column so the screen recording
   has pixels to be legible in (it was rendering at 436px wide; now about 560). Copy 1fr, laptop 1.6fr; the laptop
   itself may fill its column. */
.hero{display:grid;grid-template-columns:1.2fr 1.4fr;background:transparent}
.hero.hero--form{grid-template-columns:1.15fr 1fr}   /* a hero whose right column is a form card, not a laptop */
.hero.hero--form .r{display:block;align-items:flex-start;padding-top:164px;padding-right:calc(var(--content-pad) + var(--shadow-w))}
/* 164px, not 44: the card's top lands exactly on the bottom of the standfirst opposite (44px hero
   padding + eyebrow + H1 + standfirst). Measured on the rendered page, not guessed. It holds while
   the H1 is one line, so below 1200px the card goes back to the plain hero padding. The
   padding-right keeps the card's offset shadow on the column edge; the compound selector
   outranks .hero .r. */
@media (max-width:1200px){.hero.hero--form .r{padding-top:44px}}
.hero.hero--form .l{padding-right:16px}   /* 2026-09-07: 1fr/1.6fr left 378px for the H1 and "The AI Control Plane" needs 464 at 48px; the laptop gives up 12% */
.hero>*{position:relative;min-height:400px}
.hero .paper{display:none}   /* texture off for now - ruling 2026-09-06; the markup stays so it can come back */
.hero .l{padding:44px 32px 32px var(--content-pad)}
.hero .l>*{position:relative}
.hero h1{max-width:760px;margin-bottom:16px}   /* 640 clipped the 56px headline onto a third line */
.hero .lede{font:700 20px/28px var(--sans);max-width:640px;margin:0 0 24px}
.hero .r{display:flex;align-items:center;justify-content:flex-end;padding:36px var(--content-pad) 36px 24px}
/* The hero clip already contains the laptop, so it is never placed inside our laptop frame -
   that would be a laptop within a laptop. It is used at its native 3716x2230 with no re-encoding,
   so nothing is thrown away: at the size it renders there is far more resolution than needed. */
/* The clip is opaque white to its edges - H.264 cannot carry an alpha channel at all. Multiply
   drops that white into the hero ground so the laptop reads as cut out, and a white plate sits
   underneath exactly where the screen is, so the screen content blends against white and keeps
   its own colour instead of picking up the peach. Plate measured off the frame: the screen
   occupies 9.5% / 3.9% / 80.7% / 83.8% of a 3716x2230 canvas.
   The video itself is untouched - no re-encode, no scaling, native resolution. */
.hero-shot{position:relative;width:100%;max-width:760px}
.hero-shot::before{content:"";position:absolute;left:9.5%;top:3.9%;width:80.7%;height:83.8%;
  background:var(--white);border-radius:4px}
.hero-video{position:relative;width:100%;height:auto;display:block;mix-blend-mode:multiply}
/* the frame + separate screen recording, kept for anywhere a bare screen capture is used */
.laptop{position:relative;width:100%;max-width:900px;aspect-ratio:1400/847}
.laptop img{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.laptop video{position:absolute;left:9.56%;top:4.38%;width:80.62%;height:82.97%;object-fit:cover;background:var(--ink);border-radius:6px 6px 0 0}
@media (max-width:900px){.hero,.hero.hero--form{grid-template-columns:1fr}
  .hero.hero--form .l{padding-right:var(--content-pad)}
  .hero .r{padding-left:var(--content-pad)}}   /* stacked, the narrowed gutter goes back to the page padding, or the .halo's pull overruns the right edge. The compound selector must be repeated or .hero--form outranks the stack. */

.stats{background:var(--ink);color:var(--bone)}
/* RULING 2026-09-06: the band read crowded once the sans became Figtree (rounder, wider-set than
   Inter). Air, not size: the band is taller, the three columns sit further apart, the number
   gets a breath below it, and the source line stands off the sentence. Tandem's 208px band
   height is superseded by this. */
.stats .wrap{display:grid;grid-template-columns:repeat(3,1fr);gap:56px;padding-top:44px;padding-bottom:44px}
.stat{padding:6px 0 0 40px;border-left:var(--line-w) solid var(--azure)}   /* was 3px; ruling 2026-09-07: separators 1px, colour stays azure */
.stat:first-child{border-left:0;padding-left:0}
.stat b{display:block;font:900 40px/48px var(--sans);color:var(--azure);margin-bottom:10px}   /* = .n-stat */
.stat p{font:400 16px/26px var(--sans);margin:0 0 14px;max-width:320px;color:rgba(252,250,246,.9)}
.stat small{display:block;font:500 12px/16px var(--mono);letter-spacing:.04em;color:rgba(252,250,246,.6)}   /* = .n-src */
@media (max-width:900px){.stats .wrap{grid-template-columns:1fr;gap:28px}.stat{padding-left:0;border-left:0;border-top:3px solid var(--azure);padding-top:18px}.stat:first-child{border-top:0;padding-top:0}}
@media (max-width:900px){.stats .wrap{grid-template-columns:1fr}.stat{border-left:0;padding-left:0}}

/* ───────────────────────── 7. CARDS + ROWS ─────────────────────────
   SPEC, from the node tree ("Card text content", "Card text&Icon content"):
     radius 8 - border 1px #061635 - padding 24 - gap between children 16
     5-up row: 213 wide, 24 gutter, in the 1160 column (213x5 + 24x4 = 1161)
     4-up row: 272 wide, 24 gutter
     fill in the design is #FCFAF6 Bone on EVERY card; ours is white by the 2026-09-03 ruling.
     RESOLVED 2026-09-04: no section is ever plain white - a white ground always carries the
     dashed grid - so a white card does lift off it and the white-on-white ban is satisfied.
     dark card: fill #061635, border #1BB5E8, azure offset */
.cards{display:grid;gap:var(--gutter)}
.cards-5{grid-template-columns:repeat(5,1fr)}
.cards-4{grid-template-columns:repeat(4,1fr)}
@media (max-width:1100px){.cards-5,.cards-4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:600px){.cards-5,.cards-4{grid-template-columns:1fr}}
a.card{text-decoration:none;color:inherit}
.card{background:var(--white);border:1px solid var(--ink);border-radius:var(--radius-box);padding:24px;display:flex;flex-direction:column;gap:16px;box-shadow:var(--shadow-ink)}
.card .top{display:flex;align-items:flex-start;justify-content:space-between;gap:6px}
.card .top .mono12{display:flex;gap:6px}
.card .top img{width:32px;height:32px;flex:none}
/* ICONS. Source: Graphic elements for web\mini elements (51 interface icons) and
   iconsrutor-icon-set.svg (the semantic set). Drawn on a 24 grid, stroke only, no fill,
   1.5px, round caps and joins. Tandem's sheet colours them #131927; here an icon inherits the
   text colour, so one file works on white and on navy.
   Sizes by place: card top-right 32 - deployment row card 44 - inside a button 24 (inherits)
   - text-button arrow-tr 24 Azure, Azure Ink on hover - nav chevron 24 Azure (ruling; the sheet
   draws it Ink Navy) - form field leading icon 20 Grey 70 - strap arrow 24 Ink Navy. */
.b-icon{width:44px;height:44px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.card .top .b-icon{width:56px;height:56px}   /* was 44 (Card sheet ~40). RULING 2026-09-07: the icons are vectors; "fuzzy" was the drawing collapsing at 44px, 56 lets it resolve */
/* A CARD WHOSE TITLE SITS IN THE HEAD (2026-09-08). The number and the title stack on the left,
   directly under one another, and the icon stands beside them running the full height of that
   stack: its top on the number's top, its bottom on the title's bottom. Mark the head
   .top--titled and put the h3 inside it; a head without the h3 keeps the old arrangement. The
   icon is bigger here because it has the height to fill. */
.card .top--titled{display:block;position:relative;padding-right:92px}
.card .top--titled .thead{display:flex;flex-direction:column;gap:4px;min-width:0}
.card .top--titled .thead h3{margin:0;min-height:56px}   /* two lines reserved, so every head in the row is the same height and the icons come out the same size */
/* the icon is taken out of the flow and pinned to the head's own box: its top on the number's top,
   its bottom on the title's bottom. height:100%, never auto - an SVG is a replaced element, so with
   height:auto it takes its intrinsic height and the bottom offset is ignored. */
.card .top--titled .b-icon,.card .top--titled img.b-icon{position:absolute;right:0;top:0;
  width:76px;height:100%;object-fit:contain;flex:none}
.card--row .b-icon{width:44px;height:44px}
.b-icon--sm{width:24px;height:24px}
.b-icon--azure{stroke:var(--azure)}
.card h3{font-weight:700}
.card h3.black{font-weight:900}
.card .cfoot{margin-top:auto}
/* a card that links somewhere deeper carries the same arrow as a CTA, in our orange */
.ic--go{width:24px;height:24px;margin:auto 0 0 auto;stroke:var(--orange);fill:none;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;align-self:flex-end}
a.card:hover .ic--go{transform:translate(2px,-2px)}
.card--navy{background:var(--ink);border-color:var(--azure);color:var(--bone)}
.card--navy .dim{color:rgba(252,250,246,.8)}
.card--row{flex-direction:row;align-items:center;gap:16px}
.card--row img{width:58px;height:auto;flex:none}
.card--bone{background:var(--bone)}                               /* the sheet's own light card */
.on-dark .card,.bg-navy .card{box-shadow:var(--shadow-azure)}     /* boxes on navy: azure offset */
/* the sheet gives every card an optional TOP TAG and BOTTOM TAG in mono azure caps,
   and an index number in the same style pinned to the title row */
/* On a BLOG card the top tag is ALWAYS the category - on the featured card too. Ruling
   2026-09-05: a label reading "Featured read" tells the reader nothing and a crawler less,
   and the featured card is obviously featured because it is first and twice the size. */
.ttag,.btag{display:block;font:500 12px/16px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--azure-ink)}
.on-dark .ttag,.on-dark .btag,.card--navy .ttag,.card--navy .btag{color:var(--azure)}
.btag{margin-top:auto}
.ix{font:500 12px/16px var(--mono);color:var(--azure-ink)}
.card--navy .ix{color:var(--azure)}

/* BLOG CARD - built to `00-SPECS\Web style guidelines from Tandem\Card.png`, "Card: Blog".
   The sheet is the authority on treatment; the wireframe only supplies the page around it.

   The card is a picture band, then a Bone body holding five things in this order:
     1  TOP TAG      mono caps, wide tracking, Azure Ink - "featured read", "guide", the kind
                     of thing this is. It is bare text, never a bordered pill.
     2  TITLE        Inter Black, ink, two lines.
     3  STANDFIRST   on EVERY card, not just a featured one. It is what the card is for.
     4  BYLINE       "BRUTOR TEAM | MAY 25, 2026" - mono caps, a pipe with a space either side.
                     Tandem's system has no author name and no avatar. Do not add one.
     5  FOOT         the View button, and the Brutor.AI wordmark opposite it.

   THE PICTURE IS CROPPED TO A BAND, about 3:1, not the illustration's native 8:5. The crop
   takes the middle, which drops the label burned into the illustration's top-left corner -
   deliberately, because the card carries its own top tag and two labels would fight. */
.bcard{display:flex;flex-direction:column;background:var(--bone);border:1px solid var(--ink);
  border-radius:var(--radius-box);overflow:hidden;box-shadow:var(--shadow-ink);
  text-decoration:none;color:inherit;height:100%;transition:transform .12s,box-shadow .12s}
.bcard>img,.bcard .illus{display:block;width:100%;aspect-ratio:3/1;object-fit:cover;
  border:0;border-radius:0}
.bcard .body{display:flex;flex-direction:column;gap:12px;padding:22px 24px 0;flex:1}
.bcard h3{font:900 20px/28px var(--sans);color:var(--ink-black)}
.bcard p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0}
/* the byline. The pipe is written into the markup as " | " so it reads correctly to a screen
   reader and survives being copied out of the page.
   RULING 2026-09-05, OVERRIDING THE CARD SHEET: the byline carries the AUTHOR'S NAME, not
   "Brutor Team". Tandem's mock-up says team; we publish under a person and that is worth more
   than the consistency. Everything else about the byline - mono, caps, spaced pipe, Azure Ink
   - is unchanged. */
.bcard .byline{font:500 12px/16px var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--azure-ink)}
/* the foot sits on the dot grid, full width, and is the only part of the card with texture */
.bcard .cfoot{margin-top:auto;display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:18px 24px 20px;margin-left:-24px;margin-right:-24px;
  background-image:radial-gradient(var(--ink-10) 1.5px,transparent 1.5px);
  background-size:22px 22px}
.bcard .cfoot img{height:18px;width:auto}
/* THE ONE ARROW ALLOWED IN A BUTTON. The site rule is "no arrows inside buttons". The blog
   card's View button is the exception, because Tandem's Card sheet draws it with the ↗ and the
   card was approved with it on 2026-09-05. Nowhere else - not a CTA, not a nav link. */
.bcard:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--ink)}

/* FEATURED - the same card turned on its side: picture left, words right. The picture is no
   longer a band here, so it keeps the illustration's own 8:5. */
.bcard--feature{flex-direction:row;height:auto}
/* framed from the right, so the label burned into the illustration's top-left corner falls
   outside the crop. Centred, it was cutting the word in half - "NOMICS /" - and fighting the
   card's own top tag. Same reason the small cards crop to a band. */
.bcard--feature>img,.bcard--feature .illus{width:46%;aspect-ratio:auto;align-self:stretch;
  object-fit:cover;object-position:78% center}
.bcard--feature .body{width:54%;justify-content:center;gap:16px;padding:44px 44px 0}
.bcard--feature h3{font:900 34px/42px var(--sans);letter-spacing:-.01em}
.bcard--feature p{font-size:16px;line-height:26px}
.bcard--feature .cfoot{margin-left:-44px;margin-right:-44px;padding:20px 44px 24px}
@media (max-width:860px){
  .bcard--feature{flex-direction:column}
  .bcard--feature>img,.bcard--feature .illus{width:100%;aspect-ratio:3/1}
  .bcard--feature .body{width:100%;padding:22px 24px 0}
  .bcard--feature h3{font-size:24px;line-height:32px}
  .bcard--feature .cfoot{margin-left:-24px;margin-right:-24px;padding:18px 24px 20px}}

.bcard-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
@media (max-width:1000px){.bcard-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.bcard-grid{grid-template-columns:1fr}}

/* The row above the grid - a heading with a category filter beside it - comes from the
   wireframe, NOT from a Tandem sheet. Tandem's card system says nothing about filtering.
   Flagged to Veronika 2026-09-05; built plainly until she rules on it. It is a link list, not
   a control, so it works without JavaScript and WordPress does the filtering. */
/* the heading and the filter pills are one thing and get one halo between them, so no ruled
   line crosses either. Sized to the Tandem H2 (28/42) - it was falling through to the browser
   default of 24px, which is why it read a size small. */
.blist-head h2{font-size:28px;line-height:42px}
.blist-head{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;
  padding-bottom:18px;border-bottom:1px solid var(--ink-10);margin-bottom:28px}
/* CATEGORY NAMES ARE ESTABLISHED SEARCH TERMS, never our own coinage. An answer engine
   decomposes a question into sub-queries in established vocabulary and then looks for
   corroboration - several independent sources agreeing we are an authority on that term. A
   term only we use has no corroboration set, so nothing can agree and we cannot be retrieved
   on it. "AI Control & Assurance" is therefore positioning - masthead, llms.txt, about copy -
   and never a category. Checked against Kong (12 categories, all established terms) and
   Credo AI (8 subjects, exactly one coinage). Live taxonomy 2026-09-05: AI Governance,
   AI Gateway, AI FinOps & Tokenomics, Agentic AI & MCP, Shadow AI,
   AI Guardrails & Data Protection. */
.bfilter{display:flex;gap:10px;flex-wrap:wrap}
.bfilter a{font:500 12px/16px var(--mono);letter-spacing:.08em;text-transform:uppercase;
  padding:8px 14px;border-radius:var(--radius);border:1px solid var(--ink-10);
  background:var(--white);color:var(--ink-60);text-decoration:none}
.bfilter a:hover{border-color:var(--ink);color:var(--ink)}
.bfilter a[aria-current]{background:var(--ink);border-color:var(--ink);color:var(--bone)}

/* Video card - same shape, screenshot with an azure play badge, "Watch" text button */
.vcard{display:flex;flex-direction:column;background:var(--bone);border:1px solid var(--ink);border-radius:var(--radius-box);
  overflow:hidden;box-shadow:var(--shadow-ink)}
.vcard .shot{position:relative;border-bottom:1px solid var(--ink)}
.vcard .shot img{width:100%;height:auto}
.vcard .play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:44px;height:44px;border-radius:50%;
  background:var(--azure);display:flex;align-items:center;justify-content:center}
.vcard .play::after{content:"";border-left:14px solid var(--white);border-top:9px solid transparent;border-bottom:9px solid transparent;margin-left:4px}
.vcard .body{display:flex;flex-direction:column;gap:12px;padding:20px 24px 24px;flex:1}
.vcard h3{font:900 20px/28px var(--sans)}
.vcard .byline{font:500 12px/16px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-60)}

/* RULE: separation is either a line or a box, never both. A line-separated list (.rows) is for
   text standing on the page; if one is dropped inside a card or a schematic frame the lines come
   off, because the box is already doing the separating. */
.card .rows .row,.note .rows .row{border-top:0;padding-top:0}
.rows{display:grid}
.row{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:24px 0;border-top:1px solid var(--ink)}
.row:first-child{border-top:0}
.row .t{display:flex;gap:12px}
.row .t h3{font-weight:700}
.row .d{display:grid;gap:10px;align-content:start}
@media (max-width:760px){.row{grid-template-columns:1fr}}

/* BULLETS - ruling 2026-09-04: an azure CIRCLE, the same dot as in the Brutor logo. Never a
   square, never a rounded rectangle. Everywhere a list appears. 8x8, Azure 100%, 12px from its text.
   Tandem's sheets do not specify a body bullet, so this is ours and it applies to every list. */
.blist{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.blist li{position:relative;padding-left:22px;font:400 17px/24px var(--sans)}   /* body size and body leading: a list is prose, not a caption (2026-09-08) */
.blist li::before{content:"";position:absolute;left:0;top:9px;width:8px;height:8px;border-radius:50%;background:var(--azure)}
.on-dark .blist li::before{background:var(--azure)}

.list3{display:grid;gap:24px;margin:40px 0}
.list3 .it h3{font-weight:700;margin:0 0 8px}
.two{display:grid;grid-template-columns:1fr 3px 1fr;gap:40px}
.two .div{background:var(--azure)}
@media (max-width:900px){.two{grid-template-columns:1fr}.two .div{display:none}}
.qbox{padding:24px 28px;display:grid;grid-template-columns:1fr 1fr;gap:24px;margin:60px 0}
@media (max-width:760px){.qbox{grid-template-columns:1fr}}

/* ───────────────────────── 8. SCHEMATICS (notebook + info cards) ───────────────────────── */
/* ═══ THE DRAWING LAW (Veronika 2026-09-07 evening). Every schematic, drawing and figure on the site
   is drawn to ONE grammar, and an existing one is re-skinned to it with one command
   (_ref/reskin-schematic.py in out - style only, text and geometry verified unchanged). The
   grammar is the architecture schematic's, which she likes, "brutalized a bit":
     LINES     hairline: 1px everywhere; 1.5px only for an emphasised boundary. Never thicker.
     DASHES    short and tight: 3 3 ("not ours / not yet"), 4 3 (a flow line). Never long dashes.
     ARROWS    small: 5px heads; a filled dot (r 2.5) where the line simply ends at a step.
     OPACITY   none. Tints are solid palette tints (#E8F4FA azure tint, #FFF0E6 orange tint,
               #F3EFE7 bone deep). No alpha, no blur, no filter, no gradient.
     CORNERS   boxes r 6; the outer frame, when there is one, follows the FRAME LAW (r 8).
     COLOUR    four classes, each one meaning, learned once (the architecture schematic's legend):
                 in the request path (Brutor)      fill Azure #1BB5E8, white type
                 alongside it (Brutor service)     fill Azure tint #E8F4FA, ink type, azure line
                 you deploy and own                fill White, ink line
                 outside the gateway               fill Ink #061635, bone type
                 the boundary / the one way out    Orange #FF6D00 line (and orange type on dark)
               Orange is allowed as a line and as emphasis; a fifth fill is not.
     TYPE      Figtree for labels (13-15px), IBM Plex Mono for indices, kickers and ports (10-12px).
     CONTENT   a re-skin never adds, removes or moves a word or a shape. Tandem's semi-transparent
               orange/azure treatment is retired; their three information-card classes below map
               onto the four classes above (primary = in the path, secondary = alongside,
               tertiary = you deploy). */
/* SPEC, from the node tree ("Rectangle 28") and the Schematics sheet:
     frame   1160 wide - border 1px #061635 - radius 8 - ink offset. RULING 2026-09-04:
           the frame is TRANSPARENT; a schematic sits on the section ground, never on a
           panel of its own. (The node tree fills it Bone Deep 80% - overridden.)
     info card  radius 6 - border 1px - fill at 10%: Azure for a step, Orange for Brutor,
                Azure with a dashed border for the customer's side ("Card text content"
                226x115 fill #1BB5E8@0.10 stroke #1BB5E8/1.0 r=6)
     connector  dashed, ending in a filled dot; azure between steps, orange to and from Brutor
   Tandem Schematics sheet. "Frame for the visual" = the notebook panel; inside it sit three
   kinds of information card, joined by dashed connectors that end in a dot.
     .sc--orange  Primary   - anything that IS Brutor (the gateway, the step it takes over)
     .sc--azure   Secondary - a step in the Brutor process, numbered
     .sc--yours   Tertiary  - the customer's side: "your framework", "any MCP client",
                              "your content", "your app or agent" - dashed border
   Illustration width: --schematic-max (1160px) when content-heavy; otherwise split the frame
   50:50, 60:40 or 70:30 with .sch-split. RULING: the frame has no spiral holes - the page
   edges carry that idea now. */
.note{position:relative;background:transparent;border:1px solid var(--ink);border-radius:var(--radius-box);padding:24px;box-shadow:var(--shadow-ink)}   /* frame: Bone Deep 80%, ink 1px, r8 - node tree "Rectangle 28" */
.note--white{background:var(--white)}
/* .note--paper RETIRED 2026-09-07 (frame law) */
/* a diagram drawn as SVG: no panel, no border, nothing behind it */
.figure{margin:24px 0;background:transparent;border:0;box-shadow:none;padding:0}
.figure svg{width:100%;height:auto;display:block}
.figure>p{margin-bottom:16px}
.figure.frame{overflow:hidden;background:var(--bone)}   /* a drawn picture in the standard frame: the drawing fills it edge to edge */
.figure.frame svg{display:block}
.sch{max-width:var(--schematic-max)}
/* LAYOUTS. Tandem gave us the vocabulary - the frame, the three information cards, the dashed
   connectors - but no layouts, so every diagram so far invented its own pixel grid (.life, .gw,
   .flow, .frames, .diff below, all hard-coded column widths). These four replace that: the
   columns are proportional, so a diagram adapts instead of needing new numbers each time.
     .sch--chain  a row of steps joined by connectors; wraps onto further rows
     .sch--hub    inputs, then Brutor in the middle, then what comes out
     .sch--stack  a centred stack, for grouped pills or frames
     .sch--split  a diagram beside its explanation (50:50, --60, --70)
   Rules: at most four boxes in a chain row, exactly one Brutor card per diagram, the caption
   sits above the diagram and the note below it, and the frame is optional. */
.sch--chain{display:flex;flex-wrap:wrap;align-items:stretch;gap:0 8px}
.sch--chain>.sc{flex:1 1 190px}
.sch--chain>.conn{flex:0 0 30px}
.sch--chain+.sch--chain{margin-top:20px}
.sch--hub{display:grid;grid-template-columns:1fr 40px 1.3fr 40px 1fr;gap:8px;align-items:stretch}
.sch--hub .col{display:grid;gap:16px;align-content:start}
.sch--hub .mid{display:grid;gap:12px;align-content:start}
.sch--stack{max-width:686px;margin:24px auto 0;display:grid;gap:14px;text-align:center}
.sch--stack .r{display:flex;flex-wrap:wrap;justify-content:center;gap:14px}
@media (max-width:900px){
  .sch--chain>.conn{display:none}
  .sch--chain{gap:12px}
  .sch--chain>.sc{flex:1 1 100%}
  .sch--hub{grid-template-columns:1fr}
  .sch--hub .conn{display:none}
}
.sch-split{display:grid;gap:var(--gutter);grid-template-columns:1fr 1fr}
.sch-split--60{grid-template-columns:6fr 4fr}
.sch-split--70{grid-template-columns:7fr 3fr}
@media (max-width:900px){.sch-split,.sch-split--60,.sch-split--70{grid-template-columns:1fr}}
.sc{border-radius:var(--radius);padding:12px;font:400 15px/24px var(--sans)}
.sc b{display:block;font:900 17px/24px var(--sans)}
/* COLOUR MEANINGS in a schematic. Tandem specified only two fills, diluted azure and diluted
   orange, which is not enough to draw with. The set below extends it while keeping each colour
   tied to one meaning, so a reader learns it once:
     azure   a governed step Brutor performs
     orange  Brutor itself, and the moments that matter - the boundary, the gate, the response
     ink     neutral structure: your people, your applications, the box the traffic passes through
     muted   outside the path, or wound down: your own tooling before Brutor, an agent retired
   Dashed always means "not ours / not yet ours". Solid means enforced. */
.sc--azure,.sc--secondary{background:var(--azure-10);border:1px solid var(--azure)}
.sc--ink{background:var(--white);border:1px solid var(--ink)}
.sc--ink-solid{background:var(--ink);border:1px solid var(--ink);color:var(--bone)}
.sc--muted{background:var(--grey-30);border:1px solid var(--grey);color:var(--ink)}
.sc--muted-dash{background:transparent;border:1px dashed var(--grey)}
.sc--orange,.sc--primary{background:var(--orange-10);border:1px solid var(--orange)}
.sc--yours,.sc--tertiary{background:var(--azure-10);border:1px dashed var(--azure)}
.sc .n{float:right;font:500 14px/16px var(--mono);color:var(--azure-ink);margin-left:8px}
/* "Semantic" chips inside an information card - they take the card's own tint */
.sc .chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.sc .chip{font:600 14px/16px var(--sans);padding:6px 10px;border-radius:var(--radius);border:1px solid var(--azure);background:var(--white)}
.sc--orange .chip,.sc--primary .chip{border-color:var(--orange);background:rgba(255,109,0,.06)}
/* connectors: dashed, ending in a dot. Azure between steps, orange to and from Brutor. */
.conn{position:relative;width:30px;height:2px;flex:none;align-self:center;
  background:repeating-linear-gradient(90deg,var(--azure) 0 4px,transparent 4px 8px)}
.conn::after{content:"";position:absolute;right:-2px;top:50%;transform:translateY(-50%);width:7px;height:7px;border-radius:50%;background:var(--azure)}
.conn--o{background:repeating-linear-gradient(90deg,var(--orange) 0 4px,transparent 4px 8px)}
.conn--o::after{background:var(--orange)}
.conn--v{width:2px;height:30px;margin:0 auto;background:repeating-linear-gradient(180deg,var(--azure) 0 4px,transparent 4px 8px)}
.conn--v::after{right:auto;left:50%;top:auto;bottom:-2px;transform:translateX(-50%)}
.conn--v.conn--o{background:repeating-linear-gradient(180deg,var(--orange) 0 4px,transparent 4px 8px)}
.cap{font:700 15px/24px var(--sans);text-align:center}

.life{display:grid;gap:20px}
.life .r1{display:grid;grid-template-columns:226px 30px 131px 30px 1fr 30px 1fr;gap:8px;align-items:center}
.life .r2{display:grid;grid-template-columns:1fr 30px 1fr 30px 1fr 30px 1fr;gap:8px;align-items:center}
@media (max-width:900px){.life .r1,.life .r2{grid-template-columns:1fr}.conn{display:none}}
.gw{display:grid;grid-template-columns:147px 40px 226px 40px 202px;gap:8px;align-items:stretch}
.gw .col{display:grid;gap:16px;align-content:start}
.gw .links{display:grid;gap:130px;align-content:center}
.gw .brutor{display:grid;gap:12px;align-content:start}
.gw .brutor b{font:900 20px/28px var(--sans);text-align:center;padding:38px 0 0}
.gw .brutor h4{font:900 17px/24px var(--sans);text-align:center}
.gw .brutor p{text-align:center}
.gw-caps{display:flex;justify-content:space-between;gap:24px;margin-top:16px;font:400 15px/24px var(--sans);text-transform:uppercase}
@media (max-width:900px){.gw{grid-template-columns:1fr}.gw .links{display:none}}
.flow{display:grid;grid-template-columns:1fr 40px 1fr 40px 1fr;gap:8px;align-items:center}
@media (max-width:900px){.flow{grid-template-columns:1fr}}
.frames{max-width:686px;margin:24px auto 0;display:grid;gap:14px;text-align:center}
.frames .r{display:flex;flex-wrap:wrap;justify-content:center;gap:14px}
/* THE DIFFERENCE block. EXCEPTION to the heading-above rule, hers, 2026-09-08: the H2 sits in the
   left column with its text, and the picture on the right runs the full height of that column, its
   top on the H2's top and its bottom on the CTA's. The EYEBROW still opens the section, above both
   columns, so the section label never sits inside a column (2026-09-08). */
.diff{display:grid;grid-template-columns:1.25fr 1fr;column-gap:56px;row-gap:14px;align-items:stretch}   /* row-gap is the eyebrow's leading, NOT the column gap (2026-09-08) */
/* RULING 2026-09-08 (supersedes the 09-07 one that put it across the top): the eyebrow sits in
   the text column, directly above the H2 it labels. The picture is sized and pushed to the
   column's right edge, so it aligns with the page rather than floating in its cell. */
/* The picture's top sits on the HEADLINE's top, not the eyebrow's (ruling 2026-09-08), so it is
   pushed down by the eyebrow's own block: 11/14 mono plus its 6px margin, less the 12px the
   figure already sits below the row start. Measured on the rendered page, not guessed. */
.diff .figure{width:400px;max-width:100%;justify-self:end;align-self:start;margin-top:8px;
  height:auto;display:block}   /* ONE rule for this figure: a second .diff .figure further down the
  sheet was silently winning on margin and stretching the picture to the row height. Merged 2026-09-08. */
.diff .figure svg{width:100%;height:auto;display:block}
/* equal air above and below the paragraph: headline to first line = last line to the CTA */
.diff .lead{margin-top:32px;margin-bottom:32px}   /* measured equal on the rendered page: headline to first line = last line to the CTA */

.diff>div:first-of-type{display:flex;flex-direction:column;align-items:flex-start}
.diff>div:first-child .tbtn{margin-top:auto}
/* .diff .shot: the screenshot is a plain .shot frame like every other (frame law 2026-09-07) */
@media (max-width:1000px){.diff{grid-template-columns:1fr;gap:40px}}



/* ───────────────────────── 10. FORMS ─────────────────────────
   SPEC, from the Figma "Input Field" frame:
     field    48 tall, radius 6, fill Azure 10%, border 1px Azure 30%, optional leading icon,
              placeholder in Grey 50. Focus takes a full Azure border. Disabled fades the text.
     on dark  fill Grey 80, border Grey 70, placeholder Grey 40, text Bone.
     radio    20px circle, 2px Ink border; selected fills Azure, unselected fills Grey 50.
     toggle   dark track, Azure knob.
   Labels, help text and errors are ours; the frame does not draw them. */
.form{display:grid;gap:20px}
.form-row{display:grid;gap:20px;grid-template-columns:1fr 1fr}
@media (max-width:760px){.form-row{grid-template-columns:1fr}}
.field{display:grid;gap:6px}
.field label{font:700 14px/20px var(--sans)}
.field .help{font:400 12px/16px var(--sans);color:var(--ink-60)}
.field .err{font:400 12px/16px var(--sans);color:var(--danger)}

.input,.select,.textarea{width:100%;height:48px;padding:0 14px;border-radius:var(--radius);
  border:1px solid var(--azure);background:var(--azure-10);color:var(--ink);
  font:400 15px/24px var(--sans);transition:border-color .12s,box-shadow .12s}
.textarea{height:auto;min-height:120px;padding:12px 14px;resize:vertical}
.input::placeholder,.textarea::placeholder{color:var(--grey);opacity:1}
.input:hover,.select:hover,.textarea:hover{border-color:var(--azure-ink)}
.input:focus,.select:focus,.textarea:focus{outline:0;border-color:var(--ink);box-shadow:0 0 0 3px var(--azure-10)}
.input[disabled],.select[disabled],.textarea[disabled]{color:var(--disabled-fg);border-color:var(--grey-30);background:rgba(27,181,232,.05);cursor:not-allowed}
.field--invalid .input,.field--invalid .textarea,.field--invalid .select{border-color:var(--danger)}

/* SEARCH - ruling 2026-09-05: NOT the tinted Input Field. A plain white box with a thin ink
   border, no icon inside it, and the Book Demo button beside it - .btn--secondary, which is
   white with the ink border and the azure hard shadow, so the search reads as the same kind of
   control as the one in the header rather than as a form field.
   It is a real GET form: works with JavaScript off, WordPress does the searching. */
/* a visible placeholder is not a label, so the real label is present and hidden */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.search{display:flex;gap:10px;align-items:center;max-width:520px;margin:64px 0 18px auto}
.search .field-wrap{position:relative;flex:1}
.search .input{background:var(--white);border:1px solid var(--ink);padding:0 16px}
.search .input::placeholder{color:var(--ink-60)}
.search .input:hover{border-color:var(--ink)}
.search .input:focus{border-color:var(--ink);box-shadow:0 0 0 3px var(--azure-10)}
.search .btn{flex:none}
@media (max-width:520px){.search{flex-wrap:wrap}.search .btn{width:100%;justify-content:center}}
.select{appearance:none;padding-right:40px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231BB5E8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat;background-position:right 12px center;background-size:20px 20px}
/* a field with a leading icon */
.input-ic{position:relative;display:block}
.input-ic .ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:20px;height:20px;
  stroke:var(--grey);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.input-ic .input{padding-left:42px}
/* on a navy ground */
.on-dark .input,.on-dark .select,.on-dark .textarea{background:var(--grey-80);border-color:var(--grey);color:var(--bone)}
.on-dark .input::placeholder,.on-dark .textarea::placeholder{color:var(--disabled-bg)}
.on-dark .field label{color:var(--bone)}
.on-dark .field .help{color:rgba(252,250,246,.6)}

/* radio + checkbox: 20px, 2px Ink border, Azure when chosen */
.choice{display:inline-flex;align-items:center;gap:10px;font:400 15px/24px var(--sans);cursor:pointer}
.choice input{appearance:none;margin:0;width:20px;height:20px;border:2px solid var(--ink);
  background:var(--grey);flex:none;cursor:pointer;transition:background .12s}
.choice input[type=radio]{border-radius:50%}
.choice input[type=checkbox]{border-radius:4px}
.choice input:checked{background:var(--azure)}
.choice input:disabled{background:var(--disabled-bg);border-color:var(--disabled-fg);cursor:not-allowed}
.choices{display:flex;flex-wrap:wrap;gap:20px}

/* toggle: dark track, azure knob */
.toggle{display:inline-flex;align-items:center;gap:10px;cursor:pointer;font:400 15px/24px var(--sans)}
.toggle input{appearance:none;margin:0;width:44px;height:20px;border-radius:10px;background:var(--ink);
  position:relative;cursor:pointer;flex:none;transition:background .12s}
.toggle input::after{content:"";position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;
  background:var(--azure);transition:transform .14s}
.toggle input:checked::after{transform:translateX(24px)}
.toggle input:disabled{background:var(--disabled-fg)}


/* ───────────────────────── 11. CONTENT ELEMENTS ─────────────────────────
   The pieces a page reaches for that are not cards, buttons or schematics. Built to the same
   line weights and radii as everything else: 1px Ink Navy borders, radius 6 on a chip, 8 on a
   block, the hard offset only where a thing is meant to lift. */

/* ═══ THE PILL RULE (Veronika 2026-09-08, settled after checking Docker and Kong) ═══════════════
   WHAT A PILL IS. A pill is a LABEL, not a control. It states a fact about something else: a
   capability, a state, a framework. It is never pressed. That is the whole reason its treatment
   differs from a button's.

   HOW IT LOOKS.
     corner    6px, the same radius as a button. (Her 2026-07-06 ruling said ~8px; SUPERSEDED
               2026-09-08 after the options were seen side by side.)
     fill      NONE. Transparent, always. "No creepy fills by sicko orange and blue" - the tinted
               azure and orange backgrounds are retired.
     border    1px, and the BORDER carries the meaning:
                 ink     neutral, a plain fact
                 azure   something governed by Brutor
                 orange  Brutor itself, or a moment that matters
     type      500 15/24 Figtree, Ink Navy, sentence case. Never uppercase, never mono.

   WHERE A PILL BELONGS (the rule that matters more than the radius).
     YES  inside a schematic, inside a card, as a status label, as a short list of named things
          the reader will scan rather than read.
     NO   as a row in body copy where a sentence would do the work. Checked 2026-09-08: neither
          Docker nor Kong puts a row of chips in prose. Docker uses a badge only for "New" and
          "MOST POPULAR"; Kong's only page chip is a countdown, and its docs badge is a 4px "New".
          Both write capabilities as text. A row of seven pills reads as a control panel, not a
          sentence, and that is the fault to avoid.
   EXISTING PAGES ARE HER JOB, NOT A SCRIPT'S (2026-09-08): the look changes everywhere from this
   rule, but turning a pill row back into prose is a CONTENT edit and is done by hand, page by
   page, so no wording is ever lost to an automatic pass. */
.pill{display:inline-block;padding:6px 12px;border-radius:var(--radius);border:1px solid var(--ink);
  background:transparent;font:500 15px/24px var(--sans);color:var(--ink)}
.pill--azure{border-color:var(--azure)}
.pill--orange{border-color:var(--orange)}
.pill--plain{border-color:transparent}
.pill--lg{font:600 17px/24px var(--sans);padding:8px 16px}
.pill--sm{font:700 11px/14px var(--mono);letter-spacing:.1em;padding:3px 8px;text-transform:uppercase}   /* a badge beside a line of type: the strap's NEW (2026-09-08) */
/* RULING 2026-09-08: the strap's badge is the ONE pill drawn heavier than a hairline. It sits in
   a 36px bar at 11px type, where a 1px border disappears. Orange border, IBM Plex Mono, caps.
   Audit check 6 knows .pill--thick; nothing else may use it without a ruling. */
.pill--thick{border-width:2px}
.strap .pill{font:700 11px/14px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}   /* .strap a sets a 900 sans font on everything inside it, so the badge has to say otherwise */
.on-dark .pill,.bg-navy .pill{border-color:var(--bone);color:var(--bone)}
.on-dark .pill--azure,.bg-navy .pill--azure{border-color:var(--azure)}
.on-dark .pill--orange,.bg-navy .pill--orange{border-color:var(--orange)}
.pills{display:flex;flex-wrap:wrap;gap:10px}
/* a button row inside a hero needs air below it, or the next line sits on the buttons'
   hard shadow (seen on /mcp-workbench/ 2026-09-06) */
.hero .pills{margin:26px 0 30px}
.on-dark .pill{background:transparent;border-color:var(--azure);color:var(--bone)}

/* TABLES - for pricing and feature comparison. Ink Navy hairlines, no zebra striping, no
   vertical rules: the row line does the work, as it does in .rows. A figure in a cell follows
   the number rule, so it is mono unless it is the headline number. */
.table-wrap{overflow-x:auto}
table.tbl{width:100%;border-collapse:collapse;font:400 15px/24px var(--sans)}
table.tbl caption{text-align:left;font:500 12px/16px var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--plum);padding-bottom:12px}
table.tbl th,table.tbl td{text-align:left;padding:14px 16px;border-bottom:1px solid var(--ink-10);vertical-align:top}
table.tbl thead th{font:900 15px/24px var(--sans);border-bottom:1px solid var(--ink);white-space:nowrap}
table.tbl tbody tr:last-child td{border-bottom:1px solid var(--ink)}
table.tbl th[scope=row]{font:700 15px/24px var(--sans)}
table.tbl .n-data,table.tbl .n-stat{white-space:nowrap}
table.tbl .yes{color:var(--success)}      /* a tick, the only place green is allowed */
table.tbl .no{color:var(--danger)}        /* a failure cross, the only place red is allowed */
.on-dark table.tbl th,.on-dark table.tbl td{border-color:var(--divider-dark);color:var(--bone)}

/* CALLOUT - a short aside that must not be missed. Left rule in the colour of its kind. */
.callout{border-left:3px solid var(--azure);padding:4px 0 4px 18px;margin:24px 0;
  font:400 15px/24px var(--sans)}
.callout b{display:block;font:900 17px/24px var(--sans);margin-bottom:4px}
.callout--orange{border-left-color:var(--orange)}
.callout--quiet{border-left-color:var(--ink-10)}

/* FIGURE + CAPTION - an image or a diagram with its explanation underneath. */
.fig{margin:24px 0}
.fig img{width:100%;height:auto;border:1px solid var(--ink);border-radius:var(--radius-box)}
.fig figcaption{margin-top:10px;font:500 12px/18px var(--sans);color:var(--ink-80);max-width:760px}

/* PULL QUOTE */
.quote{margin:32px 0;padding-left:20px;border-left:3px solid var(--orange);
  font:900 20px/28px var(--sans);color:var(--ink);max-width:760px}
.quote cite{display:block;margin-top:10px;font:500 12px/16px var(--mono);
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-80);font-style:normal}

/* PROSE - long-form running text: the blog, the legal pages, anything written rather than laid
   out. Lists take the azure box; links carry the azure-ink underline so they read as links in a
   wall of text without shouting. */
.prose{max-width:760px}
.prose p{margin:0 0 18px;font:400 17px/27px var(--sans)}
.prose h2{font-size:28px;line-height:42px;margin:36px 0 10px}
.prose h3{font-size:20px;line-height:28px;margin:28px 0 8px}
.prose ul,.prose ol{margin:0 0 18px;padding-left:0;list-style:none}
.prose li{position:relative;padding-left:20px;margin-bottom:8px;font:400 17px/27px var(--sans)}
.prose ul li::before{content:"";position:absolute;left:0;top:10px;width:8px;height:8px;border-radius:50%;background:var(--azure)}
.prose ol{counter-reset:n}
.prose ol li{counter-increment:n}
.prose ol li::before{content:counter(n,decimal-leading-zero);position:absolute;left:0;top:2px;
  font:500 12px/16px var(--mono);color:var(--azure-ink)}
.prose a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--azure-ink);
  text-decoration-thickness:2px;text-underline-offset:3px}
.prose a:hover{color:var(--azure-ink)}
.prose blockquote{margin:24px 0;padding-left:20px;border-left:3px solid var(--azure);
  font:400 17px/27px var(--sans);color:var(--ink-80)}
.prose small{font:500 12px/18px var(--sans);color:var(--ink-80)}
.prose code{font:500 14px/22px var(--mono);background:var(--azure-10);padding:1px 5px;border-radius:4px}

/* LOGO STRIP - the customer row from the wireframes. */
.logos{display:flex;flex-wrap:wrap;align-items:center;gap:40px;padding:8px 0}
.logos img{height:28px;width:auto;opacity:.75}

/* FOCUS - one visible ring for anyone using a keyboard. Azure, offset so it never touches the
   thing it is marking. Not in any Tandem sheet; required, so it is here. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:3px solid var(--azure);outline-offset:2px;border-radius:2px}
/* a jump link must not land under the sticky header */
:target{scroll-margin-top:calc(var(--header-h) + 24px)}


/* ───────────────────────── 11b. PICTURES, TABLES, WORKFLOW, SPLIT ─────────
   All of these were read off the Brutor deck template, which already follows the brand. */

/* SCREENSHOTS AND PICTURES. A picture is a box, so it takes a box's treatment: 1px Ink Navy,
   radius 8, and the hard offset. Black offset on a light ground, azure on a dark one - the same
   rule as a card, so a screenshot never invents its own frame. */
.shot{display:block;max-width:100%;height:auto}   /* framed by the FRAME LAW. max-width, never width: a screenshot is shown at its own pixels or smaller, never stretched (the fuzz rule) */
.shot--plain{box-shadow:none}
.fig img{width:100%;height:auto}   /* framed by the FRAME LAW */

/* WHICH CARD ON WHICH GROUND. A card never contrasts by fill; it matches its ground's family and
   separates with the border and the offset. So:
     on a light ground (white+grid, white+fuzzy)  -> white card, Ink border, BLACK offset
     on a navy ground                             -> navy card, Azure border, AZURE offset
     inside a schematic frame                     -> the tinted information cards, 10% fills
   The only time a card changes fill is Bone (.card--bone), used when a white card would sit on
   pure white with no texture behind it - which on this site should never happen. */

/* COMPARISON TABLE - from the deck. Column heads in mono azure caps, rows split by a hairline,
   the row label bold, and the Brutor column raised out of the table as a navy panel. */
table.tbl--compare thead th{font:800 12px/16px var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--azure);border-bottom:0;padding-bottom:18px}
table.tbl--compare th,table.tbl--compare td{border-bottom:1px solid var(--ink-10);padding:18px 16px}
table.tbl--compare th[scope=row]{font:700 15px/24px var(--sans);color:var(--ink)}
table.tbl--compare td{color:var(--ink-80)}
table.tbl--compare .brutor{position:relative;background:var(--ink);color:var(--bone);
  border-bottom:1px solid rgba(252,250,246,.12);text-align:center;font:700 15px/24px var(--sans)}
table.tbl--compare thead .brutor{color:var(--azure);font:800 14px/20px var(--sans);letter-spacing:.04em;
  border-radius:var(--radius-box) var(--radius-box) 0 0;border-bottom:0}
table.tbl--compare tbody tr:last-child .brutor{border-radius:0 0 var(--radius-box) var(--radius-box);
  border-bottom:0;box-shadow:var(--shadow-azure)}

/* WORKFLOW - numbered steps on a dotted rail. The badge is an orange square, the rail is dotted
   orange, the step card is Bone with the black offset, and the arrows between are azure. */
.wf{display:grid;gap:0}
.wf-rail{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;align-items:center;margin-bottom:14px}
.wf-rail span{position:relative;justify-self:start;margin-left:18px;z-index:1;
  display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:30px;padding:0 8px;
  background:var(--orange);color:var(--white);border-radius:var(--radius);
  font:800 13px/16px var(--mono);letter-spacing:.08em}
.wf-rail{background-image:repeating-linear-gradient(90deg,var(--orange) 0 3px,transparent 3px 9px);
  background-size:100% 2px;background-position:0 14px;background-repeat:no-repeat}
.wf-steps{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;align-items:stretch}
.wf-step{position:relative;background:transparent;border:1px solid var(--ink);border-radius:var(--radius-box);
  box-shadow:var(--shadow-ink);padding:22px 20px;margin-right:34px}
.wf-step:last-child{margin-right:0}
.wf-step::after{content:"";position:absolute;right:-30px;top:50%;width:26px;height:2px;background:var(--azure)}
.wf-step:last-child::after{display:none}
.wf-step b{display:block;font:900 20px/28px var(--sans);margin-bottom:8px}
.wf-step p{font:400 15px/22px var(--sans);color:var(--ink-80)}
@media (max-width:900px){
  .wf-rail,.wf-steps{grid-auto-flow:row;background-image:none}
  .wf-step{margin:0 0 14px}.wf-step::after{display:none}
}

/* SPLIT - colour blocking edge to edge. Two fields meet on a hard vertical with no gutter and no
   rule; nothing straddles the join and each side keeps its own margin. */
.split{display:grid;grid-template-columns:1fr 1fr}
.split>*{padding:var(--section-y) var(--page-pad)}
.split .l{background:var(--ink);color:var(--bone)}
.split .r{background:var(--white)}
.split .accent{height:3px;background:var(--azure);margin:26px 0;max-width:470px}
.split .l .accent{background:var(--azure)}
.split .r .accent{background:var(--azure)}
@media (max-width:900px){.split{grid-template-columns:1fr}}

/* NUMBERED POINTS with an accent rule under each - the deck's supporting panel.
   Azure on a light ground, orange on a dark one, matching the underline rule. */
.points{display:grid;gap:22px;margin:0;padding:0;list-style:none}
.points li{font:700 15px/24px var(--sans);padding-bottom:12px;border-bottom:2px solid var(--azure)}
.on-dark .points li{color:var(--bone);border-bottom-color:var(--orange)}
.points li .n{font:800 12px/16px var(--mono);letter-spacing:.11em;color:inherit;margin-right:6px}

/* TERMINAL - a code or log panel. Navy ground, azure border and offset, mono throughout, with
   the syntax colours drawn from the closed palette: azure for values, orange for a label. */
.term{background:var(--ink);border:1px solid var(--azure);border-radius:var(--radius-box);
  box-shadow:var(--shadow-azure);overflow:hidden;font:500 14px/24px var(--mono)}
.term .bar{padding:12px 18px;border-bottom:1px solid var(--azure);color:var(--orange);
  font:500 14px/20px var(--mono)}
.term .body{padding:18px;color:var(--azure);white-space:pre-wrap}
.term .k{color:var(--bone)}
.term .v{color:var(--azure)}
.term .w{color:var(--orange)}


/* ───────────────────────── 11c. CONTENT BLOCK ─────────────────────────
   The workhorse for a feature section: a numbered heading, a grid of points, an optional CTA
   pill, and a screenshot or a schematic. Taken from Tandem's "two cards blended", with one
   change: their version sits inside a perforated paper frame, and the page edges now carry the
   perforation, so the block drops the frame. It sits directly on the section ground instead,
   and the section's own texture does the separating. Never put a perforated frame inside a
   perforated page.

   Two layouts, both from the reference:
     .cb--split   text on the left, media on the right, 50:50
     .cb--stack   text across the top, media full width beneath
*/
.cb{display:grid;gap:40px}
.cb--split{grid-template-columns:1fr 1fr;align-items:start}
.cb--stack{grid-template-columns:1fr}
@media (max-width:900px){.cb--split{grid-template-columns:1fr}}

/* the heading: a navy numbered badge, the headline, and a mono subtitle */
.cb-head{display:grid;grid-template-columns:auto 1fr;gap:0 20px;align-items:start;margin-bottom:32px}
.cb-head .badge{grid-row:span 2;display:flex;align-items:center;justify-content:center;
  width:62px;height:62px;background:var(--ink);color:var(--bone);border-radius:var(--radius);
  font:800 22px/24px var(--mono);letter-spacing:.06em}
.cb-head h2{align-self:end}
.cb-head .sub{font:500 17px/26px var(--mono);color:var(--plum);margin-top:6px}
.on-dark .cb-head .badge{background:var(--azure);color:var(--ink)}
.on-dark .cb-head .sub{color:var(--azure)}

/* the points: an azure box bullet, a bold title, a line of body. Rows split by a hairline. */
.cb-points{display:grid;gap:0;grid-template-columns:repeat(2,1fr)}
.cb-points--3{grid-template-columns:repeat(3,1fr)}
@media (max-width:760px){.cb-points,.cb-points--3{grid-template-columns:1fr}}
.cb-point{padding:20px 24px 20px 0;border-top:1px solid var(--ink-10)}
.cb-points>.cb-point:nth-child(1),.cb-points>.cb-point:nth-child(2){border-top:0}
.cb-points--3>.cb-point:nth-child(3){border-top:0}
.cb-point b{display:flex;align-items:flex-start;gap:12px;font:700 17px/24px var(--sans);margin-bottom:6px}
.cb-point b::before{content:"";flex:none;width:10px;height:10px;margin-top:7px;border-radius:50%;background:var(--azure)}
.cb-point p{font:400 15px/22px var(--sans);color:var(--ink-80);padding-left:22px}
.on-dark .cb-point{border-top-color:var(--divider-dark)}
.on-dark .cb-point p{color:rgba(252,250,246,.8)}

/* the CTA pill: an orange bar with a play badge, a mono eyebrow, a title and an arrow */
.cta-pill{display:flex;align-items:center;gap:16px;padding:14px 18px;background:var(--azure-10);
  border:1px solid var(--ink);border-radius:var(--radius);box-shadow:var(--shadow-ink);
  text-decoration:none;color:var(--ink);max-width:520px;margin-top:28px}
.cta-pill:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--ink)}
/* orange is NOT used for this - the tinted-orange treatment was rejected 2026-09-04 */
.cta-pill .play{flex:none;display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  background:var(--white);border:1px solid var(--ink);border-radius:var(--radius)}
.cta-pill .play::after{content:"";border-left:12px solid var(--ink);border-top:8px solid transparent;
  border-bottom:8px solid transparent;margin-left:3px}
.cta-pill .t{flex:1}
.cta-pill .t span{display:block;font:800 11px/16px var(--mono);letter-spacing:.13em;text-transform:uppercase}
.cta-pill .t b{display:block;font:900 17px/24px var(--sans)}
.cta-pill .ic{width:24px;height:24px;flex:none;stroke:var(--ink);fill:none;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}

/* the media half: a screenshot framed the way every picture is framed */
.cb-media{align-self:start}
.cb-media img{width:100%;height:auto;border:1px solid var(--ink);border-radius:var(--radius-box);box-shadow:var(--shadow-ink)}
.on-dark .cb-media img{border-color:var(--azure);box-shadow:var(--shadow-azure)}
.cb--stack .cb-media{margin-top:8px}


/* ───────────────────────── 11d. FIGURES AND DATA TABLES ─────────────────────
   Values read off `Graphic elements for web\schematics\Brutor AI - Homepage v9 ...html`,
   which is the best use of the palette we have. Every label inside a figure is IBM Plex Mono;
   only the caption's description is set in Inter. */

/* the figure wrapper: a numbered caption, a white panel with the black offset, a legend */
.fig2{margin:36px 0 0}
.fig2-head{display:flex;align-items:baseline;gap:14px;margin-bottom:12px;
  font:600 11px/16px var(--mono);letter-spacing:.14em;text-transform:uppercase}
.fig2-head b{color:var(--ink);font-weight:700}
.fig2-head span{color:var(--ink-60);font:400 12px/18px var(--sans);letter-spacing:0;text-transform:none}
/* FRAME LAW (Veronika 2026-09-07, after the same mistake came back): every framed element - a
   figure panel, an illustration, a screenshot, a tile, a code excerpt, a schematic frame - is
   THE SAME FRAME: transparent, 1px Ink border, radius 8, hard offset shadow: black on a light
   ground, azure (with an azure border) on a dark one. No fill, no texture, no colour treatment
   inside it. Never define a boxed component without this rule; extend .frame, don't restyle. */
/* ── NO PERFORATION ON A PICTURE (ruling 2026-09-09) ───────────────────────────────────────
   THE SPROCKET HOLES BELONG TO THE PAGE, NOWHERE ELSE. A picture, a schematic, a figure
   panel or a card NEVER carries a punched or perforated edge of its own: the page edges
   carry that idea now, and a second row of holes inside the content reads as a sheet inside
   a sheet. Wherever such an edge appears, it is replaced by THE FRAME: 1px ink, radius 8,
   6px black offset shadow (azure on dark), which is the FRAME LAW block directly below.
   This supersedes the older half-sentence buried in section 8 ("the frame has no spiral
   holes"), which was too easy to miss. The hole pattern is drawn in exactly one place in
   this sheet, on `.page--edges main::before/::after`; audit check 15 fails the deploy if it
   turns up anywhere else. */
.frame,.illus,.wptile,.codebox,.shot,.fig img,.qbox,.pcard{border:1px solid var(--ink);border-radius:var(--radius-box);box-shadow:var(--shadow-ink);background:transparent}
.on-dark .frame,.on-dark .illus,.on-dark .wptile,.on-dark .codebox,.on-dark .shot,.on-dark .fig img,.on-dark .qbox,.bg-navy .qbox,
.bg-navy .frame,.bg-navy .illus,.bg-navy .wptile,.bg-navy .codebox,.bg-navy .shot,.bg-navy .fig img{box-shadow:var(--shadow-azure);border-color:var(--azure)}
/* RULING 2026-09-08: a FIGURE PANEL carries NO frame. The drawing is already a closed composition;
   a border around it doubles the edge. It sits on the section ground with air, nothing else.
   (The frame law still governs pictures, screenshots, tiles and code: those are not drawings.) */
.fig2-panel{padding:0;border:0;box-shadow:none;background:transparent}
.fig2-body{padding:22px 0 18px}
.fig2-body svg{width:100%;height:auto;display:block}
/* the legend: mono, with a 15x11 swatch that says which kind of mark it explains */
.fig2-key{display:flex;gap:22px;flex-wrap:wrap;padding:12px 0 16px;border-top:1px solid var(--ink-10)}
.fig2-key i{font-style:normal;display:inline-flex;align-items:center;gap:8px;
  font:600 10px/14px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-60)}
.fig2-key i::before{content:"";width:15px;height:11px;border:1.8px solid var(--ink);background:var(--white)}
.fig2-key i.k-ink::before{background:var(--ink)}
.fig2-key i.k-dash::before{border-style:dashed;border-color:rgba(6,22,53,.45)}
.fig2-key i.k-flow::before{border:0;height:0;border-top:2px dashed var(--azure);width:19px}
.fig2-key i.k-limit::before{background:var(--orange);border-color:var(--ink)}

/* LEDGER TABLE - rows that alternate. A tinted row is Azure at 12%, the row between it is left
   clear; the tint replaces the hairline rather than joining it, so the two never both appear.
   Row pitch 26. Use this when a table is dense enough that the eye loses its place; use
   .tbl--compare when the point is one column beating the others. */
table.tbl--ledger{border-collapse:collapse;width:100%}
table.tbl--ledger caption{text-align:left;font:600 11px/16px var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-60);padding-bottom:8px;border-bottom:2px solid var(--ink)}
table.tbl--ledger th,table.tbl--ledger td{border:0;padding:6px 12px;font:600 13px/26px var(--sans);color:var(--ink)}
table.tbl--ledger tbody tr:nth-child(odd){background:rgba(27,181,232,.12)}
table.tbl--ledger th[scope=row]{font-weight:700}
table.tbl--ledger td.dim{color:var(--ink-60);font-weight:400}
table.tbl--ledger td.mono{font:600 13px/26px var(--mono);color:var(--azure-ink)}
table.tbl--ledger td.fig{text-align:right;font-weight:700;white-space:nowrap}
table.tbl--ledger tbody{border-bottom:2px solid var(--ink)}
.on-dark table.tbl--ledger th,.on-dark table.tbl--ledger td{color:var(--bone)}

/* METER - a budget bar with a warn mark and a refuse mark */
.meter{position:relative;height:24px;border:1.8px solid var(--ink);background:var(--white)}
.meter span{position:absolute;left:2px;top:2px;bottom:2px;background:var(--azure)}
.meter i{position:absolute;top:-8px;bottom:-8px;width:3px;background:var(--orange)}
.meter-key{display:flex;justify-content:space-between;gap:16px;margin-top:8px;
  font:600 10px/14px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-60)}

/* the small navy panel that sits beside a figure - Sky is its rule, and this is the one place
   Sky earns its keep */
.fig2-aside{background:var(--ink);color:var(--bone);border-top:5px solid var(--sky);padding:18px 20px}
.fig2-aside h4{font:600 11px/16px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--azure);margin:0 0 12px}
.fig2-aside ul{list-style:none;margin:0;padding:0}
.fig2-aside li{display:flex;justify-content:space-between;gap:16px;padding:4px 0;font:700 15px/24px var(--sans)}
.fig2-aside li span{color:var(--azure);font-weight:600}
.fig2-aside p{margin:12px 0 0;padding-top:10px;border-top:1px solid var(--divider-dark);
  font:400 12px/18px var(--sans);color:rgba(252,250,246,.7)}

/* ───────────────────────── 11e. ILLUSTRATIONS ────────────────────────────────
   AN ILLUSTRATION IS NOT A SCHEMATIC. Keep the two words apart:
     ILLUSTRATION  a finished picture from Tandem, used to carry a blog card or an H1.
                   Paper-cut style, decorative. It does not explain anything.
                   Lives in `assets/illustrations/`. We never draw one.
     SCHEMATIC     a thing we design on purpose to show how something works - the
                   .fig2 / .schem components above. Labelled, legended, load-bearing.
   Never use one where the other belongs, and never call one by the other's name.

   WHAT WE HAVE - 21 files, all 6667 x 4167 (exactly 8:5), from
   `Web Design and Assets\Graphic elements for web\illustrations and cards`:
     topics/     13 finished illustrations, one per subject. USE THESE.
     templates/   7 card LAYOUTS with placeholder type baked into the flat PNG
                  ("Guide Title", "Event Name", "Write a quote / main headline").
                  Reference only until Tandem gives us editable files - see the note below.
     tiles/       1 asset cover (the Assurance white paper title page).

   TWO THINGS EVERY TOPIC ILLUSTRATION ALREADY CARRIES, so we must not add them again:
     1. ITS OWN EYEBROW, burned into the top-left corner: an azure square and the subject
        set in mono caps between slashes. Do not put a .eyebrow above the picture, and do
        not crop the top-left - the crop would eat the label.
     2. ITS OWN GROUND. Some are bone, some are near-black navy, and the ground runs to
        the edge of the file. So an illustration never sits on a coloured band and never
        needs a background behind it. It brings its own.
   Both of those hold WHEN THE ILLUSTRATION IS PLACED WHOLE - an H1 band, a wide feature.
   A BLOG CARD IS THE EXCEPTION: Tandem's Card sheet crops the picture to a band of about 3:1,
   which takes the middle and drops the burned-in corner label on purpose, because the card
   supplies its own top tag. So: whole at 8:5 for an H1, cropped to a band for a card, and
   never any other shape. */

/* the picture itself. 8:5 is not a suggestion - every file is that ratio, so a box of any
   other shape is cropping the artwork. */
.illus{display:block;width:100%;aspect-ratio:8/5;object-fit:cover}   /* framed by the FRAME LAW (11d) */
.illus--plain{border:0;box-shadow:none;border-radius:0}   /* when the illustration meets a dark band edge-on */
.bcard .illus,.card .illus{border:0;box-shadow:none;border-radius:0}   /* already inside a frame */

/* WHICH FILE TO ASK FOR. Two derivatives are built from each original:
     assets/illustrations/<group>/web/<slug>@800.jpg   a card, up to ~560px wide
     assets/illustrations/<group>/web/<slug>.jpg       an H1 or a full-width band
   The 6667px original stays in <group>/<slug>.png and is never served to a browser. */

/* BLOG CARD - see .bcard in section 7. It is defined once, with the other cards, because
   that is where a card belongs; only its picture rule lives here. */
.bcard .illus{border:0;border-bottom:1px solid var(--ink)}

/* H1 BAND - the illustration beside the headline, not behind it. Text over one of these is
   unreadable: the artwork runs light-on-bone in one corner and near-black in another. */
.h1-illus{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.h1-illus .illus{box-shadow:var(--shadow-azure)}
@media (max-width:900px){.h1-illus{grid-template-columns:1fr;gap:28px}}

/* THE TEMPLATES, AND WHY THEY ARE NOT READY. All seven are flat PNGs with their placeholder
   type painted into the artwork, sitting ON the illustration rather than beside it - so the
   words cannot be covered without covering the picture. Until Tandem sends layered files,
   treat a template as a LAYOUT REFERENCE: rebuild it with .bcard and real type, and take
   only the arrangement from the PNG. Do not ship one with "Write a quote" still on it. */

/* ───────────────────────── 14. BLOG POST ─────────────────────────
   Layout: a full-width headline on one of our normal grounds, then a two-column body - prose
   left at a readable measure, a sticky rail right carrying the contents and the tags.
   SOURCE: the main web design guidelines and the rulings of 2026-09-05. From Tandem's blog
   PDF we take ONLY the illustration and the table of contents - the rest of that file is
   ruled out. */

/* HERO - our own grounds, not the Tandem blog PDF (ruled out 2026-09-05: from that file we
   take ONLY the illustration and the table of contents). The hero section takes a normal
   ground class - .bg-grid or .bg-lined - with a .halo under the type, exactly like every
   other page. Nothing here invents a band or a border of its own.
   The headline runs the FULL page width. */
.post-hero h1{font-size:52px;line-height:60px;letter-spacing:-.02em;max-width:22ch}
@media (max-width:900px){.post-hero h1{font-size:34px;line-height:42px}}
.post-hero .stand{font:400 19px/30px var(--sans);color:var(--ink-80);margin:22px 0 0;max-width:62ch}

/* AUTHOR - a small picture, the name in bold, the job title underneath, sitting under the
   headline. No biography and no navy band (ruling 2026-09-05). */
.post-by{display:flex;align-items:center;gap:14px;margin-top:32px;flex-wrap:wrap}
.post-by img{width:48px;height:48px;border-radius:50%;border:1px solid var(--ink);object-fit:cover;flex:none}
.post-by .who b{display:block;font:700 16px/22px var(--sans);color:var(--ink)}
.post-by .who span{display:block;font:400 14px/20px var(--sans);color:var(--ink-60)}
.post-by .meta{margin-left:auto;font:500 12px/16px var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-60)}
@media (max-width:640px){.post-by .meta{margin-left:0;width:100%}}

/* BODY - prose and rail. 1fr/320px, which puts the measure at about 70 characters. */
.post-body{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:56px;align-items:start}
@media (max-width:980px){.post-body{grid-template-columns:1fr;gap:36px}
  .post-rail{order:-1;position:static !important}}

/* the prose itself. A post body carries NO style attributes - see the note at the top. */
.post-prose h2{font-size:32px;line-height:40px;margin:56px 0 14px;scroll-margin-top:100px}
.post-prose h2:first-child{margin-top:0}
.post-prose h3{font-size:19px;line-height:28px;margin:32px 0 8px}
.post-prose p{font:400 17px/29px var(--sans);color:var(--ink-80);margin:0 0 20px}
.post-prose a{color:var(--azure-ink);text-decoration:underline;text-underline-offset:3px}
.post-prose a:hover{color:var(--ink)}
.post-prose strong{color:var(--ink);font-weight:700}
.post-prose ul,.post-prose ol{margin:0 0 22px;padding-left:0;list-style:none}
.post-prose ul li{position:relative;padding-left:26px;margin-bottom:10px;
  font:400 17px/29px var(--sans);color:var(--ink-80)}
.post-prose ul li::before{content:"";position:absolute;left:0;top:11px;width:8px;height:8px;
  border-radius:50%;background:var(--azure)}
.post-prose img{display:block;width:100%;height:auto;border:1px solid var(--ink);
  box-shadow:var(--shadow-ink);margin:32px 0 36px}
/* a dashed rule closes each section, as in the Tandem design */
.post-prose .sect + .sect{border-top:1.5px dashed var(--ink-10);padding-top:8px}

/* RAIL - contents and tags, and it follows you down the page */
.post-rail{position:sticky;top:88px;display:grid;gap:24px}

/* CONTENTS - Tandem's design: a dot per section, joined by a dotted line, and the line above
   the current section fills in azure so the dots double as a progress bar. The current item
   takes a solid azure dot and an azure-tinted label. */
.toc{background:var(--white);border:1px solid var(--ink-10);border-radius:var(--radius-box);
  padding:22px 20px}
.toc h4{font:500 12px/16px var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-60);margin:0 0 16px}
.toc ol{list-style:none;margin:0;padding:0;position:relative}
.toc li{position:relative;padding-left:34px;padding-bottom:20px}
.toc li:last-child{padding-bottom:0}
/* the joining line: dotted by default, and the ::after of a DONE item paints it azure */
.toc li::before{content:"";position:absolute;left:7px;top:20px;bottom:0;width:0;
  border-left:2px dotted var(--ink-10)}
.toc li:last-child::before{display:none}
.toc li.done::before{border-left:2px solid var(--azure)}
.toc a{display:block;font:400 14px/20px var(--sans);color:var(--ink-80);text-decoration:none;
  padding:2px 8px;margin-left:-8px;border-radius:4px}
.toc a::before{content:"";position:absolute;left:0;top:4px;width:16px;height:16px;
  border-radius:50%;background:var(--grey-30);border:2px solid var(--white);
  box-shadow:0 0 0 1px var(--ink-10)}
.toc li.done a::before{background:var(--azure);box-shadow:0 0 0 1px var(--azure)}
.toc a:hover{color:var(--ink)}
.toc li[aria-current] a{background:var(--azure-10);color:var(--ink);font-weight:600}
.toc li[aria-current] a::before{background:var(--azure);box-shadow:0 0 0 3px rgba(27,181,232,.25)}

/* TAGS - the rail's second block. Ruling 2026-09-05: a post shows its tags; they were
   missing entirely. The category leads, in the card top-tag style, then the tags. */
.post-tags{display:grid;gap:12px}
.post-tags h4{font:500 12px/16px var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-60);margin:0}
.post-tags .list{display:flex;flex-wrap:wrap;gap:8px}
.post-tags a{font:500 12px/16px var(--mono);letter-spacing:.06em;text-transform:uppercase;
  padding:7px 12px;border-radius:var(--radius);border:1px solid var(--ink-10);
  background:var(--white);color:var(--ink-60);text-decoration:none}
.post-tags a:hover{border-color:var(--ink);color:var(--ink)}
.post-tags a.is-cat{border-color:var(--azure);color:var(--azure-ink);background:var(--azure-10)}

/* END CTA - the two buttons that close the Tandem design */
.post-end{display:flex;gap:14px;flex-wrap:wrap;margin-top:44px;padding-top:36px;
  border-top:1.5px dashed var(--ink-10)}

/* RELATED - three cards, restyled from the old strap onto .bcard.
   RULE 2026-09-05: there must ALWAYS be three. If fewer than three posts share the category,
   fill the remaining slots first with a video, then with the most recent posts not already
   shown. A row of two, or a row with a hole in it, is never shipped. */
.related{border-top:1px solid var(--ink)}
.related h2{font-size:28px;line-height:42px;margin-bottom:24px}

/* TANDEM SCHEMATICS - lifted as vectors from `Final UI screens\Home Screen - 3rd Iteration.svg`
   by _ref/extract-from-tandem-svg.py into assets/tandem/. Their text is outlines, so the words
   travel in the alt attribute (the verified aria-label text). Ruling 2026-09-06: use Tandem's
   schematics as given. The lifecycle one carries Tandem's own copy bugs baked into the outlines
   (repeated placeholder lines, wrong numbering), so it stays the inline SVG with correct text
   until it is rebuilt in Tandem's style with the right words. */
.schem-img{display:block;width:100%;height:auto}

/* ───────────────────────── 11f. COMPARISON TABLE ─────────────────────────
   The competitive matrix as a FIGURE, built on the ledger (11d): alternating azure rows, mono
   labels, and one solid navy Brutor column with the Sky rule on top - the one place Sky earns
   its keep. Three tiers, each opened by its question in the figure-head style; the tier
   headings are the argument. Colour says something: navy tick = yes, orange tilde = partial or
   claimed (the cell a buyer should question), quiet dash = no public claim, ring = not assessed yet. */
.cmp{width:100%;border-collapse:separate;border-spacing:0;font:400 14px/20px var(--sans);color:var(--ink)}
.cmp th,.cmp td{padding:9px 10px;text-align:center;vertical-align:middle}
.cmp th{font:500 11px/14px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-60);
  border-bottom:2px solid var(--ink);padding-bottom:12px}
.cmp th:first-child,.cmp td:first-child{text-align:left;padding-left:0;font-weight:600;min-width:260px}
.cmp tbody tr:nth-child(odd) td{background:rgba(27,181,232,.12)}
.cmp tbody tr:nth-child(odd) td.us{background:var(--ink)}
/* the Brutor column: a navy panel the full height of the table, sky rule on top */
.cmp th.us{background:var(--ink);color:var(--bone);border-top:5px solid var(--sky);border-bottom-color:var(--ink);
  font:700 12px/14px var(--mono);letter-spacing:.12em}
.cmp td.us{background:var(--ink);color:var(--bone);font-weight:700}
.cmp tbody tr:last-child td.us{border-bottom:5px solid var(--sky)}
/* tier rows: the question spans the whole table, set like a figure head. The navy Brutor
   column pauses under it and resumes below: three navy panels, one per tier, each with the sky
   rule top and bottom (the row that closes a tier carries .last). */
.cmp tr.tier td{background:var(--white) !important;text-align:left;padding:38px 0 12px;border-bottom:2px solid var(--ink)}
.cmp tr.tier td .n{font:600 11px/16px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--azure-ink);display:block;margin-bottom:6px}
.cmp tr.tier td b{font:900 24px/30px var(--sans);color:var(--ink-black);display:block}
.cmp tr.tier td span{font:400 15px/22px var(--sans);color:var(--ink-80);display:block;margin-top:4px;max-width:80ch}
.cmp tr.tier+tr td.us{border-top:5px solid var(--sky)}
.cmp tr.last td.us{border-bottom:5px solid var(--sky)}
.cmp tbody tr:last-child td.us{border-bottom:5px solid var(--sky)}
/* the marks */
.cmp .y,.cmp .p,.cmp .n0,.cmp .na{font-size:19px;line-height:20px}
.cmp .na{color:rgba(6,22,53,.28);font-weight:400;font-size:15px}   /* ○ not assessed yet */
.cmp .y{color:var(--ink);font-weight:900}
.cmp .p{color:var(--orange);font-weight:900}
.cmp .n0{color:rgba(6,22,53,.28);font-weight:400}
.cmp td.us .y{color:var(--bone)}
.cmp td.us .n0{color:rgba(252,250,246,.35)}
/* legend, as on the ledger */
.cmp-key{display:flex;gap:26px;flex-wrap:wrap;padding:14px 0 0;font:500 11px/16px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-60)}
.cmp-key i{font-style:normal;display:inline-flex;align-items:center;gap:8px}
.cmp-key .y,.cmp-key .p,.cmp-key .n0{font-size:15px}
.cmp-note{font:400 12px/18px var(--sans);color:var(--ink-60);max-width:100ch;margin-top:14px}
.cmp-wrap{overflow-x:auto}
.halo .lead+.lead{margin-top:16px}   /* two-paragraph intro on the masthead */
@media (max-width:900px){.cmp th:first-child,.cmp td:first-child{min-width:200px}}


/* ───────────────────────── 11g. HOMEPAGE 2026: CHAPTERS, QUESTION STRIP, ANSWERS ─────────
   Rulings 2026-09-06/07. A "divider" is a CHAPTER OPENER, not an ornament: a full-bleed band with
   its own ground, a mono chapter mark, a masthead-size title, a one-line dek, and an illustration
   crop bleeding off the right two-fifths. Each chapter a different picture and a different ground
   (bone, azure, ink) so the page reads as three chapters, not one scroll. Boxes only for parallel
   items; the five questions are a strip, not cards; each answer is a claim heading, a short lead
   and one visual. */
.chapter{position:relative;display:grid;grid-template-columns:3fr 2fr;gap:48px;align-items:center;min-height:300px;
  padding:48px calc(var(--content-pad) + var(--shadow-w)) 48px var(--content-pad)}   /* RULING 2026-09-07: the picture stays INSIDE the content column (it bled under the rail before) */
.chapter>*{position:relative}
.chapter .ch-text{padding:16px 0}
.chapter .ch-num{display:block;font:700 12px/16px var(--mono);letter-spacing:.14em;text-transform:uppercase;margin:0 0 14px}
.chapter .ch-title{font:900 56px/62px var(--sans);letter-spacing:-.02em;margin:0 0 14px;max-width:16ch}
.chapter .ch-dek{font:400 17px/24px var(--sans);max-width:52ch;margin:0}
.chapter .ch-art img{display:block;width:100%;aspect-ratio:8/5;object-fit:cover;border:1px solid var(--ink);border-radius:var(--radius-box);box-shadow:var(--shadow-ink)}   /* the one frame */
.chapter--bone{background:var(--bone-deep);color:var(--ink)}
.chapter--bone .ch-num{color:var(--plum)}
.chapter--azure{background:var(--azure);color:var(--ink)}
.chapter--azure .ch-num{color:var(--ink)}
.chapter--ink{background:var(--ink);color:var(--bone)}
.chapter--ink .ch-num{color:var(--azure)}
.chapter--ink .ch-title{color:var(--bone)}
.chapter--ink .ch-art img{border-color:var(--azure);box-shadow:var(--shadow-azure)}
@media (max-width:900px){.chapter{grid-template-columns:1fr}.chapter .ch-title{font-size:40px;line-height:46px}}

/* four stats on the band (the IBM line joined the three) */
.stats--4 .wrap{grid-template-columns:repeat(4,1fr);gap:40px}
.stats--4 .stat{padding-left:28px}
.stats--4 .stat b{font-size:36px;line-height:44px}
.stats--4 .stat p{font-size:15px;line-height:24px}

/* the five questions: a strip, not cards. Number, question, one link to its answer. */
.qstrip{display:grid;grid-template-columns:repeat(5,1fr);gap:32px;margin-top:32px}
.qstrip a{display:grid;align-content:start;gap:10px;text-decoration:none;color:var(--ink)}
.qstrip .num{font:700 13px/16px var(--mono);letter-spacing:.12em;color:var(--azure-ink)}
.qstrip h3{font:700 18px/26px var(--sans);margin:0}
.qstrip .go{display:inline-flex;align-items:center;gap:6px;font:600 15px/22px var(--sans);color:var(--azure)}
.qstrip .go .ic{width:20px;height:20px;stroke:var(--azure);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.qstrip a:hover h3{color:var(--azure-ink)}
@media (max-width:1000px){.qstrip{grid-template-columns:repeat(2,1fr)}}

/* an answer: the question it answers, a claim heading, three sentences, one visual */
.ans{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
/* A SPLIT WHOSE RIGHT-HAND SIDE IS A CARD, not a picture: the content column takes the width and
   the card sits beside it at a fixed size (2026-09-08). */
.ans--card{grid-template-columns:2.6fr 1fr;gap:56px;align-items:start}   /* the content takes the width; the card is a companion, not a second column (2026-09-08) */
/* PROMO CARD - one article, offered beside a section, never competing with the section's own CTA.
   It takes the FRAME LAW like any other box; the ORANGE is the accent only, on the kicker and the
   arrow, never a fill (her ruling 2026-09-08: orange allowed here). */
.pcard{padding:22px;display:grid;gap:8px;align-content:start;background:var(--bone);min-width:270px}
.pcard .ttag{color:var(--orange-deep)}   /* Orange on Bone is 2.7:1, under the 3:1 floor, and this
  is an 11px tracked mono label. Orange Deep is the readable orange; the card keeps the signature
  orange on its arrow, which is a graphic and not type. (2026-09-08) */
.pcard h3{font:900 18px/26px var(--sans)}
.pcard p{font:400 14px/22px var(--sans);color:var(--ink-80);margin:0}
.pcard .tbtn{margin-top:4px}
.pcard .tbtn .ic{stroke:var(--orange)}
.ans--text-wide{grid-template-columns:1.25fr 1fr}
.qline{display:flex;gap:14px;align-items:baseline;font:600 19px/28px var(--sans);color:var(--ink-80);margin:0 0 14px}
.qline .num{font:700 13px/16px var(--mono);letter-spacing:.12em;color:var(--azure-ink);flex:none}
.ans h2{margin-bottom:16px}
.ans .lead{margin-bottom:22px}
.ans .illus{aspect-ratio:8/5}   /* native: the illustrations carry their topic label, never crop it */
@media (max-width:900px){.ans,.ans--text-wide{grid-template-columns:1fr;gap:32px}}

/* the white paper tile: cover crop + one paragraph + the link */
.wptile{display:grid;grid-template-columns:200px 1fr;gap:28px;align-items:center;padding:24px 28px}
.wptile img{width:100%;height:auto;border:1px solid var(--ink);border-radius:4px;display:block}
.wptile h3{font:900 22px/28px var(--sans);margin:0 0 8px}
.wptile p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0 0 14px}
@media (max-width:700px){.wptile{grid-template-columns:1fr}}

/* a code / ledger excerpt inside a row: mono on Bone Deep, ink border, no shadow (it is content, not a card) */
.codebox{margin:16px 0;padding:14px 18px;font:500 13px/22px var(--mono);color:var(--ink);white-space:pre;overflow-x:auto}
.row .d .pills{margin:4px 0 8px}
.row .d h4{margin-top:8px}
.qstrip p{font:400 15px/22px var(--sans);color:var(--ink-80);margin:0}   /* the strip carries plain items too */

/* STEPS: numbered steps read top to bottom beside a picture, joined by centred orange arrows
   (Veronika 2026-09-07, Shadow AI section: Discover -> Onboard -> Control). (.flow is an older
   schematic layout; this is the prose component.) */
.steps{display:grid;gap:6px;max-width:52ch}
.steps .step b{display:block;font:900 17px/24px var(--sans);color:var(--ink);margin-bottom:4px}
.steps .step p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0}
.steps .arr{display:flex;justify-content:center;padding:6px 0}
.steps .arr svg{width:18px;height:22px;stroke:var(--orange);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
/* an orange underline on any heading (the masthead's .u-o, generalised) */
.u-o{text-decoration:underline;text-decoration-color:var(--orange);text-decoration-thickness:3px;text-underline-offset:6px}
/* an Azure Ink underline on a heading word (Veronika 2026-09-07: "your way" in dark azure) */
.u-ai{text-decoration:underline;text-decoration-color:var(--azure-ink);text-decoration-thickness:3px;text-underline-offset:6px}
/* a deployment card: icon on top, title, one line, all centred (Veronika 2026-09-07, from her screenshot) */
.card--dep{align-items:center;text-align:center;gap:10px;padding:28px 24px}
.card--dep img{width:58px;height:auto}
.card--dep h3{margin:4px 0 0}
.card--dep p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0}
/* a CTA button may carry the ↗ glyph; it takes the button's text colour unless told otherwise */
.btn .ic{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.btn--navy .ic{stroke:var(--azure)}

/* STEPS AS A SCHEMATIC (Veronika 2026-09-07): each step is a box in the drawing law (azure 50%,
   azure hairline, r6, ink type, the index in Ink Navy mono), joined by centred azure arrows of the
   schematic's weight: 1px line, 6px head. */
.steps--boxed{max-width:none}
/* A WORKFLOW ACROSS THE PAGE (2026-09-09): the same boxed steps laid out left to right, with the
   arrows turned to match. Equal columns so the three read as one sequence rather than three
   cards of different weight; the arrow columns take only the width of the arrow. Below 900px it
   goes back to a stack and the arrows point down again. */
.steps--flow{grid-template-columns:1fr auto 1fr auto 1fr;align-items:stretch;gap:0}
.steps--flow .arr{padding:0 18px;align-items:center}
.steps--flow .arr svg{transform:rotate(-90deg)}
@media (max-width:900px){.steps--flow{grid-auto-flow:row;gap:6px}
  .steps--flow .arr{padding:6px 0}.steps--flow .arr svg{transform:none}}
.sc--step{background:#8DDAF4;border:1px solid var(--azure);border-radius:var(--radius);padding:14px 18px}
.sc--step b{display:block;font:900 17px/24px var(--sans);color:var(--ink);margin-bottom:4px}
.sc--step b .n{float:none;font:700 12px/16px var(--mono);letter-spacing:.1em;color:var(--ink);margin:0 10px 0 0}   /* the index LEADS the title (the generic .sc .n floats right) */
.sc--step p{font:400 15px/24px var(--sans);color:var(--ink);margin:0}
.steps--boxed .arr{padding:2px 0}
.steps--boxed .arr svg{width:14px;height:26px;stroke:var(--azure);stroke-width:1;fill:var(--azure)}
/* a picture beside a block: fill the block's height so top and bottom align with it */
.ans--fill{align-items:stretch}
.ans--fill .illus{height:100%;aspect-ratio:auto;object-fit:contain;object-position:center}
/* a fuzzy oval ground under a transparent picture, in the colour of the picture's original ground */
.illus-halo{position:relative;display:grid}
.illus-halo::before{content:"";position:absolute;left:-6%;right:-6%;top:-4%;bottom:-4%;border-radius:50%;
  background:radial-gradient(ellipse at center,var(--halo-c,#EBE0D8) 0 52%,transparent 76%);pointer-events:none}   /* reaches past the picture so its hard edges sit on the oval, not on the grid */
.illus-halo .illus{position:relative}
/* three claims, one per line, a 1px hairline between them */
.claims{display:grid;max-width:56ch}
.claims p{margin:0;padding:14px 0;font:400 17px/24px var(--sans);color:var(--ink);border-top:var(--line-w) solid var(--ink-10)}
.claims p:first-child{border-top:0;padding-top:0}

/* QUESTION MARK (Veronika 2026-09-07 late, corrected): a quoted question is HIGHLIGHTED, the way a
   word processor fills behind each letter, so the Bone follows the text and leaves a ragged stack of
   rectangles. Never a bordered box: no border, no radius, no shadow. box-decoration-break:clone puts
   the padding on every line, not only the first and last. */
/* the highlight sits BEHIND THE LETTERS ONLY (2026-09-08): the padding is tight, box-decoration-break
   clones it onto every line, and the line box never runs on to fill the column. */
/* THE HIGHLIGHT SITS BEHIND THE LETTERS ONLY. It must stay display:inline for that, so it can never
   be a direct child of a flex or grid container: a flex item is blockified and the background then
   fills the whole box (the fault of 2026-09-08). Always wrap it: <div class="qwrap"><span
   class="qmark">…</span></div>. box-decoration-break clones the padding onto every line. */
.qwrap{display:block}
/* the highlighter behind the question. BONE DEEP, not Bone: the card face is white, and Bone is
   three levels off white, so the fill was there but invisible (2026-09-08). Deep is twelve
   levels, which reads as a highlighter and still never as a filled box. */
.qmark{display:inline;background:var(--bone-deep);box-decoration-break:clone;-webkit-box-decoration-break:clone;
  padding:2px 5px;font:700 18px/28px var(--sans);color:var(--ink)}

/* FLIP CARD (Veronika 2026-09-07/08). Front = the index, its label under it, the icon in the top
   right, and the question highlighted. Hover turns the card to its back (the sub-text and the link);
   the whole card is one link to its section, so a click goes straight there. Both faces are in the
   DOM, so an agent or a reader with motion off sees both, never nothing.
   HOVER INTENT (2026-09-08): the flip waits 180ms before it starts, so dragging the pointer across
   the row no longer sets five cards spinning. Leaving turns back at once. */
.flip{perspective:1400px;display:block;text-decoration:none;color:inherit}
.flip-inner{display:grid;height:100%;transform-style:preserve-3d;
  transition:transform .5s cubic-bezier(.2,.7,.2,1);transition-delay:0s}
.flip:hover .flip-inner,.flip:focus-visible .flip-inner{transform:rotateY(180deg);transition-delay:.18s}
.flip-face{grid-area:1/1;backface-visibility:hidden;-webkit-backface-visibility:hidden;display:flex;flex-direction:column;gap:14px;padding:22px;
  background:var(--white);border:1px solid var(--ink);border-radius:var(--radius-box);box-shadow:var(--shadow-ink)}
/* the head: index over its label on the left, the icon on the right, its top on the index's top and
   its bottom on the label's baseline block (2026-09-08) */
.flip-face--front{align-items:flex-start}
.flip-face--front .top{width:100%;display:flex;align-items:stretch;justify-content:space-between;gap:12px}
.flip-face--front .top .mono12{display:flex;flex-direction:column;gap:2px}
.flip-face--front .top .num{display:block;font:700 13px/16px var(--mono);letter-spacing:.1em;color:var(--azure-ink)}
.flip-face--front .top .lbl{display:block;font:500 13px/18px var(--mono);color:var(--ink)}
.flip-face--front .b-icon{width:38px;height:38px;flex:none;align-self:stretch;object-fit:contain}
.flip-face--front img.b-icon{width:38px;height:38px}
.flip-face--front .qwrap{margin:auto 0;text-align:center}   /* the question is centred in the card (2026-09-08) */
/* the back: everything centred, and the link stands clear of the sentence */
.flip-face--back{transform:rotateY(180deg);justify-content:center;align-items:center;text-align:center;gap:0}
.flip-face--back .dim{font:400 17px/24px var(--sans);margin:0}
.flip-face--back .tbtn{margin-top:22px}
@media (prefers-reduced-motion:reduce){
  .flip-inner{transform:none !important;transition:none;display:grid;gap:16px}
  .flip-face{grid-area:auto;transform:none}
}

/* ═══ THE DOWNLOAD FORM (2026-09-08) ════════════════════════════════════════════════════════════
   A gated asset's form is OURS: our type, our fields, our button. HubSpot's own embed renders in a
   cross-origin iframe that ignores this stylesheet (fonts included), so the fields are written in the
   page and posted to the same HubSpot form through its submission API. HubSpot keeps the contact, the
   segment and the reporting; the page keeps its design. Reusable for any gated asset. */
.hsform{background:var(--bone);border:1px solid var(--ink);border-radius:var(--radius-box);
  box-shadow:var(--shadow-ink);padding:26px}   /* bone card on the white page (2026-09-08) */
/* the cover stands ABOVE the card, not inside it */
.paper-cover{display:block;width:274px;max-width:100%;height:auto;margin:0}   /* the paper's own cover, in the reading column under the standfirst */
.hsform-intro{margin:0 0 20px}
.hsform-intro h3{font:900 22px/28px var(--sans);margin:0 0 6px}
.hsform-intro p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0}
/* the head: the cover thumbnail beside the invitation, so the form itself stays above the fold */
.hsform-head{display:grid;grid-template-columns:104px 1fr;gap:18px;align-items:start;margin-bottom:20px}
.hsform-head img{width:104px;height:auto;box-shadow:none;border-radius:2px}   /* inside a frame already: a thumbnail, not a second frame */
.hsform-head .ttag{display:block;margin-bottom:6px}
.hsform h3{font:900 22px/28px var(--sans);margin:0 0 6px}
.hsform-head p{font:400 15px/24px var(--sans);color:var(--ink-80);margin:0}
.hsform-fields{display:grid;gap:12px}
.hsform-fields .two-up{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.hsform-fields .field{display:grid;gap:6px}
.hsform-fields label{font:600 13px/18px var(--sans);color:var(--ink)}
.hsform-fields .input{height:44px}
.hsform-fields .consent-note{font:400 13px/20px var(--sans);color:var(--ink-60);margin:6px 0 0}
.hsform-fields .consent{display:flex;gap:10px;align-items:flex-start;font:400 13px/20px var(--sans);color:var(--ink-80);cursor:pointer}
.hsform-fields .consent input{flex:none;width:18px;height:18px;margin-top:1px;accent-color:var(--azure)}
.hsform-fields .form-error{font:600 13px/20px var(--sans);color:var(--danger);margin:0}
.hsform-fields .btn{width:100%;justify-content:center;margin-top:6px}
.hsform-fields .btn[disabled]{opacity:.7}
@media (max-width:520px){.hsform-fields .two-up{grid-template-columns:1fr}}

/* deployment: four ways, a strip with the Tandem icons, no boxes */
.dep-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
.dep-strip div{display:flex;align-items:center;gap:16px}
.dep-strip img{width:58px;height:auto;flex:none}
.dep-strip h3{font:900 20px/28px var(--sans);margin:0}
@media (max-width:800px){.dep-strip{grid-template-columns:repeat(2,1fr)}}

/* PREVIEW ONLY: what was cut from a section, so any sentence can come back. Stripped at the flip
   (build-home-fragment.py --final). */
.cuts{margin:28px 0 0;font:400 12px/18px var(--mono);color:var(--ink-60);border:1px dashed rgba(6,22,53,.35);padding:10px 14px}
.cuts summary{cursor:pointer;font-weight:700;letter-spacing:.08em;text-transform:uppercase;font-size:11px}
.cuts ul{margin:8px 0 0;padding-left:18px}
.cuts li{margin:4px 0}
.on-dark .cuts{color:rgba(252,250,246,.7);border-color:rgba(252,250,246,.35)}


/* ───────────────────────── 12. MOTION ─────────────────────────
   One motion language, and it is the hard offset. A button or card moves INTO its own shadow on
   hover and lands flat when pressed; menus fade nothing, they simply appear. No scroll-triggered
   animation, no parallax, no counters. 120ms, the same everywhere.
   The only moving image on the site is the Mission Control clip in the hero. */
:root{--t:.12s}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
  .btn:hover,.card:hover{transform:none}
  .laptop video,.hero-video{display:none}
}


/* ── scroll reveal ──────────────────────────────────────────────────────────
   A block lifts 12px and fades in as it comes into view. Done with a CSS scroll timeline, so
   there is NO JavaScript and, crucially, the default state is VISIBLE: a browser or an agent
   that does not support it simply sees the finished page. Nothing on this site is ever hidden
   waiting for a script to reveal it. Off entirely under reduced motion. */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    @keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
    .sec .head,.sec .cards,.sec .rows,.sec .note,.sec .figure,.sec .two,.sec .diff,.sec .list3,
    .sec .qbox,.sec .frames,.stats .stat,.cta .wrap>*{
      animation:rise linear both;animation-timeline:view();animation-range:entry 0% entry 40%}
  }
}

/* ───────────────────────── 11. UTILITIES ─────────────────────────
   Written 2026-09-04 after auditing what the homepage was doing inline. Anything a page needs
   more than once belongs here, never in a style= attribute. */
.on-azure{color:var(--azure)}                    /* mono tag / eyebrow lifted to Azure on a dark band */
.on-ink{color:var(--azure-ink)}
.center{text-align:center}
/* A CENTERED COLUMN (ruled 2026-09-09, the white paper thank-you page). `.center` turns the text
   and nothing else. Inside a masthead every block carries its own max-width - .w2-3 on the
   headline, .lead--narrow on the standfirst, the picture's own width, the button row - so each
   one also needs auto side margins, or the text centers inside a block that is still hard left
   and nothing appears to move. Left alignment stays the default everywhere else
   (feedback_left_alignment); this is opt-in, per section. */
.center-col{text-align:center}
.center-col>*{margin-left:auto;margin-right:auto}
.center-col .btns{justify-content:center}
.right{text-align:right}
.caps{text-transform:uppercase}
.blk{font-weight:900}
/* .flat RETIRED 2026-09-07 (frame law): every frame carries its offset; a card without one was a one-off */
.m0{margin:0}   .mt0{margin-top:0}   .mt16{margin-top:16px}   .mt24{margin-top:24px}   .mt40{margin-top:40px}
.mt40{margin-top:40px}  .mt60{margin-top:60px}  .mt80{margin-top:80px}
.mb12{margin-bottom:12px}  .mb24{margin-bottom:24px}
.mb40{margin-bottom:40px}  .mb60{margin-bottom:60px}
.pt60{padding-top:60px}   /* a section that follows a band and needs less air on top */
/* .note--deep RETIRED 2026-09-07 (frame law): no fill inside a frame */
.gap0{gap:0}  .gap16{gap:16px}  .gap24{gap:24px}  .gap40{gap:40px}
.pad40{padding:40px}
.w220{max-width:220px}  .w1000{max-width:1000px}
.stack{display:grid;gap:16px}                    /* a plain vertical stack */
.grid-2u{display:grid;grid-template-columns:335px 1fr;gap:40px;align-items:start}   /* label column + body */
.row--plain{grid-template-columns:1fr;border:0;padding-top:0}                       /* a list row, not a two-column one */
.cards-3{grid-template-columns:repeat(3,1fr)}
@media (max-width:1000px){.grid-2u{grid-template-columns:1fr}}
@media (max-width:900px){.cards-3{grid-template-columns:1fr}}
.conn--long{width:40px}
.sc--panel{border-radius:var(--radius-box);padding:20px;text-align:center}          /* the wide Brutor panel in a schematic */
.dim-on-dark{color:rgba(243,239,231,.8)}

/* ██ LOCKED 2026-09-05 - DO NOT EDIT ████████████████████████████████████████████
   Signed off by Veronika. Change nothing in this section unless she asks for the header or
   the footer BY NAME. Not while "tidying", not while fixing a page that sits under them, not
   because a value here looks inconsistent with a newer rule elsewhere - a page problem is a
   page problem, and every page on the site inherits from here.
   The markup that goes with it is equally locked, staged at:
     wpcode-snippets/staged/01-site-wide-header-2026.php   (replaces WPCode 1512 at the flip)
     wpcode-snippets/staged/02-site-wide-footer-2026.php   (replaces WPCode 1513 at the flip)
   ████████████████████████████████████████████████████████████████████████████ */
/* ───────────────────────── 9. CTA + FOOTER ─────────────────────────
   Opened once, 2026-09-06, because Veronika asked for the footer by name: type made thin,
   headers to IBM Plex Mono caps. Locked again after. */
.cta .wrap{padding-top:80px;padding-bottom:80px;display:grid;grid-template-columns:1fr auto;gap:40px;align-items:start}
/* RULING 2026-09-08, the closing CTA:
   - the buttons align with the TEXT, top to top, instead of floating centred beside it;
   - the headline is smaller than a section H2: this band closes the page, it does not open a
     topic, and at 40px it was shouting;
   - the emphasis word is BONE with an orange underline, never orange type. Orange on Ink Navy
     at headline size is the loudest thing on the site. */
/* RULING 2026-09-08: "ALIGN TO TEXT" MEANS THE HEADLINE OR THE BODY COPY. Never align anything
   to an eyebrow, a pill, a tag or a badge. Those are labels: they sit above the text block's
   optical edge, so anything aligned to one ends up reading 8 to 20px too high. In this band the
   rule is deliberately broken the other way: the eyebrow gets real air under it and the whole
   left block is centred against the buttons. */
.cta .head{align-self:center}
.cta .eyebrow{margin-bottom:16px}
.cta .head h2{font-size:32px;line-height:42px}
.cta .head h2 .o{color:var(--bone);text-decoration:underline;text-decoration-color:var(--orange);
  text-decoration-thickness:3px;text-underline-offset:6px}
@media (max-width:760px){.cta .wrap{grid-template-columns:1fr;gap:28px}}   /* the auto column cannot shrink under a button, so it stacks (2026-09-08) */
.cta .btns{flex-direction:column;align-items:stretch;gap:14px}
.cta .btns .btn{justify-content:center}
.cta .head{margin-bottom:0}

footer.foot{background:var(--footer-bg);border-top:1px solid var(--divider-dark)}   /* brand black, Black 100% */
footer.foot .grid{display:grid;grid-template-columns:230px repeat(5,auto);gap:40px;padding:48px 0 0;justify-content:space-between}
/* RULING 2026-09-06 (Veronika, footer named): the footer type was reading THICK - 600-weight
   Inter in white on black. Nothing was a shadow or a tint; it was weight plus light-on-dark
   rendering. Now: column headers in IBM Plex Mono, ALL CAPS, 500 weight, tracked; links stay
   400 Inter but in Bone rather than pure white so they sit back. Nothing here is bold. */
footer.foot h4{font:500 11px/20px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--bone);margin:0 0 12px}
footer.foot h4::before{content:"/ ";color:var(--azure)}
/* ruling 2026-09-05: smaller again, and more air between the lines. A footer list is
   scanned, not read - the space between items is what makes it scannable, not the size. */
footer.foot .col a{display:block;padding:5px 0 5px 12px;white-space:nowrap;font:400 12px/18px var(--sans);color:rgba(252,250,246,.82);text-decoration:none}
footer.foot .col a:hover{color:var(--azure)}
.flogo{height:44px;width:auto;margin:0 0 16px;display:block}   /* the transparent logo, nothing behind it */
footer.foot .desc{font:500 13px/20px var(--mono);color:rgba(252,250,246,.6);margin:0;max-width:250px}
/* .nl-label is the class the locked footer markup carries; the bare `b` is kept so the
   rule still holds if the class is ever dropped. */
footer.foot .nl b,footer.foot .nl-label{display:block;font:500 13px/20px var(--mono);color:var(--bone);margin-bottom:8px}
footer.foot form{display:flex;gap:8px}
footer.foot input{width:156px;height:36px;padding:0 10px;font:400 12px/20px var(--sans);border-radius:var(--radius);border:1px solid var(--azure);background:var(--azure-10);color:var(--bone)}
footer.foot .btn{height:36px;padding:0 14px;font-size:13px;box-shadow:4px 4px 0 var(--azure)}
footer.foot .sub{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;padding:4px 0 20px}   /* newsletter starts right under the lowest sub-menu item; social icons sit on the Subscribe baseline */
footer.foot .bottom{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;padding:14px 0 16px;border-top:1px solid var(--divider-dark)}
footer.foot .legal{display:flex;gap:10px;align-items:center;font:400 11px/20px var(--sans);color:rgba(252,250,246,.5)}
footer.foot .legal a{color:var(--bone);text-decoration:none;padding:4px 8px}
footer.foot .social{display:flex;gap:18px;align-items:flex-end;padding-bottom:6px}
footer.foot .social a{display:block;color:var(--azure)}
footer.foot .social svg{width:24px;height:24px;fill:currentColor;display:block}
footer.foot .social a:hover{color:#fff}
@media (max-width:1100px){footer.foot .grid{grid-template-columns:1fr 1fr 1fr}}
@media (max-width:640px){footer.foot .grid{grid-template-columns:1fr 1fr}}
