/* ==========================================================================
   UTILITIES - single-purpose helpers, animation keyframes, print styles.
   Loaded last so these always win.
   ========================================================================== */

/* --------------------------------------------------------- accessibility */
/* Available to screen readers, invisible on screen. */
.visually-hidden:not(:focus):not(:active) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ text */
.text-center { text-align: center; }
.text-start { text-align: start; }
.text-muted { color: var(--text-muted); }
.text-subtle { color: var(--text-subtle); }
.text-brand { color: var(--brand); }
.text-balance { text-wrap: balance; }
.measure { max-width: 62ch; }
.measure-narrow { max-width: 46ch; }

/* ----------------------------------------------------------------- layout */
.flow > * + * { margin-block-start: var(--flow-space, var(--space-s)); }
.mt-0 { margin-block-start: 0; }
.mt-s { margin-block-start: var(--space-s); }
.mt-m { margin-block-start: var(--space-m); }
.mt-l { margin-block-start: var(--space-l); }
.mt-xl { margin-block-start: var(--space-xl); }
.mx-auto { margin-inline: auto; }
.full-width { width: 100%; }

.hide { display: none !important; }

@media (max-width: 47.99em) { .hide-sm { display: none !important; } }
@media (min-width: 48em) { .hide-md-up { display: none !important; } }

/* ==========================================================================
   SCROLL REVEAL
   Elements marked with [data-reveal] start hidden and are revealed by
   IntersectionObserver. If JavaScript never runs, the .no-js fallback in the
   <head> keeps everything visible - content is never trapped behind JS.
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.25rem);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* Stagger children of a revealed group. */
[data-reveal-group] > * { --reveal-delay: calc(var(--i, 0) * 90ms); }

@keyframes fade-up {
  from { opacity: 0; transform: translateY(0.75rem); }
  to { opacity: 1; transform: none; }
}

/* ==========================================================================
   PRINT
   ========================================================================== */
@media print {
  .site-header,
  .site-footer,
  .nav-backdrop,
  .cta-band,
  .marquee,
  .skip-link,
  .lightbox { display: none !important; }

  :root { --bg: #fff; --text: #000; }

  body { background: #fff; color: #000; font-size: 11pt; }

  [data-reveal] { opacity: 1 !important; transform: none !important; }

  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; word-break: break-all; }

  .section { padding-block: 1rem; break-inside: avoid; }
}
