/* 千江月 · 闻思苑 — the pages a reader sees.

   Set on the same paper as the 法本、大藏经 and 藏文 readers. A citation on
   these pages is a door into one of those, and someone stepping through should
   not see the sheet change colour under them. The two reader tokens are
   declared here as well as in style.css, because these pages have their own
   base template and never load it - without them the citation blocks came out
   transparent and the quoted words came out unstyled.

   One thing is loud and everything else is quiet so it can be. A sentence's
   left edge says what kind of statement it is - 原文/有据 green, 解释 amber,
   比喻 blue, 出处对不上 rust - and the 循证栏 down the right says who is
   speaking and what the discussion rests on. Those two carry the page. The
   chrome around them is hairlines and paper. */

:root {
  --paper: #fbf8f1;
  --paper-raised: #fffdf8;
  --paper-sunk: #f4efe2;
  --ink: #2f2a23;
  --ink-2: #5d564a;
  --ink-3: #8a8073;
  --rule: #e4ddcb;
  --rule-soft: #efe9db;
  --seal: #9c3b28;
  /* The water in the mark, and the only other ink this site is drawn with.
     Gilt rather than a second red, so the moon stays the one warm thing that
     is solid and the water reads as light on a surface. */
  --gilt: #c08a2e;
  /* Gilt let down into paper - what the primary button is washed with. Light
     enough to sit on the sheet without pulling the eye off the fields, warm
     enough not to read as another input box. Ink on --gilt-wash is 11.8:1. */
  --gilt-wash: #f7e8ca;
  --gilt-wash-deep: #f0d8a8;
  --gilt-edge: #d9b571;

  /* What a sentence rests on. Semantic, and deliberately not the accent: the
     page must never look as though a claim is highlighted for emphasis. */
  --ev-source: #4a6b4f;
  --ev-read: #a3822f;
  --ev-figure: #3f6a8c;
  --ev-broken: #b0512c;

  /* Shared with the 法本 readers and with qianjiangyue.css, which is loaded on
     top of this file on a thread page. */
  --read-paper: #fbf8f1;
  --read-ink: #3a352e;

  --serif: "Songti SC", "Noto Serif CJK SC", "Source Han Serif SC", "STSong", serif;
  --sans: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  /* A page about checking sources counts things: 段, 处出处, dates, seat
     numbers. They line up. */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;

  --t-xs: 12px;
  --t-sm: 13px;
  --t-md: 15px;
  --t-base: 17px;
  --t-read: 19px;
  --t-lg: 22px;
  --t-xl: 28px;
  --t-2xl: 36px;

  /* 40em of 19px serif is about 40 汉字 a line. A 汉字 carries more than a
     Latin word's worth of meaning in one glyph, so the 65-character rule of
     thumb sets a CJK line too short; past 45 the eye starts losing the head of
     the next line, which is what the old full-width column did. */
  --measure: 40em;
  --shell: 1180px;
  --gutter: 40px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 20px;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-base);
  line-height: 1.85;
  margin: 0;
}

h1,
h2,
h3,
h4 {
  font-family: var(--serif);
  font-weight: 600;
  line-height: 1.45;
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0;
}

ol,
ul {
  margin: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  color: var(--seal);
}

:focus-visible {
  outline: 2px solid var(--seal);
  outline-offset: 3px;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

.skip {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  left: 16px;
  padding: 10px 16px;
  position: absolute;
  top: -80px;
  z-index: 20;
}

.skip:focus {
  top: 12px;
}

/* --- shell --------------------------------------------------------------- */

.masthead,
.page,
.colophon {
  margin-inline: auto;
  max-width: var(--shell);
  padding-inline: var(--gutter);
  width: 100%;
}

.masthead {
  align-items: center;
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 20px 32px;
  justify-content: space-between;
  padding-block: 20px;
}

.masthead__brand {
  align-items: center;
  display: flex;
  gap: 12px;
}

.masthead__brand:hover {
  color: inherit;
}

/* The mark: 千江有水千江月, drawn. The one place the seal red is a filled
   shape rather than a line of type. */
.masthead__mark {
  flex: none;
  height: 34px;
  width: 34px;
}

.masthead__name {
  font-family: var(--serif);
  font-size: var(--t-lg);
  letter-spacing: 2px;
}

.masthead__sub {
  border-left: 1px solid var(--rule);
  color: var(--ink-3);
  font-size: var(--t-xs);
  letter-spacing: 2px;
  padding-left: 12px;
}

.masthead__nav {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  font-size: var(--t-md);
  gap: 8px 26px;
}

.masthead__nav a {
  padding-block: 4px;
}

/* Where you are, said by the nav rather than only by the page. */
.masthead__nav a[aria-current="page"] {
  box-shadow: inset 0 -1px 0 0 var(--ink);
  color: var(--ink);
}

.page {
  display: block;
  padding-bottom: 72px;
}

/* --- buttons and chips ---------------------------------------------------- */

.btn {
  background: var(--ink);
  border: 1px solid var(--ink);
  color: var(--paper);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--t-md);
  gap: 12px;
  padding: 11px 22px;
}

.btn:hover {
  background: var(--seal);
  border-color: var(--seal);
  color: var(--paper);
}

.btn--quiet {
  background: transparent;
  border-color: var(--rule);
  color: var(--ink);
}

.btn--quiet:hover {
  background: var(--paper-raised);
  border-color: var(--ink-3);
  color: var(--ink);
}

/* The one action on a page of reading. Every other block on this paper is a
   hairline rectangle, so the primary button is one too - the rounded, floating,
   drop-shadowed pill it used to be belonged to a different site.

   Light, and warm rather than loud. Solid 朱 pulled the eye off the fields the
   reader came to fill - on a phone, where it runs the width of the panel, it
   was a red bar with a form above it - and solid 墨 only traded that for a
   heavy black slab on cream. This is 金 let down into the sheet: the same ink
   the water under the moon is drawn with, washed pale, with the label in full
   墨 on top of it at 11.8:1.

   It still reads as the action rather than as another field, because nothing
   else in the panel is tinted: the inputs are paper inside a hairline, and
   this is the one warm block among them. And it presses rather than lifts - a
   seal goes down into paper, so hovering deepens the wash and the active state
   sinks the block a pixel under its own shade. */
.btn--submit {
  align-items: center;
  align-self: start;
  justify-content: center;
  background: var(--gilt-wash);
  border-color: var(--gilt-edge);
  border-radius: 0;
  color: var(--ink);
  font-size: var(--t-base);
  font-weight: 600;
  gap: 10px;
  /* A 印 is a square block with air round the characters. The left padding
     gives back half the trailing letter-space, which is what a centred line of
     tracked text loses to the blank after its last glyph. */
  letter-spacing: 0.08em;
  line-height: 1.4;
  min-height: 48px;
  padding: 12px 26px 12px calc(26px + 0.04em);
  text-decoration: none;
  transition:
    background 140ms ease,
    border-color 140ms ease,
    box-shadow 140ms ease;
}

.btn--submit:hover {
  background: var(--gilt-wash-deep);
  border-color: var(--gilt);
  color: var(--ink);
}

.btn--submit:active {
  background: var(--gilt-wash-deep);
  border-color: var(--gilt);
  box-shadow: inset 0 2px 3px rgb(90 62 18 / 20%);
  transform: translateY(1px);
}

/* 朱, and offset clear of the block. The ring has to be the one thing on the
   button that is not gold, or it disappears into its own border. */
.btn--submit:focus-visible {
  outline: 2px solid var(--seal);
  outline-offset: 3px;
}

.btn--submit svg {
  flex-shrink: 0;
  height: 17px;
  width: 17px;
}

/* Sent. The form is on its way and the button says so rather than sitting
   there inviting a second copy of the same question - which the 5-per-IP cap
   would then spend. Still a submit; only the click is refused.

   The gold drains out and the label goes to --ink-2 - 6.3:1 on this ground,
   still plainly readable, which --ink-3 at 3.4:1 would not be. */
.btn--submit[aria-disabled="true"] {
  background: var(--paper-sunk);
  border-color: var(--rule);
  color: var(--ink-2);
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .btn--submit {
    transition: none;
  }
}

/* On a phone the panel is the width of the screen and so is its one action -
   a 150px target floating at the left edge of a full-width form reads as an
   afterthought and is a worse thing to hit with a thumb. */
@media (max-width: 560px) {
  .btn--submit {
    align-self: stretch;
    width: 100%;
  }
}

/* One filter idiom for both rows. Links, not a form: there is nothing to
   submit, and a select beside a submit button was two ways to do one thing. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  border: 1px solid var(--rule);
  color: var(--ink-2);
  font-size: var(--t-sm);
  padding: 5px 13px;
  white-space: nowrap;
}

.chip:hover {
  border-color: var(--ink-3);
  color: var(--ink);
}

.chip[aria-current="page"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.chip[aria-current="page"]:hover {
  color: var(--paper);
}

.filters {
  border-block: 1px solid var(--rule);
  display: grid;
  gap: 14px;
  grid-template-columns: 5.5em minmax(0, 1fr);
  padding-block: 18px;
}

.filters__label {
  color: var(--ink-3);
  font-size: var(--t-xs);
  letter-spacing: 2px;
  padding-top: 6px;
}

/* The search, on the same row grid as the two filters: it is a third way of
   cutting the same list, not a feature bolted above it. A line rather than a
   box - the field is an underline the caret sits on, so the row stays as quiet
   as the chips beside it. */
.find {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
}

.find__box {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  flex: 1 1 15em;
  font-size: var(--t-sm);
  max-width: 24em;
  padding: 4px 2px;
}

.find__box::placeholder {
  color: var(--ink-3);
}

.find__box:focus {
  border-bottom-color: var(--seal);
  outline: none;
}

.find__go {
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  cursor: pointer;
  font-size: var(--t-sm);
  padding: 4px 14px;
}

.find__go:hover {
  border-color: var(--ink-3);
  color: var(--ink);
}

.find__clear {
  color: var(--ink-3);
  font-size: var(--t-xs);
}

/* --- home ---------------------------------------------------------------- */

/* Screen readers only. The heading a page needs and a reader does not: on the
   forum home the masthead already says whose page this is, so the h1 carries
   the name for the document outline and takes no space on the screen. */
.u-sr-only {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.intro {
  display: grid;
  gap: 12px;
  max-width: 46em;
  /* One line, not a hero. Enough air above it to separate it from the
     masthead, and little enough below that the question list is the next
     thing in view. */
  padding-block: 26px 22px;
}

.intro p {
  color: var(--ink-2);
  max-width: var(--measure);
}

/* The 偈 the product is named after. Serif and a shade quieter than the
   sentence under it: it says why there are several voices, and the plain line
   after it says what a reader is about to see - in that order, because a
   metaphor on its own tells nobody what this page does. */
.intro__verse {
  color: var(--ink-2);
  font-family: var(--serif);
  font-size: var(--t-base);
  line-height: 2;
  /* The two halves are broken by hand at the 分号; this only keeps a narrow
     screen from leaving 「亮。」 alone on a fourth line. Ignored where
     unsupported, which costs nothing. */
  text-wrap: pretty;
}

.eyebrow {
  color: var(--seal);
  font-size: var(--t-xs);
  letter-spacing: 3px;
}

.columns {
  display: grid;
  gap: 56px;
  grid-template-columns: minmax(0, 1fr) 250px;
  padding-top: 36px;
}

.section-head {
  align-items: baseline;
  border-bottom: 1px solid var(--ink);
  display: flex;
  gap: 16px;
  justify-content: space-between;
  padding-bottom: 10px;
}

.section-head h2 {
  font-size: var(--t-lg);
}

.section-head__note {
  color: var(--ink-3);
  font-size: var(--t-sm);
}

.stack {
  display: grid;
  gap: 34px;
}

/* A thread row. No 01/02 index: a list of questions is not a sequence, and a
   number in front of one implies an order to read them in that does not
   exist. What a reader can use is what it costs and what it rests on. */
.threads {
  display: grid;
  list-style: none;
}

.thread-row {
  border-bottom: 1px solid var(--rule-soft);
}

/* One row, one line. Three hundred questions at ninety pixels a row is a list
   nobody reaches the foot of; the facts sit beside the question rather than
   under it, and the row is as tall as the question it carries. */
.thread-row__link {
  align-items: baseline;
  display: grid;
  gap: 2px 22px;
  padding: 11px 6px;
}

@media (min-width: 720px) {
  .thread-row__link {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}

.thread-row__link:hover {
  background: var(--paper-raised);
}

/* Clamped at two lines, never at one: a question cut mid-clause is a question
   a reader cannot decide about. The full text is on the element's `title`, so
   the rare long one is a hover away rather than a click away, and the rows
   below it do not move to show it. */
.thread-row__q {
  display: -webkit-box;
  font-family: var(--serif);
  font-size: var(--t-base);
  line-height: 1.6;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.thread-row__facts {
  align-items: baseline;
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--t-sm);
  gap: 2px 12px;
}

/* Thirty rows of facts read as four columns or as noise. Each fact is given
   the width of the widest thing that goes in it, so 深度 sits under 深度 and
   the digits under the digits; without it the chips wander by a character or
   two a row and the eye has to find each one again. */
@media (min-width: 720px) {
  .thread-row__facts {
    flex-wrap: nowrap;
    justify-content: flex-end;
    white-space: nowrap;
  }

  .thread-row__facts .tally--column {
    min-width: 4.5em;
    text-align: right;
  }

  .thread-row__facts .depth {
    min-width: 7em;
    text-align: center;
  }

  .thread-row__facts .tally {
    min-width: 5em;
    text-align: right;
  }
}

.tally {
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
}

.depth {
  border: 1px solid var(--rule);
  color: var(--ink-2);
  font-size: var(--t-xs);
  padding: 2px 9px;
  white-space: nowrap;
}

/* The same two doors, in the line that says how many pages there are. Small
   and beside the count, because up here it is a fact with arrows on it; the
   pager at the foot of the list is the one that is a control. */
.pagemark {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin-left: 10px;
}

.pagemark__at {
  font-variant-numeric: tabular-nums;
}

.pagemark__step {
  color: var(--seal);
  font-size: var(--t-md);
  line-height: 1;
  padding: 0 4px;
}

.pagemark__step--off {
  color: var(--ink-3);
  opacity: 0.4;
}

/* Paging, at the foot of a list that no longer fits on one page. Quiet: it is
   the way out of the list, not part of what the list says. */
/* The section a row belongs to. Same weight as the other facts on the row -
   it is where the thread lives, not a badge on it. */
.tally--column {
  color: var(--ink-2);
}

.pager {
  align-items: baseline;
  border-top: 1px solid var(--rule);
  display: flex;
  gap: 20px;
  justify-content: space-between;
  margin-top: 26px;
  padding-top: 18px;
}

.pager__step {
  color: var(--seal);
  font-size: var(--t-md);
}

.pager__step--off {
  color: var(--ink-3);
  opacity: 0.5;
}

.pager__at {
  color: var(--ink-3);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
}

.empty {
  display: grid;
  gap: 14px;
  justify-items: start;
  padding: 48px 0;
}

.empty h3 {
  font-size: var(--t-lg);
}

.empty p {
  color: var(--ink-2);
  max-width: var(--measure);
}

.aside {
  display: grid;
  gap: 30px;
  height: fit-content;
}

.aside__block {
  display: grid;
  gap: 12px;
}

.aside__block h2 {
  font-size: var(--t-base);
  letter-spacing: 1px;
}

.aside__block p {
  color: var(--ink-2);
  font-size: var(--t-md);
}

/* Reading these three in order is the method, so they are numbered. */
.steps {
  counter-reset: step;
  display: grid;
  gap: 16px;
  list-style: none;
}

.steps li {
  display: grid;
  gap: 2px;
  grid-template-columns: 2.2em minmax(0, 1fr);
}

.steps li::before {
  color: var(--seal);
  content: counter(step, decimal-leading-zero);
  counter-increment: step;
  font-family: var(--mono);
  font-size: var(--t-xs);
  grid-row: span 2;
  padding-top: 4px;
}

.steps b {
  font-weight: 600;
}

.steps span {
  color: var(--ink-3);
  font-size: var(--t-sm);
  line-height: 1.7;
}

/* --- reading: a thread, and the historical previews ----------------------- */

.reading {
  display: grid;
  gap: 56px;
  grid-template-columns: minmax(0, 1fr) 250px;
  padding-top: 26px;
}

.reading__main {
  min-width: 0;
}

.crumb {
  color: var(--ink-3);
  font-size: var(--t-sm);
  margin-bottom: 18px;
}

.thread-head {
  border-bottom: 1px solid var(--rule);
  display: grid;
  gap: 12px;
  padding-bottom: 20px;
}

/* Where the question was asked. Seal-coloured and letterspaced, the same
   register as the 循证栏's own headings - a label on the page, not a line of
   its writing. */
.thread-head__where {
  color: var(--seal);
  font-size: var(--t-xs);
  letter-spacing: 3px;
}

.thread-head__dot {
  color: var(--ink-3);
  margin: 0 8px;
}

/* The question, set as a question: 問 hanging in the margin on a wide screen,
   so the first line of the title starts where every other line does and the
   mark reads as who is speaking rather than as part of the sentence. */
.thread-head__q {
  font-size: clamp(var(--t-xl), 3.4vw, var(--t-2xl));
  line-height: 1.5;
  max-width: 18em;
  overflow-wrap: anywhere;
  position: relative;
  text-wrap: pretty;
}

.thread-head__ask {
  color: var(--seal);
  font-family: var(--serif);
  font-size: 0.62em;
  opacity: 0.75;
  padding-right: 0.5em;
  vertical-align: 0.22em;
}

@media (min-width: 900px) {
  .thread-head__q {
    margin-left: 1.55em;
  }

  .thread-head__ask {
    padding-right: 0;
    position: absolute;
    right: 100%;
    top: 0.1em;
    width: 1.55em;
  }
}

.thread-head__facts {
  align-items: center;
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  gap: 8px 16px;
}

/* Staff work, kept apart from what the page says to a reader. The two used to
   run together in one dot-separated line, which read as though 「审核视角」
   were a fact about the discussion. */
.staff-bar {
  align-items: center;
  border: 1px dashed var(--rule);
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--t-sm);
  gap: 8px 18px;
  margin-top: 18px;
  padding: 9px 14px;
}

.staff-bar__tag {
  color: var(--ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 1px;
}

.notice {
  background: var(--paper-sunk);
  border-left: 2px solid var(--ev-read);
  color: var(--ink-2);
  font-size: var(--t-md);
  line-height: 1.8;
  margin-top: 18px;
  padding: 12px 16px;
}

/* Said once, at the top, instead of a label in front of every sentence. */
/* Sample data. Loud enough that nobody reads a templated discussion as a real
   one, quiet enough that it is not the first thing on the page. */
.notice--mock {
  border-left: 3px solid var(--seal);
  color: var(--ink-2);
}

.legend {
  border-block: 1px solid var(--rule-soft);
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--t-xs);
  gap: 8px 18px;
  letter-spacing: 1px;
  margin-top: 22px;
  padding-block: 12px;
}

.legend__key {
  border-left: 3px solid var(--rule);
  padding-left: 8px;
}

.legend__key--source {
  border-left-color: var(--ev-source);
}

.legend__key--read {
  border-left-color: var(--ev-read);
}

.legend__key--figure {
  border-left-color: var(--ev-figure);
}

.legend__key--broken {
  border-left-color: var(--ev-broken);
}

.legend__hint {
  margin-left: auto;
}

/* --- 循证栏 — the rail ---------------------------------------------------- */

/* The one loud thing on the page, and it is loud only by being always there.
   Who is speaking and what the discussion rests on are the two questions a
   reader of a 9000-pixel page keeps having to scroll to answer. */
.rail {
  align-self: start;
  border-left: 1px solid var(--rule);
  display: grid;
  gap: 26px;
  font-size: var(--t-sm);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding-left: 24px;
  position: sticky;
  top: 24px;
}

.rail__group {
  display: grid;
  gap: 10px;
}

.rail__title {
  color: var(--ink-3);
  font-size: var(--t-xs);
  letter-spacing: 3px;
}

.rail__seats {
  display: grid;
  gap: 2px;
  list-style: none;
}

.rail__seat {
  border-left: 2px solid transparent;
  display: flex;
  gap: 10px;
  justify-content: space-between;
  padding: 5px 0 5px 10px;
}

.rail__seat:hover {
  border-left-color: var(--rule);
}

.rail__seat[aria-current="true"] {
  border-left-color: var(--seal);
  color: var(--ink);
}

.rail__seat span:last-child {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
}

.rail__note {
  color: var(--ink-3);
  font-size: var(--t-xs);
  line-height: 1.8;
  /* A column this narrow strands the last two characters on a line of their
     own often enough to be worth asking the browser not to. */
  text-wrap: pretty;
}

/* The one rule the discussion rests on, in the rail rather than the footer:
   marked with the seal and set in the reading ink, so it is not read as the
   small print the notes around it are. */
.rail__rule {
  border-left: 2px solid var(--seal);
  color: var(--ink-2);
  line-height: 1.8;
  padding-left: 10px;
}

.rail__link {
  color: var(--seal);
  font-size: var(--t-sm);
}

/* Narrow: the rail is not dropped, it folds. A page this long needs its
   contents more on a phone, not less. */
.rail-fold {
  border: 1px solid var(--rule);
  display: none;
  margin-top: 22px;
  padding: 10px 14px;
}

.rail-fold > summary {
  cursor: pointer;
  font-size: var(--t-md);
  list-style: none;
}

.rail-fold > summary::-webkit-details-marker {
  display: none;
}

.rail-fold > summary::after {
  content: " ▾";
  color: var(--ink-3);
}

.rail-fold[open] > summary::after {
  content: " ▴";
}

.rail-fold .rail {
  border-left: 0;
  max-height: none;
  overflow: visible;
  padding-left: 0;
  padding-top: 14px;
  position: static;
}

/* --- historical preview posts (JSON archives) ----------------------------- */

.discussion {
  border-bottom: 1px solid var(--rule-soft);
  padding-block: 30px;
  scroll-margin-top: 24px;
}

.discussion__head {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-bottom: 18px;
}

.discussion__head h2 {
  font-size: var(--t-lg);
}

.discussion__seat {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--t-xs);
}

.claim {
  border-left: 3px solid var(--rule);
  font-family: var(--serif);
  font-size: var(--t-read);
  line-height: 2;
  margin-bottom: 16px;
  max-width: var(--measure);
  overflow-wrap: anywhere;
  padding-left: 14px;
}

/* One small mark at the end of the sentence, not a heading under it. Closed,
   the draft reads as a discussion; open, the quoted words are there to check.
   `details` rather than a script, so it works with JavaScript off. */
.source-details {
  display: inline;
  font-family: var(--sans);
}

.source-details > summary {
  color: var(--ink-3);
  cursor: pointer;
  display: inline;
  font-size: 0.7em;
  list-style: none;
  margin-left: 5px;
  opacity: 0.55;
  user-select: none;
  vertical-align: 0.2em;
}

.source-details > summary::-webkit-details-marker {
  display: none;
}

.source-details > summary:hover,
.source-details[open] > summary {
  opacity: 1;
}

.source-details > summary span {
  margin-left: 2px;
}

.source-details__body {
  display: block;
  margin-top: 6px;
}

blockquote {
  background: var(--paper-raised);
  border: 1px solid var(--rule-soft);
  border-left: 2px solid var(--ev-source);
  font-family: var(--serif);
  font-size: var(--t-md);
  line-height: 1.95;
  margin: 10px 0 0;
  padding: 14px 16px;
}

cite {
  color: var(--ink-3);
  display: block;
  font-family: var(--sans);
  font-size: var(--t-xs);
  font-style: normal;
  line-height: 1.7;
  margin-top: 10px;
}

cite small {
  display: block;
}

.end-note {
  display: grid;
  gap: 14px;
  justify-items: start;
  padding-top: 34px;
}

.end-note h2 {
  font-size: var(--t-lg);
}

.end-note p {
  color: var(--ink-2);
  max-width: var(--measure);
}

/* --- requests ------------------------------------------------------------- */

.head {
  display: grid;
  gap: 14px;
  max-width: 40em;
  padding-block: 44px 30px;
}

.head h1 {
  font-size: clamp(var(--t-xl), 3.4vw, var(--t-2xl));
  overflow-wrap: anywhere;
}

.head p {
  color: var(--ink-2);
}

.form-layout {
  display: grid;
  gap: 56px;
  /* The panel does not stretch: a one-line question in a 770px box invites a
     paragraph, and the answer to 「你想读懂什么」 should look like one line. */
  grid-template-columns: minmax(0, 320px) minmax(0, 600px);
  padding-block: 44px 60px;
}

.form-layout__intro {
  display: grid;
  gap: 16px;
  height: fit-content;
}

.form-layout__intro h1 {
  font-size: var(--t-2xl);
}

.form-layout__intro p {
  color: var(--ink-2);
}

.form-panel {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  display: grid;
  gap: 22px;
  padding: 32px 34px;
}

.form-panel h2 {
  font-size: var(--t-lg);
}

.form-fields {
  display: grid;
  gap: 22px;
}

.field {
  display: grid;
  gap: 7px;
}

.field label {
  font-size: var(--t-md);
}

.field input:not([type="checkbox"]),
.field textarea,
.field select {
  background: var(--paper);
  border: 1px solid var(--rule);
  color: var(--ink);
  padding: 10px 12px;
  width: 100%;
}

.field input:not([type="checkbox"]):focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--ink-3);
}

.field textarea {
  line-height: 1.8;
  resize: vertical;
}

.field .hint,
.hint {
  color: var(--ink-3);
  font-size: var(--t-sm);
  line-height: 1.7;
}

.check-field {
  align-items: center;
  display: flex;
  font-size: var(--t-md);
  gap: 9px;
}

.check-field input {
  accent-color: var(--ink);
  height: 16px;
  margin: 0;
  width: 16px;
}

.errorlist {
  color: var(--ev-broken);
  font-size: var(--t-sm);
  list-style: none;
}

.status-block {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  display: grid;
  gap: 6px;
  padding: 24px 26px;
}

.status-block h2 {
  align-items: center;
  display: flex;
  font-size: var(--t-xl);
  gap: 12px;
}

.status-dot {
  background: var(--ev-source);
  border-radius: 50%;
  flex: none;
  height: 9px;
  width: 9px;
}

.request-section {
  border-top: 1px solid var(--rule-soft);
  display: grid;
  gap: 12px;
  padding-top: 26px;
}

.request-section h2 {
  font-size: var(--t-base);
  letter-spacing: 1px;
}

.request-section p {
  overflow-wrap: anywhere;
}

.request-form {
  display: grid;
  gap: 12px;
  justify-items: start;
}

/* --- colophon ------------------------------------------------------------- */

/* The disclaimer is here, on every page, in the page's own voice - not a
   banner added later to a page people already read, which reads as a
   retraction. */
.colophon {
  border-top: 1px solid var(--rule);
  color: var(--ink-3);
  display: grid;
  font-size: var(--t-sm);
  gap: 10px;
  padding-block: 26px 44px;
}

.colophon__line {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.colophon__line > a:last-child {
  margin-left: auto;
}

.colophon__name {
  font-family: var(--serif);
  letter-spacing: 3px;
}

/* --- narrow ---------------------------------------------------------------- */

@media (max-width: 1000px) {
  :root {
    --gutter: 22px;
  }

  .columns,
  .reading,
  .form-layout {
    gap: 34px;
    grid-template-columns: minmax(0, 1fr);
  }

  .aside {
    border-top: 1px solid var(--rule);
    padding-top: 30px;
  }

  .reading > .rail {
    display: none;
  }

  .rail-fold {
    display: block;
  }

  .intro {
    padding-block: 20px 16px;
  }

  .filters {
    gap: 8px;
    grid-template-columns: minmax(0, 1fr);
  }

  .filters__label {
    padding-top: 0;
  }

  .form-layout__intro h1 {
    font-size: var(--t-xl);
  }

  .form-panel {
    padding: 24px 22px;
  }
}

@media (max-width: 620px) {
  :root {
    --t-read: 18px;
    --t-2xl: 30px;
  }

  .masthead {
    gap: 12px 20px;
  }

  .masthead__nav {
    font-size: var(--t-sm);
    gap: 6px 18px;
    width: 100%;
  }

  .thread-row__q {
    font-size: var(--t-md);
  }

  .legend__hint {
    margin-left: 0;
  }

  .claim {
    padding-left: 11px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

@media print {
  .masthead__nav,
  .rail,
  .rail-fold,
  .seats,
  .staff-bar {
    display: none;
  }

  .source-details {
    display: block;
  }
}

/* --- 返回顶部 ------------------------------------------------------------- */

/* The site-wide disc, in 千江月's colours. `back-to-top.js` drives it: it
   shows the disc past half a screen and sets the ring from scroll position,
   which on a thread of a hundred 句 is worth more than the words 返回顶部.
   The seal red is the same one the masthead 印 uses, so the one saturated
   thing on the page is the same red twice rather than two reds. */
.js-cd-top {
  align-items: center;
  background: var(--paper-raised);
  /* A seal-tinted rim, not the page's own hairline: on this paper a neutral
     rule made the disc almost the same colour as what is behind it. */
  border: 1px solid rgba(156, 59, 40, 0.28);
  border-radius: 50%;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 6px 18px rgba(47, 42, 35, 0.22);
  color: var(--seal);
  display: none;
  height: 38px;
  justify-content: center;
  padding: 0;
  position: fixed;
  right: 16px;
  text-decoration: none;
  transition:
    background-color 0.15s,
    transform 0.15s,
    box-shadow 0.15s;
  width: 38px;
  z-index: 60;
}

.js-cd-top:hover {
  background: var(--paper-raised);
  box-shadow: 0 10px 24px rgba(47, 42, 35, 0.22);
  color: var(--seal);
  transform: translateY(-2px);
}

.js-cd-top:focus-visible {
  outline: 2px solid var(--seal);
  outline-offset: 3px;
}

.js-cd-top-show {
  display: flex;
}

/* On the border box, so the ring reads as the rim of the disc. The viewBox
   stays 0 0 44 44 while the box is 38, so the geometry just scales and the
   script's numbers still hold. */
.js-cd-top__ring {
  height: 38px;
  left: -1px;
  pointer-events: none;
  position: absolute;
  top: -1px;
  transform: rotate(-90deg);
  width: 38px;
}

.js-cd-top__track {
  fill: none;
  stroke: rgba(156, 59, 40, 0.16);
  stroke-width: 2.9;
}

.js-cd-top__bar {
  fill: none;
  stroke: var(--seal);
  stroke-dashoffset: 999;
  stroke-linecap: round;
  stroke-width: 2.9;
  transition: stroke-dashoffset 0.1s linear;
}

.qjy-top__arrow {
  height: 15px;
  width: 15px;
}

@media (prefers-reduced-motion: reduce) {
  .js-cd-top,
  .js-cd-top__bar {
    transition: none;
  }

  .js-cd-top:hover {
    transform: none;
  }
}

@media print {
  .js-cd-top {
    display: none !important;
  }
}
