/* plinth.fish — paper and ink. One stylesheet for both languages. */

@font-face {
  font-family: "Alegreya";
  src: url("/fonts/alegreya.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya";
  src: url("/fonts/alegreya-italic.woff2") format("woff2");
  font-weight: 400 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Zhuque Fangsong";
  src: url("/fonts/zhuque-fangsong.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Paper Mono";
  src: url("/fonts/paper-mono-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Rice paper and the ink on it; one cinnabar for the seals. */
  --paper: oklch(95.2% 0.014 84);
  --paper-shade: oklch(91.5% 0.018 80);
  --ink: oklch(24% 0.008 60);
  --ink-soft: oklch(45% 0.012 62);
  --ink-faint: oklch(60% 0.014 70);
  --rule: oklch(24% 0.008 60 / 0.16);
  --cinnabar: oklch(51% 0.15 31);
  --cinnabar-press: oklch(45% 0.14 31);
  --seal-ink: oklch(96% 0.012 80);
  /* The night hall the skins stand in. */
  --night: oklch(16.5% 0.012 265);
  --night-text: oklch(90% 0.01 85);
  --night-soft: oklch(68% 0.012 85);

  --serif: "Alegreya", "Zhuque Fangsong", "Songti SC", Georgia, serif;
  --han: "Zhuque Fangsong", "Songti SC", "STSong", "Noto Serif CJK SC", serif;
  --mono: "Paper Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --gutter: clamp(20px, 5vw, 72px);
  --measure: 34rem;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: light;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background-color: var(--paper);
  /* Paper fibre: a fixed, faint noise, so the page reads as a sheet, not a screen. */
  background-image: url("/img/paper.svg");
  background-size: 360px 360px;
  color: var(--ink);
  font: 400 1.1875rem/1.62 var(--serif);
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
:lang(zh) body, body:lang(zh) {
  font-family: var(--han);
  font-size: 1.125rem;
  line-height: 1.95;
  letter-spacing: 0.02em;
}
.han { font-family: var(--han); }

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.22em;
  transition: text-decoration-color 160ms ease;
}
@media (hover: hover) {
  a:hover { text-decoration-color: currentColor; }
}
:focus-visible {
  outline: 2px solid var(--cinnabar);
  outline-offset: 4px;
  border-radius: 2px;
}
code {
  font-family: var(--mono);
  font-size: 0.82em;
  letter-spacing: 0;
  padding: 0.12em 0.4em;
  background: oklch(24% 0.008 60 / 0.06);
  border-radius: 3px;
  white-space: nowrap;
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Masthead: just the name and the other language ─────────────────── */

.mast {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 3;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: max(22px, env(safe-area-inset-top)) var(--gutter) 0;
  font-size: 1rem;
}
.mast .name {
  font-family: "Alegreya", var(--serif);
  font-weight: 600;
  font-size: 1.375rem;
  letter-spacing: -0.012em;
  text-decoration: none;
}
.mast .lang {
  color: var(--ink-soft);
  text-decoration: none;
  padding: 10px 0 10px 12px;
}
@media (hover: hover) {
  .mast .lang:hover { color: var(--ink); }
}

/* ── The first sheet: one fish, one line, one seal ───────────────────── */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: 1fr auto;
  grid-template-areas:
    "stage verse"
    "lead  lead";
  column-gap: var(--gutter);
  padding: clamp(84px, 12vh, 132px) var(--gutter) clamp(36px, 7vh, 72px);
  overflow: hidden;
}

.stage {
  --side: min(62vh, 520px, 78vw);
  grid-area: stage;
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
}

/* The fish, its mallet and its ink are laid out in one square, in the
   app's own coordinates: everything is a fraction of --side. */
.fish {
  position: relative;
  width: var(--side);
  height: var(--side);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  border-radius: 50%;
}
.fish:focus-visible { outline-offset: -8%; }
.fish .body {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform-origin: 50% 88%;
  pointer-events: none;
  user-select: none;
}
.fish .mallet {
  position: absolute;
  width: calc(var(--side) * 0.6);
  height: calc(var(--side) * 0.6);
  /* Placed by site.js so its grip sits up and to the right of the strike point. */
  left: 0;
  top: 0;
  transform-origin: 96.4% 50.5%;
  transform: rotate(10deg);
  pointer-events: none;
  user-select: none;
  z-index: 2;
}
.fish .splash,
.fish .bleed {
  position: absolute;
  pointer-events: none;
  translate: -50% -50%;
}
.fish .splash {
  width: calc(var(--side) * 0.26);
  height: calc(var(--side) * 0.26);
  z-index: 1;
}
/* Ink soaking into the paper where the mallet landed. */
.fish .bleed {
  width: calc(var(--side) * 0.5);
  height: calc(var(--side) * 0.5);
  border-radius: 50%;
  background: radial-gradient(closest-side, oklch(24% 0.008 60 / 0.55), oklch(24% 0.008 60 / 0.18) 55%, transparent);
  filter: blur(10px);
  z-index: 0;
}

.hint {
  position: absolute;
  left: 50%;
  bottom: calc(50% - var(--side) / 2 - 2.2em);
  translate: -50% 0;
  margin: 0;
  font-style: italic;
  color: var(--ink-faint);
  font-size: 1rem;
  white-space: nowrap;
  transition: opacity 900ms ease;
  pointer-events: none;
}
:lang(zh) .hint { font-style: normal; letter-spacing: 0.3em; }
.knocked .hint { opacity: 0; }

/* 并无功德: the seal pressed onto the sheet by the first knock, and never again. */
.merit {
  position: absolute;
  z-index: 2;
  /* On the paper beside the pedestal, where a painter would sign. */
  left: calc(50% + var(--side) * 0.47);
  top: calc(50% + var(--side) * 0.12);
  display: grid;
  justify-items: center;
  gap: 10px;
  pointer-events: none;
  opacity: 0;
}
.merit[hidden] { display: none; }
.merit .seal { width: clamp(64px, 8vw, 84px); rotate: -4deg; }
.merit figcaption {
  font-style: italic;
  font-size: 0.95rem;
  color: var(--ink-soft);
  white-space: nowrap;
  opacity: 0;
}
:lang(zh) .merit figcaption { font-style: normal; font-size: 0.9rem; letter-spacing: 0.08em; }
.merit.pressed { opacity: 1; animation: press 420ms var(--ease-out) both; }
.merit.pressed figcaption { animation: rise 900ms 500ms ease both; }
.merit.shown { opacity: 1; }
.merit.shown figcaption { opacity: 1; }
@keyframes press {
  0% { opacity: 0; transform: scale(1.32) translateY(-6px); filter: blur(2px); }
  45% { opacity: 1; transform: scale(0.98); filter: blur(0); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* The rule, top to bottom, right to left, as it would hang. */
.verse {
  grid-area: verse;
  align-self: start;
  display: flex;
  flex-direction: row-reverse;
  align-items: flex-start;
  gap: clamp(10px, 1.6vw, 22px);
  margin: clamp(12px, 4vh, 48px) 0 0;
}
.verse .line {
  writing-mode: vertical-rl;
  font-family: var(--han);
  font-size: clamp(38px, 5.4vw, 74px);
  line-height: 1;
  letter-spacing: 0.16em;
  color: var(--ink);
  margin: 0;
}
.verse .source {
  writing-mode: vertical-rl;
  font-family: var(--han);
  font-size: clamp(14px, 1.2vw, 17px);
  letter-spacing: 0.3em;
  color: var(--ink-faint);
  margin: 0.4em 0 0;
}

.lead {
  grid-area: lead;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px 40px;
  margin-top: clamp(20px, 4vh, 40px);
}
.lead .words { max-width: 30rem; }
.lead h1 {
  margin: 0;
  font-weight: 500;
  font-size: clamp(1.75rem, 3.2vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -0.018em;
  text-wrap: balance;
}
:lang(zh) .lead h1 { font-weight: 400; letter-spacing: 0.04em; line-height: 1.4; }
.lead p {
  margin: 0.55em 0 0;
  color: var(--ink-soft);
  font-style: italic;
  font-size: 1.125rem;
}
:lang(zh) .lead p { font-style: normal; }

/* ── The download seal ───────────────────────────────────────────────── */

.get {
  display: flex;
  align-items: center;
  gap: 18px;
}
.stamp {
  position: relative;
  display: inline-grid;
  place-items: center;
  min-width: 132px;
  min-height: 56px;
  padding: 12px 22px;
  isolation: isolate;
  color: var(--seal-ink);
  font: 500 1.125rem/1 "Alegreya", var(--serif);
  letter-spacing: 0.01em;
  text-decoration: none;
  transition-property: scale;
  transition-duration: 140ms;
  transition-timing-function: ease;
}
/* The cinnabar, worn at the edges like a real impression; the lettering stays crisp. */
.stamp::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--cinnabar);
  border-radius: 3px;
  filter: url("#worn");
  transition: background-color 140ms ease;
}
:lang(zh) .stamp { font-family: var(--han); font-weight: 400; letter-spacing: 0.3em; padding-right: calc(22px - 0.3em); }
.stamp:active { scale: 0.96; }
.stamp:active::before { background: var(--cinnabar-press); }
@media (hover: hover) {
  .stamp:hover::before { background: var(--cinnabar-press); }
}
.get .meta {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* ── The sheets below: a hanging scroll, read downward ───────────────── */

.sheet {
  padding: clamp(72px, 14vh, 160px) var(--gutter);
  position: relative;
}
.sheet + .sheet { padding-top: 0; }
.sheet > .inner { max-width: 68rem; margin: 0 auto; }

/* A short brushed rule between sheets, instead of section borders. */
.stroke {
  display: block;
  width: 120px;
  height: 10px;
  margin: 0 auto clamp(56px, 10vh, 112px);
  color: var(--ink);
  opacity: 0.55;
}

h2 {
  margin: 0 0 1.1em;
  font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.2;
  letter-spacing: -0.014em;
  text-wrap: balance;
}
:lang(zh) h2 { font-weight: 400; letter-spacing: 0.08em; }
p { text-wrap: pretty; }

/* Why a fish: the rule hangs on the right, the reading on the left. */
.why .inner {
  display: grid;
  grid-template-columns: minmax(0, var(--measure)) auto;
  justify-content: space-between;
  gap: 48px clamp(40px, 8vw, 120px);
}
.why .scroll {
  display: flex;
  flex-direction: row-reverse;
  gap: 18px;
  align-items: flex-start;
}
.why .scroll p {
  writing-mode: vertical-rl;
  margin: 0;
  font-family: var(--han);
  font-size: clamp(22px, 2.2vw, 30px);
  line-height: 1.7;
  letter-spacing: 0.14em;
  max-height: 14em;
}
.why .scroll .source { font-size: 15px; color: var(--ink-faint); letter-spacing: 0.3em; }
.why .reading p { margin: 0 0 1em; }
.why blockquote {
  margin: 0 0 1.4em;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.5;
  color: var(--ink);
}
:lang(zh) .why blockquote { font-style: normal; }
.why .answer {
  font-family: var(--han);
  font-style: normal;
  white-space: nowrap;
}

/* What it does: notes in the margin of a scroll, numbered in Chinese. */
.notes ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 40px clamp(32px, 5vw, 72px);
}
.notes li {
  display: grid;
  align-content: start;
  grid-template-columns: 2.2em minmax(0, 1fr);
  column-gap: 0.4em;
}
.notes li::before {
  content: attr(data-n);
  font-family: var(--han);
  color: var(--cinnabar);
  font-size: 1.1em;
  line-height: 1.5;
}
.notes h3 {
  margin: 0;
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.5;
}
:lang(zh) .notes h3 { font-weight: 400; }
.notes li p {
  grid-column: 2;
  margin: 0.2em 0 0;
  color: var(--ink-soft);
  font-size: 1.0625rem;
  line-height: 1.6;
}

/* ── Night: the skins, as a handscroll you can knock ─────────────────── */

.night {
  background: var(--night);
  color: var(--night-text);
  padding: clamp(72px, 13vh, 140px) 0 clamp(64px, 11vh, 120px);
  overflow: hidden;
}
.night .head {
  max-width: 68rem;
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.night h2 { margin: 0 0 0.5em; }
.night .head p { margin: 0; color: var(--night-soft); max-width: 30rem; }
.night a { text-decoration-color: oklch(90% 0.01 85 / 0.3); }

.shelf {
  list-style: none;
  margin: clamp(40px, 7vh, 72px) 0 0;
  /* Starts in line with the heading above, and runs off the right edge. */
  padding: 8px var(--gutter) 28px max(var(--gutter), calc((100% - 68rem) / 2 + var(--gutter)));
  display: flex;
  gap: clamp(8px, 1.5vw, 20px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: max(var(--gutter), calc((100% - 68rem) / 2 + var(--gutter)));
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: oklch(90% 0.01 85 / 0.2) transparent;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--gutter), #000 calc(100% - var(--gutter)), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 var(--gutter), #000 calc(100% - var(--gutter)), transparent);
}
.shelf li { flex: 0 0 auto; scroll-snap-align: start; }
.skin {
  --glow: oklch(80% 0.05 85);
  position: relative;
  display: grid;
  justify-items: center;
  gap: 6px;
  width: clamp(132px, 15vw, 172px);
  padding: 0 0 6px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.skin img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  transform-origin: 50% 86%;
  pointer-events: none;
}
/* The pedestal's own neon, pooled on the floor under it. */
.skin::before {
  content: "";
  position: absolute;
  left: 18%;
  right: 18%;
  top: 78%;
  height: 14%;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in oklch, var(--glow) 55%, transparent), transparent);
  opacity: 0.35;
  filter: blur(6px);
  transition: opacity 600ms ease;
}
.skin.lit::before { opacity: 0.95; transition-duration: 40ms; }
.skin .label {
  font-size: 0.9375rem;
  line-height: 1.3;
  color: var(--night-soft);
  text-align: center;
}
.skin .label .han { display: block; color: var(--night-text); font-size: 0.875rem; letter-spacing: 0.1em; }
:lang(zh) .skin .label { font-size: 0.875rem; }
.night .more {
  max-width: 68rem;
  margin: 8px auto 0;
  padding: 0 var(--gutter);
  color: var(--night-soft);
  font-size: 1rem;
}

/* ── The last sheet: get it, then put it down ────────────────────────── */

.end .inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 48px clamp(40px, 8vw, 120px);
  align-items: start;
}
.end .get { margin: 0 0 28px; }
.end dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 22px;
  font-size: 1rem;
  color: var(--ink-soft);
  max-width: 36rem;
}
.end dt { color: var(--ink); }
.end dd { margin: 0; }
.letgo {
  display: flex;
  flex-direction: row-reverse;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px;
  max-width: 9rem;
}
.letgo p {
  writing-mode: vertical-rl;
  margin: 0;
  font-family: var(--han);
  font-size: clamp(34px, 4vw, 56px);
  letter-spacing: 0.2em;
  line-height: 1;
}
.letgo .who { font-size: 15px; letter-spacing: 0.3em; color: var(--ink-faint); margin-top: 0.3em; }
.letgo .chop { width: 30px; margin-top: 6px; }
.letgo .gloss {
  writing-mode: horizontal-tb;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.95rem;
  letter-spacing: 0;
  color: var(--ink-faint);
  flex-basis: 100%;
  text-align: right;
  margin-top: 4px;
}

footer {
  padding: 0 var(--gutter) max(36px, env(safe-area-inset-bottom));
  font-size: 0.9375rem;
  color: var(--ink-faint);
}
footer .inner {
  max-width: 68rem;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 32px;
  padding-top: 22px;
  border-top: 1px solid var(--rule);
}
footer p { margin: 0; }

/* ── Small screens ───────────────────────────────────────────────────── */

@media (max-width: 720px) {
  .hero {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    grid-template-areas:
      "stage verse"
      "lead  lead";
    padding-top: 76px;
    column-gap: 4px;
    min-height: auto;
  }
  .stage { --side: min(56vw, 400px); }
  .hint { bottom: -1.6em; }
  /* Under the fish, where the hint was: seal and words side by side. */
  .merit {
    right: auto;
    left: 50%;
    top: calc(50% + var(--side) / 2 + 2px);
    translate: -50% 0;
    grid-auto-flow: column;
    align-items: center;
    gap: 12px;
  }
  .merit .seal { width: 54px; }
  .verse { margin-top: 4px; gap: 6px; }
  .verse .line { font-size: clamp(30px, 9vw, 44px); }
  .lead { margin-top: 92px; }
  .why .inner, .end .inner { grid-template-columns: minmax(0, 1fr); }
  .why .scroll, .letgo { justify-content: flex-start; }
  .why .scroll { order: -1; }
  .why .scroll p { max-height: 10.5em; font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .merit.pressed, .merit.pressed figcaption { animation-duration: 1ms; animation-delay: 0ms; }
  .hint { transition: none; }
}
