[x-cloak] { display: none !important; }

/* Thin header — brand + tiny progress strip. Override Pico's generous
   nav padding so the chrome is as low as possible. Sticky so the
   sidebar toggle + chapter-position strip stay reachable while
   scrolling through long chapters. */
header.container {
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--pico-muted-border-color);
  margin-bottom: 0.5rem;
  position: sticky;
  top: 0;
  z-index: 90;
  background: var(--pico-background-color);
}
header.container nav {
  padding: 0;
  min-height: 0;
  /* Pico's nav defaults to space-between; with our single <ul> child
     the ul ends up flush-left. Override to center the ul horizontally
     inside the header strip. */
  justify-content: center;
}
header.container nav ul {
  margin: 0;
  padding: 0;
  /* Centered: brand + language pair + chapter-progress sit in the
     middle of the header strip. The sidebar toggle was moved to a
     fixed-position element on the left edge so it stays reachable
     and doesn't tug the rest of the header off-center. */
  justify-content: center;
  gap: 0.6rem;
}
header.container nav ul li {
  padding: 0.05rem 0;
}

header.container .brand {
  text-decoration: none;
}
header.container .brand strong {
  font-size: 1rem;
}
header.container .lang-pair small {
  color: var(--pico-muted-color);
  font-size: 0.8rem;
  white-space: nowrap;
}
/* Compact chapter-position indicator: "27/70" + a tiny progress bar.
   The bar is purely cosmetic — exact numbers are in the text. */
header.container .chapter-progress {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
header.container .chapter-progress small {
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--pico-muted-color);
}
header.container .chapter-progress progress {
  width: 80px;
  height: 5px;
  margin: 0;
}

/* Header "✓ Saved" badge — fades in briefly after every successful
   persistNow, fades out under JS control after SAVE_BADGE_MS. The
   transition only applies to the show direction (no exit animation)
   because x-show toggles `display: none`, which can't be transitioned. */
.save-indicator {
  color: var(--pico-color-green-600, #2c8c3a);
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: opacity 0.2s ease-in;
}

/* Apply rules — three-column grid: translation (left) | buttons
   (middle) | original (right). The translation column carries the
   current paragraph and, on diff rows, the suggestion stacked
   beneath it. The middle column holds the accept/reject buttons
   when a suggestion is pending and stays empty otherwise — its
   width is fixed so non-diff rows keep the same layout, just with
   nothing in the middle slot. */
.rules-view .rules-paragraphs {
  margin-top: 1rem;
  /* 3-col template: prose | icon-button column | prose. The middle
     column is just wide enough for a single ✓/✕ icon button (~2.5rem
     including padding), eaten symmetrically out of the two prose
     columns so they keep the editor's --split-pct ratio. */
  grid-template-columns:
    calc(var(--split-pct, 50%) - 1.5rem)
    2.5rem
    calc(100% - var(--split-pct, 50%) - 1.5rem);
}

/* Explicit column placement so non-diff rows (which only emit
   left + right + an empty middle marker) still land in cols 1
   and 3, leaving col 2 visually empty. */
.rules-view .rules-col-left  { grid-column: 1; }
.rules-view .rules-col-mid   { grid-column: 2; }
.rules-view .rules-col-mid-empty {
  grid-column: 2;
  /* Marker only — the empty middle column needs an explicit grid
     item so the next sibling lands in col 3 instead of col 2.
     Zero size so it doesn't shift the row vertically. */
  width: 0; height: 0; overflow: hidden;
}
.rules-view .rules-col-right { grid-column: 3; }

/* Left column wrap: current on top, suggestion stacked below it
   on diff rows. Spacing between is set by the suggestion's margin
   so non-diff rows don't get an extra gap. */
.rules-view .rules-wrap {
  display: flex;
  flex-direction: column;
}

/* Diff highlighting is intentionally restrained: text reads as
   prose, with just enough marking to spot the before-vs-after
   boundary. Current gets a thin red gutter; suggestion gets a
   thin yellow gutter. No fills — backgrounds drowned out short
   paragraphs and made the column look like an alert box. */
.rules-view .rules-pair.has-diff .rules-current {
  border-left: 3px solid var(--pico-color-red-400, #e58383);
  padding-left: 0.6rem;
}
.rules-view .rules-suggestion {
  margin-top: 0.6rem;
  border-left: 3px solid var(--pico-color-yellow-500, #d4a700);
  padding-left: 0.6rem;
  white-space: pre-wrap;
}

/* Buttons stack vertically inside the middle column so the
   column stays narrow regardless of label length. align-self:
   center on the col-mid item itself centers the button stack
   VERTICALLY in the row — so on diff rows they sit literally
   between the current (top of left col) and the suggestion
   (bottom of left col). Equi-width via column's fixed track +
   width: 100% on each button so labels never look ragged. */
.rules-view .rules-actions {
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  align-items: center;
  justify-content: center;
  padding: 0;
}
/* Square-ish icon buttons: just the symbol, no label, fixed width
   so accept and reject align vertically. Slightly larger font so
   the ✓ / ✕ glyphs are readable at this size. */
.rules-view .rules-actions button.tiny {
  width: 2rem;
  height: 1.7rem;
  padding: 0;
  font-size: 0.95rem;
  line-height: 1;
  margin: 0;
  min-height: 0;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Sidebar marker: tiny dot next to a chapter title when it has a
   pending Apply-rules pass. Lets the user spot pending work without
   clicking through every chapter. */
.rules-view .sidebar .rules-pending-mark {
  color: var(--pico-color-yellow-500, #d4a700);
  margin-left: 0.25rem;
  font-size: 0.7rem;
  vertical-align: super;
}
.rules-view article.warning {
  border-left: 4px solid var(--pico-color-yellow-500, #d4a700);
  background: var(--pico-color-yellow-50, #fffbe6);
  padding: 0.6rem 0.8rem;
  margin-top: 0.75rem;
}

/* Editor status bar — tiny, fixed at the bottom of the viewport,
   always visible while editing. Shows total chars / chars left /
   time left for the current chapter. Stays out of the way (low
   contrast, single line, narrow padding) so it doesn't crowd the
   editor; widens to full width so the readout is centred and
   doesn't shift when its numbers change. */
/* Apply-rules: floating "next suggestion" button. Sits in the
   bottom-right (just above the editor progress dial would be, but
   since the dial only shows in editor view, they don't collide).
   Primary-tinted so it stands out as a navigational action. */
.next-suggestion {
  position: fixed;
  right: 0.6rem;
  bottom: 0.6rem;
  z-index: 11;
  padding: 0.4rem 0.85rem;
  font-size: 0.8rem;
  line-height: 1.3;
  margin: 0;
  min-height: 0;
  width: auto;
  white-space: nowrap;
  border-radius: 4px;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.12));
}

/* Editor progress dial — fixed-position circular indicator, right
   edge of the viewport. Arc fills with chapter scroll progress;
   center text is the estimated minutes-until-finished. Hover for
   the full chars-left + rate breakdown via title attr. */
.progress-dial {
  position: fixed;
  right: 0.6rem;
  bottom: 0.6rem;
  width: 60px;
  height: 60px;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  font-variant-numeric: tabular-nums;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.08));
}
.progress-dial-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);   /* arc starts at 12 o'clock */
}
.progress-dial-track,
.progress-dial-arc {
  fill: var(--pico-background-color, #fff);
  stroke-width: 3;
}
.progress-dial-track {
  stroke: var(--pico-muted-border-color, #ddd);
}
.progress-dial-arc {
  stroke: var(--pico-primary, #4f46e5);
  stroke-linecap: round;
  transition: stroke-dasharray 0.18s ease-out;
}
.progress-dial-text {
  position: relative;
  z-index: 1;
  font-size: 0.78rem;
  color: var(--pico-color);
  text-align: center;
}

/* Header chars/min rolling-rate badge — sits next to the chapter count
   and the save indicator. Same tabular-nums treatment so the digits
   don't jump as the rate ticks up; muted so it reads as ambient info,
   not an alert. */
.rate-indicator {
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Stats view tables: dense, right-aligned numerics, the same chapter
   status dot the editor sidebar uses. Pico's default <table> styles are
   light-touch enough that we mostly just need the numeric alignment. */
.stats-view table { margin-bottom: 1.5rem; }
.stats-view td.num,
.stats-view th.num { text-align: right; font-variant-numeric: tabular-nums; }
.stats-view .stats-summary {
  margin-top: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--pico-muted-border-color, #ddd);
}

:root {
  --pico-font-size: 16px;
}

main.container-fluid { padding: 1rem 1.5rem; }

article[role="alert"] {
  border-left: 4px solid var(--pico-color-red-500);
  background: var(--pico-color-red-50);
  color: var(--pico-color-red-900);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.gloss-progress {
  margin-top: 0.75rem;
}
.gloss-progress small { opacity: 0.75; }
.gloss-progress progress {
  width: 100%;
  margin: 0.25rem 0 0;
}

article[role="alert"] .close {
  margin-left: auto;
  background: transparent;
  border: none;
  color: inherit;
  font-size: 1.25rem;
  cursor: pointer;
  padding: 0 0.5rem;
  width: auto;
}

/* ---------- editor layout ---------- */

.editor-grid {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 1rem;
  align-items: start;
}

.sidebar {
  position: sticky;
  top: 1rem;
  border-right: 1px solid var(--pico-muted-border-color);
  padding-right: 0.75rem;
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
}

.sidebar h4 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.55;
  margin: 0 0 0.4rem 0;
  padding-left: 0.5rem;
}

.sidebar ul.chapters {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem 0;
}

.sidebar ul.chapters li a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.4rem;
  padding: 0.18rem 0.5rem;
  border-radius: 3px;
  text-decoration: none;
  color: var(--pico-color);
  font-size: 0.78rem;
  line-height: 1.35;
}

.sidebar ul.chapters li a:hover { background: var(--pico-secondary-background); }
.sidebar ul.chapters li a.active { background: var(--pico-primary); color: var(--pico-primary-inverse); }
.sidebar ul.chapters li a.disabled { opacity: 0.45; pointer-events: none; }

.sidebar .chapter-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

/* Status as a small dot — pending = empty ring, translated = half opacity
   filled, accepted = fully filled. Inherits currentColor so it stays
   readable on the active (primary-background) row. */
.chapter-status {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  flex-shrink: 0;
  background: transparent;
  opacity: 0.6;
}
.chapter-status.translated {
  background: currentColor;
  opacity: 0.45;
}
.chapter-status.accepted {
  background: currentColor;
  opacity: 1;
}

/* Sidebar glossary — vertically stacked entries so each input gets the
   full sidebar width (the previous side-by-side table squeezed words to
   illegibility at 180px). Filtered to the current chapter's subset; the
   full Glossary view is for editing the rest. */
.sidebar details > summary { font-size: 0.85rem; }
.sidebar details .gloss-count {
  opacity: 0.55;
  font-weight: normal;
  margin-left: 0.3rem;
}
.sidebar .gloss-hint {
  font-size: 0.7rem;
  opacity: 0.55;
  margin: 0.3rem 0 0.5rem 0;
  line-height: 1.3;
}

/* "+ term" button on top — compact, full-width so it lines up
   with the filter input below it. */
.sidebar .gloss-add {
  width: 100%;
  margin: 0 0 0.4rem 0;
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
}

/* Live text filter — case-insensitive substring match over each
   entry's term / translation / notes / originalForm. Sits between
   the add-term button and the list. */
.sidebar .gloss-filter {
  width: 100%;
  margin: 0 0 0.5rem 0;
  padding: 0.2rem 0.4rem;
  font-size: 0.75rem;
  height: auto;
  min-height: 0;
  line-height: 1.4;
  border-radius: 2px;
}

.sidebar .gloss-mini {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0.4rem 0;
}

.sidebar .gloss-mini-entry {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-bottom: 0.45rem;
  border-bottom: 1px dotted var(--pico-muted-border-color);
}

.sidebar .gloss-mini input {
  width: 100%;
  font-size: 0.75rem;
  padding: 0.18rem 0.35rem;
  margin: 0;
  border: 1px solid var(--pico-muted-border-color);
  background: var(--pico-background-color);
  border-radius: 2px;
  height: auto;
  min-height: 0;
  line-height: 1.4;
}
/* Term + translation columns mirror the source / translation panes:
   term in muted (source-side), translation in default body color
   (translation-side) — same scheme as `.original` / `.translation`. */
.sidebar .gloss-mini input.gloss-mini-term {
  color: var(--pico-muted-color);
}
.sidebar .gloss-mini input.gloss-mini-trans {
  color: var(--pico-color);
}

.sidebar .gloss-mini button {
  margin-top: 0.4rem;
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
  width: auto;
}

/* ---------- A/B test view ---------- */

.abtest-running .ab-source {
  background: var(--pico-card-background-color);
  border-left: 3px solid var(--pico-muted-border-color);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}
.abtest-running .ab-source header { margin: 0 0 0.25rem 0; opacity: 0.6; }

.abtest-running .ab-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.abtest-running .ab-side {
  margin: 0;
  padding: 0.85rem 1rem;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 6px;
  background: transparent;
}
.abtest-running .ab-side header { margin: 0 0 0.4rem 0; }

.abtest-running .ab-text {
  white-space: pre-wrap;
  line-height: 1.55;
}
/* renderBlockMd splits source/A/B on blank lines into <p> elements;
   trim outer margins so the rendered block hugs the card padding. */
.abtest-running .ab-text > p { margin: 0 0 0.6em 0; }
.abtest-running .ab-text > p:last-child { margin-bottom: 0; }

.abtest-running .ab-buttons {
  margin-top: 1.25rem;
  display: flex;
  gap: 0.5rem;
  justify-content: center;
}
.abtest-running .ab-buttons button {
  flex: 1;
  max-width: 14rem;
}

.ab-reveal li { font-size: 0.85rem; line-height: 1.5; margin-bottom: 0.25rem; }

/* Bilingual setup: chapter-count mismatch warning. Pico's role="alert"
   defaults to error red; soften to amber for a non-blocking heads-up. */
article[role="alert"].warning {
  background: #fff8e1;
  border-color: #ffb74d;
  color: #855600;
}

@media (max-width: 700px) {
  .abtest-running .ab-pair { grid-template-columns: 1fr; }
}

/* Editor toolbar (chapter info + font-size selectors) sits above the
   paragraph grid. Flex row that wraps on narrow viewports. */
/* Chapter prev/next pair in the editor toolbar. Compact tiny buttons
   that sit on the left while the font-size controls float to the
   right (toolbar is space-between). */
.chapter-nav {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.chapter-nav button {
  padding: 0.15rem 0.55rem;
  font-size: 0.75rem;
  line-height: 1.4;
  margin: 0;
  min-height: 0;
  width: auto;
  white-space: nowrap;
}

.editor-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.4rem;
  flex-wrap: wrap;
}
.editor-toolbar .chapter-info { margin: 0; }
.font-size-controls {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}
.font-size-controls label {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  margin: 0;
  white-space: nowrap;
}
.font-size-controls select {
  margin: 0;
  padding: 0.15rem 0.4rem;
  font-size: 0.8rem;
  width: auto;
  min-width: 0;
  height: auto;
}
.font-size-controls small {
  color: var(--pico-muted-color);
  font-size: 0.72rem;
}

/* ---------- two-column paragraph editor ----------
   Reads like prose: no per-cell borders or backgrounds, no internal padding.
   Row-gap separates paragraphs visually; the boundary between the two columns
   is a draggable handle (.resize-handle) backed by --split-pct on this grid. */

.paragraphs {
  display: grid;
  grid-template-columns:
    calc(var(--split-pct, 50%) - 0.75rem)
    calc(100% - var(--split-pct, 50%) - 0.75rem);
  column-gap: 1.5rem;
  row-gap: 0.85rem;
  align-items: start;
  position: relative;
}

.original,
textarea.translation,
.translation.rendered {
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  font-family: var(--pico-font-family);
  line-height: 1.6;
  /* Justify paragraphs by width — both source and translation columns
     read as proper prose blocks instead of left-ragged lines. */
  text-align: justify;
  hyphens: auto;
}

.original {
  white-space: pre-wrap;
  color: var(--pico-muted-color);
  font-size: var(--original-font-size, 1rem);
}

textarea.translation,
.translation.rendered {
  font-size: var(--translation-font-size, 1.15rem);
}

textarea.translation {
  width: 100%;
  field-sizing: content;
  resize: none;
  overflow: hidden;
  color: var(--pico-color);
  /* No visible border by default — the textarea blends into prose.
     Focus shows a subtle outline so the editor knows what's active. */
}
textarea.translation:focus {
  outline: 1px solid var(--pico-primary);
  outline-offset: 4px;
}

/* Rendered-markdown view of a translation paragraph. Identical typography
   to the textarea so the swap on click is invisible (no layout jump).
   Click anywhere inside to switch to the textarea editor. */
.translation.rendered {
  width: 100%;
  white-space: pre-wrap;
  cursor: text;
  min-height: 1.6em;
  /* Subtle hover-focus on rendered paragraphs — the click target needs
     SOME visible affordance even before the user mouses over the
     hover-revealed retranslate buttons. Theme-neutral gray so it
     reads on both light and dark Pico themes. */
  border-radius: 3px;
  transition: background-color 0.12s ease;
}
.translation.rendered:hover {
  background-color: rgba(127, 127, 127, 0.07);
}
.translation.rendered em { font-style: italic; }
.translation.rendered strong { font-weight: 600; }
.translation-placeholder {
  color: var(--pico-muted-color);
  opacity: 0.45;
  font-style: italic;
}

/* Same rendered styling on the (read-only) original side: inherit prose
   look, just italic / bold get their HTML treatment instead of literal
   asterisks in the source. */
.original em { font-style: italic; }
.original strong { font-weight: 600; }

/* Title row — bigger and separated from the body, but still no boxes. */
.title-row {
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 0.75rem;
}
/* Title row colours inherit from the base .original / .translation
   rules: original-side title in muted (matches the source pane),
   translation-side title in the default color (matches the
   translation pane). No per-title-row color overrides. */
input.translation.title-row {
  font-size: 1.4rem;
  font-weight: 600;
  padding: 0;
  margin: 0;
  height: auto;
  min-height: 0;
  border: none;
  background: transparent;
}
input.translation.title-row:focus {
  outline: 1px solid var(--pico-primary);
  outline-offset: 4px;
}

/* Wraps the textarea + per-paragraph retranslate buttons; goes in the
   first grid column because `.pair` uses `display: contents`. */
.translation-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.paragraph-actions {
  display: flex;
  gap: 0.35rem;
  justify-content: flex-end;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}
.translation-wrap:hover .paragraph-actions,
.translation-wrap:focus-within .paragraph-actions {
  opacity: 1;
  pointer-events: auto;
}

.paragraph-actions button.tiny {
  padding: 0.1rem 0.45rem;
  font-size: 0.7rem;
  line-height: 1.4;
  margin: 0;
  min-height: 0;
  width: auto;
  background: transparent;
  color: var(--pico-muted-color);
  border: 1px solid var(--pico-muted-border-color);
}
.paragraph-actions button.tiny:hover:not(:disabled) {
  color: var(--pico-primary);
  border-color: var(--pico-primary);
  background: transparent;
}
.paragraph-actions button.tiny:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Drag handle for resizing the column split. Sits at the column boundary
   (left = --split-pct), absolutely positioned so it doesn't take a grid
   slot. Visible-but-faint by default; brightens on hover/active. */
.resize-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--split-pct, 50%);
  transform: translateX(-50%);
  width: 1.25rem;
  cursor: col-resize;
  z-index: 5;
  display: flex;
  align-items: stretch;
  justify-content: center;
  user-select: none;
}
.resize-handle::before {
  content: '';
  width: 1px;
  background: var(--pico-muted-border-color);
  opacity: 0.5;
  transition: opacity 0.15s, background 0.15s, width 0.15s;
}
.resize-handle:hover::before,
.resize-handle:active::before {
  width: 3px;
  background: var(--pico-primary);
  opacity: 0.7;
}

/* End-of-chapter action row: NOT sticky — surfaces only when the
   reader scrolls to the bottom of the chapter. Keeps the chapter
   reading experience uncluttered until a decision is needed. */
.editor-actions {
  margin-top: 1.5rem;
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  flex-wrap: wrap;
  padding: 1rem 0 2rem;
}

.editor-actions button { margin: 0; }

/* Project view — landing dashboard. Cards link to each section so
   the editor view can stay focused on the chapter being edited. */
.project-view hgroup p { color: var(--pico-muted-color); margin-top: 0.25rem; }
.project-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0 1.5rem;
}
.project-card {
  display: block;
  padding: 1rem;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 4px;
  text-decoration: none;
  color: var(--pico-color);
  transition: border-color 0.12s, background-color 0.12s;
}
.project-card:hover {
  border-color: var(--pico-primary);
  background-color: rgba(127, 127, 127, 0.04);
}
.project-card.disabled {
  opacity: 0.45;
  pointer-events: none;
}
.project-card strong { display: block; }
.project-card small {
  color: var(--pico-muted-color);
  display: block;
  font-size: 0.78rem;
  line-height: 1.5;
}

/* Section title that introduces a row of project cards (Pipeline /
   Tools). Small, muted; double-acts as a hierarchy hint. */
.project-section-title {
  margin: 0.5rem 0 0.4rem;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pico-muted-color);
}

/* Numbered step badge in the top-right of pipeline cards (1, 2, 3).
   When the step is `checked` (Alpine class on the card), the same
   slot becomes a green ✓ — bigger, brighter — to show "this stage
   is done" at a glance. */
.project-card .step-num {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--pico-muted-color);
  letter-spacing: 0;
}
.project-card.checked {
  border-color: var(--pico-color-green-300, #9bd3a4);
}
.project-card .check-mark {
  color: var(--pico-color-green-600, #2c8c3a);
  margin-right: 0.25rem;
}
.project-card { position: relative; }

/* Progress bar inside the Editor card (accepted / total). */
.project-card .step-progress {
  display: block;
  width: 100%;
  height: 4px;
  margin-top: 0.4rem;
}

/* Project-view chapter list. Wider than the old sidebar copy, so it
   flows in a multi-column grid; reuses the .sidebar ul.chapters li a
   visual styling for the rows themselves. */
.chapters.project-chapters {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.15rem 0.4rem;
}
.project-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
}
.project-actions .project-save {
  margin-left: auto;
}

/* Setup view's Import-project button — sits above the book-input
   block so the user can either paste fresh markdown or restore a
   previously exported project. */
.setup-import {
  margin: 0.5rem 0 1rem;
}

/* Tiny hint shown under the source textareas in Setup once they're
   locked (glossary already built). Same muted style as Pico's <small>
   but italic to flag it as a status note rather than a label. */
.readonly-hint {
  font-style: italic;
  color: var(--pico-muted-color);
}

/* Bottom of Setup. Red-tinted outline so the destructive action is
   unmistakable; not solid-filled so it doesn't look inviting to click. */
.setup-danger {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--pico-muted-border-color);
}
.setup-danger .danger-action {
  color: var(--pico-color-red-600, #c14040);
  border-color: var(--pico-color-red-300, #e8a4a4);
}
.setup-danger .danger-action:hover:not(:disabled) {
  background: var(--pico-color-red-50, #fff5f5);
  border-color: var(--pico-color-red-500, #d35454);
}

.translation-stats {
  margin: 1rem 0 0;
  font-size: 0.85rem;
  color: var(--pico-muted-color);
  text-align: right;
}

/* ---------- glossary table ---------- */

.gloss-table { overflow-x: auto; }
.gloss-table input { margin: 0; }

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

@media (max-width: 900px) {
  .editor-grid { grid-template-columns: 1fr; }
  .sidebar {
    position: static;
    border-right: none;
    border-bottom: 1px solid var(--pico-muted-border-color);
    padding: 0 0 0.75rem;
    max-height: none;
  }
  .paragraphs {
    grid-template-columns: 1fr;
    column-gap: 0;
    row-gap: 0.4rem;
  }
  .original {
    background: var(--pico-card-background-color);
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    margin-top: 0.4rem;
  }
  .resize-handle { display: none; }
}
