/* The accessibility toolkit for the applicant pages (/apply, /interview).

   It is the same toolkit the public websites carry — fiducia-situs/a11y.go,
   itself a rebuild of the apps' AccessibilityToolkit — control for control and
   label for label, so somebody who set their reading up on the organisation's
   website meets the same sheet when they land here to apply. The settings, the
   cookie and the profiles are shared with it; what differs is only how a change
   is applied, and that difference is in a11y.js rather than here.

   The colours come from pages.css's tokens rather than from a palette of their
   own, so the sheet is this page's design rather than a widget bolted onto it,
   and it follows the page into dark mode without a single extra rule.

   Load order matters: this file comes after pages.css and overrides its root
   font-size, so a <link> for it must stay second. */

/* ── the overlay: what a setting does to the page ─────────────────────────── */

/* 112.5% is pages.css's own base — an 18px root, chosen because these pages are
   read on phones by people we owe large text to. The text-size setting scales
   that rather than replacing it, so 100% here is still the larger base. */
html { font-size: calc(112.5% * var(--a11y-scale, 1)); }

/* 1.55 is pages.css's authored line-height; the setting scales it. */
body.a11y-lineheight { line-height: var(--a11y-lh, 1.55); }
body.a11y-spacing {
  letter-spacing: calc(var(--a11y-sp, 1) * 0.06em);
  word-spacing: calc(var(--a11y-sp, 1) * 0.18em);
}

body.a11y-dysfont {
  font-family: Verdana, Tahoma, "Segoe UI", sans-serif;
  letter-spacing: 0.05em;
  word-spacing: 0.12em;
}
body.a11y-dysfont :is(p, li, .hint) { max-width: 62ch; }

/* Bionic reading emboldens the leading letters in the markup (a11y.js); all
   that is left for CSS is the extra word spacing the setting promises, which is
   what stops a page of part-bold words closing up into a single texture. */
body.a11y-bionic main :is(p, li) { word-spacing: 0.16em; }

body.a11y-links main :is(a, button) {
  text-decoration: underline;
  font-weight: 700;
  outline: 2px solid currentColor;
  outline-offset: 2px;
}
body.a11y-headings main :is(h1, h2, h3, legend) {
  text-decoration: underline;
  font-weight: 800;
}
/* Stop animations — and the Vision and Autism profiles, which include it —
   need no rule of their own: motion on these pages is opt-in. A transition or
   animation is written under `body:not(.a11y-stopmotion, .a11y-vision,
   .a11y-autism)`, as the switch's is below, so there is never one to undo. */

/* The pointer is a served file rather than a data: URI because these pages'
   CSP is img-src 'self' — and a cursor is an image as far as CSP is concerned.
   Relaxing the policy for the sake of one arrow would be the wrong trade. */
body:is(.a11y-cursor, .a11y-vision),
body:is(.a11y-cursor, .a11y-vision) * {
  cursor: url("/recruitment-pages/cursor.svg") 4 2, auto;
}

/* The colour filters are applied to <main> rather than to the body. A filter
   makes an element the containing block for its fixed-position descendants, so
   filtering the body would detach the accessibility button from the viewport
   and strand it at the foot of the document — in the one mode where somebody is
   most likely to want to reach it again. It also leaves the control that turns
   inversion off un-inverted. */
/* The filtered region paints the page background rather than inheriting a
   transparent one, and that is what makes Invert usable rather than dangerous.
   A filter only acts on the pixels the element itself paints: with a
   transparent <main>, the body's background stayed as it was while the text on
   top of it flipped — which in dark mode meant near-black headings on a
   near-black page. Painting the background into the filtered element flips
   both together. The full height keeps a short page (an expired link, a
   thank-you) from ending in a hard band halfway down the screen. */
body:is(.a11y-greyscale, .a11y-invert, .a11y-autism) > main {
  background: var(--bg);
  min-height: 100vh;
  filter: var(--a11y-filter);
}
/* In this order deliberately: a colour the applicant picked outranks the
   softening a profile applies for them. */
body.a11y-autism { --a11y-filter: saturate(0.75); }
body.a11y-greyscale { --a11y-filter: grayscale(1); }
body.a11y-invert { --a11y-filter: invert(1) hue-rotate(180deg); }
body.a11y-invert :is(img, video) { filter: invert(1) hue-rotate(180deg); }

/* High contrast repaints the tokens on the BODY, not on :root — pages.css sets
   its dark palette in a prefers-color-scheme block on :root, and a value
   declared on the body wins for everything inside it whichever scheme the
   device is in. */
body:is(.a11y-contrast, .a11y-vision) {
  --bg: #ffffff;
  --card: #ffffff;
  --ink: #000000;
  --muted: #1a1a1a;
  --line: #000000;
  --accent: #00003c;
  --accent-ink: #ffffff;
  --focus: #b45309;
  --notice-bg: #ffffff;
  --error-bg: #ffffff;
  --error-ink: #8a1c1c;
  --ok-bg: #ffffff;
  --ok-ink: #14532d;
}
/* Every border in these pages is the one thing separating a card, a field or a
   chosen slot from the page behind it. At 1px black-on-white that edge is
   there but thin; this mode exists for people for whom thin is not there. */
body:is(.a11y-contrast, .a11y-vision) :is(.card, .notice, .row, .slot span, input, select, textarea) {
  border-width: 2px;
  box-shadow: none;
}
body:is(.a11y-contrast, .a11y-vision) main a { color: #00003c; text-decoration: underline; }
body:is(.a11y-contrast, .a11y-vision) main button { border: 2px solid #000000; }

/* ── the profiles ─────────────────────────────────────────────────────────── */
/* One-tap set-ups, the apps' own five. Each is the whole reading change rather
   than a colour scheme: size, measure, motion and emphasis together. */

body.a11y-vision { line-height: 1.85; }
body.a11y-vision main :is(a, button) { text-decoration: underline; font-weight: 700; }
body.a11y-vision :is(h1, h2, h3, legend) { text-decoration: underline; font-weight: 800; }
body.a11y-vision :is(p, li) { max-width: 58ch; }

body.a11y-dyslexia {
  font-family: Verdana, Tahoma, "Segoe UI", sans-serif;
  letter-spacing: 0.05em;
  word-spacing: 0.12em;
  line-height: 1.9;
  font-size: 1.08em;
}
body.a11y-dyslexia :is(p, li) { max-width: 62ch; }

body.a11y-adhd { font-size: 1.05em; line-height: 1.85; }
body.a11y-adhd :is(p, li) { max-width: 60ch; }

body.a11y-motor { font-size: 1.18em; }
body:is(.a11y-motor, .a11y-vision) :is(button, .a11y-chip, .a11y-launcher, .slot span) {
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}

/* ── the toolkit's own chrome ─────────────────────────────────────────────── */

/* Every operable edge in here is --a11y-edge rather than --line: a chip and a
   switch are only distinguishable from the panel by their outline, and the
   page's hairline is drawn for cards, not for controls. It is declared on these
   two roots rather than up at :root because high contrast and low vision
   repaint --ink and --bg on the body — a copy computed at :root would keep
   mixing the original colours and drift out of contrast in the one mode that
   exists for contrast. */
.a11y-launcher, .a11y-sheet { --a11y-edge: color-mix(in srgb, var(--ink) 50%, var(--bg)); }

.a11y-launcher {
  position: fixed;
  left: 1rem;
  bottom: 1rem;
  z-index: 70;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.6rem 1.15rem;
  border: 1px solid var(--a11y-edge);
  border-radius: 999px;
  background: var(--card);
  color: var(--accent);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.18);
}
.a11y-launcher:hover { border-color: var(--accent); }

/* The launcher floats over the page's bottom-left corner, where the form's own
   submit button sits. The extra room below the last field is what keeps the
   two from overlapping on a short form. */
main { padding-bottom: 7rem; }

.a11y-sheet svg, .a11y-launcher svg {
  width: 1.3rem;
  height: 1.3rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A <button>, so it is a real "tap past it to close" control rather than a div
   with a click handler — which means pages.css's button rules reach it, and its
   pill radius has to be undone or the scrim is drawn as a giant lozenge. */
.a11y-scrim {
  position: fixed;
  inset: 0;
  z-index: 75;
  border: 0;
  border-radius: 0;
  padding: 0;
  background: rgba(15, 20, 28, 0.55);
  cursor: pointer;
}

.a11y-sheet {
  display: flex;
  flex-direction: column;
  position: fixed;
  z-index: 80;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: min(34rem, 100%);
  max-height: min(92vh, 46rem);
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -6px 40px rgba(0, 0, 0, 0.35);
}
.a11y-sheet[hidden], .a11y-scrim[hidden] { display: none; }

.a11y-head { padding: 0.55rem 1.15rem 0.5rem; border-bottom: 1px solid var(--line); }
.a11y-grab {
  display: block;
  width: 2.5rem;
  height: 0.25rem;
  margin: 0 auto 0.55rem;
  border-radius: 999px;
  background: var(--line);
}
.a11y-titlerow { display: flex; align-items: center; gap: 0.6rem; }
.a11y-titlerow h2 { flex: 1; margin: 0; font-size: 1.25rem; letter-spacing: -0.01em; }
.a11y-done {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 0.6rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}

.a11y-body { overflow-y: auto; overscroll-behavior: contain; padding: 0.9rem 1.15rem 1.1rem; }
.a11y-label {
  margin: 0.2rem 0 0.55rem;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.a11y-rule { border: 0; border-top: 1px solid var(--line); margin: 1.1rem 0; }

.a11y-row { display: flex; align-items: center; gap: 0.75rem; min-height: 44px; padding: 0.15rem 0; }
.a11y-row > svg { color: var(--muted); }
.a11y-name { flex: 1 1 7rem; min-width: 0; font-weight: 400; margin: 0; }
.a11y-hint { display: block; font-size: 0.8rem; line-height: 1.35; color: var(--muted); }
.a11y-value {
  flex: none;
  min-width: 3.6rem;
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.a11y-slider { flex: 2 1 7rem; min-width: 5rem; min-height: 44px; width: auto; accent-color: var(--accent); }

.a11y-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0 0.5rem;
  border: 1px solid var(--a11y-edge);
  border-radius: 999px;
  background: var(--card);
  color: var(--accent);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}
.a11y-step:hover:not(:disabled) { border-color: var(--accent); }
.a11y-step:disabled { opacity: 0.55; cursor: not-allowed; }

/* The knob is drawn as two stacked circles — white, on a ring of the edge
   colour. Without the ring, a white knob on the pale off-track is about 1.7:1,
   and the knob's position is the whole of what tells you the switch is off. */
.a11y-switch input {
  flex: none;
  appearance: none;
  -webkit-appearance: none;
  width: 3.1rem;
  height: 1.8rem;
  margin: 0;
  border: 1px solid var(--a11y-edge);
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--ink) 22%, var(--bg));
  background-image:
    radial-gradient(circle, #fff 0 42%, transparent 43%),
    radial-gradient(circle, var(--a11y-edge) 0 48%, transparent 49%);
  background-size: 1.4rem 1.4rem;
  background-position: 0.2rem center;
  background-repeat: no-repeat;
  cursor: pointer;
}
body:not(.a11y-stopmotion, .a11y-vision, .a11y-autism) .a11y-switch input {
  transition: background-color 0.15s, background-position 0.15s;
}
.a11y-switch input:checked {
  background-color: var(--accent);
  border-color: var(--accent);
  background-position: calc(100% - 0.2rem) center;
}

.a11y-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.a11y-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.5rem;
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--a11y-edge);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
}
.a11y-chip svg { width: 1.05rem; height: 1.05rem; }
button.a11y-chip:hover { border-color: var(--accent); }
.a11y-chip.on, .a11y-radio input:checked + .a11y-chip {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}
/* The radio is laid invisibly over its chip, so the whole chip is the target. */
.a11y-radio { display: inline-flex; position: relative; }
.a11y-radio input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.a11y-radio input:focus-visible + .a11y-chip { outline: 3px solid var(--focus); outline-offset: 3px; }

/* Not pinned, unlike the websites' sheet. Theirs has to keep an Apply button
   within reach because a change there is a navigation; here every control acts
   as it is touched, so the only thing at the foot of the list is the reset —
   and the Default profile at the top of the sheet already is one. A bar pinned
   over the scrolling controls to hold a single link reads as a rendering fault. */
.a11y-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.1rem;
  padding: 0.75rem 0;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.a11y-reset {
  border: 0;
  padding: 0.45rem 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.9rem;
  text-decoration: underline;
  cursor: pointer;
}
.a11y-note { margin: 0.75rem 0 0; font-size: 0.8rem; color: var(--muted); }

/* High contrast paints the sheet itself too — it is on the page, and a toolkit
   that stays mid-grey while everything behind it goes black and white is the
   one control the mode has failed. */
body:is(.a11y-contrast, .a11y-vision) :is(.a11y-sheet, .a11y-launcher, .a11y-chip, .a11y-step) {
  background: #ffffff;
  color: #000000;
  border-color: #000000;
}
body:is(.a11y-contrast, .a11y-vision) .a11y-switch input { border-color: #000000; }
body:is(.a11y-contrast, .a11y-vision) :is(.a11y-chip.on, .a11y-radio input:checked + .a11y-chip) {
  background: #00003c;
  color: #ffffff;
  border-color: #00003c;
}
body:is(.a11y-contrast, .a11y-vision) .a11y-switch input:checked {
  background-color: #00003c;
  border-color: #00003c;
}
body:is(.a11y-contrast, .a11y-vision) :is(.a11y-label, .a11y-hint, .a11y-note, .a11y-reset, .a11y-done, .a11y-row > svg) {
  color: #000000;
}

@media print {
  .a11y-launcher, .a11y-sheet, .a11y-scrim { display: none; }
}
