/* ============================================================
   v9.css — "the camera turns as you read". Loaded after v7.css
   (V9 keeps V7.1's paper, ink, link style, header and footer).

   Desktop: text on the left scrolls; the stone on the right stays put
   and turns to a new projection when a new chapter takes the middle of
   the screen: top view (circle) = Understand, side view (triangle) =
   Decide, front view (square) = Deliver, then back to rest.
   Phones: compact chapter drawings and full-width project images.
   ============================================================ */
/* The header is 93px tall on desktop and tablet (the stage used to assume 84, so at the top of the
   page it sat 9px low and slid up under the header during the first 9px of scroll). v9.js sets
   --v9-head from the real header height; 93px is the no-JS fallback. (2026-09-26) */
:root { --v9-head: 93px; }
.v9-grid { display: grid; grid-template-columns: 5fr 7fr; gap: 48px; align-items: start; }
.v9-text { min-width: 0; grid-column: 1; grid-row: 1; }
.v9-stage { grid-column: 2; grid-row: 1; }
.chapter { min-height: calc(100vh - var(--v9-head)); display: flex; flex-direction: column; justify-content: center; padding: 64px 0; scroll-margin-top: var(--v9-head); }
.v9-hero { min-height: calc(100vh - 150px); padding-top: 24px; }
.v9-hero .role { margin-top: 28px; font-size: 15px; letter-spacing: .14em; color: var(--sumi-2); }
html[data-lang="zh"] .v9-hero .role { letter-spacing: .08em; }
.ch-title { font-size: 52px; font-weight: 300; line-height: 1.15; margin: 18px 0 0; }
html[data-lang="zh"] .ch-title { font-size: 46px; letter-spacing: .08em; }
.ch-say { margin-top: 22px; font-size: 18px; line-height: 1.75; color: var(--sumi-2); max-width: 26em; }
html[data-lang="zh"] .ch-say { font-size: 17px; letter-spacing: .04em; line-height: 1.95; }
.v9-coda { min-height: 64vh; }
/* The coda already supplies navigation; the homepage footer is contact only.
   Footer layout now lives in v7.css (.v7-foot--compact), shared with Work and About. */
.v9-coda .ch-title, html[data-lang="zh"] .v9-coda .ch-title { font-size: 40px; line-height: 1.3; letter-spacing: .02em; }
.v9-coda .ch-say, html[data-lang="zh"] .v9-coda .ch-say { max-width: 26em; font-size: 17px; line-height: 1.9; letter-spacing: .02em; }

/* project rows inside a chapter */
.ch-work { list-style: none; margin: 44px 0 0; padding: 0; border-top: 1px solid var(--hair); }
.ch-work li { border-bottom: 1px solid var(--hair); }
.ch-row { display: grid; grid-template-columns: 104px 1fr 20px; gap: 20px; align-items: center; padding: 18px 0; }
.ch-row .th { aspect-ratio: 16 / 10; overflow: hidden; background: #ebe7e0; }
.ch-row .th img { width: 100%; height: 100%; object-fit: cover; }
.ch-row .nm { display: block; font-size: 18px; color: var(--sumi); line-height: 1.35; }
.ch-row .ln { display: block; margin-top: 4px; font-size: 14px; line-height: 1.6; color: var(--sumi-2); }
.ch-row .meta { margin-top: 8px; }
.ch-row .go { color: var(--sumi-3); transition: transform .2s ease, color .2s ease; }
.ch-row:hover .nm { color: var(--mura); text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
.ch-row:hover .go { color: var(--mura); transform: translateX(3px); }
.ch-row:focus-visible .nm { color: var(--mura); text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* the stage */
/* svh = the viewport with the browser's bars shown, which does not change while scrolling; with
   plain vh the stage was taller than the visible area on iPad Safari until the toolbar collapsed. */
.v9-stage { position: sticky; top: var(--v9-head); height: calc(100vh - var(--v9-head)); height: calc(100svh - var(--v9-head)); min-height: 520px; }
.stage-inner { height: 100%; display: grid; grid-template-rows: 1fr auto auto; padding-bottom: 28px; }
.stage-cap { text-align: center; margin-bottom: 6px; }
.stage-svg { width: 100%; height: 100%; min-height: 0;
  -webkit-mask-image: radial-gradient(closest-side, #000 70%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 70%, transparent 100%); }
.stage-svg [data-part="sand"] path { fill: none; stroke: var(--rake); stroke-width: 1; }
.stage-svg [data-part="hull"] { fill: none; stroke: var(--mura); stroke-width: 1.6; stroke-linejoin: round; }
.stage-svg [data-part="base"], .stage-svg [data-part="top"] { fill: none; stroke: var(--mura); stroke-width: 1; }
.stage-svg [data-part="rules"] { fill: none; stroke: var(--mura); stroke-width: .8; }

/* The stage stays put to the end of the page (2026-09-26). It used to be released when the text
   column ended, and the 176px gap + footer (277px at 1440) pushed the stone up under the header.
   Now the text column reserves that space (padding) so the stage's sticky range runs to the page
   end, and the footer is pulled up by its own height to sit where it was, sliding over the
   caption and view buttons at the very bottom. Page length and footer position are unchanged.
   v9.js sets --v9-foot from the footer's real height; 101px is the fallback. */
.v9-text { padding-bottom: calc(176px + var(--v9-foot, 101px)); }
.v9-home .v7-foot { margin-top: calc(-1 * var(--v9-foot, 101px)); position: relative; z-index: 2; background: var(--sand); }

/* labelled chapter buttons under the stone: where am I, and a way to jump */
.stage-nav { display: flex; justify-content: center; gap: 36px; }
.stage-nav a { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-size: 15px; color: var(--sumi-2); }
/* Shared stroke and icon box; geometric bounds compensate for optical weight. */
.stage-nav .g { display: block; width: 20px; height: 20px; flex: 0 0 20px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linejoin: round; color: var(--sumi-3); transition: color .3s ease; }
/* Nav glyphs (2026-09-26): true side-view proportions (triangle base = height, as the stone's side
   view). Circle r 6.91 and square 12.25 have equal area (150 units² in the 20-unit box). The
   triangle is 14.41 × 14.41: Wenyu stepped it down from equal area (17.32) toward the 1:1
   projection (14), through 15.66 and 14.83 to 14.41 (half steps); area 103.8. It is
   lifted 0.8 unit because its mass sits at 2/3 of its height; overflow:
   visible lets a round join cross the box edge. */
.stage-nav .g { overflow: visible; }
.stage-nav a:hover, .stage-nav a:hover .g { color: var(--mura); }
.stage-nav a[aria-current="true"] { color: var(--sumi); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 8px; }
.stage-nav a[aria-current="true"] .g { color: var(--mura); }

/* phones: each chapter carries its own still view */
.ch-glyph { display: none; }
.ch-glyph svg { width: 100%; max-width: 320px; height: auto; display: block; }
.ch-glyph [data-part="sand"] path { fill: none; stroke: var(--rake); stroke-width: 1.2; }
.ch-glyph [data-part="hull"] { fill: none; stroke: var(--mura); stroke-width: 2; }
.ch-glyph [data-part="rules"] { fill: none; stroke: var(--mura); stroke-width: .8; }
.ch-glyph [data-part="base"] { fill: none; stroke: var(--mura); stroke-width: 1; }  /* the base's far edge, as on the desktop stage */

@media (max-width:719px), (max-width:1023px) and (max-height:520px) and (pointer:coarse) {
  .v9-grid { grid-template-columns: 1fr; gap: 0; }
  .v9-stage { display: none; }
  .chapter { position: relative; min-height: 0; padding: 40px 0 48px; scroll-margin-top: 92px; }
  .chapter + .chapter { border-top: 1px solid var(--hair); }
  /* 72px = the Work / About page-head offset, so the first line sits at the same height on all
     three nav destinations (was 28px while the stone sat above the name). */
  .v9-hero { padding-top: 72px; padding-bottom: 48px; }
  .ch-glyph { display: block; margin: 0; }
  /* One scale for all four glyphs (Wenyu, 2026-09-26): the stone and its three views are the same
     solid at the same size, so the hero stone's width equals the circle's diameter, the square's
     side and the triangle's base, and its height (88 model units) equals the square's and the
     triangle's. mark.js projects every view at sc 44 (base Ø 88, height 88 units); build-v9.mjs
     sets each viewBox to the hull, whose width is 88 in all four views, so equal SVG widths =
     one scale. 55px makes the stone (55 × 106.8/88 = 66.8px) span the name block, cap line to
     the 顧文宇 line; the chapter shapes (55 × 55) sit centred on eyebrow + title (57px zh,
     ~62px en). Earlier the glyphs were sized per block and drifted 55–62px (1 : 1.13). */
  .chapter[data-view]:not(.v9-coda) { --glyph: 55px; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 24px; align-content: start; }
  .chapter[data-view]:not(.v9-coda) > * { grid-column: 1 / -1; }
  .chapter[data-view]:not(.v9-coda) > .ch-glyph { grid-column: 2; grid-row: 1 / span 2; align-self: center; padding: 0 2px; }
  .chapter[data-view]:not(.v9-hero):not(.v9-coda) > .k { grid-column: 1; grid-row: 1; }
  .chapter[data-view]:not(.v9-hero):not(.v9-coda) > .ch-title { grid-column: 1; grid-row: 2; }
  .chapter[data-view].v9-hero > .name { grid-column: 1; grid-row: 1; }
  .chapter[data-view].v9-hero > .ch-glyph { grid-row: 1; align-self: start; padding: 10px 2px 0; }
  .ch-glyph svg { width: var(--glyph); height: auto; max-width: none; overflow: visible; }
  .ch-glyph path { vector-effect: non-scaling-stroke; }
  /* ...but not the mask that breaks the rings around the stone: its width is geometry (model units),
     and as a non-scaling stroke it became 8.2 screen px and still cut the first ring. */
  .ch-glyph [data-part="gap"] { vector-effect: none; }
  .ch-glyph [data-part="hull"] { stroke-width: 1.5; }
  .ch-glyph [data-part="sand"] path { stroke-width: 1; }
  .ch-glyph [data-part="rules"] { stroke-width: .6; }
  /* The rings (3 on phones, see build-v9.mjs) reach past the glyph; each section is their
     frame top and bottom (as the stage frame is on desktop), so they never cross a divider; sideways
     they run to the screen edge. */
  .chapter[data-view] { overflow-x: visible; overflow-y: clip; }
  .ch-title { font-size: 36px; margin-top: 12px; }
  html[data-lang="zh"] .ch-title { font-size: 32px; letter-spacing: .04em; }
  .ch-say, html[data-lang="zh"] .ch-say { font-size: 16px; line-height: 1.85; letter-spacing: .02em; margin-top: 24px; }
  .v9-hero .role { max-width: none; font-size: 14px; letter-spacing: .08em; margin-top: 22px; }
  html[data-lang="zh"] .v9-hero .role { letter-spacing: .06em; }
  .v9-hero .lede { margin-top: 14px; }
  .v9-hero .hero-actions { margin-top: 22px; }
  .ch-work { margin-top: 28px; border-top: 0; }
  .ch-work li { border-bottom: 0; }
  .ch-work li + li { margin-top: 32px; }
  .ch-row { grid-template-columns: minmax(0, 1fr) 24px; gap: 16px 12px; padding: 0; align-items: start; }
  .ch-row .th { grid-column: 1 / -1; }
  .ch-row .nm { font-size: 20px; line-height: 1.5; text-decoration: underline; text-decoration-color: var(--sumi-3); text-decoration-thickness: 1px; text-underline-offset: 5px; }
  .ch-row .nm-zh { display: block; font-size: 16px; }
  .ch-row .ln { font-size: 15px; line-height: 1.8; margin-top: 10px; }
  .ch-row .meta { margin-top: 12px; gap: 6px 14px; }
  .ch-row .go { display: block; padding-top: 4px; color: var(--sumi); }
  .v9-coda { padding-top: 40px; padding-bottom: 0; }
  .v9-coda .ch-title, html[data-lang="zh"] .v9-coda .ch-title { font-size: 30px; line-height: 1.4; }
  .v9-coda .ch-say, html[data-lang="zh"] .v9-coda .ch-say { font-size: 16px; }
  .v9-coda .hero-actions { gap: 8px 24px; }
  .v9-text { padding-bottom: 0; }
  .v9-home .v7-foot { margin-top: 64px; position: static; background: none; }
}
@media (min-width:720px) and (max-width:1023px) {
  .v9-grid { grid-template-columns: 1fr 1fr; gap: 28px; }
  .ch-title { font-size: 42px; }
}
@media (max-width:359px) {
  .ch-title, html[data-lang="zh"] .ch-title { font-size: 30px; }
}
/* A short landscape phone still uses the one-column phone edition. */
@media (min-width:720px) and (max-width:1023px) and (max-height:520px) and (pointer:coarse) {
  .v9-grid { grid-template-columns: 1fr; gap: 0; }
  .ch-title { font-size: 36px; }
}
