.csl-accessibility-menu {
  position: fixed;
  /* Lifted clear of the selection bar while it is up (0 otherwise), so the bar can never sit
     on top of the one control that must always be reachable. The bar publishes its occupied
     height as --csl-selection-bar-h from csl.js.

     Lifted through `bottom`, and every rule below that sets `bottom` carries the same term.
     From 1.65.0 to 1.138.1 this was a transform instead, chosen so the phone rule's reset of
     `bottom` could not drop the lift. A transform - even translateY(0) - makes this element the
     containing block for its fixed-position child, and on phones the panel IS fixed-position:
     it rendered 42px wide inside the button, a sliver reading "Di", on every portal page, for a
     month. No transform on this element, ever. */
  bottom: calc(20px + var(--csl-selection-bar-h, 0px));
  left: 20px;
  z-index: 99990;
  color: #0e2329;
  font-family: Optima, "Optima nova", Candara, "Gill Sans", "Gill Sans MT", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.45;
}

.csl-accessibility-menu summary {
  min-height: var(--csl-control-height, var(--qv-control-height, 42px));
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 13px;
  color: #fff;
  background: #16333b;
  border: 2px solid #16333b;
  border-radius: 5px;
  box-shadow: 0 4px 14px rgba(14,35,41,.16);
  cursor: pointer;
  font-weight: 700;
  list-style: none;
}

.csl-accessibility-menu summary::-webkit-details-marker { display: none; }
.csl-accessibility-menu summary:hover { background: #214750; border-color: #214750; }
.csl-accessibility-menu summary:focus-visible { outline: 3px solid #d7a54a; outline-offset: 3px; }
.csl-accessibility-menu summary > span:first-child { font-family: Georgia, "Times New Roman", serif; }

.csl-accessibility-panel {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: 340px;
  max-width: calc(100vw - 28px);
  max-height: calc(100vh - 90px);
  overflow-y: auto;
  box-sizing: border-box;
  padding: 20px;
  background: #fff;
  border: 1px solid #cbd3d3;
  border-top: 4px solid #d7a54a;
  border-radius: 6px 6px 0 0;
  box-shadow: 0 18px 42px rgba(14,35,41,.2);
}

.csl-accessibility-title { margin: 0; color: #0e2329; font-size: 18px; font-weight: 800; }
.csl-accessibility-intro { margin: 4px 0 18px; color: #4a5a5d; font-size: 13px; }
.csl-accessibility-size { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: center; padding-bottom: 16px; border-bottom: 1px solid #cbd3d3; }
.csl-accessibility-size > span { display: inline-grid; grid-template-columns: repeat(3, 42px); gap: 4px; padding: 3px; background: #f1eee6; border-radius: 5px; }
.csl-accessibility-size button { min-height: var(--csl-control-height, var(--qv-control-height, 42px)); padding: 6px; color: #0e2329; background: transparent; border: 1px solid transparent; border-radius: 3px; cursor: pointer; font: inherit; }
.csl-accessibility-size button:hover { border-color: #16333b; }
.csl-accessibility-size button[aria-pressed="true"] { color: #fff; background: #16333b; border-color: #16333b; }

.csl-accessibility-toggle { width: 100%; min-height: 0; display: grid; grid-template-columns: 1fr 38px; gap: 12px; align-items: center; padding: 12px 0; color: #0e2329; text-align: left; background: transparent; border: 0; border-bottom: 1px solid #cbd3d3; cursor: pointer; font: inherit; }
.csl-accessibility-toggle strong, .csl-accessibility-toggle small { display: block; }
.csl-accessibility-toggle small { margin-top: 2px; color: #4a5a5d; font-size: 12px; line-height: 1.35; }
.csl-accessibility-toggle i { position: relative; width: 38px; height: 22px; box-sizing: border-box; background: #d9dede; border: 1px solid #aeb9ba; border-radius: 999px; }
.csl-accessibility-toggle i::after { content: ""; position: absolute; top: 3px; left: 3px; width: 14px; height: 14px; background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(14,35,41,.3); transition: transform .16s ease; }
.csl-accessibility-toggle[aria-pressed="true"] i { background: #16333b; border-color: #16333b; }
.csl-accessibility-toggle[aria-pressed="true"] i::after { transform: translateX(16px); }
.csl-accessibility-toggle:focus-visible, .csl-accessibility-size button:focus-visible, .csl-accessibility-reset:focus-visible { outline: 3px solid #d7a54a; outline-offset: 2px; }

.csl-accessibility-reset { min-height: var(--csl-control-height, var(--qv-control-height, 42px)); margin-top: 13px; padding: 4px 0; color: #0e2329; background: transparent; border: 0; cursor: pointer; font: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 4px; }
.csl-accessibility-status { min-height: 1.2em; margin: 9px 0 0; color: #4a5a5d; font-size: 12px; }

/* Larger text.
 *
 * This used to set font-size on the portal containers, which did nothing: every size
 * inside them was a fixed pixel value and inherited nothing. The scale is now one
 * variable that each of those sizes multiplies by, so the control moves real type.
 * It is 1 unless the learner asks otherwise, so the default rendering is unchanged.
 *
 * The panel itself is deliberately left out - it is a fixed-width control, and
 * growing it would push its own buttons off the screen. */
html { --csl-a11y-scale: 1; }
html[data-text-size="large"], body.csl-a11y-large { --csl-a11y-scale: 1.25; }
html[data-text-size="largest"], body.csl-a11y-largest { --csl-a11y-scale: 1.5; }
.csl-accessibility-menu, .csl-accessibility-menu * { --csl-a11y-scale: 1; }

/* Text that never named a size did not respond to this control at all.
 *
 * The scale works by multiplying sizes that are written down - calc(14px * scale) - so every
 * paragraph, heading and label that simply inherited the browser's 16px stayed at 16px however
 * far the control was pushed. Around thirty-five elements across the portal, and the ones a
 * person with low vision most needs: ordinary body copy.
 *
 * Setting a scaled base on each surface fixes all of them at once and cannot double-scale,
 * because every explicit size in this product is an absolute px calc rather than an em or a
 * percentage - checked, not assumed. The menu keeps scale 1 above, so it never grows itself
 * off the screen. */
:where(.csl-dashboard, .csl-tutor-workspace, .csl-login-shell, .csl-single-page,
       .csl-course, .csl-knowledge-check, .csl-certificate-verifier) {
  font-size: calc(16px * var(--csl-a11y-scale, 1));
}

/* Both settings at once. They carry the same weight and reduced colour is written second, so on its
   own it silently replaced high contrast: a reader who needs both was handed the weaker of the two.
   Answering the pair explicitly wins on specificity and gives what both settings ask for at once,
   which is monochrome at maximum separation. */
html[data-contrast="true"][data-reduce-colour="true"] :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) {
  --qv-ink: #000; --qv-petrol: #000; --qv-stone: #fff; --qv-surface: #fff; --qv-slate: #111;
  --qv-line: #000; --qv-gold: #000; --csl-ink: #000; --csl-muted: #111; --csl-line: #000; --csl-soft: #fff;
}
html[data-contrast="true"] :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) { --qv-ink: #000; --qv-petrol: #000; --qv-stone: #fff; --qv-surface: #fff; --qv-slate: #111; --qv-line: #000; --qv-gold: #ffd800; --csl-ink: #000; --csl-muted: #111; --csl-line: #000; --csl-soft: #fff; }
body.csl-a11y-contrast :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) { --qv-ink: #000; --qv-petrol: #000; --qv-stone: #fff; --qv-surface: #fff; --qv-slate: #111; --qv-line: #000; --qv-gold: #ffd800; --csl-ink: #000; --csl-muted: #111; --csl-line: #000; --csl-soft: #fff; }
html[data-contrast="true"] .csl-tutor-workspace,
body.csl-a11y-contrast .csl-tutor-workspace {
  --ink: #000 !important;
  --muted: #111 !important;
  --line: #000 !important;
  --brand: #000 !important;
  --accent: #000 !important;
  --accent-hover: #222 !important;
  --accent-soft: #fff !important;
  --focus: #ffd800 !important;
  color: #000 !important;
}
html[data-contrast="true"] body.csl-lms-portal-page,
body.csl-a11y-contrast.csl-lms-portal-page {
  color: #000 !important;
  background: #fff !important;
}
html[data-contrast="true"] .csl-tutor-workspace :where(
  .csl-tutor-header,
  .csl-tutor-metrics article,
  .csl-tutor-panel,
  .csl-tutor-editor,
  .csl-tutor-filter,
  .csl-tutor-empty,
  .csl-content-owner,
  .csl-tutor-editor aside,
  .csl-knowledge-author,
  .csl-question-author,
  .csl-question-author-body,
  .csl-tutor-scorm,
  .csl-tutor-availability,
  .csl-course-builder,
  .csl-course-sequence > li,
  .csl-course-available > li,
  .csl-course-sequence-empty,
  .csl-course-available-empty,
  .csl-quiz-import,
  .csl-tutor-archived-banner
),
body.csl-a11y-contrast .csl-tutor-workspace :where(
  .csl-tutor-header,
  .csl-tutor-metrics article,
  .csl-tutor-panel,
  .csl-tutor-editor,
  .csl-tutor-filter,
  .csl-tutor-empty,
  .csl-content-owner,
  .csl-tutor-editor aside,
  .csl-knowledge-author,
  .csl-question-author,
  .csl-question-author-body,
  .csl-tutor-scorm,
  .csl-tutor-availability,
  .csl-course-builder,
  .csl-course-sequence > li,
  .csl-course-available > li,
  .csl-course-sequence-empty,
  .csl-course-available-empty,
  .csl-quiz-import,
  .csl-tutor-archived-banner
) {
  color: #000 !important;
  background: #fff !important;
  border-color: #000 !important;
  box-shadow: none !important;
}
html[data-contrast="true"] .csl-tutor-workspace :where(th, .csl-tutor-feedback, .csl-tutor-notice, .csl-tutor-scorm-trust, .csl-tutor-mode-note),
body.csl-a11y-contrast .csl-tutor-workspace :where(th, .csl-tutor-feedback, .csl-tutor-notice, .csl-tutor-scorm-trust, .csl-tutor-mode-note) {
  color: #000 !important;
  background: #fff !important;
  border-color: #000 !important;
}
html[data-contrast="true"] .csl-tutor-workspace :where(p, span, small, th, td, label, legend, summary, h2, h3, h4, strong, b),
body.csl-a11y-contrast .csl-tutor-workspace :where(p, span, small, th, td, label, legend, summary, h2, h3, h4, strong, b) {
  color: #000 !important;
}
/* Supporting text is still text, and high contrast is not "high contrast except the small
   grey bits". Measured at 4.62:1 in this mode - a hair over the ordinary AA floor, in the
   setting somebody chooses precisely because the ordinary floor is not enough for them.
   Every class the product uses for quiet copy, in one place, so a new one is added here
   rather than discovered later at 4.6:1. */
html[data-contrast="true"] :where(.csl-dashboard-muted, .csl-dashboard-kicker, .csl-signed-in-label,
  .csl-signed-in-detail, .csl-field-note, .csl-course-kind, .csl-no-action, .description, small),
body.csl-a11y-contrast :where(.csl-dashboard-muted, .csl-dashboard-kicker, .csl-signed-in-label,
  .csl-signed-in-detail, .csl-field-note, .csl-course-kind, .csl-no-action, .description, small) {
  color: #1a1a1a !important;
}

html[data-contrast="true"] .csl-tutor-workspace :where(a, button),
body.csl-a11y-contrast .csl-tutor-workspace :where(a, button) {
  border-color: #000 !important;
}
html[data-contrast="true"] .csl-tutor-workspace :where(.csl-tutor-header-actions a:not(.secondary), .csl-tutor-panel-head > a, .csl-tutor-filter button, .csl-tutor-editor button[type="submit"], .csl-tutor-scorm button),
body.csl-a11y-contrast .csl-tutor-workspace :where(.csl-tutor-header-actions a:not(.secondary), .csl-tutor-panel-head > a, .csl-tutor-filter button, .csl-tutor-editor button[type="submit"], .csl-tutor-scorm button) {
  color: #fff !important;
  background: #000 !important;
}
html[data-contrast="true"] body.csl-login-document,
body.csl-a11y-contrast.csl-login-document,
html[data-contrast="true"] body.csl-login-document .csl-login-page,
body.csl-a11y-contrast.csl-login-document .csl-login-page,
html[data-contrast="true"] body.csl-login-document .csl-login-shell,
body.csl-a11y-contrast.csl-login-document .csl-login-shell,
html[data-contrast="true"] body.csl-login-document .csl-login-stage { color: #000 !important; background: #fff !important; }
body.csl-a11y-contrast.csl-login-document .csl-login-stage { color: #000 !important; background: #fff !important; }
html[data-contrast="true"] body.csl-login-document .csl-login-context { color: #fff !important; background: #000 !important; }
body.csl-a11y-contrast.csl-login-document .csl-login-context { color: #fff !important; background: #000 !important; }
html[data-contrast="true"] body.csl-login-document .csl-login-context :where(h1, p, span, strong) { color: #fff !important; }
body.csl-a11y-contrast.csl-login-document .csl-login-context :where(h1, p, span, strong) { color: #fff !important; }
html[data-contrast="true"] body.csl-login-document .csl-login-context .csl-dashboard-kicker,
html[data-contrast="true"] body.csl-login-document .csl-login-trust span::before,
body.csl-a11y-contrast.csl-login-document .csl-login-context .csl-dashboard-kicker,
body.csl-a11y-contrast.csl-login-document .csl-login-trust span::before { color: #ffd800 !important; }
html[data-contrast="true"] :where(.csl-login-card, .csl-dashboard > section, .csl-dashboard-card, .csl-course, .csl-knowledge-check, .csl-certificate-verifier) { color: #000 !important; background: #fff !important; border-color: #000 !important; box-shadow: none !important; }
body.csl-a11y-contrast :where(.csl-login-card, .csl-dashboard > section, .csl-dashboard-card, .csl-course, .csl-knowledge-check, .csl-certificate-verifier) { color: #000 !important; background: #fff !important; border-color: #000 !important; box-shadow: none !important; }
html[data-contrast="true"] :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) :where(input, select, textarea) { color: #000 !important; background: #fff !important; border: 2px solid #000 !important; }
body.csl-a11y-contrast :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) :where(input, select, textarea) { color: #000 !important; background: #fff !important; border: 2px solid #000 !important; }
html[data-contrast="true"] :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) :where(a, button):focus-visible { outline-color: #ffd800 !important; outline-width: 4px !important; }
body.csl-a11y-contrast :where(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace) :where(a, button):focus-visible { outline-color: #ffd800 !important; outline-width: 4px !important; }
html[data-reduce-colour="true"],
body.csl-a11y-reduce-colour {
  --qv-ink: #111;
  --qv-petrol: #252525;
  --qv-petrol-2: #3a3a3a;
  --qv-stone: #eee;
  --qv-surface: #fff;
  --qv-slate: #444;
  --qv-line: #999;
  --qv-gold: #d8d8d8;
  --csl-ink: #111;
  --csl-muted: #444;
  --csl-line: #999;
  --csl-soft: #eee;
}
/* Take the colour out of the page, not only out of the pictures.
 *
 * The filter goes on the portal's own containers rather than on <body>: a filter
 * makes its element a containing block, and putting one on the body would strand
 * the fixed-position widgets - and this menu - halfway down the page. */
html[data-reduce-colour="true"] :is(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace, .csl-report-problem, .csl-support-preview-bar, .site-header, .site-footer, .qv-header, .qv-footer),
body.csl-a11y-reduce-colour :is(.csl-login-shell, .csl-dashboard, .csl-single-page, .csl-course, .csl-knowledge-check, .csl-certificate-verifier, .csl-tutor-workspace, .csl-report-problem, .csl-support-preview-bar, .site-header, .site-footer, .qv-header, .qv-footer) { filter: grayscale(1); }
html[data-reduce-colour="true"] :is(.accessibility-menu, .csl-accessibility-menu),
html[data-reduce-colour="true"] :is(.accessibility-menu, .csl-accessibility-menu) *,
body.csl-a11y-reduce-colour :is(.accessibility-menu, .csl-accessibility-menu),
body.csl-a11y-reduce-colour :is(.accessibility-menu, .csl-accessibility-menu) * { filter: none !important; }
html[data-reduce-motion="true"] { scroll-behavior: auto; }
html[data-reduce-motion="true"] *, html[data-reduce-motion="true"] *::before, html[data-reduce-motion="true"] *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
body.csl-a11y-reduce-motion *, body.csl-a11y-reduce-motion *::before, body.csl-a11y-reduce-motion *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }

@media (max-width: 640px) {
  /* Flush to the edge, NOT inset.
     Inset by 14px the 44px button spanned x 14-58, and a phone-width form puts its controls at
     x 41 - so the sign-in "Keep me signed in" checkbox sat under it and a tap opened the
     accessibility panel instead. Shrinking the button was not available: 44x44 is the WCAG 2.5.5
     touch-target minimum, and shrinking the accessibility control below the accessibility minimum
     to stop it covering a checkbox is not a trade worth making. Moving it flush to x 0-44 keeps the
     full target and clears the CENTRE of those controls, which is where a tap actually lands.
     The square left edge is deliberate: a rounded corner against the viewport edge reads as a
     rendering fault. */
  .csl-accessibility-menu { bottom: calc(14px + var(--csl-selection-bar-h, 0px)); left: 0; }
  .csl-accessibility-label { display: none; }
  .csl-accessibility-menu summary { width: 44px; justify-content: center; padding: 8px; border-radius: 0 6px 6px 0; }
  .csl-accessibility-panel { position: fixed; top: 14px; right: 14px; bottom: auto; left: 14px; width: auto; max-width: none; max-height: calc(100vh - 28px); border-radius: 6px; }
  body.admin-bar .csl-accessibility-panel { top: 60px; max-height: calc(100vh - 74px); }
}

@media print {
  .csl-accessibility-menu { display: none !important; }
}
