/* ============================================================================
   Results — client picker, slider, and the two-column case-study slide.
   ========================================================================= */

/* overflow-x: clip, not hidden. The track is five slides wide and runs off the
   right of the page on purpose (the next slide peeks). Left unclipped, the
   document was 6,584px wide at a 1440 viewport: body clips it visually, but
   that does not reliably stop horizontal panning (iOS Safari ignores it). The
   section spans the full viewport, so clipping here still shows the peek.
   `clip` rather than `hidden` because it creates no scroll container. */
.results { background: var(--bg-sunken); overflow-x: clip; }

/* `.sec-head__title` caps at 22ch, which is right for the short section
   headings elsewhere on the page and far too narrow here: this one is a full
   78-character sentence, and 22ch breaks it into a five-line column. Released
   to the header's own 46rem measure, where it sets in three comfortable
   lines. */
.results__head { margin-bottom: clamp(2rem, 1.5rem + 1.5vw, 3rem); }
/* Plain and heavy, like every other homepage heading. It used to set its
   closing phrase in the serif italic accent, the only visible heading on the
   page still doing so. */
.results__head .sec-head__title { max-width: none; font-weight: 700; }

/* --- The client picker ----------------------------------------------------
   One pill rail holding five agency names, the active one lifted onto white.
   It is a segmented control, so the rail carries the border and the buttons
   carry nothing until they are chosen — five bordered buttons in a row read as
   five separate things rather than as one choice.

   It scrolls rather than wraps below its natural width: five agency names is
   ~46rem of text, and wrapping to three rows turns a control into a paragraph.
   `scroll-snap` keeps a part-scrolled rail from stopping mid-label.          */
.csx__tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: clamp(1.25rem, 1rem + 1vw, 2rem);
  padding: 0.35rem;
  border-radius: var(--r-pill);
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--border);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}
.csx__tabs::-webkit-scrollbar { display: none; }

.csx__tab {
  flex: none;
  scroll-snap-align: center;
  padding: 0.6rem 1.05rem;
  min-height: 44px;
  border-radius: var(--r-pill);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--text-secondary);
  transition: color var(--d-fast) var(--ease-out-soft),
              background-color var(--d-fast) var(--ease-out-soft),
              box-shadow var(--d-base) var(--ease-out-soft);
}
.csx__tab:hover { color: var(--text); background: var(--blue-100); }
.csx__tab.is-active {
  color: var(--text);
  font-weight: 600;
  background: var(--white);
  box-shadow: var(--e-2);
}

/* --- Track ---------------------------------------------------------------- */

.csx { position: relative; }

/* The viewport is not `overflow: hidden`: the peeking next slide is the point.
   It is clipped by the section's own padding instead, and `overflow-x: clip`
   would kill the peek along with the overflow. Slides past the edge are
   `inert`, so nothing reachable ever sits outside it. */
.csx__viewport { overflow: visible; }
.csx__viewport:focus-visible { outline: none; }

.csx__track { display: flex; align-items: stretch; will-change: transform; }
.csx__slide { flex: none; }

/* Inactive slides step back rather than disappear — they are visible past the
   edge and should read as "more of the same", not as the active card's twin
   competing for attention. Not opacity on text: this dims the whole slide as a
   decorative object, and it is `inert`, so nothing here has to be readable. */
.csx__slide { transition: opacity var(--d-slow) var(--ease-out-soft); }
.csx__slide:not(.is-active) { opacity: .55; }

@media (prefers-reduced-motion: reduce) {
  .csx__slide { transition: none; }
}

/* --- Arrows --------------------------------------------------------------- */

.csx__arrows {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: clamp(1.25rem, 1rem + 1vw, 2rem);
}
.csx__arrow {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--white);
  color: var(--blue-600);
  box-shadow: inset 0 0 0 1px var(--border-strong);
  transition: background-color var(--d-fast) var(--ease-out-soft),
              color var(--d-fast) var(--ease-out-soft),
              box-shadow var(--d-base) var(--ease-out-soft);
}
.csx__arrow:hover:not(:disabled) {
  background: var(--blue-500);
  color: #fff;
  box-shadow: var(--e-brand);
}
/* Disabled, not hidden. A control that vanishes at the ends moves the two
   beside it, and the row jumps every time you reach the last client. */
.csx__arrow:disabled { color: var(--ink-300); cursor: not-allowed; }

.csx__count { font-size: var(--fs-sm); font-weight: 600; color: var(--text); }
.csx__count-total { color: var(--text-muted); font-weight: 500; }

/* --- The slide ------------------------------------------------------------
   Laid out to the supplied case-study design: logo and headline together at the
   top left, a 2 × 2 of figures, the client's own words, the two actions; the
   story with a rule beside it at the top right and a fixed-shape picture at the
   foot of that column.                                                       */

.cs {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  height: 100%;
  display: grid;
  /* Slides share one height. On a single column that spare height would be
     shared out BETWEEN the rows, opening a hole under the buttons; it belongs
     at the bottom of the card. */
  align-content: start;
  gap: clamp(1.75rem, 1rem + 2.5vw, 3.5rem);
  padding: clamp(1.5rem, 1rem + 2vw, 3rem);
  border-radius: var(--r-2xl);
  /* Near-white with the faintest cool wash top-left and warm wash bottom-right,
     which is what the design's card reads as. Both are under 4% colour, so no
     text on the card changes contrast because of them. */
  background:
    radial-gradient(60% 55% at 0% 100%, rgba(35, 105, 210, .07) 0%, transparent 70%),
    radial-gradient(55% 50% at 100% 0%, rgba(245, 245, 114, .16) 0%, transparent 70%),
    linear-gradient(160deg, #F6F8FC 0%, #FFFFFF 55%, #FBFCF6 100%);
  box-shadow: inset 0 0 0 1px var(--border), var(--e-2);
}

.cs__main { display: flex; flex-direction: column; min-width: 0; }

/* --- Logo + headline ------------------------------------------------------ */

.cs__id {
  --seal-size: clamp(76px, 5.5vw, 104px);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 0.75rem + 1vw, 1.5rem);
  margin-bottom: clamp(1.25rem, 1rem + 1vw, 1.75rem);
}
/* The plate sits on white with a soft ring, which is what gives the design's
   logo its "badge" look without cropping a wordmark into a circle. */
.cs__id .seal {
  flex: none;
  background: var(--white);
  box-shadow: 0 0 0 1px var(--border), var(--e-1);
}

.cs__headline {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 40, 'wdth' 100;
  font-size: clamp(1.3rem, 1.05rem + 0.9vw, 1.75rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--ink-900);
  text-wrap: balance;
  min-width: 0;
}
.cs__client { display: block; margin-bottom: 0.2rem; color: var(--blue-500); }

/* --- Figures -------------------------------------------------------------- */

.cs__metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.6rem, 0.45rem + 0.5vw, 0.9rem);
  margin-bottom: clamp(1rem, 0.8rem + 0.7vw, 1.4rem);
}
.cs__metrics li {
  padding: clamp(1rem, 0.8rem + 0.8vw, 1.4rem) clamp(1rem, 0.8rem + 0.8vw, 1.35rem);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .72);
  box-shadow: inset 0 0 0 1px var(--border-tint);
  transition: box-shadow var(--d-base) var(--ease-out-soft), transform var(--d-base) var(--ease-out-expo);
}
/* An odd count (Racine has three) closes the grid up: the last figure takes
   the full row rather than leaving an empty box beside it. */
.cs__metrics li:last-child:nth-child(odd) { grid-column: 1 / -1; }
.cs__metrics li:hover { box-shadow: inset 0 0 0 1px var(--blue-300), var(--e-1); transform: translateY(-2px); }

.cs__figure {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 96, 'wdth' 100;
  font-size: clamp(1.9rem, 1.45rem + 1.4vw, 2.6rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--blue-500);
}
.cs__figure-word { font-size: 0.72em; }
.cs__figure-label {
  margin-top: 0.6rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-800);
}

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

.cs__quote {
  margin: 0;
  padding: clamp(1.1rem, 0.9rem + 0.8vw, 1.5rem);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .72);
  box-shadow: inset 0 0 0 1px var(--border-tint);
}
.cs__quote blockquote {
  margin: 0;
  font-size: var(--fs-body);
  font-style: italic;
  line-height: 1.65;
  color: var(--ink-800);
  text-wrap: pretty;
}
.cs__quote figcaption {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
}
/* Initials, not a photograph. Nobody's face is invented for this site. */
.cs__avatar {
  width: 40px;
  height: 40px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--blue-100);
  color: var(--blue-700);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.cs__quote-name { display: block; font-size: var(--fs-sm); font-weight: 650; color: var(--ink-900); }
.cs__quote-role { display: block; font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.45; }

/* The quote slot's stand-in on a client with no testimonial: the same card, so
   the slide keeps its shape, but upright and unattributed, because it is a
   result from the source and not a person's words. */
.cs__note {
  margin: 0;
  padding: clamp(1.1rem, 0.9rem + 0.8vw, 1.5rem);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .72);
  box-shadow: inset 0 0 0 1px var(--border-tint);
}
.cs__note--list { display: grid; gap: 0.9rem; }
.cs__note-label {
  margin: 0 0 0.35rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-600);
}
.cs__note-text {
  margin: 0;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ink-800);
  text-wrap: pretty;
}

/* --- Actions -------------------------------------------------------------- */

.cs__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding-top: clamp(1.25rem, 1rem + 1vw, 1.75rem);
}
/* The design's second action is an outline in brand blue, not the grey-ringed
   white secondary used elsewhere. */
.cs .cs__ghost { background: transparent; box-shadow: inset 0 0 0 1.5px var(--blue-500); }
.cs .cs__ghost:hover { background: var(--blue-50); }

/* --- Right column --------------------------------------------------------- */

.cs__aside { display: flex; flex-direction: column; gap: clamp(1.1rem, 0.9rem + 0.8vw, 1.6rem); min-width: 0; }

/* The narrative with a rule beside it, not in a panel. */
.cs__story {
  display: grid;
  gap: 0.7rem;
  padding-left: clamp(1rem, 0.85rem + 0.5vw, 1.35rem);
  border-left: 3px solid var(--blue-200);
}
.cs__story p {
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--text-secondary);
  text-wrap: pretty;
}

/* One fixed shape for every client. The panel used to flex into whatever
   height the story left over, so its shape followed the copy: 1.1 : 1 on
   Lancaster, 2.24 : 1 on Oak Park, whose longer story squeezed the square photo
   into a letterbox and cropped the phone. Fixed, every slide has the same
   picture at the same size. `margin-top: auto` sits it at the foot of the
   column, and slides share one height, so the pictures line up across slides
   too; the story's varying length becomes space above it, not a different
   shape. */
.cs__shot {
  position: relative;
  aspect-ratio: 3 / 3;
  margin-top: auto;
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--e-3);
  background: var(--ink-100);
}
/* The supplied photos are square and the panel is not, so the photo is
   contained, never covered, and a blurred copy of itself fills the sides. The
   photos are shot against an out-of-focus desk already, so the extension reads
   as more of the same scene rather than as bars. */
.cs__shot-fill,
.cs__shot-img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cs__shot-fill { object-fit: cover; filter: blur(22px) saturate(1.05); transform: scale(1.15); }
/* Full panel height at the photo's OWN proportions (`width: auto` on a
   replaced element keeps its intrinsic ratio), centred. Not forced square:
   the owner's photos are not all square (Racine's is portrait), and a forced
   square cropped it top and bottom. Sized to the photo rather than the panel,
   the mask lands on the photo's edges, so it feathers into its blurred copy
   instead of meeting it at a hard line that read as two bars. */
.cs__shot-img {
  left: 50%;
  right: auto;
  width: auto;
  max-width: none;
  translate: -50% 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
}

/* --- The stylised device -------------------------------------------------- */

.cs__shot--device {
  display: grid;
  place-items: center;
  background:
    radial-gradient(70% 60% at 30% 25%, rgba(255, 255, 255, .55) 0%, transparent 70%),
    linear-gradient(145deg, #E7ECF4 0%, #D8DFEA 45%, #CFD6E2 100%);
}
.cs__glow {
  position: absolute;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--cid-soft, rgba(35, 105, 210, .18)) 0%, transparent 70%);
  filter: blur(8px);
}

/* Sized from the panel's HEIGHT and taken out of flow. Sized by width, the
   phone's tall ratio set the panel's height, which set every slide's height:
   the device, not the content, decided how tall the card was. Out of flow, the
   left column's real content sets the card and the phone fills what is left. */
.dev {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  height: min(86%, 30rem);
  max-width: 70%;
  aspect-ratio: 9 / 18.5;
  padding: 0.5rem;
  border-radius: 2rem;
  background: #1B2230;
  box-shadow: 0 30px 60px -22px rgba(16, 24, 40, .55), inset 0 0 0 2px #2C3444;
  transform: rotate(-7deg);
  transition: transform 0.7s var(--ease-out-expo);
}
.csx__slide.is-active .dev { transform: rotate(-4deg) translateY(-4px); }

.dev__notch {
  position: absolute;
  top: 0.85rem;
  left: 50%;
  z-index: 2;
  width: 32%;
  height: 0.9rem;
  transform: translateX(-50%);
  border-radius: 1rem;
  background: #1B2230;
}
.dev__screen {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: 1.55rem;
  background: var(--white);
}
.dev__bar {
  --seal-size: 26px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 1.9rem 0.7rem 0.55rem;
}
.dev__logo .seal { box-shadow: none; padding: 2px; }
.dev__menu { display: grid; gap: 3px; }
.dev__menu i { width: 14px; height: 2px; border-radius: 2px; background: var(--ink-400); }

.dev__hero {
  display: grid;
  align-content: end;
  gap: 0.45rem;
  flex: 1.25;
  margin: 0 0.45rem;
  padding: 0.85rem 0.75rem;
  border-radius: 1rem;
  background:
    linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, .18) 100%),
    var(--cid-ink, var(--blue-600));
  color: #fff;
}
.dev__kind {
  font-size: 0.5rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.9;
}
.dev__title {
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.dev__cta {
  justify-self: start;
  margin-top: 0.15rem;
  padding: 0.28rem 0.65rem;
  border-radius: var(--r-pill);
  background: var(--yellow-300);
  color: var(--ink-900);
  font-size: 0.55rem;
  font-weight: 700;
}
.dev__rows { display: grid; gap: 0.45rem; padding: 0.7rem 0.7rem 1rem; }
.dev__row { display: flex; align-items: center; gap: 0.45rem; }
.dev__row i { width: 22px; height: 22px; flex: none; border-radius: 6px; background: var(--cid-tint, var(--blue-100)); }
.dev__row b { height: 6px; flex: 1; border-radius: 4px; background: var(--ink-100); }
.dev__row:nth-child(2) b { margin-right: 22%; }
.dev__row:nth-child(3) b { margin-right: 38%; }

@media (prefers-reduced-motion: reduce) {
  .dev, .csx__slide.is-active .dev { transition: none; transform: rotate(-5deg); }
  .cs__metrics li, .cs__metrics li:hover { transition: none; transform: none; }
}

/* --- Breakpoints ---------------------------------------------------------- */

@media (min-width: 1000px) {
  /* One row, stretched to the slide's shared height, so each column is as tall
     as the card and the picture's `margin-top: auto` reaches the same foot on
     every slide. `align-content: start` is only right when the card is one
     stacked column. */
  .cs {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    align-content: stretch;
  }
}

/* Square on a phone: at ~300px wide a 4 : 3 panel shows the phone in the
   photo too small to read, and a square photo in a square panel needs no fill. */
@media (max-width: 599px) {
  .cs__shot { aspect-ratio: 1; }
  /* The drawn phone is taller than it is wide, and a square this narrow cut it
     off at the foot. The real photos are square and stay square. */
  .cs__shot--device { aspect-ratio: 4 / 5; }
  .cs__metrics li { padding: 0.9rem 0.85rem; }
  .cs__figure { font-size: 1.75rem; }
  .cs__figure-label { font-size: var(--fs-xs); }
  .cs__id { flex-direction: column; align-items: flex-start; }
  .cs__actions .btn { flex: 1 1 100%; }
  .csx__tabs { margin-inline: 0; width: auto; }
}

@media (max-width: 379px) {
  .cs__metrics { grid-template-columns: minmax(0, 1fr); }
}
