/* ============================================================================
   a little bit of... — the site stylesheet.
   Every colour, type, space and motion value below is CONSUMED from
   docs/art-direction-2026-10-08.md (§2.1 palette · §3.1/§3.4 type · §4.2/§4.4
   space and grid · §5.2–§5.4 the mark · §7.1–§7.4 motion) — none is invented.
   Every client URL carries the build's / token, substituted by
   scripts/build.js from BASE_PATH (the tailnet build's path prefix, or "/"
   for the public root-domain build), so a stylesheet can never resolve
   against the wrong origin root.
   ========================================================================= */

@font-face{
  font-family:"alb-display";
  src:url("/assets/fonts/architects-daughter.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"alb-cjk-display";
  src:url("/assets/fonts/noto-serif-sc-display.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap;
}

:root{
  /* ground — measured (art-direction §2.1) */
  --paper:#FAF9F3; --paper-plate:#FDFCF5; --paper-2:#F8F4EC;
  --rule:#DAD8D3; --rule-strong:#CBC5BF;
  /* ink — measured */
  --ink:#181818; --ink-body:#3A3A38; --ink-muted:#5C5A54; --ink-faint:#6B6862;
  /* the ONE UI accent (derived from the supplied mark's own pencil) */
  --accent:#8E5A2B; --accent-hover:#7A4C22; --accent-soft:#C79A6A; --graphite:#383148;
  --radius:14px; --radius-sm:8px;

  /* type — §3.1, §3.3, §3.4 */
  --font-cjk:"Songti SC","STSong","Source Han Serif SC","Noto Serif CJK SC",
             "Noto Serif CJK TC","AR PL UMing CN","SimSun",serif;
  --font-body:ui-sans-serif,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",
              Arial,"Noto Sans",sans-serif;
  --font-display:"alb-display","Architects Daughter",var(--font-body);
  --font-cjk-display:"alb-cjk-display","Songti SC","STSong","Source Han Serif SC",
                     "Noto Serif CJK SC",serif;
  --fs-caption:13px; --fs-small:14px; --fs-body:17px; --fs-lead:21px;
  --fs-h4:24px; --fs-h3:30px; --fs-h2:38px; --fs-h1:48px;
  --fs-display:clamp(40px,8vw,60px);
  --lh-latin:1.70; --lh-cjk:1.85;
  --ls-eyebrow:0.08em; --ls-display:0.01em;
  --measure:578px;

  /* space — §4.2, §4.3, §4.4 */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:32px;
  --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px; --s-11:160px; --s-12:224px;
  --container:1100px; --gutter:24px;
  --sec:var(--s-9); --rowgap:var(--s-8); --colgap:var(--s-7);

  /* motion — §7.4: one duration, one easing, and only colour/opacity/transform */
  --dur:180ms;
}
@media (max-width:720px){ :root{ --sec:var(--s-8); --rowgap:var(--s-6); } }

*,*::before,*::after{box-sizing:border-box}
html{background:var(--paper);-webkit-text-size-adjust:100%}
body{
  margin:0;font-family:var(--font-body);font-size:var(--fs-body);
  line-height:var(--lh-latin);color:var(--ink-body);background:var(--paper);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
img{max-width:100%;height:auto;display:block}
h1,h2,h3,h4{margin:0;font-weight:400}
p{margin:0}
ul{margin:0;padding:0;list-style:none}

/* --- the two languages, set apart on purpose ------------------------------
   The document is lang="en" (the chrome is English) and each Chinese element
   carries its own lang="zh-Hans", so a screen reader switches voice exactly
   there. Chinese gets its own line-height and ZERO tracking — a letter-spacing
   inherited from a Latin display rule visibly unpicks it (§3.4). */
.cjk{
  font-family:var(--font-cjk);line-height:var(--lh-cjk);letter-spacing:0;
  line-break:strict;word-break:normal;overflow-wrap:break-word;
  font-kerning:normal;text-rendering:optimizeLegibility;
}
.cjk-display{font-family:var(--font-cjk-display)}

a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover);text-decoration:underline;text-underline-offset:3px}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:3px;
  border-radius:var(--radius-sm)}

.skip{position:absolute;left:-9999px;top:0;background:var(--paper-plate);color:var(--ink);
  border:1px solid var(--rule-strong);border-radius:var(--radius-sm);padding:10px 14px;z-index:99}
.skip:focus{left:var(--s-4);top:var(--s-4)}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.wrap{max-width:var(--container);margin:0 auto;padding:0 var(--gutter)}
.measure{max-width:var(--measure)}

/* --- the brand mark on its plate (§5.2, §5.3) ----------------------------
   The supplied drawing's ground is OPAQUE #FDFCF5 (alpha 253–255, measured).
   The plate IS that ground, so the seam is designed rather than hidden: no
   blend mode, no cut-out, no drop shadow, ever (§5.3, §8 rules 2 and 10). */
.plate{
  background:var(--paper-plate);border:1px solid var(--rule-strong);
  border-radius:var(--radius);padding:8px;line-height:0;flex:none;
  display:inline-block;
}
.plate img{width:var(--box,96px);height:var(--box,96px)}

/* --- header -------------------------------------------------------------- */
header{border-bottom:1px solid var(--rule);background:var(--paper)}
.bar{display:flex;align-items:center;gap:var(--s-5);padding:var(--s-3) 0;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:var(--s-4);text-decoration:none;color:inherit;
  flex:1 1 auto;min-width:0}
.brand:hover{text-decoration:none}
.brand .plate{padding:6px}
.brand .plate img{width:var(--box,96px);height:var(--box,96px)}
.wordmark{font-family:var(--font-display);font-size:var(--fs-h4);letter-spacing:var(--ls-display);
  color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
nav ul{display:flex;gap:var(--s-5)}
nav a{font-size:var(--fs-small);color:var(--ink-body);text-decoration:none;
  padding:var(--s-3) 2px;min-height:44px;display:inline-flex;align-items:center}
nav a:hover{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
nav a[aria-current="page"]{color:var(--ink)}
nav a[aria-current="page"] span{border-bottom:1px solid var(--rule-strong);padding-bottom:2px}

/* --- the drawn rule (§7.1). The wobble lives in the PATH DATA, never in the
   animation — a drawn rule is not a border: it overshoots ~2 px at each end. */
.rule{display:block;width:100%;max-width:400px;height:16px;overflow:visible}
.rule path{fill:none;stroke:var(--rule-strong);stroke-width:1.5;stroke-linecap:round;
  vector-effect:non-scaling-stroke}
.rule.armed path{stroke-dasharray:420;stroke-dashoffset:420}
.rule.armed.seen path{stroke-dashoffset:0;
  transition:stroke-dashoffset 420ms cubic-bezier(0.22,0.61,0.36,1)}

/* --- hero (§4.3) --------------------------------------------------------- */
.hero{padding:var(--s-11) 0 var(--s-9)}
.hero .plate{--box:200px;display:inline-block}
h1.display{font-family:var(--font-display);font-size:var(--fs-display);line-height:1.15;
  letter-spacing:var(--ls-display);color:var(--ink);margin-top:var(--s-6)}
.tagline{font-size:var(--fs-h2);color:var(--ink);margin-top:var(--s-3)}
.lead{font-size:var(--fs-lead);color:var(--ink-body);line-height:1.6;margin-top:var(--s-6)}
.intro{font-size:var(--fs-body);color:var(--ink-muted);margin-top:var(--s-4)}

section{padding:var(--sec) 0;border-top:1px solid var(--rule)}
.eyebrow{font-size:var(--fs-caption);letter-spacing:var(--ls-eyebrow);text-transform:uppercase;
  color:var(--ink-faint);margin-bottom:var(--s-4)}
h1.pageh1{font-size:var(--fs-h2);color:var(--ink);line-height:1.5;margin-top:var(--s-4)}

/* --- the featured slot was removed (Commander, 2026-10-08) -----------------
   .featured / .featured-text / h3.feat / .gloss / h2.sec served only that block
   (and the Connect h2 that is now a small footer label), so they are gone with
   it.  h2.sec is deliberately deleted, not left as dead CSS. */
.meta{font-size:var(--fs-caption);color:var(--ink-faint);margin-top:var(--s-4)}
.feat-desc{font-size:var(--fs-body);color:var(--ink-body);margin-top:var(--s-5)}
.acts{display:flex;flex-wrap:wrap;gap:var(--s-4) var(--s-5);align-items:center;margin-top:var(--s-6)}
.btn{display:inline-flex;align-items:center;gap:var(--s-2);font-size:var(--fs-small);
  color:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:11px 20px;min-height:44px;
  background:none;cursor:pointer;font-family:inherit;
  transition:background-color var(--dur) ease-out,color var(--dur) ease-out}
.btn:hover{background:var(--ink);color:var(--paper);text-decoration:none}
.more{font-size:var(--fs-small)}

/* --- media: the 16:9 slot, the facade, and the "not out yet" panel --------
   At load a release page carries a LOCAL image and nothing else: no iframe, no
   YouTube script, no i.ytimg.com request, zero third-party bytes (§6.4). */
.media{position:relative;width:100%;aspect-ratio:16/9;background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden}
.media img{width:100%;height:100%;object-fit:cover}
.hero .plate img{width:var(--box,200px);height:var(--box,200px)}
.facade{appearance:none;-webkit-appearance:none;border:0;padding:0;margin:0;width:100%;
  height:100%;background:transparent;cursor:pointer;display:block;font-family:inherit;
  color:inherit;position:relative}
.glyph{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;
  border-radius:50%;background:var(--paper-plate);border:1px solid var(--rule-strong);
  display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--ink)}
.media iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.chip{position:absolute;left:10px;bottom:10px;font-size:11px;letter-spacing:.05em;
  color:var(--ink-faint);background:var(--paper-plate);border:1px solid var(--rule);
  border-radius:var(--radius-sm);padding:3px 7px;font-family:var(--font-body)}
.notout{margin-top:var(--s-5);border:1px solid var(--rule-strong);border-radius:var(--radius);
  padding:var(--s-5);max-width:var(--measure);background:var(--paper)}
.notout b{display:block;font-size:var(--fs-body);color:var(--ink);margin-bottom:var(--s-2)}
.notout span{display:block;font-size:var(--fs-small);color:var(--ink-muted)}

/* --- the collection: TWO columns above 900 px, ONE below (§4.4). Never three
   — two large stills read as a gallery, three read as a catalogue. */
.collection{margin-top:var(--s-7)}
.grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--rowgap) var(--colgap)}
@media (max-width:900px){ .grid{grid-template-columns:1fr} }
.card{display:block;color:inherit}
.card .media{transition:background-color var(--dur) ease-out}
.card:hover .media,.card:focus-within .media{background:var(--paper-2)}
.card h3{font-size:var(--fs-h4);color:var(--ink);margin-top:var(--s-4);line-height:1.65;
  position:relative;display:inline-block}
.card h3 a{color:var(--ink);text-decoration:none}
.card h3 .u{position:absolute;left:0;right:0;bottom:-6px;height:10px;overflow:visible}
.card h3 .u path{fill:none;stroke:var(--rule-strong);stroke-width:1.5;stroke-linecap:round;
  stroke-dasharray:420;stroke-dashoffset:420}
.card:hover h3 .u path,.card:focus-within h3 .u path{stroke-dashoffset:0;
  transition:stroke-dashoffset 240ms cubic-bezier(0.22,0.61,0.36,1)}
.card .cardtitle-en{font-family:var(--font-display);font-size:var(--fs-body);
  color:var(--ink-body);letter-spacing:var(--ls-display);line-height:1.4;
  margin-top:var(--s-1)}
.card .cardmeta{display:block;font-size:var(--fs-caption);color:var(--ink-faint);margin-top:var(--s-4)}
.card p.carddesc{font-size:var(--fs-small);color:var(--ink-muted);margin-top:var(--s-3);
  max-width:46ch}

/* --- release page -------------------------------------------------------- */
.back{font-size:var(--fs-small);display:inline-flex;align-items:center;min-height:44px}
.release-head{padding:var(--s-7) 0 0}
.release-art{max-width:720px}
h1.rel{font-size:var(--fs-h1);color:var(--ink);margin-top:var(--s-7);line-height:1.45}
/* the English title under the Chinese one — the brand's own naming construction
   ("a little bit of " + a noun) set in the SAME display face as the wordmark, at
   the wordmark's own 24 px, so a visitor can SEE that the three songs are one
   system and not three stray subtitles.  The Chinese title above it stays primary. */
.reltitle-en{font-family:var(--font-display);font-size:var(--fs-h4);color:var(--ink);
  letter-spacing:var(--ls-display);line-height:1.4;margin-top:var(--s-3)}
.relbody{max-width:var(--measure)}
/* the release page LEADS with the song's own description — the substance, not
   a caption above a video. It is the release's prose, so it takes the prose
   block's own paragraph rhythm; only the gap under the meta line is new. */
.lead-desc{margin-top:var(--s-5);font-size:var(--fs-body);color:var(--ink-body)}
.listen{margin-top:var(--s-5);font-size:var(--fs-small);color:var(--ink-muted)}
.listen ul{margin-top:var(--s-2)}
.listen li{margin-bottom:var(--s-2)}
.prevnext{border-top:1px solid var(--rule);margin-top:var(--s-7);padding-top:var(--s-5);
  display:flex;flex-wrap:wrap;gap:var(--s-4) var(--s-7);justify-content:space-between;
  font-size:var(--fs-small)}
.prevnext a{display:inline-flex;align-items:center;min-height:44px}

/* --- about --------------------------------------------------------------- */
.prose p+p{margin-top:var(--s-5)}
.prose .cjk{font-size:var(--fs-lead);color:var(--ink);margin-top:var(--s-7)}

/* --- footer: ONE closing block --------------------------------------------
   The footer holds three things and reads as one block, not as a section followed
   by a footer: the brand statement (mark + name + tagline), the three platform
   links, and the enquiry line.  The brand block takes the SAME treatment as the
   header wordmark — the .wordmark rule above gives it the display face, the 24 px
   size and the ink — and sits beside the mark the same way (mark left, name
   right, --s-4 gap), with the Chinese tagline quiet beneath the name.  The
   一点点…… line is gone.

   ONE monochrome mark per platform, 20 px tall: 20 px is YouTube's own published
   digital minimum for the Icon, so the height is a floor and not a taste.  Each
   mark keeps its own platform-approved black (the fill lives in the file).  The
   48 px column gap wrapped the row 2+1 at 390 px; 24 px (--s-5) puts all three on
   one line.  The clear space the three guidelines require is met by that column
   gap and by the .55em gap between a mark and its own label.

   NOTE: because Connect now sits inside a <nav>, the global `nav a` rule would
   add 2 px of horizontal padding to each link — 12 px across the three, which
   wrapped the row at 390 px.  `.connect li a{padding:0}` restores the section's
   own geometry; the 44 px min-height keeps the touch target. */
footer{border-top:1px solid var(--rule);padding:var(--s-6) 0 var(--s-8);
  color:var(--ink-faint);font-size:var(--fs-caption)}
/* --- the footer's TWO COLUMNS (Commander, 2026-10-08) ---------------------
   "move the connect portion to the right of the footer.  so it's not stacked
   below the image and the 'a little bit of... 一笔一画，一首歌'"
   The footer is ONE closing block, laid out as two columns: the brand statement
   on the left (mark, then the English name in the header's own .wordmark rule and
   the CJK tagline beneath it) and Connect to its RIGHT, right-aligned so the row
   hangs off the same right margin as the brand's own text column.  The enquiry line
   spans both columns underneath, where it still closes the footer.  Below the fold
   width the two columns are geometrically impossible (the numbers are in the report
   and in the media query below), so the footer becomes ONE column and Connect keeps
   its right alignment — the same right edge it has in the two-column composition,
   so the eye reads it as that column folded down, not as a plain stack. */
.foot{display:grid;grid-template-columns:1fr auto;column-gap:var(--s-7);
  row-gap:var(--s-5);align-items:center}
.foot-brand{display:flex;align-items:center;gap:var(--s-4)}
.foot-brand .plate{padding:6px;border-radius:var(--radius-sm)}
.foot-brand .plate img{width:96px;height:96px}
.foot-ident{display:flex;flex-direction:column;gap:var(--s-1);min-width:0}
.foot-tagline{font-size:var(--fs-body);color:var(--ink-muted)}
.connect{justify-self:end;max-width:100%}
.connect .eyebrow{text-align:right}
.connect ul{margin-top:var(--s-2);display:flex;flex-wrap:wrap;align-items:center;
  justify-content:flex-end;gap:var(--s-2) var(--s-7)}
.connect li a{font-size:var(--fs-body);color:var(--ink-body);min-height:44px;
  display:inline-flex;align-items:center;gap:.55em;padding:0}
.connect picture{display:inline-flex;align-items:center}
.connect .ico{flex:none;display:block;height:20px;width:auto}
.connect li a:hover{color:var(--accent)}
.enquiries{font-size:var(--fs-small);color:var(--ink-muted);
  max-width:var(--measure);grid-column:1 / -1}
@media (max-width:430px){ .connect ul{gap:var(--s-2) var(--s-5)} }   /* 24px — one line at 390 */
@media (max-width:380px){ .connect ul{column-gap:var(--s-4)} }      /* 16px — one line at 375 */
@media (max-width:364px){ .connect ul{column-gap:var(--s-3)} }      /* 12px — one line at 360 */
/* --- where the footer's two columns stop fitting --------------------------
   MEASURED, not guessed (report + browser proof): at >= 761 px the brand block's
   280 px of content and the Connect row's 334 px both have room beside each other
   (280 + 48 + 381 = 709 <= 713 of content width); below that they do not.  Geometry,
   not taste: the mark may not drop under 96 px and the Connect marks may not drop
   under 20 px, so there is no smaller arrangement that keeps two columns.

   So the footer folds to ONE column — and Connect folds with it as a compact
   VERTICAL rail, right-aligned, rather than a one-line row.  That is deliberate: a
   one-line row needs 333 px of the 342 px available at 390 px, so right-aligning it
   would shift it by 9 px and look EXACTLY like the old left-stacked row — an
   unchanged footer.  A right-hand rail reads as the second column folded down: the
   same right edge, the same order, the marks still 20 px with their clear space and
   their 44 px touch targets. */
@media (max-width:760px){
  .foot{grid-template-columns:1fr}
  .connect ul{flex-direction:column;align-items:flex-end}
}

.toTop{position:fixed;right:var(--s-4);bottom:calc(var(--s-4) + env(safe-area-inset-bottom,0px));
  width:46px;height:46px;border-radius:50%;border:1px solid var(--rule-strong);
  background:var(--paper-plate);color:var(--ink);font-size:15px;cursor:pointer;opacity:0;
  pointer-events:none;transition:opacity var(--dur) ease-out;z-index:30;
  font-family:inherit;appearance:none;-webkit-appearance:none}
.toTop.on{opacity:1;pointer-events:auto}

/* --- 404 ----------------------------------------------------------------- */
.nf{padding:var(--s-11) 0 var(--s-10)}

@media (max-width:900px){
  .hero .plate{--box:160px}
}
@media (max-width:560px){
  /* one 96 px plate + two short nav words do not fit a 390 px row, so the nav
     drops to its own line — keep that line tight rather than 24 px away */
  .bar{row-gap:0;padding:var(--s-2) 0}
}
@media (max-width:430px){
  .brand .plate img{width:96px;height:96px}
  .wordmark{font-size:var(--fs-lead)}
  .hero{padding:var(--s-9) 0 var(--s-8)}
  .hero .plate{--box:160px}
  .foot-brand .plate img{width:96px;height:96px}
}

/* --- reduced motion (§7.2): the FINISHED state is the CSS default, the
   animation is what gets ADDED. With JS off, with reduced motion on, or on a
   printing browser, the page renders complete — never half-drawn. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none !important;transition:none !important}
  html{scroll-behavior:auto !important}
  .rule.armed path,.card h3 .u path{stroke-dashoffset:0 !important}
}
@media print{
  header,footer,.toTop,nav{display:none}
  .rule.armed path,.card h3 .u path{stroke-dashoffset:0 !important}
  body{background:#fff}
}
