/* twoplus11.com — accessibility options
   ─────────────────────────────────────────────────────────────────────────
   Loaded by every page on the origin: the root site, the twoplus11-admin form
   pages, and all twenty-two app sites. Those are ~110 hand-written pages with
   their own inline stylesheets, so nothing here may depend on a page's own
   class names. It leans instead on the two things every page does share:

     • the design-system tokens — --bg/--bg2/--card, --t1…--t4, --sep — which
       every app site declares in :root, and which the root site declares under
       the same names for text (--t1…--t4) and its own for borders (--b0…--b2);
     • semantic elements — <nav>, :focus-visible.

   The three settings match what claytonia.twoplus11.com and Midwest Feline
   offer, minus dark mode: these pages have only ever had one theme.

   Classes land on <html> (a11y.js sets them before first paint, so a setting
   restored from a previous visit never flashes off). */

/* ── Larger text ───────────────────────────────────────────────────────────
   The root site sizes in rem, but the app sites size in px, so raising the
   root font-size would move ten pages and leave ninety-four unchanged. zoom
   is the one lever that scales both, and unlike transform it reflows, so
   percentage-width layouts keep fitting the viewport exactly.

   The nav is deliberately left out of it. zoom does not move media queries:
   a page zoomed to 1.15 still answers a max-width query with the real
   viewport width, so it renders into 87% of the space while the layout it
   picked assumed 100%. Fluid content absorbs that — a max-width wrapper is a
   percentage of whatever it is given. A nav bar cannot: it is a fixed row of
   items sized to fit the breakpoint it just matched, and on the app sites
   that row clears its own 1100px breakpoint by about thirty pixels. Zooming
   it there is a horizontal scrollbar on every app page, so the bar keeps its
   size and everything below it grows.

   font-size is the fallback for browsers without zoom (Firefox before 126).
   The two must never both apply — 1.15 × 1.14 is a different, much larger
   site — so @supports hands off from one to the other. */
html.a11y-text { font-size: 114%; }

@supports (zoom: 1.15) {
  html.a11y-text { font-size: 100%; }
  /* The scrim sizes itself against the viewport and the floating button is
     pinned to it, so neither may sit in a zoomed coordinate space. */
  html.a11y-text body > *:not(nav):not(.a11y-scrim):not(.a11y-btn) { zoom: 1.15; }
}

/* ── Higher contrast ───────────────────────────────────────────────────────
   The text ramp is built to fade back: --t3 and --t4 are the 6:1 and 4.6:1
   steps used for labels, meta and legal microtext. They pass AA as shipped,
   but AA is a floor, so this lifts the whole ramp to white and near-white and
   brings the hairline separators up with it — otherwise the boxes would
   disappear against the ink they now hold. */
html.a11y-contrast {
  --t2: #FFFFFF;
  --t3: rgba(255, 255, 255, 0.94);
  --t4: rgba(255, 255, 255, 0.90);
  --sep: rgba(255, 255, 255, 0.40);
  /* The root site's own border ramp. Absent on app sites, where declaring
     them is inert rather than wrong. */
  --b0: rgba(255, 255, 255, 0.24);
  --b1: rgba(255, 255, 255, 0.38);
  --b2: rgba(255, 255, 255, 0.55);
}

/* Every nav on the origin is a translucent blur over whatever is scrolling
   beneath it, which is the one place text sits on an unknowable background.
   Contrast mode makes it opaque — var(--bg) is the page's own base colour on
   every site, so this stays on-palette. */
html.a11y-contrast nav {
  background: var(--bg, #0A0A0C) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.a11y-contrast :focus-visible {
  outline: 3px solid #FFFFFF !important;
  outline-offset: 2px !important;
}

/* ── Reduce motion ─────────────────────────────────────────────────────────
   Kept, rather than zeroed, so a transition that a script waits on still
   fires its transitionend. Scripted motion is handled in a11y.js instead —
   it makes matchMedia('(prefers-reduced-motion: reduce)') answer yes, which
   is the check the animated pages already run. */
html.a11y-motion *,
html.a11y-motion *::before,
html.a11y-motion *::after {
  animation-duration: 0.001ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  transition-delay: 0s !important;
}

html.a11y-motion,
html.a11y-motion body {
  scroll-behavior: auto !important;
}

/* ── The nav button ────────────────────────────────────────────────────────
   Sized to sit inside a 56px (app sites) or 60px (root) nav bar without
   changing its height. */
.a11y-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  margin-left: 8px;
  padding: 5px 9px;
  border: 1px solid var(--sep, rgba(255, 255, 255, 0.14));
  border-radius: 8px;
  background: transparent;
  color: var(--t2, rgba(255, 255, 255, 0.78));
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.a11y-btn:hover {
  color: var(--t1, #fff);
  border-color: var(--t4, rgba(255, 255, 255, 0.4));
  background: rgba(255, 255, 255, 0.06);
}
.a11y-btn svg { display: block; flex-shrink: 0; }

/* The form pages lay their bar out with space-between and exactly two items,
   so a third would be dealt into the middle. Pinning the second one right
   leaves no free space to deal. a11y.js marks the row it joined. */
.nav-i.a11y-nav-hosted > .nav-back { margin-left: auto; }

/* An app site's home bar carries eight links and a download button, and at
   its own 1100px breakpoint the row ends about thirty pixels short of the
   edge — less than this button needs. So inside that bar the button goes
   icon-only, and the rest comes out of the link row's 24px gap. Six pixels
   across seven gaps is more than the button costs, and it only applies to a
   row this button actually joined. */
.nav-right .a11y-btn__label { display: none; }
.nav-right.a11y-nav-hosted > .nav-links { gap: 18px; }

/* Bars that set their own flex gap space the button for us; the margin is
   only there for the two that do not. Eight pixels is the difference between
   "← Back to Home" holding one line on a 360px phone and wrapping to two. */
nav.a11y-nav-hosted > .a11y-btn,
.nav__i.a11y-nav-hosted > .a11y-btn { margin-left: 0; }

/* An app site's inner pages have no .nav-right, so the button joins the bar
   itself — which is how a11y.js marks it, and how this tells the two apart.
   That bar already carries a twoplus11 link, a logo and a back link, and at
   phone widths the button costs it the few pixels that kept "← Back to Home"
   on one line. The bar is already down to 16px of side padding by then, so
   the room comes mostly out of its 20px gaps. */
@media (max-width: 480px) {
  nav.a11y-nav-hosted { gap: 12px; padding-left: 12px; padding-right: 12px; }
}

/* On: the button reports the state of the page, so someone who left a setting
   on last visit can see that at a glance. The accent carries the border and
   the icon, never text on a fill — several fleet accents are under 4.5:1 with
   white ink, and a chip nobody can read is a poor way to announce this. */
.a11y-btn[aria-pressed="true"] {
  color: var(--t1, #fff);
  border-color: var(--acc, var(--blue, #0A84FF));
  background: rgba(255, 255, 255, 0.07);
}
.a11y-btn[aria-pressed="true"] svg { color: var(--acc, var(--blue, #0A84FF)); }

/* The label is the first thing to go when the bar gets tight — the icon and
   the accessible name carry it from there. 800px is where the root site drops
   its link row for the burger. */
@media (max-width: 800px) {
  .a11y-btn__label { display: none; }

  /* Below that the link row is display:none, so the button is the only thing
     between the wordmark and the burger. Moving the auto margin from the
     burger onto the button carries the pair to the right together, instead of
     leaving one at each end. */
  .nav__i.a11y-nav-hosted > .a11y-btn { margin-left: auto; }
  .nav__i.a11y-nav-hosted > .nav__burger { margin-left: 0; }
}

/* Four pages — the vs-<competitor> comparison pages — have no nav at all.
   There the button floats instead, clear of the footer. */
.a11y-btn--float {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 200;
  margin-left: 0;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--card, var(--bg2, #1C1C1E));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}

/* ── The dialog ────────────────────────────────────────────────────────────
   Solid, not translucent: it is the one surface that has to stay readable
   while high contrast is being turned on and off underneath it. */
.a11y-scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.62);
}
.a11y-scrim[hidden] { display: none; }

.a11y-dialog {
  width: 100%;
  max-width: 400px;
  padding: 22px;
  border: 1px solid var(--sep, rgba(255, 255, 255, 0.14));
  border-radius: 16px;
  background: var(--card, var(--bg2, #1C1C1E));
  color: var(--t1, #fff);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6);
  font-family: inherit;
}

.a11y-dialog__title {
  margin: 0 0 4px;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--t1, #fff);
}
.a11y-dialog__lede {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--t3, rgba(255, 255, 255, 0.58));
}

.a11y-opt {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 10px;
  padding: 13px 14px;
  border: 1px solid var(--sep, rgba(255, 255, 255, 0.14));
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--t1, #fff);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.a11y-opt:hover { background: rgba(255, 255, 255, 0.07); }
.a11y-opt[aria-pressed="true"] {
  border-color: var(--acc, var(--blue, #0A84FF));
  background: rgba(255, 255, 255, 0.07);
}

.a11y-opt__text { flex: 1; min-width: 0; }
.a11y-opt__name {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--t1, #fff);
}
.a11y-opt__desc {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--t3, rgba(255, 255, 255, 0.58));
}

/* A switch rather than a checkmark: it reads as on/off even with the label
   hidden by a screen reader's own presentation. */
.a11y-opt__switch {
  position: relative;
  flex-shrink: 0;
  width: 40px;
  height: 23px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid var(--sep, rgba(255, 255, 255, 0.18));
  transition: background 0.15s;
}
.a11y-opt__switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.15s;
}
.a11y-opt[aria-pressed="true"] .a11y-opt__switch {
  background: var(--acc, var(--blue, #0A84FF));
  border-color: var(--acc, var(--blue, #0A84FF));
}
.a11y-opt[aria-pressed="true"] .a11y-opt__switch::after { transform: translateX(17px); }

.a11y-dialog__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--sep, rgba(255, 255, 255, 0.14));
}

.a11y-reset {
  padding: 8px 0;
  border: none;
  background: none;
  color: var(--t3, rgba(255, 255, 255, 0.58));
  font: inherit;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}
.a11y-reset:hover { color: var(--t1, #fff); }
.a11y-reset[disabled] { opacity: 0.45; cursor: default; text-decoration: none; }

/* White on the accent is under 4.5:1 for several of the fleet accents, so the
   one filled button on the sheet takes the page's own text colour on a
   neutral fill instead. */
.a11y-done {
  padding: 10px 22px;
  border: 1px solid var(--t4, rgba(255, 255, 255, 0.4));
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.10);
  color: var(--t1, #fff);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.a11y-done:hover { background: rgba(255, 255, 255, 0.18); }

/* The sheet is about 480px tall, so only a short window needs it to scroll —
   and it must not be a scroll container the rest of the time. On a Mac set to
   always show scrollbars, Chrome reserves the track the moment overflow is
   `auto`, which paints a bar down the side of a sheet with nothing to scroll. */
@media (max-height: 620px) {
  .a11y-dialog { max-height: calc(100dvh - 40px); overflow-y: auto; }
}

@media (max-height: 560px) {
  .a11y-dialog { padding: 16px; }
  .a11y-opt__desc { display: none; }
}
