/* Generated from DESIGN.md by site/tokens.mjs. Do not edit by hand. */
@font-face {
  font-family: "Newsreader";
  src: url("/fonts/newsreader-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
:root {
  --step-n2: clamp(0.6683rem, 0.7651rem + -0.1209vw, 0.7378rem);
  --step-n1: clamp(0.8854rem, 0.8833rem + 0.0094vw, 0.8908rem);
  --step-0: clamp(1.0625rem, 1.0136rem + 0.2174vw, 1.1875rem);
  --step-1: clamp(1.275rem, 1.1545rem + 0.5355vw, 1.5829rem);
  --step-2: clamp(1.53rem, 1.303rem + 1.0088vw, 2.1101rem);
  --step-3: clamp(1.836rem, 1.4538rem + 1.6986vw, 2.8127rem);
  --step-4: clamp(2.2032rem, 1.5982rem + 2.6889vw, 3.7493rem);
  --space-3xs: clamp(0.2656rem, 0.2534rem + 0.0543vw, 0.2969rem);
  --space-2xs: clamp(0.5313rem, 0.5068rem + 0.1087vw, 0.5938rem);
  --space-xs: clamp(0.7969rem, 0.7602rem + 0.163vw, 0.8906rem);
  --space-s: clamp(1.0625rem, 1.0136rem + 0.2174vw, 1.1875rem);
  --space-m: clamp(1.5938rem, 1.5204rem + 0.3261vw, 1.7813rem);
  --space-l: clamp(2.125rem, 2.0272rem + 0.4348vw, 2.375rem);
  --space-xl: clamp(3.1875rem, 3.0408rem + 0.6522vw, 3.5625rem);
  --space-2xl: clamp(4.25rem, 4.0543rem + 0.8696vw, 4.75rem);
  --space-3xl: clamp(6.375rem, 6.0815rem + 1.3043vw, 7.125rem);
  --font-display: "Newsreader", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --font-body: Charter, "Bitstream Charter", "Sitka Text", Cambria, Georgia, serif;
  --measure: 34em;
  --column: 46rem;
  --rail: 15rem;
  --note: 11rem;
  --radius-s: 0.25rem;
  --line-thin: 1px;
  --leading-tight: 1.15;
  --leading-body: 1.55;
  color-scheme: light dark;
  --color-background: #f5f5f5;
  --color-surface-2: #eceeed;
  --color-line: #cacecc;
  --color-line-strong: #a1a9a5;
  --color-muted: #4f5b55;
  --color-text: #222624;
  --color-accent-wash: #e4e9e5;
  --color-accent-line: #7c9484;
  --color-accent: #33523d;
  --color-link: #647f6c;
}
:lang(ja) {
  --font-display: "Newsreader", "Hiragino Mincho ProN", "Shippori Mincho Display", "Yu Mincho", "YuMincho", "Noto Serif JP", serif;
  --font-body: "Hiragino Mincho ProN", "Yu Mincho", "YuMincho", "Noto Serif JP", "Noto Serif CJK JP", serif;
  --leading-body: 1.9;
}
/* Screen only: print always uses the light palette. */
@media screen and (prefers-color-scheme: dark) {
  :root {
    --color-background: #1a1e1c;
    --color-surface-2: #202422;
    --color-line: #333b37;
    --color-line-strong: #4b5650;
    --color-muted: #9aa39e;
    --color-text: #e9eaea;
    --color-accent-wash: #162b1d;
    --color-accent-line: #3b734e;
    --color-accent: #8dbe9d;
    --color-link: #46895d;
  }
}
/* 89 characters from the display roles, subset from site/fonts/ShipporiMincho-Regular.ttf (SIL OFL 1.1, fonts/OFL.txt). */
@font-face {
  font-family: "Shippori Mincho Display";
  src: url("/fonts/shippori-mincho-display.a9b7aa73c4.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3001, U+3002, U+300C, U+300D, U+300E, U+300F, U+3042, U+3044, U+3048, U+304C, U+304D, U+3051, U+3053, U+3055, U+3059, U+305A, U+305B, U+305D, U+305F, U+3061, U+3063, U+3064, U+3066, U+3067, U+3068, U+306B, U+306E, U+306F, U+3072, U+307E, U+3082, U+308A, U+308B, U+3092, U+3093, U+30A7, U+30A8, U+30AB, U+30B8, U+30B9, U+30C4, U+30C8, U+30CD, U+30CF, U+30DA, U+30DC, U+30E9, U+30EB, U+30ED, U+30F3, U+30FC, U+4E00, U+4E0A, U+4EBA, U+4EE3, U+4EFB, U+4F5C, U+5224, U+5247, U+52D5, U+5411, U+5C5E, U+5F0F, U+5F8B, U+5FC3, U+6027, U+60F3, U+610F, U+63A2, U+65AD, U+660E, U+6642, U+66F8, U+6CE8, U+6E21, U+7791, U+7D44, U+7E54, U+8003, U+8005, U+81EA, U+8457, U+898B, U+898F, U+8AAC, U+8CAC, U+95A2, U+FF08, U+FF09;
}

/* The sentence, glossed. Rules and values: DESIGN.md. Tokens come first in the built file. */

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

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  hanging-punctuation: first last;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  /* Moving between pages of the site, the header and footer stay where they are and only the page between them
     cross-fades (竜也, 2026-10-18). Browsers without cross-document view transitions simply load the page. */
  @view-transition {
    navigation: auto;
  }

  .site-head {
    view-transition-name: site-head;
  }

  .site-foot {
    view-transition-name: site-foot;
  }

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.32s;
    animation-timing-function: cubic-bezier(0.2, 0.6, 0.2, 1);
  }

  /* Links settle into their hover colour and underline instead of switching at once. */
  a,
  a .u {
    transition: color 0.2s ease, text-decoration-color 0.2s ease;
  }
}

body {
  min-block-size: 100vh;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  color: var(--color-text);
  background: var(--color-background);
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-size: inherit;
  font-weight: inherit;
  line-height: var(--leading-tight);
  text-wrap: balance;
}

p,
li,
dd {
  text-wrap: pretty;
}

ul[role="list"] {
  list-style: none;
  padding: 0;
}

a {
  color: inherit;
}

::selection {
  background: var(--color-accent-wash);
  color: var(--color-text);
}

:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 3px;
  border-radius: 1px;
}

.visually-hidden {
  position: absolute !important;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  inset-inline-start: var(--space-s);
  inset-block-start: var(--space-s);
  padding: var(--space-2xs) var(--space-s);
  background: var(--color-text);
  color: var(--color-background);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* Japanese: phrase breaks come from BudouX (<wbr>); words stay whole otherwise, and strict kinsoku keeps
   ー and small kana off the start of a line. */
:lang(ja) {
  line-break: strict;
  /* A line that starts with （ or 「 sits flush; the bracket's built-in half space is dropped at every line start. */
  text-spacing-trim: trim-start;
}

/* Small Japanese text (dates, link labels, footer) a touch larger: Mincho W3 at 14px reads faint. */
:lang(ja) {
  --step-n1: clamp(0.9375rem, 0.92rem + 0.05vw, 0.97rem);
}

/* An eighth-em gap where Latin meets Japanese with no space (verbatim titles such as 「Evalとレビュー」). */
:lang(ja) {
  text-autospace: normal;
}

/* Short lines (headings, the sentence, names, labels) keep BudouX phrases whole. Running paragraphs break
   anywhere kinsoku allows, as Japanese body text does, so lines fill the measure instead of going ragged. */
:lang(ja) :is(h1, h2, h3, dt, .sentence, .work-name, .entrance-group dd) {
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.tie {
  white-space: nowrap;
}

/* ---------- Layout ---------- */
.center {
  box-sizing: content-box;
  max-inline-size: var(--column);
  margin-inline: auto;
  padding-inline: max(var(--space-m), env(safe-area-inset-left, 0px)) max(var(--space-m), env(safe-area-inset-right, 0px));
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-space, var(--space-s));
}

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--cluster-space, var(--space-xs) var(--space-s));
}

/* ---------- Header and footer ---------- */
.site-head {
  display: flex;
  justify-content: flex-end;
  padding-block: var(--space-m);
}

.site-nav ul {
  --cluster-space: 0 var(--space-s);
  /* Four items on one line down to 320px (tighter gaps below 24rem); if text zoom wraps them, they stay flush right. */
  justify-content: flex-end;
}

@media (max-width: 23.99rem) {
  .site-nav ul {
    --cluster-space: 0 0.625rem;
  }
}

@media (min-width: 30rem) {
  .site-nav ul {
    --cluster-space: 0 var(--space-m);
  }
}

.site-nav a,
.site-foot a {
  display: inline-block;
  /* Short labels (X) still get a 24px target. */
  min-inline-size: 1.5rem;
  padding-block: var(--space-2xs);
  color: var(--color-muted);
  text-decoration: none;
  font-size: var(--step-n1);
}

/* Footer links leave the site, so they carry the solid underline like every other outbound link. */
.site-foot a {
  text-decoration-line: underline;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
  text-underline-offset: 0.22em;
}

.site-nav a:hover,
.site-foot a:hover {
  color: var(--color-text);
}

.site-nav [aria-current="page"] {
  color: var(--color-text);
}

.site-foot {
  padding-block: var(--space-l) var(--space-xl);
}

.site-foot ul {
  padding-block-start: var(--space-s);
  border-block-start: var(--line-thin) solid var(--color-line);
}

.site-foot ul {
  --cluster-space: var(--space-3xs) var(--space-m);
}

/* ---------- Page ---------- */
.page {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
  padding-block: var(--space-l) var(--space-3xl);
}

@media (min-width: 48rem) {
  .page {
    gap: var(--space-3xl);
  }
}

.intro {
  display: flex;
  flex-direction: column;
}

/* The name: the root text's own face, as its attribution. */
.name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-1);
  line-height: var(--leading-tight);
}

.name a {
  text-decoration: none;
}

.sentence {
  /* On phones the page gap alone separates the sentence from the first section. */
  margin-block: var(--space-xs) 0;
  font-family: var(--font-display);
  font-weight: 400;
  /* Below step-4 at both ends (30px on a 375px phone, 52px from about 880px), so the English sits at about 1.15
     times the Japanese line beside it, the usual optical pair for Latin over kanji and kana. */
  font-size: clamp(1.625rem, 0.75rem + 4.8vw, 3.25rem);
  line-height: 1.16;
  letter-spacing: -0.012em;
  max-inline-size: 19em;
  overflow-wrap: break-word;
}

@media (min-width: 48rem) {
  .sentence {
    margin-block-end: var(--space-xl);
  }
}

/* Japanese display lines: proportional kana and punctuation (palt), opened slightly, and a narrower gap
   between Latin and Japanese than a full word space. Body text stays full-width. */
:is(.sentence, .section-title, .work-name, .lost-title):lang(ja) {
  font-feature-settings: "palt";
  letter-spacing: 0.04em;
}

.sentence:lang(ja) {
  word-spacing: -0.05em;
  /* About 12 characters across a 375px phone, so the first two sentences stay on one line each.
     The rem floor keeps it growing under page and text zoom (WCAG 1.4.4). */
  font-size: max(min(var(--step-3), 7.1vw), 1.375rem);
  line-height: 1.5;
  max-inline-size: 23em;
}

/* One sentence per line. A sentence that turns over starts its next line flush, as Japanese text does. */
.sentence .line {
  display: block;
}

/* A "keep" group moves to the next line whole rather than splitting (phones);
   a "tail" group always starts its own line, so the break falls where the sections divide. */
.sentence .keep {
  display: inline-block;
}

.sentence .tail {
  display: block;
}

.sentence--small {
  font-size: var(--step-2);
  max-inline-size: 24em;
  margin: 0;
}

.sentence--small:lang(ja) {
  font-size: var(--step-1);
}

/* The sentence's links are coloured, not underlined (竜也, 2026-10-18): the phrases that open onto the page read as
   links before anyone points at them. The colour sits 3:1 from both the ground and the text. */
.sentence a {
  color: var(--color-link);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 0.06em;
  text-underline-offset: 0.27em;
}

.sentence a:hover {
  color: var(--color-accent);
  text-decoration-color: var(--color-accent-line);
}

/* The 404's smaller sentence is not large text, so the light moss would fall below 4.5:1: it takes the deeper moss
   and keeps a thin line to tell it from the text. */
.sentence--small a {
  color: var(--color-accent);
  text-decoration-color: var(--color-accent-line);
}

/* ---------- Entrances ---------- */
.entrances {
  padding-block-start: var(--space-m);
  border-block-start: var(--line-thin) solid var(--color-line);
}

.entrance-groups {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-m) var(--space-l);
}

@media (min-width: 30rem) {
  .entrance-groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* On the writing page the two languages sit on the page's own axes: rail and gloss column. */
@media (min-width: 48rem) {
  .entrance-groups {
    grid-template-columns: var(--rail) minmax(0, 1fr);
  }
}

.entrance-group {
  display: grid;
  align-content: start;
  gap: var(--space-3xs);
}

.entrance-group dt {
  font-size: var(--step-n1);
  color: var(--color-muted);
  margin-block-end: var(--space-3xs);
}

.entrance-group dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2xs);
}

.entrance {
  display: inline-block;
  /* Short names (X) still get a 24px target: the padding widens the hit area, the negative margin keeps the
     text where it was, so the description sits the same distance from every name. */
  padding-block: var(--space-3xs);
  padding-inline: var(--space-2xs);
  margin-inline: calc(var(--space-2xs) * -1);
  font-weight: 600;
  text-decoration-line: underline;
  text-decoration-thickness: var(--line-thin);
  text-underline-offset: 0.22em;
  text-decoration-color: var(--color-line-strong);
}

.entrance:hover {
  text-decoration-color: currentColor;
}

.entrance-what {
  color: var(--color-muted);
  font-size: var(--step-n1);
}

/* ---------- Sections: the quoted phrase in the rail, the gloss beside it ---------- */
.gloss {
  display: grid;
  align-content: start;
  gap: var(--space-s);
  scroll-margin-block-start: var(--space-l);
}

@media (min-width: 48rem) {
  .gloss {
    grid-template-columns: var(--rail) minmax(0, 1fr);
    gap: var(--space-l);
    align-items: baseline;
  }

  .gloss > :not(.section-title) {
    grid-column: 2;
  }

  .gloss > .section-title {
    grid-row: 1 / span 2;
  }

  /* A section with no intro has no second row to span. */
  .gloss:not(:has(> .section-intro)) > .section-title {
    grid-row: auto;
  }
}

.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-1);
  line-height: 1.25;
  color: var(--color-accent);
}

.section-title:lang(ja) {
  line-height: 1.5;
}

/* The opening mark hangs so the words, not the mark, sit on the column edge. The indent does the hanging,
   so Safari's own hanging-punctuation is turned off here to avoid hanging it twice. */
.section-title {
  hanging-punctuation: none;
}

.section-title:has(> q:first-child) {
  text-indent: -0.41em;
}

/* A title that quotes two phrases sets each on its own line; each inherits the hang. */
.section-title > q + q {
  display: block;
  margin-block-start: var(--space-3xs);
}

.section-title > q:has(+ q) {
  display: block;
}

.section-title:lang(ja):has(> q:first-child) {
  /* With palt the 「 is half an em wide, so half an em hangs it and the words sit on the column edge. */
  text-indent: -0.5em;
}

@media (min-width: 48rem) {
  /* The quoted phrase stays in view while its gloss scrolls past. */
  .gloss > .section-title {
    position: sticky;
    inset-block-start: var(--space-l);
  }

  .section-title:lang(ja) {
    font-size: min(var(--step-1), 1.3rem);
  }
}

.section-title a {
  text-decoration: none;
}

.section-intro {
  max-inline-size: var(--measure);
}

.works {
  --stack-space: var(--space-l);
}

.work {
  --stack-space: var(--space-3xs);
  scroll-margin-block-start: var(--space-xl);
  border-radius: var(--radius-s);
}

/* Arriving from the sentence: a moss mark in the margin beside what the phrase pointed to.
   It fades after a moment; with reduced motion it simply stays. */
.work,
.gloss > .section-title {
  position: relative;
}

@media (min-width: 48rem) {
  .gloss > .section-title {
    position: sticky;
  }
}

.work:target::before,
.gloss:target > .section-title::before {
  content: "";
  position: absolute;
  inset-block: 0.2em;
  inset-inline-start: calc(var(--space-s) * -1);
  inline-size: 2px;
  background: var(--color-accent);
}

.gloss:target > .section-title::before {
  inset-inline-start: calc(var(--space-s) * -1 - 0.41em);
}

.gloss:target > .section-title:lang(ja)::before {
  inset-inline-start: calc(var(--space-s) * -1 - 0.5em);
}

@media (prefers-reduced-motion: no-preference) {
  .work:target::before,
  .gloss:target > .section-title::before {
    animation: arrive 2.4s ease-in 0.6s forwards;
  }
}

@keyframes arrive {
  to {
    opacity: 0;
  }
}

.work-name {
  /* Charter has a true bold; Hiragino Mincho's heaviest face (W6) answers to 600 too. */
  font-weight: 700;
  font-size: var(--step-0);
  line-height: 1.3;
}

/* In an all-Mincho page the name stands out by size, not by a second typeface: a size between body and the quote. */
.work-name:lang(ja) {
  /* Android's serif has no bold face; let the browser embolden it there rather than lose the weight. */
  font-synthesis-weight: auto;
  /* Capped below the quoted phrase (1.3rem) so the gloss never reads louder than what it comments on. */
  font-size: min(calc((var(--step-0) + var(--step-1)) / 2), 1.2rem);
  margin-block-end: 0.2em;
  /* Most names are Latin ("Contemplative Agent"); tracking would space out the bold lowercase. palt is enough. */
  letter-spacing: 0;
}

.work-name a {
  /* Padding grows the target to 24px without moving the text (the margin gives the space back). */
  display: inline-block;
  padding-block: 0.15em;
  margin-block: -0.15em;
  text-decoration-line: underline;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
  text-underline-offset: 0.2em;
}

/* Clauses of a Japanese title (see clauses() in build.mjs). An inline-block takes no underline from its link,
   so the words carry their own and the 、 between clauses goes without. */
.work-name .clause {
  display: inline-block;
  /* A clause that itself wraps would sit on its last line's baseline and rise into the row above; align its top. */
  vertical-align: top;
}

.work-name .u {
  text-decoration-line: underline;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
}

.work-name a:hover .u {
  text-decoration-color: currentColor;
}

.work-name a:hover {
  text-decoration-color: currentColor;
}

.work-line {
  max-inline-size: var(--measure);
}

.work-links {
  --cluster-space: 0 var(--space-s);
  font-size: var(--step-n1);
}

/* 「Zenodo（DOI）」: half-width brackets, so the underline does not run on under the bracket's empty half. */
:lang(ja) :is(.work-links a, .site-foot a, .piece-where, .entrance-what) {
  font-feature-settings: "halt";
}

.work-links a {
  display: inline-block;
  min-inline-size: var(--space-l);
  padding-block: var(--space-3xs);
  color: var(--color-muted);
  text-decoration-line: underline;
  text-decoration-color: var(--color-line-strong);
  text-decoration-thickness: var(--line-thin);
  text-underline-offset: 0.22em;
}

.work-links a:hover {
  color: var(--color-accent);
  text-decoration-color: currentColor;
}

/* Wide screens: each work's links step out of the column into a margin note on its right, so the column keeps
   its measure and the width beside it carries something. The page shifts left by half the note so the two
   together sit centred. Only space separates the note from the column; no rule, no tint. */
@media (min-width: 80rem) {
  /* Every page shifts, header and footer included, so the nav stays put between pages. */
  .center {
    padding-inline-end: calc(var(--note) + var(--space-xl));
  }

  /* The note is a grid column that runs into the margin, so it takes space and never runs into the next work. */
  .work {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--note);
    column-gap: var(--space-xl);
    row-gap: var(--space-3xs);
    margin-inline-end: calc(-1 * (var(--note) + var(--space-xl)));
    align-items: baseline;
  }

  .work > :not(.work-links) {
    grid-column: 1;
  }

  .work-links {
    grid-column: 2;
    grid-row: 1 / span 2;
    /* The first link shares the name's baseline, as the rail shares the section's. */
    align-self: baseline;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  .work-links a {
    padding-block: 0.15em;
  }
}

/* ---------- About ---------- */
.lead {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.35;
  max-inline-size: 24em;
}

.lead:lang(ja) {
  font-size: var(--step-1);
  line-height: 1.75;
  max-inline-size: 28em;
}

/* About: the name in the rail, as the sections quote their phrase. */
.about > .section-title {
  /* On phones the name is a byline above the page title, smaller and muted; from 48rem it holds the rail. */
  font-size: var(--step-0);
  color: var(--color-muted);
}

@media (min-width: 48rem) {
  .about > .section-title {
    font-size: var(--step-1);
    color: var(--color-text);
    /* Only where the rail is wide enough; on a phone with text zoom the name must be free to wrap. */
    white-space: nowrap;
  }
}

.about-body {
  display: grid;
  gap: var(--space-s);
}

.about-next {
  --cluster-space: 0 var(--space-m);
  margin-block-start: var(--space-xs);
}

.about-next a {
  display: inline-block;
  padding-block: var(--space-3xs);
  font-weight: 600;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
  text-underline-offset: 0.22em;
}

.about-next a:hover {
  text-decoration-color: currentColor;
}


.facts {
  display: grid;
  gap: var(--space-s);
}

.fact {
  display: grid;
  gap: var(--space-3xs);
}

@media (min-width: 48rem) {
  .fact {
    grid-template-columns: var(--rail) minmax(0, 1fr);
    gap: var(--space-l);
    align-items: baseline;
  }
}

.fact dt {
  color: var(--color-muted);
  font-size: var(--step-n1);
}

.fact dd {
  margin: 0;
}

.fact a {
  /* Inline (not inline-block) keeps the first baseline for the rail; padding grows the target only. */
  padding-block: 0.15em;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
  text-underline-offset: 0.2em;
}

.fact a:hover {
  text-decoration-color: currentColor;
}

/* ---------- Writing: the name in the rail as on About; then one year per rail row ---------- */
.writing-title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.3;
}

.years {
  display: grid;
  gap: var(--space-xl);
}

.year {
  display: grid;
  gap: var(--space-xs);
}

/* Above 48rem the year heads its list and each piece's date sits in the rail, under the year, so the rail carries
   something all the way down and the title has the whole gloss column. */
@media (min-width: 48rem) {
  .pieces {
    --piece-cols: var(--rail) minmax(0, 1fr);
  }
}

.year-label {
  color: var(--color-muted);
  font-size: var(--step-n1);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.pieces {
  display: grid;
}

/* One piece: the date and platform above the title on phones; above 48rem the date beside the title, the platform under it.
   Hairlines between pieces, as a list of leaving links. */
.piece {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "date where" "title title";
  column-gap: var(--space-xs);
  row-gap: var(--space-3xs);
  padding-block: var(--space-xs);
  border-block-end: var(--line-thin) solid var(--color-line);
}

.piece:first-child {
  border-block-start: var(--line-thin) solid var(--color-line);
}

@media (min-width: 48rem) {
  .piece,
  .piece:lang(ja) {
    grid-template-columns: var(--piece-cols);
    grid-template-areas: "date title" ". where";
    column-gap: var(--space-l);
    align-items: baseline;
  }
}

.piece-date,
.piece-where {
  color: var(--color-muted);
  font-size: var(--step-n1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.piece-date {
  grid-area: date;
}

.piece-where {
  grid-area: where;
}

.piece-title {
  grid-area: title;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
  text-underline-offset: 0.2em;
}

.piece-title:hover {
  text-decoration-color: currentColor;
}

:lang(ja) .piece-title {
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* A Japanese title's clauses (clauses() in build.mjs) carry their own underline, as in .work-name. */
.piece-title .clause {
  display: inline-block;
  /* A clause that itself wraps would sit on its last line's baseline and rise into the row above; align its top. */
  vertical-align: top;
}

.piece-title .u {
  text-decoration-line: underline;
  text-decoration-thickness: var(--line-thin);
  text-decoration-color: var(--color-line-strong);
}

.piece-title:has(.u) {
  text-decoration-line: none;
}

.piece-title:hover .u {
  text-decoration-color: currentColor;
}

.writing-more {
  font-size: var(--step-n1);
}

.writing-more a {
  display: inline-block;
  padding-block: var(--space-3xs);
  color: var(--color-muted);
  text-decoration-thickness: var(--line-thin);
  text-underline-offset: 0.22em;
}

.writing-more a:hover {
  color: var(--color-text);
}

/* ---------- 404 ---------- */
/* Wide screens: the platform steps into the margin note, as a work's links do on the home page. */
@media (min-width: 80rem) {
  /* The platform is a third grid column running into the margin, so it shares the row's baseline. The hairlines
     stay under the date and title only. */
  .piece,
  .piece:lang(ja) {
    grid-template-columns: var(--rail) minmax(0, 1fr) var(--note);
    grid-template-areas: "date title where";
    margin-inline-end: calc(-1 * (var(--note) + var(--space-xl)));
    border: 0;
    background:
      linear-gradient(var(--color-line), var(--color-line)) left bottom / calc(100% - var(--note) - var(--space-xl)) var(--line-thin) no-repeat;
  }

  .piece:first-child {
    background:
      linear-gradient(var(--color-line), var(--color-line)) left top / calc(100% - var(--note) - var(--space-xl)) var(--line-thin) no-repeat,
      linear-gradient(var(--color-line), var(--color-line)) left bottom / calc(100% - var(--note) - var(--space-xl)) var(--line-thin) no-repeat;
  }

  .piece-where {
    margin-inline-start: calc(var(--space-xl) - var(--space-l));
    white-space: normal;
  }
}

.lost {
  display: grid;
  gap: var(--space-s);
}

.lost-title {
  font-family: var(--font-display);
  font-size: var(--step-3);
  color: var(--color-accent);
}

.lost + .lost {
  padding-block-start: var(--space-l);
  border-block-start: var(--line-thin) solid var(--color-line);
}

/* ---------- Forced colours and print ---------- */
/* Reveal: each work, intro, quoted title and piece below the first screen fades up once as it comes into view (the
   script in the page head marks those as .pending, then .in; 竜也, 2026-10-18, after hiraoku.dev/blog). What is on
   screen at load is never hidden. Without the script, or with reduced motion, nothing is hidden. */
@media screen {
  .reveal .pending {
    opacity: 0;
    translate: 0 1.5rem;
    transition:
      opacity 0.8s cubic-bezier(0.2, 0.6, 0.2, 1),
      translate 0.8s cubic-bezier(0.2, 0.6, 0.2, 1);
  }

  .reveal .pending.in {
    opacity: 1;
    translate: 0 0;
  }
}

/* Opening: the name, then the sentence one line at a time, rise into place once as the page loads (竜也, 2026-10-18:
   「クオリティ感を少しだけ」). Under a second in all; nothing waits on it, and links work while it plays. */
@media screen and (prefers-reduced-motion: no-preference) {
  .intro .name,
  .sentence .line {
    animation: open 0.9s cubic-bezier(0.2, 0.6, 0.2, 1) both;
  }

  .sentence .line:nth-child(1) { animation-delay: 0.12s; }
  .sentence .line:nth-child(2) { animation-delay: 0.24s; }
  .sentence .line:nth-child(3) { animation-delay: 0.36s; }
  .sentence .line:nth-child(4) { animation-delay: 0.48s; }

  /* Parallax: as the page scrolls past the opening, the sentence drifts a little slower than the page and dims, so
     the commentary below slides over it. Gone by the time the first section reaches the top. */
  @supports (animation-timeline: scroll()) {
    .intro {
      animation: drift linear both;
      animation-timeline: scroll(root);
      animation-range: 0 85vh;
    }

    .intro ~ * {
      position: relative;
      z-index: 1;
    }
  }
}

@keyframes open {
  from {
    opacity: 0;
    translate: 0 0.5em;
  }
}

@keyframes drift {
  to {
    opacity: 0.2;
    translate: 0 14vh;
  }
}

/* ---------- Underlines draw in ---------- */
/* On hover a line draws in from the left over the resting hairline (竜也, 2026-10-18, after hiraoku.dev/blog). The line
   is a background, so it can grow; names and titles that wrap carry it on inline spans (.u), cloned onto each line.
   Single-line labels sit it a fifth of an em under the baseline (from the middle of their line box). */
:is(.site-nav a, .site-foot a, .entrance, .work-links a, .about-next a, .writing-more a) {
  --u-y: calc(0.5lh + 0.5em);
}

.site-nav a,
.sentence a {
  --rest: transparent;
}

.sentence--small a {
  --rest: var(--color-accent-line);
}

.work-name a,
.piece-title {
  text-decoration-line: none;
}

:is(.site-nav a, .site-foot a, .entrance, .work-links a, .about-next a, .writing-more a, .fact a, .sentence a, .work-name .u, .piece-title .u) {
  text-decoration-line: none;
  background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--rest, var(--color-line-strong)), var(--rest, var(--color-line-strong)));
  background-repeat: no-repeat;
  background-origin: content-box;
  /* Inline spans hold the line just under their glyph box, inside a little padding (which moves nothing): drawn on
     the box's very edge, a 1px line fell between device pixels and vanished on some lines. */
  background-clip: border-box;
  background-position: 0 var(--u-y, calc(100% + 1px)), 0 var(--u-y, calc(100% + 1px));
  background-size: 0% var(--line-thin), 100% var(--line-thin);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

:is(.site-nav a, .site-foot a, .entrance, .work-links a, .about-next a, .writing-more a, .fact a, .sentence a):is(:hover, :focus-visible),
:is(.work-name a, .piece-title):is(:hover, :focus-visible) .u {
  background-size: 100% var(--line-thin), 100% var(--line-thin);
}

.work-name .u,
.piece-title .u,
.sentence a {
  padding-block-end: 0.15em;
}

@media (prefers-reduced-motion: no-preference) {
  :is(.site-nav a, .site-foot a, .entrance, .work-links a, .about-next a, .writing-more a, .fact a, .sentence a, .work-name .u, .piece-title .u) {
    transition: background-size 0.45s cubic-bezier(0.2, 0.6, 0.2, 1), color 0.2s ease;
  }
}

/* Article titles turn moss under the pointer (竜也, 2026-10-18). */
.piece-title:hover {
  color: var(--color-accent);
}

/* Where backgrounds are dropped (forced colours, print), links fall back to a plain underline. */
@media (forced-colors: active), print {
  :is(.site-foot a, .entrance, .work-links a, .about-next a, .writing-more a, .fact a, .sentence a, .work-name .u, .piece-title .u) {
    background: none;
    text-decoration-line: underline;
  }
}

@media (forced-colors: active) {
  .work:target::before,
  .gloss:target > .section-title::before {
    background: Highlight;
  }
}

@media print {
  .skip-link,
  .site-nav {
    display: none !important;
  }

  body {
    background: none;
    color: black;
    font-size: 11pt;
  }

  .page {
    gap: 1.5rem;
  }

  .sentence {
    font-size: 20pt;
  }

  .sentence:lang(ja) {
    font-size: 16pt;
  }

  .gloss > .section-title {
    position: static;
  }

  .work {
    break-inside: avoid;
  }

  .work-links a[href^="http"]::after,
  .entrance[href^="http"]::after,
  .fact a::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    word-break: break-all;
  }
}
