/* ================================================================
   GLOBAL — base element styles.

   Design tokens live in tokens.css, which is loaded before this file and also on
   its own in wp-admin. Keep them there: everything in this file styles bare
   elements, and this design is dark-first, so an unscoped `body` rule would repaint
   the entire admin.

   Scoping
   -------
   Every element rule below is confined to the frontend and the editor canvas:

     body:not(.wp-admin)      the frontend
     .editor-styles-wrapper   the editor canvas, which is not always iframed —
                              ACF registers blocks at API version 2, which keeps the
                              canvas in the main admin document

   The scope sits inside :where(), which contributes no specificity, so these rules
   weigh exactly what a bare element selector would and block CSS still overrides
   them with a single class.
   ================================================================ */

/* ── Base ─────────────────────────────────────────────────────── */

:where(body:not(.wp-admin), .editor-styles-wrapper),
:where(body:not(.wp-admin), .editor-styles-wrapper) *,
:where(body:not(.wp-admin), .editor-styles-wrapper) *::before,
:where(body:not(.wp-admin), .editor-styles-wrapper) *::after {
  box-sizing: border-box;
}

:where(body:not(.wp-admin), .editor-styles-wrapper) {
  margin: 0;
  font-family: var(--f-body);
  color: var(--text);
  background: var(--bg-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

:where(body:not(.wp-admin), .editor-styles-wrapper) :is(h1, h2, h3, h4, h5, h6) {
  font-family: var(--f-display);
  font-weight: 800;          /* the design sets every heading in the heavy weight */
  line-height: 1.2;
  letter-spacing: -0.01em;
}

:where(body:not(.wp-admin), .editor-styles-wrapper) :is(img, video, svg) {
  max-width: 100%;
  height: auto;
}

:where(body:not(.wp-admin), .editor-styles-wrapper) a { color: inherit; }

:where(body:not(.wp-admin), .editor-styles-wrapper) :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Skip link — visible only when focused. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.focus\:not-sr-only:focus {
  position: static;
  width: auto; height: auto;
  margin: 0; padding: 0.5rem 1rem;
  overflow: visible;
  clip: auto;
  white-space: normal;
}

/* ── Scroll reveal ────────────────────────────────────────────────
   The resting (hidden) state for everything resources/js/animations.js
   observes. Without these rules the observer adds .is-visible to elements
   nothing reacts to and the animation system silently does nothing.

   Class-based, so these are safe to leave unscoped — nothing in the admin
   carries them.
   ─────────────────────────────────────────────────────────────── */

.anim-reveal,
.anim-stagger > * {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.anim-reveal--left  { transform: translateX(-24px); }
.anim-reveal--right { transform: translateX(24px); }
.anim-reveal--scale { transform: scale(0.96); }

.anim-reveal.is-visible,
.anim-stagger > .is-visible {
  opacity: 1;
  transform: none;
}

.anim-img-reveal {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.anim-img-reveal.is-visible {
  clip-path: inset(0 0 0 0);
}

.anim-line::before {
  content: "";
  display: block;
  width: 0;
  height: 2px;
  background: var(--accent);
  transition: width 0.6s ease;
}

.anim-line.is-visible::before { width: 3rem; }

/* Anything animated must have a reduced-motion resting state. animations.js
   also bails early and marks everything visible, but this covers CSS-only cases. */
@media (prefers-reduced-motion: reduce) {
  .anim-reveal,
  .anim-stagger > *,
  .anim-img-reveal {
    opacity: 1;
    transform: none;
    clip-path: none;
    transition: none;
  }
}
