/* Homepage-specific styles */

/* ---- Hero section ---- */
/* Unique to the homepage — not a reusable/global hero component. */

.hero {
  position: relative;
  width: 100%;
  height:800px;
  display: flex;
  justify-content: center;
  padding-top: 208px;
  box-sizing: border-box;
  overflow: hidden; /* clip video to the hero's exact area, incl. auto-height mobile/tablet */
}

/* Background video — replaces the old hero-background.jpg background-image.
   Sits behind .hero__content, filling the hero exactly (any height, incl.
   the auto-height mobile/tablet variants) while cropping via object-fit
   rather than affecting layout. hero-background.jpg is kept as the
   poster/fallback. */
.hero__video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 110%;
  object-fit: cover;
}

/* Gradient overlay over the video — sits between .hero__video (z-index:0)
   and .hero__content (z-index:2). */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(0, 186, 193, 0.00) 75.39%, rgba(7, 46, 55, 0.80) 100%);
}

.hero__content {
  position: relative; /* stacks above .hero__video and .hero::before overlay */
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5xl);
  width: 100%;
  max-width: 1280px;
}

.hero__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
}

.hero__heading {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 600;
  /* Fluid between the mobile (390px) and desktop (1280px) sizes rather
     than a stepped jump at some in-between breakpoint — both endpoints are
     exact: clamp() saturates to precisely 40px/46px at ≤390px (matching
     the mobile implementation) and precisely 80px/80px at ≥1280px
     (matching the untouched desktop design), with tablet widths
     interpolating smoothly between them. */
  font-size: clamp(40px, 22.47px + 4.494vw, 80px);
  line-height: clamp(46px, 31.1px + 3.82vw, 80px);
  text-align: center;
  color: var(--colour-white);
  text-shadow: 0 3px 40px rgba(0, 0, 0, 0.14);
}

.hero__heading-line {
  display: block;
}

.hero__heading-line--muted {
  margin-top: 12px;
  color: var(--colour-white-70);
}

.hero__trust-list {
  display: flex;
  gap: var(--space-5xl);
  list-style: none;
  margin: 0;
  padding: 0;
}

.hero__trust-item {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  font-family: var(--font-primary);
  font-weight: 600;
  font-size: 24px;
  line-height: 28.8px;
  color: var(--colour-white);
  white-space: nowrap;
}

.hero__trust-item img {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.hero__actions {
  display: flex;
  gap: var(--space-l);
}

/* ---- Product transition ----
   The wave + Product Selector overlap wrapper now lives in
   css/section-transition.css as the reusable .section-transition
   component (.section-transition / .section-transition__wave /
   .section-transition__overlay) — see index.html for the current
   markup. .product-selector itself (the panel content) keeps its own
   position:relative;z-index:2 in css/style.css unchanged; that
   declaration is now redundant (the new .section-transition__overlay
   wrapper carries the same stacking context) but is left in place
   rather than removed, so this extraction stays zero-risk. */

/* ---- Self service ---- */
/* Rebuilt from Figma node 18501:7222. Homepage-only for now (no other page
   exists yet to share it with), so it lives here rather than in
   css/style.css alongside the genuinely cross-page components. */

.self-service {
  display: flex;
  justify-content: center;
  width: 100%;
  padding: var(--space-section-l) 0; /* 144px — matches the Figma section's own top/bottom spacing exactly */
  box-sizing: border-box;
  background: var(--colour-white);
}

.self-service__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-6xl); /* 64px between header row and cards row */
  width: 100%;
  max-width: 1280px;
}

/* ---- Header row ---- */

.self-service__header {
  display: flex;
  align-items: flex-end; /* CTA is bottom-aligned against the heading */
  justify-content: space-between;
  gap: var(--space-2xl);
  width: 100%;
}

.self-service__intro {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Typography/padding/radius come from .eyebrow (css/style.css) — Self
   Service sits on a white section background, so its eyebrow needs the
   grey chip instead of .eyebrow's white default. */
.self-service__eyebrow {
  background: var(--colour-grey-101);
}

/* Typography comes from .text-h2 (css/typography.css) at desktop — Figma
   wraps this in a 628px column, but the heading itself measures 653px and
   is explicitly single-line in the source, so at the desktop width it
   naturally fits on one line without needing white-space: nowrap to force
   it (removed: nowrap only ever mattered as a safety net, and would have
   fought the fluid sizing below at narrower widths). font-size/line-height
   are fluid between the mobile (390px) and desktop (1280px) .text-h2
   values rather than a stepped swap at some in-between breakpoint. */
.self-service__heading {
  font-size: clamp(30px, 22.11px + 2.022vw, 48px);
  line-height: clamp(37.5px, 28.69px + 2.258vw, 57.6px);
}

.self-service__heading-dark {
  color: var(--colour-header-grey);
}

.self-service__heading-accent {
  color: var(--colour-brand-teal);
}

.self-service__header-cta {
  flex-shrink: 0;
}

/* ---- Cards row ---- */

.self-service__cards {
  display: grid;
  grid-template-columns: 411px 1fr; /* 411 + 24 gap + 845 = 1280 */
  gap: var(--space-2xl);
  width: 100%;
}

.self-service__stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl); /* 24px between the two left-column cards */
}

.self-service__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-l); /* 16px between title and the description/button beneath it */
  height: 241px;
  padding: var(--space-3xl); /* 32px */
  box-sizing: border-box;
  border: 1px solid var(--colour-light-grey);
  border-radius: 12px;
  overflow: hidden;
}

.self-service__card--renew {
  background: var(--colour-grey-101);
}

/* Figma's own background for this card is three stacked gradients rather
   than a flat grey — reproduced exactly (via get_variable_defs / the raw
   design context) rather than substituted with --colour-grey-101. */
.self-service__card--update {
  background:
    linear-gradient(90deg, #F7F8F9 0%, #F7F8F9 100%),
    linear-gradient(180deg, #FAFAFA 50%, #EEEEEE 100%),
    linear-gradient(90deg, #F7FBFB 0%, #F7FBFB 100%);
}

.self-service__card-title {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 600;
  /* Fluid 28px (mobile) → 36px (desktop) — same technique as .hero__heading
     above. */
  font-size: clamp(28px, 24.49px + 0.899vw, 36px);
  line-height: clamp(36.4px, 32.63px + 0.966vw, 45px);
  color: var(--colour-header-grey);
}

.self-service__card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl); /* 24px between description and button */
}

.self-service__card-desc {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 16px;
  line-height: 25.6px;
  color: var(--colour-body-grey);
}

.self-service__card--renew .self-service__card-desc {
  max-width: 207px; /* Figma text width — wraps to two lines */
}

.self-service__card--update .self-service__card-desc {
  max-width: 247px; /* Figma text width — wraps to two lines */
}

/* Shared white pill CTA — used for the Renew/Update card buttons, and the
   claim card's "Start your claim today". Distinct from .btn/.btn-primary
   (different padding, weight and a teal not used anywhere else in the
   project), so it isn't a modifier of that shared component. */
.self-service__pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  padding: var(--space-s) var(--space-xl); /* 8px 20px */
  border-radius: var(--space-full);
  background: var(--colour-white);
  color: #117A90; /* Figma's own value — distinct from --colour-brand-teal (#14849D) */
  font-family: var(--font-primary);
  font-weight: 700;
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
  white-space: nowrap;
}

.self-service__pill-btn:hover,
.self-service__pill-btn:focus-visible {
  color: var(--colour-cta-orange);
}

.self-service__pill-btn:focus-visible {
  outline: 2px solid var(--colour-brand-teal);
  outline-offset: 2px;
}

/* ---- Claim card ---- */

.self-service__claim {
  position: relative;
  display: flex;
  height: 506px; /* explicit, rather than relying on grid stretch to infer it —
                     .self-service__claim-copy's own height: 100% needs a
                     resolved height to anchor to */
  overflow: hidden;
  border-radius: 12px;
  /* Exact Figma gradient (Card — Make a claim background), not a generic
     teal gradient. */
  background: linear-gradient(-48.289243434970814deg, #013743 0%, #14849D 69.753%);
}

/* The turquoise wave is real Figma vector artwork (node 18552:10149), not a
   CSS shape — see assets/images/self-service-claim-wave.svg. It's 870px
   wide, deliberately wider than the 845px card, and left to be clipped by
   .self-service__claim's own overflow: hidden + border-radius. Sits above
   the gradient background but below the copy/phone (z-index 1 vs. 2). */
.self-service__claim-wave {
  position: absolute;
  left: 0;
  top: 178px;
  width: 870px;
  height: 334px;
  z-index: 1;
  pointer-events: none;
}

.self-service__claim-copy {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  /* space-between, not stacked from the top: the heading/description sit at
     the top of the column and the stats/CTA block sits toward the bottom,
     per Figma. */
  justify-content: space-between;
  width: 411px;
  height: 100%;
  padding: var(--space-3xl); /* 32px */
  box-sizing: border-box;
}

.self-service__claim-intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-l); /* 16px below heading */
  width: 271px;
}

.self-service__claim-heading {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 600;
  /* Fluid 28px (mobile) → 36px (desktop) — same technique/values as
     .self-service__card-title above (both start/end at the same sizes). */
  font-size: clamp(28px, 24.49px + 0.899vw, 36px);
  line-height: clamp(36.4px, 32.63px + 0.966vw, 45px);
  color: var(--colour-white);
  white-space: nowrap;
}

.self-service__claim-desc {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 500; /* Inter Medium */
  font-size: 16px;
  line-height: 25.6px;
  color: rgba(255, 255, 255, 0.9);
}

.self-service__claim-bottom {
  display: flex;
  flex-direction: column;
  gap: 36px; /* CTA sits 36px below the stats block */
  width: 100%;
}

.self-service__claim-stats {
  display: flex;
  /* space-between (not an even split) is what actually produces Figma's
     "second stat begins around x:200 in the 347px row" relationship: the
     first stat is left-aligned, the second is pushed to its own natural
     (label-driven) width from the right edge, landing at ~200px rather
     than an even 50/50 column. */
  justify-content: space-between;
  width: 347px;
  padding-top: var(--space-2xl); /* 24px above, from the divider */
  border-top: 1px solid rgba(255, 255, 255, 0.3);
}

.self-service__stat {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2xs); /* 4px */
}

.self-service__stat-value {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 600;
  font-size: 40px;
  line-height: 1.25;
  color: var(--colour-white);
  white-space: nowrap;
}

.self-service__stat-label {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.6; /* bumped for readability, was 1.5 */
  color: var(--colour-white);
}

.self-service__stat--claims .self-service__stat-label {
  width: 102px;
}

.self-service__stat--rating .self-service__stat-label {
  width: 147px;
}

/* The phone/chat visual is Figma's own exported artwork (node 18501:7307,
   "Visual (placeholder)" — the name is misleading, this is the real image
   in the design), not an HTML/CSS phone mockup. Exported at 2x (868×1012)
   for a sharp image at its displayed 434×506 size. */
.self-service__claim-visual {
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  width: 434px;
  height: 506px;
  object-fit: contain;
  pointer-events: none;
}

/* ---- Promo panel ---- */
/* Built from Figma node 18658:16897. A rounded photographic banner that
   sits INSIDE the page's standard 1280px container (not full-bleed).
   The generic panel shell (.promo, .promo__panel, .promo__bg,
   .promo__overlay, .promo__text, .promo__visual, .promo__heading*) now
   lives in css/promo-panel.css so it can be reused by other pages/panels
   (e.g. the Emergency Assistance region-map panel, css/region-map.css)
   without duplication — this file keeps only what's genuinely specific to
   the homepage's own instance: the benefits list, and the image+tags
   composition inside .promo__visual. */

.promo__benefits {
  display: flex;
  flex-direction: column;
  gap: var(--space-l); /* 16px between rows */
  list-style: none;
  margin: 0;
  padding: 0;
}

.promo__benefit {
  display: flex;
  align-items: center;
  gap: var(--space-m); /* 12px icon-to-text */
  font-family: var(--font-primary);
  font-weight: 600;
  font-size: 24px;
  line-height: 28.8px;
  color: var(--colour-white);
}

.promo__benefit-icon {
  flex-shrink: 0;
}

/* ---- Right: image + floating tags ---- */
/* .promo__visual's own positioning/sizing lives in css/promo-panel.css —
   this is just its homepage-specific content. */

.promo__image {
  position: relative;
  width: 82.21%;
  margin-left: 12.03%;
  aspect-ratio: 410 / 300;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.04);
}

/* Same technique as .promo__bg: Figma crops this photo by enlarging and
   offsetting it inside its frame rather than a plain cover fit, so the
   same literal percentages reproduce the exact framing. */
.promo__image img {
  position: absolute;
  top: -62.3%;
  left: -92.04%;
  width: 243.75%;
  height: 222.35%;
  max-width: none;
}

/* Floating tags are positioned relative to .promo__visual (the image
   composition), not the page — .promo__tags spans the same box as
   .promo__image's own row, and each tag is placed within it. Both axes are
   percentages of that shared box (matching Figma's proportions): horizontal
   was already a percentage of the shared width; vertical is now Figma's
   own pixel value divided by its 300px-tall reference frame (e.g.
   102.6px → 34.2%) rather than the literal pixel figure, so the whole
   composition scales as a unit at any width — including down to phone —
   instead of drifting out of alignment as soon as the image isn't
   rendering at that exact reference size. Widths are NOT copied from
   Figma — those were sized to fit its placeholder Lorem Ipsum, not the
   real copy below, so each tag is sized to its own content instead. */
.promo__tags {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.promo__tag {
  position: absolute;
  display: inline-flex;
  align-items: center;
  width: max-content;
  background: var(--colour-sky-teal);
  color: var(--colour-white);
  font-family: var(--font-primary);
  font-weight: 600;
  font-size: 18px;
  line-height: 25.2px;
  white-space: nowrap;
  pointer-events: auto;
}

.promo__tag--manage {
  top: 34.2%; /* 102.6 / 300 */
  left: 5.21%;
  padding: 12px var(--space-l); /* 12px 16px */
  border-radius: 13px;
  border: 1px solid var(--colour-sky-teal);
}

.promo__tag--claims {
  top: 63%; /* 189 / 300 */
  left: 69.78%;
  padding: 12px var(--space-xl); /* 12px 20px */
  border-radius: 12px;
}

.promo__tag--cover {
  top: 85.37%; /* 256.1 / 300 */
  left: 0;
  padding: 12px var(--space-xl); /* 12px 20px */
  border-radius: 12px;
}

/* ---- Testimonials ---- */
/* Built from Figma node 18564:3727 (visuals) — the continuous vertical
   column motion is a behavioural reference from 21st.dev's
   testimonials-columns-1 (see js/testimonials.js), not its styling.
   Homepage-only for now, so it stays alongside the other sections here. */

.testimonials {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6xl); /* 64px between header and columns */
  width: 100%;
  padding: var(--space-section-l) 0 128px; /* 144px top, 128px bottom */
  box-sizing: border-box;
  background: var(--colour-grey-101);
}

/* ---- Header ---- */

.testimonials__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2xl); /* 24px below the heading group */
  max-width: 1280px;
  padding: 0 var(--space-2xl);
  box-sizing: border-box;
  text-align: center;
}

.testimonials__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* .testimonials__eyebrow needs no rule of its own — Testimonials' grey-101
   section background is exactly what .eyebrow's white default (see
   css/style.css) is designed to contrast against. The class stays on the
   markup as a hook in case this section ever needs its own tweak. */

/* Typography comes from .text-h2 (css/typography.css) at desktop — fluid
   28px (mobile) → 48px (desktop) below, same technique as .hero__heading.
   No white-space: nowrap: it already fits on one line at the desktop
   width this was authored for, and removing the forced nowrap is what
   lets it wrap gracefully at narrower widths instead. */
.testimonials__heading {
  font-size: clamp(28px, 19.24px + 2.247vw, 48px);
  line-height: clamp(36.4px, 27.11px + 2.382vw, 57.6px);
}

.testimonials__heading-dark {
  color: var(--colour-header-grey);
}

.testimonials__heading-accent {
  color: var(--colour-brand-teal);
}

.testimonials__subcopy {
  margin: 0;
  max-width: 100%;
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 20px;
  line-height: 30px;
  color: var(--colour-body-grey);
}

/* ---- Columns / viewport ---- */

/* The constrained viewing window the columns scroll through — 603px tall
   and clipped, by design (see brief: cards continue beyond it but must
   never expand the section to reveal them all). */
.testimonials__viewport {
  position: relative;
  width: 100%;
  max-width: 1280px;
  height: 603px;
  overflow: hidden;
}

/* Three equal columns at the 1280px container works out to ~410px each
   with a 24px gap either side — the same relationship as "each column
   spans 4 of 12 grid columns" without the project needing an actual
   12-column grid utility (none exists elsewhere in the codebase either). */
.testimonials__columns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2xl); /* 24px */
  width: 100%;
  height: 100%;
}

.testimonials__column {
  position: relative;
  overflow: visible; /* only .testimonials__viewport clips — the track itself is taller than the column and scrolls through it */
  min-width: 0;
}

.testimonials__track,
.testimonials__track-repeat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl); /* 24px between cards */
}

.testimonials__track {
  will-change: transform;
  animation-name: testimonials-scroll;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/* Three different durations (not evenly spaced multiples of one another)
   so the columns drift in and out of phase with each other rather than
   feeling mechanically synchronised — same principle as the 21st.dev
   reference's 15s/19s/17s, scaled up for our taller/wider cards (our
   per-column content is roughly 2-3x the height of that reference's, so
   the seconds are scaled accordingly rather than reused verbatim). */
.testimonials__column:nth-child(1) .testimonials__track {
  animation-duration: 26s;
}

.testimonials__column:nth-child(2) .testimonials__track {
  animation-duration: 33s;
}

.testimonials__column:nth-child(3) .testimonials__track {
  animation-duration: 29s;
}

/* The track is the same set of cards twice, back to back (see
   js/testimonials.js) — animating exactly halfway (-50%) always lands on
   a frame identical to the start, so the loop point is undetectable. */
@keyframes testimonials-scroll {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-50%);
  }
}

/* Lets someone read a card without it scrolling out from under their
   cursor/focus — not a decorative hover effect, a usability one. */
.testimonials__column:hover .testimonials__track,
.testimonials__column:focus-within .testimonials__track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  /* Motion stops entirely; nothing further is needed to hide the
     duplicated second half of each track — .testimonials__viewport is a
     fixed 603px with overflow: hidden, and one full card set is taller
     than that, so with the track parked at translateY(0) the duplicate
     never scrolls into view in the first place. */
  .testimonials__track {
    animation: none;
  }
}

.testimonials__card {
  width: 100%;
  padding: var(--space-2xl); /* 24px */
  box-sizing: border-box;
  background: var(--colour-white);
  border: 1px solid var(--colour-light-grey);
  border-radius: 14px;
}

.testimonials__text {
  margin: 0 0 var(--space-2xl); /* 24px to the name below */
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 16px;
  line-height: 25.6px;
  color: var(--colour-grey-700);
}

.testimonials__name {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: 16px;
  line-height: 19.2px;
  color: #117A90; /* same distinct Figma teal used in the Self Service pill CTAs */
}

/* ---- Fades ---- */
/* Sit above the moving cards, don't affect track height/position. Fade
   into the section's own background colour so testimonials appear to
   dissolve as they cross the top/bottom edges of the viewport. */

.testimonials__fade {
  position: absolute;
  left: 0;
  width: 100%;
  height: 101px;
  z-index: 1;
  pointer-events: none;
}

.testimonials__fade--top {
  top: 0;
  background: linear-gradient(to bottom, var(--colour-grey-101) 0%, rgba(247, 248, 249, 0) 100%);
}

.testimonials__fade--bottom {
  bottom: 0;
  background: linear-gradient(to top, var(--colour-grey-101) 0%, rgba(247, 248, 249, 0) 100%);
}

/* ---- Featured stories ---- */
/* Built from Figma node 18564:3647. Full-bleed section (no 1280px cap) —
   unlike every other homepage section, the whole point here is that the
   side cards intentionally overflow past the visible viewport and get
   clipped, which needs the carousel itself to span the full page width.
   The header/CTA stay inside the standard 1280px container as normal. */

.stories {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6xl); /* 64px: header→carousel and carousel→CTA */
  width: 100%;
  padding-bottom: var(--space-section-l); /* 144px — no top padding, per Figma */
  box-sizing: border-box;
  background: var(--colour-grey-101);
}

/* ---- Header ---- */

.stories__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2xl); /* 24px below the heading group */
  max-width: 1280px;
  padding: 0 var(--space-2xl);
  box-sizing: border-box;
  text-align: center;
}

.stories__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* .stories__eyebrow needs no rule of its own — same reasoning as
   .testimonials__eyebrow above (grey-101 section background, .eyebrow's
   white default already contrasts correctly). Class kept on the markup as
   a hook. */

/* Typography comes from .text-h2 (css/typography.css) at desktop — fluid
   28px (mobile) → 48px (desktop) below, same values as
   .testimonials__heading (both share the same mobile/desktop sizes). No
   forced nowrap, for the same reason noted there. */
.stories__heading {
  font-size: clamp(28px, 19.24px + 2.247vw, 48px);
  line-height: clamp(36.4px, 27.11px + 2.382vw, 57.6px);
}

.stories__heading-dark {
  color: var(--colour-header-grey);
}

.stories__heading-accent {
  color: var(--colour-brand-teal);
}

.stories__subcopy {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 20px;
  line-height: 30px;
  color: var(--colour-body-grey);
}

/* ---- Carousel viewport ---- */

.stories__viewport {
  position: relative;
  width: 100%;
  /* Fluid 520px (mobile) → 700px (desktop), same clamp() technique as the
     section headings above — tracks .stories__card's own fluid height
     (below) so there's always sensible breathing room around it, without
     the two needing to share one literal formula. */
  height: clamp(520px, 441.1px + 20.22vw, 700px);
  overflow: hidden; /* the whole point: side cards are clipped, not squeezed to fit */
}

.stories__track {
  position: relative;
  width: 100%;
  height: 100%;
}

/* Every card (real or clone) shares one fluid box — 846×700 at desktop
   (the exact active-card size from Figma), scaling fluidly down to
   300×460 at mobile (see css/home.css's mobile section — same clamp()
   technique as the section headings, both endpoints exact). Side cards
   are a true scaled-down rendering of the same card (via transform: scale,
   set in JS below), not a separate smaller layout, so their padding/
   typography shrinks naturally with them. js/featured-stories.js reads
   the rendered width at runtime (not a hardcoded constant) to keep the
   prev/next peek spacing correct at whatever size this resolves to — see
   measureCentreOffset() there. Only transform/opacity transition, so moving
   the carousel never triggers layout. */
.stories__card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(300px, 60.73px + 61.35vw, 846px);
  height: clamp(460px, 354.8px + 26.97vw, 700px);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: 12px;
  overflow: hidden;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.6s ease;
}

.stories__card-link {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  color: inherit;
  text-decoration: none;
}

/* Each card's transform/opacity is computed and set inline by
   js/featured-stories.js as a function of its fixed slot's distance from
   the active slot (delta) — not a small set of CSS role classes — since
   the circular-track architecture there needs distances beyond ±1 (the
   boundary clones) to resolve to "fully hidden" too. The ~864px offset
   (846/2 + 64px gap + (846 × 0.891)/2) is the same Figma-derived
   active↔side centre distance as before, just applied per-delta in JS
   instead of hardcoded per role here.

   .stories__track--jump is added just long enough to silently snap a
   clone back to its equivalent real slot (or to set the very first
   render) without animating — see resolveClonesIfNeeded() in the JS. */
.stories__track--jump .stories__card {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .stories__card {
    transition: none;
  }
}

.stories__card-image {
  position: relative;
  width: 100%; /* fills the card's own fluid width, above */
  height: clamp(200px, 103.6px + 24.72vw, 420px);
  flex-shrink: 0;
  overflow: hidden;
}

/* Figma crops each photo by enlarging/offsetting it within its frame
   (see js/featured-stories.js's imageStyle per story) rather than a plain
   cover fit — the percentages are relative to the image's own box, so
   they reproduce the exact crop proportionally at any size the card
   itself resolves to. */
.stories__card-image img {
  position: absolute;
  max-width: none;
}

.stories__card-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl); /* 24px */
  width: 100%; /* fills the card's own fluid width, above */
  height: clamp(260px, 251.24px + 2.247vw, 280px);
  padding: 42px 40px;
  box-sizing: border-box;
  background: var(--colour-white);
}

.stories__card-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-l); /* 16px between headline group and description */
}

.stories__card-meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-s); /* 8px below date */
}

.stories__card-date {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: 16px;
  line-height: 19.2px;
  color: #117A90; /* same distinct Figma teal as Self Service / Testimonials */
}

.stories__card-title {
  margin: 0;
  font-family: var(--font-primary);
  font-weight: 600;
  font-size: 24px;
  line-height: 28.8px;
  color: var(--colour-header-grey);
}

.stories__card-excerpt {
  margin: 0;
  font-family: var(--font-secondary);
  font-weight: 400;
  font-size: 16px;
  line-height: 25.6px;
  color: var(--colour-body-grey);
}

/* flex: 0 0 1px (not the flex default of 0 1 auto) is load-bearing here:
   .stories__card-content is a fixed-height (280px) flex column, and the
   date/headline/excerpt block above this often needs more than the
   available space at its natural size (long headlines/excerpts). Without
   an explicit flex-shrink: 0, the default shrink behaviour squeezes this
   1px-tall item toward 0 under that pressure before it touches the taller
   siblings, which is why it wasn't rendering. min-height backs that up
   for the same reason. */
.stories__card-divider {
  flex: 0 0 1px;
  width: 100%;
  height: 1px;
  min-height: 1px;
  background-color: var(--colour-grey-200); /* #ECEDEF */
}

.stories__card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.stories__card-tag {
  padding: var(--space-2xs) var(--space-m); /* 4px 12px */
  background: var(--colour-grey-101);
  border-radius: var(--space-2xs); /* 4px */
  font-family: var(--font-primary);
  font-weight: 600;
  font-size: 14px;
  line-height: 19.5px;
  letter-spacing: 0.42px;
  color: var(--colour-mid-grey);
}

.stories__cta {
  z-index: 1;
}

/* ==========================================================================
   Mobile (≤767px) — primary design/testing viewport 390px, sensible down to
   ~320px. Desktop rules above are completely untouched; everything here is
   scoped inside this one media query. See CLAUDE.md: desktop stays the
   source of truth, this only adapts layout direction/spacing/sizing.
   ========================================================================== */

@media (max-width: 767px) {
  /* ---- Hero ---- */
  /* Heading font-size/line-height are fluid (clamp(), above) across the
     whole responsive range, not set here. */

  .hero {
    height: auto;
    padding: 176px var(--space-l) var(--space-6xl);
  }

  .hero__content {
    gap: var(--space-3xl);
  }

  .hero__intro {
    gap: var(--space-2xl);
  }

  .hero__heading-line--muted {
    margin-top: var(--space-s);
  }

  /* Stacked, not the desktop's single wide row — three 24px-gap items at
     desktop's own font size would overflow a 390px viewport. */
  .hero__trust-list {
    flex-direction: column;
    align-items: center;
    gap: var(--space-m);
  }

  .hero__trust-item {
    font-size: 16px;
    line-height: 1.3;
  }

  .hero__actions {
    flex-direction: column;
    width: 100%;
  }

  .hero__actions .btn {
    width: auto;
  }

  /* ---- Self service ---- */

  .self-service {
    padding: var(--space-section-xxs) 0; /* 64px, down from the desktop 144px */
  }

  .self-service__content {
    gap: var(--space-3xl);
    padding: 0 var(--space-l);
  }

  .self-service__header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-l);
  }

  .self-service__heading {
    white-space: normal;
  }

  /* "Get a quote" is dropped from the mobile self-service header entirely
     (not just resized) — the header keeps only the eyebrow/heading. */
  .self-service__header-cta {
    display: none;
  }

  .self-service__cards {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }

  .self-service__stack {
    gap: var(--space-l);
  }

  .self-service__card {
    height: auto;
    min-height: 200px;
    padding: var(--space-2xl);
  }

  .self-service__card--renew .self-service__card-desc,
  .self-service__card--update .self-service__card-desc {
    max-width: none;
  }

  /* Claim card: desktop's fixed-width copy column + fixed-size phone visual
     side by side becomes a stacked card — the wave stays as a decorative
     backdrop behind the copy, the phone visual moves below it at a
     contained size instead of its fixed 434×506. No bottom padding on the
     card itself (unlike the tablet block below) — the phone visual is the
     last item in the stack and must sit flush against the card's bottom
     edge, matching desktop, with no gap beneath it. */
  .self-service__claim {
    flex-direction: column;
    height: auto;
  }

  .self-service__claim-wave {
    top: auto;
    bottom: 0;
    width: 100%;
    height: auto;
  }

  .self-service__claim-copy {
    width: 100%;
    height: auto;
    gap: var(--space-3xl);
    padding: var(--space-2xl);
  }

  .self-service__claim-intro {
    width: 100%;
    gap: var(--space-m);
  }

  .self-service__claim-heading {
    white-space: normal;
  }

  .self-service__claim-bottom {
    gap: var(--space-2xl);
  }

  .self-service__claim-stats {
    width: 100%;
  }

  .self-service__stat--claims .self-service__stat-label,
  .self-service__stat--rating .self-service__stat-label {
    width: auto;
    max-width: 140px;
  }

  .self-service__claim-visual {
    position: relative;
    z-index: 2;
    align-self: center;
    width: 100%;
    max-width: 280px;
    height: auto;
    margin-top: var(--space-l);
  }

  /* ---- Promo (homepage instance) ---- */
  /* Shell stacking/padding lives in css/promo-panel.css — this is just the
     homepage-specific children (benefits list, image+tags). */

  .promo__benefits {
    gap: var(--space-m);
  }

  .promo__benefit {
    font-size: 18px;
    line-height: 1.3;
  }

  .promo__image {
    width: 100%;
    margin-left: 0;
  }

  /* The floating tags stay part of the same overlapping composition here
     — .promo__tags/.promo__tag keep the absolute positioning declared
     above, unchanged. Both axes are now percentages of the shared box
     (see the note above .promo__tag--manage), so they track .promo__image
     as it shrinks to this column's own width instead of drifting off it.
     Made smaller here, so three tags reads as accents on a much narrower
     photo rather than crowding it. */
  .promo__tag {
    font-size: 14px;
    padding: var(--space-s) var(--space-l); /* 8px 16px, down from 12px 16-20px */
    line-height: 1.3;
  }

  /* "Claims made simple" is the one tag whose overhang isn't governed by
     a percentage alone — left: 69.78% plus its own (largely fixed) text
     width. At desktop/tablet that overhang bleeds harmlessly onto the
     panel background; below ~550px .promo__image is close enough to the
     column's full width that the same overhang runs past
     .promo__panel's own overflow: hidden and off the edge of the screen.
     Nudged left here so the same tag still overlaps the image's right
     side — just not quite as far past its edge — rather than leaving the
     panel's clip in place and having its text cut off mid-word. */
  .promo__tag--claims {
    left: 56%;
  }

  /* ---- Testimonials ---- */

  .testimonials {
    gap: var(--space-3xl);
    padding: var(--space-section-xxs) 0 var(--space-6xl);
  }

  .testimonials__header {
    gap: var(--space-l);
    padding: 0 var(--space-l);
  }

  .testimonials__subcopy {
    font-size: 16px;
    line-height: 1.4;
  }

  /* Single column, not three — three concurrent auto-scrolling columns
     reading three-abreast doesn't hold up in a single narrow column; one
     column keeps the same continuous-scroll concept front and centre
     instead of stacking three separate motions the eye can't follow at
     this width. */
  .testimonials__viewport {
    max-width: 400px;
    height: 480px;
    padding: 0 var(--space-l);
  }

  .testimonials__columns {
    grid-template-columns: 1fr;
  }

  .testimonials__column:nth-child(2),
  .testimonials__column:nth-child(3) {
    display: none;
  }

  .testimonials__card {
    padding: var(--space-l);
  }

  /* ---- Featured stories ---- */

  .stories {
    gap: var(--space-3xl);
    padding-bottom: var(--space-section-xxs);
  }

  .stories__header {
    gap: var(--space-l);
    padding: 0 var(--space-l);
  }

  .stories__subcopy {
    font-size: 16px;
    line-height: 1.4;
  }

  /* Card/viewport WIDTH stays the fluid clamp() from above — js/
     featured-stories.js reads the rendered card width at runtime (not a
     hardcoded constant) so the prev/next spacing/peek stays
     proportionally correct at whatever size that resolves to.

     Card/content HEIGHT, however, is overridden here rather than left on
     the desktop clamp(): that clamp() bottoms out at exactly the size
     tuned for the (short) placeholder copy most stories carry, and two
     things push a real card taller at mobile widths — a long title
     (Hamilton Island's real story wraps four lines at mobile's narrower
     card width) and every card's fixed 4-tag row (STORY_TAGS) wrapping
     to two lines once the card is narrow. Both used to overflow the
     fixed-height content box and get clipped by .stories__card's own
     overflow: hidden. Title/excerpt are now clamped to 2 lines each
     (below) so every card's content has a known, bounded height —
     .stories__card-content and .stories__card itself then switch to
     auto height to fit that exactly (JS positions/centres/scales cards
     via inline transform: translate(-50%, -50%) ... — see
     js/featured-stories.js — which works the same with an auto height as
     a fixed one), and .stories__viewport gets a flat, generous mobile
     floor tall enough to contain the now-taller card without clipping
     it, replacing the desktop clamp() that bottomed out too close to
     fit it. */
  .stories__viewport {
    height: 560px;
  }

  .stories__card {
    height: auto;
  }

  .stories__card-content {
    height: auto;
    padding: var(--space-2xl) var(--space-l);
    gap: var(--space-l);
  }

  .stories__card-title {
    font-size: 20px;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }

  .stories__card-excerpt {
    font-size: 14px;
    line-height: 1.6; /* bumped for readability, was 1.4 */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }
}

/* ==========================================================================
   Tablet (768–1279px) — intermediate widths between the mobile block above
   and the untouched desktop rules at the top of this file. Split into a
   768–1023px "tablet portrait" band and a 1024–1279px "tablet landscape /
   small laptop" band only where the two genuinely need different
   treatment (self-service's outer grid, testimonials' column count);
   everything else in this range is covered by ONE shared block, or by the
   fluid clamp() typography set unconditionally further up, so this isn't
   a repeat of the mobile file per breakpoint. Most section headings/hero
   type need no explicit rule here at all — see the clamp() font-size/
   line-height on .hero__heading, .self-service__heading, etc. above.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {
  /* ---- Hero ----
     The desktop's fixed 800px height (tuned for a wide, short viewport)
     reads as an oversized, mostly-empty box on a portrait tablet — auto
     height keeps it content-driven instead, same idea as the mobile
     treatment but with room for the trust list/actions to stay in a row. */
  .hero {
    height: auto;
    padding: 200px var(--space-2xl) var(--space-6xl);
  }

  .hero__trust-list {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: var(--space-m);
  }

  .hero__trust-item {
    font-size: 20px;
  }

  .hero__actions {
    flex-wrap: wrap;
    justify-content: center;
  }
}

@media (min-width: 768px) and (max-width: 1279px) {
  /* ---- Self service ----
     The claim card's desktop composition (a 411px copy column beside a
     434px phone visual, side by side) only balances at the full 1280px
     container — below that the two would either overlap or squeeze
     illegibly, so the copy/visual stack for the whole tablet range, just
     at roomier tablet proportions than the mobile-tuned pixel values
     below 768px. */
  .self-service__content {
    padding: 0 var(--space-2xl);
  }

  .self-service__header {
    flex-wrap: wrap;
    row-gap: var(--space-l);
  }

  .self-service__card {
    height: auto;
    min-height: 220px;
  }

  .self-service__card--renew .self-service__card-desc,
  .self-service__card--update .self-service__card-desc {
    max-width: none;
  }

  .self-service__claim {
    flex-direction: column;
    height: auto;
    padding-bottom: var(--space-3xl);
  }

  .self-service__claim-wave {
    top: auto;
    bottom: 0;
    width: 100%;
    height: auto;
  }

  .self-service__claim-copy {
    width: 100%;
    height: auto;
    padding: var(--space-3xl);
  }

  .self-service__claim-intro {
    width: 100%;
  }

  .self-service__claim-heading {
    white-space: normal;
  }

  .self-service__claim-stats {
    width: 100%;
  }

  .self-service__stat--claims .self-service__stat-label,
  .self-service__stat--rating .self-service__stat-label {
    width: auto;
    max-width: 220px;
  }

  .self-service__claim-visual {
    align-self: center;
    width: 100%;
    max-width: 360px;
    height: auto;
    margin-top: var(--space-l);
  }

  /* ---- Promo (homepage instance) ----
     No override needed here any more: .promo__tags/.promo__tag keep the
     absolute, overlapping composition declared in the default rules
     (both axes are percentages of .promo__image's own box — see the note
     above .promo__tag--manage), so it scales as .promo__image shrinks to
     the stacked column's own width at this range without drifting. */
}

@media (min-width: 768px) and (max-width: 1023px) {
  /* Single column at the full 1280px container's own 411px width would be
     cramped well before 1024px — stack the two intro cards above the
     claim card instead, same shape as mobile. */
  .self-service__cards {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }

  .self-service__stack {
    gap: var(--space-l);
  }

  /* ---- Testimonials ----
     Three concurrent auto-scrolling columns need real width each to stay
     legible — two fits tablet portrait without the cards narrowing to the
     point their text turns into a ladder of isolated words; the third
     returns at 1024px (see below), where there's room for it again. */
  .testimonials__viewport {
    max-width: 700px;
    height: 560px;
  }

  .testimonials__columns {
    grid-template-columns: repeat(2, 1fr);
  }

  .testimonials__column:nth-child(3) {
    display: none;
  }
}

@media (min-width: 1024px) and (max-width: 1279px) {
  /* Two fluid columns rather than the desktop's fixed 411px + 1fr split —
     411px fixed would leave the claim card column too narrow before
     1280px. minmax keeps the intro column from either collapsing below a
     usable width or ballooning past what it needs. */
  .self-service__cards {
    grid-template-columns: minmax(300px, 380px) 1fr;
  }
}
