.story {
  display: flex;
  flex-direction: column;
  background-color: var(--pure-white);
}

.story__photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 402 / 352;
  object-fit: cover;
}

.story__content {
  display: flex;
  flex-direction: column;
  gap: 53.08px;
  padding-top: var(--space-40);
  padding-bottom: var(--space-60);
  padding-inline: var(--container-padding);
}

.story__lockup {
  display: flex;
  flex-direction: column;
  gap: 13.06px;
}

.story__heading {
  color: var(--dozen-dark);
  font-size: clamp(1.5rem, 0.9191rem + 2.3121vw, 3rem);
  line-height: 1.2;
  font-style: italic;
}

.story__intro {
  display: flex;
  flex-direction: column;
  gap: 34.54px;
}

.story__subline {
  color: var(--dozen-blue);
  font-size: clamp(2.25rem, 2.1532rem + 0.3854vw, 2.5rem);
  line-height: clamp(2.7rem, 2.3841rem + 1.2573vw, 3.515625rem);
  font-style: normal;
}

.story__body {
  color: var(--dozen-dark);
}

.story__link {
  color: var(--dozen-blue);
  text-underline-offset: 0.15em;
}

.story__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  padding: var(--space-20) var(--space-40);
  border: 1.26px solid var(--dozen-blue);
  border-radius: 42px;
  /* Figma paint: linear gradient dozen-blue -> #e5e5e5, whole layer at 30% opacity */
  background: linear-gradient(
    117deg,
    rgba(81, 63, 199, 0.3),
    rgba(229, 229, 229, 0.3)
  );
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: 1rem;
  line-height: 1;
  letter-spacing: -0.56px;
  color: var(--dozen-blue);
  text-decoration: none;
  transition:
    filter 0.2s ease,
    transform 0.2s ease;
}

.story__cta:hover,
.story__cta:focus-visible {
  filter: brightness(1.05);
  transform: translateY(-1px);
}

/* About page variant: split hero-style layout with a taller portrait photo,
   an h1-scale heading (never italic), an always-italic subline, and a
   multi-paragraph body. Scoped under .story--split so Home's single-photo,
   single-paragraph story is untouched. */
.story--split .story__heading {
  font-style: normal;
  font-size: var(--h1-size);
  line-height: 1.2;
}

.story--split .story__subline {
  font-style: italic;
  font-size: clamp(1.5rem, 1.1127rem + 1.5414vw, 2.5rem);
  line-height: 1.2;
}

.story__body-group {
  display: flex;
  flex-direction: column;
  gap: 22.5px;
}

/* Case Study Detail variant: same split anatomy and heading/subline
   treatment as --split, but a single-paragraph body (no body-group) and
   its own photo aspect ratio (796.679 tall vs About's 881.679). */
.story--detail .story__heading {
  font-style: normal;
  font-size: var(--h1-size);
  line-height: 1.2;
}

.story--detail .story__subline {
  font-style: italic;
  font-size: clamp(1.5rem, 1.1127rem + 1.5414vw, 2.5rem);
  line-height: 1.2;
}

/* Text-only variant: the case-study narrative bands run without a photo, so
   the copy holds the full board width instead of the 50% text column. Content
   is constrained to the shared 1280px column like .container does, and the
   photo-driven board min-height is dropped so padding sets the band height. */
.story--text .story__content {
  width: 100%;
  max-width: calc(var(--content-max) + 2 * var(--container-padding));
  margin-inline: auto;
}

/* Carousel slide wrapper: kept as a plain block element (never flex/grid)
   so carousel.css's own display:none/block toggling always wins — the
   .story--carousel anatomy lives one level deeper, inside this wrapper. */
.story-carousel__slide {
  width: 100%;
}

/* Services carousel variant: five story-anatomy slides (Figma frames
   968169:19976/19990/20004/20018/20032), each photo half + text half like
   the base component, but with a bulleted service list instead of a body
   paragraph, no CTA, and a tinted photo (dozen-blue at 60% over a grayscale
   photo, matching the Figma image+solid-fill layering). Never italic
   heading / always-italic subline, matching the About story mobile
   pattern. carousel.css owns the slide wrapper's show/hide — this variant
   only styles the nested .story anatomy. */
.story--carousel .story__heading {
  font-style: normal;
}

.story--carousel .story__subline {
  font-style: italic;
}

.story--carousel .story__photo {
  position: relative;
  overflow: hidden;
}

/* ::after, not ::before: at desktop the photo <img> itself becomes
   position: absolute (see the 1024px block below), which puts it in the
   same z-index: auto paint step as this pseudo-element — same-step
   elements paint in DOM order, so a ::before (generated ahead of the img)
   would end up painted first and hidden underneath it. ::after always
   comes after the img in that ordering, keeping the tint on top. */
.story--carousel .story__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--dozen-blue-60);
  pointer-events: none;
}

.story--carousel .story__details {
  display: flex;
  flex-direction: column;
  gap: 22.5px;
}

.story--carousel .story__list {
  margin: 0;
  padding: 0;
  list-style-position: inside;
}

.story--carousel .story__list li {
  margin: 0;
}

.story--carousel .story__note {
  margin: 0;
}

/* People carousel variant: same --carousel grid/anatomy (photo half, text
   half, never-italic heading, always-italic subline, no CTA) but the photo
   runs untinted and the copy is a single body paragraph instead of a
   bulleted list (Figma boards 968169:20696/20710/20725/20739 — bio-card
   lockup, not a service pitch). Scoped so the Services carousel's tint is
   untouched. */
.story--carousel-people .story__photo::after {
  display: none;
}

/* Mobile: dots sit in a white band under the stacked card. Desktop keeps
   the card flush against the next section, so the dots overlay its bottom
   edge instead — straddling the tinted photo and the white text half — and
   each dot carries a white halo to stay legible on both. */
.story-carousel__carousel .carousel__dots {
  color: var(--dozen-blue);
}

@media (max-width: 1023.98px) {
  .story-carousel__carousel .carousel__dots {
    position: static;
    padding-block: var(--space-20);
  }
}

@media (min-width: 1024px) {
  .story-carousel__carousel .carousel__dot::before {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
  }
}

@media (min-width: 1024px) {
  .story {
    flex-direction: row;
  }

  .story__photo,
  .story__content {
    flex: 0 0 50%;
    max-width: 50%;
  }

  /* Fill-and-crop, like the --split/--carousel variants below: an in-flow
     fixed-ratio image leaves a white gap under itself whenever the text
     column runs taller. Out of flow, the text column drives the row height
     and the photo fills whatever results; the min-height keeps the 1440
     board when the text runs short. */
  .story {
    min-height: 738px;
  }

  .story__photo {
    position: relative;
  }

  .story__photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  .story__content {
    padding-top: var(--space-120);
    padding-bottom: var(--space-120);
  }

  .story__heading {
    font-style: normal;
  }

  .story__subline {
    font-style: italic;
  }

  .story__cta {
    align-self: flex-start;
  }

  /* Board heights for the split variants (base .story min-height is 738). */
  .story--split {
    min-height: 881.679px;
  }

  .story--split.story--detail {
    min-height: 796.679px;
  }

  /* No photo column to fill, so the row is a single stacked block and the
     board min-height no longer applies. The lockup splits into heading-left /
     copy-right, matching the intro bands that neighbour it on the page. */
  .story--text,
  .story--split.story--detail.story--text {
    flex-direction: column;
    min-height: 0;
  }

  .story--text .story__content {
    flex: 1 1 auto;
    max-width: calc(var(--content-max) + 2 * var(--container-padding));
  }

  .story--text .story__lockup {
    flex-direction: row;
    align-items: flex-start;
    gap: 82px;
  }

  .story--text .story__heading {
    flex: 0 1 639px;
  }

  .story--text .story__intro {
    flex: 0 1 559px;
  }

  .story--split .story__heading {
    line-height: var(--h1-leading);
  }

  .story--split .story__subline {
    line-height: 1.40625;
  }

  .story--detail .story__heading {
    line-height: var(--h1-leading);
  }

  .story--detail .story__subline {
    line-height: 1.40625;
  }

  /* Slide heights vary with content (the last slide's extra note paragraph
     runs long — see services/story.html); the photo fills the row's full
     height rather than using a fixed aspect ratio, matching the Figma
     instance where the photo frame always matches its sibling's height.
     Grid (like carousel.css already uses for tallest-slide sizing) lets a
     stretched item's height resolve percentages that flexbox can't — but
     the image itself still can't use a percentage height: its own natural
     size feeds back into the row's auto-height *before* stretch is
     resolved, so a percentage there is circular and every browser falls
     back to the image's intrinsic ratio (portrait photos blew the row out
     to their own aspect height). Taking the image out of flow with
     position: absolute removes it from that measurement entirely — the
     row's height is then driven purely by .story__content's text, and the
     image just fills whatever height results. */
  .story--carousel {
    display: grid;
    grid-template-columns: 50% 50%;
    /* Figma story boards are fixed 619.679 — text content alone runs
       shorter; the photo fills whatever the row resolves to. */
    min-height: 619.679px;
    /* The slide wrappers all stretch to the tallest slide (grid-area 1/1
       stacking in carousel.css); without this, shorter slides' photos stop
       at the 619.679 minimum and leave a white strip below. */
    height: 100%;
  }

  /* The base flex rule's max-width: 50% is relative to the .story row
     (1440); a grid item's percentage resolves against its own already-50%
     track, which would halve it again to 25%. Grid's columns already do
     the 50/50 split, so cancel it. */
  .story--carousel .story__photo,
  .story--carousel .story__content {
    max-width: none;
  }

  .story--carousel .story__photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }
}
