/* Rendered text: the document renderer's HTML (docs/editor-schema.md, "渲染出的 HTML") and the
   about page's Markdown. Load after site.css; posts/code.css (code highlighting) comes after
   this file. Layout (column widths, wide and full figures) belongs to the page: see
   article.css. Every class here is one the renderer emits.

   Type and rhythm (D082): 17px text on a 32px line, and every vertical space a multiple of
   half a line (16px): 32 between paragraphs, 48 around blocks, 64 before a section heading.
   Written in rem (1rem = 16px), so the reader's font size and the studio's text size (D085)
   scale text and rhythm together; widths and what hangs into the margins stay in px.
   Chinese text: no tracking, automatic CJK/Latin spacing, strict line breaking; no
   `text-wrap: pretty` on paragraphs (Safari breaks Chinese lines early with it). */

.st-prose {
  --st-block-gap: 3rem;
  --st-rule: #3b4643;
  --st-soft: #f1f1ec;
  --st-warning: #9a7432;
  --st-danger: #a2493f;
  font-size: 1.0625rem;
  line-height: 2rem;
  letter-spacing: 0;
  overflow-wrap: anywhere;
  text-autospace: normal;
  line-break: strict;
}

/* v2 dark colours only. D082's sizes, columns, spacing and side notes stay unchanged. */
[data-public-theme="dark"] .st-prose {
  --st-rule: var(--st-muted);
  --st-soft: var(--st-surface);
  --st-warning: oklch(0.78 0.10 75);
  --st-danger: oklch(0.78 0.10 30);
}
[data-public-theme="dark"] .st-prose mark,
[data-public-theme="dark"] .st-prose :not(pre) > code {
  background: color-mix(in srgb, var(--st-accent) 15%, var(--st-surface));
}
[data-public-theme="dark"] .st-prose .st-task > input:not(:checked) {
  background: var(--st-surface);
  border-color: var(--st-muted);
}
[data-public-theme="dark"] .st-prose > pre,
[data-public-theme="dark"] .st-figure__missing,
[data-public-theme="dark"] .st-table--striped thead tr:last-child > * {
  border-color: var(--st-line);
}
[data-public-theme="dark"] :is(.st-figure img, .st-linkcard__media, .st-table--grid thead th),
[data-public-theme="dark"] .st-prose > table th {
  background: var(--st-surface);
}
[data-public-theme="dark"] .st-table--striped tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--st-ink) 4%, transparent);
}
[data-public-theme="dark"] :is(.st-linkcard__link, .st-linkcard--nolink) {
  background: var(--st-surface);
}
[data-public-theme="dark"] .st-linkcard__link:hover { border-color: var(--st-muted); }
[data-public-theme="dark"] .st-prose :is(.st-ref, .st-footnote):target {
  background: color-mix(in srgb, var(--st-accent) 15%, var(--st-paper));
}

/* ---------------------------------------------------------------- rhythm */

.st-prose > * + * {
  margin-top: 2rem;
}
/* Figures, tables, code, callouts and other blocks get more air before and after. */
.st-prose
  > :where(
    figure,
    blockquote,
    hr,
    pre,
    table,
    .st-callout,
    .st-details,
    .st-linkcard,
    .st-math,
    .st-mermaid-diagram
  ),
.st-prose
  > :where(
    figure,
    blockquote,
    hr,
    pre,
    table,
    .st-callout,
    .st-details,
    .st-linkcard,
    .st-math,
    .st-mermaid-diagram
  )
  + * {
  margin-top: var(--st-block-gap);
}
/* Space above a heading against space below: 4:1 for h2, 3:1 for h3 and h4. */
.st-prose > h2 {
  margin-top: 4rem;
}
.st-prose > :is(h3, h4) {
  margin-top: 3rem;
}
.st-prose > :is(h2, h3, h4) + * {
  margin-top: 1rem;
}
/* posts/code.css resets .st-code's margin and loads later; these win on specificity. */
.st-prose > * + .st-code {
  margin-top: var(--st-block-gap);
}
.st-prose > :is(h2, h3, h4) + .st-code {
  margin-top: 1rem;
}
.st-prose > :first-child {
  margin-top: 0;
}

/* ---------------------------------------------------------------- headings */

.st-prose :is(h2, h3, h4) {
  font-weight: 600;
  letter-spacing: 0;
  text-wrap: balance;
}
.st-prose h2 {
  font-size: 1.625rem;
  line-height: 2.5rem;
}
.st-prose h3 {
  font-size: 1.25rem;
  line-height: 2rem;
}
/* One step above the body, so a fourth-level heading never reads as a bold paragraph. */
.st-prose h4 {
  font-size: 1.125rem;
  line-height: 2rem;
}
.st-prose :is(h2, h3, h4) code {
  font-size: 0.82em;
}

/* ---------------------------------------------------------------- inline */

.st-prose a {
  color: var(--st-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.st-prose strong {
  font-weight: 600;
}
.st-prose u {
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.st-prose s {
  color: var(--st-muted);
}
.st-prose mark {
  padding: 0.05em 0.15em;
  color: inherit;
  background: #efe9cf;
  border-radius: 2px;
}
.st-prose :is(sup, sub) {
  font-size: 0.72em;
  line-height: 0;
}
.st-prose :not(pre) > code {
  padding: 0.15em 0.35em;
  font-family: var(--st-mono);
  font-size: 0.875em;
  background: #e9eee7;
  border-radius: 3px;
}
.st-prose .st-align-center {
  text-align: center;
}
.st-prose .st-align-right {
  text-align: right;
}
.st-prose .st-align-justify {
  text-align: justify;
}

/* ---------------------------------------------------------------- lists */

.st-prose :is(ul, ol) {
  padding-left: 28px;
}
.st-prose :is(li + li, li :is(ul, ol)) {
  margin-top: 1rem;
}
.st-prose li > * + * {
  margin-top: 1rem;
}
.st-prose li::marker {
  color: var(--st-meta);
}
.st-prose ol ol {
  list-style-type: lower-alpha;
}
.st-prose ol ol ol {
  list-style-type: lower-roman;
}
.st-prose .st-tasklist {
  padding-left: 0;
  list-style: none;
}
.st-prose .st-task {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.st-prose .st-task > input {
  flex: none;
  width: 15px;
  height: 15px;
  margin: calc(1em - 7.5px) 0 0;
  appearance: none;
  background: #fff;
  border: 1px solid #a9b2ab;
  border-radius: 3px;
}
.st-prose .st-task > input:checked {
  background: var(--st-accent)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.2l2.6 2.6L12 5.4' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 100% no-repeat;
  border-color: var(--st-accent);
}
.st-prose .st-task > .st-task__body {
  flex: 1;
  min-width: 0;
  margin-top: 0;
}
.st-prose .st-task[data-checked='true'] > .st-task__body {
  color: var(--st-muted);
}

/* ---------------------------------------------------------------- quotes and rules
   Quotes hold examples, analogies and definitions: they are part of the text, so they keep
   its colour, one size down. At the top level the rule hangs in the left margin and the quote
   lines up with the paragraphs; nested quotes (in lists, callouts, notes) indent instead. */

.st-prose blockquote {
  position: relative;
  padding-left: 20px;
  font-size: 1rem;
  color: var(--st-ink);
}
.st-prose blockquote::before {
  content: '';
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: 0;
  width: 2px;
  background: color-mix(in srgb, var(--st-accent) 45%, transparent);
  border-radius: 1px;
}
.st-prose > blockquote {
  padding-left: 0;
}
.st-prose > blockquote::before {
  left: -22px;
}
.st-prose blockquote > * + * {
  margin-top: 1rem;
}
.st-prose hr {
  height: 1px;
  background: var(--st-line);
  border: 0;
}

/* ---------------------------------------------------------------- code
   Highlighted blocks (figure.st-code) are styled by posts/code.css; this covers Markdown <pre>
   on the about page and gives code blocks the same quiet look. At the top level the frame
   hangs into the margins by its padding and border, so the code lines up with the text. */

.st-prose > :is(pre, .st-code) {
  margin-inline: -21px;
}

.st-prose > pre {
  padding: 18px 20px;
  overflow-x: auto;
  font-family: var(--st-mono);
  font-size: 0.875rem;
  line-height: 1.5rem;
  white-space: pre;
  overflow-wrap: normal;
  color: var(--st-ink);
  background: var(--st-soft);
  border: 1px solid #e2e5de;
  border-radius: 6px;
}
.st-prose > pre code {
  padding: 0;
  font: inherit;
  background: none;
}

/* ---------------------------------------------------------------- images */

.st-figure img {
  width: 100%;
  background: #eceee8;
  border-radius: 4px;
}
.st-figure--full img {
  border-radius: 0;
}
/* Captions: one size down in the meta colour, centred under the figure (over a table) and
   never wider than the text column. The renderer numbers them "图 N　…" / "表 N　…". */
.st-prose :is(.st-figure, .st-video, .st-table) > figcaption {
  max-width: 680px;
  margin: 1rem auto 0;
  font-size: 0.875rem;
  line-height: 1.5rem;
  letter-spacing: 0;
  color: var(--st-meta);
  text-align: center;
  text-wrap: balance;
}
.st-figure__label,
.st-table__label {
  font-weight: 500;
  color: var(--st-ink);
}
.st-figure--full > figcaption {
  max-width: calc(680px + 48px);
  padding-inline: 24px;
}
/* SVG and TeX figures (M6) are drawn at their own size, never wider than the column. */
.st-figure:is(.st-figure--svg, .st-figure--tex) img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  background: none;
  border-radius: 0;
}
.st-figure__missing {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  font-size: 0.875rem;
  color: var(--st-muted);
  border: 1px dashed #cdd3cb;
  border-radius: 4px;
}

/* ---------------------------------------------------------------- tables
   three-line (default, academic), grid (hairlines) and striped. The caption ("表 N　…") sits
   above the table as in print; wide tables scroll inside .st-table__scroll. */

.st-table {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.st-prose .st-table > figcaption {
  order: -1;
  margin: 0 auto 1rem;
}
.st-table__scroll {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.st-table table {
  width: 100%;
  font-size: 0.875rem;
  line-height: 1.5rem;
  letter-spacing: 0;
  overflow-wrap: normal;
  font-variant-numeric: tabular-nums;
  border-collapse: collapse;
  border-spacing: 0;
}
.st-table :is(th, td) {
  padding: 9px 16px;
  text-align: left;
  vertical-align: top;
}
.st-table th {
  font-weight: 600;
  white-space: nowrap;
}
.st-table th[scope='row'] {
  font-weight: 500;
}
.st-table :is(th, td):first-child {
  padding-left: 4px;
}
.st-table :is(th, td):last-child {
  padding-right: 4px;
}
.st-table .st-align-left {
  text-align: left;
}
.st-table .st-align-center {
  text-align: center;
}
.st-table .st-align-right,
.st-table .st-align-decimal {
  text-align: right;
}
.st-table .st-align-decimal {
  white-space: nowrap;
}
/* article.js pads decimal cells to the same number of fraction digits with this. */
.st-decimal-pad {
  visibility: hidden;
}

.st-table--three-line table {
  border-top: 1.5px solid var(--st-rule);
  border-bottom: 1.5px solid var(--st-rule);
}
.st-table--three-line thead tr:last-child > * {
  border-bottom: 1px solid var(--st-rule);
}
.st-table--three-line thead tr:first-child > * {
  padding-top: 11px;
}
.st-table--three-line tbody tr:last-child > * {
  padding-bottom: 11px;
}

/* grid and striped keep the old site's roomy table cells (14px 18px). */
.st-table--grid :is(th, td),
.st-table--grid :is(th, td):is(:first-child, :last-child) {
  padding: 14px 18px;
  border: 1px solid var(--st-line);
}
.st-table--grid thead th {
  background: #eff1ec;
}

.st-table--striped thead tr:last-child > * {
  border-bottom: 1px solid #c9d0c7;
}
.st-table--striped :is(th, td),
.st-table--striped :is(th, td):is(:first-child, :last-child) {
  padding: 14px 18px;
}
.st-table--striped tbody tr:nth-child(even) {
  background: rgb(36 46 44 / 0.035);
}
.st-table--striped table {
  border-bottom: 1px solid var(--st-line);
}

/* Bare Markdown tables (about page). */
.st-prose > table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  font-size: 14px;
  border-collapse: collapse;
}
.st-prose > table :is(th, td) {
  padding: 14px 18px;
  text-align: left;
  border-bottom: 1px solid var(--st-line);
}
.st-prose > table th {
  background: #edf0e9;
}

/* ---------------------------------------------------------------- formulas and diagrams
   Without JavaScript (or before KaTeX loads) formulas show their LaTeX source. */

.st-math {
  overflow-x: auto;
  overflow-y: hidden;
  text-align: center;
}
.st-prose [data-latex]:not(.is-rendered) {
  font-family: var(--st-mono);
  font-size: 0.86em;
  color: var(--st-meta);
}
.st-math .katex-display {
  margin: 0;
  padding: 0.5em 0;
}
.st-prose .katex {
  font-size: 1.1em;
}
.st-prose pre.st-mermaid {
  color: var(--st-meta);
}
.st-mermaid-diagram {
  display: flex;
  justify-content: center;
  overflow-x: auto;
}
.st-mermaid-diagram svg {
  max-width: 100%;
  height: auto;
}

/* ---------------------------------------------------------------- callouts
   A quiet sheet, no bar: the title is the text's own size in 600. note is the plain sheet;
   tip, warning and danger add a small dot in the left padding, level with the first line. */

.st-callout {
  --st-callout: var(--st-meta);
  position: relative;
  padding: 20px 24px 22px;
  font-size: 1rem;
  line-height: 1.875rem;
  background: color-mix(in srgb, var(--st-ink) 2.6%, transparent);
  border-radius: 10px;
}
.st-callout--tip {
  --st-callout: var(--st-accent);
}
.st-callout--warning {
  --st-callout: var(--st-warning);
}
.st-callout--danger {
  --st-callout: var(--st-danger);
}
.st-callout:is(.st-callout--tip, .st-callout--warning, .st-callout--danger)::before {
  content: '';
  position: absolute;
  top: calc(17px + 0.9375rem);
  left: 10px;
  width: 6px;
  height: 6px;
  background: var(--st-callout);
  border-radius: 50%;
}
.st-callout__title {
  margin-bottom: 6px;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--st-ink);
}
.st-callout__body > * + * {
  margin-top: 1rem;
}

/* ---------------------------------------------------------------- details */

.st-details {
  border-top: 1px solid var(--st-line);
  border-bottom: 1px solid var(--st-line);
}
.st-prose > .st-details + .st-details {
  margin-top: 0;
  border-top: 0;
}
.st-details__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 2px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}
.st-details__summary::-webkit-details-marker {
  display: none;
}
.st-details__summary::after {
  content: '+';
  flex: none;
  font-family: var(--st-mono);
  font-weight: 400;
  color: var(--st-meta);
}
.st-details[open] > .st-details__summary::after {
  content: '−';
}
.st-details__summary:hover {
  color: var(--st-accent);
}
.st-details__body {
  padding: 0 2px 18px;
}
.st-details__body > * + * {
  margin-top: 0.8em;
}

/* ---------------------------------------------------------------- link cards */

.st-linkcard__link,
.st-linkcard--nolink {
  display: flex;
  overflow: hidden;
  color: var(--st-ink);
  background: rgb(255 255 255 / 0.5);
  border: 1px solid var(--st-line);
  border-radius: 8px;
  transition: border-color 0.2s;
}
.st-prose .st-linkcard__link {
  color: var(--st-ink);
  text-decoration: none;
}
.st-linkcard__link:hover {
  opacity: 1;
  border-color: #c3cbc1;
}
.st-linkcard__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 16px 20px;
}
.st-linkcard__title {
  display: -webkit-box;
  overflow: hidden;
  font-size: 16px;
  font-weight: 550;
  line-height: 1.6;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}
.st-linkcard__link:hover .st-linkcard__title {
  color: var(--st-accent);
}
.st-linkcard__desc {
  display: -webkit-box;
  overflow: hidden;
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--st-meta);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}
.st-linkcard__site {
  margin-top: auto;
  padding-top: 6px;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--st-muted);
}
.st-linkcard__media {
  flex: none;
  width: 200px;
  background: #eceee8;
}
.st-linkcard__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------------------------------------------------------------- video */

.st-video__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #1f2826;
  border-radius: 6px;
}
.st-video__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.st-prose .st-video__link {
  color: var(--st-meta);
  text-underline-offset: 3px;
}

/* ---------------------------------------------------------------- footnotes and references */

.st-prose .st-fnref a,
.st-prose .st-cite a {
  text-decoration: none;
}
/* A note mark hugs the word before it: no CJK/Latin gap from text-autospace, and never the
   first thing on a line (a generated U+2060 word joiner, so copied text does not carry it). */
.st-prose .st-fnref {
  text-autospace: no-autospace;
}
.st-prose .st-fnref::before {
  content: '\2060';
}
.st-prose .st-fnref a {
  padding: 0 0.12em;
}
.st-prose .st-cite {
  font-size: 0.92em;
  color: var(--st-meta);
  white-space: nowrap;
}
.st-prose > :is(.st-references, .st-footnotes) {
  margin-top: 4rem;
  padding-top: 2rem;
  font-size: 0.875rem;
  line-height: 1.5rem;
  color: var(--st-meta);
  border-top: 1px solid var(--st-line);
}
.st-prose > .st-references + .st-footnotes {
  margin-top: 3rem;
  padding-top: 0;
  border-top: 0;
}
.st-prose :is(.st-references__title, .st-footnotes__title) {
  margin: 0 0 1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.2em;
  color: var(--st-muted);
}
.st-prose .st-references__list {
  padding-left: 0;
  list-style: none;
}
.st-prose .st-ref {
  position: relative;
  padding-left: 2.6em;
}
.st-ref__num {
  position: absolute;
  left: 0;
  color: var(--st-muted);
  font-variant-numeric: tabular-nums;
}
.st-prose .st-footnotes__list {
  padding-left: 1.6em;
}
.st-prose :is(.st-ref, .st-footnote) + * {
  margin-top: 8px;
}
.st-prose .st-footnote > * + * {
  margin-top: 0.5em;
}
.st-prose .st-footnote__back {
  margin-left: 2px;
  color: var(--st-muted);
  text-decoration: none;
}
.st-prose :is(.st-ref, .st-footnote):target {
  background: rgb(219 231 220 / 0.55);
  border-radius: 3px;
  transition: background 0.6s;
}

/* ---------------------------------------------------------------- phone */

/* Phones keep the rhythm; h2 steps down, and what hangs into the margins hangs less, since the
   page margin is only 24px. */
@media (max-width: 640px) {
  .st-prose h2 {
    font-size: 1.4375rem;
    line-height: 2rem;
  }
  .st-prose > blockquote::before {
    left: -14px;
  }
  .st-prose > :is(pre, .st-code) {
    margin-inline: -13px;
  }
  .st-prose > pre,
  .st-prose > .st-code .st-code__pre {
    padding-inline: 12px;
  }
  .st-prose > .st-code .st-code__filename {
    padding-inline: 12px;
  }
  .st-callout {
    padding: 18px 18px 20px;
  }
  .st-callout:is(.st-callout--tip, .st-callout--warning, .st-callout--danger)::before {
    top: calc(15px + 0.9375rem);
    left: 6px;
  }
  .st-linkcard__media {
    width: 30%;
  }
  .st-linkcard__body {
    padding: 12px 14px;
  }
  .st-table table {
    font-size: 13px;
  }
  .st-table :is(th, td) {
    padding: 8px 12px;
  }
}

/* Phones keep the 17px body on its 32px line (about 20 characters a line at 390px). */
@media (max-width: 480px) {
  .st-prose > pre {
    padding-block: 14px;
  }
}

