/* ==========================================================================
   MyCabin Customer Stories — Page Pack CSS
   Scoped entirely under .pp-customer-stories (Page Pack Spec §5). Every
   selector in this file is nested under that root class — no bare element
   or utility selectors. Trimmed from the Claude Design export's shared
   styles.css: only rules this one page's sections actually use. Methodology
   (root-class scoping, Flow-margin protection, the generic rail engine,
   whole-card click-delegate markup) follows the homepage Page Pack
   (page-packs/homepage/, v1.1.2); every visual value below comes from this
   page's own source (source-design/mycabin-customer-stories.zip), never
   copied from the homepage's or Milla 47's own design.

   01  Tokens (scoped custom properties, not :root)
   02  Base resets (scoped)
   03  Section / layout helpers
   04  Buttons
   05  Hero
   06  Featured story
   07  Pull quote
   08  All-stories grid + card
   09  Testimonial rail + generic rail-engine controls
   10  Gallery grid + lightbox
   11  Final CTA
   12  Scroll reveal (io-fade)
   13  Desktop layer (min-width: 900px — this page's own breakpoint)
   14  Reduced motion
   15  v1.0.1 source-parity corrections (appended, see its own comment)
   ========================================================================== */


/* ==========================================================================
   01  TOKENS — scoped to .pp-customer-stories, never :root, so nothing leaks
   to the rest of the WordPress site (Page Pack Spec §5, layer 2).
   ========================================================================== */

.pp-customer-stories {
  --pp-ink:          #27272C;
  --pp-bone:         #FFFFFF;
  --pp-paper:        #FFFFFF;
  --pp-surface:      #FBF6F3;
  --pp-accent:       #917EBC;
  --pp-accent-soft:  #CDCBFF;
  --pp-tint:         #E6E6FF;

  --pp-stone:            color-mix(in oklab, var(--pp-ink) 11%, var(--pp-bone));
  --pp-ink-line:         color-mix(in oklab, var(--pp-ink) 13%, var(--pp-bone));
  --pp-ink-hair:         color-mix(in oklab, var(--pp-ink) 7%,  var(--pp-bone));
  --pp-tint-line-strong: color-mix(in oklab, var(--pp-accent) 34%, var(--pp-tint));

  --pp-ink-72:  color-mix(in oklab, var(--pp-ink) 72%, transparent);
  /* 65%, not 56% — matches the source's own WCAG-AA fix (its :root comment,
     section 01): 56% measured under AA for normal text against the new
     beige surface tone; 65% restores the original ~4.25:1 contrast. */
  --pp-ink-56:  color-mix(in oklab, var(--pp-ink) 65%, transparent);
  --pp-ink-28:  color-mix(in oklab, var(--pp-ink) 28%, transparent);
  --pp-bone-80: color-mix(in oklab, var(--pp-bone) 80%, transparent);
  --pp-bone-60: color-mix(in oklab, var(--pp-bone) 60%, transparent);

  --pp-maxw:   1280px;
  --pp-gutter: clamp(18px, 4vw, 40px);

  /* Header clearance. The site's fixed global header is supplied by the
     WordPress theme, not this Page Pack, so its real height can't be read
     here — this reproduces the source design's own --hdr-h token
     (clamp(58px, 7vw, 74px)) as a best-effort estimate, same convention
     already used by the Privacy Policy/Warranty Page Packs' own
     --pp-hdr-h. If the live theme's header renders a meaningfully
     different height, the hero's top padding will need a one-line
     adjustment — flagged in the handoff doc for staging verification. */
  --pp-hdr-h: clamp(58px, 7vw, 74px);

  /* Centers content at --pp-maxw via padding rather than a nested "wrap"
     div — same formula as the homepage Page Pack's --pp-section-pad. */
  --pp-section-pad: max(var(--pp-gutter), calc((100% - var(--pp-maxw)) / 2 + var(--pp-gutter)));

  --pp-r-pill: 999px;
  --pp-r-card: 11px;
  --pp-r-lg:   10px;
  --pp-r-md:   9px;

  --pp-ease:   cubic-bezier(.22, 1, .36, 1);
  --pp-t-med:  .25s;
  --pp-t-slow: .35s;

  background: var(--pp-bone);
  color: var(--pp-ink);
  overflow-x: clip;
}


/* ==========================================================================
   02  BASE RESETS (scoped)
   ========================================================================== */

.pp-customer-stories h1, .pp-customer-stories h2, .pp-customer-stories h3,
.pp-customer-stories p, .pp-customer-stories blockquote, .pp-customer-stories figure {
  margin: 0;
}
.pp-customer-stories a { color: var(--pp-ink); text-decoration: none; }
.pp-customer-stories a:hover { color: var(--pp-accent); }
.pp-customer-stories img { max-width: 100%; display: block; }
.pp-customer-stories button { font: inherit; color: inherit; }


/* ==========================================================================
   03  SECTION / LAYOUT HELPERS
   ========================================================================== */

.pp-customer-stories .pp-section {
  position: relative;
  padding-inline: var(--pp-section-pad);
}

.pp-customer-stories .pp-eyebrow {
  display: block;
  margin-bottom: 14px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--pp-ink-56);
}

.pp-customer-stories .pp-lead { margin-top: 10px; }

.pp-customer-stories .pp-mw-18 { max-width: 18ch; }
.pp-customer-stories .pp-mw-40 { max-width: 40ch; }

/* Flow-layout margin protection (Page Pack Spec §6 / Reference
   Implementation §5). Every group listed here is a plain core/group with
   no explicit `layout` attribute in content.html, so it defaults to
   WordPress's "Flow" layout — which injects `margin-block-start` on every
   direct child but the first, sized from the active theme's own
   `spacing.blockGap` (or a built-in fallback), regardless of whether this
   Page Pack ever asked for it. Every one of these groups' own vertical
   rhythm is already fully specified above/below via this file's own
   padding-top (a native block attribute) or margin-top (a scoped class)
   declarations — an unrequested extra margin on top of that would silently
   over-space these sections on a real WordPress install in a way no local
   preview can reproduce (padding and the Flow-injected margin are
   different box-model layers and do not cancel each other out). Scoped
   narrowly to each component's own direct children only — never a global
   margin reset — so nothing inside a card/panel's own internal spacing is
   touched. */
.pp-customer-stories .pp-section > *,
.pp-customer-stories .pp-feature > *,
.pp-customer-stories .pp-feature__panel > *,
.pp-customer-stories .pp-card > *,
.pp-customer-stories .pp-card__body > *,
.pp-customer-stories .pp-review > *,
.pp-customer-stories .pp-cta > *,
.pp-customer-stories .pp-cta__copy > *,
.pp-customer-stories .pp-review__who > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}

/* Shared "model/category pill" used by the featured story and every
   All-stories card meta row. */
.pp-customer-stories .pp-tag {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 4px 11px;
  border-radius: var(--pp-r-pill);
  background: var(--pp-tint);
  border: 1px solid var(--pp-tint-line-strong);
  color: var(--pp-accent);
  font-size: 11.5px;
  font-weight: 500;
  white-space: nowrap;
}

/* Shared avatar-plus-name byline (featured story panel; reused generically
   as the name-only foot row on each All-stories card). */
.pp-customer-stories .pp-byline { display: flex; align-items: center; gap: 10px; }
.pp-customer-stories .pp-byline__avatar {
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: var(--pp-surface);
}
.pp-customer-stories .pp-byline__avatar img { width: 100%; height: 100%; object-fit: cover; }
.pp-customer-stories .pp-byline__name { font-size: 13px; font-weight: 500; color: var(--pp-ink); }


/* ==========================================================================
   04  BUTTONS
   ========================================================================== */

.pp-customer-stories .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding-inline: 21px;
  border-radius: var(--pp-r-pill);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
/* Base fill/text colors for accent/light are native block attributes
   (inline `style`, edited via the Gutenberg color picker); their :hover
   colors stay here, since Gutenberg's color attributes have no native
   hover state. !important is required because an inline style attribute
   otherwise always beats a class-based :hover rule regardless of match —
   same reasoning as the homepage Page Pack's own button-hover overrides. */
.pp-customer-stories .pp-btn-accent .wp-block-button__link:hover { background: var(--pp-accent) !important; color: var(--pp-ink) !important; }
.pp-customer-stories .pp-btn-light .wp-block-button__link:hover { background: var(--pp-accent-soft) !important; color: var(--pp-ink) !important; }

.pp-customer-stories .pp-btn-outline .wp-block-button__link {
  background: transparent;
  color: var(--pp-ink);
  border: 1px solid var(--pp-ink);
}
.pp-customer-stories .pp-btn-outline .wp-block-button__link:hover { background: var(--pp-surface); color: var(--pp-ink); }

.pp-customer-stories .pp-btn-ghost .wp-block-button__link {
  background: color-mix(in oklab, var(--pp-ink) 30%, transparent);
  color: var(--pp-paper);
  border: 1px solid var(--pp-bone-60);
}
.pp-customer-stories .pp-btn-ghost .wp-block-button__link:hover {
  background: color-mix(in oklab, var(--pp-bone) 14%, transparent);
  border-color: var(--pp-paper);
  color: var(--pp-paper);
}

.pp-customer-stories .pp-hero__btns .wp-block-button,
.pp-customer-stories .pp-more .wp-block-button { flex: 0 0 auto; }

/* Post-translation fidelity (1.1.1) -- button font weight. The translated final-CTA
   label "Ieplānot apmeklējumu" carries a <strong> (a Bold toggle left by the translation
   pass; the same editor artifact found on the Homepage). The link's own weight is already
   source's 500 (`.btn { font-weight: 500 }`, same as "Konfigurē māju" beside it), but UA
   `strong { font-weight: bolder }` made the inner text 700, rendered as the 600 face --
   the heavy look. The label keeps the link's weight; text and markup are untouched. Scoped
   to this page's button links only. */
.pp-customer-stories .wp-block-button__link :is(strong, b) { font-weight: inherit; }

/* Small round icon buttons used by the testimonial rail's prev/next controls. */
.pp-customer-stories .pp-iconbtn {
  width: 37px;
  height: 37px;
  border-radius: var(--pp-r-pill);
  border: 1px solid var(--pp-ink-line);
  background: transparent;
  color: var(--pp-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
.pp-customer-stories .pp-iconbtn:hover { background: var(--pp-ink); color: var(--pp-bone); }
.pp-customer-stories .pp-iconbtn:disabled { opacity: .35; cursor: default; }
.pp-customer-stories .pp-iconbtn:disabled:hover { background: transparent; color: var(--pp-ink); }


/* ==========================================================================
   05  HERO
   Plain text hero, no photo — a flat surface-colour band. Top padding
   clears the WordPress theme's fixed global header (see --pp-hdr-h above);
   bottom padding is this hero's own, unrelated to the header.
   ========================================================================== */

.pp-customer-stories .pp-hero {
  padding: calc(var(--pp-hdr-h) + clamp(28px, 6vw, 48px)) 0 clamp(32px, 5vw, 48px);
}
.pp-customer-stories .pp-hero__inner { max-width: var(--pp-maxw); margin: 0 auto; padding-inline: var(--pp-gutter); }
.pp-customer-stories .pp-hero__text { max-width: 640px; }
.pp-customer-stories .pp-hero__title {
  font-size: clamp(34px, 8.6vw, 46px);
  line-height: 1.06;
  letter-spacing: -.026em;
  font-weight: 500;
}
.pp-customer-stories .pp-hero__lead { margin-top: 14px; line-height: 1.55; color: var(--pp-ink-72); }
.pp-customer-stories .pp-hero__btns { margin-top: 22px; max-width: 420px; gap: 10px; }
.pp-customer-stories .pp-hero__btns .wp-block-button { flex: 1 1 200px; }


/* ==========================================================================
   06  FEATURED STORY
   Photo and a solid dark panel, side by side at desktop (§13) and stacked
   on mobile — not text laid over the photo (see the source's own README
   for why an overlay version was tried and dropped).
   ========================================================================== */

.pp-customer-stories .pp-feature {
  display: flex;
  flex-direction: column;
  border-radius: var(--pp-r-card);
  overflow: hidden;
}
.pp-customer-stories .pp-feature:focus-within { outline: 2px solid var(--pp-accent); outline-offset: -3px; }
.pp-customer-stories .pp-feature__media { position: relative; aspect-ratio: 5 / 4; margin: 0; }
.pp-customer-stories .pp-feature__media img { width: 100%; height: 100%; object-fit: cover; }
.pp-customer-stories .pp-feature__panel { display: flex; flex-direction: column; gap: 14px; padding: clamp(24px, 4vw, 40px); }
.pp-customer-stories .pp-feature__meta { display: flex; align-items: center; gap: 10px; }
.pp-customer-stories .pp-feature__loc { font-size: 12.5px; color: var(--pp-bone-60); }
.pp-customer-stories .pp-feature__title {
  font-size: clamp(24px, 3.2vw, 34px);
  line-height: 1.15;
  letter-spacing: -.02em;
  font-weight: 500;
  color: var(--pp-paper);
}
.pp-customer-stories .pp-feature__excerpt { font-size: 14.5px; line-height: 1.6; font-weight: 300; color: var(--pp-bone-80); max-width: 46ch; }
/* Reuses .pp-byline as-is (avatar + name) — just needs its name text light
   instead of the default --pp-ink, since this panel is dark ink. */
.pp-customer-stories .pp-feature__byline .pp-byline__name { color: var(--pp-paper); }
.pp-customer-stories .pp-feature__cta { margin-top: 6px; align-self: flex-start; }
.pp-customer-stories .pp-feature.pp-is-clickable { cursor: pointer; }


/* ==========================================================================
   07  PULL QUOTE
   Beige, not white, so the page doesn't run three white sections in a row
   (hero → featured story → pull quote would otherwise all read as one flat
   white block).
   ========================================================================== */

.pp-customer-stories .pp-pull { padding: clamp(48px, 7vw, 84px) 0; }
.pp-customer-stories .pp-pull__inner { max-width: 62ch; margin: 0 auto; padding-inline: var(--pp-gutter); text-align: center; }
/* The giant opening quotation mark is a purely decorative typographic
   flourish with no editorial content of its own (Page Pack Spec §6) — a
   CSS-generated glyph, not markup, so nothing here can ever be mistaken
   for editable text. */
.pp-customer-stories .pp-pull__inner::before {
  content: "\201C";
  display: block;
  font-size: clamp(64px, 11vw, 128px);
  line-height: .6;
  font-weight: 600;
  color: var(--pp-accent-soft);
}
.pp-customer-stories .pp-pull__quote {
  margin-top: 4px;
  border: 0;
  padding: 0;
}
.pp-customer-stories .pp-pull__quote p {
  font-size: clamp(22px, 3vw, 32px);
  line-height: 1.35;
  letter-spacing: -.012em;
  font-weight: 400;
  color: var(--pp-ink);
}
.pp-customer-stories .pp-pull__attr {
  margin-top: 20px;
  font-size: 14px;
  font-weight: 500;
  color: var(--pp-accent);
}


/* ==========================================================================
   08  ALL-STORIES GRID + CARD
   ========================================================================== */

.pp-customer-stories .pp-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(16px, 2.2vw, 22px);
}
/* WordPress's default Flow layout would otherwise add margin-block-start to
   every direct child but the first (Page Pack Spec §6 / Reference
   Implementation §5) — .pp-grid already owns its own child spacing via
   `gap`, so that injected margin is neutralized narrowly on exactly its
   own direct children. */
.pp-customer-stories .pp-grid > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}

.pp-customer-stories .pp-card {
  display: flex;
  flex-direction: column;
  background: var(--pp-bone);
  border: 1px solid var(--pp-stone);
  border-radius: var(--pp-r-card);
  overflow: hidden;
}
.pp-customer-stories .pp-card:focus-within { outline: 2px solid var(--pp-accent); outline-offset: -3px; }
.pp-customer-stories .pp-card.pp-is-clickable { cursor: pointer; }
.pp-customer-stories .pp-card__media { position: relative; aspect-ratio: 4 / 3; margin: 0; }
.pp-customer-stories .pp-card__media img { width: 100%; height: 100%; object-fit: cover; }
.pp-customer-stories .pp-card__body { padding: clamp(18px, 2.2vw, 22px); display: flex; flex-direction: column; gap: 10px; flex: 1; }
.pp-customer-stories .pp-card__meta { display: flex; align-items: center; gap: 8px; }
.pp-customer-stories .pp-card__loc { font-size: 12.5px; color: var(--pp-ink-56); }
.pp-customer-stories .pp-card__title { font-size: 17px; line-height: 1.25; letter-spacing: -.015em; font-weight: 500; }
.pp-customer-stories .pp-card__excerpt { font-size: 13px; line-height: 1.55; font-weight: 300; color: var(--pp-ink-72); flex: 1; }
.pp-customer-stories .pp-card__foot { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; }
.pp-customer-stories .pp-card__foot .pp-byline__name { font-size: 12.5px; }

/* "Read story →" small text link — arrow wipes closer on hover, matching
   the source's .link-arrow underline-adjacent treatment. */
.pp-customer-stories .pp-link-arrow-sm a { font-size: 12.5px; font-weight: 500; color: var(--pp-ink); transition: color var(--pp-t-med); }
.pp-customer-stories .pp-link-arrow-sm a:hover { color: var(--pp-accent); }

.pp-customer-stories .pp-more { margin-top: clamp(28px, 4vw, 40px); }


/* ==========================================================================
   09  TESTIMONIAL RAIL + GENERIC RAIL-ENGINE CONTROLS
   Same generic rail-engine architecture as the homepage Page Pack's
   pp-rail--models/pp-rail--stories (Reference Implementation §3): a plain
   core/group carries the repeated cards, a core/html block carries the
   non-content prev/next/progress/count controls, linked purely by the
   pp-rail--<name> / data-pp-rail-controls-for="<name>" name pair — no ids,
   no per-page importer knowledge required.
   ========================================================================== */

.pp-customer-stories .pp-rail {
  display: flex;
  gap: clamp(12px, 2vw, 20px);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  margin-top: clamp(24px, 3.5vw, 32px);
  margin-inline: calc(-1 * var(--pp-section-pad));
  padding: 0 var(--pp-section-pad) 6px;
  scroll-padding-left: var(--pp-section-pad);
}
.pp-customer-stories .pp-rail::-webkit-scrollbar { display: none; }
.pp-customer-stories .pp-rail > * { scroll-snap-align: start; }
/* Flow-margin protection (Reference Implementation §5) — the rail already
   owns its own child spacing via `gap`. */
.pp-customer-stories .pp-rail > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}

.pp-customer-stories .pp-review {
  display: flex;
  flex-direction: column;
  flex: 0 0 min(72vw, 270px);
  border-radius: var(--pp-r-md);
  box-shadow: 0 6px 20px color-mix(in oklab, var(--pp-ink) 7%, transparent);
  justify-content: space-between;
  gap: 12px;
}
.pp-customer-stories .pp-review__quote { border: 0; padding: 0; }
.pp-customer-stories .pp-review__quote p { font-size: 14px; line-height: 1.5; color: var(--pp-ink-72); font-weight: 300; }
.pp-customer-stories .pp-review__who { display: flex; flex-direction: column; }
.pp-customer-stories .pp-review__name { font-size: 14px; font-weight: 500; }
.pp-customer-stories .pp-review__model { font-size: 12.5px; color: var(--pp-ink-56); }

.pp-customer-stories .pp-rail-controls {
  max-width: var(--pp-maxw);
  margin: clamp(20px, 3vw, 26px) auto 0;
  padding-inline: var(--pp-gutter);
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.pp-customer-stories .pp-rail-controls__progress {
  flex: 1 1 auto;
  max-width: 220px;
  height: 3px;
  border-radius: var(--pp-r-pill);
  background: var(--pp-ink-line);
  overflow: hidden;
}
.pp-customer-stories .pp-rail-controls__thumb {
  height: 100%;
  border-radius: var(--pp-r-pill);
  background: var(--pp-ink);
  width: 25%;
  transition: width .3s ease, margin-left var(--pp-t-slow) var(--pp-ease);
}
.pp-customer-stories .pp-rail-controls__count { font-size: 13px; color: var(--pp-ink-56); font-variant-numeric: tabular-nums; }
.pp-customer-stories .pp-rail-controls__arrows { margin-left: auto; display: flex; gap: 8px; }


/* ==========================================================================
   10  GALLERY GRID + LIGHTBOX
   2-up on mobile, one item in every group of six spanning both rows for a
   loose masonry feel without actual masonry layout (see §13 for the 4-up
   desktop version).
   ========================================================================== */

.pp-customer-stories .pp-gallery-grid {
  margin-top: clamp(20px, 3vw, 28px);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: dense;
  gap: clamp(10px, 1.6vw, 14px);
}
/* Flow-margin protection (Reference Implementation §5) — the grid already
   owns its own child spacing via `gap`. */
.pp-customer-stories .pp-gallery-grid > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}
.pp-customer-stories .pp-gallery-item {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--pp-r-lg);
  overflow: hidden;
  cursor: zoom-in;
}
.pp-customer-stories .pp-gallery-item:focus-visible { outline: 2px solid var(--pp-accent); outline-offset: -3px; }
.pp-customer-stories .pp-gallery-item--tall { aspect-ratio: 1 / 2.05; grid-row: span 2; }
.pp-customer-stories .pp-gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--pp-ease); }
.pp-customer-stories .pp-gallery-item:hover img,
.pp-customer-stories .pp-gallery-item:focus-visible img { transform: scale(1.06); }
.pp-customer-stories .pp-gallery-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--pp-ink) 10%, transparent);
  opacity: 0;
  transition: opacity .3s ease;
  pointer-events: none;
}
.pp-customer-stories .pp-gallery-item:hover::after,
.pp-customer-stories .pp-gallery-item:focus-visible::after { opacity: 1; }

/* Full-size photo viewer — built lazily by frontend.js on first open, and
   appended as a child of the .pp-customer-stories root (not <body>) so
   every selector here stays properly scoped (Page Pack Spec §5) while
   still sitting above the entire page: it's `position: fixed`, which
   positions against the viewport regardless of DOM depth as long as no
   ancestor establishes a new containing block (a transform/filter/
   perspective) — this root sets none of those, only `overflow-x: clip`
   (§01), which does not trap fixed-position descendants. It still only
   exists at all once frontend.js decides to build it. */
.pp-customer-stories .pp-lightbox-cs {
  position: fixed;
  inset: 0;
  z-index: 999999;
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, #27272C 92%, transparent);
  padding: clamp(16px, 4vw, 48px);
}
.pp-customer-stories .pp-lightbox-cs.pp-is-open { display: flex; }
.pp-customer-stories .pp-lightbox-cs__frame { max-width: min(92vw, 1100px); max-height: 86vh; }
.pp-customer-stories .pp-lightbox-cs__img { display: block; width: 100%; height: 100%; max-height: 86vh; object-fit: contain; border-radius: var(--pp-r-md); }
.pp-customer-stories .pp-lightbox-cs__close { position: absolute; top: clamp(14px, 3vw, 28px); right: clamp(14px, 3vw, 28px); }
.pp-customer-stories .pp-lightbox-cs__prev  { position: absolute; left: clamp(8px, 2.4vw, 24px); top: 50%; transform: translateY(-50%); }
.pp-customer-stories .pp-lightbox-cs__next  { position: absolute; right: clamp(8px, 2.4vw, 24px); top: 50%; transform: translateY(-50%); }
.pp-customer-stories .pp-lightbox-cs__count {
  position: absolute;
  bottom: clamp(14px, 3vw, 24px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 13px;
  color: color-mix(in oklab, #FFFFFF 80%, transparent);
  font-variant-numeric: tabular-nums;
}
/* Dark-background icon-button variant, for controls sitting on the scrim. */
.pp-customer-stories .pp-iconbtn-light {
  position: relative;
  width: 37px;
  height: 37px;
  border-radius: var(--pp-r-pill);
  border: 1px solid color-mix(in oklab, #FFFFFF 22%, transparent);
  color: #FFFFFF;
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--pp-t-med), color var(--pp-t-med), border-color var(--pp-t-med);
}
.pp-customer-stories .pp-iconbtn-light:hover { background: #FFFFFF; color: #27272C; border-color: #FFFFFF; }


/* ==========================================================================
   11  FINAL CTA
   ========================================================================== */

.pp-customer-stories .pp-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  padding-inline: var(--pp-section-pad);
}
.pp-customer-stories .pp-cta__copy { display: flex; flex-direction: column; gap: 12px; flex: 1 1 300px; min-width: 0; }
.pp-customer-stories .pp-cta__title { font-size: clamp(25px, 7vw, 42px); line-height: 1.16; letter-spacing: -.03em; font-weight: 500; color: var(--pp-paper); }
.pp-customer-stories .pp-cta__text { font-size: clamp(13px, 2.8vw, 15px); line-height: 1.65; font-weight: 300; color: var(--pp-bone-80); }
.pp-customer-stories .pp-cta__btns { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.pp-customer-stories .pp-cta__btns .wp-block-button { width: 100%; }
.pp-customer-stories .pp-cta__btns .wp-block-button__link { width: 100%; }


/* ==========================================================================
   12  SCROLL REVEAL (io-fade)
   Every .pp-io-fade block fades up the first time it crosses the viewport,
   via one shared IntersectionObserver in frontend.js — ported from the
   source's own script.js mechanism (also already used, same class naming
   convention, by the Homepage/Blog/Privacy Policy Page Packs).
   ========================================================================== */

.pp-customer-stories .pp-io-fade {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .8s var(--pp-ease), transform .8s var(--pp-ease);
}
.pp-customer-stories .pp-io-fade.pp-in-view { opacity: 1; transform: none; }


/* ==========================================================================
   13  DESKTOP LAYER (min-width: 900px)
   This page's own breakpoint, confirmed from the source's own styles.css
   §15 "DESKTOP LAYER" — independent of any other page's breakpoint (Milla
   47's own 900px is a coincidence of this shared design system, not an
   assumption carried over; re-derived here from this page's own source).
   ========================================================================== */

@media (min-width: 900px) {
  .pp-customer-stories .pp-feature { flex-direction: row; min-height: clamp(400px, 38vw, 480px); }
  .pp-customer-stories .pp-feature__media { flex: 1.3; aspect-ratio: auto; }
  .pp-customer-stories .pp-feature__panel { flex: 1; justify-content: center; }
  .pp-customer-stories .pp-feature__title { font-size: clamp(26px, 2.4vw, 32px); }

  .pp-customer-stories .pp-pull__inner { max-width: 78ch; }

  .pp-customer-stories .pp-grid { grid-template-columns: repeat(3, 1fr); }

  .pp-customer-stories .pp-gallery-grid { grid-template-columns: repeat(4, 1fr); }

  /* Grid, not flex — 1fr 1fr sizes both columns to match whichever
     button's label is longer, so the pair stays equal-width instead of
     one being wider than the other (same reasoning as the source's own
     comment for this exact rule). */
  .pp-customer-stories .pp-cta__btns { display: grid; grid-template-columns: 1fr 1fr; width: auto; }
  .pp-customer-stories .pp-cta__btns .wp-block-button,
  .pp-customer-stories .pp-cta__btns .wp-block-button__link { width: auto; }

  /* Post-translation fidelity (1.1.1) -- hero CTA row. Source: `.btn-row` capped at 420px
     (inline `max-width:420px`) with every button `flex: 1 1 200px`, i.e. two equal buttons
     that stay on one line because the English labels fit (2 x 200 + 10 <= 420). The longer
     Latvian label ("Ieplānot apmeklējumu", ~232px with its 21px side padding) cannot shrink
     below its min-content, so 232 + 200 + 10 exceeds the 420px cap, `flex-wrap: wrap` drops
     the second button to its own line and the pair stacks. From this page's own 900px desktop
     layer the row is content-driven instead: two EQUAL columns sized by the longer label
     (like source's equal buttons), never narrower than source's 420px, never wider than its
     column (the hero text block is 640px). Height, padding, gap, radius, font and labels are
     unchanged; below 900px the source's wrapping row is untouched, so a pair that genuinely
     cannot fit still stacks. The editor's own block-list layout is excluded. */
  .pp-customer-stories .pp-hero__btns.wp-block-buttons:not(.block-editor-block-list__layout) {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    width: max-content;
    min-width: min(420px, 100%);
    max-width: 100%;
  }
  .pp-customer-stories .pp-hero__btns.wp-block-buttons:not(.block-editor-block-list__layout) .wp-block-button__link { width: 100%; }
}


/* ==========================================================================
   14  REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .pp-customer-stories, .pp-customer-stories * {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
  .pp-customer-stories .pp-rail { scroll-behavior: auto; }
}


/* ==========================================================================
   15  v1.0.1 SOURCE-PARITY CORRECTIONS
   Every value below is taken from the source's own styles.css (source-design/
   customer-stories-original.zip) — see docs/MYCABIN-CUSTOMER-STORIES-PAGE-
   PACK-HANDOFF.md §v1.0.1 for the root cause of each.
   ========================================================================== */

/* 15.1  White lanes between sections. The root .pp-customer-stories group is
   a plain Flow-layout core/group, so WordPress injected margin-block-start
   (the theme's blockGap) on every one of its direct children — each section
   band — and the root's own white background showed through those strips
   (lavender -> pale, pale -> dark). The section-internal resets in §03
   never covered the root's own children. Neutralised on exactly those
   direct children; no negative margins. */
.pp-customer-stories > * {
  margin-block-start: 0 !important;
  margin-block-end: 0 !important;
}

/* 15.2  Paper grain — the source's body::after overlay, missing from 1.0.0.
   Scoped to this root, same established pattern as the Warranty/Homepage/
   Milla packs. */
.pp-customer-stories::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: .05;
  background-image: radial-gradient(color-mix(in oklab, var(--pp-ink) 55%, transparent) .5px, transparent .5px);
  background-size: 3px 3px;
}

/* 15.3  Margins the source declares that the §03 blanket !important reset
   (`.pp-section > *`) was silently cancelling (specificity 0,2,0 + !important
   beat every plain class margin). Restored here at 0,3,0 + !important, each
   with the exact source value. */
.pp-customer-stories .pp-section > .pp-more         { margin-block-start: clamp(28px, 4vw, 40px) !important; } /* .blog-more */
.pp-customer-stories .pp-section > .pp-rail         { margin-block-start: clamp(24px, 3.5vw, 32px) !important; } /* #cs-testi-rail inline */
.pp-customer-stories .pp-section > .pp-rail-controls{ margin-block-start: clamp(20px, 3vw, 26px) !important; } /* .rail__controls */
.pp-customer-stories .pp-section > .pp-lead         { margin-block-start: 10px !important; }                   /* .lead inline */
.pp-customer-stories .pp-section > .pp-gallery-grid { margin-block-start: clamp(20px, 3vw, 28px) !important; } /* .cs-gallery-grid */

/* 15.4  Featured story + All stories sections — the source's .blog-list-section geometry (both use it):
   padding clamp(28px,5vw,44px) 0 var(--sec-y-p), eyebrow margin-bottom 14px,
   grid margin-top clamp(32px,5vw,48px) (collapsing with the eyebrow's 14px,
   as in the source). Replaces the 1.0.0 grid padding-top preset. */
.pp-customer-stories .pp-section--list {
  padding-block: clamp(28px, 5vw, 44px) clamp(48px, 7vw, 104px);
}
.pp-customer-stories .pp-section--list > .pp-eyebrow { margin-block-end: 14px !important; }
.pp-customer-stories .pp-section--list > .pp-grid    { margin-block-start: clamp(32px, 5vw, 48px) !important; }

/* 15.5  Story-card photo — the source's .slot fills its 4/3 box absolutely.
   The wp-block-image <figure> has no height of its own, so 1.0.0's
   `img { height:100% }` never resolved and the portrait photos rendered at
   their natural (very tall) aspect. */
.pp-customer-stories .pp-card__media > .wp-block-image { position: absolute; inset: 0; margin: 0; }
.pp-customer-stories .pp-card__media > .wp-block-image img { width: 100%; height: 100%; object-fit: cover; }

/* 15.6  Card hover — in the source the whole card is an <a>, and
   a:hover { color: accent } is inherited by the title and the "Read story"
   link (the byline name and excerpt carry their own explicit colours, so
   they stay ink). Normal state is ink. */
.pp-customer-stories .pp-card__title { color: var(--pp-ink); }
.pp-customer-stories .pp-card:hover .pp-card__title,
.pp-customer-stories .pp-card:hover .pp-link-arrow-sm a { color: var(--pp-accent); }

/* 15.7  Testimonial rail — the source's rail sits OUTSIDE .wrap and pads
   itself with --rail-pad. In 1.0.0 the rail sat inside .pp-section's own
   padding and re-derived the pad against that already-narrowed box, which
   clipped it to <=1280px. Here the section carries no inline padding; the
   heading and rail apply --pp-section-pad against the full-width parent. */
.pp-customer-stories .pp-section--rail { padding-inline: 0; }
.pp-customer-stories .pp-section--rail > .pp-h2-xs { margin-inline: var(--pp-section-pad); }
.pp-customer-stories .pp-section--rail > .pp-rail {
  margin-inline: 0;
  padding-inline: var(--pp-section-pad);
  scroll-padding-left: var(--pp-section-pad);
}
.pp-customer-stories .pp-iconbtn { flex: 0 0 auto; position: relative; }

/* 15.8  Section headings / lead — .h2.h2--xs and .lead from the source
   (.pp-h2-xs had no rule at all in 1.0.0, so the headings fell back to the
   theme's default h2). */
.pp-customer-stories .pp-h2-xs {
  font-size: clamp(26px, 4.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -.022em;
  font-weight: 500;
}
.pp-customer-stories .pp-lead {
  font-size: clamp(16px, 2vw, 20px);
  line-height: 1.55;
  color: var(--pp-ink-72);
  font-weight: 300;
}

/* 15.9  APPROVED SOURCE DEVIATION — 10th gallery photo fills the masonry
   cell the source leaves empty (row 3 / col 3 at 900px+; the last cell at
   mobile). Do not remove in later parity passes. Landscape photo, so bias
   the square crop toward the house + terrace. */
.pp-customer-stories .pp-gallery-item--extra img { object-position: 62% center; }

/* 15.10  v1.0.2 — source-global behaviours the pack was missing, scoped to the root. */

/* The source sets *,*::before,*::after { box-sizing: border-box }. Without it
   the theme leaves plain divs content-box, so .pp-rail-controls (max-width
   1280px + gutter padding) rendered 2*gutter wider than the source and its
   content started 40px LEFT of the heading/cards. */
.pp-customer-stories,
.pp-customer-stories *,
.pp-customer-stories *::before,
.pp-customer-stories *::after { box-sizing: border-box; }

/* Source body has text-wrap: pretty; the theme's own heading rule balances,
   which re-wrapped card/feature titles differently from the original. */
.pp-customer-stories :is(h1, h2, h3) { text-wrap: pretty; }

/* "Read story →" — the source's .link-arrow (16px / 500, inline-flex, gap 10px),
   not the 12.5px small link 1.0.0 used. Colour/hover unchanged (§15.6). */
.pp-customer-stories .pp-link-arrow-sm a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
}
.pp-customer-stories .pp-card__foot { gap: 10px; }

/* 15.11  v1.0.4 — Featured Story photo fills its media box at EVERY width,
   as the source's absolutely-positioned .slot does. The wp-block-image
   <figure> has no height, so `img{height:100%}` never resolved and the photo
   kept its natural 4:3 height: shorter than the 5/4 box on mobile (white
   strip above the dark panel, fixed in 1.0.3) and, at 900px+, ~5px shorter
   than the stretched 480px row (the source .cs-feature min-height), leaving
   the photo's lower edge short of the card. 1.0.3 had scoped the fill to
   max-width:899.98px only; the same root cause at desktop is now fixed by
   removing that scoping. Desktop geometry itself (flex 1.3, aspect-ratio
   auto, min-height clamp(400px,38vw,480px)) is unchanged. object-fit: cover,
   default object-position (center), as the source. */
.pp-customer-stories .pp-feature__media > .wp-block-image { position: absolute; inset: 0; margin: 0; }
.pp-customer-stories .pp-feature__media > .wp-block-image img { width: 100%; height: 100%; object-fit: cover; }

/* 15.12  v1.1.0 — dynamic story blocks (MyCabin Blog plugin emits the DOM; these are the only additions). */
.pp-customer-stories .pp-stories-empty { font-size: 15px; color: var(--pp-ink-56); }
/* No customer name -> the "Read story →" link keeps its right-hand position. */
.pp-customer-stories .pp-card__foot > .pp-link-arrow-sm:only-child { margin-left: auto; }
