/* =====================================================================
   GeekLanguage — Words · product stylesheet
   Tokens, primitives and copy are lifted from design/design.html (approved
   2026-09-02). Light theme = warm paper, dark = warm charcoal, one moss-green
   accent; theme follows the system only.
   ===================================================================== */

:root{
  --bg:#f5f1e8;          /* warm paper */
  --bg-elev:#fffdf8;     /* cards */
  --bg-sunk:#ebe5d8;     /* tracks, wells */
  --ink:#1f1c17;
  --ink-2:#5a5449;
  --ink-3:#706a5c;       /* muted text: 4.77:1 on --bg, 5.29:1 on cards (WCAG AA) */
  --line:#dbd3c4;
  --line-2:#e9e3d6;

  --accent:#2e6d4d;      /* moss green — primary + Know */
  --accent-strong:#22553b;
  --accent-ink:#ffffff;
  --accent-soft:#e2eee5;
  --accent-line:#b9d5c4;

  --amber:#8a5312;       /* Don't Know — warm, quiet */
  --amber-soft:#f5e7cd;
  --amber-line:#e0c48e;
  --amber-hover:#f0dcb6;

  --danger:#a33a2a;
  --danger-soft:#f7e3df;
  --danger-line:#e5b9b1;

  --scroll:#c8bfad;
  --shadow:0 1px 2px rgba(30,25,15,.05),0 14px 36px -16px rgba(30,25,15,.22);
  --shadow-soft:0 1px 0 rgba(30,25,15,.04),0 8px 24px -14px rgba(30,25,15,.16);
  --grain-opacity:.045;

  --font-ui:"Schibsted Grotesk","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-display:"Schibsted Grotesk","Helvetica Neue",Helvetica,Arial,sans-serif;   /* display = the UI face at 600-800 (the serif display face was dropped 2026-09-02) */
  --font-cjk:"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC",sans-serif;
  --font-ipa:"Charis SIL","Doulos SIL","Gentium Plus","Noto Sans","Segoe UI","DejaVu Sans",sans-serif;
  /* one content column on wide screens: the mockup's 1180px screen. Full-bleed bands (nav,
     session header, landing sections, footer) keep their rules across the whole viewport and
     cap their content at --col by growing their side padding by --gutter past 1180px. */
  --col:1180px;
  --gutter:max(0px,calc((100% - var(--col)) / 2));
  color-scheme:light;
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#15130f;
    --bg-elev:#1d1a15;
    --bg-sunk:#0e0d0a;
    --ink:#ece6d9;
    --ink-2:#b1a999;
    --ink-3:#908979;     /* 5.34:1 on --bg, 4.99:1 on cards */
    --line:#2f2b24;
    --line-2:#262219;
    --accent:#5fb384;
    --accent-strong:#7cc79c;
    --accent-ink:#0d1a12;
    --accent-soft:#1b2c22;
    --accent-line:#2f4d3c;
    --amber:#e6ac60;
    --amber-soft:#2a2116;
    --amber-line:#5a4526;
    --amber-hover:#342917;
    --danger:#e08a7a;
    --danger-soft:#2c1c19;
    --danger-line:#5a3029;
    --scroll:#3a352c;
    --shadow:0 1px 2px rgba(0,0,0,.4),0 18px 40px -16px rgba(0,0,0,.6);
    --shadow-soft:0 1px 0 rgba(0,0,0,.3),0 8px 24px -14px rgba(0,0,0,.5);
    --grain-opacity:.06;
    color-scheme:dark;
  }
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;height:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font-ui);font-size:16px;line-height:1.5;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;min-height:100%;position:relative;
}
/* paper grain — fixed, non-interactive */
body::before{
  content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;
  opacity:var(--grain-opacity);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* global thin scrollbars */
*{scrollbar-width:thin;scrollbar-color:var(--scroll) transparent}
*::-webkit-scrollbar{width:8px;height:8px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--scroll);border-radius:8px;border:2px solid transparent;background-clip:padding-box}
*::-webkit-scrollbar-thumb:hover{background:var(--ink-3);background-clip:padding-box;border:2px solid transparent}

a{color:inherit}
h1,h2,h3,p,dl,dd{margin:0}
button{font-family:inherit;color:inherit}
svg.i{width:1.25em;height:1.25em;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
svg.i.fill{fill:currentColor;stroke:none}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[hidden]{display:none!important}
kbd.k{
  display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:22px;padding:0 6px;
  font:600 12px/1 var(--font-ui);color:var(--ink-2);background:var(--bg-elev);
  border:1px solid var(--line);border-bottom-width:2px;border-radius:6px;
}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* green-filled controls get an ink ring, so focus is visible against the fill */
.btn-primary:focus-visible,.ans-yes:focus-visible{outline-color:var(--ink)}
/* busy state: an inline SVG spinner replaces the button's icon while a request is in flight */
svg.i.spin{animation:en-spin .8s linear infinite}
@keyframes en-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){svg.i.spin{animation:none}}
.sprite{position:absolute}

/* ---------- product primitives ---------- */
.app-nav{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px calc(var(--gutter) + 40px);border-bottom:1px solid var(--line-2)}
/* wordmark "GeekLanguage": one word, two colours, same weight, no italic */
.wordmark{display:inline-flex;align-items:baseline;gap:0;text-decoration:none;white-space:nowrap}
.wordmark .a{font:700 19px/1 var(--font-ui);letter-spacing:-.02em;color:var(--ink)}
.wordmark .b{font:700 19px/1 var(--font-ui);letter-spacing:-.02em;color:var(--accent)}
.wordmark.small .a,.wordmark.small .b{font-size:15px}
.nav{display:flex;gap:4px;align-items:center}
.nav a{
  display:inline-flex;align-items:center;min-height:44px;padding:0 14px;border-radius:10px;
  text-decoration:none;color:var(--ink-2);font-weight:600;font-size:15px;
}
.nav a.on{color:var(--ink);background:var(--bg-sunk)}
.nav a:hover{color:var(--ink)}
.nav a.btn-primary,.nav a.btn-primary:hover{color:var(--accent-ink)}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 22px;
  border-radius:12px;font:600 16px var(--font-ui);border:1px solid var(--line);background:var(--bg-elev);
  color:var(--ink);cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:transform .12s ease,background .15s ease,border-color .15s ease,box-shadow .15s ease;
}
.btn:hover{transform:translateY(-1px);border-color:var(--ink-3)}
.btn-primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);box-shadow:0 8px 20px -10px var(--accent)}
.btn-primary:hover{background:var(--accent-strong);border-color:var(--accent-strong)}
.btn-ghost{background:transparent}
.btn-block{width:100%}
.btn-lg{min-height:56px;padding:0 28px;font-size:17px;border-radius:14px}
.btn[disabled]{opacity:.65;cursor:default;transform:none;pointer-events:none}
.btn.busy{opacity:1;cursor:progress;transform:none;pointer-events:none}
.ans.busy{cursor:progress;pointer-events:none}
.link{color:var(--accent);font-weight:600;text-decoration:none;border-bottom:1px solid transparent;background:none;border-top:0;border-left:0;border-right:0;padding:0;cursor:pointer;font-family:inherit;font-size:inherit}
.link:hover{border-bottom-color:currentColor}
/* standalone text links get a 44px tap area through padding + negative margins (layout unchanged) */
.swap .link,.state .link{display:inline-block;padding:12px 6px;margin:-12px -6px}
.eyebrow{font-size:12.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.muted{color:var(--ink-3)}

/* inputs — 16px minimum (iOS zoom rule), including hidden radios and the range */
input,select,textarea{font-size:16px}
.field{display:block;margin:0 0 18px}
.field .lbl{display:block;font-size:14px;font-weight:700;margin:0 0 8px;color:var(--ink-2)}
.field .box{position:relative;display:flex;align-items:center}
.field .box svg.i{position:absolute;left:14px;color:var(--ink-3);pointer-events:none}
.input{
  width:100%;min-height:50px;padding:0 14px;font:400 16px var(--font-ui);color:var(--ink);
  background:var(--bg-elev);border:1px solid var(--line);border-radius:12px;outline:none;
}
.box svg.i + .input{padding-left:44px}
.input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.input::placeholder{color:var(--ink-3)}
.input.pw{padding-right:52px}
.eye{
  position:absolute;right:4px;width:44px;height:44px;display:grid;place-items:center;border:0;background:transparent;
  color:var(--ink-3);border-radius:10px;cursor:pointer;
}
.eye:hover{color:var(--ink)}
.help{font-size:13px;color:var(--ink-3);margin:8px 0 0}
.form-error{
  display:flex;gap:10px;align-items:flex-start;margin:0 0 18px;padding:12px 14px;border-radius:12px;
  background:var(--danger-soft);border:1px solid var(--danger-line);color:var(--danger);font-size:14.5px;line-height:1.4;
}
.form-error svg.i{margin-top:2px}

/* tags */
.tag{
  display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:999px;
  font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-2);background:var(--bg);border:1px solid var(--line);white-space:nowrap;
}
.tag-new{color:var(--accent);background:var(--accent-soft);border-color:var(--accent-line)}
.tag-confirm{color:var(--amber);background:var(--amber-soft);border-color:var(--amber-line)}
.tag .dots{display:inline-flex;gap:3px}
.tag .dots i{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.3;display:block}
.tag .dots i.on{opacity:1}
.tags{display:flex;gap:8px;flex-wrap:wrap;min-width:0}

/* session header: five counters + bar */
.session{padding:14px calc(var(--gutter) + 40px) 18px}
.counters{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px}
.counter{padding:8px 12px 6px;border-radius:12px;background:var(--bg-elev);border:1px solid var(--line-2);min-width:0}
.counter b{display:block;font:700 24px/1.1 var(--font-display);letter-spacing:-.02em}
.counter span{display:block;margin-top:3px;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.counter span .short{display:none}
.counter.done b{color:var(--accent)}
.bar{margin-top:12px;height:6px;border-radius:3px;background:var(--bg-sunk);overflow:hidden}
.bar i{display:block;height:100%;width:0;background:var(--accent);border-radius:3px;transition:width .25s ease}
.bar-meta{display:flex;justify-content:space-between;margin-top:8px;font-size:12.5px;color:var(--ink-3)}

/* the card */
.card{background:var(--bg-elev);border:1px solid var(--line);border-radius:24px;box-shadow:var(--shadow);position:relative}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:20px 22px 0}
.card-head .lvl-tag{font-size:13px;white-space:nowrap}
.word{
  margin:0;text-align:center;font-family:var(--font-display);font-weight:700;
  letter-spacing:-.035em;line-height:1;
  overflow-wrap:anywhere;
}
.card-A .word{font-size:96px;padding:84px 40px 96px}
.card-A .word.long{font-size:68px}
.card-A .word.xlong{font-size:48px}
.answers{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.ans{
  min-height:72px;border-radius:16px;display:inline-flex;align-items:center;justify-content:center;gap:12px;
  font:700 19px var(--font-ui);border:1.5px solid;cursor:pointer;text-decoration:none;
  transition:transform .12s ease,background .15s ease,opacity .15s ease;-webkit-appearance:none;appearance:none;
}
.ans:hover{transform:translateY(-1px)}
.ans:active,.ans.pressed{transform:translateY(1px)}
.ans[disabled]{cursor:default;transform:none}
.ans[disabled]:not(.pressed){opacity:.7}
.ans-no{background:var(--amber-soft);color:var(--amber);border-color:var(--amber-line)}
.ans-no:hover{background:var(--amber-hover)}
.ans-yes{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);box-shadow:0 10px 24px -12px var(--accent)}
.ans-yes:hover{background:var(--accent-strong);border-color:var(--accent-strong)}
.hints{display:none;justify-content:center;flex-wrap:wrap;gap:8px 26px;margin-top:20px;font-size:13px;color:var(--ink-3);flex:none}
@media (hover:hover) and (min-width:1024px){.hints{display:flex}}   /* keyboard hints: desktop only */
.hints span{display:inline-flex;align-items:center;gap:6px}
.undo{
  display:inline-flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink-3);text-decoration:none;
  min-height:44px;padding:0;background:none;border:0;cursor:pointer;font-family:inherit;text-align:left;
}
.undo b{color:var(--ink-2);font-weight:600}
.undo .link{font-size:13.5px}

/* learn layout: the page is exactly one viewport tall and the card is the only part that
   may shrink — long reveal content scrolls INSIDE it (.card-scroll), so Know / Don't Know /
   Continue never leave the screen. `min-height:0` all the way down the flex chain is what
   lets the card shrink; `height` (not min-height) on .learn is what bounds it. Desktop
   keeps the design's fixed-height word card and centres it; below 1024px the card fills
   the viewport and the buttons sit under the thumb (pinned layout, further down). */
.learn{display:flex;flex-direction:column;height:100vh;height:100dvh}
.learn-main{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:36px 40px 44px}
.learn-col{width:100%;max-width:700px;display:flex;flex-direction:column;min-height:0}
.learn-col .card{display:flex;flex-direction:column;flex:0 1 auto;min-height:0}
.learn-col .card-A{height:332px}              /* design height; shrinks only on a short viewport */
.learn-col .card-A .word{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;padding:0 40px 12px}
.card-scroll{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}
.learn-col .pfoot{margin-top:20px;flex:none}
.learn-col .undo{margin-bottom:4px;flex:none}
.pfoot .cont{display:none}
.learn-col[data-state="reveal"] .answers{display:none}
.closed{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;padding:32px 24px;text-align:center;color:var(--ink-2);font-size:16.5px}
.closed p{max-width:30ch}
/* learn-page state switches */
.complete{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column}
body:not([data-mode="complete"]) .complete{display:none}
body[data-mode="complete"] .session,body[data-mode="complete"] .learn-main{display:none}
body[data-mode="loading"] .pfoot,body[data-mode="error"] .pfoot,body[data-mode="closed"] .pfoot,
body[data-mode="loading"] .hints,body[data-mode="error"] .hints,body[data-mode="closed"] .hints{visibility:hidden}
.counter em{font-style:normal}

/* revealed card (state B) */
.card-B{padding:0 0 28px}
.card-B .word{font-size:64px;padding:40px 32px 14px;text-align:left}
.card-B .word.long{font-size:50px}
.card-B .word.xlong{font-size:40px}
.reveal{padding:0 32px}
.pron{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.ipa{font-family:var(--font-ipa);font-size:22px;color:var(--ink-2);letter-spacing:.01em}
.play{
  width:44px;height:44px;border-radius:50%;display:grid;place-items:center;border:1.5px solid var(--accent-line);
  background:var(--accent-soft);color:var(--accent);cursor:pointer;flex:none;
}
.play svg.i{width:20px;height:20px;margin-left:2px}
.play:hover{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.play[disabled]{opacity:.4;cursor:default;pointer-events:none}
.pron .cap{font-size:13px}
.zh{font-family:var(--font-cjk);font-size:21px;line-height:1.55;margin-top:18px;color:var(--ink)}
/* pos labels ("n." / "vt." / "adj."): the same face, size and colour in the Chinese gloss and
   in the English definition, so the two blocks read as one dictionary entry */
.reveal .pos{font-family:var(--font-ui);font-style:italic;font-weight:500;color:var(--ink-3);font-size:16px;margin-right:4px}
/* several senses: one row per sense, label column + text column - the same grid in both blocks,
   so "n. 中心…" and "n. the middle point…" line up; a single sense stays inline (above) */
.senses{display:grid;grid-template-columns:max-content 1fr;column-gap:10px;row-gap:4px;align-items:baseline}
.senses .pos{margin:0;white-space:nowrap}
.def{margin-top:22px;padding-top:20px;border-top:1px solid var(--line-2);font-size:17px;line-height:1.55;color:var(--ink-2)}
.def dt{font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);margin:0 0 6px}
.def dd{margin:0}
.def dd + dt{margin-top:16px}
.example{font-family:var(--font-ui);font-style:italic;font-size:17.5px;color:var(--ink)}
.example mark{background:transparent;color:var(--accent);font-style:normal;text-decoration:underline;text-decoration-color:var(--accent-line);text-underline-offset:4px}
.again{display:flex;align-items:center;gap:10px;margin:22px 32px 0;font-size:14px;color:var(--ink-3)}
.again svg.i{color:var(--amber)}
.again .short{display:none}
.cont{margin:16px 32px 0}
.cont .btn{width:100%;min-height:60px;font-size:18px;border-radius:16px}

/* inline network-error banner (never a blank screen) */
.banner{
  display:flex;align-items:center;justify-content:space-between;gap:14px;margin:0 0 14px;flex:none;
  padding:12px 16px;border-radius:14px;background:var(--danger-soft);border:1px solid var(--danger-line);color:var(--danger);font-size:14.5px;
}
.banner span{flex:1 1 auto;min-width:0}          /* the message wraps, Retry stays on the right */
.banner .btn{min-height:40px;padding:0 16px;font-size:14px;border-radius:10px;flex:none}
.loading{display:flex;align-items:center;justify-content:center;min-height:240px;color:var(--ink-3);font-size:14px}

/* "A new version is available" bar (EN.showUpdateBar in app.js): a small card pinned top
   centre above everything, on any page whose scripts are older than the server's (/learn
   uses its in-flow #banner instead). Centred with left/right 0 + auto margins, NOT left:50%:
   a fixed box only gets the space right of its `left`, which wrapped the text at 375px. */
.update-bar{
  position:fixed;top:12px;left:0;right:0;width:fit-content;margin:0 auto;z-index:60;
  display:flex;align-items:center;gap:14px;max-width:calc(100% - 24px);
  padding:8px 8px 8px 16px;border-radius:14px;background:var(--bg-elev);border:1px solid var(--line);
  box-shadow:var(--shadow);color:var(--ink);font-size:14.5px;
}
.update-bar span{min-width:0}
.update-bar .btn{min-height:40px;padding:0 16px;font-size:14px;border-radius:10px;flex:none}

/* complete */
.complete .body{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:48px 40px 56px}
.complete .ring{width:76px;height:76px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;border:1.5px solid var(--accent-line)}
.complete .ring svg.i{width:34px;height:34px}
.complete h1{margin-top:22px;font-family:var(--font-display);font-weight:800;font-size:64px;line-height:1;letter-spacing:-.04em}
.complete h1 small{display:block;margin-top:10px;font:400 22px var(--font-ui);letter-spacing:0;color:var(--ink-2)}
.stats{display:grid;grid-template-columns:repeat(4,minmax(150px,1fr));gap:12px;margin-top:36px;width:100%;max-width:760px}
.stat{padding:18px 18px 16px;border:1px solid var(--line);border-radius:16px;background:var(--bg-elev);text-align:left}
.stat b{display:flex;align-items:center;gap:8px;font:700 30px/1 var(--font-display);letter-spacing:-.025em}
.stat b svg.i{color:var(--amber);width:26px;height:26px}
.stat span{display:block;margin-top:8px;font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.stat.accent{background:var(--accent-soft);border-color:var(--accent-line)}
.stat.accent b{color:var(--accent)}
.tomorrow{margin-top:36px;font-family:var(--font-ui);font-style:italic;font-weight:500;font-size:21px;color:var(--ink-2)}
.complete .cta{display:flex;gap:14px;margin-top:22px;align-items:center;flex-wrap:wrap;justify-content:center}
.complete .cta .link{padding:0 8px;min-height:44px;display:inline-flex;align-items:center}

/* progress + settings pages: the mockup's 1000px block, centred on wide screens
   (auto margins; width:100% so the flex column does not shrink-wrap it) */
.page{width:100%;max-width:1000px;margin-inline:auto;padding:40px 64px 64px}
.page h1{font-family:var(--font-display);font-weight:700;font-size:40px;letter-spacing:-.03em}
.page .sub{margin-top:6px;color:var(--ink-2)}
.block{margin-top:36px}
.block-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:14px;flex-wrap:wrap}
.block-head h2{font-size:13px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.block-head .state{font-size:14px;color:var(--ink-2)}
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.tile{padding:22px 22px 20px;border:1px solid var(--line);border-radius:18px;background:var(--bg-elev)}
.tile b{display:flex;align-items:center;gap:10px;font:700 40px/1 var(--font-display);letter-spacing:-.03em;white-space:nowrap}
.tile b svg.i{width:30px;height:30px;color:var(--amber)}
.tile span{display:block;margin-top:10px;font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.tile small{display:block;margin-top:6px;font-size:13.5px;color:var(--ink-2)}
/* last-14-days chart: one .day column per date = count label, bar (max 64px), weekday tick (desktop) */
.days{display:flex;gap:6px;align-items:flex-end;height:84px;margin-top:6px}
.day{flex:1 1 0;min-width:0;height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;border-radius:6px;outline-offset:3px}
.day i{display:block;width:100%;border-radius:4px 4px 2px 2px;background:var(--accent);opacity:.9;min-height:4px}
.day i.off{background:var(--line);opacity:1;height:6px}
.day .n{display:block;margin-bottom:3px;font-size:11px;font-weight:600;line-height:1;color:var(--ink-2);letter-spacing:-.02em;white-space:nowrap}   /* proportional figures: fixed-width digits spaced "1.2k" out to "1 . 2k" at 9.5px */
.day.today .n{color:var(--accent);font-weight:700}
.day .wd{display:none}
@media (min-width:1024px){
  .days{height:100px}
  .day .wd{display:block;margin-top:5px;font-size:10px;line-height:1;color:var(--ink-3);letter-spacing:.02em}
}
.days-x{display:flex;justify-content:space-between;margin-top:8px;font-size:12px;color:var(--ink-3)}
/* settings: one Save for staged changes + the result line */
.save-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.save-msg{font-size:14.5px;line-height:1.45;color:var(--ink-2)}
.save-msg.error{color:var(--danger)}
.save-msg .link{white-space:nowrap}

/* settings */
.set{display:grid;grid-template-columns:220px 1fr;gap:20px 48px;padding:28px 0;border-top:1px solid var(--line)}
.set:first-of-type{border-top:0;padding-top:8px}
.set h2{font-size:17px;font-weight:800;letter-spacing:-.01em}
.set .why{margin-top:6px;font-size:14px;color:var(--ink-3);max-width:26ch}
.target{display:grid;grid-template-columns:120px 1fr;gap:18px;align-items:center}
.target .input{text-align:center;font-size:20px;font-weight:600;font-family:var(--font-display);min-height:54px}
input[type=range].range{width:100%;height:44px;margin:0;accent-color:var(--accent);background:transparent;cursor:pointer}
input[type=range].range:focus-visible{outline-offset:-3px}   /* ring inside the 44px box, clear of the 50 / 1000 labels */
.field-msg{display:block;margin-top:10px;font-size:13.5px;font-weight:600;color:var(--danger)}
.range-x{display:flex;justify-content:space-between;font-size:12px;color:var(--ink-3);margin-top:-6px}
.split{
  display:inline-flex;align-items:center;gap:10px;margin-top:14px;padding:10px 14px;border-radius:12px;
  background:var(--bg-sunk);font-size:14.5px;color:var(--ink-2);flex-wrap:wrap;
}
.split b{color:var(--ink)}
.split .arrow{color:var(--ink-3)}
.levels{display:grid;gap:8px}
.lvl{display:flex;align-items:center;gap:14px;min-height:56px;padding:8px 14px 8px 10px;border:1px solid var(--line);border-radius:14px;background:var(--bg-elev);cursor:pointer;position:relative}
.lvl:hover{border-color:var(--ink-3)}
.lvl input{position:absolute;opacity:0;width:0;height:0}
.lvl .n{
  width:38px;height:38px;border-radius:10px;display:grid;place-items:center;flex:none;
  font:700 18px var(--font-display);background:var(--bg-sunk);color:var(--ink-2);
}
.lvl .t{flex:1;min-width:0;line-height:1.35}
.lvl .t b{display:block;font-weight:700}
.lvl .t span{display:block;font-size:14px;color:var(--ink-2)}
.lvl .r{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--line);flex:none;display:grid;place-items:center}
.lvl:has(input:checked),.lvl.on{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.lvl:has(input:checked) .n,.lvl.on .n{background:var(--accent);color:var(--accent-ink)}
.lvl:has(input:checked) .r,.lvl.on .r{border-color:var(--accent);background:var(--accent)}
.lvl:has(input:checked) .r::after,.lvl.on .r::after{content:"";width:7px;height:7px;border-radius:50%;background:var(--accent-ink)}
.acct{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 18px;border:1px solid var(--line);border-radius:14px;background:var(--bg-elev);flex-wrap:wrap}
.acct .em{display:flex;align-items:center;gap:12px;font-size:16px;min-width:0;flex:1 1 auto}
.acct .em > span{min-width:0;overflow-wrap:anywhere}
.acct .em .part{display:inline-block;max-width:100%}   /* a long email breaks before the @ first, then anywhere */
.acct .em svg.i{color:var(--ink-3)}
.acct .btn{gap:8px}
.saved{color:var(--accent)}

/* auth */
.auth-body{flex:1;display:grid;place-items:center;padding:48px 24px}
.auth{width:100%;max-width:420px}
.auth h1{font-family:var(--font-display);font-weight:700;font-size:36px;letter-spacing:-.03em}
.auth .sub{margin:8px 0 28px;color:var(--ink-2)}
.auth .swap{margin-top:22px;text-align:center;font-size:14.5px;color:var(--ink-2)}
.shell{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}

/* landing */
.hero{display:grid;grid-template-columns:1.1fr .9fr;gap:48px;align-items:center;padding:72px calc(var(--gutter) + 64px) 56px}
.hero h1{
  margin-top:18px;font-family:var(--font-display);font-weight:800;
  font-size:60px;line-height:1.04;letter-spacing:-.04em;max-width:13ch;
}
.hero h1 em{font-style:italic;color:var(--accent)}
.hero .lede{margin-top:22px;font-size:19px;line-height:1.55;color:var(--ink-2);max-width:46ch}
.hero .cta{display:flex;gap:12px;margin-top:32px;flex-wrap:wrap}
.hero .fine{margin-top:18px;font-size:13.5px;color:var(--ink-3);display:flex;gap:14px;flex-wrap:wrap}
.hero .fine span{white-space:nowrap}
.hero .fine span::before{content:"·";margin-right:14px;color:var(--line)}
.hero .fine span:first-child::before{content:none;margin:0}
.preview{position:relative;justify-self:end;width:100%;max-width:440px;padding:24px 0 34px 24px}
.preview .ghost{position:absolute;inset:0 24px 34px 0;border-radius:24px;border:1px solid var(--line);background:var(--bg-sunk);transform:rotate(-3.5deg);opacity:.7}
.preview .card{position:relative;padding:0}
.preview .word{font-size:52px;padding:44px 24px 52px}
.preview .answers{margin-top:14px;position:relative}
.preview .ans{min-height:56px;font-size:16px}
.preview .cap{position:relative;margin-top:14px;text-align:center;font-size:13px;color:var(--ink-3)}
.steps{padding:16px calc(var(--gutter) + 64px) 72px;border-top:1px solid var(--line-2)}
.steps .eyebrow{display:block;margin-top:40px}
.steps h2{margin-top:10px;font-family:var(--font-display);font-weight:700;font-size:36px;letter-spacing:-.03em}
.steps ol{list-style:none;padding:0;margin:40px 0 0;display:grid;grid-template-columns:repeat(3,1fr);gap:0}
.steps li{padding:26px 28px 0 0;border-top:1px solid var(--line)}
.steps li + li{padding-left:28px;border-left:1px solid var(--line-2)}
.steps .n{font:800 46px/1 var(--font-display);color:var(--accent);letter-spacing:-.04em}
.steps h3{margin-top:16px;font-size:19px;font-weight:800;letter-spacing:-.01em}
.steps p{margin-top:8px;color:var(--ink-2);font-size:15.5px;max-width:34ch}
.foot{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:24px calc(var(--gutter) + 64px);border-top:1px solid var(--line);font-size:13.5px;color:var(--ink-3);flex-wrap:wrap;margin-top:auto}
.foot .links{display:flex;gap:18px;flex-wrap:wrap}
.foot a{text-decoration:none;color:var(--ink-2)}
.foot a:hover{color:var(--ink)}

/* ---------- tablet ---------- */
@media (max-width:900px){
  .hero{grid-template-columns:1fr;padding:48px 28px}
  .preview{justify-self:start}
  .steps{padding:16px 28px 56px}
  .steps ol{grid-template-columns:1fr}
  .steps li + li{padding-left:0;border-left:0}
  .foot{padding:24px 28px}
  .set{grid-template-columns:1fr}
  .save-set > div:first-child{display:none}
  .tiles,.stats{grid-template-columns:1fr 1fr}
  .tiles .tile:nth-child(3):last-child{grid-column:1/-1}   /* three tiles: 2 + 1 full-width, no empty cell */
  .page{padding:32px 28px 56px}
  .app-nav{padding:12px 24px}
  .session{padding:12px 24px 16px}
  .card-A .word{font-size:80px;padding:64px 32px 76px}
  .card-A .word.long{font-size:58px}
  .card-A .word.xlong{font-size:44px}
  .complete h1{font-size:54px}
}

/* ---------- pinned learn layout (phone + tablet, < 1024px): the card fills what is left of
   the viewport, the answers sit at the bottom under the thumb, reveal content scrolls
   inside the card while Continue stays in the pinned footer ---------- */
@media (max-width:1023px){
  .learn-main{align-items:stretch;justify-content:flex-start;padding:16px 24px 0}
  .learn-col{flex:1 1 auto;max-width:none}
  .learn-col .card{flex:1 1 auto}
  .learn-col .card-A{height:auto}
  .pfoot{margin:0 -24px;padding:16px 24px calc(20px + env(safe-area-inset-bottom));flex:none}
  .learn-col .pfoot{margin-top:0}
  .card-B{padding-bottom:0}
  .card-scroll{padding-bottom:16px}
  .card-B .cont{display:none}
  .learn-col[data-state="reveal"] .pfoot .cont{display:block;margin:0}
}

/* ---------- phone (matches the 375 x 812 frames of the design) ---------- */
@media (max-width:767px){
  .app-nav{padding:calc(8px + env(safe-area-inset-top)) 16px 8px;gap:12px}
  .app-nav .wordmark .a,.app-nav .wordmark .b{font-size:17px}
  .nav{gap:0}
  .nav a{padding:0 10px;font-size:14px;min-height:44px}
  .nav a.on{display:none}                 /* the current page needs no link at 375px */
  .nav a.phone-hide{display:none}
  .nav a.btn-primary{padding:0 14px;font-size:14px;min-height:44px}
  body[data-page="login"] .nav,body[data-page="register"] .nav{display:none}   /* auth: wordmark only (mockup) */
  .learn .app-nav{border-bottom:0;padding-bottom:0}                             /* learn: no rule, 10px of air */
  .session{padding:0 16px 12px}
  .learn .session{padding-top:10px}
  .counters{gap:6px}
  .counter{padding:6px 6px 5px;text-align:center;border-radius:10px}
  .counter b{font-size:18px}
  .counter span{font-size:9.5px;letter-spacing:.06em}
  .counter span .full{display:none}
  .counter span .short{display:inline}
  .bar{margin-top:10px}

  .learn-main{padding:6px 16px 0}
  .card-head{padding:14px 16px 0}
  .card-head .lvl-tag{font-size:12px}
  /* 64px is the phone maximum: learn.js (fitWord) measures the word and scales a long one down
     to the card width instead of the fixed long / xlong steps used on tablet and desktop */
  .learn-col .card-A .word,.learn-col .card-A .word.long,.learn-col .card-A .word.xlong{font-size:64px;padding:12px 20px 48px}
  .pfoot{margin:0 -16px;padding:14px 16px calc(16px + env(safe-area-inset-bottom))}
  .answers{gap:10px}
  .ans{min-height:64px;font-size:17px;border-radius:14px}
  .card-B .word{font-size:42px;padding:18px 20px 8px}
  .card-B .word.long{font-size:34px}
  .card-B .word.xlong{font-size:26px}
  .reveal{padding:0 20px}
  .pron .cap{display:none}
  .ipa{font-size:18px}
  .zh{font-size:18px;margin-top:12px}
  .def{margin-top:14px;padding-top:14px;font-size:15px}
  .example{font-size:16px}
  .again{margin:12px 20px 0;font-size:13px}
  .again .full{display:none}
  .again .short{display:inline}
  .cont .btn{min-height:60px;border-radius:14px}

  .complete .body{padding:32px 20px 40px}
  .complete h1{font-size:46px}
  .complete h1 small{font-size:18px}
  .stats{margin-top:28px}
  .stat b{font-size:26px}
  .tomorrow{font-size:18px}

  .page{padding:24px 16px 48px}
  .page h1{font-size:32px}
  .days{gap:2px}                                  /* 14 columns of ~22.6px: "1.2k" at 9.5px still fits */
  .day .n{font-size:9.5px;letter-spacing:-.04em}
  .tile b{font-size:32px}
  .target{grid-template-columns:100px 1fr;gap:14px}
  .auth-body{padding:36px 20px 24px;align-items:start}
  .auth h1{font-size:30px}
  .hero{padding:36px 20px 40px}
  .hero h1{font-size:40px}
  .hero .lede{font-size:17px}
  .hero .fine{gap:6px 16px}
  .hero .fine span::before{content:none;margin:0}   /* no separator dots on phones: nothing to orphan on a wrap */
  .preview{max-width:100%;padding:16px 0 26px 16px}
  .preview .ghost{inset:0 16px 26px 0}
  .preview .word{font-size:44px;padding:36px 20px 44px}
  .steps{padding:8px 20px 44px}
  .steps h2{font-size:30px}
  .foot{padding:20px;flex-direction:column;align-items:flex-start;gap:12px}
}
