/* ============================================================
   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, SuperDry 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: 1024px;     /* 桌機/平板 only — Phase 2 再加 mobile */
  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;
}

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;
  border-bottom: 1px solid #ececec;
  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; }

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

.site-header .brand {
  font-size: var(--text-lead);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.site-header .brand-secondary {
  font-size: var(--text-meta);
  color: #666;
  margin-left: 12px;
  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-size: var(--text-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #666;
  margin-bottom: 16px;
}

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

.case-tagline {
  font-size: var(--text-lead);
  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;
}

.case-meta-item .label {
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #666;
  margin-bottom: 6px;
}

.case-meta-item .value {
  font-size: var(--text-meta);
  color: #1a1a1a;
}

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

.case-section-eyebrow {
  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: 400;
  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: 600;
  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) */
}

/* 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-superdry"] {
  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.55em;
  color: #666;
  font-weight: 400;
  margin-left: 12px;
  letter-spacing: 0.02em;
}

.case-intro .case-tagline {
  font-size: var(--text-lead);
  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-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #666;
  margin-bottom: 6px;
}
.case-meta-bar .meta-item .value {
  font-size: var(--text-meta);
  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;
}




/* SuperDry §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-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: 400;
  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-superdry.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: 600;
  font-size: var(--text-meta);
  margin-bottom: 3px;
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}
@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: 600;
  color: #1a1a1a;
  margin-bottom: 4px;
  letter-spacing: 0.02em;
}
.spec-list dd {
  font-size: var(--text-small);
  color: #555;
  line-height: 1.55;
}


/* ============================================================
   HOME HERO (light theme) — Triquetra opening visual
   Adapted from Gemini Plan B v9.2 to white aesthetic.
   ============================================================ */

.home-hero {
  width: 100%;
  min-height: calc(100vh - 92px);  /* viewport minus sticky header */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 32px 40px;
  background: #ffffff;
}

.home-hook {
  max-width: 640px;
  text-align: center;
  margin-top: -36px;
  margin-bottom: 0;
  font-weight: 300;
  font-size: var(--text-lead);
  line-height: 1.6;
  color: #2a2a2a;
  letter-spacing: 0.005em;
}
.home-hook .accent {
  color: #5B3A8C;       /* XT purple, matches center */
  font-weight: 500;
}

.module {
  position: relative;
  width: min(86vw, 620px, 70vh);
  aspect-ratio: 1 / 1;
}

svg.vis-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  overflow: visible;
}

/* triquetra rings — light, restrained default */
.ring {
  fill: rgba(0, 0, 0, 0.005);
  stroke: rgba(0, 0, 0, 0.18);
  stroke-width: 14;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.6s cubic-bezier(0.22, 1, 0.36, 1),
              fill   0.6s cubic-bezier(0.22, 1, 0.36, 1),
              filter 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.orbit-text {
  font-family: var(--font-sans);
  font-size: var(--text-micro);
  font-weight: 700;
  fill: rgba(0, 0, 0, 0.55);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  transform: scale(0.92);
  transform-origin: 300px 300px;
  transform-box: view-box;
  transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Orbit ring — visible at rest, fades on XTD hover so the text takes over its role */
.orbit-ring {
  fill: none;
  stroke: rgba(0, 0, 0, 0.18);
  stroke-width: 14;
  transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

/* XTD hover lights all three petals subtly + reveals orbit text + fades the ring */
.module:has(.svg-xtd-node:hover) .orbit-text {
  opacity: 1;
  transform: scale(1.05);
}
.module:has(.svg-xtd-node:hover) .orbit-ring { opacity: 0; }
.module:has(.svg-xtd-node:hover) .seg-ux { stroke: #2C4A7C; fill: rgba(44, 74, 124, 0.04); }
.module:has(.svg-xtd-node:hover) .seg-pm { stroke: #2D5F3F; fill: rgba(45, 95, 63, 0.04); }
.module:has(.svg-xtd-node:hover) .seg-id { stroke: #B8753C; fill: rgba(184, 117, 60, 0.04); }

/* per-petal hover — single petal lights up */
.module:has(.svg-ux-node:hover) .seg-ux { stroke: #2C4A7C; fill: rgba(44, 74, 124, 0.10); stroke-width: 16; }
.module:has(.svg-pm-node:hover) .seg-pm { stroke: #2D5F3F; fill: rgba(45, 95, 63, 0.10); stroke-width: 16; }
.module:has(.svg-id-node:hover) .seg-id { stroke: #B8753C; fill: rgba(184, 117, 60, 0.10); stroke-width: 16; }

/* SVG nodes (UX / PM / ID / XTD) — geometry baked into SVG, scales as one unit */
.svg-node {
  cursor: pointer;
}

.svg-hit-area {
  fill: transparent;
}

.svg-abbr {
  font-family: var(--font-sans);
  font-size: var(--text-section);
  font-weight: 700;
  fill: rgba(0, 0, 0, 0.30);
  letter-spacing: 0.02em;
  text-anchor: middle;
  dominant-baseline: middle;
  transition: fill 0.4s ease;
}

.svg-label {
  font-family: var(--font-sans);
  font-size: var(--text-micro);
  font-weight: 500;
  fill: #1a1a1a;
  letter-spacing: 0.05em;
  text-anchor: middle;
  dominant-baseline: middle;
  opacity: 0;
  transform: translateY(8px);
  transform-box: fill-box;
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.svg-node:hover .svg-label {
  opacity: 1;
  transform: translateY(0);
}

/* Per-petal hover: abbr colour shift */
.svg-ux-node:hover .svg-abbr { fill: #2C4A7C; }
.svg-pm-node:hover .svg-abbr { fill: #2D5F3F; }
.svg-id-node:hover .svg-abbr { fill: #B8753C; }

/* XTD center — different size, scales subtly on hover */
.svg-xtd-abbr {
  font-size: var(--text-section);
  fill: rgba(0, 0, 0, 0.55);
  transform-origin: 300px 300px;
  transform-box: view-box;
  transition: fill 0.4s ease, transform 0.4s ease;
}

.svg-xtd-node:hover .svg-xtd-abbr {
  fill: #5B3A8C;
  transform: scale(1.08);
}

/* below-triquetra: workflow line + nudge hint */
.hero-foot {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.workflow {
  font-size: var(--text-meta);            /* up from text-micro */
  letter-spacing: 0.36em;                  /* slightly looser tracked */
  color: #5B3A8C;
  text-transform: uppercase;
  font-weight: 600;                        /* up from 500 */
  display: flex;
  align-items: center;
  gap: 18px;
  padding-top: 22px;
  position: relative;
}
.workflow::before,
.workflow::after {
  content: "";
  display: block;
  width: 56px;
  height: 1px;
  background: rgba(91, 58, 140, 0.45);
}
.workflow .workflow-sep {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #5B3A8C;
  margin: 0 4px;
  vertical-align: middle;
  opacity: 0.7;
}
.nudge {
  font-size: var(--text-micro);
  letter-spacing: 0.2em;
  color: rgba(0, 0, 0, 0.22);
  text-transform: uppercase;
}

/* ============================================================
   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: 600;
  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-regular);
  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-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: 400;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}

.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;
}

.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: 1080px;
  margin: 64px auto 96px;
  padding: 0 24px;
}
.about-page .about-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #888;
  /* 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;
}
.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.14em;
  text-transform: uppercase;
  color: #888;
  display: inline-block;
  width: 70px;
}

/* 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;
  }
}
