/* ==========================================================================
   The Cross Family: one stylesheet for the whole site.

   The palette is not invented. All four products already ship the same three
   colours (navy #14315b, teal #1797b3, orange #f1851f), so the family brand is
   the products' brand. Each product page sets a body class that overrides only
   the --accent tokens; nothing else in the system moves.

   Spacing: 4 / 8 / 16 / 24 / 32 / 48 / 64 / 96
   Type:    12 / 13 / 15 / 17 / 20 / 26 / 34 / 44 / 56
   ========================================================================== */

:root {
  /* Ink */
  --ink:       #16203a;
  --ink-soft:  #4a5571;
  --ink-faint: #6b768f;
  --ink-mute:  #6a7488;   /* 4.70:1 on white. Was #8b95aa (3.01:1), which failed AA. */

  /* Family brand */
  --navy:      #14315b;
  --navy-deep: #0d2143;
  --navy-soft: #2a4a7c;
  --teal:      #1797b3;
  --teal-deep: #0d7d90;
  --orange:    #f1851f;

  /* Surfaces */
  --bg:      #ffffff;
  --bg-soft: #f6f8fb;
  --bg-warm: #eef2f7;
  --line:    #dfe5ee;
  --line-soft:#eaeff5;

  /* Status (shared by every product's engine) */
  --good: #2e9e6b;
  --fair: #b7841f;
  --poor: #c86526;
  --bad:  #c33a2f;

  /* Default accent = teal. Product pages override. */
  --accent:       #1797b3;
  --accent-deep:  #0d7d90;
  --accent-light: #e7f5f8;

  /* This is a system-font site, and it says so. It used to name 'Inter' first, but
     nothing here loads Inter: there is no @font-face, and the site makes no external
     requests by design. So the name did nothing except mislead the next person to
     open this file, while the page rendered in San Francisco or Segoe anyway.
     Personality comes from the weight and tracking below instead of from a webfont
     we are not allowed to fetch. */
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;

  /* Four radii. No exceptions. */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-pill: 999px;

  /* A contact shadow plus a soft one. A single blurred blob reads as 2016. */
  --shadow-sm: 0 1px 2px rgba(20,49,91,.06), 0 1px 1px rgba(20,49,91,.04);
  --shadow-md: 0 1px 2px rgba(20,49,91,.06), 0 6px 18px rgba(20,49,91,.08);
  --shadow-lg: 0 1px 2px rgba(13,33,67,.06), 0 8px 20px rgba(13,33,67,.08), 0 24px 60px rgba(13,33,67,.10);

  /* Section rhythm. Three steps, so the page has a pulse. Kept tight so the eye
     moves from one section to the next without crossing a field of dead space. */
  --s-tight: 44px;
  --s-base:  68px;
  --s-loud:  92px;
}

/* Per-product accents. Each is that product's real brand colour. */
.t-scan    { --accent:#1596a5; --accent-deep:#0d7180; --accent-light:#e4f4f7; }
.t-connect { --accent:#2f6fb0; --accent-deep:#215389; --accent-light:#e8f0f9; }
.t-check   { --accent:#b8760f; --accent-deep:#8d5a09; --accent-light:#fbf0dd; }
.t-room    { --accent:#e35a1c; --accent-deep:#b34413; --accent-light:#fdeee5; }
/* CrossTrust's own wordmark navy. It is the darkest of the five on purpose: this is
   the product that reads the paperwork, and it sits at the authoritative end of the
   same family scale rather than competing with CrossConnect's mid blue. */
.t-trust   { --accent:#173a6b; --accent-deep:#0f2749; --accent-light:#e8edf5; }

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, svg { display: block; max-width: 100%; height: auto; }
a { color: var(--navy); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
::selection { background: var(--accent-light); color: var(--navy); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.dark :focus-visible, .site-footer :focus-visible, .demo-head :focus-visible, .app-nav :focus-visible { outline-color: #7fd3e2; }

.skip-link { position: absolute; left: -9999px; background: var(--navy); color: #fff; padding: 8px 16px; z-index: 200; }
.skip-link:focus { left: 16px; top: 12px; }

/* ---- Layout ------------------------------------------------------------ */
.wrap        { max-width: 1160px; margin: 0 auto; padding: 0 28px; }
.wrap-narrow { max-width: 780px;  margin: 0 auto; padding: 0 28px; }

section { padding: var(--s-base) 0; }
/* The two sections that should breathe: the discipline statement and the close. */
section.dark, section.cta-band { padding: var(--s-loud) 0; }
/* Two soft bands back to back read as noise. Tighten the seam. */
section + section.soft { padding-top: var(--s-tight); }
/* Hairlines top and bottom so a tinted band reads as a distinct layer against
   the white sections instead of a barely-there shift. */
.soft { background: var(--bg-soft); box-shadow: inset 0 1px 0 rgba(20,49,91,.05), inset 0 -1px 0 rgba(20,49,91,.045); }

/* The closing band. This used to be six inline style attributes pasted onto every
   page, and one of them (padding:76px) quietly overrode the --s-loud rule above,
   so the section that was supposed to breathe was the tightest on the page. It
   lives here now, and the pages just say class="cta-band". */
/* Left-aligned like every other section, so the page keeps one reading edge from
   the hero to the close instead of snapping to centre at the end. */
.cta-band h2 { max-width: 24ch; margin: 0 0 16px; }
.cta-band > .wrap-narrow > p { max-width: 56ch; margin: 0; }
.cta-band .btn-row { justify-content: flex-start; }
/* The closing band gets a soft accent wash from the top so it lifts off the
   page rather than sitting as one flat colour. */
.cta-band.warm { background: radial-gradient(72% 130% at 50% 0%, color-mix(in srgb, var(--accent) 9%, var(--bg-warm)), var(--bg-warm) 72%); }
.warm { background: var(--bg-warm); box-shadow: inset 0 1px 0 rgba(20,49,91,.055), inset 0 -1px 0 rgba(20,49,91,.05); }
.dark { background: var(--navy); color: #fff; }
/* A faint teal light spilling from the top edge gives the navy bands dimension
   rather than one dead fill. */
section.dark { position: relative; overflow: hidden; }
section.dark > .wrap, section.dark > .wrap-narrow { position: relative; z-index: 1; }
section.dark::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 62%;
  background: radial-gradient(58% 100% at 50% 0%, rgba(127,211,226,.13), transparent 72%);
  pointer-events: none;
}
.dark h2, .dark h3, .dark h4 { color: #fff; }
.dark p, .dark li { color: rgba(255,255,255,.76); }
.dark-intro { max-width: 640px; margin-bottom: 22px; font-size: 15px; line-height: 1.6; }
.dark a { color: #fff; }
.dark .eyebrow { color: #7fd3e2; }

.eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  color: var(--accent-deep); margin-bottom: 12px;
}

/* ---- Type -------------------------------------------------------------- */
/* h1 was only 6px above h2, so the h1 never won. Widen the gap. */
h1, h2, h3, h4 { color: var(--navy); line-height: 1.16; letter-spacing: -.02em; font-weight: 700; }
/* The h1 is the only place the type is allowed to shout: heavier than everything
   else, and tracked in tighter. On a system-font site this is where the voice has
   to come from, because no webfont is coming to supply it. */
/* The scale is wider than it was. A technical reader scans headings and skips the
   prose between them (NN/g call it the layer-cake pattern), and that only happens
   when the headings are unmistakably louder than the body. At 32px against 17px
   body the h2 was not winning by enough to catch a scanning eye, so the page read
   as one long grey column and the argument in the headings went unread. */
h1 { font-size: 52px; font-weight: 800; letter-spacing: -.034em; }
h2 { font-size: 38px; margin-bottom: 18px; letter-spacing: -.026em; }
h3 { font-size: 21px; margin-bottom: 8px; }
h4 { font-size: 16px; margin-bottom: 6px; letter-spacing: -.005em; }
p { color: var(--ink-soft); }
p + p { margin-top: 14px; }
strong { color: var(--ink); font-weight: 650; }
.lede { font-size: 20px; line-height: 1.55; color: var(--ink-soft); max-width: 64ch; }
/* The prose under a section heading sits quieter, so the heading keeps the contrast
   it just gained instead of handing it straight back. */
.section-intro { max-width: 66ch; margin-bottom: 40px; }
.section-intro > p { font-size: 16px; color: var(--ink-faint); }
.muted { color: var(--ink-faint); font-size: 15px; }
code, .mono { font-family: var(--mono); font-size: .88em; }

/* ---- Header ------------------------------------------------------------ */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255,255,255,.9);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; height: 68px; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--navy); font-weight: 700; font-size: 17px; letter-spacing: -.01em; }
.brand:hover { text-decoration: none; }
.brand > svg { width: 26px; height: 26px; flex: none; }
.brand .c2 { color: var(--teal); }
.brand .by { font-size: 11px; font-weight: 500; color: var(--ink-mute); letter-spacing: .02em; margin-left: 2px; }

.nav { display: flex; align-items: center; gap: 24px; }
/* :not(.btn) or these win on specificity (0,1,1 beats .btn-primary's 0,1,0) and
   repaint the navy CTA's label in muted ink, on navy. */
.nav a:not(.btn) { font-size: 15px; font-weight: 500; color: var(--ink-soft); }
.nav a:not(.btn):hover { color: var(--navy); text-decoration: none; }
.nav a:not(.btn)[aria-current="page"] { color: var(--navy); font-weight: 650; }
.nav .btn { padding: 9px 16px; font-size: 14px; }
.nav-toggle { display: none; background: none; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 8px 10px; cursor: pointer; }
.nav-toggle span { display: block; width: 18px; height: 2px; background: var(--navy); border-radius: 2px; }
.nav-toggle span + span { margin-top: 4px; }

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 22px; border-radius: var(--r-sm);
  font-size: 15px; font-weight: 650; font-family: inherit;
  border: 1px solid transparent; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, box-shadow .15s, transform .08s;
}
.btn:hover { text-decoration: none; box-shadow: var(--shadow-sm); }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--navy); color: #fff; }
.btn-primary:hover { background: var(--navy-soft); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-deep); }
.btn-ghost { background: #fff; color: var(--navy); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--navy-soft); }
.dark .btn-primary { background: #fff; color: var(--navy); }
.dark .btn-primary:hover { background: #e7eef6; }
.dark .btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.3); }
.dark .btn-ghost:hover { border-color: rgba(255,255,255,.65); background: rgba(255,255,255,.07); }
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 28px; }
.startchip {
  font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  background: var(--accent-light); color: var(--accent-deep);
  padding: 3px 7px; border-radius: 4px;
}
.btn-primary .startchip { background: rgba(255,255,255,.18); color: #fff; }

/* ---- Hero -------------------------------------------------------------- */
.hero {
  padding: 88px 0 72px; position: relative;
  /* A soft wash of the page accent behind the headline and the product shot,
     over the old top-to-bottom fade. Depth, not decoration. */
  background:
    radial-gradient(58% 52% at 84% 4%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 68%),
    radial-gradient(46% 60% at 6% 0%, color-mix(in srgb, var(--navy) 6%, transparent), transparent 62%),
    linear-gradient(180deg, var(--bg-soft), var(--bg));
}
.hero h1 { max-width: 18ch; margin-bottom: 20px; }
.hero .lede { font-size: 21px; }
/* The hero shot is the loudest proof on the page, so it gets the deepest lift. */
.hero .figure img, .hero .shot { box-shadow: var(--shadow-lg); }
.hero-product { border-top: 4px solid var(--accent); }
.hero-split { display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center; }
.hero-product h1 { font-size: 40px; max-width: 15ch; }

.trust-line {
  margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 14px; color: var(--ink-faint); max-width: 58ch;
}
.product-eyebrow { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.product-eyebrow img, .product-eyebrow svg { width: 40px; height: 40px; flex: none; }
.product-eyebrow .pn { font-size: 22px; font-weight: 700; color: var(--navy); letter-spacing: -.01em; }
.product-eyebrow .pn em { font-style: normal; color: var(--accent); }
.product-eyebrow .pt { font-size: 13px; color: var(--ink-faint); }

/* ---- Pillars ----------------------------------------------------------- */
.pillar { margin-bottom: 44px; }
.pillar-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 6px; padding-bottom: 14px; border-bottom: 2px solid var(--line); }
.pillar-head h2 { font-size: 26px; margin: 0; }
/* These labels are prose ("an afternoon", "before the change"), and prose does not
   go in the code face. Mono is for the things that are literally typed at a machine:
   an address, a port, a MAC, a command. The uppercase and the tracking carry the
   label voice on their own. */
.pillar-head .when { font-size: 12px; font-weight: 700; color: var(--ink-mute); letter-spacing: .09em; text-transform: uppercase; margin-left: auto; }
.pillar > p { margin: 12px 0 22px; max-width: 70ch; }

/* Product cards: ONE line each. Research-backed hard cap. */
.pcards { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.pcard {
  display: block; background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  border-left: 4px solid var(--pa, var(--line));
  padding: 22px 24px; transition: border-color .15s, box-shadow .15s, transform .15s;
}
.pcard:hover { text-decoration: none; box-shadow: var(--shadow-md); transform: translateY(-2px); }
.pcard:focus-visible { outline-offset: 3px; border-radius: var(--r-md); }
.pcard-top { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.pcard-top img, .pcard-top svg { width: 28px; height: 28px; flex: none; }
.pcard-top .name { font-size: 18px; font-weight: 700; color: var(--navy); }
.pcard-top .name em { font-style: normal; color: var(--pa); }
.pcard .job { font-size: 15px; color: var(--ink-soft); line-height: 1.5; }
/* The third pillar holds one product, so the second grid cell carries the thing a
   reader is about to ask instead of an empty column or a padded-out second card. */
.pcard-note {
  align-self: center; padding: 4px 4px 4px 22px;
  border-left: 1px solid var(--line);
}
.pcard-note p { font-size: 14.5px; color: var(--ink-soft); line-height: 1.6; }
.pcard-note p + p { margin-top: 12px; }
.pcard-note b { color: var(--navy); }
@media (max-width: 860px) { .pcard-note { border-left: 0; padding-left: 4px; } }
.pcard .q { margin-top: 12px; font-size: 14px; color: var(--ink-faint); font-style: italic; }
.pcard .go { margin-top: 14px; font-size: 14px; font-weight: 650; color: var(--pa); }

/* ---- Compare table (CrossScan vs CrossConnect) --------------------------
   The two products both "find out what is on your network". If a reader cannot
   tell them apart in five seconds, the whole portfolio reads as padding. Prose
   was not doing it. A table does. */
.compare { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; box-shadow: var(--shadow-md); }
.compare th, .compare td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--line-soft); font-size: 15px; vertical-align: top; }
.compare tbody tr:nth-child(even) td, .compare tbody tr:nth-child(even) th { background: color-mix(in srgb, var(--bg-soft) 50%, #fff); }
.compare thead th { background: var(--bg-soft); font-size: 13px; letter-spacing: .04em; }
.compare thead th:first-child { color: var(--ink-mute); text-transform: uppercase; font-size: 11px; letter-spacing: .09em; }
.compare thead th.h-scan    { color: #0d7180; border-top: 3px solid #1596a5; }
.compare thead th.h-connect { color: #215389; border-top: 3px solid #2f6fb0; }
.compare tbody th { font-weight: 600; color: var(--ink-faint); width: 24%; font-size: 14px; }
.compare td { color: var(--ink); }
.compare tr:last-child th, .compare tr:last-child td { border-bottom: none; }
.compare .lead { font-weight: 680; color: var(--navy); display: block; }
.compare .sm { display: block; font-size: 13px; color: var(--ink-faint); margin-top: 2px; line-height: 1.45; }

/* ---- The assembly diagram (puzzle) ------------------------------------- */
.assembly { position: relative; }
.assembly-stage { margin: 0 auto; max-width: 940px; }
/* GAP ZERO IS LOAD-BEARING. The tabs are positioned at 50% of each PIECE; the
   sockets are cut at 50% of each 25%-wide tile of the PLATE. Those two only agree
   when the four pieces tile the stage exactly, with nothing between them. With a
   14px gap the outer tabs drifted about 5px off their holes, which is what made
   the thing look broken. It also made the pieces impossible to read as a jigsaw:
   pieces that do not touch cannot interlock. */
.piecegrid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin-bottom: 0; }
.piece {
  position: relative; border: 1px solid var(--line);
  border-top: 5px solid var(--pa); border-radius: 0;
  padding: 20px 17px 34px;
  /* A thick physical puzzle tile, not a flat panel. Layered, in order:
     - a concave socket dimple sunk into the left edge (every piece but the first),
       where the neighbour's knob plugs in;
     - a lit top-down surface. */
  background:
    radial-gradient(18px at left center, rgba(23,58,107,.28), rgba(23,58,107,.06) 62%, transparent 74%),
    radial-gradient(120% 80% at 50% -10%, rgba(255,255,255,.95), rgba(255,255,255,0) 55%),
    linear-gradient(158deg, #eef2f9 0%, #ffffff 34%, #d4ddec 100%);
  /* A thick tile with real relief. In order: a bright top-and-left inner highlight and a
     dark bottom-and-right inner shade (the bevel); dark hairlines down each side edge so
     the butted seam reads as a cut groove between two separate pieces; a soft inner floor
     shadow; a stacked hard lip along the bottom that is the tile's THICKNESS; and a large
     cast shadow so it clearly stands above the tray. */
  box-shadow:
    inset 3px 3px 0 rgba(255,255,255,1),
    inset -3px -4px 0 rgba(23,58,107,.16),
    inset 1px 0 0 rgba(23,58,107,.10),
    inset -1px 0 0 rgba(23,58,107,.14),
    inset 0 -26px 26px -22px rgba(23,58,107,.32),
    0 5px 0 -1px rgba(23,58,107,.16),
    0 9px 0 -2px rgba(23,58,107,.09),
    0 26px 34px -14px rgba(20,49,91,.46);
  z-index: 2;
}
/* The first piece has no neighbour on its left, so no socket, but the same lit dome. */
.piece:first-child {
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(255,255,255,.95), rgba(255,255,255,0) 55%),
    linear-gradient(158deg, #eef2f9 0%, #ffffff 34%, #d4ddec 100%);
}
/* Butted together, so one seam between neighbours instead of two borders. */
.piece + .piece { border-left: 0; }
/* Earlier pieces stack ABOVE later ones, or each piece's white body paints over
   the interlock tab reaching into it from its left, and the tabs come out sliced
   in half. The puzzle only reads if the tab sits on top of the piece it plugs into. */
.piece:nth-child(1) { z-index: 5; }
.piece:nth-child(2) { z-index: 4; }
.piece:nth-child(3) { z-index: 3; }
.piece:nth-child(4) { z-index: 2; }
.piece:first-child { border-radius: var(--r-md) 0 0 3px; }
.piece:last-child  { border-radius: 0 var(--r-md) 3px 0; }

/* The interlock. A tab on the right edge of every piece but the last, in that
   piece's own colour, sitting on the seam it shares with its neighbour. This is
   what makes them read as pieces of one puzzle rather than four cards in a row. */
.piece:not(:last-child)::before {
  content: ""; position: absolute; top: 50%; right: -14px; margin-top: -14px;
  width: 28px; height: 28px; border-radius: 50%;
  /* A raised knob, not a flat dot: a bright highlight toward the top-left, its own colour
     rounding away to a darker rim, ringed in white and casting a shadow into the socket
     it plugs into. */
  background: radial-gradient(circle at 33% 28%,
    color-mix(in srgb, var(--pa) 30%, #fff), var(--pa) 62%,
    color-mix(in srgb, var(--pa) 72%, #000) 100%);
  box-shadow: 0 3px 6px rgba(20,49,91,.38);
  z-index: 4;
}
.piece h4 { font-size: 16px; color: var(--navy); margin-bottom: 8px; }
.piece h4 em { font-style: normal; color: var(--pa); }
/* The question the product answers. This is the section's whole promise ("four
   questions"), so it leads the piece and carries the weight. */
.piece .q { font-size: 15px; line-height: 1.35; font-weight: 650; color: var(--navy); margin-bottom: 8px; }
.piece .when { font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--pa); margin-bottom: 8px; }
.piece .does { font-size: 13px; line-height: 1.55; color: var(--ink-soft); }

/* The plate the four pieces sit on. Its top edge is flush with their base. */
.baseplate {
  margin-top: 0; background: var(--navy); color: #fff;
  border-radius: 3px 3px var(--r-lg) var(--r-lg); padding: 30px 26px 24px;
  position: relative; z-index: 1;
}
/* The 2x2 and 1-col reflows below no longer line up with four sockets. Once the
   pieces stop tiling the stage they stop being a puzzle, so the tabs and the
   interlocks come off and they go back to being four separate cards, with their
   own borders and corners again. */
@media (max-width: 960px) {
  .baseplate { border-radius: var(--r-lg); margin-top: 14px; }
  .piece::before { display: none; }
  .piece,
  .piece + .piece { border: 1px solid var(--line); border-top: 4px solid var(--pa); border-radius: var(--r-md); }
}
.baseplate h4 { color: #fff; font-size: 15px; letter-spacing: .02em; }
.baseplate .rules { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 12px; }
.baseplate .rule { font-size: 13px; color: rgba(255,255,255,.72); line-height: 1.45; }
.baseplate .rule b { display: block; color: #7fd3e2; font-weight: 650; margin-bottom: 2px; font-size: 12px; letter-spacing: .05em; text-transform: uppercase; }

/* Default state = ASSEMBLED. Progressive enhancement only pulls them apart, so
   Firefox (no scroll-driven animation as of 2026), reduced-motion and print all
   get the finished diagram and nothing looks missing.
   Transform and opacity only, so this stays on the compositor. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .piece {
      animation: snap-in linear both;
      animation-timeline: view();
      animation-range: entry 45% cover 62%;
      will-change: transform, opacity;
    }
    .piece:nth-child(1) { --dx: -150px; --dy: -60px; --rot: -8deg; }
    .piece:nth-child(2) { --dx:  -60px; --dy: -110px; --rot:  6deg; }
    .piece:nth-child(3) { --dx:   70px; --dy: -100px; --rot: -5deg; }
    .piece:nth-child(4) { --dx:  160px; --dy: -50px;  --rot:  9deg; }
    .baseplate { animation: base-in linear both; animation-timeline: view(); animation-range: entry 5% cover 30%; }
  }
}
/* The overshoot at 78% is what makes it read as a snap instead of a slide:
   the piece drops slightly past its seat, then settles. */
@keyframes snap-in {
  from { transform: translate(var(--dx), var(--dy)) rotate(var(--rot)) scale(.96); opacity: 0; }
  78%  { transform: translate(0, -5px) rotate(0deg) scale(1.012); opacity: 1; }
  to   { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; }
}
@keyframes base-in {
  from { transform: translateY(36px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ---- Chooser (route, don't explain) ------------------------------------ */
.chooser { display: grid; gap: 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: #fff; box-shadow: var(--shadow-md); }
.chooser-row { display: grid; grid-template-columns: 1.35fr 1fr; gap: 24px; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--line-soft); transition: background .14s; }
.chooser-row:last-child { border-bottom: none; }
.chooser-row:hover { background: var(--bg-soft); text-decoration: none; }
.chooser-row:hover .ans { transform: translateX(3px); }
.chooser-row .ans { transition: transform .14s; }
.chooser-row .said { font-size: 16px; color: var(--ink); }
.chooser-row .said b { font-weight: 650; }
.chooser-row .ans { display: flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 650; color: var(--navy); justify-self: start; }
.chooser-row .ans img, .chooser-row .ans svg { width: 22px; height: 22px; flex: none; }

/* ---- Generic cards ----------------------------------------------------- */
.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: 1fr 1fr; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.card { background: #fff; border: 1px solid var(--line); border-radius: var(--r-md); padding: 26px; }
.card .num { font-size: 12px; font-weight: 700; color: var(--ink-mute); letter-spacing: .08em; font-variant-numeric: tabular-nums; margin-bottom: 10px; }
.card p { font-size: 15px; }

.caps { list-style: none; border-top: 1px solid var(--line); }
.caps li { padding: 20px 0; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 210px 1fr; gap: 30px; align-items: start; }
.caps strong { color: var(--navy); font-size: 15.5px; font-weight: 680; }
.caps span { color: var(--ink-soft); font-size: 15px; line-height: 1.55; }

.not-list { list-style: none; display: grid; gap: 11px; }
.not-list li { font-size: 15.5px; color: var(--ink-soft); padding-left: 26px; position: relative; }
.not-list li::before { content: ""; position: absolute; left: 0; top: 10px; width: 13px; height: 2px; background: var(--ink-mute); border-radius: 2px; }
.dark .not-list li { color: rgba(255,255,255,.78); }
.dark .not-list li::before { background: rgba(255,255,255,.45); }

/* ---- Screenshot frame -------------------------------------------------- */
.shot { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; box-shadow: var(--shadow-lg); background: #fff; }
.shot img { width: 100%; }
.shot-cap { font-size: 13px; color: var(--ink-faint); margin-top: 12px; text-align: center; }
.shot-cap b { color: var(--ink-soft); font-weight: 600; }

/* ---- The guided demo --------------------------------------------------- */
/* No overflow:hidden here. It makes this a scroll container, which silently disables
   position:sticky on the hint inside it, and the sticky hint is the only thing keeping
   the walkthrough's instruction on screen while the page scrolls to the control it is
   pointing at. The head and the foot round their own corners instead. */
.demo { border: 1px solid var(--line); border-radius: var(--r-lg); background: #fff; box-shadow: var(--shadow-md); }
.demo-head {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 16px 20px; background: var(--navy); color: #fff;
  border-radius: calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
}
.demo-head .dt { font-size: 14px; font-weight: 650; }
.demo-head .badge {
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  background: var(--orange); color: #2a1400; padding: 3px 8px; border-radius: 4px; font-weight: 700;
}
.demo-head .spacer { margin-left: auto; }
.demo-head .reset {
  background: rgba(255,255,255,.12); color: #fff; border: 1px solid rgba(255,255,255,.24);
  border-radius: 6px; padding: 6px 12px; font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit;
}
.demo-head .reset:hover { background: rgba(255,255,255,.2); }

/* the start-here bar: the user asked for this to be unmissable */
.demo-start {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 14px 20px; background: var(--accent-light); border-bottom: 1px solid var(--line);
}
.demo-start .step-n {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  background: var(--accent); color: #fff;
  display: grid; place-items: center; font-size: 13px; font-weight: 700;
}
.demo-start .txt { font-size: 15px; color: var(--ink); flex: 1; min-width: 260px; }
.demo-start .txt b { font-weight: 680; color: var(--navy); }
.demo-start .go {
  background: var(--accent); color: #fff; border: none; border-radius: var(--r-sm);
  padding: 9px 18px; font-size: 14px; font-weight: 650; cursor: pointer; font-family: inherit;
}
.demo-start .go:hover { background: var(--accent-deep); }
.demo-start .prog { font-size: 12px; font-weight: 650; color: var(--ink-mute); letter-spacing: .03em; font-variant-numeric: tabular-nums; }
/* Explore mode hides the step counter and progress; the author display values on
   these beat the UA [hidden] rule, so say it explicitly. */
.demo-start .step-n[hidden], .demo-start .prog[hidden] { display: none; }
/* In the live app, anything that navigates or toggles should invite the click. */
.app [data-goto]:not(.inert), .app [data-open], .app [data-configs],
.app [data-trust], .app [data-unk], .app [data-do] { cursor: pointer; }

.demo-body { position: relative; padding: 0; background: var(--bg-soft); min-height: 560px;
  display: flex; flex-direction: column; }
.demo-screen { display: none; padding: 22px; opacity: 0; transform: translateY(4px); }
.demo-screen.on { display: block; opacity: 1; transform: none; transition: opacity .18s ease, transform .18s ease; }

/* the coach-mark hint: tells the reader what to look at */
/* The hint sticks below the site header while the demo scrolls. The app frame is taller
   than a laptop viewport, so the control you are told to click is often further down the
   page than the sentence telling you to click it. Sticky keeps the instruction and the
   control on screen together, which is the only arrangement where the walkthrough works. */
.hint {
  position: sticky; top: 76px; z-index: 6;
  display: flex; gap: 12px; align-items: flex-start;
  margin: 0 22px 18px; padding: 13px 16px;
  background: #fff; border: 1px solid var(--accent); border-left: 4px solid var(--accent);
  border-radius: var(--r-sm); box-shadow: var(--shadow-sm);
}
/* An author display value beats the UA [hidden] rule on specificity, so the hidden
   idle hint would otherwise show. It never mattered before the hint was sticky: an
   empty box scrolled off with the rest. Sticky pins it to the top, in view. */
.hint[hidden] { display: none; }
.hint .icon { flex: none; width: 20px; height: 20px; color: var(--accent); margin-top: 1px; }
.hint .h-txt { font-size: 14.5px; color: var(--ink); line-height: 1.5; }
.hint .h-txt b { color: var(--navy); font-weight: 680; }
.hint .h-next {
  margin-left: auto; flex: none; align-self: center;
  background: var(--navy); color: #fff; border: none; border-radius: 6px;
  padding: 7px 14px; font-size: 13px; font-weight: 650; cursor: pointer; font-family: inherit; white-space: nowrap;
}
.hint .h-next:hover { background: var(--navy-soft); }
.hint .h-next[disabled] { opacity: .45; cursor: default; }

/* things the reader is meant to click, in the demo */
.tgt { position: relative; cursor: pointer; }
.tgt.live { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); border-radius: inherit; }
.tgt.live::after {
  content: ""; position: absolute; inset: -3px; border-radius: inherit;
  border: 2px solid var(--accent); animation: pulse 2.2s cubic-bezier(.4,0,.2,1) infinite; pointer-events: none;
}
@keyframes pulse { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.07); } }
@media (prefers-reduced-motion: reduce) { .tgt.live::after { animation: none; opacity: .6; } }

/* The end of the demo. This is peak intent, so it gets a real next step. */
.demo-done {
  margin: 0 22px 22px; padding: 22px 24px;
  background: var(--accent-light); border: 1px solid var(--accent);
  border-radius: var(--r-md);
}
.demo-done h3 { font-size: 19px; margin-bottom: 6px; }
.demo-done p { font-size: 15px; max-width: 62ch; }
.demo-done .btn-row { margin-top: 18px; }

/* inert controls: never a silent dead click */
/* Do NOT grey these out. Dimming half the UI shows a prospect a product that
   looks broken. The click still explains itself via the toast. */
.inert { cursor: default; }
.demo-note { padding: 12px 22px 20px; font-size: 12.5px; color: var(--ink-mute); text-align: center; }
.demo-toast {
  position: sticky; margin: 0 auto 16px; bottom: 16px; width: fit-content; z-index: 5;
  background: var(--navy); color: #fff; font-size: 13px; padding: 8px 16px; border-radius: var(--r-pill);
  box-shadow: var(--shadow-md); opacity: 0; pointer-events: none; transition: opacity .2s;
}
.demo-toast.on { opacity: 1; }

/* ---- App chrome inside the demo ----------------------------------------
   This is a reproduction of the real application shell, and the values are not
   invented: they are lifted from the product's own stylesheet (CrossScan ships
   its theme in app/ui/theme.py, and the four products share the palette). The
   rail is #14315b, the header carries the product's gradient, the footer carries
   the product's own read-only notice.

   The reason to be this literal: a buyer who runs the demo and then opens the
   product should recognise the screen. A prettier mock would be a lie with a
   long tail, because it sets an expectation the software then fails to meet. */
.app {
  position: relative;          /* the device-detail dialog covers the shell, as it does in the app */
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "hd hd" "nav main" "ft ft";
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: #eef1f5; min-height: 380px; font-size: 13px;
}
/* header ---------------------------------------------------------------- */
.app-hd {
  grid-area: hd;
  display: flex; align-items: center; gap: 10px; padding: 9px 14px;
  /* The product's own header runs a three-stop gradient across these navy-to-teal
     tones. This takes the middle stop flat. At 40px tall in an embedded frame the
     two are indistinguishable, and a flat colour is the house rule. */
  background: #12283a;
  color: #eef4f8;
}
.app-hd img { width: 22px; height: 22px; flex: none; border-radius: 5px; }
.app-hd .hd-name { font-weight: 700; font-size: 14px; }
.app-hd .hd-tag { font-size: 10.5px; color: rgba(238,244,248,.7); }
.app-hd .hd-badge {
  margin-left: auto; font-size: 10px; font-weight: 700; padding: 2.5px 7px;
  border-radius: 4px; background: #f2a33c; color: #2a1a04; white-space: nowrap;
}
/* rail ------------------------------------------------------------------- */
.app-nav { grid-area: nav; background: #14315b; color: #e9f0fb; padding: 12px 8px 14px; }
.app-nav .an-brand {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 2px 8px 14px; text-align: center;
}
.app-nav .an-brand img { width: 30px; height: 30px; }
.app-nav .an-brand .wm { font-size: 17px; font-weight: 700; color: #fff; }
.app-nav .an-brand .wm .c2 { color: #5cc8dd; }
.app-nav .an-brand .tag {
  font-size: 8px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: #aebfdb; line-height: 1.5;
}
.app-nav .an-grp {
  display: block; padding: 9px 10px 3px; text-transform: uppercase;
  letter-spacing: .1em; font-size: 9px; font-weight: 700; color: #aebfdb;
}
.app-nav .an-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 6px 10px; border-radius: 8px; border: 0; background: none;
  color: #aebfdb; font: inherit; font-size: 12.5px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.app-nav .an-item svg { width: 15px; height: 15px; flex: none; opacity: .9; }
.app-nav .an-item:hover { background: rgba(255,255,255,.10); color: #e9f0fb; }
.app-nav .an-item.sel { background: rgba(255,255,255,.17); color: #fff; }
.app-nav .an-item.inert { cursor: default; opacity: .55; }
.app-nav .an-item.inert:hover { background: none; color: #aebfdb; }
/* body + footer ---------------------------------------------------------- */
.app-main { grid-area: main; padding: 14px 16px; background: #eef1f5; overflow: auto; }
.app-ft {
  grid-area: ft; padding: 7px 14px; background: #fff; border-top: 1px solid var(--line);
  font-size: 10px; color: var(--ink-mute); line-height: 1.5;
}
.app-card {
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 12px;
}
.app-title { font-size: 15px; font-weight: 700; color: var(--navy); margin-bottom: 3px; }
.app-sub { font-size: 12px; color: var(--ink-faint); margin-bottom: 14px; }

/* Real form controls. Divs-dressed-as-inputs read as DISABLED, which makes the
   product look broken before the reader has even started. */
.app-label { display: block; font-size: 11px; color: var(--ink-faint); margin-bottom: 4px; font-weight: 500; }
.app-field {
  width: 100%; font: inherit; font-size: 13px; color: var(--ink);
  background: #fff; border: 1px solid #cfd6e2; border-radius: var(--r-sm);
  padding: 9px 11px;
  box-shadow: inset 0 1px 2px rgba(20,49,91,.06);
}
.app-field.mono { font-family: var(--mono); font-size: 12.5px; }
.app-field:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.app-hint { font-size: 11px; color: var(--ink-mute); margin-top: 5px; line-height: 1.45; }
.app-num { font-size: 11px; color: var(--ink-mute); margin-bottom: 4px; font-weight: 600; }

/* ---- CrossCheck's run form, the parts the reader is allowed to work ------
   The segmented control is the product's "How do you know the current firmware?"
   select, opened out so its three answers are visible without a click. Picking one
   changes which verdict the engine already computed gets shown, so a reader can
   watch the same change score 36 and then 60. */
.cform { display: grid; gap: 14px; max-width: 470px; }
.cform-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cform-go { display: flex; gap: 9px; align-items: center; margin-top: 2px; }
.cform-go .btn { padding: 10px 20px; font-size: 14px; }

.cseg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.cseg-b {
  display: flex; flex-direction: column; gap: 2px; text-align: left; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--ink-soft);
  background: #fff; border: 1px solid #cfd6e2; border-radius: var(--r-sm);
  padding: 8px 10px; line-height: 1.3; transition: border-color .12s, background .12s;
}
.cseg-b span { font-size: 10px; font-weight: 500; color: var(--ink-mute); }
.cseg-b:hover { border-color: var(--accent); }
.cseg-b.on {
  background: var(--accent-light); border-color: var(--accent); color: var(--accent-deep);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cseg-b.on span { color: var(--accent-deep); }

.csamp { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.csamp-h {
  font-size: 12px; font-weight: 700; color: var(--navy); cursor: pointer;
  list-style: none; display: flex; align-items: baseline; gap: 6px;
}
.csamp-h::-webkit-details-marker { display: none; }
.csamp-h::before { content: '\203A'; color: var(--accent); font-weight: 700; }
.csamp[open] .csamp-h { margin-bottom: 10px; }
.csamp[open] .csamp-h::before { content: '\2039'; }
.csamp-h span { font-weight: 500; color: var(--ink-mute); }
.csamp-g { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.csamp-c {
  display: block; text-align: left; cursor: pointer; font: inherit;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 10px 12px; transition: border-color .12s, transform .12s;
}
.csamp-c:hover { border-color: var(--accent); transform: translateY(-1px); }
.csamp-c.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.csamp-c b { display: block; font-size: 12.5px; color: var(--navy); margin-bottom: 3px; }
.csamp-c span { font-size: 11px; color: var(--ink-mute); line-height: 1.45; }
@media (max-width: 700px) {
  .cseg, .csamp-g { grid-template-columns: 1fr; }
}

table.g { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.g th {
  text-align: left; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 700; padding: 7px 8px; border-bottom: 1px solid var(--line);
}
table.g td { padding: 9px 8px; border-bottom: 1px solid var(--line-soft); color: var(--ink-soft); vertical-align: top; }
table.g tr:last-child td { border-bottom: none; }
table.g .dev { color: var(--ink); font-weight: 600; }
table.g .sub { display: block; color: var(--ink-mute); font-size: 11px; font-family: var(--mono); margin-top: 1px; }
table.g tr.row-click { cursor: pointer; }
table.g tr.row-click:hover td { background: var(--bg-soft); }

.pill {
  display: inline-block; font-size: 10.5px; font-weight: 650; padding: 2.5px 8px;
  border-radius: var(--r-pill); border: 1px solid; white-space: nowrap;
}
/* Pill TEXT is small, so it needs its own darker tone to clear AA (4.5:1).
   The --good/--fair tokens stay bright for fills and large numbers. */
.p-good { color: #1a6e48; border-color: color-mix(in srgb, var(--good) 40%, transparent); background: color-mix(in srgb, var(--good) 8%, transparent); }
.p-fair { color: #7d5a12; border-color: color-mix(in srgb, var(--fair) 40%, transparent); background: color-mix(in srgb, var(--fair) 8%, transparent); }
.p-poor { color: #a8500f; border-color: color-mix(in srgb, var(--poor) 40%, transparent); background: color-mix(in srgb, var(--poor) 8%, transparent); }
.p-bad  { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 40%, transparent);  background: color-mix(in srgb, var(--bad) 8%, transparent); }
.p-mute { color: var(--ink-mute); border-color: var(--line); background: var(--bg-soft); }

/* the big score + band, shared by CrossCheck and CrossRoom */
.verdict { display: flex; align-items: center; gap: 22px; padding: 18px; border: 1px solid var(--line); border-radius: 10px; background: #fff; box-shadow: var(--shadow-md); }
.verdict .ring { flex: none; width: 104px; height: 104px; position: relative; }
.verdict .ring svg { width: 104px; height: 104px; transform: rotate(-90deg); }
.verdict .ring .rv { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; }
.verdict .ring .rv b { display: block; font-size: 30px; font-weight: 700; color: var(--navy); line-height: 1; }
.verdict .ring .rv span { font-size: 9px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-mute); }
.verdict .vmeta { flex: 1; min-width: 0; }
.verdict .vchange { font-size: 10px; font-family: var(--mono); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 5px; }
.verdict .vband { font-size: 25px; font-weight: 700; line-height: 1.1; margin-bottom: 4px; }
.verdict .vscale { font-size: 11.5px; color: var(--ink-faint); font-family: var(--mono); }
.verdict .vsay { font-size: 14px; color: var(--ink); margin-top: 7px; font-weight: 600; }
.verdict .vfid { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 11.5px; color: var(--ink-faint); }
.verdict .vfid .bar { width: 90px; height: 5px; border-radius: 3px; background: var(--line); overflow: hidden; }
.verdict .vfid .bar i { display: block; height: 100%; background: var(--accent); }

.finding { border: 1px solid var(--line); border-radius: var(--r-md); padding: 13px 15px; margin-top: 10px; background: #fff; }
.finding .fh { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.finding .ft { font-size: 13.5px; font-weight: 680; color: var(--navy); }
.finding .prov { margin-left: auto; font-size: 9.5px; font-family: var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute); }
.finding .fd { font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
.finding .fix { font-size: 12.5px; color: var(--ink); margin-top: 6px; }
.finding .fix b { color: var(--accent-deep); }
.cli {
  font-family: var(--mono); font-size: 11.5px; background: #0d1b2f; color: #cfe3f2;
  padding: 10px 12px; border-radius: 6px; margin-top: 8px; overflow-x: auto; line-height: 1.6;
}
.cli .c { color: #7fd3e2; }

/* ---- Footer ------------------------------------------------------------ */
.site-footer { background: var(--navy); color: rgba(255,255,255,.62); padding: 56px 0 30px; font-size: 14px; }
.site-footer p { color: rgba(255,255,255,.62); }
.footer-top { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: 40px; padding-bottom: 34px; border-bottom: 1px solid rgba(255,255,255,.13); }
.site-footer h4 { color: #fff; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; margin-bottom: 14px; }
.site-footer ul { list-style: none; display: grid; gap: 9px; }
.site-footer a { color: rgba(255,255,255,.72); }
.site-footer a:hover { color: #fff; }
.site-footer .blurb { max-width: 42ch; line-height: 1.6; }
.site-footer .site-privacy { margin-top: 12px; font-size: 12.5px; color: rgba(255,255,255,.5); }
.footer-bottom { padding-top: 22px; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 13px; color: rgba(255,255,255,.6); }
.footer-bottom .legal a { color: rgba(255,255,255,.66); }
.footer-bottom .legal a:hover { color: #fff; }

/* ---- Compatibility spec tables ----------------------------------------- */
/* The spec tables carry the whole compatibility page, so they get lifted off it:
   a bordered, shadowed card with a tinted header band and quiet zebra rows,
   rather than hairline rules floating on white. */
.spec-wrap {
  overflow-x: auto; margin: 22px 0 8px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-md); background: #fff;
}
table.spec { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 640px; }
table.spec th, table.spec td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.spec thead th {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute);
  font-weight: 700; border-bottom: 1px solid var(--line); white-space: nowrap;
  background: var(--bg-soft);
}
table.spec tbody th { font-weight: 650; color: var(--ink); white-space: nowrap; }
table.spec tbody tr:nth-child(even) { background: color-mix(in srgb, var(--bg-soft) 50%, #fff); }
table.spec tbody tr:hover { background: var(--accent-light); }
table.spec td { color: var(--ink-soft); line-height: 1.55; }
table.spec .mono { font-family: var(--mono); font-size: 12.5px; }
table.spec tr:last-child td, table.spec tr:last-child th { border-bottom: 0; }
.yes { color: var(--good); font-weight: 700; }
.no  { color: var(--ink-mute); }
.spec-note { font-size: 13px; color: var(--ink-mute); line-height: 1.6; margin-top: 10px; }
.tier {
  display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; padding: 3px 8px; border-radius: var(--r-pill); white-space: nowrap;
}
.tier-1 { background: #e4f4f7; color: #0d7180; }
.tier-2 { background: #eef2f7; color: #46536e; }
.tier-3 { background: #fbf0dd; color: #7d5a12; }
.anchors { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.anchors a {
  font-size: 13px; padding: 7px 13px; border: 1px solid var(--line); border-radius: var(--r-pill);
  text-decoration: none; color: var(--ink-soft); background: #fff;
}
.anchors a:hover { border-color: var(--teal); color: var(--teal-deep); }

/* ---- 404 --------------------------------------------------------------- */
.nf { text-align: center; padding: 96px 0 110px; }
.nf .code { font-family: var(--mono); font-size: 13px; letter-spacing: .12em; color: var(--ink-mute); text-transform: uppercase; font-weight: 700; }
.nf h1 { font-size: 34px; margin: 14px 0 12px; }
.nf .lede { max-width: 54ch; margin: 0 auto 34px; }
.nf-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; text-align: left; margin-bottom: 34px; }
.nf-grid a {
  display: block; padding: 16px 18px; background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-md); text-decoration: none; transition: border-color .12s ease, transform .12s ease;
}
.nf-grid a:hover { border-color: var(--pa, var(--teal)); transform: translateY(-2px); }
.nf-grid b { display: block; color: var(--ink); font-size: 14.5px; margin-bottom: 3px; }
.nf-grid span { display: block; font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
@media (max-width: 780px) { .nf-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .nf-grid { grid-template-columns: 1fr; } }

/* ---- Responsive -------------------------------------------------------- */
@media (max-width: 960px) {
  h1 { font-size: 36px; }
  .hero-product h1 { font-size: 32px; }
  h2 { font-size: 28px; }
  .hero, section { padding: 56px 0; }
  .hero-split { grid-template-columns: 1fr; gap: 36px; }
  .piecegrid { grid-template-columns: 1fr 1fr; gap: 12px; }
  .baseplate .rules { grid-template-columns: 1fr; gap: 14px; }
  .grid-3 { grid-template-columns: 1fr 1fr; }
  .footer-top { grid-template-columns: 1fr 1fr; }
  /* Never animate the assembly on small screens: the layout reflows to 2x2. */
  .piece { animation: none !important; transform: none !important; opacity: 1 !important; }
}

@media (max-width: 760px) {
  .nav {
    display: none; position: absolute; top: 68px; left: 0; right: 0;
    background: #fff; border-bottom: 1px solid var(--line);
    flex-direction: column; align-items: stretch; gap: 0; padding: 8px 28px 18px;
  }
  .nav.open { display: flex; }
  .nav a:not(.btn) { padding: 12px 0; border-bottom: 1px solid var(--bg-warm); }
  .nav .btn { margin-top: 10px; justify-content: center; }
  .nav-toggle { display: block; }
  .pcards, .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .piecegrid { grid-template-columns: 1fr; }
  .caps li { grid-template-columns: 1fr; gap: 6px; }
  .chooser-row { grid-template-columns: 1fr; gap: 10px; }
  .app { grid-template-columns: 1fr; }
  .app-nav { display: none; }
  .verdict { flex-direction: column; align-items: flex-start; }
  .lede, .hero .lede { font-size: 18px; }
  .footer-top { grid-template-columns: 1fr; gap: 28px; }
  .demo-body { min-height: 0; }
  .hint { flex-wrap: wrap; }
  .hint .h-next { margin-left: 0; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::after, *::before { animation: none !important; transition: none !important; }
  .piece { transform: none !important; opacity: 1 !important; }
}

/* The assembly must never print (or export) as an empty box. If the scroll
   timeline is not running for any reason, show the finished diagram. */
@media print {
  .piece, .baseplate { animation: none !important; transform: none !important; opacity: 1 !important; }
  .site-header, .nav, .demo-start, .hint { display: none !important; }
}

/* The comparison table stacks on phones. Three columns at 348px is unreadable,
   so each row becomes a card and each cell announces which product it is. */
@media (max-width: 760px) {
  /* width:auto, not 100%: a 100% width plus horizontal margins overflows. */
  .compare, .compare tbody, .compare tr, .compare th, .compare td { display: block; width: auto; }
  .compare thead { display: none; }
  .compare tr { border-bottom: 1px solid var(--line); padding: 4px 0 10px; }
  .compare tr:last-child { border-bottom: none; }
  .compare tbody th {
    width: 100%; font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
    color: var(--ink-mute); font-weight: 700; padding: 16px 18px 4px; border: none;
  }
  .compare td { border: none; padding: 8px 18px; position: relative; }
  .compare td[data-p]::before {
    content: attr(data-p);
    display: block; font-size: 11px; font-weight: 700; letter-spacing: .04em;
    margin-bottom: 3px;
  }
  .compare td[data-p="CrossScan"]::before    { color: #0d7180; }
  .compare td[data-p="CrossConnect"]::before { color: #215389; }
  .compare td[data-p="CrossScan"]    { border-left: 3px solid #1596a5; margin: 0 18px 6px; padding: 8px 0 8px 12px; }
  .compare td[data-p="CrossConnect"] { border-left: 3px solid #2f6fb0; margin: 0 18px 6px; padding: 8px 0 8px 12px; }
  .compare td[colspan] { padding: 8px 18px 14px; }
}

/* ---------------------------------------------------------------------------
   The explorable demo. The guided story runs on top of this; underneath it, the
   whole scan is here to be poked at. Every row and every evidence line is real
   output from the product (assets/data/*.js, built by bin/build-demo-data.py),
   so this is the one part of the site that cannot drift from what ships.
   --------------------------------------------------------------------------- */
.ex-bar { display: flex; align-items: center; gap: 6px; margin: 10px 0 6px; flex-wrap: wrap; }
.ex-chip {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--ink-mute);
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px 12px; cursor: pointer;
}
.ex-chip:hover { border-color: var(--accent); color: var(--accent); }
.ex-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.ex-chip b { font-weight: 700; opacity: .7; margin-left: 2px; }
.ex-count { margin-left: auto; font-size: 12px; color: var(--ink-mute); }
.ex-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }

/* The reason a device stayed unknown, in the product's own words, one line per row. */
.unk-why { font-size: 12px; color: var(--ink-soft); line-height: 1.5; max-width: 420px; }

/* The scan is 43 rows. Give it a window rather than a page. */
.ex-scroll { max-height: 340px; overflow-y: auto; border: 1px solid var(--line-soft); border-radius: var(--r-sm); }
.ex-scroll thead th { position: sticky; top: 0; background: #fff; z-index: 1; }

/* Dashboard tiles. Every number is read out of result.summary(), the same call
   the product's own Dashboard makes. */
.ex-tiles { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.ex-tile {
  flex: 1 1 96px; background: #fff; border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 12px; text-align: center;
}
.ex-tile b { display: block; font-size: 22px; font-weight: 700; color: var(--navy); line-height: 1.15; }
.ex-tile span { font-size: 10.5px; color: var(--ink-mute); }
.ex-tile.t-good b { color: #1a6e48; }
.ex-tile.t-info b { color: #1d5fa8; }
.ex-tile.t-warn b { color: #a8500f; }
.ex-tile.t-note b { color: #6b3fa0; }
.ex-h { font-size: 11.5px; font-weight: 700; color: var(--ink-soft); margin: 12px 0 6px; }
.ex-src { font-size: 10px; color: var(--ink-faint); line-height: 1.5; margin-top: 8px; }

/* Port map. The columns are the app's columns, in the app's order. */
.ex-port { font-family: var(--mono); font-size: 11.5px; color: var(--ink); }
.ex-port small { display: block; font-size: 10px; color: var(--ink-faint); }
.ex-role {
  display: inline-block; font-size: 10px; font-weight: 650; padding: 1.5px 6px;
  border: 1px solid var(--line); border-radius: 4px; color: var(--ink-mute); white-space: nowrap;
}
.ex-role.r-link { color: #6b3fa0; border-color: color-mix(in srgb, #6b3fa0 35%, transparent); }
.ex-conf { font-size: 12px; font-weight: 650; white-space: nowrap; }
.c-good { color: #1a6e48; } .c-fair { color: #7d5a12; } .c-mute { color: var(--ink-faint); }
.ex-sub2 { display: block; font-size: 10.5px; color: var(--ink-faint); }
.ex-ev {
  font-size: 10.5px; color: var(--ink-faint);
  max-width: 210px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Nine columns of real data need the room. Let the table scroll rather than crushing
   the device names into two characters a line. */
.ex-scroll table.g { min-width: 860px; }
.ex-scroll { overflow-x: auto; }

/* Device detail. In the product this is a dialog over the port map, so it is a
   dialog here too. Same badges, same narrative block, same evidence rows. */
.ev-panel {
  position: absolute; inset: 0; z-index: 5;
  background: rgba(15,26,40,.45); padding: 18px;
  display: flex; align-items: flex-start; justify-content: center; overflow: auto;
}
/* `display:flex` above beats the `hidden` attribute's `display:none`, so the dialog
   scrim sits over the whole app dimming it, even when it is supposed to be closed. */
.ev-panel[hidden] { display: none; }
.ev-dlg {
  width: 100%; max-width: 620px; background: #fff; border-radius: 10px;
  padding: 16px 18px; box-shadow: 0 18px 44px rgba(10,20,35,.3);
}
.ev-top { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 10px; }
.ev-top > div:first-child { flex: 1; }
.ev-close {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--ink-mute);
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 5px 11px; cursor: pointer;
}
.ev-close:hover { color: var(--navy); border-color: var(--navy); }
/* The engine's own sentence, printed the way the product prints it: monospace,
   because it is output, not prose. */
.ev-why-block {
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 6px;
  padding: 10px 12px; margin-bottom: 12px; font-family: var(--mono);
  font-size: 11px; line-height: 1.65; color: var(--ink-soft); white-space: pre-wrap;
}
.ev-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 6px; }
.ev-cols h4 { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; font-size: 12px; }
.kv { display: flex; gap: 8px; font-size: 11px; padding: 1.5px 0; }
.kv b { flex: none; width: 96px; color: var(--ink-faint); font-weight: 500; }
.kv span { color: var(--ink-soft); word-break: break-word; }

.ev { list-style: none; margin: 0; padding: 0; }
.ev li { display: flex; gap: 10px; padding: 7px 0; border-top: 1px solid var(--line-soft); }
.ev li:first-child { border-top: 0; }
.ev-pts {
  flex: none; width: 34px; font-family: var(--mono); font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ev-pts.up { color: #1a6e48; } .ev-pts.down { color: var(--bad); } .ev-pts.zero { color: var(--ink-faint); }
/* The engine's own reasoning, in its own words. This is the whole point of the panel. */
.ev-why { font-size: 12px; line-height: 1.5; color: var(--ink-soft); margin: 0; }
/* The raw fact underneath the sentence: which MIB field said it, and what it said. */
.ev-raw { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); margin: 1px 0 0; word-break: break-all; }
.ev-next { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--line); font-size: 12px; }

/* Network Map. The SVG is the product's own render, so it is given room and left
   alone: no restyling, no recolouring. It scrolls if it is bigger than the frame. */
.ex-map {
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  padding: 10px; max-height: 420px; overflow: auto;
}
.ex-map svg { display: block; width: 100%; height: auto; }

.ex-search { flex: 1; min-width: 180px; max-width: 340px; font-size: 12px; padding: 6px 10px; }

/* Rooms. One card per room group, with the evidence that inferred it. */
.rm-card { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; margin-bottom: 10px; }
.rm-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.rm-head b { font-size: 14px; color: var(--navy); }
.rm-head .n { font-size: 11px; color: var(--ink-mute); }
.rm-meta { font-size: 10.5px; color: var(--ink-faint); font-family: var(--mono); margin-bottom: 8px; }
.rm-ev { margin-top: 8px; }
.rm-ev summary { cursor: pointer; font-size: 11.5px; font-weight: 600; color: var(--accent); }
.rm-ev .ev { margin-top: 8px; }

@media (max-width: 720px) {
  .ev-cols { grid-template-columns: 1fr; }
}

/* ---- The CrossCheck verdict page ---------------------------------------
   The verdict is one page you scroll, exactly as it is in the product. The
   severity tones are the engine's own (it hands us amber / rose / orange /
   sky / slate on every finding), mapped onto the shared status palette so a
   No-Go here is the same red as a Bad meeting on the CrossRoom page. */
:root {
  --sv-rose: var(--bad);
  --sv-orange: var(--poor);
  --sv-amber: var(--fair);
  --sv-sky: #2f6fb0;
  --sv-slate: var(--ink-mute);
  /* The engine names a Go emerald. Without this the ring stays red on a verdict the
     reader has just earned, which would be the site calling the product a liar. */
  --sv-emerald: var(--good);
}

.vwarn {
  background: #fdf6e6; border: 1px solid #f0dcae; color: #7a5a10;
  border-radius: var(--r-sm); padding: 10px 13px; font-size: 13px; margin-bottom: 16px;
}
.vwarn b { color: #6b4f0c; }

.vsec { padding: 18px 0; border-top: 1px solid var(--line-soft); scroll-margin-top: 14px; }
.vsec:first-of-type { border-top: 0; padding-top: 4px; }
/* The lit section is the one the walkthrough is talking about. */
.vsec.lit {
  background: var(--accent-light); border-radius: var(--r-sm);
  box-shadow: 0 0 0 10px var(--accent-light); margin: 6px 0;
}
.vh { font-size: 15px; font-weight: 700; color: var(--navy); margin-bottom: 12px; }
.vh-s { font-weight: 500; font-size: 12.5px; color: var(--ink-mute); margin-left: 8px; }

.vhead { display: flex; gap: 22px; align-items: center; }
.vgauge { position: relative; flex: 0 0 auto; width: 108px; height: 108px; }
.vg { width: 108px; height: 108px; display: block; }
.vg-num {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; line-height: 1;
}
.vg-num b { font-size: 30px; font-weight: 750; color: var(--navy); }
.vg-num span { font-size: 10.5px; color: var(--ink-mute); margin-top: 3px; }
.vwhat { min-width: 0; }
.vband {
  display: inline-block; font-size: 17px; font-weight: 750; color: #fff;
  padding: 3px 12px; border-radius: 5px; background: var(--sv-slate);
}
.vband.sv-rose { background: var(--bad); }
.vband.sv-amber { background: var(--fair); }
.vband.sv-emerald { background: var(--good); }
.vthresh { font-size: 12px; color: var(--ink-mute); margin: 8px 0 10px; }
.vgap {
  margin-left: 8px; background: var(--bg-warm); color: var(--ink-soft);
  padding: 2px 7px; border-radius: 4px; font-weight: 650;
}
.vline { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; margin-top: 5px; }
.vline b { color: var(--navy); }

.vfind { padding: 11px 0; border-bottom: 1px dashed var(--line-soft); }
.vfind:last-child { border-bottom: 0; }
.vfind-t { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.vfind-t b { font-size: 14px; color: var(--navy); }
.sv {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: #fff; padding: 2px 7px; border-radius: 4px; background: var(--sv-slate);
}
.sv-rose { background: var(--sv-rose); } .sv-orange { background: var(--sv-orange); }
.sv-amber { background: var(--sv-amber); } .sv-sky { background: var(--sv-sky); }
.sv-emerald { background: var(--sv-emerald); }
.vprov {
  font-size: 10.5px; color: var(--ink-mute); border: 1px solid var(--line);
  padding: 1px 6px; border-radius: 4px;
}
/* Every check it ran, including the ones it could not. This is the "show your work"
   panel, and it is the reason the score is worth reading. */
.vchecks { display: grid; gap: 2px; }
.vchk {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; background: #fff; border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
}
.vchk .sv { flex: none; margin-top: 1px; }
.vchk-b { min-width: 0; }
.vchk-b b { font-size: 13px; color: var(--navy); }
.vchk-f {
  font-size: 10px; color: var(--ink-mute); text-transform: uppercase;
  letter-spacing: .06em; margin-left: 7px;
}
.vchk-b p { font-size: 12.5px; color: var(--ink-soft); line-height: 1.55; margin-top: 4px; }
.vchk-c { color: var(--ink-mute) !important; font-weight: 600; }

/* The change window. */
.vroll-h {
  font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-mute); margin: 16px 0 8px;
}
.vroll { margin: 0 0 4px; padding-left: 18px; }
.vroll li { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; margin-bottom: 4px; }

/* The knowledge base behind every finding. */
.vkb { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 16px 0 4px; }
.vkb-n {
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 14px 14px 12px;
}
.vkb-n b {
  display: block; font-size: 26px; font-weight: 800; color: var(--navy);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.vkb-n span { font-size: 11px; color: var(--ink-mute); display: block; margin-top: 5px; }
.vkb-v { display: flex; flex-wrap: wrap; gap: 5px; }
.vkb-c {
  font-size: 11.5px; color: var(--ink-soft); background: #fff;
  border: 1px solid var(--line); border-radius: 20px; padding: 3px 10px;
}
@media (max-width: 700px) { .vkb { grid-template-columns: repeat(2, 1fr); } }

/* How-it-works: one card per check, showing the rule and the Go / No-go line. */
.vmeth {
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 13px 15px; margin-bottom: 10px;
}
.vmeth-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.vmeth-h b { font-size: 13.5px; color: var(--navy); }
.vmeth-id {
  font-size: 11px; color: var(--ink-mute); font-variant-numeric: tabular-nums;
  white-space: nowrap; letter-spacing: .02em;
}
.vmeth-rule { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; margin: 6px 0 9px; }
.vmeth-in { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-bottom: 10px; }
.vmeth-inl {
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-mute); margin-right: 2px;
}
.vmeth-gb { display: grid; gap: 6px; }
.vmeth-g, .vmeth-b {
  font-size: 12px; color: var(--ink-soft); line-height: 1.55;
  display: flex; gap: 8px; align-items: baseline;
}
.vmeth-g .sv, .vmeth-b .sv { flex: none; }

.vfind-d { font-size: 13px; color: var(--ink-soft); line-height: 1.6; margin-top: 6px; }
.vfind-f { font-size: 13px; color: var(--ink-soft); line-height: 1.6; margin-top: 5px; }
.vfind-f b { color: var(--navy); }

.vimp { padding: 10px 0; border-bottom: 1px dashed var(--line-soft); }
.vimp:last-child { border-bottom: 0; }
.vimp b { font-size: 13.5px; color: var(--navy); }
.vimp p { font-size: 13px; color: var(--ink-soft); line-height: 1.6; margin-top: 4px; }
.vimp-m { font-size: 12.5px; color: var(--ink-soft); margin-top: 3px; }
.vimp-m span { font-weight: 650; color: var(--navy); }

.vsteps { margin: 0 0 14px 18px; }
.vsteps li { font-size: 13px; color: var(--ink-soft); line-height: 1.6; margin-bottom: 10px; }
.vsteps li b { color: var(--navy); font-size: 13.5px; }

.vcfg { background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--r-sm); padding: 13px 15px; }
.vcfg-h { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.vcfg-h b { font-size: 13px; color: var(--navy); }
.vcfg-k {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  background: var(--accent-light); color: var(--accent-deep); padding: 2px 7px; border-radius: 4px;
}
.vcfg-l { margin: 0 0 10px 18px; }
.vcfg-l li { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; margin-bottom: 4px; }
.vcfg-m { font-size: 12.5px; color: var(--ink-soft); margin-top: 3px; }
.vcfg-m span { font-weight: 650; color: var(--navy); }
.vcfg-s { font-size: 11.5px; color: var(--ink-mute); margin-top: 9px; }
.vadv { font-size: 12.5px; color: var(--ink-mute); margin-top: 11px; font-style: italic; }

.vledger { width: 100%; border-collapse: collapse; }
.vledger td { padding: 8px 0; font-size: 13px; color: var(--ink-soft); border-bottom: 1px solid var(--line-soft); }
.vledger td.n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 650; color: var(--navy); white-space: nowrap; }
.vledger .vl-n { display: block; font-size: 11.5px; color: var(--ink-mute); margin-top: 2px; }
.vledger tr.bind td { background: #fdf6e6; }
.vledger tr.bind td.n { color: var(--fair); }
.vledger tr.inert-row td { color: var(--ink-mute); }
.vledger tr.tot td { border-bottom: 0; padding-top: 11px; font-weight: 700; color: var(--navy); font-size: 14px; }

@media (max-width: 640px) {
  .vhead { flex-direction: column; align-items: flex-start; gap: 14px; }
}

/* CrossCheck's verdict is a long page, and in the product you scroll it inside the
   app window. Without a fixed height the frame just grows to fit, the reader gets a
   3,000px wall, and the walkthrough has nothing to scroll. So the app gets a window. */
.app[data-app="check"] { height: 580px; }
.app[data-app="check"] .app-main { scroll-behavior: smooth; }
@media (max-width: 640px) { .app[data-app="check"] { height: 520px; } }

/* ---- The CrossRoom screens ---------------------------------------------
   The band colours are the product's own AA-fixed pill shades, so a Fair here
   is the Fair a user sees in the software. */
.app[data-app="room"] { height: 580px; }

.rlede {
  background: var(--accent-light); border-left: 3px solid var(--accent);
  padding: 10px 13px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 13px; color: var(--ink-soft); margin: 12px 0 16px;
}
.rlede b { color: var(--navy); }

/* Section subheading between two grouped tables (Hotspots). */
.rgrp {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-mute); margin: 18px 0 8px;
}
.rgrp:first-of-type { margin-top: 4px; }

/* Far-end: the direction picture. This room clean, inbound degraded, far end at fault. */
.rfe {
  display: flex; align-items: stretch; gap: 10px; margin: 14px 0 18px; flex-wrap: wrap;
}
.rfe-node {
  flex: 1; min-width: 150px; background: #fff; border: 1px solid var(--line);
  border-radius: 8px; padding: 12px 14px; display: flex; flex-direction: column; gap: 4px;
}
.rfe-node.bad { border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); background: color-mix(in srgb, var(--bad) 5%, #fff); }
.rfe-node b { font-size: 15px; color: var(--navy); }
.rfe-k { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute); }
.rfe-s { font-size: 12px; color: var(--ink-soft); }
.rfe-s.good { color: #1a7d50; font-weight: 650; }
.rfe-node.bad .rfe-s { color: var(--bad); font-weight: 600; }
.rfe-arrow {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; min-width: 92px; color: var(--accent-deep);
}
.rfe-arrow span { font-size: 10px; font-weight: 650; letter-spacing: .03em; }
.rfe-arrow svg { width: 80px; height: 20px; }
@media (max-width: 640px) {
  .rfe-arrow { transform: rotate(90deg); min-width: 0; height: 32px; }
}

.rtab { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; }
.rtab th {
  text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-mute); padding: 9px 11px;
  border-bottom: 1px solid var(--line); background: var(--bg-soft);
}
.rtab td { padding: 9px 11px; border-bottom: 1px solid var(--line-soft); font-size: 12.5px; color: var(--ink-soft); vertical-align: middle; }
.rtab tr:last-child td { border-bottom: 0; }
.rtab td b { color: var(--navy); font-size: 13px; display: block; }
.rsub { font-size: 11px; color: var(--ink-mute); }
.rroom { color: var(--ink-mute); }
.rtab tr[data-open] { cursor: pointer; }
.rtab tr[data-open]:hover { background: var(--accent-light); }
.ropen { color: var(--accent-deep); font-weight: 650; white-space: nowrap; }
.rcause { font-weight: 600; color: var(--ink); }
.rnone { color: var(--ink-mute); font-weight: 400; }
.rscore { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--navy); }

.rpill {
  display: inline-block; font-size: 10px; font-weight: 700; text-transform: capitalize;
  color: #fff; padding: 2px 8px; border-radius: var(--r-pill);
}
.rpill.b-good { background: #1a7d50; } .rpill.b-fair { background: #8a6414; }
.rpill.b-poor { background: #a8501c; } .rpill.b-bad, .rpill.b-failed { background: #b23127; }

.reyebrow {
  display: block; font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent-deep); margin-bottom: 4px;
}
.rhd { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.rstage { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 12px; margin: 14px 0; }
.rtrace { width: 100%; height: auto; display: block; }
.rax { font-size: 9px; fill: var(--ink-mute); }
.rtrans { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.rplay {
  width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--line);
  background: #fff; color: var(--navy); cursor: pointer; font-size: 11px; flex: none;
}
.rbar { flex: 1; height: 4px; background: var(--bg-warm); border-radius: 2px; overflow: hidden; }
.rbar i { display: block; height: 100%; background: var(--accent); }
.rtime { font-size: 11px; color: var(--ink-mute); white-space: nowrap; }
.rjump {
  font-size: 11.5px; font-weight: 650; padding: 5px 11px; border-radius: var(--r-sm);
  border: 1px solid var(--accent); background: #fff; color: var(--accent-deep); cursor: pointer;
  white-space: nowrap;
}
.rjump:hover { background: var(--accent-light); }
.rback { display: flex; gap: 8px; margin-top: 16px; }

.rnow { display: grid; grid-template-columns: 150px 1fr; gap: 14px; }
.rnow-l, .rnow-r { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; }
.rmos { display: flex; align-items: baseline; gap: 5px; margin: 4px 0; }
.rmos b { font-size: 30px; font-weight: 750; color: var(--navy); line-height: 1; }
.rmos.b-poor b, .rmos.b-bad b { color: var(--bad); }
.rmos span { font-size: 11px; color: var(--ink-mute); }
.rcap { font-size: 10.5px; color: var(--ink-mute); line-height: 1.45; }
.rmeters { display: grid; gap: 7px; margin-top: 6px; }
.rmeter { display: grid; grid-template-columns: 96px 1fr 58px; align-items: center; gap: 9px; }
.rml { font-size: 11.5px; color: var(--ink-soft); }
.rmb { height: 6px; background: var(--bg-warm); border-radius: 3px; overflow: hidden; }
.rmb i { display: block; height: 100%; background: var(--accent); }
.rmb i.hot { background: var(--bad); }
.rmv { font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--navy); font-weight: 650; text-align: right; }

.rmoment { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; margin-top: 14px; }
.rmoment.bad { border-color: #e8b3ad; background: #fdf3f2; }
.rmk {
  display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-mute); margin-bottom: 5px;
}
.rmoment.bad .rmk { color: var(--bad); }
.rmoment p { font-size: 13px; color: var(--ink-soft); line-height: 1.6; }
.rmoment b { color: var(--navy); }

.rthesis { background: #fff; border-left: 3px solid var(--bad); border-radius: 0 8px 8px 0; padding: 12px 14px; margin: 12px 0 16px; }
.rthesis b { font-size: 16px; color: var(--navy); }
.rconf { font-size: 10.5px; color: var(--ink-mute); margin-left: 8px; text-transform: uppercase; letter-spacing: .05em; font-weight: 650; }
.rthesis p { font-size: 13px; color: var(--ink-soft); margin-top: 5px; line-height: 1.6; }

.rfive { display: grid; grid-template-columns: 62px 1fr; gap: 8px 14px; }
.rfive dt { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--accent-deep); padding-top: 2px; }
.rfive dd { font-size: 13px; color: var(--ink-soft); line-height: 1.6; }

@media (max-width: 640px) {
  .app[data-app="room"] { height: 520px; }
  .rnow { grid-template-columns: 1fr; }
  .rroom, .rtab th:nth-child(2) { display: none; }
}

/* ---- The CrossConnect screens ------------------------------------------ */
.app[data-app="connect"] { height: 580px; }

.ctiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 14px 0 20px; }
.ctile { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; }
.ctile b { display: block; font-size: 24px; font-weight: 750; color: var(--navy); line-height: 1.1; }
.ctile span { font-size: 11px; color: var(--ink-mute); }

.ch { font-size: 14px; font-weight: 700; color: var(--navy); margin: 18px 0 10px; }
.ch-s { font-weight: 500; font-size: 12px; color: var(--ink-mute); margin-left: 7px; }

.ccrit {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  padding: 2px 7px; border-radius: 4px; color: #fff; background: var(--ink-mute);
}
.ccrit.c-critical { background: var(--bad); }
.ccrit.c-high { background: var(--poor); }
.ccrit.c-normal { background: var(--sv-sky); }
.ccrit.c-low { background: var(--ink-mute); }

.rtab td.n, .rtab th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.cverd { display: flex; gap: 16px; align-items: center; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; margin: 14px 0; }
.cverd.bad { border-color: #e8b3ad; background: #fdf3f2; }
.cverd.unknown { border-color: #d9c48f; background: #fbf6e8; }
.cverd-l { flex: 0 0 auto; }
.cbad {
  display: inline-block; font-size: 14px; font-weight: 750; color: #fff;
  background: var(--bad); padding: 3px 11px; border-radius: 5px;
}
.cwarn {
  display: inline-block; font-size: 12px; font-weight: 700; color: #fff;
  background: var(--ink-mute); padding: 3px 10px; border-radius: 5px;
  text-transform: uppercase; letter-spacing: .05em;
}

/* Running-config collection: the one control the reader owns on the Black Box screen. */
.ctoggle {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding: 12px 14px; margin: 14px 0;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px;
}
.ctoggle-l { font-size: 12.5px; font-weight: 650; color: var(--navy); }
.cseg2 { display: flex; gap: 6px; }
.cseg2-b {
  display: flex; flex-direction: column; gap: 1px; text-align: left; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 650; color: var(--ink-soft);
  background: #fff; border: 1px solid #cfd6e2; border-radius: var(--r-sm);
  padding: 6px 12px; line-height: 1.25; transition: border-color .12s, background .12s;
}
.cseg2-b span { font-size: 10px; font-weight: 500; color: var(--ink-mute); }
.cseg2-b:hover { border-color: var(--accent); }
.cseg2-b.on {
  background: var(--accent-light); border-color: var(--accent); color: var(--accent-deep);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cseg2-b.on span { color: var(--accent-deep); }
.cverd-l b { display: block; font-size: 13px; color: var(--navy); margin-top: 6px; }
.cverd-r p { font-size: 13px; color: var(--ink-soft); line-height: 1.6; }
.cverd-r b { color: var(--navy); }
.cverd-s { font-size: 12px; color: var(--ink-mute); margin-top: 4px; }

.cchips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 4px; }
.cchip {
  font-size: 11.5px; color: var(--ink-soft); background: var(--bg-warm);
  border-radius: var(--r-pill); padding: 3px 10px;
}
.cchip b { color: var(--navy); }

.cfail { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; margin-bottom: 8px; }
.cfail-h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 6px; }
.cfail-h b { font-size: 13px; color: var(--navy); }
.ccat {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--bad); background: #fdecea; padding: 2px 7px; border-radius: 4px;
}
.cmore { font-size: 12px; color: var(--ink-mute); margin: 8px 0 4px; }

@media (max-width: 640px) {
  .app[data-app="connect"] { height: 520px; }
  .ctiles { grid-template-columns: repeat(2, 1fr); }
  .cverd { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* The Black Box: the change, in the operator's own words. */
.cchip.lost { background: #fdecea; color: var(--bad); font-weight: 650; }
.cchip.lost b { color: var(--bad); font-weight: 700; margin-left: 4px; font-size: 10.5px; }
.cdiff { background: #0f1f38; border-radius: 8px; padding: 10px 12px; overflow-x: auto; }
.cadd { display: flex; gap: 8px; align-items: baseline; padding: 2px 0; }
.cpm { color: #6ee7a8; font-weight: 700; flex: none; }
.cadd code { color: #ffd9d4; font-size: 12px; white-space: pre; font-family: var(--mono); }

/* Flow Assurance, built to look like the screen it reproduces: a sortable grid with
   uppercase headers, pill verdicts, and a plain-English answer column that is the
   whole reason the screen exists. */
.ctab { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; }
.ctab th {
  text-align: left; font-size: 10px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-soft); padding: 10px 11px;
  background: #eef1f8; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.ctab td { padding: 10px 11px; border-bottom: 1px solid var(--line-soft); font-size: 12.5px; color: var(--ink-soft); vertical-align: top; }
.ctab tr:last-child td { border-bottom: 0; }
.ctab td b { color: var(--navy); font-size: 13px; }
.ctab tr.row-bad td { background: #fdf6f5; }
.cpill {
  display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .03em;
  padding: 3px 9px; border-radius: var(--r-pill); white-space: nowrap;
}
.cpill.p-bad  { background: #fdecea; color: #b23127; }
.cpill.p-good { background: #e6f4ec; color: #1a7d50; }
.cpill.p-fair { background: #fbf0dd; color: #8a5a12; }
.cpill.p-sky  { background: #e4f2f7; color: #16607a; }
.cpill.p-mute { background: var(--bg-warm); color: var(--ink-mute); }
.ctab td.n, .ctab th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cdash { color: var(--ink-mute); }
.cans { line-height: 1.55; }
.ccause {
  display: block; margin-top: 5px; font-size: 11.5px; color: #b23127;
  background: #fdecea; border-radius: 4px; padding: 3px 7px; width: fit-content;
}

/* ---- The CrossTrust screens ---------------------------------------------
   A documents product, so the screens are typographic rather than graphical:
   tables, cited sources and code with findings pinned to lines. The one piece
   of real layout is the two-sided disagreement card, because two answers side
   by side with neither winning is the thing the product is for. */
.app[data-app="trust"] { height: 580px; }

.ttab { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; margin-bottom: 6px; }
.ttab th {
  text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-mute); padding: 9px 11px;
  border-bottom: 1px solid var(--line); background: var(--bg-soft);
}
.ttab td { padding: 9px 11px; border-bottom: 1px solid var(--line-soft); font-size: 12.5px; color: var(--ink-soft); vertical-align: top; }
.ttab tr:last-child td { border-bottom: 0; }
.ttab td b { color: var(--navy); font-size: 13px; display: block; }
.ttab .n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ttab .tmono { font-family: var(--mono); font-size: 12px; color: var(--navy); }
.ttab .tfix { color: var(--ink-mute); font-size: 12px; }
.ttab .tmiss { color: var(--ink-mute); font-size: 11.5px; line-height: 1.5; }
.tfull { color: #1a7d50; font-weight: 700; }
.tpart { color: var(--fair); font-weight: 700; }
.tnone { color: var(--ink-mute); font-weight: 400; }

/* Tiles: the run's headline counts, the product's own wording under each. */
.ttiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; margin: 12px 0 18px; }
.ttile { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; }
.ttile .n { display: block; font-size: 24px; font-weight: 800; line-height: 1; color: var(--accent); font-variant-numeric: tabular-nums; }
.ttile .k { display: block; margin-top: 5px; font-size: 11px; color: var(--ink-mute); line-height: 1.4; }
.ttile.warnish { border-color: color-mix(in srgb, var(--fair) 40%, var(--line)); }
.ttile.warnish .n { color: #9a6c10; }
.ttile.alert { border-color: color-mix(in srgb, var(--bad) 42%, var(--line)); background: color-mix(in srgb, var(--bad) 4%, #fff); }
.ttile.alert .n { color: var(--bad); }

/* The credential panel, which the product puts above everything else. */
.tpanel { border: 1px solid var(--line); border-radius: 8px; padding: 13px 15px; margin-bottom: 16px; background: #fff; }
.tpanel.alert { border-color: color-mix(in srgb, var(--bad) 40%, var(--line)); background: color-mix(in srgb, var(--bad) 4%, #fff); }
.tp-h { font-size: 13.5px; font-weight: 700; color: var(--bad); margin-bottom: 5px; }
.tp-b { font-size: 12px; color: var(--ink-soft); line-height: 1.55; margin-bottom: 8px; }
.tlist { list-style: none; display: grid; gap: 4px; margin-bottom: 8px; }
.tlist li { font-size: 12px; color: var(--ink-soft); }
.tlist li b { color: var(--navy); font-family: var(--mono); font-size: 11.5px; }
.tp-ok { font-size: 12px; color: #1a7d50; line-height: 1.55; border-top: 1px solid var(--line-soft); padding-top: 8px; }
.tp-ok b { color: #14663f; }

/* Group heading with a count, as the findings page prints it. */
.tgrp {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-mute); margin: 18px 0 4px;
}
.tgrp:first-of-type { margin-top: 4px; }
.tcount {
  display: inline-block; margin-left: 5px; padding: 1px 6px; border-radius: var(--r-pill);
  background: var(--accent-light); color: var(--accent-deep); font-size: 10.5px;
}
.ttier-why { font-size: 12px; color: var(--ink-mute); margin-bottom: 10px; }

/* A finding card: AV gap, or the disagreement itself. */
.tfind { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 13px 15px; margin-bottom: 12px; }
.tfind.sev-high { border-left: 3px solid var(--bad); }
.tfind.sev-medium { border-left: 3px solid var(--fair); }
.tfind.sev-low { border-left: 3px solid var(--line); }
.tf-top { display: flex; align-items: flex-start; gap: 10px; }
.tf-h { font-size: 13.5px; font-weight: 700; color: var(--navy); margin-bottom: 3px; flex: 1; }
.tf-q { font-size: 12px; color: var(--ink-mute); margin-bottom: 10px; }
.tf-fam { font-size: 11px; font-weight: 700; color: var(--accent-deep); margin-bottom: 6px; }
.tf-b, .tf-note, .tf-fix, .tf-where { font-size: 12px; color: var(--ink-soft); line-height: 1.55; margin-bottom: 6px; }
.tf-note { color: var(--ink-mute); font-style: italic; }
.tf-fix b, .tf-where b { color: var(--navy); }
.tf-where { font-size: 11.5px; color: var(--ink-mute); margin-bottom: 0; }
.tsev {
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 7px; border-radius: var(--r-pill); white-space: nowrap; flex: none;
}
.tsev.s-high { background: #fdecea; color: #a8331b; }
.tsev.s-medium { background: #fbf1dd; color: #8d5a09; }
.tsev.s-low { background: var(--bg-warm); color: var(--ink-mute); }
.ttab .tsev { display: inline-block; margin-top: 4px; }

/* The two sides. Neither is styled as the winner, because the engine named none. */
.tsides { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 4px 0 14px; }
.tside { border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; background: var(--bg-soft); }
.tv { font-size: 26px; font-weight: 800; color: var(--navy); line-height: 1; font-variant-numeric: tabular-nums; margin-bottom: 8px; }
.tsays { font-size: 12px; color: var(--ink-soft); line-height: 1.5; margin-bottom: 7px; }
.twhere { font-size: 11.5px; color: var(--ink-mute); line-height: 1.5; margin-bottom: 5px; }
.twhere b { color: var(--navy); font-family: var(--mono); font-size: 11px; }
.twhen, .tband { font-size: 11px; color: var(--ink-mute); }
.tnote { font-size: 11px; color: #8d5a09; margin-top: 6px; line-height: 1.45; }
@media (max-width: 640px) { .tsides { grid-template-columns: 1fr; } }

/* The decision. The refusal, and what to do instead. */
.tdec { border-top: 1px solid var(--line); padding-top: 12px; }
.td-h { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 5px; }
.td-q { font-size: 13.5px; font-weight: 700; color: var(--navy); margin-bottom: 4px; }
.td-stakes { font-size: 12px; color: var(--ink-soft); line-height: 1.55; margin-bottom: 10px; }
.topts { list-style: none; display: grid; gap: 7px; margin-bottom: 11px; }
.topts li { display: grid; grid-template-columns: 58px 1fr; gap: 10px; align-items: baseline; border: 1px solid var(--line); border-radius: 6px; padding: 8px 11px; }
.to-v { font-size: 16px; font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; }
.to-s { font-size: 12px; color: var(--ink-soft); }
.to-i { grid-column: 2; font-size: 11.5px; color: var(--ink-mute); }
.td-verdict {
  font-size: 12.5px; color: var(--ink-soft); line-height: 1.55; background: var(--accent-light);
  border-left: 3px solid var(--accent); padding: 9px 12px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  margin-bottom: 9px;
}
.td-verdict b { color: var(--accent-deep); }
.td-settle {
  font-size: 12.5px; color: var(--ink-soft); line-height: 1.6;
  border-left: 3px solid #e8731c; padding: 8px 12px; background: #fff;
  border-radius: 0 var(--r-sm) var(--r-sm) 0; margin-bottom: 9px;
}
.td-settle b { color: var(--navy); }
.td-open { font-size: 12px; color: var(--ink-soft); line-height: 1.6; }
.td-open code { font-family: var(--mono); font-size: 11.5px; color: var(--accent-deep); }
.tdec .td-h:not(:first-child) { margin-top: 12px; }

/* The file view: lines, with findings pinned to them. */
.tcode { background: #fff; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; margin-bottom: 10px; }
.tln { display: grid; grid-template-columns: 34px 1fr; gap: 8px; padding: 2px 10px 2px 0; align-items: baseline; }
.tln .tn { text-align: right; font-family: var(--mono); font-size: 10.5px; color: var(--ink-mute); padding-top: 1px; background: var(--bg-soft); }
.tln code { font-family: var(--mono); font-size: 11.5px; color: var(--ink-soft); white-space: pre-wrap; word-break: break-word; }
.tln.hit { background: #fffaf3; }
.tln.hit.s-high { background: #fdf2f0; }
.tln.hit code { color: var(--ink); font-weight: 600; }
.twhy { grid-column: 2; font-size: 10.5px; color: #a8331b; padding-bottom: 3px; line-height: 1.4; }
.tln.hit.s-medium .twhy { color: #8d5a09; }
.tln.hit.s-low .twhy { color: var(--ink-mute); }

/* The run path: the button that moves you forward, and what it does not do. */
.tgo { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.tgo .btn { padding: 9px 18px; font-size: 13.5px; }
.tgo-n { font-size: 11.5px; color: var(--ink-mute); }
.tquiet { background: var(--bg-soft); }
.tq-h { font-size: 12.5px; font-weight: 700; color: var(--navy); margin-bottom: 3px; }
.tnext { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.tjump {
  font: inherit; font-size: 12px; font-weight: 650; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 6px 14px; color: var(--accent-deep);
}
.tjump:hover { border-color: var(--accent); background: var(--accent-light); }
.an-badge {
  margin-left: auto; font-size: 9.5px; font-weight: 700; padding: 1px 6px;
  border-radius: var(--r-pill); background: #f2a33c; color: #2a1a04;
}

@media (max-width: 640px) {
  .app[data-app="trust"] { height: 520px; }
  .ttiles { grid-template-columns: repeat(2, 1fr); }
}

/* =========================================================================
   Making each replica look like the application it reproduces.

   The three products do not share a skin, and until now these frames did:
   they all wore the website's palette, which made them look like the website's
   idea of the products instead of the products. A buyer who plays with this and
   then installs the software has to recognise what they opened.

   CrossCheck is teal on a dotted lavender field. CrossRoom is warm: cream, tan
   and orange. CrossConnect is a cool grey grid. Those are their real colours,
   read off the running apps (assets/shots/).
   ========================================================================= */

/* ---- CrossCheck: teal, on a dotted field, in white cards ---------------- */
.app[data-app="check"] {
  --accent: #1a9cb8; --accent-deep: #14788d; --accent-light: #e2f2f6;
}
.app[data-app="check"] .app-nav { background: #0f2233; }
.app[data-app="check"] .app-nav .an-brand .wm .c2 { color: #4cc6dd; }
.app[data-app="check"] .app-main {
  background: #eef1f8;
  /* The dot grid the app draws behind its cards. */
  background-image: radial-gradient(rgba(20,49,91,.10) 1px, transparent 1px);
  background-size: 16px 16px;
}
/* Its verdict sections are white cards floating on that field, not flat bands. */
.app[data-app="check"] .vsec {
  background: #fff; border: 1px solid #e2e7f0; border-radius: 12px;
  padding: 16px 18px; margin-bottom: 12px; border-top: 1px solid #e2e7f0;
  box-shadow: 0 1px 2px rgba(20,49,91,.04);
}
.app[data-app="check"] .vsec.lit {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light);
  background: #fff;
}
/* The band is large rose type, not a filled pill. That is how the app says No-Go. */
/* CrossCheck writes the band as a headline rather than a pill, so the skin drops the
   background. The colour has to follow the engine's own band, or a Caution and a Go
   both land on the page in No-Go red, which would be the site overruling the verdict. */
.app[data-app="check"] .vband {
  background: none; color: var(--bad); font-size: 26px; font-weight: 750;
  padding: 0; letter-spacing: -.02em;
}
.app[data-app="check"] .vband.sv-amber { color: var(--fair); }
.app[data-app="check"] .vband.sv-emerald { color: var(--good); }
.app[data-app="check"] .vh {
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-mute);
}
.app[data-app="check"] .vh-s { text-transform: uppercase; letter-spacing: .08em; font-size: 10px; }
.app[data-app="check"] .vg-num span { text-transform: uppercase; letter-spacing: .08em; }

/* ---- CrossRoom: warm. Cream, tan, orange, and green when it is good. ---- */
.app[data-app="room"] {
  --accent: #d2632a; --accent-deep: #b34413; --accent-light: #fbeee4;
}
.app[data-app="room"] .app-hd { background: #1b1a17; }
.app[data-app="room"] .app-nav { background: #14315b; }
.app[data-app="room"] .app-main { background: #faf7f2; }
.app[data-app="room"] .rstage,
.app[data-app="room"] .rnow-l,
.app[data-app="room"] .rnow-r,
.app[data-app="room"] .rmoment,
.app[data-app="room"] .rtab { background: #fff; border-color: #ece4d8; }
.app[data-app="room"] .rtab th { background: #f6f0e6; color: #7a6a52; border-bottom-color: #ece4d8; }
.app[data-app="room"] .rtab td { border-bottom-color: #f2ece2; }
.app[data-app="room"] .rbar { background: #f0e7d9; }
.app[data-app="room"] .rmb { background: #f0e7d9; }
/* Good is green in this app, and the number is the loudest thing on the screen. */
.app[data-app="room"] .rmos b { color: #2e9e6b; font-size: 40px; }
.app[data-app="room"] .rmos.b-poor b, .app[data-app="room"] .rmos.b-bad b { color: #c33a2f; }
.app[data-app="room"] .rmb i { background: #2e9e6b; }
.app[data-app="room"] .rmb i.hot { background: #c33a2f; }
.app[data-app="room"] .reyebrow { color: #8a7a63; }
.app[data-app="room"] .rthesis { border-left-color: var(--bad); background: #fff; }
.app[data-app="room"] .rmoment.bad { border-color: #e8b3ad; background: #fdf3f2; }
.app[data-app="room"] .rfive dt { color: var(--accent-deep); }

/* ---- CrossConnect: a cool grey grid, the way a Vaadin app looks. -------- */
.app[data-app="connect"] {
  --accent: #2f6fb0; --accent-deep: #215389; --accent-light: #e8f0f9;
}
.app[data-app="connect"] .app-main { background: #f4f6fa; }

/* ---- CrossTrust: paper. A white page, a navy rail, orange to mark the place --
   Its own app.css sets --page: #ffffff and puts tiles on --wash: #f5f8fa, so the
   application reads like a document rather than a dashboard. That is the right
   look for the one product in the family whose subject is documents, and it is
   what the reader will see when they open the real thing. */
.app[data-app="trust"] {
  --accent: #173a6b; --accent-deep: #0f2749; --accent-light: #e8edf5;
}
.app[data-app="trust"] .app-nav { background: #173a6b; }
.app[data-app="trust"] .app-nav .an-brand .wm .c2 { color: #36a9e1; }
/* The rail marks the open screen with an orange edge, as the product does. */
.app[data-app="trust"] .app-nav .an-item.sel {
  border-left: 3px solid #e8731c; padding-left: 7px; border-radius: 0 8px 8px 0;
}
.app[data-app="trust"] .app-main { background: #fff; }
.app[data-app="trust"] .ttab th { background: #f5f8fa; }
.app[data-app="trust"] .ttile { background: #f5f8fa; }
.app[data-app="trust"] .tside { background: #f5f8fa; }
.app[data-app="trust"] .app-hd { background: #10294b; }
.app[data-app="room"] .rax { fill: #9c8a6e; font-size: 9px; }
.app[data-app="room"] .rbx { fill: #b23127; font-size: 9.5px; font-weight: 700; }
.app[data-app="room"] .rjump { border-color: #d2632a; color: #b34413; }
.app[data-app="room"] .rjump:hover { background: #fbeee4; }
.app[data-app="room"] .rplay { border-color: #e3d5bf; color: #b34413; }
.rhd-v { text-align: right; }
.rthes { font-size: 13px; font-weight: 700; color: var(--navy); margin-top: 6px; max-width: 24ch; }
.vfid { display: flex; align-items: center; gap: 9px; margin: 10px 0 4px; }
.vfid span { font-size: 12px; color: var(--ink-soft); }
.vfid-b { width: 90px; height: 6px; background: var(--bg-warm); border-radius: 3px; overflow: hidden; }
.vfid-b i { display: block; height: 100%; background: var(--ink-mute); }
.vfid b { font-size: 12px; color: var(--navy); font-variant-numeric: tabular-nums; }

/* ---- The trust ladder ---------------------------------------------------
   Three rungs, and the number on each is the real multiplier the engine applies
   (1.0 confirmed, 0.8 imported, 0.6 inferred). It reads as a ladder because that
   is what it is: the reader is being told how to climb it. */
.ladder { display: grid; gap: 0; max-width: 82ch; margin-bottom: 28px; }
.rung {
  display: flex; gap: 20px; align-items: flex-start;
  padding: 22px 0; border-top: 1px solid var(--line);
}
.rung:last-child { border-bottom: 1px solid var(--line); }
/* Each step is a raised, lit disc in the page accent instead of a flat numeral,
   so the ladder reads as a sequence with weight to it. */
.rung .rung-n {
  flex: 0 0 auto; width: 42px; height: 42px; display: grid; place-items: center;
  font-size: 17px; font-weight: 750; color: #fff; border-radius: 50%; line-height: 1;
  font-variant-numeric: tabular-nums;
  background: radial-gradient(115% 115% at 30% 24%,
    color-mix(in srgb, var(--accent) 68%, #fff), var(--accent) 52%, var(--accent-deep) 100%);
  box-shadow: 0 2px 5px rgba(20,49,91,.26), inset 0 1px 0 rgba(255,255,255,.45);
}
.rung strong { display: block; font-size: 16px; color: var(--navy); margin-bottom: 5px; padding-top: 8px; }
.rung span { display: block; color: var(--ink-soft); font-size: 15px; line-height: 1.6; }
.ladder-foot { max-width: 72ch; margin-top: 14px; }
.ladder-foot strong { color: var(--navy); }

@media (max-width: 640px) {
  .rung { gap: 14px; }
  .rung-n { width: 38px; height: 38px; font-size: 15px; }
}
/* The change under test, the way the app prints it: small caps, not a command. */
.vchg { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute); }

/* ---- Figures: the product's own UI, used as evidence ---------------------
   The most persuasive image a technical buyer can be shown is the software
   actually running. These are real captures, and the caption says what the
   reader is looking at rather than admiring it. */
.figure { margin: 30px 0 0; }
.figure img {
  width: 100%; border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-md); background: #fff;
}
.dark .figure img { border-color: rgba(255,255,255,.14); }
.figure figcaption {
  margin-top: 12px; font-size: 14px; color: var(--ink-faint); line-height: 1.6;
  max-width: 70ch;
}
.figure figcaption b { color: var(--navy); font-weight: 650; }
.dark .figure figcaption { color: rgba(255,255,255,.7); }
.dark .figure figcaption b { color: #fff; }

/* ---- Receipts: the numbers, as artefacts rather than sentences ----------- */
.receipt {
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 22px 24px; box-shadow: var(--shadow-sm); max-width: 620px;
}
.receipt-h {
  font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-mute); padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.receipt-r { display: flex; align-items: baseline; gap: 14px; padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
.receipt-r .lab { flex: 1; font-size: 15px; color: var(--ink-soft); }
.receipt-r .lab em { display: block; font-style: normal; font-size: 12.5px; color: var(--ink-mute); margin-top: 2px; }
.receipt-r .val { font-size: 15px; font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; white-space: nowrap; }
.receipt-r.bind { background: var(--accent-light); margin: 0 -24px; padding-left: 24px; padding-right: 24px; }
.receipt-r.bind .val { color: var(--accent-deep); }
.receipt-r.dim .lab, .receipt-r.dim .val { color: var(--ink-mute); font-weight: 500; }
.receipt-r.tot { border-bottom: 0; padding-top: 16px; }
.receipt-r.tot .lab { font-size: 17px; font-weight: 700; color: var(--navy); }
.receipt-r.tot .val { font-size: 26px; font-weight: 800; color: var(--bad); }
.receipt-foot { margin-top: 14px; font-size: 13.5px; color: var(--ink-faint); line-height: 1.6; }

/* A receipt whose rows are answers rather than arithmetic (CrossRoom). */
.answers { display: grid; grid-template-columns: 74px 1fr; }
.answers dt {
  font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--accent-deep); padding: 13px 0; border-bottom: 1px solid var(--line-soft);
}
.answers dd {
  margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft);
  padding: 13px 0; border-bottom: 1px solid var(--line-soft);
}
.answers dt:last-of-type, .answers dd:last-of-type { border-bottom: 0; padding-bottom: 4px; }

/* ---- Scoreboard: the four ceilings, before the prose that explains them ---- */
.scoreboard {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; margin-bottom: 34px;
}
.score { background: #fff; padding: 22px 20px 20px; }
.score-n {
  font-size: 42px; font-weight: 800; line-height: 1; color: var(--accent-deep);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; margin-bottom: 12px;
}
.score-n.word { font-size: 26px; padding-top: 14px; padding-bottom: 2px; }
.score-l { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
@media (max-width: 1080px) { .scoreboard { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 860px) { .scoreboard { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .scoreboard { grid-template-columns: 1fr; } }

/* ---- Contact form -------------------------------------------------------- */
.contact-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 44px; align-items: start; }
.contact-form-col { min-width: 0; }
.contact-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.contact-form .field { margin-bottom: 16px; }
.contact-form label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-soft); margin-bottom: 6px; }
.contact-form input,
.contact-form select,
.contact-form textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 15px; color: var(--ink);
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 11px 13px; transition: border-color .14s, box-shadow .14s;
}
.contact-form textarea { resize: vertical; min-height: 104px; line-height: 1.5; }
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(23,151,179,.16);
}
.contact-form input:user-invalid { border-color: #cf5a3c; }
.contact-form .hp { position: absolute; left: -9999px; width: 1px; height: 0; overflow: hidden; }
.btn.btn-large { font-size: 16px; padding: 13px 26px; margin-top: 4px; }
.form-error {
  background: #fdeceb; border: 1px solid #f1b6ab; color: #9a3418;
  border-radius: var(--r-md); padding: 12px 15px; font-size: 14px; line-height: 1.5; margin-bottom: 18px;
}
.form-error[hidden] { display: none; }
.form-fallback { font-size: 13px; color: var(--ink-faint); margin-top: 14px; line-height: 1.55; }

.contact-aside { background: #fff; border: 1px solid var(--line); border-radius: var(--r-md); padding: 26px 26px 24px; box-shadow: var(--shadow-md); }
.contact-aside h2 { font-size: 17px; color: var(--navy); margin-bottom: 16px; }
.contact-facts { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 15px; }
.contact-facts li { font-size: 14px; line-height: 1.55; color: var(--ink-soft); padding-left: 16px; position: relative; }
.contact-facts li::before { content: ""; position: absolute; left: 0; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.contact-facts b { color: var(--ink); font-weight: 650; }
.contact-alt { font-size: 14px; color: var(--ink-faint); border-top: 1px solid var(--line-soft); padding-top: 16px; margin: 0; }
@media (max-width: 820px) {
  .contact-grid { grid-template-columns: 1fr; gap: 30px; }
  .contact-form .row { grid-template-columns: 1fr; gap: 0; }
}
