/* ═══════════════════════════════════════════════════════════════
   AFROTUNDA — LABEL 2026 layout & motion utilities
   The only stylesheet in this system that carries rules rather than
   tokens. It exists because two things cannot be expressed in the
   inline styles the components use: media queries and keyframes.
   Component visual styling still lives inline; these classes only
   handle RESPONSIVE COLLAPSE and the subtle reveal.
   Enqueue after styles.css. Safe alongside WooCommerce/Astra — every
   selector is namespaced .af-*.
   ══════════════════════════════════════════════════════════════ */

/* ── Responsive grid. Set --cols inline; steps down on its own. ── */
.af-grid { display: grid; gap: var(--ed-grid-gap); grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); }
.af-grid.af-grid-tight { gap: var(--ed-grid-gap-tight); }
@media (max-width: 1100px) { .af-grid { grid-template-columns: repeat(min(var(--cols, 3), 3), minmax(0, 1fr)); } }
@media (max-width: 860px) { .af-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .af-grid { grid-template-columns: minmax(0, 1fr); } }

/* ── 50/50 split: image and prose stack, image first. ── */
.af-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; }
.af-split > * { min-width: 0; }
@media (max-width: 900px) {
  .af-split { grid-template-columns: minmax(0, 1fr); }
  .af-split > .af-split-media { order: -1; }
  .af-split > .af-split-text { padding: clamp(28px, 6vw, 48px) var(--ed-gutter); }
}

/* ── Lookbook row ──
   Deleted 2026-09-02. `.af-lookbook` was the mixed-span grid whose column
   count was the sum of its frames' spans; the lookbook is a reel now and
   nothing emits the class. The component is `.lb-reel` in label.css. */

/* ── Generic two-column content block (sticky sidebars, buy column). ── */
.af-two { display: grid; grid-template-columns: var(--split, 1fr 1fr); gap: clamp(28px, 5vw, 88px); align-items: start; }
.af-two > * { min-width: 0; }
@media (max-width: 900px) {
  .af-two { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .af-two > .af-sticky { position: static !important; }
}

/* ── Header: the nav becomes a drawer, logo centres. ──
   The desktop nav is still hidden here — it is a hover-and-focus row of links
   with a fan-out panel, and neither gesture exists on a thumb. What is new is
   that something replaces it: until 2026-09-03 this rule hid the nav and left
   nothing behind, so a phone had no navigation at all and the seven collection
   categories were unreachable.

   Three cells: burger, wordmark, cart. `auto 1fr auto` does NOT centre the
   wordmark the way the desktop bar's `1fr auto 1fr` does — the side columns
   are their own widths, so the mark sits centred in what is left rather than
   centred in the bar. That is the right trade here: at 375px the exact centre
   would cost either the burger's touch target or the cart's label, and a mark
   88px wide inside 224px of slack reads as centred anyway. */
@media (max-width: 860px) {
  .af-header-bar {
    grid-template-columns: auto minmax(0, 1fr) auto !important;
    grid-template-areas: "burger mark utils" !important;
  }
  .af-header-nav { display: none !important; }
  .lb-burger { grid-area: burger; }
  .lb-logo { grid-area: mark; justify-self: center; }
  .lb-utils { grid-area: utils; }

  /* The bar keeps the cart and gives up the rest.
     The measurement below records 18px of slack at 375px BEFORE a burger
     existed; the burger needs 44 of them. Account and the EN/NL pair move into
     the drawer, where they are given a row of their own — the cart stays
     because it is the one utility a shopper reaches for mid-visit and it
     carries a count that has to stay visible.
     Selected as "every utility link that is not the bag" rather than by class,
     because the language switch prints two bare anchors with no wrapper of
     their own and giving them one would change the desktop bar's spacing. */
  .lb-utils > a:not(.lb-bag) { display: none; }
}

/* Above the breakpoint exactly one of the two navigations is reachable: the
   bar's row of links. `display: none` takes the drawer out of the
   accessibility tree as well as off the screen, so a screen reader at desktop
   width never meets a duplicate menu — the panel is in the DOM either way,
   because it is one `wp_nav_menu()` call rendered once for both widths.
   Belt and braces beside the `hidden` attribute the script drives: a browser
   resized past the breakpoint mid-session must not leave it standing. */
@media (min-width: 861px) {
  .lb-burger, .lb-drawer { display: none !important; }
}

/* Utilities on a narrow header. Below 860px the nav is gone and the bar is
   just the wordmark and the utility row, so those two carry the full width.
   Adding "Account" to the row put it over: at 375px the pair measured 378px
   against a 335px budget (viewport less two 20px gutters), and the utilities
   pushed out of the bar.

   The gaps tighten and the wordmark steps down rather than anything being
   hidden — the language switch and the cart both matter on mobile, which is
   most of the traffic. Measured after: ~300px against the same 335px budget.

   Re-measured after the 14px type floor (2026-08-26), which took the utilities
   from 0.78rem to 0.875rem: 317px against the same 335px budget. It still fits,
   but the slack is halved — 18px, not 36px. Nothing else goes in this row
   without shortening a label or tightening the gap again.
   Below ~340px the wordmark keeps shrinking instead of overflowing. */
@media (max-width: 480px) {
  .af-header-bar { gap: 12px !important; }
  .lb-utils { gap: 12px; min-width: 0; }
  .lb-logo { min-width: 0; }
  .lb-logo img { height: 34px; max-width: 100%; object-fit: contain; }
}

/* ── Footer columns become accordions under 760px. ── */
.af-fcol-toggle { display: none; }
.af-fcol-body { display: block; }
@media (max-width: 760px) {
  .af-footer-grid { grid-template-columns: minmax(0, 1fr) !important; }
  .af-fcol { border-top: 1px solid var(--ed-line); }
  .af-fcol-head { display: none !important; }
  .af-fcol-toggle { display: flex !important; }
  .af-fcol-body { display: none; }
  .af-fcol-body.is-open { display: block; }
}

/* ── Sticky rails give up gracefully on short viewports. ── */
@media (max-height: 620px) { .af-sticky { position: static !important; } }

/* ═══ Motion — deliberately almost imperceptible ═══
   6px of travel and an opacity fade over 0.7s. No scale, no blur,
   no stagger beyond 60ms. If you can clearly see it happen, it is
   too much for this brand. */
@keyframes af-rise { from { opacity: 0; transform: translateY(var(--ed-reveal-offset, 6px)); } to { opacity: 1; transform: none; } }
@keyframes af-fade { from { opacity: 0; } to { opacity: 1; } }

.af-reveal { opacity: 1; }
.js .af-reveal { opacity: 0; }
.js .af-reveal.af-in { animation: af-rise var(--ed-reveal-dur, 0.7s) var(--ed-ease, ease-out) both; }

/* Images settle in as they decode — one fade, no movement. */
.af-media img { animation: af-fade 0.5s var(--ed-ease, ease-out) both; }

/* Hovering a grid quiets its siblings by a hair.
   0.82 was the readme's prose figure; --ed-hover-dim is the token, and the
   editorial-interaction guideline card uses it too. The token wins. */
.af-quiet-siblings:hover > * { opacity: var(--ed-hover-dim, 0.72); }
.af-quiet-siblings > * { transition: opacity var(--ed-dur, 0.4s) var(--ed-ease, ease); }
.af-quiet-siblings:hover > *:hover { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .af-reveal, .js .af-reveal, .js .af-reveal.af-in { opacity: 1; animation: none; }
  .af-media img { animation: none; }
  .af-quiet-siblings:hover > * { opacity: 1; }
}
