/* ===========================================================================
   VMČ Query Interface — main stylesheet
   ===========================================================================
   Zeitlos-scholarly design ("paper & ink"):

   - UI typeface: EB Garamond (variable), self-hosted (app/fonts/, OFL).
   - Church Slavonic text: class .cs — font stack 'MonomakhUnicode' first
     (Achim's reviewed font), 'BukyVede' as the FONT-FALLBACK (rescue tar;
     covers glyphs Monomakh may miss, e.g. titlo combinators), serif last.
   - Paper feel: background #faf8f3 (warm paper white), ink #2b2b2b.
   - Accent: dark red #8b2500 — chosen as a quiet, bookish accent (rubric
     red of early printed Cyrillic books); used sparingly (links, active
     tab, toggle focus).
   - Generous whitespace, single column on mobile.

   All fonts self-hosted; no CDN, no build chain.
   ======================================================================== */

/* -- Fonts ---------------------------------------------------------------- */

/* EB Garamond, variable weight (OFL; license: app/fonts/OFL-EBGaramond.txt) */
@font-face {
  font-family: 'EB Garamond';
  src: url('../fonts/EBGaramond-Variable.ttf') format('truetype-variations');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'EB Garamond';
  src: url('../fonts/EBGaramond-Italic-Variable.ttf') format('truetype-variations');
  font-weight: 400 800;
  font-style: italic;
  font-display: swap;
}

/* MonomakhUnicode — primary Church Slavonic face (license: Achim Rabus
   reviewed, cleared for VMČ; license file to follow before deployment). */
@font-face {
  font-family: 'MonomakhUnicode';
  src: url('../fonts/MonomakhUnicode-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* BukyVede — fallback Church Slavonic face (from the VMČ rescue tar;
   license to be clarified before deployment). All three cuts get their own
   @font-face so italic/bold synthesize correctly and the fallback stays
   visible in the font-check page. */
@font-face {
  font-family: 'BukyVede';
  src: url('../fonts/BukyVede-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'BukyVede';
  src: url('../fonts/BukyVede-Italic.ttf') format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'BukyVede';
  src: url('../fonts/BukyVede-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* -- Design tokens --------------------------------------------------------- */

:root {
  --paper: #faf8f3;
  --ink: #2b2b2b;
  --ink-soft: #5a5650;
  --accent: #8b2500;
  --accent-soft: #8b25001a;
  --hairline: #d8d2c4;
  --font-ui: 'EB Garamond', 'Times New Roman', serif;
  /* Church Slavonic face: BukyVede first, by decision (06.11.2026). It carries
     31 of the corpus's 33 combining marks; Monomakh carries 32 but is kept as the
     fallback. Neither has U+035B (COMBINING ZIGZAG ABOVE, 1 occurrence), which
     stays tofu — a documented data defect, see the font-check page. */
  --font-cs: 'BukyVede', 'MonomakhUnicode', serif;
  --maxw: 64rem;
}

/* -- Base ------------------------------------------------------------------ */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 1.125rem;
  line-height: 1.6;
  font-variation-settings: 'wght' 420;
}

/* Church Slavonic text — use everywhere Slavonic tokens are rendered. */
.cs {
  font-family: var(--font-cs);
  font-variation-settings: normal;
  line-height: 1.75;
}

a {
  color: var(--accent);
  text-underline-offset: 0.15em;
}

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

/* -- Layout ---------------------------------------------------------------- */

.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* -- Header ---------------------------------------------------------------- */

.site-header {
  border-bottom: 1px solid var(--hairline);
  padding: 2.5rem 0 1.5rem;
}

.site-header .masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}

.site-title {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.site-subtitle {
  margin: 0.25rem 0 0;
  color: var(--ink-soft);
  font-size: 1.05rem;
  font-style: italic;
}

/* Language toggle DE|EN */
.lang-toggle {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0.25rem 0.9rem;
  cursor: pointer;
  white-space: nowrap;
}

.lang-toggle:hover {
  background: var(--accent-soft);
}

.lang-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* -- Main / search / results ------------------------------------------------ */

main {
  padding: 2.5rem 0 3rem;
}

.search-section {
  margin-bottom: 2.5rem;
}

.mode-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 1.25rem;
}

.mode-tab {
  font: inherit;
  font-size: 1rem;
  color: var(--ink-soft);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.5rem 1.1rem;
  cursor: pointer;
}

.mode-tab[aria-selected='true'],
.mode-tab.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.mode-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.palette-button {
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.7rem;
  margin-left: auto;
  cursor: pointer;
}

.palette-button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.search-panel {
  min-height: 3.5rem; /* keeps the layout calm while the panel is a stub */
}

/* -- Search panel: forms, inputs, mode-specific layouts ---------------------- */

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.6rem;
}

/* Positioning context for the autocomplete dropdown: one per input. */
.search-field {
  position: relative;
  display: block;
  flex: 1 1 22rem;
  min-width: 0;
}

.search-input {
  /* `font: inherit` would reset font-family to the inherited EB Garamond and
     silently undo the `.cs` class on the same element (a shorthand always wins
     over the longhand it contains, regardless of source order). Church Slavonic
     combining marks — titlo, pokrytie — only exist in the Slavonic faces, so the
     field MUST carry --font-cs. */
  font-family: var(--font-cs);
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1.5;
  font-variation-settings: normal;
  color: var(--ink);
  background: #fffdf8;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.5rem 0.7rem;
  width: 100%;
  min-width: 0;
}

.search-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.search-input-expert {
  /* Monospace for the CQP syntax (alignment matters), with the Slavonic faces
     as a per-glyph fallback: Consolas/Cascadia lack all Cyrillic combining
     marks (titlo U+0483, pokrytie U+0487, the U+2DE0–U+2DFF block), so a query
     like [word="гл҃еть"] would be tofu without them. Monomakh carries every
     ASCII glyph too, so the fallback never changes how the syntax looks. */
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', 'MonomakhUnicode', 'BukyVede', monospace;
  font-size: 1rem;
  line-height: 1.5;
  resize: vertical;
  flex: 1 1 100%;
}

.search-run {
  font: inherit;
  font-size: 1rem;
  color: var(--paper);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0.5rem 1.4rem;
  cursor: pointer;
}

.search-run:hover {
  background: #6f1d00;
}

.search-run:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.search-hint {
  margin: 0.6rem 0 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-style: italic;
}

/* -- Advanced mode: rows ------------------------------------------------ */

.advanced-rows {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1 1 100%;
}

.advanced-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  border-left: 2px solid var(--hairline);
}

.advanced-row:focus-within {
  border-left-color: var(--accent);
}

.advanced-row .search-input {
  font-size: 1rem;
  padding: 0.35rem 0.5rem;
}

.advanced-row .search-field {
  flex: 1 1 12rem;
}

.advanced-row-index {
  color: var(--ink-soft);
  font-size: 0.85rem;
  min-width: 1.2em;
  text-align: right;
}

.advanced-sep {
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.advanced-distance {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.advanced-distance input {
  font: inherit;
  font-size: 0.9rem;
  width: 4rem;
  padding: 0.2rem 0.3rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: #fffdf8;
  color: var(--ink);
}

.advanced-remove {
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 2px;
  padding: 0 0.4rem;
  cursor: pointer;
}

.advanced-remove:hover {
  color: var(--accent);
  border-color: var(--hairline);
}

.advanced-add {
  font: inherit;
  font-size: 0.9rem;
  color: var(--accent);
  background: transparent;
  border: 1px dashed var(--hairline);
  border-radius: 2px;
  padding: 0.25rem 0.8rem;
  margin-top: 0.5rem;
  cursor: pointer;
}

.advanced-add:hover {
  border-color: var(--accent);
}

.advanced-preview-box {
  margin: 0.75rem 0 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.advanced-preview {
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--accent-soft);
  padding: 0.1rem 0.35rem;
  border-radius: 2px;
  word-break: break-word;
}

/* -- Query error (non-blocking, above the results) ------------------------ */

.query-error {
  border: 1px solid var(--accent);
  border-left-width: 4px;
  background: var(--accent-soft);
  color: var(--ink);
  padding: 0.6rem 1rem;
  margin: 0 0 1.5rem;
  font-size: 0.98rem;
}

.query-error[hidden] {
  display: none;
}

/* -- KWIC --------------------------------------------------------------- */

.kwic-count {
  margin: 0 0 0.75rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.kwic-empty {
  color: var(--ink-soft);
  font-style: italic;
}

.kwic-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--hairline);
}

.kwic-hit {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.3rem 0.4rem;
  border-bottom: 1px solid var(--hairline);
  cursor: pointer;
}

.kwic-hit:hover,
.kwic-hit:focus-visible {
  background: var(--accent-soft);
  outline: none;
}

.kwic-left {
  flex: 1 1 0;
  min-width: 0;
  text-align: right;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}

.kwic-right {
  flex: 1 1 0;
  min-width: 0;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}

.kwic-hit .hit {
  flex: 0 0 auto;
  max-width: 22rem;
  color: var(--accent);
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* Tokens that carry a grammatical annotation on hover.  The cue is deliberately
   quiet: a dotted underline that appears only when the pointer is over the word,
   so the reading line stays clean until someone asks for the tag. */
.kwic-token[title],
.reader-token[title] {
  cursor: help;
}

.kwic-token[title]:hover,
.reader-token[title]:hover {
  background: var(--accent-soft);
  box-shadow: 0 1px 0 0 var(--accent);
}

/* The left context keeps its right alignment even when split into spans. */
.kwic-left .kwic-token {
  white-space: pre-wrap;
}

.kwic-nr {
  flex: 0 0 auto;
  min-width: 2.5rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  font-size: 0.85em;
}

.kwic-pos {
  flex: 0 0 auto;
  color: var(--ink-soft);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  align-self: center;
}

.kwic-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1rem;
  font-size: 0.95rem;
}

.kwic-pager button {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.8rem;
  cursor: pointer;
}

.kwic-pager button:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.kwic-pager button:disabled {
  color: var(--hairline);
  cursor: default;
}

.kwic-page-label {
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.kwic-jump {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.kwic-jump-input {
  font: inherit;
  font-size: 0.9rem;
  width: 4.5rem;
  padding: 0.15rem 0.3rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: #fffdf8;
  color: var(--ink);
}

/* -- Context view ------------------------------------------------------- */

.context-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
  font-size: 0.95rem;
}

.context-back {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.8rem;
  cursor: pointer;
}

.context-back:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.context-window {
  color: var(--ink-soft);
  font-style: italic;
}

.context-body {
  font-size: 1.2rem;
  line-height: 1.95;
  max-width: 46rem;
}

.context-token {
  /* spacing comes from the text nodes between tokens */
}

.context-token.is-match {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  border-bottom: 2px solid var(--accent);
}

.structure-break {
  display: block;
  margin: 0.5rem 0 0.2rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--hairline);
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.4;
}

/* -- Autocomplete ------------------------------------------------------- */

.search-form,
.search-form-simple,
.search-form-expert {
  position: relative;
}

.autocomplete-list {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  min-width: 14rem;
  max-width: 26rem;
  max-height: 18rem;
  overflow-y: auto;
  margin: 0.15rem 0 0;
  padding: 0.25rem 0;
  list-style: none;
  background: #fffdf8;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  box-shadow: 0 6px 18px rgb(43 43 43 / 12%);
}

.autocomplete-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.2rem 0.7rem;
  cursor: pointer;
  font-size: 1.05rem;
}

.autocomplete-item:hover,
.autocomplete-item.is-active {
  background: var(--accent-soft);
}

.autocomplete-form {
  overflow-wrap: anywhere;
}

.autocomplete-freq {
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* -- Character palette -------------------------------------------------- */

.palette-anchor {
  position: relative;
  margin-left: auto;
}

.palette-popover {
  position: absolute;
  z-index: 30;
  top: calc(100% + 0.4rem);
  right: 0;
  width: min(26rem, 90vw);
  background: #fffdf8;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  box-shadow: 0 8px 24px rgb(43 43 43 / 14%);
  padding: 0.75rem;
}

.palette-title {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
}

.palette-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(2.4rem, 1fr));
  gap: 0.25rem;
}

.palette-char {
  font-size: 1.35rem;
  line-height: 1.2;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.15rem 0;
  cursor: pointer;
}

.palette-char:hover,
.palette-char:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}

.palette-hint {
  margin: 0.6rem 0 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
  line-height: 1.4;
}

.results-section {
  border-top: 1px solid var(--hairline);
  padding-top: 1.5rem;
}

.results-placeholder {
  color: var(--ink-soft);
  font-style: italic;
}

.results-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.results-header .results-placeholder {
  margin-bottom: 0.75rem;
}

.reader-open {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.9rem;
  cursor: pointer;
  white-space: nowrap;
}

.results-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
  align-items: baseline;
  margin-bottom: 0.75rem;
}

/* The statistics toggle borrows the reader button's shape; `is-active` marks the open
   panel, so the button state and the panel visibility never disagree. */
.stats-toggle {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.9rem;
  cursor: pointer;
  white-space: nowrap;
}

.stats-toggle:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.stats-toggle.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.stats-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The reader cannot open the panel (it shows one page, not the result set), so the button is
   disabled there rather than pretending to be clickable. Muted, not hidden: the control stays
   findable and its `title` explains why it is unavailable. */
.stats-toggle:disabled {
  color: var(--ink-soft);
  border-color: var(--hairline);
  background: transparent;
  cursor: not-allowed;
  opacity: 0.6;
}

.stats-toggle:disabled:hover {
  border-color: var(--hairline);
  background: transparent;
}

.reader-open:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.reader-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* -- Reading mode ---------------------------------------------------------- */

.reader-host {
  /* the reader replaces the result list, it does not sit next to it */
}

.reader {
  max-width: 60rem;
}

.reader-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.95rem;
}

.reader-bar button {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.2rem 0.8rem;
  cursor: pointer;
}

.reader-bar button:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.reader-bar button:disabled {
  color: var(--ink-soft);
  opacity: 0.45;
  cursor: default;
}

.reader-bar button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.reader-position {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.reader-range {
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.reader-columns {
  display: inline-flex;
  gap: 0.35rem;
  margin-left: auto;
}

.reader-jump {
  display: inline-flex;
  gap: 0.35rem;
  margin-left: auto;
}

.reader-jump-input {
  font: inherit;
  font-size: 0.9rem;
  width: 5.5rem;
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: #fffdf8;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.reader-notice {
  margin: 0.6rem 0 0;
  padding-left: 0.6rem;
  border-left: 2px solid var(--accent);
  color: var(--accent);
  font-size: 0.9rem;
  font-style: italic;
}

.reader-hits {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0.6rem 0 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.reader-hit-count {
  font-variant-numeric: tabular-nums;
}

.reader-back-link {
  color: var(--accent);
  cursor: pointer;
}

/* The page itself: columns side by side, each a narrow block of lines. */

.reader-page {
  display: flex;
  align-items: flex-start;
  gap: 2.5rem;
  margin: 1.25rem 0 1rem;
  padding: 1.25rem 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.reader-column {
  flex: 1 1 0;
  min-width: 0;
  max-width: 24rem;
  padding: 0.25rem 0.5rem;
  border-radius: 2px;
  transition: background 120ms ease-out;
}

.reader-column.is-active {
  background: #fffdf8;
  box-shadow: 0 0 0 1px var(--hairline);
}

.reader-lines {
  /* one row per line of the edition — the line breaks ARE the layout */
}

.reader-line {
  min-height: 1.6em;
  line-height: 1.75;
  overflow-wrap: anywhere;
}

.reader-line.is-empty {
  /* zero-width unit: a blank line of the edition, kept as vertical space */
  min-height: 0.9em;
}

.reader-token.cs {
  line-height: inherit;
}

.reader-token.hit {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  border-bottom: 2px solid var(--accent);
}

.reader-token.is-anchor {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* The `line=` anchor: the row the link names, marked with a quiet rubric-red rule on
   the left so it reads as a margin mark, not as a selection. */
.reader-line.is-anchor-line {
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  padding-left: 0.35rem;
  margin-left: -0.35rem;
}

.reader-shortcuts {
  margin: 0.75rem 0 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.reader-empty {
  color: var(--ink-soft);
  font-style: italic;
}

/* A KWIC hit's page label doubles as the reader entry point. The label stays a
   plain span (the <li> is the button, so a nested button would confuse screen
   readers); the item's own focus ring shows when the row is keyboard-focused. */

.kwic-pos.is-link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
}

.kwic-pos.is-link:hover,
.kwic-hit:focus-visible .kwic-pos.is-link {
  background: var(--accent-soft);
  outline: none;
}

@media (max-width: 48rem) {
  .reader-page {
    flex-direction: column;
    gap: 1.25rem;
  }

  .reader-column {
    max-width: none;
    width: 100%;
  }

  .reader-jump,
  .reader-columns {
    margin-left: 0;
  }
}

/* -- Loading indicator ------------------------------------------------------ */

.loading-indicator {
  color: var(--ink-soft);
  font-style: italic;
}

.loading-indicator[hidden] {
  display: none;
}

.loading-indicator .spinner {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  border: 2px solid var(--hairline);
  border-top-color: var(--accent);
  border-radius: 50%;
  vertical-align: -0.1em;
  margin-right: 0.5em;
  animation: vmc-spin 0.9s linear infinite;
}

@keyframes vmc-spin {
  to {
    transform: rotate(360deg);
  }
}

.error-banner {
  border: 1px solid var(--accent);
  border-left-width: 4px;
  background: var(--accent-soft);
  color: var(--ink);
  padding: 0.75rem 1rem;
  margin: 1rem 0;
}

.error-banner[hidden] {
  display: none;
}

/* -- Export group (Task 15) ------------------------------------------------- */

/* Sits under the results header: a label, the three format buttons, the note that
   says the export is the RESULT SET and the live progress line. Muted and compact —
   the export is an aside to the results, not a second toolbar. */
.export-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.5rem;
  margin: 0 0 0.9rem;
  font-size: 0.95rem;
}

.export-title {
  color: var(--ink-soft);
  font-variant: small-caps;
  letter-spacing: 0.04em;
  margin-right: 0.15rem;
}

.export-button {
  font: inherit;
  font-size: 0.95rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.15rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
}

.export-button:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.export-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Disabled = no result set to export. Muted, not hidden: the control stays findable
   and its note explains the state. */
.export-button:disabled {
  color: var(--ink-soft);
  border-color: var(--hairline);
  background: transparent;
  cursor: not-allowed;
  opacity: 0.55;
}

.export-button[aria-busy="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.export-note {
  flex: 1 1 18rem;
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-style: italic;
}

.export-status {
  flex: 1 1 100%;
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.export-status[hidden] {
  display: none;
}

/* -- Statistics panel (Task 13) --------------------------------------------- */

.stats-host {
  margin-top: 1.5rem;
}

.stats {
  border-top: 1px solid var(--hairline);
  padding-top: 1rem;
}

.stats-title {
  font-size: 1.15rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
}

.stats-summary {
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
  margin: 0 0 1rem;
}

.stats-figure .stats-label {
  margin-right: 0.3rem;
}

.stats-figure .stats-value {
  color: var(--ink);
}

.stats-block {
  margin: 0 0 1.5rem;
}

.stats-heading {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
}

/* POS bars: pure CSS, one row per class. The track is the full width, the fill is the
   class's share of the matched tokens — no canvas, no chart library. */
.stats-bars {
  display: grid;
  gap: 0.2rem;
  max-width: 40rem;
}

.stats-bar-row {
  display: grid;
  grid-template-columns: 1.5rem 1fr auto;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.stats-bar-label {
  font-weight: 600;
  text-align: center;
}

.stats-bar-track {
  background: var(--hairline);
  height: 0.75rem;
  border-radius: 1px;
  overflow: hidden;
}

.stats-bar-fill {
  background: var(--accent);
  height: 100%;
  min-width: 1px;
}

.stats-bar-value {
  color: var(--ink-soft);
  white-space: nowrap;
}

.stats-table {
  border-collapse: collapse;
  width: 100%;
  max-width: 40rem;
  font-size: 0.95rem;
}

.stats-th {
  text-align: left;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--hairline);
  padding: 0.15rem 0.5rem 0.15rem 0;
}

.stats-row .stats-cell {
  padding: 0.1rem 0.5rem 0.1rem 0;
  border-bottom: 1px solid var(--hairline);
}

.stats-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.stats-copy {
  font: inherit;
  font-size: 0.85rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.1rem 0.7rem;
  margin-top: 0.4rem;
  cursor: pointer;
}

.stats-copy:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.stats-copy:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.stats-empty {
  color: var(--ink-soft);
  font-style: italic;
}

/* -- Collocations and n-grams (Task 14) -------------------------------------- */
/* Both are <details> sections: closed by default, so nothing is computed until the
   user opens them (see stats-panel.js). */

.stats-details {
  border-top: 1px solid var(--hairline);
  padding-top: 0.6rem;
}

.stats-details > summary.stats-heading {
  cursor: pointer;
  margin: 0;
  padding: 0.15rem 0;
  list-style-position: inside;
}

.stats-details > summary.stats-heading:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.stats-details[open] > summary.stats-heading {
  margin-bottom: 0.6rem;
}

.stats-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.1rem;
  margin: 0 0 0.7rem;
  font-size: 0.9rem;
}

.stats-control {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  color: var(--ink-soft);
}

.stats-control.is-inactive {
  opacity: 0.45;
}

.stats-select,
.stats-number {
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.05rem 0.3rem;
}

.stats-number {
  width: 3.5rem;
}

.stats-select:focus-visible,
.stats-number:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.stats-sort {
  display: inline-flex;
  gap: 0.25rem;
}

.stats-sort-button {
  font: inherit;
  font-size: 0.85rem;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.05rem 0.5rem;
  cursor: pointer;
}

.stats-sort-button:hover {
  border-color: var(--accent);
}

.stats-sort-button.is-active {
  color: var(--ink);
  background: var(--accent-soft);
  border-color: var(--accent);
}

.stats-sort-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.stats-caption {
  color: var(--ink-soft);
  font-size: 0.85rem;
  margin: 0.35rem 0 0;
}

.stats-caption-warn {
  font-style: italic;
}

/* The busy line (review finding 2): painted BEFORE the compute, so a 271–288 ms pass is
   visible as work rather than as a frozen control. `aria-busy` on the body carries the same
   state to a screen reader; the pulsing dot is the visual echo, and it stops (via
   prefers-reduced-motion) for users who ask for less motion. */
.stats-busy {
  color: var(--ink-soft);
  font-size: 0.85rem;
  margin: 0.35rem 0 0;
}

.stats-busy::after {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-left: 0.4rem;
  border-radius: 50%;
  background: var(--accent);
  animation: stats-busy-pulse 1s ease-in-out infinite;
}

@keyframes stats-busy-pulse {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .stats-busy::after { animation: none; opacity: 0.6; }
}

/* The collocation table has six columns; keep the numbers from wrapping so the
   direction column does not drift under the G² column on a narrow screen. */
.stats-colloc-table {
  max-width: 48rem;
}

/* -- Header nav (link to the info page) -------------------------------------- */

.site-nav {
  margin-left: auto;
}

/* Header right corner: the info link and the language toggle share one baseline.
   Flex with `align-items: center` fixes the drift that comes from mixing a text
   link with a bordered button. */
.header-actions {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-left: auto;
}

.header-actions .site-nav {
  margin-left: 0;
}

.site-nav-link {
  font-size: 0.95rem;
  color: var(--accent);
  text-decoration: none;
}

.site-nav-link:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.site-nav-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* -- Info page --------------------------------------------------------------- */

.info-main {
  max-width: 52rem;
}

.info-root {
  /* A calm reading column: the info page is prose, not a table. */
  max-width: 46rem;
}

.info-section {
  margin-bottom: 2.5rem;
}

.info-heading {
  margin: 0 0 0.75rem;
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 0.35rem;
}

.info-subheading {
  margin: 1.5rem 0 0.6rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.info-lede,
.info-body {
  margin: 0 0 0.75rem;
}

.info-work {
  margin: 0 0 0.9rem;
  font-size: 1.1rem;
}

.info-work-title {
  font-style: italic;
}

.info-work-alt {
  color: var(--ink-soft);
}

/* Definition list: label column stays narrow and quiet, value column carries the data. */
.info-dl {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  gap: 0.35rem 1.25rem;
  align-items: baseline;
}

.info-dt {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.info-dd {
  margin: 0;
  min-width: 0;
}

.info-dl-counts .info-dd {
  font-variant-numeric: tabular-nums;
}

.info-list {
  margin: 0;
  padding-left: 1.1rem;
}

.info-item {
  margin: 0 0 0.15rem;
}

.info-note {
  margin: 0.9rem 0 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-style: italic;
}

.info-link {
  color: var(--accent);
}

.info-back {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
}

/* Citation blocks: monospace, selectable, no horizontal page overflow. */
.citation-block {
  margin-bottom: 1.75rem;
}

.citation-text {
  margin: 0 0 0.6rem;
  padding: 0.85rem 1rem;
  background: #fffdf8;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--accent);
  border-radius: 2px;
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.92rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  /* The text must stay selectable: a copy button is a convenience, not the only way. */
  user-select: text;
}

.copy-button {
  font: inherit;
  font-size: 0.9rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0.2rem 0.85rem;
  cursor: pointer;
}

.copy-button:hover {
  background: var(--accent-soft);
}

.copy-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.copy-button[data-state='copied'] {
  color: var(--paper);
  background: var(--accent);
}

.copy-button[data-state='failed'] {
  color: var(--ink-soft);
  border-color: var(--hairline);
}

.copy-status {
  margin-left: 0.6rem;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

/* -- Footer ------------------------------------------------------------------ */

.site-footer {
  border-top: 1px solid var(--hairline);
  padding: 1.5rem 0 2.5rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.site-footer .footer-links {
  margin-top: 0.5rem;
}

.site-footer .footer-links a {
  margin-right: 1.25rem;
}

/* -- Responsive: single column on small screens ------------------------------ */

@media (max-width: 48rem) {
  body {
    font-size: 1.05rem;
  }

  .site-header {
    padding: 1.75rem 0 1.25rem;
  }

  .masthead {
    flex-direction: column;
    align-items: flex-start;
  }

  .mode-tabs {
    flex-wrap: wrap;
  }

  .palette-button {
    margin-left: 0;
  }

  .site-nav {
    margin-left: 0;
  }

  /* Stacked header: the action row starts at the left margin like the title. */
  .header-actions {
    margin-left: 0;
  }

  .kwic-hit {
    flex-wrap: wrap;
  }

  .kwic-left {
    text-align: left;
  }

  main {
    padding: 1.75rem 0 2rem;
  }

  /* One column: a narrow screen cannot afford a separate label column. */
  .info-dl {
    grid-template-columns: 1fr;
    gap: 0.1rem;
  }

  .info-dt {
    margin-top: 0.6rem;
  }

  .citation-text {
    font-size: 0.85rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .loading-indicator .spinner {
    animation: none;
  }
}

/* Spelling section: one block per rule, each with a heading and a paragraph. */
.info-spelling-item {
  margin: 0.9rem 0;
  padding-left: 0.9rem;
  border-left: 2px solid var(--accent-soft);
}

.info-subheading {
  font-family: 'EB Garamond', serif;
  font-size: 1.02rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
  color: var(--ink);
}
