/*
  Design tokens and base styles.

  Strict monochrome: links are distinguished by underline and weight, never by hue.
  Images are the only colour on the site. Hairline rules, no shadows, no radii.

  Inter and Noto Sans SC are self-hosted — see css/fonts.css and wwwroot/fonts/.
  The system-stack fallbacks below only matter if a font file fails to load.
*/

:root {
  /* Locked palette — see DESIGN.md */
  --bg: #fafaf8;
  --ink: #1a1a1a;
  --muted: #6b6b68;
  --rule: #e2e2de;
  --code-bg: #f2f2ee;

  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --cjk: "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --measure: 68ch;
  --gap: 1.5rem;
  --step: 1.5;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #121212;
    --ink: #e8e8e4;
    --muted: #9a9a96;
    --rule: #2a2a2a;
    --code-bg: #1c1c1c;
  }
}

:root[data-theme="dark"] {
  --bg: #121212;
  --ink: #e8e8e4;
  --muted: #9a9a96;
  --rule: #2a2a2a;
  --code-bg: #1c1c1c;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: var(--step);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
}

/* Chinese posts get a matched CJK stack rather than a browser fallback. */
[lang="zh"],
[lang^="zh-"] {
  font-family: var(--cjk);
  line-height: 1.9;
}

img,
picture,
video,
iframe,
embed {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: calc(var(--gap) * 2) 0;
}

/* ---------- layout ---------- */

.shell {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--gap);
}

.site-header {
  border-bottom: 1px solid var(--rule);
  margin-bottom: calc(var(--gap) * 2);
}

.site-header .shell {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap);
  padding-block: var(--gap);
}

.site-header a {
  text-decoration: none;
}

.site-header a:hover,
.site-header a[aria-current] {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.wordmark {
  font-weight: 600;
  letter-spacing: -0.01em;
}

.site-nav {
  display: flex;
  gap: var(--gap);
  font-size: 0.9375rem;
}

.site-footer {
  border-top: 1px solid var(--rule);
  margin-top: calc(var(--gap) * 3);
  padding-block: var(--gap);
  color: var(--muted);
  font-size: 0.875rem;
}

.site-footer .shell {
  display: flex;
  justify-content: space-between;
  gap: var(--gap);
  flex-wrap: wrap;
}

main {
  min-height: 60vh;
}

/* ---------- typography ---------- */

h1,
h2,
h3,
h4 {
  line-height: 1.25;
  letter-spacing: -0.015em;
  font-weight: 600;
  margin: calc(var(--gap) * 1.5) 0 0.5rem;
}

h1 {
  font-size: 1.75rem;
  margin-top: 0;
}

h2 {
  font-size: 1.25rem;
}

h3 {
  font-size: 1.0625rem;
}

p,
ul,
ol,
blockquote,
pre,
table {
  margin: 0 0 1rem;
}

ul,
ol {
  padding-left: 1.25rem;
}

blockquote {
  margin-left: 0;
  padding-left: var(--gap);
  border-left: 1px solid var(--rule);
  color: var(--muted);
}

small,
.meta {
  color: var(--muted);
  font-size: 0.875rem;
}

.meta {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}

/* ---------- code ---------- */

code,
kbd,
samp {
  font-family: var(--mono);
  font-size: 0.875em;
}

:not(pre) > code {
  background: var(--code-bg);
  padding: 0.1em 0.35em;
}

pre {
  background: var(--code-bg);
  border: 1px solid var(--rule);
  padding: var(--gap);
  overflow-x: auto;
  line-height: 1.5;
}

pre code {
  background: none;
  padding: 0;
}

/* ---------- syntax highlighting ----------
   ColorCode.HtmlClassFormatter emits these class names. Strict monochrome per
   DESIGN.md: tokens are differentiated by weight, opacity and italic only — never
   hue. To add colour later, these three rules are the only thing to change. */

pre .keyword,
pre .controlKeyword,
pre .preprocessorKeyword,
pre .type,
pre .typeVariable,
pre .className,
pre .constructor,
pre .predefined,
pre .pseudoKeyword,
pre .builtinFunction,
pre .builtinValue,
pre .cssPropertyName,
pre .cssSelector,
pre .htmlElementName,
pre .htmlAttributeName,
pre .xmlName,
pre .xmlAttribute,
pre .jsonKey,
pre .sqlSystemFunction,
pre .powershellCommand,
pre .powershellType,
pre .markdownHeader,
pre .bold {
  font-weight: 600;
}

pre .comment,
pre .htmlComment,
pre .xmlComment,
pre .xmlDocComment,
pre .attribute,
pre .italic {
  color: var(--muted);
  font-style: italic;
}

pre .string,
pre .stringCSharpVerbatim,
pre .stringEscape,
pre .cssPropertyValue,
pre .htmlAttributeValue,
pre .xmlAttributeValue,
pre .jsonString,
pre .jsonConst,
pre .number,
pre .jsonNumber,
pre .namespace,
pre .powershellVariable,
pre .powershellParameter {
  color: var(--muted);
}

/* ---------- media embeds ---------- */
/* Markup produced by Core/Media/MediaEmbeds.cs: :::youtube and :::pdf directives,
   the archive's legacy ![pdf](...) convention, and a bare YouTube URL on its own
   line. picture/img already get max-width:100% + display:block above, so they need
   nothing further here. */

.embed {
  margin: 0 0 1rem;
}

.embed-video {
  position: relative;
  aspect-ratio: 16 / 9;
}

.embed-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.embed-pdf object {
  width: 100%;
  min-height: 70vh;
  border: 1px solid var(--rule);
  background: var(--code-bg);
}

.embed-pdf figcaption {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  color: var(--muted);
}

/* ---------- tables ---------- */

/* Wraps every rendered table — see SyntaxHighlighting.cs's ScrollableTableRenderer.
   No margin here: the table inside already carries it via the generic block-margin
   rule above, and adding it here too would double the gap after a table. */
.table-scroll {
  overflow-x: auto;
}

table {
  border-collapse: collapse;
  width: 100%;
  /* A table that fits stretches to 100% exactly as before (short, prose-heavy
     tables like the licenses page are unaffected). A table whose columns need
     more room than that — the regex cheatsheet's dense, bilingual columns —
     claims the width it actually wants instead of being squeezed into
     mid-character wraps, and scrolls horizontally via .table-scroll instead. */
  min-width: max-content;
  font-size: 0.9375rem;
}

th,
td {
  border-bottom: 1px solid var(--rule);
  padding: 0.5rem 0.75rem 0.5rem 0;
  text-align: left;
  vertical-align: top;
}

th {
  font-weight: 600;
}

/* ---------- content index ---------- */

.entry-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.entry {
  border-bottom: 1px solid var(--rule);
  padding-block: 1rem;
  display: grid;
  gap: 0.25rem;
}

.entry:last-child {
  border-bottom: 0;
}

.entry-title {
  font-weight: 600;
  text-decoration: none;
}

.entry-title:hover {
  text-decoration: underline;
}

.entry-desc {
  color: var(--muted);
  font-size: 0.9375rem;
}

.tags {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--muted);
  font-family: var(--mono);
}

/* ---------- search form ---------- */
/* Shared by /writing's tier search and the 404 page's search prompt. */

.search {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.9375rem;
}

.search input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule);
  padding: 0.4rem 0.6rem;
  font: inherit;
}

.search input:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: -1px;
}

.search button {
  background: none;
  border: 1px solid var(--rule);
  color: var(--ink);
  padding: 0.4rem 0.75rem;
  font: inherit;
  cursor: pointer;
}

.search button:hover {
  border-color: var(--ink);
}

/* ---------- utility ---------- */

.stack > * + * {
  margin-top: var(--gap);
}

.lede {
  font-size: 1.0625rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 34rem) {
  :root {
    --gap: 1.125rem;
  }

  .site-header .shell {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}
