/* Case studies — ONE unified design for all ten /projects/<slug> pages.
   There are no per-project theme files any more: every page is the same
   skeleton, the same rhythm, the same motion, and a project expresses its
   identity through exactly one custom property — --case-accent — plus its
   own imagery and copy. The visual vocabulary is the homepage journey (jr-)
   card language, taken over to paper: white shell, 1px ink rim, a soft lift,
   a .3125rem bezel, outer radius 1.5rem / inner 1.1875rem, and images that
   never transform.

   Type: Quicksand for body and Orbitron for display, both self-hosted SIL OFL;
   they replaced the commercial Matter set ("Brier" / "Mona Sans Variable") and
   Azeret Semimono. --cs-mono stays a real monospace (the system stack) because
   the spec bar, crumbs and code carry aligned figures that a proportional face
   would break. 1rem is a fluid design unit here, not 16px.

   Motion: hidden start states are gated on .csjs, set pre-paint by an inline
   one-liner in each content.html. No class -> no JS -> settled end state.
   The runtime (case/init.js) is unchanged: reveal observer for .cs-rise,
   data-cs-count count-ups, .cs-par parallax, .cs-prog writing --cs-p, the
   TOC highlighter, and the click-to-activate demo iframe. */

/* ONE CHAPTER, ONE SET OF NAMES.
   The page reads light from the masthead to the footer — the same white as
   /contact, /projects and the homepage's body. The masthead, the architecture
   block, the browser chrome around the live demo and the five next-project
   cards were all dark objects once; they are paper objects now, told apart
   from the page by a hairline rim and a soft lift rather than by inversion.
   The token block that used to invert them for their own scope is gone, and
   so is the dissolve that used to bridge the two themes: there is no seam
   left to hide. */

.taxi-w.case {
  --cs-bg: #fafcfb;
  --cs-ink: #040504;
  --cs-dim: #535450;
  --cs-line: rgba(4, 5, 4, .09);
  --cs-card: #e9efeb;
  --cs-code: rgba(4, 5, 4, .06);
  /* THE FRAMED OBJECT, as an object. The shell used to be #ffffff on a #fafcfb
     page — the same colour, effectively, so every card needed a drop shadow to
     exist at all. It is a soft grey-green paper now, plainly darker than the
     page, edged with a real grey rim. --cs-lift is deliberately empty: there
     are no shadows on this page, and nothing may reintroduce one. */
  --cs-shell: #e9efeb;
  --cs-rim: #cbd3ce;
  --cs-rim-hover: #9fa9a4;
  --cs-lift: none;
  --cs-measure: 62ch;
  --cs-rhythm: 6.5rem;

  --cs-mono: ui-monospace, SFMono-Regular, Menlo, 'Courier New', monospace;
  --cs-ease: cubic-bezier(.215, .61, .355, 1);

  /* The one per-project lever, in two tempers: --cs-hi is the project's colour
     on ink (the masthead and every dark object), --cs-lo the same hue taken
     down until it clears 4.5:1 on the page white. --case-accent points at
     whichever the current chapter needs, so no rule below ever changes. */
  --cs-hi: var(--color--lime, #21f1a8);
  --cs-lo: #0c7a55;
  /* the page is light throughout, so the paper temper is the only one used —
     --cs-hi is kept because the identity table below is written in it and it
     still tints the mint-on-ink details (the badge, the demo lights) */
  --case-accent: var(--cs-lo);

  /* what the shared footer band paints itself with — see css-main.html */
  --page-bg: var(--cs-bg);

  background-color: var(--cs-bg);
  color: var(--cs-ink);
  display: block;
  position: relative;
}

/* Ten identities, two values each: on ink (≥6.6:1) and on paper (≥4.6:1). */
.taxi-w.case[data-cs="ember-and-oak"]   { --cs-hi: #e0764a; --cs-lo: #b04f27; }
.taxi-w.case[data-cs="aurelia-house"]   { --cs-hi: #c7a867; --cs-lo: #816835; }
.taxi-w.case[data-cs="norra-health"]    { --cs-hi: #7fb0a0; --cs-lo: #4c7467; }
.taxi-w.case[data-cs="arke-estates"]    { --cs-hi: #b9b5ae; --cs-lo: #726b61; }
.taxi-w.case[data-cs="slab-strength"]   { --cs-hi: #d8f21d; --cs-lo: #66720c; }
.taxi-w.case[data-cs="noctis-studio"]   { --cs-hi: #ff5d54; --cs-lo: #d6160b; }
.taxi-w.case[data-cs="root-and-ritual"] { --cs-hi: #c0a98e; --cs-lo: #816748; }
.taxi-w.case[data-cs="signalform"]      { --cs-hi: #9d8fff; --cs-lo: #6550f2; }
.taxi-w.case[data-cs="neonframe"]       { --cs-hi: #00e5ff; --cs-lo: #077785; }
.taxi-w.case[data-cs="brightloop"]      { --cs-hi: #ffc94d; --cs-lo: #8d6407; }


/* The shared sheet sets list-style on the ELEMENT, which beats inheritance. */
.taxi-w.case ol,
.taxi-w.case ul { list-style: none; margin: 0; padding: 0; }
.taxi-w.case li { list-style: none; list-style-type: none; }
.taxi-w.case li::marker { content: none; }

.taxi-w.case p { margin: 0; }
.taxi-w.case h1, .taxi-w.case h2, .taxi-w.case h3 { margin: 0; }
.taxi-w.case code {
  font-family: var(--cs-mono);
  font-size: .85em;
  background-color: var(--cs-code);
  padding: .1em .35em;
  border-radius: .3em;
}

/* ------------------------------------------------------------------ layout */

.cs-wrap {
  width: 100%;
  max-width: var(--fluid-container);
  margin-inline: auto;
  padding-inline: var(--padding--container);
}

/* ------------------------------------------------------------- skip links */

.cs-skip {
  position: fixed;
  top: 1rem;
  left: 50%;
  z-index: 20;
  transform: translate(-50%, -150%);
  opacity: 0;
  pointer-events: none;
  /* neutral on purpose: this pill can appear over either chapter */
  background: #040504;
  color: #edf5f3;
  font-family: var(--cs-mono);
  font-size: .6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .625rem 1rem;
  border-radius: .375rem;
  transition: transform .25s var(--cs-ease), opacity .25s linear;
}
.cs-skip:focus-visible {
  transform: translate(-50%, 0);
  opacity: 1;
  pointer-events: auto;
  outline: 2px solid var(--case-accent);
  outline-offset: 2px;
}

/* --------------------------------------------------------------- masthead */

.cs-mast {
  position: relative;
  background-color: var(--cs-bg);
  padding-top: calc(var(--on-t-nav-spacer, 5.375rem) + 2.5rem);
  padding-bottom: 8rem;
}
.cs-crumb {
  display: flex;
  align-items: baseline;
  gap: .625rem;
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cs-dim);
}
.cs-crumb a {
  color: var(--cs-dim);
  text-decoration: none;
  transition: color .3s linear;
}
.cs-crumb a:hover, .cs-crumb a:focus-visible { color: var(--case-accent); }
.cs-crumb b { color: var(--cs-ink); font-weight: inherit; }
.cs-crumb-n { margin-left: auto; color: var(--case-accent); }

.cs-mast-title { margin-top: 2.25rem; }
.cs-title-row {
  display: block;
  /* Both title lines share the display face. Line 2 (.cs-title-sub) was
     always Brier while line 1 inherited the body font — with two different
     typefaces that split reads as a mistake, so line 1 joins it here. */
  font-family: Orbitron, Arial, sans-serif;
  font-size: clamp(2.75rem, 6vw, 5.75rem);
  line-height: .92;
  letter-spacing: -.125rem;
  text-transform: uppercase;
  font-variation-settings: normal;
  color: var(--cs-ink);
}
.cs-title-sub {
  display: block;
  font-family: Orbitron, Arial, sans-serif;
  font-variation-settings: normal;
  letter-spacing: -.0625rem;
  color: var(--case-accent);
}
.cs-mast-lede {
  margin-top: 1.75rem;
  max-width: 46rem;
  color: var(--cs-dim);
  font-size: 1.0625rem;
  line-height: 1.55;
}

/* The spec bar: the project's hard numbers, count-ups included. */
.cs-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 3rem;
  margin: 2.75rem 0 0;
  padding: 1.25rem 0;
  border-top: 1px solid var(--cs-line);
  border-bottom: 1px solid var(--cs-line);
}
.cs-meta > div { display: flex; flex-direction: column; gap: .3rem; }
.cs-meta dt {
  font-family: var(--cs-mono);
  font-size: .5625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cs-dim);
}
.cs-meta dd {
  margin: 0;
  font-size: .9375rem;
  font-variation-settings: "wght" 600;
  color: var(--cs-ink);
}
.cs-meta dd b { color: var(--case-accent); font-weight: inherit; }

/* The masthead figure: THE WHOLE PAGE, top to bottom, across N jr frames.

   One image — the full-page strip — is sliced by geometry alone. Each cell is
   a window exactly 1/N of the image's displayed height, and cell i parks the
   image at top: i × -100% of that window. The slices are therefore contiguous
   by construction: nothing repeats, nothing is skipped, and the arithmetic
   cannot drift, because both the window height and the image height are
   derived from the same column width.

     window height  = colW × sh / (sw × N)     (--cs-ar, the ratio below)
     image height   = colW × sh / sw           (width:100%, height:auto)
                    = N × window height

   The grid carries two stamped values per project: --cs-fold-n (the slice
   count — four when the page is at least 5× taller than it is wide, three
   otherwise, so a cell lands near the old masthead's proportions) and
   --cs-ar, already multiplied out to `sw*N / sh`. It is a plain literal
   ratio on purpose: a calc() inside aspect-ratio would put the whole
   masthead's height at the mercy of one browser's support for it. */
.cs-fold-fig { margin: 3rem 0 0; }
.cs-fold {
  display: grid;
  grid-template-columns: repeat(var(--cs-fold-n, 3), minmax(0, 1fr));
  gap: .875rem;
}
.cs-fold-cell {
  position: relative;
  background-color: var(--cs-shell);
  border: 1px solid var(--cs-rim);
  border-radius: 1.5rem;
  padding: .3125rem;
  overflow: clip;
}
.cs-fold-in {
  display: block;
  position: relative;
  border-radius: 1.1875rem;
  overflow: clip;
  aspect-ratio: var(--cs-ar);
}
.cs-fold-in img {
  position: absolute;
  left: 0;
  top: calc(var(--i, 0) * -100%);
  width: 100%;
  height: auto;
}
.cs-fold-tag {
  position: absolute;
  z-index: 1;
  left: .625rem;
  top: .625rem;
  padding: .3rem .5rem;
  border-radius: .375rem;
  /* the tag lands on whichever page is in the cell — dark or light — so it
     stays an ink chip with paper type, readable over either */
  background-color: rgba(10, 12, 13, .78);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  font-family: var(--cs-mono);
  font-size: .5rem;
  letter-spacing: .08em;
  color: #edf5f3;
}
.cs-fold-tag b { color: var(--cs-hi); font-weight: inherit; }
.cs-fold-cap {
  margin-top: .875rem;
  font-family: var(--cs-mono);
  font-size: .5625rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--cs-dim);
}

/* --------------------------------------------------- chapter rail + article */

.cs-layout { padding-bottom: var(--cs-rhythm); }
.cs-rail { margin: 0; }
.cs-rail-list {
  display: flex;
  gap: 1.25rem;
  overflow-x: auto;
  padding: 1rem 0;
  border-bottom: 1px solid var(--cs-line);
}
.cs-rail a {
  display: inline-flex;
  align-items: baseline;
  gap: .45rem;
  white-space: nowrap;
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--cs-dim);
  transition: color .3s linear;
}
.cs-rail a b { color: var(--case-accent); font-weight: inherit; }
.cs-rail a:hover, .cs-rail a:focus-visible { color: var(--cs-ink); }
.cs-rail a.is-here { color: var(--cs-ink); }
.cs-rail-line { display: none; }

@media screen and (min-width: 992px) {
  .cs-layout {
    display: grid;
    grid-template-columns: 12rem minmax(0, 1fr);
    column-gap: 4rem;
    align-items: start;
  }
  .cs-rail {
    position: sticky;
    top: calc(var(--on-t-nav-spacer, 5.375rem) + 2.5rem);
    margin: var(--cs-rhythm) 0 0;
    display: flex;
    gap: 1.125rem;
  }
  /* The reading-progress line: .cs-prog sits on .cs-layout and init.js writes
     --cs-p there as it crosses the viewport; both children inherit it. */
  .cs-rail-line {
    display: block;
    position: relative;
    width: 1px;
    align-self: stretch;
    background-color: var(--cs-line);
    overflow: hidden;
  }
  .cs-rail-line::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--case-accent);
    transform: scaleY(var(--cs-p, 0));
    transform-origin: top center;
  }
  .cs-rail-list {
    flex-direction: column;
    align-items: flex-start;
    gap: .875rem;
    overflow: visible;
    padding: 0;
    border-bottom: 0;
  }
  .cs-rail a { white-space: normal; }
}

/* --------------------------------------------------------------- sections */

.cs-section { padding-top: var(--cs-rhythm); }
.cs-section + .cs-section { border-top: 1px solid var(--cs-line); margin-top: var(--cs-rhythm); }

.cs-eyebrow {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cs-dim);
}
.cs-eyebrow b { color: var(--case-accent); font-weight: inherit; }
.cs-h2 {
  margin-top: 1.125rem;
  font-size: clamp(1.75rem, 3vw, 2.625rem);
  line-height: 1.02;
  letter-spacing: -.0625rem;
  text-transform: uppercase;
  font-variation-settings: "wght" 700, "wdth" 93;
  max-width: 24ch;
  color: var(--cs-ink);
}
.cs-h3 {
  font-size: 1.0625rem;
  line-height: 1.25;
  letter-spacing: -.01em;
  font-variation-settings: "wght" 650;
  text-transform: none;
  color: var(--cs-ink);
}
.cs-body {
  margin-top: 1.25rem;
  max-width: var(--cs-measure);
  color: var(--cs-dim);
  font-size: 1rem;
  line-height: 1.6;
}
.cs-body + .cs-body { margin-top: 1rem; }
/* Inside a surface the card's own gap does the spacing. */
.cs-card .cs-body, .cs-step .cs-body, .cs-pair .cs-body { margin-top: 0; font-size: .9375rem; }
.cs-body strong { color: var(--cs-ink); font-variation-settings: "wght" 600; font-weight: normal; }
.cs-body a { color: var(--case-accent); text-underline-offset: .2em; }
.cs-note {
  margin-top: 1.5rem;
  max-width: var(--cs-measure);
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--case-accent);
  background-color: var(--cs-card);
  border-radius: 0 .625rem .625rem 0;
  color: var(--cs-dim);
  font-size: .875rem;
  line-height: 1.55;
}
.cs-note b, .cs-note strong { color: var(--cs-ink); }

/* ------------------------------------------------------------------ steps */

.cs-steps {
  counter-reset: cs-step;
  display: grid;
  margin-top: 1.25rem;
  border-top: 1px solid var(--cs-line);
}
.cs-step {
  counter-increment: cs-step;
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: 1rem;
  padding: 1.375rem 0;
  border-bottom: 1px solid var(--cs-line);
}
.cs-step::before {
  content: counter(cs-step, decimal-leading-zero);
  font-family: var(--cs-mono);
  font-size: .6875rem;
  letter-spacing: .05em;
  color: var(--case-accent);
  padding-top: .25rem;
}
.cs-step b {
  display: block;
  font-size: 1.0625rem;
  font-variation-settings: "wght" 650;
  color: var(--cs-ink);
}
.cs-step p { margin-top: .45rem; color: var(--cs-dim); font-size: .9375rem; line-height: 1.55; max-width: 56ch; }

/* --------------------------------------------------------------- surfaces */

.cs-grid-2, .cs-grid-3 {
  display: grid;
  gap: 1.25rem;
  margin-top: 2rem;
}
@media screen and (min-width: 768px) {
  .cs-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cs-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.cs-card {
  background-color: var(--cs-card);
  border: 1px solid var(--cs-rim);
  border-radius: 1rem;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: .625rem;
}
.cs-card b { font-size: 1rem; font-variation-settings: "wght" 650; color: var(--cs-ink); }
.cs-card p { color: var(--cs-dim); font-size: .875rem; line-height: 1.55; }

/* The architecture tree: three files, byte counts, mono. */
.cs-tree {
  margin-top: 2rem;
  background-color: var(--cs-shell);
  border: 1px solid var(--cs-rim);
  border-radius: 1rem;
  padding: 1.5rem 1.75rem;
  font-family: var(--cs-mono);
  font-size: .8125rem;
  line-height: 1.9;
  color: var(--cs-dim);
  overflow-x: auto;
}
.cs-tree b { color: var(--cs-ink); font-weight: inherit; }
.cs-tree i { font-style: normal; color: var(--case-accent); }

.cs-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.5rem; }
.cs-chips li {
  font-family: var(--cs-mono);
  font-size: .5625rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cs-ink);
  border: 1px solid var(--cs-line);
  border-radius: 999px;
  padding: .375rem .75rem;
  opacity: .85;
}

/* Challenge -> solution pairs. */
.cs-pairs { margin-top: 2rem; display: grid; gap: 1.25rem; }
.cs-pair {
  display: grid;
  gap: 1.25rem;
  background-color: var(--cs-card);
  border: 1px solid var(--cs-line);
  border-radius: 1rem;
  padding: 1.5rem;
}
@media screen and (min-width: 768px) {
  .cs-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; }
}
.cs-pair > div { display: flex; flex-direction: column; gap: .5rem; }
.cs-pair span {
  font-family: var(--cs-mono);
  font-size: .5625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cs-dim);
}
.cs-pair .is-fix span { color: var(--case-accent); }
.cs-pair p { color: var(--cs-dim); font-size: .875rem; line-height: 1.55; }
.cs-pair b { color: var(--cs-ink); font-variation-settings: "wght" 600; font-size: .9375rem; }

/* ------------------------------------------------------------ live preview */

/* Mechanics owned by case/init.js and unchanged: the iframe is created on
   click only, sandboxed WITHOUT allow-same-origin, rendered at 1440x900 and
   scaled by --cs-demo-s from a ResizeObserver. The chrome is the jr frame. */
/* Deliberately narrower than the column it sits in: at full width the browser
   frame read as the page rather than as a specimen inside it. --cs-demo-s
   scales the 1440px document to whatever width this lands on, so a smaller
   window still shows the whole layout — just smaller. */
.cs-demo { margin: 2rem 0 0; max-width: 68rem; }
.cs-demo-chrome {
  background-color: var(--cs-shell);
  border: 1px solid var(--cs-rim);
  border-radius: 1.5rem;
  padding: .3125rem;
  overflow: clip;
  transition: border-color .5s var(--cs-ease);
}
.cs-demo:hover .cs-demo-chrome { border-color: color-mix(in srgb, var(--case-accent) 55%, transparent); }
.cs-demo-bar {
  display: flex;
  align-items: center;
  gap: .875rem;
  padding: .625rem 1rem;
}
.cs-demo-lights { display: inline-flex; gap: .375rem; }
.cs-demo-lights i {
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background-color: var(--cs-line);
}
.cs-demo-lights i:first-child { background-color: var(--case-accent); }
.cs-demo-url {
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .07em;
  color: var(--cs-dim);
}
.cs-demo-port {
  position: relative;
  aspect-ratio: 1440 / 900;
  overflow: hidden;
  border-radius: 0 0 1.1875rem 1.1875rem;
  background-color: var(--cs-bg);
  contain: layout paint;
}
.cs-demo-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
  transition: opacity .4s linear;
}
.cs-demo-port.is-live .cs-demo-poster { opacity: 0; pointer-events: none; }
.cs-demo-frame {
  position: absolute;
  inset: 0 auto auto 0;
  width: 1440px;
  height: 900px;
  border: 0;
  transform: scale(var(--cs-demo-s, .5));
  transform-origin: 0 0;
}
.cs-demo-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  appearance: none;
  border: 0;
  cursor: pointer;
  /* --cs-hi, not --case-accent (= --cs-lo). Near-black ink on the darkened
     temper measured 3.54-3.58:1 after G1 deepened it; on the bright temper the
     same ink reads 6.15-14.92:1 across the ten. No token changes value, the ink
     is unchanged, and each project keeps its own colour -- only which of its
     two tempers this control fills with. */
  background-color: var(--cs-hi);
  color: #10120f;
  font-family: var(--cs-mono);
  font-size: .6875rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: .875rem 1.5rem;
  border-radius: 999px;
  transition: transform .3s var(--cs-ease);
}
.cs-demo-play:hover { transform: translate(-50%, -50%) scale(1.05); }
.cs-demo-play:focus-visible { outline: 2px solid var(--cs-ink); outline-offset: 3px; }
.cs-demo-port.is-live .cs-demo-play { display: none; }
.cs-demo-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: .875rem;
}
.cs-demo-cap { font-family: var(--cs-mono); font-size: .625rem; letter-spacing: .05em; color: var(--cs-dim); }
.cs-demo-full {
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--case-accent);
  text-decoration: none;
}
.cs-demo-full:hover, .cs-demo-full:focus-visible { text-decoration: underline; text-underline-offset: .25em; }
.cs-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* -------------------------------------------------------------- next / nav */

/* Five portrait cards instead of one wide one: the way out of a case study is
   five more pieces of work, each shown from the top of its page in the same
   8:15 plate the /projects rail uses. Type is a size down from the rest of the
   page — these are signposts, not headlines. */
.cs-nav { padding-bottom: calc(var(--cs-rhythm) + 2rem); }
.cs-nav-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 1.125rem;
  border-bottom: 1px solid var(--cs-line);
}
.cs-nav-title {
  font-size: 1.375rem;
  line-height: 1.1;
  letter-spacing: -.02em;
  font-variation-settings: "wght" 650, "wdth" 95;
}
.cs-nav-sub {
  font-family: var(--cs-mono);
  font-size: .5625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cs-dim);
}
.cs-more {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: .875rem;
  margin-top: 1.5rem;
}
.cs-more-card {
  display: block;
  position: relative;
  text-decoration: none;
  color: var(--cs-ink);
  background-color: var(--cs-shell);
  border: 1px solid var(--cs-rim);
  border-radius: 1.125rem;
  padding: .25rem;
  overflow: clip;
  transition: border-color .5s var(--cs-ease);
}
/* hover deepens the rim — the card never lifts off the page */
.cs-more-card:hover, .cs-more-card:focus-visible { border-color: var(--cs-rim-hover); }
.cs-more-card:focus-visible { outline: 2px solid var(--case-accent); outline-offset: 3px; }
.cs-more-frame {
  display: block;
  position: relative;
  border-radius: .875rem;
  overflow: clip;
  aspect-ratio: 8 / 15;
}
.cs-more-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0; /* every card starts at the top of its page */
  /* the shot is no longer dimmed to make room for copy over it — the frost
     below carries the copy, so the work is shown as it really looks */
  filter: saturate(.94);
  transition: filter .5s var(--cs-ease);
}
.cs-more-card:hover .cs-more-frame img, .cs-more-card:focus-visible .cs-more-frame img { filter: saturate(1.06); }
.cs-more-info {
  position: absolute;
  inset: auto 0 0;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: 2.25rem .75rem .875rem;
  /* half these shots are DARK pages — the ramp has to finish opaque or the
     name lands on a paragraph of someone else's body copy. Ink, not paper,
     and no taller than the copy needs, so the shot stays the card. */
  background-image: linear-gradient(rgba(8, 10, 10, 0) 0%, rgba(8, 10, 10, .07) 12%, rgba(8, 10, 10, .24) 23%, rgba(8, 10, 10, .52) 33%, rgba(8, 10, 10, .78) 42%, rgba(8, 10, 10, .92) 51%, rgba(8, 10, 10, .96) 62%, rgba(8, 10, 10, .96) 100%);
}
.cs-more-n {
  font-family: var(--cs-mono);
  font-size: .5rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--case-accent);
}
.cs-more-name {
  font-size: .9375rem;
  line-height: 1.1;
  letter-spacing: -.01em;
  font-variation-settings: "wght" 650, "wdth" 95;
  color: #f2f4ef;
}
.cs-more-cat {
  font-family: var(--cs-mono);
  font-size: .5rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #a7ada6;
}
.cs-nav-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-top: 1.75rem;
}
.cs-nav-row a {
  font-family: var(--cs-mono);
  font-size: .625rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--cs-dim);
  text-decoration: none;
  transition: color .3s linear;
}
.cs-nav-row a:hover, .cs-nav-row a:focus-visible { color: var(--case-accent); }

/* ------------------------------------------------------------------ motion */

/* .cs-rise: one-shot reveal, staggered by an inline --i. Hidden start state
   only exists once .csjs is on <html> (set pre-paint). */
.csjs .cs-rise { opacity: 0; transform: translateY(1.75rem); }
.csjs .cs-rise.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .8s var(--cs-ease), transform .8s var(--cs-ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}
/* .cs-par: init.js writes translate3d from data-cs-par. */
.cs-par { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .csjs .cs-rise { opacity: 1; transform: none; }
  .csjs .cs-rise.is-in { transition: none; }
  .cs-par { will-change: auto; }
  .cs-rail-line::after { transform: none; }
  .cs-demo-play, .cs-demo-poster, .cs-more-card, .cs-more-frame img, .cs-demo-chrome { transition: none; }
}

/* -------------------------------------------------------------- responsive */

@media screen and (max-width: 991px) {
  .taxi-w.case { --cs-rhythm: 4.5rem; }
  .cs-mast { padding-top: calc(var(--on-t-nav-spacer, 5.375rem) + 1.5rem); }
  .cs-crumb-n { display: none; }
  .cs-demo { max-width: none; }
  .cs-fold { gap: .5rem; }
  /* Five portrait cards will not fit across a tablet, and dropping two would
     hide work — so the row swipes instead. All five stay. */
  .cs-more {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 38vw;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
    padding-bottom: .5rem;
  }
  .cs-more-card { scroll-snap-align: center; }
}
@media screen and (max-width: 767px) {
  .cs-meta { gap: 1rem 1.75rem; }
  .cs-step { grid-template-columns: 2.25rem minmax(0, 1fr); }
  /* The slices are far too narrow to read at phone width, so the fold stops
     being a grid and becomes a swipe: same geometry, one card at a time. */
  .cs-fold {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 64vw;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    padding-bottom: .5rem;
  }
  .cs-fold-cell { scroll-snap-align: center; }
  .cs-more { grid-auto-columns: 56vw; }
}

/* ═══ RTL — html[dir="rtl"] only ═══════════════════════════════════════════
   The fold tags are counters (`01 / 04`) split across inline boxes, so the
   RTL container lays them out reversed — measured `/ 04  01` on
   /ar/projects/ember-and-oak. A counter is one token: keep it LTR. The
   `.cs-fold` STRIP itself is a sequence of steps and mirrors correctly —
   step 01 belongs on the right in Arabic — so it is deliberately untouched. */
html[dir="rtl"] .cs-fold-tag { direction: ltr; }

/* `.cs-more-n` is the same counter in a single text node (`02 / 10` read as
   `10 / 02`), so it takes the other mechanism. */
html[dir="rtl"] .cs-more-n { unicode-bidi: plaintext; }

/* The file tree is ASCII art — box-drawing characters, indentation and Latin
   filenames whose alignment IS the meaning. It is not a paragraph of Arabic
   with Latin in it, so it takes a wholesale LTR context rather than
   per-token isolation: measured `32.6 KB` rendering `KB 32.6` inside it, and
   the branch glyphs cannot mirror without the tree ceasing to read as one.
   The block still sits where RTL puts it; only its interior is LTR. */
html[dir="rtl"] .cs-tree { direction: ltr; text-align: left; }
