/* ==========================================================================
   WAHSUN — DIGITAL LAB
   Editorial / generative / cinematic. One scene, one motion system.
   ========================================================================== */

/* ── 主題：深色 / 淺色 ───────────────────────────────────────────────
   淺色是白底，深色回復原本的深墨底。切換時 data-scene 與 SEC[].scene
   會一起改，所以既有的 sequential lerp 會把過場演成連續的淡化。 */
:root[data-theme="light"]{
  --base:#ffffff;
  --paper:#ffffff;
  --o:#c2410c;                    /* 白底要深橙（5.18:1） */
  --grid:rgba(13,13,13,.045);
  --lab-ruler:rgba(13,13,13,.085);
  --lab-glow:rgba(194,65,12,.026);
  --veil:rgba(255,255,255,.84);
  --panel:rgba(255,255,255,.95);
  --btn-hi:rgba(13,13,13,.34);
}
:root[data-theme="dark"]{
  --base:#0b0b0c;
  --paper:#f2efe9;
  --o:#ff7a2f;                    /* 深底用亮橙，與原設計一致 */
  --grid:rgba(242,239,233,.05);
  --lab-ruler:rgba(242,239,233,.10);
  --lab-glow:rgba(255,122,47,.032);
  --veil:rgba(11,11,12,.80);
  --panel:rgba(11,11,12,.93);
  --btn-hi:rgba(242,239,233,.42);
}

/* ── 字型（全部自架，無外部 CDN） ───────────────────────────────── */
@font-face{font-family:'Instrument Serif';src:url('fonts/instrumentserif-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Instrument Serif';src:url('fonts/instrumentserif-400-italic.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'Inter';src:url('fonts/inter-var.woff2') format('woff2');font-weight:100 900;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('fonts/plexmono-400.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('fonts/plexmono-500.woff2') format('woff2');font-weight:500;font-display:swap}

/* ── tokens ──────────────────────────────────────────────────────── */
:root{
  --ink:#0b0b0c;                 /* 黑（暖黑，不是純黑） */
  --paper:#ffffff;               /* 白（使用者指示：全白背景） */

  --o:#c2410c;                   /* orange（白底用深橙：#ff7a2f 在白色上只有 2.2:1） */
  --c:#ff5a45;                   /* coral  */
  --p:#ff5fa2;                   /* pink   */
  --m:#b83bb0;                   /* magenta */

  /* 由 JS 依場景淡入淡出即時覆寫：文字與細線要跟著場景反轉 */
  /* 對比原則：低對比只留給裝飾。控制項、標籤、說明文字必須可讀。 */
  --fg:rgba(242,239,233,.95);
  --fg-dim:rgba(242,239,233,.62);
  --fg-faint:rgba(242,239,233,.44);
  --hair:rgba(242,239,233,.15);
  --paper-op:0;

  --serif:'Instrument Serif',Georgia,'Times New Roman',serif;
  --sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* 電影感緩動：慢、精準、無回彈 */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-io:cubic-bezier(.45,.05,.55,.95);

  --pad:clamp(22px,5.2vw,104px);

  /* ── 安全區域（瀏海／狀態列／手勢列／橫向缺口）───────────────
     desktop 與一般瀏覽器上全部解析為 0px，等於沒有這段；
     只有在 iPhone 全屏／加到主畫面時才會撐開。
     頂列是 fixed、top:0，若不補 inset，品牌字會壓進瀏海。 */
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --sal:env(safe-area-inset-left,0px);
  --sar:env(safe-area-inset-right,0px);
  --pad-l:max(var(--pad),var(--sal));
  --pad-r:max(var(--pad),var(--sar));
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html,body{margin:0;padding:0}
html{background:var(--base);scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  /* 底色只在 html 上設，body 這裡刻意不設。
     CSS 繪製順序是「根背景 → 負 z-index → 一般區塊背景」，
     而 body 的背景只有在 html 沒有背景時才會傳播到根。
     兩邊都設的話 body 會退化成一塊一般背景，畫在 z-index:-1 的
     canvas 之上 —— 整個生成場會被一片實心白蓋掉（看起來就像特效被刪了）。
     html 有背景、body 沒有 → 場畫在 html 底色之上、內容之下，正確。 */
  color:var(--fg);
  font-family:var(--sans);
  font-weight:300;
  line-height:1.5;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}
body.no-scroll{overflow:hidden}
img,svg,canvas{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--c);color:#0b0b0c}

/* ── 場景層：黑白交叉淡化（絕不直接換 background-color） ─────────── */
.scene-paper{
  position:fixed;inset:0;z-index:-2;background:var(--paper);
  opacity:var(--paper-op);pointer-events:none;
  will-change:opacity;
}
/* 頁面底層永遠是黑；暖白壓在上面淡入淡出，所以過場是連續的 */

/* ── 生成式舞台 ──────────────────────────────────────────────────── */
.stage{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
#coreCanvas{position:absolute;inset:0;width:100%;height:100%}
/* 讓圖形只在中央區活躍，邊緣自然收束——避免整頁被粒子填滿 */
.stage-veil{
  position:absolute;inset:0;
  background:radial-gradient(ellipse 78% 62% at 50% 50%,transparent 0%,transparent 46%,rgba(11,11,12,.55) 100%);
  opacity:calc(1 - var(--paper-op));
  pointer-events:none;
}

/* ── 顆粒質感：消除漸層色帶（純黑/純白都會有） ─────────────────── */
.grain{
  position:fixed;inset:-50%;z-index:40;pointer-events:none;opacity:.032;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grainShift 7s steps(2) infinite;
}
@keyframes grainShift{0%{transform:translate(0,0)}50%{transform:translate(-2%,1.5%)}100%{transform:translate(0,0)}}

/* ── 全站細線：編輯式的頁面框 ───────────────────────────────────── */
.hairlines{position:fixed;inset:0;z-index:35;pointer-events:none}
.hairlines i{
  /* 左右兩條長豎線已移除（使用者要求）。只留頂列下方那條橫線。 */
  position:absolute;background:var(--hair);
  left:var(--pad-l);right:var(--pad-r);top:calc(72px + var(--sat));height:1px;
}/* ── 頂部狀態列 ──────────────────────────────────────────────────── */
.topbar{
  position:fixed;top:0;left:0;right:0;z-index:60;
  /* 高度含安全區域，再用 padding-top 把內容推下來 → 內容仍在 72px 帶內垂直居中 */
  height:calc(72px + var(--sat));
  display:flex;align-items:center;justify-content:space-between;
  padding:var(--sat) var(--pad-r) 0 var(--pad-l);pointer-events:none;
}
.topbar a,.topbar button{pointer-events:auto}
.brand{font-family:var(--mono);font-size:12px;font-weight:500;letter-spacing:.32em;color:var(--fg)}
.brand b{font-weight:500}
.topbar-r{display:flex;align-items:center;gap:clamp(14px,2.4vw,34px)}
.idx{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.24em;color:var(--fg);
  transition:opacity .45s var(--ease);
}
.idx.swap{opacity:0}
.snd{
  display:flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.22em;
  color:var(--fg);
  padding:8px 12px;min-height:32px;border:1px solid var(--hair);border-radius:999px;
  transition:color .35s var(--ease),border-color .35s var(--ease),background .35s var(--ease);
}
.snd:hover{color:var(--fg);border-color:rgba(255,122,47,.55)}
.snd[aria-pressed="true"]{color:var(--o);border-color:rgba(194,65,12,.5)}
.snd .snd-s{opacity:.4}
.snd-dot{width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.45}
.snd[aria-pressed="true"] .snd-dot{opacity:1;animation:sndPulse 2.6s var(--ease-io) infinite}
@keyframes sndPulse{0%,100%{opacity:.35}50%{opacity:1}}

/* ── 右側進度：一條線 ───────────────────────────────────────────── */

/* ── 章節基本結構 ────────────────────────────────────────────────── */
.sec{position:relative;padding:clamp(96px,17vh,190px) 0}
.pad{padding:0 var(--pad);max-width:1560px;margin:0 auto;width:100%}
/* ★ width:100% 是必要的：.sec-build / .sec-end 是 display:flex，.pad 會變成
   flex item 被壓成「內容寬度」——wordfield 因此只有 450px 寬而不是 1290，
   七個詞擠在一起。加了才會撐滿。 */
.seclabel{
  display:block;font-family:var(--mono);font-size:10px;font-weight:500;
  letter-spacing:.32em;text-transform:uppercase;
  color:var(--fg-faint);margin-bottom:clamp(48px,8vh,100px);
}

/* ── 電影字幕文字：每行獨立，慢速建立（無回彈） ─────────────────── */
.film{margin:0;font-family:var(--serif);font-weight:400;line-height:1.02;letter-spacing:-.012em}
.film .ln{display:block;overflow:hidden;padding-bottom:.06em;margin-bottom:-.06em}
.film .ln > span{
  display:block;
  opacity:0;transform:translateY(.72em);
  transition:opacity 1.35s var(--ease),transform 1.35s var(--ease);
  transition-delay:var(--d,0s);
}
.film.in .ln > span{opacity:1;transform:translateY(0)}

/* 規格 §3／§4：句子在畫面中央，背景才是生成式系統 */
.sec-hero .film,.sec-hero2 .film{text-align:center;margin-left:auto;margin-right:auto}
.sec-hero .film{font-size:clamp(48px,9.8vw,158px);margin-bottom:clamp(64px,11vh,140px)}
.sec-hero2 .film{font-size:clamp(30px,6.4vw,104px)}

/* 混排：襯線 + 無襯線，字體本身就是構成（規格 §4） */
.film-mix .s{font-family:var(--serif);font-style:normal}
.film-mix .n{
  font-family:var(--sans);font-weight:200;letter-spacing:-.035em;
  font-size:.86em;
}
.film-sub{font-size:clamp(30px,4.2vw,58px);line-height:1.24;max-width:16ch}

.hero-foot{
  display:flex;justify-content:center;gap:clamp(18px,3vw,42px);margin-left:auto;margin-right:auto;
  font-family:var(--mono);font-size:10px;letter-spacing:.26em;color:var(--fg-dim);
  border-top:1px solid var(--hair);padding-top:18px;max-width:640px;
  opacity:0;transform:translateY(14px);
  transition:opacity 1.1s var(--ease) .75s,transform 1.1s var(--ease) .75s;
}
.hero-foot.in{opacity:1;transform:translateY(0)}
.hero-foot .dim{opacity:.6}
.tag{white-space:nowrap}

.scroll-cue{position:absolute;left:50%;bottom:clamp(24px,5vh,52px);transform:translateX(-50%);width:1px;height:56px;background:var(--hair);overflow:hidden}
.scroll-cue i{position:absolute;left:0;top:-40%;width:1px;height:40%;background:var(--o);animation:cue 3.4s var(--ease-io) infinite}
@keyframes cue{0%{top:-40%}60%,100%{top:100%}}

/* ── 通用進場：簡單元素用這個；.film / .proj 有自己的子元素錯開規則 ── */
.rv-wait{opacity:0;transform:translateY(28px)}
.rv-wait.in{opacity:1;transform:none}
.rv-wait{transition:opacity 1s var(--ease),transform 1s var(--ease)}

/* ── 通用進場（捲動攝影機：位移 + 透明度） ─────────────────────── */
[data-rv]{opacity:0;transform:translateY(38px);transition:opacity 1.02s var(--ease),transform 1.02s var(--ease)}
[data-rv].in{opacity:1;transform:none}
[data-rv][data-rv-d="1"]{transition-delay:.13s}
[data-rv][data-rv-d="2"]{transition-delay:.26s}
[data-rv][data-rv-d="3"]{transition-delay:.39s}
[data-rv][data-rv-d="4"]{transition-delay:.52s}

/* ══════════════════════════════════════════════════════════════════
   02 — WHAT I BUILD：大型動態詞場（不是卡片）
   ══════════════════════════════════════════════════════════════════ */
.sec-build{min-height:100vh;display:flex;align-items:center}
.wordfield{position:relative;height:min(62vh,560px);margin-bottom:clamp(28px,5vh,56px)}
.w{
  position:absolute;left:50%;top:50%;
  font-family:var(--sans);font-weight:300;letter-spacing:-.04em;
  font-size:clamp(24px,3.4vw,58px);
  white-space:nowrap;will-change:transform,opacity;
  color:var(--fg);
  opacity:0;
}
.w.lead{font-family:var(--serif);font-weight:400;letter-spacing:-.02em}
.build-note{
  max-width:44ch;font-size:clamp(14px,1.15vw,17px);line-height:1.72;
  color:var(--fg-dim);
}

/* ══════════════════════════════════════════════════════════════════
   03 — EXPERIMENTS：垂直編輯式片捲（不是卡片格）
   ══════════════════════════════════════════════════════════════════ */
.sec-exp .exp-sub{color:var(--fg-dim);margin-bottom:clamp(50px,9vh,110px)}
.filmstrip{display:block}
/* 專案名稱：視覺主角。先前全站沒有任何 .proj h3 規則，
   它一直以瀏覽器預設 16px 呈現 —— 這是層級失焦的真正原因。 */
.proj-body h3{margin:0}
.proj-body h3 a{
  display:block;font-family:var(--sans);font-weight:200;
  font-size:clamp(46px,7.2vw,116px);line-height:.94;letter-spacing:-.045em;
  color:var(--fg);text-decoration:none;
  transition:transform 1.4s var(--ease),opacity 1.4s var(--ease);
}
.proj{
  position:relative;min-height:clamp(78vh,86vh,980px);
  display:flex;align-items:center;
  border-top:1px solid var(--hair);
  padding:clamp(64px,10.5vh,132px) var(--pad);
  overflow:hidden;
  transition:border-color 1.4s var(--ease);
}
/* 極克制：名稱極緩位移、編號略淡、分隔線一次緩移。無 3D、無 scale、無發光 */
.proj:hover .proj-body h3 a{transform:translateX(clamp(6px,.8vw,16px))}
.proj:hover .proj-n{opacity:.45;letter-spacing:.34em}
.proj:hover{border-top-color:var(--fg-faint)}
.proj-n{transition:opacity 1.4s var(--ease),letter-spacing 1.4s var(--ease)}
.proj:last-child{border-bottom:1px solid var(--hair)}
.proj-viz{position:absolute;inset:0;pointer-events:none;opacity:.9}
.proj-viz canvas{position:absolute;inset:0;width:100%;height:100%}
.proj-body{position:relative;z-index:2;max-width:1560px;margin:0 auto;width:100%}
.proj-n{
  display:flex;align-items:center;gap:clamp(11px,1vw,17px);
  font-family:var(--mono);font-size:11px;letter-spacing:.28em;
  color:var(--fg-dim);margin-bottom:clamp(14px,2.4vh,26px);
}
/* 每個實驗自己的記號。與場上的母題同一個構造，全部用線畫——
   這是 System 01 的同一條規則：能畫的就不放圖。 */
.proj-i{width:clamp(20px,1.9vw,27px);height:clamp(20px,1.9vw,27px);flex:none;overflow:visible;color:var(--fg-faint)}
.proj-i :is(path,circle,rect,polygon){fill:none;stroke:currentColor;stroke-width:1.1;vector-effect:non-scaling-stroke}
.proj-i .pi-f{fill:var(--o);stroke:none}
.proj h3{
  margin:0 0 clamp(14px,2.2vh,24px);
  font-family:var(--sans);font-weight:200;letter-spacing:-.055em;line-height:.9;
  font-size:clamp(52px,12.5vw,190px);
  opacity:0;transform:translateY(.22em);
  transition:opacity 1.15s var(--ease),transform 1.15s var(--ease);
}
.proj.in h3{opacity:1;transform:none}
.proj-m{
  display:block;font-family:var(--mono);font-size:10px;letter-spacing:.24em;
  color:var(--o);margin-bottom:clamp(18px,3vh,30px);
  opacity:0;transform:translateY(16px);
  transition:opacity 1s var(--ease) .16s,transform 1s var(--ease) .16s;
}
.proj.in .proj-m{opacity:1;transform:none}
.proj p{
  margin:0;max-width:52ch;font-size:clamp(14px,1.15vw,17px);line-height:1.7;
  color:var(--fg-dim);
  opacity:0;transform:translateY(16px);
  transition:opacity 1s var(--ease) .28s,transform 1s var(--ease) .28s;
}
.proj.in p{opacity:1;transform:none}

/* ══════════════════════════════════════════════════════════════════
   04 — IDEAS：每一句是獨立的視覺場景
   ══════════════════════════════════════════════════════════════════ */
.sec-ideas .idea-list{display:flex;flex-direction:column;gap:clamp(58px,13vh,160px)}
.idea{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(38px,7.4vw,124px);line-height:1.04;letter-spacing:-.014em;
  max-width:18ch;
  opacity:.14;transform:translateY(26px);
  transition:opacity .9s var(--ease),transform .9s var(--ease);
}
.idea.act{opacity:1;transform:none}
.idea[data-idea="1"]{align-self:flex-end;text-align:right;font-style:italic}
.idea[data-idea="2"]{font-family:var(--sans);font-weight:200;letter-spacing:-.04em;font-size:clamp(30px,5.2vw,88px)}

/* ══════════════════════════════════════════════════════════════════
   05 — SYSTEMS
   ══════════════════════════════════════════════════════════════════ */
.syslist{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}
.syslist li{
  display:grid;grid-template-columns:64px minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(16px,3vw,54px);align-items:baseline;
  padding:clamp(26px,4.4vh,50px) 0;border-bottom:1px solid var(--hair);
}
.syslist .sn{font-family:var(--mono);font-size:10px;letter-spacing:.28em;color:var(--fg-faint)}
.syslist b{font-family:var(--serif);font-weight:400;font-size:clamp(21px,2.5vw,38px);line-height:1.16;letter-spacing:-.01em}
.syslist .sd{font-size:clamp(13.5px,1.06vw,16px);line-height:1.72;color:var(--fg-dim)}

/* ══════════════════════════════════════════════════════════════════
   06 — ABOUT
   ══════════════════════════════════════════════════════════════════ */
.about-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);gap:clamp(30px,6vw,90px);margin-bottom:clamp(46px,8vh,96px)}
.about-mark{font-family:var(--sans);font-weight:200;letter-spacing:-.05em;font-size:clamp(34px,5.4vw,86px);line-height:.96;margin:0}
.about-mark span{font-family:var(--mono);font-weight:400;font-size:.22em;letter-spacing:.34em;color:var(--fg-dim);display:inline-block;margin-top:1.4em;transform:translateY(-.2em)}
.about-line{font-family:var(--mono);font-size:10px;letter-spacing:.24em;color:var(--fg-faint);margin:clamp(22px,4vh,40px) 0 0}
.about-claim{font-family:var(--serif);font-size:clamp(26px,3.4vw,50px);line-height:1.18;margin:0 0 clamp(20px,3.4vh,34px)}
.about-p{margin:0;max-width:50ch;font-size:clamp(14px,1.12vw,17px);line-height:1.76;color:var(--fg-dim)}
.about-links{list-style:none;margin:0;padding:clamp(22px,3.4vh,34px) 0 0;border-top:1px solid var(--hair);display:flex;flex-wrap:wrap;gap:clamp(20px,3.6vw,56px)}
.about-links li{font-family:var(--mono);font-size:10.5px;letter-spacing:.24em}
.about-links a{position:relative;padding-bottom:4px;color:var(--fg-dim);transition:color .35s var(--ease)}
.about-links a::after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease)}
.about-links a:hover{color:var(--fg)}
.about-links a:hover::after{transform:scaleX(1)}
.about-links .mute{color:var(--fg-faint);opacity:.55}

/* ══════════════════════════════════════════════════════════════════
   07 — END
   ══════════════════════════════════════════════════════════════════ */
.sec-end{min-height:100vh;display:flex;align-items:center;text-align:center}
.end-pad{width:100%}
.end-claim{
  font-family:var(--serif);font-size:clamp(30px,5.4vw,86px);line-height:1.12;margin:0 auto;
  max-width:20ch;opacity:0;transform:translateY(24px);
  transition:opacity 1.3s var(--ease),transform 1.3s var(--ease);
}
.end-claim.in{opacity:1;transform:none}
.end-claim .el{display:block;opacity:0;transform:translateY(.3em);
  transition:opacity 2.2s var(--ease),transform 2.2s var(--ease)}
.end-claim .el:nth-child(1){transition-delay:.15s}
.end-claim .el:nth-child(2){transition-delay:1.5s}
.end-claim.in .el{opacity:1;transform:none}
.end-dot{
  display:block;width:7px;height:7px;margin:clamp(52px,11vh,120px) auto 0;border-radius:50%;
  background:var(--o);opacity:0;
  transition:opacity 1.6s var(--ease) .5s;
}
.end-dot.in{opacity:1}

/* ══════════════════════════════════════════════════════════════════
   響應式：重新編排，不是縮小桌面版（規格 §19）
   ══════════════════════════════════════════════════════════════════ */
@media (max-width:1024px){
  .about-grid{grid-template-columns:minmax(0,1fr)}
  .syslist li{grid-template-columns:44px minmax(0,1fr);gap:14px 18px}
  .syslist .sd{grid-column:2}
}
@media (max-width:720px){
  :root{--pad:20px}
  .topbar{height:calc(58px + var(--sat))}
  .hairlines i{top:calc(58px + var(--sat))}   /* 原本是 nth-child(3)，豎線移除後只剩一個 i */
  .brand{font-size:10px;letter-spacing:.26em}
  .idx{font-size:9px;letter-spacing:.2em}
  .snd{font-size:9px;padding:6px 9px}

  .sec{padding:clamp(72px,13vh,120px) 0}
  .sec-hero{min-height:100svh;display:flex;align-items:center}
  .sec-hero .film{font-size:clamp(41px,11.8vw,78px)}
  .sec-hero2 .film{font-size:clamp(28px,8vw,52px)}
  .film .ln > span{transform:translateY(.78em)}
  .film-mix .n{font-size:.9em}

  /* 詞場：改成非絕對定位的流式排列，避免手機上互相重疊 */
  .wordfield{height:auto;display:flex;flex-wrap:wrap;gap:6px 14px;margin-bottom:26px}
  .w{position:static;font-size:clamp(26px,8.4vw,44px);opacity:1}
  .w.lead{font-size:clamp(30px,9.6vw,50px)}
  .build-note{font-size:14px}

  .proj{min-height:auto;padding:56px var(--pad) 64px;display:block}
  .proj-viz{opacity:.5}
  .proj h3{font-size:clamp(46px,17vw,92px)}
  .proj p{font-size:14px}

  .idea{font-size:clamp(30px,10.4vw,58px);max-width:none}
  .idea[data-idea="1"]{align-self:flex-start;text-align:left}
  .idea[data-idea="2"]{font-size:clamp(24px,7.6vw,44px)}
  .sec-ideas .idea-list{gap:56px}

  .syslist li{grid-template-columns:minmax(0,1fr);gap:10px;padding:26px 0}
  .syslist .sd{grid-column:1}
  .syslist .sn{margin-bottom:2px}

  .about-mark{font-size:clamp(38px,13vw,64px)}
  .about-claim{font-size:clamp(24px,7.4vw,40px)}
  .about-links{gap:18px 26px}

  .sec-end{min-height:92svh}
  .end-claim{font-size:clamp(28px,8.6vw,52px)}
  .scroll-cue{height:42px}
}

/* ── 減少動態：只降複雜度，不把動效殺光 ─────────────────────────
   使用者要求：不可以因為 Reduce Motion 就讓站點失去動效。
   所以這裡只縮短距離、拉長淡入，視覺敘事完整保留。               */
@media (prefers-reduced-motion:reduce){
  .grain{animation:none}
  .film .ln > span{transform:none;transition:opacity 1.1s var(--ease)}
  [data-rv]{transform:none;transition:opacity 1.1s var(--ease)}
  .proj h3,.proj p,.proj-m{transform:none}
  .idea{transform:none;opacity:.22}
  .idea.act{opacity:1}
  .end-claim{transform:none}
  .sec-end.gone .end-dot{animation:endOut 3.4s linear .55s forwards}
  .scroll-cue i{animation-duration:4.6s}
}

/* ══════════════════════════════════════════════════════════════════
   V2.1 — 動態敘事強化
   ══════════════════════════════════════════════════════════════════ */

/* ── 生成場：一個引擎、五種狀態。斷點在 .stage 內，於核心之上 ── */
#fieldCanvas{position:absolute;inset:0;width:100%;height:100%}

/* ── 詞場連線層（規格 §4：詞通過 line/arc/node 連成網絡）── */
.wf-net{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;opacity:0;
  overflow:visible;
}
.wf-net path{
  fill:none;stroke:var(--fg);stroke-width:1;
  vector-effect:non-scaling-stroke;
}

/* ── Hero 啟動（規格 §2/§3）：文字由 JS 逐行放行，不是 IO 觸發 ──
   每一行出現時會把系統再推一步，所以文字是動畫的一部分。 */
.film.booted .ln > span{
  opacity:0;transform:translateY(.62em);
  transition:none;
}
.film.booted .ln.on > span{
  opacity:1;transform:translateY(0);
  transition:opacity 1.6s var(--ease),transform 1.6s var(--ease);
}
/* 別的行還在等，不要讓 overflow:hidden 裁掉未出現的行 */
.film.booted .ln{overflow:visible;padding-bottom:0;margin-bottom:0}

/* ── SYSTEMS：系統圖（規格 §8）── */
.syslist li{
  display:grid;
  grid-template-columns:auto 1fr clamp(72px,9vw,116px);
  gap:clamp(16px,2.6vw,44px);
  align-items:center;
}
.sysviz{
  width:100%;height:auto;aspect-ratio:1;
  overflow:visible;
}
.sysviz *{fill:none;stroke:var(--fg);stroke-width:.9;vector-effect:non-scaling-stroke}
.sysviz .sv-ray,.sysviz .sv-geom,.sysviz .sv-img{opacity:0;transition:opacity 1.1s var(--ease)}
.sysviz .sv-code{opacity:0;transition:opacity 1.1s var(--ease)}
.sysviz .sv-hub{fill:var(--fg);stroke:none;opacity:0;transition:opacity .9s var(--ease)}
.sysviz .sv-dot{fill:var(--fg);stroke:none}
/* I — code → geometry → image */
.sysviz[data-viz="code"].st1 .sv-code{opacity:.85}
.sysviz[data-viz="code"].st2 .sv-geom{opacity:.5}
.sysviz[data-viz="code"].st3 .sv-img{opacity:.32}
.sysviz[data-viz="code"].st2 .sv-code,
.sysviz[data-viz="code"].st3 .sv-code{opacity:0}
/* II — 所有軌跡匯聚到中央節點 */
.sysviz[data-viz="hub"].st1 .sv-ray{opacity:.34}
.sysviz[data-viz="hub"].st2 .sv-ray{opacity:.2}
.sysviz[data-viz="hub"].st2 .sv-hub{opacity:.9}
.sysviz[data-viz="hub"].st3 .sv-ray{opacity:.1}
.sysviz[data-viz="hub"].st3 .sv-hub{opacity:.55}
/* III — 一圈比一圈慢 */
.sysviz[data-viz="slow"] circle{opacity:0;transition:opacity 1.2s var(--ease)}
.sysviz[data-viz="slow"].st1 .sv-o1{opacity:.55}
.sysviz[data-viz="slow"].st2 .sv-o1{opacity:.42}
.sysviz[data-viz="slow"].st2 .sv-o2{opacity:.34}
.sysviz[data-viz="slow"].st3 .sv-o1{opacity:.30}
.sysviz[data-viz="slow"].st3 .sv-o2{opacity:.24}
.sysviz[data-viz="slow"].st3 .sv-o3{opacity:.18}
.sysviz[data-viz="slow"].st1 .sv-dot{opacity:1;animation:svOrbit 9s linear infinite}
.sysviz[data-viz="slow"].st2 .sv-dot{opacity:1;animation:svOrbit 15s linear infinite}
.sysviz[data-viz="slow"].st3 .sv-dot{opacity:1;animation:svOrbit 26s linear infinite}
@keyframes svOrbit{
  from{transform:rotate(0deg);transform-origin:50px 50px}
  to{transform:rotate(360deg);transform-origin:50px 50px}
}

/* ── 結尾（規格 §10）：一切都停下來，然後才放手 ──
   文字淡出 → 只剩一個極小的點 → pulse 一次 → 熄滅。 */
.sec-end .end-claim{
  transition:opacity 2.4s var(--ease),transform 2.4s var(--ease);
}
.sec-end.gone .end-claim{opacity:0;transform:translateY(-.34em)}
/* 只剩一個極小的點：pulse 一次，然後熄滅 */
.sec-end.gone .end-dot{animation:endOut 3.4s var(--ease-io) .55s forwards}
@keyframes endOut{
  0%{opacity:0;transform:scale(.4)}
  22%{opacity:1;transform:scale(1)}
  34%{opacity:.6;transform:scale(.86)}
  46%{opacity:1;transform:scale(1.08)}
  100%{opacity:0;transform:scale(.12)}
}

/* ── 手機 ── */
@media (max-width:720px){
  .syslist li{grid-template-columns:auto 1fr;grid-template-rows:auto auto}
  .sysviz{grid-column:2;width:clamp(64px,20vw,96px);justify-self:start;margin-top:12px}
  .wf-net{display:none}
}
@media (prefers-reduced-motion:reduce){
  .film.booted .ln > span{transition:opacity 1.2s linear}
  .sysviz .sv-dot{animation:none}
}

/* ── 項目標題連到真實站點 ── */
.proj h3 a{color:inherit;text-decoration:none;display:inline-block;
  transition:opacity .65s var(--ease)}
.proj h3 a:hover{opacity:.6}

/* ══════════════════════════════════════════════════════════════════════
   V2.1 — DIGITAL LAB 精細化
   只加「實驗室的資訊語言」：更小的字、更低的對比、更細的線。
   不動既有 Motion、不動 Canvas、不動 Hero、不動專案內容。
   新增動畫只允許 opacity / transform，極慢。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 09 BACKGROUND：極淡的數位實驗空間 ──────────────────────────────
   純 CSS、pointer-events:none。z-index 與紙層同為 -2，靠 DOM 順序
   排在紙層之後 → 在紙之上、現有 canvas(-1) 之下。無 WebGL、無粒子。 */
.labspace{
  position:fixed;inset:0;z-index:-2;pointer-events:none;
  background-image:
    linear-gradient(to right, var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size:200px 200px;
}
/* 邊緣測量刻度 */
.labspace::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:15px;
  background:repeating-linear-gradient(to bottom,
    var(--lab-ruler) 0 1px, transparent 1px 40px);
}
/* 非常弱的徑向環境光：只是讓白不要死平，不是光暈效果 */
.labspace::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(118% 76% at 50% 15%,
    var(--lab-glow), transparent 62%);
}

/* ── 共用：實驗室小標籤 ─────────────────────────────────────────── */
.build-map{
  margin:0 0 clamp(22px,4vh,48px);
  font-family:var(--mono);font-size:9.5px;line-height:1.9;
  letter-spacing:.22em;text-transform:uppercase;color:var(--fg-faint);
}
.sys-map{margin-bottom:clamp(34px,6vh,72px)}

/* ── 01 HERO：實驗室系統資訊（純視覺語言，不搶主標題） ───────────── */
.hero-lab{
  position:absolute;left:var(--pad);top:calc(72px + clamp(18px,3.4vh,40px));
  margin:0;display:grid;gap:5px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.20em;
  text-transform:uppercase;
}
.hero-lab > div{display:flex;gap:16px}
.hero-lab dt{color:var(--fg-faint);min-width:118px}
.hero-lab dd{margin:0;color:var(--fg-dim)}
.hero-coord{
  position:absolute;right:var(--pad);bottom:clamp(26px,4.4vh,54px);
  margin:0;display:flex;gap:20px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;
  color:var(--fg-faint);
}

/* ── 02 WHAT I BUILD：七個模組是一個系統的內部結構 ───────────────── */
/* 注意：.w 本身已是 position:absolute（由 JS transform 定位）。
   不要在這裡再寫 position:relative —— 那會蓋掉絕對定位，詞掉回正常流向而溢出。 */
.w::before{
  content:attr(data-i);position:absolute;top:-1.15em;left:.1em;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;
  color:var(--fg-faint);opacity:.75;
}

/* ── 03 EXPERIMENTS：實驗記錄 ───────────────────────────────────── */
.proj-n{text-transform:uppercase}
.proj-log{
  --logw:min(340px,100%);
  width:var(--logw);margin:clamp(22px,3.4vh,38px) 0 0;
  border-top:1px solid var(--hair);
}
.proj-log > div{
  display:flex;justify-content:space-between;gap:20px;
  padding:7px 0;border-bottom:1px solid var(--hair);
}
.proj-log dt,.proj-log dd{
  font-family:var(--mono);font-size:9px;letter-spacing:.19em;
  text-transform:uppercase;
}
.proj-log dt{color:var(--fg-faint)}
.proj-log dd{margin:0;color:var(--fg-dim)}
.proj-open{
  display:inline-flex;align-items:center;gap:.7em;
  margin-top:clamp(22px,3.4vh,38px);
  font-family:var(--mono);font-size:14px;letter-spacing:0;
  color:var(--fg-dim);text-decoration:none;
  border-bottom:1px solid transparent;padding-bottom:3px;
  transition:color .6s var(--ease),border-color .6s var(--ease);
}
.proj-open span{transition:transform .7s var(--ease)}
.proj-open:hover{color:var(--fg);border-color:var(--hair)}
.proj-open:hover span{transform:translateX(4px)}

/* ── 04 LAB STATUS：實驗室內部狀態面板 ──────────────────────────── */
.sec-status .labpanel{
  --pw:min(560px,100%);width:var(--pw);margin:0;
  border-top:1px solid var(--hair);
}
.labpanel > div{
  display:flex;justify-content:space-between;gap:24px;
  padding:9px 0;border-bottom:1px solid var(--hair);
}
.labpanel dt,.labpanel dd{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.20em;
  text-transform:uppercase;
}
.labpanel dt{color:var(--fg-faint)}
.labpanel dd{margin:0;color:var(--fg-dim)}
.labpanel-note{
  margin:clamp(20px,3.4vh,34px) 0 0;
  font-family:var(--mono);font-size:9px;line-height:1.9;
  letter-spacing:.16em;text-transform:uppercase;color:var(--fg-faint);
}

/* ── 05 IDEAS：THE INTERFACE IS. 放大、但透明度稍低 ────────────── */
.idea[data-idea="1"]{
  text-transform:uppercase;font-style:normal;
  font-size:clamp(44px,9vw,152px);letter-spacing:-.022em;
}
.idea.idea-b.act{opacity:.84}

/* ── 06 SYSTEMS：三個系統原則 ──────────────────────────────────── */
.sec-sys .sn{text-transform:uppercase}
/* 三條原則：以細線分隔的實驗室規範 */
.sec-sys .syslist{list-style:none;margin:0;padding:0}
.sec-sys .syslist li{
  position:relative;border-top:1px solid var(--hair);
  padding-top:clamp(28px,4.4vh,52px);
  display:grid;grid-template-columns:minmax(0,1fr) clamp(90px,11vw,150px);
  gap:clamp(18px,3vw,48px);align-items:start;
}
.sec-sys .syslist li + li{margin-top:clamp(52px,9vh,110px)}
.sec-sys .syslist .sn{grid-column:1 / -1;margin-bottom:clamp(18px,3vh,30px)}
.sec-sys .sysbody b{
  display:block;font-family:var(--sans);font-weight:200;
  font-size:clamp(26px,3.4vw,52px);line-height:1.04;letter-spacing:-.035em;
  margin-bottom:clamp(20px,3.2vh,34px);
}

/* ── 07 INDEX：Lab Index 面板 ──────────────────────────────────── */
.sec-now{
  font-family:var(--mono);font-size:10px;letter-spacing:.28em;
  color:var(--fg-faint);transition:opacity .28s var(--ease);
}
.sec-now.swap{opacity:0}
.idx{
  font-family:var(--mono);font-size:10px;letter-spacing:.28em;
  color:var(--fg-dim);background:none;border:0;padding:0;cursor:pointer;
  transition:color .5s var(--ease);
}
.idx:hover,.idx[aria-expanded="true"]{color:var(--fg)}
.topbar-r{display:flex;align-items:center;gap:clamp(18px,3vw,40px)}

.labindex{position:fixed;inset:0;z-index:70}
.labindex[hidden]{display:none}
.li-scrim{
  position:absolute;inset:0;background:var(--veil);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  opacity:0;transition:opacity .44s var(--ease);
}
.li-panel{
  position:absolute;top:0;right:0;height:100%;
  width:min(460px,100%);
  padding:calc(72px + var(--sat) + clamp(16px,3vh,30px)) var(--pad-r) calc(clamp(30px,6vh,64px) + var(--sab)) var(--pad-l);
  display:flex;flex-direction:column;
  background:var(--panel);
  border-left:1px solid var(--hair);
  opacity:0;transform:translateX(14px);
  transition:opacity .46s var(--ease),transform .46s var(--ease);
  overflow-y:auto;
}
.labindex.on .li-scrim{opacity:1}
.labindex.on .li-panel{opacity:1;transform:none}
.li-head{
  display:flex;align-items:baseline;justify-content:space-between;
  padding-bottom:14px;border-bottom:1px solid var(--hair);
}
.li-title{
  font-family:var(--mono);font-size:10px;letter-spacing:.28em;color:var(--fg-dim);
}
.li-x{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.22em;
  background:none;border:0;padding:0;cursor:pointer;color:var(--fg-faint);
  transition:color .5s var(--ease);
}
.li-x:hover{color:var(--fg)}
.li-list{list-style:none;margin:clamp(22px,4vh,40px) 0 0;padding:0}
.li-list li{margin:0}
.li-sep{height:1px;background:var(--hair);margin:14px 0}
.li-list a,.li-mute{
  display:flex;align-items:baseline;gap:18px;padding:9px 0;
  font-family:var(--mono);font-size:11px;letter-spacing:.20em;
  text-transform:uppercase;text-decoration:none;
}
.li-list a{color:var(--fg-dim);transition:color .5s var(--ease)}
.li-list a:hover{color:var(--fg)}
.li-list a i,.li-mute i{font-style:normal;color:var(--fg-faint);font-size:9.5px;min-width:2.2em}
.li-list a span{transition:transform .55s var(--ease)}
.li-list a:hover span{transform:translateX(3px)}
.li-mute{color:var(--fg-faint);opacity:.55;cursor:default}

/* ── 08 END：整個 Lab 的出口 ───────────────────────────────────── */
.end-seclabel{display:block;margin-bottom:clamp(26px,5vh,58px)}
.end-cta{
  display:inline-flex;align-items:center;gap:.7em;
  margin-top:clamp(26px,4.6vh,52px);
  font-family:var(--mono);font-size:10px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--fg-dim);text-decoration:none;
  border-bottom:1px solid var(--hair);padding-bottom:4px;
  transition:color .6s var(--ease),border-color .6s var(--ease);
}
.end-cta:hover{color:var(--fg);border-color:var(--fg-dim)}
.end-cta span{transition:transform .7s var(--ease)}
.end-cta:hover span{transform:translateX(4px)}
.labfoot{
  display:flex;flex-wrap:wrap;gap:10px clamp(20px,4vw,48px);
  align-items:baseline;justify-content:space-between;
  margin-top:clamp(48px,10vh,120px);padding-top:18px;
  border-top:1px solid var(--hair);
  font-family:var(--mono);font-size:9px;letter-spacing:.20em;
  text-transform:uppercase;color:var(--fg-faint);
}

/* ── 12 RESPONSIVE ─────────────────────────────────────────────── */
@media (max-width:1024px){
  /* 平板：減少工程輔助資訊 */
  .labspace::before{width:10px;
    background:repeating-linear-gradient(to bottom,
      var(--lab-ruler) 0 1px, transparent 1px 64px);}
  .hero-lab > div:nth-child(3){display:none}
}
@media (max-width:720px){
  /* 手機：隱藏座標與刻度，實驗改縱向 */
  .hero-coord{display:none}
  .labspace::before{display:none}
  .hero-lab{top:calc(68px + 14px);gap:4px}
  .hero-lab dt{min-width:0}
  .hero-lab > div{flex-direction:column;gap:1px}
  .hero-lab > div:nth-child(3){display:flex}
  .proj-log{--logw:100%}
  .li-panel{width:100%;border-left:0}
}
/* 手機：顯微標籤放大一級（§12 不要讓文字過小）。
   放在既有 720px 區塊之後，才能覆蓋上面的 9-9.5px。 */
@media (max-width:720px){
  .hero-lab,.hero-lab dt,.hero-lab dd{font-size:10.5px}
  .proj-n,.proj-open,.build-map,.sys-map{font-size:10.5px}
  .proj-log dt,.proj-log dd{font-size:10.5px}
  .labpanel dt,.labpanel dd{font-size:10.5px}
  .labpanel-note,.labfoot,.labfoot span{font-size:10px}
  .li-list a,.li-mute{font-size:12px}
  .li-list a i,.li-mute i{font-size:10px}
  .sec-now,.idx{font-size:10.5px}
  .proj-log > div{padding:9px 0}
  .labpanel > div{padding:11px 0}
}

/* ── 主題按鈕：與 INDEX 同一套微型字，不是開關元件 ─────────────── */
.thm{
  font-family:var(--mono);font-size:10px;letter-spacing:.28em;
  color:var(--fg-faint);background:none;border:0;padding:0;cursor:pointer;
  transition:color .5s var(--ease);
}
.thm:hover{color:var(--fg)}
@media (max-width:720px){ .thm{font-size:10.5px} }


/* ══════════════════════════════════════════════════════════════════
   ── TYPOGRAPHY SCALE (authoritative) ───────────────────────────────

   The small end of this page had accumulated eleven sizes inside a 3.5px
   band (8.5 / 9 / 9.5 / 10 / 10.5 / 11 / 12), and the display end twenty-
   seven one-off clamps. Neither was a scale; both were the residue of
   adjusting one label at a time. This block is the single source of truth
   for type, and it sits last so it settles every earlier declaration
   without having to hunt them down through the cascade.

   Hierarchy, in the order the eye should take it:
     real content  >  explanatory prose  >  section title  >  metadata
                                                        >  decorative micro

   Metadata is not removed -- STATUS, MEDIUM, YEAR, the module map and the
   system numbers all stay. They are simply no longer yelling at the same
   volume as the prose. Nothing on this page is set below 11px any more,
   and nothing meant to be read as a sentence is below 15px.

   Deliberately NOT touched: the hero. Its display sizes are the one place
   where scale-as-impact is the point, and this pass is about the reading
   text underneath it.
   ══════════════════════════════════════════════════════════════════ */

:root{
  /* Seven steps. Everything on the page is one of these. */
  --fs-display: clamp(42px, 7vw, 92px);
  --fs-title:   clamp(28px, 4vw, 52px);
  --fs-sub:     clamp(18px, 2vw, 26px);
  /* 1.12vw rather than 1vw so a 1440 screen keeps the ~16px it reads well
     at; the point of the clamp is the 15px floor, which mobile now hits. */
  --fs-body:    clamp(15px, 1.12vw, 17px);
  --fs-small:   14px;
  --fs-meta:    12px;
  --fs-meta-v:  13px;
  --fs-micro:   11px;

  /* Tracking. Smaller type needs more of it -- but past roughly .2em a
     label stops being a word and becomes a row of separate letters, which
     is the opposite of readable. */
  --ls-ui:    .14em;
  --ls-label: .16em;
  --ls-meta:  .12em;

  /* Reading measure. Prose stops here; only structural blocks run full
     width. 640px is about 75 characters at 16px. */
  --measure:  640px;
  --measure-wide: 680px;

  /* Horizontal rhythm: content edge, not the viewport edge. */
  --pad:clamp(24px,4vw,64px);
}

/* ── Chrome: brand, index, section readout, theme. Nav is read, not
      decoded, so it sits at metadata size with restrained tracking. ── */
.brand,.idx,.sec-now,.thm,.snd{
  font-size:var(--fs-meta);
  letter-spacing:var(--ls-ui);
}
.brand{font-weight:500}

/* ── Section label. Was 10px at .32em -- a row of disconnected capitals.
      Same role, now legible. ── */
.seclabel{
  font-size:var(--fs-meta);
  letter-spacing:var(--ls-label);
}

/* ── MODULE MAP / DESIGN PROTOCOL: a section descriptor, not decoration.
      Size up roughly a third, tracking down by the same amount. ── */
.build-map,.sys-map{
  font-size:var(--fs-meta-v);
  line-height:1.7;
  letter-spacing:var(--ls-ui);
}

/* ══ 03 — EXPERIMENTS ══════════════════════════════════════════════
   The log is the metadata block, and it had both columns at 9px on
   desktop -- label and value the same size, the same weight and the same
   colour, so STATUS and ACTIVE read as one undifferentiated string.
   Label stays quiet; value becomes the thing you actually read. ── */
.proj-n{
  font-size:var(--fs-meta);
  letter-spacing:var(--ls-label);
}
.proj-m{
  font-size:var(--fs-meta-v);
  letter-spacing:var(--ls-meta);
}
.proj-log > div{padding:12px 0}
.proj-log dt,.proj-log dd{letter-spacing:var(--ls-meta)}
.proj-log dt{
  font-size:var(--fs-meta);
  color:var(--fg-faint);
}
.proj-log dd{
  font-size:var(--fs-meta-v);
  font-weight:500;
  color:var(--fg);
}
.proj p{
  max-width:var(--measure);
  font-size:var(--fs-body);
  line-height:1.65;
}
.proj-open{font-size:var(--fs-meta-v)}

/* ══ 02 — WHAT I BUILD ══════════════════════════════════════════════
   This is the page's central explanation and it was set as a 27-character
   column -- narrower than the metadata beside it. ── */
.build-note{
  max-width:var(--measure-wide);
  font-size:var(--fs-body);
  line-height:1.68;
}

/* ══ 06 — SYSTEMS ═══════════════════════════════════════════════════
   The principle is the visual subject; the description supports it.
   They now differ by more than three times. ── */
.syslist .sn{
  font-size:var(--fs-meta);
  letter-spacing:var(--ls-ui);
}
.syslist b,.sec-sys .sysbody b{
  font-size:var(--fs-title);
  line-height:1.06;
}
.syslist .sd{
  max-width:620px;
  font-size:var(--fs-body);
  line-height:1.68;
}

/* ══ 07 — ABOUT ═════════════════════════════════════════════════════ */
.about-line{
  font-size:var(--fs-meta);
  letter-spacing:var(--ls-ui);
}
.about-claim{
  font-size:var(--fs-title);
  line-height:1.12;
}
.about-p{
  max-width:var(--measure);
  font-size:var(--fs-body);
  line-height:1.68;
}
.about-links li{
  font-size:var(--fs-meta-v);
  letter-spacing:var(--ls-ui);
}

/* ── Remaining technical micro. Raised to metadata or micro; nothing
      below 11px survives. .hero-coord is the one true decoration and it
      keeps the smallest step. ── */
.hero-lab,.hero-lab dt,.hero-lab dd,.hero-coord,.hero-foot,.w::before,
.labpanel dt,.labpanel dd,.labpanel-note,.labfoot,.labfoot span,
.li-title,.li-x,.li-list a i,.li-mute i,.end-cta,.sec-now,.idx{
  letter-spacing:var(--ls-meta);
}
.hero-lab,.hero-lab dt,.hero-lab dd,.labpanel dt,.labpanel dd,.hero-foot{
  font-size:var(--fs-meta);
}
.hero-coord{font-size:var(--fs-micro)}
.w::before{font-size:var(--fs-micro)}
.labpanel-note,.labfoot,.labfoot span{font-size:var(--fs-small)}
.li-title{font-size:var(--fs-meta)}
.li-x{font-size:var(--fs-micro)}
.li-list a,.li-mute{font-size:var(--fs-small)}
.li-list a i,.li-mute i{font-size:var(--fs-micro)}
.end-cta{font-size:var(--fs-meta-v)}

/* ── Mobile: the floor holds. Body stays at 15px, secondary at 14px,
      metadata at 12px, buttons at 13px and up. Nothing shrinks to fit a
      line -- text is allowed to wrap instead. ── */
@media (max-width:720px){
  :root{--pad:22px}
  .proj p,.build-note,.about-p,.syslist .sd{
    font-size:max(15px,var(--fs-body));
    line-height:1.62;
  }
  .proj-log dd,.about-links li,.build-map,.sys-map,.proj-m,.proj-open,.end-cta{
    font-size:var(--fs-meta-v);
  }
  /* This one used to drop the brand to 10px on phones -- the smallest the
     mark gets anywhere, on the smallest screen. */
  .brand{font-size:var(--fs-meta)}
  .idx,.sec-now,.thm{font-size:var(--fs-meta)}
  /* A tap target, not a glyph. */
  .proj-open{min-width:44px;min-height:44px;justify-content:flex-end;align-items:center}
}

/* ── 320px: tighten the gutter rather than the type. ── */
@media (max-width:360px){
  :root{--pad:18px}
  .proj p,.build-note,.about-p,.syslist .sd{font-size:15px}
}

/* ── Refinements after measuring the result. ──────────────────────── */

/* The systems row keeps a fixed-width illustration column, and on a 320px
   screen that left the principle description 163px wide -- about eighteen
   characters a line, which is a column, not a paragraph. The drawing gives
   back what it does not need on small screens. */
.sec-sys .syslist li{
  grid-template-columns:minmax(0,1fr) clamp(64px,18vw,150px);
  gap:clamp(14px,2.4vw,48px);
}

/* The arrow was an inline glyph with an 8px hit box -- fine to look at,
   not fine to aim at. A tap target now, at every size. */
.proj-open{
  min-width:44px;
  min-height:44px;
  justify-content:flex-end;
  align-items:center;
}

/* Label to content was up to 100px of air, which reads as two unrelated
   blocks rather than a heading and what follows it. */
.seclabel{margin-bottom:clamp(36px,5.6vh,68px)}

/* ── Last three, found by scanning every text node rather than a list. ── */

/* "DIGITAL LAB" is set at .22em of its parent mark, so it shrank with the
   mark: 9.1px on a 320px screen, 10.7px at 375. Proportional type needs an
   absolute floor, or the smallest screen gets the smallest type. */
.about-mark span{font-size:max(11px,.22em)}

/* Below 560px the illustration column squeezed the principle text to about
   fifteen characters a line. The drawing is removed from the row and runs
   under the text instead, at a size it can hold. */
@media (max-width:560px){
  .sec-sys .syslist li{
    grid-template-columns:minmax(0,1fr);
    gap:0;
  }
  .sec-sys .sysviz{
    grid-column:1;
    width:clamp(76px,22vw,120px);
    margin-top:22px;
    justify-self:start;
  }
}

/* 22px of visible air between a section label and its content read as one
   block, not a heading and what follows it. */
.seclabel{margin-bottom:clamp(44px,6.5vh,84px)}
