/* ════════════════════════════════════════════════════════════════════════
   MONITOR · THE ACCESSIBILITY MENU

   Loaded on all three surfaces: the workspace, the operator console and the
   marketing site.

   ── Three surfaces, three palettes ──────────────────────────────────────

   That sentence is the whole reason the first version of this file was
   broken, so it goes at the top:

     css/app.css                M3 names   --surface  --on-surface  --outline
     css/home.css               marketing  --ink      --fg/-2/-3    --line
     monitoradmin/css/admin.css console    --s-0..5   --fg/-2/-3    --line

   The first version redefined the M3 set only. On the marketing site the
   background went white and the text did not move, because --fg-2 there is
   rgba(255,255,255,.68) — white ink, now on white paper. Every mode below
   sets ALL THREE vocabularies, and the sweep at the end catches the colours
   those stylesheets hardcode rather than tokenise.

   ── Why the colour modes are not filters ────────────────────────────────

   The widgets that get pasted onto sites do all of this with a CSS filter on
   the html element. A filter makes its element the containing block for every
   position:fixed descendant, and this product has ten of them — the mobile
   nav rail, every modal scrim, the sign-in gate, the Find basket, the add
   button, the tour spotlight, this menu. Under a filter they detach from the
   viewport and scroll away. The reader who just turned on high contrast is
   the last person who should lose the navigation.

   Grayscale is the one thing tokens cannot express. It used to be a filter on
   <body> with a list of fixed elements "compensated" by restating
   position:fixed — which does nothing at all, because the property was never
   what changed. The menu button scrolled off with everything else, so the
   mode had no exit. It is now a fixed overlay with backdrop-filter, which
   desaturates everything painted beneath it and is a containing block for
   nothing.

   ── Why the text size is zoom ───────────────────────────────────────────

   Every size in this project is in px, so scaling the root font-size — the
   usual answer — would move nothing at all.
   ════════════════════════════════════════════════════════════════════════ */

html[data-a11y-zoom="80"]  { zoom: .8 }
html[data-a11y-zoom="90"]  { zoom: .9 }
html[data-a11y-zoom="110"] { zoom: 1.1 }
html[data-a11y-zoom="120"] { zoom: 1.2 }
html[data-a11y-zoom="130"] { zoom: 1.3 }
html[data-a11y-zoom="150"] { zoom: 1.5 }

html[data-a11y-links="on"] :where(a, .a-link):not(.a11y-root *) {
  text-decoration: underline !important; text-underline-offset: 2px;
}

/* A face with wide apertures and unambiguous letterforms. Named rather than
   bundled: a reader who needs this usually has one installed already, and a
   webfont download is the wrong thing to make them wait for. */
html[data-a11y-font="readable"],
html[data-a11y-font="readable"] :where(body, button, input, select, textarea, h1, h2, h3, h4) {
  font-family: "Atkinson Hyperlegible", Verdana, Tahoma, "DejaVu Sans", sans-serif !important;
  letter-spacing: .01em !important;
}

/* ════════════════════════════════════════════════════════════════════════
   THE THREE COLOUR MODES

   Each sets --a11y-ink and --a11y-paper for the sweep further down, then
   every token name all three stylesheets actually read.
   ════════════════════════════════════════════════════════════════════════ */

/* ── High contrast: black on white, real borders, no soft greys ───────── */
html[data-a11y-display="contrast"] {
  color-scheme: light;
  --a11y-ink: #000000; --a11y-paper: #FFFFFF;

  /* app.css (M3) */
  --brand: #000000; --brand-2: #000000; --brand-dark: #000000;
  --primary: #000000; --on-primary: #FFFFFF;
  --primary-container: #FFFFFF; --on-primary-container: #000000;
  --secondary: #000000; --secondary-container: #FFFFFF;
  --surface: #FFFFFF; --surface-dim: #FFFFFF;
  --surface-c-lowest: #FFFFFF; --surface-c-low: #FFFFFF;
  --surface-c: #FFFFFF; --surface-c-high: #FFFFFF; --surface-c-highest: #FFFFFF;
  --on-surface: #000000; --on-surface-var: #000000;
  --outline: #000000; --outline-var: #000000;
  --success: #00552F; --success-c: #FFFFFF;
  --warning: #6B3200; --warning-c: #FFFFFF;
  --danger: #8B0014; --danger-c: #FFFFFF;
  --info: #000000; --info-c: #FFFFFF;

  /* home.css (marketing) + admin.css (console) */
  --ink: #FFFFFF; --ink-2: #FFFFFF; --ink-3: #FFFFFF;
  --s-0: #FFFFFF; --s-1: #FFFFFF; --s-2: #FFFFFF;
  --s-3: #FFFFFF; --s-4: #FFFFFF; --s-5: #000000;
  --fg: #000000; --fg-2: #000000; --fg-3: #1A1A1A;
  --line: #000000; --line-2: #000000;
  --sky: #000000; --blue: #000000; --violet: #000000; --teal: #000000;
  --mint: #00552F; --amber: #6B3200; --coral: #8B0014; --rose: #8B0014;

  --e1: none; --e2: none; --e3: none; --e4: none;
}

/* ── Light background ────────────────────────────────────────────────────
   Not the same thing as high contrast: warm paper, flat, no glare, brand
   intact. Every accent is darkened, though — the marketing palette is tuned
   for a near-black page, and #6EE7B7 mint on paper is decoration, not text. */
html[data-a11y-display="light"] {
  color-scheme: light;
  --a11y-ink: #1A1A17; --a11y-paper: #FFFDF8;

  --surface: #FFFDF8; --surface-dim: #FFFDF8;
  --surface-c-lowest: #FFFFFF; --surface-c-low: #FFFDF8;
  --surface-c: #FBF7EF; --surface-c-high: #F6F1E6; --surface-c-highest: #F1EADC;
  --on-surface: #1A1A17; --on-surface-var: #3E3E37;
  --outline: #8A8375; --outline-var: #C9C2B4;

  --ink: #FFFDF8; --ink-2: #FBF7EF; --ink-3: #F1EADC;
  --s-0: #FFFDF8; --s-1: #FBF7EF; --s-2: #FFFFFF;
  --s-3: #F6F1E6; --s-4: #F1EADC; --s-5: #8A8375;
  --fg: #1A1A17; --fg-2: #3E3E37; --fg-3: #55554B;
  --line: #C9C2B4; --line-2: #8A8375;
  --sky: #04528C; --blue: #04528C; --violet: #5B33C6; --teal: #00707C;
  --mint: #0A6B48; --amber: #8A4B00; --coral: #B3172E; --rose: #A0124F;

  --e1: none; --e2: none; --e3: none; --e4: none;
}

/* ── Negative contrast: light on dark ────────────────────────────────────
   The marketing site is already dark, which is why this mode looked like it
   did nothing there. What it has to change on that page is not the
   background — it is the dimming. --fg-2 and --fg-3 are white at 68% and
   44%, and translucent grey text is the exact thing a reader turns this mode
   on to escape. Everything goes to full-strength ink on true black. */
html[data-a11y-display="negative"] {
  color-scheme: dark;
  --a11y-ink: #FFFFFF; --a11y-paper: #000000;

  --brand: #FFE14D; --brand-2: #FFE14D; --brand-dark: #FFE14D;
  --primary: #FFE14D; --on-primary: #000000;
  --primary-container: #3A3200; --on-primary-container: #FFF4B0;
  --secondary: #9FD2FF; --secondary-container: #10304A;
  --surface: #000000; --surface-dim: #000000;
  --surface-c-lowest: #000000; --surface-c-low: #000000;
  --surface-c: #0A0E14; --surface-c-high: #141A22; --surface-c-highest: #1C242E;
  --on-surface: #FFFFFF; --on-surface-var: #FFFFFF;
  --outline: #FFFFFF; --outline-var: #6E7A88;
  --success: #6BE3A6; --success-c: #06301D;
  --warning: #FFC46B; --warning-c: #3A2405;
  --danger: #FF9AA6; --danger-c: #3E0710;
  --info: #9FD2FF; --info-c: #10304A;

  --ink: #000000; --ink-2: #000000; --ink-3: #0A0E14;
  --s-0: #000000; --s-1: #000000; --s-2: #0A0E14;
  --s-3: #141A22; --s-4: #1C242E; --s-5: #FFFFFF;
  --fg: #FFFFFF; --fg-2: #FFFFFF; --fg-3: #FFFFFF;
  --line: rgba(255,255,255,.42); --line-2: rgba(255,255,255,.68);
  --sky: #7FD0FF; --blue: #9FD2FF; --violet: #D7BEFF; --teal: #6EE6F0;
  --mint: #7DF3BE; --amber: #FFC46B; --coral: #FFA8B4; --rose: #FFA8C8;

  --e1: none; --e2: none; --e3: none; --e4: none;
}

/* ════════════════════════════════════════════════════════════════════════
   THE SWEEP

   Tokens cover what the stylesheets tokenise. These three also hardcode:
   rgba(255,255,255,.08) card washes, color:#fff on buttons, and four
   gradient-clipped headings that are color:transparent and would vanish
   completely on paper. The sweep is deliberately blunt — one ink, one paper —
   because that is what these modes ARE, and a half-swept page is exactly
   where the unreadable pairs come from.

   Everything here excludes .a11y-root. The menu has to stay legible while
   the reader is halfway through a mode they have just discovered they cannot
   read, so it is never themed by the thing it controls.
   ════════════════════════════════════════════════════════════════════════ */

html:is([data-a11y-display="contrast"],[data-a11y-display="light"],[data-a11y-display="negative"]) body {
  background: var(--a11y-paper) !important;
  color: var(--a11y-ink) !important;
}

/* Text. -webkit-text-fill-color is what actually undoes background-clip:text;
   plain `color` is ignored while a clip is in force, which is how .grad,
   .hero h1 em, .bignum .n and .nf-code would otherwise stay invisible. */
html:is([data-a11y-display="contrast"],[data-a11y-display="light"],[data-a11y-display="negative"]) body
  :where(p,li,h1,h2,h3,h4,h5,h6,span,strong,em,b,i,small,dt,dd,td,th,caption,label,legend,
         figcaption,blockquote,summary,a,.lede,.label,.grad,.eyebrow,.sub,.title,.headline,
         .display,.mono,.n):not(.a11y-root *) {
  color: var(--a11y-ink) !important;
  -webkit-text-fill-color: var(--a11y-ink) !important;
  background-image: none !important;
  text-shadow: none !important;
}

/* Containers: drop the washes, keep the edges. */
html:is([data-a11y-display="contrast"],[data-a11y-display="light"],[data-a11y-display="negative"]) body
  :where(section,div,article,header,footer,main,aside,nav,ul,ol,dl,figure,form,table,thead,
         tbody,tr,td,th,details,fieldset):not(.a11y-root):not(.a11y-root *) {
  background-color: transparent !important;
  background-image: none !important;
  box-shadow: none !important;
  border-color: var(--line, var(--outline)) !important;
}

/* Controls keep a real, visible edge — "subtle border" is the first thing to
   disappear for the reader who turned this on. */
html:is([data-a11y-display="contrast"],[data-a11y-display="light"],[data-a11y-display="negative"]) body
  :where(button,.b,input,select,textarea,.chip,.pill,.tab,.card):not(.a11y-root *) {
  background: var(--a11y-paper) !important;
  background-image: none !important;
  color: var(--a11y-ink) !important;
  -webkit-text-fill-color: var(--a11y-ink) !important;
  border: 1px solid var(--a11y-ink) !important;
  box-shadow: none !important;
}

/* Decoration that is only decoration. The blurred colour mesh under the
   marketing copy costs contrast in every one of these modes, negative
   included, so it goes in all three rather than only the light ones. */
html:is([data-a11y-display="contrast"],[data-a11y-display="light"],[data-a11y-display="negative"])
  :where(.mesh,.grain) { display: none !important }

html[data-a11y-display] :where(a,button):focus-visible {
  outline: 3px solid var(--a11y-ink, #000) !important; outline-offset: 2px !important;
}

/* ── Grayscale ───────────────────────────────────────────────────────────
   An overlay, not a filter on an ancestor: backdrop-filter desaturates
   everything painted beneath it and is a containing block for nothing, so
   the rail, the modals and this menu all stay anchored to the viewport.
   .a11y-root sits above it on z-index and therefore stays visible AND
   clickable, which is the only reason this mode has a way out. */
html[data-a11y-display="grayscale"] body::after {
  content: ''; position: fixed; inset: 0; z-index: 2147482000; pointer-events: none;
  -webkit-backdrop-filter: grayscale(1); backdrop-filter: grayscale(1);
}

/* ── Read aloud ──────────────────────────────────────────────────────────
   Marks what is about to be spoken. Hover-driven, so links and buttons keep
   working normally while it is on. */
html[data-a11y-read="on"] body
  :where(p,li,h1,h2,h3,h4,h5,h6,td,th,blockquote,figcaption,label,summary,dd,dt,a,button):not(.a11y-root *):hover {
  outline: 2px dashed currentColor !important; outline-offset: 3px;
  cursor: help;
}

/* ════════════════════════════════════════════════════════════════════════
   The menu itself. Fixed ink, fixed paper, never themed by the tokens above.
   ════════════════════════════════════════════════════════════════════════ */
.a11y-root { position: fixed; right: 18px; bottom: 18px; z-index: 2147483000; }
@media (max-width: 900px) { .a11y-root { bottom: 84px } }

.a11y-open {
  width: 46px; height: 46px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center;
  background: #0B1220; color: #FFFFFF; border: 2px solid #FFFFFF;
  box-shadow: 0 4px 18px rgba(0,0,0,.34);
}
.a11y-open:hover { background: #16233A }
.a11y-open.on { background: #1B5E20; }
.a11y-open:focus-visible { outline: 3px solid #FFD400; outline-offset: 2px }

.a11y-panel {
  position: absolute; right: 0; bottom: 58px; width: 264px;
  background: #FFFFFF; color: #0B1220;
  border: 2px solid #0B1220; border-radius: 14px; padding: 8px;
  box-shadow: 0 10px 40px rgba(0,0,0,.32);
  font: 500 14px/1.35 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  max-height: min(78vh, 560px); overflow-y: auto;
}
.a11y-head { display: flex; align-items: center; gap: 8px; padding: 4px 6px 8px }
.a11y-head h2 { margin: 0; font-size: 15px; font-weight: 700; flex: 1 }
.a11y-close {
  width: 30px; height: 30px; border-radius: 8px; border: 0; background: none;
  color: #0B1220; cursor: pointer; display: grid; place-items: center;
}
.a11y-close:hover { background: #E9EDF3 }

.a11y-item {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border: 0; border-radius: 9px; background: none;
  color: #0B1220; font: inherit; text-align: left; cursor: pointer;
}
.a11y-item span { flex: 1 }
.a11y-item i { font-style: normal; font-size: 12.5px; opacity: .7; font-variant-numeric: tabular-nums }
.a11y-item:hover:not([disabled]) { background: #E9EDF3 }
.a11y-item[aria-pressed="true"] { background: #0B1220; color: #FFFFFF }
.a11y-item[disabled] { opacity: .42; cursor: default }
.a11y-item:focus-visible { outline: 3px solid #FFD400; outline-offset: -2px }
.a11y-sep { border: 0; border-top: 1px solid #D7DDE6; margin: 6px 4px }

@media print { .a11y-root { display: none } }
@media (prefers-reduced-motion: reduce) { .a11y-open, .a11y-item { transition: none !important } }
