/* ==========================================================================
   KatangaVox — accessibility enhancements.

   Deliberately additive and invisible by default: nothing here changes the
   site's colours, typography, spacing or layout for a mouse user. Every rule
   either activates only on keyboard focus, or honours an explicit OS setting.

   Tap-target sizing is NOT included: enforcing 44px on the existing footer and
   social links would visibly change their spacing, so it is raised as a
   proposal instead of shipped.
   ========================================================================== */

/* --- Keyboard focus -------------------------------------------------------
   The handover CSS removes outlines in places without providing a replacement,
   which leaves keyboard users with no visible position. :focus-visible shows
   a ring for keyboard navigation only, so pointer users see no change. */

:focus-visible {
  outline: 3px solid #166341;
  outline-offset: 2px;
  border-radius: 2px;
}

[data-theme='dark'] :focus-visible {
  outline-color: #7ec9a3;
}

/* Interactive elements that sit on the copper/red brand fills need a light
   ring to stay visible against the background. */
.btn-primary:focus-visible,
.announce-bar-main:focus-visible,
.announce-dismiss:focus-visible {
  outline-color: #fffdf8;
  outline-offset: 3px;
}

/* --- Skip link ------------------------------------------------------------
   Present in the markup but visually lost until focused. */

.skip-link:focus,
.skip-link:focus-visible {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 10000;
  padding: 12px 18px;
  width: auto;
  height: auto;
  clip: auto;
  clip-path: none;
  overflow: visible;
  background: #166341;
  color: #fffdf8;
  font-weight: 700;
  text-decoration: none;
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
}

/* --- Reduced motion -------------------------------------------------------
   The homepage reveals cards with transform/opacity transitions and the
   announcement modal animates in. Respect the OS preference. */

@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;
  }

  /* Cards are revealed by inline opacity/transform from JS; force them
     visible so reduced-motion users never get stuck with hidden content. */
  .article-card,
  .topic-card,
  .pillar-card {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* --- Forced colours (Windows high contrast) ------------------------------ */

@media (forced-colors: active) {
  .flag-ribbon {
    forced-color-adjust: none;
  }
}

/* ==========================================================================
   Motion pass — conservative.

   Transform and opacity only, so nothing reflows; nothing animates while
   reading; everything is disabled under prefers-reduced-motion.
   ========================================================================== */

/* Mobile drawer.
   style.css already transitions the drawer (transform) and the overlay
   (opacity), but .mobile-nav toggles display:none, and display is not
   transitionable — the browser has no previous frame to animate from, so both
   directions snapped open and shut. Swapping to visibility keeps the element
   in the layer tree so the existing transforms actually run. The delayed
   visibility on close lets the drawer finish sliding out before it hides. */
.mobile-nav {
  display: block;
  visibility: hidden;
  pointer-events: none;
  transition: visibility 0s linear 260ms;
}

.mobile-nav.open {
  visibility: visible;
  pointer-events: auto;
  transition: visibility 0s linear 0s;
}

.mobile-nav-drawer {
  /* 350ms read as sluggish on a small screen. */
  transition: transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.mobile-nav-overlay {
  transition: opacity 200ms ease;
}

/* Card entrances: one short rise as the page settles, with a small stagger.
   Capped at six cards so a long index does not trickle in, and driven by
   transform/opacity so no layout shift is possible. */
@keyframes kv-rise {
  from {
    opacity: 0.01;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.index-card,
.article-card,
.topic-card {
  animation: kv-rise 240ms ease-out both;
}

.index-card:nth-child(2),
.article-card:nth-child(2),
.topic-card:nth-child(2) { animation-delay: 40ms; }
.index-card:nth-child(3),
.article-card:nth-child(3),
.topic-card:nth-child(3) { animation-delay: 80ms; }
.index-card:nth-child(4),
.article-card:nth-child(4),
.topic-card:nth-child(4) { animation-delay: 120ms; }
.index-card:nth-child(5),
.article-card:nth-child(5),
.topic-card:nth-child(5) { animation-delay: 160ms; }
.index-card:nth-child(n + 6),
.article-card:nth-child(n + 6),
.topic-card:nth-child(n + 6) { animation-delay: 200ms; }

/* Motion budget.

   Measured with tools/motion-audit.mjs: eight transitions on the homepage ran
   400-520ms, which is the slow half of the pass and sits well outside the
   ~300ms the rest of it targets. Capped here rather than in style.css or
   light-refresh.css so the handover stylesheets stay untouched and the whole
   motion pass reverts by deleting one file's worth of rules.

   Durations only — no property, easing or geometry is changed, so nothing
   moves that did not move before.

   Scoped to no-preference on purpose. `transition-duration` needs !important
   to outrank the inline style main.js writes, and an important declaration
   with a class selector would otherwise beat the `*` reset in the reduce
   block below and quietly re-enable motion for the people who opted out. */
@media (prefers-reduced-motion: no-preference) {
  /* initAnimations() in main.js sets `opacity .5s ease, transform .5s ease`
     as an inline style on every revealed card. The reveal is sound —
     transform/opacity, no reflow — but 500ms reads as sluggish beside the
     240ms kv-rise entrance running on the same elements. Match them. */
  .topic-card,
  .article-card,
  .pillar-card {
    transition-duration: 240ms !important;
  }

  /* Hover zooms and the topic-card clip-path wipe: 420-520ms. */
  .article-img img,
  .article-card-image img,
  .topic-image,
  .topic-image img,
  .pillar-card::after {
    transition-duration: 260ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-nav,
  .mobile-nav.open {
    transition: none;
  }

  .mobile-nav-drawer,
  .mobile-nav-overlay {
    transition: none;
  }

  .index-card,
  .article-card,
  .topic-card {
    animation: none;
  }
}
