/* ============================================================
   CYNEXIX — Product Showcase consistency pass
   Scope: sections .details / .details-2 on the homepage only.
   Loaded after the main stylesheet (see functions.php enqueue).
   Design language unchanged: every value below already exists in
   the build; this file consolidates them as tokens and removes
   the per-section divergence. Source: docs/showcase-refactor/
   product-showcase.css with the legacy-markup selector blocks
   dropped (markup is fully migrated to .ps-cta / .ps-media--cutout).
   ============================================================ */

:root {
  /* Color (existing values, now named) */
  --ps-navy:            #1C2D5A;   /* matches --default-color */
  --ps-navy-hover:      #24396F;
  --ps-surface-section: #F9FAFE;   /* odd sections (unchanged) */
  --ps-surface-band:    #F2F6FF;   /* solid equiv. of rgba(229,237,255,.48) */
  --ps-surface-panel:   #E7F1FF;   /* card / media-frame fill (unchanged) */

  /* Radius motif (existing) */
  --ps-radius-card:  16px;
  --ps-radius-flare: 80px;

  /* Rhythm (existing) */
  --ps-space-section: 56px;
  --ps-media-height:  420px;
  --ps-text-measure:  560px;   /* shared reading-column width */
}

/* ------------------------------------------------------------
   1) Surfaces — exactly two section surfaces in the showcase.
   .blue-bg previously used rgba(229,237,255,.48); the solid
   equivalent renders identically but composites predictably.
   ------------------------------------------------------------ */
.details   { background: var(--ps-surface-section); }
.blue-bg   { background: var(--ps-surface-band) !important; }

/* ------------------------------------------------------------
   2) One CTA for every showcase block.
   The site's existing primary pill (.btn-get-started values),
   promoted to the single showcase CTA.
   ------------------------------------------------------------ */
.ps-cta {
  display: inline-block;
  background: var(--ps-navy);
  color: #fff;
  border-radius: 50px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 1px;
  line-height: 1;
  padding: 12px 32px;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform 0.25s, background-color 0.3s, box-shadow 0.25s;
  margin: 0;               /* replaces .btn-get-started's margin: 8px */
}

.ps-cta:hover {
  background: var(--ps-navy-hover);
  color: #fff;
  box-shadow: rgba(13, 30, 61, 0.18) 0 8px 20px;
  transform: translateY(-2px);
}

/* Accessibility: visible focus, never removed */
.ps-cta:focus-visible {
  outline: 2px solid var(--ps-navy);
  outline-offset: 2px;
}

/* ------------------------------------------------------------
   3) Media frame — the container is the invariant.
   Carousel blocks already render the standard frame; this extends
   it to single-image "cutout" products (e.g. Mastersky): fixed
   height, studio-sweep fill, mirrored corner flare, centered art.
   ------------------------------------------------------------ */
.ps-media--cutout {
  height: var(--ps-media-height);
  width: 100%;
  background: linear-gradient(180deg, #FFFFFF 0%, #E4F3FC 100%);
    /* studio-sweep fallback for transparent cutouts only — invisible
       under cover-fit photography; white top separates from the
       surfaces, sky-tinted base (brand cyan family) grounds the
       product */
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ------------------------------------------------------------
   Open composition (Pattern 1): no card chrome anywhere in the
   showcase. Text sits directly on the section surface and centers
   vertically against the media column.
   ------------------------------------------------------------ */
section.details .row,
section.details-2 .row {
  align-items: center;
}
section.details .row > [class*="col-"]:not(.featImage),
section.details-2 .row > [class*="col-"]:not(.featImage) {
  padding-top: 16px;
  padding-bottom: 16px;
}

/* Visual rhythm: lift the text block ~24px above true center so it
   aligns with the upper portion of the media (asymmetric padding
   rather than transform — the columns are AOS-animated). Desktop only;
   stacked layouts keep symmetric spacing. */
@media (min-width: 992px) {
  section.details .row > [class*="col-"]:not(.featImage),
  section.details-2 .row > [class*="col-"]:not(.featImage) {
    padding-bottom: 64px;
  }
}

/* One reading column for every section: kicker, title, description
   and CTA all live within the same measure (~70 characters at this
   type size), so every showcase block shares one visual rhythm and
   right boundary regardless of copy length. The measure is a token so
   a future design-system pass can tune it in one place. */
section.details .row > [class*="col-"]:not(.featImage) > *,
section.details-2 .row > [class*="col-"]:not(.featImage) > * {
  max-width: var(--ps-text-measure, 560px);
}

/* Flare mirrors with layout: image-left flares top-right,
   image-right flares top-left (matches existing carousels). */
section.details   .featImage .image-container {
  border-radius: var(--ps-radius-card) var(--ps-radius-flare)
                 var(--ps-radius-card) var(--ps-radius-card);
}
section.details-2 .featImage .image-container {
  border-radius: var(--ps-radius-flare) var(--ps-radius-card)
                 var(--ps-radius-card) var(--ps-radius-card);
}

.ps-media--cutout img {
  /* Slightly larger presence so the product is the primary visual;
     the width cap keeps wide assets (or future images that ship with
     their own backgrounds) inside the frame without layout changes. */
  max-height: calc(var(--ps-media-height) * 0.95);
  max-width: 94%;
  width: auto;
}

/* ------------------------------------------------------------
   4) Responsive — mirrors current Bootstrap behavior; the flare
   steps down so it doesn't dominate small frames.
   ------------------------------------------------------------ */
@media (max-width: 991.98px) {
  :root { --ps-radius-flare: 48px; }

  .ps-media--cutout {
    height: 340px;
  }
}

/* ------------------------------------------------------------
   5) Scroll reveal — dedicated, dependency-free (no AOS).
   Directional entrances that complement the alternating layout:
   the left column slides in from the left, the right column from
   the right (plus a gentle fade), triggered per column by an
   IntersectionObserver in the template. The hidden start state is
   gated on html.ps-anim (set by inline JS), so content is always
   visible without JavaScript. Only opacity/transform animate:
   compositor-friendly, no layout shift — the sections' own
   overflow-hidden clips the off-axis start positions.
   ------------------------------------------------------------ */
html.ps-anim .ps-reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}
html.ps-anim .ps-reveal--from-left {
  transform: translateX(-56px);
}
html.ps-anim .ps-reveal--from-right {
  transform: translateX(56px);
}
html.ps-anim .ps-reveal--late {
  transition-delay: 0.15s;
}
html.ps-anim .ps-reveal.is-revealed {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  html.ps-anim .ps-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Newland fix: the even (image-right) media container had no bottom
   padding, so the carousel dots sat flush against the rounded,
   overflow-hidden container edge and were clipped. Match the odd
   sections' pb-4 so pagination clears the edge consistently. */
section.details-2 .featImage .image-container:not(.ps-media--cutout) {
  padding-bottom: 24px;
}
