/* ==========================================================================
   PCP — Transformation Stories
   A sequential, cinematic reading experience. One person per chapter, given
   substantial screen space: a tall sticky portrait on one side, the three
   movements of their story scrolling past on the other.

   Everything here is scoped to [data-stories]. The default state of every
   element is VISIBLE — GSAP animates *from* a hidden state at runtime — so
   with no JavaScript, no GSAP, or reduced motion, the section still reads as
   a finished editorial spread.
   ========================================================================== */

[data-stories] {
  --story-gap: clamp(3rem, 6vw, 7rem);
  --story-rhythm: clamp(5rem, 11vh, 9rem);
  --story-stick: calc(84px + clamp(1.5rem, 4vh, 3.5rem));
  --story-rule: rgba(212, 175, 55, 0.22);
  --story-label: rgba(212, 175, 55, 0.92);

  --story-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 40px 80px -40px rgba(0, 0, 0, 0.9),
    0 0 0 1px rgba(212, 175, 55, 0.14),
    0 60px 120px -60px rgba(212, 175, 55, 0.18);

  position: relative;
}

/* --- Chapter ----------------------------------------------------------- */

[data-stories] .story {
  position: relative;
  padding-block: var(--story-rhythm);
}

/* A hairline between chapters, fading at both ends so it reads as a rule
   rather than a border. */
[data-stories] .story + .story::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--story-rule) 22%, var(--story-rule) 78%, transparent);
}

[data-stories] .story-grid {
  display: grid;
  /* Row gap is the mobile stack spacing. Column gap must stay a normal
     gutter: on the 12-column desktop grid an oversized gap consumes the
     container and collapses the columns themselves. */
  row-gap: var(--story-gap);
  column-gap: clamp(1.25rem, 2.4vw, 2.25rem);
}

/* --- Figure: the person ------------------------------------------------ */

[data-stories] .story-figure {
  margin: 0;
  /* The caption is absolutely positioned inside this figure. Sticky supplies
     a containing block on desktop, but below that breakpoint the figure is
     static, so declare it here or the caption escapes the frame. */
  position: relative;
}

[data-stories] .story-stage {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius, 16px);
  aspect-ratio: 4 / 5;
  background:
    radial-gradient(120% 90% at 50% 0%, #10233d 0%, transparent 60%),
    linear-gradient(180deg, #0a1526 0%, #060d18 100%);
  box-shadow: var(--story-shadow);
  isolation: isolate;
}

/* The media is deliberately taller than its frame. The scroll drift moves it
   a couple of percent and this overscan guarantees no edge is ever exposed. */
[data-stories] .story-media {
  position: absolute;
  left: 0;
  width: 100%;
  top: -6%;
  height: 112%;
  object-fit: cover;
  object-position: 50% 35%;
  display: block;
  opacity: 0;
  transition: opacity 900ms var(--ease-spring, cubic-bezier(0.22, 1, 0.36, 1));
  will-change: transform;
}

[data-stories] .story-stage.is-showing .story-media { opacity: 1; }

/* Lift from the bottom, so the caption always has something to sit on. */
[data-stories] .story-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(5, 5, 5, 0.86) 0%,
    rgba(5, 5, 5, 0.45) 26%,
    rgba(5, 5, 5, 0) 58%
  );
}

/* A warm treatment layer, so a photograph sits inside the brand palette
   instead of on top of it. */
[data-stories] .story-wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: multiply;
  background: linear-gradient(150deg, rgba(212, 175, 55, 0.16) 0%, rgba(11, 31, 58, 0.42) 100%);
}

/* No photograph yet: the name becomes the image. Editorial and honest — this
   is never a stand-in face. */
[data-stories] .story-panel {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 12%;
  text-align: center;
}

[data-stories] .story-panel::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 42%;
  width: 78%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(212, 175, 55, 0.20) 0%, transparent 68%);
  filter: blur(28px);
}

[data-stories] .story-panel-numeral {
  position: relative;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(5rem, 12vw, 9rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  color: rgba(255, 255, 255, 0.16);
}

/* --- Caption: name and role ------------------------------------------- */

[data-stories] .story-id {
  position: absolute;
  z-index: 3;
  left: clamp(1.5rem, 4%, 2.5rem);
  right: clamp(1.5rem, 4%, 2.5rem);
  bottom: clamp(1.5rem, 4%, 2.25rem);
}

[data-stories] .story-index {
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--story-label);
  margin: 0;
}

[data-stories] .story-name {
  margin: 0.5rem 0 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(1.85rem, 3.4vw, 2.75rem);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: #fff;
}

[data-stories] .story-role {
  margin: 0.55rem 0 0;
  font-size: 0.78rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.58);
}

/* --- Narrative: the three movements ----------------------------------- */

[data-stories] .story-narrative {
  position: relative;
  display: flex;
  gap: clamp(1rem, 1.6vw, 1.75rem);
}

/* The gold spine, filling as the chapter is read. */
[data-stories] .story-spine {
  position: relative;
  flex: 0 0 1px;
  width: 1px;
  background: rgba(255, 255, 255, 0.08);
}

[data-stories] .story-spine-fill {
  position: absolute;
  inset: 0;
  transform-origin: top center;
  background: linear-gradient(180deg, rgba(212, 175, 55, 0.85) 0%, rgba(232, 106, 36, 0.55) 100%);
  box-shadow: 0 0 12px rgba(212, 175, 55, 0.45);
}

[data-stories] .story-flow {
  flex: 1 1 auto;
  min-width: 0;
  padding-block: clamp(0.5rem, 2vh, 2rem);
}

[data-stories] .story-movement + .story-movement {
  margin-top: clamp(3rem, 8vh, 6rem);
}

[data-stories] .story-movement-label {
  margin: 0 0 1.25rem;
  font-size: 0.66rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--story-label);
}

[data-stories] .story-body {
  margin: 0;
  font-size: clamp(1rem, 1.1vw, 1.09rem);
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.72);
  max-width: 34em;
}

[data-stories] .story-body + .story-body { margin-top: 1.15rem; }

/* --- Quote ------------------------------------------------------------- */

[data-stories] .story-quote-block {
  margin: clamp(3rem, 8vh, 6rem) 0 0;
  padding-left: clamp(1.25rem, 3vw, 2rem);
  border-left: 2px solid rgba(212, 175, 55, 0.55);
}

[data-stories] .story-quote {
  margin: 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.6rem, 2.9vw, 2.4rem);
  line-height: 1.28;
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.94);
  max-width: 24em;
}

[data-stories] .story-quote-cite {
  margin-top: 1.25rem;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: rgba(255, 255, 255, 0.5);
}

/* --- Optional measurable achievement ---------------------------------- */

[data-stories] .story-achievement {
  margin-top: clamp(2.5rem, 6vh, 4rem);
  padding-top: clamp(1.5rem, 4vh, 2.25rem);
  border-top: 1px solid var(--story-rule);
}

[data-stories] .story-achievement-value {
  margin: 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(2.75rem, 5.5vw, 4rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  background: linear-gradient(135deg, #F1D27A 0%, #D4AF37 45%, #B8891B 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

[data-stories] .story-achievement-label {
  margin: 0.75rem 0 0;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: rgba(255, 255, 255, 0.55);
}

/* --- Desktop: sticky portrait, alternating sides ---------------------- */

@media (min-width: 1024px) {
  [data-stories] .story-grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }

  [data-stories] .story-figure-col { grid-column: 1 / span 6; }
  [data-stories] .story-narrative  { grid-column: 8 / span 5; }

  /* Alternate the composition so consecutive chapters do not read as a
     template. */
  [data-stories] .story:nth-child(even) .story-figure-col { grid-column: 7 / span 6; grid-row: 1; }
  [data-stories] .story:nth-child(even) .story-narrative  { grid-column: 1 / span 5; grid-row: 1; }

  /* The person holds the screen while their story scrolls past. Plain
     position: sticky — no pin, no spacer maths, and it still works with
     JavaScript disabled. */
  [data-stories] .story-figure {
    position: sticky;
    top: var(--story-stick);
  }

  [data-stories] .story-stage {
    max-height: calc(100vh - var(--story-stick) - 3rem);
  }

  /* Give the narrative enough length that the sticky portrait actually
     holds for a while. */
  [data-stories] .story-flow { padding-block: clamp(2rem, 8vh, 6rem); }
}

/* --- Mobile ----------------------------------------------------------- */

@media (max-width: 1023px) {
  [data-stories] .story-stage {
    aspect-ratio: 3 / 4;
    border-radius: var(--radius, 16px);
  }
  [data-stories] .story-name { font-size: clamp(1.6rem, 7vw, 2.15rem); }
  [data-stories] .story-quote { font-size: clamp(1.4rem, 6vw, 1.9rem); }
  [data-stories] .story-body { font-size: 1rem; }
}

/* --- Neutral state ---------------------------------------------------- */

/* Deliberately composed. It explains the open space as a standard, which is
   why it reads as finished rather than unbuilt. No empty frames, no
   placeholder faces, no "coming soon". */
[data-stories] .stories-neutral {
  max-width: 40rem;
  margin-inline: auto;
  padding-block: clamp(0.5rem, 2vh, 1.5rem);
  text-align: center;
}

[data-stories] .stories-neutral-title {
  margin-top: 1.5rem;
}

[data-stories] .stories-neutral-body {
  margin: 1.75rem auto 0;
  max-width: 34rem;
  font-size: clamp(1rem, 1.1vw, 1.09rem);
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.62);
}

[data-stories] .stories-neutral-rule {
  width: 3.5rem;
  height: 1px;
  margin: clamp(2rem, 5vh, 3rem) auto;
  background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.9), transparent);
}

/* --- Reduced motion --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  [data-stories] .story-media {
    opacity: 1;
    transition: none;
    /* No drift, so no overscan is needed. */
    top: 0;
    height: 100%;
    will-change: auto;
  }
  [data-stories] .story-figure { position: static; }
  [data-stories] .story-spine-fill { transform: none; }
}

/* ==========================================================================
   Proof band (Results)
   Driven by `verifiedStats` / `supportingProof` in stories.js.

   Deliberately NOT cards on a grid — a card grid of numbers reads as a SaaS
   dashboard. This is an editorial band: oversized numerals, thin gold rules
   between them, quiet labels, and the measurement date underneath.

   Every value is in the DOM as written and visible by default. Animation is
   applied at runtime by stories.js, so no-JS and reduced-motion viewers see
   the finished band. Never uses the shared `.reveal` class — that starts at
   opacity 0 and is switched on by a one-shot scanner that has already run.
   ========================================================================== */

[data-stats] {
  --proof-rule: rgba(212, 175, 55, 0.20);
  --proof-gold: rgba(212, 175, 55, 0.92);
}

[data-stats] .proof-band {
  padding-block: clamp(2rem, 5vh, 3.5rem);
  border-top: 1px solid var(--proof-rule);
  border-bottom: 1px solid var(--proof-rule);
}

[data-stats] .proof-figures {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  margin: 0;
}

[data-stats] .proof-figure {
  position: relative;
  text-align: center;
}

/* Oversized, and the single most prominent thing in the section. */
[data-stats] .proof-value {
  margin: 0;
  /* A fixed box, sized to the numerals, that every value is centred inside.
     Text values are set smaller than figures, so without this the cells would
     be different heights and the labels would not line up across the row.
     It also reserves the line box, so a running count-up cannot reflow the
     band. `overflow: hidden` is what the mask reveal slides out of. */
  display: flex;
  align-items: center;
  justify-content: center;
  /* Sized off the numeral scale with headroom for descenders, so a cell whose
     value is smaller text does not end up a shorter box than a cell of
     figures — that is what knocks the labels out of line across the row. */
  min-height: calc(clamp(3.25rem, 7.5vw, 6rem) * 1.2);
  overflow: hidden;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(3.25rem, 7.5vw, 6rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

/* A value that is a word, a range or a date is not a figure and must not
   outshout one. Smaller, looser, and it stays on one line. */
[data-stats] [data-proof-mode="mask"] .proof-value {
  font-size: clamp(1.6rem, 3.4vw, 2.75rem);
  letter-spacing: -0.02em;
  text-wrap: balance;
}

[data-stats] .proof-value-inner {
  display: block;
  background: linear-gradient(150deg, #F1D27A 0%, #D4AF37 42%, #B8891B 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  will-change: transform;
}

[data-stats] .proof-label {
  margin: clamp(0.9rem, 2vh, 1.35rem) 0 0;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.72);
}

/* Provenance. Small, quiet, and the reason the band reads as proof. */
[data-stats] .proof-asof {
  margin: 0.6rem 0 0;
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.38);
}

/* Thin gold separators between figures, not around them. */
@media (min-width: 640px) {
  [data-stats] .proof-figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  [data-stats] .proof-figure + .proof-figure::before {
    content: "";
    position: absolute;
    left: calc(clamp(2.5rem, 6vw, 4rem) / -2);
    top: 8%;
    bottom: 8%;
    width: 1px;
    background: linear-gradient(180deg, transparent, var(--proof-rule) 30%, var(--proof-rule) 70%, transparent);
  }
  /* On two columns the third cell starts a new row, so it has no rule. */
  [data-stats] .proof-figure:nth-child(odd)::before { display: none; }
}

@media (min-width: 1024px) {
  /* One row of equal columns, however many figures are configured. */
  [data-stats] .proof-figures {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: start;
  }
  [data-stats] .proof-figure:nth-child(odd)::before { display: block; }
  [data-stats] .proof-figure:first-child::before { display: none; }
}

/* --- Supporting proof ------------------------------------------------- */

[data-stats] .proof-support {
  margin-top: clamp(2rem, 5vh, 3rem);
}

[data-stats] .proof-support-head {
  margin: 0 0 1.5rem;
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--proof-gold);
  text-align: center;
}

[data-stats] .proof-support-list {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Side by side once there is room, so it reads as a row of credentials
   rather than a stacked list. */
@media (min-width: 640px) {
  [data-stats] .proof-support-list {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.25rem clamp(1.75rem, 4vw, 3.25rem);
  }
}

[data-stats] .proof-support-item {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-align: center;
}

[data-stats] .proof-support-label {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.86);
}

[data-stats] .proof-support-detail {
  font-size: 0.72rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.45);
}

[data-stats] .proof-support-link {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 240ms var(--ease-spring, cubic-bezier(0.22, 1, 0.36, 1));
}

[data-stats] .proof-support-link:hover,
[data-stats] .proof-support-link:focus-visible {
  border-bottom-color: var(--proof-gold);
}

[data-stats] .proof-support-link:active .proof-support-label { color: var(--proof-gold); }

/* --- Neutral state: the evidence standard ----------------------------- */

/* Before there is data, the band states the standard the numbers will be
   held to. That is the only honest proof available, and it keeps the section
   reading as finished rather than as a hole where figures should be. */
[data-stats] .proof-neutral {
  max-width: 46rem;
  margin-inline: auto;
  padding-block: clamp(2rem, 5vh, 3.25rem);
  border-top: 1px solid var(--proof-rule);
  border-bottom: 1px solid var(--proof-rule);
  text-align: center;
}

[data-stats] .proof-neutral-eyebrow {
  margin: 0;
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--proof-gold);
}

[data-stats] .proof-neutral-title {
  margin: 1.5rem auto 0;
  max-width: 30rem;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(1.85rem, 4vw, 3rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: #fff;
}

[data-stats] .proof-neutral-body {
  margin: 1.6rem auto 0;
  max-width: 34rem;
  font-size: 0.95rem;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.56);
}

[data-stats] .proof-neutral-rule {
  width: 3rem;
  height: 1px;
  margin: clamp(1.75rem, 4vh, 2.5rem) auto;
  background: linear-gradient(90deg, transparent, var(--proof-gold), transparent);
}

[data-stats] .proof-neutral-status {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--proof-gold);
}

/* --- Reduced motion --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  [data-stats] .proof-value-inner { will-change: auto; transform: none; }
}

/* ==========================================================================
   Pending photography frames (Results gallery)
   Deliberately empty designed surfaces. Not stand-in photographs — there is
   no person, and no caption claiming a documented event. Replace a
   .pending-frame div with an <img> when real photography arrives.
   ========================================================================== */

.pending-frame {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(90% 70% at 50% 0%, rgba(212, 175, 55, 0.07) 0%, transparent 60%),
    linear-gradient(160deg, #0a1526 0%, #060d18 100%);
}

.pending-frame::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2.25rem;
  height: 1px;
  transform: translate(-50%, -50%);
  background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.55), transparent);
}

@media (max-width: 767px) {
  /* Four-layer shadows are expensive on a phone; two layers read the same. */
  [data-stories] { --story-shadow: 0 1px 0 rgba(255,255,255,0.05) inset, 0 30px 60px -36px rgba(0,0,0,0.9); }
  [data-stories] .story-panel::after { filter: blur(16px); }
}

/* ==========================================================================
   The mansion as one continuous ground — results page
   --------------------------------------------------------------------------
   Same treatment as Home and About. The room is painted on .pcp-cinematic-bg,
   the single position:fixed, inset:0, z-index:-1 layer that already sits
   behind all content. One layer means it never scrolls, there is no seam
   between sections, and no section owns a background block of its own.

   The veil is the same gradient the other pages carry (0.82-0.96), so the
   darkness behind the copy — and therefore its legibility — matches exactly.

   This file is loaded by results.html and by nothing else, so these rules
   need no page class and cannot reach another page.
   ========================================================================== */
.pcp-cinematic-bg {
  background-image:
    linear-gradient(180deg,
      rgba(3, 10, 20, 0.96) 0%,
      rgba(3, 10, 20, 0.84) 12%,
      rgba(3, 10, 20, 0.82) 88%,
      rgba(3, 10, 20, 0.96) 100%),
    url('../media/backgrounds/pcp-business-background.png');
  background-size: cover, cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

/* Section fills cleared, so the one ground shows through unbroken. */
.surface-navy,
.surface-navy-solid,
.surface-elevated {
  background: none;
}

/* The bar stays opaque at the exact colour it already uses. It was
   translucent, which over a fixed room would have let the mansion show
   through the navigation. Only the alpha changes — the hue does not.

   This page's <body> carries no page class, so the scrolled state is matched
   explicitly: site.css sets .site-header.is-scrolled at a specificity a bare
   .site-header cannot beat. stories.css loads after it, so matching that
   specificity here is enough to win on order. */
.site-header,
.site-header.is-scrolled { background-color: rgb(13, 5, 5); }

/* ==========================================================================
   "Inside the community" — the large frame shows its photograph plainly
   --------------------------------------------------------------------------
   [data-results-photo] is on that one box. The other four frames in the grid
   are still placeholders and keep their designed plate; the origin-story
   frame on About keeps its treatment too.

   .img-frame dresses a photograph for a design: ::before is a colour wash in
   mix-blend-mode: multiply, ::after is a dark gradient from the bottom, and
   the image itself carries saturate(.85) contrast(1.05). All three are right
   for a picture meant to sit back behind a caption. There is no caption here
   and the picture is the point, so all three are off and the photograph is
   shown as it is.

   The frame keeps its border, its radius and its overflow: hidden, which is
   what crops the image to the box.
   ========================================================================== */
/* No page scope: there is no .page-results class anywhere on this site, and
   [data-results-photo] is unique to this one box, so it needs none. */
/* Any frame in this grid that holds a real photograph shows it plainly: the
   colour wash, the dark gradient and the image filter all come off. Two
   frames carry it now, and a third would only need the attribute. */
[data-photo-plain]::before,
[data-photo-plain]::after { content: none; }
[data-photo-plain] img {
  filter: none;
  /* Out of flow, so the picture fills the frame without SETTING its height.

     .img-frame img is position: static with height: 100%. In a frame whose
     own height is auto — which the four small frames now are, so they can
     take the row height the big frame sets — that percentage has nothing to
     resolve against, so the image fell back to its intrinsic ratio and drove
     the box instead. The row grew from 181px to 196px and the bottom edge of
     the grid stopped lining up with the big frame by 28px.

     Absolute against .img-frame's own position: relative, the image fills
     the box and contributes no height at all. */
  position: absolute;
  inset: 0;
}

/* --- The grid takes its shape from the photograph ------------------------
   The big frame was square — 568x568 on a laptop — because it spans two
   columns and two rows of a grid whose cells were all aspect-square. A 3:2
   picture in a 1:1 box leaves a band of the frame's navy plate above and
   below it, which is the blank space to remove.

   So the frame is given the picture's own 3:2 and the four small frames give
   up their fixed square: on a laptop they take whatever row height the big
   frame now sets, which lines all five up along the same top and bottom
   edges. They end up shorter than before, which is the "shrink them a bit"
   part — nothing about their style, order or position changes.

   On a phone the small frames sit BELOW the big one rather than beside it,
   so there is no row height to inherit; they take the same 3:2 instead, so
   the whole grid reads as one family.
   ---------------------------------------------------------------------- */
[data-results-photo] { aspect-ratio: 3 / 2; }

@media (min-width: 768px) {
  [data-results-photo] ~ .img-frame { aspect-ratio: auto; }
}
@media (max-width: 767px) {
  [data-results-photo] ~ .img-frame { aspect-ratio: 3 / 2; }
}
[data-results-photo] img {
  /* contain, not the frame's usual cover.

     The box is SQUARE — 568x568 on a laptop — because it spans two columns
     and two rows of a grid whose cells are aspect-square. The photograph is
     1536x1024, a 3:2 landscape. Covering a 1:1 box with a 3:2 picture throws
     away a third of its width, 16.7% off each side, and that crop cut the
     headline in the artwork in half: it read "...WEST Sports Car C...".

     contain keeps the whole frame visible, which is what was asked for. The
     band above and below it is the frame's own dark plate, not an added
     overlay. Nothing about the box's size, border or corners changes. */
  object-fit: contain;
}
