/* Kingdom Advisors Elementor Widgets — Button
   Osmo "Button 009" hover choreography, adapted to Elementor. Pure CSS, no JS.

   TWO HOVER MOTIONS, chosen by the Hover Motion control:

     Slide Across (default, `.kaw-button` on its own) — at rest the icon sits on the right; on hover
     the right icon slides out and fades while a matching icon slides in from the left and the text
     shifts over. One continuous motion, identical for every icon.

     Cycle Down (`.kaw-button--down`) — for a downward-pointing icon. The icon leaves through the
     bottom of its own box while an identical one arrives from above and lands exactly where the
     first one started. The label does not move, and there is no reverse on mouseout. See the
     section near the foot of this file for how that is arranged.

     Cycle Down → Full Button (`.kaw-button--down.kaw-button--down-full`, v1.43.0, opt-in) — the
     same cycle, but the window is the whole button: the icon drops out through the bottom edge and
     its twin arrives from the top edge. The last section of this file; every rule in it needs both
     classes, so nothing above it changes for a button without the new class.

   v1.44.0 adds three opt-in pieces, each keyed to a class the widget prints only when its control is used,
   so a button without them uses exactly the rules it always did:
     .kaw-button--flow + --icon-left   Icon Position: Before the Label - a second LAYOUT, not a third
                                       motion; see "Flow layout" just before the Full Button section.
     .kaw-button--wrap                 Allow Label to Wrap.
   (The third, Screen-Reader Suffix, is an aria-label and needs no CSS.) It also adds one rule that is not
   behind a class, the doubled label-color rule right after the `.kaw-button` block.

   Every tunable value is a CSS custom property (--kaw-btn-*) that the widget's Elementor controls
   set on {{WRAPPER}} .kaw-button, so the animation math (which depends on icon size, gap, and
   padding) always stays in sync with the styling. The structure, transitions, and easings follow
   Osmo 009 verbatim — only the fixed :root values were swapped for the control-driven variables.

   Both motions are gated behind (hover: hover) and (pointer: fine), so touch devices show the
   clean resting state (icon on the right, fully tappable), and both respect prefers-reduced-motion. */

.kaw-button-wrap,
.kaw-button-wrap *,
.kaw-button-wrap *::before,
.kaw-button-wrap *::after {
  box-sizing: border-box;
}

/* Alignment: one full-width grid cell whose single item is placed/sized by justify-items —
   start / center / end hug the content; stretch makes the button fill the width. */
.kaw-button-wrap {
  display: grid;
  grid-template-columns: 100%;
  justify-items: start;
}

.kaw-button {
  --kaw-btn-color: #ffffff;
  --kaw-btn-bg: #147bd1;
  --kaw-btn-focus: #051c2c;
  --kaw-btn-icon-size: 18px;
  --kaw-btn-gap: 10px;
  --kaw-btn-pad-top: 18px;
  --kaw-btn-pad-right: 28px;
  --kaw-btn-pad-bottom: 18px;
  --kaw-btn-pad-left: 28px;
  --kaw-btn-radius: 8px;
  --kaw-btn-overflow: hidden;   /* upgraded to `clip` by the @supports gate below */
  --kaw-btn-focus-inset: -0.125em;
  --kaw-btn-click-scale: 0.97 0.94;
  --kaw-btn-fade: 0.3s;
  --kaw-btn-blur: 0px;
  /* How far the icons travel on the swap — the full icon width plus the gap, so they clear out. */
  --kaw-btn-icon-travel: calc(var(--kaw-btn-icon-size) + var(--kaw-btn-gap));
  /* Cycle Down travel is one icon height, so it is expressed as a percentage of the glyph itself
     and needs no variable (Full Button adds --kaw-btn-drop-* on its slots, at the foot of the file).
     This is only its duration — deliberately the same 0.5s as the swap. */
  --kaw-btn-cycle: 0.5s;
  --kaw-btn-ease-hover: cubic-bezier(0.32, 0.72, 0, 1);
  --kaw-btn-ease-click: cubic-bezier(0.4, 0, 0.2, 1);
  --kaw-btn-ease-focus: cubic-bezier(0.32, 0.72, 0, 1);

  color: var(--kaw-btn-color);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  background-color: transparent;
  /* Reset native <button> chrome so the element works identically whether rendered as <a> or
     <button> (the Folio "See Bio" control is a <button class="kaw-button">). */
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  outline-style: none;
  padding: 0;
  line-height: 1;
  text-decoration: none;
  display: inline-grid;
  position: relative;
  -webkit-tap-highlight-color: transparent;
  transition: scale 0.15s var(--kaw-btn-ease-click), color var(--kaw-btn-fade) ease;
}

/* THE LABEL COLOR GETS A SECOND, STRONGER RULE (v1.44.0), AND THE CLASS IS DOUBLED ON PURPOSE. Most
   buttons are an <a>, and an <a> is also matched by the Elementor kit's link colors: `.elementor-kit-N a`
   at (0,1,1) and, once a link hover color is set, `.elementor-kit-N a:hover` at (0,2,1), plus a theme
   reset such as `a:hover`. The `color` declaration in the block above is (0,1,0) and loses to all of them,
   so whenever the control's own rule is not on the page the label paints the kit's link color. That
   happens when a page's generated post-N.css is missing or not yet regenerated, when a Text Color
   control is stored empty, and always on a button that only ever sets the variable (Folio's "More About"
   link, which writes --kaw-btn-color and nothing else). Doubling the class is the cheapest specificity
   that beats the kit - (0,2,0) at rest and (0,3,0) on hover - without a wrapper, an ID or !important, and
   it still loses to every control rule, which starts at {{WRAPPER}} (0,3,0) + .kaw-button = (0,4,0).
   On a page whose CSS is present nothing changes. The declaration in the block above is NOT removed:
   it is now only the floor, and it keeps every earlier rule of this file present and unchanged
   (tools/test-button-render.php row E.1 checks that against the 1.42.0 file). The custom properties
   above stay at (0,1,0) on purpose: Call to Action and Folio override them from (0,2,0) selectors whose
   win depends on staying above that block. */
.kaw-button.kaw-button,
.kaw-button.kaw-button:hover {
  color: var(--kaw-btn-color);
}

/* `overflow: clip` is Baseline (Chrome 90, Firefox 81, Safari 16.0). It cannot be guarded with a
   preceding `overflow: hidden` at the point of use — see the note in .kaw-button__inner — so the
   VARIABLE is gated instead. Every engine at this pack's support floor passes the test and computes
   exactly what it computed before; Safari 15 and older keep `hidden`, which clips identically. It
   matters most on Call to Action, which ships --kaw-btn-pad-right: 0, so without any clipping its
   incoming arrow parks outside the box at full opacity beside every card. */
@supports (overflow: clip) {
  .kaw-button { --kaw-btn-overflow: clip; }
}

/* Focus ring (keyboard only) — a ring just outside the button, same radius. */
.kaw-button::after {
  content: '';
  display: block;
  position: absolute;
  inset: var(--kaw-btn-focus-inset);
  border-radius: var(--kaw-btn-radius);
  transition: box-shadow 0.3s var(--kaw-btn-ease-focus);
  pointer-events: none;
  z-index: 2;
}

.kaw-button:focus-visible::after {
  box-shadow: 0 0 0 0.125em var(--kaw-btn-focus);
}

.kaw-button:active {
  scale: var(--kaw-btn-click-scale);
}

/* The label + icons live here. The inner fills the button and uses space-between, so a normal
   (content-sized) button keeps the label and icon snug together — there is no free space to
   distribute — while a stretched (full-width) button pins the label left and the icon right, like
   the Conference full-width CTA. */
.kaw-button__inner {
  pointer-events: none;
  gap: var(--kaw-btn-gap);
  padding: var(--kaw-btn-pad-top) var(--kaw-btn-pad-right) var(--kaw-btn-pad-bottom) var(--kaw-btn-pad-left);
  z-index: 1;
  border-radius: var(--kaw-btn-radius);
  /* The value arrives through the variable, which is gated by @supports where it is declared. Do NOT
     "simplify" this to `overflow: hidden; overflow: clip;` via the variable — that shape looks like a
     fallback and is not one. A declaration containing var() is valid at PARSE time, so the cascade
     keeps it and discards the plain `hidden` above it; an unsupported substituted keyword is then
     invalid at COMPUTED-VALUE time, which resolves to the property's initial value — `visible` — not
     to the earlier declaration. Measured: that shape computes `visible` in a browser without `clip`.
     v1.30.0 shipped exactly that mistake here and it did nothing. */
  overflow: var(--kaw-btn-overflow);
  grid-area: 1 / 1;
  justify-self: stretch;
  justify-content: space-between;
  align-items: center;
  display: flex;
  position: relative;
}

.kaw-button__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--kaw-btn-icon-size);
  height: var(--kaw-btn-icon-size);
  flex: none;
  color: currentColor;
  transition: translate 0.5s var(--kaw-btn-ease-hover), opacity 0.15s ease-out, color var(--kaw-btn-fade) ease;
}

/* Icons render inline (SVG uploads / the built-in arrow), so fill and stroke follow the colour
   controls. Uploaded font icons fall back to font-size. */
.kaw-button__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.kaw-button__icon i {
  font-size: var(--kaw-btn-icon-size);
  line-height: 1;
}

/* The incoming (left) icon is out of flow and hidden until hover, so at rest the button reads as
   text + right icon only. */
.kaw-button__icon.is--left {
  position: absolute;
  left: var(--kaw-btn-pad-right);
  opacity: 0;
  translate: calc(-1 * var(--kaw-btn-icon-travel)) 0;
}

/* --nofade: the incoming icon slides in at full opacity instead of fading up.
   What hides the icon at rest is CLIPPING, not opacity: it parks at `left: var(--kaw-btn-pad-right)`
   minus its travel, i.e. at `pad-right - gap - icon-size`, and `overflow: clip` on the inner cuts
   anything left of zero. So it is only safe while `pad-right <= gap` — beyond that the icon peeks out
   before hover, which is why this is opt-in rather than the default.
   The OUTGOING icon still fades: it exits past the label with no edge to disappear behind. */
.kaw-button--nofade .kaw-button__icon.is--left {
  opacity: 1;
  transition: translate 0.5s var(--kaw-btn-ease-hover), color var(--kaw-btn-fade) ease;
}

.kaw-button__text {
  flex: none;
  transition: translate 0.5s var(--kaw-btn-ease-hover);
}

/* v1.44.0 Allow Label to Wrap. `flex: none` above is what keeps a label on one line: the item can never
   be narrower than its longest line, so a long label in a narrow column is wider than the button's inner
   box, which clips it and pushes the icon to the edge. Letting the label shrink (with min-width 0, since a flex item's automatic minimum is its
   min-content width) hands the line breaking back to the text, and white-space is reset in case a theme or
   typography setting made it nowrap. Everything else - padding, gap, icon, motion - is the same; the label
   simply takes two lines where one will not fit. */
.kaw-button--wrap .kaw-button__text {
  flex: 0 1 auto;
  min-width: 0;
  white-space: normal;
}

/* Background layer (colour, border, radius) behind the clipped content. */
.kaw-button__bg {
  background-color: var(--kaw-btn-bg);
  border-radius: var(--kaw-btn-radius);
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  padding: 0;
  transition: background-color var(--kaw-btn-fade) ease, border-color var(--kaw-btn-fade) ease;
}

/* Frosted glass, opt-in — only emitted when the Background Blur control is above 0.

   THE BLUR GOES ON __bg AND NOT ON .kaw-button. In WebKit an element with a backdrop-filter clips
   its descendants to its own border box, and the focus ring is drawn by .kaw-button::after at
   inset: -0.125em — i.e. deliberately OUTSIDE the button. Put the blur on the button and the ring
   is swallowed, silently, for keyboard users only. __bg has no descendants, so nothing can be lost.

   __bg is also the right layer for a second reason: __inner carries z-index: 1, so the label and
   icons paint above this element and are never themselves blurred.

   Gated on the attribute rather than always emitting blur(0px), because a backdrop-filter costs a
   compositing layer even at zero and buttons repeat down a page. */
.kaw-button[data-blur="on"] .kaw-button__bg {
  -webkit-backdrop-filter: blur(var(--kaw-btn-blur));
          backdrop-filter: blur(var(--kaw-btn-blur));
}

/* --------------------------------------------------------------------- Slide Across (default)
   Every selector here is scoped with :not(.kaw-button--down). Cycle Down reuses the same two icon
   elements, so without the exclusion the sideways choreography would run underneath it — the label
   would shift and the resting icon would slide out to the right.

   .kaw-button--noicon is excluded from the LABEL rule below and from that one only. Every other rule
   in this block descends into .kaw-button__icon, and render() emits no icon spans for a text-only
   button, so those rules have nothing left to match and need no exclusion. The label rule is the
   exception: it targets .kaw-button__text, which is still there, and would slide the label sideways
   over empty space on hover. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .kaw-button:not(.kaw-button--down, .kaw-button--noicon):is(:hover, :focus-visible) .kaw-button__text,
  [data-hover]:is(:hover, :focus-visible) .kaw-button:not(.kaw-button--down, .kaw-button--noicon) .kaw-button__text {
    /* Shift the label right by exactly icon + gap + (padding-right − padding-left) so it lands
       right after the incoming left icon and its gap. */
    translate: calc(var(--kaw-btn-icon-size) + var(--kaw-btn-gap) + var(--kaw-btn-pad-right) - var(--kaw-btn-pad-left)) 0;
    transition: translate 0.5s 0.075s var(--kaw-btn-ease-hover);
  }

  .kaw-button:not(.kaw-button--down):is(:hover, :focus-visible) .kaw-button__icon.is--left,
  [data-hover]:is(:hover, :focus-visible) .kaw-button:not(.kaw-button--down) .kaw-button__icon.is--left {
    translate: 0 0;
    opacity: 1;
    transition: translate 0.5s 0.075s var(--kaw-btn-ease-hover), opacity 0.15s 0.075s ease-out;
  }

  /* --nofade: same slide, but never animate opacity in either direction. */
  .kaw-button--nofade:not(.kaw-button--down):is(:hover, :focus-visible) .kaw-button__icon.is--left,
  [data-hover]:is(:hover, :focus-visible) .kaw-button--nofade:not(.kaw-button--down) .kaw-button__icon.is--left {
    transition: translate 0.5s 0.075s var(--kaw-btn-ease-hover);
  }

  .kaw-button:not(.kaw-button--down):is(:hover, :focus-visible) .kaw-button__icon.is--right,
  [data-hover]:is(:hover, :focus-visible) .kaw-button:not(.kaw-button--down) .kaw-button__icon.is--right {
    translate: var(--kaw-btn-icon-travel) 0;
    opacity: 0;
    transition: translate 0.5s 0.05s var(--kaw-btn-ease-hover), opacity 0.15s 0.075s ease-out;
  }
}

/* ================================================================================== Cycle Down
   The second hover motion, for a downward-pointing icon: the icon leaves through the bottom of its
   own box while an identical one arrives from above and lands exactly where the first one started.
   The label does not move. Same two icon elements as Slide Across — no extra markup.

   WHY THERE IS NO REVERSE ON MOUSEOUT. The two icons swap roles the instant hover begins, and
   because they are the same icon in the same place, the swap itself is invisible:

                        is--right glyph        is--left glyph
     at rest            0      (visible)       100%   (below, clipped)
     hover frame 0      -100%  (above)         0      (visible)   <- identical pixels to "at rest"
     hover frame 1      0      (visible)       100%   (below)     <- identical to "at rest" again

   So the animation ENDS on the resting state. When the pointer leaves, the animation is torn down
   and the element lands on exactly what it was already showing — nothing happens, which is the
   design. It also means a pointer that leaves MID-animation jumps FORWARD to the finished position
   rather than rewinding: the motion reads as "finished early", never as "undone".

   THIS IS WHY IT IS @keyframes AND NOT A TRANSITION. A transition would run backwards on mouseout,
   which is the one thing this motion must not do. */

/* Each icon slot becomes its own window and the glyph inside it is what moves. __inner cannot do
   this job: its clip is at the padding edge, so a glyph parked one icon-height above centre still
   sits inside the top padding (18px by default, against an 18px icon) and would show at rest. */
.kaw-button--down .kaw-button__icon {
  overflow: hidden;   /* Safari < 16 fallback — see the note on __inner's overflow above. */
  overflow: clip;
}

/* Stack the incoming icon exactly on top of the resting one — same right edge, same (static,
   flex-centred) vertical position. `translate: none` cancels the sideways parking that Slide
   Across uses, and the icon is opaque here because clipping, not opacity, is what hides it. */
.kaw-button--down .kaw-button__icon.is--left {
  left: auto;
  right: var(--kaw-btn-pad-right);
  opacity: 1;
  translate: none;
}

/* Resting positions of the glyphs — and, deliberately, the END of the keyframes below.
   `> *` covers both an inline <svg> and a font-icon <i>. */
.kaw-button--down .kaw-button__icon.is--right > * { translate: 0 0; }
.kaw-button--down .kaw-button__icon.is--left > *  { translate: 0 100%; }

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .kaw-button--down:is(:hover, :focus-visible) .kaw-button__icon.is--right > *,
  [data-hover]:is(:hover, :focus-visible) .kaw-button--down .kaw-button__icon.is--right > * {
    animation: kaw-btn-cycle-in var(--kaw-btn-cycle) var(--kaw-btn-ease-hover);
  }

  .kaw-button--down:is(:hover, :focus-visible) .kaw-button__icon.is--left > *,
  [data-hover]:is(:hover, :focus-visible) .kaw-button--down .kaw-button__icon.is--left > * {
    animation: kaw-btn-cycle-out var(--kaw-btn-cycle) var(--kaw-btn-ease-hover);
  }
}

/* No fill-mode on either: landing back on the base state IS the point (see above). */
@keyframes kaw-btn-cycle-in {
  from { translate: 0 -100%; }
  to   { translate: 0 0; }
}

@keyframes kaw-btn-cycle-out {
  from { translate: 0 0; }
  to   { translate: 0 100%; }
}

/* ================================================================================ Flow layout
   v1.44.0. Only for `.kaw-button--flow`, which the widget adds (together with `--icon-left`) when Icon
   Position is Before the Label. No button without that setting carries the class, so nothing above this
   line changes for them, and every rule below needs the class.

   WHY A SECOND LAYOUT. Above, the incoming icon is parked ABSOLUTELY at `left: pad-right`, i.e. against
   the button's edge. That is right only while the resting icon sits on the other side of the label: mirror
   it and the incoming icon has to arrive after the label, wherever the label ends, which an edge offset
   cannot express. Here the incoming icon joins the flex run instead, with a margin that cancels its own
   width plus one gap, so it adds NOTHING to the run and sits exactly where the label ends. The label's hover
   shift is then exactly one icon + gap.

   The run on this layout, in visual order (`order` moves the elements, the markup is unchanged):

     [resting .is--right] [label] [incoming .is--left, net width 0, parked one travel to the right]

   At rest the incoming icon is invisible for the same reason as on the other side: opacity 0 (the base
   .is--left rule), and past the label into the right padding or beyond the clipped edge. On a Stretch
   button the label carries an auto margin, so the icon is pinned left and the label right, the mirror of
   the original layout's label-left / icon-right. */

.kaw-button--flow .kaw-button__icon.is--left {
  position: static;
  left: auto;
}

.kaw-button--icon-left .kaw-button__icon.is--right {
  order: -1;
}

.kaw-button--icon-left .kaw-button__text {
  margin-left: auto;
}

.kaw-button--icon-left:not(.kaw-button--down) .kaw-button__icon.is--left {
  order: 1;
  margin: 0 0 0 calc(-1 * var(--kaw-btn-icon-travel));
  translate: var(--kaw-btn-icon-travel) 0;
}

/* Cycle Down on the flow layout. Its incoming icon must sit ON TOP of the resting one (the glyph arrives
   from above inside the same box), so it goes right beside the resting icon at the front of the run and the
   same net-zero margin pulls the resting one back over it. `translate: none`, the opacity and the glyph
   keyframes come from the Cycle Down section above, unchanged. */
.kaw-button--icon-left.kaw-button--down .kaw-button__icon.is--left {
  order: -1;
  margin: 0 calc(-1 * var(--kaw-btn-icon-travel)) 0 0;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  /* The mirror of Slide Across: the label moves LEFT by one icon + gap, the resting icon leaves to the left
     (fading, from the base hover rule), and the incoming one slides in from the right to land one gap after
     the label (translate 0 and opacity 1 come from the base .is--left hover rule). */
  .kaw-button.kaw-button--icon-left:not(.kaw-button--down, .kaw-button--noicon):is(:hover, :focus-visible) .kaw-button__text,
  [data-hover]:is(:hover, :focus-visible) .kaw-button.kaw-button--icon-left:not(.kaw-button--down, .kaw-button--noicon) .kaw-button__text {
    translate: calc(-1 * var(--kaw-btn-icon-travel)) 0;
  }

  .kaw-button.kaw-button--icon-left:not(.kaw-button--down):is(:hover, :focus-visible) .kaw-button__icon.is--right,
  [data-hover]:is(:hover, :focus-visible) .kaw-button.kaw-button--icon-left:not(.kaw-button--down) .kaw-button__icon.is--right {
    translate: calc(-1 * var(--kaw-btn-icon-travel)) 0;
  }
}

/* ================================================================= Cycle Down → Full Button travel
   Opt-in (v1.43.0, the Travel control): `.kaw-button--down-full` is added beside `.kaw-button--down`.
   EVERY selector below requires both classes, so a button without the new class matches none of it
   and the Icon Height motion above is untouched. No rule above this section was edited for it (two
   comments were); tools/test-button-render.php row E.1 checks that against the 1.42.0 file.

   Same cycle, bigger window. In Icon Height each icon slot is its own clip window, so the glyph
   vanishes one icon-height below where it started. On a 60px button with a 16px icon that reads as
   being cut off by the label's line. Here the slots stop clipping and __inner's own clip is the
   window. That clip is its padding edge, which is the button's edge, rounded by the Border Radius.
   The resting icon drops out through the bottom edge while its twin arrives from just above the top
   edge and lands in the middle.

   THE DISTANCE, WITHOUT JS. The glyphs still run the Icon Height keyframes above, which move them one
   glyph height. What is missing is the distance from the icon to the button's edge. It depends on the
   label's line height, which no variable carries. So each SLOT is made exactly as tall as the button
   and carries the rest of the trip, as a percentage of itself:

     is--right (in flow) stretches to the flex line, and negative block margins cancel its block
     padding. Its margin box still equals the line, so the button keeps its height, while its border
     box spans the whole padding box of __inner, 0 to H.
     is--left (absolutely positioned) gets top: 0 / bottom: 0 and the same padding.

   The padding keeps each glyph centred on the content band (C = H - pad-top - pad-bottom) exactly
   where it sits in Icon Height, so the two glyphs still stack pixel-identically. With the glyph
   h = icon-size tall, its top at pad-top + (C - h) / 2:

     out: the glyph's top must reach H      slot + glyph = 50% + (pad-bottom - pad-top + h) / 2
          the glyph keyframe supplies h  ->  slot = 50% + (pad-bottom - pad-top - h) / 2   (+ 1px)
     in:  the glyph's bottom starts at 0    slot = -50% - (pad-top - pad-bottom - h) / 2  (- 1px)

   THE 1px OVERSHOOT. Without it the twins would sit exactly on the edges, and that has no margin.
   The paddings and the label line are laid out in 1/64px units while the percentages are resolved
   in floats, so on fractional geometry (padding 18.4 / 19.1px, a 17.5px icon, a 21.3px line) the
   parked glyph's top lands about 0.01px INSIDE the clip. The clip is pixel-snapped, and the glyph's
   antialiased top row then shows as a hairline just inside the bottom edge. That was measured at
   DPR 1 and 2 with a top-edge stroke. One whole pixel beyond each edge means no pixel row is ever
   shared. The cost is nothing visible: the arriving icon starts 1px above the edge and crosses that
   pixel in well under one frame. With equal top and bottom padding both trips grow by the same 1px,
   so the twins still travel as one belt. The slot and the glyph inside it share duration, easing and
   start, so the two animations add up to one motion. Same no-reverse rule: both end on the resting
   state.

   Each glyph is clipped to its own box (overflow: hidden). In Icon Height the slot did that, because
   the glyph fills the slot. Some uploaded SVGs carry overflow="visible" with strokes beyond the
   viewBox edge. Unclipped, the resting icon would show strokes that Icon Height cuts off, and a
   heavy enough stroke on a parked twin would reach past the 1px margin. With the clip and the
   margin, a Full Button at rest paints its resting icon, cut exactly as in Icon Height, and nothing
   of the parked twin.

   Reduced motion and touch: the hover rules sit in the same media query as Icon Height's, and the
   resting positions (is--left parked below the bottom edge, clipped by __inner) sit outside it. */
.kaw-button--down.kaw-button--down-full .kaw-button__icon {
  --kaw-btn-drop-out: calc(50% + (var(--kaw-btn-pad-bottom) - var(--kaw-btn-pad-top) - var(--kaw-btn-icon-size)) / 2 + 1px);
  --kaw-btn-drop-in: calc(-50% - (var(--kaw-btn-pad-top) - var(--kaw-btn-pad-bottom) - var(--kaw-btn-icon-size)) / 2 - 1px);
  overflow: visible;
  height: auto;
  padding-top: var(--kaw-btn-pad-top);
  padding-bottom: var(--kaw-btn-pad-bottom);
  /* No translate transition: the slot's translate only ever comes from the keyframes or from the
     fixed parking below, and a breakpoint change to the padding must not glide a parked icon. */
  transition: color var(--kaw-btn-fade) ease;
}

.kaw-button--down.kaw-button--down-full .kaw-button__icon.is--right {
  align-self: stretch;
  margin-top: calc(-1 * var(--kaw-btn-pad-top));
  margin-bottom: calc(-1 * var(--kaw-btn-pad-bottom));
}

.kaw-button--down.kaw-button--down-full .kaw-button__icon.is--left {
  top: 0;
  bottom: 0;
  translate: 0 var(--kaw-btn-drop-out);
}

/* The glyph keeps the Icon Height box. An inline SVG is height: 100% of its slot, and the slot's
   content band is now the label's line, so it is pinned back to the icon size. A font icon is already
   one icon-size line tall (line-height: 1 on its own font-size) and is left alone, because an em
   icon size would resolve against the icon's own font-size here. */
.kaw-button--down.kaw-button--down-full .kaw-button__icon > svg,
.kaw-button--down.kaw-button--down-full .kaw-button__icon > img {
  height: var(--kaw-btn-icon-size);
}

.kaw-button--down.kaw-button--down-full .kaw-button__icon > * {
  overflow: hidden;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .kaw-button--down.kaw-button--down-full:is(:hover, :focus-visible) .kaw-button__icon.is--right,
  [data-hover]:is(:hover, :focus-visible) .kaw-button--down.kaw-button--down-full .kaw-button__icon.is--right {
    animation: kaw-btn-drop-in var(--kaw-btn-cycle) var(--kaw-btn-ease-hover);
  }

  .kaw-button--down.kaw-button--down-full:is(:hover, :focus-visible) .kaw-button__icon.is--left,
  [data-hover]:is(:hover, :focus-visible) .kaw-button--down.kaw-button--down-full .kaw-button__icon.is--left {
    animation: kaw-btn-drop-out var(--kaw-btn-cycle) var(--kaw-btn-ease-hover);
  }
}

/* No fill-mode, as above: the end of each is the resting state. */
@keyframes kaw-btn-drop-in {
  from { translate: 0 var(--kaw-btn-drop-in); }
  to   { translate: 0 0; }
}

@keyframes kaw-btn-drop-out {
  from { translate: 0 0; }
  to   { translate: 0 var(--kaw-btn-drop-out); }
}

/* Full Button on the flow layout (Icon Position: Before the Label + Cycle Down + Travel: Full Button). There
   the incoming slot is a flex item in the run instead of an absolutely placed one, so the `top: 0; bottom:
   0` of the Full Button section does nothing to it, and its block padding would be added to the flex line:
   the button would grow by the top and bottom padding, and the 50% in its translate would resolve against
   that wrong height. It gets what is--right gets, stretch to the line with negative block margins that
   cancel the padding, so its margin box is the line again and its border box spans the button. Only the
   block margins are set here. The negative right margin that stacks it over the resting icon comes from the
   flow rule above and stays. This rule sits last because it has the same specificity as that one and has to
   win on the block margins. */
.kaw-button--flow.kaw-button--down-full .kaw-button__icon.is--left {
  align-self: stretch;
  margin-top: calc(-1 * var(--kaw-btn-pad-top));
  margin-bottom: calc(-1 * var(--kaw-btn-pad-bottom));
}
