/* ============ CANONICAL BUTTON TIER — ONE component, TWO variants ============
   Every filled interactive element on the site is the SAME button, rendered in one of two
   variants. The variant is a flag, not a second implementation: it sets four colour tokens
   and nothing else, so primary and secondary can never drift in geometry, type, brush or
   motion again.

     PRIMARY  (black fill) .cta, .corner-cta, and the active/selected chips
                           .chip.on / .subchip.on (nav rail), .fchip.on (Expertise
                           filters), .cbtn.sel (Get in touch options)
                           --btn-fill #242424 · --btn-ink #FFFFFF · --btn-brush #F1BE48
     SECONDARY (yellow fill) .btn-sec — the fixed top-right "Get in Touch" CTA, the
                           mobile menu overlay's "Get in Touch" button, and Get in touch's
                           top-right "Menu" trigger (MenuPanel .mpbtn)
                           --btn-fill #F1BE48 · --btn-ink #242424 · --btn-brush #242424

   Shared by BOTH variants, defined here only: label colour, fill, hover fill, brush colour,
   brush geometry + draw/retract timing, focus ring colour, motion, and the hover bounce.
   Geometry that is genuinely per-slot (padding, font-size for the small chips) stays with the
   component; the two variants of the nav CTA slot share ONE box rule in Nav.dc.html
   (.btn-sec,.cta.navcta), so equal labels render at equal size.

   Treatment (source of truth: the Intro "See my work" button):
     rest ........... --btn-fill, --btn-ink label at full opacity
     hover .......... bounce (translateY(-2px), see the bounce tier below) + fill lifts to
                      --btn-fill-hover + --btn-brush sweeps in behind the label (.35s in /
                      .2s out, inside .t so it underlines the text only)
     focus-visible .. fill lift + brush sweep + ring, NO bounce (the bounce is hover-only)
   The label NEVER dims, recolours, or hides; the brush sits behind the glyphs (z-index:-1
   inside .t, .t itself z-index:1 above the fill).

   Selectors are tripled with :is() (specificity 0,6,0) so this tier outranks any page-level
   link or component rule (pages demote theirs with :where()) regardless of load order.
   Contact's .afq (post-click focus quiet) is exempt from focus treatment only.
   Do NOT add per-page or per-element hover rules for these classes — edit here.
   Linked from every page's helmet directly after scale.css. */

/* ---- variant flag: the ONLY thing that differs between primary and secondary ---- */
:is(.cta,.corner-cta,.chip.on,.subchip.on,.fchip.on,.cbtn.sel){--btn-fill:#242424;--btn-fill-hover:#3a3a3a;--btn-ink:#FFFFFF;--btn-brush:#F1BE48;--btn-ring:#F1BE48}
:is(.btn-sec){--btn-fill:#F1BE48;--btn-fill-hover:#F6CB60;--btn-ink:#242424;--btn-brush:#242424;--btn-ring:#242424}

/* ---- bounce parameters: ONE implementation, one amplitude knob ----
   --btn-bounce-full  travel for buttons and selection chips (the primary's existing lift)
   --btn-bounce-scale small-element share of it (nav items, filter labels) = 60%
   --btn-bounce-dur / -ease  the primary's existing timing, identical at both amplitudes */
:root{--btn-bounce-full:2px;--btn-bounce-scale:.6;--btn-bounce-dur:.5s}

/* Label: full-opacity variant ink in every state (pins <a>-rendered buttons past page a:hover rules) */
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel),
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(:link,:visited,:hover,:focus,:focus-visible,:active){color:var(--btn-ink);text-decoration:none}

/* Fill (buttons only; the chips' own rules own their unfilled states) */
:is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec){background:var(--btn-fill)}
:is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec)::after{box-shadow:inset 0 0 0 2px var(--btn-ring)}

/* Label above the brush; brush behind the glyphs, above the fill */
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel) .t{position:relative;z-index:1}
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel) :is(.bfill,.bsfill,.cfill){color:var(--btn-brush)}
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel) .t :is(.bfill,.bsfill,.cfill){z-index:-1}
/* Brush geometry + retract timing, shared by both button variants (the small chips keep
   their own slightly tighter stroke box) */
:is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec):is(.cta,.corner-cta,.btn-sec) :is(.bfill,.bsfill,.cfill){position:absolute;left:-4px;right:-4px;bottom:-2px;height:6px;z-index:-1;-webkit-clip-path:inset(0 100% 0 0);clip-path:inset(0 100% 0 0);transition:clip-path .2s cubic-bezier(.4,0,.6,1)}
:is(.bfill,.bsfill,.cfill) svg{display:block;width:100%;height:100%}
:is(.bfill,.bsfill,.cfill) path{fill:currentColor}

/* Canonical motion (no opacity here — .wcta keeps its scene-reveal transition;
   .cbtn.sel keeps its selection-morph list, transform appended below) */
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on):not(.wcta){transition:background .5s var(--ease,ease),color .3s var(--ease,ease),transform var(--btn-bounce-dur) var(--ease,ease)}
/* Unfilled members of the bounce tier keep their own background/colour timing and gain the
   same travel, so the bounce is identical everywhere */
:is(.chip:not(.on),.subchip:not(.on),.fchip:not(.on),.cbtn:not(.sel)):is(.chip:not(.on),.subchip:not(.on),.fchip:not(.on),.cbtn:not(.sel)):is(.chip:not(.on),.subchip:not(.on),.fchip:not(.on),.cbtn:not(.sel)){transition:background .3s var(--ease,ease),color .3s var(--ease,ease),transform var(--btn-bounce-dur) var(--ease,ease)}

/* ---- HOVER BOUNCE — the shared implementation, hover only ----
   Gated on a real hovering pointer: touch devices never bounce (their existing tap feedback
   is untouched), and it never fires on focus or press. Amplitude is the only variable. */
:is(.chip,.subchip,.fchip):is(.chip,.subchip,.fchip):is(.chip,.subchip,.fchip){--btn-bounce:calc(var(--btn-bounce-full) * var(--btn-bounce-scale))}
@media (hover:hover) and (pointer:fine){
:is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):hover{transform:translateY(calc(-1 * var(--btn-bounce,var(--btn-bounce-full))))}
}

/* ---- DISABLED VARIANT — one state flag on the same component ----
   For a CTA whose destination does not exist yet (today: the seven unbuilt books on About's
   shelf). NOT a third variant: it re-points the SAME four colour tokens at the system's
   disabled tokens, so geometry, type, radius, position and appearance timing are untouched.
   Solid fill --color-fill-disabled (#F5F5F5) with --color-text-disabled (#A4A7AE) at FULL
   opacity — never an alpha/opacity reduction, so the state stays legible and does not
   fluctuate with the cover behind it (disabled controls are exempt from WCAG 1.4.3 text
   contrast, inactive-component exception); the brush stroke is removed entirely for this
   state (token transparent AND the element hidden), and the fill no longer lifts on hover.
   The hover BOUNCE is deliberately kept: it is what tells the visitor the object is alive,
   just not open yet.
   Contract: .btn-dis (and/or aria-disabled="true") on the button, with its click handler
   suppressed in JS. A real disabled attribute is avoided on purpose — browsers stop
   dispatching pointer events to it, which would kill :hover and with it the bounce.
   Applies to both variants; any future disabled CTA inherits this by carrying the flag. */
:root{--color-fill-disabled:#F5F5F5;--color-text-disabled:#A4A7AE}
:is(.cta,.corner-cta,.btn-sec):is(.btn-dis,[aria-disabled="true"]){--btn-fill:var(--color-fill-disabled);--btn-fill-hover:var(--color-fill-disabled);--btn-ink:var(--color-text-disabled);--btn-brush:transparent;--btn-ring:transparent;cursor:not-allowed}
:is(.cta,.corner-cta,.btn-sec):is(.btn-dis,[aria-disabled="true"]) :is(.bfill,.bsfill,.cfill){display:none}

/* ---- SCROLL-HINT NUDGE (mobile dead-end pages) ----
   A page whose boundary scroll cannot advance anywhere pulses its end-of-page CTA: the SAME
   travel as the hover bounce (--btn-bounce-full), lifted three times with a small pause
   between each, so it reads as a nudge toward the button rather than a twitch. Pages add
   .nudge from JS (throttled, >=1.5s apart, only on a genuine extra scroll attempt at the
   boundary) and remove it on animationend. Reduced motion: no movement at all. */
@keyframes btn-nudge{0%,24%,38%,62%,76%,100%{transform:translateY(0)}12%,50%,88%{transform:translateY(calc(-1 * var(--btn-bounce-full)))}}
:is(.cta,.btn-sec).nudge{animation:btn-nudge 1.8s var(--ease,ease)}
@media (prefers-reduced-motion:reduce){:is(.cta,.btn-sec).nudge{animation:none}}

/* Hover / keyboard focus: fill lifts; the label is untouched. No transform on focus. */
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):hover,
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):focus-visible:not(.afq){background:var(--btn-fill-hover)}

/* Brush sweep behind the label */
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):hover :is(.bfill,.bsfill,.cfill),
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):focus-visible:not(.afq) :is(.bfill,.bsfill,.cfill){-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0);opacity:1;transition:clip-path .35s cubic-bezier(.2,.7,.3,1)}

/* Selected contact chips: brush parks closed at rest so the canonical sweep plays on hover */
.cbtn.sel.sel.sel .cfill{opacity:1;-webkit-clip-path:inset(0 100% 0 0);clip-path:inset(0 100% 0 0);transition:clip-path .2s cubic-bezier(.4,0,.6,1)}
.cbtn.sel.sel.sel:hover,.cbtn.sel.sel.sel:focus-visible:not(.afq){transition:background .5s var(--ease,ease),color .3s var(--ease,ease),transform var(--btn-bounce-dur) var(--ease,ease),box-shadow .3s var(--ease,ease)}

@media (prefers-reduced-motion:reduce){
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel),
:is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel):is(.cta,.corner-cta,.btn-sec,.chip.on,.subchip.on,.fchip.on,.cbtn.sel) :is(.bfill,.bsfill,.cfill){transition:none}
:is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):is(.cta,.corner-cta,.btn-sec,.cbtn,.chip,.subchip,.fchip):hover{transform:none}
}
