:root {
  --bg: #f5f5f7; --card: #ffffff; --ink: #1d1d1f; --muted: #7a7a7a;
  --hair: #e0e0e0; --accent: #0071e3; --again: #d9564e; --good: #5a67d8;
  --easy: #34a853; --master: #8a8a8e;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; background: var(--bg); color: var(--ink);
  font-family: -apple-system, "SF Pro Text", "Helvetica Neue", "Hiragino Sans GB", sans-serif; }
#app { max-width: 720px; margin: 0 auto; padding: env(safe-area-inset-top) 16px 40px; }

.screen { padding-top: 12px; }
.screen.center { min-height: 80vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 16px; text-align: center; }
.topbar { display: flex; justify-content: space-between; align-items: center; padding: 6px 0 14px; }
.brand { font-size: 34px; margin: 0 0 8px; }
.brand-sm { font-weight: 600; }
h2 { font-size: 15px; color: var(--muted); font-weight: 600; margin: 22px 2px 10px; text-transform: none; }
.muted { color: var(--muted); }

.card-btn { width: 100%; display: flex; align-items: center; justify-content: space-between;
  background: var(--card); border: 1px solid var(--hair); border-radius: 18px;
  padding: 20px 22px; margin-bottom: 12px; cursor: pointer; font-size: 17px;
  color: var(--ink); text-align: left; transition: transform .06s ease; }
.card-btn:active { transform: scale(.99); }
.card-btn .big { font-weight: 600; }
.card-btn.pile { border-style: dashed; }
.pill { background: var(--bg); border-radius: 999px; padding: 5px 12px; font-size: 13px; color: var(--muted); white-space: nowrap; }
.empty { color: var(--muted); background: var(--card); border: 1px solid var(--hair);
  border-radius: 18px; padding: 20px; text-align: center; }

/* review — fixed-size flip card (same screen proportion on every device; never jumps) */
.review { display: flex; flex-direction: column; align-items: center; }
.progress { color: var(--muted); font-size: 14px; margin: 6px 0 14px; }
.flashcard { position: relative; width: min(92vw, 440px); aspect-ratio: 4 / 5; margin: 0 auto;
  perspective: 1200px; cursor: pointer; -webkit-user-select: none; user-select: none; }
.flip-inner { position: absolute; inset: 0; transform-style: preserve-3d;
  transition: transform .45s cubic-bezier(.2, .7, .2, 1); }
.flashcard.flipped .flip-inner { transform: rotateY(180deg); }
.face { position: absolute; inset: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden;
  background: var(--card); border: 1px solid var(--hair); border-radius: 22px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 30px; overflow: hidden; text-align: center; }
/* back: word+IPA header on top, definition/example left-aligned below */
.face.back { transform: rotateY(180deg); justify-content: flex-start; padding: 24px 26px; }
/* no mid-word break: a long single word overflows → fitFace shrinks it to one line;
   multi-word phrases still wrap at spaces */
.face .lemma { font-weight: 600; letter-spacing: -.01em; line-height: 1.15; word-break: keep-all; overflow-wrap: normal; }
.face .ipa { color: var(--muted); font-size: 20px; margin-top: 14px; }
.back .head { width: 100%; text-align: center; padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid var(--hair); }
.back .head .lemma-sm { font-weight: 600; letter-spacing: -.01em; font-size: 23px; word-break: keep-all; }
.back .head .ipa-sm { color: var(--muted); font-size: 15px; margin-top: 4px; }
.back .abody { align-self: stretch; text-align: left; }
.back .sec-label { font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: .6em; margin: 0 0 3px; }
.back .sec-label.def { color: var(--accent); }              /* Definition — blue */
.back .sec-label.ex { color: var(--easy); margin-top: .85em; }  /* Example — green */
.back .sec-label.src { color: #c77d00; margin-top: .85em; } /* Source — amber */
.back .sec-text { font-size: 1em; line-height: 1.5; white-space: pre-wrap; margin: 0; }
.back .sec-text.src-text { color: var(--muted); font-size: .92em; }
.hidden, .banner.hidden { display: none; }

.btn { border: none; border-radius: 14px; padding: 15px 20px; font-size: 16px; font-weight: 600;
  cursor: pointer; color: #fff; }
.btn:active { filter: brightness(.94); }
.btn.primary { background: var(--accent); }
.btn.ghost { background: var(--card); color: var(--accent); border: 1px solid var(--hair); }
.grades { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: min(92vw, 440px); margin-top: 18px; }
.btn.again { background: var(--again); } .btn.good { background: var(--good); }
.btn.easy { background: var(--easy); } .btn.master { background: var(--master); grid-column: 1 / -1; }
.link { background: none; border: none; color: var(--accent); font-size: 15px; cursor: pointer; }
.back { margin-top: 18px; }
.input { width: 100%; max-width: 320px; padding: 13px 15px; border: 1px solid var(--hair);
  border-radius: 12px; font-size: 16px; }
.done { font-size: 26px; font-weight: 600; }
.banner { background: #fff3cd; color: #664d03; border: 1px solid #ffe69c;
  border-radius: 12px; padding: 12px 16px; margin-bottom: 14px; text-align: center; }
@media (prefers-color-scheme: dark) {
  :root { --bg: #000; --card: #1c1c1e; --ink: #f5f5f7; --muted: #98989d; --hair: #2c2c2e; }
  .banner { background: #3a2e00; color: #ffe69c; border-color: #5a4a00; }
}

/* ── pile browse: ‹ › nav, 全部/複習中 toggle, 清單 view (2026-07-27) ── */
.rev-top { display: flex; justify-content: space-between; align-items: center;
  width: min(92vw, 440px); margin: 2px auto 6px; }
.seg { display: flex; background: var(--card); border: 1px solid var(--hair);
  border-radius: 10px; overflow: hidden; }
.seg-btn { border: none; background: none; padding: 7px 12px; font-size: 13px;
  color: var(--muted); cursor: pointer; }
.seg-btn.on { background: var(--accent); color: #fff; }
.toggle { border: 1px solid var(--hair); background: var(--card); color: var(--muted);
  border-radius: 999px; padding: 7px 12px; font-size: 13px; cursor: pointer; }
.toggle.on { border-color: var(--accent); color: var(--accent); font-weight: 600; }
/* gray = filter/opacity on the faces' CHILDREN: either property on the rotated
   .face itself is a grouping property that flattens preserve-3d → broken flip */
.flashcard.gray .face > * { filter: grayscale(1); opacity: .55; }
/* overlays the card's bottom padding (inside .card-wrap) — costs zero height,
   so the grade buttons sit right under the card like the main deck */
.status-note { position: absolute; left: 0; right: 0; bottom: 8px; z-index: 4;
  color: var(--muted); font-size: 13px; text-align: center; pointer-events: none; }
/* ‹ › on the card's edges: wrapper shrink-wraps to the card width, buttons are
   absolutely-positioned SIBLINGS of .flashcard (a tap never bubbles into a flip),
   overhanging 10px — a phone's 92vw card leaves only ~15px outside, so fully
   outside would overflow */
.card-wrap { position: relative; width: min(92vw, 440px); margin: 0 auto; }
.navbtn { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--hair);
  background: var(--card); color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .08); }
/* disabled arrows must not eat taps: without pointer-events none a disabled
   <button> still wins hit-testing and silently swallows the flip tap in its
   34px overlap band on the card edge */
.navbtn:disabled { opacity: .3; cursor: default; pointer-events: none; }
.navbtn.side { position: absolute; top: 50%; transform: translateY(-50%); z-index: 5; }
.navbtn.side.prev { left: -10px; }
.navbtn.side.next { right: -10px; }
/* pile cards only: widen face side-padding past the arrows' 34px inner reach so
   left-aligned back-face text never hides behind an opaque button (main-deck
   cards have no arrows → keep their original padding) */
.flashcard.with-nav .face { padding-left: 38px; padding-right: 38px; }
/* pile cards drag horizontally (tinder-style) — let the browser keep vertical */
.flashcard.with-nav { touch-action: pan-y; }
.flashcard.enter-right { animation: card-in-r .2s ease-out; }
.flashcard.enter-left { animation: card-in-l .2s ease-out; }
@keyframes card-in-r { from { transform: translateX(48px); opacity: .4; } to { transform: none; opacity: 1; } }
@keyframes card-in-l { from { transform: translateX(-48px); opacity: .4; } to { transform: none; opacity: 1; } }
.navpos { color: var(--muted); font-size: 13px; text-align: center; margin: 0 0 8px; }
.grades.off .btn { opacity: .35; pointer-events: none; }
.list { width: 100%; }
/* item = white card + action cluster OUTSIDE it on the page background */
.list-item { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
.list-row { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px;
  text-align: left; background: var(--card); border: 1px solid var(--hair);
  border-radius: 12px; padding: 12px 14px; cursor: pointer; font-size: 15px; color: var(--ink); }
.list-row.gray { opacity: .5; }
.list-main { flex: 1 1 auto; min-width: 0; }
.row-actions { display: grid; grid-template-columns: repeat(2, 34px); gap: 6px; flex: none; }
.rbtn { width: 34px; height: 34px; border-radius: 50%; border: none; padding: 0;
  font-size: 16px; line-height: 1; cursor: pointer; }
.rbtn.again { background: var(--again); } .rbtn.good { background: var(--good); }
.rbtn.easy { background: var(--easy); } .rbtn.master { background: var(--master); }
.rbtn:active { filter: brightness(.92); }
.row-actions.single { grid-template-columns: 34px; }
.rbtn.unmaster { background: var(--card); border: 1px solid var(--accent); }
/* card view: undo-畢業 row under the (disabled) grade buttons */
.unmaster-row { width: min(92vw, 440px); margin-top: 10px; display: grid; }
.btn.unmaster { background: var(--card); color: var(--accent); border: 1px solid var(--accent); }
.list-row .row-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.list-row .word-wrap { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
/* the word is the primary: the IPA shrinks/ellipsizes 8× more eagerly, so a
   long lemma stays whole and the IPA gives way first */
.list-row .word { font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; }
.list-row .row-ipa { color: var(--muted); font-size: 12px; white-space: nowrap;
  flex: 0 8 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.badge { font-size: 12px; color: var(--muted); white-space: nowrap; }
.badge.due-b { color: var(--accent); font-weight: 600; }
.badge.occ-b { color: var(--accent2, #b8842c); }   /* 出現次數（🔁 N 篇）chip */
.sort-toggle { display: block; margin: 6px 2px 0; font-size: 13px; }
/* full display, nothing cut off (owner ask): 中文 gloss = the scan anchor,
   english/extra + example wrap freely below it */
.list-row .row-zh { font-size: 14px; margin-top: 5px; line-height: 1.5; }
.list-row .row-def { color: var(--muted); font-size: 13px; line-height: 1.5; margin-top: 2px;
  white-space: pre-wrap; }
.list-row .row-ex { color: var(--muted); font-style: italic; font-size: 12.5px; margin-top: 4px;
  line-height: 1.45; }

/* ── source provenance meta row (2026-08-17) ── */
/* one muted line under the pile header: type icon · uploader · date · 原文 ↗ */
.pile-meta { color: var(--muted); font-size: 12.5px; text-align: center; margin: -6px 0 8px;
  max-width: min(92vw, 440px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meta-link { color: var(--accent); text-decoration: none; white-space: nowrap; }

/* ── 閱讀 view (2026-07-29) ── */
/* article typography: serif, book-ish measure — the point is comfortable reading */
.rv-wrap { width: 100%; max-width: 620px; margin: 4px auto 0; text-align: left;
  font-family: Georgia, "Times New Roman", "Songti TC", serif; }
.rv-head { margin: 10px 0 6px; }
.rv-title { font-size: 22px; font-weight: 700; line-height: 1.35; }
.rv-meta { color: var(--muted); font-size: 13px; margin-top: 4px;
  font-family: -apple-system, "SF Pro Text", sans-serif; }
.rv-p { font-size: 17.5px; line-height: 1.75; margin: 0 0 1.1em; }
/* carded terms: subtle dashed underline — reading first, decoration second */
.rv-term { border-bottom: 1px dashed rgba(0, 113, 227, .5); cursor: pointer; }
.rv-term.wait { border-bottom-color: rgba(122, 122, 122, .45); }
.rv-term.mst { border-bottom: none; }                /* mastered/unknown: plain but tappable */
.rv-mark { background: rgba(255, 214, 90, .45); border-radius: 3px; padding: 0 1px; cursor: pointer; }
/* 剛處理完（送出標記 → 建卡完成後的第一次閱讀）：綠底一次性 highlight，
   下次進來就回歸一般樣式 — 讓「這批剛變成卡」一眼可掃 */
.rv-term.fresh { background: rgba(52, 168, 83, .16); border-radius: 3px; padding: 0 1px; }
.rv-status { font-size: 13px; white-space: nowrap; }
/* floating ⭐ pill under the selection (iOS system menu sits above it) */
.pill-btn { position: fixed; z-index: 70; background: var(--accent); color: #fff; border: none;
  border-radius: 999px; padding: 9px 16px; font-size: 15px; font-weight: 600; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .22); }
/* bottom sheet card preview */
.sheet-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, .35); z-index: 80; }
.sheet { position: fixed; left: 0; right: 0; bottom: 0; max-width: 720px; margin: 0 auto;
  background: var(--card); border-radius: 18px 18px 0 0; padding: 22px 24px calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -6px 30px rgba(0, 0, 0, .18); }
.sheet-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.sheet-word { font-size: 22px; font-weight: 700; }
.sheet-ipa { color: var(--muted); font-size: 14px; }
.sheet-badge { color: var(--muted); font-size: 13px; margin-bottom: 8px; }
.sheet-def { font-size: 15px; line-height: 1.6; white-space: pre-wrap; margin-bottom: 8px; }
.sheet-ex { color: var(--muted); font-style: italic; font-size: 14px; line-height: 1.55; }
.sheet .btn.ghost { width: 100%; margin-top: 12px; }
.sheet .btn.sheet-master { width: 100%; margin-top: 12px; }
/* pile sort toggle: centered link line under the meta row */
.sort-toggle.pile-sort { display: block; margin: -2px auto 8px; }
/* desktop hover tooltip */
.rv-tip { position: fixed; z-index: 75; max-width: 320px; background: var(--card);
  border: 1px solid var(--hair); border-radius: 12px; padding: 12px 14px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .14); font-size: 14px;
  font-family: -apple-system, "SF Pro Text", "Hiragino Sans GB", sans-serif; }
.rv-tip .tip-word { font-weight: 700; margin-bottom: 4px; }
.rv-tip .tip-def { white-space: pre-wrap; line-height: 1.5; }
.rv-tip .tip-badge { color: var(--muted); font-size: 12px; margin-top: 6px; }
/* home: 純閱讀 rows are quieter than review piles */
.card-btn.read-row { border-style: solid; opacity: .8; }
.read-extra.hidden { display: none; }
@media (prefers-color-scheme: dark) {
  .rv-term { border-bottom-color: rgba(100, 170, 255, .55); }
  .rv-mark { background: rgba(160, 128, 0, .5); }
  .rv-term.fresh { background: rgba(52, 168, 83, .3); }
}

/* ── unified piles home (2026-07-07) ── */
.divider { border: 0; border-top: 1px solid var(--hair); margin: 20px 0 4px; }
.card-btn.row { padding: 10px 14px; margin: 6px 0; }        /* compact source rows: 30+ sources on a phone */
.card-btn.row .row-title { font-weight: 600; font-size: 15px; text-align: left;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pile-extra.hidden { display: none; }

/* 🚩 dedupe adjudication (2026-07-30) */
.dedupe-entry { border-color: #e3b04b; }
.pill.warn { background: #fdf3dd; color: #9a6b00; }
.dd-help { margin: 2px 2px 14px; font-size: 14px; }
.dd-pair { background: var(--card); border: 1px solid var(--hair); border-radius: 18px;
  padding: 14px; margin-bottom: 14px; }
.dd-cards { display: flex; align-items: stretch; gap: 8px; }
.dd-vs { align-self: center; color: var(--muted); font-weight: 600; }
.dd-card { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 6px;
  background: var(--bg); border: 2px solid var(--hair); border-radius: 14px;
  padding: 12px; text-align: left; cursor: pointer; color: var(--ink); font-size: 14px; }
.dd-card.sel { border-color: var(--accent); background: #eef5fe; }
.dd-card.sel .dd-lemma::after { content: "  ✓ 留這張"; color: var(--accent); font-size: 12px; }
.dd-lemma { font-weight: 700; font-size: 16px; overflow-wrap: anywhere; }
.dd-def { white-space: pre-line; color: var(--ink); overflow-wrap: anywhere; }
.dd-state { color: var(--muted); font-size: 12px; }
.dd-actions { display: flex; gap: 10px; margin-top: 12px; }
.dd-btn { flex: 1 1 0; }
.dd-note { margin-top: 8px; font-size: 13px; min-height: 1em; }
/* narrow phones: two ~118px text columns defeat the side-by-side comparison —
   stack the pair vertically instead (07-30 review) */
@media (max-width: 480px) {
  .dd-cards { flex-direction: column; }
  .dd-vs { align-self: center; }
}
@media (prefers-color-scheme: dark) {
  /* hardcoded light .sel background + dark --ink text ≈ 1:1 contrast — the
     selected (= most important) card went unreadable (07-30 review) */
  .dd-card.sel { background: #10304d; }
  .pill.warn { background: #3a2e00; color: #ffe69c; }
  .dedupe-entry { border-color: #8a6d1f; }
}
