/* Kuaizhi 快知 web UI, round 1. Spec: docs/design_handoff_kuaizhi_v1/README.md
   Reading-screen type is in em so the A / A+ / A++ control (--size) scales it; top-bar chrome stays in px. */

/* ---- Design tokens (tokens.css, pasted unchanged) ---- */
/* Kuaizhi 快知 design tokens (round 1). Drop into web/static/style.css. */
:root{
  --bg:#FAF6EE; --card:#FFFFFF; --ink:#1B1815; --ink2:#4A433B;
  --line:#DDD4C3; --line-strong:#857A69;
  --accent:#A4231A; --accent-ink:#FFFFFF; --accent-text:#A4231A; --accent-soft:#F7E7E2;
  --skel:#ECE5D8; --focus:#1446C8;
  --src-1:#1F6F78; --src-2:#5A4FA0;
  --size:22px;                       /* A=22, A+=26, A++=30 (TV base 32) */
  --r-btn:12px; --r-btn-lg:14px; --r-card:16px; --r-panel:18px;
  --tap:56px; --tap-primary:64px; --tap-audio:72px;
  --font-hant:"PingFang TC","Noto Sans CJK TC","Microsoft JhengHei",system-ui,sans-serif;
  --font-hans:"PingFang SC","Noto Sans CJK SC","Microsoft YaHei",system-ui,sans-serif;
}
@media (prefers-color-scheme:dark){:root{
  --bg:#14120F; --card:#1F1C18; --ink:#F4EFE6; --ink2:#CEC6B8;
  --line:#38332C; --line-strong:#7A7264;
  --accent:#FF8C78; --accent-ink:#1A0B08; --accent-text:#FF8C78; --accent-soft:#3B201B;
  --skel:#2C2823; --focus:#FFD25C;
  --src-1:#6FC3CC; --src-2:#ADA4E8;
}}
html:lang(zh-Hant) body{font-family:var(--font-hant)}
html:lang(zh-Hans) body{font-family:var(--font-hans)}
body{margin:0;background:var(--bg);color:var(--ink);font-size:var(--size);line-height:1.7;font-weight:400}
:focus-visible{outline:5px solid var(--focus);outline-offset:4px}

/* ---- Base ---- */
*,*::before,*::after{box-sizing:border-box}
/* First run sets html lang="zh" and shows both scripts; each language button carries its own lang. */
body{font-family:"PingFang TC","PingFang SC","Noto Sans CJK TC","Noto Sans CJK SC","Microsoft JhengHei",system-ui,sans-serif;min-height:100vh;-webkit-text-size-adjust:100%}
[lang="zh-Hant"]{font-family:var(--font-hant)}
[lang="zh-Hans"]{font-family:var(--font-hans)}
h1,h2,h3,p{margin:0}
button{font:inherit;color:inherit;cursor:pointer}
button:disabled{cursor:default;opacity:.4}
.ic{flex:none;width:24px;height:24px}
.tv-only{display:none}

/* ---- Buttons ---- */
.btn{display:flex;align-items:center;justify-content:center;gap:12px;min-height:var(--tap);padding:0 14px;border:2px solid var(--line-strong);border-radius:var(--r-btn);background:var(--card);color:var(--ink);font-weight:700;line-height:1.4;text-align:center;text-decoration:none}
.btn-accent{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}
.btn-ink{border-color:var(--ink);background:var(--ink);color:var(--bg)}
.btn-primary{width:100%;min-height:var(--tap-primary);border-radius:var(--r-btn-lg);font-size:.95em;font-weight:800}
.btn-primary .ic{width:26px;height:26px}
.btn-audio{width:100%;min-height:var(--tap-audio);border-radius:var(--r-btn-lg);font-weight:800}
.btn-audio .ic{width:26px;height:26px}

/* ---- Top bar (px chrome) ---- */
.topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px max(20px,calc((100% - 720px) / 2));border-bottom:1px solid var(--line)}
.wordmark{display:flex;align-items:center;gap:9px;line-height:1}
.wm-zh{font-size:28px;font-weight:800;letter-spacing:.06em}
.wm-dot{width:8px;height:8px;border-radius:2px;background:var(--accent)}
.wm-en{font-size:14px;font-weight:600;letter-spacing:.14em;color:var(--ink2)}
.chrome-btn{display:flex;align-items:center;gap:8px;min-height:56px;padding:0 18px;border:2px solid var(--line-strong);border-radius:12px;background:var(--card);color:var(--ink);font-size:20px;font-weight:700;line-height:1.2}
.chrome-btn .ic{width:22px;height:22px}
.chrome-btn.back{gap:4px;padding:0 20px 0 12px}
.chrome-btn.back .ic{width:24px;height:24px}
.pos{font-size:18px;font-weight:600;color:var(--ink2)}

/* ---- Pages ---- */
.page,.today-grid{display:flex;flex-direction:column;gap:18px;width:100%;max-width:760px;margin:0 auto;padding:20px 20px 32px}
.date,.sub{font-size:.82em;font-weight:500;color:var(--ink2)}
.title{font-size:1.45em;line-height:1.35;font-weight:800}
.stack{display:flex;flex-direction:column;gap:18px}

/* ---- Today: phone stacks rail + feed into one column, ordered as in the mock ---- */
.rail,.feed{display:contents}
.o1{order:1}.o2{order:2}.o3{order:3}.o4{order:4}.o5{order:5}.o6{order:6}.o7{order:7}.o8{order:8}.o9{order:9}
.today.reading .rail .play-main,.today.reading .rail .player{display:none}

.play-main{display:flex;align-items:center;gap:16px;width:100%;min-height:100px;padding:16px 20px;border:0;border-radius:var(--r-panel);background:var(--accent);color:var(--accent-ink);text-align:left}
.play-dot{display:flex;align-items:center;justify-content:center;flex:none;width:60px;height:60px;border-radius:50%;background:var(--accent-ink);color:var(--accent)}
.play-dot .ic{width:26px;height:26px}
.play-text{display:flex;flex-direction:column}
.play-label{font-size:1.12em;font-weight:800;line-height:1.35}
.play-sub{font-size:.78em;font-weight:500}

.player{display:flex;flex-direction:column;gap:14px;padding:18px;border:3px solid var(--accent);border-radius:var(--r-panel);background:var(--card)}
.player-label{font-size:.8em;font-weight:700;color:var(--accent-text)}
.player-headline{margin-top:-8px;font-size:1.05em;font-weight:700;line-height:1.45}
.segs{display:flex;gap:6px}
.seg{flex:1;height:10px;border-radius:5px;background:linear-gradient(90deg,var(--accent) var(--p,0%),var(--line) var(--p,0%))}
.player .btn-audio{font-size:1.05em}

.ctl{display:flex;align-items:center;gap:12px}
.ctl-label{flex:none;font-size:.8em;font-weight:600;color:var(--ink2)}
.ctl-row{display:flex;flex:1;gap:8px}
.opt{flex:1;min-height:56px;padding:0 4px;border:2px solid var(--line-strong);border-radius:var(--r-btn);background:var(--card);color:var(--ink);font-size:20px;font-weight:700;line-height:1}
.opt.sel{border-color:var(--ink);background:var(--ink);color:var(--bg)}
.sz{font-weight:800}.sz0{font-size:18px}.sz1{font-size:23px}.sz2{font-size:28px}
.ctl-row.tall .opt{min-height:64px}
.regionctl{flex-direction:column;align-items:stretch;gap:8px}
.ctl-row.wrap{flex-wrap:wrap}
.opt.rg{flex:1 0 auto;padding:0 14px}

/* Episodes and story cards */
.ep{display:flex;flex-direction:column;gap:14px;margin-top:6px}
.src{display:flex;align-items:center;flex-wrap:wrap;column-gap:10px;padding-bottom:8px;border-bottom:2px solid var(--line-strong)}
.swatch{flex:none;width:14px;height:14px;border-radius:3px}
.src-name{font-size:.92em;font-weight:800}
.src-show{font-size:.74em;font-weight:500;color:var(--ink2)}
.card{display:flex;flex-direction:column;gap:10px;padding:18px 20px 16px;border:1.5px solid var(--line);border-radius:var(--r-card);background:var(--card)}
.card.now{padding:16.5px 18.5px 14.5px;border:3px solid var(--accent)}
.card-head{display:flex;flex-direction:column-reverse;align-items:flex-start;gap:10px}
.card h3{font-size:1.14em;font-weight:700;line-height:1.45;text-wrap:pretty}
.card p{text-wrap:pretty}
.pill{font-size:.72em;font-weight:800;padding:2px 12px;border-radius:999px;background:var(--accent-soft);color:var(--accent-text)}
.meta{font-size:.74em;font-weight:500;line-height:1.55;color:var(--ink2)}
.card-actions{display:flex;flex-wrap:wrap;gap:12px;padding-top:12px;border-top:1px solid var(--line)}
.card-actions .btn{flex:1 1 auto;font-size:.8em}
.ai-note{margin-top:8px;font-size:.78em;font-weight:500;line-height:1.6;color:var(--ink2)}
.end{padding-top:8px;text-align:center;font-size:.78em;font-weight:600;color:var(--ink2)}

/* States */
.loading-text{font-size:.9em;font-weight:600;color:var(--ink2)}
.skel-card{display:flex;flex-direction:column;gap:12px;padding:20px;border:1.5px solid var(--line);border-radius:var(--r-card);background:var(--card)}
.skel-card span{height:18px;border-radius:6px;background:var(--skel)}
.skel-card span:first-child{width:72%;height:26px}
.skel-card span:last-child{width:88%}
.notice{display:flex;flex-direction:column;gap:14px;padding:24px 20px;border:1.5px solid var(--line);border-radius:var(--r-panel);background:var(--card)}
.notice.offline{gap:12px;padding:20px;border:3px solid var(--ink)}
.notice-title{font-size:1.2em;font-weight:800;line-height:1.4}
.notice.novoice{border:3px solid var(--accent)}
.cached{margin-top:6px;font-size:.85em;font-weight:700;color:var(--ink2)}

/* 1b reading first: fixed bottom play bar */
.readbar{position:fixed;left:0;right:0;bottom:0;padding:14px 20px 18px;border-top:2px solid var(--line-strong);background:var(--bg)}
.readbar>*{max-width:720px;margin:0 auto}
.play-bar{width:100%;min-height:72px;gap:14px;border-radius:16px}
.pb-label{font-size:1em;font-weight:800}
.pb-sub{font-size:.74em;font-weight:500}
.player.compact{gap:10px;padding:12px 14px}
.readbar-spacer{height:110px}
.readbar-spacer.tall{height:240px}

/* ---- Story ---- */
.story-h{font-size:1.4em;line-height:1.4;font-weight:800;text-wrap:pretty}
.story-s{font-size:1.1em;line-height:1.75;text-wrap:pretty}
.story-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;margin-top:4px}
.span2{grid-column:1 / -1}
.story-grid .btn-audio{font-size:1em}
.story-grid .btn-orig{padding:8px 16px;font-size:.92em}
.note-box{margin:6px 0;padding:14px 16px;border:1.5px solid var(--line);border-radius:14px;background:var(--card);font-size:.78em;font-weight:500;line-height:1.6;color:var(--ink2)}
.btn-nav{min-height:64px;border-radius:14px;font-size:.88em;font-weight:800}

/* ---- Past days ---- */
.past{gap:14px}
.day{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:76px;padding:10px 18px;border:2px solid var(--line-strong);border-radius:14px;background:var(--card);color:var(--ink);text-align:left}
.day.today-row{padding:9px 17px;border:3px solid var(--ink)}
.day-text{display:flex;flex-direction:column}
.day-title{font-size:1em;font-weight:800;line-height:1.35}
.day-sub{font-size:.76em;font-weight:500;color:var(--ink2)}
.day-count{flex:none;font-size:.8em;font-weight:700;color:var(--ink2)}
.past .end{padding-top:6px}

/* ---- Settings ---- */
.settings{gap:28px}
.set{display:flex;flex-direction:column;gap:12px}
.set h2{font-size:.9em;font-weight:800}
.langrow{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:72px;padding:8px 18px;border:3px solid var(--line-strong);border-radius:14px;background:var(--card);color:var(--ink);text-align:left}
.langrow.sel{border-color:var(--ink)}
.lr-text{display:flex;flex-direction:column}
.lr-label{font-size:1em;font-weight:800;line-height:1.35}
.lr-sub{font-size:.74em;font-weight:500;color:var(--ink2)}
.radio{display:flex;align-items:center;justify-content:center;flex:none;width:30px;height:30px;border:3px solid var(--line-strong);border-radius:50%}
.radio span{width:14px;height:14px;border-radius:50%}
.langrow.sel .radio{border-color:var(--ink)}
.langrow.sel .radio span{background:var(--ink)}
.preview{padding:14px 16px;border:1.5px solid var(--line);border-radius:14px;background:var(--card)}
.help-body{font-size:.88em}
.helpcard{display:flex;flex-direction:column;gap:12px;padding:16px;border:1.5px solid var(--line);border-radius:var(--r-card);background:var(--card)}
.kv{display:flex;flex-direction:column}
.kv.divider{padding-top:12px;border-top:1px solid var(--line)}
.k{font-size:.76em;font-weight:600;color:var(--ink2)}
.v{font-size:1.05em;font-weight:800}

/* ---- Live TV / radio (not in the round-1 mocks; built from the Past days row and the player panel) ---- */
.live{gap:22px}
.chans{display:flex;flex-direction:column;gap:12px}
.chan{display:flex;align-items:center;justify-content:space-between;gap:14px;width:100%;min-height:84px;padding:10px 18px;border:2px solid var(--line-strong);border-radius:14px;background:var(--card);color:var(--ink);text-align:left;text-decoration:none}
.chan.sel{padding:9px 17px;border:3px solid var(--accent)}
.chan-text{display:flex;flex-direction:column;min-width:0}
.chan-name{font-size:1em;font-weight:800;line-height:1.35}
.chan-note{font-size:.74em;font-weight:500;line-height:1.5;color:var(--ink2)}
.chan-go{display:flex;align-items:center;gap:8px;flex:none;font-size:.8em;font-weight:700;color:var(--ink2)}
.chan.sel .chan-go{color:var(--accent-text)}
.chan.off{border-style:dashed;background:transparent}
.chan.off .chan-name{color:var(--ink2)}
.chan.rp .chan-name{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;font-size:.92em} /* YouTube titles run long */
.live-dot{display:inline-block;flex:none;width:12px;height:12px;margin-right:8px;border-radius:50%;background:var(--accent);animation:live-pulse 1.6s ease-in-out infinite}
.chan-go .live-dot{margin-right:0}
@keyframes live-pulse{50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.live-dot{animation:none}}
.live-player .player-label{display:flex;align-items:center}
.live-slot:empty,.live-slot.gone{display:none}
.live-slot.screen{position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:12px;background:#000}
.live-slot.screen video,.live-slot.screen iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.live-slot audio:not([controls]){display:none}
.live-slot audio{width:100%;height:56px}
.live-err{padding:12px 14px;border:2px solid var(--ink);border-radius:12px;font-size:.88em;font-weight:700;line-height:1.5}
.live-note{font-size:.76em;font-weight:500;line-height:1.55;color:var(--ink2)}
.live-player .btn:not(.btn-audio){font-size:.85em}

/* ---- Weather (Markham, Environment Canada) ---- */
.wx{display:flex;flex-direction:column;gap:12px;padding:16px 18px;border:1.5px solid var(--line);border-radius:var(--r-card);background:var(--card)}
.wx-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 14px}
.wx-place{font-size:.85em;font-weight:800}
.wx-now{display:flex;align-items:center;gap:8px}
.wx-ic{width:30px;height:30px}
.wx-temp{font-size:1.3em;font-weight:800;line-height:1.2}
.wx-text{font-size:.85em;font-weight:600}
.wx-warn{padding:10px 12px;border:2px solid var(--accent);border-radius:12px;color:var(--accent-text);font-size:.85em;font-weight:800;line-height:1.5}
.wx-ps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;padding-top:12px;border-top:1px solid var(--line)}
.wx-p{display:flex;flex-direction:column;gap:2px;min-width:0}
.wx-name{font-size:.74em;font-weight:700;color:var(--ink2)}
.wx-row{display:flex;align-items:center;gap:4px}
.wx-row .wx-ic{width:24px;height:24px}
.wx-t{font-size:.8em;font-weight:800;white-space:nowrap}
.wx-d{font-size:.7em;font-weight:500;line-height:1.45}
.wx-credit{font-size:.62em;font-weight:500;color:var(--ink2)}
.wx-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px}
.wx-btn{font-size:.72em}
.wx-btn .ic{width:22px;height:22px}
.wx-msg{font-size:.76em;font-weight:700;line-height:1.5;color:var(--ink2)}
.live-news .card h3{font-size:1.05em}

/* ---- First run (px: shown before a text size is chosen) ---- */
.first{display:flex;flex-direction:column;justify-content:center;gap:40px;max-width:520px;min-height:100vh;margin:0 auto;padding:40px 24px}
.brand{display:flex;flex-direction:column;align-items:center;gap:18px}
.appicon{display:flex;align-items:center;justify-content:center;width:104px;height:104px;border-radius:24px;background:var(--accent);color:var(--accent-ink);font-size:38px;font-weight:800;letter-spacing:.02em;line-height:1}
.wordmark.lg{gap:10px}
.wordmark.lg .wm-zh{font-size:34px}
.wordmark.lg .wm-dot{width:9px;height:9px}
.wordmark.lg .wm-en{font-size:18px}
.first-btns{display:flex;flex-direction:column;gap:16px}
.lang-big{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:128px;padding:16px;border:3px solid var(--line-strong);border-radius:20px;background:var(--card);color:var(--ink)}
.lb-label{font-size:40px;font-weight:800;line-height:1.3}
.lb-sub{font-size:20px;font-weight:500;color:var(--ink2)}

/* ---- TV box (>= 1280 px; mocks at 1920 x 1080, base 32 px set by app.js) ---- */
@media (min-width:1280px){
  :focus-visible{outline-width:8px;outline-offset:6px}
  .phone-only{display:none !important}
  span.tv-only{display:inline}
  body.v-today{overflow:hidden}

  .today-grid{display:grid;grid-template-columns:640px minmax(0,1fr);gap:0;max-width:none;height:100vh;padding:0}
  .rail>*,.feed>*{order:0}
  .rail{display:flex;flex-direction:column;gap:28px;padding:64px 56px 48px 72px;border-right:2px solid var(--line);overflow-y:auto}
  .feed{display:flex;flex-direction:column;gap:22px;padding:64px 80px 64px 72px;overflow-y:auto}
  .feed>*{max-width:1060px}
  .tv-brand{display:flex;align-items:center;gap:18px}
  .appicon.sm{width:84px;height:84px;border-radius:20px;font-size:30px}
  .tv-brand .wm-en{font-size:22px;letter-spacing:.16em}
  .rail .date{font-size:30px}
  .rail .title{font-size:64px;line-height:1.3}
  .play-main{min-height:150px;gap:24px;padding:20px 28px;border-radius:24px}
  .play-dot{width:92px;height:92px}
  .play-dot .ic{width:40px;height:40px}
  .play-label{font-size:42px;line-height:1.3}
  .play-sub{font-size:28px}
  .rail .player{gap:18px;padding:26px;border-width:4px;border-radius:24px}
  .rail .player-label{font-size:28px}
  .rail .player-headline{display:none}
  .rail .segs{gap:8px}
  .rail .seg{height:14px;border-radius:7px}
  .rail .player .btn-audio{gap:16px;min-height:96px;border-radius:18px;font-size:38px}
  .rail .player .btn-audio .ic{width:36px;height:36px}
  .rail .ctl{gap:16px}
  .rail .ctl-label{font-size:28px}
  .rail .ctl-row{gap:12px}
  .rail .opt{min-height:72px;border-width:3px;border-radius:14px;font-size:28px;font-weight:800}
  .rail .sizectl .opt{min-height:80px}
  .rail .opt.rg{padding:0 18px}
  .tv-nav{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:20px}
  .tv-nav .btn{min-height:96px;border-width:3px;border-radius:18px;font-size:34px;font-weight:800}
  .remote{display:block;margin-top:auto;font-size:24px;font-weight:600;color:var(--ink2)}
  .sz0{font-size:26px}.sz1{font-size:32px}.sz2{font-size:38px}

  .ep{gap:22px;margin-top:0}
  .src{column-gap:16px;padding-bottom:10px;border-bottom-width:3px}
  .swatch{width:20px;height:20px;border-radius:4px}
  .src-name{font-size:1.0625em}
  .src-show{font-size:.875em}
  .card{padding:26px 32px;border-width:2px;border-radius:22px}
  .card.now{padding:24px 30px;border-width:4px}
  .card-head{flex-direction:row;align-items:center;flex-wrap:wrap;gap:16px}
  .card h3{font-size:1.25em;line-height:1.4}
  .pill{padding:2px 16px;font-size:.75em}
  .meta{font-size:.75em}
  .card-actions .btn{flex:0 1 auto;min-height:72px;padding:0 28px;border-width:3px;font-size:.75em}

  /* Story (and Past days / Settings, which follow the TV Story layout) */
  .topbar{padding:56px 72px 0;border-bottom:0}
  .chrome-btn.back{gap:8px;min-height:88px;padding:0 34px 0 22px;border-width:3px;border-radius:18px;font-size:34px;font-weight:800}
  .chrome-btn.back .ic{width:38px;height:38px}
  .pos{font-size:30px}
  .page{gap:24px;max-width:1544px;margin:0;padding:36px 72px 56px}
  .story-page .src-name{font-size:1em}
  .story-h{font-size:2em;line-height:1.35}
  .story-s{font-size:1.3125em;line-height:1.7}
  .story-grid{display:flex;flex-wrap:wrap;gap:24px;margin-top:12px}
  .story-grid .btn{width:auto;min-height:104px;padding:0 40px;border-width:3px;border-radius:20px;font-size:34px;font-weight:800}
  .story-grid .btn-accent{font-size:36px}
  .story-grid .ic{width:34px;height:34px}
  .story-grid .prev{display:none}
  .note-box{order:9;flex-basis:100%;margin:12px 0 0;padding:0;border:0;background:none;font-size:.8125em}
  .day{min-height:96px;padding:12px 28px;border-width:3px}
  .day.today-row{padding:12px 28px}
  .langrow{min-height:96px;padding:12px 28px}
  .btn-primary,.ctl-row.tall .opt{min-height:88px;border-width:3px}
  .tv-nav .btn .ic{width:34px;height:34px}
  .wx{flex-direction:row;flex-wrap:wrap;align-items:center;gap:16px 40px;padding:22px 32px;border-width:2px;border-radius:22px}
  .wx-head{flex-direction:column;align-items:flex-start;gap:4px}
  .wx-ic{width:44px;height:44px}
  .wx-row .wx-ic{width:32px;height:32px}
  .wx-ps{flex:1;gap:24px;padding:0 0 0 36px;border-top:0;border-left:2px solid var(--line)}
  .wx-warn,.wx-msg,.wx-foot{flex-basis:100%}
  .wx-btn{min-height:72px;padding:0 28px;border-width:3px;font-size:.75em}
  .live{max-width:1240px}
  .chan{min-height:104px;padding:12px 28px;border-width:3px}
  .chan.sel{padding:12px 28px;border-width:4px}
  .live-dot{width:18px;height:18px}
  .live-player{gap:20px;padding:28px;border-width:4px;border-radius:24px}
  .live-player .player-label{font-size:28px}
  .live-player .btn{min-height:96px;border-width:3px;border-radius:18px;font-size:34px}
  .first{max-width:760px}
  .lang-big{min-height:160px}
}
