/* ==========================================================================
   Case study page — design tokens
   --------------------------------------------------------------------------
   Scoped to .case-study so nothing here can affect Astra or Elementor pages.
   Values extracted from Figma file "Portfolio", node 2114:22.
   Loaded only on pages using the Case Study template — see functions.php.
   ========================================================================== */

.case-study {

  /* --- Colour ------------------------------------------------------------ */
  --cs-klein:       #002fa7;  /* accent: eyebrows, tags, links, CTA band     */
  --cs-ink:         #0a0a0a;  /* headings                                    */
  --cs-body:        #4b4f58;  /* body text                                   */
  --cs-paper:       #ffffff;  /* default section background                  */
  --cs-warm:        #f7f5f0;  /* alternating section background              */
  --cs-rule:        #e3dfd6;  /* hairlines, card borders                     */

  /* --- Typeface ---------------------------------------------------------- */
  --cs-font: "Atkinson Hyperlegible", system-ui, -apple-system, sans-serif;

  /* --- Type scale -------------------------------------------------------- */
  /* Letter spacing is in em so it stays proportional if sizes change.       */

  --cs-h1-size:      70px;
  --cs-h1-lh:        1.12;
  --cs-h1-ls:        -0.03em;

  --cs-h2-size:      46px;
  --cs-h2-lh:        1.12;
  --cs-h2-ls:        -0.015em;

  --cs-h3-size:      22px;
  --cs-h3-lh:        1.2;
  --cs-h3-ls:        -0.015em;

  --cs-cardtitle-size: 18px;
  --cs-cardtitle-lh:   1.32;
  --cs-cardtitle-ls:   -0.015em;

  --cs-body-size:    19px;
  --cs-body-lh:      1.72;

  --cs-small-size:   16px;
  --cs-small-lh:     1.62;

  --cs-eyebrow-size: 13px;
  --cs-eyebrow-lh:   1.5;
  --cs-eyebrow-ls:   0.13em;

  --cs-caption-size: 14px;
  --cs-caption-lh:   1.5;

  /* --- Layout ------------------------------------------------------------ */
  /* The rest of the site (menu, footer) runs Elementor's "Boxed" content
     width, confirmed at exactly 1200px from the footer's own separator
     line. On very wide screens, content should stop growing at that same
     1200px and center itself, rather than keep spreading out — see the
     .cs-section rule below. */
  --cs-boxed-max:       1200px;
  --cs-page-inline:     122px;  /* left/right page padding                   */
  --cs-section-block:   100px;  /* section top/bottom padding                */
  --cs-banner-top:      120px;
  --cs-banner-bottom:    96px;

  --cs-label-col:       165px;  /* left "eyebrow" column                     */
  --cs-row-gap:          79px;  /* gap between label and body columns        */
  --cs-body-col:        586px;  /* text measure                              */

  --cs-radius-card:      16px;
  --cs-radius-image:      8px;
  --cs-radius-pill:     100px;

  --cs-banner-copy:     708px;  /* banner copy column — wider than the usual body column */
}

/* --- Base ----------------------------------------------------------------- */

.case-study {
  font-family: var(--cs-font);
  color: var(--cs-body);
  /* Astra's own content wrapper is a flex container, which would otherwise
     let a full-bleed child (see .cs-bleed) stretch this box to match its
     width instead of the other way around. */
  width: 100%;
  min-width: 0;
}

.case-study *,
.case-study *::before,
.case-study *::after {
  box-sizing: border-box;
}

/* On the live site, Elementor's own global heading font (Georgia) was
   winning over this page's own — inheritance alone isn't enough once
   something else sets font-family directly on the same element.
   Forcing it on every element in the page settles that regardless of
   what else is set site-wide. */
.case-study,
.case-study * {
  font-family: var(--cs-font) !important;
}

.case-study h1,
.case-study h2,
.case-study h3 {
  color: var(--cs-ink);
  font-weight: 700;
  margin: 0;
}

/* --- Responsive scale -------------------------------------------------------
   Every section is built from the tokens above, so scaling the page down
   for smaller screens is mostly a matter of redefining a handful of them.
   Breakpoints match Astra's own (921px / 544px) so the case study reflows
   at the same points as the rest of the site. */

@media (max-width: 921px) {
  .case-study {
    --cs-page-inline:   40px;
    --cs-section-block: 64px;
    --cs-row-gap:        32px;
    --cs-h1-size:        44px;
    --cs-h2-size:        32px;
  }
}

@media (max-width: 544px) {
  .case-study {
    --cs-page-inline:   20px;
    --cs-section-block: 48px;
    --cs-h1-size:        32px;
    --cs-h2-size:        26px;
  }
}

/* --- Full-bleed sections -----------------------------------------------------
   Astra centres page content inside its own padded container. Every section
   needs its background to run edge-to-edge regardless, so the bleed applies
   to .cs-section and .cs-banner directly rather than needing an extra class
   on each one. .cs-bleed stays available for one-off full-width elements
   (e.g. the closing CTA band). */

.cs-bleed,
.cs-section,
.cs-banner {
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

/* --- Section — Banner ------------------------------------------------------ */

.cs-banner {
  display: flex;
  align-items: center;
  background: var(--cs-paper);
  padding-top: var(--cs-banner-top);
  padding-bottom: var(--cs-banner-bottom);
  /* Same boxed-left rule as .cs-section, so the headline lines up with
     every other section's left edge on wide screens — the hero photo
     stays unconstrained on the right (see the ≥922px override below). */
  padding-left: max(var(--cs-page-inline), calc((100vw - var(--cs-boxed-max)) / 2));
  padding-right: var(--cs-page-inline);
  flex-wrap: wrap;
  gap: 40px;
}

@media (min-width: 922px) {
  .cs-banner {
    /* On desktop the hero image bleeds to the true right edge, so the
       section itself carries no right-hand padding. */
    padding-right: 0;
  }
}

.cs-banner-copy {
  width: 100%;
  max-width: var(--cs-banner-copy);
  flex: 1 1 var(--cs-banner-copy);
}

.cs-banner-hero {
  flex: 1 1 320px;
  height: 464px;
  overflow: hidden;
}

/* Between 922-1189px wide, the copy and the image no longer both fit on
   one line (708 + 320 + 40 gap needs 1068px, and that range only has
   830-1188px to give them) — the image wraps onto a line of its own and,
   uncapped, grows to fill the row's full width instead of staying near
   its intended 610px size. Scoped to just this range: the hero is meant
   to keep growing past its 610px size at genuinely wide screens (it
   bleeds to the true edge by design), so capping it unconditionally
   would have stopped that too. */
@media (min-width: 922px) and (max-width: 1189px) {
  .cs-banner-hero {
    max-width: 610px;
  }
}

@media (max-width: 921px) {
  .cs-banner-hero {
    height: 320px;
    flex-basis: 100%;
  }
}

@media (max-width: 544px) {
  .cs-banner-hero {
    height: 220px;
  }
}

.cs-banner-hero img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cs-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}

.cs-tag {
  border: 1px solid var(--cs-klein);
  border-radius: var(--cs-radius-pill);
  color: var(--cs-klein);
  font-size: var(--cs-caption-size);
  line-height: var(--cs-caption-lh);
  padding: 5px 12px;
}

.cs-h1 {
  font-size: var(--cs-h1-size);
  line-height: var(--cs-h1-lh);
  letter-spacing: var(--cs-h1-ls);
}

.cs-h1 .cs-accent {
  color: var(--cs-klein);
}

.cs-intro {
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
  margin: 22px 0 0;
  max-width: 100%;
}

.cs-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 24px 52px;
  margin: 40px 0 0;
}

.cs-meta-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.cs-meta dt {
  font-size: var(--cs-eyebrow-size);
  line-height: var(--cs-eyebrow-lh);
  letter-spacing: var(--cs-eyebrow-ls);
  font-weight: 700;
  text-transform: uppercase;
}

.cs-meta dd {
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
  margin: 0;
}

/* --- Recurring row pattern --------------------------------------------------
   Most sections below the banner share this shape: a section with alternating
   background, holding one row made of a narrow eyebrow-label column and a
   wider body column. */

.cs-section {
  background: var(--cs-paper);
  padding-top: var(--cs-section-block);
  padding-bottom: var(--cs-section-block);
  /* Below ~1444px wide this is identical to the plain --cs-page-inline
     value (whichever is larger wins); past that, it grows to keep
     content capped at --cs-boxed-max and centered, instead of the
     content column spreading out with a huge gap on the right.
     Uses 100vw rather than 100% deliberately: padding percentages
     resolve against the containing block's width, not this element's
     own (which is only 100vw itself via the full-bleed rule below) —
     with 100% here this silently resolved against Astra's narrower
     wrapper instead of the real viewport. */
  padding-left: max(var(--cs-page-inline), calc((100vw - var(--cs-boxed-max)) / 2));
  padding-right: max(var(--cs-page-inline), calc((100vw - var(--cs-boxed-max)) / 2));
}

.cs-section--warm {
  background: var(--cs-warm);
}

.cs-row {
  display: flex;
  align-items: flex-start;
  gap: var(--cs-row-gap);
}

@media (max-width: 921px) {
  .cs-row {
    flex-direction: column;
  }
}

.cs-row-label {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 0 0 auto;
  width: var(--cs-label-col);
}

@media (max-width: 921px) {
  .cs-row-label {
    width: 100%;
    flex-direction: row;
    align-items: center;
  }
}

.case-study .cs-eyebrow {
  margin: 0;
  color: var(--cs-klein);
  font-size: var(--cs-eyebrow-size);
  line-height: var(--cs-eyebrow-lh);
  letter-spacing: var(--cs-eyebrow-ls);
  font-weight: 700;
  text-transform: uppercase;
}

.cs-rule {
  display: block;
  width: 28px;
  height: 2px;
  background: var(--cs-klein);
  opacity: 0.35;
}

.cs-row-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.cs-row-body p {
  margin: 0;
  max-width: var(--cs-body-col);
  color: var(--cs-body);
  font-size: var(--cs-body-size);
  line-height: var(--cs-body-lh);
}

.cs-row-body p + p {
  margin-top: 16px;
}

.case-study .cs-h2 {
  font-size: var(--cs-h2-size);
  line-height: var(--cs-h2-lh);
  letter-spacing: var(--cs-h2-ls);
  max-width: var(--cs-body-col);
}

/* Sections with more than one row/block stacked vertically (e.g. Context's
   text row + full-width image, followed by the Role & constraints row). */
.cs-section-rows {
  display: flex;
  flex-direction: column;
  gap: 92px;
}

/* --- Section — Context ------------------------------------------------------ */

.cs-context-block {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.cs-figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cs-figure img,
.cs-figure video {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

.cs-context-block .cs-figure img,
.cs-context-block .cs-figure video {
  aspect-ratio: 1196 / 673;
  /* Matches the animated screenshot's own backdrop, so the reserved box
     never flashes plain white while the file is still loading/decoding. */
  background: var(--cs-warm);
}

.cs-figure--faded img {
  /* Confirmed via SVG export: this specific photo (the rough wireframes
     scan) sits at 80% opacity in Figma, softening it slightly. */
  opacity: 0.8;
}

.cs-figure figcaption {
  margin: 0;
  text-align: center;
  font-style: italic;
  color: var(--cs-body);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

.cs-figure figcaption a {
  color: var(--cs-klein);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cs-row-body figure {
  max-width: var(--cs-body-col);
}

/* --- Section — The hard part -------------------------------------------------
   Checked against a Figma SVG export: the checkmark icon and the inset
   canvas image's 342px width were already correct; added its 8px corner
   radius, which was missing. */

.cs-figure--inset img {
  width: 342px;
  max-width: 100%;
  margin: 0 auto;
  border-radius: var(--cs-radius-image);
}

/* --- Role structure animation -------------------------------------------
   Replaces the earlier Lottie export with a hand-built, four-step sequence
   (rows merging, labels appearing, the Volunteer switch flipping) driven by
   plain CSS transitions + a small script below. Matches the same Figma
   keyframes (node 2114:22) the rest of this page's tokens come from. */

.cs-figure--role {
  /* Extra breathing room on top of the .cs-row-body flex gap (18px), so the
     animation reads as its own moment rather than another paragraph. */
  margin-top: 40px;
}

.cs-role-stage {
  width: 367px;
  max-width: 100%;
  margin: 0 auto;
}

.cs-role-card {
  background: var(--cs-paper);
  border: 1px solid var(--cs-rule);
  border-radius: var(--cs-radius-card);
  box-shadow: 0 1px 2px rgba(10, 10, 10, 0.04), 0 16px 40px -24px rgba(10, 10, 10, 0.28);
  padding: 26px 24px 22px;
  display: flex;
  flex-direction: column;
  /* Steps 1-2 need ~480px, steps 3-4 (more rows expanded) need ~533px —
     reserving the taller amount for every step keeps the card's own
     size constant, so content below it never shifts as it steps
     through on its own during autoplay. */
  min-height: 540px;
}

.cs-role-tag {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 6px;
  font-family: var(--cs-font);
  font-size: var(--cs-eyebrow-size);
  font-weight: 700;
  letter-spacing: var(--cs-eyebrow-ls);
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-klein);
  color: var(--cs-klein);
  transition: background-color 0.35s ease, color 0.35s ease;
}
.cs-role-tag[data-tone="accent"] {
  background: var(--cs-klein);
  color: var(--cs-paper);
}
.cs-role-tag::before {
  content: "/";
  opacity: 0.6;
}

.cs-role-rows {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* .cs-role-rows .cs-role-label (not just .cs-role-label): same specificity
   fix as the caption below — out-specifies the page-wide ".cs-row-body p"
   rule (19px) so this matches the 16px row text it labels. */
.cs-role-rows .cs-role-label {
  font-family: var(--cs-font);
  font-style: italic;
  font-weight: 700;
  font-size: var(--cs-small-size);
  color: var(--cs-body);
  padding-left: 2px;
  overflow: hidden;
  max-height: 26px;
  opacity: 1;
  margin-top: 4px;
  transform: translateY(0);
  transition: max-height 0.42s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.3s ease, margin 0.42s ease, transform 0.38s ease;
}
.cs-role-label.cs-role-collapsed {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  transform: translateY(-4px);
}

.cs-role-row {
  background: var(--cs-warm);
  border-radius: var(--cs-radius-image);
  overflow: hidden;
  max-height: 120px;
  opacity: 1;
  transition: max-height 0.42s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.32s ease, margin 0.42s ease, background-color 0.4s ease;
}
.cs-role-row.cs-role-collapsed {
  max-height: 0;
  opacity: 0;
  margin-block: -5px 0;
}
.cs-role-row.cs-role-blue {
  background: rgba(0, 47, 167, 0.08);
}

.cs-role-row-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 17px 16px;
}
.cs-role-row-text {
  font-family: var(--cs-font);
  font-weight: 700;
  font-size: var(--cs-small-size);
  color: var(--cs-ink);
  line-height: 1.35;
  transition: opacity 0.18s ease;
}

.cs-role-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0;
  transform: scale(0.88);
  pointer-events: none;
  transition: opacity 0.32s ease, transform 0.32s ease;
  flex-shrink: 0;
}
.cs-role-toggle.cs-role-visible {
  opacity: 1;
  transform: scale(1);
}
.cs-role-toggle-label {
  font-family: var(--cs-font);
  font-size: var(--cs-caption-size);
  font-weight: 700;
  color: var(--cs-body);
}
.cs-role-switch {
  width: 34px;
  height: 19px;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-rule);
  position: relative;
  transition: background-color 0.38s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cs-role-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--cs-paper);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.38s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cs-role-switch.cs-role-on {
  background: var(--cs-klein);
}
.cs-role-switch.cs-role-on::after {
  transform: translateX(15px);
}

.cs-role-below {
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}
.cs-role-caption-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 367px;
  max-width: 100%;
}
/* Step count reuses .cs-eyebrow (set in the HTML) so it matches the row
   labels — e.g. "Key decisions" — pixel for pixel. Kept to one line: the
   longest combination ("Key decisions · Step 1 of 4") comfortably fits
   367px at this size, so this is a safety net against any future edit. */
.cs-role-step-line {
  white-space: nowrap;
}
/* .cs-role-below .cs-role-caption (not just .cs-role-caption): needs to
   out-specificity the page-wide ".cs-row-body p" rule (19px), since this
   paragraph sits inside a .cs-row-body like everything else in the section.
   min-height is tuned to the longest of the 4 step captions (measured at
   367px wide) so the card below never shifts as the text changes length. */
.cs-role-below .cs-role-caption {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--cs-font);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
  color: var(--cs-body);
  max-width: none;
  min-height: 106px;
  margin: 0;
  transition: opacity 0.18s ease;
}
.cs-role-controls {
  display: flex;
  align-items: center;
  gap: 18px;
}

@media (prefers-reduced-motion: reduce) {
  .cs-role-label,
  .cs-role-row,
  .cs-role-toggle,
  .cs-role-switch,
  .cs-role-switch::after,
  .cs-role-tag,
  .cs-role-caption {
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 420px) {
  .cs-role-card {
    min-height: 0;
    padding: 22px 18px 20px;
  }
}

/* --- Icon button + tooltip --------------------------------------------------
   A round icon-only button with an accessible name (aria-label, kept in sync
   with state) and a visible tooltip for sighted users, on hover or keyboard
   focus. The tooltip text is hidden from assistive tech (aria-hidden) since
   the button's own aria-label already announces the same thing. */

.cs-icon-button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px !important;
  height: 36px !important;
  padding: 0 !important;
  border: 1px solid var(--cs-klein);
  /* !important: Astra's global button style (Appearance > Customize >
     Buttons) was squaring these off on the live site. */
  border-radius: 50% !important;
  background: var(--cs-paper);
  color: var(--cs-klein);
  cursor: pointer;
}

.cs-icon-button:hover,
.cs-icon-button:focus-visible {
  background: var(--cs-klein);
  color: var(--cs-paper);
}

.cs-tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  background: var(--cs-ink);
  color: var(--cs-paper);
  font-family: var(--cs-font);
  font-size: var(--cs-caption-size);
  line-height: var(--cs-caption-lh);
  padding: 4px 10px;
  border-radius: 4px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.cs-icon-button:hover .cs-tooltip,
.cs-icon-button:focus-visible .cs-tooltip {
  opacity: 1;
}

.cs-todo {
  border: 1px dashed var(--cs-rule);
  color: var(--cs-body);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
  font-style: italic;
  padding: 20px;
}

.cs-todo--media {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  text-align: center;
  background: var(--cs-warm);
}

/* --- Section — Discovery ----------------------------------------------------- */

.cs-discovery-cols {
  display: flex;
  align-items: center;
  gap: 24px;
  width: 100%;
}

.cs-findings {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 0 0 342px;
  width: 342px;
  border-top: 1px solid var(--cs-rule);
}

.cs-findings li {
  border-bottom: 1px solid var(--cs-rule);
  padding: 20px 0;
}

.cs-findings h3 {
  margin: 0 0 2px;
  font-size: var(--cs-cardtitle-size);
  line-height: var(--cs-cardtitle-lh);
  letter-spacing: var(--cs-cardtitle-ls);
}

.cs-findings p {
  margin: 0;
  color: var(--cs-body);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

.cs-discovery-image {
  flex: 1 1 320px;
  align-self: stretch;
  overflow: hidden;
}

/* This stacks well above the general 921px row breakpoint on purpose:
   the findings list keeps a fixed 342px width, so as the row narrows
   the image is squeezed into whatever's left over — by ~1100px wide
   it was down to ~248px, badly cropped. 1200px leaves it a reasonable
   minimum width before that happens. Below the general row breakpoint
   this was also the fix for an earlier bug where the image collapsed
   to zero width entirely. */
@media (max-width: 1200px) {
  .cs-discovery-cols {
    flex-direction: column;
    align-items: stretch;
  }

  .cs-findings {
    flex: 1 1 auto;
    width: 100%;
  }

  .cs-discovery-image {
    flex: 1 1 auto;
    align-self: stretch;
    aspect-ratio: 587 / 509;
  }
}

.cs-discovery-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- Section — In one minute ------------------------------------------------ */

/* auto-fit with a fixed card size, rather than a viewport breakpoint,
   because the row it sits in isn't a fixed fraction of the viewport —
   it's already narrowed by the label column beside it, so a plain
   "@media (max-width: 1100px)" was switching to 2 columns far too
   late: at 1102px wide there was only 614px of actual room, well
   short of the 828px three fixed 268px columns need, so the third
   card was overflowing off the page. This just fits as many 268px
   columns as actually have room, at any width, automatically. */
.cs-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, 268px);
  gap: 12px;
  margin-bottom: 26px;
}

.cs-card {
  background: var(--cs-paper);
  padding: 26px 26px 28px;
}

.cs-card p {
  margin: 10px 0 0;
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

.cs-constraint {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 26px;
}

.cs-live-sign {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: var(--cs-radius-pill);
  padding: 8px 24px 8px 16px;
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
  white-space: nowrap;
}

.cs-live-sign-icon {
  flex: 0 0 auto;
  display: block;
  width: 18px;
  height: 18px;
}

/* Sonar-style pulse on the middle ring, like a typical "live" status dot —
   the ring expands and fades while the solid centre dot stays put. */
.cs-live-pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: cs-live-pulse 2s ease-out infinite;
}

@keyframes cs-live-pulse {
  0% {
    transform: scale(1);
    opacity: 0.35;
  }
  70% {
    transform: scale(1.7);
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cs-live-pulse {
    animation: none;
  }
}

.cs-constraint-text {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

.case-study .cs-h3 {
  font-size: var(--cs-h3-size);
  line-height: var(--cs-h3-lh);
  letter-spacing: var(--cs-h3-ls);
}

/* --- Section — Principles: full-width carousel --------------------------------
   Each card is a translucent white box (confirmed via SVG export: 16px
   corner radius, ~26px/38px/28px padding). The row itself is a deliberate
   departure from the Figma frame: it runs edge-to-edge and scrolls, rather
   than wrapping onto multiple lines, so a card can sit partly cut off at
   the edge as a cue that there's more to see. All cards stay in the page
   at once — scrolling only changes what's in view, nothing is removed from
   the accessibility tree, so a screen reader reads every card regardless
   of scroll position. Movement for sighted keyboard/mouse users is via the
   two arrow buttons above the row; native trackpad/touch scrolling still
   works too since the track is a plain scroll container. */

.cs-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.cs-principles-carousel {
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

.cs-carousel-controls {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 var(--cs-page-inline) 16px;
}

.cs-carousel-arrow {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 36px !important;
  height: 36px !important;
  padding: 0 !important;
  border: 1px solid var(--cs-klein);
  /* !important: Astra's global button style (Appearance > Customize >
     Buttons) was squaring these off on the live site. */
  border-radius: 50% !important;
  background: var(--cs-paper);
  color: var(--cs-klein);
  cursor: pointer;
}

.cs-carousel-arrow:hover:not(:disabled),
.cs-carousel-arrow:focus-visible {
  background: var(--cs-klein);
  color: var(--cs-paper);
}

.cs-carousel-arrow:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.cs-principles {
  list-style: none;
  margin: 0;
  padding-left: var(--cs-page-inline);
  padding-right: 0;
  padding-top: 0;
  padding-bottom: 0;
  display: flex;
  gap: 14px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.cs-principles::-webkit-scrollbar {
  display: none;
}

.cs-principle {
  flex: 0 0 264px;
  text-align: left;
  background: rgba(255, 255, 255, 0.8);
  border-radius: var(--cs-radius-card);
  padding: 26px 38px 28px;
}

.cs-principle img {
  display: block;
  height: 126px;
  width: auto;
  max-width: 100%;
  margin: 0 0 16px;
}

.cs-principle h3 {
  font-size: var(--cs-cardtitle-size);
  line-height: var(--cs-cardtitle-lh);
  letter-spacing: var(--cs-cardtitle-ls);
  margin: 0 0 8px;
}

.cs-principle p {
  margin: 0;
  color: var(--cs-body);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

/* --- Section — Prioritisation ------------------------------------------------- */

.cs-tiers {
  margin: 40px 0 0;
  border-top: 1px solid var(--cs-rule);
}

.cs-tier {
  display: flex;
  gap: 24px;
  border-bottom: 1px solid var(--cs-rule);
  padding: 20px 0;
}

.cs-tier dt {
  flex: 0 0 150px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--cs-ink);
}

.cs-tier dd {
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}

/* A fixed 150px label leaves very little room for the list beside it once
   the row itself has shrunk to phone width — stack them instead. */
@media (max-width: 544px) {
  .cs-tier {
    flex-direction: column;
    gap: 6px;
  }

  .cs-tier dt {
    flex: 0 0 auto;
  }
}

.cs-tier ul {
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--cs-body);
}

/* --- Section — Outcome ---------------------------------------------------------
   Confirmed via SVG export: each item is a bordered white card (hairline
   border, ~16px corner radius), and both the numeral and title are klein
   blue — not the light "ghost number" grey this was built with. */

.cs-outcome-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--cs-body-col);
}

.cs-outcome-cards li {
  display: flex;
  align-items: center;
  gap: 24px;
  background: var(--cs-paper);
  border: 1px solid var(--cs-rule);
  border-radius: var(--cs-radius-card);
  padding: 24px 32px;
}

.cs-outcome-cards li:not(:last-child) {
  margin-bottom: 15px;
}

.cs-outcome-number {
  flex: 0 0 auto;
  font-size: var(--cs-h1-size);
  font-weight: 700;
  line-height: 1;
  color: var(--cs-klein);
}

.cs-outcome-cards h3 {
  margin: 0 0 4px;
  color: var(--cs-klein);
  font-size: var(--cs-cardtitle-size);
  line-height: var(--cs-cardtitle-lh);
  letter-spacing: var(--cs-cardtitle-ls);
}

.cs-outcome-cards p {
  margin: 0;
  color: var(--cs-body);
  font-size: var(--cs-small-size);
  line-height: var(--cs-small-lh);
}

/* --- Section — Reflection: reuses .cs-findings, full width (no side image) --- */

.cs-findings--full {
  width: 100%;
  flex: none;
  max-width: var(--cs-body-col);
}

/* --- Section — What's next (closing CTA band) --------------------------------- */

.cs-cta {
  background: var(--cs-klein);
  color: var(--cs-paper);
  text-align: left;
}

.cs-cta h2 {
  color: var(--cs-paper);
  font-size: var(--cs-h2-size);
  line-height: var(--cs-h2-lh);
  letter-spacing: var(--cs-h2-ls);
  margin: 0 0 16px;
}

.cs-cta p {
  margin: 0;
  max-width: 700px;
  font-size: var(--cs-body-size);
  line-height: var(--cs-body-lh);
}

.cs-cta a {
  color: var(--cs-paper);
  text-decoration: underline;
}

/* --- Focus indicator -----------------------------------------------------
   A visible klein-blue outline on every interactive element in this page,
   shown for keyboard focus. The closing CTA link is the one exception: it
   sits on a klein-blue background itself, so a klein outline there would
   be invisible — it gets a white one instead, on the same background. */

.case-study a:focus-visible,
.case-study button:focus-visible {
  outline: 2px solid var(--cs-klein);
  outline-offset: 2px;
}

.cs-cta a:focus-visible {
  outline-color: var(--cs-paper);
}

/* Section styles are added here as each part of the page is built. */
