
/* OD-LAYOUT-PRIMITIVES v1 — structure only: display, flex/grid, overflow, wrapping, ratio, geometry.
   Put this @layer first; product CSS outside the layer wins ordinary layout rules.
   Native hidden and closed-dialog states take precedence over component display rules. */
@layer od-layout {
  [hidden]:not([hidden="until-found" i]) { display: none !important; }
  dialog:not([open]) { display: none !important; }

  :where(.od-stack,.od-row,.od-row-top,.od-cluster,.od-grid,.od-field,.od-stat,.od-cell,.od-tile) > :where(*) { min-width: 0; }

  /* containers */
  .od-stack   { display: flex; flex-direction: column; gap: var(--od-gap, 8px); }
  .od-row     { display: flex; align-items: center; gap: var(--od-gap, 8px); }
  .od-row-top { display: flex; align-items: flex-start; gap: var(--od-gap, 8px); }
  .od-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--od-gap, 8px); }
  .od-fill    { flex: 1 1 0; min-width: 0; }
  .od-fixed   { flex: none; }
  .od-grid    { display: grid; gap: var(--od-gap, 12px); grid-template-columns: repeat(var(--od-cols, 3), minmax(0, 1fr)); }

  /* stacked information: each piece is its own line — never sibling inline spans */
  .od-stat, .od-field, .od-cell { display: grid; gap: var(--od-gap, 2px); }
  :where(.od-stat,.od-field,.od-cell) > :where(*) { display: block; }
  .od-tile { display: grid; grid-template-rows: auto 1fr; }
  :where(.od-tile) > :where(*) { display: block; }

  /* media keeps its intrinsic ratio by default; never a distorted or cropped
     cover by accident. height:auto lets the ratio win over an <img height="…">
     attribute. Cropping to a uniform box is an explicit opt-in: set --od-ratio
     AND add .od-media-cover together (per the core rule, only where a crop is
     deliberate — tile thumbs, decorative fills — never on full-frame content). */
  .od-media { display: block; width: 100%; height: auto; aspect-ratio: var(--od-ratio, auto); }
  .od-media-cover { object-fit: cover; }

  /* functional inline SVG icons opt into bounded geometry; content SVGs keep their own */
  .od-icon { display: inline-block; inline-size: var(--od-icon-size, 1em); block-size: var(--od-icon-size, 1em); flex: none; }

  /* data text only — authored copy is rewritten to its budget instead */
  .od-truncate { display: block; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .od-clamp-2, .od-clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
  .od-clamp-2 { -webkit-line-clamp: 2; }
  .od-clamp-3 { -webkit-line-clamp: 3; }
  .od-lines-2 { min-height: calc(2 * 1.4em); }   /* block-level reservation for a shared baseline */
  .od-nowrap  { white-space: nowrap; }           /* 数字+单位 · 价格+起 · 日期+星期 */
  .od-keep    { word-break: keep-all; overflow-wrap: anywhere; } /* CJK labels break at spaces / <wbr> first */

  /* screen skeleton (optional): bars take their own space, the middle scrolls — no padding guessed for chrome */
  .od-screen { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; height: 100%; }
  .od-scroll { overflow-y: auto; overscroll-behavior: contain; min-height: 0; }

  /* horizontal rail: the next item peeks at the edge; trailing room survives overflow */
  .od-rail { display: flex; gap: var(--od-gap, 8px); overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none;
             padding-inline: var(--od-rail-pad, 16px); scroll-padding-inline: var(--od-rail-pad, 16px); }
  .od-rail::-webkit-scrollbar { display: none; }
  :where(.od-rail) > :where(*) { flex: none; scroll-snap-align: start; }
  :where(.od-rail) > :where(:last-child) { margin-inline-end: var(--od-rail-pad, 16px); }

  .od-spacer { flex: none; visibility: hidden; pointer-events: none; }
  .od-touch  { min-width: 44px; min-height: 44px; }
}
:root [hidden]:where(:not([hidden="until-found" i])) { display: none; }
/* /OD-LAYOUT-PRIMITIVES v1 */

:root{--bg:#11151c;--surface:#171c25;--ink:#f1f1ef;--muted:#a9afbc;--faint:#768093;--line:#303642;--violet:#b7a1f6;--mint:#a7d8be;--coral:#edab96;--blue:#91b8df;--display:Georgia,'Times New Roman',serif;--sans:'Trebuchet MS',Verdana,sans-serif;--mono:'SFMono-Regular',Consolas,'Liberation Mono',monospace;--space:8px;--radius:8px;--speed:220ms;--page:1200px}
*{box-sizing:border-box}html{scroll-behavior:smooth;scroll-padding-top:32px}body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.65 var(--sans);-webkit-font-smoothing:antialiased}button,a{-webkit-tap-highlight-color:transparent}button,input{font:inherit}a{color:inherit;text-decoration:none}button{cursor:pointer}button:disabled{cursor:default}button,a{touch-action:manipulation}button:focus-visible,a:focus-visible,summary:focus-visible{outline:2px solid var(--mint);outline-offset:6px}::selection{background:var(--violet);color:var(--bg)}p,h1,h2,h3{margin:0}p{max-width:68ch}button{color:var(--ink)}.wrap{width:min(var(--page),calc(100% - 96px));margin-inline:auto}.mono{font-family:var(--mono);font-size:11px;letter-spacing:.08em}.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}.text-link{display:inline-flex;align-items:center;gap:16px;min-height:44px;border-bottom:1px solid var(--violet);font-size:14px;line-height:1.3;padding:8px 0;transition:color var(--speed),gap var(--speed)}.text-link .arrow{font-size:20px}.skip{position:fixed;z-index:20;top:16px;left:16px;padding:12px 24px;background:var(--mint);color:var(--bg);transform:translateY(-200%)}.skip:focus{transform:translateY(0)}.masthead{display:flex;align-items:center;justify-content:space-between;gap:24px;min-height:112px;border-bottom:1px solid var(--line)}.brand{display:flex;align-items:center;gap:12px;min-height:44px;font-size:16px;font-weight:bold;letter-spacing:-.04em}.brand-mark{width:32px;height:32px;color:var(--violet)}.brand span span{font-weight:normal;color:var(--muted)}.navigation{display:flex;gap:32px;align-items:center}.navigation a{font-size:12px;min-height:44px;display:inline-flex;align-items:center;gap:8px;transition:color var(--speed)}.navigation .nav-note{color:var(--muted)}.tiny-star{color:var(--mint);font-size:16px}.hero{display:grid;grid-template-columns:1.05fr 1fr;align-items:center;gap:24px;padding-block:64px 48px;min-height:636px}.hero-copy{padding-bottom:24px}.hero .eyebrow{display:flex;align-items:center;gap:12px;margin-bottom:24px}.small-dash{display:block;width:24px;height:1px;background:var(--mint)}h1{font-size:clamp(48px,5.6vw,76px);font-weight:400;line-height:1.06;letter-spacing:-.065em}h1>span{display:block}h1 em{font-family:var(--display);color:var(--violet);font-weight:400;letter-spacing:-.065em}.intro{color:var(--muted);font-size:16px;max-width:410px;margin-top:28px;line-height:1.75}.intro strong{color:var(--ink);font-weight:normal}.hero-actions{display:flex;align-items:center;gap:28px;margin-top:28px}.quiet-link{display:inline-flex;align-items:center;min-height:44px;font-size:13px;color:var(--muted)}.map-area{min-width:0;position:relative}.field-art{display:block;width:100%;height:auto;aspect-ratio:580/480}.field-art path,.field-art ellipse,.field-art rect,.field-art circle,.field-art line,.field-art polyline{vector-effect:non-scaling-stroke}.art-ink{fill:none;stroke:var(--muted);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}.art-low{stroke:#495166;stroke-width:.8;fill:none}.art-violet{stroke:var(--violet)}.art-mint{stroke:var(--mint)}.art-coral{stroke:var(--coral)}.art-blue{stroke:var(--blue)}.sketch-label{font-family:var(--mono);font-size:11px;letter-spacing:.02em;fill:var(--muted)}.field-art .sketch-label,.field-art .hand-label{paint-order:stroke fill;stroke:var(--bg);stroke-width:7px;stroke-linejoin:round}.hand-label{font-family:var(--display);font-size:16px;fill:var(--violet);font-style:italic}.map-node{transition:opacity var(--speed),filter var(--speed)}.map-area[data-active] .map-node{opacity:.3}.map-area[data-active="code"] .node-code,.map-area[data-active="design"] .node-design,.map-area[data-active="music"] .node-music,.map-area[data-active="outside"] .node-outside{opacity:1;filter:drop-shadow(0 0 8px #b7a1f628)}.map-caption{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:0 16px}.map-caption>span{font-size:10px;letter-spacing:.06em;color:var(--faint)}.thread-controls{display:flex;gap:8px;flex-wrap:wrap}.thread-controls button{border:1px solid transparent;background:transparent;min-height:44px;padding:8px;color:var(--muted);font-family:var(--mono);font-size:10px;transition:color var(--speed),border-color var(--speed)}.thread-controls button[aria-pressed="true"]{border-color:var(--line);color:var(--mint)}.thread-note{min-height:56px;padding:8px 24px 0;font-family:var(--mono);font-size:11px;color:var(--muted)}.hero-foot{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:20px 0 24px;border-bottom:1px solid var(--line);color:var(--muted)}.hero-foot .interests{display:flex;flex-wrap:wrap;gap:12px;font-size:10px}.interests b{color:var(--violet);font-weight:normal}.hero-foot .page-number{font-size:10px;color:var(--faint);white-space:nowrap}.section{padding-block:72px}.section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:32px;margin-bottom:36px}.section-header h2,.about h2,.music h2,.closing h2{font-size:clamp(30px,3.4vw,44px);font-weight:normal;line-height:1.18;letter-spacing:-.05em}.section-header h2 em,.about h2 em,.music h2 em,.closing h2 em{font-family:var(--display);font-weight:400;color:var(--violet)}.section-index{display:flex;gap:16px;align-items:center;margin-bottom:16px}.section-index .number{color:var(--violet);font-size:11px}.section-intro{font-size:13px;color:var(--muted);max-width:260px;padding-top:36px}.project-feature{border:1px solid var(--line);display:grid;grid-template-columns:1fr 1fr;min-height:316px;background:var(--surface)}.feature-copy{padding:36px 40px;display:flex;flex-direction:column;align-items:flex-start}.status{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10px;color:var(--mint);letter-spacing:.06em}.status i{width:6px;height:6px;border-radius:50%;background:var(--mint);box-shadow:0 0 8px #a7d8be30}.project-no{color:var(--faint);font-size:11px}.feature-copy h3{font-size:36px;line-height:1.2;letter-spacing:-.05em;font-weight:normal;margin:24px 0 12px}.feature-copy p{font-size:14px;color:var(--muted);max-width:320px}.feature-copy button{margin-top:24px;background:transparent;color:var(--ink);border-width:0 0 1px;border-color:var(--violet)}.ledger-art{display:grid;place-items:center;position:relative;border-left:1px solid var(--line);background-color:#1d2230;background-image:radial-gradient(#8d86ac2b .8px,transparent .8px);background-size:20px 20px;padding:24px}.ledger-art svg{display:block;width:min(100%,390px);height:auto;aspect-ratio:400/270}.project-list{margin-top:8px}.project-row{border-bottom:1px solid var(--line)}.project-row summary{list-style:none;display:grid;grid-template-columns:48px 1fr 184px 116px 24px;align-items:center;gap:16px;min-height:96px;cursor:pointer;padding:16px 8px}.project-row summary::-webkit-details-marker{display:none}.project-row h3{font-size:20px;font-weight:normal;letter-spacing:-.035em}.project-category{font-size:11px;color:var(--muted)}.upcoming{font-family:var(--mono);font-size:10px;color:var(--muted);letter-spacing:.04em;white-space:nowrap}.plus{font-size:20px;font-weight:normal;color:var(--violet);transition:transform var(--speed);display:block;text-align:center}.project-row[open] .plus{transform:rotate(45deg)}.project-detail{padding:0 48px 28px 72px;color:var(--muted);font-size:14px;max-width:680px}.project-detail p+p{margin-top:8px}.margin-note{display:flex;align-items:center;justify-content:flex-end;gap:12px;color:var(--muted);font-family:var(--display);font-style:italic;font-size:15px;margin-top:20px}.margin-note svg{width:56px;height:28px;color:var(--violet)}.about{display:grid;grid-template-columns:1fr 1fr;gap:72px;padding-block:64px 72px;border-top:1px solid var(--line)}.about-content p{font-size:16px;color:var(--muted);line-height:1.8}.about-content p+p{margin-top:20px}.about-content strong{font-weight:normal;color:var(--ink)}.about-title .little-orbit{display:block;margin-top:24px;width:160px;height:80px}.about-content .aside{font:11px/1.8 var(--mono);color:var(--coral);margin-top:24px}.music{border-top:1px solid var(--line);padding-block:64px 72px;display:grid;grid-template-columns:1fr 1fr;gap:72px}.music p{font-size:14px;color:var(--muted);margin-top:20px;max-width:360px}.music .eyebrow{margin-bottom:16px}.keyboard-box{align-self:center}.keyboard-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;color:var(--faint);margin-bottom:16px;font:10px var(--mono)}.keyboard{--key-gap:4px;display:block;isolation:isolate;position:relative;padding:16px;background:#1c212a;border:1px solid #3c4351;border-radius:var(--radius)}.white-key{display:block;position:relative;min-height:144px;min-width:0;background:#cacdd1;color:#272a32;border:0;border-radius:2px 2px 4px 4px;box-shadow:inset 0 -5px 0 #999fa8;transition:background var(--speed),transform var(--speed)}.white-key span{display:block;position:absolute;bottom:12px;left:0;right:0;font:10px var(--mono);opacity:0;transition:opacity var(--speed)}.white-key:focus-visible{outline-offset:-6px;outline-color:#33304c}.white-key.playing{background:var(--violet);transform:translateY(3px)}.keyboard-keys{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:var(--key-gap);position:relative}.black-key{position:absolute;display:block;top:0;left:calc((100% + var(--key-gap)) * var(--after) / 8 - var(--key-gap) / 2);transform:translateX(-50%);width:calc((100% - 7 * var(--key-gap)) / 8 * .62);height:82px;min-width:0;padding:0;background:#141821;border:1px solid #333947;border-radius:0 0 3px 3px;z-index:2;box-shadow:0 4px 0 #0b0e13;transition:background var(--speed)}.black-key.playing{background:#8870bd}.black-key:focus-visible{outline:2px solid var(--mint);outline-offset:2px}@media(hover:hover){.black-key:hover{background:#353046}}.piano-caption{display:flex;align-items:center;justify-content:space-between;gap:16px;font:10px/1.7 var(--mono);color:var(--muted);margin-top:16px}.sound-note{color:var(--mint)}.closing{padding:48px 0;border-top:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:32px}.closing h2{font-size:32px}.closing p{font-size:13px;color:var(--muted);margin-top:12px}.closing .contact-note{max-width:300px;font:11px/1.8 var(--mono);color:var(--muted)}footer{display:flex;justify-content:space-between;gap:24px;padding:24px 0 32px;border-top:1px solid var(--line);font:10px/1.8 var(--mono);color:var(--faint)}footer a{display:inline-flex;min-height:44px;align-items:center;color:var(--muted)}footer .footer-brand{color:var(--muted);font-family:var(--sans);font-size:12px}.dialog{max-width:560px;width:calc(100% - 40px);padding:40px;border:1px solid #51536c;background:var(--surface);color:var(--ink);border-radius:var(--radius)}.dialog::backdrop{background:#070910d9;backdrop-filter:blur(6px)}.dialog-head{display:flex;justify-content:space-between;align-items:center;gap:16px}.close-dialog{background:transparent;border:1px solid var(--line);width:44px;height:44px;font-size:24px;line-height:1}.dialog h2{font-size:36px;font-weight:normal;letter-spacing:-.04em;margin:24px 0 16px}.dialog p{font-size:15px;color:var(--muted)}.dialog .connection-note{margin-top:28px;padding-top:24px;border-top:1px solid var(--line);font:12px/1.8 var(--mono)}.dialog .text-link{margin-top:24px;background:transparent;color:var(--ink);border-width:0 0 1px}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;clip-path:inset(50%);white-space:nowrap;overflow:hidden}
@media(hover:hover){.navigation a:hover,.quiet-link:hover{color:var(--violet)}.text-link:hover{color:var(--mint);gap:24px}.thread-controls button:hover{color:var(--ink);border-color:var(--line)}.project-row summary:hover{background:#ffffff03}.project-row summary:hover h3{color:var(--violet)}.white-key:hover{background:#e0d7f1}.white-key:hover span{opacity:1}.close-dialog:hover{background:#292f3d}footer a:hover{color:var(--mint)}}
@media(min-width:1440px){.hero{gap:48px;min-height:660px}.hero-copy{padding-bottom:32px}}
@media(max-width:1024px){.wrap{width:calc(100% - 64px)}.hero{gap:8px;padding-top:48px;min-height:580px}h1{font-size:clamp(44px,6vw,64px)}.hero-actions{gap:20px}.project-row summary{grid-template-columns:32px 1fr 140px 100px 24px;gap:12px}.feature-copy{padding:32px}.about,.music{gap:40px}.map-caption{padding:0;gap:4px;flex-wrap:wrap}.thread-note{padding-inline:8px}.thread-controls{gap:0}.hero-foot .interests{gap:8px}}
@media(max-width:767px){.wrap{width:calc(100% - 40px)}.masthead{min-height:88px;gap:16px}.navigation{gap:20px}.navigation a{font-size:11px}.navigation .nav-note{display:none}.hero{grid-template-columns:1fr;padding-block:48px 24px;gap:16px}.hero-copy{padding-bottom:0}h1{font-size:clamp(48px,9.3vw,68px);letter-spacing:-.06em}.intro{max-width:480px}.map-area{max-width:520px;width:100%;margin:auto}.field-art{max-height:410px}.map-caption{padding-inline:8px;flex-wrap:nowrap}.thread-note{min-height:48px;padding-inline:16px}.hero-foot{align-items:flex-start;padding-top:16px}.hero-foot .interests{max-width:300px;line-height:1.9}.hero-foot .page-number{font-size:9px}.section{padding-block:48px}.section-header{display:block;margin-bottom:28px}.section-intro{padding-top:16px;max-width:390px}.section-header h2,.about h2,.music h2{font-size:36px}.project-feature{grid-template-columns:1fr}.ledger-art{border-left:0;border-top:1px solid var(--line);padding:16px;min-height:252px}.ledger-art svg{max-width:340px}.feature-copy{padding:28px}.feature-copy h3{font-size:32px}.project-row summary{grid-template-columns:24px 1fr 24px;column-gap:12px;min-height:104px}.project-row h3{font-size:18px;grid-column:2}.project-row .project-category{grid-column:2;grid-row:2}.project-row .upcoming{grid-column:2;grid-row:3;font-size:9px}.project-row .plus{grid-column:3;grid-row:1/4}.project-row .project-no{grid-row:1/4;align-self:start;padding-top:4px}.project-row summary{row-gap:4px}.project-detail{padding:0 24px 24px 44px;font-size:13px}.margin-note{font-size:13px}.about,.music{grid-template-columns:1fr;gap:28px;padding-block:48px}.about-title .little-orbit{display:none}.about-content p{font-size:15px}.music p{max-width:440px}.keyboard-box{max-width:520px;width:100%}.closing{align-items:flex-start;flex-direction:column;gap:20px}.closing h2{font-size:30px}.closing .contact-note{max-width:440px}footer{align-items:flex-start;font-size:9px}footer>div{max-width:240px}.dialog{padding:24px}}
@media(max-width:374px){.wrap{width:calc(100% - 32px)}.navigation{gap:12px}.hero-actions{gap:16px}.hero-actions .quiet-link{font-size:11px}.map-caption{flex-direction:column;align-items:flex-start}.hero-foot .page-number{display:none}.thread-note{padding-left:8px}.project-row h3{font-size:17px}.white-key{min-height:120px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*::before,*::after{animation:none!important;transition:none!important}.white-key.playing{transform:none}}

/* Playable keyboard: keycaps double as the computer-key diagram. */
.sound-controls{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:16px}.sound-label{font:10px var(--mono);letter-spacing:.08em;color:var(--muted);margin-right:8px}.sound-controls button{min-height:44px;padding:8px 12px;background:transparent;border:1px solid var(--line);color:var(--muted);border-radius:4px;font:11px var(--mono);transition:background var(--speed),color var(--speed),border-color var(--speed)}.sound-controls button[aria-pressed="true"]{background:#292438;color:#dfd3ff;border-color:var(--violet)}.keyboard [data-note]{user-select:none;-webkit-user-select:none;touch-action:none}.keyboard .white-key span.note-label{opacity:1;bottom:36px;color:#51545e;font:9px var(--mono)}.piano-keycap{position:absolute;display:grid;place-items:center;bottom:12px;left:50%;transform:translateX(-50%);min-width:20px;height:20px;border:1px solid #9297a1;border-radius:3px;font:11px var(--mono);color:#343844;background:transparent}.black-key .piano-keycap{bottom:10px;min-width:16px;height:20px;border-color:#515367;color:#e0d8f5;font-size:10px}.white-key.playing .piano-keycap{border-color:#61527f}.black-key.playing{background:#8870bd!important}.keyboard-help{margin-top:12px!important;max-width:none!important;font:11px/1.8 var(--mono)!important;color:var(--muted)}.piano-caption{flex-wrap:wrap;min-height:36px}.sound-note{color:var(--mint)}
@media(hover:hover){.sound-controls button:hover{border-color:var(--violet);color:var(--ink)}}
@media(max-width:374px){.sound-controls{gap:8px}.sound-label{width:100%}.sound-controls button{padding-inline:8px}.piano-keycap{min-width:16px}.keyboard .white-key span.note-label{font-size:8px}}
