/* Kingdom Advisors Elementor Widgets — Folio (Speakers)
   A pinned "soft-lock" section (like Split Cards): a masked list of speaker names on the left rides
   up while a strip of portrait images rides down, meeting on the active speaker, scrubbed to scroll.
   It's a FINITE one-pass traversal (you scroll in, through every speaker once, and out) but renders
   wrapped neighbour clones at each end so it LOOKS like an infinity loop. Click a name / image /
   "See Bio" → a shared-element FLIP to a detail panel (2-colour headline + bio + CTA); close
   reverses it. Mobile is a swipeable card deck. Reduced-motion / editor / no-JS fall back to a plain
   stacked list. Buttons reuse the pack's Button (kaw-button) icon-swap. Driven by GSAP + ScrollTrigger.

   The JS reads sizing it needs (active positions, image height/gap) from --kaw-folio-* variables so
   responsive controls stay in sync with the layout math. */

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

.kaw-folio {
  /* Tunable geometry (JS reads some of these). */
  --kaw-folio-top: 140px;           /* clearance below a fixed header/nav (headline + detail) */
  --kaw-folio-intro-block-w: 60%;   /* headline + description block width */
  --kaw-folio-intro-gap: 48px;      /* gap between the headline and the description */
  --kaw-folio-intro-w: 480px;       /* description wrap width */
  --kaw-folio-names-height: 400px;  /* the names box height */
  --kaw-folio-names-bottom: 70px;   /* the names box's distance from the stage bottom */
  --kaw-folio-name-active-y: 50%;   /* active name's vertical centre WITHIN the box */
  --kaw-folio-name-gap: 22px;       /* space between name rows */
  --kaw-folio-img-active-y: 50%;    /* vertical centre of the active image */
  --kaw-folio-img-height: 74vh;     /* active image height */
  --kaw-folio-img-gap: 5vh;         /* gap between stacked images */
  --kaw-folio-img-width: 42%;       /* image column width (of the stage) */
  --kaw-folio-content-x: 5%;        /* left inset of the headline + names + detail text */
  --kaw-folio-image-right: 5%;      /* right inset of the image column */
  --kaw-folio-m-pad: 24px;          /* mobile: side padding inside the detail panel */
  --kaw-folio-m-top: 90px;          /* mobile: clearance above the detail so a fixed nav can't cover
                                       its close button (the mobile twin of --kaw-folio-top) */
  --kaw-folio-m-x-top: 14px;        /* mobile: close (X) offset inside the detail image */
  --kaw-folio-m-x-right: 14px;
  /* MOBILE SIZES ARE px, NOT vh — deliberately. On phones `vh` is measured against a viewport that
     changes as the browser chrome hides/shows while scrolling, and it jumps hard on rotation, so a
     vh-sized card visibly resizes mid-scroll and looks wrong in landscape. Desktop keeps vh (the
     section/image heights above), where the viewport is stable and vh is what you want. */
  --kaw-folio-m-card-h: 480px;      /* mobile deck: card height (the section is ONE card tall) */
  --kaw-folio-m-card-w: 100%;       /* mobile deck: max card width (100% = fill, like the other widgets) */
  --kaw-folio-m-deck-pad: 0px;      /* mobile deck: side padding around the deck. Kept SEPARATE from
                                       --kaw-folio-m-pad (the detail panel's padding) so tuning the
                                       open profile's insets never moves the card deck, and vice versa */
  --kaw-folio-m-head-pad: 24px;     /* mobile: headline side inset (own value, so full-bleed cards
                                       don't drag the headline flush against the screen edge) */
  --kaw-folio-m-detail-img-w: 100%; /* mobile: image width within the padded content column */
  --kaw-folio-m-detail-img-h: 380px;/* mobile: image height (px — see the vh note above) */
  --kaw-folio-m-detail-gap: 28px;   /* mobile: gap between the image and the text below it */
  --kaw-folio-m-detail-bottom: 72px;/* mobile: space under the open profile */
  --kaw-folio-m-deck-top: 90px;     /* mobile: space above the deck */
  --kaw-folio-m-deck-bottom: 64px;  /* mobile: space below the counter */
  --kaw-folio-m-head-gap: 40px;     /* mobile: gap between the headline and the deck */
  --kaw-folio-m-cap-x: 22px;        /* mobile deck: name/role inset from the card's left/bottom */
  --kaw-folio-m-cap-y: 22px;
  --kaw-folio-m-count-gap: 20px;    /* mobile deck: space above the position counter */
  --kaw-folio-m-count-align: center;
  --kaw-folio-seebio-top: 18px;     /* See Bio button offset inside the active card */
  --kaw-folio-seebio-left: 18px;
  --kaw-folio-x-top: 18px;          /* Close (X) button offset — inside the detail image by default */
  --kaw-folio-x-right: 18px;
  --kaw-folio-mask: 90px;           /* names fade zone height (top & bottom) */
  --kaw-folio-bg: #051C2C;
  --kaw-folio-fade-color: var(--kaw-folio-bg); /* colour the names fade into (defaults to the bg) */
  --kaw-folio-name: #ffffff;        /* active name colour */
  --kaw-folio-name-muted: #3f5c6b;  /* inactive name colour */

  position: relative;
  width: 100%;
  margin: 0;
  background-color: var(--kaw-folio-bg);
  color: var(--kaw-folio-name);
}

/* The widget fills its container's content box by default. A boxed Elementor layout can still leave
   padding around the widget; this stops the widget's OWN wrapper from adding horizontal inset. */
.elementor-widget-kaw_folio > .elementor-widget-container {
  padding-left: 0;
  padding-right: 0;
}

/* Optional Full Bleed (control): break out of the container entirely so the section spans the full
   viewport width, edge-to-edge, regardless of any container/column padding around it. The width comes
   from --kaw-folio-vw, which the JS sets to document.documentElement.clientWidth (the viewport MINUS
   the vertical scrollbar) so it never overflows into a horizontal scrollbar; it falls back to 100vw
   when JS is off (in which case the readable stacked-list fallback is showing anyway). */
.kaw-folio[data-kaw-folio-fullbleed] {
  width: var(--kaw-folio-vw, 100vw);
  max-width: var(--kaw-folio-vw, 100vw);
  margin-left: calc(50% - var(--kaw-folio-vw, 100vw) / 2);
  margin-right: calc(50% - var(--kaw-folio-vw, 100vw) / 2);
}

/* ------------------------------------------------------------------ Pinned stage */
.kaw-folio__pin {
  position: relative;
  width: 100%;
  height: 100vh;                    /* Section Height control (100–105vh) */
  overflow: hidden;
}

/* Headline block, top-left — pushed below the fixed header by the top offset. This is the positioned
   layer; the headline and its optional description stack in NORMAL FLOW inside it, so the description
   always follows the headline no matter how the headline wraps. It is deliberately a separate layer
   from .kaw-folio__names (which is anchored to the BOTTOM of the stage) — that is what guarantees the
   description can never move the speaker list, at any length. */
.kaw-folio__intro {
  position: absolute;
  top: var(--kaw-folio-top);
  left: var(--kaw-folio-content-x);
  z-index: 3;
  max-width: var(--kaw-folio-intro-block-w);
  pointer-events: none;
}

.kaw-folio__headline {
  margin: 0;
  max-width: 100%;
  font-size: 3rem;
  line-height: 1.02;
  font-weight: 550;
  letter-spacing: -0.01em;
  color: #48D597;
}

/* Optional paragraph under the headline.
   TWO deliberate things here, both learned the hard way (v1.11.0 → v1.11.2):

   1. Spacing and width arrive as VARIABLES. The controls write --kaw-folio-intro-gap / -w onto the
      root rather than writing `margin-top` / `max-width` onto this element, so a control can never
      end up competing with this rule's own `margin` shorthand.

   2. `!important` on the two variable-driven properties. A <p> inside a page builder is one of the
      most contested elements on a WordPress site — themes and Elementor kits routinely set paragraph
      margins at a specificity a single class cannot reach, and on a real install that was silently
      eating the gap whatever the control said. `!important` is safe HERE precisely because the value
      is a variable: the control still fully owns the number, it just guarantees this declaration is
      the one that resolves it. Do NOT copy this to properties a control writes directly — there it
      would lock the user out (see the "Elementor specificity trap" note in the rundown). */
.kaw-folio__intro-text {
  font-size: 16.65px;
  line-height: 20px;
  font-weight: 550;
  letter-spacing: 0.5px;
  color: #48D597;
}
/* Split out deliberately: ONLY the two variable-driven properties are hardened. Typography and colour
   stay in the low-specificity rule above so their controls keep winning normally. */
.kaw-folio .kaw-folio__intro-text {
  margin: var(--kaw-folio-intro-gap) 0 0 !important;
  max-width: var(--kaw-folio-intro-w) !important;
}

/* ------------------------------------------------------------------ Names box (left), masked
   A fixed-height box near the bottom of the stage. The strip scrolls inside it; the active name is
   centred in the box and the top/bottom edges fade with the mask. */
.kaw-folio__names {
  position: absolute;
  left: var(--kaw-folio-content-x);
  top: auto;
  bottom: var(--kaw-folio-names-bottom);
  /* Span from the left inset to a gutter before the image column, so long names never collide. The
     max() keeps a readable floor: at extreme inset + image-width combos the calc can hit 0, which
     (with overflow:hidden) would blank the names column — the floor prevents that total collapse. */
  width: max(15%, calc(100% - var(--kaw-folio-content-x) - var(--kaw-folio-image-right) - var(--kaw-folio-img-width) - 5%));
  height: var(--kaw-folio-names-height);
  overflow: hidden;
  z-index: 2;
}

/* Top & bottom fade — colour-controllable gradient overlays (a solid fade-colour edge easing to
   transparent over the fade zone), so the fade can be tinted independently of the section bg. */
.kaw-folio__names::before,
.kaw-folio__names::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: var(--kaw-folio-mask);
  z-index: 3;
  pointer-events: none;
}
/* Fade toward the SAME color at zero alpha (via a color-mix mid-stop) rather than straight to
   `transparent` (= transparent black), so a light/tinted fade color doesn't wash through gray.
   The color-mix() gradient lives in an @supports block over a plain two-stop base. A background that
   mixes var() with color-mix() parses in every engine, and an engine without color-mix() (Chrome <111,
   Safari <16.2, Firefox <113) rejects it only when values are computed, so the whole `background`
   becomes `none` and the names get no fade. The base keeps a simple fade there, and every engine that
   knows color-mix() takes the block and draws the same gradient as before. */
.kaw-folio__names::before {
  top: 0;
  background: linear-gradient(180deg, var(--kaw-folio-fade-color) 0%, transparent 100%);
}
.kaw-folio__names::after {
  bottom: 0;
  background: linear-gradient(0deg, var(--kaw-folio-fade-color) 0%, transparent 100%);
}
@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .kaw-folio__names::before {
    background: linear-gradient(180deg, var(--kaw-folio-fade-color) 0%, color-mix(in srgb, var(--kaw-folio-fade-color), transparent) 55%, transparent 100%);
  }
  .kaw-folio__names::after {
    background: linear-gradient(0deg, var(--kaw-folio-fade-color) 0%, color-mix(in srgb, var(--kaw-folio-fade-color), transparent) 55%, transparent 100%);
  }
}

.kaw-folio__names-strip {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  will-change: transform;
}

.kaw-folio__name {
  display: flex;
  align-items: baseline;
  gap: 16px;
  width: 100%;
  padding: calc(var(--kaw-folio-name-gap) / 2) 0;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: start;
  cursor: pointer;
  color: var(--kaw-folio-name-muted);
  -webkit-tap-highlight-color: transparent;
  transition: color 0.35s ease;
}

.kaw-folio__name-text {
  font-size: 2.6rem;
  line-height: 1;
  font-weight: 550;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* The job-title label sits beside the active name only (JS toggles is-active). */
.kaw-folio__name-role {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  white-space: nowrap;
}

.kaw-folio__name.is-active { color: var(--kaw-folio-name); }
.kaw-folio__name.is-active .kaw-folio__name-role { opacity: 1; transform: translateX(0); }

.kaw-folio__name:focus-visible { outline: 2px solid #48D597; outline-offset: 4px; }
/* Wrap-around preview names (clones) are decorative loop hints — not interactive. */
.kaw-folio__name[data-clone] { cursor: default; }

/* ------------------------------------------------------------------ Images (right) */
.kaw-folio__images {
  position: absolute;
  right: var(--kaw-folio-image-right);
  top: 0;
  width: var(--kaw-folio-img-width);
  height: 100%;
  z-index: 1;
}

.kaw-folio__images-strip {
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  will-change: transform;
}

.kaw-folio__slot {
  position: absolute;
  left: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* top + height set inline by JS from --kaw-folio-img-* */
}

.kaw-folio__card {
  position: relative;
  /* Fixed 4:5 portrait so the strip card and the detail image share an aspect ratio — the FLIP
     then scales uniformly (sx === sy) and never stretches. Height drives it; width follows. */
  height: var(--kaw-folio-img-height);
  aspect-ratio: 4 / 5;
  width: auto;
  max-width: 100%;
  border-radius: 22px;
  overflow: hidden;
  background-color: #0b2536;
  transform-origin: center center;
  will-change: transform, opacity;
  /* NOTE: the card's own `box-shadow` is deliberately left free for the Image Shadow control. The
     Figma "Card Bevel" moved to ::before below, because a second box-shadow declaration REPLACES the
     first rather than adding to it — the control would otherwise wipe the bevel out. */
}

/* Subtle bevel from the Figma "Card Bevel". On ::before so the card's box-shadow stays controllable.
   Clipped to the rounded corners by the card's own overflow:hidden. */
.kaw-folio__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: inset 1px 1px 1px rgba(255, 255, 255, 0.35), inset -1px -1px 1px rgba(0, 0, 0, 0.4);
}

.kaw-folio__img {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  object-fit: cover;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}

.kaw-folio__card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.12), transparent 45%);
  pointer-events: none;
  transition: opacity 0.4s ease;
}

/* The See Bio button — offset inside the active card (position adjustable via the two vars). */
.kaw-folio__seebio {
  position: absolute;
  top: var(--kaw-folio-seebio-top);
  left: var(--kaw-folio-seebio-left);
  z-index: 2;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
}
.kaw-folio__slot.is-active .kaw-folio__seebio { opacity: 1; transform: translateY(0); pointer-events: auto; }

/* Returning from the detail (close): the active card is re-shown, so SNAP its overlay + See-Bio to 0
   (transition:none, so they don't slowly fade toward 0), then JS removes .is-returning a couple frames
   later — which re-enables the transitions above and eases them from 0 up to their normal state.
   Placed after the is-active rule so it wins on equal specificity. */
.kaw-folio__slot.is-returning .kaw-folio__card::after { opacity: 0; transition: none; }
.kaw-folio__slot.is-returning .kaw-folio__seebio { opacity: 0; transform: translateY(-6px); transition: none; }

/* ------------------------------------------------------------------ Detail (FLIP target) */
.kaw-folio__detail {
  position: absolute;
  inset: 0;
  z-index: 20;
}
.kaw-folio__detail[hidden] { display: none; }

.kaw-folio__detail-scrim {
  position: absolute;
  inset: 0;
  background-color: var(--kaw-folio-bg);
  opacity: 0;
}

.kaw-folio__detail-left {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  width: calc(55% - 30px);
  height: 100%;
  /* Top offset clears the fixed header; the left inset matches the names, bottom/right keep 5%. */
  padding: var(--kaw-folio-top) 5% 5% var(--kaw-folio-content-x);
  z-index: 2;
}

.kaw-folio__back {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  border: 0;
  background: none;
  font: inherit;
  padding: 0;
  color: #ffffff;
  font-size: 1rem;
  font-weight: 550;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.3s ease;
}
.kaw-folio__back svg { width: 22px; height: 22px; transform: rotate(180deg); transition: color 0.3s ease; }
.kaw-folio__back:focus-visible { outline: 2px solid #48D597; outline-offset: 4px; }

.kaw-folio__detail-headline {
  margin: 6% 0 0;
  font-size: clamp(2.2rem, 6vh, 4.4rem);
  line-height: 1.08;
  font-weight: 550;
  letter-spacing: -0.01em;
  transform-origin: top left;
}
/* The name is the FLIP target — give it the SAME line-height (1) as the strip name so the
   height-based FLIP scale equals the font-size ratio and the glyph doesn't shrink/pop. It MUST be
   inline-block: CSS transforms on a plain inline <span> are unreliable (some engines ignore the
   translate/scale mid-tween), which made the name jump to its final spot instead of morphing like
   the block-level image does. inline-block gives it a real box to transform. */
.kaw-folio__detail-name { display: inline-block; color: #ffffff; line-height: 1; transform-origin: top left; will-change: transform; }
.kaw-folio__detail-subline { color: #48D597; }

.kaw-folio__detail-bio {
  margin-top: auto;
  max-width: 46ch;
  font-size: 1rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.8);
}
.kaw-folio__detail-bio :last-child { margin-bottom: 0; }

.kaw-folio__detail-cta { margin-top: 28px; }

/* Right side — the FLIP target image + close button. Anchored below the header (top offset) and as
   tall as the remaining stage allows; width follows the 4:5 aspect and is capped so it never crosses
   into the text column. */
.kaw-folio__detail-right {
  position: absolute;
  top: var(--kaw-folio-top);
  right: 30px;
  width: min(44%, calc((100vh - var(--kaw-folio-top) - 40px) * 0.8));
  aspect-ratio: 4 / 5;
  z-index: 2;
}
.kaw-folio__detail-image {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 22px;
  overflow: hidden;
  background-color: #0b2536;
  transform-origin: top left;
}
.kaw-folio__detail-image img {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
}

.kaw-folio__detail-x {
  position: absolute;
  top: var(--kaw-folio-x-top);
  right: var(--kaw-folio-x-right);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 0;
  border-radius: 50%;
  background-color: #A7E6D7;
  color: #051C2C;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  transition: background-color 0.3s ease, color 0.3s ease;
}
.kaw-folio__detail-x svg { width: 20px; height: 20px; }
.kaw-folio__detail-x:focus-visible { outline: 2px solid #48D597; outline-offset: 3px; }

.kaw-folio__reveal { will-change: transform, opacity, filter; }

/* Hidden per-speaker detail data (JS reads it to populate the one detail panel on open). It is
   also the source for the no-JS / reduced-motion fallback list below. */
.kaw-folio__data { display: none; }
.kaw-folio__data-img { display: none; }

/* ------------------------------------------------------------------ Mobile: simple vertical card list
   Below the breakpoint the JS drops the pin/scrub entirely (data-mobile). The stage becomes a plain
   vertically-scrolling column of speaker cards — portrait image + name + role + See-Bio — and tapping a
   card (or its See-Bio) opens the detail, which stacks to one column and fades in. Nothing is pinned. */
/* The ENTIRE desktop stage is hidden on mobile — the JS has moved the headline + speaker cards into the
   flat `.kaw-folio__mlist` (and the detail panel out to the root). Hiding it outright means none of the
   pin's absolute scaffolding, its 100vh Section Height, or its overflow can affect the mobile layout at
   all — there is nothing left to fight over. */
.kaw-folio[data-mobile] .kaw-folio__pin { display: none !important; }

/* The mobile wrapper: an ordinary static block holding the headline, the deck, and the counter. */
.kaw-folio__mlist { display: none; }
.kaw-folio[data-mobile] .kaw-folio__mlist {
  display: block;
  position: static;
  width: 100%;
  height: auto;
  padding: var(--kaw-folio-m-deck-top) var(--kaw-folio-m-deck-pad) var(--kaw-folio-m-deck-bottom);
}

/* The DECK. This is the whole point of the mobile design: a FIXED height, so the section is exactly one
   card tall no matter how many speakers there are. Nothing here grows with the speaker count, so there
   is no tall column that a stray theme rule could clip. */
.kaw-folio__mdeck {
  position: relative;
  width: 100%;
  max-width: var(--kaw-folio-m-card-w);
  height: var(--kaw-folio-m-card-h);
  margin: 0 auto;
}
.kaw-folio[data-mobile] .kaw-folio__mdeck > .kaw-folio__slot {
  position: absolute !important;
  inset: 0;
  width: 100%;
  height: 100% !important;
  display: block !important;
  cursor: grab;
  will-change: transform;
}
.kaw-folio[data-mobile] .kaw-folio__mdeck > .kaw-folio__slot:active { cursor: grabbing; }
.kaw-folio[data-mobile] .kaw-folio__mdeck .kaw-folio__card {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  aspect-ratio: auto;   /* the deck sets the height; don't let 4:5 fight it */
}

/* Name + role sit ON the card, bottom-left, over a scrim so they stay legible on any photo. */
.kaw-folio[data-mobile] .kaw-folio__mdeck .kaw-folio__m-caption {
  position: absolute;
  left: var(--kaw-folio-m-cap-x);
  right: var(--kaw-folio-m-cap-x);
  bottom: var(--kaw-folio-m-cap-y);
  z-index: 3;
  text-align: start;
  pointer-events: none;
}
.kaw-folio[data-mobile] .kaw-folio__mdeck .kaw-folio__card::after {
  /* Deepen the existing overlay into a bottom scrim behind the caption. */
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.28) 32%, transparent 62%);
  opacity: 1;
}

/* The shared arrows (assets/css/arrows.css) belong to the mobile deck only — never the desktop reel,
   and never while a profile is open. This is the one arrow rule each widget owns. */
.kaw-folio:not([data-mobile]) .kaw-arrows,
.kaw-folio[data-detail-open] .kaw-arrows { display: none; }

/* Position counter under the deck. Fully stylable from the Buttons/Mobile controls. */
.kaw-folio__mcount { display: none; }
.kaw-folio[data-mobile] .kaw-folio__mcount {
  display: block;
  margin-top: var(--kaw-folio-m-count-gap);
  padding: 0 var(--kaw-folio-m-head-pad);   /* follow the headline inset, not the full-bleed deck */
  text-align: var(--kaw-folio-m-count-align);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.55);
}
.kaw-folio[data-mobile][data-kaw-folio-mcount-off] .kaw-folio__mcount { display: none; }
/* NOTHING in the widget's own box chain may cap the column's height, or the last card gets clipped at
   the section's bottom edge. The root, the image column, and the Elementor widget wrapper all get the
   same release.

   min-height MUST be `auto`, never `0`. Elementor containers are flex, so the widget is a flex ITEM,
   and a flex item's default `min-height: auto` is its content-based minimum — the thing that stops it
   being squashed below its own content. Forcing `0` removes that protection and lets any flex pressure
   compress the column (exactly the "last card is cut off" symptom). `auto` still overrides an explicit
   `min-height: 100vh`, so it defeats a cap without giving up the protection. */
.kaw-folio[data-mobile],
.kaw-folio[data-mobile] .kaw-folio__images {
  height: auto !important;
  min-height: auto !important;
  max-height: none !important;
  overflow: visible !important;
}
/* Upper bound covers the widest "Switch to Cards At" option (Tablet Landscape ≤ 1200px). These are
   only height/overflow RELEASES, so applying them a little wider than the active breakpoint is benign. */
@media (max-width: 1200.02px) {
  .elementor-widget-kaw_folio,
  .elementor-widget-kaw_folio > .elementor-widget-container {
    height: auto !important;
    min-height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    /* Never let the widget shrink inside a flex container — grow to content instead. */
    flex-shrink: 0 !important;
    flex-basis: auto !important;
  }
  /* Release the Elementor Container/Section that actually holds a Folio (and only those). Themes and
     Elementor's own mobile CSS commonly add `overflow: hidden` or a height at the ≤767px breakpoint,
     which crops the tall card column. :has() is ignored by browsers that don't support it, so this is
     purely additive. */
  .e-con:has(> .e-con-inner > .elementor-widget-kaw_folio),
  .e-con:has(> .elementor-widget-kaw_folio),
  .elementor-section:has(.elementor-widget-kaw_folio),
  .e-con-inner:has(> .elementor-widget-kaw_folio) {
    height: auto !important;
    min-height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }
}
/* The headline lives inside .kaw-folio__mlist, which owns the outer padding. NOTE: the slot/card rules
   live in the deck block above and are deliberately scoped to `.kaw-folio__mdeck >` — they must NOT
   force `transform: none` or a static position here, because the deck's stacking IS transforms. */
.kaw-folio[data-mobile] .kaw-folio__mlist > .kaw-folio__intro {
  position: static !important;
  max-width: 100%;
  margin: 0 0 var(--kaw-folio-m-head-gap);
  padding: 0 var(--kaw-folio-m-head-pad);
  pointer-events: auto;
}
.kaw-folio[data-mobile] .kaw-folio__mlist .kaw-folio__headline {
  margin: 0;
  font-size: clamp(2rem, 9vw, 3rem);   /* vw is fine — it doesn't shift as browser chrome hides */
}
/* The description is deliberately NOT overridden here — Description Width and Space Above Description
   are both responsive controls, so a rule of ours at this specificity would silently beat whatever the
   user set on the Mobile tab. The 480px default is already wider than a phone column. */
/* Name + role caption (built in JS from the matching name; positioned on the card by the deck block). */
.kaw-folio__m-caption { display: none; }
.kaw-folio[data-mobile] .kaw-folio__m-caption { display: block; }
.kaw-folio__m-name { display: block; font-size: 1.7rem; font-weight: 550; line-height: 1.05; color: #ffffff; }
.kaw-folio__m-role { display: block; margin-top: 6px; font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255, 255, 255, 0.72); }

/* ---- Detail on mobile: NORMAL FLOW, not a fixed overlay -------------------------------------------
   The panel used to be `position: fixed; inset: 0` with its own inner scroll container. That is the
   fragile pattern: a fixed box spans the viewport INCLUDING the scrollbar gutter (so percentages inside
   it overflowed), iOS breaks `position: fixed` for its descendants, and the panel opened wherever its
   internal scroll happened to sit — which read as "starting in the middle".
   Instead the panel is now an ordinary block in the page: while it's open the deck is swapped out for
   it (root gets data-detail-open), its sections simply stack down the page, and the PAGE scrolls it
   natively. No inner scroller, no fixed positioning, no scrollbar maths, nothing to trap.
   All spacing here is in px on purpose — see the note by --kaw-folio-m-card-h about vh on phones. */
.kaw-folio[data-mobile][data-detail-open] .kaw-folio__mlist { display: none; }
.kaw-folio[data-mobile] .kaw-folio__detail {
  position: relative;
  inset: auto;
  width: 100%;
  max-width: 100%;
  overflow: visible;
  padding-top: var(--kaw-folio-m-top);
  padding-bottom: var(--kaw-folio-m-detail-bottom);
}
/* Flex column purely for ORDER — the image markup comes after the text, and the photo belongs on top.
   Flex here is just stacking; the panel is still an ordinary in-flow block that the PAGE scrolls. */
.kaw-folio[data-mobile] .kaw-folio__detail:not([hidden]) { display: flex; flex-direction: column; }
/* No backdrop needed once the panel is in flow — it isn't floating over anything. */
.kaw-folio[data-mobile] .kaw-folio__detail-scrim { display: none; }

/* The image fills the CONTENT COLUMN and lines up with the text beneath it, rather than running to the
   screen edge — same left/right inset as the copy, so the panel reads as one padded column. Its height
   is an explicit px value (not the 4:5 ratio), which is what stops a full-width image from becoming
   enormous on a phone and keeps it stable when the device rotates. */
.kaw-folio[data-mobile] .kaw-folio__detail-right {
  order: -1;            /* photo on top, above the back link and copy */
  position: relative;   /* anchors the close button to the image, exactly like desktop */
  width: auto;
  max-width: var(--kaw-folio-m-detail-img-w);
  height: var(--kaw-folio-m-detail-img-h);
  flex: none;           /* never let the flex column stretch or squash the fixed photo height */
  aspect-ratio: auto;   /* the px height governs on mobile, not the desktop 4:5 */
  margin: 0 var(--kaw-folio-m-pad) var(--kaw-folio-m-detail-gap);
  right: auto;
  top: auto;
}
/* Padding uses a dedicated mobile value (--kaw-folio-m-pad), NOT the desktop content inset, so lowering
   the desktop Content Left Inset doesn't leave the mobile detail's text/button touching the edges. */
.kaw-folio[data-mobile] .kaw-folio__detail-left { position: static; width: 100%; height: auto; padding: 0 var(--kaw-folio-m-pad); }
.kaw-folio[data-mobile] .kaw-folio__detail-bio { margin-top: 18px; max-width: 100%; }
/* Close X on mobile — DEFAULT: sits in the image's top-right and scrolls away with the panel, exactly
   like desktop, positioned by its own offsets. */
.kaw-folio[data-mobile] .kaw-folio__detail-x {
  position: absolute;
  top: var(--kaw-folio-m-x-top);
  right: var(--kaw-folio-m-x-right);
  z-index: 21;
}
/* Optional (Mobile Close Button = "Pinned to the screen"): keep it stuck to the viewport so it stays
   reachable through a long bio, riding the header clearance so a fixed nav can't cover it. */
.kaw-folio[data-mobile][data-kaw-folio-mclose="fixed"] .kaw-folio__detail-x {
  position: fixed;
  top: calc(var(--kaw-folio-m-top) + var(--kaw-folio-m-x-top));
}

/* ------------------------------------------------------------------ Fallback (no-JS / reduced-motion / editor)
   Root never gets .is-ready → the interactive deck is hidden and the per-speaker data block is
   rendered as a plain, fully readable list (image + name + role + subline + bio + working CTA), so
   all content and links are reachable without the animation. */
/* !important for the same reason as the mobile pin rule: the Section Height control generates
   `{{WRAPPER}} .kaw-folio__pin` (= `.elementor-element.elementor-element-ID .kaw-folio__pin`), which
   matches this rule's specificity but loads later — so without it the EDITOR preview and every
   reduced-motion / no-JS visitor get the readable stacked list cropped to 100vh. */
.kaw-folio:not(.is-ready) .kaw-folio__pin { height: auto !important; overflow: visible !important; }
.kaw-folio:not(.is-ready) .kaw-folio__intro { position: static; max-width: 100%; margin: 0 0 8px; padding: 5% 5% 0; pointer-events: auto; }
.kaw-folio:not(.is-ready) .kaw-folio__names,
.kaw-folio:not(.is-ready) .kaw-folio__images,
.kaw-folio:not(.is-ready) .kaw-folio__counter,
.kaw-folio:not(.is-ready) .kaw-folio__detail { display: none; }
.kaw-folio:not(.is-ready) .kaw-folio__data { display: block; padding: 3% 5% 6%; }
.kaw-folio:not(.is-ready) .kaw-folio__data > div { max-width: 620px; margin: 0 0 56px; }
.kaw-folio:not(.is-ready) .kaw-folio__data-img { display: block; width: 100%; max-width: 380px; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 22px; margin-bottom: 20px; }
.kaw-folio:not(.is-ready) [data-field="name"] { display: block; font-size: 2rem; font-weight: 550; color: var(--kaw-folio-name); }
.kaw-folio:not(.is-ready) .kaw-folio__data-role { display: block; margin-top: 4px; font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(255, 255, 255, 0.55); }
.kaw-folio:not(.is-ready) [data-field="subline"] { display: block; margin: 6px 0 14px; color: #48D597; }
.kaw-folio:not(.is-ready) [data-field="img"] { display: none; }
.kaw-folio:not(.is-ready) [data-field="bio"] { display: block; margin-bottom: 18px; color: rgba(255, 255, 255, 0.8); }
.kaw-folio:not(.is-ready) [data-field="cta"] { display: block; }

@media (prefers-reduced-motion: reduce) {
  .kaw-folio__name, .kaw-folio__name-role, .kaw-folio__seebio, .kaw-folio__card { transition: none !important; }
}
