/* ============================================================
   PROTOTYPE V1 — Wenyu Ku Portfolio 2026
   Design system tokens — single source of truth for typography
   ============================================================
   TYPE SCALE (8 sizes, never exceed)
   --text-micro    11px  eyebrow, badge, monospace label
   --text-small    13px  card subtitle, footer copy, image caption
   --text-meta     14px  top nav, card hook, meta value, footer-nav
   --text-body     16px  paragraph body (uniform across all pages)
   --text-lead     19px  page lead/tagline, home hook, card title
   --text-section  32px  in-page section heading, story-heading, pull-text
   --text-page     48px  category-title (page heading)
   --text-display  64px  case-title (deepest detail level, display)

   FONT-WEIGHT SCALE (3 weights, never exceed)
   --weight-light    300  display titles, large hooks
   --weight-regular  400  body
   --weight-medium   500  emphasis (subtitle, accent words)
   --weight-bold     700  rare, only for badge/abbr

   FONT-FAMILY (1 family for body, 1 mono for tech labels)
   System sans-serif for all UI, monospace for tech metadata only.
   ============================================================ */

:root {
  --text-micro:    11px;
  --text-small:    13px;
  --text-meta:     14px;
  --text-body:     16px;
  --text-lead:     19px;
  --text-section:  32px;
  --text-page:     48px;
  --text-display:  64px;

  --weight-light:    300;
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-bold:     700;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", "Noto Sans TC", sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;

  /* Phone-display size tokens (red-line · use only these across the site).
     Hero  = single protagonist that owns its section (Night Market §03 video).
     Strip = any multi-phone arrangement (AR Maze lineups, footwear receipt rows). */
  --phone-hero:   360px;
  --phone-strip:  220px;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: 1.6;
  color: #1a1a1a;
  background: #ffffff;
  min-width: 720px;      /* floor, not a phone layout. Phones stay out of scope;
                            720 lets iPad portrait (744-1023) render without a
                            horizontal scrollbar. See the RESPONSIVE block below. */
  overflow-x: clip;      /* was `hidden` — `clip` cuts horizontal overflow without
                            creating a scroll container, which preserves `position: sticky`
                            on .site-header. `hidden` on html/body kills sticky descendants. */
}

a {
  color: inherit;
  text-decoration: none;
}

/* Global keyboard-focus visibility — WCAG 2.4.7
   Applied to any interactive or tab-stop element. Uses XTDesign purple as accent.
   Mouse users don't see it (only :focus-visible, not :focus). */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
  outline: 2px solid #5B3A8C;
  outline-offset: 3px;
  border-radius: 2px;
}

strong, b {
  font-weight: var(--weight-medium);   /* the system has no 700 outside badges */
}

img {
  display: block;
  max-width: 100%;
}

/* ============================================================
   LAYOUT CONTAINER
   ============================================================ */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 48px;
}

/* ============================================================
   GLOBAL HEADER (top nav)
   — sticky on every page including home; the nav follows the user
     as they scroll so it's always reachable on shorter viewports
   — discipline accent stripe lives in border-bottom and rides
     along with the sticky header (set via body[data-discipline])
   ============================================================ */
.site-header {
  padding: 24px 0;
  /* The header rule is a STRUCTURAL boundary — chrome above, content below —
     so it is deliberately one step darker than #ececec, the hairline used for
     content dividers everywhere else. At #ececec it half-disappeared against
     white and read as an unfinished edge, especially on case pages, where the
     discipline pages' 4px accent sets the expectation that this line matters. */
  border-bottom: 1px solid #d6d6d6;
  background: #ffffff;
  position: sticky;
  top: 0;
  z-index: 100;
}

/* Discipline accent stripe — sits below the header, travels with it.
   Replaces the old .category-header border-top so there is no double line. */
body[data-discipline="xt"] .site-header { border-bottom: 4px solid #5B3A8C; }
body[data-discipline="us"] .site-header { border-bottom: 4px solid #2C4A7C; }
body[data-discipline="pm"] .site-header { border-bottom: 4px solid #2D5F3F; }
body[data-discipline="id"] .site-header { border-bottom: 4px solid #B8753C; }

/* Opening — gated by `nav-zone.js`, which adds .nav-switch to <html>
   only when this page's nav variant differs from the previous page's.
   There are four variants (home / about / notfound / main course); moving
   between two of them swaps the links, and the entrance is what keeps that
   swap from reading as a glitch. Moving within the main course — discipline
   index to case, case to case — changes nothing in the nav, so nothing moves.
   See nav-zone.js for the full reasoning and the no-JS fallback.

   The sticky element itself is never transformed (that would fight
   position: sticky); only its contents move. Same rise, same curve as
   every other entrance on the site. */
html.nav-switch .site-header .container > div:first-child > *,
html.nav-switch .site-header nav > * {
  opacity: 0;
  animation: up .6s cubic-bezier(.22, 1, .36, 1) forwards;
}
html.nav-switch .site-header .container > div:first-child > * { animation-delay: .04s; }
html.nav-switch .site-header nav > *            { animation-delay: .28s; }  /* 6th link onward */
html.nav-switch .site-header nav > :nth-child(1){ animation-delay: .10s; }
html.nav-switch .site-header nav > :nth-child(2){ animation-delay: .145s; }
html.nav-switch .site-header nav > :nth-child(3){ animation-delay: .19s; }
html.nav-switch .site-header nav > :nth-child(4){ animation-delay: .235s; }
html.nav-switch .site-header nav > :nth-child(5){ animation-delay: .28s; }
@media (prefers-reduced-motion: reduce) {
  html.nav-switch .site-header .container > div:first-child > *,
  html.nav-switch .site-header nav > * { opacity: 1; animation: none; }
}

.site-header .container {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.site-header .brand {
  font-size: var(--text-lead);
  font-weight: var(--weight-medium);   /* was 600 — off the 3-weight scale, and heavier
                                          than anything else on the page after the v4 pass */
  letter-spacing: 0;
}

.site-header .brand-secondary {
  font-family: var(--font-mono);       /* same technical-label register as the home role line
                                          and the category eyebrows */
  font-size: var(--text-small);
  letter-spacing: 0.1em;
  color: #6e6e6e;
  margin-left: 14px;
  font-weight: 400;
}

.site-header nav a,
.site-header nav .nav-disabled {
  font-size: var(--text-meta);
  margin-left: 32px;
  color: #444;
}

.site-header nav a:hover {
  color: #000;
}

.site-header nav a.active {
  color: #000;
  border-bottom: 1px solid #000;
  padding-bottom: 4px;
}

.site-header nav a.external::after {
  content: " ↗";
  color: #aaa;
  font-size: var(--text-micro);
}

.site-header nav .nav-disabled {
  color: #b3b3b3;
  cursor: default;
}

.site-header nav .nav-disabled .soon {
  font-size: var(--text-micro);
  color: #c47a00;
  margin-left: 6px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 2px;
}

/* ============================================================
   CASE STUDY PAGE
   ============================================================ */
.case-hero {
  padding: 60px 0 40px;
}

.case-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #666;
  margin-bottom: 16px;
}

.case-title {
  font-size: var(--text-display);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 16px;
}

.case-tagline {
  font-size: var(--text-lead);
  font-weight: var(--weight-light);
  color: #444;
  max-width: 720px;
  line-height: 1.6;
  margin-bottom: 40px;
}

.case-hero-image {
  background: #f2f2f2;
  border: 1px dashed #c8c8c8;
  aspect-ratio: 16 / 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #aaa;
  font-size: var(--text-small);
  text-align: center;
  padding: 24px;
  margin-bottom: 40px;
}

.case-hero-image .thumb-spec {
  font-size: var(--text-micro);
  font-family: ui-monospace, "SF Mono", monospace;
  margin-top: 8px;
}

.case-hero-image .thumb-need {
  font-size: var(--text-micro);
  color: #2D5F3F;
  margin-top: 4px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.case-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding: 32px 0;
  border-top: 1px solid #ececec;
  border-bottom: 1px solid #ececec;
  margin-bottom: 80px;
}



/* Section wrapper */
.case-section {
  padding: 80px 0;
  border-top: 1px solid #ececec;
}

.case-section-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #666;
  margin-bottom: 8px;
}

.case-section-title {
  font-size: var(--text-section);
  font-weight: 300;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}

.case-section-intro {
  font-size: var(--text-body);
  color: #555;
  line-height: 1.7;
  max-width: 720px;
  margin-bottom: 48px;
}

/* Interactive note callout (你不用準備素材，由我做) */
.web-render-note {
  display: inline-block;
  background: #eff6ff;
  border: 1px solid #c7d2fe;
  color: #3949ab;
  font-size: var(--text-micro);
  padding: 4px 10px;
  border-radius: 3px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 16px;
}

.asset-needed-note {
  display: inline-block;
  background: #fffbeb;
  border: 1px solid #fde68a;
  color: #92400e;
  font-size: var(--text-micro);
  padding: 4px 10px;
  border-radius: 3px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 16px;
}

/* AEIOU Grid */
.aeiou-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
}

.aeiou-cell {
  border: 1px solid #ececec;
  border-radius: 4px;
  overflow: hidden;
  background: #fafafa;
}

.aeiou-cell summary {
  padding: 20px 16px;
  cursor: pointer;
  list-style: none;
  text-align: center;
}

.aeiou-cell summary::-webkit-details-marker {
  display: none;
}

.aeiou-cell .letter {
  font-size: var(--text-section);
  font-weight: 300;
  color: #2C4A7C;
  line-height: 1;
  margin-bottom: 8px;
}

.aeiou-cell .label {
  font-size: var(--text-small);
  font-weight: 500;
  letter-spacing: 0.04em;
}

.aeiou-cell .hint {
  font-size: var(--text-micro);
  color: #aaa;
  margin-top: 4px;
  letter-spacing: 0.04em;
}

.aeiou-cell[open] {
  background: #ffffff;
}

.aeiou-cell[open] summary {
  border-bottom: 1px solid #ececec;
}

.aeiou-cell .body {
  padding: 16px;
  font-size: var(--text-small);
  line-height: 1.6;
  color: #444;
}

.aeiou-cell .body ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.aeiou-cell .body li {
  padding: 4px 0;
  border-bottom: 1px dashed #ececec;
}

.aeiou-cell .body li:last-child {
  border-bottom: none;
}

/* Insights cards (5 cards) */
.insights-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
}

.insight-card {
  padding: 24px 20px;
  border: 1px solid #ececec;
  border-radius: 4px;
  background: #fafafa;
}

.insight-card .icon {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #2C4A7C;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-meta);
  margin-bottom: 14px;
}

.insight-card h4 {
  font-size: var(--text-meta);
  font-weight: var(--weight-medium);
  margin-bottom: 6px;
}

.insight-card p {
  font-size: var(--text-micro);
  color: #555;
  line-height: 1.6;
}

/* Image / scene */
.case-fig {
  background: #f2f2f2;
  border: 1px dashed #c8c8c8;
  aspect-ratio: 16 / 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #aaa;
  font-size: var(--text-micro);
  padding: 16px;
  text-align: center;
  margin: 24px 0;
}

/* Pull quote */
.pullquote {
  border-left: 3px solid #2C4A7C;
  padding: 8px 0 8px 24px;
  margin: 32px 0;
  font-size: var(--text-lead);
  line-height: 1.5;
  color: #1a1a1a;
  font-style: italic;
}

.pullquote cite {
  display: block;
  font-size: var(--text-micro);
  color: #666;
  margin-top: 12px;
  font-style: normal;
  letter-spacing: 0.04em;
}

/* Process gallery (4-photo grid) */
.process-gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}

.process-fig {
  background: #f2f2f2;
  border: 1px dashed #c8c8c8;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #aaa;
  font-size: var(--text-micro);
  text-align: center;
  padding: 8px;
}

/* Testing gallery */
.testing-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

/* ============================================================
   ID CASE STUDY (Diana Chang style)
   Image-driven, generous whitespace, minimal text.
   For E.Jet, Midnight Hour, Liang-Zhu Jewelry.
   ============================================================ */

/* Full-bleed hero (breaks out of .container, spans viewport).
   Aspect-locked to 16:9 so the section never has empty area below the
   image. Hero source images all target 16:9 per ASSETS_GUIDE; any source
   with mismatched aspect gets center-cropped via object-fit: cover. */
.case-hero-fullbleed {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  position: relative;
  background: #1a1a1a;
  aspect-ratio: 16 / 9;
  max-height: 80vh;
  overflow: hidden;
}

.case-hero-fullbleed img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: 50% 23%;  /* default: upper bias (works for E.Jet / Liang-Zhu) */
}

/* Opening — the hero settles in on the home page's curve and timing.
   Only the hero: it is the one element a visitor meets before scrolling,
   so it carries the entrance and the rest of the page stays still. */
.case-hero-fullbleed img,
.case-hero-fullbleed svg,
.case-hero-fullbleed video {
  animation: hero-in 1.8s cubic-bezier(.22, 1, .36, 1) .05s both;
}
@keyframes hero-in {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .case-hero-fullbleed img,
  .case-hero-fullbleed svg,
  .case-hero-fullbleed video { animation: none; opacity: 1; }
}

/* Per-image tone correction — Midnight PU model images had blown
   highlights after browser downscaling. Slight brightness/contrast
   correction restores material texture without affecting hue. */
.crop-frame img[src*="case-midnight/04-product-detail"],
.crop-frame img[src*="case-midnight/06-pu-catkins"] {
  filter: brightness(0.94) contrast(1.06);
}

/* Per-case hero object-position overrides — keep each case's preferred
   anchor on its own selector so global never gets polluted by per-page
   tuning (lesson learned 2026-05-12 from the calc(30% - 65px) leak). */
.case-hero-fullbleed img[src*="case-armaspeed"] {
  object-position: 50% 100%;  /* bottom-aligned: lock to rear lower diffuser */
}
.case-hero-fullbleed img[src*="case-washenjoy"] {
  object-position: 50% 52%;   /* anchor mid-low: pulled back halfway from 80% */
}
.case-hero-fullbleed img[src*="case-midnight"] {
  object-position: 50% 65%;   /* anchor low: reveal woman's hand and wine glass */
}
.case-hero-fullbleed img[src*="case-footwear"] {
  object-position: 50% 50%;   /* centered: source is already cropped to 16:9 focal */
}

/* Scaffold placeholder block — TBD diagram / triptych regions in case pages.
   Shows dashed-bordered "waiting for asset" state during scaffolding phase.
   Remove or repurpose once final visuals land. */
.placeholder-block {
  aspect-ratio: 16 / 9;
  background: #f5f5f7;
  border: 1px dashed #c8c8d0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #666;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--text-small);
  letter-spacing: 0.04em;
  margin: 48px 0;
  border-radius: 4px;
}

/* Title block placed below hero */
.case-intro {
  padding: 64px 0 48px;
}

.case-intro .case-eyebrow {
  margin-bottom: 18px;
}

.case-intro .case-title {
  font-size: var(--text-display);
  font-weight: 300;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: 24px;
}

.case-intro .case-title .ch {
  font-size: 0.5em;
  color: #666;
  font-weight: 400;
  margin-left: 12px;
  letter-spacing: 0.02em;
}

.case-intro .case-tagline {
  font-size: var(--text-lead);
  font-weight: var(--weight-light);
  color: #444;
  max-width: 640px;
  line-height: 1.6;
}

/* Meta bar (one-line strip below intro) */
.case-meta-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding: 28px 0;
  border-top: 1px solid #ececec;
  border-bottom: 1px solid #ececec;
  margin-bottom: 96px;
}
@media (max-width: 760px) {
  .case-meta-bar { grid-template-columns: repeat(2, 1fr); gap: 20px 18px; margin-bottom: 64px; }
}
@media (max-width: 480px) {
  .case-meta-bar { grid-template-columns: 1fr; gap: 18px; padding: 22px 0; margin-bottom: 48px; }
}
.case-meta-bar .meta-item .label {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: #666;
  margin-bottom: 6px;
}
.case-meta-bar .meta-item .value {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: #1a1a1a;
}

/* Story section — image first, then text aligned with whitespace */
.story-section {
  padding: 64px 0 96px;
}

.story-section + .story-section {
  border-top: 1px solid #f0f0f0;
}

/* ============================================================
   Dark immersive modifier — Apple-style cinematic section.
   Full-bleed dark bg using box-shadow + clip-path trick so the
   section stays at container width but the background extends
   to viewport edges. Use sparingly — one per case maximum.
   ============================================================ */
.story-section--dark {
  position: relative;
  background: #0a0a0a;
  color: #d4d4d4;
  padding: 96px 0;
  border-top: none !important;
  box-shadow: 0 0 0 100vmax #0a0a0a;
  clip-path: inset(0 -100vmax);
}

.story-section--dark + .story-section {
  border-top: none;
}

.story-section--dark .story-heading,
.story-section--dark h2.story-heading {
  color: #ffffff;
}

.story-section--dark .story-eyebrow {
  color: #a7a7a7;
}

.story-section--dark .story-body,
.story-section--dark .story-body p {
  color: #d4d4d4;
}

.story-section--dark .case-image-caption {
  color: #a7a7a7;
}




/* Footwear §03 trio uses .boot-caption for product spec lines.
   Default is #555 on white — needs lift on dark bg. */
.story-section--dark .boot-caption {
  color: #c8c8c8;
}

.story-section--dark .boot-caption strong {
  color: #ffffff;
}

.story-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #666;
  margin-bottom: 8px;
}

.story-heading {
  font-size: var(--text-section);
  font-weight: 300;
  letter-spacing: -0.01em;
  margin-bottom: 20px;
}

.story-body {
  font-size: var(--text-body);
  line-height: 1.75;
  color: #2a2a2a;
  max-width: 640px;
  margin-bottom: 48px;
}

.story-body p + p { margin-top: 16px; }

/* ============================================================
   Numbered-section pattern (used by case-footwear.html)
   Variant of .story-* with a monospace numerical eyebrow.
   Visual treatment matches .story-heading / .story-body so
   numbered cases share the same headline rhythm as the rest
   of the site — the only addition is the §01 number prefix.
   ============================================================ */




/* Single image, full container width */
.case-image {
  margin: 0 0 24px;
}
.case-image img,
.case-image video {
  width: 100%;
  height: auto;
  display: block;
}

/* Image with caption */
.case-image-caption {
  margin-top: 12px;
  font-size: var(--text-micro);
  color: #666;
  letter-spacing: 0.04em;
  font-style: italic;
}

/* External commercial product link — used in case studies for "View live product" */
.product-link {
  display: inline-block;
  margin-top: 8px;
  font-size: var(--text-meta);
  font-weight: var(--weight-medium);
  color: #B8753C;          /* ID amber, ties to Industrial Design domain */
  letter-spacing: 0.02em;
  font-style: normal;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.product-link:hover {
  color: #5B3A8C;          /* XT purple on hover */
}

/* Step caption — for numbered process steps in a grid (e.g. ARMASPEED 6 steps).
   Body-tier readable text, NOT caption-tier (which is for short attribution).
   The <strong> lead block sits on its own line as a mini-heading. */
.step-caption {
  margin-top: 12px;
  font-size: var(--text-meta);
  color: #2a2a2a;
  line-height: 1.55;
  letter-spacing: 0;
  font-style: normal;
}
.step-caption strong {
  display: block;
  margin-bottom: 4px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.02em;
  color: #1a1a1a;
}

/* Crop spec — dev hint, recommends Vizcom output ratio for each image.
   Visible to project owner during build, removable before launch.
   Vizcom ratios: Landscape 16:9 / Standard 5:4 / Square 1:1 / Portrait 4:5 / Vertical 9:16 */
.crop-spec {
  margin-top: 6px;
  margin-bottom: 4px;
  font-size: var(--text-micro);
  color: #b8860b;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.02em;
  background: #fffbeb;
  padding: 3px 8px;
  display: inline-block;
  border-radius: 2px;
  border: 1px solid #f3e6b5;
}

.crop-spec.section-spec {
  margin-bottom: 12px;
  margin-top: 0;
}

/* === Crop-frame system ===
   Wrap any <img> in <div class="crop-frame crop-XxY"> to enforce
   a target aspect ratio with object-fit: cover. Lets the page show
   the FINAL cropped look even when source files are uncropped/
   low-res. */
.crop-frame {
  width: 100%;
  overflow: hidden;
  background: #e8e8e8;
  display: block;
}
.crop-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.crop-16x9 { aspect-ratio: 16 / 9; }
.crop-4x5  { aspect-ratio: 4 / 5; }
.crop-2x3  { aspect-ratio: 2 / 3; }
.crop-1x1  { aspect-ratio: 1 / 1; }
.crop-5x4  { aspect-ratio: 5 / 4; }
.crop-4x3  { aspect-ratio: 4 / 3; }
.crop-3x2  { aspect-ratio: 3 / 2; }

/* Per-image visual correction: when Gemini accidentally renders a thick
   comic-panel border inside the image itself, scale the image up so the
   border gets cropped by the frame's overflow:hidden. */
.panel-overscale img {
  transform: scale(1.08);
  transform-origin: center center;
}

/* Storyboard grid — shared pattern across cases with 6-panel storyboards
   (case-night-market, case-washenjoy, case-gongxin). Cream card with image
   (1:1) and a figcaption below carrying a mono-label + a short description.
   No code-drawn borders on the image; if a panel needs a visible border it
   comes from the asset itself. Promoted from case-night-market case-local
   on 2026-05-18 so all 6-panel storyboards share one hand. */
.storyboard {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  max-width: 1100px;
  margin: 48px auto 24px;
}
.story-panel {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: #faf6ee;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #ccc;
}
.story-panel img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.story-panel figcaption {
  flex: 1;
  min-height: 64px;
  padding: 12px 14px 14px;
  font-size: var(--text-small);
  color: #555;
  line-height: 1.5;
  background: #faf6ee;
  border-top: 1px solid #eee2d0;
}
.story-panel figcaption strong {
  display: block;
  color: #1a1a1a;
  font-weight: var(--weight-medium);
  font-size: var(--text-meta);
  margin-bottom: 3px;
  letter-spacing: 0.02em;
}
@media (max-width: 880px) {
  .storyboard { grid-template-columns: repeat(2, 1fr); }
}

/* Storyboard — tall portrait, capped width, centered (no crop) */
.storyboard-frame {
  max-width: 480px;
  margin: 0 auto 24px;
}
.storyboard-frame img {
  width: 100%;
  height: auto;
  display: block;
}

/* Storyboard wide — square/landscape comic set displayed as centerpiece */
.storyboard-frame-wide {
  max-width: 720px;
  margin: 0 auto 24px;
}
.storyboard-frame-wide img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}

/* Mechanism diptych — asymmetric side-by-side at native aspects.
   Used when two images of mismatched aspect (e.g., 4:5 portrait
   labeled-diagram + 9:16 tall pour-cross-section) need to share a
   row at equal height without AI background extension. Column
   widths are tuned so both images render at the same height. */
.mechanism-diptych {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  justify-content: center;
  max-width: 820px;
  margin: 0 auto 24px;
}
.mechanism-diptych > div {
  flex: 0 0 auto;
}
.mechanism-diptych img {
  width: 100%;
  height: auto;
  display: block;
}
.mechanism-diptych .mech-side {
  width: 61%;
}
.mechanism-diptych .pour-side {
  width: 39%;
}

/* Centered-image utilities — vary max-width to control display weight
   while preserving each image's native aspect (no forced crop). */
.case-image-narrow {
  max-width: 520px;
  margin: 0 auto 24px;
}
.case-image-narrow img {
  width: 100%;
  height: auto;
  display: block;
}
.case-image-medium {
  max-width: 540px;
  margin: 0 auto 24px;
}
.case-image-medium img {
  width: 100%;
  height: auto;
  display: block;
}
.case-image-tall {
  max-width: 380px;
  margin: 0 auto 24px;
}
.case-image-tall img {
  width: 100%;
  height: auto;
  display: block;
}

/* Magazine spread — yearbook-style 2-column layout for studio shots.
   Per portfolio-skill.txt: left cells stay strict Square 1:1.
   Right hero stretches to fit the left stack's total height (2L + gap),
   absorbing the 16px gap as a ~1.3% portrait deviation — invisible to
   the eye but keeps the visual rhythm: 16px gap everywhere. */
.studio-spread {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 16px;
  margin: 0 0 24px;
  align-items: stretch;
}
.studio-spread-left {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 16px;
}
.studio-spread-right > .crop-frame {
  aspect-ratio: auto;
  height: 100%;
}

/* Asset status panel — dev-mode summary, removable for final */
.asset-status {
  margin: 48px 0 24px;
  padding: 20px 24px;
  background: #fffbeb;
  border: 1px solid #f3e6b5;
  border-radius: 4px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--text-micro);
  color: #5a4a1a;
  letter-spacing: 0.02em;
}
.asset-status h4 {
  margin: 0 0 12px;
  font-size: var(--text-meta);
  color: #b8860b;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 700;
}
.asset-status ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.asset-status li {
  display: flex;
  gap: 12px;
  align-items: baseline;
}
.asset-status .badge {
  display: inline-block;
  min-width: 60px;
  padding: 1px 8px;
  border-radius: 2px;
  font-weight: 700;
  font-size: var(--text-micro);
  text-align: center;
  letter-spacing: 0.06em;
}
.asset-status .badge.ok     { background: #d4edda; color: #155724; }
.asset-status .badge.crop   { background: #fff3cd; color: #856404; }
.asset-status .badge.renew  { background: #f8d7da; color: #721c24; }
.asset-status .badge.remove { background: #e2e3e5; color: #383d41; }

/* Diptych — 2 images side by side */
.case-diptych {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 0 0 24px;
}
.case-diptych > img {
  width: 100%;
  height: auto;
  display: block;
}

/* 2x2 grid */
.case-grid-2x2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 0 0 24px;
}
.case-grid-2x2 > img {
  width: 100%;
  height: auto;
  display: block;
}

/* 1x3 horizontal grid */
.case-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0 0 24px;
}
.case-grid-3 > img {
  width: 100%;
  height: auto;
  display: block;
}

/* Build grid — narrower than full 3-col to keep 2014 photos at native res */
.case-grid-3-narrow {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0 auto 24px;
  max-width: 780px;
}

/* Act row — image-text side-by-side, used for narrative sub-blocks
   like the Liang-Zhu Three Acts section. Square images sit naturally
   at ~40% container width; text breathes at ~50%. Alternate direction
   per row for editorial rhythm using the .reverse modifier. */
.act-row {
  display: grid;
  grid-template-columns: minmax(280px, 0.85fr) 1fr;
  gap: 56px;
  align-items: center;
  margin: 56px 0;
}
.act-row.reverse {
  grid-template-columns: 1fr minmax(280px, 0.85fr);
}
.act-row.reverse .case-image {
  order: 2;
}
.act-row.reverse .story-body {
  order: 1;
}
.act-row .case-image {
  margin: 0;
}
.act-row .story-body {
  max-width: none;
  margin-bottom: 0;
}

/* Pull text — large quotation style */
.case-pull-text {
  font-size: var(--text-section);
  line-height: 1.45;
  letter-spacing: -0.01em;
  font-weight: 300;
  color: #1a1a1a;
  max-width: 760px;
  margin: 32px 0 48px;
}

/* Material list (for Midnight Hour mechanism explanation) */
.spec-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px 48px;
  margin: 32px 0;
  max-width: 640px;
}
.spec-list dt {
  font-size: var(--text-small);
  font-weight: var(--weight-medium);
  color: #1a1a1a;
  margin-bottom: 4px;
  letter-spacing: 0.02em;
}
.spec-list dd {
  font-size: var(--text-small);
  color: #555;
  line-height: 1.55;
}


/* ============================================================
   HOME (v4 · Axis) — one solid, three views
   The three disciplines are orthographic projections of the same
   body; hovering one turns the solid until it reads as that shape.
   Homepage-only rules are namespaced `home-` so nothing here can
   reach the case pages.
   ============================================================ */
.home-hero{
  --line:#c2c2c2; --rule:#e2e2e2;
  --c-ux:#2C4A7C; --c-pm:#2D5F3F; --c-id:#B8753C; --c-xt:#5B3A8C;
  --col-split:1.06fr .94fr; --col-gap:72px; --mark-size:460px; --row-pad:20px;
max-width:1200px;margin:0 auto;padding:56px 48px;min-height:calc(100vh - 182px);
  display:grid;grid-template-columns:var(--col-split);gap:var(--col-gap);align-items:center}

/* header wordmark yields to the hero on the homepage, returns on scroll */
.brandblock{opacity:0;transform:translateY(-4px);pointer-events:none;
  transition:opacity .45s ease,transform .45s ease}      /* fades in once the hero name scrolls away */
.brandblock.show{opacity:1;transform:none;pointer-events:auto}

/* ---------- left: the type column ---------- */
.home-lede>*{opacity:0;animation:up .8s cubic-bezier(.22,1,.36,1) forwards}
.home-name{font-size:var(--text-display);font-weight:var(--weight-light);letter-spacing:-.025em;line-height:1.02;animation-delay:.10s}
.home-role{margin-top:16px;font-family:var(--font-mono);font-size:var(--text-small);
  letter-spacing:.22em;text-transform:uppercase;color:#6e6e6e;animation-delay:.20s}
.home-epigraph{margin-top:30px;max-width:560px;animation-delay:.32s}
.home-epigraph blockquote p{font-size:var(--text-lead);font-weight:var(--weight-light);line-height:1.65;color:#2a2a2a}
.home-epigraph figcaption{margin-top:12px;font-size:var(--text-small);color:#6e6e6e}
.home-epigraph figcaption cite{font-style:italic}
@keyframes up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

.home-list{margin-top:44px;border-top:1px solid var(--rule)}
.home-row{display:grid;grid-template-columns:34px 1fr auto;align-items:baseline;column-gap:16px;
  padding:var(--row-pad) 4px;border-bottom:1px solid var(--rule);
  opacity:0;animation:up .8s cubic-bezier(.22,1,.36,1) forwards;
  transition:padding-left .45s cubic-bezier(.22,1,.36,1)}
.r-ux{animation-delay:.62s} .r-pm{animation-delay:.76s} .r-id{animation-delay:.90s}
.home-row .home-idx{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.1em;color:#6e6e6e;transition:color .35s ease}
.home-row .home-label{font-size:var(--text-section);font-weight:var(--weight-light);letter-spacing:-.01em;
  color:#3a3a3a;line-height:1.15;white-space:nowrap;transition:color .35s ease}
.home-row .home-keys{grid-column:2;font-size:var(--text-small);letter-spacing:.04em;color:#6e6e6e;
  margin-top:6px;opacity:0;transform:translateY(4px);
  transition:opacity .4s ease,transform .4s cubic-bezier(.22,1,.36,1)}
.home-row .home-arrow{grid-row:1;grid-column:3;font-size:var(--text-meta);color:#c8c8c8;opacity:0;
  transform:translateX(-6px);transition:opacity .35s ease,transform .35s ease,color .35s ease}
.home-row:hover,.home-row:focus-visible{padding-left:16px}
.home-row:hover .home-keys,.home-row:focus-visible .home-keys,.home-row:hover .home-arrow,.home-row:focus-visible .home-arrow{opacity:1;transform:none}
.r-ux:hover .home-label,.r-ux:hover .home-arrow,.r-ux:hover .home-idx,.r-ux:focus-visible .home-label{color:var(--c-ux)}
.r-pm:hover .home-label,.r-pm:hover .home-arrow,.r-pm:hover .home-idx,.r-pm:focus-visible .home-label{color:var(--c-pm)}
.r-id:hover .home-label,.r-id:hover .home-arrow,.r-id:hover .home-idx,.r-id:focus-visible .home-label{color:var(--c-id)}

/* ---------- right: one solid, three views ---------- */
.home-markwrap{justify-self:center;text-align:center;width:100%;max-width:var(--mark-size)}
.home-mark{display:block;position:relative;width:100%;aspect-ratio:1/1;margin:0 auto;cursor:pointer;
  pointer-events:none}                                   /* only the solid itself is hittable ↓ */
.home-mark svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
/* 判定區固定不動。以前是把 #home-hull（每一幀重算的輪廓）當作滑鼠目標，
   立體一轉，作用範圍就跟著飄。現在改由 #home-hit 負責：它的形狀是「靜止姿態
   的輪廓」，在初始化時算一次就凍結，之後立體怎麼轉都不動它。 */
#home-hit{fill:transparent;pointer-events:auto;cursor:pointer}
#home-hull{fill:transparent;pointer-events:none;stroke-width:2;stroke-linejoin:round;
  transition:stroke .5s cubic-bezier(.22,1,.36,1)}
#home-base,#home-top,#home-rules{fill:none;stroke-width:1;stroke-linecap:round;transition:stroke .5s cubic-bezier(.22,1,.36,1)}
/* the idle hint: a grey arc that runs the silhouette every few seconds.
   Greyscale on purpose — it must read as light on an edge, not as a colour cue. */
#home-glint{fill:none;stroke:#8a8a8a;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;
  opacity:0;pointer-events:none}
@media (prefers-reduced-motion: reduce){ #home-glint{display:none} }

/* the hub label carries the same weight as a discipline title, so it reads as one of them */
.home-hub{display:inline-block;position:relative;margin-top:10px;
  opacity:0;animation:fadein .65s ease 1.02s forwards}
@keyframes fadein{from{opacity:0}to{opacity:1}}
.home-hub .home-hub-name,.home-hub .home-hub-full{display:block;font-size:var(--text-section);
  font-weight:var(--weight-light);letter-spacing:-.01em;line-height:1.15;white-space:nowrap;
  transition:opacity .3s ease,transform .35s cubic-bezier(.22,1,.36,1),color .4s ease}
.home-hub .home-hub-name{color:#3a3a3a}
.home-hub .home-hub-full{position:absolute;left:50%;top:0;opacity:0;color:var(--c-xt);
  transform:translate(-50%,6px)}
.home-hub::before{content:"";position:absolute;inset:-14px -24px}
.home-hub:hover .home-hub-name,.home-hub:focus-visible .home-hub-name{opacity:0;transform:translateY(-6px)}
.home-hub:hover .home-hub-full,.home-hub:focus-visible .home-hub-full{opacity:1;transform:translate(-50%,0)}
/* the solid is part of the same target — you find the button by pointing at the object */
.home-markwrap:has(.home-mark:hover) .home-hub-name{opacity:0;transform:translateY(-6px)}
.home-markwrap:has(.home-mark:hover) .home-hub-full{opacity:1;transform:translate(-50%,0)}

.home-caption{margin-top:12px;font-family:var(--font-mono);font-size:var(--text-micro);
  letter-spacing:.18em;text-transform:uppercase;color:#6e6e6e;
  opacity:0;animation:fadein .65s ease 1.20s forwards;transition:color .4s ease}

@media (prefers-reduced-motion: reduce){
  .home-lede>*,.home-row,.home-hub,.home-caption{opacity:1;animation:none}
}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}

@media (prefers-reduced-motion: reduce){
  .home-lede>*,.home-row,.home-hub,.home-caption{opacity:1;animation:none}
}


/* ============================================================
   TOAST NOTIFICATION (Medium · Coming Soon)
   ============================================================ */
.toast {
  position: fixed;
  top: 24px;
  right: 32px;
  background: #1a1a1a;
  color: #ffffff;
  padding: 14px 22px;
  border-radius: 4px;
  font-size: var(--text-small);
  letter-spacing: 0.02em;
  line-height: 1.4;
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
  z-index: 1000;
  box-shadow: 0 4px 20px rgba(0,0,0,0.12);
  min-width: 220px;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

.toast strong {
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
}

.toast .toast-sub {
  display: block;
  font-size: var(--text-micro);
  color: #aaa;
  margin-top: 4px;
  letter-spacing: 0.02em;
}

/* ============================================================
   LANDING — Hero & Venn
   ============================================================ */
.hero {
  padding: 80px 0 40px;
  text-align: center;
}

.hero h1 {
  font-size: var(--text-section);
  font-weight: var(--weight-light);
  max-width: 720px;
  margin: 0 auto 16px;
  letter-spacing: -0.01em;
  line-height: 1.4;
}

.hero .workflow {
  font-size: var(--text-meta);
  color: #666;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 60px;
}

/* ============================================================
   CATEGORY PAGE
   ============================================================ */
.category-header {
  padding: 60px 0 40px;
  border-bottom: 1px solid #ececec;
}

.category-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #666;
  margin-bottom: 12px;
}

.category-title {
  font-size: var(--text-page);
  font-weight: 300;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}

/* a second paragraph under a page title (e.g. a pull quote) needs air */
.category-desc + .category-desc {
  margin-top: 22px;
}

.category-desc {
  font-size: var(--text-body);
  color: #555;
  max-width: 640px;
  line-height: 1.7;
}

/* 類別色帶 (subtle accent) */
/* Discipline accent moved to sticky .site-header bottom-border (see top of file).
   The .us / .pm / .id / .xt classes remain on .category-header for any future
   per-discipline hero styling, but the visible color stripe is now in the header. */

/* ============================================================
   WORK GRID
   ============================================================ */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 40px 32px;
  padding: 60px 0 100px;
}

.work-grid.cols-2 {
  grid-template-columns: repeat(2, 1fr);
}

.work-grid.cols-1 {
  grid-template-columns: 1fr;
  max-width: 720px;
  margin: 0 auto;
}

/* Work Card */
.work-card {
  display: flex;
  flex-direction: column;
  cursor: pointer;
}

.work-card .thumb {
  background: #f2f2f2;
  border: 1px dashed #c8c8c8;
  aspect-ratio: 4 / 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #aaa;
  font-size: var(--text-micro);
  padding: 16px;
  text-align: center;
  margin-bottom: 16px;
}

.work-card .thumb-spec {
  font-size: var(--text-micro);
  color: #6a6a6a;
  margin-top: 8px;
  font-family: ui-monospace, "SF Mono", monospace;
}

.work-card .thumb-need {
  font-size: var(--text-micro);
  color: #c47a00;
  margin-top: 4px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.work-card .thumb-need.ready {
  color: #2D5F3F;
}

.work-card .thumb-need.photo {
  color: #555;
}

.work-card h2 {
  font-size: var(--text-lead);
  font-weight: 500;
  margin-bottom: 4px;
  letter-spacing: -0.01em;
}

/* WIP / In Progress pill — orange-red status badge floating to the right
   of the card title. Visual lineage: case-ar-maze .iter-tag. */
.work-card .title-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 4px;
}
.work-card .title-row h3 {
  margin-bottom: 0;
}
.work-card .wip-badge {
  display: inline-block;
  padding: 3px 11px;
  background: #fff0e8;
  border: 1px solid #f0c4b4;
  border-radius: 14px;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.12em;
  color: #c5371a;
  white-space: nowrap;
  text-transform: uppercase;
}

.work-card .subtitle {
  font-size: var(--text-small);
  color: #777;
  margin-bottom: 10px;
}

.work-card .hook {
  font-size: var(--text-meta);
  color: #444;
  line-height: 1.5;
  margin-bottom: 12px;
  min-height: 42px;
}

.work-card .meta {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  font-size: var(--text-micro);
  color: #666;
  letter-spacing: 0.04em;
}

.work-card .year {
  color: #aaa;
  font-family: ui-monospace, "SF Mono", monospace;
}

/* Tag dots (圈別色點) */
.tag-dots {
  display: inline-flex;
  gap: 4px;
  margin-right: 8px;
}

.tag-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid;
}

.tag-dot.us  { background: #2C4A7C; border-color: #2C4A7C; }
.tag-dot.pm  { background: #2D5F3F; border-color: #2D5F3F; }
.tag-dot.id  { background: #B8753C; border-color: #B8753C; }
.tag-dot.xt  { background: #5B3A8C; border-color: #5B3A8C; }

/* 頁級比例修飾符（每頁內統一比例） */
.work-grid.thumbs-16-10 .work-card .thumb {
  aspect-ratio: 16 / 10;
}

.work-grid.thumbs-4-3 .work-card .thumb {
  aspect-ratio: 4 / 3;
}

/* Tier 1 強調僅作用於標題大小（不再改變縮圖比例） */
.work-card.tier-1 h3 {
  font-size: var(--text-lead);
}

/* Card with real image (replaces dashed placeholder) */
.work-card .thumb.has-image {
  border: none;
  background: #f5f5f5;
  padding: 0;
  overflow: hidden;
  position: relative;
  display: block;
}
.work-card .thumb.has-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.work-card a:hover .thumb.has-image img {
  transform: scale(1.03);
}
.work-card a {
  color: inherit;
  text-decoration: none;
  display: block;
}

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  border-top: 1px solid #ececec;
  padding: 40px 0;
  font-size: var(--text-small);
  color: #666;
}

.footer-sep { color: #6e6e6e; }

.site-footer .container {
  display: flex;
  justify-content: space-between;
}

/* ============================================================
   PROTOTYPE NOTE BANNER
   ====================

/* === A11y utilities ============================================ */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: #5B3A8C;
  color: #fff;
  padding: 8px 16px;
  z-index: 200;
  text-decoration: none;
  font-size: 13px;
  font-family: var(--font-mono);
}
.skip-link:focus {
  left: 16px;
  top: 16px;
}
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* === Discipline note: closing explainer block on category pages ====
   Replaces inline style="" overrides previously hand-rolled on
   product-management.html and xtdesign.html.
   ================================================================== */
.discipline-note {
  padding: 0 0 100px;
  max-width: 720px;
  color: #666;
  font-size: var(--text-small);
  line-height: 1.7;
}
.discipline-note--bordered {
  margin: 40px auto 0;
  color: #5B3A8C;
  border-top: 1px solid #e8e2f0;
  padding-top: 32px;
}
.discipline-note__caption {
  color: #666;
  margin-top: 8px;
}

/* ============================================================
   §about — About page
   Two-column biographical page (Diana Chang–style): body text on
   the left, a square portrait on the right. Contact line spans full
   width below. No page-level h1 — the site header carries the name.
   ============================================================ */
.about-page {
  max-width: 1200px;              /* same rail as the header and every other page */
  margin: 64px auto 96px;
  padding: 0 48px;
}
.about-page .about-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #6e6e6e;
  /* sits in row 1 of the grid; row-gap handles spacing to the body */
  grid-column: 1;
  grid-row: 1;
  margin: 0;
}
.about-page .about-layout {
  display: grid;
  grid-template-columns: 1fr 340px;
  grid-template-rows: auto auto;
  column-gap: 56px;
  row-gap: 28px;
  align-items: start;
}
.about-page .about-body {
  grid-column: 1;
  grid-row: 2;
}
.about-page .about-photo {
  width: 340px;
  overflow: hidden;
  background: #f0ebe0;
  /* sits only in row 2 (next to body); align-self stretches the photo
     to match the body text column's full top–bottom height. */
  grid-column: 2;
  grid-row: 2;
  align-self: stretch;
  min-height: 0;
}
.about-page .about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.about-page .about-body p {
  font-size: var(--text-body);
  line-height: 1.75;
  color: #2a2a2a;
  margin: 0 0 22px;
  max-width: 62ch;                /* the rail widened; the measure did not */
}
.about-page .about-body p:first-child {
  margin-top: 0;
}
.about-page .about-body p:last-child {
  margin-bottom: 0;
}
.about-page .about-contact {
  margin-top: 56px;
  padding-top: 28px;
  border-top: 1px solid #ececec;
  font-size: var(--text-meta);
  color: #555;
  line-height: 1.85;
}
.about-page .about-contact a {
  color: #2a2a2a;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.about-page .about-contact a:hover { color: #000; }
.about-page .about-contact .label {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #6e6e6e;
  display: inline-block;
  width: 70px;
}

/* Opening — mirrors the discipline pages: the eyebrow leads, the
   paragraphs follow one at a time, the portrait settles in last. */
.about-page .about-eyebrow,
.about-page .about-body p {
  opacity: 0;
  animation: up .8s cubic-bezier(.22, 1, .36, 1) .52s forwards;   /* .52s = default for a 4th paragraph onward */
}
.about-page .about-eyebrow                { animation-delay: .10s; }
.about-page .about-body p:nth-of-type(1)  { animation-delay: .24s; }
.about-page .about-body p:nth-of-type(2)  { animation-delay: .38s; }
.about-page .about-body p:nth-of-type(3)  { animation-delay: .52s; }
.about-page .about-photo {
  opacity: 0;
  animation: fadein .9s ease .46s forwards;
}
@media (prefers-reduced-motion: reduce) {
  .about-page .about-eyebrow,
  .about-page .about-body p,
  .about-page .about-photo { opacity: 1; animation: none; }
}

/* Mobile: stack to single column, photo above body. */
@media (max-width: 768px) {
  .about-page .about-layout {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .about-page .about-photo {
    width: 100%;
    max-width: 340px;
    height: auto;
    aspect-ratio: 1 / 1;
    order: -1;
  }
}

/* ============================================================
   DISCIPLINE PAGE (v4) — hero with the page's own projection of the
   solid, then an index of case rows. Was duplicated inline in the four
   discipline pages; single source since 2026-08-18.
   Accent comes from body[data-discipline], set per page.
   ============================================================ */
body[data-discipline="us"] { --db-accent: #2C4A7C; }
body[data-discipline="pm"] { --db-accent: #2D5F3F; }
body[data-discipline="id"] { --db-accent: #B8753C; }
body[data-discipline="xt"] { --db-accent: #5B3A8C; }

/* ============================================================
   DISCIPLINE PAGE · B draft — the home page's language applied
   to a discipline page. Page-scoped (`db-`); nothing here can
   reach the live pages.
   ============================================================ */
.db-hero{max-width:1200px;margin:0 auto;padding:44px 48px 28px;display:grid;
  grid-template-columns:1.18fr .82fr;row-gap:0;column-gap:72px;align-items:start;align-content:center;
  min-height:max(464px, calc(100vh - 74px))}                      /* fixed band: the divider below lands on the
                                            same line on all four discipline pages */
.db-markwrap{align-self:center}
.db-hero > div:first-child{min-height:392px}   /* tallest text column — keeps every
                                                  discipline page in the same place */
@media (max-width:1120px){.db-hero{min-height:max(490px, calc(100vh - 74px))}
  .db-hero > div:first-child{min-height:418px}}  /* narrower column wraps more text */
.db-title{min-height:2.1em}              /* reserve two lines so one- and two-line
                                            titles start at the same y */
.db-quote{grid-column:1 / -1;margin:30px 0 0;min-height:54px;font-size:var(--text-body);
  line-height:1.7;color:#555;white-space:nowrap}   /* full width so the quote never wraps */
.db-eyebrow{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.16em;
  text-transform:uppercase;color:#6e6e6e}
.db-title{margin-top:14px;font-size:var(--text-page);font-weight:var(--weight-light);
  letter-spacing:-.02em;line-height:1.05}
.db-desc{margin-top:22px;max-width:620px;font-size:var(--text-body);line-height:1.65;color:#555}
.db-desc + .db-desc{margin-top:20px}

.db-markwrap{justify-self:center;text-align:center;width:100%;max-width:245px}
.db-mark{display:block;position:relative;width:100%;aspect-ratio:1/1;pointer-events:none}
.db-hull{pointer-events:auto;cursor:pointer}   /* the shape itself is the target */
.db-mark svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.db-hull{fill:transparent;stroke-width:2;stroke-linejoin:round}
.db-cloud path{fill:none;stroke-width:1;stroke-linejoin:round}
.db-line{fill:none;stroke-width:1;stroke-linecap:round;transition:stroke .5s ease}
.db-caption{margin-top:14px;transition:color .35s ease;font-family:var(--font-mono);font-size:var(--text-micro);
  letter-spacing:.16em;text-transform:uppercase;color:#6e6e6e;transition:color .4s ease}

/* opening — the hero settles in on the home page's timing, then the mark's
   silhouette draws itself (handled in the page script). */
.db-hero > div:first-child > *{opacity:0;animation:up .8s cubic-bezier(.22,1,.36,1) forwards}
.db-eyebrow{animation-delay:.06s}
.db-title{animation-delay:.16s}
.db-desc{animation-delay:.30s}
.db-desc + .db-desc{animation-delay:.42s}
.db-caption{opacity:0;animation:fadein .65s ease 1.20s forwards}
@media (prefers-reduced-motion: reduce){
  .db-hero > div:first-child > *,.db-caption{opacity:1;animation:none}
}


/* work index — the home page's row grammar, with a plate */
@media (max-height:640px){
  .db-hero{padding-top:32px;padding-bottom:20px;align-content:start}  /* short screens: top-align,
                                        so the four pages still share one baseline */
  .db-hero > div:first-child{min-height:0}
  .db-quote{min-height:0;margin-top:20px}
  .db-markwrap{max-width:205px}
}
.db-index{max-width:1200px;margin:-48px auto 72px;   /* lifts the “Selected work” line
                                                       into the first screen */padding:0 48px}
.db-index-head{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.16em;
  text-transform:uppercase;color:#6e6e6e;padding-bottom:14px;border-bottom:1px solid #e2e2e2}
.db-row{display:grid;grid-template-columns:34px 220px 1fr auto;column-gap:28px;align-items:start;
  padding:26px 4px;border-bottom:1px solid #e2e2e2;color:inherit;
  transition:padding-left .45s cubic-bezier(.22,1,.36,1)}
.db-row:hover{padding-left:16px}
.db-idx{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.16em;color:#6e6e6e;
  padding-top:6px;transition:color .35s ease}
.db-thumb{position:relative;overflow:hidden;background:#f4f4f4;aspect-ratio:16/10}   /* one card ratio
   site-wide; every card asset is authored or recomposed to match, so nothing is cropped by surprise */
.db-thumb img{width:100%;height:100%;object-fit:cover;
  /* per-card framing: set --card-pos / --card-zoom on the individual image below.
     Tuned by hand in _card-tuner.html; defaults are dead centre, no zoom. */
  object-position:var(--card-pos,50% 50%);
  transform:scale(var(--card-zoom,1));transform-origin:var(--card-pos,50% 50%);
  transition:transform .6s cubic-bezier(.22,1,.36,1)}
.db-row:hover .db-thumb img{transform:scale(calc(var(--card-zoom,1) * 1.04))}

/* ---- per-card framing overrides (paste from the tuner) ---- */
/* (none needed — every card asset is authored at 16:10 as of 2026-08-18) */
.db-title-row{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.db-name{font-size:var(--text-section);font-weight:var(--weight-light);letter-spacing:-.01em;
  line-height:1.15;color:#3a3a3a;transition:color .35s ease}
.db-row:hover .db-name,.db-row:hover .db-idx{color:var(--db-accent)}
.db-wip{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.12em;
  text-transform:uppercase;color:#c5371a;border:1px solid #f0c4b4;border-radius:14px;padding:2px 10px}
.db-body{display:block}
.db-name,.db-sub,.db-hook{display:block}
.db-sub{margin-top:8px;font-size:var(--text-small);letter-spacing:.02em;color:#6e6e6e}
.db-hook{margin-top:10px;font-size:var(--text-body);line-height:1.6;color:#444;max-width:52ch}
.db-meta{font-family:var(--font-mono);font-size:var(--text-micro);letter-spacing:.16em;
  text-transform:uppercase;color:#6e6e6e;padding-top:8px;white-space:nowrap;text-align:right}
.db-arrow{display:block;margin-top:10px;font-size:var(--text-meta);color:#8f8f8f;opacity:0;
  transition:opacity .35s ease,color .35s ease}
.db-row:hover .db-arrow{opacity:1;color:var(--db-accent)}
@media (prefers-reduced-motion: reduce){.db-row,.db-thumb img{transition:none}}


/* ============================================================
   RESPONSIVE — target devices are iPad, desktop monitors and TV
   browsers. Phones are deliberately OUT of scope; `body` carries a
   720px floor rather than a phone layout.
   Measured 2026-08-18 at 744 / 768 / 834 / 1024 / 1366 / 1440 / 1920 / 2560.
   ============================================================ */

/* --- Tablet portrait: iPad mini 744 through iPad Pro 1023 ---
   The two-column heroes stop working just under 1024. At 768 the type
   column falls to about 335px — roughly 28 characters — which is too
   narrow to read. Below 1024 both heroes stack and the rail tightens. */
@media (max-width: 1023px) {
  .container,
  .home-hero,
  .db-hero,
  .db-index,
  .about-page { padding-left: 32px; padding-right: 32px; }

  .home-hero {
    grid-template-columns: 1fr;
    gap: 44px;
    --mark-size: 340px;
    min-height: 0;
    padding-top: 40px;
    align-items: start;
  }
  .home-markwrap { justify-self: center; }

  .db-hero {
    grid-template-columns: 1fr;
    gap: 36px;
    min-height: 0;
    align-items: start;
  }
  .db-hero > div:first-child { min-height: 0; }
  .db-markwrap { max-width: 300px; }
  /* pinned to a single line on wide screens; at tablet width it has to be
     allowed to wrap, or it pushes the page sideways */
  .db-quote { white-space: normal; }
  .db-index { margin-top: 0; }

  /* The five-link nav (discipline + case pages) is 608px wide and starts
     wrapping to a second line below ~900px — the brand wraps with it, and the
     header doubles in height. Home and About never wrap because their nav is
     only ~342px. Rather than let the tall pages behave differently from the
     short ones, the nav stays on ONE line and scrolls sideways instead. */
  .site-header .container { flex-wrap: nowrap; gap: 24px; }
  .site-header .container > div:first-child {
    flex: 0 0 auto;
    white-space: nowrap;          /* "Wenyu Ku  UX × PM × ID" stays one line */
  }
  .site-header nav {
    /* ⚠️ flex-grow 必須是 0。曾經寫 `1 1 auto`,結果 nav 這個盒子會撐滿剩餘寬度、
       連結靠左排,右邊留下一大片死空間(about/首頁 423px、子領域 161px),
       看起來就像「導航列擠在中央」。實測 2026-08-25,回報自另一台設定了顯示縮放
       的電腦。grow=0 之後,容器的 justify-content:space-between 會把 nav 推回右邊,
       跟 ≥1024px 的桌機版一致;shrink 保留 1 + min-width:0,窄到放不下時
       (子領域頁 ≤880px)照樣可以橫向捲動。 */
    flex: 0 1 auto;
    min-width: 0;                 /* lets the nav shrink below its content width */
    display: flex; flex-wrap: nowrap; white-space: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;        /* the rail scrolls, but shows no bar */
  }
  .site-header nav::-webkit-scrollbar { display: none; }
  /* run to the screen edge so the last link reads as "continues", not "cropped" */
  .site-header nav { margin-right: -32px; padding-right: 32px; }
  /* ...and let it actually dissolve into the edge. The class is put on by
     rotate-prompt.js only while there is more to the right, so a nav that fits,
     or one already scrolled to its end, has no fade hanging off it. */
  .site-header nav.nav-fades-right {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
            mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
  }

  .about-page .about-layout { grid-template-columns: 1fr; gap: 32px; }
  .about-page .about-photo  { width: 100%; max-width: 340px; height: auto;
                              aspect-ratio: 1 / 1; order: -1; }
}

/* --- Very large viewports: TV browsers and 27"+ monitors ---
   A 1080p TV reports 1920 CSS px but is read from across a room, and a 27-32"
   monitor is simply further from the eye than a laptop. The rail stays at
   1200px — that measure is the design — and instead the WHOLE type scale steps
   up one notch (x1.125, rounded to whole pixels so it is still eight discrete
   sizes, not a fluid ramp). Body measure goes from ~61 to ~54 characters, still
   inside the comfortable 45-75 band.
   Caveat: inline SVG hardcodes its own px sizes and does not scale with this.
   Labels inside diagrams stay put; that is a known, accepted limit. */
@media (min-width: 1800px) {
  :root {
    --text-micro:    12px;
    --text-small:    15px;
    --text-meta:     16px;
    --text-body:     18px;
    --text-lead:     21px;
    --text-section:  36px;
    --text-page:     54px;
    --text-display:  72px;
  }
}
