:root {
  --ink: #000;
  --ink-70: rgba(0, 0, 0, 0.7);
  --ink-40: rgba(0, 0, 0, 0.4);
  --bg: #fafafa;
  --font-sans: 'Lunchtype22', 'Helvetica Neue', Arial, sans-serif;
  --font-display: 'Bodoni Moda SC', 'Times New Roman', serif;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  overflow-x: hidden;
}

img {
  display: block;
  max-width: 100%;
}

/* Identical to the homepage nav (same markup, same rules, copied verbatim
   including the progressive-blur hover effect) so it reads as the same
   piece of UI, just fixed here instead of positioned within the home
   page's canvas — "sticky" per the ask means it stays put as this page's
   own content scrolls under it, which position:fixed gives directly. */
/* Bottom-left, 24px in from both edges, where the homepage has it. */
.nav {
  position: fixed;
  left: 24px;
  bottom: 24px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-family: var(--font-sans);
  font-weight: 800;
  text-transform: lowercase;
  z-index: 70;
}

.nav-link {
  position: relative;
  display: inline-block;
  color: var(--ink-70);
  text-decoration: none;
  font-size: 18px;
  line-height: 1;
  opacity: 0.4;
  transition: opacity 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
  .nav-link:hover {
    opacity: 0.7;
  }
}

.nav-link.active {
  font-size: 20px;
  line-height: 0.9;
  opacity: 1;
}

.nav-link::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: inherit;
  filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  mask-image: linear-gradient(to bottom, black 0%, black 10%, transparent 10%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 10%, transparent 10%);
}

.nav-link.active::before {
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  .nav-link:hover::before {
    opacity: 1;
  }
}

.nav-link .txt {
  position: relative;
  display: inline-block;
}

/* Table of contents: fixed at the top of the left column (the nav is at
   the bottom) — a page-local nav for jumping between this case study's
   own sections, with the current one highlighted as you scroll (see the
   IntersectionObserver in case-study.html). A back arrow sits above it. */
.cs-toc {
  position: fixed;
  left: 24px;
  top: 24px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 160px;
}

/* Soft blur across the bottom edge of the viewport, the same kind as on
   the homepage's peeking images: one 8px blur that fades in smoothly
   toward the edge (a gradient mask), rather than stacked bands of
   increasing strength, which left faint lines between the steps. It sits
   under the nav (z-index 70 above), so the links stay sharp. */
.cs-bottom-blur {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 96px;
  pointer-events: none;
  z-index: 60;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 20%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, #000 20%, transparent 100%);
}

.cs-bottom-blur span {
  display: none;
}

/* Back arrow: to the page you came from (transition.js points it at the
   referrer when that's this site), otherwise the homepage's work. */
.cs-back {
  display: inline-flex;
  align-self: flex-start;
  margin: -4px 0 20px -4px;
  padding: 4px;
  color: var(--ink);
  transition: transform 0.2s ease, color 0.2s ease;
}

.cs-back svg {
  display: block;
}

@media (hover: hover) and (pointer: fine) {
  .cs-back:hover {
    transform: translateX(-3px);
  }
}

.cs-toc-link {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 16px;
  line-height: 1.3;
  color: var(--ink-40);
  text-decoration: none;
  transition: color 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
  .cs-toc-link:hover {
    color: var(--ink-70);
  }
}

.cs-toc-link.active {
  color: var(--ink);
}

/* The case study column starts 40px past the wider of .nav and .cs-toc's
   own right edges (the TOC's longer labels, like "The approach", are what
   actually sets this — .nav alone is narrower). Left-aligned throughout —
   nothing in this column centers itself, unlike a typical narrow-measure
   article layout, per the brief. */
.cs-content {
  margin-left: 232px;
  padding-right: 56px;
}

/* Editorial hero: oversized serif title, generous margins, a short dek —
   the proportions a design case study needs room to breathe, not the
   dense fixed-canvas layout of the homepage. */
.cs-hero {
  max-width: 780px;
  padding: 96px 0 64px;
}

.cs-eyebrow {
  margin: 0 0 20px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-40);
}

.cs-title {
  margin: 0 0 24px;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.cs-dek {
  margin: 0;
  max-width: 640px;
  font-size: 20px;
  line-height: 1.5;
  color: var(--ink-70);
}

/* max-width matches .cs-hero's own (780px) since this now sits after the
   hero media as its own element rather than nested inside .cs-hero — it
   needs to carry that constraint itself instead of inheriting it. */
.cs-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px 24px;
  max-width: 900px;
  margin: 56px 0;
}

.cs-meta-label {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-40);
}

.cs-meta-value {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  font-weight: 500;
  color: var(--ink-70);
}

/* Big images: the whole point of an editorial case study layout — let the
   work itself take up real space instead of being squeezed into a grid. */
.cs-media {
  max-width: 1260px;
  margin: 0;
}

.cs-media img,
.cs-media video {
  width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
}

.cs-media--hero,
.cs-media--wide {
  margin-bottom: 8px;
}

.cs-media--hero img,
.cs-media--wide img,
.cs-media--hero video,
.cs-media--wide video {
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.cs-media-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  max-width: 1260px;
  margin: 0 0 8px;
}

.cs-media-grid .cs-media {
  max-width: none;
}

.cs-media-grid img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.cs-media-caption {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--ink-40);
  text-align: center;
}

.cs-carousel {
  position: relative;
  margin: 40px 0 64px;
}

.cs-carousel-viewport {
  overflow: visible;
}

.cs-carousel-track {
  display: flex;
  gap: 20px;
  transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.cs-carousel-slide {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
  filter: blur(3px);
  transform: scale(0.7);
  transition: filter 1.1s cubic-bezier(0.22, 1, 0.36, 1), transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.cs-carousel-slide.is-active {
  filter: blur(0);
  transform: scale(1);
}

.cs-carousel-slide img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.08);
}

.cs-carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.1);
  background: #fff;
  color: var(--ink);
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

@media (hover: hover) and (pointer: fine) {
  .cs-carousel-arrow:hover {
    background: #f4f4f5;
  }
}

.cs-carousel-arrow svg {
  width: 20px;
  height: 20px;
}

.cs-carousel-prev {
  left: -64px;
}

.cs-carousel-next {
  right: -64px;
}

.cs-carousel-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
}

.cs-carousel-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: none;
  padding: 0;
  background: rgba(0, 0, 0, 0.15);
  cursor: pointer;
}

.cs-carousel-dot.is-active {
  background: var(--ink);
}

.cs-bar-chart {
  margin: 40px 0 8px;
}

.cs-bar-chart-bars {
  display: flex;
  align-items: flex-end;
  gap: 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}

.cs-bar {
  width: 160px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  padding: 24px 20px;
  border-radius: 4px 4px 0 0;
}

.cs-bar--before {
  background: rgba(214, 88, 88, 0.16);
}

.cs-bar--after {
  background: rgba(88, 168, 108, 0.16);
}

.cs-bar-value {
  display: block;
  font-family: var(--font-serif, var(--font-sans));
  font-size: 44px;
  font-weight: 700;
  line-height: 1;
  margin-bottom: 8px;
}

.cs-bar--before .cs-bar-value {
  color: #b5453f;
}

.cs-bar--after .cs-bar-value {
  color: #3f8a54;
}

.cs-bar-caption {
  display: block;
  font-size: 13px;
  font-weight: 600;
}

.cs-bar--before .cs-bar-caption {
  color: #b5453f;
}

.cs-bar--after .cs-bar-caption {
  color: #3f8a54;
}

.cs-bar-chart-labels {
  display: flex;
  gap: 24px;
  margin-top: 12px;
}

.cs-bar-chart-labels span {
  width: 160px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}

.cs-workflow-card {
  background: #f4f4f5;
  border-radius: 8px;
  padding: 32px 16px 0;
}

.cs-workflow-card img {
  border-radius: 4px;
}

.cs-workflow-label {
  font-size: 17px;
  font-weight: 700;
  margin: 0 0 44px;
}

/* A video (or image) centered in a white stage, surrounded by four
   red annotation callouts at fixed corner positions with dashed
   connector lines pointing back to the stage's edge — matches the
   reference site's "problem" annotation composition. Percentage-based
   so it scales with the column width instead of a fixed pixel canvas. */
.cs-annotated-frame {
  max-width: 1200px;
  margin: 40px auto 64px;
  background: #fff;
  border-radius: 12px;
}

.cs-annotated-frame__stage {
  position: relative;
  padding-bottom: 62%;
}

.cs-annotated-frame__video {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 22%;
  min-width: 220px;
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
}

.cs-callout {
  position: absolute;
  margin: 0;
  max-width: 220px;
  padding: 12px 18px;
  background: #fdecec;
  border: 1px solid #eba7a7;
  border-radius: 8px;
  color: #c23b3b;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
}

.cs-callout--tl {
  top: 16%;
  left: 4%;
}

.cs-callout--tr {
  top: 18%;
  right: 4%;
  text-align: right;
}

.cs-callout--bl {
  top: 52%;
  left: 8%;
}

.cs-callout--br {
  top: 58%;
  right: 6%;
  text-align: right;
}

.cs-callout-line {
  position: absolute;
  border: none;
  border-top: 1px dashed #eba7a7;
}

.cs-callout-line--tl {
  top: 22%;
  left: 17%;
  width: 21%;
}

.cs-callout-line--tr {
  top: 24%;
  right: 17%;
  width: 21%;
}

.cs-callout-line--bl {
  top: 58%;
  left: 21%;
  width: 12%;
}

.cs-callout-line--br {
  top: 64%;
  right: 19%;
  width: 12%;
}

@media (max-width: 780px) {
  .cs-annotated-frame__stage {
    padding-bottom: 130%;
  }

  .cs-annotated-frame__video {
    width: 60%;
    top: 32%;
  }

  .cs-callout {
    position: static;
    max-width: none;
    margin: 12px 16px;
    text-align: left !important;
  }

  .cs-callout-line {
    display: none;
  }
}

.cs-edge-case img {
  display: block;
  width: 56px;
  height: 56px;
  object-fit: contain;
  margin-bottom: 12px;
}

/* A small screenshot dropped inline as evidence rather than a full-bleed
   hero &mdash; used for real artifacts like a reference spreadsheet. */
.cs-media--inline {
  max-width: 640px;
  margin: 40px auto;
}

.cs-media--inline img {
  width: 100%;
  height: auto;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  display: block;
}

/* Text sections: one column, full measure — a short uppercase label, a
   bold editorial sub-headline, then body paragraphs, all stacked. */
.cs-section {
  max-width: 640px;
  margin: 0;
  padding: 96px 0;
  /* Leaves breathing room above the section when a TOC click scrolls it
     to the very top of the viewport, instead of landing flush against
     the edge. */
  scroll-margin-top: 48px;
}

/* Selector is `.cs-section .cs-label` (not plain `.cs-label`) on purpose:
   `.cs-section p` outranks a single class on specificity, so a plain
   `.cs-label` rule silently lost its own color/margin to it despite
   looking like it applied (font-weight/uppercase/letter-spacing don't
   conflict, so those came through, masking the bug). */
.cs-section .cs-label {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.28);
}

.cs-section-head {
  margin: 0 0 28px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 28px;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.cs-section p {
  margin: 0 0 24px;
  font-size: 18px;
  line-height: 1.7;
  color: var(--ink-70);
}

.cs-section p:last-child {
  margin-bottom: 0;
}

/* A single emphasized callout line (e.g. a "How might we" prompt) —
   reuses the section's own type scale, just bolder and indented with a
   rule to read as a pull-quote rather than body copy. */
.cs-hmw {
  margin: 32px 0 0;
  padding-left: 20px;
  border-left: 2px solid var(--ink-40);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--ink);
}

/* A labeled list (e.g. one entry per interviewed role, or per problem
   found) — same type scale as body copy, just broken into discrete
   items with a bold lead-in instead of one running paragraph. */
.cs-list {
  margin: 0 0 24px;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.cs-list:last-child {
  margin-bottom: 0;
}

.cs-list li {
  font-size: 18px;
  line-height: 1.7;
  color: var(--ink-70);
}

.cs-list strong {
  color: var(--ink);
  font-weight: 600;
}

/* Plain items with no bold lead-in (e.g. a set of questions) need a
   visible dot so they read as a list rather than loose lines. */
.cs-list--bullets {
  gap: 10px;
}

.cs-list--bullets li {
  position: relative;
  padding-left: 22px;
}

.cs-list--bullets li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 0.78em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}

/* Big serif stat numerals, echoing the homepage's numeral treatment
   without the brush-stroke filter — this page is calmer/editorial. */
.cs-stats {
  max-width: 980px;
  margin: 0;
  padding: 64px 0 128px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 40px;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
}

.cs-stat-num {
  margin: 0 0 12px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(36px, 5vw, 56px);
  line-height: 1;
  color: var(--ink-70);
}

.cs-stat-caption {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-70);
  max-width: 220px;
}

.cs-footer {
  max-width: 780px;
  margin: 0;
  padding: 64px 0 128px;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
}

.cs-footer-label {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-40);
}

.cs-footer-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: clamp(28px, 4vw, 40px);
  color: var(--ink);
  text-decoration: none;
}

/* Over the next-project link (transition.js), a small card with that
   project's homepage picture follows the pointer, in place of an
   underline. Mouse only. */
.cs-next-preview {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  width: 220px;
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 6px;
  background: #FFFFFF;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.14);
  pointer-events: none;
  opacity: 0;
  scale: 0.94;
  transition: opacity 0.25s ease, scale 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.cs-next-preview img {
  display: block;
  width: 100%;
  aspect-ratio: 676 / 446;   /* the homepage card's shape */
  object-fit: cover;
}

.cs-next-preview.is-on {
  opacity: 1;
  scale: 1;
}

@media (max-width: 780px) {
  /* No room for a fixed sidebar TOC alongside content at this width. */
  .cs-toc {
    display: none;
  }

  .cs-content {
    margin-left: 24px;
    padding-right: 24px;
    padding-top: 96px;
  }

  .cs-hero {
    padding: 0 0 48px;
  }

  .cs-meta {
    grid-template-columns: repeat(2, 1fr);
  }

  .cs-media-grid {
    grid-template-columns: 1fr;
  }

  .cs-stats {
    grid-template-columns: 1fr;
  }

  .cs-diagram-cols,
  .cs-edge-cases {
    grid-template-columns: 1fr;
  }
}

/* ---- Editorial "scene" components for the Widget Builder case study ----
   A giant thesis statement, an old-workflow arrow chain, a three-column
   system diagram, a step-by-step widget assembly, a grid of edge cases,
   and a small component tree — all built from the same tokens as the
   rest of the page (no new colors/fonts), since the point is pacing
   (whitespace → artifact → text → diagram) rather than a new visual
   language. */

.cs-thesis {
  max-width: 760px;
  margin: 0 0 24px;
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.cs-flow {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  max-width: 520px;
  margin: 48px auto;
}

.cs-flow-step {
  width: 100%;
  padding: 14px 20px;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 6px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-70);
  text-align: center;
}

.cs-flow-arrow {
  padding: 8px 0;
  color: var(--ink-40);
  font-size: 16px;
  line-height: 1;
}

.cs-diagram {
  margin: 48px 0;
  padding: 40px 32px;
  background: #f4f4f5;
  border-radius: 8px;
}

.cs-diagram-title {
  text-align: center;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-40);
  margin: 0 0 32px;
}

.cs-diagram-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}

.cs-diagram-col-head {
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-70);
  text-align: center;
  margin: 0 0 14px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--ink-40);
}

.cs-diagram-col-items {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: center;
}

.cs-diagram-col-items span {
  font-size: 14px;
  color: var(--ink-70);
}

.cs-widget-steps {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  margin: 48px 0;
}

.cs-widget-step {
  width: 100%;
  max-width: 460px;
  padding: 20px 24px;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 6px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
}

.cs-widget-step-num {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-40);
}

.cs-widget-step-title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
}

.cs-widget-step-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cs-widget-step-tags span {
  font-size: 12px;
  padding: 5px 12px;
  background: #f4f4f5;
  border-radius: 100px;
  color: var(--ink-70);
}

.cs-widget-final {
  width: 100%;
  max-width: 460px;
  margin-top: 4px;
  padding: 24px;
  background: var(--ink);
  color: #fff;
  border-radius: 6px;
  text-align: center;
  font-weight: 600;
  font-size: 16px;
}

.cs-edge-cases {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 32px 0;
}

.cs-edge-case {
  padding: 20px;
  background: #f4f4f5;
  border-radius: 6px;
}

.cs-edge-case strong {
  display: block;
  color: var(--ink);
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 6px;
}

.cs-edge-case span {
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-70);
}

.cs-anatomy {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 380px;
  margin: 32px auto;
}

.cs-anatomy div {
  padding: 12px 16px;
  background: #f4f4f5;
  border: 1px dashed rgba(0, 0, 0, 0.18);
  border-radius: 4px;
  font-size: 13px;
  color: var(--ink-70);
  text-align: center;
}

.cs-tree {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  margin: 32px 0;
}

.cs-tree-root {
  padding: 12px 24px;
  background: var(--ink);
  color: #fff;
  border-radius: 4px;
  font-weight: 500;
  font-size: 14px;
}

.cs-tree-children {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.cs-tree-children span {
  padding: 8px 16px;
  background: #f4f4f5;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  font-size: 13px;
  color: var(--ink-70);
}

/* A small WhatsApp-style chat mock used on the Kurti Video Agent case
   study to illustrate its input/output without claiming to be a real
   product screenshot. */
.cs-chat-mock {
  max-width: 420px;
  margin: 48px auto;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}

.cs-chat-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  background: #f4f4f5;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.cs-chat-avatar {
  width: 32px;
  height: 32px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
}

.cs-chat-name {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.cs-chat-status {
  margin: 0;
  font-size: 11px;
  color: var(--ink-40);
}

.cs-chat-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px 18px;
  background: #efeae2;
}

.cs-chat-bubble {
  max-width: 82%;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
}

.cs-chat-bubble--in {
  align-self: flex-start;
  background: #fff;
  color: var(--ink-70);
}

.cs-chat-bubble--out {
  align-self: flex-end;
  background: #d9fdd3;
  color: var(--ink);
}

/* A video in the place of a grey stand-in: the same width and spacing. */
.cs-media--video {
  max-width: 900px;
  margin: 24px 0;
}

/* The hero video at the top: as wide as the old hero picture. */
.cs-media--video.cs-media--hero-video {
  max-width: 1170px;
  margin: 0 0 8px;
}

/* The same thin frame as the embedded prototype. */
.cs-media--video video,
.cs-media--video img {
  box-sizing: border-box;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

/* An interactive prototype in a fixed-height frame (its edit panel
   scrolls inside). */
.cs-prototype {
  position: relative;
  max-width: 900px;
  margin: 24px 0;
}

/* "It's clickable": the first time the prototype scrolls into view a hand
   taps one of its controls twice, with a ripple, then fades away
   (case-study-widget-builder.html places it). */
.cs-tap-hint {
  position: absolute;
  z-index: 2;
  width: 40px;
  height: 40px;
  margin: -4px 0 0 -16px;   /* puts the fingertip on the point */
  pointer-events: none;
  opacity: 0;
}

.cs-tap-hint.is-on {
  animation: tap-hint-fade 3.6s ease forwards;
}

.cs-tap-hint svg {
  display: block;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
  transform-origin: 40% 10%;
}

.cs-tap-hint.is-on svg {
  animation: tap-hint-press 1.2s ease-in-out 0.4s 2;
}

.cs-tap-hint::before {
  content: '';
  position: absolute;
  left: 16px;
  top: 4px;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  background: rgba(37, 99, 235, 0.35);
  transform: scale(0);
  opacity: 0;
}

.cs-tap-hint.is-on::before {
  animation: tap-hint-ripple 1.2s ease-out 0.4s 2;
}

@keyframes tap-hint-fade {
  0% { opacity: 0; transform: translate(14px, 14px); }
  10% { opacity: 1; transform: translate(0, 0); }
  85% { opacity: 1; transform: translate(0, 0); }
  100% { opacity: 0; transform: translate(0, 0); }
}

@keyframes tap-hint-press {
  0%, 30%, 70%, 100% { transform: scale(1); }
  45%, 55% { transform: scale(0.82); }
}

@keyframes tap-hint-ripple {
  0%, 40% { transform: scale(0); opacity: 0; }
  50% { transform: scale(0.3); opacity: 1; }
  100% { transform: scale(1.4); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cs-tap-hint.is-on svg,
  .cs-tap-hint.is-on::before {
    animation: none;
  }
}

/* The prototype sits in a browser window: a light top bar with the
   traffic lights. (Not
   positioned, so the tap hint still measures the frame from the figure.) */
.cs-browser {
  overflow: hidden;
  border-radius: 12px;
  background: #FFFFFF;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 14px 32px -12px rgba(0, 0, 0, 0.18);
}

.cs-browser-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 36px;
  padding: 0 14px;
  background: #E6E6E8;
}

.cs-browser-lights {
  display: flex;
  gap: 7px;
  margin-right: 8px;
}

.cs-browser-lights i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #EB4A5A;
}

.cs-browser-lights i:nth-child(2) { background: #F2B12B; }
.cs-browser-lights i:nth-child(3) { background: #2BAA73; }

.cs-prototype iframe {
  display: block;
  width: 100%;
  height: 560px;
  border: 0;
  background: #F3F4F8;
}

/* Before/after slider: the two screenshots stacked in one frame; the
   "before" one on top is clipped at the line (--pos), so dragging the
   line wipes between them. A full-size, invisible range input takes the
   drag and the arrow keys. */
.cs-compare {
  max-width: 900px;
  margin: 24px 0;
}

.cs-compare-frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 5863 / 3028;
  user-select: none;
  touch-action: pan-y;
  cursor: ew-resize;
}

.cs-media .cs-compare-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  pointer-events: none;
}

.cs-compare-before {
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}

.cs-compare-tag {
  position: absolute;
  top: 12px;
  z-index: 2;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(17, 24, 39, 0.72);
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1;
  color: #FFFFFF;
  pointer-events: none;
}

.cs-compare-tag--before { left: 12px; }
.cs-compare-tag--after { right: 12px; }

.cs-compare-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  z-index: 3;
  width: 2px;
  margin-left: -1px;
  background: #FFFFFF;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 0 12px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}

.cs-compare-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  transform: translate(-50%, -50%);
}

.cs-compare-knob svg {
  fill: none;
  stroke: #1F2937;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cs-compare-range {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  pointer-events: none;   /* dragging is the frame's (pointer events); this takes the arrow keys */
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}

.cs-compare-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 2px;
  height: 100%;
}

.cs-compare-range::-moz-range-thumb {
  width: 2px;
  height: 100%;
  border: 0;
}

.cs-compare-frame:has(.cs-compare-range:focus-visible) .cs-compare-knob {
  outline: 2px solid #2563EB;
  outline-offset: 2px;
}

/* The drag hint: a hand on the knob that follows the line as it moves. */
.cs-drag-hint {
  position: absolute;
  top: 50%;
  left: var(--pos);
  z-index: 5;
  width: 40px;
  height: 40px;
  margin: 6px 0 0 -14px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.cs-drag-hint svg {
  display: block;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

.cs-drag-hint.is-on {
  opacity: 1;
}

/* Grey stand-ins for images and videos still to come (sized to the
   Figma frames by an inline aspect-ratio). --split shows a before/after
   pair with a divider down the middle. */
.cs-placeholder {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 900px;
  margin: 24px 0;
  border-radius: 4px;
  background: #d9d9d9;
}

.cs-placeholder span {
  position: relative;
  z-index: 1;
  padding: 4px 8px;
  background: #d9d9d9;
  font-size: 14px;
  color: var(--ink-70);
}

.cs-placeholder--hero {
  max-width: 1170px;
  margin: 0 0 8px;
}

.cs-placeholder--split::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: 1px solid rgba(0, 0, 0, 0.45);
}

/* A text block that follows straight on from a picture, without the full
   section padding above it. */
.cs-section--tight {
  padding: 40px 0;
}

.cs-subhead {
  margin: 48px 0 16px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 22px;
  line-height: 1.35;
  color: var(--ink);
}

.cs-section--tight > .cs-subhead:first-child {
  margin-top: 24px;
}

.cs-minorhead {
  margin: 36px 0 8px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.4;
  color: var(--ink);
}

.cs-section--tight > .cs-minorhead:first-child {
  margin-top: 0;
}

.cs-section p.cs-note {
  font-size: 15px;
  color: var(--ink-40);
}

.cs-list--numbered {
  gap: 6px;
  padding-left: 24px;
  list-style: decimal;
}

/* A short first-person quote pulled out as its own editorial beat —
   distinct from .cs-thesis (which is Claude's/the author's own claim)
   because this one is someone else's words, attributed. */
.cs-quote {
  max-width: 640px;
  margin: 48px 0;
  padding-left: 24px;
  border-left: 3px solid var(--ink-40);
}

.cs-quote p {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(24px, 3.4vw, 32px);
  line-height: 1.35;
  color: var(--ink);
}

.cs-quote cite {
  display: block;
  margin-top: 12px;
  font-style: normal;
  font-size: 13px;
  color: var(--ink-40);
}

/* Same pulled-out treatment, but for the author's own rhetorical question
   rather than someone else's attributed words — sans-serif instead of
   the display face, no citation line, and a tighter margin since it's a
   quick aside rather than a full editorial beat. */
.cs-quote--question {
  margin: 56px 0;
}

.cs-quote--question p {
  font-family: var(--font-sans);
  color: var(--ink-70);
}

.cs-outcome-list {
  max-width: 560px;
  margin: 40px 0;
  padding: 0;
  list-style: none;
}

.cs-outcome-list li {
  position: relative;
  padding: 14px 0 14px 28px;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-70);
}

.cs-outcome-list li:last-child {
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.cs-outcome-list li::before {
  content: '\2192';
  position: absolute;
  left: 0;
  color: var(--ink-40);
}

/* ---- Rhythm -------------------------------------------------------------
   One set of spacing for every case study, set here rather than per page:
   blocks in the content column sit 40px apart (text to a picture, a
   picture to its follow-on text), two pictures in a row 24px apart, a new
   sub-topic (a section opening on a sub-heading) 80px down, and a new
   labelled section (Overview, Problem...) 128px down. Pictures, videos,
   grids and carousels are left-aligned and up to 900px wide; the hero
   picture at the top up to 1170px. Headings step down from the 28px section
   heading to the 22px sub-heading and the 18px small heading. (The doubled
   .cs-content keeps these ahead of the components' own margins.) */
.cs-content {
  --gap: 40px;
  --gap-media: 24px;
  --gap-sub: 80px;
  --gap-major: 128px;
}

.cs-content.cs-content > * {
  margin-top: 0;
  margin-bottom: 0;
}

.cs-content.cs-content > .cs-section,
.cs-content.cs-content > .cs-stats {
  padding-top: 0;
  padding-bottom: 0;
}

.cs-hero {
  padding-bottom: 0;
}

.cs-content.cs-content > * + * {
  margin-top: var(--gap);
}

.cs-content.cs-content > :is(figure.cs-media, .cs-carousel, .cs-media-grid, .cs-chat-mock, .cs-edge-cases, .cs-diagram, .cs-flow)
  + :is(figure.cs-media, .cs-carousel, .cs-media-grid, .cs-chat-mock, .cs-edge-cases, .cs-diagram, .cs-flow) {
  margin-top: var(--gap-media);
}

.cs-content.cs-content > .cs-media-caption {
  margin-top: 12px;
}

.cs-content.cs-content > .cs-section:has(> :is(.cs-subhead, .cs-minorhead, .cs-section-head):first-child) {
  margin-top: var(--gap-sub);
}

.cs-content.cs-content > .cs-section:has(> .cs-label:first-child) {
  margin-top: var(--gap-major);
}

.cs-content.cs-content > .cs-footer {
  margin-top: 160px;
}

/* A details block kept inside the header follows the same 40px step. */
.cs-hero > .cs-meta {
  margin: 40px 0 0;
}

/* Widths and alignment of pictures. */
.cs-content.cs-content > figure.cs-media,
.cs-content.cs-content > .cs-carousel,
.cs-content.cs-content > .cs-media-grid {
  max-width: 900px;
  margin-left: 0;
  margin-right: 0;
}

/* Diagrams, card rows and stats share that 900px width; the narrow ones
   (step flows, the chat mock) keep their own width but line up on the
   left like everything else. */
.cs-content.cs-content > :is(.cs-diagram, .cs-edge-cases, .cs-stats) {
  max-width: 900px;
}

.cs-content.cs-content > :is(.cs-flow, .cs-chat-mock) {
  margin-left: 0;
  margin-right: 0;
}

.cs-content.cs-content > .cs-media-caption {
  max-width: 900px;
}

/* Only the picture at the top of a case study runs wider. */
.cs-content.cs-content > figure:is(.cs-media--hero, .cs-media--hero-video) {
  max-width: 1170px;
}

.cs-media-grid {
  gap: 24px;
}

.cs-media-grid > .cs-media {
  margin: 0;
}

/* Card captions under grid pictures: a small heading, then a line. */
.cs-media-grid .cs-media-caption {
  margin: 16px 0 0;
  text-align: left;
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-70);
}

.cs-media-grid .cs-media-caption strong {
  display: block;
  margin-bottom: 4px;
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
}

/* Inside a section: whatever opens it sits flush at its top. */
.cs-content .cs-section > :first-child {
  margin-top: 0;
}

.cs-section > .cs-label + .cs-subhead {
  margin-top: 0;
}

.cs-section p + .cs-thesis {
  margin-top: 32px;
}

@media (max-width: 780px) {
  .cs-content {
    --gap: 32px;
    --gap-media: 16px;
    --gap-sub: 56px;
    --gap-major: 88px;
  }

  .cs-content.cs-content > .cs-footer {
    margin-top: 112px;
  }

  .cs-hero {
    padding-top: 0;
  }

  /* Grids stack to one column on phones (their column counts are set on
     each grid in the page). */
  .cs-media-grid,
  .cs-diagram-cols {
    grid-template-columns: 1fr !important;
  }
}

/* Contact, at the very end of every case study (after the next project):
   a line of copy with a dark "Let's talk" pill under it that opens an email
   (mailto, subject filled in); the address itself isn't shown. */
.cs-content.cs-content > .cs-contact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 780px;
  margin-top: 0;
  padding: 64px 0 128px;
  border-top: 1px solid rgba(0, 0, 0, 0.12);   /* the same divider as above the next project */
}

/* The two closing blocks follow one pattern: a divider, 64px, a small
   label, then the line itself (the next project large, the contact
   question a step down), and 64px before the next divider. */
.cs-content.cs-content > .cs-footer:has(+ .cs-contact) {
  padding-bottom: 64px;
}

.cs-contact .cs-footer-label {
  margin-bottom: 12px;
}

.cs-contact-text {
  margin: 0 0 24px;
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.35;
  color: var(--ink);
}

.cs-contact-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 18px;
  border-radius: 999px;
  background: #1C1C1E;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: #FFFFFF;
  text-decoration: none;
  transition: background-color 0.2s ease;
}

.cs-contact-button svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (hover: hover) and (pointer: fine) {
  .cs-contact-button:hover {
    background: #000000;
  }

  .cs-contact-button:hover svg {
    transform: translate(2px, -2px);
  }
}

.cs-contact-button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}
