/* ============================================================
   assets/css/promo-slider.css - v0.6.1
   Homepage promo slider.

   Originally lifted from the design handoff reference, then rewritten to
   Brian's notes on 2026-08-16. The handoff's green accent (#84b56f) and its
   kicker chip are GONE, not overridden - the CTA and the progress bar now use
   the same two blues as the Product Loop "view all" button so the homepage has
   one button language instead of two.

   Project rules: NO border-radius anywhere, NO em dashes in copy.
   ============================================================ */

/* No @import of Poppins here. The site already loads it (the theme, the header
   promo and the Product Loop all use it), so importing it again is a second
   render-blocking request for a font that is already on the page. If Poppins
   ever stops shipping site-wide, bundle woff2 files here rather than adding the
   Google import back. */

/* ---- Design tokens ---------------------------------------
   Scoped to .ps-wrap, not :root, so they do not leak generically-named custom
   properties onto every element on the page.
   The two blues are read from plugins/bdo-product-loop/assets/bdo-product-loop.css
   (the .bdo-pl-viewall button). If that button is ever recolored, these are the
   two lines that have to move with it. */
.ps-wrap {
  --ps-ink:       #0b1020;  /* slider background behind the art */
  --ps-blue:      #1f6feb;  /* CTA label, ACTIVE progress segment */
  --ps-navy:      #163a6b;  /* CTA chevron cap, inactive progress segment */
  --ps-white:     #ffffff;
  --ps-body:      rgba(255,255,255,.88);
  --ps-fade:      11,16,32; /* rgb of --ps-ink, for the scrim gradient */
  --ps-fade-time: .8s;

  container-type: inline-size; /* the wrap IS the responsive context */
  width: 100%;
}

/* Written as an explicit 0 !important rather than left unset. Left unset, the
   theme's and Elementor's own button and image rules round our CTA and art,
   which is how a square design quietly stops being square. */
.ps-wrap,
.ps-wrap * {
  border-radius: 0 !important;
}

.ps-slider {
  position: relative;
  width: 100%;
  aspect-ratio: 40 / 19;            /* wide desktop hero */
  overflow: hidden;
  background: var(--ps-ink);
  font-family: 'Poppins', Helvetica, Arial, sans-serif;
}

/* Portrait hero on narrow containers (phones). Uses CONTAINER width, not
   viewport, so it is correct inside any theme column.

   BOTH numbers here are height levers and they have to move together. The
   aspect-ratio governs on an ordinary phone (390px wide gives a 468px tall
   box, well under the cap), while max-height only bites on a short screen. Move
   one without the other and the component is shorter on most phones but not on
   the ones that were already cramped.

   Brian asked for 10% less height on 2026-08-16, from the handoff's 3/4 and
   78svh. 3/4 means height = 1.333x width; 10% off that is 1.2x, which is 5/6.
   78svh less 10% is 70svh. svh rather than vh so the iOS URL bar hiding and
   showing does not resize the hero mid-scroll. */
@container (max-width: 600px) {
  .ps-slider { aspect-ratio: 5 / 6; max-height: 70svh; }
}

/* ---- Slides (cross-fade) ---------------------------------- */
.ps-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  z-index: 1;
  transition: opacity var(--ps-fade-time) ease;
}
.ps-slide.is-active { opacity: 1; z-index: 2; }

.ps-media { position: absolute; inset: 0; }

/* The extra .ps-wrap and the !important are both load-bearing, do not tidy them
   away. Elementor ships `.elementor img { height: auto }` at the same
   specificity as a bare `.ps-media img`, and its stylesheet loads after ours, so
   the tie went to Elementor and the art rendered at its natural proportions
   instead of filling the slide. On mobile that left a hard-edged block of empty
   --ps-ink under the photo which read as a heavy black bar, not as a fade. With
   height beaten, object-fit works again. */
.ps-wrap .ps-media img {
  width: 100%;
  height: 100% !important;
  object-fit: cover;
  display: block;
}

/* Bottom scrim so text stays legible without hiding the art */
.ps-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(0deg,
    rgba(var(--ps-fade), .90) 0%,
    rgba(var(--ps-fade), .60) 22%,
    rgba(var(--ps-fade), 0)   46%);
}

/* Whole-slide click target. Sits above the art and the scrim but BELOW
   .ps-content, so the real CTA is the thing a click actually lands on when the
   pointer is over it. Deliberately empty and invisible. */
.ps-hit {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
  text-decoration: none;
}

/* ---- Content ---------------------------------------------- */
.ps-content {
  position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 4;                         /* above .ps-hit */
  padding: clamp(22px, 5cqw, 60px);
  /* Still none, so a swipe that starts on the headline is a swipe rather than a
     drag on text, and so .ps-hit collects the click everywhere except the CTA. */
  pointer-events: none;
}

.ps-title {
  margin: 0 0 10px;
  max-width: 22ch;
  color: var(--ps-white);
  font-weight: 800;
  font-size: clamp(22px, 4.4cqw, 50px);
  line-height: 1.05;
  letter-spacing: -.01em;
  text-transform: uppercase;
  text-shadow: 0 2px 18px rgba(var(--ps-fade), .55);
  /* hard cap at two lines */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}

.ps-desc {
  margin: 0 0 18px;
  max-width: 60ch;
  color: var(--ps-body);
  font-weight: 400;
  font-size: clamp(12px, 1.6cqw, 16px);
  line-height: 1.45;
  text-wrap: pretty;
  text-shadow: 0 1px 12px rgba(var(--ps-fade), .5);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}

/* ---- CTA --------------------------------------------------
   A deliberate copy of the Product Loop "view all" button (.bdo-pl-viewall):
   a colored label segment butted against a chevron cap, and on hover, keyboard
   focus or tap the two colors swap. CSS only, no JS. Same markup shape, same
   two blues, same swap, so the two buttons cannot drift apart by accident.
   ----------------------------------------------------------- */
.ps-cta {
  display: inline-flex;
  align-items: stretch;
  pointer-events: auto;               /* .ps-content above is pointer-events:none */
  overflow: hidden;
  text-decoration: none;
  /* !important: beat the theme's default link color so text and chevron stay white. */
  color: var(--ps-white) !important;
  font-weight: 600;
  font-size: clamp(13px, 1.5cqw, 17px);
}
.ps-cta,
.ps-cta:hover,
.ps-cta:focus,
.ps-cta .ps-cta-label,
.ps-cta .ps-cta-cap { color: var(--ps-white) !important; text-decoration: none; }

.ps-cta-label {
  display: flex;
  align-items: center;
  white-space: nowrap;
  padding: clamp(13px, 1.7cqw, 19px) clamp(22px, 3cqw, 34px);
  background: var(--ps-blue);
  text-transform: lowercase;          /* button text renders all lower case */
  transition: background .18s ease;
}
.ps-cta-cap {
  display: flex;
  align-items: center;
  padding: clamp(13px, 1.7cqw, 19px) clamp(16px, 2.1cqw, 24px);
  font-size: 1.3em;
  font-weight: 700;
  line-height: 1;
  background: var(--ps-navy);
  transition: background .18s ease;
}

/* Hover / keyboard focus / tap: swap the two segment colors. */
.ps-cta:hover  .ps-cta-label,
.ps-cta:focus-visible .ps-cta-label,
.ps-cta:active .ps-cta-label { background: var(--ps-navy); }
.ps-cta:hover  .ps-cta-cap,
.ps-cta:focus-visible .ps-cta-cap,
.ps-cta:active .ps-cta-cap { background: var(--ps-blue); }

/* ---- Progress / navigation -------------------------------- */
.ps-progress {
  position: absolute; top: 0; left: 0; right: 0; z-index: 6;
  display: flex; gap: 6px;
  /* align-items:center, NOT the flex default of stretch. Stretched, each segment
     grows to the tallest item in the row, so any height the theme puts on a
     button silently becomes the height of the whole bar. */
  align-items: center;
  padding: 14px clamp(22px, 5cqw, 60px);
}

/* border: 0 !important for the same reason border-radius is written that way.
   These are real <button>s, so the theme's button rules apply to them, and a
   plain `border: none` lost to them: the segments rendered with the theme's red
   outline. Background-clip stops that outline's ghost showing through the fill.

   The two background-colors carry !important for the same reason. The theme
   styles <button> backgrounds, and these are real buttons, so an unweighted
   declaration is not guaranteed to win. Dark blue inactive, light blue active,
   and both have to actually land or the bar reads as one flat color. */
.ps-seg {
  position: relative;                 /* anchors the touch target below */
  flex: 1;
  /* 4px is Brian's settled choice, arrived at by looking at all three: 4px, then
     2px which read too thin, then 3px, then back to 4px. It happens to match the
     handoff's original value, which is coincidence rather than a reason. Do not
     "restore" 2px or 3px from an older commit thinking it was the intent.

     Every declaration here is weighted, and none of it is belt-and-braces. The
     bar ignored a plain `height` through v0.2.1 because the theme styles
     <button> and these are real buttons: its min-height and padding beat an
     unweighted height, and line-height alone can hold a thin bar open. The
     colors landed in that same release only because they were the one thing
     already weighted. Confirmed in the browser at v0.2.2, where the computed
     height read exactly what this rule asked for. */
  height: 4px !important;
  min-height: 0 !important;
  max-height: 4px !important;
  line-height: 0 !important;
  font-size: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 0 !important;
  outline: 0;
  box-shadow: none !important;
  background-color: var(--ps-navy) !important;   /* inactive: dark blue */
  background-image: none !important;
  background-clip: padding-box;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: background-color .3s ease;
}
/* Active is the LIGHTER blue, swapped from the other way round on 2026-08-16.
   The active segment sits on photographic artwork, and the dark one disappeared
   into dark images, which is the opposite of what an active indicator is for. */
.ps-seg.is-active { background-color: var(--ps-blue) !important; }

/* The bar is 4px tall, which is far below a usable touch target, so give each
   segment an invisible one that overhangs it. Without this the only manual
   control on mobile would be a 4px line. Swipe is the primary gesture (see
   promo-slider.js); this is the fallback. */
.ps-seg::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -14px;
  height: 30px;
}

/* ---- Reduced motion: no cross-fade, no autoplay ----------- */
@media (prefers-reduced-motion: reduce) {
  .ps-slide,
  .ps-cta-label,
  .ps-cta-cap,
  .ps-seg { transition: none; }
}
