/* Kingdom Advisors Elementor Widgets — Split Cards Scroll (Schedule)
   A single wide front image/video splits into three portrait cards that flip 180° in place
   (no rotation/fan) to reveal a schedule back: icon → title … (spacer) … bottom line → table.
   assets/js/split-cards.js pins the card-height stage and drives the split + a triggered flip
   on scroll (desktop) and a flick stack (mobile). Card height is an explicit Elementor control
   (bulletproof — no aspect-ratio dependency). The front "A" radius rides on --kaw-radius-a and
   the animated gap on --kaw-gap. Without JS the merged front shows; reduced-motion/editor fall
   back to a static, content-first schedule. */

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

.kaw-split {
  position: relative;
  width: 100%;
}

.kaw-split-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

/* The stage stays the height of the cards (tight in the layout, no 100vh block). Centering is
   handled by the ScrollTrigger pin (start:'center center'), which locks the compact widget in the
   middle of the screen only once it's scrolled to — so the layout above stays tight. */

/* ------------------------------------------------------------------ Card row */
.kaw-split-cards {
  position: relative;
  display: flex;
  gap: var(--kaw-gap, 0px);
  width: 100%;
  margin: 0 auto;
  perspective: 1600px;
  transform-origin: center center;
  will-change: transform;
}

.kaw-split-card {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: 600px;
  transform-style: preserve-3d;
  will-change: transform;
}

/* ---------------------------------------------------------------------- Faces */
.kaw-split-card__front,
.kaw-split-card__back {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  overflow: hidden;
}

/* Front (A). Merged start: only the outer corners of the end cards are rounded; JS rounds
   every corner to --kaw-radius-a on split. */
.kaw-split-card__front {
  border-radius: 0;
  background-color: #0b1c28;
  /* Forces WebKit to clip a composited child (an <img>/<video> slice) to the rounded corners
     while the card is mid-3D-flip. */
  isolation: isolate;
}

/* Keyed on --first / --last, which PHP puts on the end cards, NOT on the card number: the count
   is a control now, so with two cards there is no card 3 to be the right-hand end. */
.kaw-split-card--first .kaw-split-card__front {
  border-radius: var(--kaw-radius-a, 16px) 0 0 var(--kaw-radius-a, 16px);
}

.kaw-split-card--last .kaw-split-card__front {
  border-radius: 0 var(--kaw-radius-a, 16px) var(--kaw-radius-a, 16px) 0;
}

/* Overlap the inner two cards by 1px so the merged image has no sub-pixel seam. The overlap
   shows the SAME image pixel (the exact third boundary), so it is invisible; it just covers the
   hairline gap. The JS-animated `gap` opens on top of this (effective gap = gap − 1px). */
.kaw-split-card:not(.kaw-split-card--first) {
  margin-left: -1px;
}

/* Front media — a cover <img>/<video>. The base slice is 300% wide and shifted per card with a
   transform, so the three slices reassemble seamlessly at gap 0 and tear apart as the gap opens.
   object-fit: cover means it holds up at any card height without distortion. */
.kaw-split-card__media {
  position: absolute;
  top: 0;
  left: 0;
  /* !important defeats theme/Elementor `img,video { max-width:100%; height:auto }` rules that
     would otherwise clamp the 300%-wide slice down to one card (leaving cards 2 & 3 blank). */
  width: 100%;
  height: 100% !important;
  max-width: none !important;
  object-fit: cover;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

.kaw-split-card__media--slice {
  /* One slice per card: the element is COUNT x the card width and each card shifts it by its own
     share, so the slices reassemble seamlessly at gap 0. Was a hard-coded 300%. */
  width: calc(var(--kaw-sc-count, 3) * 100%) !important;
  transform-origin: left center;
}

/* Back (B) — the schedule. Rotated so it's hidden until the card flips. */
.kaw-split-card__back {
  transform: rotateY(180deg);
  border-radius: 16px;
  background-color: #2f2f2f;
  display: flex;
  flex-direction: column;
  text-align: start;
}

/* PER-CARD BACK FALLBACKS. The three `back_bg_{n}` controls default to three different colors (Card 1
   aqua, Card 2 night, Card 3 daybreak) but all of them consume the single #2f2f2f rule above. While a
   control holds a value, Elementor's own rule (0,4,0) wins, and while it is untouched the registered
   default substitutes. The third state is a control that is STORED BUT EMPTY: Elementor drops the whole
   declaration, and every card then fell back to that neutral gray. Cards 1 and 3 carry night text by
   default, which is 1.30:1 on the gray.

   These three rules are (0,2,0), so they sit under any control and over the shared rule, and each card
   falls back to ITS OWN default instead of a color nobody chose. Keep them in step with `$card_defaults`
   in widgets/split-cards.php: they are the same three values written twice. */
.kaw-split-card--1 .kaw-split-card__back { background-color: #48D597; }  /* C_AQUA */
.kaw-split-card--2 .kaw-split-card__back { background-color: #051C2C; }  /* C_NIGHT */
.kaw-split-card--3 .kaw-split-card__back { background-color: #8BD3E6; }  /* C_DAYBREAK */

.kaw-split-card__top {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Stretches to fill the card height, pushing the bottom block down; its min-height is the
   "Middle Space (min)" control, which arrives as --kaw-sc-mid.

   The cap is the point of the indirection. The spacer is `flex: 1 1 auto` with an empty content box,
   so its flex basis resolves to 0 and it simply GROWS to whatever is left over: whenever the card is
   tall enough, the spacer already equals the free space and its min-height is irrelevant. The floor
   therefore only ever engages in the one case where it does damage — when there is NOT enough room —
   and there it holds space hostage and pushes the bottom block (date line + schedule table) past the
   card, where `overflow: hidden` on the back cuts it off.

   That is why this is capped rather than removed: the control still guarantees the gap it promises on
   any card with room to spare, and quietly gives way on one without. Measured on the live Conference
   home page, whose Card Height is authored as `65vh` so the card really does track the browser window
   while the control's 200px floor did not: at a 1080px-tall window nothing changes at all (spacer
   401/361/361, nothing clipped, identical before and after); at 700px the schedule was losing
   10/50/50px and now loses none; at 600px it was losing 75/115/115px and now loses none. 20% and 15%
   caps were also measured and buy nothing extra at any height, so 25% is the largest value that works
   and keeps the most breathing room.

   A percentage min-height on a flex item resolves against the flex container's height, and the
   container here is `.kaw-split-card__back`, which has a definite height (`inset: 0` on a card with an
   explicit height), so the 25% is well defined. Override --kaw-sc-mid-cap from site CSS if a card's
   top and bottom blocks are unusually tall. This affects the SCHEDULE back only; the Image & Text back
   has no spacer, and the mobile flick stack uses a fixed px card height where the cap never engages. */
.kaw-split-card__spacer {
  flex: 1 1 auto;
  min-height: min(var(--kaw-sc-mid, 40px), var(--kaw-sc-mid-cap, 25%));
}

.kaw-split-card__bottom {
  flex: 0 0 auto;
}

.kaw-split-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  line-height: 0;
  font-size: 24px;
  color: #051c2c;
}

/* Size by HEIGHT and let width follow the icon's aspect ratio, so wide icons (2–3 shapes)
   keep their width instead of being crushed into a square. */
.kaw-split-card__icon svg {
  height: 24px;
  width: auto;
  max-width: none;
  display: block;
  fill: currentColor;
}

.kaw-split-card__icon i {
  font-size: inherit;
  line-height: 1;
}

.kaw-split-card__title {
  margin: 0;
  font-size: 2.75rem;
  line-height: 1.02;
  font-weight: 600;
}

.kaw-split-card__bottomline {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.kaw-split-card__table {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 16px;
}

.kaw-split-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.kaw-split-row__time {
  flex: 0 0 64px;
  font-weight: 700;
}

.kaw-split-row__text {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---------------------------------------------- Static schedule (reduced-motion / editor back)
   JS adds .is-static-back when the scroll/flick animation can't (or shouldn't) run, so the
   schedule backs show upright, content-first, no 3-D motion. Fronts hide. The default (no class)
   shows the merged fronts, which covers editor "Front" preview and no-JS. */
.kaw-split.is-static-back .kaw-split-cards {
  width: 100% !important;
  gap: 16px;
}

.kaw-split.is-static-back .kaw-split-card {
  transform: none;
  height: auto;
  margin-left: 0;
}

.kaw-split.is-static-back .kaw-split-card__front {
  display: none;
}

.kaw-split.is-static-back .kaw-split-card__back {
  position: relative;
  inset: auto;
  transform: none;
  -webkit-backface-visibility: visible;
  backface-visibility: visible;
  height: auto;
}

/* --------------------------------------------------------------- Mobile flick stack
   JS sets data-mobile-mode="flick" below the breakpoint: the cards become an absolutely
   stacked deck of schedule backs, flicked through with GSAP Draggable. */
.kaw-split[data-mobile-mode="flick"] .kaw-split-cards {
  display: block;
  position: relative;
  width: 100%;
  max-width: 340px;
  height: 460px;
  perspective: none;
  touch-action: pan-y;
}

.kaw-split[data-mobile-mode="flick"] .kaw-split-card {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin-left: 0;
  transform-style: flat;
  cursor: grab;
}

.kaw-split[data-mobile-mode="flick"] .kaw-split-card__front {
  display: none;
}

.kaw-split[data-mobile-mode="flick"] .kaw-split-card__back {
  position: relative;
  inset: auto;
  transform: none;
  -webkit-backface-visibility: visible;
  backface-visibility: visible;
  height: 100%;
}

.kaw-split[data-mobile-mode="flick"] .kaw-split-card.is-dragging {
  cursor: grabbing;
}

/* The shared arrows (assets/css/arrows.css) belong to the flick deck only — never the desktop split,
   the editor preview, or the reduced-motion/no-JS static schedule. This is the one arrow rule this
   widget owns; hiding the nav (not the buttons) also beats the Show/Hide control's own display rule,
   so a stray "Show" on desktop can never leak arrows onto the scrolling split. */
.kaw-split:not([data-mobile-mode="flick"]) .kaw-arrows { display: none; }

/* No-JS / very old browsers: keep the merged front centered and a touch narrower on small
   screens. JS gates the real responsive behavior on the configurable breakpoint. */
@media (max-width: 1000px) {
  .kaw-split:not([data-mobile-mode]) .kaw-split-cards {
    max-width: 480px;
  }

  /* Static schedule on small screens: stack the upright backs into a single column. */
  .kaw-split.is-static-back .kaw-split-cards {
    flex-direction: column;
    max-width: 420px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .kaw-split-card {
    transition: none !important;
  }
}


/* ============================================================ Back layout: Image & Text
   The alternative card back: a photo running edge to edge across the top, and a paragraph on the
   card's own background underneath. Added alongside the schedule back, never replacing it — the
   layout is a control and it defaults to the schedule, so existing pages are untouched.

   The photo is deliberately NOT padded. It bleeds to all three edges and the card's own radius
   does the clipping, which is what `overflow: hidden` on the back is already there for. Only the
   text block is padded, and that padding is its own control. */
.kaw-split-card__back--media {
  display: flex;
  flex-direction: column;
}

/* The photo yields to the copy on a short card, and yields the SAME amount on every card in the row.

   The bug this fixes: the card has a fixed `height` (the Card Height control), the back is
   `position: absolute; inset: 0` with `overflow: hidden`, and inside it the photo was `flex: 0 0 auto`
   at a fixed height while the copy took the remainder. So the copy's share was
   `card height - back padding - photo height`, and anything longer than that was simply not painted.
   Narrow the window and it fails from BOTH ends at once: the cards get narrower so the same sentence
   wraps onto more lines, while Elementor's WIDTH breakpoints take the card height down (600/520/460).
   Narrower windows need more height and are given less. Nothing here ever read the viewport height.

   This is also exactly why the schedule back never showed the bug: it has had a shock absorber since
   day one - `.kaw-split-card__spacer` at `flex: 1 1 auto` above - and the media back had none.

   Why a reserved floor for the copy rather than making the photo shrinkable. `flex-shrink` on the photo
   also works, but each card then shrinks by ITS OWN shortfall, so a row of cards with different copy
   lengths ends up with its photos at different heights and the clean horizontal line through the row is
   lost. The form below is a function of the CARD, not of the content, so every card in a row computes an
   identical number and the photos stay level. That was a deliberate client requirement.

   `min()` can only ever make the photo SHORTER, never taller, so a card whose Image Height is set below
   the reserve is untouched - important, because `min-height` would have been a floor in both directions
   and would have GROWN a deliberately small photo. Measured in a browser at 16px/1.5 copy: desktop
   (600px card) and a windowed laptop are byte-identical to before at 300px with nothing clipped; tablet
   (520px) goes 300 -> 236 and clipped 46px -> 0; phone (460px) goes 300 -> 176 and clipped 57px -> 0;
   photos level in all four.

   The `max(120px, ...)` is load-bearing, not belt-and-braces: on a very short card `calc(100% - 220px)`
   goes NEGATIVE, and without the guard the photo collapses to 0 and disappears entirely.

   `--kaw-sc-copy-min` is the escape hatch. It is deliberately NOT a control: as a stylesheet constant it
   can be revised in any future version without touching a single saved page, whereas a registered control
   default could never be changed again (see section 2, control-value state 3). Override it in site CSS if
   the description typography is much larger than the 16px/1.5 this was measured against.

   KEEP THIS DECLARATION ON ONE LINE. It was authored across two lines for readability and a CSS
   minifier on the live site mangled it: the comma before the second argument came out as a `)`,
   producing `min(var(--kaw-sc-photo-h, 300px)) max(120px, calc(...))));` — unbalanced, invalid, and
   silently dropped by the browser. With no height the photo fell back to the image's natural ratio
   and rendered 427px instead of 299px on a 519px card, stealing ~128px from the copy. That is what a
   client reported as text being cut off, and it was invisible to us because minified assets are not
   served to logged-in users. A single-line `min()` elsewhere in this same file came through the same
   minifier untouched. Do not reformat this across lines, and do not "simplify" it to clamp() either:
   clamp(120px, X, var(--kaw-sc-photo-h)) looks equivalent and is not — where the Image Height control
   is set BELOW 120px, clamp returns the minimum and would GROW the photo, which is the exact
   regression the min()/max() pair is shaped to avoid. */
.kaw-split-card__photo {
  flex: 0 0 auto;
  width: 100%;
  height: min(var(--kaw-sc-photo-h, 300px), max(120px, calc(100% - var(--kaw-sc-copy-min, 220px))));
  overflow: hidden;
}

/* A bare <img> is the most contested element on a WordPress site — near enough every theme ships
   `img { height: auto }`, and that beats a single-class selector and leaves the photo at its
   natural height. Hardened for the same reason the Image Marquee's logo height is. Safe here only
   because the value is a VARIABLE: the control still owns the number. */
.kaw-split-card__back--media .kaw-split-card__photo img {
  display: block;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
  object-position: var(--kaw-sc-photo-pos, center);
}

.kaw-split-card__copy {
  flex: 1 1 auto;
  padding: var(--kaw-sc-copy-pt, 28px) var(--kaw-sc-copy-pr, 28px)
           var(--kaw-sc-copy-pb, 28px) var(--kaw-sc-copy-pl, 28px);
}

/* Hardened for the same reason as every other bare tag in this pack: a theme's `p { margin }` on a
   single-class selector would push the copy off the padding the control just set. */
.kaw-split-card__back--media .kaw-split-card__copy p {
  margin: 0 !important;
}

/* Optional headline above the description. It renders only when the card has one, so the gap lives
   on the headline's own margin rather than on the copy block — a card without a headline is spaced
   exactly as it was before this existed.

   Hardened with !important for the same reason as the paragraph above: an h3 is a bare tag, and
   near enough every theme sets heading margins at a specificity one class cannot reach, which would
   throw out the gap the control just set. Safe because the value is a VARIABLE — the control still
   owns the number.

   The size and weight below are only a starting point so an unstyled headline does not fall back to
   the browser's own heading metrics; the Headline Typography control beats them at (0,4,0) the
   moment it is touched, and emits nothing until then. */
.kaw-split-card__back--media .kaw-split-card__copy .kaw-split-card__headline {
  margin: 0 0 var(--kaw-sc-headline-gap, 12px) !important;
  padding: 0 !important;
  font-size: 1.25em;
  line-height: 1.25;
  font-weight: 700;
}

/* A headline with no description under it should not leave a dangling gap inside the padded box. */
.kaw-split-card__back--media .kaw-split-card__copy .kaw-split-card__headline:last-child {
  margin-bottom: 0 !important;
}
