/* ---- 00-tokens.css ---- */
/* Design tokens — "直排刊头 × 终端分身".
   Paper and ink, one cinnabar red (the seal), a terminal black for the AI twin.
   Change colours, type and spacing here; every module reads from these. */

:root {
  --paper: #ecebe7;
  --paper-2: #e2e1dc;
  --ink: #111111;
  --ink-2: #333331;
  --ink-3: #6b6a65;
  --line: #111111;
  --line-soft: #c9c8c2;
  --cinnabar: #c23a22;
  --cinnabar-soft: #e2644c;

  --term-bg: #111111;
  --term-ink: #ecebe7;
  --term-dim: #6c6b66;
  --term-line: #2c2c2a;
  --term-user: #e2644c;
  --term-twin: #7fd1a4;

  /* Chinese serif: a subset webfont if present (assets/fonts), then the system's Song faces */
  --font-serif: "Lynn Serif", "Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", "SimSun", serif;
  --font-sans: -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --gutter: clamp(16px, 5.5vw, 80px);
  --max: 1440px;
  --section-gap: clamp(40px, 5vw, 56px);
  --ease: cubic-bezier(.2, .7, .2, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #141413;
    --paper-2: #1c1c1a;
    --ink: #ecebe7;
    --ink-2: #c9c8c2;
    --ink-3: #8b8a85;
    --line: #ecebe7;
    --line-soft: #3a3a37;
    --cinnabar: #e2644c;
    --term-bg: #0b0b0a;
    --term-line: #262624;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #141413;
  --paper-2: #1c1c1a;
  --ink: #ecebe7;
  --ink-2: #c9c8c2;
  --ink-3: #8b8a85;
  --line: #ecebe7;
  --line-soft: #3a3a37;
  --cinnabar: #e2644c;
  --term-bg: #0b0b0a;
  --term-line: #262624;
}

/* ---- 10-base.css ---- */
/* Base elements and small shared pieces. */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 24px; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 16px/1.75 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration-color: var(--line-soft); text-underline-offset: 3px; }
a:hover { color: var(--cinnabar); }
h1, h2, h3 { margin: 0; font-weight: 900; font-family: var(--font-serif); text-wrap: balance; }
p { margin: 0; }
/* avoid a lone character on the last line (iOS 17.4+, recent Chrome; older browsers just wrap normally) */
p, li, blockquote, .note__text, .article-row__title, .fan__story { text-wrap: pretty; }
/* Chinese body text runs to both edges, like a printed page */
.prose, .entry__body, .note__text { text-align: justify; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid var(--cinnabar); outline-offset: 3px; }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: max(var(--gutter), env(safe-area-inset-left, 0px)) max(var(--gutter), env(safe-area-inset-right, 0px)); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: -999px; top: 8px; z-index: 100; background: var(--ink); color: var(--paper); padding: 6px 12px; }
.skip-link:focus { left: 8px; }

.mono { font-family: var(--font-mono); }
.eyebrow { font: 12px/1.4 var(--font-mono); letter-spacing: .18em; color: var(--ink-3); }
.eyebrow a { text-decoration: none; }
.more-link { font-size: 14px; letter-spacing: .1em; color: var(--cinnabar); text-decoration: none; white-space: nowrap; }
.more-link:hover { text-decoration: underline; }
.count { font: 12px/1 var(--font-mono); color: var(--ink-3); }

/* vertical Chinese label, used for tags and dates */
.v-label { writing-mode: vertical-rl; font: 400 13px/1.2 var(--font-serif); letter-spacing: .14em; color: var(--cinnabar); white-space: nowrap; }

.seal {
  display: inline-grid; place-items: center;
  width: 64px; height: 64px;
  background: var(--cinnabar); color: var(--paper);
  font: 900 20px/1.05 var(--font-serif); text-align: center;
}

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  background: transparent;
  font-size: 13px; letter-spacing: .12em;
  text-decoration: none;
}
.btn:hover { background: var(--ink); color: var(--paper); }

.prose p + p { margin-top: .9em; }
.prose h2 { font-size: 1.5rem; line-height: 1.35; margin: 2em 0 .6em; }
.prose h3 { font-size: 1.2rem; margin: 1.6em 0 .5em; }
.prose ul, .prose ol { margin: .8em 0; padding-left: 1.4em; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose strong { font-weight: 700; }
.prose hr { border: 0; border-top: 1px solid var(--line-soft); margin: 2.4em 0; }
.prose blockquote { margin: 1.2em 0; padding-left: 1em; border-left: 2px solid var(--cinnabar); color: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* seal with Latin letters (site.yaml -> seal), stacked like a Chinese seal */
.seal--latin { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; font: 700 15px/1.02 Georgia, "Times New Roman", serif; letter-spacing: 0; }

/* ---- 20-layout.css ---- */
/* Page frame: header line, the shared section frame, footer.
   The section frame (templates/partials/section.html) is used by every home
   section and the footer; its phone layout is in 90-mobile.css. */

.site-header__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px 32px;
  padding-block: 30px 18px;
  border-bottom: 1px solid var(--line);
}
.site-header__meta { font: 12px/1.4 var(--font-mono); letter-spacing: .24em; text-decoration: none; }
.site-nav { display: flex; gap: 32px; font-size: 14px; letter-spacing: .2em; }
.site-nav a { text-decoration: none; }

/* ---- section frame: head (number + title) | "more" link, content below ---- */
.section { padding-block: var(--section-gap); border-bottom: 1px solid var(--line); }
.section__frame {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "head more" "body body";
  column-gap: 16px;
}
.section__head { grid-area: head; display: flex; align-items: baseline; gap: 14px; min-width: 0; }
.section__num { font: 400 15px/1 var(--font-serif); color: var(--cinnabar); }
.section__title { font-size: clamp(2rem, 1.5rem + 1.6vw, 3rem); line-height: 1.1; }
.section__rule { display: none; }
.section__more { grid-area: more; align-self: center; }
.section__body { grid-area: body; min-width: 0; margin-top: 24px; }
.section__lede { margin-bottom: 18px; font: 300 15px/1.6 var(--font-serif); letter-spacing: .3em; color: var(--ink-3); }

/* two sections side by side: site.yaml  - [articles, projects] */
.section-row {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 0 40px;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  border-bottom: 1px solid var(--line);
}
.section-row > .section { border-bottom: 0; }
.section-row > .section > .wrap { padding-inline: 0; }
.section-row .section__title { font-size: clamp(1.5rem, 1.3rem + .6vw, 1.875rem); }
@media (max-width: 860px) {
  .section-row { grid-template-columns: minmax(0, 1fr); }
}

/* ---- footer: "关于" in a narrow column, a few plain lines, contact, ICP ---- */
.section--about { border-bottom: 0; padding-block: 36px 40px; }
.section--about .section__frame { grid-template-columns: 40px minmax(0, 1fr); grid-template-areas: "head body"; column-gap: 20px; }
.section--about .section__head { flex-direction: column; align-items: center; }
.section--about .section__title { writing-mode: vertical-rl; font-size: 18px; letter-spacing: .3em; line-height: 1; }
.section--about .section__body { margin-top: 0; max-width: 640px; }
.about p { font: 400 15px/1.95 var(--font-serif); color: var(--ink-2); }
.site-footer__contact { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 18px; font-size: 12px; color: var(--ink-3); }
.site-footer__contact a { color: var(--ink); }
.site-footer__icp { display: inline-block; margin-top: 20px; font-size: 11px; color: var(--ink-3); text-decoration: none; }

/* ---- 30-hero.css ---- */
/* Hero: terminal twin | vertical slogan | vertical masthead + seal.
   Opening: the masthead's characters fall in with an ink blur, the seal stamps down,
   the terminal unrolls from the top. */

.hero { border-bottom: 1px solid var(--line); }
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 200px 190px;
  grid-template-areas: "main slogan mast";
  gap: 48px;
  padding-top: 56px;
  min-height: min(860px, 92vh);
}
.hero__main { grid-area: main; display: flex; flex-direction: column; gap: 28px; padding-bottom: 56px; min-width: 0; }
.hero__foot { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px 40px; flex-wrap: wrap; }
.hero__lede { display: none; }
.hero__intro { max-width: 460px; font: 400 20px/1.9 var(--font-serif); }
.hero__count { font-size: 11px; letter-spacing: .18em; color: var(--ink-3); }

.hero__slogan {
  grid-area: slogan;
  justify-self: center;
  padding-top: 20px;
  max-height: 700px;
  writing-mode: vertical-rl;
  font: 300 22px/2.2 var(--font-serif);
  letter-spacing: .3em;
  color: var(--ink-2);
  animation: ink-fade 1.6s ease .9s both;
}

.hero__mast { grid-area: mast; position: relative; display: flex; justify-content: flex-end; padding-bottom: 40px; }
.hero__title {
  writing-mode: vertical-rl;
  font-size: clamp(56px, 8.6vw, 124px);
  line-height: 1;
  letter-spacing: .06em;
}
.hero__ch { display: inline-block; animation: ink-drop 1s var(--ease) both; animation-delay: calc(.1s + var(--i) * .12s); }
.hero__ch--red { color: var(--cinnabar); }
.hero__seal { position: absolute; left: 6px; bottom: 60px; animation: stamp .6s var(--ease) 1s both; }

@keyframes ink-drop { from { transform: translateY(-40px); opacity: 0; filter: blur(10px); } }
@keyframes ink-fade { from { opacity: 0; filter: blur(6px); } }
@keyframes stamp { 0% { transform: scale(2.2) rotate(-10deg); opacity: 0; } 70% { transform: scale(.94); opacity: 1; } }

@media (max-width: 1080px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr) 150px; grid-template-areas: "main mast"; gap: 32px; }
  .hero__slogan { display: none; }
  .hero__lede { display: block; font: 300 15px/1.9 var(--font-serif); letter-spacing: .24em; color: var(--ink-3); }
}


/* ---- 31-terminal.css ---- */
/* The AI twin as a terminal window. */

.term {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  min-height: 460px;
  background: var(--term-bg);
  color: var(--term-ink);
  font: 14px/1.8 var(--font-mono);
  animation: unroll 1.2s cubic-bezier(.7, 0, .2, 1) .6s both;
}
@keyframes unroll { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

.term__bar { display: flex; align-items: center; gap: 8px; padding: 14px 18px; border-bottom: 1px solid var(--term-line); }
.term__dot { width: 10px; height: 10px; border-radius: 50%; background: #3d3d3a; }
.term__dot--on { background: var(--cinnabar); }
.term__title { margin-left: 12px; color: #8b8a85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.term__status { margin-left: auto; color: var(--term-twin); white-space: nowrap; }

.term__body { flex-grow: 1; display: flex; flex-direction: column; gap: 14px; padding: 24px 26px 20px; min-height: 0; }
.term__log { display: flex; flex-direction: column; gap: 14px; max-height: 420px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: #3d3d3a transparent; }
.term__sys { color: var(--term-dim); }
.term__who { color: var(--term-user); font-family: var(--font-mono); font-size: 14px; }
.term__line--twin .term__who { color: var(--term-twin); }
.term__line--twin .term__text { font: 400 19px/1.9 var(--font-serif); }
.term__line--error .term__text { color: var(--cinnabar-soft); }
.term__typing::after { content: "▍"; color: var(--cinnabar); animation: blink 1s steps(1) infinite; }

.term__chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; }
.term__chips button {
  padding: 6px 12px;
  border: 1px solid #3d3d3a;
  background: transparent;
  color: #cfcec8;
  font: 12px/1.5 var(--font-mono);
  transition: border-color .2s, color .2s;
}
.term__chips button:hover { border-color: var(--term-ink); color: var(--term-ink); }

.term__form { display: flex; align-items: center; gap: 10px; padding-top: 14px; border-top: 1px dashed #3d3d3a; }
.term__form input { flex-grow: 1; min-width: 0; border: 0; background: transparent; color: var(--term-ink); font: 16px/1.5 var(--font-mono); outline: none; }
.term__form input::placeholder { color: var(--term-dim); }
.term__form:focus-within .term__cursor { display: none; }
.term__cursor { width: 9px; height: 18px; background: var(--cinnabar); animation: blink 1s steps(1) infinite; }
.term__note { font-size: 11px; color: var(--term-dim); }
@keyframes blink { 50% { opacity: 0; } }


/* ---- 40-mind.css ---- */
/* Mind: horizontal notes in two columns, vertical labels, one pull quote. */

.mind { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 56px; border-top: 1px solid var(--line); }
.note { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 20px; padding: 24px 0; border-bottom: 1px solid var(--line-soft); min-width: 0; }
.note__main { display: grid; gap: 8px; align-content: start; min-width: 0; }
.note__text { font: 400 19px/1.9 var(--font-serif); text-decoration: none; }
.note__date { font-size: 11px; letter-spacing: .12em; color: var(--ink-3); }
.note__text b { font-weight: 900; }
.note__text:hover { color: var(--ink); text-decoration: underline; text-decoration-color: var(--cinnabar); }

.note-quote {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  gap: 20px;
  align-items: center;
  margin: 12px 0;
  padding: 40px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.note-quote blockquote { margin: 0; max-width: 880px; font: 500 clamp(22px, 1.4rem + 1vw, 32px)/1.6 var(--font-serif); letter-spacing: .02em; }
.note-quote blockquote a { text-decoration: none; }
.note-quote__mark { color: var(--cinnabar); }
.note-quote figcaption { align-self: end; font-size: 11px; letter-spacing: .2em; color: var(--ink-3); }

/* ---- /thoughts/ list page ---- */
.filter { display: flex; flex-wrap: wrap; gap: 8px; }
.filter a { padding: 6px 16px; border: 1px solid var(--line); font-size: 13px; letter-spacing: .12em; text-decoration: none; }
.filter a[aria-current="page"] { background: var(--ink); color: var(--paper); }
.filter a[aria-current="page"] .count { color: inherit; opacity: .7; }

.year-nav { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-top: 8px; font: 13px/1.6 var(--font-mono); }
.year-nav a { text-decoration: none; }
.journal__year {
  position: sticky; top: 0; z-index: 2;
  padding: 18px 0 10px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  font: 900 28px/1.2 var(--font-serif);
}
.entry { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 20px; padding: 26px 0; border-bottom: 1px solid var(--line-soft); scroll-margin-top: 80px; }
.entry__main { display: grid; gap: 10px; min-width: 0; }
.entry__title { font-size: 22px; line-height: 1.4; }
.entry__title a { text-decoration: none; }
.entry__body { font: 400 18px/1.9 var(--font-serif); }
.entry__meta { font-size: 11px; letter-spacing: .12em; color: var(--ink-3); }
.entry__meta a { text-decoration: none; }
.entry:target .entry__body { background: linear-gradient(transparent 60%, color-mix(in srgb, var(--cinnabar) 14%, transparent) 0); }

.note-images { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; max-width: 540px; margin-top: 4px; }
.note-images--1 { grid-template-columns: minmax(0, 1fr); max-width: 380px; }
.note-images--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 440px; }
.note-images img { width: 100%; aspect-ratio: 1; object-fit: cover; background: var(--paper-2); }
.note-images--1 img { aspect-ratio: auto; max-height: 440px; }

.badge-private { padding: 1px 6px; border: 1px solid var(--cinnabar); color: var(--cinnabar); font: 11px/1.4 var(--font-sans); letter-spacing: .1em; }


/* ---- 50-works.css ---- */
/* Essays and works: ruled lists, side by side on the home page. */

.article-list { border-top: 1px solid var(--line); }
.article-row { border-bottom: 1px solid var(--line); }
.article-row a {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  padding: 14px 0;
  text-decoration: none;
}
.article-row a:hover .article-row__title { color: var(--cinnabar); }
.article-row__main { display: grid; gap: 4px; min-width: 0; }
.article-row__title { font: 400 19px/1.6 var(--font-serif); }
.article-row__summary { font-size: 14px; color: var(--ink-3); }
.article-row__date { flex: none; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.project-list { border-top: 1px solid var(--line); }
.project { position: relative; padding: 16px 0; border-bottom: 1px solid var(--line); }
.project > a:first-child { display: grid; gap: 4px; text-decoration: none; }
.project__name { font: 900 20px/1.4 var(--font-serif); }
.project__tagline { font-size: 14px; color: var(--ink-2); }
.project__url { font-size: 11px; color: var(--cinnabar); letter-spacing: .04em; }
.project > a:first-child:hover .project__name { color: var(--cinnabar); }
.project__story { position: absolute; right: 0; top: 18px; font-size: 12px; color: var(--ink-3); text-decoration: none; }
.project__story:hover { color: var(--cinnabar); }
.article-row__no { display: none; }

/* ---- 70-life.css ---- */
/* Life: a vertical title and a flat photo strip. The photo at the anchor (centre on
   computers, left edge on phones) is full size, its neighbours step back, the outer ones
   are cut by the edge to say "there is more".
   photo-fan.js sets --a (distance from the anchor, in cards) and reads --fan-anchor. */

.section--life { border-bottom: 0; }
.section--life .section__frame { grid-template-columns: 120px minmax(0, 1fr); grid-template-areas: "head body"; column-gap: 40px; }
.section--life .section__head { flex-direction: column; align-items: flex-start; gap: 12px; }
.section--life .section__title { writing-mode: vertical-rl; font-size: 34px; letter-spacing: .2em; line-height: 1.2; }
.section--life .section__body { margin-top: 0; display: flex; flex-direction: column; gap: 14px; }

.fan { position: relative; }
.fan__track {
  --fan-anchor: .5;
  --card: clamp(180px, 26vw, 380px);
  display: flex;
  align-items: center;
  height: calc(var(--card) * 0.86);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-inline: calc(50% - var(--card) / 2);
  outline: none;
}
.fan__track::-webkit-scrollbar { display: none; }
.fan__card {
  --a: 0;
  flex: none;
  width: var(--card);
  height: 100%;
  margin: 0 calc(var(--card) * -0.05);
  scroll-snap-align: center;
  cursor: pointer;
  transform: scale(calc(1 - min(var(--a), 2) * .2));
  opacity: calc(1 - min(var(--a), 2.5) * .28);
  transition: transform .45s var(--ease), opacity .45s;
  will-change: transform;
}
.fan__card img,
.fan__placeholder { display: block; width: 100%; height: 100%; object-fit: cover; }
.fan__placeholder--sky { background: linear-gradient(180deg, #b9c3c8, #5d6a70); }
.fan__placeholder--ginkgo { background: linear-gradient(180deg, #d8c79a, #7a6a3f); }
.fan__placeholder--hill { background: linear-gradient(180deg, #c9ccc8 0%, #a6a8a3 40%, #3c3f3c 40.4%, #151615 100%); }
.fan__placeholder--forest { background: linear-gradient(180deg, #9aa39b, #2d332e); }
.fan__placeholder--sea { background: linear-gradient(180deg, #cdd6da 48%, #6b7f8a 48%, #2a3a44); }
.fan__placeholder--dusk { background: linear-gradient(180deg, #4a4f5e, #a08c86 60%, #d9c3a8); }
.fan__placeholder--city { background: linear-gradient(90deg, #8a9096 14%, #c9ccce 14% 32%, #5d646a 32% 46%, #b4b9bc 46% 70%, #474d52 70%); }

.fan__foot { display: flex; justify-content: space-between; align-items: baseline; gap: 12px 24px; flex-wrap: wrap; }
.fan__story { font: 400 22px/1.7 var(--font-serif); }
.fan__text { color: var(--ink-2); }
.fan__story.is-in { animation: story-in .5s var(--ease); }
@keyframes story-in { from { opacity: 0; transform: translateY(6px); } }
.fan__controls { display: flex; align-items: center; gap: 14px; font-size: 12px; color: var(--ink-3); }
.fan__controls button { padding: 4px 2px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: 14px; }
.fan__controls button:hover { color: var(--cinnabar); }
.fan__controls [data-fan-sound][aria-pressed="true"] { color: var(--cinnabar); }


/* ---- 75-viewer.css ---- */
/* Life photos, full screen (photo-viewer.js). One photo per screen width, fitted to the
   screen without cropping; ✕ top-right, count top-left, caption over the bottom edge.
   Same on phones and computers, so it lives outside 90-mobile.css. */

.fan__card.is-active { cursor: zoom-in; }
html.is-viewing { overflow: hidden; }

.viewer {
  --pull: 0px;
  position: fixed; inset: 0;
  width: 100vw; height: 100dvh; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  background: #0b0b0a; color: #f2f1ed;
  overflow: hidden;
}
.viewer::backdrop { background: #0b0b0a; }
.viewer[open] { animation: viewer-in .28s var(--ease); }
@keyframes viewer-in { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }

.viewer__track {
  display: flex; height: 100%;
  overflow-x: auto; overscroll-behavior: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none;
}
.viewer__track::-webkit-scrollbar { display: none; }
.viewer__slide {
  flex: none; width: 100%; height: 100%; margin: 0;
  display: grid; place-items: center;
  grid-template: 100% / 100%;          /* a definite cell, so the photo's max-height works */
  scroll-snap-align: center; scroll-snap-stop: always;
}
.viewer__slide img {
  display: block; max-width: 100vw; max-height: 100vh; max-height: 100dvh;
  width: auto; height: auto; object-fit: contain;
  user-select: none; -webkit-user-drag: none;
}

/* swipe down: the photo follows the finger and the page fades */
.viewer.is-pulling .viewer__track { transform: translateY(var(--pull)); }
.viewer.is-pulling { background: rgb(11 11 10 / calc(1 - min(var(--pull) / 400px, .6))); }
.viewer.is-pulling .viewer__top, .viewer.is-pulling .viewer__cap { opacity: 0; }

.viewer__top {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; justify-content: space-between; align-items: center;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px 10px 20px;
  background: linear-gradient(rgb(0 0 0 / .45), transparent);
  pointer-events: none; transition: opacity .2s;
}
.viewer__count { font-size: 11px; letter-spacing: .16em; color: rgb(242 241 237 / .75); }
.viewer__close {
  pointer-events: auto;
  display: grid; place-items: center;
  width: 44px; height: 44px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgb(0 0 0 / .35); color: inherit; cursor: pointer;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.viewer__close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.viewer__close:hover { background: var(--cinnabar); }
.viewer__close:focus-visible { outline: 2px solid var(--cinnabar-soft); outline-offset: 2px; }

.viewer__cap {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0;
  padding: 36px 24px calc(env(safe-area-inset-bottom, 0px) + 20px);
  background: linear-gradient(transparent, rgb(0 0 0 / .6));
  font: 400 15px/1.8 var(--font-serif); text-align: center; text-wrap: pretty;
  pointer-events: none; transition: opacity .2s;
}
.viewer__cap:empty { display: none; }
.viewer__cap b { display: block; font: 400 11px/1.6 var(--font-mono); letter-spacing: .16em; color: rgb(242 241 237 / .7); }

@media (prefers-reduced-motion: reduce) { .viewer[open] { animation: none; } }

/* ---- 80-pages.css ---- */
/* Inner pages: lists and single posts. */

.page { padding-block: 48px 64px; }
.page__head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px;
  padding-bottom: 32px; margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.page__head > div { display: grid; gap: 14px; align-content: end; }
.page__title { font-size: clamp(3rem, 2rem + 4vw, 6rem); line-height: 1; }
.page__lead { max-width: 36em; font: 400 18px/1.8 var(--font-serif); color: var(--ink-2); }
.page__vert { writing-mode: vertical-rl; font: 300 18px/2 var(--font-serif); letter-spacing: .3em; color: var(--ink-3); max-height: 260px; }
.page__tools { display: grid; gap: 12px; margin-bottom: 8px; }
.reading { max-width: 820px; }

.post__head { display: grid; gap: 16px; padding-bottom: 28px; margin-bottom: 32px; border-bottom: 1px solid var(--line); }
.post__title { font-size: clamp(2rem, 1.4rem + 2vw, 3rem); line-height: 1.3; }
.post__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; font-size: 12px; letter-spacing: .08em; color: var(--ink-3); }
.post__cat { padding: 1px 8px; background: var(--cinnabar); color: var(--paper); font-family: var(--font-serif); letter-spacing: .2em; }
.notice { padding: 12px 16px; border: 1px solid var(--line-soft); font-size: 14px; }
.prose--long { font: 400 18px/2 var(--font-serif); }
.prose--long p + p { margin-top: 1.1em; }
.prose--note { font-size: 21px; }

.post-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 56px; padding-top: 18px; border-top: 1px solid var(--line); }
.post-nav a { display: grid; gap: 4px; text-decoration: none; font: 400 16px/1.6 var(--font-serif); }
.post-nav a span { font: 11px/1.4 var(--font-mono); letter-spacing: .12em; color: var(--ink-3); }
.post-nav__older { text-align: right; }


/* 旧笔记重逢: later readings under a note */
.layers { margin: 36px 0 0; }
.layer { margin: 0 0 22px; padding-left: 14px; border-left: 2px solid var(--cinnabar); }
.layer__date { font-size: 12px; letter-spacing: .08em; opacity: .65; margin: 0 0 4px; }
.layer .prose { font-size: .95em; }

/* ---- 90-mobile.css ---- */
/* ==========================================================================
   Phones (iPhone and similar, up to 720px wide).
   Everything that changes on a phone lives in this one file, so the phone
   layout can be tuned without touching the computer rules above.

   Layout: a cover (vertical masthead + site slogan), the terminal twin below it,
   then every section in the same frame — a narrow rail on the left
   (numeral, vertical title, thin line) and one reading column on the right.
   Spacing is set once in the variables below.
   ========================================================================== */

@media (max-width: 720px) {
  :root {
    --gutter: 24px;
    --rail: 34px;          /* width of the left rail */
    --rail-gap: 18px;      /* rail → content */
    --rail-left: 20px;     /* screen edge → rail */
    --sec-gap: 44px;       /* space above each section */
    --item-gap: 16px;      /* space between items inside a section */
  }
  body { font-size: 15px; }

  /* ---- header: one line, no rule ---- */
  .site-header__inner { flex-wrap: nowrap; gap: 12px; padding-block: calc(env(safe-area-inset-top, 0px) + 18px) 14px; border-bottom: 0; }
  .site-header__meta { font-size: 10px; letter-spacing: .16em; white-space: nowrap; }
  .site-header__coord { display: none; }
  .site-nav { gap: 18px; font-size: 13px; letter-spacing: .16em; }
  .site-nav a { padding-block: 8px; }

  /* ---- cover: slogan | masthead, intro under a rule, terminal below ---- */
  .hero { border-bottom: 0; }
  .hero__grid {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "slogan mast" "foot foot" "term term";
    gap: 0;
    padding-top: 20px;
    min-height: 0;
  }
  .hero__main { display: contents; }
  .hero__slogan {
    display: block; grid-area: slogan; justify-self: start;
    padding-top: 28px; max-height: none;
    font-size: 15px; line-height: 2.2; letter-spacing: .42em; color: var(--ink-3);
  }
  .hero__mast { grid-area: mast; padding-bottom: 0; }
  .hero__title { font-size: min(84px, 21.5vw); letter-spacing: .04em; }
  .hero__seal { left: auto; right: calc(min(84px, 21.5vw) + 18px); bottom: 10px; width: 40px; height: 52px; font-size: 13px; }
  .hero__foot {
    grid-area: foot;
    flex-direction: column; flex-wrap: nowrap; align-items: stretch;
    gap: 12px; margin-top: 36px; padding-top: 18px;
    border-top: 1px solid var(--line);
  }
  .hero__intro { font-size: 15px; line-height: 1.9; color: var(--ink-2); }
  .hero__count { font-size: 10px; letter-spacing: .16em; }

  /* terminal: a card slightly wider than the text column */
  .hero__main > .term { grid-area: term; margin: 36px -8px 0; min-height: 0; font-size: 12px; }
  .term__bar { padding: 12px 18px; }
  .term__title { font-size: 10.5px; margin-left: 6px; }
  .term__body { padding: 18px 18px 14px; gap: 12px; }
  .term__sys { display: none; }
  .term__log { max-height: 220px; gap: 10px; }
  .term__who { font-size: 12px; }
  .term__line--twin .term__text { font-size: 15px; line-height: 1.85; }
  .term__chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: -18px; padding-inline: 18px; }
  .term__chips::-webkit-scrollbar { display: none; }
  .term__chips button { white-space: nowrap; padding: 8px 12px; font-size: 11px; }
  .term__form { padding-top: 10px; }
  .term__form input { font-size: 16px; }          /* 16px stops iOS from zooming in */
  .term__note { font-size: 10px; }

  /* ---- section frame: rail on the left, content on the right ---- */
  .section, .section-row > .section { padding-block: var(--sec-gap) 0; border-bottom: 0; }
  .section-row { border-bottom: 0; padding-inline: 0; }
  .section-row > .section > .wrap { padding-inline: var(--rail-left) var(--gutter); }
  .section__frame {
    grid-template-columns: var(--rail) minmax(0, 1fr);
    grid-template-areas: "head body" "head more";
    column-gap: var(--rail-gap);
    padding-left: var(--rail-left);
  }
  .section__head { flex-direction: column; align-items: center; gap: 8px; }
  .section__num { font-size: 12px; }
  .section__title,
  .section-row .section__title { writing-mode: vertical-rl; font-size: 21px; letter-spacing: .3em; line-height: 1; }
  .section__title-more { display: none; }
  .section__rule { display: block; flex: 1; width: 1px; min-height: 24px; margin-top: 6px; background: var(--line-soft); }
  .section__body { margin-top: 0; }
  .section__more { grid-area: more; justify-self: start; align-self: start; margin-top: 14px; font: 11px/1.6 var(--font-mono); letter-spacing: .14em; }
  .section__lede { margin-bottom: var(--item-gap); padding-bottom: 14px; border-bottom: 1px solid var(--line); font-size: 13px; }

  /* ---- 异想: one column, tag inline before the text ---- */
  .mind { display: block; border-top: 0; }
  /* tag sits at the start of the first line */
  .note { display: block; padding: 0 0 var(--item-gap); margin-bottom: var(--item-gap); border-bottom: 1px solid var(--line-soft); }
  .note--phone-hidden { display: none; }
  .note__tag { float: left; margin-right: 8px; writing-mode: horizontal-tb; font: 400 12px/30px var(--font-serif); letter-spacing: .2em; }
  .note__main { display: block; }
  .note__text { font-size: 16px; line-height: 30px; }
  .note__date { display: block; margin-top: 4px; font-size: 10.5px; }

  /* the pull quote turns vertical, read right to left like the masthead */
  .note-quote {
    display: flex; flex-direction: row-reverse; justify-content: flex-start; align-items: flex-start;
    gap: 14px; margin: 4px 0 var(--item-gap); padding: 0 0 20px;
    border: 0; border-bottom: 1px solid var(--line-soft);
  }
  .note-quote > .v-label { display: none; }
  .note-quote blockquote { writing-mode: vertical-rl; height: 208px; max-width: none; font-size: 20px; font-weight: 600; line-height: 1.9; letter-spacing: .12em; }
  .note-quote figcaption { writing-mode: vertical-rl; align-self: flex-start; font-size: 10.5px; letter-spacing: .2em; }

  /* ---- 长文: numbered list, titles may wrap ---- */
  .article-row { border-bottom-color: var(--line-soft); }
  .article-row a { gap: 12px; padding: 13px 0; }
  .article-row a:has(.article-row__no) { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 8px; }
  .article-row__no { display: block; padding-top: 5px; font-size: 10.5px; letter-spacing: .12em; color: var(--ink-3); }
  .article-row__title { font-size: 16px; line-height: 1.6; }
  .page-home .article-row__date { display: none; }

  /* ---- 作品: plain text, no boxes ---- */
  .project-list { display: flex; flex-direction: column; gap: 20px; padding-top: var(--item-gap); }
  .project { padding: 0; border: 0; }
  .project__name { font-size: 18px; }
  .project__tagline { font-size: 14px; color: var(--ink-3); }
  .project__url { font-size: 10.5px; }
  .project__story { display: none; }

  /* ---- 生活: one big photo at the left, the next one peeking in at the edge ---- */
  .section--life .section__frame { grid-template-columns: var(--rail) minmax(0, 1fr); column-gap: var(--rail-gap); }
  .section--life .section__head { align-items: center; gap: 8px; }
  .section--life .section__title { font-size: 21px; letter-spacing: .3em; line-height: 1; }
  .section--life .section__body {
    gap: 12px;
    --card: calc((100vw - var(--rail-left) - var(--rail) - var(--rail-gap) - var(--gutter)) * .80);
  }
  .fan { margin-right: calc(-1 * var(--gutter)); }
  /* whole photo in the middle, a sliver of the previous and next photo on each side */
  .fan__track {
    --fan-anchor: .5;
    height: calc(var(--card) * 1.3);
    padding-inline: calc(50% - var(--card) / 2);
  }
  .fan__card { margin: 0 5px; scroll-snap-align: center; transform: scale(calc(1 - min(var(--a), 1) * .06)); opacity: calc(1 - min(var(--a), 1) * .35); }
  /* same width as the photo strip, padded to the photo's width, so the text sits right under it */
  .fan__foot { flex-direction: column; align-items: stretch; gap: 4px; margin-right: calc(-1 * var(--gutter)); padding-inline: calc(50% - var(--card) / 2 + 5px); }
  .fan__story { font-size: 15px; line-height: 1.8; min-height: 1.8em; text-align: center; }
  .fan__controls { justify-content: space-between; gap: 4px; }
  .fan__controls [data-fan-prev], .fan__controls [data-fan-next] { display: none; }
  .fan__controls button { min-height: 44px; }

  /* ---- 关于: a light footer in the same frame ---- */
  .section--about { padding-block: var(--sec-gap) calc(env(safe-area-inset-bottom, 0px) + 44px); }
  .section--about .section__frame { grid-template-columns: var(--rail) minmax(0, 1fr); column-gap: var(--rail-gap); }
  .section--about .section__title { font-size: 21px; }
  .about { display: grid; gap: 2px; }
  .about p { font-size: 14px; line-height: 2; letter-spacing: .02em; text-align: left; text-wrap: balance; }
  .site-footer__contact { gap: 6px 16px; margin-top: 20px; font-size: 11px; }
  .site-footer__icp { margin-top: 24px; font-size: 10px; }

  /* ---- inner pages ---- */
  .page { padding-block: 24px 40px; }
  .page__head { grid-template-columns: minmax(0, 1fr); padding-bottom: 20px; }
  .page__title { font-size: 44px; }
  .page__lead { font-size: 16px; }
  .page__vert { display: none; }
  .filter { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .filter a { white-space: nowrap; }
  .entry { grid-template-columns: 22px minmax(0, 1fr); gap: 12px; padding: 20px 0; }
  .entry > .v-label { align-self: center; }
  .entry__body { font-size: 17px; }
  .journal__year { font-size: 22px; padding-top: 12px; }
  .post__title { font-size: 26px; }
  .prose--long { font-size: 17px; }
  .prose--note { font-size: 19px; }
  .post-nav { grid-template-columns: minmax(0, 1fr); }
  .post-nav__older { text-align: left; }
}
