/**
 * @file
 * Accessibility base layer: skip link, focus ring, hiding utilities.
 * FND-5 / DONI-708.
 *
 * ─────────────────────────────────────────────────────────────────────────
 * 🔴 EVERYTHING IN THIS FILE IS OUR DECISION, NOT THE DESIGN'S.
 *
 * The Figma file draws NO skip link and NO focus state, at any breakpoint.
 * That is not permission to ship neither — WCAG 2.4.1 and 2.4.7 require
 * both. So these values are chosen and justified here, and a future
 * "faithful re-extraction" must not delete them for being absent upstream.
 * ─────────────────────────────────────────────────────────────────────────
 *
 * ## The focus ring is two-tone, and here is the measurement that forced it
 *
 * FND-5's AC specifies 3px `--color-dark-coral` at `outline-offset: 2px`,
 * "which clears 3:1 against both white and charcoal."
 *
 * 🔴 Measured 2026-08-05 — the second half of that is false:
 *
 * | Ring against | Ratio | 3:1 |
 * |--------------|-------|-----|
 * | White        | 4.76  | ✅  |
 * | CHARCOAL `#1d2d3a` | **2.96** | ❌ |
 * | STEEL `#515861`    | **1.51** | ❌ |
 * | Coral `#f16b50`    | **1.58** | ❌ |
 *
 * Coral is the one that matters most: a dark-coral ring on a coral button
 * is very nearly invisible. So the ring keeps the specified 3px dark-coral
 * outline and adds a 2px white separator immediately inside it. White
 * against dark-coral is 4.76:1, so the indicator is always distinguishable
 * from whatever it sits on — the standard two-tone technique.
 *
 * Logged on DONI-866 as required. It does not block anything.
 */

/**
 * The focus ring.
 *
 * `:focus-visible` rather than `:focus`, so a mouse click on a button does
 * not leave a ring behind. Keyboard users still get it.
 */
:focus-visible {
  outline: 3px solid var(--color-dark-coral);
  outline-offset: 2px;
  /* The white separator. Sits between the element and the outline, in the
     gap `outline-offset` opens. Not decoration — see the table above. */
  box-shadow: 0 0 0 2px var(--color-white);
}

/**
 * The skip link.
 *
 * ⚠️ It targets `#main-content`, not `#main` as FND-5's AC says. The anchor
 * `<a id="main-content" tabindex="-1">` at `templates/layout/page.html.twig:100`
 * already exists, is Drupal's own convention, and works. Renaming it buys
 * nothing and would break three `twigify/` templates. Deviation recorded on
 * DONI-708.
 *
 * The positioning lives in `css/components/layout.css`. This block exists
 * only to undo the `outline: none` that file sets on `:focus` — a skip link
 * you cannot see you have focused is not a skip link.
 */
.skip-link.visually-hidden.focusable:focus,
.skip-link.visually-hidden.focusable:focus-visible,
.skip-link:focus,
.skip-link:focus-visible {
  outline: 3px solid var(--color-dark-coral);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--color-white);

  /* 🔴 `position: fixed !important` is load-bearing, not tidiness.
   *
   * Core's `.visually-hidden.focusable:focus` sets `position: static
   * !important`. That makes the `top: 0` in css/components/layout.css inert,
   * so the focused link landed in normal flow and the sticky header covered
   * it — measured at 390 as `top: -6px`, i.e. clipped off the viewport.
   * A skip link you cannot see is not a skip link, so this has to outrank it. */
  position: fixed !important;
  top: 0;
  left: 0;
  z-index: var(--z-tooltip);
}

/**
 * `.visually-hidden` — off-screen for sighted users, still read aloud.
 *
 * Drupal core's `stable9` ships this in `hidden.module.css` and the theme
 * has been relying on that. Declared here as well so it cannot vanish if a
 * route stops attaching core's library. Same rules, so load order is moot.
 */
.visually-hidden {
  position: absolute !important;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  width: 1px;
  height: 1px;
  word-wrap: normal;
}

/* `.focusable` is what lets the skip link come back on keyboard focus. */
.visually-hidden.focusable:focus,
.visually-hidden.focusable:active {
  position: static !important;
  overflow: visible;
  clip: auto;
  clip-path: none;
  width: auto;
  height: auto;
}

/**
 * `.sprite` — the inline SVG symbol sprite's own container.
 *
 * FND-6 (DONI-711) ships twelve `<symbol>`s in one inline `<svg>` near the
 * top of `<body>`. That element must take up no space and must never be
 * announced, but it CANNOT use `display: none` or `visibility: hidden` —
 * those stop `<use>` from resolving in some browsers and every icon on the
 * page renders empty.
 *
 * So: zero-size, clipped, out of the accessibility tree via `aria-hidden`
 * on the element itself.
 */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/**
 * Zero-width-space spacer paragraphs.
 *
 * Figma uses empty lines as vertical rhythm, and the extraction reproduces
 * them as `<p>&#8203;</p>`. Keep them — deleting one changes the spacing the
 * design draws. But a screen reader must not announce a blank paragraph, so
 * the markup carries `aria-hidden="true"` and this rule makes the intent
 * greppable rather than invisible.
 *
 * ⚠️ `aria-hidden` is markup, not CSS. This class does not create the
 * behaviour on its own — it documents and reserves it. Any spacer that ships
 * needs `<p class="spacer" aria-hidden="true">&#8203;</p>`.
 */
.spacer {
  user-select: none;
}

/**
 * Reduced motion.
 *
 * ✅ The ISI tray's own transition is already handled by the module that
 * owns it — `project/modules/dtc_nxt_isi/css/isi-tray.css:519-524` sets
 * `transition: none` on `.isi-tray` and `.isi-tray__icon`. Not duplicated
 * here; two owners for one rule is how they drift apart.
 *
 * `css/base/variables.css` separately zeroes `--transition-fast/base/slow`
 * under the same query. This block covers what neither reaches: anything
 * animating through a literal duration.
 */
@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;
  }
}
