/* =============================================================================
 * Base accessibility contract. Rides along with Tailwind (or a11y-css) so the
 * focus / motion / visibility / target-size rules are never lost. Keep this
 * even if you swap the utility layer.
 * ========================================================================== */

:root {
  color-scheme: light dark;
  --color-focus: #1d4ed8;
  --focus-ring-width: 3px;
  --focus-ring-offset: 2px;
  --target-size-min: 24px; /* WCAG 2.2 SC 2.5.8 */
}

/* Explicit theme choice pins the scheme so native controls, form fields, and
 * scrollbars match. The .dark class is toggled by the theme button; data-theme
 * is set before first paint. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"], .dark { color-scheme: dark; --color-focus: #60a5fa; }

/* Respect reduced motion, but keep a hair of duration so animation-end logic
 * still fires. Recipes define their own reduced alternatives. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Never prevent zoom. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* One strong, visible focus ring for every focusable element. :focus-visible
 * so pointer users don't see rings but keyboard users always do. Stays visible
 * in forced colors. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}
:focus:not(:focus-visible) { outline: none; }
@media (forced-colors: active) {
  :focus-visible { outline-color: Highlight; }
}

/* Minimum target size for interactive controls. */
a, button, input, select, textarea, [role="button"] {
  min-height: var(--target-size-min);
}

/* Skip link: visually hidden until focused, then visible and at the top. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.5rem 1rem;
  background: Canvas;
  color: CanvasText;
  z-index: 1000;
}
.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
}

/* Screen-reader-only text (announced, not shown). Clip pattern — never
 * display:none. Add focus:not-sr-only in markup to reveal skip links. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Links keep a non-color affordance in prose. */
.link { text-underline-offset: 0.16em; text-decoration: underline; }

/* Responsive single-tree nav: toggle hidden and list inline at wide widths;
 * toggle shown and list collapsible at narrow widths. One DOM tree, no copies. */
.nav-toggle { display: none; }
@media (max-width: 640px) {
  .nav-toggle { display: inline-flex; align-items: center; }
  .nav-list { display: none; width: 100%; }
  .nav-list[data-open] { display: flex; }
}

/* Disabled is not opacity alone — keep text readable, state is programmatic. */
[disabled], [aria-disabled="true"] { cursor: not-allowed; }
