/* Medina Way app UI. Mobile first; breakpoints: 700px (icon rail), 1100px (labels + right column). */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
body{margin:0;background:var(--bg);color:var(--ink);font:600 16px/1.5 var(--f-body)}
img,svg{max-width:100%}
a{color:inherit}
button{font:inherit;color:inherit}
::placeholder{color:var(--muted);opacity:1}  /* browser grey fails WCAG AA on --sunken (4.05:1) */
[hidden]{display:none!important}
.ar{font-family:var(--f-ar);direction:rtl;unicode-bidi:isolate;font-weight:500}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.skip{position:absolute;left:12px;top:-60px;z-index:100;padding:12px 16px;border-radius:var(--r-sm);background:var(--ink);color:var(--bg);font-weight:800;text-decoration:none}
.skip:focus{top:12px}

/* Buttons: flat face + edge, pressed sinks */
.btn{appearance:none;border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:50px;padding:0 24px;border-radius:var(--r);font:800 15px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;text-decoration:none;
  background:var(--primary);color:var(--on-primary);box-shadow:0 4px 0 var(--primary-dark);transition:transform .06s,box-shadow .06s}
.btn:active{transform:translateY(4px);box-shadow:0 0 0 transparent}
.btn-ghost{background:var(--surface);color:var(--primary-text);border:var(--bw) solid var(--line);box-shadow:0 4px 0 var(--line)}
.btn-gold{background:var(--accent);color:#2A1E00;box-shadow:0 4px 0 var(--accent-dark)}
.btn-flat{background:none;box-shadow:none;color:var(--muted);padding:0 12px}
.btn-danger{background:var(--err-solid);color:#fff;box-shadow:0 4px 0 color-mix(in srgb,var(--err-solid) 65%,#000)}
.btn:disabled,.btn[aria-disabled="true"]{background:var(--locked);color:var(--locked-text);box-shadow:0 4px 0 var(--locked-edge);cursor:default;transform:none}
.btn-block{width:100%}

/* Stats chips */
.stats{display:flex;align-items:center;justify-content:space-between;gap:8px}
.stat{display:inline-flex;align-items:center;gap:6px;min-height:44px;min-width:44px;padding:0 6px;font:800 16px/1 var(--f-body);text-decoration:none;border-radius:var(--r-sm)}
.stat .fa-fire{color:var(--flame)}.stat .fa-coins,.stat .fa-bolt{color:var(--accent)}
.stat.is-off .fa-fire{color:var(--locked-ink)}

/* ---------- App shell ---------- */
.shell{min-height:100dvh}
.top{position:sticky;top:0;z-index:20;height:calc(var(--top-h) + env(safe-area-inset-top,0px));padding:env(safe-area-inset-top,0px) 12px 0;
  background:var(--bg);border-bottom:var(--bw) solid var(--line)}
.top .stats{height:var(--top-h);max-width:600px;margin:0 auto}
.side{display:none}
.main{padding:16px 16px calc(var(--tabs-h) + 32px + env(safe-area-inset-bottom,0px));max-width:632px;margin:0 auto}
.aside{display:none}
.tabs{position:fixed;inset:auto 0 0 0;z-index:20;display:flex;justify-content:space-around;align-items:center;
  height:calc(var(--tabs-h) + env(safe-area-inset-bottom,0px));padding:0 6px env(safe-area-inset-bottom,0px);background:var(--bg);border-top:var(--bw) solid var(--line)}
.tab{display:grid;place-items:center;width:56px;height:48px;border-radius:var(--r-sm);font-size:22px;color:var(--muted);text-decoration:none;border:var(--bw) solid transparent}
.tab[aria-current="page"]{color:var(--primary-text);border-color:var(--primary);background:var(--surface)}
.tab .label{display:none}
/* Keyboard focus never lands under the sticky top bar, the pinned map banner or the tab bar (WCAG 2.4.11, tools/check_ui.py focus-covered). */
html:has(.shell){scroll-padding:calc(var(--top-h) + env(safe-area-inset-top,0px) + 12px) 0 calc(var(--tabs-h) + env(safe-area-inset-bottom,0px) + 12px)}
html:has([data-map]){scroll-padding-top:calc(var(--top-h) + env(safe-area-inset-top,0px) + var(--unit-h,110px) + 28px)}

@media (min-width:700px){
  .shell{display:grid;grid-template-columns:96px minmax(0,1fr)}
  .tabs{display:none}
  .side{display:flex;flex-direction:column;gap:6px;position:sticky;top:0;height:100dvh;padding:20px 12px;border-right:var(--bw) solid var(--line)}
  .side .brand{display:grid;place-items:center;height:56px;margin-bottom:14px;text-decoration:none}
  .side .brand .logo-mark{height:46px;width:auto}.side .brand .logo-horizontal{display:none}
  .side .tab{width:100%;height:52px}
  .content{min-width:0}
  .top{position:sticky}
  .main{padding-bottom:48px}
  html:has(.shell){scroll-padding-bottom:12px}
}
@media (min-width:1100px){
  .shell{grid-template-columns:256px minmax(0,1fr) 380px}
  .side{padding:22px 16px}
  .side .brand{display:block;height:auto;padding:4px 14px 22px}
  .side .brand .logo-mark{display:none}.side .brand .logo-horizontal{display:block;height:44px;width:auto}
  .side .tab{display:flex;justify-content:flex-start;gap:18px;padding:0 16px;font-size:21px}
  .side .tab .label{display:inline;font:800 15px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase}
  .side .tab i{width:28px;text-align:center}
  .top{display:none}
  .main{padding-top:28px}
  html:has(.shell){scroll-padding-top:12px}html:has([data-map]){scroll-padding-top:calc(var(--unit-h,110px) + 36px)}
  .aside{display:flex;flex-direction:column;gap:18px;position:sticky;top:0;height:100dvh;overflow:auto;padding:22px 24px 22px 8px}
  .aside .stats{padding:0 4px}
}

/* Right column panels (desktop) */
.panel{border:var(--bw) solid var(--line);border-radius:var(--r);padding:18px;background:var(--surface)}
.panel h2{margin:0 0 8px;font:800 19px/1.2 var(--f-display);display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.panel h2 a{display:inline-flex;align-items:center;min-height:44px;margin:-12px 0;font:800 13px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;color:var(--primary-text);text-decoration:none}
.panel p{margin:0;color:var(--muted)}
.quest{display:flex;gap:12px;align-items:center;margin-top:14px}
.quest>i{font-size:24px;color:var(--accent);width:28px;text-align:center}
.quest .q{flex:1;font-weight:700}
.meter{height:14px;border-radius:99px;background:var(--track);margin-top:6px;overflow:hidden}
.meter i{display:block;height:100%;width:0;background:var(--primary);border-radius:99px}
.is-done .meter i,.is-claimed .meter i{background:var(--accent)}

/* ---------- Map ---------- */
.unit{--pin-gap:10px;position:sticky;top:calc(var(--top-h) + env(safe-area-inset-top,0px) + var(--pin-gap));z-index:5;display:flex;justify-content:space-between;align-items:center;gap:12px;
  background:var(--primary);color:#fff;border-radius:var(--r);padding:14px 14px 14px 18px;box-shadow:0 4px 0 var(--primary-dark)}
@media (min-width:1100px){.unit{--pin-gap:20px;top:var(--pin-gap)}}
/* Banners stack (docs/ux-ui.md "Map layers", founder 2026-10-27: the sliding handover is "beaucoup mieux" than the push):
   the sections have no box, so every open banner sticks in the whole map at the same place and the next one slides over the
   pinned one. All open banners share one height (--unit-h, the tallest, set by map.js), so an older banner never peeks out
   under a newer one and titles wrap instead of being cut. A locked lesson (no path) never pins: it scrolls under the pinned
   banner. No page-colour ring around open banners (founder 2026-10-27, screenshot: the white band between the sliding
   banner and the pinned one, "retire le truc blanc") and no page-colour strip above the pin (founder 2026-10-27: it cut
   the top of the first banner and was "plus déstabilisant qu'autre chose"); the short skirt below (::after, 12px, founder
   2026-10-25) fades the nodes out under it. tools/check_map.py checks all of this on every beta deploy and before every promote. */
.lesson{display:contents}
.unit:not(.is-locked){min-height:var(--unit-h,0)}
.unit.is-locked{position:relative;top:auto}  /* top:auto: the sticky offset would push a locked banner 66px down, the last one under the tab bar */
.unit::after{content:"";position:absolute;left:0;right:0;top:calc(100% + 4px);height:12px;background:linear-gradient(var(--bg) 4px,transparent);pointer-events:none}
.unit.is-up{z-index:15}
.unit.is-locked{background:var(--locked);color:var(--locked-text);box-shadow:0 4px 0 var(--locked-edge)}
.unit small{display:block;margin-bottom:4px;font:800 13px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase}
.preview-tag{display:inline-block;margin-inline-start:6px;padding:2px 7px;border-radius:99px;background:rgba(0,0,0,.34);font-size:11px;letter-spacing:.04em;vertical-align:1px}
.unit h2{margin:0;font:800 21px/1.15 var(--f-display)}
.unit h2:has(.ar){line-height:1.6}  /* a title with Arabic (L8 « لِ ») may wrap: room for the harakat (check_ui harakat-lines) */
.unit .guide{flex:0 0 auto;display:grid;place-items:center;width:48px;height:48px;border-radius:var(--r-sm);border:var(--bw) solid rgba(255,255,255,.45);color:inherit;text-decoration:none;font-size:18px}
.unit.is-locked .guide{border-color:var(--locked-edge)}
.lesson+.lesson>.unit{margin-top:28px}
.path{position:relative;display:flex;flex-direction:column;align-items:center;gap:22px;padding:34px 0 26px;list-style:none;margin:0}
.path li{display:flex;justify-content:center;width:100%}

/* Level node: medallion (design-system.md) */
.node{--face:var(--primary);--edge:var(--primary-dark);position:relative;width:70px;height:77px;padding:0;border:0;background:none;cursor:pointer;
  transform:translateX(var(--x,0))}
.node::before{content:"";position:absolute;left:0;top:7px;width:70px;height:70px;border-radius:50%;background:var(--edge)}
.node .face{position:absolute;left:0;top:0;width:70px;height:70px;border-radius:50%;background:var(--face);transition:transform .06s}
.node .face::before{content:"";position:absolute;left:14px;right:14px;top:7px;height:13px;border-radius:50%;background:rgba(255,255,255,.22)}
.node .face::after{content:"";position:absolute;inset:6px;border-radius:50%;border:2px solid rgba(255,255,255,.38)}
.node .n{position:absolute;left:0;top:0;width:70px;height:70px;display:grid;place-items:center;padding-bottom:6px;
  font:700 42px/1 var(--f-ar-num);color:#fff;paint-order:stroke fill;-webkit-text-stroke:5px var(--edge);text-shadow:0 3px 0 var(--edge);transition:transform .06s}
.node:active .face,.node:active .n{transform:translateY(5px)}
.node[data-state="done"]{--face:var(--accent);--edge:var(--accent-dark)}
/* a skipped step stays playable but only the step in progress wears the current colours (docs/ux-ui.md) */
.node[data-state="open"]{--face:var(--locked);--edge:var(--locked-edge)}
.node[data-state="open"] .n{color:var(--primary);-webkit-text-stroke:0;text-shadow:none}
.node[data-state="locked"]{--face:var(--locked);--edge:var(--locked-edge);cursor:pointer}
.node[data-state="locked"] .n{color:var(--locked-ink);-webkit-text-stroke:0;text-shadow:none}
.node[data-state="locked"] .face::after{border-color:rgba(255,255,255,.5)}
.node.jar{--face:var(--flame);--edge:var(--flame-dark)}
.node.jar .face::after{display:none}
.node.jar .n{font-size:30px;padding:0;-webkit-text-stroke:0;text-shadow:none}
.node.jar[data-state="locked"]{--face:var(--locked);--edge:var(--locked-edge)}
.node.jar[data-state="locked"] .n{color:var(--locked-ink)}
.node.jar[data-state="done"]{--face:var(--accent);--edge:var(--accent-dark)}
.node.jar[data-state="open"] .n{color:#fff} /* the jar icon stays white on its orange face (design-system.md) */
[data-map]:has(.pop) .start{visibility:hidden}
.main[data-hydrating]{opacity:0;animation:reveal 0s 3.2s forwards}
.main{transition:opacity .12s}
@keyframes reveal{to{opacity:1}}
li.is-current{margin:52px 0 12px}
.ring{position:absolute;left:50%;top:38.5px;width:104px;height:111px;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:conic-gradient(var(--primary) 0 var(--p,0%),var(--line) 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 8px),#000 calc(100% - 7px));mask:radial-gradient(farthest-side,transparent calc(100% - 8px),#000 calc(100% - 7px))}
.start{position:absolute;left:50%;bottom:calc(100% + 34px);transform:translateX(-50%);white-space:nowrap;background:var(--surface);color:var(--primary-text);pointer-events:auto;cursor:pointer;
  border:var(--bw) solid var(--line);border-radius:var(--r-sm);padding:9px 13px;font:800 13px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;box-shadow:0 3px 0 var(--line)}
.start::before,.start::after{content:"";position:absolute;left:50%;transform:translateX(-50%);border:8px solid transparent;border-bottom:0}
.start::before{top:100%;border-top-color:var(--line);margin-top:2px}
.start::after{top:100%;border-top-color:var(--surface);border-width:7px 7px 0}
@media (prefers-reduced-motion:no-preference){.start{animation:bob 1.6s ease-in-out infinite}}
@keyframes bob{50%{transform:translate(-50%,-4px)}}

/* Node popover (Duolingo-like card under the node) */
.pop{--pop-bg:var(--primary);position:absolute;z-index:6;width:min(320px,calc(100vw - 32px));background:var(--pop-bg);color:#fff;border-radius:var(--r);padding:16px;box-shadow:0 4px 0 var(--primary-dark)}
.pop.is-locked{--pop-bg:var(--surface);background:var(--surface);color:var(--ink);border:var(--bw) solid var(--line);box-shadow:0 4px 0 var(--line)}
.pop.is-done{--pop-bg:var(--accent);background:var(--accent);color:#2A1E00;box-shadow:0 4px 0 var(--accent-dark)}
.pop::before{content:"";position:absolute;top:-9px;left:var(--arrow,50%);margin-left:-9px;border:9px solid transparent;border-top:0;border-bottom-color:var(--pop-bg)}
.pop h3{margin:0 0 4px;font:800 19px/1.2 var(--f-display)}
.pop p{margin:0 0 14px}  /* no opacity: white on --primary is 4.7:1, at .9 it fell to 4.15 (WCAG AA) */
.pop .btn{width:100%;background:#fff;color:var(--primary);box-shadow:0 4px 0 rgba(0,0,0,.18)}
.pop.is-done .btn{color:#8A6700}
.pop.is-locked .btn{background:var(--locked);color:var(--locked-text);box-shadow:0 4px 0 var(--locked-edge)}
.pop.is-locked .btn.btn-gold{background:var(--accent);color:#2A1E00;box-shadow:0 4px 0 var(--accent-dark)}

/* ---------- Exercise player ---------- */
.player{display:flex;flex-direction:column;height:100dvh;overflow:hidden;overflow:clip;max-width:640px;margin:0 auto}
.player-top{display:grid;grid-template-columns:44px minmax(0,1fr) auto;align-items:center;gap:8px 14px;padding:calc(12px + env(safe-area-inset-top,0px)) 16px 12px}
.quit{display:grid;place-items:center;width:44px;height:44px;margin-left:-8px;border:0;background:none;color:var(--muted);font-size:24px;cursor:pointer;text-decoration:none}
.progress{flex:1;height:20px;border-radius:99px;background:var(--track);overflow:hidden}
.progress i{display:block;height:100%;width:0;background:var(--primary);border-radius:99px;position:relative;transition:width .35s ease}
.progress-count{font-size:14px;font-weight:800;color:var(--muted);font-variant-numeric:tabular-nums;min-width:3.2em;text-align:end}
.progress i::after{content:"";position:absolute;left:10px;right:10px;top:4px;height:4px;border-radius:9px;background:rgba(255,255,255,.35)}
.combo{display:flex;align-items:center;gap:5px;min-width:44px;font:800 15px/1 var(--f-body);color:var(--ink)}
.combo i{color:var(--accent)}
.combo.is-off{color:var(--muted)}
.combo.is-off i{color:var(--locked-text)}
.ex{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px 16px 24px;display:flex;flex-direction:column}
.ex-kicker{margin:0 0 6px;font:800 13px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;color:var(--primary-text)}
.ex-q{margin:0 0 20px;font:800 24px/1.2 var(--f-display)}
.prompt{display:flex;align-items:center;gap:12px;margin-bottom:22px}
.bubble{margin-left:auto;border:var(--bw) solid var(--line);border-radius:var(--r);padding:6px 18px;background:var(--surface);font-size:34px;line-height:1.75}
.prompt-fr{font:800 22px/1.3 var(--f-display)}
.opts{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.opt{display:flex;align-items:center;gap:14px;width:100%;min-height:60px;padding:10px 14px;text-align:start;cursor:pointer;
  border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface);box-shadow:0 3px 0 var(--line);font:700 17px/1.3 var(--f-body)}
.opt kbd{flex:0 0 auto;display:none;place-items:center;width:28px;height:28px;border:var(--bw) solid var(--line);border-radius:8px;font:800 13px/1 var(--f-body);color:var(--muted)}
/* Digit hints only where a physical keyboard is likely (docs/ux-ui.md). */
@media (hover:hover) and (pointer:fine){.opt kbd{display:grid}}
@media not ((hover:hover) and (pointer:fine)){.choice[data-keys]{display:none}}  /* the shortcuts setting only where the hints show */
/* physical left: .ar is direction:rtl, so its inline-start is its right side (app round 2026-10-29: options sat on the left) */
.opt .ar{font-size:28px;line-height:1.6;margin-left:auto}
.opt[aria-checked="true"]{border-color:var(--primary);box-shadow:0 3px 0 var(--primary)}
.opt[aria-checked="true"] kbd{border-color:var(--primary);color:var(--primary-text)}
.opt.is-right{border-color:var(--ok);background:var(--ok-bg);box-shadow:0 3px 0 var(--ok)}
.opt.is-right kbd{border-color:var(--ok);color:var(--ok)}
.opt.is-wrong{border-color:var(--err);background:var(--err-bg);box-shadow:0 3px 0 var(--err)}
/* Block flow, not flex: a long answer wraps line by line and the caret follows the last letter. */
.answer{flex-shrink:0;min-height:76px;padding:6px 4px;margin-bottom:14px;border-bottom:var(--bw) solid var(--line);direction:rtl;text-align:right;overflow-wrap:anywhere}
.answer .ar{font-size:38px;line-height:1.7;vertical-align:middle}
.answer.is-long .ar{font-size:30px;line-height:1.75}
.caret{display:inline-block;vertical-align:middle;width:2px;height:38px;margin-inline-start:4px;background:var(--primary)}
@media (prefers-reduced-motion:no-preference){.caret{animation:blink 1s steps(1) infinite}}
@keyframes blink{50%{opacity:0}}
/* Compact 11-column board at every width (founder choice): four low rows that read as a keyboard, not a tall grid. */
.kb{direction:ltr;display:grid;grid-template-columns:repeat(11,1fr);gap:4px;margin-top:auto}
.key{height:46px;min-width:0;padding:0;border:var(--bw) solid var(--line);border-radius:10px;background:var(--surface);box-shadow:0 2px 0 var(--line);cursor:pointer;
  font:500 22px/1 var(--f-ar);color:var(--ink)}
.key:active{transform:translateY(2px);box-shadow:none}
.key.wide{grid-column:span 2;font:800 13px/1 var(--f-body);letter-spacing:.04em}
.key.space{grid-column:span 5}
.key.row-start{grid-column-start:1}  /* each KEYBOARD row starts a new line, like the physical layout */
/* Short screens (360x640 phones, 2026-10-27): the whole keyboard fits above the action bar without scrolling the exercise
   (its last row, with delete, hid under "Vérifier"). tools/check_keyboard.py checks it on every beta deploy. */
@media (max-height:700px){.answer{min-height:56px;margin-bottom:8px}.answer .ar{font-size:32px;line-height:1.5}
  .hint-row{margin:-4px 0 6px}.ex{padding-bottom:10px}.key{height:44px}}
@media (max-height:630px){.ex-hint{display:none}}
.marks{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:0;max-width:420px;width:100%;margin-inline:auto}
.mark{min-width:0;height:60px;padding:0;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 3px 0 var(--line);cursor:grab;touch-action:none;
  font:500 52px/1 var(--f-ar);color:var(--ink)}
.mark:active{transform:translateY(3px);box-shadow:none}
/* The word is one unbroken inline run, so the browser keeps the letters joined. No padding or border on the letters: they would cut the joins. */
.letters{display:block;direction:rtl;text-align:center;margin:auto 0;padding:22px 12px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface);
  font:500 68px/2 var(--f-ar);color:var(--ink);overflow-wrap:anywhere}
@media (max-width:480px){.letters{font-size:60px;padding:14px 8px}}
.fixed{color:var(--muted)}
.slot{cursor:pointer;color:var(--ink);border-radius:8px}
.slot.is-target{background:var(--ok-bg);box-shadow:inset 0 -4px 0 var(--primary)}
.slot.is-wrong,.slot.is-target.is-wrong{background:var(--err-bg);color:var(--err);box-shadow:inset 0 -4px 0 var(--err)}
.slot.is-right,.slot.is-target.is-right{color:var(--ok);box-shadow:inset 0 -4px 0 var(--ok)}
.words{display:flex;flex-wrap:wrap;gap:8px;direction:rtl;justify-content:center;margin-bottom:22px}
.word{min-height:52px;padding:4px 16px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 3px 0 var(--line);cursor:pointer;font:500 28px/1.6 var(--f-ar)}
.word[aria-pressed="true"]{border-color:var(--err);background:var(--err-bg)}
.word.is-right{border-color:var(--ok);background:var(--ok-bg);box-shadow:0 3px 0 var(--ok)}
.cloze{font-size:34px;line-height:1.9;text-align:center;margin:6px 0 24px}
.cloze .gap{display:inline-block;min-width:110px;border-bottom:3px solid var(--primary);margin:0 6px}
.intro-card{border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface);padding:18px;margin-bottom:16px}
.intro-items{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.intro-items li{display:flex;flex-direction:row-reverse;justify-content:space-between;align-items:center;gap:16px;border:var(--bw) solid var(--line);border-radius:var(--r);padding:8px 16px;background:var(--surface)}
.intro-items .ar{font-size:30px}
.flag-unverified{display:inline-flex;align-items:center;gap:6px;margin-bottom:12px;padding:4px 10px;border-radius:99px;background:var(--err-bg);color:var(--err);font:800 12px/1.4 var(--f-body)}
.player-foot{position:sticky;bottom:0;padding:14px 16px calc(18px + env(safe-area-inset-bottom,0px));border-top:var(--bw) solid var(--line);background:var(--bg)}
.player-foot .row{display:flex;gap:12px;width:100%;max-width:640px;box-sizing:border-box;margin:0 auto}
.player-foot .btn{flex:1;min-width:0;padding-inline:12px}
.sheet{position:sticky;bottom:0;padding:16px 16px calc(18px + env(safe-area-inset-bottom,0px));background:var(--ok-bg);color:var(--ok)}
.sheet.is-wrong{background:var(--err-bg);color:var(--err)}
@media (prefers-reduced-motion:no-preference){.sheet{animation:up .18s ease-out}}
@keyframes up{from{transform:translateY(100%)}}
.sheet .sheet-title{margin:0 0 2px;display:flex;align-items:center;gap:10px;font:800 22px/1.2 var(--f-display)}
.sheet-alt{margin:10px 0 0!important;text-align:center}
.sheet-alt .btn-flat{color:inherit;width:auto;background:none;box-shadow:none}
.sheet p{margin:0 0 14px;font-weight:700}
.sheet .ar{font-size:26px;line-height:1.7}  /* the answer can wrap at 360 px: harakat of line 2 ran 5 px into line 1 (docs/ux-ui.md "UI audit") */
.sheet .btn{width:100%;background:var(--ok);color:var(--bg);box-shadow:0 4px 0 color-mix(in srgb,var(--ok) 65%,#000)}
.sheet.is-wrong .btn{background:var(--err-solid);color:#fff;box-shadow:0 4px 0 color-mix(in srgb,var(--err-solid) 65%,#000)}
.player.is-finished .hk-btn,.player.is-finished .combo{visibility:hidden}  /* end screen: nothing left to toggle or count */
.done-screen{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:24px 16px}
/* End of step: the map medallion (green done, gold for a perfect run = reward), ink title, one hero number, one sentence. No stat tiles. */
.done-badge{position:relative;display:grid;place-items:center;width:96px;height:96px;margin-bottom:18px;border-radius:50%;font-size:40px;color:#fff;
  background:var(--primary);box-shadow:0 7px 0 var(--primary-dark)}
.done-badge.is-gold{background:var(--accent);box-shadow:0 7px 0 var(--accent-dark);color:#5A4300}
.done-screen h1{margin:0 0 6px;font:800 30px/1.1 var(--f-display);color:var(--ink)}
.done-hero{margin:4px 0 8px;font:800 24px/1 var(--f-display);color:var(--muted)}
.done-hero b{font-size:56px;color:var(--ink)}
.done-line{max-width:420px;margin:0;color:var(--muted);font-weight:700;line-height:1.45}
.done-share{min-height:44px;color:var(--primary-text)}
.done-recap{width:100%;max-width:420px;margin-top:20px;text-align:start}
.done-recap summary{min-height:44px;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;font-weight:800;color:var(--primary-text);list-style:none}
.done-recap summary::-webkit-details-marker{display:none}
.done-recap summary::after{content:"";width:8px;height:8px;border:solid currentColor;border-width:0 2px 2px 0;transform:translateY(-2px) rotate(45deg);transition:transform var(--dur-2)}
.done-recap[open] summary::after{transform:translateY(2px) rotate(-135deg)}
.done-recap ol{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:10px}
.done-recap li{padding:12px 14px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.done-recap p{margin:0;line-height:1.5}
.recap-right{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;font-weight:800;color:var(--ink)}
.recap-right i{color:var(--ok)}
.recap-given{color:var(--muted);font-weight:700}
.recap-given .ar{text-decoration:line-through;text-decoration-thickness:1px}
.recap-why{margin-top:4px!important;color:var(--muted);font-size:15px}
.panel .btn-block{margin-top:14px}
.ex-help{margin:-10px 0 14px;color:var(--muted)}
.prompt-fr.is-under{text-align:center;margin:-10px 0 22px}
.prompt-fr.is-gap{margin:0 0 18px}
.ex-q:focus{outline:none}
.intro-card p{margin:0}
.hint-row{display:flex;justify-content:flex-end;margin:-6px 0 12px}
.hint-btn{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 2px 0 var(--line);cursor:pointer;font:800 13px/1 var(--f-body);color:var(--ink)}
.hint-btn i{color:var(--accent)}
/* "Pourquoi ?" after a wrong answer: a quiet link-like button in the sheet; the explanation reads in ink, not in red. */
.why{margin:-4px 0 14px}
.why-btn{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;border:var(--bw) solid color-mix(in srgb,currentColor 35%,transparent);border-radius:var(--r-sm);background:var(--bg);color:inherit;cursor:pointer;font:800 15px/1 var(--f-body)}
.why-text,.why-q,.why-note,.why-wait{margin:0 0 8px!important;color:var(--ink);font-weight:600!important;line-height:1.5}
.why-q{color:var(--muted)}
.why-wait,.why-note{display:flex;align-items:center;gap:8px;color:inherit}
.why-text .ar,.why-q .ar{font-size:22px;line-height:1.3}
.why-actions{display:flex;flex-wrap:wrap;gap:4px 18px}
.why-link{min-height:44px;padding:0;border:0;background:none;color:inherit;cursor:pointer;font:800 14px/1.2 var(--f-body);text-decoration:underline;text-underline-offset:3px}
.why-done{display:inline-flex;align-items:center;min-height:44px;font:700 14px/1.2 var(--f-body)}
.why-ask{display:flex;gap:8px}
.why-ask input{flex:1;min-width:0;min-height:44px;padding:0 12px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--bg);color:var(--ink);font:600 16px/1.2 var(--f-body)}
.why-send{min-height:44px;padding:0 16px;border:0;border-radius:var(--r-sm);background:var(--err-solid);color:#fff;cursor:pointer;font:800 15px/1 var(--f-body)}
/* Player, wide screens: full-width footer band, content row on the 640px column, action button on the right. */
@media (min-width:700px){
  .player{max-width:none}
  .player-top,.ex{width:100%;max-width:640px;margin-inline:auto}
  .player-top{padding-top:28px}
  .ex{padding-top:24px}
  .player-foot,.sheet{padding:22px 24px 26px}
  .player-foot .row{max-width:640px;justify-content:flex-end}
  .sheet{padding-inline:max(24px,calc((100vw - 640px)/2))}
  .player-foot .btn{flex:0 0 auto;min-width:180px}
  .sheet{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:24px}
  .sheet>*{max-width:none}
  .sheet .sheet-title,.sheet>p,.sheet>.why{grid-column:1}
  .sheet>.why{margin:12px 0 0}
  .sheet .btn,.sheet>.row{grid-column:2;grid-row:1/span 2;width:auto;min-width:180px}
  .sheet>p{margin:0}
  .sheet-alt{grid-column:2!important}
  .kb{max-width:560px;margin-inline:auto;width:100%}
}
/* Auth pages */
.auth{min-height:100dvh;display:flex;flex-direction:column}
.auth-top{display:flex;justify-content:space-between;align-items:center;padding:calc(12px + env(safe-area-inset-top,0px)) 16px 0;max-width:520px;width:100%;margin:0 auto}
.auth-switch{min-height:44px;padding:0 16px;font-size:13px}
.auth-card{width:100%;max-width:440px;margin:0 auto;padding:20px 16px 40px}
.auth-card h1{margin:12px 0 8px;font:800 30px/1.1 var(--f-display);text-align:center}
.auth-lead{margin:0 0 22px;text-align:center;color:var(--muted)}
.auth-card h1+form{margin-top:22px}
.field{margin-bottom:14px}
.field label{display:block;margin:0 0 6px;font:800 14px/1.2 var(--f-body)}
.field input{width:100%;min-height:52px;padding:0 16px;border:var(--bw) solid var(--line-strong);border-radius:var(--r-sm);background:var(--sunken);color:var(--ink);font:700 17px/1 var(--f-body)}
.field textarea{display:block;width:100%;min-height:168px;padding:14px 16px;border:var(--bw) solid var(--line-strong);border-radius:var(--r-sm);background:var(--sunken);color:var(--ink);font:600 17px/1.45 var(--f-body);resize:vertical}
.field textarea:focus{border-color:var(--ink);background:var(--surface)}
.field.has-error textarea{border-color:var(--err)}
.field input:focus{border-color:var(--ink);background:var(--surface)}
.field.has-error input{border-color:var(--err)}
.field-error,.form-error{margin:6px 0 0;color:var(--err);font-weight:700;font-size:14px}
.form-error{margin:0 0 14px;padding:10px 14px;border-radius:var(--r-sm);background:var(--err-bg)}
.auth-card form .btn{margin-top:8px}
.auth-link{text-align:center;margin:18px 0 0}
.auth-details{margin:18px 0 0}
.auth-details summary{cursor:pointer;min-height:44px;display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--primary-text)}
.auth-details form{margin-top:12px}
.auth-link a{display:inline-flex;align-items:center;min-height:44px;font-weight:800;color:var(--primary-text);text-decoration:none}
.auth-or{display:flex;align-items:center;gap:14px;margin:22px 0;color:var(--muted);font-weight:800;font-size:13px;text-transform:uppercase;letter-spacing:.06em}
.auth-or::before,.auth-or::after{content:"";flex:1;height:2px;background:var(--line)}
.auth-legal{margin:22px 0 0;text-align:center;color:var(--muted);font-size:14px}
.auth-messages{list-style:none;margin:0 0 16px;padding:10px 14px;border-radius:var(--r-sm);background:var(--ok-bg);color:var(--ok);font-weight:700}
.auth-card p{max-width:none}
.auth-card form p, .auth-card form ul{margin:0 0 12px}
/* Reviews tab */
.review-hero{text-align:center;padding:28px 18px 22px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.review-glass{display:grid;place-items:center;width:84px;height:84px;margin:0 auto 14px;border-radius:50%;background:var(--accent);box-shadow:0 6px 0 var(--accent-dark);color:#fff;font-size:36px}
.review-hero h1{margin:0 0 6px;font:800 26px/1.15 var(--f-display)}
.review-sub{margin:0 auto 20px;max-width:34ch;color:var(--muted)}
.review-facts{margin:16px auto 0;max-width:40ch;color:var(--muted);font-size:15px;font-weight:700;line-height:1.45}
.review-note{margin:18px 4px 0;color:var(--muted);font-size:14px;text-align:center}
/* Reviews > Mots appris (docs/ux-ui.md "Mots appris"): one hero number, lesson chips, groups by memory state, due first */
.to-words{display:flex;align-items:center;gap:12px;min-height:64px;margin-top:14px;padding:12px 16px;border:var(--bw) solid var(--line);border-radius:var(--r);
  background:var(--surface);box-shadow:0 4px 0 var(--line);text-decoration:none;transition:transform .06s,box-shadow .06s}
.to-words:active{transform:translateY(4px);box-shadow:0 0 0 transparent}
.to-words span{flex:1;min-width:0}
.to-words b{display:block;font:800 18px/1.2 var(--f-display)}
.to-words small{display:block;margin-top:2px;color:var(--muted);font-size:15px;font-weight:700}
.to-words i{color:var(--muted);font-size:18px}
.words-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:-6px 0 10px}
.back{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin-left:-6px;padding:0 6px;border-radius:var(--r-sm);font:800 16px/1 var(--f-body);color:var(--muted);text-decoration:none}
.words-hero{padding:18px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.words-hero h1{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:0 0 6px;font:800 20px/1.2 var(--f-display);color:var(--muted)}
.words-hero h1 b{font-size:44px;line-height:1;color:var(--ink)}
.words-hero h1 b:empty{display:none}
.words-hero h1 b:empty+span{color:var(--ink)} /* no count yet: the label is the title */
.words-hero p{margin:0;color:var(--muted);font-weight:700;line-height:1.45}
.words-hero .btn{margin-top:16px}
.lesson-filter{display:flex;gap:8px;margin:18px -16px 0;padding:0 16px 4px;overflow-x:auto;scrollbar-width:none}
.lesson-filter::-webkit-scrollbar{display:none}
.chip{flex:none;min-height:44px;padding:0 16px;border:var(--bw) solid var(--line);border-radius:99px;background:var(--surface);cursor:pointer;
  font:800 15px/1 var(--f-body);color:var(--ink);transition:border-color var(--dur-1) var(--ease-std),box-shadow var(--dur-1) var(--ease-std)}
.chip[aria-pressed="true"]{border-color:var(--primary);box-shadow:inset 0 0 0 1px var(--primary)}
.w-group{margin-top:26px}
.w-group h2{margin:0;font:800 20px/1.2 var(--f-display)}
.w-group>p{margin:2px 0 10px;color:var(--muted);font-size:15px;font-weight:700}
.w-list{list-style:none;margin:0;padding:0;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.w-row{display:grid;grid-template-columns:20px minmax(0,1fr) auto;grid-template-areas:"bars txt ar";align-items:center;gap:4px 14px;min-height:68px;padding:10px 16px}
.w-row+.w-row{border-top:var(--bw) solid var(--line)}
.w-row.is-sentence{grid-template-columns:20px minmax(0,1fr);grid-template-areas:"ar ar" "bars txt"}
.is-sentence .w-ar{justify-self:end}
.w-bars{grid-area:bars;display:flex;align-items:flex-end;gap:2px;height:20px}
.w-bars i{width:4px;height:8px;border-radius:2px;background:var(--track)}
.w-bars i:nth-child(2){height:12px}.w-bars i:nth-child(3){height:16px}.w-bars i:nth-child(4){height:20px}
.w-bars[data-level="1"] i:nth-child(-n+1),.w-bars[data-level="2"] i:nth-child(-n+2),.w-bars[data-level="3"] i:nth-child(-n+3){background:var(--primary)}
.w-bars[data-level="4"] i{background:var(--accent)}
.w-ar{grid-area:ar;font-size:28px;line-height:1.5;color:var(--ink)}
.is-sentence .w-ar{font-size:22px;line-height:1.7}
.w-txt{grid-area:txt;min-width:0}
.w-txt b{display:block;font-size:17px;font-weight:800;line-height:1.3}
.w-txt small{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;margin-top:4px;color:var(--muted);font-size:14px;font-weight:700}
.w-txt .badge{padding:1px 8px}
.offline{min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:24px 16px;text-align:center}
.offline>i{font-size:40px;color:var(--muted);margin-bottom:10px}
.offline h1{margin:0;font:800 26px/1.2 var(--f-display)}
.offline p{max-width:38ch;color:var(--muted);margin:6px 0 18px}
.offline [data-lang]{display:flex;flex-direction:column;align-items:center;gap:12px}.offline [data-lang][hidden]{display:none}
.offline .offline-en{margin-top:22px;font-size:14px}
/* Leagues */
.league-head{text-align:center;padding:8px 0 20px;border-bottom:var(--bw) solid var(--line)}
.tiers{display:flex;justify-content:center;gap:12px;list-style:none;margin:0 0 16px;padding:0}
.tier{display:grid;place-items:center;width:52px;height:58px;font-size:40px;color:var(--locked-edge)}
.tier.is-current{transform:scale(1.25);margin:0 8px}
.tier-bronze:not(.is-locked){color:#B5652E}.tier-argent:not(.is-locked){color:#8E99A3}.tier-or:not(.is-locked){color:#E2A800}
.tier-rubis:not(.is-locked){color:#C0263D}.tier-diamant:not(.is-locked){color:#2E9DBF}
.tier.is-locked{width:44px;height:44px;align-self:center;font-size:18px;color:var(--locked-text);border:var(--bw) dashed var(--line-strong);border-radius:50%}
.league-head h1{margin:6px 0 6px;font:800 26px/1.15 var(--f-display)}
.league-head p{margin:0 auto 14px;max-width:38ch;color:var(--muted)}
.board{list-style:none;margin:8px 0 0;padding:0}
.row{display:flex;align-items:center;gap:12px;min-height:64px;padding:8px 10px;border-radius:var(--r)}
.row.is-me{background:var(--ok-bg)}
.rank{width:28px;text-align:center;font:800 17px/1 var(--f-body);color:var(--muted)}
.zone-up .rank{color:var(--ok)}.zone-down .rank{color:var(--err)}
.avatar{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;background:var(--sunken);border:var(--bw) solid var(--line);font:800 18px/1 var(--f-display);color:var(--muted)}
.who{flex:1;font-weight:800;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.who small{color:var(--muted);font-weight:700}
.xp{font-weight:800;color:var(--muted)}
.zone-line{display:flex;align-items:center;justify-content:center;gap:8px;margin:6px 0;padding:8px;border-top:var(--bw) dashed var(--line);border-bottom:var(--bw) dashed var(--line);
  font:800 12px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;color:var(--ok)}
.row.is-empty{justify-content:center;color:var(--muted)}
.zone-line.down{color:var(--err)}
/* Shop and quests */
.page-title{margin:4px 0 14px;font:800 24px/1.2 var(--f-display)}
h2.page-title{margin-top:32px}
.quests{list-style:none;margin:0;padding:0;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.quests li{display:flex;align-items:center;gap:14px;padding:16px}
.quests li+li{border-top:var(--bw) solid var(--line)}
.quests li>i{width:32px;text-align:center;font-size:26px;color:var(--accent)}
.quests .q{flex:1;min-width:0}
.quests .q b{display:block;font-weight:800}
.quests .q small{display:block;margin-top:4px;color:var(--muted);font-weight:700}
.quests .btn{min-height:44px;padding:0 14px;font-size:13px}
.claimed{display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:var(--ok-bg);color:var(--ok)}
.is-claimed .meter i{background:var(--ok)}
.hint-line{margin:10px 4px 0;color:var(--muted);font-size:14px}
.shop-item{display:grid;grid-template-columns:64px minmax(0,1fr);align-items:center;gap:6px 16px;padding:16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
/* Plain icon, no tinted square behind it (CLAUDE.md blacklist: icon in a pastille). */
.shop-ico{display:grid;place-items:center;width:64px;height:64px;color:#2E86AB;font-size:34px}
:root[data-theme="dark"] .shop-ico{color:#7CC6E3}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .shop-ico{color:#7CC6E3}}
.shop-txt{flex:1;min-width:0}
.shop-txt h3{margin:0 0 2px;font:800 18px/1.2 var(--f-display)}
.shop-txt p{margin:0;color:var(--muted);font-size:15px}
.shop-txt small{display:block;margin-top:6px;font-weight:800;color:var(--muted)}
.shop-item .btn{grid-column:2;justify-self:start;min-width:120px}
@media (min-width:560px){.shop-item{grid-template-columns:64px minmax(0,1fr) auto}.shop-item .btn{grid-column:3;grid-row:1}}
.shop-item .btn i{color:var(--accent)}
.shop-msg{min-height:24px;margin:12px 4px 0;font-weight:800;color:var(--primary-text)}
.shop-why{grid-column:2;margin:0;color:var(--muted);font-size:14px;font-weight:700}
@media (min-width:560px){.shop-why{grid-column:2/4}}
/* Profile */
.profile-head{display:flex;align-items:center;gap:16px;padding:6px 0 18px}
.avatar.big{width:76px;height:76px;font-size:32px;flex:0 0 auto}
.profile-head h1{margin:0;font:800 26px/1.15 var(--f-display)}
.profile-head p{margin:2px 0 0;color:var(--muted)}
.profile-hero{margin:0 0 22px;padding:18px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.ph-num{display:flex;align-items:baseline;gap:10px;margin:0 0 6px;font:800 18px/1.2 var(--f-display)}
.ph-num b{font-size:44px;line-height:1;color:var(--ink)}
.ph-line{margin:0;color:var(--muted);font-weight:700;line-height:1.45}
.ach-list{list-style:none;margin:0 0 22px;padding:0;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.ach{display:grid;grid-template-columns:28px 1fr;gap:14px;align-items:center;padding:14px 16px}
.ach+.ach{border-top:var(--bw) solid var(--line)}
.ach-icon{color:var(--accent-text);font-size:22px;text-align:center}
.ach.is-locked .ach-icon{color:var(--locked-text)}
.ach-name{margin:0;font-weight:800}
.ach.is-locked .ach-name{color:var(--muted)}
.ach-bar{height:10px;margin:6px 0 4px;border-radius:999px;background:var(--track);overflow:hidden}
.ach-bar i{display:block;height:100%;border-radius:inherit;background:var(--accent)}
.ach-next{margin:0;color:var(--muted);font-size:14px;font-weight:700;line-height:1.4}
.done-ach{display:flex;align-items:center;gap:10px;margin:0;font-weight:800}
.done-ach i{color:var(--accent-text)}
.profile-cta .row-btns{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.profile-cta .row-btns .btn{flex:1 1 160px}
.settings{display:grid;gap:18px}
.choice{border:0;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
@media (min-width:560px){.choice{grid-template-columns:repeat(4,1fr)}}
.choice legend,.choice .legend{grid-column:1/-1;margin:0 0 6px;padding:0;font:800 14px/1.2 var(--f-body)}
.choice label{position:relative;cursor:pointer}
.choice input{position:absolute;opacity:0;inset:0;margin:0;cursor:pointer}
.choice span,.lang-choice button{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:60px;padding:8px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 3px 0 var(--line);font-weight:800;text-align:center}
.choice span small{color:var(--muted);font-weight:700}
.choice input:checked+span,.lang-choice a[aria-current]{border-color:var(--accent);box-shadow:0 3px 0 var(--accent)}
.choice input:focus-visible+span{outline:3px solid var(--focus);outline-offset:2px}
.choice.seg{grid-template-columns:repeat(3,1fr)}
/* The sounds fieldset has no "saved" line under it: keep the 22px rhythm of the form fieldsets before the next one. */
[data-keys],[data-push],[data-measure]{margin-top:22px}
.choice input:disabled+span{opacity:.55;cursor:not-allowed}
.choice.seg span{flex-direction:row;min-height:48px}
.lang-choice{margin-top:18px;grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.lang-choice{display:grid;gap:10px}.lang-choice .legend{grid-column:1/-1;margin:0}.lang-choice a{display:flex;align-items:center;justify-content:center;min-height:48px;padding:8px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 3px 0 var(--line);font:800 15px/1 var(--f-body);color:var(--ink);text-decoration:none}
.plans{display:grid;gap:12px}
@media (min-width:760px){.plans{grid-template-columns:repeat(3,1fr)}.plans.is-member{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}}
.plans.is-solo{max-width:440px}
.plan{position:relative;display:flex;flex-direction:column;border:var(--bw) solid var(--line);border-radius:var(--r);padding:18px;background:var(--surface)}
.plan.is-best{border-color:var(--primary);box-shadow:0 4px 0 var(--primary)}
.plan h3{margin:0;font:800 20px/1.2 var(--f-display)}
.plan .price{margin:2px 0 10px;font-weight:800;color:var(--muted)}
.plan ul{margin:0 0 16px;padding-left:18px;flex:1}
.plan .btn{margin-top:auto;white-space:nowrap}
.plan li{margin:5px 0}
.plan-tag{margin:0;font:800 13px/1 var(--f-body);letter-spacing:.06em;text-transform:uppercase;color:var(--primary-text)}
.account p{margin:0 0 12px;font-weight:800}
.saved{min-height:22px;margin:0;font-weight:800;color:var(--primary-text)}
.paywall-note{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px;margin:0 0 16px;padding:14px 16px;border:var(--bw) solid var(--accent);border-radius:var(--r);background:var(--surface);font-weight:800}
.paywall-note a{display:inline-flex;align-items:center;gap:8px;min-height:44px;color:var(--primary-text);text-decoration:none}
.perk-note{display:flex;align-items:center;gap:10px;margin:0 0 12px;padding:12px 14px;border-radius:var(--r-sm);background:var(--ok-bg);color:var(--ok);font-weight:800}
.referral p{margin:0 0 12px}
.ref-row{display:flex;gap:8px}
.ref-row input{flex:1;min-width:0;min-height:50px;padding:0 12px;border:var(--bw) solid var(--line-strong);border-radius:var(--r-sm);background:var(--sunken);color:var(--ink);font:700 15px/1 var(--f-body)}
.ref-row input:focus{border-color:var(--ink);background:var(--surface)}
.ref-row .btn{flex:0 0 auto}
.ref-count{margin:10px 0 0!important;color:var(--muted);font-weight:700}
/* Weak points + memory stats (Intégrale) */
:root{--chart:#3B8321}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--chart:#58A83A}}
:root[data-theme="dark"]{--chart:#58A83A}
.weak{display:grid;grid-template-columns:56px minmax(0,1fr);align-items:center;gap:8px 14px;margin-top:18px;padding:16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.weak-ico{display:grid;place-items:center;width:56px;height:56px;color:var(--err);font-size:30px}
.weak h2{margin:0;font:800 18px/1.2 var(--f-display)}
.weak p{margin:2px 0 0;color:var(--muted);font-size:15px}
.weak .btn{grid-column:1/-1;justify-self:stretch;min-height:44px;padding:0 14px;letter-spacing:.02em;text-align:center}
@media (min-width:560px){.weak{grid-template-columns:56px minmax(0,1fr) auto}.weak .btn{grid-column:3;justify-self:start}}
.memory{position:relative;margin-top:26px}
.memory.is-locked .memory-body{filter:blur(6px);pointer-events:none;user-select:none}
.lock-over{position:absolute;inset:48px 0 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px;text-align:center}
.lock-over p{margin:0;max-width:30ch;font-weight:800}
.mem-head{margin:0 0 14px;padding:16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.mem-hero{display:flex;flex-wrap:wrap;align-items:flex-end;gap:6px 28px;margin:0 0 6px;font:800 14px/1.2 var(--f-body);color:var(--muted)}
.mem-hero p{display:flex;flex-direction:column;gap:4px;margin:0}
.mem-hero p[hidden]{display:none}
.mem-hero b{font:800 44px/1 var(--f-display);color:var(--ink)}
.mem-hero small{order:-1;flex-basis:100%;font:inherit}
.mem-hero small::first-letter{text-transform:uppercase}
.mem-line{margin:0;color:var(--muted);font-weight:700;line-height:1.45}
.forecast{margin:0;padding:16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.forecast figcaption{margin:0 0 10px;font:800 14px/1.2 var(--f-body);color:var(--muted)}
.bars{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;height:160px;align-items:end;border-bottom:1px solid var(--line)}
.bar-col{position:relative;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%}
.bar{width:min(28px,70%);background:var(--chart);border-radius:4px 4px 0 0}
.bar-val{font:800 13px/1 var(--f-body);color:var(--ink);margin-bottom:4px}
.bar-lab{position:absolute;bottom:-22px;font:700 12px/1 var(--f-body);color:var(--muted);text-transform:capitalize}
.forecast{padding-bottom:34px}
.btn[aria-disabled="true"]{background:var(--locked);color:var(--locked-text);box-shadow:0 4px 0 var(--locked-edge);pointer-events:none}
.unit .guide[aria-disabled="true"]{opacity:.55}
.unit .guide.is-ready{background:var(--accent);border-color:var(--accent);color:#2A1E00}
.sheet-upsell{margin:-6px 0 14px!important;font-size:14px}
.sheet-upsell a{color:inherit;font-weight:800}
@media (min-width:700px){.sheet .sheet-upsell{grid-column:1}}
.founder{color:var(--primary-text);font-size:14px}
.founder-badge{display:inline-flex;align-items:center;gap:6px;vertical-align:middle;margin-left:6px;padding:4px 10px;border-radius:99px;background:var(--ok-bg);color:var(--ok);font:800 13px/1 var(--f-body)}

/* Harakat toggle + translation tiles */
.hk-btn{display:grid;place-items:center;min-width:44px;height:44px;padding:0 6px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 2px 0 var(--line);cursor:pointer;color:var(--ink)}
.hk-btn{display:flex;gap:6px;align-items:center;padding:0 10px}
.hk-btn .ar{font-size:24px;line-height:1.5}
.hk-label{font:700 14px/1 var(--f-body)}
.hk-btn[aria-pressed="false"] .hk-label{text-decoration:line-through}
.combo-l{font:700 13px/1 var(--f-body)}
.hk-btn[aria-pressed="false"]{color:var(--muted);box-shadow:none;background:var(--sunken)}
.hk-btn:disabled{opacity:.45;cursor:not-allowed;text-decoration:none}
.build-answer{min-height:76px;display:flex;flex-wrap:wrap;align-content:flex-start;gap:8px;padding:10px 4px;margin-bottom:22px;border-bottom:var(--bw) solid var(--line);border-top:var(--bw) solid var(--line)}
.build-answer.is-ar,.build-bank.is-ar{direction:rtl}
.build-bank{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:auto}
.tile{min-height:56px;padding:8px 18px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:0 3px 0 var(--line);cursor:pointer;font:700 18px/1.3 var(--f-body);color:var(--ink)}
.tile.is-ar{font:500 32px/1.6 var(--f-ar)}
.tile:active{transform:translateY(2px);box-shadow:none}
.pairs{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:20px}
.pairs-col{display:grid;gap:10px;align-content:start}
.pair{width:100%;min-height:64px;padding:8px 10px;overflow-wrap:anywhere}
.pair.is-ar{font-size:28px}
.pair[aria-pressed="true"]{border-color:var(--mark);box-shadow:0 3px 0 var(--mark);background:var(--sunken)}
.pair.is-right{border-color:var(--ok);background:var(--ok-bg);box-shadow:none;color:var(--ok);cursor:default}
.pair.is-miss{border-color:var(--err);background:var(--err-bg)}
@media (prefers-reduced-motion:no-preference){.pair.is-miss{animation:pair-shake .35s}}
@keyframes pair-shake{25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
.intro-items .meaning{display:flex;flex-direction:column;gap:2px;font:700 17px/1.3 var(--f-body)}
.intro-items .meaning small{font:500 14px/1.3 var(--f-body);color:var(--muted)}
.intro-card .ar{font-size:1.25em}
.word-card{display:flex;flex-direction:column;align-items:center;gap:10px;margin:28px 0;padding:32px 16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface);text-align:center}
.word-ar .ar{font-size:64px;line-height:1.5}
.word-fr{font:800 24px/1.2 var(--f-display)}
.word-meta{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.word-card small{color:var(--muted);font:500 14px/1.3 var(--f-body)}
.badge{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border:var(--bw) solid var(--line);border-radius:99px;font:800 12px/1.4 var(--f-body);color:var(--ink);background:var(--sunken)}
.badge.g-m{border-color:var(--primary)}
.badge.g-f{border-color:var(--accent-dark)}
.note-big{text-align:center;margin:12px 0}
.note-big .ar{font-size:72px;line-height:1.5}
.note-line{margin:0 0 14px;font:700 17px/1.4 var(--f-body)}
.chips{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin:0 0 14px;padding:0;list-style:none}
.chips li{padding:8px 14px;border-radius:8px;font:700 16px/1 var(--f-body);background:var(--line);color:var(--ink)}
.ex-hint{margin:-4px 0 12px;color:var(--muted);font:600 15px/1.3 var(--f-body)}
.note-rows{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.note-rows li{display:flex;flex-direction:row-reverse;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:4px 16px;padding:10px 16px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface)}
.hl{background:none;color:var(--mark);font-weight:inherit}
.hl-pair{position:relative;display:inline-block;white-space:nowrap}
.hl-base,.hl-under{position:absolute;inset:0;pointer-events:none;user-select:none}
.hl-under{color:transparent}
.hl-under .hl{color:var(--mark)}
.hl2,.hl-under .hl2{color:var(--mark2)}
.hl-top{position:relative}
/* a whole sentence (L6 « وَأَيْنَ السَّاعَةُ؟ هِيَ عَلَى السَّرِيرِ ») is wider than the card: it wraps between words and the
   translation goes under it (founder's screenshot 2026-10-29, tools/check_rows.py) */
.note-rows .ar{font-size:28px;flex:none;max-width:100%}  /* flex:none: never squeezed, wraps only past the full width */
.note-rows li>span:not(.ar){flex:1 1 9em}
/* one layout per card: if one row stacks, they all do (static/js/rows.js), Arabic on top at the right */
.note-rows.is-stacked li{flex-direction:column;align-items:stretch}
.note-rows.is-stacked .ar{align-self:flex-end}
.note-rows.is-stacked li>span:not(.ar){flex:none}
.note-rows small{display:block;color:var(--muted);font:500 14px/1.3 var(--f-body)}
.note-rows small .ar,.note-rows span:not(.ar) .ar{font-size:1em;white-space:normal}
.note-line .ar{white-space:nowrap}
/* lighter depth: an explanation already given is folded, one tap away (docs/adaptive-system.md) */
.note-fold>summary{cursor:pointer;min-height:44px;display:flex;align-items:center;gap:8px;font-weight:800;color:var(--primary-text)}
.note-fold>summary::-webkit-details-marker{display:none}
.note-fold>summary i{font-size:14px;transition:transform .2s}
.note-fold[open]>summary{margin-bottom:12px}
.note-fold[open]>summary i{transform:rotate(180deg)}
.compare{width:100%;border-collapse:separate;border-spacing:0 8px}
.compare th{font:800 12px/1 var(--f-body);letter-spacing:.05em;text-transform:uppercase;color:var(--muted);text-align:start;padding:0 12px}
.compare td{padding:12px;border:var(--bw) solid var(--line);background:var(--surface);font:700 17px/1.3 var(--f-body)}
.compare td:first-child{border-radius:var(--r) 0 0 var(--r);border-right:0}
.compare td:last-child{border-radius:0 var(--r) var(--r) 0}
.compare .ar{font-size:28px}
.flash-answer[hidden]{display:none}
.flash-answer{display:flex;justify-content:center;margin:8px 0 0;padding-top:18px;border-top:var(--bw) solid var(--line)}
.player-foot .rate-row .btn{padding-inline:6px;min-width:0;font-size:13px;letter-spacing:0;white-space:nowrap}
@media (min-width:900px){.player-foot .rate-row .btn{flex:0 0 auto;min-width:150px}}

.langmenu{position:relative}
.langmenu summary{display:flex;align-items:center;justify-content:center;min-width:48px;min-height:44px;cursor:pointer;list-style:none}
.langmenu summary::-webkit-details-marker{display:none}
.langmenu summary span[aria-hidden]{border:var(--bw) solid var(--line-strong);border-radius:7px;padding:3px 6px;font:800 13px/1 var(--f-body);color:var(--muted)}
.langmenu ul{position:absolute;z-index:30;top:100%;left:0;margin:4px 0 0;padding:6px;list-style:none;min-width:180px;max-height:60dvh;overflow-y:auto;background:var(--surface);border:var(--bw) solid var(--line);border-radius:var(--r-sm);box-shadow:0 4px 0 var(--line)}
.langmenu li a{display:flex;align-items:center;min-height:44px;padding:0 12px;border-radius:8px;font:800 15px/1 var(--f-body);color:var(--ink);text-decoration:none}
.langmenu li a:hover,.langmenu li a[aria-current]{background:var(--sunken);color:var(--primary-text)}
::view-transition-old(root),::view-transition-new(root){animation-duration:.35s;animation-timing-function:ease}

/* ---- Satisfaction effects (see docs/ux-ui.md, "Effets") ---- */
#fx{position:fixed;inset:0;z-index:9998;pointer-events:none;overflow:hidden}
.fx-p{position:absolute;border-radius:2px}
.fx-ring{position:absolute;border:4px solid;border-radius:50%}
.fx-coin{position:absolute;width:22px;height:22px;font-size:20px;line-height:22px;text-align:center;color:var(--accent)}
.node.jar.is-shaking{animation:jar-shake .65s ease-in-out}
.node.jar.is-popping .face{animation:jar-pop .45s cubic-bezier(.2,1.6,.4,1)}
@keyframes jar-shake{0%,100%{transform:rotate(0)}10%{transform:rotate(-9deg) translateY(-2px)}25%{transform:rotate(9deg)}40%{transform:rotate(-12deg) translateY(-3px)}55%{transform:rotate(12deg)}70%{transform:rotate(-8deg) scale(1.08)}85%{transform:rotate(6deg) scale(1.12)}}
@keyframes jar-pop{0%{transform:scale(1.35)}100%{transform:scale(1)}}
.opt.is-right,.tile.is-right{position:relative;overflow:hidden}
.combo.is-hot{color:var(--flame)}
@media (prefers-reduced-motion:no-preference){
  .opt.is-right,.tile.is-right{animation:ans-pop .3s cubic-bezier(.2,1.5,.4,1)}
  /* The shine exists only while it moves: before and after, it sits outside the clipped box (never a grey band at rest). */
  .opt.is-right::after,.tile.is-right::after{content:"";position:absolute;inset:0 auto 0 -40%;width:30%;background:var(--shine);transform:skewX(-20deg);pointer-events:none;animation:shine .7s .1s ease-out both}
  .opt.is-wrong{animation:ans-shake .4s ease-in-out}
  .progress i.is-gain::before{content:"";position:absolute;inset:0;border-radius:99px;background:rgba(255,255,255,.55);animation:bar-flash .5s ease-out forwards}
  .combo.bump b{animation:combo-bump .45s cubic-bezier(.2,1.8,.4,1)}
  .done-screen h1{animation:done-in .5s cubic-bezier(.2,1.4,.4,1) both}
  .done-badge{animation:jar-pop .5s cubic-bezier(.2,1.6,.4,1) both}
  .done-hero,.done-line{animation:done-in .5s .2s cubic-bezier(.2,1.4,.4,1) both}
  .btn:active{transform:translateY(3px);box-shadow:none}
}
@keyframes ans-pop{0%{transform:scale(1)}45%{transform:scale(1.04)}100%{transform:scale(1)}}
@keyframes ans-shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-7px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(3px)}}
@keyframes shine{to{left:130%}}
:root{--shine:rgba(255,255,255,.45)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--shine:rgba(255,255,255,.14)}}
:root[data-theme="dark"]{--shine:rgba(255,255,255,.14)}
@keyframes bar-flash{to{opacity:0}}
@keyframes combo-bump{0%{transform:scale(1)}40%{transform:scale(1.6)}100%{transform:scale(1)}}
@keyframes done-in{from{opacity:0;transform:translateY(18px) scale(.9)}}
.fx-callout{position:absolute;left:50%;top:84px;padding:10px 20px;border-radius:99px;background:var(--flame);color:#fff;font:800 20px/1 var(--f-display);box-shadow:0 4px 0 var(--flame-dark);white-space:nowrap}
.tile.is-used{background:var(--sunken);border:var(--bw) dashed var(--line);box-shadow:none;color:transparent;pointer-events:none}
.tile.is-used .ar{color:transparent}
.build-answer .tile{align-self:flex-start}
.build-answer.is-ar{min-height:96px}
.pop{transform-origin:var(--arrow,50%) -9px}
@media (prefers-reduced-motion:no-preference){.pop{animation:pop-in .32s cubic-bezier(.2,1.5,.4,1)}}
@keyframes pop-in{0%{transform:scale(.15);opacity:0}35%{opacity:1}100%{transform:scale(1)}}

.player-top .hk-btn{grid-column:1/3;justify-self:start;margin-left:-8px}
.player-top .combo{grid-column:3;justify-self:end}
.progress{height:18px}
/* leaving is a choice, not a mistake: neutral sheet, not the red error one (docs/ux-ui.md) */
.sheet.is-quit{background:var(--surface);color:var(--ink);border-top:var(--bw) solid var(--line)}
.sheet.is-quit>p:not(.sheet-alt){color:var(--muted)}
.sheet.is-quit .row{display:block}
.sheet.is-quit .btn{display:flex;width:100%;min-height:52px;box-sizing:border-box}
.sheet.is-quit [data-action="stay"]{background:var(--primary);color:var(--on-primary);box-shadow:0 4px 0 var(--primary-dark)}
.sheet.is-quit .sheet-alt{margin:12px 0 0!important}
.sheet.is-quit .sheet-alt .btn{background:none;box-shadow:none;border:var(--bw) solid currentColor;color:var(--err)}
li:has(.pop){z-index:6}
@media (min-width:700px){.sheet.is-quit .btn{width:240px;min-width:0}.sheet.is-quit .sheet-alt{justify-self:end}}
.build-answer,.build-bank{flex-shrink:0}
.build-answer{box-sizing:border-box;align-content:center}
.tile{display:inline-flex;align-items:center;justify-content:center;text-align:center}
.choice.seg[data-sound],.choice.seg[data-keys],.choice.seg[data-push],.choice.seg[data-measure]{grid-template-columns:repeat(2,1fr)}
.slot:not(.is-filled):not(.is-target){text-decoration:underline dotted var(--locked-edge) 3px;text-underline-offset:10px}

.letters.is-long{font-size:46px;line-height:1.9}
@media (max-width:480px){.letters.is-long{font-size:38px;line-height:1.85;padding:10px 6px}.mark{height:50px;font-size:44px}}
/* The palette sits on the scroll edge: .ex drops its bottom padding, so no strip of letters shows under the palette. */
.ex:has(> .marks){padding-bottom:0}
.marks{position:sticky;bottom:0;padding:10px 0 16px;background:var(--bg)}
/* App notices (streak, offline, update): same look as server messages. */
.notice a,.notice button{color:var(--primary-text);font-weight:800}
.notice button{border:0;background:none;padding:0 0 0 8px;min-height:44px;cursor:pointer;text-decoration:underline}
.notice.is-toast{position:fixed;z-index:40;left:16px;right:16px;bottom:calc(var(--tabs-h) + 12px + env(safe-area-inset-bottom,0px));max-width:480px;margin:0 auto;box-shadow:0 4px 0 var(--line)}
@media (min-width:700px){.notice.is-toast{bottom:24px}}
/* In an exercise the toast never covers Check/Continue: it sits at the top (docs/ux-ui.md). */
body.is-player .notice.is-toast{top:calc(12px + env(safe-area-inset-top,0px));bottom:auto}
.notice.is-toast{display:flex;align-items:center;gap:4px}
.notice .notice-close{margin-inline-start:auto;min-width:44px;padding:0;color:var(--muted);text-decoration:none}
.choice .saved{grid-column:1/-1}
.plan-soon{margin:auto 0 0;color:var(--muted);font-weight:800;font-size:14px}
/* Server messages (django.contrib.messages) at the top of the app column. */
.notices{margin:0 0 16px}
.notice{margin:0 0 8px;padding:12px 14px;border:var(--bw) solid var(--line);border-radius:var(--r-sm);background:var(--surface);font-weight:700}
.notice-error{border-color:var(--err);background:var(--err-bg)}

/* League avatars: one tint per learner (hue from public_id), never the same disc down the list. */
.avatar.av-0{--h:20}.avatar.av-1{--h:45}.avatar.av-2{--h:140}.avatar.av-3{--h:175}.avatar.av-4{--h:205}.avatar.av-5{--h:340}
.avatar[class*="av-"]{background:hsl(var(--h) 60% 92%);border-color:hsl(var(--h) 40% 78%);color:hsl(var(--h) 55% 28%)}
:root[data-theme="dark"] .avatar[class*="av-"]{background:hsl(var(--h) 30% 20%);border-color:hsl(var(--h) 30% 34%);color:hsl(var(--h) 60% 80%)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .avatar[class*="av-"]{background:hsl(var(--h) 30% 20%);border-color:hsl(var(--h) 30% 34%);color:hsl(var(--h) 60% 80%)}}
.name-prompt{margin:0 0 12px;text-align:center}
/* 1100px+: the right column shows the daily goal, the XP quest is the same goal (target = daily goal): the shop list drops it, except while its Dinars wait to be claimed */
@media (min-width:1100px){.quests [data-quest-row="xp"]:not(:has(> .btn:not([hidden]))){display:none}}
.league-offline{margin:12px 0;padding:10px 14px;border:var(--bw) solid var(--line);border-radius:var(--r);background:var(--surface);color:var(--muted);font-weight:700;text-align:center}
.name-prompt a{display:inline-flex;align-items:center;min-height:44px;font-weight:800;color:var(--primary-text)}
.auth-card h2{margin:28px 0 12px;font:800 20px/1.2 var(--f-display)}
.email-row{padding:14px 0;border-bottom:var(--bw) solid var(--line)}
.email-row p{margin:0 0 8px;overflow-wrap:anywhere}
.email-state{display:inline-block;margin-left:8px;font-size:14px;font-weight:700;color:var(--muted)}
.email-state.is-ok{color:var(--primary-text)}
.email-actions{display:flex;flex-wrap:wrap;gap:8px}
/* Install and reminder pop-ups (nudge.js): bottom sheet on phones, centred card from 640px. */
dialog.nudge{box-sizing:border-box;width:100%;max-width:100%;max-height:92dvh;margin:auto auto 0;padding:24px 20px calc(20px + env(safe-area-inset-bottom,0px));border:0;border-top:var(--bw) solid var(--line);border-radius:var(--r) var(--r) 0 0;background:var(--surface);color:var(--ink);text-align:center;overflow:auto}
dialog.nudge::backdrop{background:rgb(20 16 10 / .5)}
@media (min-width:640px){dialog.nudge{width:420px;margin:auto;padding:28px 28px 22px;border:var(--bw) solid var(--line);border-radius:var(--r);box-shadow:0 6px 0 var(--line)}}
@media (prefers-reduced-motion:no-preference){dialog.nudge[open]{animation:up var(--dur-3) var(--ease-out)}
  @media (min-width:640px){dialog.nudge[open]{animation:none}}}
.nudge-icon{display:grid;place-items:center;width:64px;height:64px;margin:0 auto 12px;border-radius:50%;background:var(--ok-bg);color:var(--primary-text);font-size:28px}
dialog.nudge h2{margin:0 0 14px;font:800 22px/1.2 var(--f-display);text-wrap:balance}
.nudge-list,.nudge-steps{margin:0 0 20px;padding:0;list-style:none;display:grid;gap:10px;text-align:start;font-weight:700}
.nudge-list li,.nudge-steps li{display:flex;align-items:flex-start;gap:12px}
.nudge-list i,.nudge-steps i{flex:none;width:22px;margin-top:2px;color:var(--primary-text);text-align:center}
.nudge-steps{counter-reset:s}
.nudge-actions{display:grid;gap:6px}
.nudge-actions .btn-flat{min-height:44px}
.setting-note{grid-column:1/-1;margin:2px 0 0;color:var(--muted);font-weight:700}
.install-row{margin:12px 0 0}
.install-row .btn{display:inline-flex;gap:10px;align-items:center}

/* Beta copy (apps/core/beta.py): a small fixed tag so nobody mistakes it for the live app. */
.beta-flag{position:fixed;left:8px;bottom:calc(8px + env(safe-area-inset-bottom));z-index:90;pointer-events:none;padding:3px 8px;
  border-radius:6px;background:var(--ink);color:var(--bg);font:800 11px/1.2 var(--f-display, sans-serif);letter-spacing:.06em;text-transform:uppercase;opacity:.85}
@media (max-width:699px){body:has(.tabs) .beta-flag{bottom:calc(var(--tabs-h) + 8px + env(safe-area-inset-bottom))}}  /* above the tab bar, never on a tab */
/* Résiliation (templates/billing/cancel.html) */
.cancel-panel{display:grid;gap:14px}
.cancel-panel p{margin:0}
.cancel-facts{margin:0;padding-left:20px;display:grid;gap:8px}
.cancel-done{display:flex;align-items:center;gap:10px;font-weight:800;color:var(--ok)}
.plan-cancel{display:block;margin-top:10px;text-align:center;color:var(--muted);font-weight:700}
.plan-ends{margin:10px 0 0;color:var(--muted);font-weight:700;font-size:14px}
.contact-addr{margin:8px 0 4px;font-size:14px;overflow-wrap:anywhere;user-select:all}
