/* Work / case-study pages — styles/work.css
   Shell (nav, mega-menu, cursor-ring, footer) reuses tokens/base/layout/components
   from the home page unmodified. Everything below is specific to work/*.html:
   the case-study header (title + intro + fact table), body sections, figures,
   and the "back to the work" close.

   Placement follows site-director/PLACEMENT-MAP.md's 12-col grid (same --edge/
   --gutter tokens, same repeat(12,1fr) math as layout.css's `.grid`) and
   site-director/LAYOUT-STUDY.md's rule set. Full citations for every number
   used here live in site-director/WORK-PLACEMENT.md — this file only carries
   short inline pointers to the rule number.

   `.wgc` is one generic placement utility (grid-column from two custom
   properties) instead of dozens of one-off `.gc-N-S` classes: each work page
   sets its own --col-start/--col-span per element, so six pages with six
   different measured layouts don't require thirty near-duplicate class names.
   Below 768px it does nothing — layout.css's own `.grid > *{grid-column:1/-1}`
   already collapses every child to one full-width column (LAYOUT-STUDY §2,
   "universal collapse"), which is exactly the 375 behaviour this brief asks
   for, so .wgc only needs to exist at >=768. */

@media (min-width: 768px) {
  .wgc { grid-column: var(--col-start, 1) / span var(--col-span, 12); }
}

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

/* ---------------------------------------------------------------- header: title + intro + facts */
.cs-head {
  padding-top: calc(var(--nav-height) + 4.5rem);
  padding-bottom: 3rem;
  border-bottom: 1px solid var(--divider);
}
.cs-head-grid { row-gap: 2.25rem; }

.cs-title {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -.015em;
  font-size: clamp(2.25rem, 1.25rem + 4.2vw, 4.75rem); line-height: 0.95; margin: 0;
}
/* Rule 1 (LAYOUT-STUDY §4): a multi-word title jogs across two column starts
   instead of sharing one left edge. `subgrid` lets the two line-spans inherit
   the page's own 12 column lines so the jog lines up with every other
   grid-placed element on the page, not an independent measurement. Below
   768px this collapses to plain stacked block lines at the page margin. */
.cs-title-lines { display: block; }
.cs-title-line { display: block; }
@media (min-width: 768px) {
  .cs-title-lines {
    display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; column-gap: var(--gutter);
  }
  .cs-title-line { grid-column: var(--col-start, 1) / span var(--col-span, 12); }
  .cs-title-line:first-child { grid-row: 1; }
  .cs-title-line:last-child { grid-row: 2; }
}

.cs-intro { margin: 0; color: var(--text); font-family: var(--font-copy); font-size: .95rem; line-height: 1.55; }
/* Rule 4 (arunnm): the offset/aside column can carry more weight than the
   body copy it sits beside, even at the same size — used on pages whose
   intro sits in a narrow right-hand lane. */
.cs-intro--weighted { font-weight: 500; }

.cs-facts-wrap { margin-top: 2.75rem; }
/* Rule 12: data rows get a hairline `border-bottom` grid, never inline dots. */
.cs-facts { margin: 0; border-top: 1px solid var(--divider); }
.cs-fact {
  display: grid; grid-template-columns: minmax(120px, 30%) 1fr; column-gap: 1.5rem;
  padding: 1.05rem 0; border-bottom: 1px solid var(--divider); align-items: baseline;
}
.cs-fact dt {
  margin: 0; font-family: var(--font-mono); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted); font-weight: 400;
}
.cs-fact dd { margin: 0; color: var(--text); font-size: .95rem; }

/* ---------------------------------------------------------------- body sections */
.cs-block { border-top: 1px solid var(--divider); padding-block: 3.25rem; }
.cs-block:first-of-type { border-top: 0; }
.cs-block-grid { row-gap: 1.5rem; }

.cs-h2 {
  margin: 0; font-family: var(--font-display); font-weight: 600; letter-spacing: -.01em;
  font-size: var(--text-h2); line-height: 0.95;
}

.cs-body { color: var(--text); font-family: var(--font-copy); font-size: .95rem; line-height: 1.55; }
.cs-body p { margin: 0; }
.cs-body p + p { margin-top: 1.15rem; }
.cs-body strong { color: var(--text); font-weight: 600; }
.cs-body em { color: var(--text); font-style: italic; }

/* ---------------------------------------------------------------- figures
   Rule 2: caption pinned in a narrow side lane at the same y as the figure's
   top edge (align-items:start on the row), not centred or stacked below on
   desktop. Explicit --col-start on each half is what lets a caption sit to
   either side of its image (most pages: image left / caption right; ash
   mirrors it) without touching DOM order — DOM stays image-then-caption
   everywhere so the 375 collapse (`.grid > *{grid-column:1/-1}`) always stacks
   the caption directly under its figure, matching the brief's mobile rule. */
.cs-figure { margin-top: 3.25rem; }
.cs-figure-grid { align-items: start; }
.cs-figure-media picture,
.cs-figure-media img { display: block; width: 100%; height: auto; border: 1px solid var(--divider); }
.cs-figure-caption {
  margin: 0; font-family: var(--font-mono); font-size: .72rem; line-height: 1.55; color: var(--muted);
}
@media (max-width: 767px) { .cs-figure-caption { margin-top: .85rem; } }

/* ---------------------------------------------------------------- reveal-on-scroll
   Reuses base.css's [data-reveal] hidden state (opacity:0 / translateY(16px),
   already forced visible under prefers-reduced-motion there); this file only
   adds the transition and the visible end-state. IntersectionObserver in
   js/work.js flips the class once per element then unobserves — no scroll
   handler, no rAF loop, nothing runs off-screen (web-perf: runtime). */
[data-reveal] { transition: opacity .6s var(--ease-out-expo), transform .6s var(--ease-out-expo); }
[data-reveal].is-visible { opacity: 1; transform: none; }

/* ---------------------------------------------------------------- close */
.cs-end { border-top: 1px solid var(--divider); padding-block: 3rem 4rem; }
/* .cs-back lives in components.css (shared with the home page's manifesto link) */

/* ---------------------------------------------------------------- race-calendar data card
   v5.1 redesign (coordinator feedback: v1 read as an empty tall box with a tiny
   icon). ~/design-library/kits/landonorris/components.md Addendum + §9. Lives in
   .cs-head-grid beside .cs-intro (row-2 — "top edge aligns with the intro's first
   line"), sized to its own content (no fixed aspect, no dead space): the outline
   graphic is now the hero (120-180px, .cs-stat-icon below), the number is Geist 100
   at near-headline scale, bottom-left, and the §9 cut-corner frame is flipped
   (`transform="scale(1,-1) translate(0,-411)"` on the UNCHANGED path — still the
   kit's numbers 1:1, just mirrored) so the notch sits top-right where the graphic
   breaks the frame, instead of bottom-right by the label. One real number per page,
   never derived (evals/v5-stat-sources.md has the exact source sentence for each);
   two pages (Whitestone, ASH) have a genuine second number, added as .cs-stat-secondary
   below a hairline divider — no dot separators anywhere. */
.cs-stat-card {
  position: relative; align-self: start; padding: 1.75rem 1.5rem 1.5rem;
  display: flex; flex-direction: column; gap: 1.5rem;
}
.cs-stat-frame { position: absolute; inset: 0; pointer-events: none; }
.cs-stat-frame-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.cs-stat-frame-svg path { fill: none; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.cs-stat-frame-svg.is-base path { stroke: var(--divider); }
.cs-stat-frame-svg.is-accent path { stroke: var(--accent); opacity: 0; transition: opacity .3s ease; }
.cs-stat-card:hover .cs-stat-frame-svg.is-accent path,
.cs-stat-card:focus-within .cs-stat-frame-svg.is-accent path { opacity: 1; }

/* the graphic is the hero: big, top-right (opposite nothing — the flipped frame's
   notch is ALSO top-right, so it frames the glyph rather than sitting empty by the
   label). 96px flat below 768 per the brief, clamp up to 180px above it. */
.cs-stat-graphic { position: relative; display: flex; justify-content: flex-end; }
.cs-stat-icon { width: 96px; height: 96px; color: var(--text); }
@media (min-width: 768px) {
  .cs-stat-icon { width: clamp(120px, 14vw, 180px); height: clamp(120px, 14vw, 180px); }
}
.cs-stat-icon path, .cs-stat-icon line, .cs-stat-icon circle, .cs-stat-icon rect, .cs-stat-icon ellipse {
  fill: none; stroke: currentColor; stroke-width: 1; stroke-linecap: round; stroke-linejoin: round;
}
.cs-stat-icon .accent { stroke: var(--accent); }

.cs-stat-primary, .cs-stat-secondary { position: relative; display: flex; flex-direction: column; gap: .5rem; }
.cs-stat-secondary { border-top: 1px solid var(--divider); padding-top: 1.25rem; }
.cs-stat-number {
  margin: 0; font-family: var(--font-display); font-weight: 100;
  font-size: clamp(5.5rem, 9vw, 10.5rem); line-height: .85; letter-spacing: -.04em; color: var(--text);
}
.cs-stat-number--sm { font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem); letter-spacing: -.02em; }
.cs-stat-label {
  margin: 0; font-family: var(--font-mono); font-size: .7rem;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}
@media (prefers-reduced-motion: reduce) {
  .cs-stat-frame-svg.is-accent path { transition: none; }
}

/* ---------------------------------------------------------------- Breq Studio additions
   BUILD-BRIEF.md REVISION 2 §C. Not in the portfolio source — its case pages
   never needed a plain "what I did" list or a narrow phone-width shot. Both
   reuse this file's existing hairline-row / figure language rather than
   inventing a new visual idiom. */

/* "Yang saya kerjakan" — a flat list, unlike .cs-facts' dt/dd pairs, so it
   gets its own minimal hairline-row component instead of overloading .cs-facts. */
.cs-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--divider); }
.cs-list li { padding: .85rem 0; border-bottom: 1px solid var(--divider); color: var(--text); font-family: var(--font-copy); font-size: .93rem; line-height: 1.55; }
@media (max-width: 767px) { .cs-intro, .cs-body, .cs-list li { font-size: .9rem; } }

/* mobile screenshot figure — narrow (~320px), real device pixels, no fake phone
   frame per the brief: just the hairline border .cs-figure-media img already
   carries, plus a border-radius and a width cap so it doesn't stretch to the
   full grid column. */
.cs-figure-media--mobile { max-width: 320px; }
.cs-figure-media--mobile img { border-radius: 14px; }
