/* ==========================================================================
   parts/buttons.css — Monarch button system v2 (docs/design/BUTTONS.md §4.2, as amended by
   docs/design/UPGRADE-SPEC.md A-B1…A-B4). Tokens: tokens.css "Buttons v2".
   Markup (parts/button.php):
     <a class="btn btn--{primary|secondary} [btn--on-light] [btn--sm|btn--lg] [btn--glow] [btn--block] [btn--tight] <bem>">
   Styles    .btn--primary     solid brand gradient, white label
             .btn--secondary   2px #1263FF outline, white label
             .btn--on-light    surface modifier for white / grey surfaces: secondary → 2px #002D80 outline and label
             .btn--on-photo    surface modifier for busy photos: secondary gets a translucent navy backing (AA label)
   Hover     one language for every style: a fill wipes in from the left under the label (MX .btn--wipe).
             Dark / photo / brand surfaces: ice #E6EEFF fill, navy label, #1263FF ring.
             Light surfaces (.btn--on-light): ink #002D80 fill, white label. Keyboard focus shows the same fill.
   Sizes     .btn--sm 32 · md (no class) 44 · .btn--lg 56 px tall, whatever the style
   Mods      .btn--glow   static halo + a ring that breathes outwards (big CTAs only)
             .btn--block  full width         .btn--tight  ≤478px: 16px side padding, no min-width
   Layers    ::before = the wipe fill (z -1, clip-path), ::after = the glow ring (z -2, transform + opacity).
             The label is the element's own text, painted above both; the border is outside ::before.
   Blocks tune geometry only, through --btn-h / --btn-padding-inline / --btn-min-width / --btn-font-size
   ("Buttons v2 lock" comments in the block / part CSS). Never a translate / scale / rotate at rest: GSAP owns
   transform during a reveal, and the hover lift is the individual `translate` property (UPGRADE-SPEC C6).
   The Fluent submit (.frm-fluent-form .ff-btn-submit) is listed next to .btn: its markup is Fluent's (on
   WordPress too) and cannot take our classes. It is a primary md button.
   ========================================================================== */

/* ---- 1. Base: md, primary, dark surface ------------------------------------------------------------ */
.btn,
.frm-fluent-form .ff-btn-submit {
  --btn-h: var(--btn-md-h);
  --btn-font-size: var(--btn-md-font);
  --btn-padding-inline: var(--btn-md-pad-x);
  --btn-padding-block: calc((var(--btn-h) - var(--btn-font-size) * var(--btn-line-height) - 2 * var(--btn-border-width)) / 2);
  --btn-bg: var(--btn-primary-bg);
  --btn-border: transparent;
  --btn-text: var(--btn-primary-text);
  --btn-wipe: var(--btn-wipe-deep);                    /* base = primary look: deeper blue sweep */
  --btn-text-hover: var(--btn-wipe-text);
  --btn-border-hover: var(--btn-outline);
  --btn-glow-sy: 1.64;                                 /* ring scale fallback (md); animations.js sets the exact pair */
  --focus-color: var(--btn-focus-dark);

  position: relative;
  isolation: isolate;                                  /* keeps the ::before / ::after layers inside the button */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  max-width: 100%;
  min-inline-size: var(--btn-min-width);
  margin: 0;
  padding: var(--btn-padding-block) var(--btn-padding-inline);
  border: var(--btn-border-width) solid var(--btn-border);
  border-radius: var(--btn-radius);
  background: var(--btn-bg) border-box;                /* runs under the transparent border: no seam, no repeat */
  color: var(--btn-text);
  font-family: var(--btn-font-family);
  font-size: var(--btn-font-size);
  font-style: normal;
  font-weight: var(--btn-font-weight);
  line-height: var(--btn-line-height);
  letter-spacing: var(--btn-letter-spacing);
  text-align: center;
  text-decoration: none;
  text-transform: var(--btn-text-transform);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--btn-wipe-dur) var(--btn-wipe-ease),
              border-color var(--btn-wipe-dur) var(--btn-wipe-ease),
              translate .25s ease;
}

/* ---- 2. Wipe: a ROUND fill that grows from where the pointer enters (Pete, 2026-09-29) ----------------
        At rest ::before is clipped to circle(0) at the entry point. assets/js/parts/button-wipe.js (fine pointers)
        moves that point to where the mouse lands, then adds .is-wiping: the circle grows to --wipe-r (the distance
        to the farthest corner, so it always covers the button). Pointer-out collapses it toward the exit point.
        The fill keeps the button's rounded corners (border-radius on ::before). Keyboard focus grows it from the
        centre. Without the script (no JS / failed load) :hover grows it from the left edge, as before. */
.btn::before,
.frm-fluent-form .ff-btn-submit::before {
  content: "";
  position: absolute;
  inset: 0;                                            /* the padding box: the 2px border stays visible around it */
  z-index: -1;
  border-radius: max(0px, calc(var(--btn-radius) - var(--btn-border-width)));
  background: var(--btn-wipe);
  clip-path: circle(0px at var(--wipe-x, 0px) var(--wipe-y, 50%));
  transition: clip-path var(--btn-wipe-circle-dur, .6s) var(--btn-wipe-circle-ease, cubic-bezier(.22, 1, .36, 1));
  pointer-events: none;
}
.btn.is-wipe-reset::before,
.frm-fluent-form .ff-btn-submit.is-wipe-reset::before { transition: none; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover,
  .frm-fluent-form .ff-btn-submit:hover {
    color: var(--btn-text-hover);
    border-color: var(--btn-border-hover);
    translate: 0 -2px;                                 /* MX lift. `translate` composes with GSAP's inline transform */
  }
  html:not(.has-wipe-js) .btn:hover::before,
  html:not(.has-wipe-js) .frm-fluent-form .ff-btn-submit:hover::before { clip-path: circle(150% at 0px 50%); }
  .btn.is-wiping::before,
  .frm-fluent-form .ff-btn-submit.is-wiping::before {
    clip-path: circle(var(--wipe-r, 150%) at var(--wipe-x, 0px) var(--wipe-y, 50%));
  }
}
.btn:focus-visible,
.frm-fluent-form .ff-btn-submit:focus-visible {
  color: var(--btn-text-hover);
  border-color: var(--btn-border-hover);
}
.btn:focus-visible:not(.is-wiping)::before,
.frm-fluent-form .ff-btn-submit:focus-visible:not(.is-wiping)::before { clip-path: circle(72% at 50% 50%); }
.btn:active,
.frm-fluent-form .ff-btn-submit:active { translate: none; }
@media (prefers-reduced-motion: reduce) {
  .btn::before,
  .frm-fluent-form .ff-btn-submit::before { transition: none; }
}
html.nomotion .btn::before,
html.nomotion .frm-fluent-form .ff-btn-submit::before { transition: none; }

/* ---- 3. Styles ------------------------------------------------------------------------------------- */
.btn--primary {
  --btn-bg: var(--btn-primary-bg);
  --btn-border: transparent;
  --btn-text: var(--btn-primary-text);
  --btn-wipe: var(--btn-wipe-deep);
}
.btn--secondary {
  --btn-bg: transparent;
  --btn-border: var(--btn-outline);
  --btn-text: var(--btn-outline-text);
  --btn-wipe: var(--btn-wipe-blue);                    /* fills to the brand blue gradient */
}
/* Surface modifier: white / grey / light-photo surfaces. Same blue hover as everywhere (white label); ink outline
   + ink label at rest for secondary, and the ink focus ring. */
.btn--on-light {
  --btn-text-hover: var(--btn-wipe-text);
  --btn-border-hover: var(--btn-outline);
  --focus-color: var(--btn-focus-light);               /* #B3CDFF is 1.6:1 on white; ink is ≥ 5.9:1 on every light surface */
}
.btn--secondary.btn--on-light {
  --btn-border: var(--btn-ink);
  --btn-text: var(--btn-ink);
  --btn-wipe: var(--btn-wipe-blue);
}
/* Surface modifier: a busy photo right behind a secondary (S2 tiles). Dark-surface hover; the transparent rest
   fill becomes a translucent navy backing so the white label stays ≥ 4.5:1 over the photo's light patches. */
.btn--secondary.btn--on-photo { --btn-bg: var(--btn-scrim); }

/* ---- 4. Sizes (md is the base) --------------------------------------------------------------------- */
.btn--sm {
  --btn-h: var(--btn-sm-h);
  --btn-font-size: var(--btn-sm-font);
  --btn-padding-inline: var(--btn-sm-pad-x);
  --btn-glow-sy: 1.88;
}
.btn--lg {
  --btn-h: var(--btn-lg-h);
  --btn-font-size: var(--btn-lg-font);
  --btn-padding-inline: var(--btn-lg-pad-x);
  --btn-glow-sy: 1.5;
}
.btn--block {
  display: flex;
  width: 100%;
}
/* live .wlp-btn: phones get 16px side padding and no min-width (header "Call now", hero "Enquire now") */
@media (max-width: 478px) {
  .btn--tight {
    --btn-padding-inline: 1.6rem;
    --btn-min-width: 0px;
  }
}

/* ---- 5. Glow (big CTAs): a static halo + a ring that breathes outwards (MX btn-pulse) -----------------
   Only transform and opacity animate (the ring layer is composited); the halo is a static box-shadow.
   --btn-glow-sx / -sy scale the border-box ring so it travels --btn-glow-spread out on every side:
   animations.js sets the exact pair per button; the CSS fallback is per size (sx 1.08 ≈ a 350px button).
   The ring runs only in motion mode (no reduced motion, no ?nomotion=1); the halo shows in every mode. */
.btn--glow,
body .btn--glow:focus:not(:focus-visible) { box-shadow: var(--btn-glow-halo); }   /* base.css strips box-shadow
                                                            from mouse-focused elements at (0,2,1) (A-B2) */
.btn--glow::after {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--btn-border-width));           /* the border box */
  z-index: -2;
  border-radius: var(--btn-radius);
  box-shadow: var(--btn-glow-ring);
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  html:not(.nomotion) .btn--glow::after {
    animation: btn-glow var(--btn-glow-dur) var(--btn-glow-ease) infinite;
    will-change: transform, opacity;
  }
  /* the ring stops on focus / press (MX); (0,3,2) beats the animation rule's (0,2,2) (A-B1) */
  html:not(.nomotion) .btn--glow:is(:focus-visible, :active)::after { animation: none; }
}
@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
  html:not(.nomotion) .btn--glow:hover::after { animation: none; }   /* the ring stops while the wipe plays (MX) */
}
@keyframes btn-glow {
  0%        { opacity: 0; transform: none; }
  10%       { opacity: 1; }
  70%, 100% { opacity: 0; transform: scale(var(--btn-glow-sx, 1.08), var(--btn-glow-sy, 1.64)); }
}
/* Paused until the button has been revealed (.is-reveal-waiting on it or on its reveal ancestor), and while it
   is off-screen or entirely under the compact header (.is-glow-idle, animations.js initGlow). Motion mode only:
   the ring does not run otherwise. (0,3,2) beats the animation rule (0,2,2). UPGRADE-SPEC C2 / C5 (A-B3). */
@media (prefers-reduced-motion: no-preference) {
  html:not(.nomotion) .btn--glow:is(.is-reveal-waiting, .is-glow-idle)::after,
  html:not(.nomotion) .is-reveal-waiting .btn--glow::after { animation-play-state: paused; }
}

/* ---- 6. Reduced motion: the fill still shows on hover / focus, at once; no lift ---------------------- */
@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn::before,
  .frm-fluent-form .ff-btn-submit,
  .frm-fluent-form .ff-btn-submit::before { transition: none; }
  .btn:hover,
  .frm-fluent-form .ff-btn-submit:hover { translate: none; }
}

/* ---- 6b. Forced colours: system colours replace ours; keep a visible edge, drop the decorative layers (A-B4) */
@media (forced-colors: active) {
  .btn,
  .frm-fluent-form .ff-btn-submit { border-color: ButtonText; }
  .btn::before,
  .frm-fluent-form .ff-btn-submit::before,
  .btn--glow::after { display: none; }
}

/* ---- 7. Transition aliases: old class combinations keep working and get the v2 look. -----------------
        Remove this section when `grep -rnE "btn--(outline|primary-dark|compact|v1|pad-12|l|m)\b"` over
        parts/ blocks/ templates/ inc/ data/ finds nothing (docs/design/BUTTONS.md §8). */
.btn--primary.btn--outline {                            /* old variant 'outline' → secondary */
  --btn-bg: transparent;
  --btn-border: var(--btn-outline);
  --btn-text: var(--btn-outline-text);
  --btn-wipe: var(--btn-wipe-blue);
}
.btn--primary-dark.btn--outline {                       /* old variant 'outline-dark' → secondary on light */
  --btn-bg: transparent;
  --btn-border: var(--btn-ink);
  --btn-text: var(--btn-ink);
  --btn-wipe: var(--btn-wipe-blue);
  --btn-text-hover: var(--btn-wipe-text);
  --btn-border-hover: var(--btn-outline);
  --focus-color: var(--btn-focus-light);
}
.btn--compact { --btn-h: var(--btn-sm-h); --btn-font-size: var(--btn-sm-font); --btn-padding-inline: var(--btn-sm-pad-x); }
.btn--l { --btn-h: var(--btn-lg-h); --btn-font-size: var(--btn-lg-font); --btn-padding-inline: var(--btn-lg-pad-x); }
/* .btn--m, .btn--pad-12, .btn--v1 are retired with no rule: the button renders at its size. */
