/* APED — listings in full colour, and the "Pay with" chips.
 *
 * Own lane: nothing here touches the mirror's own stylesheet
 * (site/assets/index.dc7c478f.css), which stays byte-identical to the original.
 * The build only links this file when content/fx.json turns something on, so a
 * visitor with fx off makes ZERO requests to /fx/.
 *
 * Flat landing colours only (red #6a0000, white, black). No fill gradients, no
 * glassmorphism: depth comes from a layered shadow with ONE light direction (top).
 */

/* ---------------------------------------------------------------------------
   1. "Our Partners" cards in full colour
   ---------------------------------------------------------------------------
   Cause of the red tint, measured in the DOM: every `.partner__image` holds TWO
   copies of the same photo, and the mirror's own stylesheet says

       .partner__image img:nth-child(2) { filter: url(#duotone); }

   so the second copy — an SVG <filter id="duotone"> that maps the photo onto the
   theme's two-colour ramp — sits on top of the untouched one and is what you see.
   The site's own hover already knows how to reveal the colour underneath:

       .partner:hover .partner__image img:nth-child(2) { opacity: 0 }

   So "always in colour" is that same hover state made permanent. Fading the
   duotone copy out (instead of dropping it with `display:none`) keeps the node,
   its box and the `.partners.in-view` entrance animation exactly as they were —
   only the pixels change. The hover pill (`.partner__name`) and its transition
   are untouched: they live on `.partner`, not on the image. */
[data-hape-fx-listings='full-color'] .partner__image img:nth-child(2) {
  opacity: 0;
}

/* ---------------------------------------------------------------------------
   2. animated-icon size system (XS inline · S chips · M headings · L graphic)
   ---------------------------------------------------------------------------
   XS and S are sized in `em` on purpose: they ride the line-height of the text
   they sit next to, so inserting one never changes the height of its line. */
.fx-ai {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
  flex: none;
  line-height: 0;
  vertical-align: -0.16em;
}
.fx-ai svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.fx-ai svg [data-fxp] {
  stroke-width: var(--fxi-sw, 2);
  vector-effect: non-scaling-stroke;
}
/* the compositor only gets a layer while something is actually animating */
.fx-ai.is-busy svg [data-fxp] {
  will-change: transform, opacity, stroke-dashoffset;
}

.fx-ai-xs { width: 1em;     height: 1em;     --fxi-sw: 2; }
.fx-ai-s  { width: 1.15em;  height: 1.15em;  --fxi-sw: 2; }
.fx-ai-m  { width: 30px;    height: 30px;    --fxi-sw: 1.6; }
.fx-ai-l  { width: 96px;    height: 96px;    --fxi-sw: 1.5; }

/* --- M next to a content block's eyebrow ---------------------------------
   The eyebrow is a 9px Integral CF line with 30px of margin under it. Laying it
   out as a flex row puts the mark optically centred on that line instead of
   above it, and the icon inherits the eyebrow's own GSAP reveal (the site sets
   `opacity`/`visibility` inline on the <p>, never `display`, so this is safe). */
.content-block__eyebrow[data-hape-fx='eyebrow'] {
  display: flex;
  align-items: center;
  gap: 12px;
}
.content-block__eyebrow[data-hape-fx='eyebrow'] .fx-ai-m {
  /* the eyebrow is 40 % white; the mark carries the block's full ink */
  color: var(--content-block-title, currentColor);
  opacity: 0.9;
}

/* --- S inside a roadmap item's title -------------------------------------- */
.roadmap-item__title[data-hape-fx='roadmap'] {
  display: flex;
  align-items: center;
  gap: 0.55em;
}
/* the roadmap title drops to 12px on a phone, and a 12px box turns a multi-stroke
   figure into mush: the mark never goes below 15px, whatever the type does */
.roadmap-item__title[data-hape-fx='roadmap'] .fx-ai {
  width: max(1.15em, 15px);
  height: max(1.15em, 15px);
  opacity: 0.85;
}

/* ---------------------------------------------------------------------------
   3. "Pay with" chips
   --------------------------------------------------------------------------- */
.fx-pay {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 26px;
  /* the row must never eat a wheel event meant for the scene behind it */
  pointer-events: none;
}
/* the label sits on its own line, in the same ink as the block's body copy, so the
   two chips get the full width and never break mid-row */
.fx-pay__label {
  flex-basis: 100%;
  margin: 0 0 10px;
  font-family: 'Integral CF', Helvetica, Arial, sans-serif;
  font-size: 0.5625rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--content-block-text, currentColor);
}
.fx-pay__chip {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 14px 0 8px;
  border-radius: 20px;
  border: 1px solid rgba(0, 0, 0, 0.12);
  background-color: #fff;
  color: #000;
  font-family: 'Druk Text Wide', Helvetica, Arial, sans-serif;
  font-size: 0.5625rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
  /* one light source, straight above: contact, ambient, cast */
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.11),
    0 2px 4px rgba(0, 0, 0, 0.09),
    0 6px 12px -5px rgba(0, 0, 0, 0.22);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.fx-pay__chip:hover {
  transform: translateY(-2px);
}
/* the third-party mark keeps its own artwork and its own aspect ratio: fixed
   height, automatic width, never stretched and never recoloured */
.fx-pay__logo {
  display: block;
  height: 22px;
  width: auto;
  border-radius: 50%;
  flex: none;
  user-select: none;
  -webkit-user-drag: none;
}
.fx-pay__chip .fx-ai {
  color: #000;
  opacity: 0.75;
}

/* a row pinned inside a content block goes away with the copy it belongs to: the
   block itself is `position: fixed` and stays put all the way down the page */
.fx-pay--tied {
  visibility: hidden;
  transition: visibility 0s linear 0.5s;
}
.fx-pay--tied.is-in {
  visibility: visible;
  transition-delay: 0s;
}

/* entrance: fade + 12 px, 500 ms, the site's own curve, 60 ms apart */
.fx-pay__item {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i, 0) * 60ms);
}
.fx-pay.is-in .fx-pay__item {
  opacity: 1;
  transform: translateY(0);
}

/* in the open menu the row sits at the end of the footer line, beside the
   trailer button, and reads on the same ink as the rest of the menu */
.site-menu__footer .fx-pay {
  margin-top: 0;
  margin-left: auto;
  align-self: center;
}

@media (max-width: 767px) {
  .fx-pay {
    gap: 8px;
    margin-top: 20px;
  }
  .fx-pay__chip {
    height: 30px;
    padding: 0 11px 0 6px;
    font-size: 0.5rem;
  }
  .fx-pay__logo {
    height: 19px;
  }
  .site-menu__footer .fx-pay {
    margin-left: 0;
    margin-top: 18px;
    width: 100%;
  }
  .content-block__eyebrow[data-hape-fx='eyebrow'] {
    gap: 10px;
  }
  .content-block__eyebrow[data-hape-fx='eyebrow'] .fx-ai-m {
    width: 24px;
    height: 24px;
  }
}

/* ---------------------------------------------------------------------------
   4. reduced motion: everything already drawn, nothing looping
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .fx-ai svg [data-fxp] {
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
  }
  .fx-pay__item,
  .fx-pay.is-in .fx-pay__item {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .fx-pay__chip {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   5. the loading screen's logo box is never the old sprite, not for one frame
   ---------------------------------------------------------------------------
   /fx/logo.js puts the APED lockup INSIDE the mirror's `<div class="logo-sprite">`
   and switches the original artwork off with `.logo-sprite[data-hape-logo-host]
   {background-image:none}` — but that rule only exists once the node has been
   mounted, and the loader's box is on screen (painted with the animated "Hape®"
   WebP) from Vue's very first frame. The visitor read the old letters and then
   watched them flick to APED.

   So the loader's slot — and ONLY the loader's slot, the header and the menu are
   revealed later by the site itself and are gated for the WebGL resize trap — is
   emptied statically, with no JavaScript in the way. `html.aped-brand-loader-off`
   is written inline by the build (tools/build.mjs, fxTags) when `brand.loader`
   (or `logo.enabled`) is false, which puts the mirror's own sprite back.

   The same rule is in the <style> logo.js writes at boot, because this sheet is
   loaded the non-blocking way (preload + rel swap) and cannot promise frame 0 on
   its own. Two copies of four declarations, and the box itself never moves. */
html:not(.aped-brand-loader-off) .site-loader__logo .logo-sprite {
  background-image: none !important;
}
