/* ============================================================
   ZOXA.AI — CASE STUDY STYLES
   Namespace: .zx-cs-*
   All values from tokens.css. No raw hex.
   ============================================================ */


/* ── reveal-card link wrapper (listing page) ── */
.zxr-card--link {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
}

.zxr-card--link .zxr-body h2 {
  font-size: var(--fs-h3);
  line-height: var(--lh-sub);
  margin: 0;
}

/* Hide the reveal-on-hover badge on listing cards — not needed here */
.zxr-card--link .zxr-badge { display: none; }

/* Clamp description to 2 lines with ellipsis */
.zxr-card--link .zxr-body > p {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "Read case study →" inline CTA at card bottom */
.zx-cs-card-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s4);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--primary);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.zxr-card--link:hover .zx-cs-card-cta,
.zxr-card--link:focus-within .zx-cs-card-cta { opacity: 1; }

/* ── Case Studies index hero ── */
.zx-cs-index-hero {
  /* var(--nav-height) is the floor, not a style choice — the nav is
     fixed, so anything less puts the eyebrow underneath it. The token
     after it is the only part that is discretionary; --s5 rather than
     --s8 pulls the grid ~40px further up the fold. */
  padding-top: calc(var(--nav-height) + var(--s5));
  padding-bottom: var(--s7);
  padding-inline: var(--gutter);
  text-align: center;
}

.zx-cs-index-hero__inner { max-width: 680px; margin-inline: auto; }
.zx-cs-index-hero__inner .zx-eyebrow { justify-content: center; margin-bottom: var(--s4); }

.zx-cs-index-title {
  font-size: clamp(2.5rem, 6vw, 4rem);
  font-weight: var(--fw-heavy);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  margin: 0 0 var(--s5);
  text-wrap: balance;
}

.zx-cs-index-sub {
  font-size: var(--fs-lead);
  color: var(--muted);
  line-height: var(--lh-body);
  max-width: 54ch;
  margin-inline: auto;
}

.zx-cs-index-grid { padding-top: 0; }

/* ══════════════════════════════════════════════════════════════
   CASE STUDY DETAIL PAGE
   ══════════════════════════════════════════════════════════════ */

.zx-cs { padding-bottom: var(--s10); }

/* ── 1 · HERO ──────────────────────────────────────────────────
   Full bleed, ember gradient, split copy | image. The gradient sits
   on its own layer rather than on the header, so the header keeps a
   plain background-color for the [data-band] contract and the art
   can be swapped without touching the band system. */
.zx-cs-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: calc(var(--nav-height) + var(--s8)) var(--s9);
  border-bottom-left-radius: var(--r-2xl);
  border-bottom-right-radius: var(--r-2xl);
}
/* Flat ink. No gradient and no ember: the eyebrow chip, the title and
   the case study's own artwork carry the colour on this page, and a
   plain ground stops the hero competing with them.

   Kept as its own layer rather than folded onto .zx-cs-hero so the
   header keeps a plain background-color for the [data-band] contract —
   and so putting artwork back later is one rule, not a restructure. */
.zx-cs-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--ink);
}
.zx-cs-hero__in {
  display: grid;
  grid-template-columns: 1.25fr .75fr;
  align-items: center;
  gap: var(--s8);
}
.zx-cs-hero__copy { min-width: 0; }

.zx-cs-crumb { margin-bottom: var(--s5); }
.zx-cs-crumb a {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 24px;                 /* WCAG 2.5.8 target size */
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.zx-cs-crumb a:hover { color: var(--bone); }

.zx-cs-hero__eyebrow {
  display: inline-block;
  margin-bottom: var(--s4);
  padding: var(--s1) var(--s3);
  border-radius: var(--r-chip);
  background: rgba(239, 90, 25, .18);
  border: 1px solid rgba(255, 158, 113, .38);
  color: var(--ember-300);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.zx-cs-hero__title {
  margin: 0 0 var(--s4);
  font-size: clamp(2rem, 1.1rem + 3.1vw, 3.5rem);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
  color: var(--bone);
  text-wrap: balance;
}
.zx-cs-hero__sub {
  margin: 0 0 var(--s6);
  max-width: 46ch;
  font-size: var(--fs-lead);
  line-height: var(--lh-small);
  color: var(--muted);
}
.zx-cs-hero__meta { display: flex; flex-wrap: wrap; gap: var(--s5); }
.zx-cs-hero__metaitem {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--muted);
}

.zx-cs-hero__media { min-width: 0; }
.zx-cs-hero__img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-xl);
  border: 1px solid rgba(255, 158, 113, .22);
  box-shadow: 0 30px 70px -20px rgba(15, 10, 8, .6);
}
.zx-cs-hero__img--empty {
  display: grid;
  place-items: center;
  background: rgba(251, 250, 246, .05);
  color: rgba(255, 158, 113, .35);
}

/* ── 2 · BODY + RAIL ───────────────────────────────────────── */
.zx-cs-wrap {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--s8);
  padding-top: var(--s8);
  /* NO align-items: start here.
     It looks like the right call and is exactly backwards. `start` shrinks
     each grid item to its own content height, so .zx-cs-rail collapsed to
     880px — precisely its sticky child's height — leaving 0px of travel.
     A sticky element can only move within its parent's box, so it never
     stuck at all. Letting the items stretch gives the rail the full row
     height and the child something to travel down. */
}
.zx-cs-rail { min-width: 0; }
.zx-cs-rail__stick {
  position: sticky;
  top: calc(var(--nav-height) + var(--s5));
  display: flex;
  flex-direction: column;
  gap: var(--s5);
}

/* facts panel */
.zx-cs-facts {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s5);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--border);
}
.zx-cs-fact { display: flex; gap: var(--s3); align-items: flex-start; }
.zx-cs-fact__ico {
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  flex: none;
  border-radius: var(--r-xs);
  background: var(--primary-soft);
  color: var(--primary);
}
.zx-cs-fact__txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.zx-cs-fact__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.zx-cs-fact__value {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--text);
  line-height: var(--lh-small);
}

/* contents rail */
.zx-cs-toc {
  padding: var(--s5);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--border);
}
.zx-cs-toc__head {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}

/* The rolling readout. overflow:hidden is what makes it read as one
   label replacing another rather than two labels crossfading. */
.zx-cs-toc__now {
  display: block;
  overflow: hidden;
  margin: var(--s3) 0 var(--s4);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--border);
}
.zx-cs-toc__nowtxt {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  font-size: var(--fs-small);
  line-height: 1.35;
  color: var(--primary);
  transition: transform var(--dur-slow) var(--ease-out),
              opacity var(--dur-slow) var(--ease-out);
}
/* start state: sat below the mask. JS removes this and the label rises. */
.zx-cs-toc__now.is-enter .zx-cs-toc__nowtxt {
  transform: translateY(110%);
  opacity: 0;
  transition: none;                 /* jump to the start, then animate out of it */
}

.zx-cs-toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.zx-cs-toc__list a {
  display: block;
  padding: var(--s2) var(--s3);
  border-left: 2px solid transparent;
  border-radius: 0 var(--r-2xs) var(--r-2xs) 0;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.zx-cs-toc__list a:hover { color: var(--text); background: var(--surface-2); }
.zx-cs-toc__list a.is-active {
  color: var(--text);
  font-weight: var(--fw-medium);
  border-left-color: var(--ember-500);
  background: var(--surface-2);
}

/* share */
.zx-cs-share {
  padding: var(--s5);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--border);
}
.zx-cs-share__head {
  display: block;
  margin-bottom: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.zx-cs-share__row { display: flex; gap: var(--s2); }
.zx-cs-share__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  flex: none;
  border-radius: var(--r-icon);
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.zx-cs-share__btn:hover {
  color: var(--on-primary);
  background: var(--primary);
  border-color: var(--primary);
}
.zx-cs-share__note {
  display: block;
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--success);
}

/* ── 3 · AUTHOR CARD ───────────────────────────────────────── */
.zx-cs-author {
  margin-top: var(--s9);
  padding: var(--s6);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--border);
}
.zx-cs-author__tag {
  display: block;
  margin-bottom: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.zx-cs-author__row { display: flex; align-items: center; gap: var(--s4); }
.zx-cs-author__avatar {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  flex: none;
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--grad);
  color: var(--on-primary);
  font-family: var(--font-display);
  font-weight: var(--fw-heavy);
  font-size: var(--fs-h4);
}
.zx-cs-author__avatar img { width: 100%; height: 100%; object-fit: cover; }
.zx-cs-author__who { display: flex; flex-direction: column; margin-right: auto; min-width: 0; }
.zx-cs-author__who strong { font-size: var(--fs-body); color: var(--text); }
.zx-cs-author__who span { font-size: var(--fs-small); color: var(--muted); }
.zx-cs-author__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 24px;
  flex: none;
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--primary);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.zx-cs-author__cta:hover { color: var(--primary-hover); }

/* ── ARTICLE BODY ──────────────────────────────────────────── */
.zx-cs-body { min-width: 0; max-width: 72ch; }
/* scroll-margin so anchor jumps and scroll-spy don't hide headings
   under the fixed nav */
.zx-cs-body :where(h2, h3) { scroll-margin-top: calc(var(--nav-height) + var(--s5)); }
.zx-cs-body :where(h2) {
  margin: var(--s8) 0 var(--s4);
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
}
.zx-cs-body > :where(h2):first-child { margin-top: 0; }
.zx-cs-body :where(h3) {
  margin: var(--s6) 0 var(--s3);
  font-size: var(--fs-h4);
  line-height: var(--lh-sub);
}
.zx-cs-body :where(p) {
  margin-bottom: var(--s4);
  color: var(--muted);
  line-height: var(--lh-body);
}
.zx-cs-body :where(strong) { color: var(--text); font-weight: var(--fw-bold); }
.zx-cs-body :where(a) { color: var(--primary); text-underline-offset: 3px; }
.zx-cs-body :where(blockquote) {
  margin: var(--s6) 0;
  padding: var(--s5) var(--s6);
  border-left: 3px solid var(--ember-500);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  background: var(--surface);
}
.zx-cs-body :where(blockquote p) { margin-bottom: var(--s3); color: var(--text); font-size: var(--fs-lead); line-height: var(--lh-small); }
.zx-cs-body :where(blockquote p:last-child) { margin-bottom: 0; font-size: var(--fs-small); color: var(--muted); }
.zx-cs-body :where(ul, ol) { margin: 0 0 var(--s4); padding-left: var(--s5); color: var(--muted); }
.zx-cs-body :where(li) { margin-bottom: var(--s2); line-height: var(--lh-body); }
.zx-cs-body :where(hr) { margin: var(--s7) 0; border: 0; border-top: 1px solid var(--border); }
.zx-cs-body :where(table) {
  width: 100%;
  margin: var(--s5) 0;
  border-collapse: collapse;
  font-size: var(--fs-small);
}
.zx-cs-body :where(th) {
  padding: var(--s3);
  text-align: left;
  border-bottom: 1px solid var(--border-strong);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.zx-cs-body :where(td) { padding: var(--s3); border-bottom: 1px solid var(--border); color: var(--muted); }
.zx-cs-body :where(td strong) { color: var(--primary); }

/* ── RESPONSIVE ────────────────────────────────────────────── */
@media (max-width: 1023px) {
  .zx-cs-hero__in { grid-template-columns: 1fr; gap: var(--s7); }
  .zx-cs-hero__media { order: -1; }         /* image leads on narrow */
  .zx-cs-wrap { grid-template-columns: 1fr; }
  /* Sticky is pointless once the rail is a full-width block above the
     article — it would pin a tall panel over the reading column. */
  .zx-cs-rail__stick { position: static; }
  .zx-cs-facts { flex-direction: row; flex-wrap: wrap; gap: var(--s5); }
  .zx-cs-fact { flex: 1 1 160px; }
  .zx-cs-toc { display: none; }             /* the rolling rail needs the sticky column */
}
@media (max-width: 767px) {
  .zx-cs-hero { padding-block: calc(var(--nav-height) + var(--s6)) var(--s7); }
  .zx-cs-author__row { flex-wrap: wrap; }
  .zx-cs-author__cta { width: 100%; }
}

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


/* ── markdown heading anchors ───────────────────────────────────
   The markdown plugin appends `<a class="direct-link">#</a>` to every
   heading for deep-linking. Unstyled it renders as a full-size glyph in
   the heading's own colour — a large orange # after each title. Keep the
   affordance, make it quiet: hidden until the heading is hovered or the
   link itself is focused. */
.zx-cs-body .direct-link {
  margin-left: var(--s2);
  font-weight: var(--fw-medium);
  color: var(--muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.zx-cs-body :where(h2, h3):hover .direct-link,
.zx-cs-body .direct-link:focus-visible { opacity: 1; }
.zx-cs-body .direct-link:hover { color: var(--primary); }

/* Never hide it from keyboard users outright — opacity:0 keeps it
   focusable, and focus brings it back. */
@media (prefers-reduced-motion: reduce) {
  .zx-cs-body .direct-link { transition: none; }
}
