/* Practica Conmigo: every color is a token; light and dark both ship. Warm paper and terracotta by day,
   ink and ember by night. Every control is at least 44 px to press with 8 px or more between neighbours; body
   text is 14 px or more; hover looks only where there is a pointer that hovers; nothing sits in a phone's
   notch, rounded corners or home-indicator band (the env(safe-area-inset-*) sides); the bar and the tab bar
   are allowed for when the browser scrolls something into view (scroll-padding), and a text field with
   the keyboard up is never under them. */
:root {
  --bg: #f7f3ee; --panel: #ffffff; --sunk: #efe9e1; --fg: #1d1a16; --mute: #645d53; --faint: #6f675b; --line: #e3dbd0; --line2: #d4c9bb;
  --accent: #b8461c; --accent-ink: #ffffff; --accent-soft: #fbede5; --accent-2: #2f6f5e; --accent-2-soft: #dcefe8;
  --good: #23784f; --good-soft: #def2e6; --bad: #b3261e; --bad-soft: #fbe3df; --warn: #946200; --warn-soft: #fbefd2;
  --shadow: 0 1px 2px rgba(40, 28, 16, .06), 0 8px 24px rgba(40, 28, 16, .08); --shadow-lg: 0 18px 50px rgba(40, 28, 16, .18);
  --c1: #b8461c; --c2: #2f6f5e; --c3: #4b5fb0; --c4: #946200; --c5: #8a3f8f; --c6: #2b7a99; --c7: #6b7d1e; --c8: #a33a52; --c9: #5e5a52; --c10: #c97a12;
  --r: 14px; --r-sm: 10px; --font: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Helvetica Neue", sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif; --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --field: #8f8477; --bar-h: 60px; --tab-h: 0px; color-scheme: light;
  /* the page's side gutter: 20 px, or the notch's own inset when a phone lies on its side */
  --gut-l: max(20px, env(safe-area-inset-left)); --gut-r: max(20px, env(safe-area-inset-right));
}
@media (prefers-color-scheme: dark) { :root:not([data-theme=light]) {
  --bg: #14110e; --panel: #1d1915; --sunk: #26211c; --fg: #f3eee8; --mute: #bdb4a8; --faint: #a0978a; --line: #342e27; --line2: #453d34;
  --accent: #ff8a5c; --accent-ink: #1a0f08; --accent-soft: #3b2418; --accent-2: #6fc9ae; --accent-2-soft: #173229;
  --good: #6fd39c; --good-soft: #15301f; --bad: #ff8a80; --bad-soft: #3a1a17; --warn: #f1c25b; --warn-soft: #33290f;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .35); --shadow-lg: 0 18px 50px rgba(0, 0, 0, .55);
  --c1: #ff8a5c; --c2: #6fc9ae; --c3: #9aa9ff; --c4: #f1c25b; --c5: #e39ae8; --c6: #7fd0ef; --c7: #c4d86a; --c8: #ff8fa8; --c9: #bdb4a8; --c10: #ffb35c;
  --field: #776c60; color-scheme: dark;
} }
:root[data-theme=dark] {
  --bg: #14110e; --panel: #1d1915; --sunk: #26211c; --fg: #f3eee8; --mute: #bdb4a8; --faint: #a0978a; --line: #342e27; --line2: #453d34;
  --accent: #ff8a5c; --accent-ink: #1a0f08; --accent-soft: #3b2418; --accent-2: #6fc9ae; --accent-2-soft: #173229;
  --good: #6fd39c; --good-soft: #15301f; --bad: #ff8a80; --bad-soft: #3a1a17; --warn: #f1c25b; --warn-soft: #33290f;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .35); --shadow-lg: 0 18px 50px rgba(0, 0, 0, .55);
  --c1: #ff8a5c; --c2: #6fc9ae; --c3: #9aa9ff; --c4: #f1c25b; --c5: #e39ae8; --c6: #7fd0ef; --c7: #c4d86a; --c8: #ff8fa8; --c9: #bdb4a8; --c10: #ffb35c;
  --field: #776c60; color-scheme: dark;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent;
  /* what the browser scrolls into view (focus, find, scrollIntoView) lands clear of the sticky bar and the tab bar */
  scroll-padding-top: calc(var(--bar-h) + env(safe-area-inset-top) + 12px); scroll-padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 16px); }
/* the tour places each step itself, allowing for the bar (tour.js) */
html:has(.tour-ring) { scroll-padding: 0; }
body { margin: 0; background: var(--bg); color: var(--fg); font: 16px/1.5 var(--font); min-height: 100vh; overflow-x: hidden; }
a { color: var(--accent); }
h1, h2, h3 { line-height: 1.2; margin: 0 0 .4em; }
h1 { font-size: 26px; letter-spacing: -.01em; }
h2 { font-size: 19px; }
h3 { font-size: 16px; }
p { margin: 0 0 .8em; }
.mute { color: var(--mute); }
.faint { color: var(--faint); }
.small { font-size: 14px; }
.tiny { font-size: 13px; }
.num { font-variant-numeric: tabular-nums; }
.es { font-family: var(--serif); }
.list .es, td.es, .msg .es { font-family: var(--font); font-weight: 600; font-size: 16px; letter-spacing: -.005em; }
.flash .front .chip { font-family: var(--font); }
.hidden, [hidden] { display: none !important; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.skip:focus { position: fixed; z-index: 300; top: 10px; left: 12px; width: auto; height: auto; clip: auto; padding: 10px 16px; border-radius: 999px; background: var(--panel); color: var(--fg); font-weight: 600; box-shadow: var(--shadow-lg); }

/* Buttons */
button, .btn { font: 600 15px/1 var(--font); border-radius: 999px; min-height: 44px; padding: 0 18px; border: 1px solid var(--line2); background: var(--panel); color: var(--fg); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; text-decoration: none; white-space: nowrap; transition: background .15s, border-color .15s, transform .08s; }
@media (hover: hover) { button:hover, .btn:hover { border-color: var(--faint); } }
button:active, .btn:active { transform: translateY(1px); }
button:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
@media (hover: hover) { .primary:hover { border-color: var(--accent); filter: brightness(1.06); } }
.ghost { background: transparent; border-color: transparent; }
@media (hover: hover) { .ghost:hover { background: var(--sunk); border-color: transparent; } }
.quiet { background: var(--sunk); border-color: transparent; }
.danger { color: var(--bad); }
.big { min-height: 52px; padding: 0 26px; font-size: 17px; }
.icon { width: 44px; padding: 0; flex: none; }
.icon svg, button svg, .btn svg { width: 20px; height: 20px; flex: none; }
.link { background: none; border: 0; padding: 0; min-height: 0; color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; border-radius: 4px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.end { justify-content: flex-end; }
.row.between { justify-content: space-between; }
.row.bottom { align-items: flex-end; }
.grow { flex: 1; min-width: 0; }
.stack { display: grid; gap: 14px; }

/* Shell */
.bar { position: sticky; top: 0; z-index: 30; height: var(--bar-h); display: flex; align-items: center; gap: 8px; padding: 0 var(--gut-r) 0 var(--gut-l); background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(1.4) blur(10px); -webkit-backdrop-filter: saturate(1.4) blur(10px); border-bottom: 1px solid var(--line); padding-top: env(safe-area-inset-top); height: calc(var(--bar-h) + env(safe-area-inset-top)); }
.brand { display: flex; align-items: center; gap: 10px; min-height: 44px; min-width: 0; font-weight: 750; font-size: 17px; color: var(--fg); text-decoration: none; margin-right: 14px; letter-spacing: -.01em; }
.brand svg { width: 32px; height: 32px; flex: none; }
.brand span { white-space: nowrap; }
.nav { display: flex; gap: 8px; min-width: 0; }
.nav a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; font-size: 15px; color: var(--mute); text-decoration: none; padding: 0 14px; border-radius: 999px; white-space: nowrap; }
@media (hover: hover) { .nav a:hover { color: var(--fg); background: var(--sunk); } }
.nav a[aria-current=page] { color: var(--fg); background: var(--sunk); }
.bar .add-btn { margin-left: 8px; }
.menu { position: relative; }
.menu-list { position: absolute; right: 0; top: calc(100% + 8px); z-index: 40; display: flex; flex-direction: column; min-width: 240px; padding: 6px; background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-lg); }
.menu-list > button, .menu-list > a, .menu-list .smcp-inline { justify-content: flex-start; text-align: left; border: 0; background: none; padding: 10px 12px; min-height: 44px; border-radius: 8px;
  font: 500 15px var(--font); color: var(--fg); width: 100%; text-decoration: none; display: flex; align-items: center; gap: 10px; cursor: pointer; }
@media (hover: hover) { .menu-list > button:hover, .menu-list > a:hover, .menu-list .smcp-inline:hover { background: var(--sunk); } }
/* Software MCP's "Problem or idea?" row comes without an icon: a bug, drawn in the menu's quiet ink. */
.menu-list .smcp-inline::before { content: ''; width: 20px; height: 20px; flex: none; background: var(--mute); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 7.5V7a3 3 0 0 1 6 0v.5'/%3E%3Crect x='7' y='8' width='10' height='12' rx='5'/%3E%3Cpath d='M12 12v8M3.5 13H7M17 13h3.5M4.5 19.5 7.4 17M19.5 19.5 16.6 17M4.5 6.5 7.4 9M19.5 6.5 16.6 9'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 7.5V7a3 3 0 0 1 6 0v.5'/%3E%3Crect x='7' y='8' width='10' height='12' rx='5'/%3E%3Cpath d='M12 12v8M3.5 13H7M17 13h3.5M4.5 19.5 7.4 17M19.5 19.5 16.6 17M4.5 6.5 7.4 9M19.5 6.5 16.6 9'/%3E%3C/svg%3E") center / contain no-repeat; }
/* an item's icon is the size of a button's, whatever the item is (a link too) */
.menu-list svg { width: 20px; height: 20px; flex: none; }
/* A page's own More menu never runs past the screen either: it scrolls inside itself, and opening it brings
   it into view above the tab bar (lessons.js, decks.js). */
.page .menu-list { max-height: calc(100dvh - var(--bar-h) - var(--tab-h) - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 24px); overflow-y: auto; overscroll-behavior: contain; }
/* The account menu never runs past the screen: it scrolls inside itself, and while it is open the bar (and the
   menu in it) sits above the tab bar and Lola. */
.bar .menu-list { max-height: calc(100dvh - var(--bar-h) - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 16px); overflow-y: auto; overscroll-behavior: contain; }
.bar:has(#menu-list:not([hidden])) { z-index: 70; }
.menu-list hr { border: 0; border-top: 1px solid var(--line); margin: 6px 4px; }
/* The Software MCP report form reads its colours from these (no shadow DOM): the site's own tokens, light and
   dark, so it opens as part of this site. !important beats the widget's own sheet, which loads after this one. */
.smcp-ui { --smcp-bg: var(--panel) !important; --smcp-fg: var(--fg) !important; --smcp-mute: var(--mute) !important; --smcp-line: var(--line) !important;
  --smcp-soft: var(--sunk) !important; --smcp-accent: var(--accent) !important; --smcp-on: var(--accent-ink) !important; --smcp-bad: var(--bad) !important; }
/* Its form keeps this site's rules too (its own sheet has 12.5 to 13 px text, a 14 px box that makes iPhone
   Safari zoom in, a faint chosen kind and a 100vh height that can hide Send): text 14 px or more, the box 16 px
   with the fields' border, Problem and Idea 8 px apart with the chosen one in the accent, and Cancel and Send
   kept at the foot while the rest scrolls; under 500 px tall (a phone on its side, or the keyboard up) it takes
   the whole screen, as the site's own dialog does. Two classes beat the widget's one, so no !important. */
.smcp-ui.smcp-back { padding: 12px; }
.smcp-ui .smcp-dlg { max-height: calc(100dvh - 24px); padding-bottom: 0; overscroll-behavior: contain; }
.smcp-ui .smcp-sub, .smcp-ui .smcp-dlg label, .smcp-ui .smcp-shot, .smcp-ui .smcp-err, .smcp-ui .smcp-kind button, .smcp-ui .smcp-btn, .smcp-ui .smcp-mine, .smcp-ui .smcp-new { font-size: 14px; }
.smcp-ui .smcp-dlg textarea { font-size: 16px; border-color: var(--field); }
.smcp-ui .smcp-kind { gap: 8px; }
.smcp-ui .smcp-kind button { min-height: 44px; padding: 0 16px; }
.smcp-ui .smcp-kind button[aria-checked="true"] { background: var(--accent); color: var(--accent-ink); box-shadow: none; }
.smcp-ui .smcp-btn { min-height: 44px; }
.smcp-ui .smcp-acts { position: sticky; bottom: 0; z-index: 1; margin: 16px -20px 0; padding: 10px 20px calc(10px + env(safe-area-inset-bottom)); background: var(--smcp-bg); border-top: 1px solid var(--smcp-line); }
.smcp-ui .smcp-mine { padding-bottom: 16px; }
@media (max-height: 500px) {
  .smcp-ui.smcp-back { padding: 0; }
  .smcp-ui .smcp-dlg { width: 100%; height: 100dvh; max-height: 100dvh; border: 0; border-radius: 0; padding: 14px max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left)); }
  .smcp-ui .smcp-acts { margin-left: calc(-1 * max(20px, env(safe-area-inset-left))); margin-right: calc(-1 * max(20px, env(safe-area-inset-right)));
    padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right)); }
}
/* Its note after sending ("Sent as #57. Thank you."): 14 px, its × a full 44 px, and on a phone or a short
   screen under the bar like the site's own toasts, never on the bar's name or Sign in. It goes by itself
   after a few seconds (app.js). */
.smcp-ui .smcp-note { font-size: 14px; align-items: center; }
.smcp-ui .smcp-x { min-width: 44px; min-height: 44px; margin: -8px -10px -8px 0; }
@media (max-width: 720px), (max-height: 500px) {
  .smcp-ui.smcp-notes { top: calc(var(--bar-h) + env(safe-area-inset-top) + 8px); bottom: auto; left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right)); max-width: none; }
}
.who { padding: 8px 12px 6px; font-size: 14px; color: var(--mute); overflow-wrap: anywhere; }
.page { max-width: 1120px; margin: 0 auto; padding: 28px var(--gut-r) 140px var(--gut-l); }
.page.wide { max-width: 1320px; }
/* Data pages use the full width up to 1100 px (Lola is small there and steps aside on scroll); wider, they
   leave her corner free. */
@media (min-width: 1101px) { .page.wide { max-width: min(1320px, calc(100vw - 96px)); } }
@media (min-width: 1361px) { .page.wide { max-width: min(1320px, calc(100vw - 240px)); } }
.tabbar { display: none; }

/* Cards and panels */
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 20px; box-shadow: var(--shadow); min-width: 0; }
.panel.flat { box-shadow: none; }
.panel h2 { display: flex; align-items: center; gap: 8px; }
.grid { display: grid; gap: 18px; align-items: start; }
.grid.two { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; }
.grid.even { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.chip { white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--sunk); color: var(--mute); font-size: 14px; font-weight: 600; max-width: 100%; }
.chip.accent { background: var(--accent-soft); color: var(--accent); }
.chip.green { background: var(--accent-2-soft); color: var(--accent-2); }
.chip.good { background: var(--good-soft); color: var(--good); }
.chip.bad { background: var(--bad-soft); color: var(--bad); }
.chip.warn { background: var(--warn-soft); color: var(--warn); }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.back { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); font-weight: 600; text-decoration: none; margin-bottom: 14px; min-height: 44px; padding: 0 12px 0 6px; border-radius: 999px; }
@media (hover: hover) { .back:hover { background: var(--sunk); color: var(--fg); } }
.back svg { width: 20px; height: 20px; }
.pagehead { display: flex; gap: 14px; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; margin-bottom: 18px; }
.pagehead h1 { margin: 0; }
/* the title keeps a readable width; the buttons beside it go under it instead of squeezing it */
.pagehead > .grow { flex: 1 1 320px; }
.pagehead p { margin: 6px 0 0; }

/* Hero (home) */
.hero { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px 26px; align-items: center; padding: 26px 28px; border-radius: 20px; background:
  radial-gradient(120% 140% at 100% 0%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%), radial-gradient(90% 120% at 0% 100%, color-mix(in srgb, var(--accent-2) 12%, transparent), transparent 60%), var(--panel);
  border: 1px solid var(--line); box-shadow: var(--shadow); }
.hero .greet { color: var(--mute); font-weight: 600; margin-bottom: 6px; }
.hero h1 { font-size: 30px; margin-bottom: 10px; }
.hero .actions { display: flex; flex-direction: column; gap: 10px; align-items: stretch; min-width: 220px; }
.seg { display: inline-flex; padding: 3px; background: var(--sunk); border-radius: 999px; gap: 4px; flex-wrap: wrap; }
.seg button { min-height: 44px; padding: 0 14px; border: 0; background: transparent; color: var(--mute); font-size: 14px; }
/* the chosen one is unmistakable in light and dark: the accent, not a slightly lighter pill */
.seg button[aria-pressed=true] { background: var(--accent); color: var(--accent-ink); box-shadow: none; }
.seg .short { display: none; }
.stat-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.stat { padding: 14px 16px; border-radius: var(--r-sm); background: var(--sunk); min-width: 0; }
.stat b { display: block; font-size: 24px; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.stat span { color: var(--mute); font-size: 14px; font-weight: 600; }
.meter { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: var(--sunk); }
.meter i { display: block; height: 100%; }
.meter .m-new { background: transparent; } .meter .m-master { background: var(--c2); }
.meter .m-learn { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--c4) 60%, transparent) 0 4px, color-mix(in srgb, var(--c4) 35%, transparent) 4px 8px); }
.legend .sw-learn { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--c4) 60%, transparent) 0 3px, color-mix(in srgb, var(--c4) 35%, transparent) 3px 6px); }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 14px; color: var(--mute); margin-top: 8px; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
.list { list-style: none; margin: 0; padding: 0; }
.list > li { display: flex; gap: 12px; align-items: center; padding: 12px 2px; border-top: 1px solid var(--line); min-width: 0; flex-shrink: 0; }
.list > li:first-child { border-top: 0; }
.list .main { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.list .main small { display: block; color: var(--mute); font-size: 14px; }
.badge { font: 700 14px/1 var(--font); padding: 5px 8px; border-radius: 999px; background: var(--bad-soft); color: var(--bad); font-variant-numeric: tabular-nums; white-space: nowrap; }
.plan { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.plan li { display: flex; gap: 12px; align-items: flex-start; padding: 8px 4px; }
.plan label { display: flex; gap: 12px; align-items: flex-start; cursor: pointer; flex: 1; }
.plan input { width: 22px; height: 22px; margin: 1px 0 0; accent-color: var(--accent-2); flex: none; }
.plan .day { font-weight: 700; color: var(--accent-2); font-size: 14px; min-width: 44px; padding-top: 2px; }
.plan .done { color: var(--faint); text-decoration: line-through; }
.empty { text-align: center; padding: 34px 20px; color: var(--mute); }
.empty svg { width: 54px; height: 54px; color: var(--faint); margin-bottom: 8px; }
.deckgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.deck { display: flex; flex-direction: column; gap: 10px; text-decoration: none; color: inherit; padding: 18px; border-radius: var(--r); background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); min-width: 0; transition: border-color .15s, transform .15s; }
@media (hover: hover) { .deck:hover { border-color: var(--line2); transform: translateY(-1px); } }
.deck h3 { margin: 0; overflow-wrap: anywhere; }
.deck p { margin: 0; color: var(--mute); font-size: 14px; }
.deck .foot { display: flex; justify-content: space-between; gap: 4px 12px; flex-wrap: wrap; color: var(--mute); font-size: 14px; font-weight: 600; margin-top: auto; }

/* Study */
.study { max-width: 760px; margin: 0 auto; }
.study-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.progressline { height: 6px; background: var(--sunk); border-radius: 999px; overflow: hidden; margin-bottom: 18px; }
.progressline i { display: block; height: 100%; background: var(--accent); border-radius: 999px; transition: width .3s; }
.flash { position: relative; min-height: 320px; border-radius: 22px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); padding: 34px 30px 26px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; cursor: pointer; user-select: text; }
.flash .kind { position: absolute; top: 16px; left: 18px; }
.flash .say { position: absolute; top: 12px; right: 12px; }
.flash .front { font-family: var(--serif); font-size: clamp(32px, 8vw, 44px); line-height: 1.25; overflow-wrap: anywhere; max-width: 100%; }
/* Lola's word picture (pics.js): on a new card's answer side, and small beside a card's Spanish in its deck. The
   pictures are drawn on warm paper, so they sit on a rounded tile in either theme. */
.flash .word-pic { display: block; width: 160px; height: 160px; margin: 0 auto 12px; border-radius: var(--r-sm); }
@media (max-width: 380px), (max-height: 700px) { .flash .word-pic { width: 120px; height: 120px; margin-bottom: 8px; } }
td.es .word-thumb { width: 40px; height: 40px; border-radius: 8px; vertical-align: middle; margin-right: 10px; }
.flash .front.en { font-family: var(--font); font-weight: 600; font-size: clamp(22px, 4.2vw, 32px); }
.flash .hint { margin-top: 14px; color: var(--faint); font-size: 14px; }
.flash .answer { margin-top: 22px; padding-top: 20px; border-top: 1px dashed var(--line2); width: 100%; }
.flash .answer .big-ans { font-size: clamp(20px, 3.6vw, 26px); font-weight: 600; overflow-wrap: anywhere; }
.flash .answer .big-ans.es { font-weight: 500; font-family: var(--serif); }
.flash .note { margin-top: 10px; color: var(--mute); }
.flash .ex { margin-top: 6px; color: var(--mute); font-style: italic; font-family: var(--serif); }
.blank { display: inline-block; min-width: 3.2em; border-bottom: 3px solid var(--accent); margin: 0 .1em; color: var(--accent); font-weight: 600; }
.grades { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px; }
.grades button { min-height: 56px; font-size: 17px; border-radius: 16px; }
.grades .again { background: var(--bad-soft); border-color: transparent; color: var(--bad); }
.grades .got { background: var(--good-soft); border-color: transparent; color: var(--good); }
.grades kbd, .key { font: 600 13px var(--mono); padding: 2px 6px; border-radius: 6px; background: color-mix(in srgb, currentColor 12%, transparent); }
/* inside the accent button the key's chip darkens the button instead of lightening it, so it stays readable */
.primary kbd, .primary .key { background: rgba(0, 0, 0, .2); color: var(--accent-ink); }
.typeans { display: flex; gap: 10px; margin-top: 16px; }
.typeans input { flex: 1; min-width: 0; }
.verdict { margin-top: 14px; padding: 12px 16px; border-radius: 12px; font-weight: 600; text-align: left; }
.verdict.ok { background: var(--good-soft); color: var(--good); }
.verdict.no { background: var(--bad-soft); color: var(--bad); }
.verdict.near { background: var(--warn-soft); color: var(--warn); }
/* the answer inside a verdict is emphasis in the verdict's own face, not the card's serif */
.verdict .es { font-family: var(--font); font-weight: 750; }
.accents { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.accents { gap: 8px; }
.accents button { min-height: 44px; min-width: 44px; padding: 0 10px; border-radius: 10px; font-family: var(--serif); font-size: 17px; }
.summary { text-align: center; padding: 30px 20px; }
.summary .score { font-size: 54px; font-weight: 750; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
/* a summary's heading sits centred under its score, on one line or several (.panel h2 is a flex row) */
.summary h2 { justify-content: center; }
.choices { display: grid; gap: 10px; margin-top: 18px; width: 100%; text-align: left; }
.choice { display: flex; gap: 12px; align-items: center; width: 100%; min-height: 54px; padding: 10px 16px; border-radius: 14px; border: 1.5px solid var(--line2); background: var(--panel); cursor: pointer; font: 500 17px/1.3 var(--font); color: var(--fg); text-align: left; }
.choice .dot { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--field); flex: none; display: grid; place-items: center; }
.choice[aria-checked=true] .dot::after { content: ''; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); }
.choice.right { border-color: var(--good); background: var(--good-soft); }
.choice.wrong { border-color: var(--bad); background: var(--bad-soft); }
.choice:disabled { opacity: 1; cursor: default; }
/* the quiz's verdict and Next sit inside the centred card: full width there too, as in Study and Drills */
.flash > #after { align-self: stretch; text-align: left; }
.flash > #after .verdict { margin-top: 14px; }

/* Forms */
label.field { display: grid; gap: 6px; font-weight: 600; font-size: 14px; }
label.field > span.mute { font-weight: 500; }
input[type=text], input[type=email], input[type=number], input[type=search], input:not([type]), select, textarea {
  font: 16px/1.4 var(--font); color: var(--fg); background: var(--panel); border: 1px solid var(--field); border-radius: 12px; padding: 10px 12px; min-height: 44px; width: 100%; min-width: 0; }
textarea { resize: vertical; min-height: 120px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.err { color: var(--bad); font-weight: 600; margin: 6px 0; }
.err:empty { display: none; }
.ok-text { color: var(--good); font-weight: 600; overflow-wrap: anywhere; }
.switch { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; font-weight: 600; }
.switch input { appearance: none; -webkit-appearance: none; width: 44px; height: 26px; border-radius: 999px; background: var(--field); position: relative; cursor: pointer; transition: background .15s; margin: 0; flex: none; }
.switch input::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); }
.switch input:checked { background: var(--accent-2); }
.switch input:checked::after { transform: translateX(18px); }

/* Tables */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); }
table { border-collapse: collapse; width: 100%; font-size: 15px; }
th, td { text-align: left; padding: 10px 12px; border-top: 1px solid var(--line); vertical-align: middle; overflow-wrap: break-word; word-break: normal; hyphens: auto; }
th { border-top: 0; font-size: 14px; font-weight: 650; color: var(--mute); background: var(--sunk); position: sticky; top: 0; }
tr.clickable { cursor: pointer; }
/* A clickable row's first words are its button (or link) for the keyboard: they look like the cell's text. */
td .cell-btn, td .cell-link { display: inline; min-height: 0; padding: 0; border: 0; border-radius: 4px; background: none; color: inherit; font: inherit; letter-spacing: inherit;
  text-align: left; text-decoration: none; white-space: normal; overflow-wrap: anywhere; cursor: pointer; }
@media (hover: hover) { tr.clickable:hover .cell-btn, tr.clickable:hover .cell-link { text-decoration: underline; text-underline-offset: 3px; } }
td .cell-btn:active { transform: none; }
@media (hover: hover) { tr.clickable:hover td { background: color-mix(in srgb, var(--sunk) 60%, transparent); } }
th.n, td.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.act { white-space: nowrap; text-align: right; width: 1%; }
@media (min-width: 721px) { td.act > button + button { margin-left: 8px; } }

/* Drop zone */
.drop { border: 2px dashed var(--line2); border-radius: 20px; padding: 34px 24px; text-align: center; background: var(--panel); transition: border-color .15s, background .15s; }
.drop.over { border-color: var(--accent); background: var(--accent-soft); }
.drop > svg { width: 48px; height: 48px; color: var(--accent); }
.dropveil { position: fixed; inset: 0; z-index: 90; background: color-mix(in srgb, var(--accent) 22%, transparent); display: grid; place-items: center; pointer-events: none; }
.dropveil div { background: var(--panel); padding: 22px 30px; border-radius: 18px; font-weight: 700; font-size: 20px; box-shadow: var(--shadow-lg); border: 2px dashed var(--accent); }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--line2); border-top-color: var(--accent); animation: spin .9s linear infinite; flex: none; }
@keyframes spin { to { transform: rotate(360deg); } }
.working { display: flex; gap: 14px; align-items: center; padding: 18px; border-radius: var(--r); background: var(--sunk); }

/* Dialogs and toasts */
/* A dialog is one column: its heading and buttons always show, and only its body scrolls (dvh: the height
   with the browser's own bars, and the keyboard where the browser resizes for it). */
dialog { border: 1px solid var(--line); border-radius: 18px; background: var(--panel); color: var(--fg); padding: 0; width: min(560px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); box-shadow: var(--shadow-lg); }
dialog[open]:has(> .dbody) { display: flex; flex-direction: column; }   /* the site's own (core.js), not a widget's */
dialog::backdrop { background: rgba(20, 14, 8, .45); }
dialog .dhead { display: flex; align-items: center; gap: 10px; padding: 18px 20px 6px; flex: none; }
dialog .dhead h2 { margin: 0; flex: 1; }
dialog .dbody { padding: 10px 20px 8px; overflow: auto; flex: 1 1 auto; min-height: 0; overscroll-behavior: contain; }
dialog .dfoot { display: flex; gap: 10px; justify-content: flex-end; padding: 12px 20px 18px; flex-wrap: wrap; flex: none; }
/* A short screen (a phone on its side, or any phone with the keyboard up): the dialog takes the whole screen and
   scrolls as one, its heading going up with the fields and its buttons kept at the foot, so the field being
   typed in always has room. */
@media (max-height: 500px) {
  dialog:has(> .dbody) { width: 100vw !important; max-width: 100vw; height: 100dvh; max-height: 100dvh; border: 0; border-radius: 0; }
  dialog[open]:has(> .dbody) { overflow: auto; overscroll-behavior: contain; scroll-padding: 8px 0 76px; }
  dialog .dbody { flex: none; overflow: visible; padding: 6px max(14px, env(safe-area-inset-right)) 8px max(14px, env(safe-area-inset-left)); }
  dialog .dhead { padding: 8px max(10px, env(safe-area-inset-right)) 0 max(14px, env(safe-area-inset-left)); }
  dialog .dfoot { position: sticky; bottom: 0; margin-top: auto; background: var(--panel); border-top: 1px solid var(--line);
    padding: 8px max(14px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left)); }
}
.toasts { position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 100; display: grid; gap: 8px; width: min(520px, calc(100vw - 24px)); pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: center; gap: 12px; padding: 6px 6px 6px 16px; border-radius: 14px; background: var(--fg); color: var(--bg); box-shadow: var(--shadow-lg); font-weight: 600; animation: rise .2s ease-out; }
/* a toast takes no tap until it has settled (core.js), so a tap aimed at what was there lands there */
.toast.new { pointer-events: none; }
.toast span { flex: 1; min-width: 0; }
.toast button { min-height: 44px; background: transparent; color: var(--bg); border-color: color-mix(in srgb, var(--bg) 40%, transparent); }
/* the page's own background on the error colour: 5.9:1 in light, 8.2:1 in dark (white on dark's salmon was 2.3:1) */
.toast.bad { background: var(--bad); color: var(--bg); }
@keyframes rise { from { transform: translateY(8px); opacity: 0; } }
.guard { max-width: 520px; margin: 12vh auto; padding: 26px; border-radius: 18px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); }

/* Tutor: Lola in the corner */
.tutor { position: fixed; right: calc(18px + env(safe-area-inset-right)); bottom: calc(18px + env(safe-area-inset-bottom)); z-index: 60; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; pointer-events: none; transition: right .5s cubic-bezier(.3, .7, .3, 1), bottom .5s cubic-bezier(.3, .7, .3, 1); }
.tutor > * { pointer-events: auto; }
.lola { width: 96px; height: 120px; border: 0; padding: 0; background: none; cursor: pointer; border-radius: 40px; min-height: 0; position: relative; }
.lola:hover { border: 0; }
.lola svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 6px 10px rgba(40, 28, 16, .22)); }
.lola .bob { animation: bob 3.2s ease-in-out infinite; transform-origin: 50% 90%; }
.lola.talk .beak-low { animation: talk .22s ease-in-out infinite alternate; }
@keyframes bob { 50% { transform: translateY(-3px) rotate(-1.5deg); } }
@keyframes talk { to { transform: translateY(2.5px) rotate(8deg); } }
.bubble { position: relative; max-width: 290px; padding: 12px 14px; border-radius: 16px 16px 4px 16px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-lg); font-size: 15px; line-height: 1.45; }
/* the close X is a full 44 px to press, reaching just past the bubble's corner, so a near miss closes it */
.bubble button.x { position: absolute; top: -6px; right: -6px; min-height: 44px; width: 44px; padding: 0; border: 0; background: none; color: var(--faint); }
/* overflow clip: nothing (not even focusing the message box) can scroll the head out of the panel */
.chat { width: min(400px, calc(100vw - 24px)); height: min(560px, calc(100dvh - 180px)); background: var(--panel); border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--shadow-lg); display: flex; flex-direction: column; overflow: hidden; overflow: clip; }
/* opened by a tap, the chat itself has the focus (tutor.js), so the keyboard waits for a tap in the box */
.chat:focus { outline: none; }
.chat-head { display: flex; align-items: center; gap: 8px; padding: 12px 10px 10px 16px; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.chat-head b { flex: 1; }
.chat-log { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; min-height: min(96px, 18dvh); }
.msg { max-width: 86%; padding: 10px 13px; border-radius: 16px; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; }
.msg.bot { align-self: flex-start; background: var(--sunk); border-bottom-left-radius: 4px; }
.msg.me { align-self: flex-end; background: var(--accent); color: var(--accent-ink); border-bottom-right-radius: 4px; }
.msg .fix { display: block; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line2); color: var(--accent-2); font-weight: 600; }
/* the quick replies are one row that scrolls sideways, so they never push the conversation off a short screen */
.chat-quick { display: flex; gap: 8px; padding: 0 12px 8px; flex-wrap: nowrap; flex-shrink: 0; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.chat-quick::-webkit-scrollbar { display: none; }
.chat-quick button { min-height: 44px; font-size: 14px; padding: 0 14px; flex-shrink: 0; }
.chat-in { display: flex; gap: 8px; padding: 10px; border-top: 1px solid var(--line); align-items: flex-end; flex-shrink: 0; }
.chat-in textarea { flex: 1; width: auto; min-height: 44px; max-height: 120px; resize: none; border-radius: 14px; }
.chat-in > button { flex: none; }
.chat-in .icon { width: 44px; min-height: 44px; }
.mic.on { background: var(--bad); border-color: var(--bad); color: #fff; animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--bad) 25%, transparent); } }
.tour-ring { position: fixed; z-index: 55; border-radius: 14px; box-shadow: 0 0 0 4px var(--accent), 0 0 0 9999px rgba(20, 14, 8, .35); pointer-events: none; transition: all .45s cubic-bezier(.3, .7, .3, 1); }

/* Splash */
.splash { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; background: radial-gradient(60% 50% at 30% 30%, rgba(255, 138, 92, .22), transparent 70%), radial-gradient(50% 50% at 75% 70%, rgba(111, 201, 174, .16), transparent 70%), #14110e; color: #f3eee8; transition: opacity .45s; }
.splash::before { content: ''; position: absolute; inset: 0; background-image: linear-gradient(rgba(255, 255, 255, .04) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .04) 1px, transparent 1px); background-size: 34px 34px; -webkit-mask-image: radial-gradient(circle at 50% 50%, #000, transparent 70%); mask-image: radial-gradient(circle at 50% 50%, #000, transparent 70%); animation: drift 12s linear infinite; }
@keyframes drift { to { background-position: 34px 34px; } }
.splash .mark { position: relative; text-align: center; }
.splash svg { width: 96px; height: 96px; }
.splash svg path, .splash svg circle { stroke-dasharray: 400; stroke-dashoffset: 400; animation: draw 1.6s ease-out forwards; }
.splash svg .dot { animation-delay: 1.2s; }
.splash .word { margin-top: 14px; font: 700 22px var(--font); letter-spacing: -.01em; opacity: 0; animation: fade .6s 1.3s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fade { to { opacity: 1; } }
/* A screen that takes a moment says so, but only after the moment, so a quick one never flickers. */
.page-wait { opacity: 0; animation: fade .2s .6s forwards; }
.splash.out { opacity: 0; pointer-events: none; }

/* Signed out */
.signin { max-width: 980px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 34px; align-items: center; padding: 6vh 0; }
.signin h1 { font-size: 40px; letter-spacing: -.02em; }
.signin .lead { font-size: 18px; color: var(--mute); }
.signin .panel { padding: 26px; }
.codebox { font: 700 26px/1 var(--mono); letter-spacing: 8px; text-align: center; }

@media (max-width: 900px) {
  .grid.two, .grid.three, .grid.even { grid-template-columns: minmax(0, 1fr); }
  .signin { grid-template-columns: minmax(0, 1fr); padding: 2vh 0; }
  .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  :root { --bar-h: 56px; --gut-l: max(14px, env(safe-area-inset-left)); --gut-r: max(14px, env(safe-area-inset-right)); }
  /* the tab bar's height, signed in (a signed-out page has none) */
  :root:has(#tabbar:not([hidden])) { --tab-h: 58px; }
  .bar { padding: 0 max(10px, env(safe-area-inset-right)) 0 max(14px, env(safe-area-inset-left)); }
  .bar .nav, .bar .add-btn { display: none; }
  .pubnav .ghost { display: none; }
  .brand { margin-right: auto; }
  .tabbar { display: grid; grid-template-columns: repeat(6, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; background: color-mix(in srgb, var(--panel) 92%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-top: 1px solid var(--line);
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
  .tabbar a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; height: calc(var(--tab-h) - 1px); padding: 0; font-size: 12px; line-height: 16px; font-weight: 650; color: var(--mute); text-decoration: none; white-space: nowrap; min-width: 0; }
  .tabbar a svg { width: 24px; height: 24px; flex: none; }
  .tabbar a[aria-current=page] { color: var(--accent); }
  .page { padding: 18px var(--gut-r) 170px var(--gut-l); }
  .hero { grid-template-columns: minmax(0, 1fr); padding: 20px; }
  .hero h1 { font-size: 25px; }
  .hero .actions { min-width: 0; }
  h1 { font-size: 23px; }
  .tutor { right: max(10px, env(safe-area-inset-right)); bottom: calc(var(--tab-h) + 12px + env(safe-area-inset-bottom)); }
  /* At rest she peeks in over the 14px gutter and the cards' 18px padding only (10 + 44 - 22 = 32px of
     her box on the screen), never their text or buttons; she slides fully in while she speaks and when
     her chat is open, and further out while the page scrolls. */
  .lola { width: 44px; height: 56px; transition: transform .35s cubic-bezier(.3, .7, .3, 1), opacity .35s; }
  .tutor:not(.open):not(.saying) .lola { transform: translateX(22px); }
  .tutor.tucked:not(.open):not(.saying) .lola { transform: translateX(30px); opacity: .85; }
  .seg .long { display: none; }
  .seg .short { display: inline; }
  th, td { padding: 9px 10px; }
  .chat { height: min(520px, calc(100dvh - 230px)); }
  .flash { min-height: 260px; padding: 30px 18px 20px; }
  .field-row { grid-template-columns: minmax(0, 1fr); }
  .signin h1 { font-size: 30px; }
  .hide-sm { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* Lessons, Add, Settings, Owner */
.keep-hit { display: inline-grid; place-items: center; cursor: pointer; min-width: 44px; min-height: 44px; }
.titlerow { flex-wrap: nowrap; align-items: flex-start; }
.titlerow h1 { min-width: 0; overflow-wrap: break-word; hyphens: auto; }
.titlerow .icon { margin-top: -6px; }
.ways .panel { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 16px; }
.ways .panel p { margin: 0; }
.ways .panel .btn { margin-top: auto; }
.ways .copyline { align-self: stretch; margin-top: auto; }
/* A lesson card opens from anywhere on it (its title's link reaches over the whole card), like a deck's;
   its Study and Drills buttons sit above that and open on their own. */
.lesson-card { position: relative; }
.lesson-card h3 a { color: inherit; text-decoration: none; }
.lesson-card a.stretch::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
@media (hover: hover) { .lesson-card h3 a:hover { text-decoration: underline; text-underline-offset: 3px; } }
.lesson-card .lift { margin-top: 2px; position: relative; z-index: 1; gap: 8px; }
.lesson-card .lift .btn { min-height: 44px; font-size: 14px; padding: 0 16px; }
.nowrap { white-space: nowrap; }
tr.off td { opacity: .45; }
tr.off td.act { opacity: 1; }
.preview { margin: 14px 0 0; padding: 12px 14px; border-radius: var(--r-sm); background: var(--sunk); color: var(--mute); font-size: 15px; max-height: 9.5em; overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere; }
.cost { display: flex; gap: 12px; align-items: flex-start; margin-top: 14px; padding: 14px 16px; border-radius: var(--r-sm); background: var(--accent-2-soft); color: var(--fg); }
.cost > svg { width: 22px; height: 22px; color: var(--accent-2); flex: none; margin-top: 1px; }
.cost.stop { background: var(--warn-soft); }
.cost.stop > svg { color: var(--warn); }
.tips .panel h3 { margin-bottom: 6px; }
.tips .panel p { margin: 0; }
.settings { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 22px; align-items: start; }
.settings .side { position: sticky; top: calc(var(--bar-h) + 20px); display: grid; gap: 2px; }
.settings .side a { color: var(--mute); text-decoration: none; font-weight: 600; padding: 9px 12px; border-radius: 10px; }
.settings .side a[aria-current] { background: var(--sunk); color: var(--fg); }
@media (hover: hover) { .settings .side a:hover { background: var(--sunk); color: var(--fg); } }
.settings section { scroll-margin-top: 4px; }   /* the page's scroll-padding already clears the bar */
.flash-in { animation: flashin 1.6s ease-out; }
@keyframes flashin { 0% { box-shadow: 0 0 0 3px var(--accent), var(--shadow); } 100% { box-shadow: 0 0 0 3px transparent, var(--shadow); } }
.steps { margin: 6px 0 12px; padding-left: 22px; display: grid; gap: 12px; }
.steps li::marker { font-weight: 700; color: var(--accent); }
.copyline { display: flex; gap: 8px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
.copyline code, code { font: 14px/1.4 var(--mono); background: var(--sunk); border-radius: 8px; padding: 2px 6px; overflow-wrap: anywhere; }
.copyline code { padding: 9px 12px; flex: 1; min-width: 0; }
.tile .label { color: var(--mute); font-weight: 650; font-size: 14px; }
.tile .big-num { font-size: 26px; font-weight: 750; letter-spacing: -.01em; margin: 4px 0 10px; font-variant-numeric: tabular-nums; }
.tile .big-num .mute { font-size: 15px; font-weight: 600; }
.tile p { margin: 10px 0 0; }
.meter.thick { height: 12px; }
.bars { display: grid; gap: 6px; }
.bar-row { display: grid; grid-template-columns: 70px minmax(0, 1fr) 64px; gap: 10px; align-items: center; }
.bar-row .bar { height: 10px; border-radius: 999px; background: var(--sunk); overflow: hidden; }
.bar-row .bar i { display: block; height: 100%; background: var(--accent-2); border-radius: 999px; }
.bar-row .num { text-align: right; }
.notice { margin-top: 12px; padding: 12px 14px; border-radius: var(--r-sm); background: var(--warn-soft); }
.notice p { margin: 0 0 4px; }
.ok-text svg { width: 18px; height: 18px; vertical-align: -3px; }
@media (max-width: 900px) {
  .settings { grid-template-columns: minmax(0, 1fr); }
  .settings .side { position: static; display: flex; flex-wrap: wrap; gap: 8px; }
  .settings .side a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; background: var(--sunk); font-size: 14px; }
}

/* Lola's chat, more */
.tutor.open .lola { width: 64px; height: 80px; }
.chat-head .mini { width: 30px; height: 38px; flex: none; margin: -4px 2px -4px -4px; }
.chat-head .mini svg { width: 100%; height: 100%; }
.chat-head small { display: block; font-size: 14px; }
.msg { position: relative; }
.msg.bot { padding-right: 34px; }
.msg .again { position: absolute; right: 2px; bottom: 2px; width: 30px; min-height: 30px; color: var(--faint); }
/* drawn at 30 px in the bubble's corner, pressed over 44 */
.msg .again::after { content: ''; position: absolute; inset: -7px; }
.msg .again svg { width: 16px; height: 16px; }
.msg.note { align-self: center; max-width: 92%; background: none; color: var(--mute); font-size: 14px; text-align: center; padding: 4px 8px; }
.msg.note.state { background: var(--warn-soft); color: var(--fg); border-radius: 12px; padding: 10px 12px; }
.msg.typing { display: flex; gap: 4px; padding: 14px 16px; }
.msg.typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); animation: dot 1s ease-in-out infinite; }
.msg.typing i:nth-child(2) { animation-delay: .15s; } .msg.typing i:nth-child(3) { animation-delay: .3s; }
@keyframes dot { 50% { transform: translateY(-4px); opacity: .5; } }
.chat-in .lang { width: 44px; min-width: 44px; padding: 0; font-size: 14px; color: var(--mute); }
.mic { position: relative; }
.mic .lvl { display: none; position: absolute; inset: 0; align-items: center; justify-content: center; gap: 3px; }
.mic.on svg { opacity: 0; }
.mic.on .lvl { display: flex; }
.mic .lvl i { width: 4px; height: 20px; border-radius: 2px; background: #fff; transform: scaleY(.15); transition: transform .06s linear; }

/* Tour */
.tourpop { position: fixed; z-index: 120; width: min(360px, calc(100vw - 16px)); background: var(--panel); color: var(--fg); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-lg); padding: 16px 16px 12px; }
.tourpop p { color: var(--mute); margin: 0 0 12px; font-size: 15px; }
.tourpop .tour-sec { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--accent); margin-bottom: 4px; }
.tourpop .tour-t { margin: 0 0 6px; font-size: 17px; }
.tourpop .tour-bar { height: 4px; border-radius: 999px; background: var(--sunk); overflow: hidden; margin-bottom: 10px; }
.tourpop .tour-bar i { display: block; height: 100%; background: var(--accent); }
.tourpop button { min-height: 44px; padding: 0 16px; font-size: 14px; }
/* tour.js writes its button row's gap inline (6 px); 8 px between them */
.tourpop .row[style] { gap: 8px !important; }
.tour-ring { z-index: 110; }
/* Over the page while the tour's next step gets ready (tour.js): a tap then lands here, on nothing. */
.tour-shield { position: fixed; inset: 0; z-index: 115; }
.guide .lead { font-size: 17px; }
.guide h3 { margin-top: 16px; }
.guide p { color: var(--mute); }


/* Critic round 1 */
input[type=checkbox] { accent-color: var(--accent-2); }
.picked { display: flex; gap: 12px; align-items: center; min-width: 0; }
.picked > svg { width: 34px; height: 34px; color: var(--accent); flex: none; }
.picked b { overflow-wrap: anywhere; }
.choice { white-space: normal; justify-content: flex-start; }
.settings select { max-width: 240px; }
.more-line { margin: 8px 2px 0; }
.signin .hello { display: flex; gap: 4px; align-items: flex-start; margin-top: 22px; }
.signin .hello .char { width: 112px; height: 140px; flex: none; }
.signin .hello .char svg { width: 100%; height: 100%; }
/* the bubble sits beside her head, its sharp corner toward her beak */
.signin .hello .bubble { position: static; margin-top: 16px; border-radius: 16px 16px 16px 4px; }
.chat-scrim { display: none; }
@media (max-width: 720px) {
  /* Tables become stacked rows on a phone: the Spanish, its meaning under it, the state on the right. */
  .stack-sm thead { display: none; }
  .stack-sm tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; row-gap: 2px; padding: 11px 14px; border-top: 1px solid var(--line); align-items: center; }
  .stack-sm tbody tr:first-child { border-top: 0; }
  .stack-sm td { display: block; border: 0; padding: 0; grid-column: 1; }
  .stack-sm td.hide-sm { display: none !important; }
  .stack-sm td.mean { color: var(--mute); font-size: 14.5px; }
  .stack-sm td.side { grid-column: 2; grid-row: 1 / span 2; justify-self: end; }
  .stack-sm td.act { grid-column: 2; grid-row: 1 / span 3; justify-self: end; width: auto; display: flex; gap: 12px; align-items: center; }
  .stack-sm, .stack-sm tbody { display: block; width: 100%; }
  .stack-sm.with-side td.side { grid-column: 1; grid-row: auto; justify-self: start; margin-top: 4px; }
  /* a row with two right-hand cells (Admin's Talk live calls: the length, then the credits) puts them one over the other */
  .stack-sm tbody tr:has(td.side + td.side) { grid-auto-flow: row dense; }
  .stack-sm tbody tr:has(td.side + td.side) td.side { grid-row: auto; }
  .stack-sm.lead tbody tr { grid-template-columns: auto minmax(0, 1fr); }
  .stack-sm.lead td { grid-column: 2; }
  .stack-sm.lead td.act { grid-column: 1; grid-row: 1 / span 3; justify-self: start; }
  /* keep or take out: the box is big enough to see and its whole 44px cell takes the tap */
  .stack-sm td.act input[type=checkbox] { width: 26px; height: 26px; margin: 9px 0; }
  .stack-sm.lead td.act { min-width: 44px; min-height: 44px; display: grid; place-items: center; }
  .stack-sm.below td.act { grid-column: 1 / -1; grid-row: auto; justify-self: stretch; display: flex; gap: 8px; margin-top: 8px; }
  .stack-sm.below td.act .btn, .stack-sm.below td.act button.quiet { flex: 1; }
  /* the nine accent keys in two rows, each a full 44 px key with 8 px between */
  .accents { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
  .accents button { min-width: 0; min-height: 44px; padding: 0; }
  @media (min-width: 560px) { .accents { grid-template-columns: repeat(9, minmax(0, 1fr)); } }
  /* in a drill the keys take the whole line and Hint goes under them */
  .row > .accents { flex: 1 1 100%; }
}
/* Lola's chat is a sheet from the bottom on a phone, on any short screen (a phone on its side) and on a touch
   tablet, over a dimmed page, so the page under it never looks usable. It sits on the keyboard and fits what
   is visible above it: app.js keeps --vvh (the visible height) and --kb (how much of the window the keyboard
   covers), since iOS does not shrink the page for it. */
@media (max-width: 720px), (max-height: 520px), (pointer: coarse) and (max-width: 1100px) {
  .tutor.open { left: 0; right: 0; bottom: var(--kb, 0px); align-items: stretch; }
  .tutor.open .lola { display: none; }
  .tutor.open .chat { width: 100%; height: min(calc(var(--vvh, 100dvh) - 8px), calc(100dvh - 8px), 78dvh, 640px); border-radius: 20px 20px 0 0; border-bottom: 0;
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
  .tutor.open .chat-scrim { display: block; position: fixed; inset: 0; background: rgba(20, 14, 8, .38); z-index: -1; }
  .chat-head { padding-top: 8px; padding-bottom: 8px; }
}
/* A short screen gives the sheet nearly all of it, and the quick replies step aside while you type; with a
   phone on its side and the keyboard up, the head keeps to one slim line, so the message box always shows. */
@media (max-height: 600px) {
  .tutor.open .chat { height: min(calc(var(--vvh, 100dvh) - 8px), calc(100dvh - 8px), 640px); }
  .chat:has(#tu-text:focus) .chat-quick { display: none; }
}
@media (max-height: 320px) {
  .chat-head small { display: none; }
  .chat-head { padding-top: 4px; padding-bottom: 4px; }
  .chat-log { padding-top: 6px; padding-bottom: 6px; }
  .chat-in { padding-top: 6px; padding-bottom: 6px; }
}
/* On a wider short screen (a phone on its side) or a touch tablet the sheet keeps to the right, under Lola's corner. */
@media (min-width: 721px) and (max-height: 520px), (min-width: 721px) and (max-width: 1100px) and (pointer: coarse) {
  .tutor.open .chat { align-self: flex-end; width: min(100%, 640px); margin-right: env(safe-area-inset-right); padding-right: 0; }
}
/* On the narrowest phones the head keeps to one line: Hands-free shows as its microphone (its name stays). */
@media (max-width: 380px) {
  .chat-head button.talk-btn { width: 44px; padding: 0; }
  .chat-head button.talk-btn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* Critic round 3 */
/* A heading beside a text button sits on the same line as it; borderless buttons line up with the content edge. */
.row.between > h2, .row.between > h3 { margin: 0; }
.ghost.flush-l { margin-left: -18px; }
.ghost.flush-r { margin-right: -18px; }
.title-link { color: inherit; text-decoration: none; }
@media (hover: hover) { .title-link:hover { text-decoration: underline; text-underline-offset: 3px; } }
.grid.stretch { align-items: stretch; }
.filter { max-width: 300px; }
.bar .add-btn.dup { visibility: hidden; }
.bar .add-btn[aria-current=page] { background: var(--sunk); border-color: transparent; }
.empty.compact { padding: 18px 10px 6px; }
.empty.compact svg { width: 40px; height: 40px; }
.empty.compact p { margin: 0 0 6px; }
.empty.compact .btn { margin-top: 8px; }
.copyline code { white-space: nowrap; overflow-x: auto; overflow-wrap: normal; }
/* An address to read and check (Connect ChatGPT's, an invite link) wraps where it must: never a box to scroll. */
.ways .copyline code, .notice .copyline code { white-space: normal; overflow-wrap: anywhere; overflow-x: visible; }
.bubble { padding-right: 40px; }
.flash:has(> .kind) { padding-top: 56px; }
.grades button:focus-visible { outline-color: currentColor; }
.coarse-only { display: none; }
@media (min-width: 721px) {
  .bubble { max-width: 240px; }
  .hint-btn { margin-right: -18px; }
}
/* a card's progress stays on one line where there is room for it; on a tablet it may wrap, so the words keep theirs */
@media (min-width: 1001px) { td.side { white-space: nowrap; } }
/* Between a phone and a wide screen, Lola is smaller and at rest peeks in 32 px from the edge on every page,
   inside the column's last 40 px (the gutter and a panel's padding), so she never sits on a button or text;
   further while the page scrolls, and fully in while she speaks and when her chat is open. */
@media (min-width: 721px) and (max-width: 1360px) {
  .lola { width: 64px; height: 80px; transition: transform .35s cubic-bezier(.3, .7, .3, 1), opacity .35s; }
  .tutor:not(.open):not(.saying) .lola { transform: translateX(50px); }
  .tutor.tucked:not(.open):not(.saying) .lola { transform: translateX(58px); opacity: .85; }
}
/* On a touch screen there are no keys to press on the buttons and nothing to drop. The keys still show where
   they are the subject (Keyboard shortcuts, the help pages), and Keyboard shortcuts is in the menu once a
   key has been pressed on this device (an iPad with a keyboard; app.js marks it). */
@media (hover: none) and (pointer: coarse) {
  .grades kbd, button kbd, button .key, .choice > .faint { display: none; }
  .fine-only { display: none; }
  .coarse-only { display: inline; }
  html:not([data-keys]) #keys-open { display: none; }
}
@media (max-width: 720px) {
  .pagehead > .row { width: 100%; }
  .pagehead > .row > .btn, .pagehead > .row > button { flex: 1 1 0; }
  .pagehead > .row > .primary { flex-basis: 100%; }
  .pagehead > .row > .menu { flex: none; }
  .pagehead > .row > .ghost.flush-l { margin-left: 0; }
  .drop .row, .settings .panel .row:not(.copyline) { flex-direction: column; align-items: stretch; }
  .row.end > .primary.big { flex-basis: 100%; order: -1; }
  .filter { max-width: none; flex-basis: 100%; }
  .hint-btn { margin-left: -12px; }
  /* the phone's side gutter is 14px, so a flush button never reaches past the screen edge */
  .ghost.flush-l { margin-left: -12px; }
  .ghost.flush-r { margin-right: -12px; }
  /* !important beats the align-items written on Admin's voice rows (owner.js); .row.bottom is the class for it */
  .voice-row { flex-direction: column; align-items: stretch !important; }
  /* the whole address shows on a phone, with Copy under it */
  .ways .copyline code { flex-basis: 100%; }
  .study-top h1 { order: 3; flex-basis: 100%; font-size: 17px !important; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
}
.pubnav { display: flex; gap: 6px; align-items: center; margin-right: 4px; }
.pubnav[hidden] { display: none; }
/* Admin › Voices: each column's meters and forms (owner.js) */
.own-voices .stack { gap: 22px; }
.own-voices h3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.own-meter .big-num { font-size: 22px; font-weight: 750; letter-spacing: -.01em; margin: 10px 0 8px; font-variant-numeric: tabular-nums; }
.own-meter .big-num .mute { font-size: 14px; font-weight: 600; }
.own-form { align-items: flex-end; margin-top: 10px; }
.own-form .field { max-width: 220px; flex: 1 1 160px; }
.own-chosen .chip { flex: none; }
.own-voices .switch { min-height: 44px; }
/* A button whose words may take two lines on a narrow phone (Settings: Download the ChatGPT plugin). */
.btn.wrap { white-space: normal; text-align: center; line-height: 1.25; padding-top: 8px; padding-bottom: 8px; }
/* Text with no spaces to break at (an email address) still fits a narrow phone. */
.any-wrap { overflow-wrap: anywhere; min-width: 0; }
/* No connection (js/install.js): a calm note at the foot of the window, never a pop-up. On a computer a
   small bar in the middle, clear of Lola in the corner; on a phone a full-width bar just above the tab bar
   (or the foot of the screen, signed out), clear of the home indicator's safe area, in one short line, with
   Lola stepping up above it. Toasts sit above it, and a signed-out page leaves room under its footer for it. */
.offline-note { position: fixed; z-index: 35; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom)); transform: translateX(-50%); width: max-content; max-width: min(520px, calc(100vw - 240px));
  padding: 10px 18px; border-radius: 999px; background: var(--warn-soft); color: var(--fg); border: 1px solid var(--line2); box-shadow: var(--shadow);
  font-size: 14px; font-weight: 600; line-height: 1.35; text-align: center; pointer-events: none; }
.offline-note .short { display: none; }
body:has(.offline-note) .toasts { bottom: calc(76px + env(safe-area-inset-bottom)); }
body:has(.offline-note) .pub-foot { padding-bottom: calc(32px + 64px + env(safe-area-inset-bottom)); }
.offline-start h1 { font-size: 24px; }
/* On Talk live the call's controls are pinned to the foot of the screen, so above 720 px the note sits at the
   top of the page instead, under the bar, in room the page leaves for it (--above, live.css and talk.js), and it
   goes up with the page when that scrolls: it covers neither the heading, the minutes, Lola, the words nor the
   controls. Held sideways it says its short form, in one line. The toasts sit under it. */
@media (min-width: 721px) {
  body.live-on .offline-note { position: absolute; z-index: 20; bottom: auto; top: calc(var(--bar-h) + env(safe-area-inset-top) + 8px); }
  body.live-on:has(.offline-note) #toasts { top: calc(var(--bar-h) + env(safe-area-inset-top) + 64px); }
}
@media (min-width: 721px) and (max-height: 500px) {
  body.live-on .offline-note .long { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  body.live-on .offline-note .short { display: inline; }
}
@media (max-width: 720px) {
  .offline-note { left: 0; right: 0; bottom: 0; transform: none; width: auto; max-width: none; border-radius: 0; border-width: 1px 0 0; box-shadow: none;
    padding: 9px max(16px, env(safe-area-inset-right)) calc(9px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); font-size: 14px; text-align: left; }
  .offline-note .long { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .offline-note .short { display: inline; }
  #tabbar:not([hidden]) ~ .offline-note { bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); padding-bottom: 9px; }
  body:has(.offline-note) .tutor:not(.open) { bottom: calc(var(--tab-h) + 52px + env(safe-area-inset-bottom)); }
}

/* Phones, tablets and phones on their side (mobile critics, round 1) */

/* The bar from 721 to 1100 px (an iPad either way up, a phone on its side): the links sit closer, and up to
   1000 px Add class material is its + alone (its name stays for screen readers), so the whole bar fits with
   nothing past the edge. */
@media (min-width: 721px) and (max-width: 1100px) {
  .nav { gap: 4px; }
  .nav a { padding: 0 12px; }
  .brand { margin-right: 6px; }
  .bar .add-btn { margin-left: 0; }
}
@media (min-width: 721px) and (max-width: 1000px) {
  .bar .add-btn { width: 44px; padding: 0; gap: 0; flex: none; }
  .bar .add-btn .add-txt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
@media (min-width: 721px) and (max-width: 840px) {
  .bar:has(#nav:not([hidden])) .brand span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
}
/* The narrowest phones: the name stays on one line beside Sign in and the theme button. */
@media (max-width: 380px) {
  .brand { font-size: 15px; gap: 8px; margin-right: 8px; }
  .brand svg { width: 28px; height: 28px; }
  .pubnav { gap: 4px; margin-right: 0; }
  .pubnav .primary { padding: 0 14px; }
}
@media (max-width: 340px) {
  .brand { font-size: 14px; gap: 6px; margin-right: 0; }
  .brand svg { width: 24px; height: 24px; }
  .pubnav .primary { padding: 0 12px; }
}

/* Toasts on a phone or a short screen sit at the top, under the bar: never over the buttons at the foot of
   the screen (Again and Got it, Next, the tab bar), where the thumb is. */
@media (max-width: 720px), (max-height: 500px) {
  .toasts, body:has(.offline-note) .toasts { top: calc(var(--bar-h) + env(safe-area-inset-top) + 8px); bottom: auto; }
}
/* Under 500 px tall the bar scrolls away and a card fills the screen, so they keep to the top right corner,
   narrow, off the middle where the card's words are. */
@media (max-height: 500px) {
  .toasts, body:has(.offline-note) .toasts { top: calc(env(safe-area-inset-top) + 8px); left: auto; right: max(10px, env(safe-area-inset-right)); transform: none; width: min(300px, 44vw); }
}

/* Study, the quiz and drills on a phone or a short screen: the buttons that answer (Turn it over, Again and
   Got it, Next) stay in sight above the tab bar while the card scrolls under them, and what the browser
   scrolls to keeps clear of them too. */
@media (max-width: 720px), (max-height: 500px) {
  html:has(#main .study .grades, #main .study .study-next) { scroll-padding-bottom: calc(var(--tab-h) + 96px + env(safe-area-inset-bottom)); }
  .study .grades, .study #stage > .study-next, .flash > #after:has(.study-next) { position: sticky; bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); z-index: 5; }
  .study .grades, .study #stage > .study-next { background: var(--bg); margin-top: 8px; padding: 8px 0; }
  .flash > #after:has(.study-next) { background: var(--panel); padding-bottom: 8px; }
}
.flash.drill-card { min-height: 240px; cursor: default; }
/* A short screen: a compact card, so its answer and the buttons fit together. */
@media (max-height: 700px) {
  .flash { min-height: 200px; padding: 24px 16px 18px; }
  .flash:has(> .kind) { padding-top: 52px; }
  .flash.drill-card { min-height: 0; }
}

/* A phone on its side (or any window under 500 px tall): the bar scrolls away with the page, the tab bar is one
   slim row, and the study screens drop what can wait (the title stays for screen readers). */
@media (max-height: 500px) {
  html { scroll-padding-top: calc(env(safe-area-inset-top) + 12px); }
  .bar { position: relative; }
  /* the way back, the count, the direction and Type the answer share one line where they fit */
  .study { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; }
  .study > * { flex: 1 1 100%; min-width: 0; }
  .study > .study-top, .study > .row.between { flex: 1 1 auto; margin: 0; }
  .progressline { margin-bottom: 10px; }
  .flash { min-height: 0; padding: 16px; }
  .flash:has(> .kind) { padding-top: 52px; }
  .flash .front { font-size: 28px; }
  .grades button { min-height: 48px; }
}
/* Sideways, and on the shortest upright phones, the study screens' title waits for a bigger screen (it stays for
   screen readers), so the way back, the count and Undo fit above the question after every answer (study.js). */
@media (max-height: 500px), (max-width: 720px) and (max-height: 600px) {
  .study-top h1 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
/* The very shortest (a small phone on its side) leaves out the progress line too: the count says the same. */
@media (max-height: 340px) { .study .progressline { display: none; } }
@media (max-width: 720px) and (max-height: 500px) {
  :root:has(#tabbar:not([hidden])) { --tab-h: 44px; }
  .tabbar a { flex-direction: row; gap: 6px; }
  .tabbar a svg { width: 22px; height: 22px; }
}

/* While a text field has the keyboard on a phone or a short screen, the tab bar and Lola at rest step away, so
   nothing fixed sits over what is being typed. */
@media (max-width: 720px), (max-height: 500px) {
  body:has(:is(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):not([type=button]):not([type=submit]), textarea):focus) :is(.tabbar, .tutor:not(.open)) { display: none; }
}

/* Lola at rest on a phone tucks further in where buttons and text run to the right edge (study, the quiz,
   drills, help articles, data pages); from 721 to 1360 px she peeks in the same on every page (above). */
@media (max-width: 720px) {
  body:has(#main .study, #main .help-article, #main.wide) .tutor:not(.open):not(.saying) .lola { transform: translateX(34px); }
}
/* Her speech bubble on a phone sits up under the bar on every page, never over what the thumb works at the
   foot (the main button, the microphone, a plan's ticks, Again and Got it). On every screen a tap goes through
   a bubble to what is under it: only its X takes one, and Lola herself opens the chat. */
@media (max-width: 720px) {
  .bubble { max-width: min(240px, calc(100vw - 96px)); }
  .tutor.saying .bubble { position: fixed; top: calc(var(--bar-h) + env(safe-area-inset-top) + 8px); right: max(10px, env(safe-area-inset-right)); max-width: min(280px, calc(100vw - 20px)); border-radius: 16px; }
  /* on the study screens it is a passing word of praise that takes no tap at all (its X would sit on Undo) */
  body:has(#main .study) .tutor.saying .bubble { padding-right: 14px; }
  body:has(#main .study) .tutor.saying .bubble button.x { display: none; }
}
.tutor .bubble { pointer-events: none; }
.tutor .bubble button.x { pointer-events: auto; }
.chat-head button.talk-btn { min-height: 44px; }

/* Data tables: a column marked hide-md (a deck's Note) waits for a wider screen, so the actions never go past the edge. */
@media (max-width: 1000px) { .hide-md { display: none !important; } }

/* Study's Undo (study.js): a 44 px button beside the count, from an answer until the next one, so nothing
   floats over the card or the controls above it (an answer's Undo is never a toast here). */
.study-top .undo-btn { min-height: 44px; padding: 0 14px; font-size: 14px; flex: none; }
.study-top .undo-btn svg { width: 18px; height: 18px; }
.study-top .undo-btn.idle { visibility: hidden; }   /* nothing to undo just now: its place is kept */
@media (max-width: 720px) { .study-top #count { margin-left: auto; } }

/* Add class material on a phone or a short screen: the three ways in come first (the formats line goes under
   them and the drop zone's icon waits for a bigger screen), and on a phone Import a lesson file and ChatGPT
   go under the tips (add.js draws them in both places; one shows). Sideways the three share one row. */
.add-alt.foot { display: none; }
@media (max-width: 720px) {
  .add-alt.top { display: none; }
  .add-alt.foot { display: flex; margin-top: 16px; }
}
@media (max-width: 720px), (max-height: 500px) {
  .drop { display: flex; flex-direction: column; padding: 18px 16px; }
  .drop > svg { display: none; }
  .drop > p.mute { order: 2; margin: 12px 0 0; font-size: 14px; }
}
@media (max-height: 500px) {
  .drop .row { flex-direction: row; align-items: center; }
  .drop .row > .big { flex: 1 1 auto; min-height: 44px; padding: 0 16px; font-size: 15px; }
}

/* A field a form refused (a card's empty side, a lesson with no title) is marked, beside the words saying why. */
input[aria-invalid=true], textarea[aria-invalid=true] { border-color: var(--bad); }
