/* Second Lens Recruitment Assurance Register.
 *
 * No inline style anywhere in this product, which is what lets the Content Security Policy
 * carry no unsafe-inline and no hashes. Add one and the page deploys green and renders blank.
 *
 * Tokens are Second Lens Style Guide V1.1. Use a step from the scale, never an arbitrary
 * value. There is no dark mode. */

/* The faces are declared in fonts.css, which the build writes from the font list in
   rules/settings.mjs and every page links before this file. Which one is in force is --face below,
   and the console chooses it. */

:root {
  /* surfaces */
  --bg: #F3F4F7; --surf: #FFFFFF; --rail: #FAFBFC;
  /* text */
  --ink: #0D1B2A; --mid: #5C6472; --soft: #8A92A1;
  /* lines */
  --line: #E1E4EA; --line2: #EDEFF3;
  /* action, the only blue */
  --act: #0B5FBF; --act-h: #094D9B; --act-t: #E8F1FB;
  /* status signals */
  --red: #C4314B; --red-h: #A3121F; --red-t: #FBEBEE; --amb: #B0770B; --amb-t: #FCF4E3;
  --amb-on-tint: #8A5D08;
  /* The amber a white label can sit on. --amb carries a border or a bar, where 3:1 is the
     bar and it measures 3.83:1 against white. Under white text it is text, 4.5:1 is the
     bar, and 3.83 is under it: the "Should fix" badge and the "was" word in a swapped
     phrase were both reading at 3.83:1. Scaled by 0.9, which keeps the hue, giving
     4.60:1. Red and green already measured 5.40 and 5.27 under white and do not move. */
  --amb-d: #9E6B0A;
  --grn: #107C41; --grn-t: #E7F4EC; --gry: #98A0AE; --gry-t: #F0F2F5;
  --vio: #5B4B9E; --vio-t: #EEEBF7;
  --tea: #0F6E7A; --tea-t: #E4F2F4;
  /* dark navigation surface */
  --nav: #0D1B2A; --nav-fg: rgba(255, 255, 255, .86); --nav-dim: rgba(255, 255, 255, .58);
  --nav-accent: #E63946;
  --nav-red: #F0788C; --nav-amb: #E8A33D; --nav-grn: #57C98A; --nav-gry: #9AA3B0;
  /* Other companies' colours, used only on their own marks on the share buttons. */
  --brand-linkedin: #0A66C2; --brand-whatsapp: #25D366;

  /* ------------------------------------------------------- the four button plates, and what
     each one means.

     Five roles per family: plate, plate hover, edge, edge hover, text.

     One meaning each, on every screen a customer sees. docs/style/buttons.md is the written
     version and tools/tests/button-roles.test.mjs is what holds it:

       go     blue     do this too, or carry a copy in or out of this device
       keep   amber    this came from you and you can change it. Edit the details, and nothing else
       back   neutral  move on, decline, navigate. Nothing about the advert changes
       del    red      this press lowers the score, or deletes something kept on this device

     The spine is that last line, and it is written as an effect rather than as a feeling
     because a feeling cannot classify a control. "Reset this one" reads gentle and always
     lowers the score, so it is red; "Check another advert" reads final and touches no score, so
     it is not. What the press does to the number decides, and the code can be read to check.

     Amber is the one to be careful with. It does not mean caution here, it means "your detail":
     the marked words inside a written sentence wear these same tokens, and a sweep check asserts
     the mark and the Edit button match at run time. It reached six meanings on the guided pass,
     which is what made it mean none of them.

     These four plates are 1.00 to 1.15:1 against each other. They differ in hue and in nothing
     else, so in greyscale, in a printed screenshot, and for a good share of colour-blind
     readers they are one button. Colour is therefore never the carrier: every role carries an
     icon and a verb as well, and button-plates.test.mjs asserts that near-equality as the
     reason why.

     The edges were #6A96CC, #B08F43 and #D1798C, which are 2.79, 2.79 and 2.80 against the page
     ground. WCAG 2.2 1.4.11 wants 3:1 for the visual information required to identify a
     control, and on a ghost button the edge is that information: its fill is within a whisker
     of the page. The neutral one was fixed for exactly this reason and the other three were
     left, so three of the four families carried the defect the fourth had had corrected. Each
     is scaled by 0.91, which keeps the hue, and all four now land together: 3.30, 3.32, 3.33
     and 3.30 on the page, 3.63 to 3.67 on a card. Text on every plate was already 6.3:1 or
     better and has not moved. */
  --pl-go: #DEEAF8;   --pl-go-h: #CFE0F4;   --pl-go-e: #6089BA;   --pl-go-eh: #0B5FBF;   --pl-go-t: #0A4E9E;
  /* The person's own details in a written line, the Edit the details button that changes them and
     the form it opens: one thread, in the colour of the stage the line belongs to, because that is
     what every other mark on a line says. Stage two, a line we wrote on our own, is blue; stage
     three, a line from their answers, is green. It was amber, which here also means Should fix and
     a warning, and needed a brown to be read as text. Ink 7.8:1 on its tint, 7.1:1 on the hover,
     edges 4.5:1 or better on every ground they sit on. */
  --pl-yours: #DCE9FC;  --pl-yours-h: #CCDFFA;  --pl-yours-e: #175FBB;  --pl-yours-eh: #0D4486;  --pl-yours-t: #0D4486;
  --pl-yours3: #DAF0E1; --pl-yours3-h: #C8E8D2; --pl-yours3-e: #0E8125; --pl-yours3-eh: #0A5227; --pl-yours3-t: #0A5227;
  --pl-back: #E9ECF1; --pl-back-h: #DEE2E9; --pl-back-e: #7D8797; --pl-back-eh: #5C6472; --pl-back-t: #3F4756;
  --pl-del: #F7DFE4;  --pl-del-h: #F2D2D9;  --pl-del-e: #BE6E7F;  --pl-del-eh: #A32840;  --pl-del-t: #8A2136;
  /* The Report button. Solid dark slate, the one plate that is not a pale tint, so it stands apart
     from every action without borrowing a colour that already means something: not red (removal),
     amber (your detail), green (a change made), blue (the action) or violet (safeguarding). */
  --pl-report: #2B3645; --pl-report-h: #1B2430; --pl-report-e: #1B2430; --pl-report-t: #FFFFFF;

  /* one box you type into, and its ground is never white */
  --io-type: 13px; --io-pad: 8px 10px; --io-lead: 1.55;
  --io-bg: #EDF0F5; --io-bg-h: #E6EAF1; --io-bg-on: #FFFFFF;

  /* ----------------------------------------------------------------- one light, one direction
   *
   * Every shadow in this product is cast by one light, high and to the right, so every shadow
   * falls down and to the left. The rule is one line and it is checkable: the offset of any
   * shadow is (-n, +n). Nothing is lit from anywhere else, on any screen, in any state.
   *
   * It held to a rule before this and it was a different rule: every offset was (0, +n), a
   * light directly overhead. That is internally consistent and it is flat, and it was asked to
   * change. What was not consistent is that the dial drew its own four shadow layers in SVG
   * with dx hard-coded to 0, so the one drawing in the product that is meant to look solid was
   * lit from a different place from the card it sits on. It is on the same rule now.
   *
   * The rule covers an inset shadow too, with the same offset and no inversion, and that is
   * right rather than convenient. On a raised button `inset -1px 1px 0` white draws the lit
   * bevel along the top and the right, which is the two edges this light reaches. On a pressed
   * one, and on a box you type into, `inset -2px 2px 5px` dark draws the rim's shadow on the
   * same two interior walls, which is where it falls when the thing is sunk in rather than
   * standing out. One offset, two readings, because the geometry does the work.
   *
   * Three kinds of box-shadow are deliberately outside it, because none of them is lighting:
   * a ring (`0 0 0 Npx`), which is an outline; a bar (`inset 0 -2px 0`), which is the 2px rule
   * this product draws under a stage's own row; and the glow on the turning dial, which is a
   * light rather than a shadow of one. `tools/tests/shadows.test.mjs` names all three and
   * fails on anything else that strays. */

  /* button depth */
  --lift-f: inset -1px 1px 0 rgba(255, 255, 255, .24), -1px 1px 2px rgba(13, 27, 42, .16), -3px 3px 8px rgba(11, 95, 191, .22);
  --lift-f-h: inset -1px 1px 0 rgba(255, 255, 255, .28), -2px 2px 5px rgba(13, 27, 42, .16), -8px 8px 18px rgba(11, 95, 191, .30);
  --lift-p: inset -1px 1px 0 rgba(255, 255, 255, .85), -1px 1px 2px rgba(13, 27, 42, .10);
  --lift-p-h: inset -1px 1px 0 rgba(255, 255, 255, .9), -4px 4px 11px rgba(13, 27, 42, .13);
  --press-f: inset -2px 2px 5px rgba(0, 0, 0, .26);
  --press-p: inset -2px 2px 5px rgba(13, 27, 42, .15);
  /* elevation */
  --sh: -1px 1px 2px rgba(13, 27, 42, .06), -1px 1px 3px rgba(13, 27, 42, .10);
  --sh2: -2px 2px 4px rgba(13, 27, 42, .06), -8px 8px 16px rgba(13, 27, 42, .12);
  --sh3: -4px 4px 8px rgba(13, 27, 42, .07), -16px 16px 32px rgba(13, 27, 42, .16);
  /* corners */
  --r-s: 8px; --r-m: 12px; --r-l: 16px; --r-full: 999px;
  /* type. One face for every word on every page, chosen in the console and written onto the
     root as data-font, which fonts.css turns into --face. No attribute, which is also what a page
     sees before /api/site answers or if it never does, is the face this product shipped with.
     --mono is not the chosen face and never is: references, hashes and codes have to line up. */
  --face: 'Poppins';
  --disp: var(--face), system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ui: var(--face), system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, 'SFMono-Regular', Menlo, Consolas, 'Liberation Mono', monospace;
  /* The advert's own words: the paste box, the advert on the result, and the sentences added to it.
     A serif and never the chosen face, so the person's document reads as a document whichever
     face the console picks, and every label and button round it stays --ui. READING_FONT in
     rules/settings.mjs says why this face; fonts.css declares it. */
  --read: 'Literata', Georgia, 'Times New Roman', serif;
  /* seven steps. Use a step, never an arbitrary value. */
  --t-xs: 11px; --t-s: 12.5px; --t-b: 13.5px; --t-m: 15px; --t-l: 19px; --t-xl: 26px; --t-2xl: 40px;
  /* 4px rhythm */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;
  /* motion */
  --m-state: .14s; --m-lift: .16s; --m-panel: .26s;
  --ease-panel: cubic-bezier(.22, 1, .36, 1);
  /* product identity */
  --prod: #0E7A47; --prod-blade: #1A7F4D; --prod-t: #E6F3EC; --prod-d: #0B5C36;

  /* ------------------------------------------------------------------- the training colour
   *
   * One hue, used by the guide and by nothing else, so that a ring somebody has seen once is
   * recognised the next time without being read.
   *
   * It had to be a new hue rather than a borrowed one. Every other colour in this sheet already
   * means something and the meanings are held by tests: blue is the action and the chosen state,
   * green is stage three and the brand, grey is stage one, amber is "your detail", red is a
   * removal, violet is safeguarding, teal is outside the UK. A guide wearing any of those would
   * be saying that thing while pointing at a button that is not it.
   *
   * Measured against every ground it sits on: 7.24:1 on a card, 6.58:1 on the page, 6.49:1 on
   * the guided pass, against 4.5 for text and 3 for a graphic that identifies a control. White
   * on it reads 7.24:1, and --train-e is 9.00:1 on the page.
   *
   * Colour is not the carrier and cannot be. Against the product red it separates by 9.1 for
   * normal vision but only 6.5 under deuteranopia, so a reader with red-green colour blindness
   * is not being asked to tell a training ring from a red mark by its hue. The ring never
   * arrives alone: the panel beside it says which step of which chapter this is, and the words
   * are what carry it. The same argument the four button plates make about their icons. */
  --train: #A21C68; --train-h: #8A1858; --train-e: #7E1651; --train-t: #F4E4ED;
  /* The soft outer ring, the training colour at low alpha, on the same pattern as
     --stage-three-halo: the same colour as the edge it sits outside, so the two read as one
     light rather than as two borders. */
  --train-halo: rgba(162, 28, 104, .20);
  /* And a fainter one, for the wide end of the ring's breath. The same colour again at a lower
     alpha, so the ring swelling reads as one light getting brighter rather than as a second
     border appearing and going. */
  --train-halo-2: rgba(162, 28, 104, .12);

  /* ---------------------------------------------------------------- the three stages
     One meaning each, everywhere this product shows a score or names a stage:

       one    grey   the advert exactly as the user pasted it. Nothing has happened.
       two    blue   fixed by the application on its own. No user involvement.
       three  green  gained because the user answered the questions.

     These three must never mean anything else anywhere in the product. Grey is not "disabled".
     Blue is not "link". Green is not "ok".

     The values are the score dial specification's own, and they replace three that were chosen
     here. The specification measures them against the card the marks sit on, which is what
     WCAG 1.4.11 asks about: grey 3.95:1, blue 4.12:1, green 3.22:1, against a floor of 3.

     The earlier values were picked to hold a separation between the stages where they touched,
     because the gauge they were for was a single stacked arc. The dial these are for does not
     touch: every mark is trimmed by 1.6 degrees at each end, so the adjacent colour each mark
     is measured against is the card behind it and not its neighbour. That is stated in the
     specification as the reason the palette passes, and it is why the pair separation those
     older values were protecting is no longer the governing number.

     Text on a chip is the stricter case at 4.5:1, and white does not clear it on all three, so
     each stage carries the text colour that goes on it rather than assuming white. Measured:
     4.87:1 on grey, 4.12:1 on blue, 5.76:1 on green.

     The blue one is under the line, and it is the specification's own pairing: it sets white on
     that blue and separately says chip text needs 4.5. Those two statements do not agree. The
     instruction with the file was to build it exactly as the file describes, so the file's
     value is what is here and the shortfall is written down rather than quietly corrected.
     tools/tests/stage-colours.test.mjs holds all three numbers, so changing any of them is a
     decision somebody makes rather than one that happens.

     The dark values are the specification's too. Its original design blue #0A39E0 measures
     2.18:1 on a dark card and its original green #22C51E 2.31:1 on a white one, so each theme
     takes the version of the hue that passes. */
  --stage-one: #808080; --stage-two: #1E7AF0; --stage-three: #12A62F;
  /* What goes ON the fill, and it is near-black on all three now. Stage two's was white, which
     measures 4.12:1 against its own blue: under the 4.5:1 the chip's 13px bold text asks for,
     and the browser sweep never caught it because the states it visited had no automatic stage
     in them and so drew no blue chip. Near-black measures 4.67:1 there, 4.87:1 on the grey and
     5.76:1 on the green, so one rule covers all three: a stage's own fill carries near-black.
     docs/style/stages.md has the table. */
  --stage-one-on: #0A0F15; --stage-two-on: #0A0F15; --stage-three-on: #04170B;
  /* A darker step of each, for the edge of a filled control and for nothing else. Scaled by
     0.78, which keeps the hue, and measured against the page it sits on: 5.38:1, 5.63:1 and
     4.56:1, so an edge identifies its control well past the 3:1 of 1.4.11. */
  --stage-one-e: #646464; --stage-two-e: #175FBB; --stage-three-e: #0E8125;
  /* The unpainted rest of the hundred, and the ground still on offer. The second is a lighter
     step of stage three because that is what taking it would be. */
  --stage-none: #E4E7EC; --stage-could: #8FD3AE;
  /* The grounds a stage's own content sits on, away from the dial: a panel, a sentence about
     to go into somebody's advert, a row in a list. Tints of the three above rather than new
     hues, so the ring and the thing the ring is about are plainly the same colour.
     Ink sits on all three at better than 15:1, which is what a tint is for. */
  --stage-two-t: #E9F2FE; --stage-three-t: #E8F6EC;
  /* And the paper each version of the advert is printed on, which is a tint of the tint.

     The advert panel was white behind all three versions, so the one thing on the screen that
     changes when you press a stage looked identical whichever you were on, and the tabs above
     it were grey against a white card. The owner's words: no white background, at the moment
     it is not visible to the user and they don't understand the user journey.

     A lighter step than the tints above rather than the tints themselves, because the lines
     this product wrote INTO the advert already sit on those tints: paint the whole page in
     --stage-two-t and every added line disappears into it. Each of these is its tint mixed
     55% into white, which keeps the hue and lands the page a whisker off white: ink reads at
     better than 16:1, the quiet grey at better than 5.6:1, and a line on its own tint still
     stands off the paper it sits on. */
  --stage-one-paper: #F7F8FA; --stage-two-paper: #F3F8FE; --stage-three-paper: #F2FAF5;
  /* The width of the column a marked line's controls stand in, so every such line in the
     product has its controls ending on the same edge. Sized to Undo and Edit side by side,
     which is wider than it was: both carry an icon now, and a column measured for the words
     alone would have wrapped Edit onto a line of its own on the row that has both, which is
     the moving control this column exists to stop. The sweep measures the two against it. */
  --line-do-w: 10.4rem;
  /* The halo round the card somebody is working in. Stage three's own green at low alpha, so
     the ring is the same colour as the edge it sits outside and reads as that edge's light
     rather than as a second border. */
  --stage-three-halo: rgba(18, 166, 47, .18);
  /* The dial's shadow, as an RGB triplet so each of the four layers can set its own opacity. */
  --shadow-rgb: 15,23,36;
  /* Strongest nearest the mark and fading outwards, so four layers read as one shadow with a
     short falloff. They used to rise with distance, which is what made the dial's shadow a wide
     even haze rather than an edge. */
  --shadow-o1: .30; --shadow-o2: .22; --shadow-o3: .14; --shadow-o4: .08;
  /* fixed chrome */
  --bar-h: 60px;
  --col: 44rem;
}
/* The development bar's starting guess, at the same specificity as :root so the height measureBar()
   writes through the adopted sheet, which comes later in the cascade, replaces it. As
   :root[data-site="development"] it outranked the measurement and the guess stood for good. */
:root:where([data-site="development"]) { --bar-h: 94px; }

* { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 var(--t-b)/1.55 var(--ui); }
h1, h2, h3 { font-family: var(--disp); line-height: 1.25; margin: 0; }
h1 { font-size: var(--t-xl); font-weight: 600; }
h2 { font-size: var(--t-l); font-weight: 600; }
h3 { font-size: var(--t-m); font-weight: 600; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: var(--act); }
.mono { font-family: var(--mono); font-size: var(--t-s); letter-spacing: -.01em; }
svg { width: 1.05em; height: 1.05em; flex: none; }

/* Anything permitted to break inside a word is set in the machine face. break-all breaks
 * prose mid word; overflow-wrap: anywhere does not. */
.mono { overflow-wrap: anywhere; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--act);
  outline-offset: 2px;
  border-radius: var(--r-s);
}
.bar :where(a, button):focus-visible { outline: 2px solid #fff; }
/* Focus is never hidden under the sticky header. WCAG 2.2 SC 2.4.11. */
:where(a, button, input, select, textarea, [tabindex]) { scroll-margin-top: calc(var(--bar-h) + var(--sp-4)); }

/* An author rule setting display beats [hidden]. Do not remove this reset. */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
:root[data-motion="off"] * { animation: none !important; transition: none !important; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--surf); color: var(--ink); padding: var(--sp-3) var(--sp-4);
  border-radius: 0 0 var(--r-s) 0; box-shadow: var(--sh2); font-weight: 600;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------- the development banner */

.devbar {
  position: sticky; top: 0; z-index: 48;
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--red); color: #fff; padding: 6px var(--sp-4);
  font-size: var(--t-s); border-bottom: 2px solid #fff;
}
.devbar-tag {
  font: 700 10px var(--ui); letter-spacing: .1em;
  background: #fff; color: var(--red); padding: 3px 8px; border-radius: var(--r-s); flex: none;
}
.devbar-ver {
  font: 600 11px var(--mono); background: rgba(255, 255, 255, .92); color: var(--red);
  padding: 2px 7px; border-radius: var(--r-s); flex: none; white-space: nowrap;
}
.devbar-say { min-width: 0; flex: 1; }
.devbar-out {
  flex: none; margin-left: auto; background: none; border: 1px solid #fff; color: #fff;
  border-radius: var(--r-s); padding: 4px 10px; font: 600 var(--t-xs) var(--ui);
  cursor: pointer; min-height: 26px;
}
.devbar-out:hover { background: rgba(255, 255, 255, .22); }
:root[data-site="development"] .bar { top: 34px; }

/* --------------------------------------------------------------------------- the app bar */

.bar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-5);
  background: var(--nav); color: var(--nav-fg);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  flex-wrap: wrap;
}
.bar-brand { display: flex; align-items: center; gap: var(--sp-3); text-decoration: none; color: inherit; min-height: 28px; }
.bar-brand img { width: 28px; height: 28px; border-radius: 6px; }
.bar-names { display: flex; flex-direction: column; line-height: 1.15; }
.bar-parent { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; color: var(--nav-dim); }
.bar-product { font-family: var(--disp); font-size: var(--t-m); font-weight: 600; color: #fff; }
/* Its own width, not the rest of the row. `flex: 1 1 auto` made the nav grow into every pixel
   left over, so the tools beside it were pushed onto a second line at every width there is: the
   bar was 111px tall on a 1440px screen with 500px of empty nav between the last link and the
   first tool. --bar-h says 60, which is what the rest of the sheet scrolls and positions
   against, so the bar was also half again as tall as the one number that describes it. */
.bar-nav { display: flex; gap: var(--sp-1); flex: 0 1 auto; flex-wrap: wrap; min-width: 0; }
.navlink {
  background: transparent; border: none; color: var(--nav-dim); cursor: pointer;
  font: 600 var(--t-b) var(--ui); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-s);
  min-height: 32px; display: inline-flex; align-items: center; gap: var(--sp-2);
  transition: background var(--m-state), color var(--m-state);
}
.navlink:hover { background: rgba(255, 255, 255, .08); color: var(--nav-fg); }
.navlink[aria-current="page"] { color: #fff; background: rgba(255, 255, 255, .12); }
.navlink-s { display: none; }
/* Everything in the tools sits on one centre line and at one height, so the lozenge, the four
   buttons and the version read as a row rather than as things of different sizes that happen
   to be next to each other. The four buttons are one width too, the width of the longest. */
.bar-tools { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; --tool-h: 34px; }
:is(.bar-tools, .bar-menu-tools) > .ghost-nav {
  height: var(--tool-h); min-height: var(--tool-h); min-width: 9rem; padding: 0 var(--sp-3);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  /* Tools, not places. The places on the left are flat tabs; these are outlined pills, the shape
     of the lozenge beside them, with the icon in the light blue this bar uses for an accent, so
     the two halves of the bar read as two different kinds of thing at a glance. */
  border-radius: var(--r-full); color: #fff;
  /* Raised off the bar, the way the research says depth reads on a dark ground: a face lighter
     than the bar (a dark shadow alone barely shows on near-black), lit along its top and right
     edge by this product's one light, and standing on a hard dark ledge with a soft shadow
     falling down and to the left. It lifts towards the light when pointed at and presses in
     when pressed. The label is white on the face at well over 4.5:1. */
  background-color: #1F2E45;
  background-image: linear-gradient(200deg, #33476A 0%, #22324C 55%, #1A2840 100%);
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .30), -2px 2px 0 #04080E, -5px 5px 12px rgba(0, 0, 0, .55);
  transition: transform var(--m-state), box-shadow var(--m-state), background-image var(--m-state);
}
:is(.bar-tools, .bar-menu-tools) > .ghost-nav .i { color: #9CC4FF; }
:is(.bar-tools, .bar-menu-tools) > .ghost-nav:hover {
  background-image: linear-gradient(200deg, #3B5178 0%, #293B58 55%, #1F2E48 100%);
  border-color: rgba(255, 255, 255, .34);
  transform: translate(1px, -1px);
  box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .36), -3px 3px 0 #04080E, -7px 7px 16px rgba(0, 0, 0, .6);
}
:is(.bar-tools, .bar-menu-tools) > .ghost-nav:active {
  transform: translate(-2px, 2px);
  box-shadow: inset -2px 2px 5px rgba(0, 0, 0, .45);
}
/* Share, last in the row and the one that glows, as asked: the bar's action blue instead of its
   slate, a white icon, and a soft light that breathes round it. A glow is a light rather than
   a shadow, so it has no offset; shadows.test names it as the fifth thing outside the one-light
   rule. With Motion off it stays lit and stops breathing. White text on the face measures over
   4.5:1 where it sits. */
#share-open.share-glow {
  background-color: #1661D0;
  background-image: linear-gradient(200deg, #2F7DEB 0%, #1661D0 50%, #0B4FA6 100%);
  border-color: rgba(255, 255, 255, .6);
  box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .45), -2px 2px 0 #04080E, -5px 5px 12px rgba(0, 0, 0, .55), 0 0 16px rgba(76, 149, 255, .7);
  animation: share-glow 2.8s ease-in-out infinite;
}
#share-open.share-glow .i { color: #fff; }
#share-open.share-glow:hover {
  background-image: linear-gradient(200deg, #3E8BF5 0%, #1D6BDB 50%, #0D56B3 100%);
  box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .5), -3px 3px 0 #04080E, -7px 7px 16px rgba(0, 0, 0, .6), 0 0 26px rgba(76, 149, 255, .9);
}
@keyframes share-glow {
  0%, 100% { box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .45), -2px 2px 0 #04080E, -5px 5px 12px rgba(0, 0, 0, .55), 0 0 10px rgba(76, 149, 255, .5); }
  50% { box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .45), -2px 2px 0 #04080E, -5px 5px 12px rgba(0, 0, 0, .55), 0 0 26px rgba(76, 149, 255, .95); }
}
:is(.bar-tools, .bar-menu-tools) > .ghost-nav[aria-pressed="true"], :is(.bar-tools, .bar-menu-tools) > .ghost-nav[aria-expanded="true"] {
  border-color: rgba(255, 255, 255, .6);
}
.ver { font: 600 11px var(--mono); color: var(--nav-dim); display: inline-flex; align-items: center; height: var(--tool-h); }

/* The count is the one thing in the bar that is a figure rather than a control, so it is the
   one thing that is white: a lozenge of dark text on white, the easiest thing in the band to
   read. How things stand is its border and its words, never its colour alone. */
.allow-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  background: #fff; border: 1px solid #0A1420;
  color: var(--ink); border-radius: var(--r-full); padding: 0 var(--sp-3);
  font: 600 var(--t-xs) var(--ui); cursor: pointer; height: var(--tool-h, 34px); min-height: 28px;
  /* Sunk into the bar, as asked: a well with the figure at the bottom of it. The one light is
     high and to the right, so the rim hides it from the inside top and right walls, which carry
     the shadow (inset, the same offset every shadow here takes), and the face is shaded on that
     side. Outside, the bar's own edge catches the light along the lower left of the rim, a thin
     pale lip. Nothing lifts on hover: a well does not move. */
  background-image: linear-gradient(200deg, #CDD5E1 0%, #EEF1F6 40%, #FFFFFF 72%);
  box-shadow: inset -4px 4px 7px rgba(13, 27, 42, .6), inset -1px 1px 2px rgba(13, 27, 42, .6),
    -1px 1px 0 rgba(255, 255, 255, .28);
  transition: box-shadow var(--m-state);
}
.allow-chip:hover {
  box-shadow: inset -5px 5px 9px rgba(13, 27, 42, .65), inset -1px 1px 2px rgba(13, 27, 42, .65),
    -1px 1px 0 rgba(255, 255, 255, .34);
}
.allow-chip:active { box-shadow: inset -6px 6px 11px rgba(13, 27, 42, .7), -1px 1px 0 rgba(255, 255, 255, .28); }
.allow-chip .allow-chip-l { color: var(--mid); }
/* The ring: full and green with every check left, emptying and turning through amber to red as
   they go (gaugeOf in rules/allowance.mjs). The pale track underneath is the same colour, so an
   empty ring still reads as a red ring rather than as nothing. */
.allow-gauge { display: none; width: 20px; height: 20px; flex: none; margin-left: -4px; }
.allow-chip-gauged .allow-gauge { display: block; }
.allow-gauge circle { fill: none; stroke-width: 5; }
.allow-gauge-t { stroke: var(--gauge-c, #0E8125); opacity: .2; }
.allow-gauge-f {
  stroke: var(--gauge-c, #0E8125); stroke-dasharray: var(--gauge-p, 100) 100; stroke-linecap: round;
  transition: stroke-dasharray .6s var(--ease-panel, ease), stroke .6s;
}
.allow-chip[data-tone="out"] .allow-gauge-f { stroke-dasharray: 0 100; stroke-linecap: butt; }
/* The number never breaks. On a phone the chip is narrow enough that both halves wrapped
   inside themselves, and "None left · checks used" came out as two lines reading "None checks"
   over "left used". The number is one piece; the label may go under it. */
.allow-chip { flex-wrap: wrap; row-gap: 0; }
.allow-chip-n { font-size: var(--t-s); white-space: nowrap; }
/* The counter and what answering the questions gets, side by side, and the link under the
   counter where the bar is narrow. A link rather than a plate: it goes to a page, and it is
   underlined so it reads as one without relying on its colour. 24px tall at least, the target
   size WCAG 2.5.8 asks for. */
.allow-wrap { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.allow-offer { margin: var(--sp-3) 0; }
.allow-offer a.btn { text-decoration: none; }
/* On a phone the counter and its link take a line of their own, so the link reads as one line
   under the counter rather than a column of three beside the other tools. */
@media (max-width: 620px) {
  .bar-tools { flex-wrap: wrap; }
  .allow-wrap { flex: 1 1 100%; flex-direction: column; align-items: flex-start; gap: 2px; }
}

/* --------------------------------------------------------------------------- the footer */

.foot { background: var(--nav); color: var(--nav-dim); padding: var(--sp-6) var(--sp-5); margin-top: var(--sp-7); }
.foot-in { max-width: 68rem; margin: 0 auto; display: grid; gap: var(--sp-3); font-size: var(--t-s); }
.foot-in img { width: 24px; height: 24px; }
.foot-note { color: var(--nav-dim); max-width: 42rem; }
.foot-legal { display: flex; flex-wrap: wrap; gap: var(--sp-4); padding-top: var(--sp-3); }
.foot-legal a { color: var(--nav-fg); }
.foot-share .share-lead { color: var(--nav-fg); }
.foot-share .share-say { color: var(--nav-fg); }

/* --------------------------------------------------------------------------- sharing */

/* One row of share controls, the same wherever it is met (public/js/share.mjs). */
.share { display: grid; gap: var(--sp-2); }
.share-lead { font-weight: 600; margin: 0; }
.share-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* The two companies' marks. LinkedIn asks for its mark at 21px or more on screen. */
.share-do .i svg { width: 19px; height: 19px; }
.share-do .i-logo svg { width: 21px; height: 21px; }
.logo-linkedin-blue { fill: var(--brand-linkedin); }
.logo-whatsapp-green { fill: var(--brand-whatsapp); }
.logo-white { fill: #FFFFFF; }
.share-say { margin: 0; font-size: var(--t-s); overflow-wrap: anywhere; }
.share-say:empty { display: none; }
.route-finish .share { border-top: 1px solid var(--line); padding-top: var(--sp-3); margin-top: var(--sp-3); }
.fp-share { margin-top: var(--sp-5); }

.share-box .share-row { padding: var(--sp-2) 0; }

/* ------------------------------------------------------------------------------ layout */

.wrap { max-width: 68rem; margin: 0 auto; padding: var(--sp-6) var(--sp-5); }
/* A screen whose content is a narrower centred block sets --col, and the title takes the
 * same left edge from it. A title that starts to the right of the block it names reads as
 * two pieces of page, so the two are never set separately. A screen whose content is full
 * width sets --col to 100% and everything lines up on the left. */
.view { --gutter: max(0px, (100% - var(--col)) / 2); }
.view > .page-h, .view > .page-lede, .view > .col { margin-left: var(--gutter); max-width: var(--col); }
.view-wide { --col: 100%; }
.page-h { margin-bottom: var(--sp-2); }
.page-lede { color: var(--mid); font-size: var(--t-m); margin-bottom: var(--sp-5); }

.card {
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-m);
  box-shadow: var(--sh); padding: var(--sp-5);
}
.lbl { display: block; font-weight: 600; font-size: var(--t-s); margin-bottom: var(--sp-2); }
.hint { color: var(--mid); font-size: var(--t-s); }

/* Three visual languages, and they do not blur. Something you type into is inset. Something
 * you press is raised. Something the application produced for you to read is flat, with a
 * rule down its left edge. Each also carries a word, because colour is never the only
 * carrier of meaning here. */

/* tel and url belong here as much as text does. They were missing, so the moment the details
   boxes started declaring what they hold, the phone box stopped being styled at all and came
   out 21 pixels tall, under the 24 that WCAG 2.5.8 asks of a target. A type list that has to be
   extended by hand every time is the kind that gets forgotten; this one is now the set this
   product actually uses. */
input[type="text"], input[type="password"], input[type="email"], input[type="number"],
input[type="tel"], input[type="url"], input[type="search"], textarea {
  font: 400 var(--io-type)/var(--io-lead) var(--ui);
  padding: var(--io-pad);
  background: var(--io-bg);
  border: 1px solid var(--line); border-radius: var(--r-s);
  color: var(--ink); width: 100%;
  box-shadow: inset -1px 1px 2px rgba(13, 27, 42, .07);
  cursor: text;
}
input:focus, textarea:focus { background: var(--io-bg-on); }
select {
  font: 600 var(--t-b) var(--ui);
  padding: 7px var(--sp-3);
  background: var(--pl-back); color: var(--pl-back-t);
  border: 1px solid var(--pl-back-e); border-radius: var(--r-s);
  box-shadow: var(--lift-p); cursor: pointer; min-height: 32px;
}

/* One button vocabulary, and nothing you can press is white. */
.btn, .ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font: 600 var(--t-b) var(--ui); border-radius: var(--r-s); cursor: pointer;
  padding: var(--sp-2) var(--sp-4); min-height: 36px; min-width: 24px;
  border: 1px solid transparent; transition: background var(--m-state), box-shadow var(--m-lift);
}
.btn { background: var(--act); color: #fff; border-color: var(--act-h); box-shadow: var(--lift-f); }
.btn:hover { background: var(--act-h); box-shadow: var(--lift-f-h); }
.btn:active { box-shadow: var(--press-f); }
.btn-lg { font-size: var(--t-m); padding: var(--sp-3) var(--sp-5); min-height: 44px; }
/* The same size on a ghost, which the door has asked for since it was written and never had:
   index.html carried `ghost ghost-lg` and nothing defined it, so the second button on the first
   screen anybody sees stood 36px beside a 44px one wearing a class that did nothing. */
.ghost-lg { font-size: var(--t-m); padding: var(--sp-3) var(--sp-5); min-height: 44px; }
/* The press that writes an answer into the advert, which is the whole of what stage three is,
   so it wears stage three rather than the product's brand green. Near-black on it for the
   reason given at the token: white on this green is 3.22:1. */
.btn-write { background: var(--stage-three); color: var(--stage-three-on); border-color: var(--stage-three-e); }
.btn-write:hover { background: var(--stage-three); box-shadow: var(--lift-f-h); }
/* The same press, putting back a line of stage two, in stage two's colour. */
.btn-write[data-stage="2"] { background: var(--stage-two); color: var(--stage-two-on); border-color: var(--stage-two-e); }
.btn-write[data-stage="2"]:hover { background: var(--stage-two); }
/* The record. Solid like the advert, because they are the two ways of taking something away
   and the screen should not rank them: the sentence under the row says the record is the only
   copy that will ever exist. Darker than --act so the two are told apart by more than position,
   which is what 1.4.1 asks for: the labels differ, the icons differ, and the weight matches. */
.btn-go { background: var(--act-h); border-color: #073B78; }
.btn-go:hover { background: #073B78; }
.ghost { background: var(--pl-back); color: var(--pl-back-t); border-color: var(--pl-back-e); box-shadow: var(--lift-p); }
.ghost:hover { background: var(--pl-back-h); border-color: var(--pl-back-eh); box-shadow: var(--lift-p-h); }
.ghost:active { box-shadow: var(--press-p); }
.ghost-go { background: var(--pl-go); color: var(--pl-go-t); border-color: var(--pl-go-e); }
.ghost-go:hover { background: var(--pl-go-h); border-color: var(--pl-go-eh); }
.ghost-keep, .ghost-keep-2 { background: var(--pl-yours); color: var(--pl-yours-t); border-color: var(--pl-yours-e); }
.ghost-keep:hover, .ghost-keep-2:hover { background: var(--pl-yours-h); border-color: var(--pl-yours-eh); }
.ghost-keep.ghost-keep-3 { background: var(--pl-yours3); color: var(--pl-yours3-t); border-color: var(--pl-yours3-e); }
.ghost-keep.ghost-keep-3:hover { background: var(--pl-yours3-h); border-color: var(--pl-yours3-eh); }
.ghost-warn { background: var(--pl-del); color: var(--pl-del-t); border-color: var(--pl-del-e); }
.ghost-warn:hover { background: var(--pl-del-h); border-color: var(--pl-del-eh); }
.ghost-s { font-size: var(--t-s); padding: 5px var(--sp-3); min-height: 30px; }
.ghost-nav { background: rgba(255, 255, 255, .10); color: var(--nav-fg); border-color: rgba(255, 255, 255, .22); box-shadow: none; }
.ghost-nav:hover { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .34); }
/* An unavailable control keeps aria-disabled, never disabled: a disabled element leaves the
 * tab order, so a keyboard or screen reader user can neither reach it nor find out why.
 *
 * And a control somebody can still reach, focus and be told about is a control they have to be
 * able to read. WCAG lets an inactive control off 1.4.3 altogether; that exemption is written
 * for a control nobody can get to, which is exactly what this one is not. It was --soft on the
 * grey plate, 2.79:1, and inside the guided pass a further opacity of .45 took it to 1.50:1,
 * which is not a low-contrast label so much as an absent one. It is --mid now, 5.32:1, and
 * neither of the two rules that dimmed it dims it any more.
 *
 * What says unavailable instead: the dashed edge, the grey plate, the flat shadow and the
 * cursor, four things, none of them colour alone and none of them reliant on the text fading.
 * The border colour is deliberately not overridden, so an unavailable red button still carries
 * the red edge and does not read as an unavailable blue one. */
[aria-disabled="true"] { border-style: dashed; color: var(--mid); background: var(--gry-t); box-shadow: none; cursor: default; }

.err { color: var(--red-h); font-size: var(--t-s); font-weight: 600; }

/* The short names for the four screens, from the width the long ones stop fitting beside the
   tools rather than from the width of a phone.

   They were written for a phone and only a phone, so from 621px up the bar wrapped to two rows
   at every width there is: measured, the long labels need 1,427px before the tools can share
   the line, and nothing above that exists on most desks. The cost of two rows is 46px of sticky
   header on every screen and at every scroll position, and --bar-h, which the rest of this
   sheet scrolls and positions against, says 60.

   What is lost is four words. What is kept: the screen somebody is on is still marked with
   aria-current and a filled plate, each link still carries its icon, and the page's own heading
   says the long name in full at the top of every one of them. */
@media (max-width: 1420px) {
  .navlink-t { display: none; }
  .navlink-s { display: inline; }
}

/* Narrower than the short names and the tools can share a line, so the bar wraps and is 104px
   rather than 60. --bar-h is what scroll-margin-top and the fixed panels are measured against,
   so it has to say what the bar actually is: at 60 against a 104px sticky bar, anything a link
   scrolls to lands under it, which is the trap WCAG 2.4.11 is about. It was wrong at every
   width until the line above; this is the band where it still has to be told. */
@media (max-width: 1139px) {
  :root { --bar-h: 104px; }
}

@media (max-width: 620px) {
  :root { --bar-h: 86px; }
  .wrap { padding: var(--sp-5) var(--sp-4); }
  .bar { gap: var(--sp-3); padding: var(--sp-2) var(--sp-4); }
  .bar-tools { width: 100%; }
}

/* ------------------------------------------------------------------ the check screen */

.paster-grid { display: grid; grid-template-columns: 1fr 15rem; gap: var(--sp-5); align-items: start; }
.paster-box textarea { min-height: 14rem; font-size: var(--t-m); }
.paster-acts { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); }
.paster-keep { margin-top: var(--sp-3); }
/* Why the last check produced nothing, under the button that produced nothing, and it stays
   there until the next check is started. A toast is gone in seconds and gone for good if
   somebody was looking at the button they had just pressed, which leaves a screen identical
   to the one before the press: the reasonable reading of that is a broken button. */
.goslot-fault:empty { display: none; }
.check-refused { margin-top: var(--sp-4); align-items: flex-start; }
/* A licence on this connection that has stopped counting, said before anything else in the
   panel: somebody who opens it after their allowance fell back to the default is here for
   that one answer. */
.allow-licence { margin: var(--sp-3) 0 0; }

.chips { border: 0; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.chip {
  display: block; width: 100%; text-align: left;
  font: 600 var(--t-b) var(--ui); cursor: pointer; min-height: 40px;
  padding: var(--sp-2) var(--sp-4); border-radius: var(--r-full);
  background: var(--pl-back); color: var(--pl-back-t);
  border: 1px solid var(--pl-back-e); box-shadow: var(--lift-p);
}
.chip:hover { background: var(--pl-back-h); }
/* ------------------------------------------------------------- a control somebody chose
 *
 * One look for every "pick one" control in this application: the advertiser chip, an option in
 * a segmented row, a reason on a report form, the settings in the console. The accent filled,
 * white on it at 6.2:1, bold, with a tick in front.
 *
 * It is a fill rather than a tint because a tint was the same weight on the page as the option
 * beside it. On the segmented rows it was worse than that: the unchosen hover state used the
 * same tint, so running a mouse along a row made three options look chosen at once.
 *
 * The tick is not decoration. A fill is a colour and a colour is never the only carrier, so the
 * mark has to be there for somebody who cannot tell the two apart, in print, and in forced
 * colours. aria-pressed or aria-checked is on every one of these in the markup.
 *
 * What this is NOT is where you are. The nav and the view control mark that, in the product's
 * green and in its ink, and they stay that way: where you are and what you have chosen are two
 * different facts and putting them in one colour would tell somebody that changing the view
 * changed their answer. Nor is it a toggle whose resting state is on, like the console's event
 * filters: there the interesting state is the one switched off, and filling every chip at rest
 * would paint the whole row.
 */
.chosen, .chip-on, .seg button.on, .reason.on {
  background: var(--act); color: #fff; border-color: var(--act-h);
  box-shadow: var(--press-p); font-weight: 700;
}
.chosen:hover, .chip-on:hover, .seg button.on:hover, .reason.on:hover {
  background: var(--act-h); color: #fff; border-color: var(--act-h);
}
.chosen::before, .chip-on::before, .seg button.on::before, .reason.on .reason-l::before {
  content: '\2713\00a0'; font-weight: 700;
}
/* The reason card stacks its label over its sub-line, so a ::before on the card itself would be
   a flex item and land on a line of its own above the label. It goes on the label instead. */

/* Asked for: the top of this screen is mostly air, so close it up.
   32px under a title that already carries 8px of its own margin put 65px between "Check an
   advert" and the first thing it is about. The title and the count it introduces are one
   statement read in one glance, so they stand as one. */
.result { margin-top: var(--sp-4); display: grid; gap: var(--sp-4); }
/* Nothing on the result may set the page's width. A grid column is as wide as the widest
   thing that cannot shrink inside it, and a web address in a written sentence cannot shrink:
   "https://brightpath.example/privacy" alone is wider than a phone with its gutters, and it
   pushed the result to 443px on a 390px screen. The cards stay the width of the page and the
   long word breaks where it has to. */
.result > * { min-width: 0; }
.did-text, .vacancy-add-t, .vacancy-text { overflow-wrap: anywhere; }
.did-text, .vacancy-add-t, .vacancy-text, .paster-box textarea { font-family: var(--read); }
/* Inside the advert, what belongs to the tool stays in the tool's face: the "Changed" and
   "Suggested" words, the badges and the buttons. */
.vacancy-text .swap-word, .vacancy-text button, .vacancy-text .mark { font-family: var(--ui); }
.result-head { font-size: var(--t-l); }
/* It takes focus when the paste panel is taken off the screen, so it needs a ring like anything
   else that can be focused. Inset, because a heading sits hard against the edge of the column. */
.result-head:focus-visible { outline: 2px solid var(--act); outline-offset: 3px; border-radius: var(--r-s); }
/* The waiting card takes focus the same way, when the panel that had it is hidden before there
   is a headline to land on. */
.result[tabindex]:focus-visible { outline: 2px solid var(--act); outline-offset: 3px; border-radius: var(--r-m); }
/* Whose jobs these are, beside the count it decides. The panel that used to carry this control
   is gone once there is a result, and this is the one input to a check that can be wrong
   without anything on the screen looking wrong. */
.result-top { display: flex; align-items: baseline; gap: var(--sp-2) var(--sp-4); flex-wrap: wrap; }
/* Its natural width, not a share of the row. It was `flex: 1 1 18rem`, which handed everything
   left over to the chips beside it: at 1240px that was 350px of column for two words and two
   buttons, and the row came out 101px tall to carry a 24px heading. */
.result-top > .result-head { flex: 0 1 auto; min-width: 0; }
/* One line, at the right edge, sized to what is in it. `margin-left: auto` rather than a flex
   grow on the heading, so the heading stays the width of its own words and the chips still hold
   the edge the column below them ends on. */
.result-who { display: flex; align-items: center; gap: var(--sp-2);
  flex: 0 0 auto; margin-left: auto; }
.result-who-l { font: 600 var(--t-xs) var(--ui); color: var(--mid);
  text-transform: uppercase; letter-spacing: .06em; white-space: nowrap; }
/* The same control, one step down in size, because here it sits beside a heading rather than
   under a question of its own.
   And laid out as one, which is the half that was missing. `.chip` is `display: block` with
   `width: 100%`, which is right in the panel it was written for, where the two are a stacked
   pick-one filling their fieldset, and wrong the moment they stand in a row: they went full
   width of whatever was left and stacked, one under the other, under a label of their own. */
.chip-s { display: inline-flex; align-items: center; width: auto; text-align: left;
  font-size: var(--t-s); padding: 5px var(--sp-3); min-height: 30px; }
.result-stale { margin-top: var(--sp-3); }
.result-stale p { margin: var(--sp-1) 0 0; max-width: 68ch; }
.result-stale-do { margin-top: var(--sp-3); }
.assumed { color: var(--mid); font-size: var(--t-s); }
.result-acts { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-2); }

/* Something the application produced for you to read: flat, on the rail, with a rule down
 * the left edge and a default cursor. Never the same treatment as a box you type into. */
.vacancy {
  background: var(--rail); border: 1px solid var(--line);
  border-left: 3px solid var(--act); border-radius: var(--r-s);
  padding: var(--sp-4); cursor: default;
}
.vacancy-text { white-space: pre-wrap; }
/* A line this product put into the advert, in the colour of the stage that put it there, and
   marked the way a changed phrase is marked a few lines above: a small word, the sentence, and
   one small way to take it back.

   It used to be a card. A 3px edge, a badge on its own, the sentence in a flex column and a
   plate button held off to the right, and three of them down an advert read as a form to fill
   in rather than as an advert with three lines added to it. The owner's words: the multiple
   boxes and buttons are too complex, align it with the inline mark. So it is the same shape as
   `.swap`, tinted ground and a 2px bar underneath in the stage's own colour, and the control is
   literally the same control. */
.vacancy-add {
  margin-top: var(--sp-3); padding: var(--sp-2);
  border-radius: var(--r-s); background: var(--gry-t);
  /* A shadow under the whole row, not a coloured rule under it.
     It carried `inset 0 -2px 0` in the stage's own colour, which drew a 2px line along the
     bottom edge and stopped there: a line under a box that the text and the buttons sit inside,
     rather than the box itself standing off the page. Asked for, and the line was doing a job
     the row already does twice over, because the stage is on the tint behind it and on the
     badge, in words, at the top of it. The shadow is the neutral elevation token, so the row is
     lit by the same light as everything else and the only things saying which stage it is are
     the two that were already saying it. */
  box-shadow: var(--sh);
  /* The badge on its own line, the sentence under it, and the controls in a column down the
     right spanning both.

     The badge used to be a word inside the sentence, and that is what the screenshot showing
     this asked about: it is up to 174px wide and the sentence flowed around it, so the second
     line of every wrapped sentence started back at the far left underneath the badge and no two
     lines in the list began in the same place. Three edges hold now: the badges share one, the
     sentences share one, and the controls share one.

     Beside the sentence rather than above it was built first and measured out. This panel
     stands in a column next to the score, and `.wrap` holds the page to 68rem, so the panel is
     614px at every width above about 1090 and never wider. Take 174 for the longest badge and
     166 for the controls and the sentence is left with 234, which reads four words to a line.
     A column that never fits is not an arrangement, so it is not one of the two.

     The right column is a fixed width rather than auto, because auto is sized per row and a row
     with one button would end somewhere a row with two does not. */
  display: grid; grid-template-columns: minmax(0, 1fr) var(--line-do-w);
  align-items: start; column-gap: var(--sp-3); row-gap: 2px;
}
.line-mark { grid-column: 1; grid-row: 1; }
.vacancy-add-t { grid-column: 1; grid-row: 2; }
.vacancy-add > .line-do { grid-column: 2; grid-row: 1 / span 2; }
.vacancy-add.stage-2 { background: var(--stage-two-t); }
.vacancy-add.stage-3 { background: var(--stage-three-t); }
/* The badge in its own column, at the top of the row and hard against the left of it, so the
   badges line up down the list however many lines the sentence beside each one runs to. It
   never wraps: a badge broken over two lines is a badge that is taller than the line it labels
   and a column that is no longer one width. */
.line-mark { justify-self: start; margin-right: 0; white-space: nowrap; }
/* Nothing else in this panel gets a column, so the old inline treatment stays for anything that
   is still a word inside a line. */
.vacancy-add .mark:not(.line-mark) { margin-right: var(--sp-2); vertical-align: 1px; }
/* The column the controls stand in, wherever a marked line has controls. One width and one
   edge across every row of every list, which is the whole of what makes them look aligned.
   Wide enough for the two this product puts there, Undo and Edit, at their own padding.

   Two slots rather than a row, which is the half that was still wrong. The row was pushed to
   the right edge, so a line carrying Undo alone put it where the line above had put Edit: the
   same word in two places, four lines down one advert, and nothing on the screen to say why it
   had moved. A control that moves cannot be aimed at, and what somebody learns about where it
   is is true of one line only.

   Two tracks of equal width, not two tracks sized to what is in them, and that distinction was
   measured rather than reasoned: with `auto` tracks packed to the right edge the empty second
   track is zero wide, so Undo landed at 568 on the line with no Edit and 477 on the line with
   one. The fault, reproduced by the fix. Halves hold whether or not anything stands in them, so
   Undo is at 477 on every line and Edit at 564 on every line that has one. The controls fill
   their half as well, because two buttons of different lengths in fixed slots still read as a
   ragged column. */
.line-do {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2); align-items: center;
}
.line-do-1 { grid-column: 1; }
.line-do-2 { grid-column: 2; }
/* Report on a row of its own under the two, across both, so Remove and Change keep their places
   and all three keep a readable width. */
.line-do-3 { grid-column: 1 / -1; display: flex; }
/* Report in this column is the size of Remove and Change beside it. */
.line-do .report-wrap { margin-left: 0; width: 100%; }
.line-do .btn-report { width: 100%; padding: 3px 4px; font-size: var(--t-xs); min-height: 24px; }
/* Raised, with a lift under the pointer and a press when it goes down. Asked for: the buttons
   should look three dimensional and change on hover.
   Only in this column. `.swap-undo` is also the control on a changed phrase inside the running
   text of the advert, and there a plate genuinely does break the line box, which is the reason
   the flat version was written. The reason stopped applying the moment these moved into a
   column of their own; it still applies to the other one, so the two now differ. */
.line-do .swap-undo {
  width: 100%; margin-left: 0; justify-content: center; padding: 3px 4px;
  background: var(--pl-back); color: var(--pl-back-t); border-color: var(--pl-back-e);
  box-shadow: var(--lift-p); transition: box-shadow var(--m-state), transform var(--m-state);
}
.line-do .swap-undo:hover {
  background: var(--pl-back-h); border-color: var(--pl-back-eh);
  box-shadow: var(--lift-p-h); transform: translateY(-1px);
}
/* And it goes down when it is pressed, which is the other half of a control that looks raised:
   a button that lifts and never lands reads as a picture of a button. */
.line-do .swap-undo:active { box-shadow: var(--press-p); transform: translateY(1px); }
/* Nothing moves where the page is set to be still, by either of the two switches that say so.
   The shading still changes, because a change of shading is not motion, and it is what says the
   control is under the pointer once the lift is gone. The rule at the top of this sheet kills
   the transition; only the offset itself has to be named here. */
:root[data-motion="off"] .line-do .swap-undo:hover,
:root[data-motion="off"] .line-do .swap-undo:active { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .line-do .swap-undo:hover, .line-do .swap-undo:active { transform: none; }
}
.line-do:empty { display: none; }
/* On a narrow screen the column costs more than it buys: the fixed width out of a phone's
   width leaves the sentence reading four words to a line. The controls drop under the words
   there, still in their own two slots so they do not move between lines. */
@media (max-width: 560px) {
  /* One column, in reading order: the badge, the sentence, then the controls. */
  .vacancy-add { grid-template-columns: minmax(0, 1fr); }
  .line-mark, .vacancy-add-t, .line-do { grid-column: 1; grid-row: auto; }
  /* The tracks stop stretching to the full width of a phone, which would put two buttons half
     a screen apart. They keep their order and their two slots. */
  .line-do { grid-template-columns: repeat(2, minmax(0, 5rem)); justify-content: start; }
}
/* The boxes behind Edit, under the line they belong to. Its own summary is hidden because the
   Edit button in the line is what opens it; a details with two openers is a box somebody can
   close with one control and not the other.
   Scoped to the panel, which is both where it applies and what wins: `.cap-fold > summary`
   lives further down this file and would otherwise take the rule on source order. */
.vacancy-live .did-fold-inline { margin: 0 0 var(--sp-3); }
.vacancy-live .did-fold-inline > summary { display: none; }
/* And it is not there at all until Edit opens it. With the summary hidden a closed details is
   an empty box that still draws its own border, which put a thin amber line under every added
   line in the advert. */
.vacancy-live .did-fold-inline:not([open]) { display: none; }
.vacancy-ref { margin-top: var(--sp-4); color: var(--mid); }

/* Every mark carries a word, not only a colour. */
.mark {
  display: inline-block; flex: none; font: 700 var(--t-xs) var(--ui);
  letter-spacing: .02em; padding: 3px 8px; border-radius: var(--r-full);
  min-height: 24px; line-height: 18px;
}
.mark-green { background: var(--grn); color: #fff; }
.mark-grey { background: var(--gry-t); color: var(--pl-back-t); border: 1px solid var(--gry); }
.mark-must_fix { background: var(--red); color: #fff; }
.mark-should_fix { background: var(--amb-d); color: #fff; }
.mark-have_a_look { background: var(--gry-t); color: var(--pl-back-t); border: 1px solid var(--gry); }

.block { display: grid; gap: var(--sp-3); }
.flags { display: grid; gap: var(--sp-2); }
.flag {
  display: flex; gap: var(--sp-3); align-items: flex-start; flex-wrap: wrap;
  background: var(--surf); border: 1px solid var(--line);
  border-left: 3px solid var(--gry); border-radius: var(--r-s); padding: var(--sp-3);
}
.flag-must_fix { border-left-color: var(--red); }
.flag-should_fix { border-left-color: var(--amb); }
.flag-t { flex: 1 1 18rem; display: grid; gap: 2px; }
.flag-say { color: var(--mid); font-size: var(--t-s); }
/* Where they have already answered the question behind a flag. It stays a flag, because the
   advert still says nothing, and it says their answer is on the record. */
.flag-answered { display: flex; gap: 6px; align-items: center; font-size: var(--t-xs);
  color: var(--prod-d); font-weight: 600; margin-top: 2px; }
.flag-answered .i { width: 13px; height: 13px; flex: none; }

/* The fix, on the finding it fixes.
   Folded rather than open, because a list of six findings with six forms under them is a list
   nobody reads, and shut with a summary that says what pressing it gets you is the same
   information at a tenth of the height. It is marked in the product's own colour so a row
   that can be put right looks different from a row that cannot, at a glance, down a list. */
.fold-fix { margin-top: 6px; }
.fold-fix > summary { font-size: var(--t-s); font-weight: 600; color: var(--prod-d);
  display: flex; gap: 6px; align-items: center; }
.fold-fix > summary .i { width: 14px; height: 14px; flex: none; }
.fold-fix > .cap, .fold-fix > .gap { margin-top: var(--sp-2); }
.fold-fix > .hint { margin-top: 4px; }
/* And the rows nothing can be written for say so, in the grey of a note rather than the
   colour of an action, because there is nothing here to press. */
.flag-mine { font-size: var(--t-xs); color: var(--mid); margin-top: 4px; }
/* A finding that putting right will not move the number, marked on the row. It sits on its
   own line under the wording rather than beside the band, because two marks on one line read
   as one two-part badge. */
.flag-quiet { justify-self: start; margin-top: 4px; }
/* And the same thing said once, beside the number it is about. */
.notice {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  border-radius: var(--r-s); padding: var(--sp-3); font-size: var(--t-s);
  border: 1px solid var(--line); background: var(--surf);
}
.notice-warn { background: var(--amb-t); border-color: var(--amb); color: var(--amb-on-tint); }
.notice-deep { background: var(--vio-t); border-color: var(--vio); color: var(--vio); }
/* A button whose label carries what it costs underneath it. The price used to live in a title
   tooltip, which a touch user and a keyboard user never see. */
.btn-stack { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.btn-sub { font-size: var(--t-xs); opacity: 0.85; font-weight: 400; }

.notice-scope { background: var(--tea-t); border-color: var(--tea); color: var(--tea); }
.notice-keep { background: var(--gry-t); color: var(--pl-back-t); }
.notice-error { background: var(--red-t); border-color: var(--red); color: var(--red-h); }

.fold { border: 1px solid var(--line); border-radius: var(--r-s); background: var(--surf); }
.fold > summary {
  cursor: pointer; padding: var(--sp-3) var(--sp-4); font-weight: 600;
  display: flex; justify-content: space-between; gap: var(--sp-3); min-height: 44px; align-items: center;
}
.fold > *:not(summary) { padding: 0 var(--sp-4) var(--sp-4); }
.fold-n { color: var(--mid); font-weight: 400; font-size: var(--t-s); }
.rulelist { display: grid; gap: var(--sp-3); }
#rules-lenses { display: grid; gap: var(--sp-2); }

/* A toast is a thing that floats over the page, and it has to look like one.
   The rail was a fixed 34rem, which is exactly the width of the score card and centred on the
   same axis, so "Wording checked." arrived as a dark bar ruled across the bottom of that card:
   square-cornered, card-width, flush to both its edges. It read as part of the card, and as a
   broken part of it. The rail now takes the width of its message and no more, so a short
   sentence is a short pill that is plainly sitting on top of the page rather than built into
   it. The cap is what stops a long one running the width of a desktop. */
.toast-rail {
  /* The middle of the screen, where it is seen, and above every window, the guide included. */
  /* Pinned to both sides and centred inside them, rather than moved half its own width from the
     middle: that way it shrank to half the screen on a phone and a sentence became a column. */
  position: fixed; left: var(--sp-4); right: var(--sp-4); top: 50%; transform: translateY(-50%);
  z-index: 55; display: grid; justify-items: center; gap: var(--sp-2);
  pointer-events: none;
}
.toast {
  pointer-events: auto; display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-full); max-width: min(34rem, 100%);
  font-size: var(--t-m); font-weight: 600; line-height: 1.4;
  animation: fade var(--m-panel) both;
}
.toast-t { margin: 0; text-align: left; }
.toast-i svg { width: 20px; height: 20px; }
/* Something worked: ink with a white ring, so it stands off a dark footer as well as the page. */
.toast-done {
  pointer-events: none;
  background: var(--nav); color: #fff;
  box-shadow: 0 0 0 2px #fff, var(--sh3);
}
.toast-done .toast-i { color: var(--nav-grn); }
/* Something is stopping you: amber, the colour this product already uses for a warning. */
.toast-warn {
  background: var(--amb-t); color: var(--ink); border: 2px solid var(--amb);
  border-radius: var(--r-l); padding: var(--sp-4) var(--sp-3) var(--sp-4) var(--sp-4);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .9), var(--sh3);
}
.toast-warn .toast-i { color: var(--amb-on-tint); }
.toast-x {
  flex: none; display: inline-grid; place-items: center; width: 32px; height: 32px;
  border: 1px solid var(--amb); border-radius: var(--r-full); background: #fff; color: var(--ink); cursor: pointer;
}
.toast-x:hover { background: var(--amb-t); }
.toast-x .i svg { width: 16px; height: 16px; }

@media (max-width: 720px) {
  .paster-grid { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  /* Copy used to be pinned to the bottom of the screen, in thumb reach, because it was the
     primary action. It is not any more: the result offers one way on and one way out, and the
     way out lives inside the finish route near the top. Left sticky after that move it would
     float over the reveal for the whole of the scroll. */
  .result-acts .btn { flex: 1 1 100%; }
  .result-acts .btn-lg { flex: 1 1 100%; }
}

/* The icon slot. Icons are painted into these at boot; the markup carries no SVG. */
.i { display: inline-flex; align-items: center; justify-content: center; flex: none; }
.paster { display: grid; gap: var(--sp-3); }
.flag-assume { border-left-color: var(--gry); }

/* Asked where the answer is first needed, never in a setup wizard. */
/* The offer fold. Its panels sit inside a details, so they need a little air under the
   summary rather than the margin a standalone block carried. */
.fold-offer > .cap { margin-top: var(--sp-3); }

/* An offer is stage three wherever it appears, because it is a thing the person does: a press,
   or a detail typed in. It was amber, which in this product means caution and is the colour of
   the part of a written sentence that came from them and might be wrong. That made the one
   panel somebody is meant to act on look like a warning about itself, and inside the guided
   pass it put a yellow box in the middle of a green one.

   Green here is the third wedge of the dial and the third stage of the journey. The ink on it
   is the darker product green rather than the stage colour: the stage colours are fills,
   measured against the card at 3:1, and text needs 4.5. This pairing is 7.24:1. */
/* Asked for: condense it as far as it will go and keep every control. What came out was the
   line that said what the offer was, which three other screens already say; what is left is
   the press, the sentence it writes, and the fold. The padding and the gaps come down a step
   with it, because a card of two rows at the spacing of a card of five reads as a box with
   something missing from it. */
.cap {
  background: var(--stage-three-t); border: 1px solid var(--stage-three); border-left-width: 3px;
  border-radius: var(--r-s); padding: var(--sp-3); display: grid; gap: var(--sp-2);
}
/* The one press, and the sentence it writes, side by side. Showing the words before the press
   is the difference between accepting a change and accepting a description of one. */
.cap-now { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; margin-top: 0; }
.cap-now .btn { flex: none; }
.cap-line { font-size: var(--t-s); font-style: italic; color: var(--ink); flex: 1 1 20rem; min-width: 0; }
/* The width of the card, not a column inside it.
   It carried max-width: 68ch, which is the readable measure and the right default for a body
   of prose. On this card it was wrong twice over: at --t-s that is about 440px inside a panel
   near 900px, so the paragraph filled less than half the width and then wrapped for three
   lines under a heading that ran the whole way, which reads as a column that failed to
   justify rather than as a measure somebody chose. Asked for: run it across the box.
   The cost is stated rather than hidden: on a wide screen these lines are longer than the
   measure typography would pick. It is two sentences inside a fold somebody opened on purpose,
   and the alignment of the card is what was being read as broken. */
.cap-more { font-size: var(--t-s); color: var(--mid); margin-top: 0; }
/* The fork, which is a fold now rather than a heading over a form that was always open. The
   summary is the whole of the label: an offer whose one press is a complete answer should not
   put three boxes on the screen to say so. */
/* Inside the guided pass there is no box at all. The card is already stage three, edge to
   edge, and a second green box inside it is the same statement twice with a line drawn round
   it. Owner's words: the internal green shaded box needs to be removed, it can just be white
   with no inside box. Outside the walk the panel still needs its own ground, because there it
   is one thing among several and nothing else says it is an offer. */
.walk .cap { background: transparent; border: 0; border-radius: 0; padding: 0; }
.cap-fold { background: transparent; border-color: var(--stage-three); }
.cap-fold > summary {
  padding: var(--sp-2) var(--sp-3); min-height: 36px; justify-content: flex-start;
  font: 600 var(--t-s) var(--ui); color: var(--prod-d);
}
.cap-fold > summary:hover { background: var(--stage-three-t); border-radius: var(--r-s); }
/* The same chevron the other reveals wear, drawn from two borders rather than a glyph so it
   lands the same whatever font is in use. A fold nobody can see is a fold nobody opens. */
.cap-fold > summary::after {
  content: ''; flex: none; width: 8px; height: 8px; margin-left: var(--sp-2);
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px); transition: transform var(--m-state);
}
.cap-fold[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
.cap-fold > .cap-fold-in { padding: var(--sp-2) var(--sp-3) var(--sp-3); display: grid; gap: var(--sp-2); }
.cap-fold[open] > summary { border-bottom: 1px solid var(--stage-three); border-radius: var(--r-s) var(--r-s) 0 0; }

/* A rule that is only on this advert because the job works with children. The colour is the one
   this product already uses for a child-facing check, so the strip and the notice at the top of
   the result are recognisably the same fact. It names the guidance and does not call it a duty:
   the register has it as statutory guidance that says should. */
.safeg {
  display: flex; gap: var(--sp-3); align-items: flex-start; margin: 0;
  background: var(--vio-t); border: 1px solid var(--vio); border-left-width: 3px;
  border-radius: var(--r-s); padding: var(--sp-2) var(--sp-3); color: var(--vio);
  font-size: var(--t-b);
}
.safeg .i { flex: none; margin-top: 1px; }
.safeg-t { min-width: 0; }
/* Full strength, not dimmed. The citation at 85 per cent on this ground measures 4.39:1,
   which is under the 4.5 this size of text needs, and a citation nobody can read is the part
   of the strip that makes the rest of it checkable. */
.safeg-cite { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--vio); }
.cap-fs { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.cap-f { flex: 1 1 12rem; }
.cap-acts { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }
/* Inside the guided pass the card has no ground of its own, so the fold is the only box on it
   and it can stand tighter still. */
.walk .cap-fold > summary { min-height: 32px; }

/* WCAG 2.2 SC 2.5.8. Every target is at least 24 by 24, including a text link in a row of
 * them, where the natural line box is shorter than that. */
.foot-legal a, .hint a {
  display: inline-flex; align-items: center; min-height: 24px;
}

/* ------------------------------------------------------------------ the development gate */

.devgate-body { background: var(--nav); min-height: 100vh; display: grid; place-items: center; padding: var(--sp-5); }
.devgate { width: min(30rem, 100%); display: grid; gap: var(--sp-4); }
.devgate-card { border-top: 6px solid var(--red); display: grid; gap: var(--sp-4); }
.devgate-mark { display: flex; align-items: center; gap: var(--sp-2); font: 700 10px var(--ui); letter-spacing: .06em; color: var(--mid); }
.devgate-tag {
  justify-self: start; background: var(--red); color: #fff;
  font: 700 10px var(--ui); letter-spacing: .1em; padding: 4px 10px; border-radius: var(--r-s);
}
.devgate-lede { color: var(--mid); }
.devgate-form { display: grid; gap: var(--sp-2); }
.devgate-note { color: var(--soft); font-size: var(--t-s); }
.devgate-foot { color: var(--nav-dim); font-size: var(--t-s); text-align: center; }

.flag-quote { color: var(--mid); font-size: var(--t-s); font-style: italic; }

/* A change to the wording, marked where the wording is. */
.swap { border-radius: var(--r-s); padding: 1px 4px; }
.swap-on { background: var(--grn-t); box-shadow: inset 0 -2px 0 var(--grn); }
/* A rewording on offer: the person's own words, underlined in stage three's green, and under them
   a box saying what is on offer and why. The box is the tool talking, so it is in the tool's face,
   and the new wording in it is advert text, so it is in the advert's. */
.swap-offer { padding: 0; }
.swap-offer-was { text-decoration: underline dashed var(--stage-three-e) 2px; text-underline-offset: 4px; }
.vacancy-text .offer-box {
  display: grid; gap: var(--sp-2); justify-items: start; margin: var(--sp-2) 0 var(--sp-3);
  padding: var(--sp-3); white-space: normal; font: 400 var(--t-s)/1.5 var(--ui); color: var(--ink);
  background: var(--stage-three-t); border: 1px solid var(--stage-three-e); border-left-width: 4px;
  border-radius: var(--r-s);
}
.offer-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-weight: 600; }
.vacancy-text .offer-new { font-family: var(--read); font-size: var(--t-b); }
.offer-acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); width: 100%; }
.offer-why { color: var(--mid); }
.swap-offer-2 .swap-offer-was { text-decoration-color: var(--stage-two-e); }
.vacancy-text .swap-offer-2 .offer-box { background: var(--stage-two-t); border-color: var(--stage-two-e); }
.swap-word {
  font: 700 var(--t-xs) var(--ui); letter-spacing: .02em; margin-right: var(--sp-2);
  padding: 1px 6px; border-radius: var(--r-full);
}
.swap-on .swap-word { background: var(--grn); color: #fff; }
/* An icon as well as a word, because a colourless one-word button in a column of them is told
   apart by reading it, and the two here are opposites: a press that takes the line out and a
   press that opens it up. The icons are the ones this product already uses for those two acts,
   the arrow that goes back and the pen, so the pair reads the same here as on every other
   screen. Each also carries a title saying what it does, which is the mouse-over; the word on
   the button is the name and the title is the description, never a different name. */
.swap-undo {
  margin-left: var(--sp-2); font: 600 var(--t-xs) var(--ui); cursor: pointer;
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-s);
  padding: 2px 8px; min-height: 24px;
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
}
.swap-undo .i { flex: none; }
.swap-undo .i svg { width: 13px; height: 13px; }
.swap-undo:hover { background: var(--io-bg); }

/* ==========================================================================
   The Admin console.

   This is the Operations console of the first application, renamed and otherwise
   untouched, because the two have to be identical to look at and to use. The sheet
   below is that console's own sheet, carried across whole: every class, every
   treatment, every comment. Where a name collided with something this application
   already had, the console's name changed and nothing else did.

   Read only throughout, so it takes the flat output language: on the rail, no
   raised affordance, a rule down the left of the table. The one thing that is not
   read only is the password field, which is inset like every other field a person
   types into.
   ========================================================================== */

.admin-lock{padding:var(--sp-6);max-width:520px}
.admin-lock .btn{margin-top:var(--sp-4)}
.admin-lock code{font-family:var(--mono);font-size:var(--t-s);background:var(--gry-t);padding:1px 5px;border-radius:4px}

/* --------------------------------------------------------------------------
   The console shell: a bar, a menu that is always there, and one pane.

   One subject on screen at a time, chosen by pressing something. The menu holds
   the numbers, so choosing where to look and seeing how much is there are the
   same act. Below 900px the menu becomes a drawer behind the button in the bar,
   because a permanent menu on a phone is a permanent third of the screen.
   -------------------------------------------------------------------------- */

.admin-bar{
  display:flex;align-items:flex-end;gap:var(--sp-3);flex-wrap:wrap;
  padding-bottom:var(--sp-4);border-bottom:1px solid var(--line);margin-bottom:var(--sp-4)
}
.admin-day-tools{display:flex;align-items:flex-end;gap:var(--sp-3);flex-wrap:wrap;flex:1 1 auto}

/* Day and Period line up, which they did not.

   Reported by Phil: the two are offset. Both are a label over a list, but the period
   carries an information button and it was appended after the list, inside the same
   block, so that block was one row taller and the row aligned its children at the
   bottom, which pushed the period's list up by the height of the button. The block is a
   grid now: the label spans the top row, the list and the button sit side by side on the
   second, and a block with no button leaves that cell empty. Both blocks are then two
   rows of the same heights whatever is in them, so they line up by construction rather
   than because somebody counted the pixels. */
.admin-day{min-width:min(200px,100%);display:grid;grid-template-columns:1fr auto;align-items:center;gap:0 var(--sp-2)}
.f.admin-day > label.lbl{grid-column:1 / -1;margin-bottom:5px}
.admin-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-left:auto}
.admin-actions-out{margin-left:auto;flex:none}
.admin-shell{display:block}

/* Where the tokens went.

   Five blocks, each answering one of the questions somebody watching a bill has: what it
   cost, which stage it is in, what is multiplying the calls, whether the cache is earning
   anything, and which individual checks were the expensive ones. Each is flat on the rail
   with a rule down the left edge, because every one of them is something the application
   worked out for you to read rather than something you operate. The one that turns amber
   is the cache block when the cache is costing more than it saves, which is a condition
   worth noticing rather than a number worth reading. */
.spend{display:flex;flex-direction:column;gap:var(--sp-5)}
.spend-b{
  background:var(--rail);border:1px solid var(--line2);border-left:3px solid var(--prod);
  border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-4);
  display:flex;flex-direction:column;gap:var(--sp-3)
}
.spend-b-warn{border-left-color:var(--amb);background:var(--amb-t)}
.spend-h{font-size:var(--t-m);font-family:var(--disp);font-weight:600}
.spend-s{color:var(--mid);font-size:var(--t-s);max-width:78ch}
.spend-figs{display:flex;flex-wrap:wrap;gap:var(--sp-5) var(--sp-6)}
.spend-fig{display:flex;flex-direction:column;gap:2px;min-width:0}
/* Tabular figures, because these are read against each other down a row. */
.spend-fig-n{font-family:var(--disp);font-size:var(--t-l);font-weight:600;line-height:1;font-variant-numeric:tabular-nums}
.spend-fig-l{color:var(--mid);font-size:var(--t-s)}
/* The one sentence on the pane that says what to do rather than what happened. */
.spend-lever{
  font-size:var(--t-s);color:var(--ink);background:var(--surf);
  border:1px solid var(--line);border-radius:var(--r-s);padding:var(--sp-3);max-width:78ch
}

/* The console menu floats. The button is fixed on screen whatever the pane has
   scrolled to, and the named list of sections opens above it. It lives on the left
   because the development toolbar owns the bottom right on a development site, and
   two floating controls in one corner is one of them unreachable. */
.admin-float{
  position:fixed;left:var(--sp-4);bottom:var(--sp-4);z-index:48;
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-2)
}
/* Loud on purpose. Every section of this console except the overview is behind it, and
   Phil went looking for the reported flags log and did not find it, because a quiet
   button in a corner reads as a utility rather than as the way to everything. */
.admin-fab{
  box-shadow:var(--lift-f-h);border-radius:var(--r-full);min-height:52px;padding:0 var(--sp-5);
  font-weight:700;border:2px solid var(--surf)
}
.admin-fab:hover{box-shadow:var(--lift-f-h),-12px 12px 28px rgba(11,95,191,.22)}
.admin-fab:active{box-shadow:var(--press-f)}
.admin-fab .i{width:20px;height:20px}
.admin-nav{
  display:flex;flex-direction:column;gap:2px;
  width:min(320px,calc(100vw - 32px));max-height:min(65vh,560px);overflow-y:auto;
  background:var(--surf);border:1px solid var(--line);border-radius:var(--r-m);
  box-shadow:var(--sh3);padding:var(--sp-3)
}
.nav-lead{font:700 var(--t-xs) var(--ui);letter-spacing:.06em;text-transform:uppercase;color:var(--mid);margin-bottom:var(--sp-2)}
.navgroup{display:flex;flex-direction:column;gap:2px}
.navitem{
  display:flex;align-items:center;gap:var(--sp-2);width:100%;text-align:left;min-height:40px;
  padding:6px var(--sp-3);border:1px solid var(--pl-back-e);border-radius:var(--r-s);
  background:var(--pl-back);color:var(--pl-back-t);cursor:pointer;font:600 var(--t-s) var(--ui);min-width:0;
  box-shadow:var(--lift-p);
  transition:background var(--m-state),border-color var(--m-state),box-shadow var(--m-lift)
}
.navitem:hover{background:var(--pl-back-h);border-color:var(--pl-back-eh);box-shadow:var(--lift-p-h)}
.navitem:active{box-shadow:var(--press-p)}
/* Where you are, in the product's green, which is what every other you-are-here marker
   in this application uses. Never the forward tint: where you are and what you can take
   are not the same thing and must not be the same colour. */
.navitem.on{background:var(--prod-t);border-color:var(--prod);color:var(--prod-d);box-shadow:var(--lift-p)}
.navitem-l{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.navitem-n{
  margin-left:auto;font:600 var(--t-xs) var(--mono);color:var(--mid);
  background:var(--tone-t,var(--gry-t));border-radius:var(--r-full);padding:1px 8px;flex:none
}
.navitem.tone-bad .navitem-n,.navitem.tone-warn .navitem-n{color:var(--ink)}
.navitem-mark{
  width:8px;height:8px;flex:none;border-right:2px solid var(--mid);border-bottom:2px solid var(--mid);
  transform:rotate(-45deg);transition:transform var(--m-state)
}
.navitem-group[aria-expanded="true"] .navitem-mark{transform:rotate(45deg)}
.navsub{display:flex;flex-direction:column;gap:2px;margin:2px 0 var(--sp-2) var(--sp-3);border-left:2px solid var(--line);padding-left:var(--sp-2)}
.navitem-leaf{font-weight:500;font-size:var(--t-xs);min-height:34px}
.navitem-leaf .navitem-l{font-family:var(--mono)}

.admin-pane{min-width:0}
.pane-head{margin-bottom:var(--sp-4);display:grid;grid-template-columns:auto auto 1fr;align-items:center;gap:var(--sp-2) 4px}
.pane-info{justify-self:start}

.admin-tiles{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));
  gap:var(--sp-3)
}
.admin-tile{
  background:var(--rail);border-radius:var(--r-s);padding:var(--sp-3) var(--sp-4);
  border-left:3px solid var(--prod);display:flex;flex-direction:column;gap:2px;min-width:0;
  width:100%;text-align:left;cursor:pointer;border-top:none;border-right:none;border-bottom:none
}
.admin-tile:hover{background:var(--gry-t)}
.admin-tile-n{font-family:var(--disp);font-size:var(--t-xl);font-weight:600;line-height:1}
.admin-tile-l{font-size:var(--t-s);color:var(--mid)}
.admin-tile-go{font-size:var(--t-xs);color:var(--prod);font-weight:600;margin-top:4px}
/* The movement on a tile. Green where the number went the way anybody wanted, red
   where it did not, grey where neither direction is good or bad and colouring it would
   be inventing a judgement. Every one of them also carries the word, because a green
   number and a red number that are otherwise identical carry their meaning in colour
   alone, and nothing here is allowed to do that. */
.admin-move{display:inline-flex;align-items:baseline;gap:4px;font-size:var(--t-xs);font-weight:600;margin-top:3px}
.admin-move-good{color:var(--grn)}
.admin-move-bad{color:var(--red)}
.admin-move-flat{color:var(--mid)}
.admin-move-arrow{font-size:11px;line-height:1}
.admin-move-was{color:var(--mid);font-weight:400}

/* What the period can actually speak for. */
.admin-cover{
  background:var(--amb-t);color:var(--amb-on-tint);border-radius:var(--r-s);
  padding:var(--sp-2) var(--sp-3);font-size:var(--t-s);margin-bottom:var(--sp-3)
}

/* The rates. Not counts: what a day of this costs and what a check costs, which are
   two different questions and cannot share a number. */
.admin-rates{margin-top:var(--sp-5);padding-top:var(--sp-4);border-top:1px solid var(--line)}
.admin-rates-h{font-size:var(--t-m);margin-bottom:var(--sp-3)}
.rate-list{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));
  gap:var(--sp-3);margin-bottom:var(--sp-3)
}
.rate{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--act);
  border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-3);min-width:0
}
.rate-n{font-family:var(--disp);font-size:var(--t-l);font-weight:600;line-height:1.1}
.rate-l{font-size:var(--t-s);color:var(--mid);margin-top:2px}
.rate-s{font-size:var(--t-xs);color:var(--mid);margin-top:4px}
.admin-empty{color:var(--mid);padding:var(--sp-5);text-align:center}

/* --------------------------------------------------------------------------
   The console's charts.

   Colour carries one meaning throughout and it is the product's own palette, run
   through the contrast and colour blindness validator rather than chosen by eye:
   green is the product working, amber is something refused, red is something that
   failed, blue is neutral measurement. Status colours are reserved and never used
   as a series.

   Every chart carries a single series. Green against red measures a colour
   blindness separation of 5.4 where 8 is the floor, so a stacked bar of checks,
   refusals and failures would be unreadable to a red-green colour blind reader.
   Three small multiples say the same thing to everybody.
   -------------------------------------------------------------------------- */

.tone-ok    { --tone:var(--prod); --tone-t:var(--prod-t) }
.tone-clear { --tone:var(--grn);  --tone-t:var(--grn-t) }
.tone-act   { --tone:var(--act);  --tone-t:var(--act-t) }
.tone-warn  { --tone:var(--amb);  --tone-t:var(--amb-t) }
.tone-bad   { --tone:var(--red);  --tone-t:var(--red-t) }
.tone-neutral { --tone:var(--mid); --tone-t:var(--gry-t) }

.admin-h{font-size:var(--t-l);margin:0}
.chart-note{font-size:var(--t-s);color:var(--mid);margin-top:var(--sp-3);max-width:60ch}
.chart-empty{font-size:var(--t-s);color:var(--mid);padding:var(--sp-4) 0}

/* Hourly small multiples. Twenty four real buttons per row, not twenty four
   rectangles: an hour you cannot press is a number you have to go and find again
   by hand, which was the whole complaint. */
.chart-rows{display:flex;flex-direction:column;gap:var(--sp-4)}
.hour-row{min-width:0}
.hour-head{display:flex;align-items:center;gap:7px;margin-bottom:5px;font-size:var(--t-s)}
.hour-key{width:9px;height:9px;border-radius:3px;flex:none;background:var(--tone)}
.key-ok{background:var(--prod)} .key-warn{background:var(--amb)} .key-bad{background:var(--red)}
.hour-label{font-weight:600}
.hour-total{margin-left:auto;font-family:var(--mono);color:var(--mid)}
.hourgrid{display:grid;grid-template-columns:repeat(24,minmax(0,1fr));gap:2px;align-items:end;height:52px}
.hourbar{
  display:flex;align-items:flex-end;height:100%;min-width:0;padding:0;cursor:pointer;
  background:var(--line2);border:1px solid transparent;border-radius:3px;overflow:hidden
}
.hourbar-fill{display:block;width:100%;height:var(--h,0);border-radius:2px;background:var(--mid)}
.hourbar.bar-ok .hourbar-fill{background:var(--prod)}
.hourbar.bar-warn .hourbar-fill{background:var(--amb)}
.hourbar.bar-bad .hourbar-fill{background:var(--red)}
.hourbar:hover{border-color:var(--soft)}
.hourbar.on{border-color:var(--ink)}
.hourbar-empty{cursor:default}
:root[data-motion="on"] .hourbar-fill{animation:bar-rise var(--m-panel) var(--ease-panel) both}
@keyframes bar-rise{from{height:0}to{height:var(--h,0)}}
/* --soft measures 3.13:1 and fails AA for text. It is the same trap decision 22
   recorded for form labels, and an axis label is text like any other. */
.hour-axis{display:flex;justify-content:space-between;font:500 var(--t-xs)/1 var(--mono);color:var(--mid);margin-top:var(--sp-2)}

/* Horizontal bars, one measure across identities */
.chart-bars{display:flex;flex-direction:column;gap:var(--sp-2)}
.bar-group{font:700 var(--t-xs) var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid);margin-top:var(--sp-3)}
.bar-group:first-child{margin-top:0}
.bar-row{
  display:grid;grid-template-columns:minmax(0,14rem) minmax(0,1fr) auto;gap:var(--sp-3);
  align-items:center;font-size:var(--t-s);width:100%;text-align:left;padding:4px var(--sp-2);
  border:1px solid transparent;border-radius:var(--r-s);background:none;color:var(--ink)
}
/* A row you can open is a button and looks like one on hover. A row you cannot is
   neither, because an inert thing that looks pressable is worse than one that is not. */
.bar-row-go{cursor:pointer}
.bar-row-go:hover{background:var(--gry-t);border-color:var(--line)}
.bar-row-go.on{background:var(--prod-t);border-color:var(--prod)}
.bar-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:var(--t-xs)}
.bar-track{height:10px;background:var(--line2);border-radius:5px;overflow:hidden;min-width:0}
.bar-fill{display:block;height:100%;border-radius:5px;width:var(--w,0)}
.bar-fill.bar-ok{background:var(--prod)} .bar-fill.bar-warn{background:var(--amb)}
.bar-fill.bar-bad{background:var(--red)} .bar-fill.bar-act{background:var(--act)}
:root[data-motion="on"] .bar-fill{animation:bar-grow .6s var(--ease-panel) both;animation-delay:var(--delay,0ms)}
@keyframes bar-grow{from{width:0}to{width:var(--w,0)}}
.bar-value{font-family:var(--mono);font-size:var(--t-xs);color:var(--mid);white-space:nowrap}

/* Filter chips */
.admin-filters{display:flex;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.chiprow{display:flex;gap:var(--sp-2);flex-wrap:wrap}
.chipf{
  display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:var(--r-full);
  border:1px solid var(--pl-back-e);background:var(--pl-back);color:var(--pl-back-t);cursor:pointer;
  font:600 var(--t-xs) var(--ui);min-height:30px;box-shadow:var(--lift-p);
  transition:background var(--m-state),border-color var(--m-state),color var(--m-state),
    box-shadow var(--m-lift),transform var(--m-lift)
}
.chipf:hover{background:var(--pl-back-h);border-color:var(--pl-back-eh);box-shadow:var(--lift-p-h);transform:translateY(-1px)}
.chipf:active{box-shadow:var(--press-p);transform:translateY(1px)}
.chipf-dot{width:8px;height:8px;border-radius:var(--r-full);background:var(--tone,var(--mid));flex:none;opacity:.4}
/* Not the chosen fill, and deliberately. These start on and are switched off, so "on" is the
   resting state of every chip in the row: filling them all would paint the whole filter bar and
   say nothing. The interesting state here is the one turned off, which .chipf-none below marks
   in shape as well as in weight. The tone is the category's own colour, not a selection. */
.chipf.on{background:var(--tone-t,var(--gry-t));border-color:var(--tone,var(--soft));color:var(--ink)}
.chipf.on .chipf-dot{opacity:1}
/* Nothing of this kind survives the narrowing in force. Quiet, and struck through, so
   it differs from a switched off chip in shape as well as in weight. */
.chipf-none{opacity:.55}
.chipf-none .chipf-dot{background:var(--soft)}
.chipf-all{font-weight:700;text-decoration:underline;text-underline-offset:2px}
.admin-copy{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;justify-content:flex-end}
.admin-copy-note{font-size:var(--t-xs);color:var(--prod-d);min-height:14px;flex-basis:100%;text-align:right}
.copy-out{width:100%;font-family:var(--mono);font-size:var(--t-xs);line-height:1.5;border:1px solid var(--line);border-radius:var(--r-s);padding:var(--sp-3)}

/* --------------------------------------------------------------------------
   The events.

   One event is one line, and the line never wraps. A screen holds forty of them
   and the eye runs down the times. Pressing a line opens every field the record
   holds, because the question behind a number is always which one, and then what
   exactly happened. Tone is carried by the rule down the left edge and by the
   word, never by colour alone.
   -------------------------------------------------------------------------- */

.facets{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin-bottom:var(--sp-3)}
.facets-lead{font:700 var(--t-xs) var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid)}
.facets-note{font-size:var(--t-xs);color:var(--mid)}
.facet{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-full);
  border:1px solid var(--prod);background:var(--prod-t);color:var(--prod-d);cursor:pointer;
  font:600 var(--t-xs) var(--ui);min-height:28px
}
.facet:hover{background:var(--gry-t)}
.facet-x{font-size:var(--t-m);line-height:1}
.facet-clear{border-color:var(--pl-back-e);background:var(--pl-back);color:var(--pl-back-t)}

/* The events list in the operations console. This one keeps the name, because it had it
   first and every key derived from it is older; the evidence panel is `.evpanel`. */
.ev{list-style:none;margin:0;padding:0;background:var(--rail);border-radius:var(--r-s);border-left:3px solid var(--line);overflow:hidden}
.ev-i{border-bottom:1px solid var(--line);border-left:3px solid transparent;margin-left:-3px}
.ev-i:last-child{border-bottom:none}
.ev-i.tone-bad{border-left-color:var(--red);background:var(--red-t)}
.ev-i.tone-warn{border-left-color:var(--amb);background:var(--amb-t)}
.ev-line{
  display:grid;grid-template-columns:auto 8px minmax(6rem,auto) minmax(0,1fr) auto auto;
  align-items:center;gap:var(--sp-3);width:100%;text-align:left;padding:5px var(--sp-3);
  min-height:34px;background:none;border:none;cursor:pointer;font:500 var(--t-xs) var(--ui);color:var(--ink)
}
.ev-line:hover{background:var(--gry-t)}
.ev-t{color:var(--mid);white-space:nowrap}
.ev-k{width:8px;height:8px;border-radius:2px;background:var(--tone,var(--mid))}
.ev-w{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The one part allowed to be cut short, because the whole of it is one press away. */
.ev-d{color:var(--mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.ev-c{color:var(--mid);white-space:nowrap;font-size:var(--t-xs)}
.ev-x{width:14px;height:14px;color:var(--mid);transition:transform var(--m-state)}
.ev-line[aria-expanded="true"] .ev-x{transform:rotate(180deg)}

.ev-more{padding:var(--sp-3) var(--sp-4) var(--sp-4) var(--sp-5);border-top:1px dashed var(--line);background:var(--surf)}
.ev-fields{display:grid;grid-template-columns:minmax(0,11rem) minmax(0,1fr);gap:2px var(--sp-3);margin:0 0 var(--sp-3);font-size:var(--t-xs)}
.ev-fields dt{color:var(--mid);font-weight:600}
.ev-fields dd{margin:0;word-break:break-word}
.ev-raw summary{cursor:pointer;font-size:var(--t-xs);color:var(--mid);padding:4px 0}
.ev-json{
  font-family:var(--mono);font-size:var(--t-xs);line-height:1.5;background:var(--rail);
  border-radius:var(--r-s);padding:var(--sp-3);overflow-x:auto;white-space:pre;margin-top:var(--sp-2)
}
.ev-acts{margin-top:var(--sp-3)}

/* On a narrow screen the detail is the part worth reading and the connection is
   not, so the connection steps out of the line rather than squeezing the detail
   down to one letter. It is still there, one press away, with everything else. */
@media (max-width:620px){
  .ev-line{grid-template-columns:auto 8px minmax(0,auto) minmax(0,1fr) auto;gap:var(--sp-2)}
  .ev-c{display:none}
}
:root[data-motion="on"] .ev-i{animation:row-in var(--m-state) both;animation-delay:var(--delay,0ms)}
@keyframes row-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
:root[data-motion="on"] .admin-tile{animation:tile-in var(--m-panel) var(--ease-panel) both;animation-delay:var(--delay,0ms)}
@keyframes tile-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.admin-tile{border-left-color:var(--tone,var(--prod))}
.admin-tile .admin-tile-n{color:var(--ink)}

/* ==========================================================================
   Running it: the settings pane and the answers pane.

   Two panes that change what a stranger can do, rather than describing what one
   already did, so both are louder than the analysis panes and the state of the
   switch is never carried by colour alone.
   ========================================================================== */

/* The band across the whole console while checking is off. Stuck to the top of the
   console body, because an operator who signed in an hour later has to see the state of
   the thing they are running before they see anything else. */
.admin-off{
  display:flex;align-items:center;gap:var(--sp-3);position:sticky;top:0;z-index:6;
  border-left:4px solid var(--red)
}
.admin-off .i{flex:none;color:var(--red)}
.admin-off-h{font-family:var(--disp);font-size:var(--t-m);font-weight:700}
.admin-off-s{color:var(--ink);margin-top:2px;max-width:76ch}
.admin-off .btn{flex:none;margin-left:auto}

/* The whole of the centre column, like every other pane in the console. Asked for: it was held to
   760px, a third of a laptop screen short of the edge, which put the twelve faces two across and
   wrapped the row of areas onto a second line with room to spare beside it. */
.setpane{display:flex;flex-direction:column;gap:var(--sp-5)}
.setblock{display:flex;flex-direction:column;gap:var(--sp-2)}
.set-h{font-family:var(--disp);font-size:var(--t-m);font-weight:600}
.setdo{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:center}
.setdo .btn[aria-disabled="true"]{background:transparent;border:1.5px dashed var(--gry);color:var(--mid);box-shadow:none}
.setdo .btn[aria-disabled="true"]:hover{transform:none;box-shadow:none;background:transparent;border-color:var(--mid)}

/* The five areas of the settings, and the row that picks between them.

   Phil's call: nine blocks in one column had stopped being readable, and a switch that
   closes the product for everybody sat in the same scroll as a number deciding how many
   free checks a stranger gets. The row is the segmented control this product already
   uses everywhere a choice is made from a short fixed list, so it needs no vocabulary of
   its own.

   Laid out as an even grid across the whole column rather than as a wrapping row. Asked for:
   use the space. Seven areas are wider than a laptop's column at their natural width, so a
   row wrapped with one button alone on a line of its own; and trimming the padding until it
   fitted would fit it in one face and not in a wider one the console can choose. As a grid the
   buttons share the width equally, a long label wraps inside its own button, and a narrower
   screen gets tidy equal rows instead of a straggler. */
/* Two classes, because .seg is declared later in the file as inline-flex and would win a tie. */
.seg.setnav{display:grid;grid-template-columns:repeat(auto-fit, minmax(8rem, 1fr));width:100%}
.setnav button{display:inline-flex;align-items:center;justify-content:center;gap:6px}
/* An area holding a change that is not in force. The amber edge is the mark and the word
   beside it is the meaning, because colour is never the sole carrier here. */
.setnav button.setnav-unsaved{border-color:var(--amb);box-shadow:inset 0 0 0 1px var(--amb),var(--lift-p)}
.setnav-flag{
  font:700 9px var(--ui);letter-spacing:.06em;text-transform:uppercase;
  background:var(--amb-t);color:var(--ink);border-radius:var(--r-s);padding:1px 5px
}
.setsec{display:flex;flex-direction:column;gap:var(--sp-4)}
/* A choice row is as wide as its choices. As a flex item of the column it stretched, and its grey
   track ran on across the whole pane behind nothing. */
.setpane .seg:not(.setnav){align-self:flex-start}
/* One sentence under each area's heading saying what it governs, so an operator can tell
   from the screen rather than from the shape of the controls whether they are in the
   right place. It sits tight under the heading it belongs to. */
.set-lede{margin-top:calc(var(--sp-4) * -1 + var(--sp-1))}
.set-sub{font-family:var(--disp);font-size:var(--t-b);font-weight:600}
/* The save row, below whichever of the three writing areas is open. One press writes the
   whole settings blob, so there is one of these rather than one per area. */
.setfoot{
  display:flex;flex-direction:column;gap:var(--sp-2);
  padding-top:var(--sp-4);border-top:1px solid var(--line)
}

/* The master switch. The block is the state: green while it is on, red while it is off,
   with the word beside the knob and a sentence under the heading, so the state is said
   three times over and never in colour alone. */
.masterswitch{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;
  padding:var(--sp-4);border-radius:var(--r-m);border:1px solid var(--line);
  border-left:4px solid var(--grn);background:var(--grn-t)
}
.masterswitch[data-state="off"]{border-left-color:var(--red);background:var(--red-t)}
.master-h{font-family:var(--disp);font-size:var(--t-l);font-weight:700;color:var(--grn)}
.masterswitch[data-state="off"] .master-h{color:var(--red)}
/* The words take the width the switch does not, and the switch stays at the end of the line
   beside them. It drops underneath only when there is too little room for the words to be read. */
.master-say{flex:1 1 20rem;min-width:0}
.master-s{color:var(--ink);margin-top:4px;font-size:var(--t-b)}
/* What is on the switch is not always what is in force. A draft that has not been saved
   says so here, in words, because a switch showing off and an instance that is still on
   are indistinguishable otherwise, which is exactly how Phil came to believe a change
   had taken when it had not. The amber edge is the second carrier, never the only one. */
.master-unsaved{
  margin-top:var(--sp-2);padding:6px var(--sp-3);border-radius:var(--r-s);
  border-left:3px solid var(--amb);background:var(--amb-t);color:var(--ink);
  font:600 var(--t-s) var(--ui);max-width:64ch
}
.masterswitch[data-unsaved="yes"]{border-left-color:var(--amb);background:var(--amb-t)}
/* And the heading, which then says what happens on saving, in the ink of a pending change
   rather than the green or red of a state that is not yet true. */
.masterswitch[data-unsaved="yes"] .master-h{color:var(--amb-on-tint)}
/* The save row, held at the foot of the window while anything is unsaved, with its buttons at
   the right so the console's menu button at the bottom left never sits on them. */
.setfoot[data-dirty="true"]{
  position:sticky;bottom:0;z-index:5;background:var(--bg);
  border-top:2px solid var(--amb);padding-bottom:var(--sp-3)
}
.setfoot[data-dirty="true"] .setdo{justify-content:flex-end}
#view-admin :where(a, button, input, select, textarea, [tabindex]){scroll-margin-bottom:160px}

/* A switch that is a button rather than a checkbox, because it is a console control and
   the state comes from the server. Raised, on the pressable surface, with a hover lift
   and a press state, which is this product's vocabulary for something you press. */
.switch{
  display:inline-flex;align-items:center;gap:var(--sp-2);flex:none;cursor:pointer;
  background:var(--pl-back);border:1px solid var(--pl-back-e);border-radius:var(--r-full);
  padding:5px var(--sp-3) 5px 6px;font:600 var(--t-b) var(--ui);color:var(--ink);
  min-height:34px;box-shadow:var(--lift-p);
  transition:box-shadow var(--m-lift),transform var(--m-lift),border-color var(--m-state),
    background var(--m-state)
}
.switch:hover{background:var(--pl-back-h);border-color:var(--pl-back-eh);
  box-shadow:var(--lift-p-h);transform:translateY(-1px)}
.switch:active{transform:translateY(1px);box-shadow:var(--press-p)}
.switch-knob{
  width:34px;height:20px;border-radius:var(--r-full);background:var(--gry);position:relative;flex:none;
  transition:background var(--m-state)
}
.switch-knob::after{
  content:"";position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:var(--r-full);
  background:#fff;box-shadow:var(--sh);transition:transform var(--m-lift)
}
.switch.on .switch-knob{background:var(--grn)}
.switch.on .switch-knob::after{transform:translateX(14px)}
.switch-word{white-space:nowrap}
.switch-lg{font-size:var(--t-m);padding:6px var(--sp-4) 6px 7px;min-height:42px}
.switch-lg .switch-knob{width:42px;height:24px}
.switch-lg .switch-knob::after{width:18px;height:18px}
.switch-lg.on .switch-knob::after{transform:translateX(18px)}

.setnums{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:var(--sp-4)}
.setnum{
  display:flex;flex-direction:column;gap:var(--sp-2);padding:var(--sp-3);
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--prod);border-radius:var(--r-s)
}
/* No limit is the most generous state, not the least, so it is green rather than grey. */
.setnum-free{border-left-color:var(--grn)}
.setnum-row{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
/* The words the per-tier switch answers to, beside it, so the switch itself can say On or Off. */
.setnum-sw-l{font:600 var(--t-s) var(--ui);color:var(--ink)}
/* Limits are off: the numbers are kept for when they come back, so they stay on the screen,
   greyed as a whole rather than faded, which would take the text under its contrast. */
.setnum-kept{background:var(--rail);border-left-color:var(--gry)}
.setnum-in{
  width:6rem;background:#fff;border:1px solid var(--line2);border-radius:var(--r-s);
  padding:var(--sp-2) var(--sp-3);font:600 var(--t-m) var(--ui);color:var(--ink)
}
.setnum-in:focus{outline:2px solid var(--act);outline-offset:-1px;border-color:var(--act)}
.setnum-in[aria-disabled="true"]{background:var(--rail);color:var(--mid)}

.sethist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.sethist-row{
  display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;padding:var(--sp-2) var(--sp-3);
  background:var(--rail);border-left:3px solid var(--line);font-size:var(--t-xs)
}
.sethist-when{color:var(--mid);white-space:nowrap;min-width:11rem}
.sethist-nums{color:var(--ink)}
.sethist-why{color:var(--red);font-weight:600}
.sethist-none{color:var(--mid);font-size:var(--t-s);padding:var(--sp-3)}

/* Licences. One row each, with the state carried by a colour, a word and an icon. */
.lic-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:var(--sp-3);margin-bottom:var(--sp-3)}
.lic-grid input,.lic-grid select{width:100%}
.lics{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.lic{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--grn);
  border-radius:var(--r-s);padding:var(--sp-3);display:flex;flex-direction:column;gap:4px
}
.lic-revoked{border-left-color:var(--red);background:var(--red-t)}
.lic-expired{border-left-color:var(--gry);background:var(--rail)}
.lic-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.lic-plan{font-family:var(--disp);font-weight:600}
.lic-when,.lic-uses,.lic-note{font-size:var(--t-xs);color:var(--mid)}
.lic-who{font-size:var(--t-s);font-weight:600}
.lic .ghost{align-self:flex-start;margin-top:var(--sp-2)}
.lic-new{margin-top:var(--sp-3)}

/* Finding one licence among many.
   The find box, the four states and the order sit in one row above the list, and wrap into a
   column on a narrow screen. Nothing here asks the server: the list is already in the browser,
   so a typo costs a keystroke rather than a round trip. */
.lic-find{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:flex-end;margin-bottom:var(--sp-3)}
.lic-find .f{flex:1 1 220px;min-width:0;margin:0}
.lic-sort{flex:0 1 200px}
/* The figures that answer "how many have they got left", which is what this pane is opened
   to find out. In the row's own colour rather than the grey of the notes, because it is the
   fact rather than a remark about it. */
.lic-pool{font-size:var(--t-s);font-weight:600;color:var(--ink)}
.lic-fresh{margin-top:var(--sp-2)}
.lic-fresh .mono{font-size:var(--t-l);letter-spacing:.08em;word-break:break-all}

/* What has been run on a licence.
   Four tallies side by side where there is room and stacked where there is not, then every
   use under them. Each tally scrolls on its own rather than making the whole fold the height
   of the longest one: a key with a year of daily checks would otherwise push the audit trail
   several screens down. */
.lic-hist{border-top:1px solid var(--line);margin-top:var(--sp-3);padding-top:var(--sp-3);
  display:flex;flex-direction:column;gap:var(--sp-2)}
.lic-hist-now{font-size:var(--t-m);font-weight:600;color:var(--ink)}
.lic-hist-tallies{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));
  gap:var(--sp-3)}
.tally{min-width:0}
.tally-h{font:700 11px var(--ui);letter-spacing:.05em;color:var(--mid);text-transform:uppercase;
  margin:0 0 5px}
.tally-rows{list-style:none;margin:0;padding:0;max-height:15rem;overflow-y:auto;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--surf)}
.tally-rows li{display:flex;justify-content:space-between;gap:var(--sp-2);
  padding:3px var(--sp-2);font-size:var(--t-s);border-bottom:1px solid var(--line)}
.tally-rows li:last-child{border-bottom:0}
.tally-k{min-width:0;overflow-wrap:anywhere}
.tally-n{font-variant-numeric:tabular-nums;font-weight:700}
.tally-more .tally-k{color:var(--mid);font-style:italic}
/* The audit trail. One line a check, in the order they happened, newest first. */
.uselist{list-style:none;margin:0;padding:0;max-height:22rem;overflow-y:auto;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--surf)}
.use{padding:4px var(--sp-2);font-size:var(--t-s);border-bottom:1px solid var(--line)}
.use:last-child{border-bottom:0}
/* A line whose detail has aged out reads as a line with something missing unless it is marked
   as one, and the mark is the point: the check happened, and we no longer say who ran it. */
.use-aged,.use-more{color:var(--mid);font-style:italic}
.lic-new-h{font-weight:700;color:var(--grn);margin-bottom:var(--sp-2)}
#lic-key{font-size:var(--t-l);letter-spacing:.08em;word-break:break-all}

/* The API pane.

   The keys are cards, like the licences, because each carries its own switch and its own
   limit, and a table row with four controls in it is a row nobody can use on a phone. The
   state is a word on a tag as well as the colour of the edge. */
.apikeys{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.apikey{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--grn);
  border-radius:var(--r-s);padding:var(--sp-3);display:flex;flex-direction:column;gap:4px;min-width:0
}
.apikey-paused{border-left-color:var(--amb)}
.apikey-revoked{border-left-color:var(--red);background:var(--red-t)}
.apikey-expired{border-left-color:var(--gry);background:var(--rail)}
.apikey-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.apikey-org{font-family:var(--disp);font-weight:600;min-width:0;overflow-wrap:anywhere}
.apikey-prefix{color:var(--mid)}
.apikey-name{font-size:var(--t-s);font-weight:600}
.apikey-when,.apikey-note{font-size:var(--t-xs);color:var(--mid)}
.apikey-edit{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(180px,100%),1fr));
  gap:var(--sp-2) var(--sp-3);align-items:end;margin-top:var(--sp-2)
}
.apikey-edit input{width:100%}
.apikey-acts{display:flex;align-items:center;gap:var(--sp-2) var(--sp-3);flex-wrap:wrap;margin-top:var(--sp-2)}
.apikey-once{font-size:var(--t-l);letter-spacing:.04em;padding:var(--sp-3);background:var(--rail);border-radius:var(--r-s)}

/* A heading with what goes with it on the same line: when the live view was read and its
   pause, or the period and the download. */
.api-head{display:flex;align-items:flex-end;gap:var(--sp-2) var(--sp-4);flex-wrap:wrap}
.api-head .set-h{margin-right:auto}
.api-head-say{flex:1 1 16rem;min-width:0}
.api-live-body{display:flex;flex-direction:column;gap:var(--sp-3)}

/* Now: the gauge of the minute against the maximum rate, then the three rates. The ring is
   drawn the way the allowance ring is (rules/allowance.mjs), from green to red as it fills,
   and the words beside it say the same thing, so colour never says it alone. */
.api-now{display:flex;flex-wrap:wrap;gap:var(--sp-4) var(--sp-6);align-items:center}
.api-gauge-box{display:flex;align-items:center;gap:var(--sp-3);min-width:0;flex:1 1 18rem}
.api-gauge{width:72px;height:72px;flex:none}
.api-gauge circle{fill:none;stroke-width:5}
.api-gauge-t{stroke:var(--gauge-c,#0E8125);opacity:.2}
.api-gauge-f{
  stroke:var(--gauge-c,#0E8125);stroke-dasharray:var(--gauge-p,0) 100;stroke-linecap:round;
  transition:stroke-dasharray .6s var(--ease-panel,ease),stroke .6s
}
.api-gauge-none .api-gauge-f{stroke-linecap:butt}
.api-gauge-say{font-size:var(--t-s);font-weight:600;color:var(--ink);margin-top:4px}
.api-today .rate-list{margin-bottom:0}

/* Sixty minutes to a row rather than twenty four hours. Nothing in these rows can be pressed,
   so they do not look as though they can. */
.hourgrid-60{grid-template-columns:repeat(60,minmax(0,1fr));gap:1px}
.hourgrid-still .hourbar{cursor:default}
.hourgrid-still .hourbar:hover{border-color:transparent}
.admin-tile-still{cursor:default}
.admin-tile-still:hover{background:var(--rail)}

/* Problems now. Red for one that needs attention and amber for one worth a look, each with
   the warning sign and a word, so the level is never carried by the colour alone. */
.api-probs{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.api-prob{
  display:grid;grid-template-columns:auto auto minmax(0,1fr);gap:var(--sp-2);align-items:start;
  padding:var(--sp-2) var(--sp-3);border-radius:var(--r-s);border-left:3px solid var(--amb);
  background:var(--amb-t);color:var(--ink);font-size:var(--t-s)
}
.api-prob-bad{border-left-color:var(--red);background:var(--red-t)}
.api-prob .i{color:var(--amb-on-tint)}
.api-prob-bad .i{color:var(--red)}
.api-prob-w{font-weight:700;white-space:nowrap}
.api-prob-none{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--t-s);color:var(--grn);font-weight:600}
@media (max-width:620px){
  .api-prob{grid-template-columns:auto minmax(0,1fr)}
  .api-prob-s{grid-column:1 / -1}
}

/* By connection. A table, because it is one row a key and the same five figures across, and
   it scrolls inside its own box rather than pushing the page sideways on a phone. */
.api-table-wrap{overflow-x:auto;max-width:100%}
.api-table{border-collapse:collapse;width:100%;font-size:var(--t-s)}
.api-table th,.api-table td{padding:6px var(--sp-2);border-bottom:1px solid var(--line);text-align:right;white-space:nowrap}
.api-table th:first-child{text-align:left;white-space:normal;min-width:10rem}
.api-table thead th{font-weight:700;color:var(--mid);font-size:var(--t-xs)}
.api-table td{font-variant-numeric:tabular-nums}

/* The answers. One card each, and every one of them holds somebody's name, so the card
   is the thing that gets copied or deleted rather than a row in a table. */
.signups{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-3)}
.signup{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--prod);
  border-radius:var(--r-s);padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-3)
}
.signup-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap}
.signup-who{font-family:var(--disp);font-size:var(--t-m);font-weight:600}
.signup-mail{display:flex;gap:var(--sp-3);flex-wrap:wrap;font-size:var(--t-s)}
.signup-mail a{color:var(--act)}
.signup-when{color:var(--mid)}
.signup-org{margin-left:var(--sp-2);font:600 var(--t-s) var(--ui);color:var(--mid)}
/* Where they stood when they answered: tier, checks used, which screen, which kind of device. */
.signup-context{margin-top:2px;font-size:var(--t-s);color:var(--ink)}
.signup-steps{display:flex;flex-direction:column;gap:var(--sp-2)}
.signup-step-h{font:700 var(--t-xs) var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid);margin-top:var(--sp-2)}

/* The answers, added up. The bars are the console's own bar list in one hue, with the count and
   the share written beside each; the name column is widened and allowed to wrap here, because an
   answer cut off at an ellipsis is an answer nobody can read. */
.signup-sum{display:flex;flex-direction:column;gap:var(--sp-3);margin-bottom:var(--sp-5);
  padding-bottom:var(--sp-5);border-bottom:1px solid var(--line)}
.signup-heads{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(18rem,100%),1fr));gap:var(--sp-3)}
.signup-headline{background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--act);
  border-radius:var(--r-s);padding:var(--sp-3)}
.signup-headline-n{font:700 var(--t-xl)/1.1 var(--disp);color:var(--ink)}
.signup-headline-l{font-size:var(--t-s);color:var(--ink);margin-top:4px}
.signup-sum-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(28rem,100%),1fr));gap:var(--sp-4)}
.signup-sum-q{display:flex;flex-direction:column;gap:var(--sp-1)}
.signup-sum-h{font-weight:600;font-size:var(--t-b)}
.signup-sum .bar-row{grid-template-columns:minmax(0,15rem) minmax(0,1fr) auto}
.signup-sum .bar-name{white-space:normal;font-family:var(--ui);font-size:var(--t-s)}
.signup-do{display:flex;gap:var(--sp-2);flex:none}
.signup-answers{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:2px var(--sp-3);font-size:var(--t-s);margin:0}
.signup-answers dt{color:var(--mid)}
.signup-answers dd{margin:0;font-weight:600}
.signup-wishes-h{font:700 var(--t-xs) var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid)}
.signup-wishes{margin:0;padding-left:var(--sp-4);font-size:var(--t-s)}
/* Somebody else's words, in the flat treatment this product uses for something it did
   not write, so nobody reads it as the product's own voice. */
.signup-said{background:var(--rail);border-left:3px solid var(--soft);border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-3)}
.signup-said-h{font:700 var(--t-xs) var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid);margin-bottom:4px}
.signup-said-t{white-space:pre-wrap;font-size:var(--t-b)}
@media (max-width:620px){
  .signup-answers{grid-template-columns:minmax(0,1fr)}
  .signup-answers dd{margin-bottom:var(--sp-2)}
}

/* What a visitor will read, quoted back at the operator before they close the instance. */
.quote{
  background:var(--rail);border-left:3px solid var(--act);border-radius:0 var(--r-s) var(--r-s) 0;
  padding:var(--sp-3);font-size:var(--t-b);margin-bottom:var(--sp-3)
}
.ok{color:var(--grn);font-size:var(--t-s);font-weight:600;margin-top:var(--sp-2)}
/* The same role reached from the other direction. Written as `btn btn-warn`, and this
   block sits later in the sheet, so the plate wins over the solid action above it. */
.btn-warn{background:var(--pl-del);color:var(--pl-del-t);border-color:var(--pl-del-e);
  box-shadow:var(--lift-p)}
.btn-warn:hover{background:var(--pl-del-h);border-color:var(--pl-del-eh);box-shadow:var(--lift-p-h)}
.btn-warn:active{background:var(--pl-del-h);box-shadow:var(--press-p)}
.btn-warn .i{color:var(--pl-del-t)}

/* The handheld menu. Rows rather than a list, because each one is a control and has to
   look like something you press. Forty four pixels tall, in a sheet that comes up from
   the bottom, which is where the thumb already is. */
.menu-sheet{display:flex;flex-direction:column;gap:var(--sp-2)}
.menu-cap{
  font:700 var(--t-xs) var(--ui);letter-spacing:.06em;text-transform:uppercase;color:var(--mid);
  margin-top:var(--sp-3)
}
.menu-cap:first-child{margin-top:0}
.menu-row{
  display:flex;align-items:center;gap:var(--sp-3);width:100%;text-align:left;min-height:52px;
  padding:var(--sp-3);background:var(--pl-back);border:1px solid var(--pl-back-e);border-radius:var(--r-s);
  font:inherit;font-weight:600;color:var(--ink);cursor:pointer;box-shadow:var(--lift-p);
  transition:background var(--m-state),border-color var(--m-state),box-shadow var(--m-state)
}
.menu-row:hover{background:var(--pl-back-h);border-color:var(--pl-back-eh);box-shadow:var(--lift-p-h)}
.menu-row:active{box-shadow:var(--press-p);transform:translateY(1px)}
.menu-row .i{color:var(--mid);font-size:19px;flex:none}
.menu-row-here{border-color:var(--prod);background:var(--prod-t)}
.menu-row-here .i{color:var(--prod)}
.menu-row-t{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
.menu-row-h{font-weight:600}
.menu-row-s{font-size:var(--t-s);color:var(--mid)}
.menu-meta{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-2) var(--sp-4);font-size:var(--t-s)}
.menu-meta dt{color:var(--mid)}
.menu-meta dd{margin:0;color:var(--ink)}

/* Where the rules came from. The same green and amber the rest of the product uses:
   green for a source that was fetched and read, amber for one that could not be
   reached. Both are listed. Each also says which it is in words. */
.sources{margin-top:var(--sp-7);border-top:1px solid var(--line);padding-top:var(--sp-6)}
.sources h2{margin-bottom:var(--sp-2)}
.src-list{display:flex;flex-direction:column;gap:var(--sp-3);margin-top:var(--sp-5)}
.src-item{
  background:var(--surf);border:1px solid var(--line);border-left-width:3px;border-radius:var(--r-s);
  padding:var(--sp-4)
}
.src-on{border-left-color:var(--prod)}
.src-off{border-left-color:var(--amb)}
.src-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.src-on .src-head .i{color:var(--prod)}
.src-off .src-head .i{color:var(--amb-on-tint)}
.src-title{font-weight:600;font-size:var(--t-m);font-family:var(--disp)}
.src-pub{font-size:var(--t-s);color:var(--mid)}
.src-note-line{font-size:var(--t-s);color:var(--mid);margin-top:var(--sp-2);max-width:86ch}
.src-body .lnk{font-family:var(--mono);font-size:var(--t-xs);word-break:break-all}
.src-note{
  margin-top:var(--sp-4);padding:var(--sp-4);border-radius:var(--r-s);background:var(--rail);
  border-left:3px solid var(--soft);color:var(--mid);font-size:var(--t-b);max-width:86ch
}

/* ==========================================================================
   Flags reported as incorrect.

   The answer about the check rather than about the document, and the console list it
   produces. The button takes the red the record will give the decision, as an underline
   rather than an edge, because a solid accent edge already means "the block to deal
   with" and one meaning to a treatment is the whole point of having them.
   ========================================================================== */

/* Reporting a flag as incorrect. It steps back from the finding rather than acting on it, so
   it carries the step-back plate with a red bar underneath saying what it reports. The hover
   does not turn the plate red: red is the colour of a press that removes something, and this
   removes nothing. */
/* The one Report button, used wherever somebody decides something (report-button.mjs). The same
   shape and height as every other button, in the one plate nothing else wears. Its tip shows on
   hover and on keyboard focus, stays while the pointer is on it, and goes on Escape. */
.report-wrap { position: relative; display: inline-flex; margin-left: auto; }
.btn-report {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font: 600 var(--t-b) var(--ui); border-radius: var(--r-s); cursor: pointer;
  padding: var(--sp-2) var(--sp-4); min-height: 36px; min-width: 24px;
  background: var(--pl-report); color: var(--pl-report-t); border: 1px solid var(--pl-report-e);
  box-shadow: var(--lift-f); transition: background var(--m-state), box-shadow var(--m-lift);
}
.btn-report:hover { background: var(--pl-report-h); box-shadow: var(--lift-f-h); }
.btn-report:active { box-shadow: var(--press-f); }
.btn-report:focus-visible { outline: 3px solid var(--act); outline-offset: 2px; }
.report-tip {
  position: absolute; right: 0; bottom: calc(100% + 6px); z-index: 30; width: max-content; max-width: 16rem;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-s); font: 400 var(--t-xs)/1.4 var(--ui);
  background: var(--pl-report-h); color: var(--pl-report-t); visibility: hidden; opacity: 0;
  transition: opacity var(--m-state);
}
.report-wrap:hover .report-tip, .report-wrap:focus-within .report-tip { visibility: visible; opacity: 1; }
.report-wrap[data-tip="off"] .report-tip { visibility: hidden; opacity: 0; }
.report-note { width: 100%; font: 400 var(--t-b)/1.5 var(--ui); }

/* The reason list in the dialog. Each one is a press, so each one is a target, and the hint
   under the label is the difference between two answers that sound alike. */
.reasons { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.reason {
  display: flex; flex-direction: column; gap: 2px; text-align: left; width: 100%;
  padding: var(--sp-3); border-radius: var(--r-s); cursor: pointer; min-height: 44px;
  background: var(--pl-back); border: 1px solid var(--pl-back-e); color: var(--ink);
  box-shadow: var(--lift-p); transition: background var(--m-state), border-color var(--m-state);
}
.reason:hover { background: var(--pl-back-h); border-color: var(--pl-back-eh); }
/* Chosen is the shared rule, "a control somebody chose". The sub-line under the label has to
   come with it: --mid on the accent is 2.1:1 and unreadable. */
.reason.on .reason-h { color: rgba(255, 255, 255, .85); }
.reason-l { font-weight: 600; }
.reason-h { font-size: var(--t-s); color: var(--mid); }

/* The faces in the console, each drawn in itself. Reason cards, so the chosen state, its tick and
   its colours are the shared ones. Two across where there is room, because twelve stacked is a
   list nobody compares; one across on a phone. The face itself comes from fonts.css, by
   data-face, and nothing here names one. */
.facelist { display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); }
.face-row .reason-l { font-size: var(--t-m); font-weight: 700; display: flex; flex-wrap: wrap;
  align-items: baseline; gap: var(--sp-2); }
/* The body weight whether or not the card is chosen. The shared chosen rule makes everything on
   the card bold, and a sample of body text drawn bold is a sample of something no page shows. */
.face-line { font-size: var(--t-b); line-height: 1.5; font-weight: 400; }
/* Said in words, not only by the fill, because what is picked and what is in force are two
   different facts until somebody saves. */
.face-live { font: 600 var(--t-xs)/1.4 var(--ui); padding: 1px var(--sp-2); border-radius: var(--r-full);
  background: var(--prod-t); color: var(--prod-d); }
.reason.on .face-live { background: #fff; color: var(--act-h); }

/* The console list. */
.misfire-top{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-4)}
.misfires{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-4)}
.misfire{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--red);
  border-radius:0 var(--r-m) var(--r-m) 0;padding:var(--sp-4);box-shadow:var(--sh)
}
.misfire-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.misfire-rule{font:700 var(--t-s) var(--ui);color:var(--ink)}
.misfire-at{font-size:var(--t-xs);color:var(--soft);margin-left:auto}
.misfire-why{font:600 var(--t-b) var(--ui);color:var(--red);margin-bottom:var(--sp-3)}
.misfire-lbl{font:700 10px var(--ui);letter-spacing:.05em;text-transform:uppercase;color:var(--mid);margin-bottom:4px}
.misfire-quote{
  background:var(--rail);border:1px solid var(--line2);border-left:3px solid var(--line);
  border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-3);margin:0 0 var(--sp-3);
  font-family:var(--mono);font-size:var(--t-s);color:var(--ink)
}
.misfire-said{font-size:var(--t-s);color:var(--mid);margin-bottom:var(--sp-2)}
.misfire-meta{font-size:var(--t-xs);color:var(--soft);font-family:var(--mono)}
@media (max-width:620px), (pointer:coarse) and (max-width:1024px){
  .misfire-at{margin-left:0;width:100%}
}


/* ------------------------------------------------------- what the console shares with it

   A modal, a segmented control, a form field and a handful of small blocks. All of them
   carried across from the first application with the console, because the console is
   built out of them and a console built out of near misses is not the same console. */

.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* A row of console actions, and the label that stands in for a file input. A file input cannot
   be styled and cannot be made to look like the buttons beside it, so the input is taken off
   the screen and its label wears the button's clothes: the label is still the control, so the
   keyboard and a screen reader get the real thing. */
.admin-acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;margin:var(--sp-3) 0 0}
.ghost-file{cursor:pointer}
#lic-file:focus-visible + .ghost-file,
.ghost-file:focus-visible{outline:2px solid var(--act);outline-offset:2px}
#lic-restore{margin:var(--sp-3) 0 0;display:grid;gap:var(--sp-2);justify-items:start}
/* The two licence actions, side by side, because they look alike and are not alike: one is
   reversible and the other is not. The armed delete wears the delete plate and says what it
   does, so the second press is read rather than repeated. */
.lic-acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;margin-top:var(--sp-2)}
.btn-s{padding:5px var(--sp-3);font-size:var(--t-xs);min-height:32px}
.lnk{color:var(--act);text-decoration:underline;text-underline-offset:2px}
.lnkbtn{background:none;border:none;color:var(--act);font:inherit;cursor:pointer;padding:2px 0;text-decoration:underline;text-underline-offset:2px;min-height:24px}
.lnkbtn:hover{color:var(--act-h)}
.notice-ok{background:var(--grn-t);color:var(--grn)}
.mono.big{font-size:var(--t-m);word-break:break-all}

.scrim{position:fixed;inset:0;background:rgba(13,27,42,.55);display:grid;place-items:center;padding:var(--sp-4);z-index:50;animation:fade var(--m-panel) both}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{
  background:var(--surf);border-radius:var(--r-l);width:min(620px,100%);max-height:88vh;overflow:auto;
  box-shadow:-20px 20px 60px rgba(0,0,0,.3);animation:pop var(--m-panel) var(--ease-panel) both
}
@keyframes pop{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--line)}
.modal-head h2{font-size:var(--t-m)}
.modal-body{padding:var(--sp-5)}
.modal-body .hint{margin-bottom:var(--sp-3)}
.modal-actions{display:flex;justify-content:space-between;gap:var(--sp-3);margin-top:var(--sp-5);flex-wrap:wrap}
.modal-body textarea{width:100%;min-height:110px;resize:vertical}
.modal-body textarea:focus{outline:2px solid var(--act);outline-offset:-1px}
/* Why a rule said what it said, in full.
   Wider than the rest of the overlays, because this one is a document rather than a question:
   it is what somebody forwards to whoever has to decide whether the finding is right, and a
   citation wrapped over four lines is harder to read than the law it names. */
.modal-wide{width:min(820px,100%)}
.why{display:grid;gap:var(--sp-4);margin-top:var(--sp-3)}
.why-sec h3{font-size:var(--t-s);text-transform:uppercase;letter-spacing:.06em;color:var(--mid);
  margin:0 0 var(--sp-2);font-weight:700}
/* Label and value, side by side where there is room and stacked where there is not. The label
   column is fixed so the values line up: a reader scanning for one of them is scanning a
   column, not a paragraph. */
.why-dl{display:grid;grid-template-columns:15em 1fr;gap:var(--sp-1) var(--sp-3);margin:0;
  font-size:var(--t-s)}
.why-dl dt{color:var(--mid);font-weight:600}
.why-dl dd{margin:0;color:var(--ink);overflow-wrap:anywhere}
/* The pack's own extraction lines, which are whole statements rather than labelled values, so
   they take both columns and keep the monospace they were written in. */
.why-raw{grid-column:1 / -1;font-size:var(--t-xs);color:var(--mid);
  background:var(--rail);border-radius:var(--r-s);padding:3px var(--sp-2)}
.why-acts{display:flex;gap:var(--sp-2);justify-content:space-between;flex-wrap:wrap;
  margin-top:var(--sp-5)}
.why-acts-l{display:flex;gap:var(--sp-2);flex-wrap:wrap}

/* How to reach 100.
   Named toh- rather than plan-, because plan- is already the pricing card and two treatments
   sharing one name is how they end up sharing one stylesheet rule. The first draft of this drew
   a blue bar down the side of the panel, inherited from a price.
   The one screen somebody arrives at wanting to win something, so what it has to do is give
   them the arithmetic and then the caveat, in that order, and neither quietly. */
.toh{display:grid;gap:var(--sp-4);margin-top:var(--sp-3)}
.toh-lead{font-size:var(--t-m);font-weight:600}
.toh-sec h3{font-size:var(--t-s);text-transform:uppercase;letter-spacing:.06em;color:var(--mid);
  margin:0 0 var(--sp-1);font-weight:700}
.toh-sec .hint{margin-bottom:var(--sp-3)}
.toh-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-2)}
.toh-row{
  display:flex;gap:var(--sp-3);align-items:flex-start;
  padding:var(--sp-3);border-radius:var(--r-s);background:var(--rail);
  border-left:3px solid var(--line)
}
/* What it is worth, as a figure, because that is what somebody chasing a number is scanning
   for. It is a gain rather than a loss on purpose: "+18" is the thing they would get, and
   "-18" would be a punishment for an advert they have not published yet. */
.toh-cost{
  flex:none;min-width:2.8em;text-align:center;font:700 var(--t-m) var(--ui);
  color:var(--prod-d);background:var(--prod-t);border-radius:var(--r-s);padding:2px var(--sp-2)
}
.toh-cost-none{color:var(--mid);background:var(--gry-t);font-weight:600}
.toh-t{display:grid;gap:2px;flex:1 1 auto;min-width:0}
/* Kept on one line. It is the quietest thing on the row and wrapping it over two made it the
   tallest. */
.toh-row .why-link{flex:none;white-space:nowrap;align-self:flex-start}
.toh-how{font-size:var(--t-s);color:var(--mid)}
/* What kind of press it takes, said in three words. A person deciding whether two minutes is
   worth it is really asking how many of these are typing and how many are thinking. */
.toh-route{font:600 var(--t-xs) var(--ui);text-transform:uppercase;letter-spacing:.05em;color:var(--soft)}
.toh-reach{
  display:flex;gap:var(--sp-2);align-items:flex-start;
  background:var(--prod-t);border-left:3px solid var(--prod);border-radius:0 var(--r-s) var(--r-s) 0;
  padding:var(--sp-3);color:var(--prod-d);font-weight:600
}
.toh-reach .i{flex:none;margin-top:2px}
/* The caveat, and it is not a footnote. This is the one panel somebody reaches feeling they
   have won something, which is exactly where a number has to say what it is not. */
.toh-caveat{
  display:flex;gap:var(--sp-2);align-items:flex-start;font-size:var(--t-s);
  background:var(--gry-t);border-radius:var(--r-s);padding:var(--sp-3);color:var(--pl-back-t)
}
.toh-caveat .i{flex:none;margin-top:2px}

/* The way in, under the routes. One line, and it is an argument for pressing the button above
   it rather than a heading, so it sits with the routes and not with the findings. */
.route-advice{
  display:flex;gap:var(--sp-2);align-items:flex-start;flex-wrap:wrap;
  font-size:var(--t-s);color:var(--mid);margin-top:var(--sp-3);max-width:72ch
}
.route-advice .i{flex:none;margin-top:2px;color:var(--act)}

/* The same panel in a window of its own, which is where somebody reads it beside the advert it
   is about. It borrows this stylesheet, so all it needs is a page to sit on. */
.why-window{max-width:820px;margin:0 auto;padding:var(--sp-5) var(--sp-4) var(--sp-6)}
.why-window h1{font-size:var(--t-l);margin:0 0 var(--sp-2)}
.why-fallback{width:100%;height:9em;font:11px/1.4 var(--mono);margin-bottom:var(--sp-3)}
/* The way in. Quiet on purpose: it answers a question most people will never ask, so it is the
   size of that question and sits under the thing it explains rather than beside the buttons
   that act on it. */
/* Left where it sits under prose, which is everywhere but the row of buttons that act on a
   step: there it goes to the far end, so it is clear it is not one of them. */
.why-link{font-size:var(--t-s);justify-self:start;text-align:left}
.walk-do .why-link{margin-left:auto;text-align:right}
@media (max-width:560px){
  .why-dl{grid-template-columns:1fr;gap:0 0}
  .why-dl dt{margin-top:var(--sp-2)}
  .walk-do .why-link{margin-left:0;text-align:left}
  .walk-do .ghost-warn{margin-left:0}
}

.modal-alert{border-top:4px solid var(--red)}
.modal-alert .modal-head{background:var(--red-t)}
.modal-alert .modal-head h2{color:var(--red)}

/* Anything the guide opens looks like the guide. The same border and the same filled head as the
   guide's own panel, so a panel that arrives in front of somebody says where it came from before
   they read a word of it. The body stays white: this is a page of reading rather than a line of
   instruction, and the tint the panel uses is for a box the size of a postcard. */
.modal-guide{border:2px solid var(--train)}
.modal-guide .modal-head{background:var(--train);border-bottom-color:var(--train)}
.modal-guide .modal-head h2{color:#fff}
.modal-guide .modal-head .info{color:#fff}
.modal-guide .modal-head .info:hover{background:rgba(255, 255, 255, .18)}
.modal-guide .modal-body .hint{color:var(--mid)}
/* The instruction opens what the guide opens, in the words the panel is showing, and then the
   explanation. It carries the panel's own class so the two read as the same voice, and that class
   is written for a box the size of a postcard where nothing follows it. */
.modal-guide .modal-body .guide-say{margin-bottom:var(--sp-4)}

/* Wraps. It scrolled sideways instead, and a scrolling strip inside a grid whose columns are
   sized by their content does not scroll: it sets the width of everything above it. On a phone
   the three answers to the agency question came to 616px and dragged the whole result page
   with them, so the walk, the score card and the headline all sat off the right edge of the
   screen. Three pills on two lines is what a phone should get. */
.seg{display:inline-flex;flex-wrap:wrap;background:var(--gry-t);border-radius:var(--r-s);padding:3px;gap:2px;max-width:100%}
/* A pill may wrap its own label. "Work inside the applicant tracking system we already use" is
   wider than a phone on its own, and a pill that cannot wrap sets the width of the strip, the
   grid and the page above it. Short labels stay on one line because nothing makes them wrap. */
.seg button{
  background:var(--pl-back);border:1px solid var(--pl-back-e);padding:6px 14px;border-radius:var(--r-s);
  font:600 13px var(--ui);color:var(--pl-back-t);cursor:pointer;max-width:100%;min-height:30px;
  text-align:center;
  box-shadow:var(--lift-p);
  transition:background var(--m-state),color var(--m-state),box-shadow var(--m-lift),
    transform var(--m-lift),border-color var(--m-state)
}
.seg button:hover{background:var(--pl-go);color:var(--pl-go-t);border-color:var(--pl-go-e);
  box-shadow:var(--lift-p-h);transform:translateY(-1px)}
.seg button:active{transform:translateY(1px);box-shadow:var(--press-p)}
/* Chosen is the shared rule near the top of this file, "a control somebody chose". A white pill
   against the grey track was too close to the pills either side of it to be seen at a glance,
   and the pale tint that replaced it was the same colour as an unchosen pill's hover. */
.seg-s button{padding:4px 10px;font-size:var(--t-s);min-height:26px}

/* Every type a person types into, named in one list. Any new field type goes in it or it
   will look like a different product. */
.f select,.f input[type=text],.f input[type=email],.f input[type=password],.f input[type=number],.f input[type=file],.f input[type=search],.f input[type=tel],.f input[type=url],.f textarea{
  width:100%;border:1px solid var(--line);border-radius:var(--r-s);
  padding:var(--io-pad);font-size:var(--io-type);background:var(--io-bg);color:var(--ink)
}
.f select:focus,.f input:focus,.f textarea:focus{outline:2px solid var(--act);outline-offset:-1px;border-color:var(--act)}

/* The details somebody types off a record to check it by hand.
   Grouped in a fieldset rather than left loose, because eight inputs with no boundary read as
   eight unrelated questions, and these are one question asked eight ways: they all go into the
   same code and a blank in any of them is the same as a wrong answer.
   The two long codes sit full width below the grid on purpose. A sixty-four character code in a
   half-width box wraps mid-run, and the whole job here is spotting one wrong character. */
.detailset{border:1px solid var(--line);border-radius:var(--r-s);padding:var(--sp-3);margin:0 0 var(--sp-4)}
.detailset legend{padding:0 var(--sp-2)}
.detailgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:0 var(--sp-3)}
.f label.lbl{display:block;font:700 11px var(--ui);letter-spacing:.05em;color:var(--mid);
  text-transform:uppercase;margin-bottom:5px}
.f textarea{min-height:120px;resize:vertical}

/* The console: what a check runs against. */
.runsagainst{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px var(--sp-4);margin:var(--sp-3) 0}
.runsagainst dt{font-size:var(--t-s);color:var(--mid)}
.runsagainst dd{font-size:var(--t-s);color:var(--ink);font-family:var(--mono)}
.runsources{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.runsource{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.runsource-t{font-weight:600;font-size:var(--t-s)}
.runsource-s{font-size:var(--t-xs);color:var(--mid)}

/* The house checks list in the console. Each row is something the application holds
   and the operator reads, with the one press that takes it out beside it. */
.houselist{list-style:none;margin:0 0 var(--sp-3);padding:0;display:grid;gap:var(--sp-2)}
.house-row{display:flex;gap:var(--sp-3);align-items:flex-start;justify-content:space-between;
  background:var(--rail);border-left:3px solid var(--gry);border-radius:var(--r-s);padding:var(--sp-2) var(--sp-3)}
.house-label{font:600 var(--t-m) var(--ui);color:var(--ink);margin:0}
.house-text{font-size:var(--t-s);color:var(--mid);margin:2px 0 0}
.house-none{font-size:var(--t-s);color:var(--mid)}

/* What I flagged for attention. A list written to be selected and pasted, so every block
   is in the machine face and read only, and the row above it says the day and the build. */
.fault-days{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-4)}
.faults{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-4)}
.fault{
  background:var(--surf);border:1px solid var(--line);border-left:3px solid var(--gry);
  border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-4);
  display:flex;flex-direction:column;gap:var(--sp-3)
}
.fault-major{border-left-color:var(--red)}
.fault-incorrect{border-left-color:var(--amb)}
.fault-minor{border-left-color:var(--act)}
.fault-head{display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-3);align-items:center}
.fault-where{font:600 var(--t-b) var(--ui);color:var(--ink);min-width:0;overflow-wrap:anywhere}
.fault-at{font-size:var(--t-s);color:var(--mid)}
.fault-ver{font-size:var(--t-xs);color:var(--mid)}
.fault-head .ghost{margin-left:auto}
.fault-text{min-height:160px}

/* The console menu sits above the tab bar on a phone, not under it. */
@media (max-width:900px){
  .admin-float{left:var(--sp-3);bottom:calc(env(safe-area-inset-bottom,0px) + var(--sp-3))}
}

/* A small status label. The word carries the meaning and the colour repeats it. */
.tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:600;padding:2px 8px;border-radius:var(--r-s);white-space:nowrap;max-width:100%}
@media (max-width:400px){ .tag{white-space:normal;text-align:left} }
.tag svg{width:11px;height:11px}
.tag-red{background:var(--red-t);color:var(--red)}
.tag-amb{background:var(--amb-t);color:var(--amb-on-tint)}
.tag-grn{background:var(--grn-t);color:var(--grn)}
.tag-gry{background:var(--gry-t);color:var(--mid)}
.tag-act{background:var(--act-t);color:var(--act)}
.tag-vio{background:var(--vio-t);color:var(--vio)}

/* The information button. A real button, because a tooltip needs a mouse. */
.info{
  display:inline-grid;place-items:center;width:26px;height:26px;flex:none;padding:0;
  border:none;background:none;color:var(--mid);cursor:pointer;border-radius:var(--r-full);
  transition:background var(--m-state),color var(--m-state)
}
.info svg{width:15px;height:15px}
.info:hover{background:var(--gry-t);color:var(--ink)}
.info:focus-visible{outline:2px solid var(--act);outline-offset:1px}

.explain-p{margin-bottom:var(--sp-3);max-width:64ch}
.explain-p:last-of-type{margin-bottom:var(--sp-4)}

/* A heading with its explanation beside it. */
.h-info{display:flex;align-items:center;gap:4px;flex-wrap:wrap}

/* ------------------------------------------------------- depth 2 and depth 3

   Two more views of the same result, so nothing below introduces a treatment of its own.
   Everything the application produced for you to read is flat on the rail with a rule down
   its left edge; everything you press is raised and already dressed by the button rules
   above. The only new shapes are the diff row, which is a before and an after, and the
   question block, which is a segmented control with its answer said underneath. */

/* The score, before and after, as two rings.
   Everything about the ring's geometry is an attribute rather than a style, because the policy
   is style-src 'self' and a geometry set inline is refused: the ring would silently not draw.
   This file carries only what it is allowed to carry, which is colour and size.

   The three greens were validated, not chosen. --prod against --prod-d measured 9.5 delta E
   apart for normal colour vision against a floor of 15, which means most people cannot tell
   those two arcs apart; --prod against --nav-grn measures 24.3 normal and 24.2 under
   deuteranopia. The track is a lighter step of the same green, which is what a meter's unfilled
   track is supposed to be. Nothing here is a traffic light: the ring does not go red at a low
   score, because that turns the number into a verdict the caveat beneath it denies. */
.auto{margin:0 0 var(--sp-3)}
/* One dial and its legend, centred, because the three numbers under it are the reading and a
   left-aligned gauge puts them somewhere the eye has to go looking for. */
/* On a card, and that is a measurement rather than a decoration. The specification states its
   contrast ratios against the card the marks sit on: grey 3.95:1, blue 4.12:1, green 3.22:1.
   On this product's page ground the green measures 2.93:1, under the 3:1 WCAG 1.4.11 asks of a
   graphic that carries meaning, so the dial sits on the white the ratios were taken against,
   exactly as the reference file puts it in a panel. */
/* The card while the wording is still being read. It holds the same ground as the finished
   one, so nothing under it moves when the number arrives, and it says what it is doing in the
   place the caption already occupies. */
/* Two lines' worth of room, always, whether the line it is holding needs them or not.
   The check says a different thing every few seconds, and those things are different
   lengths: on a phone "Working out which rules apply (round 2)" wraps and "Reading the
   wording" does not, so the card grew and shrank under the dial while the dial was trying
   to say the wait was one steady thing. The box is the size of the longest thing it can
   say, and the words change inside it. */
.meter-wait{color:var(--mid);font-size:var(--t-s);text-align:center;margin:0;
  display:flex;align-items:center;justify-content:center;min-height:2.9em}
.sd-unit-wait{fill:var(--mid);letter-spacing:.02em}
/* The unread gauge. Fainter than stage one's grey, because this is not a reading of anything:
   it is the shape the reading will take. */
.sd-w-wait{fill:var(--line)}
/* The comet that turns while the wording is being read.
   Six ticks lit at a time, graded from a green head through the action blue to a tail that
   fades into the unread ring, so each grey segment appears to light and go out as it passes.
   The two colours are the product's own, not the dial's three: the stage colours mean as
   pasted, automatic and your answers, and a spinner wearing them would be saying something
   about a score that does not exist yet.
   Rotated about the middle of the drawing rather than its own box, which is what transform-box
   buys: without it each tick would spin on the spot. Motion off and reduced-motion both stop
   it, and the caption under it says what is happening in words, so nothing is carried by the
   movement alone. */
.sd-w-chase{fill:var(--act)}
.sd-w-chase-0{fill:var(--prod)}
.sd-w-chase-1{fill:var(--prod-blade)}
.sd-w-chase-2{fill:var(--act)}
.sd-w-chase-3{fill:var(--act);opacity:.72}
.sd-w-chase-4{fill:var(--act);opacity:.44}
.sd-w-chase-5{fill:var(--act);opacity:.20}
/* The glow, in both colours, so the head reads as lit rather than merely coloured. */
.sd-chase{transform-box:view-box;transform-origin:150px 150px;
  filter:drop-shadow(0 0 4px rgba(14,122,71,.55)) drop-shadow(0 0 9px rgba(11,95,191,.45))}
@keyframes sd-chase{to{transform:rotate(360deg)}}
@keyframes sd-chase-glow{0%,100%{opacity:.82}50%{opacity:1}}
:root[data-motion="on"] .sd-chase{
  animation:sd-chase 2s linear infinite, sd-chase-glow 1.1s ease-in-out infinite;
}
/* Tight, on purpose. The owner asked for the height of this card down to the minimum that
   still holds the dial and every control on it, so the padding is even and small, the gap
   between the dial, the chips and the caveat is one step rather than two, and the dial itself
   is 264 rather than 300: it is still far and away the largest thing on the card, and the
   forty pixels it gives back are forty the person does not scroll past. */
.board{display:flex;flex-direction:column;align-items:center;gap:var(--sp-3);margin:0 auto;
  max-width:34rem;background:var(--surf);border:1px solid var(--line);border-radius:var(--r-l);
  padding:var(--sp-3)}
/* ---------------------------------------------------------------------- the score dial
   Ported from the supplied reference implementation. Every number is that file's number.

   The two things that live here rather than in the markup are the two the reference sets
   through an inline style attribute: the shadow's flood colour and opacity, and the numeral's
   fill and weight. The reference says why it does not use presentation attributes for them, a
   presentation attribute cannot read a custom property, and this deployment serves
   style-src 'self', which refuses an inline style attribute outright. A stylesheet is CSS, so
   it reads the properties and keeps the reference's point. */
/* 300 is the contract's default rendered width. The reference page draws it at 380 because it
   is a demonstration with a whole page to itself; this sits above a result. */
.dial{display:block;width:100%;max-width:264px;height:auto}
.dial-small{width:150px;max-width:150px}

/* The marks. Thickness is the non-colour encoding and it lives in the geometry, so all this
   carries is the colour. */
.sd-w-1{fill:var(--stage-one)}
.sd-w-2{fill:var(--stage-two)}
.sd-w-3{fill:var(--stage-three)}
/* Ground still on offer: the lighter step of stage three, because taking it is stage three. */
.sd-w-could{fill:var(--stage-could)}

/* The shadow. Four stacked layers with rising blur and opacity give a graduated falloff
   instead of a hard halo. */
.sd-sh{flood-color:rgb(var(--shadow-rgb))}
.sd-sh-1{flood-opacity:var(--shadow-o1)}
.sd-sh-2{flood-opacity:var(--shadow-o2)}
.sd-sh-3{flood-opacity:var(--shadow-o3)}
.sd-sh-4{flood-opacity:var(--shadow-o4)}

/* The numeral. Neutral, never a stage colour: all the colour belongs in the ring, where it
   carries data. Coloured, it reads as a logo rather than as a result. */
.sd-num{fill:var(--ink);font-family:var(--ui);font-weight:800;letter-spacing:-.05em;
  font-variant-numeric:tabular-nums}
/* --mid rather than --soft. The caption under the number was the lightest grey in the set and
   at 15px it was barely there: a scale nobody can read is not a scale. */
.sd-unit{fill:var(--mid);font-family:var(--ui);font-weight:700}

/* The numeral and its caption scale as one group out of the centre of the circle rather than
   out of their own bounding box, so the caption travels outward as the numeral swells. Once,
   on arrival: looping motion on a results screen is a cost with no payoff. */
.sd-pulse{transform-box:view-box;transform-origin:150px 150px}
.sd-pulse.sd-arrive{animation:sd-arrive .8s cubic-bezier(.2,.9,.25,1) 1 both}
@keyframes sd-arrive{
  0%{transform:scale(.88)}
  55%{transform:scale(1.05)}
  100%{transform:scale(1)}
}
@media (prefers-reduced-motion: reduce){ .sd-pulse.sd-arrive{animation:none} }

/* The legend. The padding grows with the stage, repeating the dial's thickness story, so it
   teaches the rule without help text. Each chip carries its own text colour: chip text needs
   4.5:1 against its own background, which is stricter than the 3:1 the marks need, and white
   does not clear that on all three.

   Not called .chip, because this page already has one: the chip is the control that asks whose
   jobs these are. */
/* A stage nobody is looking at, on a dial that is one number split three ways. Dimmed rather
   than hidden or recoloured: the guidance is explicit that a filter must not repaint what it
   leaves, and hiding the top of a cumulative ring would leave a gauge reading two out of a
   hundred. Opacity only, so the colour a chip promises is the colour the wedge keeps. */
.sd-w-past{opacity:.28}
.stages>li{display:flex}
/* Pressed, and unmistakably so: a ring in the chip's own colour, held off the chip by the card
   behind it so it reads on all three. A control that looks the same pressed as unpressed is a
   control somebody presses twice. */
.sch-on{box-shadow:0 0 0 2px var(--surf),0 0 0 4px currentColor}
.sch:hover{filter:brightness(.95)}
.stages{list-style:none;margin:0;padding:0;display:flex;gap:8px;flex-wrap:wrap;
  justify-content:center}
/* The chip is a button now. It keeps every pixel it had and gains a pressed state and a focus
   ring, because a control that looks like a label is a control nobody presses. */
.sch{display:inline-flex;align-items:center;gap:7px;border-radius:99px;font:inherit;
  cursor:pointer;border:0;
  font-family:var(--ui);font-weight:800;font-size:.86rem;letter-spacing:-.01em;
  white-space:nowrap;box-shadow:-3px 3px 10px -3px rgba(var(--shadow-rgb),.45)}
/* No opacity. The quiet half of a chip is carried by size and weight, which cost nothing
   in contrast; .88 took the number on the automatic chip to 4.31:1 against its own
   ground, under the 4.5:1 its size asks for. Opacity on text is a colour nobody measures. */
.sch small{font-weight:600;font-size:.92em}
.sch-one{background:var(--stage-one);color:var(--stage-one-on);padding:6px 15px}
.sch-two{background:var(--stage-two);color:var(--stage-two-on);padding:9px 16px}
.sch-three{background:var(--stage-three);color:var(--stage-three-on);padding:12px 18px}

.meter-what{margin:var(--sp-2) 0 0}
/* 24px tall at least. It is a small line of grey text, and it is also the one control on the
   card, and a 19px control is under the size a finger can be expected to hit. */
.meter-what>summary{color:var(--mid);font-size:var(--t-s);cursor:pointer;min-height:24px;display:flex;align-items:center}
.meter-what>summary::-webkit-details-marker{display:none}
.meter-what .hint{margin:var(--sp-1) 0 0}

/* What has changed since the advert was pasted, before anything asks for a decision.
   Stage two's own ground where everything in it was written with nobody being asked anything.
   It was the product green, which is stage three's colour, so the one part of the journey that
   costs the person nothing was painted in the colour of the part they do themselves.

   Neutral where the list is a mix, which it usually is by the time somebody has answered
   anything. A blue panel behind a green row says that row was automatic, and this panel cannot
   claim one stage while it holds two. The rows carry the stage instead. */
/* No top margin of its own any more: it is a grid item of the result now rather than the last
   thing inside the score block, and the grid's gap is the space above it. */
.auto-did{margin:0;padding:var(--sp-3);border:1px solid var(--line);
  border-radius:var(--r-m);background:var(--stage-two-t)}
.auto-did-mix{background:var(--gry-t)}
.auto-did>h3{margin:0 0 var(--sp-2);font-size:var(--t-m)}
.auto-did>.hint{margin:0}
.dids{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-2)}
.did{background:var(--surf);border:1px solid var(--line);border-radius:var(--r-s);
  padding:var(--sp-2)}
/* The stage down the edge of the card, so which lines were free and which were bought is a
   thing somebody sees running an eye down the list rather than a thing they read off six
   badges one at a time. */
.did-s2{border-left:3px solid var(--stage-two)}
.did-s3{border-left:3px solid var(--stage-three)}
/* The rule's name and the way to say it is wrong, on one line, with the name taking the room
   and the button holding the right edge. The name was a block of its own, so putting the button
   after it dropped it onto a line by itself on every row of the list. */
.did-top{display:flex;gap:var(--sp-3);align-items:baseline;justify-content:space-between}
.did-top .report-wrap{flex:none}
.did-rule{display:block;font-size:var(--t-b);min-width:0}
.did-add{margin:4px 0 0;font-size:var(--t-b)}
.did-line{margin:0;display:flex;gap:var(--sp-2);align-items:flex-start}
/* The sentence on its own ground, because it is about to go into somebody's advert and the
   screen should say so by shape as well as by the word "Added".

   In the colour of the stage that produced it, which is the whole point of having three
   colours: blue where the engine wrote it with nobody being asked anything, green where it
   exists because the person answered. A row of each, side by side in one list, is the clearest
   statement of the difference this product makes for free. */
.did-text{flex:1;min-width:0;background:var(--surf);border-left:3px solid var(--gry);
  border-radius:0 var(--r-s) var(--r-s) 0;padding:var(--sp-2) var(--sp-3)}
.stage-2 > .did-text{background:var(--stage-two-t);border-left-color:var(--stage-two)}
.stage-3 > .did-text{background:var(--stage-three-t);border-left-color:var(--stage-three)}
/* And the badge beside it. These are the chip colours from the dial's legend, so the mark on a
   row and the wedge it moved are the same colour. */
.mark-stage-2{background:var(--stage-two);color:var(--stage-two-on)}
.mark-stage-3{background:var(--stage-three);color:var(--stage-three-on)}
/* The part of it that is theirs rather than ours: remembered on this device, going into a
   published advert exactly as typed, and the part most likely to be wrong.
   In the Edit button's own colours rather than a yellow of its own, which is what makes the
   mark mean something: the highlighted words are exactly what that button changes. The two
   were a near-miss of each other before, close enough to look like a coincidence and not close
   enough to read as one thing. */
.did-yours,.did-yours-2{background:var(--pl-yours-h);color:var(--pl-yours-t);border-radius:3px;padding:0 3px;
  box-shadow:inset 0 -2px 0 var(--pl-yours-e);font-weight:600}
.did-yours.did-yours-3{background:var(--pl-yours3-h);color:var(--pl-yours3-t);box-shadow:inset 0 -2px 0 var(--pl-yours3-e)}
/* The key, on the one screen that asks somebody to keep the sentence. A colour with no key is
   a decoration. */
.did-key{margin:var(--sp-2) 0 0;font-size:var(--t-s);color:var(--mid)}
.did-key-swatch{margin-right:var(--sp-1)}
.did-off{background:var(--red-t);color:var(--red-h);box-shadow:inset 0 -2px 0 var(--red)}
.did-off-say{margin:var(--sp-2) 0 0;display:flex;gap:var(--sp-2);align-items:flex-start;
  color:var(--red-h);font-size:var(--t-s)}
.did-off-say .i{flex:none;margin-top:1px}
/* And the fold that button opens, in the same colour as the button and the marks, so the three
   read as one thread: these words, that button, this form. */
.did-fold{margin:var(--sp-2) 0 0;background:var(--surf);border-color:var(--pl-yours-e)}
/* The title strip carries the stage's light tint, as the button that opens the fold does, so the
   fold reads as that button's form whether it is open or shut. The inside stays white, where
   the boxes are. */
.did-fold > summary{color:var(--pl-yours-t);background:var(--pl-yours)}
.did-fold > summary:hover{background:var(--pl-yours-h)}
.did-fold[open] > summary{border-bottom-color:var(--pl-yours-e)}
.did-fold.did-fold-3{border-color:var(--pl-yours3-e)}
.did-fold.did-fold-3 > summary{color:var(--pl-yours3-t);background:var(--pl-yours3)}
.did-fold.did-fold-3 > summary:hover{background:var(--pl-yours3-h)}
.did-fold.did-fold-3[open] > summary{border-bottom-color:var(--pl-yours3-e)}
/* Every box that changes a detail, under the list rather than inside the row that used it.
   A control in the middle of a list of finished changes breaks the reading of it in half. */
.did-amends{margin:var(--sp-3) 0 0;padding:var(--sp-3) 0 0;border-top:1px solid var(--line)}
.did-amends>.hint{margin:0 0 var(--sp-2)}
.did-amends>.did-fold{margin:0 0 var(--sp-2)}
.did-amends>.did-fold:last-child{margin-bottom:0}
.did-swap{margin:4px 0 0}
.did-swap>.mark{margin:0 0 var(--sp-2)}
/* The new wording in the colour of the stage that wrote it. It was the product green in both
   cases, which is stage three's colour, so a rewording nobody was asked about read as one the
   person had paid for. */
.did-swap.stage-2 .diff-new{background:var(--stage-two-t)}
.did-swap.stage-3 .diff-new{background:var(--stage-three-t)}
.walk-open{margin:var(--sp-3) 0 0}

/* The guided pass, which is stage three: the person going through it themselves.

   It was the action blue, which is stage two's colour, so the manual pass was painted as
   though the machine were doing it. Green here is the same green as the third wedge of the
   dial and the same green as a change bought by an answer, because this panel is where those
   answers are given. */
/* Where you are working, said by the card itself.
 *
 * Asked for: make the green border thicker and make it glow, so it is obvious where somebody is
 * and what to do next. Three pixels and a halo, and the halo is a static ring rather than a
 * pulse that never stops, for reasons worth writing down because "make it glow" and "make it
 * blink" are one keystroke apart.
 *
 * What actually draws the eye, in order: motion, then enclosure and contrast, then colour.
 * Motion is the strongest of the three and is the one that cannot be left running. A thing that
 * moves forever is a thing the eye keeps returning to while somebody is trying to read the
 * sentence inside it, it never habituates, and for a reader with a vestibular disorder it is
 * not a nuisance but a symptom. WCAG 2.2.2 says anything moving for more than five seconds
 * needs a way to stop it; this product has one, the Motion switch, and leaning on it to excuse
 * a permanent pulse would be using an accessibility control as permission.
 *
 * So motion is spent where it is worth most: once, on arrival, when the step changes. That is
 * the moment the answer to "where am I now" changed, which is the only moment the question is
 * being asked. After it the card holds still and the halo, the thicker edge and the tinted bar
 * carry "this is the live one" without asking for anything.
 *
 * And the non-visual half, which is the part a glow cannot do: the step and its heading are
 * announced in the live region, so somebody who cannot see the card is told the same thing at
 * the same moment. See announceResult in check.mjs. */
/* ------------------------------------------------------------- the floating window

   The guided pass is a window over the page rather than a card in the middle of it. Asked for
   in those words: this screen should be above the flat one, it should take the focus, and what
   is behind it should be out of focus.

   The veil is at z-index 49. One step under .scrim, which is the modal behind "Why is this
   needed?", because a control in this window opens that modal and a window that painted above
   it would send somebody to a panel they could neither read nor close. Above the sticky bar at
   48, because a page still offering its own navigation is not behind anything. Toasts stay
   above both at 55, since the pass speaks through them. */
.winveil{position:fixed;inset:0;z-index:49;display:grid;place-items:center;
  padding:var(--sp-4);overflow:auto;
  background:rgba(13,27,42,.34);animation:fade var(--m-panel) both}
.winveil[hidden]{display:none}
/* And the page itself out of focus, which is the word that was used and is the literal one.
   Dim alone reads as a page that is loading; blurred, it reads as a page that is behind
   something. It is also inert while this class is on, so nothing here is only visual.
   Not on .winveil's own ancestors: a filter makes a containing block for fixed children, and
   the veil is a child of body rather than of main for exactly that reason. */
body.win-on > main, body.win-on > header.bar, body.win-on > footer.foot{
  filter:blur(3px) saturate(.7);pointer-events:none}
/* And the page behind does not scroll under the window. Without this a wheel over the edge of
   the veil moved the blurred page, which reads as the window drifting. */
body.win-on{overflow:hidden}
/* The window. A column that grows with what is in it, up to the height of the screen, and
   scrolls inside itself after that: a decision with three boxes on it is taller than a phone,
   and a window that grew past the screen would put its own way out off the bottom. */
.win{width:min(100%, 62rem);max-height:calc(100dvh - var(--sp-6));overflow:auto;
  border-radius:var(--r-m);background:var(--surf);
  box-shadow:0 0 0 4px var(--stage-three-halo), -24px 24px 60px rgba(13,27,42,.34), var(--sh)}
.win:focus{outline:none}
.win:focus-visible{outline:2px solid var(--act);outline-offset:3px}
/* The decision and the dial, side by side, with the dial holding a column of its own so it
   does not move when the decision under it changes height. Under 760px the dial goes above the
   decision rather than beside it, because 9rem out of a phone's width is most of the sentence.
   Asked for: the dial is on the window whenever the window is up. */
/* The bar stays at the top of the window while the decision under it scrolls. That is the
   whole reason it was moved above the decision in the first place: on a step taller than the
   screen the way out was below the form somebody had just decided not to fill in. A window
   that scrolls inside itself puts it back there unless it is pinned. */
.win .walk-nav{position:sticky;top:0;z-index:2}
.win-grid{display:grid;grid-template-columns:minmax(0,1fr) 11rem;align-items:start}
.win-dial{padding:var(--sp-3) var(--sp-3) var(--sp-3) 0;display:grid;justify-items:center;
  gap:2px;position:sticky;top:0}
.win-dial .dial{width:150px;max-width:150px}
.win-dial-c{margin:0;text-align:center;font-size:var(--t-xs);font-weight:600;color:var(--prod-d)}
.win-dial-w{margin:0;text-align:center;font-size:var(--t-xs);color:var(--mid)}
@media (max-width:760px){
  .win-grid{grid-template-columns:minmax(0,1fr)}
  .win-dial{grid-row:1;padding:var(--sp-3) var(--sp-3) 0;position:static}
  .win-dial .dial{width:110px;max-width:110px}
}
/* The summary, which is a second window and not a panel on the first one. What tells them
   apart on sight is that this one has no step bar: there is nowhere left to step. */
.recap-h{margin:0;font-size:var(--t-m)}
.recap{list-style:none;margin:var(--sp-3) 0 0;padding:0;display:grid;gap:var(--sp-2)}
.recap-row{display:grid;grid-template-columns:9.5rem minmax(0,1fr);gap:var(--sp-3);
  align-items:baseline;padding:var(--sp-2) 0;border-top:1px solid var(--line)}
.recap-row .mark{justify-self:start}
.recap-q{min-width:0}
.recap-do{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:center;
  margin-top:var(--sp-4)}
@media (max-width:560px){
  .recap-row{grid-template-columns:minmax(0,1fr);gap:2px}
}

.walk{margin:0;border:3px solid var(--stage-three);
  border-radius:var(--r-m);background:var(--surf);
  box-shadow:none}
/* The summary window wears the same edge as the pass, because it is the same journey one step
   further on, and it is a separate selector because it is a separate window: everything that
   asks whether the pass is on the screen asks for `.walk`, and a summary answering yes to that
   is a summary pretending to be the thing it replaced. */
.win-recap{margin:0;border:3px solid var(--stage-three);
  border-radius:var(--r-m);background:var(--surf)}
/* Once, on the step that has just arrived, and never again until the next one. The card is
   rebuilt on every draw, so this class is put on it only when the step index changed: without
   that it would fire on every keystroke in a box inside the card. */
@keyframes walk-arrive{
  0%{box-shadow:0 0 0 0 rgba(18,166,47,.45), var(--sh)}
  55%{box-shadow:0 0 0 14px rgba(18,166,47,0), var(--sh)}
  100%{box-shadow:0 0 0 4px var(--stage-three-halo), var(--sh)}
}
/* Inside a window the pulse is drawn on the window's own edge rather than on the card's, so
   the ring of light is round the thing somebody is looking at. */
:root[data-motion="on"] .win:has(.walk-arrived){animation:walk-arrive 900ms var(--ease-panel) 1}
.walk-body{padding:var(--sp-3)}
/* Every control that moves or undoes, across the top and on the left, on every step.

   Across the top because they were under the decision, which on a panel that ran past the
   bottom of the screen put the way out below the form somebody had just decided not to fill
   in. On the left, and in one order, because the way somebody works through seven of these is
   to put the pointer where the button was last time and press without looking. */
.walk-nav{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;
  padding:var(--sp-2) var(--sp-3);background:var(--stage-three-t);
  border-bottom:1px solid var(--stage-three);border-radius:calc(var(--r-m) - 2px) calc(var(--r-m) - 2px) 0 0}
/* Where you are, pushed to the end. It is the one thing in this bar that changes every step,
   so it is the one thing that must not sit in front of the controls and move them. */
.walk-where{margin:0 0 0 auto;color:var(--prod-d);font-weight:600;font-size:var(--t-s);
  font-variant-numeric:tabular-nums;flex:none}
/* One pip per decision, which is the count again as a shape. Aria-hidden: the words beside it
   say the same thing and a row of identical dots read out one at a time is noise. */
.walk-bar{flex:0 1 8rem;min-width:2.5rem;display:flex;gap:3px;align-items:center}
.walk-pip{flex:1 1 0;height:6px;border-radius:var(--r-full);background:#fff;
  border:1px solid var(--stage-three);opacity:.4}
.walk-pip-done{background:var(--stage-three);opacity:.7}
.walk-pip-here{background:var(--stage-three);opacity:1}
.walk-acts{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap}
/* Fixed widths, so a label that changes does not drag the buttons after it along with it.
   "Finish" is shorter than "Next" and would move the other three on the last step; "Reset this
   one" is on every step whether or not there is anything to reset, and is disabled rather than
   absent for the same reason. A control that is somewhere else on step four than it was on
   step three is a control somebody has to look at, and looking at it is the thing this is
   trying to save them. */
.walk-move{min-width:6.5rem;justify-content:center}
/* 10.5rem rather than 9. Both resets carry an undo icon now, and "Reset everything" with an
   icon, its gap and the padding comes to about 153px: at 9rem (144px) the widest control in the
   bar sets its own width and the row stops being the fixed thing it is here to be. */
.walk-wide{min-width:10.5rem;justify-content:center}
/* Disabled by aria rather than by the attribute, so it keeps its place in the tab order and
   still says what it is. Nothing here is hidden; it simply does nothing on a step with nothing
   to undo. No opacity: it used to carry .45, which took the label on "Reset this one" to
   1.50:1 against its own plate, on a control a keyboard user can still land on. The shared
   aria-disabled treatment says unavailable four ways over; this only has to say which cursor. */
.walk-acts button[aria-disabled="true"]{cursor:not-allowed}
.walk-item>h3{margin:0 0 var(--sp-1);font-size:var(--t-m)}
/* Asked for: condense the referral card as far as it will go, keeping every control. What came
   off it was the pair of boxed lines reading the answers back; what is left is the question,
   the buttons, and where the answer came from. The questions stand a step closer together,
   because three questions spaced for a card that also carried two confirmations under them
   leaves a gap where the confirmations used to be. */
.walk-ask .ask-qs{gap:var(--sp-3)}
.walk-ask .ask-outs:not(:empty){margin-top:var(--sp-2)}
.walk-say{margin:var(--sp-1) 0}
.walk-do{margin:var(--sp-3) 0 0;display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center}
/* The one that takes something out, held off the rest of the row.
   A fixed gap and never margin-left:auto: .why-link already claims an auto margin in this row
   and .report-wrap claims a second, and three autos share the free space between them, so the
   red button would sit in a place that moves when the why-link's label changes. That is the
   moving-control fault .walk-nav exists to prevent, imported into the row below it.
   On a phone the row wraps, and a stranded indent on a wrapped line reads as a bug. */
.walk-do .ghost-warn{margin-left:var(--sp-5)}
/* A finding the walk can only put in front of somebody: the wording it was read off, and the
   law behind it. The quote is marked as a quote rather than styled to look like one, so it
   reaches a screen reader as the advert's words and not as ours. */
.walk-quote{margin:var(--sp-2) 0;padding:var(--sp-2) var(--sp-3);background:var(--rail);
  border-left:3px solid var(--line);border-radius:0 var(--r-s) var(--r-s) 0}
.walk-quote q{display:block;margin-top:2px;font-style:italic}
.walk-cite{font-size:var(--t-xs)}


/* Why a rule is flagged and what to do about it, in the open under the flag it is about.
   Closed by default: somebody who already knows what a rule wants should not scroll past the
   explanation on every one of six steps. */
.brief-fold{margin:var(--sp-3) 0 0;border-color:var(--line)}
.brief-fold>summary{padding:var(--sp-2) var(--sp-3);min-height:36px;justify-content:flex-start;
  font:600 var(--t-s) var(--ui);color:var(--act)}
.brief-fold>summary:hover{background:var(--act-t);border-radius:var(--r-s)}
.brief-fold>summary::after{content:'';flex:none;width:8px;height:8px;margin-left:var(--sp-2);
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg) translateY(-2px);transition:transform var(--m-state)}
.brief-fold[open]>summary{border-bottom:1px solid var(--line);border-radius:var(--r-s) var(--r-s) 0 0}
.brief-fold[open]>summary::after{transform:rotate(-135deg) translateY(-2px)}
.brief-fold>.brief{padding:var(--sp-3);display:grid;gap:var(--sp-3)}
.brief-b{display:grid;gap:var(--sp-1)}
.brief-b h4{margin:0;font:700 var(--t-xs) var(--ui);text-transform:uppercase;letter-spacing:.06em;
  color:var(--mid)}
.brief-b p{margin:0;max-width:72ch}
/* What to do, which is the part somebody came here for, on its own ground. */
.brief-do{background:var(--act-t);border-radius:var(--r-s);padding:var(--sp-3)}
.brief-law{border-top:1px solid var(--line2);padding-top:var(--sp-3)}
.brief-row{display:flex;gap:var(--sp-3);font-size:var(--t-s);margin:0}
.brief-k{flex:none;width:11rem;color:var(--mid)}
.brief-v{min-width:0}
.brief-more{margin:0;font-size:var(--t-s)}

/* On a phone the dial takes what it needs and the chips wrap under it. The gauge is the one
   thing on this screen that must not shrink below reading size: it is a hero figure, and a hero
   figure nobody can read from arm's length is a decoration. */
@media (max-width:480px){
  /* The dial is already width:100% with a cap, so it fits by itself. The chips close up, but
     the padding still steps from one stage to the next, because that step is the legend
     teaching the ring's thickness story. */
  .stages{gap:6px}
  .sch{font-size:var(--t-xs)}
  .sch-one{padding:4px 10px}
  .sch-two{padding:6px 11px}
  .sch-three{padding:8px 12px}
  .auto-did{padding:var(--sp-2)}
  .auto-did>h3{font-size:var(--t-b)}
  .walk-nav .ghost-warn{margin-left:0}
}


/* The two routes out of the first result.
   Green carries on and raises the score, which is the same green as the ring it moves and the
   same green .btn-write uses for the other control that writes into somebody's advert. Blue
   finishes, which is what app.css means at line 51 by "action, the only blue": it is for taking
   something away. Neither leans on the colour: each carries a word and an icon as well. */
/* Every result: the reading on the left, the two ways out beside it.

   This was the last screen's layout and the rest of the journey stacked instead, on the
   reasoning that until the decisions are done the page is about the work left to do. Two
   faults came out of that. The dial card is 34rem wide and centred, so on its own on a wide
   page it is an island with empty ground either side of it and a left edge that agrees with
   nothing else on the screen. And the control that takes the advert further ended up below a
   summary of work already finished, which on a result with six changes in it is below the
   fold. One arrangement everywhere is also one fewer state to keep in agreement: there is no
   moment where the page rearranges itself under somebody who has just answered something.

   Everything in here is aligned to the page rather than to itself. The dial card starts where
   the headline starts, because beside a column a centred card is two different left edges.
   Heights match rather than being left alone: two columns ending at different points read as
   unfinished, and the dial takes up the slack so it sits in the middle of its side.

   The ratio is the dial's. It is drawn at 300 and needs its legend beside it, and the two route
   cards are text and buttons that read better narrow than wide. One column below 52rem, which
   is where the right column stops fitting the two buttons in the finish card side by side and
   the dial stops being readable next to them. */
/* The advert on the left and the reading beside it.
   It was the dial on the left and the two ways out on the right, with the advert itself two
   presses inside a fold below. The thing somebody came to produce is now the larger half of
   the screen, and the score and the ways out stack in the column next to it. The ratio is the
   advert's: prose wants a wide measure, and three columns of it at this width would leave each
   one about forty-five characters a line. */
.result-lead{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:var(--sp-4);align-items:stretch}
/* The score and the ways out, stacked, as one column. */
.lead-side{display:flex;flex-direction:column;gap:var(--sp-4);min-width:0}
.lead-side>.auto{flex:none}
.lead-side>.routes-wrap{flex:1}
/* Both columns the same height, and the dial centred in whatever height that is.
   They were left to their own heights on the reasoning that padding one with nothing reads as
   a mistake. On this screen it reads as a ragged edge instead: this is the last thing somebody
   sees and two columns ending at different points make it look unfinished. So they match, and
   the dial sits in the middle of its side rather than at the top of a tall box. */
.result-lead>.auto{display:flex;flex-direction:column}
.result-lead .board{flex:1}
/* The dial and its chips take the slack, so they sit in the middle of a tall card rather than
   at the top of one, and the caveat stays at the foot of it where it belongs. */
.result-lead .board>.dial{margin-top:auto}
.result-lead .board>.stages{margin-bottom:auto}
.board>.meter-what{align-self:stretch;margin-top:0}
.result-lead .routes-wrap{display:flex;flex-direction:column}
.result-lead .routes{flex:1;align-content:stretch}
.result-lead>.auto{margin:0}
.result-lead .board{max-width:none;margin:0}
.result-lead .routes-wrap{margin:0}
.result-lead .routes{grid-template-columns:minmax(0,1fr)}
/* The way back carries .walk-open, whose top margin is the space it needs when it follows the
   list of changes down the page. In this column that margin is the right edge of one card
   starting twelve pixels below the other, which is the whole of what "aligned" rules out. The
   space between the two cards is the grid's gap and is unaffected. */
.result-lead .walk-open{margin-top:0}
@media (max-width:52rem){
  .result-lead{grid-template-columns:minmax(0,1fr)}
  /* One column, so the two cards are a stack rather than two widths. Both are held to the same
     width and centred on the same axis. The width is stated on both rather than left to
     `margin:0 auto` on its own: an auto cross-axis margin on a flex item turns off the stretch
     that would have filled the column, so the card shrank to fit its contents and came out
     nineteen pixels narrower than the one under it, centred but not aligned. */
  .result-lead .board,
  .result-lead .routes-wrap{width:100%;max-width:34rem;margin:0 auto}
  .vacancy-live{max-width:34rem;margin:0 auto;width:100%}
  /* Its own height on one column, where the page scrolls past it rather than beside it. */
  .al-body{max-height:24rem}
  /* The reading and the two ways out first, the advert under them.
     On one column the advert is the tallest thing on the screen, so leaving it in document
     order put both of the controls that finish the journey more than a screen below the top of
     the result: the fault this screen was rebuilt to fix, reintroduced by the fix. The advert
     is still there, one scroll down, at the width of the page rather than half of it. */
  .result-lead{display:flex;flex-direction:column}
  .lead-side{order:1}
  .vacancy-live{order:2}
  /* And the column holding them is held to the same width as the advert under it, rather than
     each card inside it being held separately: a stack whose cards share a width but not an
     edge is the thing the width was stated for. */
  .lead-side{width:100%;max-width:34rem;margin:0 auto}
}

/* -------------------------------------------------------------- the advert, and its versions

   One panel, three versions, chosen by the tabs across its head. The alternative the owner was
   shown was two or three panels of near-identical text side by side, and the reason this won is
   that two walls of prose ask somebody to find the differences themselves when the product
   already knows exactly which sentences it wrote. It marks them instead.

   The panel carries a stage class, so the edge and the tab agree with the wedge on the dial
   that the same stage moved. */
/* A floor, so a short result does not leave the advert in a letterbox. */
/* One outline, in the colour of the version showing, all the way round: down the sides of the
   panel, along the bottom, up the strip and around the chosen tab, with no line across under
   that tab. Asked for in those words, with the gap marked on a screenshot.
   It was a 1px grey box with a 3px stage-coloured cap on top, which said which version was
   showing only at the very top of a panel that is two thirds of the screen. */
.vacancy-live{display:flex;flex-direction:column;min-width:0;min-height:26rem;background:var(--surf);
  border:2px solid var(--line);border-radius:var(--r-m);overflow:hidden;
  box-shadow:var(--lift-p)}
.vacancy-live.stage-1{border-color:var(--stage-one)}
.vacancy-live.stage-2{border-color:var(--stage-two)}
.vacancy-live.stage-3{border-color:var(--stage-three)}
/* The strip the tabs stand on, and its bottom edge is the same line as the panel's sides: the
   outline runs along here and the chosen tab breaks it. */
.al-head{flex:none;padding:var(--sp-3) var(--sp-4) 0;background:var(--rail);
  border-bottom:2px solid var(--line)}
.vacancy-live.stage-1 .al-head{border-bottom-color:var(--stage-one)}
.vacancy-live.stage-2 .al-head{border-bottom-color:var(--stage-two)}
.vacancy-live.stage-3 .al-head{border-bottom-color:var(--stage-three)}
.al-title{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap}
.al-title>h3{margin:0;font-size:var(--t-m)}
.al-sub{font-size:var(--t-s);color:var(--mid)}
.al-chars{margin-left:auto;font-size:var(--t-s);color:var(--mid);font-variant-numeric:tabular-nums}
/* The tabs sit on the edge of the body they change, which is the whole of how a tab says what
   it belongs to. */
.al-tabs{display:flex;gap:4px;margin-top:var(--sp-3)}
/* One line, the name and the number, because two lines put the number's descender on the
   border the tab sits against and it read as a control cut in half. */
.al-tab{flex:1 1 0;min-width:0;display:flex;align-items:baseline;gap:var(--sp-2);text-align:left;
  font:600 var(--t-b) var(--ui);cursor:pointer;padding:10px var(--sp-3);min-height:46px;
  background:var(--gry-t);color:var(--mid);border:1px solid var(--line);border-bottom:0;
  border-radius:var(--r-s) var(--r-s) 0 0}
.al-tab:hover{filter:brightness(.95)}
/* Every tab is its stage, in the stage's own fill, and it is the same pairing as the lozenge
   under the dial: `.sch-one`, `.sch-two` and `.sch-three` set exactly these two tokens.
   Asked for in those words, the tab headings should be the same colour as the stages, which is
   the same as below the score. They wore the paper before, which is where pressing them takes
   you rather than what they are, and the row came out as three near-white tabs beside three
   filled lozenges saying the same three things.
   Measured: the ink on each fill is 4.87:1, 4.67:1 and 5.76:1, and each fill is 3.95:1, 4.12:1
   and 3.22:1 against the white head it sits on, so the control is identified without the edge
   having to do it. */
.al-tab-1{background:var(--stage-one);color:var(--stage-one-on);border-color:var(--stage-one)}
.al-tab-2{background:var(--stage-two);color:var(--stage-two-on);border-color:var(--stage-two)}
.al-tab-3{background:var(--stage-three);color:var(--stage-three-on);border-color:var(--stage-three)}
/* The same hover the lozenges use, for the same reason: a tab that loses its colour when you
   point at it is a tab that denies what it is. Deepening the fill keeps the stage and says the
   pointer is on it. */
.al-tab-1:hover,.al-tab-2:hover,.al-tab-3:hover{filter:brightness(.95)}
.al-tab-n{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.al-tab-v{flex:none;font-size:var(--t-m);font-weight:700;font-variant-numeric:tabular-nums}
/* The chosen one takes its stage's colour, which is the same colour as the wedge it is about.
   Not the accent fill the pick-one controls use: this is not "which option did you choose", it
   is which of three readings of one document you are looking at, and painting it in the accent
   would say a stage had been agreed to. */
/* And the chosen one is plainly the chosen one, now by being part of the panel rather than by
   being marked on top of it: a 2px edge in its stage's colour up and over the tab, no edge
   underneath, and a negative margin of the same 2px so the tab's own ground covers the strip's
   line and the outline reads as one unbroken shape. The tint and the full-weight ink stay.
   The inset ring and bar that used to say "chosen" are gone: the outline says it now, and
   three marks for one state is two too many. */
/* Which one is chosen is now said four ways and by none of them colour, which it has to be:
   all three carry their stage's fill, so the fill cannot also be what marks one of them out.
   Raised against pressed in, 800 against 600, a 2px edge against 1px, and joined to the panel
   against sitting on top of it. Each survives greyscale and forced colours on its own. */
.al-tab{box-shadow:var(--press-p)}
.al-tab-on{font-weight:800;border-width:2px;margin-bottom:-2px;padding-bottom:11px;
  box-shadow:var(--lift-p)}
/* The advert scrolls in its own box, so the controls that act on it stay under it however long
   it is. A job advert is a long document and the page scrolling past its own footer is how the
   old arrangement lost them. */
/* flex-basis 0 and min-height 0, which is the whole of why it scrolls: a flex child will not
   shrink below its own content without min-height:0, so the box grew to the length of the
   advert, the panel grew with it, and nothing scrolled at all. At basis 0 the body contributes
   nothing to the panel's natural height, so the row is as tall as the column beside it and the
   advert scrolls inside whatever that comes to. */
.al-body{flex:1 1 0;min-height:0;overflow-y:auto;padding:var(--sp-4);
  scrollbar-gutter:stable}
.al-body:focus-visible{outline:2px solid var(--act);outline-offset:-2px}
/* The version you are on, said by the whole page rather than by a 3px edge at the top of the
   card. It is the same colour as the tab above it and the wedge on the dial beside it. */
.vacancy-live.stage-1 .al-body{background:var(--stage-one-paper)}
.vacancy-live.stage-2 .al-body{background:var(--stage-two-paper)}
.vacancy-live.stage-3 .al-body{background:var(--stage-three-paper)}
/* Flattened inside the panel. The advert used to be one card inside a fold, so it carried its
   own ground, border and accent edge; in here that is a box drawn inside a box, and the panel's
   own top edge already says which version this is. */
.al-body>.vacancy{margin:0;background:none;border:0;border-radius:0;padding:0}
.al-foot{flex:none;display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--line);background:var(--rail)}
.al-note{font-size:var(--t-s);color:var(--mid);min-width:0}
.al-foot>.al-note:last-child{margin-left:auto;text-align:right}
/* A version somebody is looking at rather than working on carries no controls, and the line
   under it says so. It used to try to say it with a grey ground as well, which never reached
   the screen: `.al-body > .vacancy` sets `background: none` and is the more specific of the
   two, so the rule had been dead since the panel was built. The paper says it now, in the
   colour of the version being looked at, which is more than the grey ever said. */

/* The consent, beside the thing it is consent for.
   A tick on its own line under the boxes, because it is a decision about the boxes rather than
   another box, and its explanation under it rather than beside it, because it is a sentence. */
.cap-keep,.mine-keep{margin:var(--sp-3) 0 0;display:grid;gap:4px}
.lbl-row{display:flex;gap:var(--sp-2);align-items:flex-start;font-size:var(--t-b);cursor:pointer}
/* Twenty-four, because that is the floor WCAG 2.5.8 puts under a target and eighteen is under
   it. It is a chunky box beside a line of text and that is the right way round: GOV.UK draws
   this control at forty. */
.lbl-row input[type="checkbox"]{flex:none;width:24px;height:24px;margin:0;cursor:pointer}
.mine{display:grid;gap:var(--sp-3)}
/* Two groups, and they have to read as two rather than as one list with a heading in it, or
   somebody puts the name that belongs on the record into a published advert. */
.mine-group{display:grid;gap:4px;padding:var(--sp-3) 0 0;border-top:1px solid var(--line)}
.mine-group>h4{margin:0;font-size:var(--t-b)}
.mine-group>.hint{margin:0 0 var(--sp-2)}
.mine .cap-fs{display:grid;gap:var(--sp-3)}
.mine-acts{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:center;margin-top:var(--sp-2)}
/* Last, and away from the rest, because it is the one control here that cannot be undone. */
.mine-clear{margin-left:auto;color:var(--red-h)}

.routes-wrap{margin:var(--sp-4) 0 var(--sp-3)}
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--sp-3);
  align-items:start}
.route{display:flex;gap:var(--sp-3);align-items:flex-start;text-align:left;
  padding:var(--sp-3);border-radius:var(--r-m);border:1px solid var(--line);background:var(--surf)}
.route-k{display:flex;align-items:center;gap:6px;font:700 var(--t-xs) var(--ui);
  text-transform:uppercase;letter-spacing:.06em}
.route-k .i{width:14px;height:14px}
.route-h{display:block;font-size:var(--t-m);margin:2px 0}
.route-t{display:flex;flex-direction:column}
.route-say{color:inherit;font-size:var(--t-s)}
.route-could{margin-top:var(--sp-2);font:700 var(--t-m) var(--ui)}
/* Where the score genuinely cannot move. Same place on the card, quieter type, because it is
   a fact rather than a gain and dressing it as one would be the product selling nothing. */
.route-could-flat{font:600 var(--t-s) var(--ui)}
.route-hint{margin:var(--sp-2) 0 0}

/* Carry on. A button rather than a card with a button in it, because the whole of it is one
   action and half a card that is clickable is worse than none of it. */
/* In stage three's own green, which is the one the chip under the dial wears.
   Reported: the large green button is a different green from the lozenge below the dial, and
   that green should be the one every stage three action carries. It was --prod, the product's
   own green, which is a brand colour and says nothing about where in the journey somebody is.
   The ink goes near-black with it, because white on this green is 3.22:1 and the whole point
   of matching the chip is to be the same colour as the chip: near-black on it measures 5.76:1,
   which is what the chip has always used.
   Hover deepens the shadow and leaves the fill alone. Darkening the fill would take the ink
   under the bar, and a card that dims its own words when you point at it is not a hover. */
.route-carry{font:inherit;cursor:pointer;color:var(--stage-three-on);background:var(--stage-three);
  border-color:var(--stage-three-e);box-shadow:var(--lift-f);align-items:center}
.route-carry:hover{box-shadow:var(--lift-f-h)}
.route-carry:active{box-shadow:var(--press-f)}
/* No opacity on it. At .82 the label measured 4.49:1 against the card, one hundredth under the
   bar, which is the kind of number that only ever turns up because something measures it. */
.route-carry .route-k{color:var(--stage-three-on)}
.route-carry .dial{width:104px;max-width:104px;height:auto;flex:none}
.route-carry .sd-num{fill:var(--stage-three-on)}
/* The three stages on a green card cannot be the three stage colours: two of them would be
   green on green. What the small dial is for here is the ground still on offer, so that is what
   keeps its colour, and the score it already has is one solid white run behind it. The big dial
   above, on the page's own surface, is where the three stages are read. The stepped outer edge
   is still there, so the three stages are still told apart by thickness.

   Which of the two is the bold one is now the other way round, and that is the correction. The
   score already won was solid white and the ground still on offer was the faint band, so the
   card whose whole job is to say "there is more here" drew the part somebody already has
   loudest. Stages one and two are done: they sit back. The band this button would win is the
   bright one, and it breathes, so what the press is for is something the eye sees before
   anybody reads a word of it. */
.route-carry .sd-w-1,
.route-carry .sd-w-2,
.route-carry .sd-w-3{fill:var(--stage-three-on);fill-opacity:.34}
.route-carry .sd-w-could{fill:var(--stage-three-on);fill-opacity:1}
/* The same white as the bright band, beside the number it is the number of, so the ring and the
   line under it are visibly one fact rather than two. */
/* The swatch that says which part of the ring the points are. The same colour as the ring's
   own spare marks, which went near-black with the card, so the key and the thing it is a key to
   are one colour rather than two. */
.route-key{display:inline-block;width:10px;height:10px;border-radius:2px;background:var(--stage-three-on);
  margin-right:var(--sp-2);vertical-align:baseline}

/* The end of it, and it has to look like the end of it.
   It was a white card under a green one, which made the thing somebody had finished and come
   for the quieter of the two. It is the loudest thing on the screen now: the product's own
   green edge down the side, a heavier heading, and the two ways of taking something away under
   it. The way back is below it, where a step already taken belongs. */
.route-finish{flex-direction:column;gap:var(--sp-2);border-left:4px solid var(--prod);
  box-shadow:var(--lift-f)}
.route-finish .route-k{color:var(--prod-d)}
.route-finish>.route-h{font-size:var(--t-l);margin:0 0 2px}
.route-finish .result-acts{margin-top:var(--sp-1)}

/* Everything the check found, one press away.
   It was a bold line with small print under it, which is a heading, and nobody presses a
   heading: the one control that opens the whole result read as a label. It is drawn as a
   control now. A filled bar with a border, the word in the accent, and a chevron that turns
   when it opens, which is the part a person actually reads as "this opens". Still quiet, because
   it is the third thing on the screen and not a third route, but unmistakably a thing you press. */
.fold-detail{margin:0 0 var(--sp-3);border-color:var(--pl-go-e)}
.fold-detail>summary{
  flex-direction:row;align-items:center;gap:var(--sp-3);
  background:var(--pl-go);color:var(--pl-go-t);border-radius:var(--r-s);font-weight:700;
  transition:background var(--m-state)
}
.fold-detail>summary:hover{background:var(--pl-go-h)}
.fold-detail[open]>summary{border-radius:var(--r-s) var(--r-s) 0 0;border-bottom:1px solid var(--pl-go-e)}
.fold-detail-t{display:grid;gap:2px;min-width:0}
.fold-detail .fold-n{font-weight:400;color:var(--pl-go-t)}
/* Drawn from two borders rather than a glyph, so it lands the same whatever font is in use and
   whatever the person has done to their text size. */
.fold-detail>summary::after{
  content:'';flex:none;width:9px;height:9px;margin-left:auto;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--m-state)
}
.fold-detail[open]>summary::after{transform:rotate(-135deg) translateY(-2px)}

@keyframes route-land{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* A slow breath on the one route that carries the journey on, so it is the thing the eye lands
   on. It stops on its own where the page is set to be still: :root[data-motion="off"] above
   kills every animation outright, and so does the reduced-motion query, so the Motion switch in
   the bar is the pause control WCAG 2.2.2 asks for and no second one is added here. */
@keyframes route-breathe{
  0%,100%{box-shadow:var(--lift-f)}
  50%{box-shadow:var(--lift-f), 0 0 0 6px rgba(14,122,71,.16)}
}
:root[data-motion="on"] .route-carry{
  animation:route-land var(--m-panel) var(--ease-panel) both,
            route-breathe 3.2s ease-in-out .5s infinite;
}
/* And the band itself, on the same 3.2s as the card, so the card and the ring breathe together
   rather than beating against each other. It sweeps out once on arrival, in ceilingDial, and
   this is what keeps it the thing the eye returns to. Both stop where the page is set to be
   still: the Motion switch in the bar kills every animation, and so does reduced-motion. */
@keyframes could-breathe{0%,100%{opacity:.7}50%{opacity:1}}
:root[data-motion="on"] .route-carry .sd-spare{
  animation:could-breathe 3.2s ease-in-out .5s infinite;
}
/* The same control once everything has been read: still the way back, no longer the thing the
   eye should land on. It keeps its place and its colour so it is recognisably where the journey
   was, and it stops breathing and sits back, because pressing it is now optional. */
/* Starting again, under the take-away actions and quieter than them, because it is the one
   control here that throws this screen away. */
.route-again-wrap{display:flex;gap:var(--sp-3);align-items:center;flex-wrap:wrap;
  margin:var(--sp-2) 0 0;padding:var(--sp-2) 0 0;border-top:1px solid var(--line)}
/* The same unavailable look as [aria-disabled], written out because this one is not
   unavailable: it is a live button that refuses and says why. --mid, not --soft, for the
   reason the shared rule gives: --soft on this plate is 2.79:1 and the label has to be
   readable on a control somebody is expected to press and be answered by. */
.route-another-off{border-style:dashed;color:var(--mid);background:var(--gry-t);box-shadow:none}
.route-again-wrap>.hint{margin:0}

/* The same card once everything has been gone through: still the way back, no longer the thing
   the eye should land on.

   It was the brand's dark green, which made the one card that changes colour on this screen
   change to a colour that means nothing. Reported twice. It is the same stage three as before
   and always, and what says "you have already been through this" is the weight rather than the
   hue: the fill comes off, the outline stays, the shadow flattens, and the words and the icon
   change with it. One colour per stage, and a second state of a control is not a second stage.
   The ink is the darker step of the same green, because the green itself on white is 3.22:1 and
   this is text: --stage-three-e measures 4.56:1. */
.route-again{background:var(--surf);color:var(--stage-three-e);
  border-color:var(--stage-three);box-shadow:var(--lift-p)}
.route-again:hover{background:var(--stage-three-paper);box-shadow:var(--lift-p-h)}
.route-again .route-k{color:var(--stage-three-e)}
.route-again .sd-num{fill:var(--stage-three-e)}
.route-again .sd-w-1,
.route-again .sd-w-2,
.route-again .sd-w-3{fill:var(--gry);fill-opacity:.55}
.route-again .sd-w-could{fill:var(--stage-three-e);fill-opacity:1}
.route-again .route-key{background:var(--stage-three-e)}
:root[data-motion="on"] .route-again{
  animation:route-land var(--m-panel) var(--ease-panel) both;
}

@media (max-width:480px){
  .route{padding:var(--sp-3)}
  .route-carry .dial{width:84px;max-width:84px}
}

.depth-do { display: inline-flex; gap: var(--sp-2); flex-wrap: wrap; }

/* How much of the result is showing.
 *
 * One control rather than two buttons, because these are three views of one result and only
 * one can be true at a time. Grey throughout and on purpose: nothing here runs, spends or
 * changes anything, and a colour would say otherwise. The selected view is marked by fill,
 * weight and aria-checked together, never by colour alone. */
.viewpick { display: inline-flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); flex-wrap: wrap; }
.viewpick-l { font: 600 var(--t-xs) var(--ui); color: var(--mid); text-transform: uppercase; letter-spacing: .06em; }
.viewseg {
  font: 600 var(--t-s) var(--ui); padding: 6px var(--sp-3); min-height: 32px; cursor: pointer;
  background: var(--pl-back); color: var(--pl-back-t);
  border: 1px solid var(--pl-back-e); border-radius: var(--r-s);
  transition: background var(--m-state), box-shadow var(--m-lift);
}
.viewseg:hover { background: var(--pl-back-h); border-color: var(--pl-back-eh); }
/* The chosen one is filled and bordered dark. Contrast against its own text is what 1.4.11
   asks for, and the fill is what carries it rather than a tint. */
.viewseg.on {
  background: var(--ink); color: #fff; border-color: var(--ink); box-shadow: var(--lift-p);
}
.viewseg.on:hover { background: var(--ink); }
/* Locked by the engine's floor, not by choice. Still focusable and still announced, because it
   has something to say: pressing it explains why the whole record is always shown. */
/* No opacity here either, and for the same reason: it is still focusable and it still has
   something to say when pressed. */
.viewseg[aria-disabled='true'] { cursor: not-allowed; }
.viewseg[aria-disabled='true']:hover { background: var(--gry-t); border-color: var(--pl-back-e); }

/* One proposed change: what is there now, and what it would become. */
.diffs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.diff {
  background: var(--rail); border: 1px solid var(--line2); border-left: 3px solid var(--soft);
  border-radius: 0 var(--r-s) var(--r-s) 0; padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.diff-must_fix { border-left-color: var(--red); }
.diff-should_fix { border-left-color: var(--amb); }
.diff-have_a_look { border-left-color: var(--gry); }
.diff-head { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.diff-head strong { font-size: var(--t-m); }
.diff-say { color: var(--mid); font-size: var(--t-s); max-width: 72ch; }
.diff-row { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); gap: var(--sp-3); align-items: baseline; }
.diff-k { font: 700 var(--t-xs) var(--ui); letter-spacing: .05em; text-transform: uppercase; color: var(--mid); }
.diff-was { color: var(--mid); text-decoration: line-through; text-decoration-thickness: 1px; }
.diff-new { color: var(--ink); font-weight: 600; background: var(--grn-t); border-radius: var(--r-s); padding: 1px 6px; }
.diff-do { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-1); }

/* The three questions. A statement, the answers as one segmented control each, and what the
   answer amounts to said underneath in words rather than by the control changing colour. */
.fold-ask > summary { font-weight: 700; }
.asks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-5); }
.ask {
  background: var(--surf); border: 1px solid var(--line); border-left: 3px solid var(--act);
  border-radius: 0 var(--r-s) var(--r-s) 0; padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
/* These three run the width of the card rather than stopping at a measure.
   68ch and 72ch are the readable line length, and on the referral card they were read as a
   fault instead: a question that wrapped after two thirds of the width, under a heading that
   ran the whole way, over a segmented control that ran the whole way. Asked for, in those
   words: it needs to read across the window. The measure is kept where it is doing its job,
   on the prose of the result, and dropped here, on three short statements inside a card
   somebody is answering rather than reading. */
.ask-lead { font-size: var(--t-m); font-weight: 600; }
.ask-qs { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-1); }
.ask-ask { font-size: var(--t-b); margin-bottom: var(--sp-1); }
/* An answer the engine filled in from the advert, said where the answer is. It is a claim about
   where a fact came from, so it is marked rather than left to look like something they pressed. */
.ask-read {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  font-size: var(--t-s); color: var(--act-h); margin-top: var(--sp-1);
}
.ask-read .i { flex: none; margin-top: 1px; }

.ask-out { font-size: var(--t-s); margin-top: var(--sp-2); }
/* One line per rule the referral settled. Regulation 27(2) settles two. */
.ask-outs { display: flex; flex-direction: column; }
.ask-out-out { color: var(--mid); }
.ask-out-in { color: var(--ink); background: var(--rail); border-left: 3px solid var(--line); border-radius: 0 var(--r-s) var(--r-s) 0; padding: var(--sp-2) var(--sp-3); }

/* The ten areas, open or closed on this advert. */
.lenses { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.lenstile { background: var(--rail); border-left: 3px solid var(--prod); border-radius: var(--r-s); padding: var(--sp-3); display: flex; flex-direction: column; gap: 2px; }
.lenstile-closed { border-left-color: var(--gry); }
.lenstile-n { font-weight: 600; }
.lenstile-s { font-size: var(--t-s); color: var(--mid); }

/* Every rule that ran. The one place in the product that prints a statute, a tier letter or
   a confidence number, which is why the vocabulary lint reads depth 1 and depth 2 and stops. */
.rules-ran { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.ruleran { background: var(--rail); border-left: 3px solid var(--line); border-radius: 0 var(--r-s) var(--r-s) 0; padding: var(--sp-3); display: flex; flex-direction: column; gap: 3px; }
.ruleran-head { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.ruleran-cite { font-size: var(--t-xs); color: var(--mid); }
.ruleran-quote { font-size: var(--t-s); }
.ruleran-say { font-size: var(--t-s); color: var(--mid); max-width: 76ch; }
.ruleran-conf { font-size: var(--t-xs); color: var(--mid); }
/* The two answers about the check rather than about the advert: what it knows, and that it is
   wrong. Side by side at the foot of the row, on every row, because every check and every rule
   can now be reported. */
.ruleran-do { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; margin-top: var(--sp-2); }

/* The allowance panel behind the chip in the bar. */
.allow-panel { display: flex; flex-direction: column; gap: var(--sp-3); }
.allow-say { font-size: var(--t-m); font-weight: 600; max-width: 64ch; }
.allow-key { margin-top: var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.allow-key .btn { margin-top: var(--sp-3); }
#licence-key { font-family: var(--mono); letter-spacing: .04em; }
/* Four states, and the word beside the number carries every one of them. The colour is the
   second carrier and never the only one. */
/* How things stand is the ring and the words now; the border stays white. */

/* ------------------------------------------------------------------ the legal documents

   Long-form prose, one column, a line no wider than about 68 characters, and a contents
   list down the side on a wide screen. A simpler header than the application's, and no
   script at all: nothing on these pages needs one. */

.legal-bar { background: var(--nav); padding: var(--sp-3) var(--gutter); }
.legal-bar .bar-brand { display: inline-flex; align-items: center; gap: var(--sp-3); text-decoration: none; }
.legal-wrap { padding-block: var(--sp-6) var(--sp-7); }
.legal-when { color: var(--mid); font-size: var(--t-s); margin-bottom: var(--sp-5); }

.legal-body { max-width: 68ch; }
.legal-body h2 { font-size: var(--t-l); margin: var(--sp-6) 0 var(--sp-3); scroll-margin-top: var(--sp-6); }
.legal-body h3 { font-size: var(--t-m); margin: var(--sp-5) 0 var(--sp-2); scroll-margin-top: var(--sp-6); }
.legal-body p { margin-bottom: var(--sp-4); }
.legal-body ul, .legal-body ol { margin: 0 0 var(--sp-4) var(--sp-5); }
.legal-body li { margin-bottom: var(--sp-2); }
.legal-body a { color: var(--act); text-decoration: underline; text-underline-offset: 2px; }
.legal-body code { font-family: var(--mono); font-size: var(--t-s); background: var(--gry-t); padding: 1px 5px; border-radius: 4px; }
.legal-body hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0; }
/* Something quoted back at the reader, in the flat treatment this product uses for
   anything it wants read rather than pressed. */
.legal-body blockquote {
  margin: 0 0 var(--sp-4); padding: var(--sp-3) var(--sp-4);
  background: var(--rail); border-left: 3px solid var(--act); border-radius: 0 var(--r-s) var(--r-s) 0;
}
.legal-body blockquote p { margin: 0; font-weight: 600; }

/* A table is the one thing on these pages allowed to be wider than the column, and it
   scrolls inside itself rather than making the page scroll sideways. */
.tablewrap { overflow-x: auto; margin-bottom: var(--sp-5); }
.legal-body table { border-collapse: collapse; width: 100%; font-size: var(--t-s); }
.legal-body th, .legal-body td { text-align: left; padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--line); vertical-align: top; }
.legal-body th { font-weight: 700; color: var(--mid); border-bottom-color: var(--line2); }

.legal-toc {
  background: var(--rail); border-left: 3px solid var(--line); border-radius: 0 var(--r-s) var(--r-s) 0;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-5); max-width: 68ch;
}
.legal-toc-h { font: 700 var(--t-xs) var(--ui); letter-spacing: .05em; text-transform: uppercase; color: var(--mid); margin-bottom: var(--sp-2); }
.legal-toc ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.legal-toc a { color: var(--act); text-decoration: none; display: inline-block; min-height: 24px; padding: 2px 0; }
.legal-toc a:hover { text-decoration: underline; }

.legal-cross { margin-top: var(--sp-7); padding-top: var(--sp-5); border-top: 1px solid var(--line); display: flex; gap: var(--sp-4); flex-wrap: wrap; align-items: baseline; }
.legal-cross-h { font: 700 var(--t-xs) var(--ui); letter-spacing: .05em; text-transform: uppercase; color: var(--mid); flex-basis: 100%; }
.legal-cross a { color: var(--act); text-decoration: underline; text-underline-offset: 2px; min-height: 24px; display: inline-flex; align-items: center; }
/* The page for an address that does not exist, drawn like the front page's opening: a small
   green line, one large sentence, one short one, and the way back. */
.nf-main { max-width: 1100px; margin: 0 auto; padding: 96px 28px 72px; }
.nf-eb { color: #0E7A47; font: 600 14px var(--ui); letter-spacing: .02em; margin: 0 0 8px; }
.nf-h1 { font-family: var(--disp); font-weight: 600; letter-spacing: -.015em; font-size: clamp(38px, 5.4vw, 62px); line-height: 1.08; max-width: 17ch; margin: 0; }
.nf-h1 em { font-style: normal; color: #0E7A47; }
.nf-lede { font-size: 20px; color: #3F4756; max-width: 60ch; margin: 22px 0 0; }
.nf-ctas { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 28px; }
.nf-ctas a { text-decoration: none; }
.nf-micro { font-size: 13px; color: #5C6472; margin: 14px 0 0; }
.nf-micro a { color: var(--act); }
@media (max-width: 720px) {
  .nf-main { padding: 56px 16px 48px; }
  .nf-lede { font-size: 18px; }
  .nf-ctas a { flex: 1 1 100%; justify-content: center; }
}

@media (min-width: 1000px) {
  /* The contents beside the prose rather than above it, once there is room for both. */
  .legal-wrap { display: grid; grid-template-columns: minmax(0, 68ch) 16rem; gap: var(--sp-6) var(--sp-7); align-items: start; }
  .legal-wrap > .page-h, .legal-wrap > .legal-when, .legal-wrap > .legal-cross { grid-column: 1; }
  .legal-toc { grid-column: 2; grid-row: 3 / span 2; position: sticky; top: var(--sp-4); margin-bottom: 0; }
  .legal-body { grid-column: 1; }
}

/* ------------------------------------------------------- the prices

   The front page has its own block at the end of this file. Prices introduces no treatment
   of its own. A card is flat on the rail with a
   rule down its left edge, because it is something the application is telling you rather
   than something you press, and every press on both screens is already dressed by the
   button rules above. */

.door-do { display: flex; gap: var(--sp-3); flex-wrap: wrap; }

.worth-h { font-size: var(--t-l); margin: var(--sp-7) 0 var(--sp-3); }
/* Wide enough for the three plans side by side. At the reading width two fitted and the third
   sat alone underneath, which is the one arrangement of three cards that is never even. */
#view-worth { --col: 64rem; }
/* One rhythm down the page: the same space above every block, and every pair in two equal
   columns that line up with the plans above them. */
#view-worth .whofor { max-width: none; }
.worth-pair {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4);
  margin-top: var(--sp-7); align-items: stretch;
}
@media (max-width: 860px) { .worth-pair { grid-template-columns: 1fr; gap: var(--sp-7); } }
.worth-pair .worth-h { margin: 0; }
/* The two lists share the pair's rows, so the first line of each sits level, then the second,
   and so on, whatever each says; the headings share a row too. */
.worth-block { display: grid; grid-row: span 6; grid-template-rows: subgrid; row-gap: var(--sp-2); }
.worth-block .whofor { display: grid; grid-row: span 5; grid-template-rows: subgrid; row-gap: var(--sp-2); margin: var(--sp-1) 0 0; padding: 0; }
.worth-card {
  background: var(--surf); border: 1px solid var(--line); border-left: 3px solid var(--act);
  border-radius: 0 var(--r-m) var(--r-m) 0; padding: var(--sp-4);
  /* Heading, words and button on the same three rows in both cards, so the buttons sit level. */
  display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: var(--sp-3);
}
.worth-card p { margin: 0; }
.worth-card .door-do { align-self: end; padding-top: var(--sp-2); }
.worth-card a.btn, .worth-card a.ghost { text-decoration: none; }
.worth-share { margin-top: var(--sp-7); }
.plans {
  list-style: none; margin: var(--sp-5) 0 var(--sp-3); padding: 0; display: grid; gap: var(--sp-4);
  grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch;
}
@media (max-width: 860px) { .plans { grid-template-columns: 1fr; } }
.plan {
  background: var(--surf); border: 1px solid var(--line); border-left: 3px solid var(--act);
  border-radius: 0 var(--r-m) var(--r-m) 0; padding: var(--sp-4);
  /* Each card borrows the list's rows, so the name, the price, the checks, the list and the line
     saying who it is for sit on the same level on all three cards, whatever each one says. */
  display: grid; grid-row: span 5; grid-template-rows: subgrid; row-gap: var(--sp-2);
  align-content: start;
}
.plan > * { margin: 0; }
.plan-free { border-left-color: var(--prod); }
.plan-n { font-family: var(--disp); font-size: var(--t-l); font-weight: 600; }
.plan-p { font-size: var(--t-m); font-weight: 600; color: var(--act); }
.plan-free .plan-p { color: var(--prod); }
.plan-c { font-size: var(--t-s); color: var(--mid); }
.plan-has { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: var(--t-s); }
.plan-has li::before { content: '\2713\00a0'; color: var(--prod); font-weight: 700; }
.plan > .plan-for { font-size: var(--t-s); color: var(--mid); margin-top: var(--sp-2); padding-top: var(--sp-3); border-top: 1px solid var(--line); }


.whofor { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); max-width: 74ch; }
.whofor-row { background: var(--rail); border-left: 3px solid var(--line); border-radius: 0 var(--r-s) var(--r-s) 0; padding: var(--sp-3); }

/* ------------------------------------------------------------------------ the questions

   Four questions, a box and a name. The number and the rule are on the question itself,
   because a marker shape on its own is a convention somebody has to already know. */

.qform { display: flex; flex-direction: column; gap: var(--sp-6); margin-top: var(--sp-5); max-width: 74ch; }
.qblock { display: flex; flex-direction: column; gap: var(--sp-2); }
.q-label { font-size: var(--t-m); font-weight: 600; }
.q-n { color: var(--act); font-weight: 700; margin-right: 4px; }
.q-how {
  display: inline-block; margin-left: var(--sp-2); font: 600 var(--t-xs) var(--ui);
  color: var(--mid); background: var(--gry-t); border-radius: var(--r-s); padding: 1px 8px;
  text-transform: none; letter-spacing: normal; vertical-align: 1px;
}
.qform .seg { flex-wrap: wrap; }
.qwho { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: var(--sp-4); }
/* Where somebody is in the four steps: said in words, and drawn as four marks that fill. The
   marks are aria-hidden, because the line above them says the same thing. */
.q-steps { display: flex; flex-direction: column; gap: var(--sp-2); }
.q-step-h { margin: 0; font: 600 var(--t-s) var(--ui); color: var(--mid); }
.q-pips { display: flex; gap: 3px; max-width: 16rem; }
.q-pip { flex: 1 1 0; height: 6px; border-radius: var(--r-full); background: #fff; border: 1px solid var(--act); opacity: .4; }
.q-pip-done { background: var(--act); opacity: .7; }
.q-pip-here { background: var(--act); opacity: 1; }
.q-nav { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: center; }

/* ------------------------------------------------------------------ the development toolbar

   Everything belonging to the development site in this product is red: the bar across the
   top, this, and the block under the note box. It sits bottom right, where the console menu
   deliberately is not, because two floating controls in one corner is one of them
   unreachable. */

.devtools { position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 47; display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }
.devtools-fab { border-radius: var(--r-full); min-height: 44px; padding: 0 var(--sp-4); box-shadow: var(--lift-f-h); }
.devtools-panel {
  display: flex; flex-direction: column; gap: 2px; width: min(320px, calc(100vw - 32px));
  background: var(--surf); border: 1px solid var(--red); border-radius: var(--r-m);
  box-shadow: var(--sh3); padding: var(--sp-3);
}
.devtools-h { font: 700 var(--t-xs) var(--ui); letter-spacing: .06em; text-transform: uppercase; color: var(--red); margin-bottom: var(--sp-2); }
.devtools-row {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%; text-align: left;
  min-height: 44px; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-s);
  background: var(--pl-back); border: 1px solid var(--pl-back-e); color: var(--ink);
  font: 600 var(--t-b) var(--ui); cursor: pointer; text-decoration: none; box-shadow: var(--lift-p);
}
.devtools-row:hover { background: var(--pl-back-h); border-color: var(--pl-back-eh); box-shadow: var(--lift-p-h); }
.devtools-row .i { color: var(--mid); flex: none; }
/* The one that cannot be taken back, in the one colour this product reserves for that. */
.devtools-row-out { background: var(--pl-del); color: var(--pl-del-t); border-color: var(--pl-del-e); margin-top: var(--sp-2); }
.devtools-row-out:hover { background: var(--pl-del-h); border-color: var(--pl-del-eh); }
.devtools-row-out .i { color: var(--pl-del-t); }

@media (max-width: 900px) {
  /* Above the console menu's own corner, and clear of a phone's home bar. */
  .devtools { right: var(--sp-3); bottom: calc(env(safe-area-inset-bottom, 0px) + var(--sp-3)); }
}

/* ------------------------------------------------------------------- closed on a handheld

   One screen and nothing else. The application is taken off the page rather than hidden
   behind this, because half a product reachable by scrolling is not an honest closed door.
   It says where the product does work and what to do about it, and it never apologises and
   never leaves a dead end: the person reading it has done nothing wrong. */

.stop {
  min-height: 100svh; display: flex; flex-direction: column; justify-content: center;
  align-items: flex-start; gap: var(--sp-4); padding: var(--sp-6) var(--gutter);
  background: var(--surf);
}
.stop-h { font-family: var(--disp); font-size: var(--t-xl); font-weight: 600; line-height: 1.2; max-width: 22ch; }
.stop-s { font-size: var(--t-m); max-width: 40ch; }
.stop-todo {
  font-size: var(--t-m); font-weight: 600; max-width: 40ch;
  background: var(--rail); border-left: 3px solid var(--prod); border-radius: 0 var(--r-s) var(--r-s) 0;
  padding: var(--sp-3) var(--sp-4);
}
.stop-foot { margin-top: auto; padding-top: var(--sp-6); font-size: var(--t-s); color: var(--mid); }
.stop-foot a { color: var(--act); text-decoration: underline; text-underline-offset: 2px; display: inline-block; min-height: 24px; }

/* ---------------------------------------------------------------- the engine window
   Development only: nothing mounts it on a production deployment and the server sends it
   nothing to show. Red throughout, because everything belonging to the development site in this
   product is red, so it can never be mistaken for part of the product.
   Moved by assigning left and top through the CSSOM, which the Content Security Policy permits
   where a style attribute is refused outright. Resizing is this one line and no JavaScript. */
.englog{
  /* Clear of the header rather than 64 pixels down, which put the folded bar inside it: a
     development site's header is 94 pixels tall and this window exists nowhere else. */
  position:fixed;top:calc(var(--bar-h) + var(--sp-2));right:12px;z-index:60;
  width:min(560px,46vw);height:min(70vh,640px);
  display:flex;flex-direction:column;resize:both;overflow:hidden;
  background:#fff;border:2px solid var(--red);border-radius:var(--r-s);box-shadow:var(--sh2);
  font:12px/1.45 var(--mono);
}
.englog-min{height:auto;resize:none}
.englog-min .englog-body{display:none}
.englog-bar{
  display:flex;align-items:center;gap:8px;flex:none;cursor:move;touch-action:none;
  background:var(--red);color:#fff;padding:4px 8px;font-size:11px;
}
.englog-bar strong{font:700 11px/1 var(--ui);letter-spacing:.06em}
.englog-ver{opacity:.85}
.englog-sp{margin-left:auto}
.englog-tog{display:flex;align-items:center;gap:3px;cursor:pointer;font-size:10px}
.englog-btn{
  background:#fff;color:var(--red);border:0;border-radius:3px;padding:1px 6px;
  font:700 10px/1.6 var(--ui);cursor:pointer;
}
.englog-body{flex:1;overflow:auto;padding:4px 6px}
.englog-none{color:var(--mid);padding:var(--sp-3);font-size:11px}
.englog-job{
  display:flex;gap:8px;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:3px 4px;font:inherit;border-bottom:1px solid var(--line);
}
.englog-jobwrap{margin-bottom:6px}
.englog-when{color:var(--mid)}
.englog-dim{color:var(--mid)}
.englog-head{
  margin:4px 0;padding:6px;background:var(--paper);border-radius:3px;
  font:11px/1.5 var(--mono);white-space:pre-wrap;overflow-x:auto;
}
.englog-lens{margin:4px 0}
.englog-lensname{
  display:block;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:2px 4px;font:700 11px/1.6 var(--mono);color:var(--navy);border-bottom:1px solid var(--line);
}
.englog-shut .englog-row{display:none}
/* The level is a word as well as a colour. A trace lands in a screenshot with no legend, and a
   reader who cannot tell red from amber still has to be able to sort one from the other. */
.englog-row{display:block;padding:0}
.englog-open{
  display:flex;gap:6px;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:1px 4px;font:inherit;
}
.englog-open:hover{background:var(--paper)}
.englog-lvl{flex:none;font-weight:700;white-space:pre}
.englog-error>.englog-open .englog-lvl,.englog-error>.englog-lvl{color:var(--red)}
.englog-warn>.englog-open .englog-lvl,.englog-warn>.englog-lvl{color:var(--amb)}
.englog-info>.englog-open .englog-lvl,.englog-info>.englog-lvl{color:var(--mid)}
.englog-ref{flex:none;width:6em;color:var(--navy)}
.englog-plain{flex:none;width:16em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.englog-stage{flex:none;width:9em;color:var(--mid)}
/* The wording the rule matched, on the shut row. It takes what space is left and gives it back
   first, because the verdict beside it must not be pushed off the end by a long quote. */
.englog-quote{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--navy)}
.englog-ms{margin-left:auto;flex:none;color:var(--mid)}
.englog-detail{
  margin:2px 0 6px 2em;padding:6px;background:var(--paper);border-left:2px solid var(--red);
  font:11px/1.5 var(--mono);white-space:pre-wrap;overflow-x:auto;
}
.englog-fallback{width:100%;height:8em;font:11px/1.4 var(--mono)}

/* Category B: a question about the job, and the sentence it writes.
   The pack calls it a gap prompt. Five rules carry it and none was implemented, so they came
   back as bare failures with nothing offered. */
.gap{margin:var(--sp-2) 0 0}
.gap .ask-ask{margin:0 0 var(--sp-1);font-weight:600}
.gap .hint{margin:0 0 var(--sp-2)}
.gap .cap-fs{display:grid;gap:var(--sp-2);margin:0 0 var(--sp-2)}
.gap-row{padding:var(--sp-3) 0;border-top:1px solid var(--line2)}
.gap-do,.ask-do{margin-top:var(--sp-3)}
.gap-row:first-of-type{border-top:0}
.gap-rule{display:block;font-size:var(--t-b)}
.gap-row .mark{margin-top:2px}
/* Where a detail came from, where it did not come from the account. The pack allows taking a
   contact out of the advert because it is marked and undoable, so the mark carries the
   permission and is not decoration. */
.did-from{display:block;color:var(--mid);font-size:var(--t-xs);margin-top:2px}

/* Two adverts in one box, said under the box before a check is spent and again on the result.
   It is a notice rather than a refusal: the detector catches a little over half of double
   pastes, so it says what it noticed and leaves the decision where it belongs. */
.two-vacancies strong { display: block; margin-bottom: var(--sp-1); }
.two-vacancies p { margin: 0; }
.two-vacancies p + p { margin-top: var(--sp-2); }
.result-two { margin: 0; }

/* A greyscale pass for looking at a screen the way somebody who cannot separate two hues
   sees it. Added by a class from the console, never shipped on any screen: no markup carries
   it. It is here because the policy refuses an injected stylesheet, which is the policy
   working. */
.sweep-grey{filter:grayscale(1)}

/* The panel saying the advert did not reach the screen. Development only, and hidden on every
   ordinary draw: it exists so a fault nobody has reproduced can be read off a screenshot. */
.al-check{margin:0;padding:var(--sp-2) var(--sp-4);background:var(--red-t);color:var(--red-h);
  font:600 var(--t-xs) var(--mono);border-top:1px solid var(--red)}

/* ------------------------------------------------------------------------------- the guide
 *
 * A ring over the control to use next, and a panel beside it saying what pressing it will do.
 *
 * The ring is a separate element sitting over the control rather than a class on the control,
 * for three reasons and all three are load-bearing. It never fights the control's own blue
 * focus ring, which is a different thing saying a different thing. It needs no JavaScript to
 * touch a colour, which the stylesheet is the only place allowed to set. And it can ring a
 * control inside the guided pass's window, which is on the body rather than in the page.
 *
 * pointer-events:none on the ring is not a nicety. The whole point is that somebody presses the
 * real button underneath it, and a ring that swallowed the click would be a guide that stopped
 * you doing the thing it was telling you to do.
 *
 * z-index 51 puts it over the guided pass's window at 49, so a question's own buttons can be
 * ringed. That also puts it over the modal at 50, which is why guide.mjs hides the whole thing
 * while one is open rather than trying to paint under it. Toasts stay above at 55.
 *
 * Both rings are rings: `0 0 0 Npx`, no offset and no blur. The one-light rule above covers
 * shadows, and an outline is not one. */
#guide{position:fixed;inset:0;z-index:51;pointer-events:none}
#guide[hidden]{display:none}
.guide-ring{position:fixed;pointer-events:none;
  left:var(--gx, 0px);top:var(--gy, 0px);width:var(--gw, 0px);height:var(--gh, 0px);
  border-radius:var(--r-m);
  box-shadow:0 0 0 5px var(--train), 0 0 0 11px var(--train-halo), 0 0 20px rgba(162, 28, 104, .45)}
.guide-ring[hidden]{display:none}

/* The ring breathes, and it keeps breathing.
 *
 * Asked for: make the border larger, make it glow and make it pulse. The first draft spent the
 * motion once on arrival and then held still, on the argument this product makes about the card
 * somebody is working in: a thing that moves for ever is a thing the eye keeps returning to
 * while they are reading the sentence inside it.
 *
 * That argument is about the thing being read. This is not that. It is the thing that says where
 * to look next, which is the same job the route card does, and the route card breathes for
 * exactly this reason. What is being read here is the panel, and the panel does not move.
 *
 * WCAG 2.2.2 wants a way to stop anything moving for more than five seconds, and this product
 * has one: the Motion switch in the bar. Everything here is written as an opt-in under
 * data-motion, so that switch stops it, and the reduced-motion query stops it as well. No second
 * control is added, which is the decision app.css already records for the route card.
 *
 * One beat is bigger than the rest: the arrival, so that moving to a new step reads as an
 * arrival rather than as the same ring in a new place. It runs once and then the breath takes
 * over, which is what the delay on the second animation is for. */
@keyframes guide-arrive{
  0%{box-shadow:0 0 0 5px var(--train), 0 0 0 4px var(--train-halo), 0 0 20px rgba(162, 28, 104, .45)}
  55%{box-shadow:0 0 0 5px var(--train), 0 0 0 26px rgba(162, 28, 104, 0), 0 0 44px rgba(162, 28, 104, .7)}
  100%{box-shadow:0 0 0 5px var(--train), 0 0 0 11px var(--train-halo), 0 0 20px rgba(162, 28, 104, .45)}
}
@keyframes guide-pulse{
  0%,100%{box-shadow:0 0 0 5px var(--train), 0 0 0 11px var(--train-halo), 0 0 20px rgba(162, 28, 104, .45)}
  50%{box-shadow:0 0 0 5px var(--train), 0 0 0 19px var(--train-halo-2), 0 0 36px rgba(162, 28, 104, .72)}
}
:root[data-motion="on"] .guide-ring{animation:guide-pulse 2.6s ease-in-out infinite}
:root[data-motion="on"] .guide-ring.guide-arrived{
  animation:guide-arrive 700ms var(--ease-panel) 1, guide-pulse 2.6s ease-in-out .7s infinite}

/* Its own colour throughout, because a white panel with a coloured edge reads as one more card
   on a page made of cards. The body is the training tint and the head is the training colour
   itself, so the guide is plainly something speaking over the product rather than part of it.
   Measured: the ink reads 14.22:1 on the tint, the quieter line 4.88:1, and white 7.24:1 on the
   head. */
/* Lifted off the page rather than laid on it. Asked for: it should look 3D and floating. An
   inset highlight along the lit edge and the deepest cast shadow in the sheet, both offset
   (-n, +n) like everything else here, so the one light is still one light. */
.guide-panel{position:fixed;pointer-events:auto;overflow:hidden;
  left:var(--px, 16px);top:var(--py, 80px);width:min(23rem, calc(100vw - 32px));
  padding:0 var(--sp-4) var(--sp-3);border-radius:var(--r-m);
  background:var(--train-t);border:2px solid var(--train);
  box-shadow:inset -1px 1px 0 rgba(255, 255, 255, .55), var(--sh3)}
/* No room to float beside anything, so it goes across the foot of the window. The words are the
   same; only where they sit changes. */
.guide-panel.guide-docked{left:0;right:0;bottom:0;top:auto;width:auto;max-width:none;
  border-radius:var(--r-m) var(--r-m) 0 0;border-width:2px 0 0 0}
/* And the head is what you pick it up by. touch-action:none so a drag on a touchscreen moves the
   panel instead of scrolling the page underneath it, and cursor:move so a mouse says so before
   it is tried. The buttons on it keep their own cursor, because they are pressed rather than
   dragged. */
.guide-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:nowrap;
  margin:0 calc(var(--sp-4) * -1) var(--sp-2);padding:var(--sp-2) var(--sp-4);
  background:var(--train);color:#fff;cursor:move;touch-action:none;user-select:none}
.guide-head.guide-held{cursor:grabbing}
.guide-head button{cursor:pointer;flex:none}
/* Nothing to drag to on a phone, where it is already across the foot of the window. */
.guide-docked .guide-head{cursor:default;touch-action:auto}
.guide-k{display:inline-flex;align-items:center;gap:var(--sp-1);
  color:#fff;font:800 var(--t-xs)/1 var(--ui);text-transform:uppercase;letter-spacing:.04em}
.guide-k .i{color:#fff}
.guide-where{margin:0;flex:1 1 auto;min-width:0;color:#fff;font-size:var(--t-xs);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* One pip per chapter, which is the "2 of 6" above again as a shape. Six on every advert,
   because a chapter nobody's advert needs is walked through rather than deleted, so it is
   behind you in the ordinary way and its pip fills like any other.
   Aria-hidden: the line above says the same thing in words, so nothing here is carried by
   colour alone (1.4.1) and this is a decoration rather than a control that has to be told
   apart from its background (1.4.11). The geometry is the guided pass's own pip bar; the
   colours are the guide's, because the stage green there means a stage and this is not one. */
.guide-bar{display:flex;gap:3px;align-items:center;margin:0 0 var(--sp-3)}
.guide-pip{flex:1 1 0;height:6px;border-radius:var(--r-full);background:#fff;
  border:1px solid var(--train);opacity:.4}
.guide-pip-done{background:var(--train);opacity:.7}
.guide-pip-here{background:var(--train);opacity:1}
.guide-head .info{color:#fff;opacity:1}
.guide-head .info:hover{background:rgba(255, 255, 255, .18)}

/* Where the box sits, inside the information panel. The chips are the product's own pick-one
   control, so the tick and the colour on the chosen one come from chosen.test.mjs like every
   other one and nothing here paints them. */
.guide-spots{margin-top:var(--sp-4);display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center}
.guide-spots legend{width:100%}
.guide-spots .chip{display:inline-flex;width:auto}
.guide-spots .hint{flex:1 0 100%;margin:0}
.guide-head .info{margin-left:auto}
.guide-say{margin:0;color:var(--ink);font-weight:700;line-height:1.45}
.guide-next{margin:var(--sp-1) 0 0;color:var(--mid);font-size:var(--t-xs);line-height:1.5}
.guide-do{display:flex;gap:var(--sp-2);margin-top:var(--sp-3);flex-wrap:wrap}
/* Ten of the fifteen steps are finished by doing the thing rather than by saying you have, so
   there is nothing in this row on those, and an empty row that still pushes the panel out is a
   gap under the last sentence with nothing in it. */
.guide-do:empty{margin-top:0}

/* The button that starts it. Its own plate rather than a borrowed one: every other colour in
   this product already means something, and a guide wearing the action blue would be saying
   "this is the thing to press" on a screen where the thing to press is the check. */
.btn-train{background:var(--train);color:#fff;border-color:var(--train-e)}
.btn-train:hover{background:var(--train-h);border-color:var(--train-e)}
.btn-train .i{color:#fff}

/* The big button that starts it, above the box it points at first. Its own row rather than in
   the action row beside Check now: it is not one of the two things you do to an advert, it is
   the offer of somebody standing next to you while you do them.

   Bigger than an ordinary button, and asked for: the first draft was the same size as everything
   else on the row and read as one more control rather than as an offer. It is the widest thing
   above the box now, so somebody meeting the product for the first time cannot miss it, and
   somebody who does not want it still only has to read six words. */
.paster-guide{display:flex;justify-content:flex-start;margin-bottom:var(--sp-4)}
.paster-guide:empty{display:none}
.paster-guide .btn-train{width:100%;justify-content:center;gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);min-height:56px;font-size:var(--t-m);font-weight:800;
  border-radius:var(--r-m)}
.paster-guide .btn-train .i{width:22px;height:22px}

/* And it breathes, so the eye lands on it. The same shape and the same colours as the ring the
   guide draws, because the two are one thing seen at two moments: the offer, and the offer taken
   up. Two spread-only rings and a glow with no offset, which the shadow audit calls a light
   rather than a shadow and names as the one shape outside the one-light rule.

   Opt-in under the motion switch, so that switch stops it and the reduced-motion query stops it,
   and no second control is added. Infinite, like the route card and like the ring: this is the
   thing saying where to start, not the thing being read. */
@keyframes guide-me-pulse{
  0%,100%{box-shadow:0 0 0 0 var(--train-halo), 0 0 0 rgba(162, 28, 104, 0)}
  50%{box-shadow:0 0 0 10px var(--train-halo-2), 0 0 26px rgba(162, 28, 104, .55)}
}
:root[data-motion="on"] .paster-guide .btn-train{animation:guide-me-pulse 2.6s ease-in-out infinite}

/* Smaller where it sits beside a heading or inside the guide's own panel, and full size above
   the advert box where it is the offer being made. The size is a fact about the row, so it is
   set here and not assembled into the button's class, which would put it past the guard that
   reads what colour a button wears. */
.routes .btn-train,.guide-do .btn-train{padding:5px var(--sp-3);font-size:var(--t-xs);min-height:32px}
/* Full width at the head of the column, like the cards under it, so the column reads as one
   stack rather than as a button with cards below it. */
.routes .btn-train{width:100%;justify-content:center}

/* Room to scroll a control out from under a docked panel. The panel covers the foot of the
   window, and on a phone that is regularly the button the step is about: the page could be
   scrolled to its end with the control still underneath. The height is measured, because the
   panel is two lines on one step and five on another. */
body.guide-foot main{padding-bottom:calc(var(--guide-foot, 0px) + var(--sp-4))}

/* ------------------------------------------------------------- the front page
   What the Assurance Register does, why it matters, and the evidence behind it. Generated from
   the sales page and scoped to #view-door, with every class prefixed fp- so nothing here can
   reach the rest of the product. The charts are drawn by public/js/door.mjs. */
#view-door .fp-wrap{margin:0 auto;padding-left:28px;padding-right:28px}
#view-door .fp-num{font-variant-numeric:tabular-nums}
#view-door h1,#view-door h2,#view-door .fp-sv,#view-door .fp-rk,#view-door .fp-v,#view-door .fp-pcap b,#view-door .fp-ucard .fp-ix{font-family:var(--disp)}
#view-door h3,#view-door .fp-eb{font-family:var(--ui)}
#view-door textarea:focus-visible,#view-door select:focus-visible{outline:3px solid #0B5FBF;outline-offset:3px}
#view-door nav{flex:0 1 auto;min-width:0;justify-content:flex-end}
#view-door nav{display:flex;align-items:center;gap:2px;flex-wrap:nowrap}
#view-door section{padding:72px 0;border-top:1px solid #E1E4EA}
#view-door .fp-head{margin-bottom:32px}
#view-door .fp-sub{margin-top:8px}
#view-door [data-fill]{color:var(--amb-on-tint)}
#view-door .fp-eb{color:#0E7A47;font-size:14px;font-weight:600;letter-spacing:.02em;margin:0 0 8px}
#view-door h2{font-weight:400;font-size:clamp(28px,3.3vw,40px);line-height:1.15;margin:0;max-width:28ch}
#view-door .fp-head p{color:#3F4756;max-width:66ch;margin:12px 0 0}
#view-door .fp-head .fp-ctas{margin-top:20px}
#view-door .fp-head .fp-ctas a{text-decoration:none}
#view-door h3{font-size:18px;line-height:1.3;margin:0 0 8px;font-weight:650}
#view-door .fp-hero{padding:56px 0 64px;border-top:0}
#view-door .fp-heroin{display:grid;grid-template-columns:7fr 5fr;gap:48px;align-items:center}
#view-door h1{font-weight:400;font-size:clamp(34px,4.6vw,58px);line-height:1.07;letter-spacing:-0.012em;margin:0 0 26px}
#view-door h1 em{font-style:normal;color:#0E7A47}
#view-door .fp-journey{display:grid;grid-template-columns:1fr 1fr;gap:12px;max-width:560px;margin:0 0 22px}
#view-door .fp-jb{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;padding:14px 16px;border-radius:14px;border:1px solid #C9CED8;background:#FAFBFC;color:#0D1B2A;cursor:pointer;transition:border-color .2s,background .2s}
#view-door .fp-jb b{font-size:16px}
#view-door .fp-jb span{font-size:13px;color:#5C6472}
#view-door .fp-jb:hover{border-color:#0E7A47}
#view-door .fp-jb[aria-pressed="true"]{border-color:#0E7A47;background:#E6F3EC;box-shadow:inset 0 0 0 1px #0E7A47}
#view-door .fp-lede{font-size:18px;color:#3F4756;max-width:56ch;margin:0 0 24px;min-height:5.4em}
#view-door .fp-lede b{color:var(--amb-on-tint);font-weight:600}
#view-door .fp-ctas{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
#view-door .fp-micro{font-size:13px;color:#5C6472;margin:14px 0 0}
#view-door .fp-heropie{display:flex;flex-direction:column;align-items:center}
#view-door .fp-heropie canvas{width:100%;max-width:460px;height:auto;display:block}
#view-door .fp-pcap{text-align:center;color:#3F4756;font-size:15px;max-width:34ch}
#view-door .fp-pcap b{display:block;font-size:44px;font-weight:400;color:var(--amb-on-tint);line-height:1.1}
#view-door .fp-pcap small{display:block;font-size:12px;color:#5C6472;margin-top:4px}
#view-door .fp-grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
#view-door .fp-grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
#view-door .fp-ucard{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:22px;display:flex;flex-direction:column}
#view-door .fp-ucard .fp-ix{font-size:15px;color:#0E7A47;margin-bottom:10px}
#view-door .fp-ucard p{color:#3F4756;font-size:15px;margin:0 0 14px}
#view-door .fp-ucard p:last-child{margin-bottom:0}
#view-door .fp-ucard .fp-jx{margin-top:auto;padding-top:12px;border-top:1px solid #E1E4EA;font-size:14px;color:#0E7A47}
#view-door .fp-cmp{width:100%;border-collapse:separate;border-spacing:0;background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;overflow:hidden;font-size:15px}
#view-door .fp-cmp th,#view-door .fp-cmp td{padding:14px 18px;text-align:left;vertical-align:top;border-bottom:1px solid #E1E4EA}
#view-door .fp-cmp tr:last-child td{border-bottom:0}
#view-door .fp-cmp thead th{font-size:14px;color:#5C6472;font-weight:600;background:#FAFBFC}
#view-door .fp-cmp th[scope=row]{color:#0D1B2A;font-weight:600;width:18%}
#view-door .fp-cmp td{color:#3F4756;width:20.5%}
#view-door .fp-cmp .fp-us{background:#E6F3EC;color:#0D1B2A}
#view-door .fp-cmp thead .fp-us{color:#0E7A47;background:#E6F3EC}
#view-door .fp-fn{font-size:12px;color:#5C6472;margin:12px 0 0}
#view-door .fp-tl{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(6,1fr);gap:20px;position:relative}
#view-door .fp-tl::before{content:"";position:absolute;left:0;right:0;top:8px;height:2px;background:#E1E4EA}
#view-door .fp-tl::after{content:"";position:absolute;left:0;top:8px;height:2px;width:0;background:#0E7A47;transition:width 1.6s cubic-bezier(.2,.7,.2,1)}
#view-door .fp-tl.fp-on::after{width:calc(100% * 5 / 6)}
#view-door .fp-tl li{position:relative;padding-top:30px;transform:translateY(8px);transition:transform .5s}
#view-door .fp-tl.fp-on li{transform:none}
#view-door .fp-tl li::before{content:"";position:absolute;left:0;top:1px;width:14px;height:14px;border-radius:50%;background:#F3F4F7;border:2px solid #0E7A47}
#view-door .fp-tl li.fp-past::before{background:#0E7A47}
#view-door .fp-tl li.fp-next::before{border-color:var(--amb-on-tint);box-shadow:0 0 0 5px rgba(255,178,62,.18)}
#view-door .fp-tl .fp-td{display:block;font-size:13px;font-weight:600;color:#0E7A47;margin-bottom:6px}
#view-door .fp-tl li.fp-next .fp-td{color:var(--amb-on-tint)}
#view-door .fp-tl h3{font-size:16px}
#view-door .fp-tl p{margin:0;font-size:14px;color:#3F4756}
#view-door .fp-tl .fp-who{display:inline-block;margin-top:10px;font-size:11px;padding:2px 8px;border-radius:999px;background:#F0F2F5;color:#3F4756}
#view-door .fp-tl li.fp-next .fp-who{background:#FCF4E3;color:#7A5207}
@media (max-width:1020px) {
  #view-door .fp-tl{grid-template-columns:1fr 1fr 1fr}
  #view-door .fp-tl::before,#view-door .fp-tl::after{display:none}
}
@media (max-width:620px) {
  #view-door .fp-tl{grid-template-columns:1fr;gap:0;padding-left:24px}
  #view-door .fp-tl::before{display:block;left:6px;right:auto;top:0;bottom:0;width:2px;height:auto}
  #view-door .fp-tl li{padding:0 0 22px 0}
  #view-door .fp-tl li::before{left:-24px;top:2px}
}
#view-door .fp-fixgrid{display:grid;grid-template-columns:1.1fr 1fr;gap:28px;align-items:center}
#view-door .fp-fixgrid .fp-side canvas{max-width:560px;margin:0 auto}
#view-door .fp-fxfig{display:grid;grid-template-columns:1fr 1fr;gap:24px 20px}
#view-door .fp-calc{margin-top:28px;background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:24px;display:grid;grid-template-columns:1.2fr 1fr;gap:24px;align-items:center}
#view-door .fp-cin{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px;align-items:end}
#view-door .fp-cin label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#3F4756}
#view-door .fp-cin input{background:#F3F4F7;color:#0D1B2A;border:1px solid #C9CED8;border-radius:10px;min-height:46px;padding:0 12px;font:inherit;font-size:16px}
#view-door .fp-cout{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
#view-door .fp-cout div{border-top:2px solid #0D1B2A;padding-top:10px}
#view-door .fp-cout b{display:block;font-family:var(--disp);font-weight:400;font-size:32px;line-height:1.1}
#view-door .fp-cout span{font-size:13px;color:#3F4756}
#view-door .fp-faq{display:grid;gap:10px;max-width:900px}
#view-door .fp-faq details{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:12px}
#view-door .fp-faq summary{list-style:none;cursor:pointer;padding:16px 50px 16px 20px;font-weight:600;font-size:16px;position:relative}
#view-door .fp-faq summary::-webkit-details-marker{display:none}
#view-door .fp-faq summary::after{content:"+";position:absolute;right:20px;top:50%;transform:translateY(-50%);font-size:22px;color:#0E7A47;transition:transform .2s}
#view-door .fp-faq details[open] summary::after{transform:translateY(-50%) rotate(45deg)}
#view-door .fp-faq details>div{padding:0 20px 18px}
#view-door .fp-faq p{margin:0;color:#3F4756;font-size:15px}
#view-door .fp-faq summary:focus-visible{outline:3px solid #0B5FBF;outline-offset:2px;border-radius:12px}
@media (max-width:1020px) {
  #view-door .fp-fixgrid,#view-door .fp-calc{grid-template-columns:1fr}
}
@media (max-width:620px) {
  #view-door .fp-fxfig,#view-door .fp-cin,#view-door .fp-cout{grid-template-columns:1fr}
}
#view-door .fp-lsub{font-size:13px;color:#5C6472;margin-top:4px;min-height:2.8em}
#view-door .fp-delta{display:flex;justify-content:center;gap:14px;flex-wrap:wrap;margin:22px 0 0;padding:18px 22px;border:1px solid #0E7A47;border-radius:14px;background:#E6F3EC;text-align:center}
#view-door .fp-delta b{font-family:var(--disp);font-weight:400;font-size:clamp(40px,5vw,60px);line-height:1;color:#107C41}
#view-door .fp-delta span{font-size:17px;color:#0D1B2A;text-align:left}
#view-door .fp-proofgrid{display:grid;grid-template-columns:1fr 1.05fr;gap:28px}
#view-door .fp-prooflist{display:grid;gap:16px}
#view-door .fp-cert{border:1px solid #0E7A47;border-radius:14px;padding:22px;box-shadow:0 0 0 4px rgba(31,191,138,.08)}
#view-door .fp-certhead{display:flex;align-items:center;gap:14px;padding-bottom:16px;border-bottom:1px solid #E1E4EA}
#view-door .fp-seal{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;background:#0E7A47;color:#FFFFFF;font-size:22px;font-weight:700;flex:none}
#view-door .fp-certhead b{display:block;font-size:17px}
#view-door .fp-certsub{font-size:13px;color:#0E7A47}
#view-door .fp-certbody{margin:0;padding:0}
#view-door .fp-certbody > div{display:grid;grid-template-columns:150px 1fr;gap:16px;padding:11px 0;border-bottom:1px solid #E1E4EA}
#view-door .fp-certbody dt{font-size:13px;color:#5C6472}
#view-door .fp-certbody dd{margin:0;font-size:14px;color:#0D1B2A}
#view-door .fp-certbody .fp-mono{font-family:var(--mono),monospace;font-size:13px;color:#0E7A47}
#view-door .fp-certfoot{margin:14px 0 0;font-size:12px;color:#5C6472}
@media (max-width:1020px) {
  #view-door .fp-proofgrid{grid-template-columns:1fr}
}
@media (max-width:620px) {
  #view-door .fp-certbody > div{grid-template-columns:1fr;gap:2px}
}
#view-door .fp-stat{text-align:left;background:none;border:0;border-top:2px solid #0D1B2A;padding:14px 0 0;color:inherit;cursor:pointer;width:100%}
#view-door .fp-stat .fp-sv,#view-door .fp-stat .fp-sl,#view-door .fp-stat .fp-src{display:block}
#view-door .fp-sv{font-size:44px;line-height:1}
#view-door .fp-sl{color:#3F4756;font-size:15px;margin-top:8px}
#view-door .fp-src{font-size:13px;color:#0E7A47;margin-top:8px;max-height:0;overflow:hidden;opacity:0;visibility:hidden;transition:max-height .35s,opacity .35s,visibility .35s}
#view-door .fp-stat[aria-expanded="true"] .fp-src{max-height:160px;opacity:1;visibility:visible}
#view-door .fp-stat::after{content:"Tap for source";display:block;font-size:12px;color:#5C6472}
#view-door .fp-stat[aria-expanded="true"]::after{content:"Hide"}
#view-door .fp-common{margin-top:36px;background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:22px 24px}
#view-door .fp-common h3{margin-bottom:12px}
#view-door .fp-bar{display:grid;grid-template-columns:280px 1fr 70px;gap:16px;align-items:center;padding:7px 0}
#view-door .fp-bl{font-size:15px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#view-door .fp-chip{font-size:11px;padding:2px 8px;border-radius:999px;white-space:nowrap}
#view-door .fp-b-m{background:#FBEBEE;color:#A3121F}
#view-door .fp-b-s{background:#FCF4E3;color:#7A5207}
#view-door .fp-b-h{background:#F0F2F5;color:#3F4756}
#view-door .fp-track{height:12px;background:#EDEFF3;border-radius:3px;overflow:hidden}
#view-door .fp-fill{display:block;height:100%;border-radius:3px;transition:width 1s cubic-bezier(.2,.7,.2,1)}
#view-door .fp-bp{text-align:right;font-size:15px}
#view-door .fp-risk{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:22px;display:flex;flex-direction:column}
#view-door .fp-rk{font-size:30px;line-height:1.1;color:var(--amb-on-tint);display:block;margin-bottom:14px;min-height:1.1em}
#view-door .fp-risk p{color:#3F4756;font-size:15px;margin:0;flex:1}
#view-door .fp-risk .fp-rsrc{flex:0;font-size:12px;color:#5C6472;margin-top:14px}
#view-door .fp-steps{list-style:none;margin:0 0 40px;padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
#view-door .fp-steps .fp-n{display:inline-grid;place-items:center;width:34px;height:34px;border-radius:50%;background:#0E7A47;color:#FFFFFF;font-weight:700;margin-bottom:12px}
#view-door .fp-steps p{color:#3F4756;font-size:15px;margin:0}
#view-door .fp-vs{display:grid;grid-template-columns:1fr 1fr;gap:20px}
#view-door .fp-side{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:20px 22px;display:flex;flex-direction:column}
#view-door .fp-side h3{color:#3F4756;font-size:15px;margin:0}
#view-door .fp-side canvas{width:100%;height:auto;display:block}
#view-door .fp-v{font-size:clamp(52px,6vw,76px);line-height:1}
#view-door .fp-l{color:#3F4756;font-size:15px;min-height:1.6em}
#view-door .fp-stage{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
#view-door .fp-st{font-size:13px;min-height:34px;padding:0 13px;border-radius:999px;border:1px solid #C9CED8;background:transparent;color:#3F4756;cursor:pointer}
#view-door .fp-st.fp-on{background:#0D1B2A;color:#F3F4F7;border-color:#0D1B2A}
#view-door .fp-keyrow{display:flex;flex-wrap:wrap;align-items:center;gap:8px 20px;margin-top:16px;font-size:13px;color:#3F4756}
#view-door .fp-keyrow i{display:inline-block;width:11px;height:11px;border-radius:2px;margin-right:6px;vertical-align:-1px}
#view-door .fp-dl{font-size:14px;color:#3F4756;display:block;margin-bottom:8px}
#view-door .fp-drow{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px;align-items:center}
#view-door .fp-empty{color:#5C6472;margin:0}
#view-door .fp-grp{margin:0 0 18px}
#view-door .fp-grp h4{margin:0 0 8px;font-size:14px;color:#0E7A47;font-weight:600}
#view-door .fp-done{opacity:.55}
#view-door .fp-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}
#view-door .fp-summary div{font-size:13px;color:#3F4756}
#view-door .fp-summary b{display:block;font-family:var(--disp);font-size:28px;color:#0D1B2A;font-weight:400}
#view-door .fp-askin{flex:1;min-width:160px;background:#F3F4F7;color:#0D1B2A;border:1px solid #C9CED8;border-radius:10px;padding:0 12px;min-height:36px;font:inherit;font-size:14px}
#view-door .fp-opt{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
#view-door .fp-audit{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;align-items:flex-end;margin-top:24px}
#view-door .fp-audit label{display:flex;flex-direction:column;text-align:left;font-size:13px;color:#3F4756;gap:6px}
#view-door .fp-audit input,#view-door .fp-audit select{background:#F3F4F7;color:#0D1B2A;border:1px solid #C9CED8;border-radius:10px;padding:0 12px;min-height:46px;font:inherit;min-width:210px}
#view-door .fp-srcs{border-top:1px solid #E1E4EA;padding:36px 0 0}
#view-door .fp-srcs h3{font-size:15px;color:#3F4756}
#view-door .fp-srcs ol{margin:8px 0 0;padding-left:20px;font-size:13px;color:#5C6472;columns:2;column-gap:40px}
#view-door .fp-srcs li{margin:0 0 6px;break-inside:avoid}
#view-door.fp-j-own [data-j="agency"],#view-door.fp-j-agency [data-j="own"]{display:none!important}
@media (max-width:1020px) {
  #view-door .fp-heroin,#view-door .fp-vs,#view-door .fp-grid4,#view-door .fp-steps{grid-template-columns:1fr 1fr}
  #view-door .fp-grid3{grid-template-columns:1fr 1fr}
  #view-door .fp-bar{grid-template-columns:200px 1fr 60px}
  #view-door .fp-srcs ol{columns:1}
}
@media (max-width:620px) {
  #view-door .fp-heroin,#view-door .fp-vs,#view-door .fp-grid4,#view-door .fp-steps,#view-door .fp-grid3,#view-door .fp-journey{grid-template-columns:1fr}
  #view-door .fp-bar{grid-template-columns:1fr 56px}
  #view-door .fp-bar .fp-track{grid-column:1/-1;order:3}
  #view-door .fp-cmp thead{display:none}
  #view-door .fp-cmp,#view-door .fp-cmp tbody,#view-door .fp-cmp tr,#view-door .fp-cmp th,#view-door .fp-cmp td{display:block;width:100%!important}
  #view-door .fp-cmp th[scope=row]{background:#FAFBFC}
  #view-door .fp-cmp td::before{content:attr(data-h);display:block;font-size:12px;color:#5C6472;margin-bottom:2px}
  #view-door .fp-summary{grid-template-columns:1fr 1fr}
}
#view-door .fp-t-hero{padding:72px 0 60px;border-top:0}
#view-door .fp-t-hero h1{font-size:clamp(38px,5.4vw,62px);line-height:1.08;max-width:17ch;margin:0}
#view-door .fp-t-hero h1 em{font-style:normal;color:#0E7A47}
#view-door .fp-t-lede{font-size:20px;color:#3F4756;max-width:60ch;margin-top:22px}
#view-door .fp-t-proof{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:44px}
#view-door .fp-t-pv{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:18px 20px}
#view-door .fp-t-pv b{display:block;font-family:var(--ui);font-size:30px;font-weight:600;color:#0D1B2A;line-height:1.2}
#view-door .fp-t-pv span{display:block;font-size:15px;color:#3F4756;margin-top:4px}
#view-door .fp-t-intro{font-size:18px;color:#3F4756;max-width:62ch;margin-top:14px}
#view-door .fp-t-risks{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:32px}
#view-door .fp-t-risk{border-left:3px solid #B0770B;background:#FAFBFC;border-radius:0 12px 12px 0;padding:18px 20px}
#view-door .fp-t-risk p{color:#3F4756;font-size:16px;margin:0}
#view-door .fp-t-risk small{display:block;color:#5C6472;font-size:13px}
#view-door .fp-t-benefits{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:34px}
#view-door .fp-t-ben{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:24px;display:flex;flex-direction:column}
#view-door .fp-t-ben h3{margin:0 0 6px}
#view-door .fp-t-ben p{color:#3F4756;font-size:16px;margin:0}
#view-door .fp-t-ben.fp-wide{grid-column:span 2}
#view-door .fp-t-ic{width:40px;height:40px;border-radius:10px;background:#E6F3EC;display:flex;align-items:center;justify-content:center;margin-bottom:14px}
#view-door .fp-t-ic svg{width:22px;height:22px;stroke:#0E7A47;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
#view-door .fp-t-who{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:34px}
#view-door .fp-t-whoc{background:#FFFFFF;border:1px solid #E1E4EA;border-radius:14px;padding:26px}
#view-door .fp-t-whoc ul{margin:12px 0 18px;padding-left:20px;color:#3F4756}
#view-door .fp-t-whoc li{margin:6px 0}
#view-door .fp-h1like{font-weight:400;font-size:clamp(30px,4vw,48px);line-height:1.1;letter-spacing:-0.012em;margin:0 0 26px;max-width:none}
#view-door .fp-h1like em{font-style:normal;color:#0E7A47}
#view-door .fp-t-detail{padding:40px 0 0;border-top:0;text-align:center}
#view-door .fp-t-detail .fp-eb{margin:0}
#view-door .fp-t-detail h2{margin:6px auto 0}
#view-door .fp-sv,#view-door .fp-rk,#view-door .fp-v,#view-door .fp-pcap b,#view-door .fp-delta b,#view-door .fp-cout b,#view-door .fp-t-pv b,#view-door .fp-bp,#view-door .fp-fig,#view-door .fp-lede b,#view-door #fp-hpv{font-weight:600}
#view-door .fp-fig{color:inherit}
#view-door .fp-stat{align-self:stretch;display:flex;flex-direction:column;height:100%}
#view-door .fp-stat .fp-sl{min-height:3.2em}
#view-door .fp-stat::after{margin-top:auto;padding-top:10px}
#view-door .fp-t-risk{display:flex;flex-direction:column}
#view-door .fp-t-risk small{margin-top:auto;padding-top:12px}
#view-door .fp-t-whoc{display:flex;flex-direction:column}
#view-door .fp-t-pv,#view-door .fp-t-ben,#view-door .fp-ucard,#view-door .fp-risk,#view-door .fp-side{height:100%}
#view-door .fp-side .fp-lsub{min-height:4.3em}
#view-door .fp-side .fp-stage{margin-top:auto;padding-top:14px}
#view-door .fp-delta{align-items:center}
#view-door .fp-delta span{max-width:46ch}
#view-door .fp-proofgrid{align-items:stretch}
#view-door .fp-cert{display:flex;flex-direction:column}
#view-door .fp-certfoot{margin-top:auto;padding-top:12px}
#view-door .fp-cout>div{display:flex;flex-direction:column}
#view-door .fp-calc>*,#view-door .fp-cin>*,#view-door .fp-cout>*{min-width:0}
#view-door .fp-cin input{min-width:0;width:100%}
@media (max-width:1020px) {
  #view-door .fp-t-proof,#view-door .fp-t-risks,#view-door .fp-t-benefits{grid-template-columns:1fr 1fr}
  #view-door .fp-t-ben.fp-wide{grid-column:span 2}
}
@media (max-width:620px) {
  #view-door .fp-t-proof,#view-door .fp-t-risks,#view-door .fp-t-benefits,#view-door .fp-t-who{grid-template-columns:1fr}
  #view-door .fp-t-ben.fp-wide{grid-column:auto}
  #view-door .fp-t-hero{padding:48px 0 40px}
  #view-door .fp-t-lede{font-size:18px}
}
#view-door {--k0c1524:#0D1B2A;--k0f1a2b:#F3F4F7;--k11362a:#E6F3EC;--k12301f:#E6F3EC;--k132038:#FAFBFC;--k13253b:#FFFFFF;--k16243a:#FFFFFF;--k16563c:#E6F3EC;--k1a7f4d:#0E7A47;--k1b2c46:#1B2C46;--k1e2e46:#E1E4EA;--k1e9159:#0E7A47;--k22324a:#EDEFF3;--k24344c:#E1E4EA;--k2a3547:#F0F2F5;--k2a3b55:#E1E4EA;--k3a4a62:#C9CED8;--k4a1520:#FBEBEE;--k4a3510:#FCF4E3;--k4a5e7e:#7D8797;--k4fc98a:#107C41;--k6fd79c:#0E7A47;--k7fb2ff:#0B5FBF;--ka3b1c4:#5C6472;--kbcc8d8:#5C6472;--kcfd8e4:#3F4756;--kd9f5e4:#0B5C36;--kdce3ec:#3F4756;--ke9eef5:#0D1B2A;--kf29a12:#B0770B;--kff8a98:#A3121F;--kffb23e:#9E6B0A;--kffc46b:#7A5207;--kffffff:#FFFFFF;--k-serif:var(--ui);color-scheme:light}
#view-door h1,#view-door h2{font-weight:600;letter-spacing:-.015em}
#view-door .fp-ucard,#view-door .fp-risk,#view-door .fp-stat,#view-door .fp-t-pv,#view-door .fp-t-ben,#view-door .fp-t-whoc,#view-door .fp-t-risk,#view-door .fp-cert,#view-door .fp-side,#view-door .fp-calc,#view-door .fp-jb{box-shadow:-1px 1px 2px rgba(13,27,42,.06),-1px 1px 3px rgba(13,27,42,.10)}
#view-door .fp-cert{background:#FFFFFF}
#view-door #fp-vw{color:var(--amb-on-tint)!important}
#view-door #fp-va:not(.fp-s6){color:#107C41!important}
#view-door #fp-va.fp-s6{color:var(--amb-on-tint)!important}
#view-door .fp-vs>*,#view-door .fp-heroin>*{min-width:0}
#view-door .fp-side canvas{max-width:100%}
#view-door .fp-herokey{justify-content:center;margin-top:12px}

/* ---- set by the conversion: the page lives inside the app's main column ---- */
#view-door{font-family:var(--ui);color:var(--ink)}
#view-door .fp-wrap{max-width:none;padding:0}
#view-door section{scroll-margin-top:calc(var(--bar-h, 60px) + 8px)}
#view-door .fp-h1{font-family:var(--disp)}
#view-door .ghost,#view-door .btn{white-space:nowrap}
#view-door .fp-tip{position:fixed;left:var(--tx,0);top:var(--ty,0);pointer-events:none;background:#0D1B2A;color:#fff;font-size:13px;padding:6px 9px;border-radius:6px;opacity:0;transition:opacity .15s;z-index:60;white-space:nowrap}
#view-door .fp-tip.fp-tip-on{opacity:1}
#view-door .fp-tl li{transition-delay:var(--fp-delay,0s)}
#view-door .fp-fill{width:0}
#view-door .fp-bars.fp-on .fp-fill,#view-door #fp-bars.fp-on .fp-fill{width:var(--fp-w,0)}
#view-door .fp-fill-m{background:#C4314B}
#view-door .fp-fill-s{background:#E8A33D}
#view-door .fp-fill-h{background:#98A0AE}
#view-door .fp-sr{position:absolute;left:-9999px}
/* These stood in for written-in styles, which outrank every rule, so they are marked to do the same. */
#view-door .fp-s1{margin-top:28px !important}
#view-door .fp-s2{background:#C4314B !important}
#view-door .fp-s3{background:#107C41 !important}
#view-door .fp-s4{margin-top:48px !important}
#view-door .fp-s5{margin-top:36px !important}
#view-door .fp-s6{color:var(--amb-on-tint) !important}
#view-door .fp-s7{color:#107C41 !important}
#view-door .fp-s8{background:#E8A33D !important}
#view-door .fp-s9{background:#98A0AE !important}
#view-door .fp-s10{margin-top:24px !important}
#view-door .fp-s11{margin-top:4px !important}
#view-door .fp-s12{grid-column:1/-1 !important;margin-top:0 !important}
#view-door .fp-s13{margin-bottom:14px !important}
#view-door .fp-s14{position:absolute !important;left:-9999px !important}
/* A button takes the page's type unless a rule above says otherwise. Weightless, so any rule wins. */
:where(#view-door button){font-family:inherit}
/* The one call to action that is a link rather than a button: an email, so it reads as a button. */
#view-door a.btn{text-decoration:none}

/* ------------------------------------------------------- the Overview sections panel

   The arrow beside Overview opens the page's sections in four groups, under the bar and across
   its full width, as GOV.UK's menu bar does. It opens on a press only (public/js/sections.mjs).
   A light panel under a navy bar, so the bar's white focus ring is replaced inside it. */
.sect-toggle { padding: var(--sp-2); min-width: 32px; justify-content: center; }
.sect-toggle .i { transition: transform var(--m-state); }
.sect-toggle[aria-expanded="true"] { color: #fff; background: rgba(255, 255, 255, .12); }
.sect-toggle[aria-expanded="true"] .i { transform: rotate(180deg); }
.sect-panel {
  position: absolute; left: 0; right: 0; top: 100%;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-5);
  padding: var(--sp-5) var(--sp-5) var(--sp-6);
  background: var(--surf); color: var(--ink);
  border-bottom: 1px solid var(--line); box-shadow: -8px 8px 20px rgba(13, 27, 42, .14);
  max-height: calc(100vh - var(--bar-h) - 16px); overflow-y: auto;
}
.sect-panel[hidden] { display: none; }
.sect-h { margin: 0 0 var(--sp-2); font: 600 var(--t-s) var(--ui); color: var(--mid); text-transform: uppercase; letter-spacing: .04em; }
.sect-g ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sect-a {
  display: flex; align-items: center; min-height: 36px; padding: 6px var(--sp-2); margin-left: calc(-1 * var(--sp-2));
  border-radius: var(--r-s); color: var(--ink); text-decoration: none; font: 500 var(--t-m) var(--ui);
}
.sect-a:hover { background: var(--bg); color: var(--act); text-decoration: underline; }
.bar .sect-panel a:focus-visible { outline: 2px solid var(--act); outline-offset: 1px; }
@media (max-width: 1139px) {
  .sect-panel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .sect-panel { grid-template-columns: 1fr; gap: var(--sp-4); padding: var(--sp-4); }
  .sect-a { min-height: 44px; }
}

/* The same sections from inside the page: a contents strip under the opening, and a way back
   to the top at the end of the long stretches. Jump targets clear the sticky bar. */
#view-door .fp-jump{scroll-margin-top:calc(var(--bar-h, 60px) + 8px)}
#view-door .fp-toc{background:#FFFFFF;border-top:1px solid #E1E4EA;border-bottom:1px solid #E1E4EA;padding:14px 0}
#view-door .fp-toc .fp-wrap{display:grid;gap:8px}
#view-door .fp-toc-h{margin:0;font-size:13px;font-weight:600;color:#5C6472;text-transform:uppercase;letter-spacing:.04em}
#view-door .fp-toc ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
#view-door .fp-toc a{display:inline-flex;align-items:center;min-height:32px;padding:4px 12px;border:1px solid #C9CED8;border-radius:999px;background:#FFFFFF;color:#0B5FBF;font-size:14px;font-weight:600;text-decoration:none}
#view-door .fp-toc a:hover{border-color:#0B5FBF;background:#F3F7FD}
#view-door .fp-top{margin:32px 0 0;font-size:14px}
#view-door .fp-top a{color:#0B5FBF}
/* A section focused by a jump is not a control, so it wears no ring. */
#view-door [tabindex="-1"]:focus{outline:none}
/* The third stage on the right-hand pie is modelled, not measured. Its key swatch is hatched with
   a dashed edge, as the slice is, so the difference never rests on colour alone. */
#view-door .fp-keyrow i.fp-hatch{background:repeating-linear-gradient(135deg,#5AB47E 0 2px,#DDF0E4 2px 4px);border:1px dashed #0B5A30}
#view-door #fp-va.fp-va-model{text-decoration:underline dashed 2px;text-underline-offset:8px}
/* Before and after as a pair: the same tag, the same size of figure and the same lines under it,
   red-amber for what was wrong and green for what the product does about it. */
#view-door .fp-tag{align-self:flex-start;margin:10px 0 6px;padding:3px 12px;border-radius:999px;font:700 12px var(--ui);letter-spacing:.06em;text-transform:uppercase;background:#E6F3EC;color:#0B5C36}
#view-door .fp-tag.fp-tag-bad{background:#FCF4E3;color:#8A5D08}
#view-door .fp-side .fp-l{min-height:3.2em}
#view-door .fp-stages{font-size:14px}
#view-door .fp-stages-h{font-weight:600;color:#0D1B2A;margin:18px 0 8px}
#view-door .fp-stages th,#view-door .fp-stages td{padding:10px 12px;width:auto}
#view-door .fp-stages tbody tr:last-child th{border-bottom:0}
/* Small print: the notes and disclaimers on the front page are folded under one short label each,
   closed until somebody asks for them. The same style everywhere, so it reads as one thing. */
#view-door .fp-fine{max-width:80ch;margin:20px 0 0;font-size:14px;color:#5C6472}
#view-door .fp-fine summary{display:inline-flex;align-items:center;gap:8px;min-height:32px;cursor:pointer;list-style:none;font-weight:600;color:#3F4756;border-radius:6px}
#view-door .fp-fine summary::-webkit-details-marker{display:none}
#view-door .fp-fine summary::before{content:"+";display:inline-grid;place-items:center;width:20px;height:20px;border:1px solid #C9CED8;border-radius:50%;font-size:14px;line-height:1;color:#0E7A47}
#view-door .fp-fine[open] summary::before{content:"\2212"}
#view-door .fp-fine summary:hover{color:#0D1B2A}
#view-door .fp-fine summary:focus-visible{outline:3px solid #0B5FBF;outline-offset:2px}
#view-door .fp-fine>div{padding:6px 0 0 28px}
#view-door .fp-fine p{margin:0 0 10px}
#view-door .fp-fine .fp-stages{margin:0 0 12px}
#view-door .fp-fine .fp-stages-h{margin:4px 0 8px}
#view-door .fp-fine-wide{max-width:none}
/* The paste box's guard: why a text cannot be checked, directly under the box, before anything is
   pressed, with the box itself outlined in the same red. */
.paster-box textarea[aria-invalid="true"] { border-color: var(--red); outline: 2px solid var(--red); outline-offset: 0; }
.paste-guard:empty { display: none; }
.paste-guard { display: grid; gap: 8px; margin-top: 8px; }
.paste-guard .notice { margin: 0; }
.paste-guard .notice p { margin: 0; }
/* A report's full record, under the row, in the exact form Copy puts on the clipboard. */
#view-admin .misfire-more { margin-top: var(--sp-2); }
#view-admin .misfire-more summary { cursor: pointer; font-weight: 600; min-height: 24px; }
#view-admin .misfire-block {
  margin: var(--sp-2) 0 0; padding: var(--sp-3); white-space: pre-wrap; overflow-wrap: anywhere;
  font: 400 var(--t-xs)/1.5 var(--mono); background: var(--io-bg); border: 1px solid var(--line); border-radius: var(--r-s);
}
#view-admin .misfire-note { white-space: pre-wrap; font-style: normal; }

/* ------------------------------------------------------------------------------- help

   A panel over the right of the screen (public/js/help.mjs). Each area has its own colour, set
   as --hc by its class, and none of them is a stage colour, a warning or a removal. Everything
   that moves stops when Motion is off, by the rule near the top of this sheet. */

.help-a-start { --hc: #0F6E7A; }
.help-a-check { --hc: #3F3FC9; }
.help-a-result { --hc: #9B2C6F; }
.help-a-finish { --hc: #6A3FB5; }
.help-a-account { --hc: #B4461B; }
.help-a-privacy { --hc: #36506B; }
.help-a-console { --hc: #0D1B2A; }

.help-root { position: fixed; inset: 0; z-index: 45; }
.help-scrim { position: absolute; inset: 0; background: rgba(13, 27, 42, .45); animation: fade var(--m-panel) both; }
.help {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(31rem, 100%);
  background: var(--bg); display: flex; flex-direction: column; box-shadow: var(--sh3);
  animation: help-in .28s cubic-bezier(.2, .8, .2, 1) both;
}
@keyframes help-in { from { transform: translateX(32px); opacity: 0; } to { transform: none; opacity: 1; } }
.help-band { display: flex; height: 6px; flex: none; }
.help-band span { flex: 1; background: var(--hc); }
.help-head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4) var(--sp-5) var(--sp-2); }
.help-h { display: flex; align-items: center; gap: var(--sp-2); margin: 0; font-size: var(--t-xl); }
.help-h .i svg { width: 26px; height: 26px; color: var(--act); }
.help-x {
  display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-full);
  border: 1px solid var(--line); background: var(--surf); color: var(--ink); cursor: pointer;
}
.help-x:hover { background: var(--gry-t); }
.help-search { position: relative; padding: 0 var(--sp-5); }
.help-q-i { position: absolute; left: calc(var(--sp-5) + 14px); top: 50%; transform: translateY(-50%); color: var(--mid); pointer-events: none; }
.help-q-i svg { width: 20px; height: 20px; }
.help-search .help-q {
  width: 100%; height: 48px; padding: 0 var(--sp-4) 0 44px; border-radius: var(--r-full);
  border: 2px solid var(--line); background: var(--surf); font: 500 var(--t-m) var(--ui); color: var(--ink);
}
.help-search .help-q:focus { outline: none; border-color: var(--act); box-shadow: 0 0 0 4px var(--act-t); }
.help-count { margin: var(--sp-2) var(--sp-5) 0; font-size: var(--t-s); color: var(--mid); min-height: 1.4em; }
.help-body { flex: 1; overflow: auto; padding: var(--sp-3) var(--sp-5) var(--sp-5); overscroll-behavior: contain; }
.help-foot { flex: none; padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line); background: var(--surf); font-size: var(--t-s); }
.help-foot p { margin: 0; }

/* The product in one moving picture: three coloured steps, lit in turn, with a dot running
   along the line between them. */
.help-searching .help-hero { display: none; }
.help-hero { position: relative; background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-l); padding: var(--sp-4); margin-bottom: var(--sp-5); }
.help-hero-h { margin: 0 0 var(--sp-3); font: 700 var(--t-xs) var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--mid); }
.help-journey { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); position: relative; z-index: 1; }
.help-j { display: grid; justify-items: center; gap: var(--sp-2); text-align: center; font-size: var(--t-s); font-weight: 600; }
.help-j-dot {
  display: grid; place-items: center; width: 48px; height: 48px; border-radius: var(--r-full);
  color: #fff; box-shadow: 0 0 0 4px var(--surf);
  animation: help-lit 4.5s ease-in-out infinite;
}
.help-j-dot svg { width: 22px; height: 22px; }
.help-j-1 .help-j-dot { background: #0F6E7A; }
.help-j-2 .help-j-dot { background: #3F3FC9; animation-delay: 1.5s; }
.help-j-3 .help-j-dot { background: #6A3FB5; animation-delay: 3s; }
@keyframes help-lit {
  0%, 30%, 100% { transform: scale(1); }
  12% { transform: scale(1.14); box-shadow: 0 0 0 4px var(--surf), 0 0 0 9px rgba(63, 63, 201, .18); }
}
.help-rail { position: absolute; left: 16.6%; right: 16.6%; top: calc(var(--sp-4) + var(--t-xs) + var(--sp-3) + 24px); height: 3px; background: var(--line); border-radius: 2px; }
.help-rail-dot { position: absolute; top: -3px; left: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--act); animation: help-run 4.5s ease-in-out infinite; }
@keyframes help-run { 0% { left: 0; opacity: 0; } 8% { opacity: 1; } 92% { opacity: 1; } 100% { left: calc(100% - 9px); opacity: 0; } }

.help-group { margin-bottom: var(--sp-5); }
.help-group-h { margin: 0 0 var(--sp-3); font-size: var(--t-m); }
.help-area-h { display: flex; align-items: center; gap: var(--sp-3); }
.help-area-b { display: block; font: 400 var(--t-s) var(--ui); color: var(--mid); }
.help-here > .help-group-h { display: flex; align-items: center; gap: var(--sp-2); }
.help-here > .help-group-h::before { content: ''; width: 10px; height: 10px; border-radius: 50%; background: var(--act); animation: help-ping 1.8s ease-out infinite; }
@keyframes help-ping { 0% { box-shadow: 0 0 0 0 rgba(11, 95, 191, .5); } 100% { box-shadow: 0 0 0 10px rgba(11, 95, 191, 0); } }
.help-cards { display: grid; gap: var(--sp-2); }

.help-tile { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: var(--r-s); background: var(--hc); color: #fff; }
.help-tile svg { width: 20px; height: 20px; }

.help-topic {
  background: var(--surf); border: 1px solid var(--line); border-left: 4px solid var(--hc);
  border-radius: 0 var(--r-m) var(--r-m) 0; animation: help-card .3s ease-out both;
}
.help-cards .help-topic:nth-child(2) { animation-delay: 40ms; }
.help-cards .help-topic:nth-child(3) { animation-delay: 80ms; }
.help-cards .help-topic:nth-child(4) { animation-delay: 120ms; }
.help-cards .help-topic:nth-child(n+5) { animation-delay: 160ms; }
@keyframes help-card { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.help-topic-s { display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-3); cursor: pointer; list-style: none; }
.help-topic-s::-webkit-details-marker { display: none; }
.help-topic-s:hover { background: color-mix(in srgb, var(--hc) 6%, var(--surf)); }
.help-topic-t { flex: 1; display: grid; gap: 2px; }
.help-topic-h { font-weight: 700; color: var(--ink); }
.help-topic-p { font-size: var(--t-s); color: var(--mid); }
.help-caret { flex: none; color: var(--mid); transition: transform var(--m-state); margin-top: 8px; }
.help-topic[open] .help-caret { transform: rotate(180deg); }
.help-topic[open] > .help-topic-s .help-tile { animation: help-bob .5s ease-out; }
@keyframes help-bob { 0% { transform: scale(1); } 40% { transform: scale(1.18) rotate(-6deg); } 100% { transform: scale(1); } }
.help-topic-b { padding: 0 var(--sp-3) var(--sp-3) calc(var(--sp-3) + 36px + var(--sp-3)); }

/* Numbered steps, each number in the area's colour, arriving one after another. */
.help-steps { list-style: none; counter-reset: help; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.help-steps li { counter-increment: help; position: relative; padding-left: 34px; font-size: var(--t-s); line-height: 1.5; animation: help-step .3s ease-out both; }
.help-steps li::before {
  content: counter(help); position: absolute; left: 0; top: -1px; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; background: var(--hc); color: #fff; font: 700 12px var(--ui);
}
.help-steps li:nth-child(2) { animation-delay: 60ms; }
.help-steps li:nth-child(3) { animation-delay: 120ms; }
.help-steps li:nth-child(4) { animation-delay: 180ms; }
@keyframes help-step { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.help-do { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-3) 0 0; }
.help-do a.ghost { text-decoration: none; }
.help mark { background: color-mix(in srgb, var(--hc, #F2C94C) 22%, #fff); color: inherit; border-radius: 3px; padding: 0 1px; }
.help-none { background: var(--surf); border: 1px dashed var(--line); border-radius: var(--r-m); padding: var(--sp-4); font-size: var(--t-s); }
.help-none p { margin: 0 0 var(--sp-2); }

/* Show me: a ring round the control a topic was about, pulsing three times. */
.help-spot { animation: help-spot 1s ease-out 3; border-radius: var(--r-s); }
@keyframes help-spot { 0% { box-shadow: 0 0 0 0 rgba(11, 95, 191, .7); } 100% { box-shadow: 0 0 0 14px rgba(11, 95, 191, 0); } }
:root[data-motion="off"] .help-spot { outline: 3px solid var(--act); outline-offset: 3px; }

@media (max-width: 620px) {
  /* One row on a phone: the counter's ring and number, then four round buttons with their
     pictures. Their names are still there for a screen reader, hidden only from sight, and the
     counter's full words are its accessible name. It was four wide buttons in two rows and a bar
     305px tall that stays on screen, a third of a phone. The version is in the footer. */
  .bar-tools { flex-wrap: nowrap; gap: 6px; }
  .allow-wrap { flex: 0 1 auto; }
  .allow-chip .allow-chip-l { display: none; }
  .allow-chip { height: 44px; }
  .bar-tools > .ghost-nav { flex: 0 0 44px; width: 44px; min-width: 44px; height: 44px; padding: 0; }
  .bar-tools .tool-w {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .bar-tools > .ver { display: none; }
  .bar-tools > .ghost-nav .i svg { width: 20px; height: 20px; }
  .help-head, .help-search, .help-body, .help-foot { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  .help-q-i { left: calc(var(--sp-4) + 14px); }
  .help-count { margin-left: var(--sp-4); }
  .help-topic-b { padding-left: var(--sp-3); }
}

/* A Share button at the top right of every part of the Overview (door.mjs). Small and quiet so it
   never competes with the heading beside it, and the same button everywhere. On a phone it is
   the icon alone, with its name still read out. */
#view-door .fp-share-host{position:relative}
#view-door .fp-share-sec{position:absolute;top:0;right:0;z-index:2;display:inline-flex;align-items:center;gap:6px;min-height:34px;padding:0 14px;border-radius:999px;border:1px solid #C9CED8;background:#FFFFFF;color:#0B5FBF;font:600 13px var(--ui);cursor:pointer;box-shadow:-2px 2px 4px rgba(13,27,42,.08)}
#view-door .fp-share-sec:hover{border-color:#0B5FBF;background:#E8F1FB}
#view-door .fp-share-sec .i svg{width:16px;height:16px}
#view-door .fp-share-host > .fp-head, #view-door .fp-share-host > .fp-eb:first-of-type{padding-right:110px}
#view-door section.fp-t-hero .fp-share-sec, #view-door section.fp-t-detail .fp-share-sec{top:-8px}
@media (max-width:620px){
  #view-door .fp-share-sec{padding:0;width:36px;justify-content:center}
  #view-door .fp-share-w{display:none}
  #view-door .fp-share-host > .fp-head, #view-door .fp-share-host > .fp-eb:first-of-type{padding-right:44px}
}

/* The chart's button sits just above it, clear of the right-hand panel's heading. */
#view-door #fp-chart{margin-top:52px}
#view-door #fp-chart > .fp-share-sec{top:-46px}
/* Every stage's wording in one place, the longest setting the height (door.mjs, layer). Hidden
   ones are hidden from a screen reader too, which reads the one showing. */
#view-door .fp-layers{display:grid}
#view-door .fp-layers>span{grid-area:1/1;visibility:hidden}
#view-door .fp-layers>span.fp-now{visibility:visible}

/* ------------------------------------------------------------------ the phone's menu

   public/js/menu.mjs. On a narrow screen the bar is one short row, the name, the checks lozenge
   and Menu, and the page links and the four tools float down in a panel under it. */
.bar-burger { display: none; }
@media (max-width: 720px) {
  :root { --bar-h: 60px; }
  .bar { flex-wrap: nowrap; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); }
  .bar-brand { flex: 1 1 auto; min-width: 0; }
  .bar-names { min-width: 0; }
  .bar-product { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .bar-brand { gap: var(--sp-2); }
  .bar-product { font-size: 14px; }
  .bar-parent { font-size: 9px; }
  .bar-tools { width: auto; flex: 0 0 auto; margin-left: 0; }
  .allow-wrap { flex: 0 1 auto; }
  .allow-chip .allow-chip-l { display: none; }
  .bar-burger {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: none;
    height: 44px; padding: 0 14px; border-radius: var(--r-full); cursor: pointer;
    font: 600 var(--t-b) var(--ui); color: #fff;
    background-color: #1F2E45; background-image: linear-gradient(200deg, #33476A 0%, #22324C 55%, #1A2840 100%);
    border: 1px solid rgba(255, 255, 255, .22);
    box-shadow: inset -1px 1px 0 rgba(255, 255, 255, .30), -2px 2px 0 #04080E, -5px 5px 12px rgba(0, 0, 0, .55);
  }
  .bar-burger[hidden] { display: none; }
  .bar-burger .i svg { width: 20px; height: 20px; color: #9CC4FF; }
  .bar-burger[aria-expanded="true"] { border-color: rgba(255, 255, 255, .6); }
  .bar-menu {
    position: absolute; top: calc(100% + 6px); left: var(--sp-2); right: var(--sp-2); z-index: 41;
    background: var(--nav); border: 1px solid rgba(255, 255, 255, .16); border-radius: var(--r-l);
    padding: var(--sp-3); box-shadow: -6px 6px 24px rgba(0, 0, 0, .45);
    max-height: calc(100vh - var(--bar-h) - 24px); overflow-y: auto; overscroll-behavior: contain;
    animation: menu-in .2s ease-out both;
  }
  .bar-menu[hidden] { display: none; }
  .bar-menu .bar-nav { display: grid; grid-template-columns: 1fr auto; gap: 4px; }
  .bar-menu .navlink { min-height: 48px; font-size: var(--t-m); justify-content: flex-start; padding: 0 var(--sp-3); }
  .bar-menu .navlink:not(.sect-toggle) { grid-column: 1; }
  .bar-menu .sect-toggle { grid-column: 2; grid-row: 1; min-width: 48px; justify-content: center; }
  .bar-menu .navlink-t { display: inline; }
  .bar-menu .navlink-s { display: none; }
  .bar-menu .sect-panel {
    position: static; grid-column: 1 / -1; border-radius: var(--r-m); box-shadow: none; border: none;
    max-height: none; margin: 4px 0;
  }
  .bar-menu-tools {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2);
    margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid rgba(255, 255, 255, .12);
  }
  .bar-menu-tools > .ghost-nav { --tool-h: 48px; min-width: 0; width: 100%; }
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

