/* companion.apexedgesalesengineering.com: the chrome.

   The header, the footer, the skip link, the back-to-top control, and the
   tokens they read. build_site.py serves this file first in site.css and
   inlines it whole into the form page, so a rule for the chrome lives here and
   nowhere else, and the 2 pages cannot drift. Everything else is in pages.css.

   Built to match www.apexedgesalesengineering.com. The hairline header rule
   and the collapsing footer grid are taken from that site's stylesheet so the
   estate reads as one thing.

   Light surface set only: 006-...-visual-brand.md Section 10 makes White the
   default until a dark theme is approved, and none is. */


/* IBM Plex Sans Condensed, weight 600 only, which is the 1 weight the estate
   guideline asks Condensed for. www gets this family from the Google Fonts CDN;
   this site cannot, because it serves script-src 'none' and its isolation check
   fails on any reference off this origin, so the face is vendored here as the
   roman faces are and served from /assets/fonts. Same 2 unicode ranges as those,
   taken from the same source, so the split matches. */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal; font-weight: 600; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-condensed-latin-roman.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal; font-weight: 600; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-condensed-latin-ext-roman.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --cobalt: #0047AB;
  --steel-blue: #2364AA;
  --orange: #FE5A1D;
  --orange-dark: #E04A10;
  --black: #1A1A1A;
  --text: #243244;
  --muted: #5A6878;
  --white: #FFFFFF;
  --paper: #FCFCFD;
  --surface: #F7F8FA;
  --surface-alt: #F1F4F8;
  --border: #DCE3EB;
  --border-strong: #C5D0DC;
  --link-hover: #1C4C84;
  --hairline: rgba(0, 71, 171, 0.08);

  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  --shadow-sm: 0 8px 24px rgba(22, 34, 51, 0.04);
  --shadow-md: 0 18px 40px rgba(22, 34, 51, 0.06);
  --shadow-lg: 0 20px 36px rgba(22, 34, 51, 0.08);

  --text-xs: 0.75rem;
  --text-sm: 0.889rem;
  --text-lg: 1.111rem;

  /* The estate's shared footer size. Every type role in the footer sets at this
     1 size, and weight, letter-spacing, and case carry the hierarchy instead.
     See docs/reference/apex-edge-sales-engineering-header-and-footer-guideline.md.

     The max() is mandatory and not decoration. This site's root is the browser
     default 16px, where 0.72rem is 11.52px, under canon 009's 12px floor for
     helper text. The clamp is the only thing holding the floor, so a bare
     0.72rem here would sit below it at every width. --text-xs is 0.75rem, which
     clears 12px by arithmetic alone and needs no clamp, which is exactly why
     swapping one for the other looks safe and is not.

     www runs a root of 18px stepping to 17px and 16px, so the same declaration
     renders 12.96 / 12.24 / 12px there against a flat 12px here. Matching its
     root would rescale every rem on this site, so section 2 of the guideline is
     taken at its word and the figure is recomputed against our own. */
  --text-micro: max(12px, 0.72rem);

  --max: 1120px;
  --measure: 68ch;
  --sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  /* Falls back to the roman face rather than to a system condensed, which would
     be a different typeface at a different width. */
  --condensed: 'IBM Plex Sans Condensed', var(--sans);
}

.wrap { width: min(calc(100% - 40px), var(--max)); margin: 0 auto; }

/* Announces to a screen reader what a sighted reader gets from the new-tab
   itself. It carries the cue inside the anchor for every external footer link,
   so it has to be defined for the whole site and not only inside a query. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: 16px; top: -52px; z-index: 200;
  padding: 10px 14px; border-radius: var(--radius-md);
  background: var(--white); color: var(--cobalt);
  border: 1px solid rgba(0, 71, 171, 0.2); font-weight: 600; font-size: 14px;
  transition: top 150ms ease;
}
.skip:focus { top: 12px; }

/* ── Header: a hairline, not a rule ─────────────*/
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: rgba(252, 252, 253, 0.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

/* The header is sticky, so without this an anchor lands its target at the top of
   the viewport and the header covers it outright. It is chrome because the
   header is: this file reaches the form page whole, and while the rule lived in
   pages.css the skip link there put the top of the form under the header.

   The header is a 36px brand mark inside 14px of padding, 65px with its rule,
   and the word mark beside it is deliberately shorter than the mark at 34.6px,
   so the mark sets the height and the type cannot push it. It does not wrap:
   both of the word mark's lines are nowrap, and the menu button beside it is
   drawn at the mark's 36px and gives up its label under 420px, where the 2 would
   not otherwise fit. 76px clears that at every width with 11px to spare. */
html { scroll-padding-top: 76px; }
.head-inner {
  display: flex; flex-wrap: nowrap; gap: 10px 24px;
  align-items: center; justify-content: space-between;
  padding: 14px 0;
}
/* www's lockup, with our strings: a 36px mark, a 12px gap, and the name over the
   company line. The mark is tools/form-assets/brand-mark.png, rendered by
   build_brand_assets.py to www's geometry and colours, so only the drawn size
   changed.

   3 constraints meet here and they fix each other's values. The 2 lines end
   together, the pair sits inside the 36px mark, and the company line holds the
   12px floor.

   The company line cannot follow the name down, because 12px is the floor, so the
   only lever which narrows it is its tracking. That makes the name size and the
   tracking 1 dial with 2 ends, and this is the whole of it, measured: the company
   line is 177.7px untracked at 12px and each 1em of tracking adds 336px, while
   the name runs 9.7px of width per px of size at 700.

     name 22.1px -> 0.109em      name 20.0px -> 0.049em
     name 21.0px -> 0.077em      name 18.3px -> 0.000em, and no smaller

   18.3px is the arithmetic floor: below it the company line cannot be narrowed to
   meet the name without going under 12px. The practical floor is higher. Tracking
   is what makes an uppercase microlabel read as one, and by 19px it is down to
   0.02em, which is not tracking any more. 20px keeps 0.0485em, which still reads.

   This site sets 20px and 0.0485em. The estate guideline gives 0.11em, and gives
   it to 4 roles at once, so this is a deviation and the only one: the footer
   tagline and both cluster labels still set 0.11em. It is taken because the name
   was too heavy at the 22.1px which 0.11em forces here, and because the guideline
   fixes the tracking for a lockup which does not also have to match 2 widths.

   Condensed is what makes any of it fit. The same string in the roman face is
   8.1% wider at 12px, which would need a 24.4px name and a 38px block, and would
   not fit the mark. It is also why the 9px this used to run at is gone, and why
   docs/decisions/0011 is retired rather than reworded.

   Re-measure if either string, either weight, or either face changes, and measure
   the rendered ink: nothing in the audit can see a glyph. */
.brand { display: flex; align-items: center; gap: 12px; }
/* The breathing space. Both lines set at 1.0 so no leading is spent inside the
   line boxes, which leaves 36 - 20 - 12 = 4px between the pair and the mark, and
   2.6px of it is the gap. The other 1.4px is left unspent: the block is centred on
   the mark, so it reads as margin above and below rather than as a loose lockup,
   and the gap was set when the name was larger and has not needed to move since.
   A wider gap is available here if it is ever wanted. */
.brand span { display: flex; flex-direction: column; align-items: stretch; gap: 2.6px; }
.brand strong {
  font-size: 20px; font-weight: 700; line-height: 1; color: var(--black);
  white-space: nowrap;
}
.brand em {
  font-style: normal; font-family: var(--condensed);
  font-size: var(--text-micro); font-weight: 600; line-height: 1;
  letter-spacing: 0.0485em; text-transform: uppercase; color: var(--muted);
  white-space: nowrap;
}
/* The menu. A <details>, as the footer's clusters are, so it opens with no
   script, and MENU_JS in build_site.py closes it from outside. Every selector
   hangs off .site-nav, because this file reaches the form page whole and a class
   of its own would be 1 more name to collide there.

   The button is a pill, as every control which reads as a button is, and is
   drawn at the mark's 36px so the header keeps its 65px. The target is 44px all
   the same: the ::after reaches 4px above and below the pill, which is the
   touch figure the estate guideline gives a toggle a reader must hit before any
   link behind it. */
.site-nav { position: relative; flex: none; }
.site-nav summary {
  position: relative; display: flex; align-items: center; gap: 8px;
  height: 36px; padding: 0 16px 0 13px; border-radius: var(--radius-pill);
  border: 1px solid var(--border); background: var(--white);
  color: var(--text); font-size: var(--text-sm); font-weight: 500; line-height: 1;
  cursor: pointer; list-style: none; user-select: none;
  transition: border-color 160ms ease, color 160ms ease, background-color 160ms ease;
}
.site-nav summary::-webkit-details-marker { display: none; }
.site-nav summary::marker { content: ''; }
.site-nav summary::after { content: ''; position: absolute; inset: -4px 0; }
.site-nav summary:hover { border-color: var(--border-strong); color: var(--cobalt); }
.site-nav[open] summary { border-color: var(--cobalt); color: var(--cobalt); background: var(--surface); }
.site-nav summary svg { flex: none; }
/* 3 bars closed and a cross open: the outer 2 meet at the middle and turn, and
   the middle one goes. Each turns about its own centre, which fill-box gives. */
.site-nav summary path {
  transform-box: fill-box; transform-origin: center;
  transition: transform 200ms ease, opacity 120ms ease;
}
.site-nav[open] summary path:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
.site-nav[open] summary path:nth-child(2) { opacity: 0; }
.site-nav[open] summary path:nth-child(3) { transform: translateY(-3.5px) rotate(-45deg); }
/* The panel hangs from the button's right edge, which is the page's, so it
   cannot leave the screen on that side, and it is no wider than a 320px screen
   has. --radius-lg and not the pill: it is a panel and not a button.

   It is 460px tall with a request row under each Topic, and it hangs from a
   sticky header, so the page cannot scroll its foot into view. On a screen
   shorter than the panel it scrolls inside itself instead, 16px clear of the
   bottom edge, and its rows keep their height rather than being squeezed. */
.site-nav nav {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  display: flex; flex-direction: column;
  width: min(264px, calc(100vw - 40px)); padding: 8px;
  max-height: calc(100vh - 77px); max-height: calc(100dvh - 77px);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  transform-origin: top right;
}
.site-nav[open] nav { animation: site-nav-open 160ms ease both; }
@keyframes site-nav-open {
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.site-nav nav a {
  position: relative; display: flex; align-items: center; gap: 12px;
  min-height: 44px; padding: 0 12px; border-radius: var(--radius-md);
  color: var(--text); font-size: var(--text-sm); font-weight: 500;
  transition: background-color 140ms ease, color 140ms ease;
}
/* The icon is quieter than its word until the row is pointed at or current. */
.site-nav nav a svg { flex: none; color: var(--muted); transition: color 140ms ease; }
/* A Topic's own pages sit under its name: in line with its word, a weight down,
   and joined by a rule which drops from the centre of its icon. */
.site-nav nav a.sub {
  min-height: 40px; padding-left: 42px; font-weight: 400; color: var(--muted);
}
.site-nav nav a.sub::before {
  content: ''; position: absolute; left: 20.5px; top: 0; bottom: 0;
  width: 1px; background: var(--border);
}
.site-nav nav a:hover { background: var(--surface); color: var(--cobalt); }
.site-nav nav a:hover svg, .site-nav nav a[aria-current] svg { color: var(--cobalt); }
.site-nav nav a[aria-current] { background: var(--surface-alt); color: var(--cobalt); font-weight: 600; }
.site-nav nav a, .site-nav nav hr { flex: none; }
.site-nav nav hr { border: 0; height: 1px; margin: 6px 12px; background: var(--border); }
/* Under 420px the word "Menu" does not fit beside the lockup, which is 242px of
   a 280px box at 320px, so the button is the 3 bars alone and its name stays for
   a screen reader. The gap closes with it: 242 + 6 + 32 is the whole box. */
@media (max-width: 419px) {
  .head-inner { column-gap: 6px; }
  .site-nav summary { width: 32px; padding: 0; justify-content: center; }
  .site-nav summary span {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
}
/* Here as well as in pages.css, because the form page carries this file alone. */
@media (prefers-reduced-motion: reduce) {
  .site-nav summary, .site-nav summary path, .site-nav nav a, .site-nav nav a svg { transition: none; }
  .site-nav[open] nav { animation: none; }
}

/* ── Footer: word mark, then clusters which collapse on a small screen ──
   The collapse is <details> and <summary>, as www does it. No script, which
   matters because this site serves script-src 'none'. */
.site-foot {
  background: var(--surface); border-top: 1px solid var(--hairline);
  padding: 56px 0 44px;
}
/* The descriptor on its own line, the clusters under it, and every one of them
   starting at the same left edge as the copyright below. A column rather than a
   row, so there is 1 measure down the footer instead of a label in a first column
   and the lists in a second. align-items is flex-start so the children take their
   own width and none of them stretches the row it sits in.

   www runs its brand block and clusters side by side, and this no longer does.
   That went with the word mark: side by side is a lockup beside a nav, and what
   is left here is 3 labels of the same size, which read as 1 group stacked. */
.foot-grid {
  display: flex; flex-direction: column; align-items: flex-start; gap: 32px;
}
.foot-brand { flex: none; }
.foot-clusters { display: flex; flex-wrap: wrap; gap: 48px; }
/* Role 2 of 5. It was a tagline under a word mark and is now a label beside the
   other 2, so it takes their treatment exactly: the same size, the same 600, the
   same 0.11em, the same case, the same Restrained Grey, and the same 24px row, so
   the 3 sit on one line across the footer.

   The estate guideline gives this role 400 on a 1.625 line in sentence case,
   which is right for a sentence sitting under a word mark and wrong for what
   this now is. Section 1 of that document is explicit that size is the shared
   thing and that weight, tracking, and case carry the hierarchy, so a role which
   changes from sentence to label changes those 3 and keeps the size and the
   colour. --text-micro and --muted are unchanged, which is what the audit holds. */
.foot-brand span {
  display: flex; align-items: center; min-height: 24px;
  font-family: var(--condensed);
  font-size: var(--text-micro); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.11em; color: var(--muted);
}

/* 10px from the label to the list it heads, which is www's figure. It is a
   column gap rather than a margin so the summary carries no spacing of its own
   and the mobile rules do not have to unset one. */
.foot-cluster { border: 0; display: flex; flex-direction: column; gap: 10px; }
.foot-cluster summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; list-style: none; min-height: 24px;
  /* A heading on desktop, where the cascade holds the cluster open whatever the
     open attribute says, so a click there changes nothing visible. It stays
     clickable: a browser without ::details-content renders the clusters closed,
     and pointer-events: none would leave a mouse user no way to open them. */
  cursor: default;
  /* Role 3 of 5, the cluster label, in Condensed as the guideline asks. It ran in
     the roman face until the Condensed one was vendored for the header, which was
     a divergence nobody had written down. */
  font-family: var(--condensed);
  font-size: var(--text-micro); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.11em; color: var(--muted);
}
.foot-cluster summary::-webkit-details-marker { display: none; }
.foot-cluster summary::marker { content: ''; }
.foot-chevron { display: none; flex: none; transition: transform 180ms ease; }
.foot-cluster[open] .foot-chevron { transform: rotate(180deg); }
/* Closed on a small screen, as www presents it, and always open on desktop.
   www toggles the open attribute with script; this site serves script-src 'none',
   so the same result comes from the cascade instead. */
/* The rows abut, as they do on www. A 10px gap on top of the line box put
   roughly 32px of pitch around 1 short line, which read as separated lines
   rather than a list. The target has not shrunk with the gap gone: each row is
   held at 24px, which is the WCAG 2.2 2.5.8 floor and is what www settled on.
   Do not take the rows below 24px to close the list up further. */
.foot-links { display: none; flex-direction: column; gap: 0; }
.foot-cluster[open] > .foot-links { display: flex; }
@media (min-width: 761px) {
  /* A closed <details> hides its content with content-visibility on
     ::details-content, which display on the child cannot override. Both are
     needed to keep the clusters open on desktop. */
  .foot-cluster > .foot-links { display: flex; }
  .foot-cluster::details-content { content-visibility: visible; }
}
/* www's footer link is max(12px, 0.74rem) in --color-muted, which on a 16px root
   renders at 12px. --text-xs is this site's own 12px, so the 2 footers set their
   links at the same size without this file reaching for a pixel value outside
   the scale. --muted is #5A6878 here and on www, so the colour needs no mapping.
   The hover darkens to --text, which is www's --color-text and the same #243244,
   rather than the cobalt the rest of this site's links take. The footer is the 1
   place the 2 sites sit side by side in a reader's memory, so it follows www. */
/* Role 4 of 5, the cluster link. 300 rather than the body's 400: at this size a
   regular weight in a list of 6 reads heavier than the label above it. The
   target is on min-height and not on the line box, so the type can move without
   the 24px moving with it. */
.foot-links a {
  display: flex; align-items: center; min-height: 24px; line-height: 1;
  font-size: var(--text-micro); font-weight: 300; color: var(--muted);
}
.foot-links a:hover { color: var(--text); }
/* The copyright line sets with the cluster links, not a size above them. www
   floors both at 12px, and its own note records why: 12px is canon 009's floor
   for a microlabel, and the copyright is the smallest thing in the footer
   rather than a size of its own. The 40px margin, the 24px padding, and the
   hairline already matched www before this. */
/* Role 5 of 5, the copyright. */
.foot-note {
  max-width: none;
  margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--hairline);
  font-size: var(--text-micro); font-weight: 300; line-height: 1.16;
  color: var(--muted);
}

@media (max-width: 760px) {
  /* The column is the base now, so this only opens the gap up. */
  .foot-grid { gap: 28px; }
  .foot-clusters {
    flex-direction: column; flex-wrap: nowrap; gap: 0; width: 100%; align-self: stretch;
  }
  /* The clusters stack as 1 ruled list, so a cluster is a block again and its
     own 10px column gap would double the padding under a closed label. */
  .foot-cluster {
    display: block; border-top: 1px solid var(--hairline); padding: 10px 0 2px;
  }
  .foot-cluster:last-child { border-bottom: 1px solid var(--hairline); padding-bottom: 10px; }
  .foot-cluster[open] { padding-bottom: 8px; }
  /* 44px here, not 24px. Where the cluster collapses the summary is the control
     a reader must hit before any link inside it can be reached at all, and
     touch is primary at this width. */
  .foot-cluster summary { cursor: pointer; min-height: 44px; }
  .foot-cluster[open] > .foot-links { padding-top: 8px; }
  .foot-links a { line-height: 1.28; }
  .foot-chevron { display: block; }
}

/* ── Back to top ────────────────────────────────
   www's dimensions, treatment, and position exactly: a 44px circle at the bottom
   right, white on a cobalt hairline, cobalt chevron. www hides it until scrolled, with script. This site
   serves script-src 'none', so it is an anchor, and only long pages carry one.
   It appears after a little scrolling, by a scroll-driven animation rather
   than script (below). The 1 script it has, TO_TOP_JS in build_site.py, only
   keeps a click from writing #top into the address. */
.to-top {
  position: fixed; right: 24px; z-index: 40;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid rgba(0, 71, 171, 0.18); border-radius: var(--radius-pill);
  background: var(--white); color: var(--cobalt); box-shadow: var(--shadow-sm);
  transition: background 180ms ease, border-color 180ms ease;
}
.to-top:hover { background: #F8FBFF; border-color: rgba(0, 71, 171, 0.32); color: var(--cobalt); }
.to-top:focus-visible { outline: 2px solid rgba(0, 71, 171, 0.25); outline-offset: 3px; }

/* Hidden at the top of the page, fading in between 160px and 320px of scroll.
   visibility and not opacity alone, so a control nobody can see is out of the
   tab order too. The timeline is declared after the shorthand, which resets it.
   A browser without scroll-driven animations shows the control always, as it
   did before, and so does a reader asking for reduced motion, where the site's
   stylesheet removes every animation. */
@supports (animation-timeline: scroll()) {
  .to-top {
    animation: to-top-reveal linear both;
    animation-timeline: scroll(root block);
    animation-range: 160px 320px;
  }
}
@keyframes to-top-reveal {
  from { opacity: 0; visibility: hidden; transform: translateY(8px); }
  to   { opacity: 1; visibility: visible; transform: none; }
}

/* companion.apexedgesalesengineering.com: the pages.

   Everything the marketing and legal pages add to the chrome: the type, the
   sections, the cards, the tables, and the rendered documents. It follows
   chrome.css in site.css and reads the tokens declared there. It is not
   inlined into the form page, which carries its own styles.

   Built to match www.apexedgesalesengineering.com. Radii, shadows, pill
   controls, the card lift, and the 22px blueprint grid are all taken from that
   site's stylesheet so the estate reads as one thing. */


@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-roman.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: italic; font-weight: 300 700; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-ext-roman.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* The 4th face, which the site served from /assets/fonts/ and never declared until
   27 September 2026, so italic text outside basic Latin fell back to a synthesised
   slant. The 4 faces here are tools/form-assets/fonts/fontface.css at /assets/fonts/,
   and check_faces in site_audit.py holds them to it. */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: italic; font-weight: 300 700; font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

html {
  /* The scroll padding which clears the sticky header is in chrome.css beside
     the header, because the form page needs it too. This stays here: the form
     sets its own scroll-behavior and resets it under prefers-reduced-motion,
     and a rule inlined after it would override that reset. */
  scroll-behavior: smooth;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

@media (max-width: 700px) { body { font-size: 16px; } }

/* Links never carry an underline. Colour and weight do the work. */
a { color: var(--steel-blue); text-decoration: none; transition: color 160ms ease; }
a:hover { color: var(--link-hover); }
a:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 3px; border-radius: 3px; }

/* ── Sections ───────────────────────────────────*/
section { padding: 68px 0; }
section.alt { background: var(--surface); }

/* Section 11 of the visual brand canon: a low-contrast blueprint grid, at the
   same 22px pitch the rest of the estate uses. */
.hero, section.alt {
  background-image:
    linear-gradient(rgba(0, 71, 171, 0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 71, 171, 0.028) 1px, transparent 1px);
  background-size: 22px 22px;
}
.hero { padding: 76px 0 64px; }

/* 2 label roles above a heading, as www sets them. The page's first, in the hero,
   is .eyebrow: the Condensed face, 0.78rem, 600, 0.12em, uppercase, in Cobalt Blue,
   with nothing before it. Every section below it opens with .accent-kicker: the
   same type in Restrained Grey, after a 36px rule running Cobalt Blue into Strategy
   Purple. Until 30 September 2026 every label here was 1 role, in the roman face in
   grey after a 28px cobalt rule, which was neither of www's. The 0.12em is the Label
   role and not the microlabel's 0.11em; the header and footer guideline says not to
   sweep it in. check_eyebrow holds both roles to www's values. */
.eyebrow {
  display: inline-block; margin-bottom: 16px;
  font-family: var(--condensed); font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--cobalt);
}
.accent-kicker {
  display: flex; align-items: center; gap: 12px; margin-bottom: 24px;
  font-family: var(--condensed); font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.accent-kicker::before {
  content: ''; flex: none; width: 36px; height: 2px;
  background: linear-gradient(90deg, var(--cobalt), rgba(128, 0, 128, 0.75));
}

h1 {
  font-size: clamp(30px, 4.2vw, 44px); line-height: 1.14; letter-spacing: -0.02em;
  font-weight: 600; color: var(--black); margin-bottom: 18px; text-wrap: balance;
}
.hero h1 {
  font-size: clamp(36px, 5.6vw, 58px); line-height: 1.06;
  letter-spacing: -0.026em; font-weight: 700;
}
h2 {
  font-size: clamp(26px, 3.2vw, 34px); line-height: 1.2; letter-spacing: -0.016em;
  font-weight: 600; color: var(--black); margin-bottom: 16px; text-wrap: balance;
}
h3 { font-size: 1.111rem; font-weight: 600; color: var(--black); margin-bottom: 8px; }

p { max-width: var(--measure); margin-bottom: 16px; text-align: left; }
p:last-child { margin-bottom: 0; }
strong { color: var(--black); font-weight: 600; }
.lede { font-size: 1.25rem; line-height: 1.5; max-width: 60ch; }
/* The hero pictures sit beside the copy at 1080px and wider, and follow it in 1 column
   below that. The home page's is the marked page and each Topic's landing page shows its
   deliverable, tagged. docs/decisions/0036 and 0037 record them, and 0031 the receipts
   they replaced. */
@media (min-width: 1080px) {
  .hero-split { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 64px; align-items: center; }
}

/* The marked page: the home page's hero picture. A proposal, the audit's marks on 2 of
   its sentences, the verdict on its foot, and a readiness pack's 5 checkpoints, turned
   the other way. The 4 labels are section 5 of each Topic's Service Description said
   shorter, and none is a figure. docs/decisions/0036 records it.

   The proposal is a picture of a document and hidden from a screen reader. It is set at
   twice its size and scaled by half, so its type is real type at thumbnail size whatever
   minimum font size a browser enforces. Its seller and customer are the fictional pair
   the example pages use, and the teal of its mark is used nowhere else, so that it cannot
   be read as ours.

   --s scales the paper and where everything sits on it, and never the labels, so they
   keep their size on a phone: 1 down to a 420px screen, 0.88 to 360px, and 0.8 below,
   where the 286px page would otherwise pass the 280px box. The verdict is placed
   from the mark above it, 14px below its foot, and the rail from the verdict, 22px below
   its foot, at every width, so no card touches another, their turned corners included. The 2 narrower values arrive
   through --s-narrow and --s-phone, so that each token is still declared once. Each turn is the rotate
   property and each entrance the translate or scale property, so the hover lift, which
   is a transform, adds to them. The dot field and every turned corner stay inside the
   20px gutter. The entrance runs once and ends on the picture as it stands, which is
   also what reduced motion shows. */
.hero-marked, .hero-tagged {
  --s: var(--s-phone, var(--s-narrow, 1));
  position: relative; isolation: isolate; width: 100%; max-width: 380px; margin-top: 44px;
}
.hero-marked { height: calc(var(--s) * 282px + 294px); }
@media (max-width: 419px) { .hero-marked, .hero-tagged { --s-narrow: 0.88; } }
@media (max-width: 359px) { .hero-marked, .hero-tagged { --s-phone: 0.8; } }
@media (min-width: 1080px) { .hero-marked, .hero-tagged { margin-top: 0; } }
.hero-marked::before, .hero-tagged::before {
  content: ''; position: absolute; inset: -34px -14px; z-index: -1;
  background-image: radial-gradient(rgba(90, 104, 120, 0.6) 1px, transparent 1.5px);
  background-size: 16px 16px;
  -webkit-mask-image: radial-gradient(closest-side, #000 50%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 50%, transparent 100%);
}
.hm-leaf, .hm-sheet {
  position: absolute; width: calc(var(--s) * 286px); height: calc(var(--s) * 404px);
  background: var(--white); border: 1px solid rgba(36, 50, 68, 0.10); border-radius: 3px;
  transition: transform 180ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hm-leaf:hover, .hm-sheet:hover {
  transform: translateY(-3px);
  box-shadow: 0 2px 2px rgba(26, 26, 26, 0.05), 0 8px 16px rgba(26, 26, 26, 0.07), 0 26px 52px rgba(20, 40, 80, 0.17);
}
.hm-leaf { left: calc(var(--s) * 12px); top: 5px; rotate: 2.4deg; box-shadow: 0 8px 22px rgba(26, 26, 26, 0.07); }
.hm-sheet {
  left: 0; top: 8px; z-index: 1; rotate: -1.5deg; overflow: hidden;
  box-shadow: 0 1px 1px rgba(26, 26, 26, 0.04), 0 4px 10px rgba(26, 26, 26, 0.05), 0 18px 40px rgba(20, 40, 80, 0.13);
}
.hm-page {
  width: 572px; height: 808px; scale: calc(var(--s) * 0.5); transform-origin: 0 0;
  padding: 44px 44px 0; font-size: 12px; line-height: 18px; color: var(--muted);
}
.hm-letterhead { display: flex; align-items: center; gap: 14px; }
.hm-logo { flex: none; width: 30px; height: 30px; }
.hm-logo rect { fill: #1F6F78; }
.hm-logo path { fill: none; stroke: var(--white); stroke-width: 3; stroke-linecap: round; }
.hm-seller { display: grid; gap: 1px; }
.hm-seller-name { font-size: 16px; font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; color: var(--text); }
.hm-seller-line, .hm-doc-kind {
  font-family: var(--condensed); font-weight: 600; text-transform: uppercase; line-height: 1.2;
}
.hm-seller-line { font-size: 9.5px; letter-spacing: 0.1em; color: #1F6F78; }
.hm-doc-kind { margin-left: auto; font-size: 12px; letter-spacing: 0.16em; }
.hm-rule { height: 2px; background: var(--border); margin: 20px 0 26px; }
.hm-doc-title { font-size: 30px; font-weight: 700; line-height: 1.13; letter-spacing: -0.02em; color: var(--text); margin-bottom: 8px; }
.hm-doc-for { font-size: 13px; line-height: 1.6; margin-bottom: 26px; }
.hm-doc-head { font-size: 15px; font-weight: 700; line-height: 1.6; color: var(--text); margin-bottom: 6px; }
.hm-doc-body { margin-bottom: 16px; }
.hm-hl {
  color: var(--black); padding: 2px 0; -webkit-box-decoration-break: clone; box-decoration-break: clone;
  background-repeat: no-repeat; background-size: 100% 100%;
}
.hm-hl--block { background-image: linear-gradient(rgba(254, 90, 29, 0.26), rgba(254, 90, 29, 0.26)); }
.hm-hl--issue { background-image: linear-gradient(rgba(0, 71, 171, 0.18), rgba(0, 71, 171, 0.18)); }
.hm-doc-table {
  display: grid; grid-template-columns: 0.7fr 1.7fr 0.8fr; margin-bottom: 20px; overflow: hidden;
  border: 2px solid var(--border); border-radius: 4px; font-size: 11px; line-height: 16px;
}
.hm-doc-table span { padding: 5px 12px; border-top: 2px solid var(--border); }
.hm-doc-table .hm-th { border-top: 0; background: var(--surface); font-weight: 600; color: var(--text); }

.hm-mark, .hm-verdict, .hm-rail, .hm-wb {
  position: absolute; border-radius: 12px;
  transition: transform 180ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hm-mark, .hm-rail, .hm-wb, .hm-tag {
  background: var(--white); border: 1px solid rgba(36, 50, 68, 0.10);
  box-shadow: 0 1px 1px rgba(26, 26, 26, 0.04), 0 6px 14px rgba(26, 26, 26, 0.07), 0 16px 32px rgba(20, 40, 80, 0.10);
}
/* Under the pointer a surface lifts and its shadow deepens, as the site's cards do. */
.hm-mark:hover, .hm-verdict:hover, .hm-rail:hover, .hm-wb:hover, .hm-tag:hover { transform: translateY(-3px); }
.hm-mark:hover, .hm-rail:hover, .hm-wb:hover, .hm-tag:hover {
  box-shadow: 0 2px 2px rgba(26, 26, 26, 0.05), 0 10px 20px rgba(26, 26, 26, 0.09), 0 24px 44px rgba(20, 40, 80, 0.15);
}
.hm-verdict:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 10px 20px rgba(0, 58, 140, 0.26), 0 26px 44px rgba(0, 58, 140, 0.30);
}
/* A mark is centred on the lines it is about, wherever the paper's scale puts them. */
.hm-mark {
  right: 0; width: 200px; z-index: 3; translate: 0 -50%;
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px 11px 10px;
}
.hm-mark::before {
  content: ''; position: absolute; right: 100%; top: calc(50% - 1px); width: 15px; height: 2px; background: var(--cobalt);
}
.hm-mark::after {
  content: ''; position: absolute; right: calc(100% + 13px); top: calc(50% - 6px); width: 12px; height: 12px;
  border-radius: var(--radius-pill); background: var(--white); border: 3px solid var(--cobalt);
}
.hm-mark--block { top: calc(8px + var(--s) * 162px); }
.hm-mark--block::before { background: var(--orange); }
.hm-mark--block::after { border-color: var(--orange); }
.hm-mark--issue { top: calc(8px + var(--s) * 282px); }
.hm-ic { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: var(--radius-pill); }
.hm-ic svg { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.hm-mark--block .hm-ic { background: var(--orange); color: var(--white); }
.hm-mark--issue .hm-ic { background: rgba(0, 71, 171, 0.10); color: var(--cobalt); }
.hm-kind {
  display: block; font-family: var(--condensed); font-size: 0.72rem; font-weight: 600; line-height: 1.3;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted);
}
.hm-mark--issue .hm-kind { color: var(--cobalt); }
/* Giants Orange is 3.14 on White, so the label takes a darker orange which clears 4.5.
   The icon beside it carries the kind as well, so the colour is not doing it alone. */
.hm-mark--block .hm-kind { color: #C2410C; }
.hm-say { display: block; font-size: 0.83rem; font-weight: 500; line-height: 1.3; color: var(--black); margin-top: 1px; }
.hm-verdict {
  left: 18px; top: calc(var(--s) * 282px + 49px); width: 200px; z-index: 2; rotate: -1.5deg;
  display: flex; align-items: center; gap: 11px; padding: 12px 14px 13px 12px;
  background: var(--cobalt); color: var(--white);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 6px 14px rgba(0, 58, 140, 0.22), 0 18px 34px rgba(0, 58, 140, 0.24);
}
.hm-verdict .hm-ic { width: 30px; height: 30px; background: var(--white); color: var(--cobalt); }
.hm-verdict .hm-kind { color: rgba(255, 255, 255, 0.85); }
.hm-verdict .hm-say { font-size: 0.86rem; font-weight: 600; line-height: 1.28; color: var(--white); }
/* The rail's top bar is its own background, drawn from the border box with no top border,
   so nothing lies between the bar and the edge. As a strip inside a 1px border it showed
   a pale line above itself wherever the turn put the edge between 2 pixels. Its far end
   is the accent kicker's purple as it reads on White, written opaque. */
.hm-rail {
  right: 0; top: calc(var(--s) * 282px + 147px); width: 264px; z-index: 4; rotate: 1.5deg;
  padding: 16px 16px 14px; border-top: 0;
  background: linear-gradient(90deg, var(--cobalt), rgb(160, 64, 160)) border-box top / 100% 4px no-repeat, var(--white);
}
.hm-title { display: block; font-size: 1.02rem; font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; color: var(--black); }
/* A tick, a ring, and a broken ring, so the 3 states differ in shape and not in colour alone. */
.hm-steps { display: flex; align-items: center; margin: 12px 0 11px; }
.hm-step {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: var(--radius-pill);
  background: var(--white); border: 2px solid var(--cobalt); color: var(--white);
}
.hm-step svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.hm-step--agreed { background: var(--cobalt); }
.hm-step--proposed::before { content: ''; width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--cobalt); }
.hm-step--missing { border: 2px dashed var(--orange); }
.hm-link { flex: 1; height: 2px; background: var(--cobalt); }
.hm-link--open { background: repeating-linear-gradient(90deg, var(--border-strong) 0 4px, transparent 4px 7px); }
.hm-key {
  display: flex; gap: 14px; padding-top: 9px; border-top: 1px dashed rgba(90, 104, 120, 0.5);
  font-size: 0.78rem; font-weight: 500; color: var(--text);
}
.hm-key span { display: flex; align-items: center; gap: 5px; }
.hm-key span::before {
  content: ''; flex: none; width: 11px; height: 11px; border-radius: var(--radius-pill); border: 2px solid var(--cobalt);
  background: radial-gradient(var(--cobalt) 0 2px, transparent 2.5px);
}
.hm-key .hm-key--agreed::before { background: var(--cobalt); }
.hm-key .hm-key--missing::before { border: 2px dashed var(--orange); background: none; }

/* The deliverable, tagged: each Topic's landing hero. The finished work set in type, with
   every part of it named on a tag pinned where it sits: a page of the report and its 6
   parts for Quality Audits, and the pack's 2 charters, its workbook, and its checkpoints
   and level for Readiness. It is the marked page's other half, drawn from the same paper,
   pins, and cards, and scaled by the same --s. The pages are ours, so they carry the
   Cobalt Blue rule, and they are pictures: hidden from a screen reader, scanned by the
   audit, and carrying no figure and no area's name. docs/decisions/0037 records it.

   The 6 tags stand 46px apart, a 36px tag and 10px clear, each still inside the section
   it names. On a phone they lose 8px of height, because at 0.8 they stand 37px apart. A tag keeps to the box by starting no further
   right than its own width from the edge. No card touches another at any width. */
.hero-tagged--report { height: calc(var(--s) * 376px + 84px); }
.hero-tagged--pack { height: calc(var(--s) * 256px + 351px); }
.hm-sheet--back { left: calc(var(--s) * 34px); top: 0; z-index: 0; rotate: 2.2deg; }
/* Nothing of the page behind reaches the strip beside the page in front, and its title
   starts below what shows above the page in front, so no word is cut by an edge. */
.hm-sheet--back .hm-page { padding-right: 150px; }
.hm-sheet--back .hm-page .hm-letterhead { margin-bottom: 120px; }
.hero-tagged--pack .hm-sheet--front { top: calc(var(--s) * 46px); }
.hm-page--ours { border-top: 8px solid var(--cobalt); padding-top: 36px; }
.hm-page--ours .hm-letterhead { margin-bottom: 18px; }
.hm-page--ours .hm-doc-title { font-size: 26px; }
.hm-page--ours .hm-doc-for { margin-bottom: 20px; }
.hm-our-kind {
  font-family: var(--condensed); font-size: 12px; font-weight: 600; line-height: 1.2;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--cobalt);
}
.hm-file {
  margin-left: auto; padding: 0 8px; border: 2px solid var(--cobalt); border-radius: 4px;
  font-family: var(--condensed); font-size: 11px; font-weight: 600; letter-spacing: 0.1em; color: var(--cobalt);
}
.hm-doc-verdict {
  display: flex; align-items: center; gap: 14px; margin-bottom: 16px; padding: 10px 16px;
  background: rgba(0, 71, 171, 0.07); border-left: 6px solid var(--cobalt);
  font-size: 13px; font-weight: 600; color: var(--text);
}
.hm-doc-verdict span {
  font-family: var(--condensed); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cobalt);
}
/* The scorecard is drawn blank: a line for each area and an empty box for its score. */
.hm-doc-score { display: grid; grid-template-columns: 44px 1fr; gap: 8px 14px; align-items: center; margin-bottom: 14px; }
.hm-doc-score span { height: 6px; border-radius: 3px; background: var(--border); }
.hm-doc-score span:nth-child(odd) { height: 12px; border-radius: 6px; background: var(--surface); border: 2px solid var(--border); }
.hm-doc-score span:nth-child(4) { width: 78%; }
.hm-doc-score span:nth-child(6) { width: 90%; }
.hm-doc-score span:nth-child(8) { width: 64%; }
.hm-doc-block { margin-bottom: 14px; padding: 8px 16px; background: rgba(254, 90, 29, 0.08); border-left: 6px solid var(--orange); color: var(--text); }
.hm-doc-table--criteria { grid-template-columns: 1.5fr 1.3fr 0.9fr; }
.hm-state { display: inline-block; padding: 0 8px; border: 2px solid var(--cobalt); border-radius: var(--radius-pill); font-size: 10px; font-weight: 600; line-height: 14px; color: var(--cobalt); }
.hm-state--agreed { background: var(--cobalt); color: var(--white); }
.hm-state--missing { border: 2px dashed var(--orange); color: #C2410C; }

.hm-tag {
  position: absolute; z-index: 3; translate: 0 -50%;
  left: min(calc(var(--s) * 198px), calc(100% - 180px));
  display: flex; align-items: center; gap: 8px; padding: 5px 13px 5px 5px; border-radius: var(--radius-pill);
  font-size: 0.82rem; font-weight: 600; line-height: 1.3; color: var(--black); white-space: nowrap;
  transition: transform 180ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hm-tag .hm-ic { width: 24px; height: 24px; background: rgba(0, 71, 171, 0.10); color: var(--cobalt); }
.hm-tag .hm-ic svg { width: 12px; height: 12px; }
.hm-tag::before {
  content: ''; position: absolute; right: 100%; top: calc(50% - 1px); width: 13px; height: 2px; background: var(--cobalt);
}
.hm-tag::after {
  content: ''; position: absolute; right: calc(100% + 11px); top: calc(50% - 5px); width: 10px; height: 10px;
  border-radius: var(--radius-pill); background: var(--white); border: 3px solid var(--cobalt);
}
.hm-tag--block::before { background: var(--orange); }
.hm-tag--block::after { border-color: var(--orange); }
.hm-tag--block .hm-ic { background: var(--orange); color: var(--white); }
.hm-tag--verdict { background: var(--cobalt); border-color: var(--cobalt); color: var(--white); }
.hm-tag--verdict .hm-ic { background: var(--white); }
@media (max-width: 419px) {
  .hm-tag { padding: 3px 11px 3px 3px; font-size: 0.78rem; }
  .hm-tag .hm-ic { width: 20px; height: 20px; }
}
.hm-tag--1 { top: calc(8px + var(--s) * 106px); }
.hm-tag--2 { top: calc(8px + var(--s) * 152px); }
.hm-tag--3 { top: calc(8px + var(--s) * 198px); }
.hm-tag--4 { top: calc(8px + var(--s) * 244px); }
.hm-tag--5 { top: calc(8px + var(--s) * 290px); }
.hm-tag--6 { top: calc(8px + var(--s) * 336px); }
.hm-tag--internal, .hm-tag--customer { left: min(calc(var(--s) * 214px), calc(100% - 166px)); }
.hm-tag--internal { top: calc(var(--s) * 26px); }
.hm-tag--customer { top: calc(var(--s) * 150px); }
/* The cards arrive in turn, 250ms apart with no pause between: the 6 tags, then the label
   on the report's foot 1 step after the last of them. */
.hm-slip { top: calc(var(--s) * 376px); width: 236px; }
.hm-wb { right: 0; top: calc(var(--s) * 256px); width: 220px; z-index: 2; rotate: -1.2deg; padding: 11px 12px 12px; }
.hm-wb-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; white-space: nowrap; }
.hm-wb-file { padding: 0 6px; border: 1px solid var(--cobalt); border-radius: 4px; font-family: var(--condensed); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; color: var(--cobalt); }
/* The workbook's first sheet, set at twice its size and scaled by half as the pages are,
   and cut on a row's edge, so no row or state is shown in part. It sits below the
   charter's table for the same reason. */
.hm-wb-screen { height: 70px; overflow: hidden; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); }
.hm-wb-sheet { width: 200%; height: 200%; scale: 0.5; transform-origin: 0 0; padding: 10px 12px 0; font-size: 11px; line-height: 16px; color: var(--muted); }
.hm-wb-tabs { display: flex; gap: 4px; }
.hm-wb-tabs span { padding: 3px 12px; border: 2px solid var(--border); border-bottom: 0; border-radius: 6px 6px 0 0; }
.hm-wb-tabs .hm-on { background: var(--white); font-weight: 600; color: var(--cobalt); }
.hm-doc-table--wb { grid-template-columns: 1.7fr 0.8fr 0.9fr; margin-bottom: 0; border-radius: 0 4px 0 0; border-bottom: 0; background: var(--white); }
/* The rail is placed from the workbook, 22px below its foot, as the home page's is from the
   verdict. The pack's cards arrive in turn as the report's do, 250ms apart with no pause:
   the 2 tags, the workbook, the rail, and then the rail's 5 steps. */
.hero-tagged--pack .hm-rail { top: calc(var(--s) * 256px + 146px); animation-delay: 1550ms; }
.hero-tagged--pack .hm-step:nth-child(1) { animation-delay: 1800ms; }
.hero-tagged--pack .hm-step:nth-child(3) { animation-delay: 1950ms; }
.hero-tagged--pack .hm-step:nth-child(5) { animation-delay: 2100ms; }
.hero-tagged--pack .hm-step:nth-child(7) { animation-delay: 2250ms; }
.hero-tagged--pack .hm-step:nth-child(9) { animation-delay: 2400ms; }
.hm-answer { margin-top: 11px; padding-top: 10px; border-top: 1px dashed rgba(90, 104, 120, 0.5); }

.hm-leaf, .hm-sheet { animation: hm-rise 700ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.hm-sheet { animation-delay: 80ms; }
.hm-hl { animation: hm-ink 620ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.hm-mark, .hm-tag { animation: hm-land 560ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.hm-wb { animation: hm-rise 640ms cubic-bezier(0.22, 1, 0.36, 1) 1300ms both; }
.hm-hl--block { animation-delay: 800ms; }
.hm-mark--block { animation-delay: 1050ms; }
.hm-hl--issue { animation-delay: 1700ms; }
.hm-mark--issue { animation-delay: 1950ms; }
.hm-verdict { animation: hm-stamp 520ms cubic-bezier(0.22, 1, 0.36, 1) 2700ms both; }
.hm-rail { animation: hm-rise 640ms cubic-bezier(0.22, 1, 0.36, 1) 3300ms both; }
.hm-step { animation: hm-pop 380ms cubic-bezier(0.22, 1, 0.36, 1) both; }
/* The steps are the odd children, a link lying between each pair. */
.hm-step:nth-child(1) { animation-delay: 3700ms; }
.hm-step:nth-child(3) { animation-delay: 3850ms; }
.hm-step:nth-child(5) { animation-delay: 4000ms; }
.hm-step:nth-child(7) { animation-delay: 4150ms; }
.hm-step:nth-child(9) { animation-delay: 4300ms; }
/* The landing heroes' turns. These follow the rules above which set each animation whole,
   because a delay set before one of those is reset by it: the tags all arrived at once,
   and the label on the report's foot at the home verdict's time, until this was moved. */
.hm-tag--1 { animation-delay: 800ms; }
.hm-tag--2 { animation-delay: 1050ms; }
.hm-tag--3 { animation-delay: 1300ms; }
.hm-tag--4 { animation-delay: 1550ms; }
.hm-tag--5 { animation-delay: 1800ms; }
.hm-tag--6 { animation-delay: 2050ms; }
.hm-tag--internal { animation-delay: 800ms; }
.hm-tag--customer { animation-delay: 1050ms; }
.hm-slip { animation-delay: 2300ms; }
@keyframes hm-rise { from { opacity: 0; translate: 0 18px; } }
@keyframes hm-ink { from { background-size: 0% 100%; } }
@keyframes hm-land { from { opacity: 0; translate: 16px -50%; } }
@keyframes hm-stamp { from { opacity: 0; scale: 1.14; } }
@keyframes hm-pop { from { opacity: 0; scale: 0.4; } }

/* www sets the paragraph which opens a section a step above body copy. Matched
   by position rather than a class, so a new section gets it without the builder
   having to remember, and scoped to a section wrap so the legal documents,
   whose headings sit inside article.doc, are untouched. */
section > .wrap > h2 + p {
  font-size: clamp(1.02rem, 1.4vw, 1.18rem);
  line-height: 1.55; max-width: 58ch; margin-bottom: 20px;
}

ul, ol { max-width: var(--measure); margin-bottom: 16px; padding-left: 24px; }
li { margin-bottom: 10px; }

/* ── Controls: pill, per www ────────────────────*/
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; max-width: none; }
.cta {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 50px; padding: 0 1.4rem; border-radius: var(--radius-pill);
  /* www's .btn exactly: 16px at 600. www computes 16px from 0.889rem on an 18px
     root; this site's root is 16px, so the same rendered size is 1rem.

     This does not meet WCAG AA. The label is white on Giants Orange, 3.14:1,
     and 16px at 600 is normal text, where the floor is 4.5:1. It was 18.7px at
     700 to reach the 3:1 large-text floor instead. Matching www was chosen with
     that measured and stated. See docs/decisions/0010. */
  border: 1px solid transparent; font-size: 1rem; font-weight: 600;
  line-height: 1; white-space: nowrap; cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}
/* On a narrow screen a label may be wider than the screen: "Check a document
   before it goes out" needs 316px, and a 320px screen has 280px inside the
   gutters. Unwrapped, it pushed the home page 16px sideways, which WCAG 2.2
   1.4.10 (Reflow) does not allow. Here it may wrap, with the leading and the
   padding a second line needs. The size, weight, and colours are untouched, so
   the pairing docs/decisions/0010 records is exactly as it was, and a label
   which fits stays on 1 line. */
@media (max-width: 700px) {
  .cta { white-space: normal; text-align: center; line-height: 1.25;
         padding-block: 12px; max-width: 100%; }
}
/* White label, on instruction and consistent with www and WinCommand. */
.cta-primary { background: var(--orange); color: var(--white); border-color: var(--orange); }
.cta-primary:hover { background: var(--orange-dark); border-color: var(--orange-dark); color: var(--white); }
.cta-secondary { background: var(--white); color: var(--cobalt); border-color: var(--border); }
.cta-secondary:hover { border-color: var(--cobalt); color: var(--cobalt); }

.cta-note { font-size: var(--text-sm); color: var(--muted); margin-top: 16px; max-width: none; }
.cta-note span + span::before { content: '  |  '; }
/* The address is the way in for a question the page has not answered. It sits under
   the note and not in the CTA row, so it never competes with Start. */
/* The address is 1 unbroken string wider than a 320px screen, so it may break. */
.cta-ask { margin-top: 6px; overflow-wrap: anywhere; }

/* ── Cards: lift, strengthen, and reveal the foot bar ──*/
.grid { display: grid; gap: 18px; margin: 28px 0 20px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.card {
  position: relative;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--white); padding: 24px 26px;
  box-shadow: var(--shadow-sm);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
/* www carries a 3px tinted bar at the card foot on hover. Its panels are wide
   enough that it disappears; at this card width the same bar reads as a
   coloured smear, so the lift, the shadow, the border and the heading colour
   carry the hover instead. */
.card:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong);
}
.card:hover h3 { color: var(--cobalt); }
.card h3 { transition: color 160ms ease; }
.card p { font-size: var(--text-sm); color: var(--muted); margin: 0; max-width: none; }

/* A card which is itself the link. The anchor covers the card, so the whole
   surface is clickable while the heading keeps the hover treatment. */
.card-link { display: block; color: inherit; }
.card-link:hover { color: inherit; }
/* A column, so the affordance can sit at the foot: cards in a row share a
   height, and a shorter description would otherwise lift its link above the
   others. */
.card-link .card { height: 100%; display: flex; flex-direction: column; }

/* ── Card eyebrow: a dot and a label ────────────
   www marks a card with a small dot and a tracked label. Cobalt is structural
   and names what a card is; orange is directional and marks the set a reader
   is being asked to choose from. Specificity is `.card .card-accent` because
   `.card p` would otherwise win and take the colour and the size back. */
.card .card-accent {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0 0 12px; max-width: none;
  font-size: max(12px, var(--text-xs)); font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted);
}
.card .card-accent::before {
  content: ''; flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--cobalt); box-shadow: 0 0 0 6px rgba(0, 71, 171, 0.08);
}
.card .card-accent--orange::before {
  background: var(--orange); box-shadow: 0 0 0 6px rgba(254, 90, 29, 0.09);
}

/* ── Panel: a section which reads as one object ─*/
.panel {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-xl); padding: 36px 40px;
  box-shadow: var(--shadow-sm);
}
.panel > p:last-child { margin-bottom: 0; }

/* ── Every card and panel answers the pointer ─────────────────────────────
   A card lifts 3px, deepens its shadow, and strengthens its border, as .card
   does. A panel the width of the page, a document sheet, a table, or the
   contents list, would read as the page itself moving if it lifted, so it
   deepens its shadow and strengthens its border in place. Nothing moves when
   reduced motion is asked for. */
.panel, .sheet, .scroller, .toc-inline {
  transition: box-shadow 180ms ease, border-color 180ms ease;
}
.panel:hover, .sheet:hover, .scroller:hover, .toc-inline:hover {
  box-shadow: var(--shadow-md); border-color: var(--border-strong);
}
@media (max-width: 700px) { .panel { padding: 26px 22px; } }

/* ── Pull line: the left-edge accent of canon Section 11, which lists quote
   blocks and strategic notes among its uses. Sized as a statement, not a
   heading, so it does not compete with the h2 above it. */
.pull {
  border-left: 3px solid var(--orange);
  padding: 2px 0 2px 22px; margin: 26px 0;
  font-size: 1.25rem; line-height: 1.4; font-weight: 600;
  color: var(--black); max-width: 44ch;
}

/* ── Reasons: three short failures, read side by side rather than as one
   paragraph, because the point is the pattern across them. */
.reasons {
  display: grid; gap: 14px; margin: 24px 0;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
}
.reason {
  border: 1px solid var(--border); border-left: 2px solid var(--border-strong);
  border-radius: var(--radius-md); background: var(--surface); padding: 18px 20px;
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.reason:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong);
}
.reason strong { display: block; color: var(--black); margin-bottom: 6px; }
.reason span { display: block; font-size: var(--text-sm); color: var(--muted); }

/* ── Step cards ─────────────────────────────────
   Still an ol, because the order is the process. The step which is ours takes
   cobalt and says so, so the heading's claim is visible rather than counted. */
.step-cards {
  list-style: none; padding: 0; max-width: none;
  display: grid; gap: 18px; margin: 28px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.step-cards li {
  position: relative; margin: 0;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--white); padding: 24px 26px; box-shadow: var(--shadow-sm);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.step-cards li:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong);
}
.step-cards li:hover h3 { color: var(--cobalt); }
.step-cards h3 { margin-bottom: 8px; transition: color 160ms ease; }
.step-cards p { font-size: var(--text-sm); color: var(--muted); margin: 0; max-width: none; }
/* Same dot and label as a card eyebrow, so the two grids read as one system.
   The label is muted rather than orange: Giants Orange is 3.14 on white, which
   clears AA only as large bold text, and this is a 12px label. The colour sits
   in the dot, which is a graphical object and needs 3:1. */
.step-n {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 12px;
  font-size: max(12px, var(--text-xs)); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
.step-n::before {
  content: ''; flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--orange); box-shadow: 0 0 0 6px rgba(254, 90, 29, 0.09);
}
.step-cards li.is-ours { border-top: 2px solid var(--cobalt); }
/* Where the 4 steps stand in 1 row, a dashed rule runs behind them at the level of
   their dots, so the gaps read as 1 process and not 4 separate cards. */
@media (min-width: 1100px) {
  .step-cards { position: relative; }
  .step-cards::before {
    content: ''; position: absolute; left: 30px; right: 30px; top: 37px;
    border-top: 1px dashed var(--border-strong);
  }
  .step-cards li { z-index: 1; }
}
.step-cards li.is-ours .step-n::before {
  background: var(--cobalt); box-shadow: 0 0 0 6px rgba(0, 71, 171, 0.08);
}

/* ── Checkpoints: Readiness's 5, as a track ───────────────────────────────
   Still an ol, because each checkpoint follows the one before it. Each card opens
   on a square marker, the shape a checkpoint takes wherever the estate draws one,
   and a cobalt rule runs between them at that level where the 5 stand in 1 row. */
.checkpoints {
  list-style: none; padding: 0; max-width: none; position: relative;
  display: grid; gap: 14px; margin: 28px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
}
.checkpoints li {
  position: relative; z-index: 1; margin: 0;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--white); padding: 22px 22px 22px; box-shadow: var(--shadow-sm);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.checkpoints li:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.checkpoints li:hover h3 { color: var(--cobalt); }
.checkpoints h3 { font-size: 1.05rem; transition: color 160ms ease; }
.checkpoints p { font-size: var(--text-sm); color: var(--muted); margin: 0; max-width: none; }
.cp-n {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 12px;
  font-size: max(12px, var(--text-xs)); font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.cp-n::before {
  content: ''; flex: none; width: 10px; height: 10px;
  border: 2px solid var(--cobalt); background: var(--white);
}
@media (min-width: 1100px) {
  .checkpoints::before {
    content: ''; position: absolute; left: 26px; right: 26px; top: 35px;
    border-top: 2px solid var(--cobalt); opacity: 0.35;
  }
}

/* ── States: Agreed, Proposed, Missing, each on its own card ───────────────
   The word is always written, and its colour only repeats it: green for a
   confirmation and red for a gap, the visual brand canon's semantic pair, which
   each clear 4.5:1 as text on white. Proposed is the ordinary state of a first pack,
   so it takes cobalt and not a warning colour. */
.states {
  display: grid; gap: 14px; margin: 22px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}
.state {
  border: 1px solid var(--border); border-top: 3px solid var(--cobalt);
  border-radius: var(--radius-md); background: var(--white); padding: 18px 20px;
  box-shadow: var(--shadow-sm);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.state:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.state p { font-size: var(--text-sm); color: var(--muted); margin: 0; max-width: none; }
.state .state-word {
  font-size: 1.05rem; font-weight: 700; letter-spacing: -0.005em; margin-bottom: 6px; color: var(--cobalt);
}
.state--agreed { border-top-color: #15803D; }
.state--agreed .state-word { color: #15803D; }
.state--missing { border-top-color: #D32F2F; }
.state--missing .state-word { color: #D32F2F; }
.state--agreed:hover { border-top-color: #15803D; }
.state--proposed:hover { border-top-color: var(--cobalt); }
.state--missing:hover { border-top-color: #D32F2F; }

/* ── Spec: what a deliverable carries, as items rather than a sentence ─*/
.spec {
  list-style: none; padding: 0; max-width: none;
  display: grid; gap: 12px; margin: 24px 0 22px;
  grid-template-columns: repeat(auto-fit, minmax(236px, 1fr));
}
.spec li {
  position: relative; margin: 0; padding: 14px 18px 14px 38px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--white); box-shadow: var(--shadow-sm);
  font-size: var(--text-sm); color: var(--text);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.spec li:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong);
}
.spec li::before {
  content: ''; position: absolute; left: 18px; top: 1.35em;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); transform: translateY(-50%);
}

/* The affordance on a card which is itself a link. The arrow is a glyph rather
   than an image, and it is not the only signal: the label says where it goes. */
.card-go {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 16px;
  font-size: var(--text-sm); font-weight: 600; color: var(--cobalt);
}
/* Auto top margin takes the spare height; the padding keeps the 16px gap on
   the tallest card, where there is none to take. */
.card-link .card-go { margin-top: auto; padding-top: 16px; align-self: flex-start; }
.card-go::after { content: '\2192'; transition: transform 160ms ease; }
.card-link:hover .card-go::after { transform: translateX(3px); }

/* ── Pricing ────────────────────────────────────*/
.price-card .price-fig {
  display: block; font-size: 2.4rem; font-weight: 700; color: var(--black);
  letter-spacing: -0.02em; margin: 6px 0 10px; max-width: none;
}
.price-note { font-size: var(--text-sm); color: var(--muted); }
/* Cobalt is the standing service, orange the expedited one. The tiers are named
   in the heading as well, so the colour is not carrying the difference alone. */
.price-card { border-top: 2px solid var(--cobalt); }
.price-card--fast { border-top-color: var(--orange); }
/* Each price as a ticket: the figure above a perforation, the terms below it, over
   the hero pictures' fading dot field. */
.grid--prices { position: relative; isolation: isolate; }
.grid--prices::before {
  content: ''; position: absolute; inset: -24px 0; z-index: -1;
  background-image: radial-gradient(rgba(90, 104, 120, 0.55) 1px, transparent 1.5px);
  background-size: 16px 16px;
  -webkit-mask-image: radial-gradient(closest-side, #000 45%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 45%, transparent 100%);
}
.price-card .price-fig + p { border-top: 1px dashed rgba(90, 104, 120, 0.7); padding-top: 14px; }
.price-card .price-fig { font-size: 2.8rem; }
/* The figure says what it leaves out, inside the figure's own span so the
   perforation still follows it. */
.price-card .price-vat {
  display: block; margin-top: 4px; font-size: var(--text-sm); font-weight: 400;
  line-height: 1.4; letter-spacing: 0; color: var(--muted);
}

/* ── Callout: left-edge accent, canon Section 11 ─*/
.callout {
  background: var(--white); border: 1px solid var(--border);
  border-left: 3px solid var(--orange);
  border-radius: var(--radius-md); padding: 22px 26px; margin: 26px 0;
  max-width: var(--measure); box-shadow: var(--shadow-sm);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.callout:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg);
  border-color: var(--border-strong); border-left-color: var(--orange);
}
.callout p { max-width: none; }

/* A question and its answer, as a card. Same hover as every other card. The
   column never asks for more than the screen has: at a plain 330px it ran 30px
   past a 320px screen and pushed both pricing pages sideways. */
.faq-grid { display: grid; gap: 18px; margin: 28px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); }
.faq-grid .card h3 { font-size: 1.05rem; margin-bottom: 10px; }
.faq-grid .card p { font-size: var(--text-sm); color: var(--text); }

/* ── Rendered documents ─────────────────────────*/
.doc { padding: 56px 0 76px; position: relative; isolation: isolate; }
/* The hero's blueprint grid, behind a document's title, fading out before the text
   it would sit behind. */
.doc::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 320px; z-index: -1;
  background-image:
    linear-gradient(rgba(0, 71, 171, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 71, 171, 0.045) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0, transparent 100%);
}
.doc h1 { margin-bottom: 22px; }
.doc h2 {
  font-size: 1.55rem; margin-top: 46px; margin-bottom: 14px;
  padding-top: 24px; border-top: 1px solid var(--border);
}
.doc h3 { font-size: 1.111rem; margin-top: 28px; }
.doc hr { border: 0; height: 0; margin: 0; }
.doc code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.86em; background: var(--surface);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 0.1em 0.36em; color: var(--black);
  /* An address or a URL is 1 unbroken string, and several are wider than a
     320px screen, so it may break, as .cta-ask's address does. It breaks only
     where it would not otherwise fit. */
  overflow-wrap: anywhere;
}
.doc a { font-weight: 500; }

/* On this page: a legal document's contents, as WinCommand sets them. A column
   of 15rem to the left of the document from 1024px, which follows the reader
   down the page, and a list which opens above section 1 below that. The page
   carries both and 1 is display: none, so a screen reader meets it once. The
   column scrolls inside itself, since the Service Terms' 24 sections are taller
   than a laptop's screen, and its top clears the 76px sticky header. Each row is
   at least 24px, the WCAG 2.2 2.5.8 floor. */
.toc ol { list-style: none; padding: 0; margin: 0; max-width: none; }
.toc li { margin: 0; }
.toc a {
  display: block; padding: 5px 0 5px 12px; border-left: 2px solid transparent;
  font-size: var(--text-sm); line-height: 1.4; font-weight: 400; color: var(--muted);
}
.toc a:hover { color: var(--link-hover); border-left-color: var(--border-strong); }
/* The column scrolls, so it clips at its padding box. The site's ring is 2px at a
   3px offset, 5px in all, and the column has 4px of padding: pulled in to 1px, the
   ring is 3px and whole. */
.toc a:focus-visible { outline-offset: 1px; }
/* The section being read, which the contents script marks with aria-current. By
   weight and a cobalt rule as well as colour, so colour is never the only cue. */
.toc a[aria-current] { color: var(--cobalt); font-weight: 600; border-left-color: var(--cobalt); }
.toc-aside { display: none; }
.toc-label {
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 12px;
}
.toc-inline {
  margin: 28px 0 8px; max-width: var(--measure);
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.toc-inline summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 44px; padding: 0 16px; list-style: none; cursor: pointer;
  font-size: var(--text-sm); font-weight: 600; color: var(--black);
}
.toc-inline summary::-webkit-details-marker { display: none; }
.toc-inline summary::marker { content: ''; }
.toc-inline summary:focus-visible {
  outline: 2px solid var(--cobalt); outline-offset: 3px; border-radius: var(--radius-md);
}
.toc-chevron { flex: none; color: var(--muted); transition: transform 180ms ease; }
.toc-inline[open] .toc-chevron { transform: rotate(180deg); }
.toc-inline nav { border-top: 1px solid var(--border); padding: 10px 16px 12px 4px; }
@media (min-width: 1024px) {
  .doc-layout {
    display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 48px; align-items: start;
  }
  /* The top margin is the article's top padding, so the list starts level with
     the title. The 4px padding holds a link's focus ring, which .toc a:focus-visible
     keeps to 3px, inside the scroll box, which would otherwise clip it. */
  .toc-aside {
    display: block; position: sticky; top: 100px; margin-top: 56px;
    max-height: calc(100vh - 124px); overflow-y: auto; overscroll-behavior: contain;
    padding: 4px;
  }
  .toc-inline { display: none; }
}
@media print {
  .toc { display: none; }
  .doc-layout { display: block; }
}
/* The legal set as cards: each document is 1 link, so the whole card is the
   link, and it lifts like every other card. */
.legal-index {
  list-style: none; padding: 0; max-width: none; margin: 18px 0 8px;
  display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}
.legal-index li { margin: 0; }
.legal-index a {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; height: 100%;
  padding: 16px 20px; border: 1px solid var(--border); border-left: 2px solid var(--cobalt);
  border-radius: var(--radius-md); background: var(--white); box-shadow: var(--shadow-sm);
  font-weight: 600; color: var(--black);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease, color 160ms ease;
}
.legal-index a::after { content: '\2192'; flex: none; color: var(--cobalt); transition: transform 160ms ease; }
.legal-index a:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg);
  border-color: var(--border-strong); border-left-color: var(--cobalt); color: var(--cobalt);
}
.legal-index a:hover::after { transform: translateX(3px); }

/* ── Tables ─────────────────────────────────────*/
.scroller {
  overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--white); margin: 24px 0; box-shadow: var(--shadow-sm);
}
table { border-collapse: collapse; width: 100%; font-size: var(--text-sm); min-width: 520px; }
th, td { text-align: left; padding: 13px 18px; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th {
  font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--cobalt); font-weight: 600; background: var(--surface-alt); white-space: nowrap;
}
tbody td { color: var(--black); }
tbody th { color: var(--black); font-weight: 600; }   /* a row header in a key and value table */
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }   /* th as well: a row header left its rule behind */

/* ── Example deliverables: an excerpt set as the document it is ─────────────
   The report or charter sits in white sheets, and our commentary sits between
   them on the orange left rule, so a note is never read as part of what a
   subscriber receives. Severity keeps the report's filled label: the word on
   its ground, never colour alone. The 2 grounds are the visual brand canon's
   semantic colours, declared here and not in chrome.css because only these
   pages use them. */
:root { --red: #D32F2F; --amber: #FFB000; }
.sheet {
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 34px 40px; margin: 24px 0;
  box-shadow: var(--shadow-sm);
}
@media (max-width: 700px) { .sheet { padding: 24px 18px; } }
.sheet h3 { margin-top: 30px; }
.sheet > h3:first-child { margin-top: 0; }
.sheet h4 { font-size: 1rem; font-weight: 600; color: var(--black); margin: 22px 0 8px; }
.sheet .scroller { box-shadow: none; margin: 16px 0; }
.sheet-cover { border-bottom: 2px solid var(--orange); padding-bottom: 18px; margin-bottom: 28px; }
.sheet-kicker {
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}
.sheet-title { font-size: var(--text-lg); font-weight: 700; color: var(--black); margin-bottom: 6px; }
.sheet-meta { font-size: var(--text-sm); color: var(--muted); }
.sheet-gap { font-size: var(--text-sm); color: var(--muted); font-style: italic; }
.sev {
  display: inline-block; font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.06em;
  line-height: 1.5; padding: 1px 8px; border-radius: 3px; margin: 0 10px 0 6px; vertical-align: 2px;
}
.sev--red { background: var(--red); color: var(--white); }
.sev--amber { background: var(--amber); color: var(--black); }
.note {
  border-left: 3px solid var(--orange); padding: 10px 14px 10px 20px; margin: 28px 0;
  max-width: var(--measure); border-radius: 0 var(--radius-md) var(--radius-md) 0;
  transition: background-color 180ms ease, transform 180ms ease;
}
.note:hover { background: rgba(254, 90, 29, 0.05); transform: translateX(3px); }
.note p { font-size: var(--text-sm); color: var(--text); margin: 0; }
.note strong { color: var(--black); }


@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .card:hover, .reason:hover, .spec li:hover, .step-cards li:hover, .callout:hover,
  .legal-index a:hover, .note:hover, .checkpoints li:hover, .state:hover { transform: none; }
  .hm-leaf:hover, .hm-sheet:hover, .hm-mark:hover, .hm-verdict:hover, .hm-rail:hover, .hm-wb:hover, .hm-tag:hover { transform: none; }
  html { scroll-behavior: auto; }
}
