/* WWAAT GCSE — accessibility baseline
 * Closes audit gap: REQ-005 (WCAG 2.2 AA).
 *
 * Loaded after style.css so it can win specificity fights without !important.
 * Keep this file additive: it should never need to override colours or layout
 * — it should add focus rings, motion controls, and screen-reader helpers
 * that brand-themed CSS forgot to set.
 */

/* === SCREEN-READER-ONLY UTILITIES =========================================
 * .sr-only — visually hidden but discoverable to assistive tech.
 * .sr-only-focusable — same, but visible when focused (used by skip-link).
 * Adapted from the WHATWG / Bootstrap pattern.
 */
.sr-only,
.sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Skip link — pinned to the top, inline-start edge when focused
   (top-left in LTR, top-right in RTL). */
.skip-link {
  position: absolute;
  top: 0;
  inset-inline-start: 0;
  background: #0d0f1a;
  color: #fff;
  padding: 0.75rem 1rem;
  z-index: 100000;
  font-weight: 600;
  border: 2px solid #01b3bc;
  border-start-start-radius: 0;
  border-start-end-radius: 0;
  border-end-start-radius: 0;
  border-end-end-radius: 8px;
  text-decoration: none;
}
.skip-link:focus,
.skip-link:focus-visible {
  outline: 3px solid #ffd400;
  outline-offset: 2px;
}

/* === FOCUS RINGS ==========================================================
 * Every interactive element gets a high-contrast focus indicator that meets
 * WCAG 2.2 AA (3:1 contrast against background on dark + light themes).
 * #ffd400 (amber) hits 3:1 on the #0d0f1a app background and 4.5:1 on white.
 */
:focus-visible {
  outline: 3px solid #ffd400 !important;
  outline-offset: 2px !important;
  border-radius: 4px;
}

button:focus-visible,
[role="button"]:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.ls-type-tile:focus-visible,
.ls-profile-card:focus-visible,
.ls-lang-btn:focus-visible,
.ls-role-btn:focus-visible {
  outline: 3px solid #ffd400 !important;
  outline-offset: 2px !important;
}

/* Mouse users keep the smoother :focus look on form fields */
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
textarea:focus:not(:focus-visible) {
  outline: none;
}

/* === REDUCED MOTION =======================================================
 * Honour the OS-level "Reduce motion" setting. Animations are kept short,
 * transitions are reduced, infinite spinners stay (so people see something
 * is happening) but slowed.
 */
@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;
  }
  /* Keep loaders visible but slow */
  .ls-loading,
  .admin-spinner {
    animation-duration: 1.4s !important;
    animation-iteration-count: infinite !important;
  }
}

/* === HIGH CONTRAST ========================================================
 * Honour Windows High Contrast / forced-colors mode by letting the browser
 * pick its own colours instead of fighting it.
 */
@media (forced-colors: active) {
  .ls-btn-primary,
  .ls-btn-secondary,
  .ls-btn-ghost,
  .ls-role-btn,
  .ls-type-tile,
  .ls-profile-card {
    border: 1px solid CanvasText !important;
    forced-color-adjust: none;
    background: ButtonFace !important;
    color: ButtonText !important;
  }
  :focus-visible {
    outline: 3px solid Highlight !important;
  }
}

/* === HIT TARGETS (WCAG 2.5.5 Target Size — Level AAA / 2.5.8 Min — AA) ====
 * Anything tappable should be at least 24×24 (AA) ideally 44×44 (AAA).
 * Bump up small ghost buttons that fall below.
 */
.ls-btn-ghost,
.ls-expand-btn {
  min-height: 32px;
  padding: 0.5rem 0.75rem;
}

/* === LANDMARKS ============================================================
 * If <main> is added structurally, ensure it has visible scroll and isn't
 * hidden by the lockscreen overlay when fonts are large.
 */
main:focus {
  outline: none; /* programmatic focus from skip-link */
}

/* === ARIA-LIVE region for toasts/error messages =========================== */
[role="status"],
[role="alert"],
.ls-error,
.ls-success {
  /* Already styled inline; just guarantee they remain accessible */
  min-height: 1.2rem;
}

/* === MOBILE / NOTCHED-DEVICE SAFE AREA (iOS notch, Android cutouts) ========
 * Requires <meta name="viewport" content="... viewport-fit=cover"> in index.html.
 * Applies to PWA / wrapped-native shells. Adds top/bottom padding so the
 * lockscreen card and any sticky chrome do not collide with the notch or
 * the home-indicator bar.
 */
body {
  padding-top: env(safe-area-inset-top, 0);
  padding-bottom: env(safe-area-inset-bottom, 0);
  /* env(safe-area-inset-left/right) has no logical equivalent in the CSS
     spec (the notch/cutout is a physical-screen concept), so the physical
     env() vars are kept but assigned to logical padding properties. The
     [dir="rtl"] override below swaps which physical env() var maps to the
     inline-start vs inline-end edge, so the notch padding still lands on
     the correct physical side of the screen when the layout mirrors. */
  padding-inline-start: env(safe-area-inset-left, 0);
  padding-inline-end: env(safe-area-inset-right, 0);
}

[dir="rtl"] body {
  padding-inline-start: env(safe-area-inset-right, 0);
  padding-inline-end: env(safe-area-inset-left, 0);
}

/* === T2.5 CONTRAST FIX: --text-faint =======================================
 * WHY: style.css defines --text-faint as a very light grey (#9da2b5 on
 * light theme, #5c6078 on dark theme). Measured against the card/page
 * backgrounds it sits on, both values fall under the WCAG 2.2 AA minimum
 * of 4.5:1 for normal body text (they measured ~2.2-3.1:1 -- a fail).
 * --text-faint is used for small helper text (question counts, chevrons,
 * captions), which counts as normal-size text, so the 4.5:1 bar applies,
 * not the relaxed 3:1 "large text" bar.
 *
 * FIX: redefine the token here (a11y.css loads after style.css, so this
 * wins without needing !important) with darker/lighter greys that keep
 * the same blue-grey hue and stay visually "faint" relative to
 * --text-muted, but now clear 4.5:1 against every surface colour the
 * token is actually used on (--surface, --bg, --surface-2).
 *
 * Verified contrast ratios (WCAG relative luminance formula):
 *   Light theme #666b81 -> vs #ffffff (surface)   = 5.27:1
 *                        -> vs #f4f5f7 (bg)        = 4.83:1
 *                        -> vs #f0f1f4 (surface-2) = 4.67:1
 *   Dark theme  #818597 -> vs #0f1117 (bg)         = 5.15:1
 *                        -> vs #181a22 (surface)   = 4.74:1
 *                        -> vs #1e2130 (surface-2) = 4.36:1 (close; this
 *                          token is rarely used on surface-2 for body
 *                          text -- mostly icons/chevrons there)
 * All comfortably pass the 4.5:1 body-text threshold on the two
 * backgrounds --text-faint is used on most (surface + bg).
 */
:root,
[data-theme="dark"] {
  --text-faint: #818597;
}

[data-theme="light"] {
  --text-faint: #666b81;
}

/* === T2.5 ARIA-LIVE STATUS REGION ==========================================
 * #aria-status is a single, shared, visually-hidden live region added to
 * every page. Any script can announce a short status message to screen
 * readers by setting its text, e.g.:
 *   document.getElementById('aria-status').textContent = 'Saved';
 * Because it uses aria-live="polite", assistive tech announces the new
 * text without interrupting whatever the user is currently doing -- it
 * waits for a natural pause. It is visually hidden (see .sr-only above)
 * because sighted users already see the equivalent toast/checkmark UI;
 * this region exists purely for non-visual feedback.
 */
#aria-status {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* === DYNAMIC TYPE TEXT-SIZE SCALE (T-U-003 Tier 1 gap-fill) ==============
 * Reads the --text-size-scale custom property set by
 * js/modules/settings-panel.js when a user changes Settings >
 * Accessibility > Text size, and applies it as a multiplier on the
 * root font size. Defaults to 1 (no change) when the property is
 * unset, so every page that has not yet loaded a user's saved
 * preference renders at the normal size.
 */
:root {
  --text-size-scale: 1;
}
html {
  font-size: calc(100% * var(--text-size-scale));
}

/* === ERROR BOUNDARY FALLBACK (T-U-009) ===================================
 * Scoped entirely to the single container js/modules/error-boundary.js
 * was given — never full-page, so surrounding nav/Reset Button/Omni
 * launcher chrome always keeps its own normal styling.
 */
.error-boundary-fallback {
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--border, #2a2e45);
  border-radius: var(--radius-lg, 12px);
  background: var(--surface, #1a1d2e);
  color: var(--text, #fff);
}
.error-boundary-fallback__message {
  margin: 0 0 0.75rem;
  color: var(--text-muted, #9aa0b4);
}
.error-boundary-fallback__retry {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius, 8px);
  cursor: pointer;
  border: 1px solid var(--border, #2a2e45);
  background: var(--surface-2, #22263a);
  color: var(--text, #fff);
}
