/* ==========================================================================
   LHB CTA BUTTON
   Ported from a frame-by-frame reverse-engineering of button-ui-reference.mp4
   (1080x1080, 60fps, 973 frames, 4 full interaction cycles).
   Derivation: Desktop/lhb-button/BUTTON-SPEC.md — keep it with this file.

   Video-pixel -> CSS-pixel scale factor: 3.208  (pill 707vpx -> 220px)

   WHAT IS MEASURED AND MUST NOT BE "TIDIED"
     - The button DESCENDS on interaction. Rest is a large soft floating
       shadow; hover is a tight contact shadow (it settles onto the page);
       press is ZERO outer shadow plus inset edge darkening. This is not an
       inverted hover-lift that someone forgot to fix. It is the reference.
     - The dashed ring DOES NOT ROTATE. Verified by cross-correlating the
       polar unwrap across eight frames: the apparent motion is film grain.
     - Press transitions are 0ms on BOTH edges. :active cannot handle the
       release, hence the is-releasing class driven by assets/js/cta.js.
       Without JS the CSS still works; only the release animates.
     - letter-spacing .19em, stroke-dasharray "2.927 1.830", the 14-stop
       surface gradient and the 480ms-in / 370ms-out asymmetry are all
       measured. They look like they want rounding. They do not.

   WHAT WAS CHANGED FOR THIS PROJECT — and why. Nothing geometric moved.
     1. HUE. The reference knob is violet (#5C12C4 body, #E2C9FC chevron,
        #DBC1F6 ring, #7B10E8 glow). design-system.md § M2 permits ONE accent
        and LH spends it on --gold, so the violet family is remapped to a
        polished gold. Every gradient keeps its measured stop OFFSETS and
        OPACITIES; only the colours at those stops move. The luminance ramp
        of the original is preserved, so the modelling reads the same.
     2. TYPEFACE. The reference CSS asks for Inter. Inter is not loaded by
        this project and design-system.md:40 forbids a third family, so the
        label runs on Archivo. Cap height is the thing being held constant:
        measured cap is 10.9px; Inter's cap ratio is .7275 (-> 15px, which is
        where the spec's 15px came from) and Archivo's is .686, so Archivo
        needs 15.9px for the same cap. See § label.
     3. max-width:none on the knob svg. system.css:51 sets a global
        img,svg,video{max-width:100%}, which resolves against the 54px knob
        and clamps the deliberately oversized 82px svg — the blur is supposed
        to spill past the disc. Without this the knob renders as an ellipse.
     4. VARIANTS. The measured 220x72 baseline is untouched and remains the
        default. Everything that needs a different size overrides the custom
        properties in a modifier, per the spec's tuning contract.
   ========================================================================== */

/* --- 0. Shared defs ------------------------------------------------------ */
/* The gradients and the blur filter live in one <svg> per page, emitted as the
   first thing in <body>, outside .viewport. Taken out of flow here rather than
   with an inline style: dropped into a flex container in flow it would become
   a flex item and collect the container's gap as dead space. */
.lhb-cta-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* --- 1. The measured baseline ------------------------------------------- */

/* The component sets its own display, which outranks the UA's
   [hidden]{display:none} — so `hidden` on one of these would do nothing at
   all. system.css § 7 carries the same rule for .btn, and for the same
   reason: the Work pane (§ 19) hides its book CTA until a look exists. */
.lhb-cta[hidden] { display: none; }


.lhb-cta {
  /* ---- geometry ------------------------------------------------------- */
  /* pill 707x231vpx; knob 174vpx dia, centre (778.5, 540.5), inset ~28vpx  */
  /* Measured: 220x72, knob 54 dia inset 9, label 28 from the left edge.
     LH ships it SLIM — 52px. 72 read bulky in place and so did 62; this is the
     third pass and it is a deliberate departure from the measured height, not
     a rounding of it. Everything else about the object is held: the knob keeps
     the reference's ~0.75 knob:height ratio (54/72 -> 38/52) so it still fills
     the pill the way the original does, the 8px inset scales with it, and the
     label does NOT shrink to match — holding type at 15px against a 52px pill
     is what keeps it reading as a slim button rather than a small one.
     Still above the project's 44px minimum target (system.css:234).
     .lhb-cta--reference restores every measured value verbatim. */
  --lhb-w: 216px;
  --lhb-h: 52px;
  --lhb-knob: 38px;
  --lhb-knob-inset: 7px;
  --lhb-pad-left: 22px;

  /* ---- motion ---------------------------------------------------------- */
  /* hover-in  f76->f105  = 29 frames = 483ms                                */
  /* hover-out f230->f252 = 22 frames = 367ms                                */
  /* press: instant both ways, held 150-200ms (real clicks in the recording) */
  --lhb-in: 480ms;
  --lhb-out: 370ms;
  --lhb-ease: cubic-bezier(0.45, 0, 0.35, 1);

  /* ---- texture --------------------------------------------------------- */
  /* measured grain: std 9.35 on mean 115 = ~8% amplitude, ~1.5vpx correlated */
  --lhb-grain: 0.18;

  /* ---- elevation ------------------------------------------------------- */
  /* rest : 0.49 opacity at contact, half at ~32px, tail to ~85px (floating) */
  --lhb-shadow-rest:
    0 6px 12px rgba(0, 0, 0, 0.20),
    0 16px 28px rgba(0, 0, 0, 0.20),
    0 32px 55px rgba(0, 0, 0, 0.17),
    0 56px 88px rgba(0, 0, 0, 0.11);
  /* hover: 0.69 at contact, half at ~5px, gone by ~32px (settled onto page) */
  --lhb-shadow-hover:
    0 2px 4px rgba(0, 0, 0, 0.42),
    0 5px 10px rgba(0, 0, 0, 0.30),
    0 11px 20px rgba(0, 0, 0, 0.16);
  /* press: outer shadow measured at exactly zero + inner edge darkening     */
  --lhb-shadow-press:
    inset 0 0 14px rgba(0, 0, 0, 0.55),
    inset 0 2px 5px rgba(0, 0, 0, 0.45);

  /* ---- shape ----------------------------------------------------------- */
  /* The reference pill is fully rounded: 115.5vpx -> 36px, i.e. height/2.
     LH ships it SQUARE. That is a deliberate override of a measured value and
     it is also the only one that moves the component TOWARD the design system
     rather than away from it — design-system.md:101, "radius is 0".
     .lhb-cta--reference below restores the measured curve. */
  --lhb-radius: 0;

  /* ---- surface --------------------------------------------------------- */
  /* EDGE-LIT. The measured gradient spreads its highlight over 7–24% of the
     height, which is what light does to a CURVED top edge — and it is why the
     reference is a pill. On a square that same band stops reading as a lit
     edge and starts reading as a gloss stripe laid across the face.
     So the highlight is compressed into the top ~3%, where a square's edge
     actually is, and the rest of the face falls evenly to black. Darker
     overall, per the ask: the face sits around #212121 where the measured one
     sat around #5f5f5f.
     The measured 14-stop original is intact in .lhb-cta--reference below. */
  --lhb-surface: linear-gradient(
    180deg,
    #272727 0%,
    #848484 1.2%,
    #5f5f5f 3%,
    #373737 7%,
    #2e2e2e 14%,
    #272727 26%,
    #212121 42%,
    #1c1c1c 58%,
    #161616 72%,
    #101010 84%,
    #090909 93%,
    #040404 100%
  );

  /* ---- the accent, as one surface -------------------------------------- */
  /* Remapped from the reference violet to gold (see header note 1). These
     are the only colour knobs; the svg reads them through currentColor-free
     explicit stops in the defs block, so keep the two in step if you retune. */
  --lhb-ring-stroke: #f0dca8;      /* was #DBC1F6 */
  --lhb-chev-rest: #6c6c6c;        /* neutral in the reference; unchanged   */
  --lhb-chev-hover: #ffedc4;       /* was #E2C9FC */
  --lhb-focus: #d9b45a;            /* was #B57CFF */

  /* ---- reset ----------------------------------------------------------- */
  position: relative;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  width: var(--lhb-w);
  height: var(--lhb-h);
  padding: 0 0 0 var(--lhb-pad-left);
  margin: 0;
  border: 0;
  border-radius: var(--lhb-radius);
  overflow: hidden;
  cursor: pointer;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  /* .hero__actions and .cta are flex containers (system.css:629). Without
     this the pill is a shrinkable flex item and loses its measured width. */
  flex: none;

  background-image: var(--lhb-surface);
  box-shadow: var(--lhb-shadow-rest);
  transition: box-shadow var(--lhb-out) var(--lhb-ease);
}

/* The measured object, verbatim — the fully-rounded pill and the surface as
   sampled off the video. Kept so the port can always be checked back against
   BUTTON-SPEC.md and against Desktop/lhb-button/lhb-cta-button.html, and so
   the two overrides above are visible as overrides rather than as drift. */
.lhb-cta--reference {
  --lhb-w: 220px;
  --lhb-h: 72px;
  --lhb-knob: 54px;
  --lhb-knob-inset: 9px;
  --lhb-pad-left: 28px;
  --lhb-radius: calc(var(--lhb-h) / 2);
  --lhb-surface: linear-gradient(
    180deg,
    #141414 0%,
    #1d1d1d 1.5%,
    #8f8f8f 7%,
    #9c9c9c 16%,
    #878787 24%,
    #6c6c6c 33%,
    #606060 42%,
    #5f5f5f 50%,
    #313131 59%,
    #252525 68%,
    #1b1b1b 76%,
    #101010 85%,
    #040404 94%,
    #010101 100%
  );
}
/* the reference label is regular at normal width; the shipped one carries the
   header's axes instead (see § label). This variant exists to be verbatim. */
.lhb-cta--reference .lhb-cta__label {
  font-weight: 400;
  font-variation-settings: "wdth" 100, "wght" 400;
}

/* .btn must never be carried onto this element — .btn::after is the gold sheen
   and would merge with the grain layer below (they are the same pseudo-element),
   and .btn::before would draw its bevel ring around the pill. This is the belt:
   if a .btn class ever survives a copy-paste, its ring still cannot paint. */
.lhb-cta::before { content: none; }

/* film grain over the surface ---------------------------------------------- */
.lhb-cta::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--lhb-grain);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- label ---------------------------------------------------------------- */
/* Measured cap height is 10.9px. Inter's cap ratio .7275 puts that at 15px,
   which is where the spec's 15px comes from. Archivo measures .686 across the
   whole wght 100..900 x wdth 62..125 space, so the same cap needs 15.9px.
   (The project's own canonical figure is .6875 — changelog 2026-09-02 — which
   would give 15.85px. The 0.05px between them is not worth a second number.)

   AXES ARE A DEPARTURE FROM THE REFERENCE, and a deliberate one. The reference
   label is regular at normal width and that is what shipped here first; it made
   the pill read as a different typeface from the header lockup, which is the
   one place on the page a reader compares two CTAs directly. It now carries the
   wordmark's "wdth" 125 / "wght" 700 (system.css § 6), same as .btn. 700 is
   inside design-system.md:63's 400/700 pair, and the width axis does not move
   Archivo's cap height, so the 15px above still lands the measured 10.9px cap.
   The pill widens: every instance on the site is --fluid or --hero, both
   width:auto over a min-width, so it grows rather than crowding the knob.
   Tracking is still measured; do not round it to .2em. */
.lhb-cta__label {
  position: relative;
  z-index: 1;
  font-family: var(--font-display, "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif);
  font-size: 15px;
  font-weight: 700;
  font-variation-settings: "wdth" 125, "wght" 700;
  line-height: 1;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #c6c6c6;
  transition: color var(--lhb-out) var(--lhb-ease);
}

/* measured: label goes #C6C6C6 -> #FFFFFF on hover */
.lhb-cta:hover .lhb-cta__label,
.lhb-cta:focus-visible .lhb-cta__label {
  color: #fff;
  transition-duration: var(--lhb-in);
}

/* ---- knob ----------------------------------------------------------------- */
.lhb-cta__knob {
  position: absolute;
  top: 50%;
  right: var(--lhb-knob-inset);
  z-index: 1;
  width: var(--lhb-knob);
  height: var(--lhb-knob);
  transform: translateY(-50%);
  pointer-events: none;
}

/* svg viewBox is -14 -14 82 82, so it renders 82/54 larger than the knob and
   the blur spills past the disc without being clipped.
   max-width:none defeats system.css:51 (img,svg,video{max-width:100%}), which
   otherwise resolves against the 54px knob and squashes this to an ellipse. */
.lhb-cta__svg {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--lhb-knob) * 82 / 54);
  height: calc(var(--lhb-knob) * 82 / 54);
  max-width: none;
  max-height: none;          /* in case the reset ever grows a max-height too */
  transform: translate(-50%, -50%);
  overflow: visible;
}

/* layers that only exist on hover */
.lhb-l-hover {
  opacity: 0;
  transition: opacity var(--lhb-out) var(--lhb-ease);
}
/* layers that only exist at rest */
.lhb-l-rest {
  opacity: 1;
  transition: opacity var(--lhb-out) var(--lhb-ease);
}

.lhb-cta:hover .lhb-l-hover,
.lhb-cta:focus-visible .lhb-l-hover {
  opacity: 1;
  transition-duration: var(--lhb-in);
}
.lhb-cta:hover .lhb-l-rest,
.lhb-cta:focus-visible .lhb-l-rest {
  opacity: 0;
  transition-duration: var(--lhb-in);
}

/* gold bloom around the disc */
.lhb-glow {
  opacity: 0;
  transition: opacity var(--lhb-out) var(--lhb-ease);
}
.lhb-cta:hover .lhb-glow,
.lhb-cta:focus-visible .lhb-glow {
  opacity: 0.72;
  transition-duration: var(--lhb-in);
}

/* dashed ring: r=21.2, C=133.2, 28 dashes, dash:gap measured 8deg:5deg.
   It does not rotate — see the header note. No animation belongs here. */
.lhb-ring {
  opacity: 0;
  transition: opacity var(--lhb-out) var(--lhb-ease),
              stroke 120ms linear;
}
.lhb-cta:hover .lhb-ring,
.lhb-cta:focus-visible .lhb-ring {
  opacity: 1;
  transition-duration: var(--lhb-in), 120ms;
}

/* ---- chevrons -------------------------------------------------------------- */
/* each 7.8 x 15.6px, 45deg arms, 1.7px stroke, butt caps, mitre join           */
.lhb-chev {
  fill: none;
  stroke: var(--lhb-chev-rest);
  stroke-width: 1.7;
  stroke-linecap: butt;
  stroke-linejoin: miter;
  transition: stroke var(--lhb-out) var(--lhb-ease),
              transform var(--lhb-out) var(--lhb-ease),
              opacity var(--lhb-out) var(--lhb-ease);
}

/* left chevron slides in from -11.8px; right one drifts right by 4.8px */
.lhb-chev--a { opacity: 0; transform: translateX(-11.8px); }
.lhb-chev--b { opacity: 1; transform: translateX(-4.8px); }

.lhb-cta:hover .lhb-chev,
.lhb-cta:focus-visible .lhb-chev {
  stroke: var(--lhb-chev-hover);
  opacity: 1;
  transform: translateX(0);
  transition-duration: var(--lhb-in);
}

/* ---- hover ----------------------------------------------------------------- */
/* The shadow TIGHTENS. The button settles onto the page; it does not lift. */
.lhb-cta:hover,
.lhb-cta:focus-visible {
  box-shadow: var(--lhb-shadow-hover);
  transition-duration: var(--lhb-in);
}

/* ---- press ----------------------------------------------------------------- */
/* instant in AND out - measured 0ms transition on both edges                    */
.lhb-cta:active,
.lhb-cta.is-pressed,
.lhb-cta.is-releasing,
.lhb-cta:active *,
.lhb-cta.is-pressed *,
.lhb-cta.is-releasing * {
  transition-duration: 0s !important;
}

.lhb-cta:active,
.lhb-cta.is-pressed {
  box-shadow: var(--lhb-shadow-press);
}
.lhb-cta:active .lhb-glow,
.lhb-cta.is-pressed .lhb-glow {
  opacity: 1;
}
/* ring shifts hot gold under the finger */
.lhb-cta:active .lhb-ring,
.lhb-cta.is-pressed .lhb-ring {
  stroke: url(#lhbRingPress);
}

/* ---- focus ----------------------------------------------------------------- */
/* system.css:1161 sets a global :where(a,button,[tabindex]):focus-visible gold
   ring. :where() is zero-specificity, so this wins — but it is the same gold,
   so the two agree rather than fight. */
.lhb-cta:focus-visible {
  outline: 2px solid var(--lhb-focus);
  outline-offset: 3px;
}

/* ---- reduced motion --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lhb-cta,
  .lhb-cta * {
    transition-duration: 1ms !important;
  }
}


/* --- 2. Variants --------------------------------------------------------- */
/* The 220x72 baseline above is the measured object and stays as it is. Each
   variant only overrides custom properties, which is the tuning surface the
   spec defines. Nothing here re-states a measured value.

   Pick by the JOB the CTA is doing, not by where it happens to sit:
     (default)          the measured object. Labels up to ~10 characters.
     --fluid            width follows the label. Use for anything bilingual:
                        "Reservar un corte" is 202px of run against the
                        baseline's 129px, so EN fits and ES does not.
     --hero             fluid, and scaled up for a first-screen primary.
     --compact          44px tall, for inline and secondary placements.
                        44px is the project's minimum target (system.css:234).
     --on-ink           for dark grounds — see the note on the rest shadow. */

/* Width follows the label. The knob is reserved with padding-right instead of
   a fixed width, so the pill grows to the right and the knob keeps its measured
   inset. min-width holds the measured proportion for short labels. */
.lhb-cta--fluid {
  width: auto;
  min-width: var(--lhb-w);
  padding-right: calc(var(--lhb-knob) + var(--lhb-knob-inset) + var(--lhb-gap, 20px));
}

/* The slim geometry now lives on the baseline, so every CTA on the page is the
   same object. --hero is what is left of the distinction: fluid, and given a
   little more room to breathe than an inline CTA. */
.lhb-cta--hero {
  --lhb-gap: 22px;
  width: auto;
  min-width: var(--lhb-w);
  padding-right: calc(var(--lhb-knob) + var(--lhb-knob-inset) + var(--lhb-gap));
}

.lhb-cta--compact {
  --lhb-h: 44px;                 /* the project's minimum target — the floor */
  --lhb-knob: 32px;
  --lhb-knob-inset: 6px;
  --lhb-pad-left: 18px;
  --lhb-gap: 12px;
  /* the falloff curve scaled to the shorter object, same three-to-four layer
     shape as the baseline so it still reads as the same material */
  --lhb-shadow-rest:
    0 4px 8px rgba(0, 0, 0, 0.20),
    0 10px 18px rgba(0, 0, 0, 0.18),
    0 20px 34px rgba(0, 0, 0, 0.13),
    0 34px 54px rgba(0, 0, 0, 0.09);
  --lhb-shadow-hover:
    0 1px 3px rgba(0, 0, 0, 0.42),
    0 3px 7px rgba(0, 0, 0, 0.28),
    0 7px 13px rgba(0, 0, 0, 0.15);
  width: auto;
  min-width: 150px;
  padding-right: calc(var(--lhb-knob) + var(--lhb-knob-inset) + var(--lhb-gap));
}
.lhb-cta--compact .lhb-cta__label { font-size: 13.8px; }

/* Dark grounds. The measured shadow stack is pure black fitted against the
   video's #EEEEEE, so on --ink (#101011) rest and hover are indistinguishable
   and the descend — the whole point of the object — reads as nothing. This
   keeps the same falloff SHAPE and the same rest/hover contrast RATIO, but
   spends it on a warm lift instead of black, so the gesture survives.
   It is an adaptation, not a measurement. Flagged as such. */
.lhb-cta--on-ink {
  --lhb-shadow-rest:
    0 6px 14px rgba(0, 0, 0, 0.55),
    0 16px 30px rgba(0, 0, 0, 0.45),
    0 32px 58px rgba(0, 0, 0, 0.30),
    0 0 0 1px rgba(240, 220, 168, 0.10),
    0 10px 44px rgba(217, 180, 90, 0.14);
  --lhb-shadow-hover:
    0 2px 4px rgba(0, 0, 0, 0.70),
    0 5px 10px rgba(0, 0, 0, 0.55),
    0 11px 20px rgba(0, 0, 0, 0.35),
    0 0 0 1px rgba(240, 220, 168, 0.22);
}

/* PAPER. The one light-surfaced instance on the site, and it exists because
   the Ideal Look (system.css § 25) is the only section whose ground is a
   near-black photograph: the black plate is the correct primary on --paper
   and on the hero's photograph, but against #0B0B0C it is the quietest thing
   in the frame rather than the loudest, and the primary there has to be the
   loudest.

   It is a VARIANT, not a second button. Every measured value is untouched —
   geometry, grain, the shadow curve's shape, the knob and its dashed ring,
   the chevrons, the timings. What moves is the surface, which is the tuning
   surface this section is for, and the label colour that has to follow it.

   The surface keeps the baseline's edge-lit construction exactly: highlight
   compressed into the top ~3% where a square's lit edge actually is, then an
   even fall across the face. Inverted, that is a warm white catching the
   light at the top edge and settling to the paper's own shadow tone.
   The knob stays as it is. #131313 on paper is the signet the section wants,
   and it is the same disc as every other CTA on the site. */
.lhb-cta--paper {
  --lhb-surface: linear-gradient(
    180deg,
    #fbf9f4 0%,
    #ffffff 1.2%,
    #fdfcf8 3%,
    #f7f5ee 7%,
    #f4f1ea 14%,
    #f1eee6 26%,
    #edeae1 42%,
    #e9e5db 58%,
    #e4e0d5 72%,
    #ded9cd 84%,
    #d8d3c6 93%,
    #d2ccbe 100%
  );

  /* grain reads roughly twice as hard on a light face as on a dark one at the
     same opacity, so the amplitude is halved to hold the measured texture */
  --lhb-grain: 0.09;

  /* Dark ground, same adaptation --on-ink makes and for the same reason: pure
     black under a plate on #0B0B0C is invisible, so the rest state spends its
     contrast on a warm lift instead. Same falloff shape, same rest/hover
     ratio. An adaptation, not a measurement. Flagged as such. */
  --lhb-shadow-rest:
    0 6px 14px rgba(0, 0, 0, 0.55),
    0 16px 30px rgba(0, 0, 0, 0.45),
    0 32px 58px rgba(0, 0, 0, 0.30),
    0 12px 48px rgba(240, 220, 168, 0.10);
  --lhb-shadow-hover:
    0 2px 4px rgba(0, 0, 0, 0.70),
    0 5px 10px rgba(0, 0, 0, 0.55),
    0 11px 20px rgba(0, 0, 0, 0.35);
  --lhb-focus: #8a6a1c;                /* the gold, darkened to hold on paper */
}

/* The measured label runs #C6C6C6 -> #FFFFFF, i.e. it BRIGHTENS into the
   hover. Inverted, the same gesture is a darkening, and it keeps the measured
   contrast step rather than a new one. */
.lhb-cta--paper .lhb-cta__label { color: #3a3730; }
.lhb-cta--paper:hover .lhb-cta__label,
.lhb-cta--paper:focus-visible .lhb-cta__label { color: #0d0d0e; }

/* Nothing to send yet. The plate stays in place and keeps its size — the row
   must not reflow the moment a visitor picks their first cut — but it stops
   claiming to be pressable: no descend, no hover, no pointer, and look.js
   swallows the click. aria-disabled rather than the disabled attribute,
   because it is an <a>. */
.lhb-cta[aria-disabled="true"] {
  cursor: default;
  opacity: 0.42;
  box-shadow: none;
}
.lhb-cta[aria-disabled="true"]:hover { box-shadow: none; }
.lhb-cta[aria-disabled="true"] .lhb-cta__knob { opacity: 0.6; }

/* THE SHOUT (index.html #shout, system.css § 23).
   The old .shout__cta was not a control sitting on the composition, it was part
   of it: sized off the section's own --core-w, and — the important one — faded
   by the echo trail as the headline's ghosts pass through it
   (opacity:calc(1 - var(--echo) * .72)). Replacing it with a plain button would
   have dropped that, so the binding moves here instead of being lost.
   z-index:2 keeps it in front of the trail, as before. */
.lhb-cta--shout {
  /* The echo band is reserved space, not occupied space: at rest it is empty
     and the button was reading as orphaned a full headline below the line it
     belongs to. Sit back up into the band's faded tail — the ghosts pass
     behind (z-index below), so nothing collides, and the pairing closes. */
  margin-top: calc(var(--echo-depth, 0px) * -.62);
  z-index: 2;
  opacity: calc(1 - var(--echo, 0) * .72);
  transition: box-shadow var(--lhb-out) var(--lhb-ease);
}
@media (prefers-reduced-motion: reduce) {
  .lhb-cta--shout { opacity: 1; }
}

/* THE CLOSING CTA (index.html #cta).
   .cta__pane clips with overflow:hidden (system.css:2209) and drops its padding
   from --s-7 to --s-6 at ≤640px, leaving ~64px under the button against a
   ~90px shadow tail — the outer third of the rest shadow would be cut off
   mid-falloff, which reads as a hard edge rather than a shadow. The tail is
   shortened to fit the room that actually exists there. */
@media (max-width: 640px) {
  .cta__pane .lhb-cta {
    --lhb-shadow-rest:
      0 6px 14px rgba(0, 0, 0, 0.55),
      0 14px 26px rgba(0, 0, 0, 0.42),
      0 24px 40px rgba(0, 0, 0, 0.26),
      0 0 0 1px rgba(240, 220, 168, 0.10);
  }
}

/* A long label must not push the button past its container — the #process CTA
   is reworded at runtime by process.js and reaches "Reservar un recorte de
   barba — $25". It steps down rather than overflowing. */
.lhb-cta--fluid { max-width: 100%; }
@media (max-width: 900px) {
  .lhb-cta--fluid .lhb-cta__label { font-size: 14.6px; }
}
/* The ladder is one notch tighter than it was, because "wdth" 125 buys the
   match with the header at the cost of ~12% advance width. Tracking pays most
   of it back: at 21 characters .14em is ~39px of pure air, and the measured
   .19em is a rest-state value for a 216px pill, not a promise about a phone. */
@media (max-width: 640px) {
  .lhb-cta--fluid { --lhb-gap: 14px; --lhb-pad-left: 20px; }
  .lhb-cta--fluid .lhb-cta__label { font-size: 12.2px; letter-spacing: .10em; }
}
/* Below ~420px the longest labels on index.html — "Build your ideal look",
   "Leave a Google review" — do not fit a nowrap pill at any legible size; they
   overflowed here before the axis change too. This notch spends the knob gap
   and the left pad to keep the shortfall smaller than it was, rather than
   claiming to solve it. See 07-operations for the copy-length caveat. */
@media (max-width: 420px) {
  .lhb-cta--fluid { --lhb-gap: 12px; --lhb-pad-left: 16px; }
  .lhb-cta--fluid .lhb-cta__label { font-size: 11.4px; letter-spacing: .07em; }
}

/* On a phone the first screen is tight (system.css § 12c hands the copy and
   the button to the plate floor). Everything steps down one notch. */
@media (max-width: 640px) {
  .lhb-cta {
    --lhb-h: 48px;
    --lhb-knob: 35px;
    --lhb-knob-inset: 6px;
    --lhb-pad-left: 18px;
    --lhb-gap: 16px;
  }
  .lhb-cta__label { font-size: 14.2px; }
  .lhb-cta--hero { min-width: 0; }
  /* --compact is already at the 44px floor; hold it there */
  .lhb-cta--compact { --lhb-h: 44px; --lhb-knob: 32px; --lhb-knob-inset: 6px;
                      --lhb-pad-left: 18px; }
  .lhb-cta--compact .lhb-cta__label { font-size: 13.4px; }
}
