/* The Lingo Press — New York Times style.
   Georgia for headlines and reading, a Helvetica small-caps voice for labels
   and controls, hairline grey rules instead of boxes, and the Times link blue
   (#326891). Flat: no rounded panels, no shadows. */
:root {
  --ink: #121212;
  --ink-soft: #333333;
  --ink-faint: #666666;
  --gray: #999999;
  --rule: #e2e2e2;
  --rule-dark: #dcdcdc;
  --blue: #326891;
  --blue-dark: #26537a;
  --red: #b42318;
  --saved: #fff2b0;
  --serif: Georgia, "Times New Roman", Times, "Noto Serif", serif;
  --sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--sans);
  background: #ffffff;
  color: var(--ink);
}

::selection {
  background: #dce9f5;
}

.container {
  max-width: 900px;
  margin: 0 auto;
  padding: 34px 20px 64px;
}

/* The nameplate: a centred serif title over a black hairline and a lighter
   rule, with the interface-language picker as the small line above it. */
.page-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  position: relative;
  padding-bottom: 16px;
  margin-bottom: 30px;
  border-bottom: 1px solid var(--ink);
}

.page-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  border-bottom: 1px solid var(--rule);
}

.page-header > div:first-child {
  order: 1;
}

.page-header .ui-language {
  order: 0;
}

h1 {
  margin: 0 0 8px;
  font-family: var(--serif);
  font-size: 46px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.subtitle {
  margin: 0;
  max-width: 58ch;
  color: var(--ink-faint);
  font-size: 15px;
  line-height: 1.5;
}

.page-header .subtitle {
  margin-bottom: 0;
}

.ui-language {
  width: auto;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}

.ui-language .field-label {
  margin: 0;
  color: var(--ink-faint);
  font-weight: 400;
  text-transform: none;
  font-size: 13px;
}

.ui-language select {
  width: auto;
  padding: 6px 9px;
  font-size: 13px;
}

/* No cards: the page is one column of sections divided by hairline rules. */
.card {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 28px 0;
  margin-bottom: 0;
  box-shadow: none;
}

.card + .card {
  border-top: 1px solid var(--rule);
}

/* The click-a-word callout: the page's one explanation of its own gesture,
   shown as a notice while the session's list is empty (js/vocabulary.js hides
   it once a word is saved). Flat like the rest — a tinted band under a blue
   rule, no rounded corners or shadow. */
.story-hint {
  margin: 0 0 20px;
  padding: 10px 12px;
  background: #eef4f9;
  border-left: 3px solid var(--blue);
  color: var(--blue-dark);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.55;
}

.story-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  margin-bottom: 18px;
}

.story-title {
  font-family: var(--serif);
  font-size: 32px;
  font-weight: 700;
  line-height: 1.12;
}

.level {
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 0;
  padding: 5px 9px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

.story-content {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.7;
}

.story-paragraph {
  margin: 0 0 18px;
}

.story-word {
  cursor: pointer;
  border-radius: 0;
  padding: 1px 2px;
  transition: background 0.15s;
}

.story-word:hover {
  background: #f7f7f7;
}

/* Every part of the token the pointer is over, lit at once — the same grey the
   plain hover gives a single word, spread over the expression it belongs to.
   Declared before .learning and .token-active so a saved or selected word keeps
   its stronger colour, exactly as the single-word hover does. */
.story-word.token-hover {
  background: #f7f7f7;
}

.story-word.learning {
  background: var(--saved);
}

/* The token the popup is showing. Its parts can sit far apart — a separable
   expression spans a whole sentence — so they are lit one by one, never as a
   range of text. */
.story-word.token-active {
  background: #dce9f5;
  outline: 1px solid var(--blue);
}

.story-word.learning.token-active {
  background: #ffe27a;
  outline: 1px solid #c99a2e;
}

.news-source {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  font-size: 13px;
  color: var(--ink-faint);
  line-height: 1.6;
}

.news-source a {
  color: var(--blue);
  text-decoration: underline;
  word-break: break-all;
}

/* The listening controls, between the story's heading and its text: the story
   on screen, read aloud by a voice the browser already has. js/speech.js hides
   the whole row when there is no story or no engine, and the buttons inside it
   when the language has no voice but the browser does. */
.story-player {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding: 12px 14px;
  background: #fafafa;
  border: 1px solid var(--rule);
  border-radius: 0;
}

/* The author rules above and below would otherwise win over the attribute. */
.story-player[hidden],
.story-player [hidden] {
  display: none;
}

.story-player #speechToggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* The headphones glyph that says the button is about listening. It takes the
   button's own colour and carries no text of its own, so the control's name is
   still the word beside it. */
.story-player #speechToggle .button-icon {
  display: block;
  flex-shrink: 0;
}

.story-player #speechRate {
  width: auto;
  padding: 8px 10px;
  font-size: 14px;
}

.story-player .field-help {
  margin-top: 0;
}

.story-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 24px;
}

/* The Times action voice: small, bold, upper-case sans on the link blue. */
button {
  border: none;
  border-radius: 3px;
  padding: 11px 18px;
  cursor: pointer;
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  background: var(--blue);
  color: #ffffff;
}

button:hover {
  background: var(--blue-dark);
}

button.secondary {
  background: #ffffff;
  border: 1px solid var(--blue);
  color: var(--blue);
}

button.secondary:hover {
  background: #f2f6f9;
}

button.danger {
  background: var(--red);
}

button.danger:hover {
  background: #901b12;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

button:focus-visible,
input:focus-visible,
select:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

.status {
  margin-top: 16px;
  padding: 10px 12px;
  border-radius: 0;
  display: none;
  font-size: 14px;
}

.status.error {
  display: block;
  background: #fbeae8;
  border-left: 3px solid var(--red);
  color: var(--red);
}

/* The wait after a click: a bar filling at the pace stories have actually taken
   in this browser. Decorative, so it has no text of its own — the status line
   above carries the wait in words. */
.load-progress {
  margin-top: 12px;
  height: 3px;
  border-radius: 0;
  background: var(--rule);
  overflow: hidden;
}

.load-progress-fill {
  height: 100%;
  width: 0;
  background: var(--blue);
  transition: width 120ms linear;
}

/* The kicker voice: small, upper-case sans. No letter-spacing, which would
   break the cursive joining of the Arabic interfaces this page ships. */
.field-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 8px;
}

textarea,
input,
select {
  width: 100%;
  border: 1px solid #cccccc;
  border-radius: 3px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  background: #ffffff;
}

textarea {
  min-height: 90px;
  resize: vertical;
}

select {
  cursor: pointer;
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--blue);
  outline: none;
  box-shadow: 0 0 0 1px var(--blue);
}

.field-help {
  margin-top: 6px;
  color: var(--ink-faint);
  font-size: 13px;
  line-height: 1.45;
}

.controls-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.radio-group {
  display: flex;
  gap: 24px;
  align-items: center;
  margin-top: 8px;
}

.radio-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 15px;
  user-select: none;
}

.radio-label input[type="radio"] {
  width: auto;
  margin: 0;
  cursor: pointer;
  accent-color: var(--blue);
}

.vocabulary-list {
  margin-top: 4px;
}

.vocabulary-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule);
}

.vocabulary-item:last-child {
  border-bottom: none;
}

.vocabulary-word {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 700;
}

/* One line per meaning, so a word met with two meanings shows both instead of
   overwriting the first. */
.vocabulary-meanings {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 3px;
}

.vocabulary-meaning {
  color: var(--ink-faint);
  font-size: 14px;
}

/* A kept word the model never explained. */
.vocabulary-meaning.missing {
  color: #a05a00;
  font-style: italic;
}

.vocabulary-delete {
  padding: 6px 10px;
  font-size: 11px;
}

.empty {
  color: var(--ink-faint);
  font-family: var(--serif);
  font-style: italic;
  margin: 0;
}

/* The section rule, set in black like the nameplate's. */
.vocabulary-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 15px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--ink);
}

.vocabulary-header h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: 23px;
}

.vocabulary-header button {
  flex-shrink: 0;
}

.vocabulary-tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  flex-shrink: 0;
}

/* The cross-device label reads as a sentence rather than a two-word action, so
   it wraps inside itself rather than pushing the row wider than the card. */
.cross-device-button {
  white-space: normal;
  text-align: left;
}

.word-order {
  width: 150px;
}

.word-order select {
  padding: 8px 10px;
  font-size: 14px;
}

/* The section kicker above a headline. */
.language-badge {
  display: inline-block;
  margin-bottom: 8px;
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

/* The word popup: a gloss and one decision, opened over the story by a click on
   a word. The backdrop covers the page, so the story behind the choice cannot
   be clicked while the popup is open. */
.popup-overlay {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(18, 18, 18, 0.5);
}

/* The attribute has to beat the flex display above, or a closed popup would
   still sit over the page. */
.popup-overlay[hidden] {
  display: none;
}

.popup {
  width: 100%;
  max-width: 380px;
  background: #ffffff;
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 24px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.28);
}

.popup-word {
  font-family: var(--serif);
  font-size: 28px;
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.popup-meaning-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 8px;
}

.popup-meaning {
  flex: 1;
  min-height: 26px;
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}

/* The thumbs-down sits beside the gloss and describes itself on hover. It is an
   icon button rather than a Times action, so it overrides the shared button
   voice down to a quiet square. */
.popup-flag {
  flex-shrink: 0;
  padding: 5px;
  line-height: 0;
  background: #ffffff;
  border: 1px solid var(--rule-dark);
  color: var(--ink-faint);
}

.popup-flag:hover {
  background: #f7f7f7;
  border-color: var(--rule);
  color: var(--ink);
}

.popup-flag.flagged {
  color: var(--red);
  border-color: var(--red);
}

.popup-flag-note {
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-faint);
}

.popup-actions {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}

.popup-actions button {
  flex: 1;
}

/* The cross-device popup: a private link and one decision. The title is a
   sentence, not a single token, so it is set smaller than a word's heading. */
.cross-device-title {
  font-size: 21px;
  line-height: 1.35;
}

.cross-device-text {
  margin: 12px 0 16px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.cross-device-link {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--rule-dark);
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--ink);
  background: #f7f7f7;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cross-device-note {
  margin: 12px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-faint);
}

.cross-device-status {
  margin-top: 12px;
  font-size: 13px;
  color: var(--ink-soft);
}

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

/* The review screen: a due word, its meaning and the sentence it was met in, and
   the four ratings. It shares the popup's frame and adds only the pieces the
   popup has no need for. */
.review-button {
  white-space: nowrap;
}

.review-popup {
  max-width: 460px;
}

.review-progress {
  margin-bottom: 14px;
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.review-prompt {
  color: var(--ink-faint);
  font-size: 14px;
}

.review-word {
  margin: 6px 0 12px;
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 700;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* The reveal: the one thing shown before the answer, so it reads as the next
   step rather than as a stray control beside the word. */
.review-reveal {
  display: block;
  width: 100%;
  margin-top: 4px;
}

/* `display: block` above would otherwise beat the browser's own `[hidden]` rule,
   so the button stayed on screen after it was hidden. Say it outright, as the
   popup overlay does. */
.review-reveal[hidden] {
  display: none;
}

.review-meaning {
  margin-top: 18px;
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}

/* The line the word was read in: quoted, quieter than the meaning, and set apart
   as the context it is rather than as a second definition. */
.review-sentence {
  margin-top: 12px;
  padding-left: 12px;
  border-left: 2px solid var(--rule-dark);
  font-style: italic;
  line-height: 1.5;
  color: var(--ink-faint);
  overflow-wrap: anywhere;
}

.review-ratings {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 22px;
}

.review-ratings button {
  padding: 10px 6px;
}

.review-empty {
  margin: 8px 0 4px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.review-next {
  margin: 0 0 4px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-faint);
}

@media (max-width: 650px) {
  h1 {
    font-size: 32px;
  }

  .page-header {
    align-items: stretch;
  }

  .page-header > div:first-child {
    order: 0;
  }

  .page-header .ui-language {
    order: -1;
    justify-content: center;
  }

  .ui-language {
    width: 100%;
  }

  .story-header {
    flex-direction: column;
  }

  .controls-grid {
    grid-template-columns: 1fr;
  }

  /* The Review button joined the word-order picker and Delete all; on a narrow
     screen the three wrap rather than run off the edge. */
  .vocabulary-tools {
    width: 100%;
    flex-wrap: wrap;
  }
}

/* The privacy policy: the app's reading column, set as a legal document rather
   than as a page of controls — one measure of serif text, section rules, and
   links in the Times blue. */
.legal {
  max-width: 720px;
}

.legal p,
.legal li {
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.65;
  color: var(--ink-soft);
}

.legal p {
  margin: 0 0 18px;
}

.legal ul {
  margin: 0 0 18px;
  padding-left: 24px;
}

.legal li {
  margin-bottom: 6px;
}

.legal a {
  color: var(--blue);
  text-decoration: underline;
}

.legal h2 {
  margin: 34px 0 16px;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 700;
  color: var(--ink);
}

.legal-header {
  padding-bottom: 16px;
  margin-bottom: 28px;
  border-bottom: 1px solid var(--ink);
}

.legal-header .legal-kicker {
  margin: 0 0 10px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.legal-header .legal-kicker a {
  color: var(--blue);
  text-decoration: none;
}

.legal-header .legal-kicker a:hover {
  text-decoration: underline;
}

.legal-header .updated {
  margin: 0;
  color: var(--ink-faint);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
}

.legal-footer {
  margin-top: 44px;
  padding-top: 18px;
  border-top: 1px solid var(--ink);
  font-size: 14px;
}

.legal-footer p {
  margin: 0 0 8px;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-faint);
}

.legal-footer p:last-child {
  margin-bottom: 0;
}

/* The app's own footer, which is how the privacy policy is reached. */
.page-footer {
  margin-top: 44px;
  padding-top: 18px;
  border-top: 1px solid var(--rule);
  font-size: 13px;
}

.page-footer a {
  color: var(--blue);
  text-decoration: underline;
}

.page-footer-contact {
  margin-left: 16px;
}
