:root {
  --paper: #f7f2e8;
  --card: #fffdf8;
  --ink: #26211a;
  --muted: #8a8072;
  --accent: #9c4530;
  --accent-weak: #bd7f6a;
  --accent-deep: #5a2416;
  --accent-soft: #f4e4dd;
  --rule: #e3dac9;
  --truku: #14544a;
  --chip-tr-bg: #dcece6;  --chip-tr-fg: #14544a;
  --chip-fr-bg: #e5e9f4;  --chip-fr-fg: #3b4c7e;
  --chip-en-bg: #f4e4dd;  --chip-en-fg: #8e3a26;
  --chip-zh-bg: #f2ead2;  --chip-zh-fg: #7d621c;
  --shadow: 43, 38, 32;
  --weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='8'%3E%3Cpath d='M7 0l4 4-4 4-4-4z' fill='%239c4530'/%3E%3Cpath d='M21 0l4 4-4 4-4-4z' fill='%2314544a'/%3E%3C/svg%3E");
  --serif: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, "Noto Serif TC", serif;
  --sans: "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #1b1813;
    --card: #262119;
    --ink: #eae2d3;
    --muted: #9c9184;
    --accent: #d98a70;
    --accent-weak: #a4705f;
    --accent-deep: #c56a45;
    --accent-soft: #3a2b24;
    --rule: #3b342a;
    --truku: #86c7b6;
    --chip-tr-bg: #1e3d37;  --chip-tr-fg: #86c7b6;
    --chip-fr-bg: #2c3350;  --chip-fr-fg: #a9b8e8;
    --chip-en-bg: #43291f;  --chip-en-fg: #e8a488;
    --chip-zh-bg: #3d3319;  --chip-zh-fg: #d9bc6a;
    --shadow: 0, 0, 0;
    --weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='8'%3E%3Cpath d='M7 0l4 4-4 4-4-4z' fill='%23d98a70'/%3E%3Cpath d='M21 0l4 4-4 4-4-4z' fill='%2386c7b6'/%3E%3C/svg%3E");
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  line-height: 1.55;
}

header {
  background: var(--card);
  padding: 1.1rem 1rem 0;
  position: sticky;
  top: 0;
  z-index: 10;
  box-shadow: 0 1px 8px rgba(var(--shadow), 0.08);
}

.header-inner {
  max-width: 46rem;
  margin: 0 auto;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

h1 {
  margin: 0;
  font-size: 1.5rem;
  letter-spacing: 0.05em;
  font-variant: small-caps;
  font-weight: 600;
}

.title-block { cursor: pointer; }

.subtitle {
  margin: 0.1rem 0 0;
  color: var(--muted);
  font-size: 0.9rem;
  letter-spacing: 0.12em;
}

.header-buttons { display: flex; gap: 0.4rem; }

.icon-btn {
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink);
  border-radius: 50%;
  width: 2.2rem;
  height: 2.2rem;
  font-size: 1.05rem;
  cursor: pointer;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.icon-btn:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.search-wrap {
  max-width: 46rem;
  margin: 0.85rem auto 0;
  position: relative;
}
.search-wrap::before {
  content: "";
  position: absolute;
  left: 0.85rem;
  top: 50%;
  width: 1rem;
  height: 1rem;
  transform: translateY(-50%);
  background: currentColor;
  color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.2-4.2'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.2-4.2'/%3E%3C/svg%3E") no-repeat center / contain;
  pointer-events: none;
}

#search {
  width: 100%;
  font: inherit;
  font-size: 1.05rem;
  padding: 0.6rem 1rem 0.6rem 2.5rem;
  border: 1.5px solid var(--rule);
  border-radius: 2rem;
  background: var(--paper);
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
#search:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--card);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
#search::placeholder { color: var(--muted); opacity: 0.8; }

main {
  max-width: 46rem;
  margin: 1.3rem auto 2rem;
  padding: 0 1rem;
}

.entry {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 0.8rem;
  padding: 1.05rem 1.25rem;
  margin-bottom: 1rem;
  box-shadow: 0 1px 3px rgba(var(--shadow), 0.05);
  transition: box-shadow 0.18s, transform 0.18s, border-color 0.18s;
}
.entry:hover {
  box-shadow: 0 5px 18px rgba(var(--shadow), 0.1);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.hw-line { margin-bottom: 0.2rem; }

.hw {
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: 0.045em;
  color: var(--truku);
}

.tag {
  color: var(--muted);
  font-size: 0.82rem;
  margin-left: 0.35rem;
  font-family: var(--sans);
  letter-spacing: 0.03em;
}

.audio-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.55rem;
  height: 1.55rem;
  margin-left: 0.4rem;
  padding: 0;
  font-size: 0.8rem;
  line-height: 1;
  vertical-align: 0.1em;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.12s, background 0.12s, border-color 0.12s, transform 0.12s;
}
.audio-btn:hover { opacity: 1; background: var(--accent-soft); border-color: var(--accent); }
.audio-btn.playing {
  opacity: 1;
  background: var(--accent);
  border-color: var(--accent);
  animation: audio-pulse 1s ease-in-out infinite;
}
.example .truku .audio-btn { width: 1.35rem; height: 1.35rem; font-size: 0.72rem; }
@keyframes audio-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--shadow), 0.18); }
  50% { transform: scale(1.06); box-shadow: 0 0 0 4px rgba(var(--shadow), 0); }
}
@media (prefers-reduced-motion: reduce) {
  .audio-btn.playing { animation: none; }
}

/* A form list, so it takes the colour of the spelling it is written in — but
   italic, small and slightly faded so it still reads as secondary. */
.paradigm {
  color: var(--truku);
  opacity: 0.85;
  font-style: italic;
  font-size: 0.9rem;
  margin: 0.1rem 0 0.3rem;
}

.gloss { margin: 0.18rem 0; }

.lang-chip {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  border-radius: 0.3rem;
  padding: 0.1rem 0.38rem;
  margin-right: 0.45rem;
  vertical-align: 0.14em;
}
.lang-chip.tr { background: var(--chip-tr-bg); color: var(--chip-tr-fg); }
.lang-chip.fr { background: var(--chip-fr-bg); color: var(--chip-fr-fg); }
.lang-chip.en { background: var(--chip-en-bg); color: var(--chip-en-fg); }
.lang-chip.zh { background: var(--chip-zh-bg); color: var(--chip-zh-fg); }

.examples { margin: 0.55rem 0 0.2rem; padding-left: 0.2rem; }

.example {
  border-left: 3px solid var(--truku);
  border-radius: 0 0.4rem 0.4rem 0;
  background: rgba(var(--shadow), 0.025);
  padding: 0.35rem 0.6rem 0.35rem 0.75rem;
  margin: 0.5rem 0;
}

.example .truku {
  color: var(--truku);
  font-weight: 700;
}

.example .ex-gloss { margin: 0.08rem 0 0; font-size: 0.95rem; }

/* Every other sentence in the book that uses this entry's words. Closed by
   default: it is a reference apparatus, not part of the entry, and on his
   particles it runs to thousands of lines. */
.conc { margin: 0.85rem 0 0; }
.conc-head {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--muted);
  padding: 0.25rem 0;
  border-top: 1px dashed var(--rule);
  list-style: none;
}
.conc-head::-webkit-details-marker { display: none; }
.conc-head::before { content: "▸ "; }
.conc[open] > .conc-head::before { content: "▾ "; }
.conc-head:hover { color: var(--accent); }
.conc-row { border-left-color: var(--rule); }
.conc-src {
  margin: 0.2rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
  cursor: pointer;
}
.conc-src:hover { color: var(--accent); }
.conc-more { color: var(--muted); font-size: 0.82rem; margin: 0.5rem 0 0; }
/* A sentence hit: the query occurs in this entry's body and nowhere in its
   headword, forms or ° line, so the card carries the sentences and not the root.
   Flat, because it is a list of citations rather than an article. */
.loose-head {
  margin: 1.4rem 0 0.4rem;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.entry.loose { padding: 0.5rem 0.9rem; }
.entry.loose:hover { transform: none; box-shadow: none; }
.entry.loose .example:first-child { margin-top: 0; }
.loose-sub { font-style: italic; }
/* Which slot of the paradigm the rows under it belong to. Sits above the rows,
   not inside one, so it reads as a heading rather than as another example. */
.conc-form {
  margin: 0.75rem 0 0.3rem;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
}
.conc-form:first-child { margin-top: 0.2rem; }
.conc-form .fine { color: var(--muted); font-size: 0.8rem; }

.subentry {
  margin-top: 0.85rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--rule);
}

.sub-form {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--truku);
  letter-spacing: 0.03em;
}

/* Cross-reference stub: a derived form standing at its own alphabetical slot in
   an A–Z listing. Lighter than a real entry card — it points at the root. */
.entry.stub {
  padding: 0.6rem 1.25rem;
  margin-bottom: 0.55rem;
  background: transparent;
  border-style: dashed;
  cursor: pointer;
}
.entry.stub:hover { transform: none; box-shadow: none; background: var(--card); }

.stub-hw {
  font-size: 1.08rem;
  color: var(--truku);
}
.stub-parent { letter-spacing: 0.04em; }
.stub-gloss {
  margin: 0.1rem 0 0;
  font-size: 0.94rem;
  color: var(--muted);
}

/* A–Z index rows. A letter is a column of headwords to scan, not a stack of
   cards to read, so the card chrome comes off entirely and the rows are divided
   by a hairline instead — at S that is 690 lines where it used to be 225,000
   characters of full entries. A sub-form is indented under its root, which is the
   only thing distinguishing the two levels once both are one line. */
.letter-head {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  margin: 0 0 0.5rem;
  padding: 0 0.25rem 0.5rem;
  border-bottom: 2px solid var(--accent);
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--muted);
  letter-spacing: 0.03em;
}
.letter-head-l {
  font-family: var(--serif, inherit);
  font-size: 2.1rem;
  font-weight: 700;
  line-height: 1;
  color: var(--accent);
  letter-spacing: 0.04em;
}

.entry.stub.idx {
  padding: 0.42rem 0.55rem;
  margin-bottom: 0;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  box-shadow: none;
}
.entry.stub.idx:hover { background: var(--accent-soft); }
.entry.stub.idx .hw-line { margin-bottom: 0; }
.entry.stub.idx .stub-gloss { margin-top: 0.05rem; font-size: 0.88rem; }
.entry.stub.idx-sub { padding-left: 1.9rem; }
.entry.stub.idx-sub .stub-hw { font-size: 0.98rem; font-weight: 600; }
.entry.stub.idx-root .stub-hw { font-size: 1.12rem; }

/* Paradigm slots: a form he only ever LISTED, on a page we generated. It sits at
   the same indent as a sub-form because that is what it is — a derived form of
   the root above it — but everything on it that is ours rather than his is set
   in the editorial hand, and the row is marked so a reader scanning the column
   can tell a page he wrote from a page we built. */
.entry.stub.idx-slot { padding-left: 1.9rem; }
.entry.stub.idx-slot .stub-hw { font-size: 0.98rem; font-weight: 600; font-style: italic; }
.entry.slot .hw { font-style: italic; }
.slot-tag {
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px dashed var(--rule);
  border-radius: 0.6rem;
  padding: 0.08rem 0.45rem;
}
.slot-parent { cursor: pointer; }
.slot-parent:hover { color: var(--accent); }
/* A generated sense is never set like one of his definitions. */
.gloss.morph { font-style: italic; }
.morph-note {
  margin: 0.4rem 0 0.6rem;
  padding-left: 0.6rem;
  border-left: 2px solid var(--rule);
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.5;
}
/* A word that is only a paradigm slot still links, and the dotted underline says
   it goes somewhere thinner than an entry. */
.slot-link {
  cursor: pointer;
  border-bottom: 1px dotted var(--rule);
}
.slot-link:hover { border-bottom-color: var(--accent); }

/* A word he only ever used inside a sentence. The same editorial hand as a slot
   card, deliberately: both are pages we built, and a reader must be able to tell
   them from a page he wrote at a glance, without reading the note that says so.
   The link is dotted for the same reason — it goes somewhere thinner than an
   entry. Thinner still than a slot, in fact: this card carries no ° line, because
   there is none. */
.entry.word .hw { font-style: italic; }
.word-link {
  cursor: pointer;
  border-bottom: 1px dotted var(--rule);
}
.word-link:hover { border-bottom-color: var(--accent); }

/* Colour is the orthography on screen, not what is tappable. Pecoraro's spelling
   is green; modern spelling is brown, and that includes the § marker, the
   punctuation and an example's left rule, which belong to the mode rather than to
   any one word. A link is told apart by its underline, which darkens on hover.

   There are THREE states, because "we have a modern spelling for it" and "the
   modern spelling is a word anyone else writes" are different claims:

     deep brown  a modern source has this exact word — dictionary or spoken corpus
     darker      settled by its class instead: a name or a loan, which no Truku
                 wordlist was ever going to list (`w-cls`, always beside `w-mod`)
     pale brown  a curated table proposed it; no modern source has it
     green       nothing vouched for it, so the blind character rules ran

   Pale is not the same as wrong — most of it is regular morphology the modern
   dictionary happens not to list — but it is a proposal, not evidence, and the
   pale words plus the green ones are exactly what is left to verify. */
.tag .w-mod, .tag .w-unv, .tag .w-raw, .tag .w-cls,
.tag .crossref-link { color: var(--truku); }
body.spelling-modern .hw,
body.spelling-modern .sub-form,
body.spelling-modern .stub-hw,
body.spelling-modern .paradigm,
body.spelling-modern .example .truku,
body.spelling-modern .word-preview .wp-hw,
body.spelling-modern .tag .w-mod,
body.spelling-modern .tag .crossref-link { color: var(--accent); }
body.spelling-modern .example { border-left-color: var(--accent); }
body.spelling-modern .w-raw,
body.spelling-modern .tag .w-raw { color: var(--truku); }
body.spelling-modern .w-unv,
body.spelling-modern .tag .w-unv { color: var(--accent-weak); }

/* Settled by class, not by attestation: a personal name, or a Japanese or
   Chinese loan. It is dark — the spelling is not in doubt, and the span keeps
   `w-mod` so every dark count still counts it — but the evidence behind it is
   the register's silence rather than the register's word, and a deeper brown is
   how the page says which. Written after the `w-mod` rules and at the same
   specificity, so it wins by order wherever both apply. */
body.spelling-modern .w-cls,
body.spelling-modern .tag .w-cls,
body.spelling-modern .gloss .w-cls { color: var(--accent-deep); }

/* A Truku form cited inside a definition. It is a word, so it follows the word
   colours rather than the gloss's — green in Pecoraro's spelling, brown once it
   has a verified modern one, and still green inside a modern gloss when it has
   not. */
.gloss .w-mod, .gloss .w-unv, .gloss .w-raw, .gloss .w-cls,
.gloss .crossref-link { color: var(--truku); }
body.spelling-modern .gloss .w-mod,
body.spelling-modern .gloss .crossref-link { color: var(--accent); }
body.spelling-modern .gloss .w-unv { color: var(--accent-weak); }
body.spelling-modern .gloss .w-raw { color: var(--truku); }

/* A tier-X substitution: the brown word is not his, so his own word is shown
   beside it in green — the same green that means "Pecoraro's spelling"
   everywhere else. Smaller and lighter, because it is a disclosure, not a
   second headword. */
.w-orig, body.spelling-modern .w-orig, body.spelling-modern .tag .w-orig {
  color: var(--truku);
  font-size: 0.85em;
  font-weight: 400;
  opacity: 0.8;
}

/* The same disclosure pointing the other way (batch 203). On a wild-species card
   HIS word is the entry — it is settled by class, not overruled — and the modern
   register's different word for the same creature is the note. So the bracket
   holds a MODERN word here, and wears the modern colour, where .w-orig holds his
   and wears green. Same size and weight: both are disclosures, not headwords. */
.w-dict, body.spelling-modern .w-dict, body.spelling-modern .tag .w-dict {
  color: var(--accent-deep);
  font-size: 0.85em;
  font-weight: 400;
  opacity: 0.85;
}

/* vr. vl. var. R. — the editor speaking, not the language. They sit in the middle
   of a Truku line, so they must not wear either word colour: green would claim
   they are Truku we have yet to verify, brown that we have respelled them. Muted
   italic, the same hand a footnote is set in, and a tooltip that expands the
   abbreviation for readers who don't have his 1977 front matter. */
.meta-abbr {
  color: var(--muted);
  font-style: italic;
  font-weight: 400;
  font-size: 0.9em;
  cursor: help;
}
/* Only the ones that carry an explanation are tappable, and they say so with a
   dotted underline — a `title` is invisible on a phone, which is where most of
   these readers are. The prose branch (French remarks) has no data-abbr and so
   stays plain. */
.meta-abbr[data-abbr] {
  border-bottom: 1px dotted var(--muted);
  cursor: pointer;
}
.meta-abbr[data-abbr]:hover,
.meta-abbr[data-abbr]:focus { color: var(--accent); border-bottom-color: var(--accent); }
.wp-abbr-full { font-style: italic; }

.crossref-link {
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.15em;
  transition: text-decoration-color 0.15s;
}
.crossref-link:hover { text-decoration-color: var(--accent); }

/* A cross-reference whose target modernizes to this card's own headword. The link
   is real — it reaches a different entry — but printing the modern form would just
   repeat the headword, so the text stays in his spelling and is marked as his. */
.xref-his { font-style: italic; }
body.spelling-modern .tag .xref-his { color: var(--muted); }

.no-results {
  text-align: center;
  color: var(--muted);
  margin-top: 2.5rem;
}

footer {
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
  padding: 0 1rem 2rem;
}

/* ---- sheet (about / settings) ---- */
#sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 16, 12, 0.5);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 1rem;
  animation: backdrop-in 0.18s ease-out;
}
#sheet-backdrop.hidden { display: none; }

@keyframes backdrop-in { from { opacity: 0; } }
@keyframes sheet-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
}

#sheet {
  background: var(--card);
  border-radius: 1rem;
  max-width: 30rem;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  padding: 1.7rem 1.5rem 1.4rem;
  position: relative;
  box-shadow: 0 16px 48px rgba(var(--shadow), 0.3);
  animation: sheet-in 0.2s ease-out;
}

#sheet-close {
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
}

#sheet.wide { max-width: 42rem; }

#sheet h2 {
  margin: 0 0 0.7rem;
  font-size: 1.2rem;
  font-variant: small-caps;
  letter-spacing: 0.04em;
}

.intro-group {
  border-bottom: 1px solid var(--rule);
}
.intro-group:last-child { border-bottom: none; }
.intro-group summary {
  cursor: pointer;
  padding: 0.85rem 0.2rem;
  font-weight: 700;
  color: var(--accent);
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.intro-group summary::-webkit-details-marker { display: none; }
.intro-group summary::before {
  content: "▸";
  color: var(--muted);
  display: inline-block;
  transition: transform 0.15s;
}
.intro-group[open] summary::before { transform: rotate(90deg); }
.group-zh { color: var(--muted); font-weight: 400; font-size: 0.85rem; }
.intro-group-body { padding: 0 0.2rem 0.4rem; }

.intro-section {
  padding: 0.9rem 0;
  border-bottom: 1px dashed var(--rule);
}
.intro-section:last-child { border-bottom: none; }

.alphabet-index { padding: 0.5rem 0.2rem; }
.alphabet-hint { color: var(--muted); font-size: 0.9rem; margin: 0 0 0.9rem; }
.alphabet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(2.6rem, 1fr));
  gap: 0.5rem;
}
.alphabet-btn {
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-weight: 700;
  border-radius: 0.5rem;
  padding: 0.6rem 0;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.alphabet-btn:hover { background: var(--accent-soft); border-color: var(--accent); }
.random-btn {
  display: block;
  margin: 1.4rem auto 0;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  border-radius: 2rem;
  padding: 0.6rem 1.2rem;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.random-btn:hover { background: var(--accent-soft); border-color: var(--accent); }
.root-tag {
  font-family: var(--serif);
  font-size: 1rem;
  margin-left: 0.4rem;
}

/* √ ° § — the markers are the spelling switch, so they have to keep looking like
   markers: no button chrome, and they inherit the colour of the line they sit on
   (which is itself the colour of the current orthography). The only affordance is
   the pointer and a soft halo under the finger, because a marker that shouted
   "button" would clutter every example in the dictionary. */
.spell-toggle {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0 0.12em;
  margin: 0;
  border-radius: 3px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s, opacity 0.15s;
}
.spell-toggle:hover, .spell-toggle:focus-visible { background: var(--accent-soft); }
.spell-toggle:focus-visible { outline: 1px solid var(--accent); }
.spell-toggle:active { opacity: 0.5; }

.intro-image {
  display: block;
  max-width: 100%;
  margin: 0 auto 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 0.5rem;
}

.intro-block { margin: 0.5rem 0; }
.intro-block p { margin: 0.35rem 0; font-size: 0.95rem; }
/* A fixed square mount, because the cycle swaps one painting for another every
   five seconds and they are not one shape: 0.75 for the portrait against 1.78
   for the grave. Sized to the image, the sheet's whole text jumped each time.
   `contain` letterboxes rather than crops -- these are paintings, and a 4:3
   frame filled by `cover` would take the top off his head. */
.about-photo {
  display: block;
  width: 100%;
  max-width: 17rem;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  margin: 0.2rem auto 0.3rem;
  border-radius: 0.6rem;
  border: 1px solid var(--rule);
  background: var(--paper);
}
.photo-caption { text-align: center; margin: 0 0 0.8rem; }
#sheet p { margin: 0.5rem 0; font-size: 0.95rem; }
#sheet .fine { color: var(--muted); font-size: 0.85rem; }

.lang-option {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.2rem;
  border-bottom: 1px solid var(--rule);
  font-size: 1rem;
  cursor: pointer;
}
.lang-option:last-of-type { border-bottom: none; }
.lang-option input { width: 1.15rem; height: 1.15rem; accent-color: var(--accent); cursor: pointer; }
.lang-option .native { color: var(--muted); font-size: 0.85rem; margin-left: auto; }

.word-preview {
  position: fixed;
  z-index: 60;
  max-width: 19rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 0.6rem;
  padding: 0.6rem 0.75rem;
  box-shadow: 0 8px 24px rgba(var(--shadow), 0.2);
  pointer-events: none;
  font-family: var(--serif);
}
.word-preview.hidden { display: none; }
.word-preview .wp-hw {
  font-weight: 700;
  color: var(--truku);
  font-size: 1.05rem;
}
.word-preview .wp-parent {
  color: var(--muted);
  font-size: 0.8rem;
  font-family: var(--sans);
  margin-left: 0.35rem;
}
.word-preview .wp-gloss {
  margin: 0.3rem 0 0;
  font-size: 0.88rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.word-preview .wp-hint {
  margin: 0.4rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
  font-family: var(--sans);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

@media (hover: none) {
  .word-preview { display: none !important; }
  .entry:hover { transform: none; }
}

@media (max-width: 480px) {
  h1 { font-size: 1.25rem; }
  .entry { padding: 0.85rem 0.95rem; }
}

/* ============ Cover hero ============ */
#hero { position: relative; }

/* ---- HOME: the whole cover fills the screen, controls overlaid on it.
   Overlays are styled for the (always light) cover art, not the page theme. ---- */
/* Cover is phone-shaped (ratio ~0.56) with a flat cream border all around, so a
   single solid cream fills any letterbox and blends into the art seamlessly. */
body.home {
  overflow: hidden;
  min-height: 100vh;
  background: #f5e9d0;
}
body.home #results { display: none; }
body.home #btn-home { display: none; }
body.home #hero {
  position: relative;
  width: fit-content;
  margin: 0 auto;
  animation: hero-in 0.35s ease;
}
body.home #hero-cover {
  display: block;
  width: auto;
  height: auto;
  max-height: 100vh;
  max-width: 100vw;
}
@keyframes hero-in { from { opacity: 0; } }

/* icons — 📖 ⚙ ⓘ trio, top-right of the cover (🎲 and 🔤 live with the search) */
body.home .hero-tools {
  position: absolute;
  top: 33%;
  right: 3.5%;
  z-index: 3;
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: 0.3rem;
  padding: 0.4rem;
  background: rgba(247, 242, 232, 0.72);
  border-radius: 1.2rem;
  backdrop-filter: blur(2px);
}
body.home .hero-tools .icon-btn {
  width: 2.35rem;
  height: 2.35rem;
  font-size: 1.2rem;
  color: #3a3226;
  border-color: rgba(60, 50, 35, 0.25);
  background: rgba(255, 253, 248, 0.6);
}
body.home .hero-tools .icon-btn:hover,
body.home .hero-search .icon-btn:hover {
  background: #fff;
  border-color: var(--accent);
  transform: translateY(-1px);
}

/* search — 🎲 random and 🔤 A–Z, then the field, centred in the frond→hut gap */
body.home .hero-search {
  position: absolute;
  top: 44%;
  left: 5%;
  right: 5%;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
body.home .hero-search .icon-btn {
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.25rem;
  color: #3a3226;
  border-color: rgba(60, 50, 35, 0.35);
  background: rgba(247, 242, 232, 0.9);
  box-shadow: 0 3px 14px rgba(60, 50, 35, 0.22);
}
body.home .hero-search-label {
  flex: 0 0 auto;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1rem, 3.2vw, 1.55rem);
  color: #4a4335;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.65);
  white-space: nowrap;
  letter-spacing: 0.02em;
}
body.home .hero-search .search-wrap {
  flex: 0 1 auto;
  width: min(78%, 17rem);
  max-width: 78%;
  margin: 0;
}
body.home .hero-search #search {
  background: rgba(255, 253, 248, 0.95);
  color: #26211a;
  border-color: rgba(60, 50, 35, 0.35);
  box-shadow: 0 3px 14px rgba(60, 50, 35, 0.22);
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 1rem;
}
body.home .hero-search .search-wrap::before { color: #6a5f4d; }

/* ---- RESULTS: hero collapses to a compact sticky search bar ---- */
body:not(.home) #hero-cover,
body:not(.home) .hero-search-label { display: none; }
body:not(.home) #hero {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 46rem;
  margin: 0 auto;
  padding: 0.6rem 1rem;
  background: var(--card);
  box-shadow: 0 1px 8px rgba(var(--shadow), 0.08);
}
/* Back. The phone's own button walks the trail now, but the desktop and the
   standalone web app have none in reach, and a card opened from a slot link was
   the whole complaint. It appears only where it would do something: at the head
   of the trail there is nothing behind us, and a control that does nothing is
   worse than no control. */
#btn-back { display: none; }
body:not(.home).can-back #btn-back { display: inline-flex; flex: 0 0 auto; }
body:not(.home) #btn-home { flex: 0 0 auto; }
body:not(.home) .hero-search { flex: 1 1 auto; display: flex; align-items: center; gap: 0.4rem; }
body:not(.home) .hero-search .icon-btn { flex: 0 0 auto; }
body:not(.home) .hero-search .search-wrap { flex: 1 1 auto; margin: 0; max-width: none; }
body:not(.home) .hero-tools { flex: 0 0 auto; display: flex; gap: 0.35rem; }

/* sheet home icon (Intro / About only) */
#sheet-home {
  position: absolute;
  top: 0.7rem;
  right: 3.3rem;
  z-index: 2;
}
#sheet-home.hidden { display: none; }
