/*
 * Comic-panel ("neo-brutalist") look: cream paper, 4px ink borders, hard offset shadows — the same
 * vocabulary as a manga page's panel frames. Brand colors come from the app's own favicon (wine
 * #5C0D11 → amber #9B4E03). Everything, including the reader demo's artwork, is CSS.
 */

:root {
  /* E-Hentai palette (apps/frontend/public/legacy/themes/g.css): beige paper, wine ink, amber. */
  --ink: #5c0d11;
  --text: #5c0d11;
  --paper: #e3e0d1;
  --card: #edebdf;
  --sand: #d9d5c3;
  --hi: #f0a500;
  --hi-text: #3d070a;
  --tint-a: #f1e2bd;
  --tint-b: #e9d3cb;
  --accent-text: #9b4e03;
  --btn-bg: #5c0d11;
  --btn-text: #f2efdf;
  --btn-shadow: #f0a500;
  --dots: rgba(92, 13, 17, 0.14);
  --wine: #5c0d11;
  --wine-2: #8a1a24;
  --line: 4px solid var(--ink);
  --line-thin: 3px solid var(--ink);
  --shadow: 8px 8px 0 var(--ink);
  --shadow-sm: 5px 5px 0 var(--ink);
  --radius: 22px;
  --display: "Dela Gothic One", "Segoe UI", "Hiragino Kaku Gothic ProN", "Noto Sans CJK JP",
    sans-serif;
  color-scheme: light;
}

/* ExHentai palette (ex.css): slate paper, light text, black ink. Follows the OS unless the
   E-H / EX switch in the top bar has picked one explicitly. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="eh"]) {
    --ink: #101114;
    --text: #f1f1f1;
    --paper: #34353b;
    --card: #43464e;
    --sand: #4f535b;
    --hi-text: #1d1e22;
    --tint-a: #4d4838;
    --tint-b: #4c3f45;
    --accent-text: #f0a500;
    --btn-bg: #f1f1f1;
    --btn-text: #34353b;
    --dots: rgba(0, 0, 0, 0.28);
    color-scheme: dark;
  }
}

:root[data-theme="ex"] {
  --ink: #101114;
  --text: #f1f1f1;
  --paper: #34353b;
  --card: #43464e;
  --sand: #4f535b;
  --hi-text: #1d1e22;
  --tint-a: #4d4838;
  --tint-b: #4c3f45;
  --accent-text: #f0a500;
  --btn-bg: #f1f1f1;
  --btn-text: #34353b;
  --dots: rgba(0, 0, 0, 0.28);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family:
    "Segoe UI", "Helvetica Neue", Arial, "Noto Sans CJK SC", "Noto Sans CJK JP", "PingFang SC",
    "Hiragino Kaku Gothic ProN", "Hiragino Sans GB", "Microsoft YaHei", "Yu Gothic", Meiryo,
    sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.08;
  letter-spacing: -0.04em;
}

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

/* ---- top bar ---------------------------------------------------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 12px 22px;
  background: var(--paper);
  border-bottom: var(--line-thin);
}

.brand {
  /* The icon's height, and the wordmark's capital height: a little under the icon's, since a
     rounded square reads smaller than heavy flat-topped capitals of the same measured height. */
  --brand-size: 30px;
  --brand-cap: 26px;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-weight: 900;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  text-decoration: none;
}

/* Capitals at `--brand-cap` (the body fonts' cap height is about 0.7 em). The line box stays the
   icon's height so the bar doesn't grow; where `text-box` is supported the text is trimmed to its
   capitals for exact centring, elsewhere a 2px nudge corrects the em box's low baseline. */
.brand span {
  font-size: calc(var(--brand-cap) / 0.7);
  line-height: var(--brand-size);
  letter-spacing: -0.03em;
}

@supports (text-box: trim-both cap alphabetic) {
  .brand span {
    line-height: 1;
    text-box: trim-both cap alphabetic;
  }
}

@supports not (text-box: trim-both cap alphabetic) {
  .brand span {
    position: relative;
    top: -2px;
  }
}

.brand img {
  display: block;
  border: var(--line-thin);
  border-radius: 9px;
}

.topnav {
  display: flex;
  gap: 4px;
  margin-left: auto;
}

.topbar > .langs {
  margin-left: -14px;
}

.topnav a {
  padding: 6px 12px;
  border: 3px solid transparent;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 850;
  text-decoration: none;
}

.topnav a:hover {
  border-color: var(--ink);
}

.langs {
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--card);
}

.langs a {
  min-width: 38px;
  text-align: center;
  text-decoration: none;
  padding: 3px 10px;
  border: 3px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 850;
  cursor: pointer;
}

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

/* ---- shared building blocks ------------------------------------------------------------- */

main {
  max-width: 1320px;
  margin: 0 auto;
  padding: 40px 24px 0;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border: var(--line);
  border-radius: 999px;
  font-size: 1rem;
  font-weight: 950;
  text-decoration: none;
  transition:
    transform 120ms ease,
    box-shadow 120ms ease;
}

.btn svg {
  width: 18px;
  height: 18px;
}

.btn.primary {
  background-color: var(--btn-bg);
  color: var(--btn-text);
  box-shadow: 5px 5px 0 var(--btn-shadow);
}

.btn.ghost {
  background-color: var(--hi);
  box-shadow: var(--shadow-sm);
}

.btn:hover {
  transform: translate(-2px, -2px);
}

.btn.primary:hover {
  box-shadow: 7px 7px 0 var(--btn-shadow);
}

.btn.ghost:hover {
  box-shadow: 7px 7px 0 var(--ink);
}

.btn:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--ink);
}

/* ---- hero ------------------------------------------------------------------------------- */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: 28px;
  align-items: stretch;
}

.hero-copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 52px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  color: var(--accent-text);
  font-size: 0.85rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.kicker-dot {
  width: 10px;
  height: 10px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--hi);
}

.hero-title {
  font-size: clamp(2.4rem, 4.6vw, 3.9rem);
  font-weight: 800;
}

.hero-title span,
.hero-title em {
  display: block;
}

/* Japanese: two fixed phrases of about 8.5 characters each, wider than the Chinese ones at the
   same size, so the shared size wrapped them and orphaned a kana. Sized to the card's own width
   instead (11cqi keeps each phrase, plus the highlight's padding, inside it), never larger than
   the shared size, and kept unbroken. */
.hero-copy {
  container-type: inline-size;
}

:lang(ja) .hero-title {
  font-size: min(3.9rem, 11cqi);
}

:lang(ja) .hero-title span,
:lang(ja) .hero-title em {
  white-space: nowrap;
}

/* English: the first line is long and wraps naturally, but the highlighted phrase must stay whole
   (a broken highlight reads as two bars). It is about 7.9 em plus the highlight's padding, so
   11.5cqi keeps it inside the card down to phone widths. */
:lang(en) .hero-title {
  font-size: min(3.9rem, 11.5cqi);
}

:lang(en) .hero-title em {
  white-space: nowrap;
}

/* A highlighter stroke behind the second line, the way a manga title card is set. */
.hero-title em {
  justify-self: start;
  width: fit-content;
  margin-top: 6px;
  padding: 0 10px;
  font-style: normal;
  background: linear-gradient(180deg, transparent 52%, var(--hi) 52%, var(--hi) 92%, transparent 92%);
}

.hero-lead {
  margin: 22px 0 28px;
  max-width: 34em;
  font-size: 1.04rem;
  font-weight: 600;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.hero-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
}

.hero-tags li {
  padding: 2px 12px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--sand);
  font-size: 0.82rem;
  font-weight: 800;
}

/* ---- the reader demo -------------------------------------------------------------------- */

.device {
  position: relative;
  margin: 0;
  padding: 34px 30px 26px;
  background:
    radial-gradient(var(--dots) 1.2px, transparent 1.5px) 0 0 / 9px 9px,
    var(--sand);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}

/* decorative tabs poking in from the edges, like the reference's pills */
.device::before,
.device::after {
  content: "";
  position: absolute;
  border: var(--line);
  border-radius: 999px;
}

.device::before {
  top: 18px;
  right: -40px;
  width: 140px;
  height: 46px;
  background: var(--hi);
}

.device::after {
  bottom: 74px;
  left: -46px;
  width: 92px;
  height: 92px;
  background: var(--wine-2);
}

.reader {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background: #1d1a17;
  border: var(--line);
  border-radius: 18px;
  box-shadow: 6px 6px 0 var(--ink);
  color: #f5efdc;
}

.reader-bar,
.reader-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  font-size: 0.78rem;
}

.reader-bar {
  border-bottom: 2px solid #000;
}

.rb-back {
  font-size: 1.3rem;
  line-height: 1;
  opacity: 0.7;
}

.rb-title {
  flex: 1;
  overflow: hidden;
  font-weight: 700;
  white-space: nowrap;
  text-overflow: ellipsis;
  opacity: 0.85;
}

.rb-translate {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 4px;
  border: 2px solid #f5efdc;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease;
}

.rb-tr-icon {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #f5efdc;
  color: #1d1e22;
  font-size: 0.72rem;
  font-weight: 900;
}

.rb-translate[aria-pressed="true"] {
  background: #f0a500;
  border-color: #f0a500;
  color: #1d1e22;
}

.rb-translate[aria-pressed="true"] .rb-tr-icon {
  background: #1d1e22;
  color: #f0a500;
}

.spread {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 12px 14px;
  background: #2b2723;
  /* right page first in reading order, but visually on the right */
  direction: rtl;
}

.page {
  position: relative;
  direction: ltr;
  display: grid;
  gap: 6px;
  aspect-ratio: 0.71;
  padding: 9px;
  background: #fbf8ef;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}

.page-r {
  grid-template: 1.1fr 1fr / 1.3fr 1fr;
  grid-template-areas: "wide wide" "a b";
}

.page-l {
  grid-template: 1fr 1.2fr / 1fr 1fr;
  grid-template-areas: "c d" "e e";
}

.koma {
  border: 2.5px solid #111;
  background: #fff;
}

.k-wide { grid-area: wide; }
.k-a { grid-area: a; }
.k-b { grid-area: b; }
.k-c { grid-area: c; }
.k-d { grid-area: d; }
.k-e { grid-area: e; }

/* screentones and effects, all gradients */
.tone-dots {
  background:
    radial-gradient(#111 1px, transparent 1.4px) 0 0 / 5px 5px,
    linear-gradient(180deg, #fff 35%, #ddd 100%);
}

.tone-sky {
  background:
    radial-gradient(circle at 70% 30%, #fff 0 16%, transparent 17%),
    radial-gradient(#111 0.8px, transparent 1.1px) 0 0 / 4px 4px,
    #fff;
}

.tone-night {
  background:
    radial-gradient(circle at 30% 30%, #fbf8ef 0 9%, transparent 10%),
    repeating-linear-gradient(45deg, #111 0 1px, transparent 1px 4px),
    #3a3a3a;
}

.tone-grad {
  background:
    linear-gradient(160deg, transparent 55%, #111 55% 58%, transparent 58%),
    radial-gradient(#111 0.9px, transparent 1.2px) 0 0 / 4px 4px,
    linear-gradient(0deg, #bbb, #fff);
}

.speed {
  background:
    radial-gradient(circle at 50% 55%, #fff 0 18%, transparent 19%),
    repeating-conic-gradient(from 0deg at 50% 55%, #111 0 1.2deg, #fff 1.2deg 7deg);
}

.speed-soft {
  background:
    radial-gradient(ellipse at 50% 60%, #fff 0 22%, transparent 23%),
    repeating-linear-gradient(90deg, #fff 0 9px, #222 9px 10px, #fff 10px 13px);
}

/* speech bubbles */
.bubble {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 13% 12%;
  background: #fff;
  border: 2.5px solid #111;
  border-radius: 50%;
  color: #111;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  transition: box-shadow 200ms ease;
}

.bubble::after {
  /* tail */
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  background: #fff;
  border-right: 2.5px solid #111;
  border-bottom: 2.5px solid #111;
}

.bubble .jp,
.bubble .tr {
  grid-area: 1 / 1;
  transition: opacity 260ms ease, filter 260ms ease;
}

.bubble .jp {
  writing-mode: vertical-rl;
  font-size: clamp(8px, 0.82vw, 11px);
  letter-spacing: 0.04em;
}

.bubble .tr {
  opacity: 0;
  font-size: clamp(8px, 0.8vw, 11px);
}

.reader.tr-vertical .bubble .tr {
  writing-mode: vertical-rl;
  letter-spacing: 0.04em;
}

.b1 {
  top: 4%;
  right: 4%;
  width: 40%;
  height: 46%;
}
.b1::after {
  bottom: -6px;
  left: 22%;
  transform: rotate(35deg);
}

.b2 {
  bottom: 5%;
  left: 2%;
  width: 44%;
  height: 40%;
  border-radius: 46% 54% 50% 50%;
}
.b2::after {
  top: -6px;
  right: 24%;
  transform: rotate(-145deg);
}

/* the shout bubble gets the jagged "burst" outline manga uses */
.b2.shout {
  border-radius: 0;
  border: 0;
  background: none;
}
.b2.shout::before {
  content: "";
  position: absolute;
  inset: -4px;
  z-index: -1;
  background: #111;
  clip-path: polygon(50% 0, 60% 12%, 78% 4%, 80% 20%, 100% 18%, 90% 36%, 100% 50%, 90% 62%, 100% 80%, 80% 80%, 76% 98%, 60% 86%, 50% 100%, 40% 86%, 22% 96%, 20% 80%, 0 82%, 10% 62%, 0 50%, 10% 36%, 0 18%, 20% 20%, 22% 4%, 40% 12%);
}
.b2.shout::after {
  inset: 0;
  width: auto;
  height: auto;
  border: 0;
  z-index: -1;
  transform: scale(0.94);
  clip-path: polygon(50% 0, 60% 12%, 78% 4%, 80% 20%, 100% 18%, 90% 36%, 100% 50%, 90% 62%, 100% 80%, 80% 80%, 76% 98%, 60% 86%, 50% 100%, 40% 86%, 22% 96%, 20% 80%, 0 82%, 10% 62%, 0 50%, 10% 36%, 0 18%, 20% 20%, 22% 4%, 40% 12%);
}

.b3 {
  top: 36%;
  left: 12%;
  width: 48%;
  height: 40%;
}
.b3::after {
  top: -6px;
  left: 40%;
  transform: rotate(-135deg);
}

/* OCR scan sweep */
.scanline {
  position: absolute;
  inset: 12px 14px;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(90deg, transparent 0, rgba(240, 165, 0, 0.5) 48%, var(--hi) 50%, transparent 52%) no-repeat;
  background-size: 40% 100%;
  background-position: 130% 0;
}

/* states, set by script.js: original → detect → erase → translated */
.reader[data-state="detect"] .scanline {
  opacity: 1;
  animation: sweep 1.1s ease-in-out forwards;
}

@keyframes sweep {
  from { background-position: 130% 0; }
  to { background-position: -40% 0; }
}

.reader[data-state="detect"] .bubble,
.reader[data-state="erase"] .bubble {
  box-shadow: 0 0 0 3px #f0a500, 0 0 0 5px #111;
}

.reader[data-state="detect"] .b2.shout,
.reader[data-state="erase"] .b2.shout {
  box-shadow: none;
  outline: 3px dashed var(--hi);
  outline-offset: 2px;
}

.reader[data-state="erase"] .bubble .jp {
  opacity: 0;
  filter: blur(3px);
}

.reader[data-state="translated"] .bubble .jp {
  opacity: 0;
}

.reader[data-state="translated"] .bubble .tr {
  opacity: 1;
}

.reader-foot {
  border-top: 2px solid #000;
  font-variant-numeric: tabular-nums;
}

.rf-track {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: #3b3530;
  overflow: hidden;
}

.rf-fill {
  display: block;
  width: 8%;
  height: 100%;
  margin-left: auto; /* RTL progress */
  background: var(--hi);
}

.rf-status {
  min-width: 5em;
  padding: 1px 8px;
  border-radius: 999px;
  background: #3b3530;
  font-weight: 800;
  text-align: center;
}

.reader[data-state="translated"] .rf-status {
  background: var(--hi);
  color: var(--ink);
}

.steps {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
}

.step {
  padding: 3px 12px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--card);
  font-size: 0.8rem;
  font-weight: 900;
  transition: background-color 200ms ease, transform 200ms ease;
}

.step.on {
  background: var(--hi);
  transform: translateY(-3px);
  box-shadow: 0 3px 0 var(--ink);
}

/* ---- chapters --------------------------------------------------------------------------- */

.chapter {
  margin-top: 96px;
}

.chapter-head {
  margin-bottom: 30px;
}

.chapter-no {
  display: inline-block;
  margin: 0 0 12px;
  padding: 2px 14px;
  border: var(--line-thin);
  border-radius: 6px;
  background: var(--ink);
  color: var(--hi);
  font-family: var(--display);
  font-size: 1rem;
  letter-spacing: 0.06em;
  transform: rotate(-2deg);
}

.chapter h2 {
  font-size: clamp(2rem, 4.2vw, 3.6rem);
  font-weight: 800;
}

.chapter-lead {
  max-width: 44em;
  margin: 16px 0 0;
  font-size: 1.04rem;
  font-weight: 600;
}

/* ---- AI koma grid ----------------------------------------------------------------------- */

.koma-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 22px;
}

.panel {
  position: relative;
  padding: 28px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.panel h3 {
  margin: 14px 0 10px;
  font-size: 1.55rem;
  font-weight: 800;
}

.panel p {
  margin: 0;
  font-weight: 600;
}

.panel-badge {
  display: inline-block;
  padding: 1px 12px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--hi);
  font-size: 0.82rem;
  font-weight: 950;
}

.p-translate {
  grid-column: span 4;
  background: var(--hi);
}

.p-translate .panel-badge {
  background: var(--card);
}

.p-translate h3 {
  font-size: clamp(1.8rem, 3vw, 2.6rem);
}

.p-wizard {
  grid-column: span 2;
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  background: var(--tint-b);
}

.p-wizard .panel-badge {
  background: var(--wine);
  color: #f2efdf;
}

.p-recommend {
  grid-column: span 2;
  background: var(--tint-a);
}

.p-tank {
  grid-column: span 2;
  background: var(--sand);
}

.p-mini {
  grid-column: span 3;
  padding: 22px 28px;
}

.p-mini h3 {
  margin-top: 0;
  font-size: 1.25rem;
}

.pipeline {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 0;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.pipeline li {
  display: inline-flex;
  align-items: center;
  font-weight: 900;
  font-size: 0.92rem;
  counter-increment: step;
}

.pipeline li::before {
  content: counter(step);
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  margin-right: 6px;
  border: var(--line-thin);
  border-radius: 50%;
  background: var(--card);
  font-size: 0.78rem;
}

.pipeline li:not(:last-child)::after {
  content: "";
  width: 22px;
  height: 3px;
  margin: 0 8px;
  background: var(--ink);
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.facts li {
  padding: 4px 12px;
  border: 2px solid var(--ink);
  border-radius: 10px;
  background: var(--card);
  font-size: 0.85rem;
  font-weight: 800;
}

/* fake wizard terminal */
.term {
  flex: 1;
  margin-top: 20px;
  padding: 16px 16px 12px;
  border: var(--line);
  border-radius: 16px;
  background: #252525;
  color: #f5efdc;
  font-family: ui-monospace, "Cascadia Code", "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.85rem;
  line-height: 1.55;
}

.term p {
  position: relative;
  margin: 0 0 9px;
  padding-left: 20px;
  font-weight: 500;
}

.term p::before {
  position: absolute;
  left: 0;
  font-weight: 900;
}

.t-in {
  color: var(--hi);
}
.t-in::before {
  content: "›";
}
.t-ok::before {
  content: "✓";
  color: #9be37a;
}
.t-err {
  color: #ffb4a8;
}
.t-err::before {
  content: "✗";
  color: #ff7a66;
}
.t-ask::before {
  content: "?";
  color: var(--hi);
}
.t-ask::after {
  content: "";
  display: inline-block;
  width: 8px;
  height: 1em;
  margin-left: 6px;
  vertical-align: -2px;
  background: currentColor;
  animation: blink 1s steps(1) infinite;
}

@keyframes blink {
  50% { opacity: 0; }
}

/* recommendation cards: mini covers fanning out */
.recs {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}

.rec {
  flex: 1;
  aspect-ratio: 0.7;
  border: var(--line-thin);
  border-radius: 8px;
  box-shadow: 3px 3px 0 var(--ink);
  background:
    linear-gradient(transparent 62%, rgba(255, 255, 255, 0.85) 62% 70%, transparent 70% 76%, rgba(255, 255, 255, 0.6) 76% 81%, transparent 81%) 0 0 / 70% 100% no-repeat,
    radial-gradient(rgba(255, 255, 255, 0.4) 1px, transparent 1.4px) 0 0 / 5px 5px;
}

.r1 { background-color: var(--wine-2); transform: rotate(-4deg); }
.r2 { background-color: #c98a2e; transform: rotate(2deg) translateY(-6px); }
.r3 { background-color: #3d5a80; transform: rotate(-1deg); }
.r4 { background-color: #2f6f6a; transform: rotate(3deg) translateY(-4px); }

/* tankoubon sorter */
.sort {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
}

.sort-in,
.sort-out {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sort-in li {
  margin-bottom: 6px;
  padding: 3px 8px;
  overflow: hidden;
  border: 2px dashed var(--ink);
  border-radius: 8px;
  background: var(--card);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.68rem;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.sort-in li:nth-child(2) { transform: rotate(-1.5deg); }
.sort-in li:nth-child(3) { transform: rotate(1deg); }

.sort-arrow {
  font-size: 1.4rem;
  font-weight: 900;
}

.sort-out li {
  display: flex;
  align-items: baseline;
  gap: 2px;
  margin-bottom: 6px;
  padding: 2px 10px;
  border: var(--line-thin);
  border-radius: 8px;
  background: var(--hi);
  font-size: 0.8rem;
  font-weight: 900;
}

.sort-out b {
  font-size: 1rem;
}

/* ---- reader features -------------------------------------------------------------------- */

.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.feature-grid li {
  padding: 24px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.feature-grid li:nth-child(3n + 2) {
  background: var(--sand);
}

.feature-grid li:nth-child(3n) {
  background: var(--tint-a);
}

.fi {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: var(--line-thin);
  border-radius: 50%;
  background: var(--hi);
  font-size: 1.1rem;
  font-weight: 900;
}

.feature-grid h3 {
  margin: 14px 0 8px;
  font-size: 1.4rem;
  font-weight: 800;
}

.feature-grid p {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
}

/* ---- library ---------------------------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 22px;
  margin: 0;
}

.stats div {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  padding: 20px 24px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.stats div:first-child {
  background: var(--hi);
}

.stats dd {
  margin: 0;
  font-family: var(--display);
  font-size: 3.2rem;
  line-height: 1.1;
}

.stats dt {
  font-size: 0.9rem;
  font-weight: 800;
}

.search-demo {
  margin-top: 30px;
  padding: 26px 30px;
  background: var(--sand);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.sd-label {
  margin: 0 0 12px;
  font-size: 1.15rem;
  font-weight: 900;
}

.sd-box {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 12px 18px;
  border: var(--line);
  border-radius: 999px;
  background: var(--card);
  overflow-x: auto;
}

.sd-icon {
  font-size: 1.3rem;
  font-weight: 900;
}

.sd-box code {
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.95rem;
  white-space: nowrap;
}

.q-ns {
  color: var(--accent-text);
  font-weight: 800;
}

.q-op {
  padding: 0 4px;
  border-radius: 4px;
  background: var(--hi);
  font-weight: 900;
}

.sd-hint {
  margin: 12px 0 0;
  font-size: 0.88rem;
  font-weight: 700;
}

.ds-note {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-top: 30px;
  padding: 22px 30px;
  background: var(--tint-a);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.ds-mascot {
  position: relative;
  flex: 0 0 auto;
  width: 96px;
  line-height: 0;
}

.ds-mascot img {
  display: block;
  width: 100%;
  height: auto;
}

/* Highlights drawn only where the picture is opaque: the picture itself is the mask. A soft
   static light from the top left, plus a sheen that sweeps across now and then. */
.ds-mascot::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.7) 50%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(circle at 30% 18%, rgba(255, 255, 255, 0.32), rgba(255, 255, 255, 0) 55%);
  background-size: 300% 100%, 100% 100%;
  background-repeat: no-repeat;
  background-position: 100% 0, 0 0;
  -webkit-mask: url("dafeiyu.webp") center / contain no-repeat;
  mask: url("dafeiyu.webp") center / contain no-repeat;
  animation: ds-sheen 5s ease-in-out infinite;
}

@keyframes ds-sheen {
  0%,
  55% {
    background-position: 100% 0, 0 0;
  }
  100% {
    background-position: 0% 0, 0 0;
  }
}

.ds-text h3 {
  margin: 0 0 8px;
  font-size: 1.2rem;
  font-weight: 900;
}

.ds-text p {
  margin: 0;
  font-weight: 650;
}

.ds-link {
  display: inline-block;
  margin-top: 10px;
  color: var(--accent-text);
  font-weight: 900;
}

.fmt-rows {
  display: grid;
  gap: 10px;
}

.fmt-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.fmt-kind {
  min-width: 5.5em;
  font-weight: 900;
}

.fmt {
  padding: 4px 14px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--card);
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.9rem;
  font-weight: 800;
  white-space: nowrap;
}

.mini-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 30px;
  margin: 30px 0 0;
  padding: 0;
  list-style: none;
}

.mini-list li {
  position: relative;
  padding-left: 30px;
  font-weight: 650;
}

.mini-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 1px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--tint-a);
  font-size: 0.7rem;
  font-weight: 900;
}

/* ---- get started ------------------------------------------------------------------------ */

.start-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: 28px;
  align-items: start;
}

.howto {
  display: grid;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: howto;
}

.howto li {
  position: relative;
  padding: 18px 22px 18px 74px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  counter-increment: howto;
}

.howto li::before {
  content: counter(howto);
  position: absolute;
  left: 18px;
  top: 16px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: var(--line-thin);
  border-radius: 50%;
  background: var(--hi);
  color: var(--hi-text);
  font-family: var(--display);
  font-size: 1.1rem;
}

.howto h3,
.howto h4 {
  margin: 0 0 4px;
  font-size: 1.25rem;
  font-weight: 800;
}

.howto p {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
}

.migrate {
  margin: 0 0 40px;
}

.migrate-title {
  margin: 0 0 16px;
  font-size: 1.6rem;
  font-weight: 800;
}

.migrate-steps {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.migrate-steps a {
  color: var(--accent-text);
  font-weight: 900;
}

.howto .howto-cmd {
  margin: 6px 0;
}

.howto code {
  padding: 2px 10px;
  border: 2px solid var(--ink);
  border-radius: 8px;
  background: var(--sand);
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.9rem;
}

.code {
  margin: 0;
  padding: 50px 26px 24px;
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background:
    radial-gradient(circle at 26px 22px, var(--hi) 0 5px, transparent 6px),
    radial-gradient(circle at 46px 22px, #9be37a 0 5px, transparent 6px),
    radial-gradient(circle at 66px 22px, var(--hi) 0 5px, transparent 6px),
    linear-gradient(#111 0 44px, #000 44px 47px, #252525 47px);
  color: #f5efdc;
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.95rem;
  line-height: 1.8;
  overflow-x: auto;
}

.c-dim {
  color: #9a9284;
}


.doc-links {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  margin-top: 34px;
}

.doc-links a {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 24px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.doc-links a:hover {
  transform: translate(-2px, -2px);
  box-shadow: 7px 7px 0 var(--ink);
}

.doc-links strong {
  font-size: 1.25rem;
  letter-spacing: -0.02em;
}

.doc-links strong::after {
  content: " →";
}

.doc-links span {
  font-size: 0.9rem;
  font-weight: 600;
}

/* ---- footer ----------------------------------------------------------------------------- */

.footer {
  max-width: 1320px;
  margin: 100px auto 0;
  padding: 26px 24px 40px;
  border-top: var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-weight: 700;
}

.footer p {
  margin: 0;
}

.footer-meta {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 6px 24px;
  font-size: 0.75rem;
  opacity: 0.7;
}

.footer-meta a {
  color: inherit;
}

.tsuzuku {
  font-family: var(--display);
  font-size: 1.6rem;
  transform: rotate(-3deg);
}

.tsuzuku::after {
  content: " ▶";
  color: var(--accent-text);
}

/* ---- responsive ------------------------------------------------------------------------- */

@media (max-width: 980px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
  }

  .koma-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .p-translate,
  .p-wizard {
    grid-column: 1 / -1;
    grid-row: auto;
  }

  .p-recommend,
  .p-tank,
  .p-mini {
    grid-column: span 1;
  }

  .feature-grid,
  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .topnav {
    display: none;
  }

  .theme-switch {
    margin-left: auto;
  }
}

@media (max-width: 640px) {
  /* No room for the large wordmark beside both switches: the previous size. */
  .brand span {
    top: 0;
    font-size: 1.05rem;
    line-height: inherit;
    letter-spacing: -0.02em;
    text-box: none;
  }

  .ds-note {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding: 22px;
  }

  .ds-mascot {
    width: 80px;
  }

  .topbar {
    gap: 8px;
  }

  .topbar > .langs {
    margin-left: 0;
  }

  .langs a,
  .theme-switch button {
    min-width: 0;
    padding: 2px 7px;
  }

  main {
    padding: 24px 16px 0;
  }

  .topbar {
    padding: 10px 16px;
  }

  .hero-copy {
    padding: 30px 22px;
  }

  .device {
    padding: 24px 14px 18px;
  }

  .spread {
    padding: 8px;
  }

  .page {
    padding: 5px;
    gap: 4px;
  }

  .chapter {
    margin-top: 72px;
  }

  .start-grid,
  .koma-grid,
  .feature-grid,
  .mini-list,
  .doc-links {
    grid-template-columns: minmax(0, 1fr);
  }

  .p-recommend,
  .p-tank,
  .p-mini {
    grid-column: auto;
  }

  .stats {
    gap: 14px;
  }

  .stats dd {
    font-size: 2.4rem;
  }

  .panel,
  .search-demo {
    padding: 22px;
  }

  .code {
    font-size: 0.82rem;
  }

  .footer {
    padding: 22px 16px 32px;
  }
}

/* Narrow phones: icon, both switches and the bar's padding already fill the width, so the
   wordmark is hidden visually (screen readers still get the link's name). */
@media (max-width: 420px) {
  .brand span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

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

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---- text on the amber highlight, and the panel children that sit back on card color ------- */

.langs a[aria-current="page"],
.btn.ghost,
.step.on,
.panel-badge,
.p-translate,
.sort-out li,
.fi,
.stats div:first-child,
.q-op,
.doc-links a:hover,
.rf-status {
  color: var(--hi-text);
}

.p-translate .panel-badge,
.p-translate .facts li,
.p-translate .pipeline li::before {
  color: var(--text);
}

.rf-status {
  color: #f5efdc;
}

.reader[data-state="translated"] .rf-status {
  color: #1d1e22;
}

/* the E-H / EX theme switch */
.theme-switch {
  position: relative;
  /* Never squeezed by a narrow top bar: that broke "E-H" at its hyphen. */
  flex-shrink: 0;
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 2px;
  padding: 4px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--card);
}

/* The active pill is one layer that slides between the two (equal-width) options instead of
   jumping. `ready` is added by script.js after the first sync, so loading on EX doesn't animate. */
.theme-switch::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  /* One column: half of the padding box minus the 4px padding and half the 2px gap. Border-box,
     since the global `* { box-sizing }` rule doesn't reach pseudo-elements. */
  box-sizing: border-box;
  width: calc(50% - 5px);
  border: 3px solid var(--ink);
  border-radius: 999px;
  background: var(--btn-bg);
}

.theme-switch.ready::before {
  transition:
    transform 320ms cubic-bezier(0.34, 1.4, 0.64, 1),
    background-color 200ms ease;
}

.theme-switch:has([data-theme-choice="ex"][aria-pressed="true"])::before {
  transform: translateX(calc(100% + 2px));
}

.theme-switch button {
  position: relative;
  padding: 3px 10px;
  white-space: nowrap;
  border: 3px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 900;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.theme-switch button[aria-pressed="true"] {
  color: var(--btn-text);
}

/* ---- compose block: copy button and proxy note -------------------------------------------- */

.code-wrap {
  position: relative;
  min-width: 0;
}

.copy-btn {
  position: absolute;
  top: 9px;
  right: 14px;
  z-index: 1;
  padding: 2px 14px;
  border: 2px solid #f5efdc;
  border-radius: 999px;
  background: transparent;
  color: #f5efdc;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 900;
  cursor: pointer;
}

.copy-btn:hover,
.copy-btn.done {
  border-color: #f0a500;
  color: #1d1e22;
}

.converter {
  margin-top: 30px;
  background: var(--sand);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.converter summary {
  padding: 18px 30px;
  font-size: 1.1rem;
  font-weight: 900;
  cursor: pointer;
}

.conv-body {
  display: grid;
  gap: 14px;
  padding: 0 30px 26px;
}

.conv-lead {
  margin: 0;
  font-weight: 650;
}

.converter textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 14px 16px;
  color: var(--text);
  background: var(--card);
  border: var(--line-thin);
  border-radius: 14px;
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  resize: vertical;
}

.conv-run {
  justify-self: start;
}

.conv-notes {
  display: grid;
  gap: 6px;
  margin: 0;
  padding-left: 1.2em;
  font-weight: 650;
}

.conv-notes:empty {
  display: none;
}

.conv-notes .warn {
  color: var(--accent-text);
}

.conv-out[hidden] {
  display: none;
}

.native-note {
  margin-top: 30px;
  padding: 22px 30px;
  background: var(--card);
  border: var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.native-note h3 {
  margin: 0 0 8px;
  font-size: 1.15rem;
  font-weight: 900;
}

.native-note p {
  margin: 0;
  font-weight: 650;
}

.native-note a {
  display: inline-block;
  margin-top: 10px;
  color: var(--accent-text);
  font-weight: 900;
}

.code-note {
  margin: 18px 0 0;
  font-weight: 700;
}

.db-note {
  color: var(--accent-text);
}

.code-note a {
  margin-left: 4px;
  color: var(--accent-text);
  font-weight: 900;
}

/* ---- 404 ---------------------------------------------------------------------------------- */

.notfound {
  max-width: 640px;
  padding-top: 18vh;
  text-align: center;
}

.notfound h1 {
  margin: 10px 0 28px;
  font-size: clamp(2rem, 5vw, 3rem);
}

.notfound-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}

.notfound-links a {
  padding: 8px 18px;
  border: var(--line-thin);
  border-radius: 999px;
  background: var(--card);
  box-shadow: var(--shadow-sm);
  font-weight: 900;
  text-decoration: none;
}

/* ---- hover fill ----------------------------------------------------------------------------
   The amber sweeps in from the left instead of switching instantly: a gradient layer over the
   element's own background colour, grown via background-size. */

.doc-links a,
.copy-btn,
.topnav a,
.btn {
  background-image: linear-gradient(var(--fill, var(--hi)), var(--fill, var(--hi)));
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 0% 100%;
  transition:
    background-size 300ms ease,
    color 200ms ease,
    border-color 200ms ease,
    transform 120ms ease,
    box-shadow 120ms ease;
}

.topnav a {
  --fill: var(--card);
}

.copy-btn {
  --fill: #f0a500;
}

.doc-links a:hover,
.copy-btn:hover,
.copy-btn.done,
.topnav a:hover,
.btn:hover {
  background-size: 100% 100%;
}

/* The hero buttons fill with a shade of their own colour, warmed towards their shadow (primary)
   or lightened (the amber GitHub one). */
.btn.primary {
  --fill: color-mix(in srgb, var(--btn-bg) 78%, var(--btn-shadow));
}

.btn.ghost {
  --fill: color-mix(in srgb, var(--hi) 62%, #fff);
}

.btn.ghost svg {
  transition: transform 300ms cubic-bezier(0.34, 1.4, 0.64, 1);
}

.btn.ghost:hover svg {
  transform: rotate(-14deg) scale(1.12);
}

/* ---- segmented switches (theme, language) ------------------------------------------------------
   The common segmented-control treatment (macOS, Vercel and GitHub tabs): unselected options sit a
   little muted and, on hover, come to full strength over a faint fill; nothing moves but the
   selected pill. */

.langs a:not([aria-current="page"]) {
  opacity: 0.7;
  transition:
    opacity 150ms ease,
    background-color 150ms ease;
}

.langs a:not([aria-current="page"]):hover {
  opacity: 1;
  background-color: color-mix(in srgb, var(--ink) 10%, transparent);
}

/* The theme switch previews the theme under the pointer: that theme's card colour wipes across
   the box from a corner — E-H from the top-left, EX from the top-right — and the unselected label
   takes that theme's text colour to stay readable. Each theme is its own layer, clipped to a
   triangle that grows from its corner along the box's own diagonal, so the edge runs corner to
   corner whatever the box's proportions. The hovered layer is always on top: otherwise a wipe
   could play underneath the other one still retracting (the pointer usually crosses E-H on its
   way to EX). The palettes are literal on purpose: the switch shows the other theme. */
.theme-switch {
  --eh-card: #edebdf;
  --eh-text: #5c0d11;
  --ex-card: #43464e;
  --ex-text: #f1f1f1;
}

.ts-fill {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  transition: clip-path 380ms ease;
}

.ts-eh {
  background: var(--eh-card);
  clip-path: polygon(0 0, 0 0, 0 0);
}

.ts-ex {
  background: var(--ex-card);
  clip-path: polygon(100% 0, 100% 0, 100% 0);
}

.theme-switch:has([data-theme-choice="eh"]:hover) .ts-eh {
  z-index: 1;
  clip-path: polygon(0 0, 200% 0, 0 200%);
}

.theme-switch:has([data-theme-choice="ex"]:hover) .ts-ex {
  z-index: 1;
  clip-path: polygon(100% 0, -100% 0, 100% 200%);
}

/* Above both fills: the sliding pill, then the labels. */
.theme-switch::before {
  z-index: 2;
}

.theme-switch button {
  z-index: 3;
}

.theme-switch button[aria-pressed="false"] {
  transition: color 320ms ease;
}

.theme-switch:has([data-theme-choice="eh"]:hover) button[aria-pressed="false"] {
  color: var(--eh-text);
}

.theme-switch:has([data-theme-choice="ex"]:hover) button[aria-pressed="false"] {
  color: var(--ex-text);
}

