/* ============================================================
   CH0 — THE BANDED CHAPTER

   The band half of /chart-glass.css, which RAF loads for the same job. That
   file also carries the chart, the lens and a WebGL scene host, none of
   which exist on this page, and its fallback field animates continuously.
   This page has no motion, so the band is rebuilt here as a still one.

   Everything below is additive: delete this file and chapter zero renders as
   a normal chapter on cream. Nothing here is required for the content to be
   readable.

   Two things depend on it. The band gives the explainer's rounded bottom
   corners something to cut into — against page ground the radius is
   invisible, because the panel and the page are the same colour. And it puts
   one dark spread at the top of the article, which is the shape RAF opens
   with.

   COLOUR: the ink is flipped by redefining the site's own tokens on the
   banded section, so every descendant reads them and no element needs its
   own override. The values are RAF's, measured against this ground rather
   than picked: --text-muted is #cac2b6 because the page's own #90918b falls
   to 3.4:1 here. Because the band is dark in both themes there is no
   .dark-mode variant — the ink depends on the band, not the page.
   ============================================================ */

.pv-chapter.is-banded {
  /* the ink, for everything inside */
  --text-primary: #f7f4f0;
  --text-body: #ded7cd;
  --text-muted: #cac2b6;
  --rule-soft: rgba(255, 255, 255, 0.14);
  --rule: rgba(255, 255, 255, 0.2);
  --surface: rgba(255, 255, 255, 0.06);
  --accent: #ff9b70;

  /* THE CHAPTER'S OWN BOX DOES NOT MOVE, and that is the whole trick.

     RAF's band is the chapter itself, bled to the viewport with a negative
     margin-inline and given the width back as padding. That construction is
     broken in Safari: a .pv-chapter is a multi-column container, and once it
     carries a negative inline margin WebKit lays the column-span:all heading
     out against a different box than the columns — the h2 landed on top of the
     first paragraph and the in-column figure vanished from the second column
     altogether. Chromium renders it correctly, which is why RAF has never
     shown it; RAF's banded chapter has no in-column figure and a shorter
     opener, so the collision is less visible there.

     So nothing bleeds here. The chapter keeps the same content box as every
     other chapter on the page — which is also why the columns line up with
     them exactly — and the dark ground is painted by .cs-band-field, an
     absolutely positioned child stretched to the viewport. Absolute offsets do
     not participate in the multi-column layout, so the columns never see them.

     Only vertical padding is left, to hold the ground clear of the type. */
  position: relative;
  padding-block: clamp(52px, 6.5vw, 104px);
  color: var(--text-body);
}

/* Close the seam. The rounded panel above has to sit ON this band for its
   corners to read at all, and between them sits the page ground: .cs-body's
   top padding plus this chapter's own top margin. Both are removed only while
   the banded chapter is the FIRST thing in the body, so moving the band down
   the page restores normal spacing without a second edit here. If :has() is
   unavailable the gap simply comes back; nothing breaks. */
.cs-body > .pv-chapter.is-banded:first-child { margin-top: 0; }
.cs-body:has(> .pv-chapter.is-banded:first-child) { padding-top: 0; }

/* The field goes BEHIND the content by sitting at z-index -1, rather than by
   lifting every sibling to z-index 1. Lifting them meant `position: relative`
   on the column-span:all heading, and that is what Safari could not lay out:
   with it, the heading was positioned against the chapter box while the
   columns were positioned against the column box, and the two overlapped. */

/* ---------- the field ----------
   THE BAND ITSELF. Empty and aria-hidden: it carries no content, only the dark
   ground and the two decorative layers below.

   Stretched to the full viewport, edge to edge, with no radius of its own —
   the curve at the top of this band belongs to the .cs-context panel above it,
   which sits one layer up and cuts into this ground.

   `left`/`right` of `50% - 50vw` is the exact distance from the chapter's edge
   to the viewport edge, so the ground grows with the window and stops at it.
   Because this box is absolutely positioned it is out of flow: the chapter's
   own content box, and therefore the columns, are untouched by it. That is the
   point — see the note above.

   The two layers are still. RAF drifts the first and shimmers the second; here
   they hold their first frame, which is the finished state. A flat rectangle
   would read as a mistake at this size, and this is the least that stops it
   being one. */
.cs-band-field {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background: #120a07;
}

/* the core: a wide, heavily feathered warm bar — a soft rectangle over a flat
   ground rather than a radial gradient. Weighted low: dark at the top where
   the heading and the prose are, light gathering toward the bottom. */
.cs-band-field::before {
  content: "";
  position: absolute;
  inset: -20% -10%;
  background:
    linear-gradient(180deg,
      transparent 0%,
      rgba(199, 62, 29, 0.06) 34%,
      rgba(226, 96, 48, 0.26) 62%,
      rgba(226, 96, 48, 0.34) 80%,
      rgba(199, 62, 29, 0.16) 100%);
  filter: blur(38px);
  transform: translate3d(0, 0, 0) scale(1.08);
}

/* the grain, screen-blended and stationary */
.cs-band-field::after {
  content: "";
  position: absolute;
  inset: -80px;
  opacity: 0.5;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

/* ---------- the chapter's own content, on the band ----------

   A figure inside the band must not use the page's figure bleed: that would
   push it outside the band it is sitting in. .cs-incol already sets
   margin-inline: 0, so only a spanning figure would need this — it is here so
   that adding one later does not break the band. */
.pv-chapter.is-banded .pv-fig {
  width: auto;
  margin-inline: 0;
}

/* The placeholder reads --veil-border, which is a dark token on a light page
   and disappears against this ground. Point it at the band's own rule instead,
   so the dashed edge is as legible here as it is on cream. */
.pv-chapter.is-banded .cs-ph {
  border-color: var(--rule);
  background: var(--surface);
}

/* ============================================================
   THE SEAM BELOW THE BAND

   Ported from /chart-glass.css, where RAF does the same thing. The band's
   bottom edge was a hard line with a full chapter gap of page ground under
   it. Instead the next chapter gets the same rounded top corners the
   explainer above the band has, by the same trick: a plate in the page's own
   colour behind the chapter, starting one radius ABOVE it, so the band shows
   through only in the two corner notches.

   THE TRAP, which caught this on RAF first: the overlap cannot come from a
   negative margin-top on the chapter. That margin collapses with the band's
   bottom margin and the plate never reaches the band at all. So the band's
   margin goes to zero, the air between the two becomes the chapter's own top
   PADDING, and the plate's `top` offset does the overlap on its own.

   Same --ctx-radius as the explainer's corners, so both curves match.
   ============================================================ */
.cs-body .pv-chapter.is-banded {
  /* the plate below has to sit ON this band; the air moves to the chapter */
  margin-bottom: 0;
}

.cs-body .pv-chapter.is-banded + .pv-chapter {
  --ctx-radius: clamp(18px, 2vw, 34px);
  position: relative;
  isolation: isolate;
  z-index: 1;
  /* a quarter of the chapter gap: with the band's own bottom padding this is
     the same space the reader saw before, now inside the plate */
  padding-top: calc(var(--cs-chapter-gap) * 0.25);
  margin-top: 0;
}

.cs-body .pv-chapter.is-banded + .pv-chapter::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: calc(-1 * var(--ctx-radius));
  bottom: 0;
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  /* dark mode redefines --bg-cream itself, so the plate follows the page */
  background: var(--bg-cream);
  border-start-start-radius: var(--ctx-radius);
  border-start-end-radius: var(--ctx-radius);
  pointer-events: none;
}

/* ============================================================
   REPAIR — the chapter headings are never invisible

   styles-sidebar.css starts every `.cs-fx .cs-body .pv-chapter h2` at
   opacity 0 and 22px low, and relies on an observer adding .is-inview to
   bring it back. RAF stopped trusting that and forces the finished state
   in rhythm.css; measured here, Factor+ was rendering every one of its
   eight headings at opacity 0, including two chapters that already
   carried .is-inview. A heading that has to wait for JavaScript is a
   heading that can fail to arrive, and this page has no motion of its own
   for the reveal to belong to.

   The `.cs-body` prefix keeps this to the case study article, and the
   .is-inview branch is listed too so the observer cannot re-hide anything
   after the fact.
   ============================================================ */
.cs-fx .cs-body .pv-chapter h2,
.cs-fx .cs-body .pv-chapter.is-inview h2,
.cs-fx .cs-body .pv-quote,
.cs-fx .cs-body .pv-chapter.is-inview .pv-quote {
  opacity: 1;
  transform: none;
  transition: none;
}
