/* =============================================================================
   Accessibility layer
   -----------------------------------------------------------------------------
   Loads LAST, after Bootstrap, so it can override the theme without !important
   sprawl. Every rule keys off a `data-a11y-*` attribute set on <html> by the
   server, so the first paint is already correct — a class toggled by JavaScript
   after load means the inaccessible render is the one the user sees first.

   v1 shipped one adjustment (the OpenDyslexic font) and only for accounts the
   backend had flagged. Everything here is available to every visitor.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   Fonts
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'OpenDyslexic';
  src: url('../fonts/opendyslexic-regular-webfont.woff2') format('woff2'),
       url('../fonts/opendyslexic-regular-webfont.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/*
  OpenDyslexic weights the bottom of each glyph and makes letterforms
  asymmetric, which reduces the rotation and mirroring that cause b/d/p/q
  confusion. Applied to everything, including headings — a partial swap is
  more disorienting than none.
*/
html[data-a11y-font='dyslexic'],
html[data-a11y-font='dyslexic'] body,
html[data-a11y-font='dyslexic'] h1,
html[data-a11y-font='dyslexic'] h2,
html[data-a11y-font='dyslexic'] h3,
html[data-a11y-font='dyslexic'] h4,
html[data-a11y-font='dyslexic'] h5,
html[data-a11y-font='dyslexic'] h6,
html[data-a11y-font='dyslexic'] p,
html[data-a11y-font='dyslexic'] a,
html[data-a11y-font='dyslexic'] li,
html[data-a11y-font='dyslexic'] span,
html[data-a11y-font='dyslexic'] label,
html[data-a11y-font='dyslexic'] button,
html[data-a11y-font='dyslexic'] input,
html[data-a11y-font='dyslexic'] textarea,
html[data-a11y-font='dyslexic'] select {
  font-family: 'OpenDyslexic', Verdana, sans-serif !important;
}

/*
  A plainer alternative for users who find OpenDyslexic's forms distracting.
  Verdana and Tahoma have wide default tracking and clearly distinct glyphs.
*/
html[data-a11y-font='readable'],
html[data-a11y-font='readable'] body,
html[data-a11y-font='readable'] h1,
html[data-a11y-font='readable'] h2,
html[data-a11y-font='readable'] h3,
html[data-a11y-font='readable'] h4,
html[data-a11y-font='readable'] h5,
html[data-a11y-font='readable'] h6,
html[data-a11y-font='readable'] p,
html[data-a11y-font='readable'] a,
html[data-a11y-font='readable'] li,
html[data-a11y-font='readable'] span,
html[data-a11y-font='readable'] label,
html[data-a11y-font='readable'] button,
html[data-a11y-font='readable'] input,
html[data-a11y-font='readable'] textarea,
html[data-a11y-font='readable'] select {
  font-family: Verdana, Tahoma, 'DejaVu Sans', sans-serif !important;
}

/* -----------------------------------------------------------------------------
   Reading comfort

   WCAG 2.1 SC 1.4.12 (Text Spacing) requires content to survive letter spacing
   at 0.12em, word spacing at 0.16em and line height at 1.5. These go further,
   because for a dyslexic reader spacing is often the difference between
   readable and not.
   -------------------------------------------------------------------------- */

html[data-a11y-letter-spacing='wide'] body  { letter-spacing: 0.08em; }
html[data-a11y-letter-spacing='wider'] body { letter-spacing: 0.16em; }

html[data-a11y-word-spacing='wide'] body { word-spacing: 0.24em; }

html[data-a11y-line-height='tall'] body,
html[data-a11y-line-height='tall'] p,
html[data-a11y-line-height='tall'] li {
  line-height: 1.8 !important;
}

html[data-a11y-line-height='taller'] body,
html[data-a11y-line-height='taller'] p,
html[data-a11y-line-height='taller'] li {
  line-height: 2.2 !important;
}

/* -----------------------------------------------------------------------------
   Text size

   Scales the root, so spacing expressed in rem grows with the text instead of
   the layout staying fixed and the copy overflowing it.
   -------------------------------------------------------------------------- */

html[data-a11y-text-scale='112'] { font-size: 112.5%; }
html[data-a11y-text-scale='125'] { font-size: 125%; }
html[data-a11y-text-scale='150'] { font-size: 150%; }
html[data-a11y-text-scale='200'] { font-size: 200%; }

/*
  Containers must be allowed to grow with the text. Fixed heights are the usual
  cause of clipped content at 200% zoom — a WCAG 1.4.4 failure.
*/
html[data-a11y-text-scale]:not([data-a11y-text-scale='100']) .card,
html[data-a11y-text-scale]:not([data-a11y-text-scale='100']) .course-box,
html[data-a11y-text-scale]:not([data-a11y-text-scale='100']) .btn {
  height: auto !important;
  min-height: 0 !important;
  white-space: normal !important;
}

/* -----------------------------------------------------------------------------
   Contrast
   -------------------------------------------------------------------------- */

/*
  High contrast — pure black on white, at least 7:1 (WCAG AAA).

  The site's brand gradient (gold #e0af14 → pink #ff409a) fails contrast against
  white for text, so in this mode gradients become solid black and buttons get
  visible borders. Losing the brand look is the correct trade: someone who has
  turned this on cannot read the gradient.
*/
html[data-a11y-contrast='high'] body,
html[data-a11y-contrast='high'] .section,
html[data-a11y-contrast='high'] .card,
html[data-a11y-contrast='high'] .course-box {
  background: #fff !important;
  color: #000 !important;
}

html[data-a11y-contrast='high'] h1,
html[data-a11y-contrast='high'] h2,
html[data-a11y-contrast='high'] h3,
html[data-a11y-contrast='high'] h4,
html[data-a11y-contrast='high'] h5,
html[data-a11y-contrast='high'] h6,
html[data-a11y-contrast='high'] p,
html[data-a11y-contrast='high'] span,
html[data-a11y-contrast='high'] li,
html[data-a11y-contrast='high'] label {
  color: #000 !important;
  text-shadow: none !important;
}

html[data-a11y-contrast='high'] a {
  color: #0000cc !important;
  text-decoration: underline !important;
}

html[data-a11y-contrast='high'] a:visited { color: #551a8b !important; }

html[data-a11y-contrast='high'] .btn,
html[data-a11y-contrast='high'] .gradient-btn,
html[data-a11y-contrast='high'] button {
  background: #000 !important;
  background-image: none !important;
  color: #fff !important;
  border: 2px solid #000 !important;
}

html[data-a11y-contrast='high'] input,
html[data-a11y-contrast='high'] textarea,
html[data-a11y-contrast='high'] select {
  background: #fff !important;
  color: #000 !important;
  border: 2px solid #000 !important;
}

html[data-a11y-contrast='high'] img:not([alt='']) {
  /* A visible boundary, since images no longer sit on a tinted surface. */
  outline: 1px solid #000;
}

/* Dark — for light sensitivity and migraine. Not pure black on pure white,
   which causes halation for some readers. */
html[data-a11y-contrast='dark'] body,
html[data-a11y-contrast='dark'] .section {
  background: #0f172a !important;
  color: #e2e8f0 !important;
}

html[data-a11y-contrast='dark'] .card,
html[data-a11y-contrast='dark'] .course-box,
html[data-a11y-contrast='dark'] .form-box {
  background: #1e293b !important;
  color: #e2e8f0 !important;
  border-color: #334155 !important;
}

html[data-a11y-contrast='dark'] h1,
html[data-a11y-contrast='dark'] h2,
html[data-a11y-contrast='dark'] h3,
html[data-a11y-contrast='dark'] h4,
html[data-a11y-contrast='dark'] h5,
html[data-a11y-contrast='dark'] h6 {
  color: #f8fafc !important;
}

html[data-a11y-contrast='dark'] a { color: #93c5fd !important; }

html[data-a11y-contrast='dark'] input,
html[data-a11y-contrast='dark'] textarea,
html[data-a11y-contrast='dark'] select {
  background: #1e293b !important;
  color: #e2e8f0 !important;
  border-color: #475569 !important;
}

/* Monochrome — removes colour for users who find it distracting or who
   experience colour-related visual stress. */
html[data-a11y-contrast='mono'] body {
  filter: grayscale(100%);
}

/* -----------------------------------------------------------------------------
   Motion

   WCAG 2.2.2. The OS-level preference is honoured automatically; the explicit
   setting exists because not everyone knows that OS setting is there.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

html[data-a11y-motion='reduced'] *,
html[data-a11y-motion='reduced'] *::before,
html[data-a11y-motion='reduced'] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* Stops carousels and marquees outright, rather than merely shortening them. */
html[data-a11y-stop-animations] *,
html[data-a11y-stop-animations] *::before,
html[data-a11y-stop-animations] *::after {
  animation: none !important;
  transition: none !important;
}

html[data-a11y-stop-animations] .owl-carousel .owl-item {
  transform: none !important;
}

/* -----------------------------------------------------------------------------
   Aids
   -------------------------------------------------------------------------- */

/*
  Link highlighting. WCAG 1.4.1 says colour alone must not convey meaning —
  v1's navigation relied entirely on colour to mark links.
*/
html[data-a11y-highlight-links] a {
  text-decoration: underline !important;
  text-underline-offset: 0.2em;
  outline: 1px dotted currentColor;
  outline-offset: 2px;
}

html[data-a11y-highlight-links] a:hover,
html[data-a11y-highlight-links] a:focus {
  background: #ffff00 !important;
  color: #000 !important;
  outline: 2px solid #000;
}

/* Large cursor, for low vision and imprecise pointing. */
html[data-a11y-big-cursor],
html[data-a11y-big-cursor] * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath d='M6 2l30 18-13 3 7 14-6 3-7-14-11 9z' fill='%23000' stroke='%23fff' stroke-width='2.5'/%3E%3C/svg%3E") 4 2, auto !important;
}

html[data-a11y-big-cursor] a,
html[data-a11y-big-cursor] button,
html[data-a11y-big-cursor] [role='button'] {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath d='M18 6v18l-5-4-4 5 11 13h16l4-16-8-3V6z' fill='%23000' stroke='%23fff' stroke-width='2.5'/%3E%3C/svg%3E") 12 4, pointer !important;
}

/*
  Reading guide — a horizontal ruler tracking the cursor, which helps hold place
  on a line. Positioned by a small script in the toolbar.
*/
#a11y-reading-guide {
  position: fixed;
  inset-inline: 0;
  height: 2.5rem;
  pointer-events: none;
  z-index: 99998;
  display: none;
  border-block: 2px solid rgb(0 0 0 / 55%);
  background: rgb(255 255 0 / 12%);
}

html[data-a11y-reading-guide] #a11y-reading-guide {
  display: block;
}

/* -----------------------------------------------------------------------------
   Baseline fixes — applied always, not only when a mode is on

   These correct v1 defects rather than offering a choice.
   -------------------------------------------------------------------------- */

/*
  Visible focus. v1 had none anywhere, so the entire site was unusable by
  keyboard — a WCAG 2.4.7 failure, and the single most damaging accessibility
  bug in the old build.
*/
:focus-visible {
  outline: 3px solid #6253f1 !important;
  outline-offset: 2px !important;
  border-radius: 2px;
}

html[data-a11y-contrast='high'] :focus-visible {
  outline: 3px solid #000 !important;
  box-shadow: 0 0 0 6px #ffff00 !important;
}

/* Skip link — WCAG 2.4.1. v1 had no way to bypass the navigation. */
.skip-link {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 99999;
  padding: 0.75rem 1.25rem;
  background: #fff;
  color: #6253f1;
  font-weight: 600;
  border: 2px solid #6253f1;
  border-radius: 4px;
  transform: translateY(-200%);
  transition: transform 120ms ease-out;
}

.skip-link:focus {
  transform: translateY(0);
}

/* Screen-reader-only text, for icon buttons and live regions. */
.sr-only-a11y {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*
  Minimum target size. WCAG 2.5.8 asks for 24×24 CSS pixels; 44×44 is the
  comfortable figure and what mobile guidelines expect.
*/
a.btn,
button,
[role='button'],
input[type='submit'],
input[type='button'] {
  min-height: 44px;
}

/* Never remove the outline without replacing it. */
*:focus {
  outline-offset: 2px;
}
