/* YoMiE core styles: tokens, base controls, sentence diagram, grammar points,
   dictionary senses and the review view. Shared by every host (extension panel, apps). */
:root {
  --ink: #1f2937;
  --muted: #5b6472;
  --line: #e5e7eb;
  --edge: #c4c9d1; /* outline of a quiet button: 1.55:1 on the panel ground (--line is 1.16:1) */
  --bg: #f6f7f9;
  --card: #ffffff;
  --card-edge: #d9dce1; /* a card's outline */
  --on-fill: #ffffff; /* letters on a filled badge or button (navy, a role colour) */
  --hover: #eceef2;
  --stop-bg: #fff7ed; /* a band for a stop that can be carried on (the limit, the AI down) */
  --out-bg: #fef2f2; /* a band for something used up */
  --S: #2563eb;
  --V: #dc2626;
  --O: #16a34a;
  --C: #d97706;
  --M: #6b7280;
  --J: #0f766e; /* conjunctions (J joins, j introduces a subordinate clause); not purple, which is position */
  /* Darker O / C / V for text and for badges with white letters (the light ones are under 4.5:1). */
  --O-dark: #15803d;
  --C-dark: #b45309;
  --V-dark: #b91c1c;
  --accent: #7c3aed; /* clause numbers and position (this page, this sentence) only */
  --accent-bg: #f5f1fe; /* the ground of the chosen sentence's row (this sentence's place) */
  --arc: #a855f7; /* dependency arcs: one neutral ink */
  --tree: #d1d5db; /* clause tree guide line */
  --guide: #7d8590; /* the outline's branch (└): 3:1 or more on every ground it sits on */
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Source Serif 4", Georgia, serif;
}
* {
  box-sizing: border-box;
}
button {
  font: inherit;
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  cursor: pointer;
  white-space: nowrap;
}
button.primary {
  background: var(--ink);
  color: var(--on-fill);
  border-color: var(--ink);
}
button.ghost {
  background: transparent;
}
button:disabled {
  opacity: 0.45;
  cursor: default;
}
.spinner {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--accent) 25%, var(--card));
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
/* How far a review session has got. It shows a fact, not a wait, so it never moves on its own
   (only the AI waits animate: spinner, ghost rows). */
.progress-track {
  position: relative;
  height: 4px;
  margin-top: 6px;
  border-radius: 2px;
  overflow: hidden;
  background: color-mix(in srgb, var(--accent) 12%, var(--card));
}
.progress-track i {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--accent);
  border-radius: 2px;
  transition: width 0.3s;
}
@keyframes shimmer {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spinner,
  .ghost-row::after {
    animation: none;
  }
  .progress-track i,
  .point,
  .diagram .scroll-wrap::before,
  .diagram .scroll-wrap::after {
    transition: none;
  }
}
.card {
  position: relative;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 12px;
  padding: 14px 14px 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07);
}
.card h2 {
  font-size: 11px;
  color: var(--muted);
  margin: 10px 0 6px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.card h2:first-child {
  margin-top: 0;
}
.card-head {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
/* The sentence screen's title row: "文の構造 SVC CEFR B2". */
.card-head.title-row h2 {
  margin: 0 2px 0 0;
}
.diagram {
  position: relative;
  margin: 6px 0 0;
}
.diagram .scroller {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 4px;
}
/* A tree wider than the panel says so: a scrollbar that stays visible (macOS hides idle
   ones), a fade on the side that has more, and a button to scroll right. */
.diagram .scroller::-webkit-scrollbar {
  height: 8px;
}
.diagram .scroller::-webkit-scrollbar-thumb {
  background: var(--edge);
  border-radius: 4px;
}
.diagram .scroller::-webkit-scrollbar-track {
  background: var(--bg);
  border-radius: 4px;
}
.diagram .scroll-wrap {
  position: relative;
}
.diagram .scroller:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.diagram .scroll-wrap::before,
.diagram .scroll-wrap::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 12px;
  width: 28px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 4;
}
.diagram .scroll-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--card), transparent);
}
.diagram .scroll-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--card), transparent);
}
.diagram .scroll-wrap.more-left::before,
.diagram .scroll-wrap.more-right::after {
  opacity: 1;
}
.diagram .scroll-more {
  display: none;
  position: absolute;
  right: 2px;
  top: 2px;
  z-index: 5;
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: 50%;
  font-size: 18px;
  line-height: 22px;
  color: var(--accent);
  background: var(--card);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}
.diagram .scroll-wrap.more-right .scroll-more {
  display: block;
}
.diagram svg {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
  overflow: visible;
  z-index: 3;
}
.diagram .canvas {
  position: relative;
  min-width: 100%;
}
/* The tree (案 B3) flows: rows, and under each row the frames of its clauses. */
.diagram:not(.fit) .canvas:has(> .main-label) {
  width: max-content;
  padding: 0 4px 6px 2px;
}
.diagram .hrow {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  white-space: nowrap;
}
.diagram .hrow.static {
  position: static;
  flex-wrap: wrap;
  row-gap: 34px;
  padding: 0 4px 4px;
}
/* The scrolling layout (the structure card, the site) keeps the row of roles on one line too. */
.diagram:not(.compact) .hrow.static {
  flex-wrap: nowrap;
}
.diagram .hrow.wrap {
  white-space: normal;
  flex-wrap: wrap;
  column-gap: 6px;
}
.diagram .hrow.wrap .box {
  max-width: 100%;
}
.diagram .hrow.wrap .box .en {
  white-space: normal;
}
/* A coordinated list ("A, B, or C") is one chunk and can run to a dozen words: where a row wraps
   (the phone's role row), wrap it inside its box. A fitted diagram lifts the cap (.diagram.fit
   below) and the scrolling tree keeps every box on one line (below). */
.diagram .box {
  max-width: 300px;
  min-width: 30px; /* a two-letter word ("if") still holds its role tab, which would reach the next box */
}
/* Only the cap wraps a box: a scrolling row never squeezes its boxes to fit the panel. */
.diagram .hrow:not(.wrap) .box {
  flex-shrink: 0;
}
.diagram .box .en,
.diagram .box .ja {
  white-space: normal;
}
/* The scrolling layouts (card, site, phone app) keep a box on one line, words and translation
   alike: the tree scrolls sideways instead. A row is placed past the canvas's current width, so
   without max-content it would shrink to the room left there while its boxes overflow it, and
   the dashed clause frame measured from the row would end inside a box. The phone's role row
   (basic, compact) still wraps, so its boxes keep the cap. */
.diagram:not(.fit) .hrow:not(.static) {
  width: max-content;
}
.diagram:not(.fit) .hrow:not(.static) .box,
.diagram:not(.compact) .hrow.static .box {
  max-width: none;
}
.diagram:not(.fit) .hrow:not(.static) .box :is(.en, .ja),
.diagram:not(.compact) .hrow.static .box :is(.en, .ja) {
  white-space: nowrap;
}
.diagram .original {
  margin: 6px 0 2px;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--bg);
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink);
  overflow-wrap: anywhere; /* a word longer than the line (a URL) breaks instead of widening the card */
}
.diagram .original .ohead {
  display: inline-block;
  width: 34px;
  text-align: center;
  font-family: -apple-system, "Hiragino Sans", sans-serif;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  border-radius: 5px;
  color: var(--muted);
  background: var(--line);
  margin-right: 8px;
  vertical-align: 2px;
}
.diagram .original .oc.sub {
  border-bottom: 2px solid color-mix(in srgb, var(--accent) 45%, var(--card));
  background: color-mix(in srgb, var(--accent) 6%, var(--card));
}
.diagram .original .oc.sub[data-num]::before {
  content: attr(data-num);
  color: var(--accent);
  font-family: -apple-system, "Hiragino Sans", sans-serif;
  font-size: 10px;
  font-weight: 700;
  margin-right: 2px;
  vertical-align: 2px;
}
.diagram .original .oja {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--line, #e5e7eb);
  font-family: -apple-system, "Hiragino Sans", sans-serif;
  font-size: 13px;
  line-height: 1.6;
}
.diagram .original .oc:hover {
  background: var(--hover);
}
/* A clause standing in its parent's row: a dashed frame with its role tab and its name. */
.diagram .slot {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 8px;
  min-height: 44px;
  padding: 2px 8px 4px;
  border: 1.5px dashed var(--accent);
  border-radius: 6px;
  background: var(--card);
  color: var(--accent);
}
/* Pressing the frame brings the clause's own frame into view. */
.diagram .slot[role="button"] {
  cursor: pointer;
}
.diagram .slot[role="button"]:hover {
  border-style: solid;
  background: color-mix(in srgb, var(--accent) 6%, var(--card));
}
.diagram .slot[role="button"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.diagram .groupbox.blk.flash {
  animation: ym-frame-flash 1.2s ease-out;
}
@keyframes ym-frame-flash {
  0%,
  40% {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
  }
  100% {
    box-shadow: 0 0 0 2px transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .diagram .groupbox.blk.flash {
    animation: none;
    border-color: var(--accent);
  }
}
.diagram .slot .role {
  position: absolute;
  left: 6px;
  top: -9px;
  min-width: 16px;
  text-align: center;
  padding: 0 5px;
  border-radius: 4px;
  font-size: 10px;
  line-height: 15px;
  font-weight: 800;
  color: var(--on-fill);
  background: var(--cb, var(--c));
}
.diagram .slot.sub .role {
  font-weight: 600;
  color: var(--cb, var(--c));
  background: var(--card);
  border: 1px solid var(--cb, var(--c));
  line-height: 13px;
}
.diagram .slot .st {
  display: flex;
  align-items: center;
  gap: 4px;
  padding-top: 4px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.diagram .slot .num {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  color: var(--on-fill);
  background: var(--accent);
  font-size: 10px;
}
/* "of A and B" sharing one arc: a dashed box around the conjuncts, drawn over the row. */
.diagram .arcbox {
  position: absolute;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 45%, var(--card));
  border-radius: 8px;
  pointer-events: none;
}
/* The children of a row, side by side under it (one below the other where the tree fits). */
.diagram .kids {
  display: flex;
  align-items: flex-start;
}
.diagram.fit .kids {
  flex-direction: column;
  gap: 10px;
  padding-left: 18px;
}
.diagram .groupbox.blk {
  position: relative;
  z-index: 1;
  width: max-content;
  padding: 4px 8px 8px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 45%, var(--card));
  border-radius: 10px;
  background: var(--card);
}
.diagram.fit .groupbox.blk {
  box-sizing: border-box;
  width: auto;
  max-width: 100%;
}
/* A fitted tree breaks a word too long for its row (a URL) instead of growing past it. */
.diagram.fit .box :is(.en, .ja) {
  overflow-wrap: anywhere;
}
/* A parallel set: its clauses one below the other, a purple line on their left. */
.diagram .grp {
  margin: 4px 0 0 4px;
  padding-left: 10px;
  border-left: 2px solid var(--accent);
}
.diagram .mem + .mem {
  margin-top: 8px;
  padding-top: 4px;
  border-top: 1px dashed color-mix(in srgb, var(--accent) 25%, var(--card));
}
/* The main clause's M before its subject: a quieter lane above the row. */
.diagram .prefix {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  width: max-content;
  margin-bottom: 2px;
  padding-bottom: 4px;
  border-bottom: 1px dashed var(--edge);
}
.diagram.fit .prefix {
  flex-wrap: wrap;
  row-gap: 22px; /* a lead chunk's line passes between the lane's lines */
  width: auto;
}
.diagram .prefix-label {
  align-self: center;
  margin-top: 8px;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
}
/* An M (not a conjunction) is quieter than S V O C: no fill, a dashed underline, smaller words. */
.diagram .box.quiet {
  background: transparent;
  border-bottom-width: 2px;
  border-bottom-style: dashed;
  padding: 5px 4px 3px;
}
.diagram .box.quiet .en {
  font-size: 13px;
  color: var(--muted);
}
.diagram .box.quiet .ja {
  font-size: 10px;
}
.diagram .rlabel {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
  line-height: 1;
  margin: 2px 0 2px;
  cursor: help;
}
.diagram.fit .rlabel {
  flex-wrap: wrap;
  row-gap: 4px;
  white-space: normal;
}
/* The conjunction's kind beside a clause's name ("until 節 時"). */
.diagram .rlabel .ckind {
  padding: 0 3px;
  border-radius: 4px;
  border: 1px solid var(--J);
  background: var(--card);
  color: var(--J);
  line-height: 13px;
}
.diagram .rlabel .kind,
.diagram .rlabel .how,
.diagram .rlabel .omit {
  flex-shrink: 0;
}
/* The left-out introducing word ("(that) 省略"): quieter than the clause's name. */
.diagram .rlabel .omit,
.outline-omit {
  font-weight: 600;
  color: var(--muted);
}
.outline-omit {
  font-size: 11px;
  white-space: nowrap;
  flex: none;
}
.diagram .rlabel .num {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  color: var(--on-fill);
  background: var(--accent);
  font-size: 10px;
}
/* What the clause is to its parent, said once: "→ said の目的語". */
.diagram .rlabel .rel {
  color: var(--ink);
  font-weight: 700;
}
.diagram .rlabel .rel em {
  font-style: normal;
  color: var(--accent);
}
.diagram .box {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: 8px;
  padding: 5px 9px 4px;
  border-radius: 6px;
  border-bottom: 3px solid var(--c);
  background: color-mix(in srgb, var(--c) 8%, var(--card));
  cursor: default;
}
.diagram .box.sub {
  border-bottom-width: 2px;
  background: color-mix(in srgb, var(--c) 3%, var(--card));
}
.diagram .box .role {
  position: absolute;
  left: 6px;
  top: -9px;
  min-width: 16px;
  text-align: center;
  padding: 0 5px;
  border-radius: 4px;
  font-size: 10px;
  line-height: 15px;
  font-weight: 800;
  color: var(--on-fill);
  background: var(--cb, var(--c));
  letter-spacing: 0.05em;
}
.diagram .box.sub .role {
  font-weight: 600;
  color: var(--cb, var(--c));
  background: var(--card);
  border: 1px solid var(--cb, var(--c));
  line-height: 13px;
}
.diagram .box .en {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.3;
}
.diagram .box .en .w {
  border-radius: 3px;
}
.diagram .box .en .w:hover {
  background: var(--hover);
}
.diagram .box .ja {
  font-size: 11px;
  color: var(--muted);
  margin-top: 1px;
}
.diagram .box:hover {
  outline: 2px solid var(--accent);
}
.diagram text {
  font-size: 10px;
  fill: var(--arc);
  paint-order: stroke;
  stroke: var(--card);
  stroke-width: 3px;
}
.diagram path {
  fill: none;
  stroke: var(--arc);
  stroke-width: 1.6;
}
.diagram marker path {
  fill: var(--arc);
  stroke: none;
} /* the rule above would hollow the arrowhead */
.diagram path.coord {
  stroke-width: 1.4;
  stroke-linecap: round;
}
.diagram path.arrow {
  stroke: var(--arc);
  stroke-width: 1.6;
}
/* A conjunction (J, or j for one introducing a subordinate clause): the role tab "J" with the
   kind of link beside it ("J 逆接"), both above the box like any role tab. */
.diagram .box .tabs {
  position: absolute;
  left: 6px;
  top: -9px;
  display: flex;
  gap: 3px;
  white-space: nowrap;
}
.diagram .box .tabs .role {
  position: static;
}
.diagram .box .kind {
  padding: 0 4px;
  border-radius: 4px;
  border: 1px solid var(--J);
  background: var(--card);
  color: var(--J);
  font-size: 11px;
  font-weight: 700;
  line-height: 13px;
}
.point {
  padding: 8px 10px;
  margin: 6px 0;
  border-radius: 8px;
  background: var(--bg);
  transition: background 0.15s;
  cursor: default;
}
.point:hover {
  background: var(--hover);
}
.point .label {
  font-weight: 700;
}
.point .quote {
  font-family: var(--serif);
  font-size: 13px;
  color: var(--ink);
  margin-top: 2px;
}
.point .pattern {
  display: inline-block;
  margin: 4px 0 2px;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--card);
  font-size: 13px;
  font-weight: 600;
}
.point .text {
  font-size: 13px;
}
.point .example {
  margin-top: 4px;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--muted);
}
.point .example .exhead {
  font-family: -apple-system, "Hiragino Sans", sans-serif;
  font-size: 10px;
  font-weight: 700;
  margin-right: 6px;
  padding: 0 4px;
  border: 1px solid var(--line);
  border-radius: 4px;
}
.diagram .box.lit {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:is(.dict-tip, .lk-dict) .head {
  font-weight: 700;
  font-size: 14px;
}
:is(.dict-tip, .lk-dict) .muted {
  color: var(--muted);
  font-weight: normal;
  font-size: 11px;
}
/* How a headword was reached (← the word as written, 連語), as on the page's card. */
:is(.dict-tip, .lk-dict) .via {
  margin-left: 6px;
  color: var(--muted);
  font-weight: normal;
  font-size: 11px;
}
.dict-tip .entry + .entry {
  border-top: 1px dashed var(--line);
  margin-top: 8px;
  padding-top: 8px;
}
:is(.dict-tip, .lk-dict) .sense {
  margin: 2px 0 0;
  padding-left: 16px;
}
:is(.dict-tip, .lk-dict) .sense li {
  margin: 2px 0;
}
:is(.dict-tip, .lk-dict) .posblock {
  margin-top: 5px;
}
:is(.dict-tip, .lk-dict) .posrow {
  display: flex;
  align-items: baseline;
  gap: 6px;
  color: var(--muted);
}
:is(.dict-tip, .lk-dict) .pos {
  display: inline-block;
  padding: 0 5px;
  border-radius: 4px;
  background: var(--bg);
  color: var(--ink);
  font-size: 10px;
  font-weight: 700;
}
:is(.dict-tip, .lk-dict) .posblock.open .pos {
  background: var(--ink);
  color: var(--on-fill);
}
:is(.dict-tip, .lk-dict) .core {
  font-weight: 700;
  font-size: 13px;
}
:is(.dict-tip, .lk-dict) .syn {
  margin-left: 4px;
}
:is(.dict-tip, .lk-dict) .gloss,
.dict-tip .hint,
.dict-tip .note {
  margin-left: 5px;
  color: var(--muted);
  font-size: 11px;
}
:is(.dict-tip, .lk-dict) .note::before {
  content: "▸ ";
  color: var(--muted);
}
:is(.dict-tip, .lk-dict) .pat {
  display: inline-block;
  margin-left: 5px;
  padding: 0 5px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  color: var(--ink);
  font-size: 10px;
}
:is(.dict-tip, .lk-dict) .more {
  margin: 2px 0 0 16px;
  font-size: 10px;
  color: var(--muted);
}
.view .view-note {
  font-size: 11px;
  color: var(--muted);
  margin: 2px 0 8px;
}
/* A switch (履歴 ページ / 単語, 新しい順 / 回数順, the review list's filter): a grey track, the
   chosen part white with an --ink outline (DESIGN.md, 選択中の見せ方), never filled. */
.seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
}
.seg button {
  min-height: 26px;
  border: 1.5px solid transparent;
  border-radius: 6px;
  background: transparent;
  padding: 1px 8px;
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
}
.seg button.on {
  background: var(--card);
  border-color: var(--ink);
  color: var(--ink);
  font-weight: 600;
}
.lk-mean {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 4px;
}
.lk-src {
  display: block;
  margin-top: 1px;
  min-height: 24px; /* a link's target (DESIGN.md, ボタンの階層) */
  line-height: 24px;
  font-size: 11px;
  color: var(--muted);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lk-src:hover {
  color: var(--ink);
  text-decoration: underline;
}
.lk-dict {
  font-size: 12px;
  margin-bottom: 4px;
}
.rv-add {
  font-size: 11px;
}
/* 復習に追加 / 復習から外す: both names share one cell, so the button keeps one width */
[data-added] {
  display: inline-grid;
  place-items: center;
}
[data-added] > span {
  grid-area: 1 / 1;
}
[data-added] > .rv-other {
  visibility: hidden;
}
/* 始める前 (DESIGN.md, 復習タブ: 原文に塗る): the count, one line, 始める the full width */
.rv-today {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 24px 16px 20px;
  text-align: center;
}
/* the large count (DESIGN.md: 28 / 700) */
.rv-big {
  font-size: 28px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.rv-sub {
  font-size: 12px;
  color: var(--muted);
}
.rv-today > .primary {
  width: 100%;
  margin-top: 12px;
}
.rv-today > .rv-next,
.rv-today > .view-note {
  margin: 8px 0 0;
}
/* Broken at a phrase, not inside one (「単語」 split across lines at 320); elsewhere as before */
.rv-today > .view-note {
  word-break: auto-phrase;
}
/* 苦手な文法 on one line (only while there is any): its name, then the chips; more chips than fit
   scroll sideways in the line (ほか N shows them) */
.rv-weak {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
  min-width: 0;
}
.rv-weak[hidden] {
  display: none;
}
.rv-weak .rv-chips {
  flex: 1;
  min-width: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.rv-weak .rv-chip {
  flex: none;
  white-space: nowrap;
}
.rv-weak-h {
  flex: none;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}
.rv-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.rv-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  font-size: 12px;
  cursor: pointer;
}
.rv-chip b {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--on-fill);
  font-size: 11px;
  text-align: center;
}
.rv-chip:hover {
  border-color: var(--ink);
}
/* 今日の復習: the count, what it is, 始める; then what comes after, on one line */
.rv-sub-h::after {
  content: " · ";
}
.rv-sub-h {
  display: block;
}
.rv-next {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--muted);
}
.rv-chip[hidden] {
  display: none;
}
.rv-chip.more {
  padding: 4px 10px;
  color: var(--muted);
}
/* the review list, folded with <details> (open at first) */
/* the review list, folded behind a small heading (the other way in; a session does not need it) */
.rv-fold {
  position: relative;
  padding: 0 4px;
}
.rv-fold-h {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 30px;
  padding-right: 140px; /* the filter sits here, beside the summary */
  white-space: nowrap; /* 復習リスト is one word */
  list-style: none;
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}
.rv-fold-h::-webkit-details-marker {
  display: none;
}
.rv-fold-h::before {
  content: "▸";
  font-size: 11px;
}
.rv-fold[open] > .rv-fold-h::before {
  content: "▾";
}
.rv-fold-n {
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.rv-filter {
  position: absolute;
  top: 0;
  right: 4px;
}
.rv-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}
.rv-list .empty {
  font-size: 12px;
  color: var(--muted);
  padding: 8px 0;
}
/* one row per item: kind, the word (and its meaning) or the sentence on one line, 開いているページ,
   the day it comes back, and × (on hover or focus) */
.rv-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  border-top: 1px solid var(--line);
}
.rv-k {
  flex: none;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: var(--bg);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}
.rv-main {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rv-text {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--ink);
}
.rv-mean {
  margin-left: 6px;
  font-size: 12px;
  color: var(--muted);
}
/* A sentence in the list is a button to open it; it reads as the text, underlined on hover. */
button.rv-open {
  max-width: 100%;
  min-height: 24px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: none;
  overflow: hidden;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  line-height: 1.5;
  vertical-align: middle;
}
button.rv-open:hover {
  text-decoration: underline;
}
button.rv-open.word {
  font-size: 14px;
}
/* a sentence met on the page open now (pressing it opens it there): this page, in purple */
.rv-here {
  flex: none;
  padding: 0 5px;
  border-radius: 4px;
  background: var(--accent-bg);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.rv-due {
  flex: none;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
.rv-due:empty {
  display: none;
}
/* × 復習から外す: shown on the row under the pointer, and on the row holding the focus */
.rv-del {
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  opacity: 0;
}
.rv-item:hover .rv-del,
.rv-item:focus-within .rv-del {
  opacity: 1;
}
.rv-del:hover {
  background: var(--hover);
  color: var(--ink);
}
.rv-top {
  display: flex;
  align-items: center;
  gap: 8px;
}
.rv-title {
  flex: 1;
  font-weight: 700;
  font-size: 13px;
}
.rv-count {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* 答えを見る (the flip card): the word or the sentence large, no frame around it */
.rv-card {
  margin: 10px 0 14px;
}
.rv-word {
  font-family: var(--serif);
  font-size: 28px;
  font-weight: 600;
  color: var(--ink);
}
/* the review tab's cards, apart like every other card stack in the panel */
.rv {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.rv-ctx {
  margin-top: 10px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}
.rv-ctx mark,
.rv-card mark {
  background: color-mix(in srgb, var(--accent) 16%, var(--card));
  color: var(--ink);
  border-radius: 3px;
  padding: 0 1px;
}
.rv-sentence {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.75;
  color: var(--ink);
}
.rv-reveal {
  width: 100%;
  padding: 10px 0;
  font-size: 14px;
}
.rv-answer {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}
.rv-ja {
  font-size: 13px;
  line-height: 1.6;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--bg);
}
.rv-ja .ohead {
  display: inline-block;
  width: 34px;
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  border-radius: 5px;
  color: var(--muted);
  background: var(--line);
  margin-right: 8px;
}
.rv-grade {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.rv-grade button {
  padding: 10px 0;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.rv-miss {
  border: 1px solid color-mix(in srgb, var(--V) 45%, var(--card));
  background: var(--out-bg);
  color: var(--V-dark);
}
.rv-ok {
  border: 1px solid color-mix(in srgb, var(--O) 50%, var(--card));
  background: color-mix(in srgb, var(--O) 6%, var(--card));
  color: var(--O-dark);
}
.rv-finish {
  margin: 18px 0;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
}
/* 役割を当てる / 意味を当てる (review-view.ts renderRecall): the question on one line, the sentence
   large on the screen's own ground (no frame), the choices under it; no role colour for right /
   wrong, only lines and words. */
.rv-session .q {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  margin: 10px 0 12px;
}
.q-sent,
.rv-paint {
  font: 19px / 1.75 var(--serif);
  color: var(--ink);
  overflow-wrap: anywhere;
  margin: 0;
}
.q-sent .tgt {
  border: 1.5px dashed var(--ink);
  border-radius: 4px;
  padding: 0 3px;
  margin: 0 -3px;
}
/* The answered sentence (paintSentence): each chunk's role as the structure card's 文法ポイント
   mark (its colour 14% + an underline, .gp-mark) with its badge; the asked chunk ringed. */
.rv-paint .rv-role {
  padding: 1px 2px 0;
  border-bottom-width: 2.5px;
  border-radius: 3px 3px 0 0;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.rv-paint .rv-role.asked {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 3px;
}
.rv-paint .rv-role .outline-role {
  display: inline-block;
  font-size: 10px;
  line-height: 15px;
  margin-right: 4px;
  vertical-align: 2px;
}
.rv-paint .rv-role .outline-role.sub {
  line-height: 13px;
}
.rv-paint .w {
  border-radius: 3px;
}
.rv-paint .w:hover {
  background: var(--hover);
}
/* the word's answer: its part of speech as a small badge, then the meaning */
.rv-mean-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 15px;
  color: var(--ink);
}
.rv-mean-line .pos {
  flex: none;
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;
  padding: 0 5px;
  border-radius: 3px;
  background: var(--ink);
  color: var(--on-fill);
}
.rv-recall .rv-dock-ask {
  margin-top: 16px;
}
.rv-recall .answers {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
  margin-top: 10px;
}
.rv-recall .answers button {
  min-height: 40px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 6px 2px;
  font-size: 11px;
  color: var(--ink);
  border-color: var(--guide); /* 3:1 on the card: the badges are the answer buttons */
  white-space: normal;
}
/* 意味を当てる: the headword over its sentence, and three meanings one per row (they can be long) */
.rv-recall .q-word {
  font: 600 22px / 1.3 var(--serif);
  color: var(--ink);
  margin: 0 0 6px;
}
.rv-recall .answers.meanings {
  grid-template-columns: minmax(0, 1fr);
}
.rv-recall .answers.meanings button {
  flex-direction: row;
  justify-content: flex-start;
  gap: 8px;
  padding: 6px 10px;
  font-size: 13px;
  text-align: left;
}
.rv-recall .answers .num {
  flex: none;
  width: 22px;
  height: 22px;
  line-height: 20px;
  border: 1px solid var(--guide);
  border-radius: 5px;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}
.rv-recall .answers .outline-role {
  width: 22px;
  height: 22px;
  font-size: 13px;
  line-height: 22px;
  border-radius: 5px;
}
.rv-recall .answers button[aria-disabled="true"] {
  cursor: default;
}
.rv-recall .answers button.is-right {
  border: 2px solid var(--ink);
  font-weight: 700;
}
.rv-recall .answers button.is-wrong {
  border: 2px dashed var(--muted);
  color: var(--muted);
}
.verdict {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  border-radius: 10px;
  padding: 8px 12px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink);
}
.verdict.ok {
  background: var(--hover);
}
.verdict.ng {
  background: var(--stop-bg);
}
.verdict .mark {
  font-weight: 700;
  font-size: 15px;
}
.verdict > span:nth-child(2) {
  flex: 1 1 150px;
  min-width: 0;
}
.verdict .outline-role {
  display: inline-block;
  margin: 0 2px;
}
.verdict .when {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}
.rv-recall .rv-answer {
  margin: 10px 0 0;
}
.rv-recall .foot-row {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
}
.rv-recall .foot-row .primary {
  flex: 1;
  min-height: 34px;
}
.rv-recall button.link {
  border: 0;
  background: none;
  padding: 4px 2px;
  min-height: 24px;
  color: var(--ink);
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.rv-recall .kbdhint {
  font-size: 11px;
  color: var(--muted);
  margin: 6px 0 0;
}

/* The sentence view shared by the side panel and the structure card (sentence-view.ts):
   chips, ghost rows, key to the symbols, the button row and the unanalysed screens. */
.status {
  color: var(--muted);
  font-size: 12px;
}
.status.error {
  color: var(--V);
}
.deep-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  color: var(--accent);
}
.deep-chip .spinner {
  width: 10px;
  height: 10px;
}
.ghost-tree {
  display: grid;
  gap: 10px;
  margin: 4px 0 10px 12px;
  padding-left: 10px;
  border-left: 2px dashed color-mix(in srgb, var(--accent) 30%, var(--card));
}
.ghost-row {
  position: relative;
  height: 26px;
  border-radius: 8px;
  overflow: hidden;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 35%, var(--card));
  background: color-mix(in srgb, var(--accent) 5%, var(--card));
}
.ghost-row::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--card) 80%, transparent), transparent);
  animation: shimmer 1.2s linear infinite;
}
/* Waiting (DESIGN.md, 待っている間の表示). The pressed button says what is being done at once;
   its spinner and the ghost lines where the result will be fade in after 150ms (BUSY_DELAY_MS
   in sentence-view.ts), so a quick answer does not flash them. */
.busy-in {
  animation: busy-in 1ms 150ms both;
}
.spinner.busy-in {
  animation:
    busy-in 1ms 150ms both,
    spin 0.8s linear infinite;
}
@keyframes busy-in {
  from {
    visibility: hidden;
  }
  to {
    visibility: visible;
  }
}
button.busy {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
button.busy:disabled,
button.busy[aria-disabled="true"] {
  opacity: 1;
  color: var(--muted);
  cursor: default;
}
/* High contrast: the system draws every enabled button alike, so a waiting button kept focusable
   (aria-disabled, not disabled) would read as one that can be pressed. GrayText is its colour for
   disabled controls (button.busy too, to outweigh the muted colour above, which is forced away). */
@media (forced-colors: active) {
  button[aria-disabled="true"],
  button.busy[aria-disabled="true"] {
    color: GrayText;
    border-color: GrayText;
  }
}
button.busy .spinner,
.busy-note .spinner {
  flex: none;
  width: 12px;
  height: 12px;
}
.busy-note {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 12px;
}
.ghost-lines {
  display: grid;
  gap: 6px;
  margin-top: 6px;
}
.ghost-bar {
  position: relative;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: color-mix(in srgb, var(--accent) 10%, var(--card));
}
.ghost-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--card) 80%, transparent), transparent);
  animation: shimmer 1.2s linear infinite;
}
.ja-line.pending,
.oja.pending {
  display: flex;
  align-items: center;
}
.ja-line.pending .ghost-lines,
.oja.pending .ghost-lines {
  flex: 1;
  margin-top: 0;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* After the rules above, which it overrides: no shimmer, and no turning spinner (the words
   beside it say what is going on). The delay stays (it is not motion). */
@media (prefers-reduced-motion: reduce) {
  .ghost-row::after,
  .ghost-bar::after {
    animation: none;
  }
  .spinner.busy-in,
  .deep-chip .spinner {
    display: none;
  }
}
.badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg);
}
/* The sentence's conjunction after the pattern in the title row: "逆接 but". */
.conj-chip {
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  padding: 0 8px;
  border-radius: 999px;
  border: 1px solid var(--J);
  background: var(--card);
  color: var(--J);
  white-space: nowrap;
}
.conj-chip .conj-word {
  font-weight: 600;
}
.badge.strong {
  background: var(--ink);
  color: var(--on-fill);
  border-color: var(--ink);
}
.sentence-plain {
  font-size: 14px;
}
.unanalysed {
  display: grid;
  gap: 6px;
  justify-items: start;
  margin-top: 6px;
}
.unanalysed .note {
  margin: 0;
}
.note.subtle {
  font-size: 11px;
  opacity: 0.8;
}
.legend {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--muted);
}
.legend span {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.legend b.sub {
  background: var(--card);
  color: var(--cb, var(--c));
  border: 1px solid var(--cb, var(--c));
  font-weight: 600;
}
.legend .legend-sub {
  flex-basis: 100%;
  height: 0;
}
.legend b {
  display: inline-grid;
  place-items: center;
  min-width: 16px;
  height: 15px;
  padding: 0 3px;
  border-radius: 4px;
  background: var(--cb, var(--c));
  color: var(--on-fill);
  font-size: 10px;
  font-weight: 800;
}
.btn-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 6px;
  margin-top: 10px;
}
/* A sentence's actions (card, the panel's selected row) sit on the right, a wrapped line too. */
.btn-row.sentence-actions {
  justify-content: flex-end;
}
/* Only right after the buttons: a sentence without them (not analysed) keeps its error on the left. */
.btn-row.sentence-actions + .status.sentence-error {
  text-align: right;
}
.note {
  color: var(--muted);
  font-size: 12px;
}
/* The translation of a sentence shown as one row of roles (the clause tree has its own). */
.ja-line {
  margin: 2px 0 6px;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--bg);
  font-size: 13px;
  line-height: 1.6;
}
.ja-line .ohead {
  display: inline-block;
  width: 34px;
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  border-radius: 5px;
  color: var(--muted);
  background: var(--line);
  margin-right: 8px;
  vertical-align: 1px;
}

/* clause outline: one line per clause, always fits the screen (phones) */
.outline {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 6px 6px 4px;
  background: var(--card);
}
.outline-h {
  font-size: 11px;
  color: var(--muted);
  margin: 0 4px 2px;
}
/* A line that does not fit wraps: the role badges drop to a second line, on the right, so the
   target ("→ ①全体") is never cut. */
.outline-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  width: 100%;
  min-height: 32px;
  padding: 4px 6px;
  border: 0;
  border-radius: 7px;
  background: none;
  text-align: left;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}
.outline-line + .outline-line {
  border-top: 1px solid var(--line);
  border-radius: 0;
}
.outline-line.seen {
  background: color-mix(in srgb, var(--accent) 8%, var(--card));
  border-radius: 7px;
}
.outline-line:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.outline-branch {
  color: var(--guide);
  margin-right: -1px;
}
.outline .num {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-fill);
  font-size: 11px;
  font-weight: 700;
}
.outline-kind {
  font-weight: 600;
  white-space: nowrap;
}
.outline-target {
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;
  flex: none;
}
/* The kind of link after the target ("↔ ① 逆接"), in the conjunction's colour. */
.outline-conj {
  color: var(--J);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  flex: none;
}
.outline-roles {
  margin-left: auto;
  display: flex;
  gap: 2px;
  flex: none;
}
/* The pattern in the title row ("文の構造 SVC"): the outline's role badges side by side. */
.pattern-roles {
  display: inline-flex;
  gap: 2px;
  flex: none;
}
.outline-role {
  min-width: 16px;
  padding: 0 3px;
  border-radius: 4px;
  text-align: center;
  font-size: 11px;
  font-weight: 800;
  line-height: 16px;
  color: var(--on-fill);
  background: var(--cb, var(--c));
}
.outline-role.sub {
  color: var(--cb, var(--c));
  background: var(--card);
  border: 1px solid var(--cb, var(--c));
  line-height: 14px;
  font-weight: 600;
}
.diagram .hrow.flash .box {
  animation: ym-flash 1.2s ease-out;
}
@keyframes ym-flash {
  0%,
  40% {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  100% {
    outline: 2px solid transparent;
    outline-offset: 2px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .diagram .hrow.flash .box {
    animation: none;
    outline: 2px solid var(--accent);
  }
}

/* compact diagram for phones: smaller boxes and type, so more of the tree fits on screen */
.diagram.compact .hrow {
  gap: 4px;
}
.diagram.compact .hrow.wrap {
  column-gap: 4px;
}
.diagram.compact .box {
  padding: 4px 6px 3px;
  border-radius: 5px;
}
.diagram.compact .box {
  max-width: 200px;
}
/* A fitted diagram (panel, card) has no width cap on a box: it is as wide as its longer line,
   English or translation, and a box that does not fit moves to the next line whole. Only a box
   wider than its row wraps inside. */
.diagram.fit .box {
  max-width: 100%;
}
.diagram.compact .box .en {
  font-size: 13px;
  line-height: 1.25;
}
.diagram.compact .box .ja {
  font-size: 11px;
  margin-top: 0;
}
.diagram.compact .box .tabs {
  left: 5px;
  top: -8px;
}
.diagram.compact .box .role {
  left: 5px;
  top: -8px;
  font-size: 10px;
  line-height: 14px;
  padding: 0 4px;
}
.diagram.compact .box.sub .role {
  line-height: 12px;
}
.diagram.compact .slot {
  min-width: 22px;
  margin-top: 8px;
  font-size: 11px;
}
.diagram.compact .rlabel .num {
  width: 15px;
  height: 15px;
  font-size: 10px;
}
/* A number range ("②–④", a parallel set) is a pill, in the row's frame and its heading alike.
   After the round number's sizes above, which would otherwise cut it to "②". */
.diagram :is(.rlabel, .slot) .num.wide {
  width: auto;
  padding: 0 4px;
  border-radius: 8px;
}

/* Touch screens: hover highlights would stick after a tap, so they are off there. */
@media (hover: none) {
  .diagram .box:hover {
    outline: none;
  }
  .diagram .box .en .w:hover,
  .diagram .original .oc:hover {
    background: none;
  }
  .point:hover {
    background: var(--bg);
  }
}

/* ---------- undo after a delete: above the tab bar for a few seconds ---------- */
.undo-toast {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: var(--undo-bottom, 16px); /* a host with a bottom bar sets this */
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px 6px 12px;
  border-radius: 10px;
  background: var(--ink);
  color: var(--on-fill);
  font-size: 13px;
  box-shadow: 0 6px 20px rgba(15, 23, 42, 0.14);
}
.undo-toast span {
  flex: 1;
}
.undo-toast button {
  height: 28px;
  padding: 0 12px;
  border-color: transparent;
  background: transparent;
  color: var(--on-fill);
  font-weight: 600;
  text-decoration: underline;
}
.undo-toast button:focus-visible {
  outline-color: var(--on-fill);
}

/* 文法ポイント (the structure card's tab): the sentence with each point's words in its colour,
   then one line a point; a press opens the rest. Not the review's full card (.point alone). */
.gp-sentence {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.7;
  margin: 2px 0 8px;
}
.gp-mark {
  background: color-mix(in srgb, var(--pt) 14%, transparent);
  border-bottom: 2px solid var(--pt);
  border-radius: 2px;
}
.point.gp {
  margin: 0;
  padding: 0;
  background: none;
  border-radius: 0;
  border-top: 1px solid var(--line);
}
.point.gp:hover {
  background: none;
}
.point.gp .gp-head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  box-sizing: border-box;
  padding: 8px 2px;
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) {
  .point.gp .gp-head:hover {
    background: var(--bg);
  }
}
/* the whole row opens it: a › at the right end that turns down when open */
.point.gp .gp-chev {
  flex: none;
  align-self: center;
  width: 7px;
  height: 7px;
  margin: 0 6px 0 2px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform 0.15s;
}
.point.gp[open] > .gp-head .gp-chev {
  transform: rotate(45deg);
}
/* 解釈の注意 as the list's last quiet row: a small 注意 tag, the note only once opened */
.point.gp-caution .gp-words {
  color: var(--muted);
  font-size: 12px;
  align-self: center;
}
.point.gp .gp-tag {
  flex: none;
  align-self: center;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  color: var(--muted);
  border: 1px solid var(--line);
}
.point.gp-caution .gp-more {
  padding-left: 2px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}
.point.gp .gp-head::-webkit-details-marker {
  display: none;
}
.point.gp .gp-num {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--pt);
  color: var(--on-fill);
  font-size: 12px;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.point.gp .gp-words {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.point.gp .text {
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.point.gp[open] .text {
  white-space: normal;
}
.point.gp .gp-more {
  padding: 0 2px 10px 32px;
}
.point.gp .pattern {
  background: var(--bg);
}

/* AI に質問 (the structure card's tab) as a chat: bubbles oldest first, then the preset
   questions on one row and the field, kept at the foot of the pane. */
.ask {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.ask-log {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  padding-bottom: 8px;
}
.ask-foot {
  position: sticky;
  bottom: 0;
  padding-top: 6px;
  background: var(--card);
}
.presets {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
}
.presets::-webkit-scrollbar {
  display: none;
}
.chip-btn {
  flex: none;
  white-space: nowrap;
  font-size: 12px;
  padding: 4px 9px;
  border-radius: 999px;
}
.ask-form {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.ask-form input {
  flex: 1;
  min-width: 0;
  font: inherit;
  padding: 5px 10px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
}
.ask-form input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ask-form button {
  border-radius: 999px;
}
.qa {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.qa .q,
.qa .a {
  max-width: 85%;
  padding: 8px 12px;
  border-radius: 14px;
  font-size: 13px;
}
.qa .q {
  align-self: flex-end;
  background: var(--ink);
  color: var(--card);
}
.qa .a {
  align-self: flex-start;
  background: var(--bg);
  color: var(--ink);
}
.qa .a.error {
  color: var(--V);
}
