/* ==========================================================================
   UP AL — Accessibility widget
   A native floating control (no third-party plugin) that lets visitors
   adjust text size, contrast, link visibility, headings, motion, reading
   aids, spacing, images and cursor size, with every choice remembered via
   localStorage. Built entirely from the site's own tokens and its
   established glass-card recipe (same 4-layer gradient + backdrop-filter
   blur/saturate + border + --shadow-card used by Process/Testimonials/
   Contact/the legal pages' own components) so it reads as part of the
   site, not a bolted-on widget. Sits on every page.

   Every mode below is opt-in and off by default — the default design of
   every other page is completely unaffected until a visitor actually
   turns one of these on. Most modes work by overriding a handful of the
   site's own CSS custom properties or adding a scoped rule at the html
   level, so every component already styled from those tokens (which is
   effectively the whole site) picks the change up automatically with no
   per-component overrides needed.
   ========================================================================== */

/* ---------- Text size ----------
   html has no explicit font-size elsewhere in the codebase (browser
   default, 100%/16px) — this is the first rule to set one, and it's
   inert until --a11y-text-scale is written by JS, so it changes nothing
   by default. Because the entire type/spacing scale is rem-based
   (tokens.css), scaling the root font-size scales text AND the spacing
   around it together, proportionally — the correct way to satisfy
   WCAG's text-resize criterion without things overlapping at larger
   sizes. */

html {
  font-size: calc(100% * var(--a11y-text-scale, 1));
}

/* ---------- High contrast mode ----------
   Overrides a few color tokens at the root; every component sitewide
   already reads its colors from these same custom properties, so the
   whole page picks this up automatically. */

html.a11y-contrast {
  --color-text-secondary: #ffffff;
  --color-text-muted: #eef2f5;
  --color-border: rgba(255, 255, 255, 0.4);
  --color-border-soft: rgba(255, 255, 255, 0.28);
  --color-border-strong: rgba(255, 255, 255, 0.6);
  --color-bg-elevated: #0c1116;
  --color-accent: #cfe8ff;
}

/* ---------- Readable font ----------
   Swaps to a plain, highly-legible system sans — a common accessible
   fallback where loading a dedicated dyslexia-friendly font isn't
   possible without pulling in a new external resource. */

html.a11y-readable-font body {
  font-family: Arial, "Segoe UI", Tahoma, sans-serif !important;
}

/* ---------- Increase letter spacing ---------- */

html.a11y-letter-spacing body {
  letter-spacing: 0.06em !important;
}

/* ---------- Increase line height ----------
   Scoped to text-bearing elements rather than "body *" so it never
   touches the line-box math of icons, media frames or layout containers. */

html.a11y-line-height p,
html.a11y-line-height li,
html.a11y-line-height a,
html.a11y-line-height span,
html.a11y-line-height h1,
html.a11y-line-height h2,
html.a11y-line-height h3,
html.a11y-line-height h4,
html.a11y-line-height h5,
html.a11y-line-height h6,
html.a11y-line-height blockquote {
  line-height: 1.9 !important;
}

/* ---------- Highlight headings ----------
   A soft tint + accent rule ahead of every heading, sitewide, so page
   structure is easier to scan. */

html.a11y-highlight-headings h1,
html.a11y-highlight-headings h2,
html.a11y-highlight-headings h3,
html.a11y-highlight-headings h4,
html.a11y-highlight-headings h5,
html.a11y-highlight-headings h6 {
  background-color: rgba(158, 207, 247, 0.14) !important;
  border-inline-start: 3px solid var(--color-accent) !important;
  padding-inline-start: var(--space-3) !important;
  border-radius: 3px;
}

/* ---------- Highlight links ----------
   A visible outline + tint on every real content link, without touching
   the site's own buttons, nav links or this widget's own controls (which
   already have their own clear focus/hover states). Underlining is its
   own separate, independent toggle below. */

html.a11y-highlight-links a:not(.btn):not(.header__nav-link):not(.mobile-menu__link):not(.footer__social-link):not(.a11y-toggle):not(.a11y-option):not(.a11y-panel__close) {
  outline: 2px solid var(--color-accent) !important;
  outline-offset: 2px;
  background-color: rgba(158, 207, 247, 0.16) !important;
  border-radius: 3px;
}

/* ---------- Underline links ----------
   Independent of "highlight links" above — a plain underline on every
   real content link, the classic low-vision affordance for telling link
   text apart from body text without relying on color alone. */

html.a11y-underline-links a:not(.btn) {
  text-decoration: underline !important;
  text-underline-offset: 3px;
}

/* ---------- Hide images ----------
   Hides photographic/video content (not the interface's own SVG icons,
   which are part of the UI chrome, not "content images") while keeping
   their layout space reserved, so the page doesn't reflow underneath. */

html.a11y-hide-images img,
html.a11y-hide-images picture,
html.a11y-hide-images video {
  visibility: hidden !important;
}

/* ---------- Pause animations ----------
   Freezes keyframe animations in place (rather than snapping them to
   their end state) and collapses transitions to effectively nothing. */

html.a11y-pause-animations,
html.a11y-pause-animations *,
html.a11y-pause-animations *::before,
html.a11y-pause-animations *::after {
  animation-play-state: paused !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* ---------- Reduce motion ----------
   Distinct from "pause" above: this snaps animations straight to their
   end state instead of freezing mid-frame — the same numeric approach
   base.css already uses for the OS-level prefers-reduced-motion query,
   reused here for a manually-triggered mode for visitors whose OS
   preference isn't set but who still want motion minimized. */

html.a11y-reduce-motion,
html.a11y-reduce-motion *,
html.a11y-reduce-motion *::before,
html.a11y-reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* ---------- Bigger cursor ----------
   Inline SVG data-URI cursors (no extra asset files) — a larger arrow
   everywhere, and a larger "hand" cursor over links/buttons so pointer
   affordance is still communicated at the bigger size. */

html.a11y-big-cursor,
html.a11y-big-cursor * {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24"><path d="M3 2l7.2 18.9 2.4-7.3 7.3-2.4z" fill="%23ffffff" stroke="%23151f28" stroke-width="1.3" stroke-linejoin="round"/></svg>') 4 4, auto !important;
}

html.a11y-big-cursor a,
html.a11y-big-cursor button,
html.a11y-big-cursor [role="button"] {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24"><path d="M8 3.2v11.3a2 2 0 0 0 3.6 1.2l.7-.9 1.9 4.6a1.5 1.5 0 0 0 2.8-1.1l-1.6-4h2a2 2 0 0 0 1.4-3.4L13 4.2a2 2 0 0 0-2-1.1H9a1 1 0 0 0-1 1.1Z" fill="%23ffffff" stroke="%23151f28" stroke-width="1.1" stroke-linejoin="round"/></svg>') 8 4, pointer !important;
}

/* ---------- Reading guide ----------
   A slim glowing line that tracks the pointer down the page, helping
   visitors keep their place while reading. Purely visual — pointer-
   events: none so it never blocks a click — and only ever created and
   attached to the page while the mode is switched on. Position (top) is
   written directly by JS on every pointer move. */

.a11y-reading-guide {
  position: fixed;
  inset-inline: 0;
  top: 0;
  height: 3px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, transparent, rgba(158, 207, 247, 0.95) 15%, rgba(158, 207, 247, 0.95) 85%, transparent);
  box-shadow: 0 0 18px 4px rgba(158, 207, 247, 0.5);
  pointer-events: none;
  z-index: 9998;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-premium);
}

.a11y-reading-guide.is-active {
  opacity: 1;
}

/* ---------- Reading mask ----------
   Two dark bands, above and below a clear reading window centered on the
   pointer, dimming everything else on the page. Implemented as two
   elements (rather than one with a CSS mask) for the most reliable
   cross-browser behavior. Both pointer-events: none. */

.a11y-reading-mask {
  position: fixed;
  inset-inline: 0;
  background-color: rgba(6, 9, 12, 0.86);
  pointer-events: none;
  z-index: 9997;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-premium);
}

.a11y-reading-mask.is-active {
  opacity: 1;
}

.a11y-reading-mask--top {
  top: 0;
  height: 0;
}

.a11y-reading-mask--bottom {
  bottom: 0;
  top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .a11y-reading-guide,
  .a11y-reading-mask {
    transition: none;
  }
}

/* ==========================================================================
   The widget itself
   ========================================================================== */

.a11y-widget {
  position: fixed;
  z-index: 60;
  right: var(--space-5);
  bottom: var(--space-5);
}

@media (max-width: 560px) {
  .a11y-widget {
    right: var(--space-4);
    bottom: var(--space-4);
  }
}

/* ---------- Toggle button ----------
   Same glass recipe as every premium surface on the site: layered
   gradient + backdrop-filter blur/saturate + --shadow-card + a hairline
   border. An ambient halo (::before) blooms behind it on hover/focus,
   the same "soft glow" device used for Portfolio/Contact/Process cards
   elsewhere, plus a small lift. */

.a11y-toggle {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: radial-gradient(120% 120% at 24% 0%, rgba(255, 255, 255, 0.14), transparent 55%),
    radial-gradient(120% 120% at 80% 100%, rgba(0, 0, 0, 0.3), transparent 60%), var(--color-bg-elevated);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: transform var(--duration-base) var(--ease-premium), border-color var(--duration-base) var(--ease-premium),
    box-shadow var(--duration-base) var(--ease-premium);
}

.a11y-toggle::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -14px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(158, 207, 247, 0.35), transparent 70%);
  opacity: 0;
  filter: blur(16px);
  transition: opacity var(--duration-slow) var(--ease-premium);
  pointer-events: none;
}

.a11y-toggle:hover,
.a11y-toggle:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(158, 207, 247, 0.4);
  box-shadow: var(--shadow-card-hover);
}

.a11y-toggle:hover::before,
.a11y-toggle:focus-visible::before {
  opacity: 1;
}

.a11y-toggle:active {
  transform: translateY(-1px) scale(0.97);
}

.a11y-toggle__icon {
  width: 24px;
  height: 24px;
}

.a11y-widget.is-open .a11y-toggle {
  border-color: rgba(158, 207, 247, 0.45);
  box-shadow: var(--shadow-card-hover);
}

.a11y-widget.is-open .a11y-toggle::before {
  opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
  .a11y-toggle:hover,
  .a11y-toggle:focus-visible {
    transform: none;
  }
}

/* ---------- Panel ----------
   Anchored with a physical `right: 0` (not `inset-inline-end`) so it is
   pinned to the toggle button's own right edge and grows LEFT, into the
   viewport — the widget itself sits close to the screen's right edge, so
   a panel that grew rightward (as inset-inline-end did under RTL) would
   push straight off-screen. Width is capped relative to the viewport so
   it can never be wider than the visible area either. Below 560px this
   is overridden entirely by a fixed, equal-margin layout (see media
   query below) that is anchored to the viewport instead of the button,
   guaranteeing full visibility on small screens regardless of exactly
   where the toggle sits. */

.a11y-panel {
  position: absolute;
  z-index: 0;
  bottom: calc(100% + var(--space-3));
  right: 0;
  width: min(360px, calc(100vw - var(--space-8)));
  max-width: calc(100vw - var(--space-8));
  opacity: 0;
  transform: translateY(10px) scale(0.98);
  visibility: hidden;
  pointer-events: none;
  transform-origin: bottom right;
  transition: opacity var(--duration-slow) var(--ease-premium), transform var(--duration-slow) var(--ease-premium),
    visibility 0s linear var(--duration-slow);
}

.a11y-panel.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--duration-slow) var(--ease-premium), transform var(--duration-slow) var(--ease-premium),
    visibility 0s linear 0s;
}

@media (prefers-reduced-motion: reduce) {
  .a11y-panel {
    transform: none;
  }
  .a11y-panel.is-open {
    transform: none;
  }
}

/* Mobile: decouple entirely from the toggle button's position. Fixed to
   the viewport with equal left/right margins, so it is mathematically
   guaranteed to fit — it can no longer inherit any overflow risk from
   the button's own placement. */
@media (max-width: 560px) {
  .a11y-panel {
    position: fixed;
    left: var(--space-4);
    right: var(--space-4);
    bottom: calc(var(--space-4) + 68px);
    width: auto;
    max-width: none;
  }
}

.a11y-panel__surface {
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: radial-gradient(120% 90% at 16% -12%, rgba(255, 255, 255, 0.1), transparent 55%),
    radial-gradient(36% 28% at 84% 4%, rgba(255, 255, 255, 0.06), transparent 62%),
    linear-gradient(205deg, rgba(255, 255, 255, 0.035) 0%, transparent 42%),
    radial-gradient(130% 85% at 50% 125%, rgba(0, 0, 0, 0.34), transparent 60%), var(--color-bg-elevated);
  backdrop-filter: blur(28px) saturate(160%);
  -webkit-backdrop-filter: blur(28px) saturate(160%);
  box-shadow: var(--shadow-card-hover);
  max-height: min(72svh, 620px);
  overflow-y: auto;
  overflow-x: hidden;
}

@media (max-width: 560px) {
  .a11y-panel__surface {
    max-height: min(64svh, 560px);
  }
}

.a11y-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-4);
}

.a11y-panel__title {
  font-size: 1.0625rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text-primary);
  margin: 0;
}

.a11y-panel__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--color-text-muted);
  border: 1px solid transparent;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-premium), border-color var(--duration-fast) var(--ease-premium),
    background-color var(--duration-fast) var(--ease-premium);
}

.a11y-panel__close svg {
  width: 16px;
  height: 16px;
}

.a11y-panel__close:hover,
.a11y-panel__close:focus-visible {
  color: var(--color-text-primary);
  border-color: var(--color-border);
  background-color: var(--color-accent-soft);
}

/* ---------- Control groups ----------
   Small uppercase labels (h3 — the panel title is an h2, so this keeps
   heading order logical) that break the many controls into scannable
   clusters, with a hairline divider between clusters. */

.a11y-group + .a11y-group {
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-5);
  border-top: 1px solid var(--color-border-soft);
}

.a11y-group-title {
  margin: 0 0 var(--space-3);
  font-size: 0.6875rem;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

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

.a11y-stepper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background-color: rgba(255, 255, 255, 0.03);
}

.a11y-stepper__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  font-size: 1rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-premium), color var(--duration-fast) var(--ease-premium),
    background-color var(--duration-fast) var(--ease-premium);
}

.a11y-stepper__btn:hover,
.a11y-stepper__btn:focus-visible {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background-color: var(--color-accent-soft);
}

.a11y-stepper__btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.a11y-stepper__btn:disabled:hover {
  border-color: var(--color-border);
  color: var(--color-text-primary);
  background-color: transparent;
}

.a11y-stepper__value {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.a11y-stepper__glyph {
  font-family: var(--font-base);
  line-height: 1;
}

.a11y-stepper__glyph--sm {
  font-size: 0.8rem;
}

.a11y-stepper__glyph--lg {
  font-size: 1.4rem;
}

/* ---------- Text-size reset (compact ghost link under the stepper) ---------- */

.a11y-text-reset {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  margin-block-start: var(--space-2);
  padding-block: var(--space-2);
  font-size: 0.75rem;
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-premium), background-color var(--duration-fast) var(--ease-premium);
}

.a11y-text-reset svg {
  width: 14px;
  height: 14px;
}

.a11y-text-reset:hover,
.a11y-text-reset:focus-visible {
  color: var(--color-accent);
  background-color: var(--color-accent-soft);
}

/* ---------- Option grid ---------- */

.a11y-panel__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
}

.a11y-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--duration-base) var(--ease-premium), background-color var(--duration-base) var(--ease-premium),
    transform var(--duration-fast) var(--ease-premium);
}

.a11y-option:hover,
.a11y-option:focus-visible {
  border-color: rgba(158, 207, 247, 0.4);
  background-color: var(--color-accent-soft);
  transform: translateY(-2px);
}

.a11y-option[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: linear-gradient(180deg, rgba(158, 207, 247, 0.16), rgba(158, 207, 247, 0.05));
  box-shadow: 0 0 0 1px rgba(158, 207, 247, 0.3) inset;
}

.a11y-option__icon {
  width: 22px;
  height: 22px;
  color: var(--color-text-secondary);
}

.a11y-option__icon--text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: 22px;
  font-family: var(--font-base);
  font-size: 1rem;
  font-weight: var(--fw-bold);
  line-height: 1;
}

.a11y-option__icon--underline {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.a11y-option[aria-pressed="true"] .a11y-option__icon {
  color: var(--color-accent);
}

.a11y-option__label {
  font-size: 0.75rem;
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  color: var(--color-text-secondary);
}

.a11y-option[aria-pressed="true"] .a11y-option__label {
  color: var(--color-text-primary);
}

/* ---------- Reset all ---------- */

.a11y-reset {
  display: flex;
  width: 100%;
  justify-content: center;
  margin-block-start: var(--space-5);
  padding-block: 0.7rem;
  font-size: var(--fs-small);
}
