/*
 * language.css — the language layer's chrome.
 *
 * Two audiences, and they want opposite things. The panel, the word card and
 * the practice screen are application chrome and follow the app's theme. The
 * marks *inside* the book — translated paragraphs, underlined words, swapped
 * words — are injected into the book's own iframe by way of MARK_CSS below,
 * and have to work against eighteen reading themes and three skins without
 * being told which is active. So they use currentColor and opacity rather
 * than any colour of their own.
 */

/* ------------------------------------------------------------------ */
/* The word card                                                       */
/* ------------------------------------------------------------------ */

.word-card {
  position: fixed;
  z-index: 60;
  width: min(22rem, calc(100vw - 2rem));
  /* A long definition with an example sentence can outgrow a short window.
     Scrolling inside the card keeps its buttons reachable, which is the thing
     that was actually lost when it ran off the bottom of the screen. */
  max-height: calc(100dvh - 1rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.85rem 1rem 1rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  font-size: 0.95rem;
}

.word-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.word-title {
  font-size: 1.15rem;
  line-height: 1.2;
  margin-inline-end: auto;
}

.word-level,
.vocab-head .word-level {
  flex: none;
  align-self: center;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  opacity: 0.75;
}

.word-pos { margin: 0 0 0.2rem; font-style: italic; }
.word-def { margin: 0 0 0.4rem; }
.word-translation { margin: 0 0 0.4rem; font-weight: 600; }
/* Which language the translation is in, and the way to change it — quieter
   than the translation itself. */
.word-lang { font-weight: 400; }
.word-lang-hint { margin: 0 0 0.4rem; }
.word-card .btn-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-weight: 400;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.word-sentence,
.vocab-sentence,
.practice-sentence {
  margin: 0.5rem 0;
  padding-inline-start: 0.7rem;
  border-inline-start: 2px solid var(--line);
  font-style: italic;
  opacity: 0.85;
}

.word-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.7rem;
}

/* ------------------------------------------------------------------ */
/* The translation badge in the reader bar                             */
/* ------------------------------------------------------------------ */

.translate-flag {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex: none;
  padding: 0.18rem 0.55rem;
  margin-inline-end: 0.4rem;
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}

.translate-flag:hover { border-color: var(--accent); }

/* On a phone the bar has no room for "Spanish · translating…": the dot and the
   language say it, and the rest is in the Language panel a tap away. Without
   this the badge pushed Aa and full screen off the end of the bar. */
@media (max-width: 600px) {
  #translate-flag-state { display: none; }
  .translate-flag { margin-inline-end: 0; padding-inline: 0.4rem; max-width: 6.5rem; }
  #translate-flag-lang { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
/* The smallest phones: the dot alone. Its tooltip and the 文 panel say which
   language, and every button on the bar stays in reach. */
@media (max-width: 420px) {
  #translate-flag-lang { display: none; }
  .translate-flag { gap: 0; }
}

/* A dot rather than a spinner: e-paper mode disables animation entirely, and a
   spinner that cannot spin reads as a broken image. */
.translate-flag::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.45;
}

.translate-flag[data-state="working"]::before { opacity: 1; animation: lx-pulse 1.4s ease-in-out infinite; }
.translate-flag[data-state="waiting"]::before,
.translate-flag[data-state="error"]::before { opacity: 1; background: var(--danger, currentColor); }

.translate-flag-state { opacity: 0.7; }

@keyframes lx-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

[data-epaper="true"] .translate-flag::before { animation: none !important; }

/* ------------------------------------------------------------------ */
/* The language panel                                                  */
/* ------------------------------------------------------------------ */

.field-stack { display: grid; gap: 0.6rem; }

/* The on/off switch sits above the explanation, so it is the first thing read
   and the first thing reachable. */
.lang-toggle { margin-bottom: 0.6rem; }

.diag-dump {
  font-size: 0.75rem;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 12rem;
  overflow: auto;
  padding: 0.5rem;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}

.set-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.warn {
  padding: 0.5rem 0.7rem;
  border-inline-start: 3px solid var(--accent);
  background: var(--surface-2);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.9rem;
}

.glossary-list {
  display: grid;
  gap: 0.35rem;
  max-height: 16rem;
  overflow-y: auto;
  margin-top: 0.5rem;
}

.glossary-row {
  display: grid;
  grid-template-columns: minmax(5rem, 1fr) auto minmax(6rem, 1.2fr);
  align-items: center;
  gap: 0.4rem;
}

.glossary-source { font-weight: 600; }
.glossary-target { font-size: 0.9rem; padding: 0.2rem 0.4rem; }

/* ------------------------------------------------------------------ */
/* Vocabulary                                                          */
/* ------------------------------------------------------------------ */

.vocab-row {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line);
}

.vocab-main { flex: 1; min-width: 0; }

.vocab-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.2rem;
}

.vocab-head strong { font-size: 1.05rem; }
.vocab-def { margin: 0 0 0.2rem; }
.vocab-translation { margin: 0 0 0.2rem; font-weight: 600; }
.vocab-meta { font-size: 0.8rem; margin: 0.3rem 0 0; }

.vocab-actions {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: none;
}

/* ------------------------------------------------------------------ */
/* Practice                                                            */
/* ------------------------------------------------------------------ */

.practice-panel { display: flex; flex-direction: column; }

.practice-body {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  /* `safe`: centred when it fits, and starting from the top when it does not.
     Plain centring pushed a tall round off the top of a short screen, where
     scrolling cannot reach — the word being tested was the part cut off. */
  justify-content: safe center;
}

.practice-intro,
.practice-round { text-align: center; }

.practice-big {
  font-size: 1.6rem;
  line-height: 1.25;
  margin: 0.3rem 0 0.6rem;
}

.practice-meaning { font-size: 1.25rem; font-weight: 500; }
.practice-prompt { margin: 0 0 0.4rem; }
.practice-sentence { text-align: start; font-size: 1.05rem; }

.practice-options,
.practice-grades {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.8rem;
}

.practice-grades button {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
}

.practice-form {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.8rem;
}

.practice-form .input { flex: 1; }
.practice-speak { margin: 0.5rem 0; }

.was-right .practice-prompt { color: var(--ok, inherit); font-weight: 600; }
.was-wrong .practice-prompt { color: var(--danger, inherit); font-weight: 600; }

/* ------------------------------------------------------------------ */
/* Selection toolbar on generated text                                 */
/* ------------------------------------------------------------------ */

/*
 * A translated paragraph or a skin's abstract has no offsets in the author's
 * text, so there is nothing for a highlight to attach to. Copy still makes
 * perfect sense, so it is the one thing left standing.
 */
.sel-toolbar[data-mode="generated"] > *:not(.sel-copy) { display: none; }

/* ------------------------------------------------------------------ */
/* Inside the book                                                     */
/* ------------------------------------------------------------------ */

/*
 * The marks inside the book are NOT here. They are injected into the book's
 * iframe as `translate.BOOK_CSS` and `difficulty.BOOK_CSS`, the same way
 * annotate.js injects `MARK_CSS` and the skins inject their stylesheets,
 * because they style the book's markup rather than the app's chrome.
 *
 * They are also deliberately colourless. The book is being read under one of
 * eighteen themes and three skins, and a hard-coded blue that looks right on
 * paper is unreadable on the dark ones and invisible in e-paper mode.
 * currentColor with an opacity works everywhere and has to know nothing about
 * which theme is on.
 */
