/* memq – simple, mobile-first styles (design variant A "Slate": system font, cool grey,
   blue-green accent). Theme: follows the system, or data-theme="light"/"dark" on <html>
   set in Settings (js/theme.js). Every color is a token; the dark values are listed twice
   (system dark without a manual choice, and manual dark). */
:root {
  --bg: #dde3e9;
  --surface: #ffffff;
  --text: #17202b;
  --muted: #536070;
  --border: #ccd4dc;
  --soft: #edf1f4;
  --accent: #1f6f8b;
  --accent-text: #ffffff;
  --accent-soft: #e3f0f4;
  --error: #b4473c;
  --error-soft: #a8625b; /* muted red for warning texts, quieter than --error */
  --ok: #2e7d4f;
  --toast: #1d2732;
  --toast-text: #eef2f5;
  --shadow: rgb(16 24 32 / 0.16);
  --radius: 8px;
  --ok-soft: #e2f2e8;
  --error-tint: #f8e6e3;
  --glow: #c3dbe5;
  --deco: rgb(31 111 139 / 0.11);
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23536070' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  --mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", "DejaVu Sans Mono", Consolas, monospace;
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #11161c;
    --surface: #1a2129;
    --text: #e4e9ee;
    --muted: #94a0ad;
    --border: #2c3641;
    --soft: #222b35;
    --accent: #5fb3cf;
    --accent-text: #0b1418;
    --accent-soft: #18323c;
    --error: #e58a7f;
    --error-soft: #c9958f;
    --ok: #6cc792;
    --toast: #e4e9ee;
    --toast-text: #11161c;
    --shadow: rgb(0 0 0 / 0.45);
    --ok-soft: #1b3227;
    --error-tint: #3a2321;
    --glow: #121b22;
    --deco: rgb(95 179 207 / 0.035);
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a0ad' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #11161c;
  --surface: #1a2129;
  --text: #e4e9ee;
  --muted: #94a0ad;
  --border: #2c3641;
  --soft: #222b35;
  --accent: #5fb3cf;
  --accent-text: #0b1418;
  --accent-soft: #18323c;
  --error: #e58a7f;
  --error-soft: #c9958f;
  --ok: #6cc792;
  --toast: #e4e9ee;
  --toast-text: #11161c;
  --shadow: rgb(0 0 0 / 0.45);
  --ok-soft: #1b3227;
  --error-tint: #3a2321;
  --glow: #121b22;
  --deco: rgb(95 179 207 / 0.035);
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a0ad' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  position: relative;
  z-index: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Soft tint of the accent under the top bar, fading into the page ground. */
  background: linear-gradient(180deg, var(--glow) 0, var(--bg) 30rem) no-repeat, var(--bg);
  color: var(--text);
}
/* The logo's two cards, large and almost transparent, fixed in the bottom right corner. */
body::before {
  content: "";
  position: fixed;
  right: -3rem;
  bottom: -3.5rem;
  z-index: -1;
  width: min(26.5rem, 84vw);
  aspect-ratio: 1;
  background: var(--deco);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='6' width='19' height='14' rx='3' transform='rotate(-12 12.5 13)'/%3E%3Crect x='10' y='12' width='19' height='14' rx='3'/%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 32 32'%3E%3Crect x='3' y='6' width='19' height='14' rx='3' transform='rotate(-12 12.5 13)'/%3E%3Crect x='10' y='12' width='19' height='14' rx='3'/%3E%3C/svg%3E") center / contain no-repeat;
  pointer-events: none;
}

a { color: var(--accent); }

/* Icons (js/icons.js): stroke in the text color, size of the text. */
.ico { width: 1.15em; height: 1.15em; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; vertical-align: -0.2em; }

.top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  /* Stays at the top while the page scrolls (PC and mobile). */
  position: sticky;
  top: 0;
  z-index: 20;
}
.top .brand { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 800; font-size: 1.3rem; letter-spacing: -0.03em; text-decoration: none; color: var(--text); }
.brand-q { color: var(--accent); }
.logo { width: 1.75rem; height: 1.75rem; flex: none; }
.logo-back { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.5; }
.logo-front { fill: var(--accent); }
.logo-line { stroke: var(--accent-text); stroke-width: 1.75; stroke-linecap: round; }
.top .spacer { flex: 1; }
.top .email { display: inline-block; vertical-align: bottom; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 12rem; }
.top .nav-memory { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.3rem 0.7rem; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); text-decoration: none; white-space: nowrap; }
.top .nav-memory:hover { background: var(--soft); border-color: var(--accent); }
.badge { min-width: 1.45em; padding: 0 0.4em; border-radius: 1em; background: var(--accent); color: var(--accent-text); font-size: 0.8rem; font-weight: 700; text-align: center; }
.badge[hidden] { display: none; }
/* The badge pulses once when the count grows (app.js updateBadge()). */
@media (prefers-reduced-motion: no-preference) {
  .badge { position: relative; }
  .badge.pulse { animation: badge-pop 0.45s ease-out; }
  .badge.pulse::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 0 var(--accent); animation: badge-ring 0.9s ease-out; }
}
@keyframes badge-pop { 40% { transform: scale(1.3); } }
@keyframes badge-ring { to { box-shadow: 0 0 0 8px transparent; } }

main { width: 100%; max-width: 48rem; margin: 0 auto; padding: 1.5rem 1rem; }
/* Footer: small and muted, at the bottom of short pages too (body is a flex column). */
.footer { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.3rem 1.2rem; width: 100%; max-width: 48rem; margin: auto auto 0; padding: 1.5rem 1rem; font-size: 0.8rem; color: var(--muted); }
.footer a { color: inherit; }
.footer a:hover { color: var(--text); }
/* Cookie consent bar: sticky at the bottom as the last element of the page, so it never covers
   the footer or other controls for good (scrolled to the end, it sits below them). */
#consent { position: sticky; bottom: 0; z-index: 50; }
.consent { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.6rem 1rem; padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px)); background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -4px 16px var(--shadow); font-size: 0.9rem; }
.consent p { margin: 0; max-width: 36rem; }
.consent-actions { display: flex; gap: 0.5rem; }
.consent-actions button { min-width: 7rem; }
/* Privacy policy and terms (public/legal/*.html). */
.legal h1 { margin-top: 0; }
.legal h2 { font-size: 1.1rem; margin: 1.5rem 0 0.4rem; }
.legal ul, .legal ol { padding-left: 1.3rem; }
.legal li { margin: 0.3rem 0; }

/* Breadcrumb trail above the heading (crumbs() in common.js). */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem 0.35rem; margin: 0 0 0.4rem; font-size: 0.9rem; color: var(--muted); }
.crumbs a, .crumbs span { display: inline-flex; align-items: center; gap: 0.3rem; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs .ico { width: 0.95em; height: 0.95em; }
h1 { font-size: 1.5rem; margin: 0 0 1rem; }
h2 { font-size: 1.15rem; margin: 1.5rem 0 0.75rem; }
.card h2 { margin-top: 0; }
.card-title { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; margin-bottom: 1rem; }
.card-title h1 { margin: 0; }
.card h3 { font-size: 1rem; margin: 1.25rem 0 0.5rem; }

.card {
  max-width: 24rem;
  margin: 0 auto;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* Login and registration: what the app is for. The form keeps the middle of the page; the intro
   sits left of it where both fit, otherwise above it. */
.with-intro { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
.app-intro { width: 100%; max-width: 24rem; margin-inline: auto; }
.app-intro-head { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.9rem; }
.app-intro-head .logo { width: 2.75rem; height: 2.75rem; }
.app-intro-head p { margin: 0; font-size: 1.15rem; font-weight: 600; line-height: 1.35; }
.app-intro ul { display: grid; gap: 0.6rem; margin: 0; padding: 0; list-style: none; }
.app-intro li { display: flex; gap: 0.65rem; }
.app-intro li .ico { width: 1.4em; height: 1.4em; color: var(--accent); }
.app-intro strong { display: block; }
.app-intro li span { display: block; font-size: 0.9rem; color: var(--muted); }
@media (min-width: 62rem) {
  main:has(.with-intro) { max-width: none; }
  .with-intro { grid-template-columns: minmax(0, 1fr) 24rem minmax(0, 1fr); gap: 2.5rem; align-items: start; }
  .app-intro { max-width: 20rem; margin: 0 0 0 auto; padding-top: 1.5rem; }
  .app-intro-head { margin-bottom: 1.25rem; }
  .app-intro ul { gap: 0.9rem; }
}

/* Home with no sets yet: a welcome instead of the empty list. */
.card.welcome { max-width: 28rem; margin: 2rem auto; padding: 2.5rem 1.5rem; text-align: center; }
.welcome .logo { width: 4.5rem; height: 4.5rem; margin-bottom: 1rem; }
.welcome-icon { display: inline-grid; place-items: center; width: 4.5rem; height: 4.5rem; margin-bottom: 1rem; border-radius: 50%; background: var(--accent-soft); color: var(--accent); }
.welcome-icon .ico { width: 2.5rem; height: 2.5rem; }
.title-row[hidden] { display: none; }
.welcome h1 { font-size: 1.75rem; margin-bottom: 0.75rem; }
.welcome p { margin: 0 0 1.5rem; }
.welcome button { width: 100%; padding-block: 0.85rem; font-size: 1.1rem; font-weight: 600; }
.welcome .welcome-alt { margin: 1rem 0 0; font-size: 0.9rem; }

.field { display: block; margin-bottom: 1rem; }
.field span { display: block; margin-bottom: 0.25rem; font-size: 0.9rem; color: var(--muted); }
/* Password with an eye button (show / hide) inside the field on the right. */
.pw { position: relative; }
.pw input { padding-right: 2.9rem; }
.pw input::-ms-reveal { display: none; }
.pw .reveal { position: absolute; top: 50%; right: 0.3rem; transform: translateY(-50%); display: inline-flex; padding: 0.35rem 0.45rem; border: 0; border-radius: 6px; background: none; color: var(--muted); }
.pw .reveal:hover { filter: none; color: var(--text); background: var(--soft); }
.pw .reveal .ico { width: 1.25rem; height: 1.25rem; }

input, select, textarea, button, .button { font: inherit; }

/* Fields: grey = the user can change it (typing or choosing), light with a faint frame = fixed
   information (.static). All the same height. */
input, textarea, select, .static {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background-color: var(--bg);
  color: var(--text);
  line-height: 1.5;
}
input, textarea { width: 100%; }
.field .static span { display: inline; margin: 0; } /* not the block label style of .field span */
.static { background-color: var(--surface); border-color: color-mix(in srgb, var(--border) 60%, var(--surface)); overflow-wrap: anywhere; }
textarea { resize: vertical; }
/* Checkboxes and radios in the app's accent instead of the browser's bright blue. */
input[type=checkbox], input[type=radio] { accent-color: var(--accent); }
[aria-invalid=true] { border-color: var(--error); }
/* Checkboxes have no styled border: mark them with an outline. */
input[type=checkbox][aria-invalid=true] { outline: 2px solid var(--error); outline-offset: 2px; }
input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

select {
  appearance: none;
  padding-right: 2.2rem;
  background-image: var(--chevron);
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 1.1rem;
  cursor: pointer;
}
.field select { width: 100%; }
select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

button, .button {
  display: inline-block;
  padding: 0.6rem 1.2rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-text);
  text-decoration: none;
  cursor: pointer;
}
button:hover, .button:hover { filter: brightness(1.08); }
button:focus-visible, .button:focus-visible, summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button.with-icon, button.icon { display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; }
form.card > button[type=submit] { width: 100%; }
button.secondary, a.button.secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
button.secondary:hover, a.button.secondary:hover { filter: none; background: var(--soft); }
button.ok { background: var(--ok); color: var(--surface); }
button.danger { background: var(--error); color: var(--surface); }
/* Delete as an icon button is quiet (grey); it turns red only on hover. The red filled
   button stays for the final confirmation in the dialog. */
button.icon.danger { background: var(--surface); color: var(--muted); border-color: var(--border); }
button.icon.danger:hover { filter: none; background: var(--soft); color: var(--error); }
button.link { padding: 0; border: 0; background: none; color: var(--accent); text-decoration: underline; }
/* Unavailable: grey outline, no color (disabled, or greyed out but clickable to say why). */
button:disabled, button[aria-disabled=true], button.icon.danger[aria-disabled=true] {
  background: none; color: var(--muted); border-color: var(--border); opacity: 0.6; cursor: not-allowed; filter: none;
}

.hint { margin: -0.6rem 0 1rem; font-size: 0.85rem; color: var(--muted); }
.status { min-height: 1.5em; margin: 0.75rem 0 0; }
.status.error { color: var(--error); }
/* Irreversible consequence in a warning text (e.g. account deletion). */
.danger-text { color: var(--error-soft); }
.status.ok { color: var(--ok); }

.links { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.5rem 1.5rem; margin-top: 1rem; }
/* Resend the email verification link (check-email card, login of an unverified account). */
.resend { margin-top: 0.75rem; }
.resend[hidden] { display: none; }
.resend button, .card.verify > button { width: 100%; }

.notice {
  padding: 0.75rem 1rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-soft);
}


.card.wide { max-width: none; margin: 1rem 0; }

details.section > summary { font-size: 1.15rem; font-weight: 700; cursor: pointer; }
details.section[open] > summary { margin-bottom: 1rem; }
.meta { color: var(--muted); font-size: 0.9rem; }

.actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.actions button, .actions .button { padding: 0.35rem 0.8rem; }
.title-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; margin-bottom: 1rem; }
.title-row h1 { margin: 0; overflow-wrap: anywhere; }

.list { list-style: none; margin: 0 0 1rem; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.list > li { padding: 0.75rem 1rem; border-top: 1px solid var(--border); overflow-wrap: anywhere; }
.list > li:first-child { border-top: 0; }
.list .row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; }
.list .row-main { min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; }
/* Mastery ring in front of a set name (masteryRing() in sets.js): SVG circle, percentage inside. */
.ring-wrap { position: relative; display: inline-flex; flex: none; align-self: center; }
/* Explanation bubble under the ring: on click/tap (.open), on PC also on hover after 0.3 s. */
.ring-wrap .tip {
  position: absolute; left: -0.25rem; top: calc(100% + 0.4rem); z-index: 15;
  width: max-content; max-width: min(18rem, calc(100vw - 3rem)); padding: 0.5rem 0.7rem;
  border-radius: var(--radius); background: var(--toast); color: var(--toast-text);
  box-shadow: 0 8px 24px var(--shadow); font-size: 0.85rem; font-weight: 400; line-height: 1.4;
  visibility: hidden; opacity: 0; transition: opacity 0.12s, visibility 0.12s;
}
.ring-wrap.open .tip { visibility: visible; opacity: 1; }
@media (hover: hover) {
  .ring-wrap:hover .tip { visibility: visible; opacity: 1; transition-delay: 0.3s; }
}
button.ring { display: inline-flex; flex: none; align-self: center; padding: 0; border: 0; border-radius: 50%; background: none; cursor: help; }
button.ring:hover { filter: none; }
.ring svg { width: 2rem; height: 2rem; }
.ring-track, .ring-fill { fill: none; stroke-width: 3.5; }
.ring-track { stroke: var(--border); }
.ring-fill { stroke: var(--accent); stroke-linecap: round; }
/* Rings fill up smoothly on arrival; a set row lifts a little under the mouse. */
@media (prefers-reduced-motion: no-preference) {
  .ring-fill { animation: ring-fill 0.7s ease-out; }
  .list > li.row { transition: background-color 0.12s, box-shadow 0.12s, transform 0.12s; }
}
@keyframes ring-fill { from { stroke-dasharray: 0 100; } }
@media (hover: hover) {
  .list > li.row:hover { position: relative; z-index: 1; border-radius: var(--radius); background: var(--soft); box-shadow: 0 3px 12px var(--shadow); }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .list > li.row:hover { transform: translateY(-1px); }
}
.ring text { fill: var(--text); font-size: 11px; font-weight: 700; text-anchor: middle; dominant-baseline: middle; font-variant-numeric: tabular-nums; }
.list .row-main a { color: var(--text); font-weight: 600; text-decoration: none; }
.list .row-main a:hover { color: var(--accent); }
.list .row .actions, .list .word .actions { flex-wrap: nowrap; flex: none; }
.list .word { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem 1rem; }
.list .word-main { display: flex; align-items: flex-start; gap: 0.75rem; cursor: pointer; }
.list .word-main input { width: 1.25rem; height: 1.25rem; margin: 0.15rem 0 0; flex: none; }
button[hidden], .bulk[hidden], p[hidden] { display: none; }
.title-row .meta { margin: 0.25rem 0 0; }
h1 .h-count { color: var(--muted); font-size: 0.7em; font-weight: 400; }
.toolbar, .bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 1rem; }
.bulk { margin: 0.5rem 0; padding-left: 1rem; }
.bulk .check { margin: 0 0.5rem 0 0; }
.bulk .check input { width: 1.25rem; height: 1.25rem; }
button.icon { padding: 0.35rem 0.6rem; }
details.folder { margin-bottom: 1rem; }
details.folder > summary { margin-bottom: 0.5rem; font-size: 1.1rem; cursor: pointer; }
details.folder > summary .meta { font-size: 0.9rem; }
details.folder .folder-icon { margin: 0 0.35rem 0 0.15rem; color: var(--accent); }
details.folder > .list { margin-left: 1.25rem; }
button.icon.small { margin-left: 0.5rem; padding: 0.2rem 0.35rem; border-color: transparent; background: none; color: var(--muted); font-size: 0.9rem; vertical-align: middle; }
button.icon.small:hover { background: var(--soft); color: var(--text); }
details.group { margin-top: 1.25rem; }
details.group > summary { margin-bottom: 0.75rem; font-size: 1.15rem; font-weight: 700; cursor: pointer; }
/* Same look as the delete icons in the rows and in line with them (list padding + border). */
button.icon.group-delete { float: right; margin: -0.25rem calc(1rem + 1px) 0 0; font-size: 1rem; font-weight: 400; }

/* Dropdown menu (details.menu): the list floats under the toggle, aligned to the right. */
details.menu { position: relative; }
details.menu > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
details.menu > summary::-webkit-details-marker { display: none; }
.menu-items {
  position: absolute;
  right: 0;
  top: calc(100% + 0.25rem);
  z-index: 10;
  min-width: 12rem;
  padding: 0.25rem 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px var(--shadow);
}
.menu-items button, .menu-items a {
  display: block;
  width: 100%;
  padding: 0.5rem 1rem;
  border-radius: 0;
  background: none;
  color: var(--text);
  text-align: left;
  text-decoration: none;
}
.menu-items button:hover, .menu-items a:hover { filter: none; background: var(--soft); }
.menu-items .danger { background: none; color: var(--error); }
.menu-items .separator { margin-top: 0.25rem; border-top: 1px solid var(--border); padding-top: 0.75rem; }
.top details.menu > summary { border: 0; background: none; }
.top details.menu > summary:hover { color: var(--accent); }

/* Two layouts: PC (wider than 600px) and mobile. */
@media (min-width: 37.5001rem) {
  .mobile-only { display: none !important; }
}
@media (max-width: 37.5rem) {
  .pc-only, button.icon .label { display: none !important; }
  .list > li { padding: 0.6rem 0.75rem; }
  .quiz-view button, .quiz-view .button { width: 100%; }
  .quiz-view .actions { flex-direction: column; }
  .quiz-view .write-actions button { flex: 1; width: auto; }
  .quiz-view .actions.flip-actions { flex-direction: row; }
  .quiz-view .flip-actions button { flex: 1; width: auto; }
}

.dialog {
  max-width: min(26rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 16px 40px var(--shadow);
}
.dialog::backdrop { background: rgb(10 16 22 / 0.45); backdrop-filter: blur(3px); }
@media (prefers-reduced-motion: no-preference) {
  .dialog[open] { animation: dialog-in 0.2s cubic-bezier(0.2, 0.8, 0.3, 1); }
  .dialog[open]::backdrop { animation: backdrop-in 0.2s ease-out; }
  .dialog.closing { animation: dialog-out 0.14s ease-in forwards; }
  .dialog.closing::backdrop { animation: backdrop-out 0.14s ease-in forwards; }
  /* A new screen fades in; no fill-mode, so no transform stays on #view (fixed/sticky children). */
  #view.enter { animation: view-in 0.22s ease-out; }
}
@keyframes dialog-in { from { opacity: 0; transform: translateY(8px) scale(0.96); } }
@keyframes dialog-out { to { opacity: 0; transform: scale(0.97); } }
@keyframes backdrop-in { from { opacity: 0; } }
@keyframes backdrop-out { to { opacity: 0; } }
@keyframes view-in { from { opacity: 0; transform: translateY(6px); } }
.dialog p { margin-top: 0; }
.dialog .actions { justify-content: flex-end; }
.form-dialog { width: min(26rem, calc(100vw - 2rem)); }
.form-dialog h2 { margin-top: 0; }
.form-dialog select { width: 100%; }

.modes { border: 0; padding: 0; margin: 0 0 1rem; }
.modes legend { margin-bottom: 0.5rem; font-weight: 600; }
.mode { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.5rem 0; cursor: pointer; }
.mode input, .check input { width: auto; margin-top: 0.3rem; }
.mode strong { display: block; }

/* Quiz start screen: forms as tiles (2 columns on PC, 1 on mobile), options under them,
   Start at the bottom right (full width on mobile). */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.quiz-setup .modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 0.5rem; margin-bottom: 1rem; }
.quiz-setup .mode { position: relative; gap: 0.7rem; padding: 0.6rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.quiz-setup .mode:hover { background: var(--soft); }
.quiz-setup .mode input { position: absolute; opacity: 0; pointer-events: none; }
.quiz-setup .mode:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.quiz-setup .mode:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.mode-icon { display: inline-grid; place-items: center; flex: none; width: 2rem; height: 2rem; border-radius: var(--radius); background: var(--soft); color: var(--muted); }
.quiz-setup .mode:has(input:checked) .mode-icon { background: var(--accent); color: var(--accent-text); }
.mode-text { display: block; color: var(--muted); font-size: 0.85rem; line-height: 1.35; }
.quiz-options { display: grid; gap: 0.75rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.quiz-count { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
.quiz-count input { width: 5.5rem; }
.quiz-checks { display: grid; gap: 0.5rem; }
.quiz-checks .check { margin: 0; }
.quiz-start { display: flex; justify-content: flex-end; margin-top: 1rem; }
@media (max-width: 37.5rem) {
  .quiz-start button { width: 100%; }
}
.check { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 1rem; cursor: pointer; }
.check input { margin-top: 0; }
.check[hidden], .field[hidden] { display: none; }
/* Terms consent at registration: the hint with the privacy link follows right below. */
.check.terms { margin-bottom: 0.75rem; }
.check.remember { margin: -0.25rem 0 1rem; font-size: 0.95rem; }

.quiz { text-align: center; }
.quiz-prompt { font-size: 1.6rem; font-weight: 600; margin: 0.5rem 0 1.25rem; overflow-wrap: anywhere; }
.quiz-answer { font-size: 1.3rem; margin: 0 0 1rem; overflow-wrap: anywhere; }
.quiz-hint { font-family: var(--mono); font-size: 1.1rem; letter-spacing: 0.18em; color: var(--muted); white-space: pre-wrap; overflow-wrap: anywhere; margin: 0 0 0.4rem; padding-left: calc(0.7rem + 1px); text-align: left; }
/* Progress bar under "Answered n of m" (all forms). */
.quiz-bar { height: 4px; margin: -0.5rem 0 1rem; border-radius: 2px; background: var(--border); overflow: hidden; }
.quiz-bar i { display: block; width: 0; height: 100%; background: var(--accent); transition: width 0.3s ease; }

/* Flash cards: the card (two faces in one grid cell, so the taller text sets the height) lies on
   a deck of the cards still to come. overflow-x: clip keeps the sliding card from adding a scrollbar. */
.flip-stage { padding: 0.5rem 1rem 0; overflow-x: clip; }
.flip-deck { position: relative; width: min(100%, 26rem); margin: 0.5rem auto 1.75rem; perspective: 1100px; }
.flip-under { position: absolute; inset: 0; border: 1px solid var(--border); border-radius: calc(var(--radius) + 4px); background: var(--surface); box-shadow: 0 2px 6px var(--shadow); }
.flip-under.u1 { transform: translate(5px, 6px) rotate(1.2deg); }
.flip-under.u2 { transform: translate(-6px, 11px) rotate(-1.6deg); }
.flip-under.u3 { transform: translate(8px, 16px) rotate(2deg); }
.flip-card { position: relative; display: grid; transform-style: preserve-3d; }
.flip-card.turned { transform: rotateY(180deg); }
.flip-card.enter { transform: scale(0.96); opacity: 0.4; }
.flip-card.right { transform: translateX(125%) rotate(8deg) rotateY(180deg); opacity: 0; }
.flip-card.left { transform: translateX(-125%) rotate(-8deg) rotateY(180deg); opacity: 0; }
.flip-face {
  grid-area: 1 / 1; display: flex; flex-direction: column; justify-content: center; gap: 0.35rem; min-width: 0; min-height: 13rem; padding: 1.25rem;
  border: 1px solid var(--border); border-radius: calc(var(--radius) + 4px); background: var(--surface); box-shadow: 0 8px 22px var(--shadow);
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
.flip-face.back { transform: rotateY(180deg); border-color: var(--accent); background: linear-gradient(180deg, var(--accent-soft), var(--surface) 70%); }
.flip-face p { margin: 0; }
.flip-text { font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; text-wrap: balance; }
.flip-text.big { font-size: 1.9rem; }
.flip-text.mid { font-size: 1.4rem; }
.flip-text.long { font-size: 1rem; font-weight: 400; line-height: 1.5; text-wrap: wrap; }
.flip-sub { color: var(--muted); font-size: 0.9rem; overflow-wrap: anywhere; }
.flip-actions button.danger { background: var(--surface); border-color: var(--error); color: var(--error); }
.flip-actions button:disabled { opacity: 0.6; }
@media (prefers-reduced-motion: no-preference) {
  .flip-card { transition: transform 0.45s cubic-bezier(0.3, 0.7, 0.3, 1), opacity 0.3s; }
  .flip-card.left, .flip-card.right { transition-duration: 0.3s; } /* SLIDE_MS in quiz-modes.js */
}

.quiz .actions { justify-content: center; margin-top: 1rem; }
.quiz > button, .quiz-step > button { margin-top: 1rem; }
.options { display: grid; gap: 0.5rem; }
button.option { width: 100%; background: var(--surface); color: var(--text); border: 1px solid var(--border); overflow-wrap: anywhere; }
button.option:hover:not(:disabled) { filter: none; background: var(--soft); }
button.option:disabled { background: var(--surface); color: var(--text); cursor: default; opacity: 1; }
.options.answered button.option:not(.right):not(.wrong) { opacity: 0.5; }
button.option .ico { margin: -0.3em 0.4rem -0.3em 0; stroke-width: 2.25; }
button.option.selected { border-color: var(--accent); outline: 2px solid var(--accent); background: var(--accent-soft); }
button.option.right { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); font-weight: 600; }
button.option.wrong { border-color: var(--error); background: var(--error-tint); color: var(--error); }
/* Matching: a correct pair turns green, then quiets down (.done; beats button.option:disabled). */
button.option.done:disabled { border-style: dashed; border-color: var(--border); background: transparent; color: var(--muted); font-weight: 400; opacity: 0.45; }

/* Answer feedback: right / wrong field and a short nudge on a wrong or empty answer;
   the next question eases in. Motion only when the system allows it. */
.write input.right { border-color: var(--ok); background-color: var(--ok-soft); }
.write input.wrong { border-color: var(--error); background-color: var(--error-tint); }
.status .ico { margin-right: 0.35rem; vertical-align: -0.2em; stroke-width: 2.25; }
@keyframes nudge { 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
@keyframes step-in { from { opacity: 0; transform: translateX(28px); } }
@media (prefers-reduced-motion: no-preference) {
  .quiz-step { animation: step-in 0.28s ease-out; }
  button.option.wrong, .write input.wrong, .write input.nudge { animation: nudge 0.3s ease; }
  button.option, .write input { transition: background-color 0.18s, border-color 0.18s, color 0.18s, opacity 0.18s; }
  button.option.done { transition: opacity 0.35s, background-color 0.35s, border-color 0.35s, color 0.35s, transform 0.35s; transform: scale(0.97); }
}
.match { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.write { display: grid; gap: 0.75rem; }
/* One line kept free for the verdict, so the buttons do not jump when it appears. */
.write-feedback { min-height: 1.5em; }
.write-feedback .status { margin: 0; }
/* Two buttons under the field: Don't know, Check (then only Next). */
.write-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; }
/* Quiz result: big ring (shares .memory-timer), then the groups of words. */
.quiz-score { display: grid; justify-items: center; margin-bottom: 1rem; text-align: center; }
.quiz-score .memory-timer { margin-bottom: 0.25rem; }
.quiz-score .status { margin: 0; color: var(--muted); }
.quiz-score .status.error { color: var(--error); }
.score-fill { stroke-width: 6; }
.timer-time.score-text { justify-items: center; font-size: 1rem; font-weight: 400; line-height: 1.15; }
.score-text b { font-size: 1.9rem; font-weight: 700; }
.score-text span { color: var(--muted); font-size: 0.85rem; }
.result-group { margin: 1rem 0 0.5rem; font-size: 1rem; }
.result-group.right { color: var(--ok); }
.result-group.wrong { color: var(--error); }
.quiz-score-actions { justify-content: center; }
.results li.right .mark { color: var(--ok); }
.results li.wrong .mark { color: var(--error); }
.results .mark { display: inline-block; width: 1.6rem; }
.results .mark .ico { stroke-width: 2.25; }

/* Memorising countdown: ring shrinking every second, time in the middle. */
.memory-timer { position: relative; width: 9.5rem; height: 9.5rem; margin: 0.25rem auto 1rem; }
.memory-timer svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); }
.timer-track, .timer-fill { fill: none; stroke-width: 6; }
.timer-track { stroke: var(--border); }
.timer-fill { stroke: var(--accent); stroke-linecap: round; stroke-dasharray: 100; }
.timer-time { position: absolute; inset: 0; display: grid; place-content: center; font-size: 1.9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: no-preference) {
  .timer-fill { transition: stroke-dashoffset 1s linear; }
}

.memory-items { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem 1.5rem; margin: 0.5rem 0 1.25rem; padding: 0; list-style: none; }
.memory-items li { font-size: 1.6rem; font-weight: 600; overflow-wrap: anywhere; }
.recall { margin: 0 0 1rem; padding: 0.75rem 1rem 0; border: 1px solid var(--border); border-radius: var(--radius); }
.recall legend { padding: 0 0.25rem; font-weight: 600; }
.recall > div { margin-bottom: 1rem; }

/* Toast: one message area at the bottom centre, dark on light and light on dark;
   the kind shows as a colored mark (ok / warning / error). */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: calc(100vw - 2rem);
  width: max-content;
  padding: 0.55rem 0.4rem 0.55rem 0.7rem;
  border-radius: var(--radius);
  background: var(--toast);
  color: var(--toast-text);
  box-shadow: 0 8px 24px var(--shadow);
  transform: translateX(-50%);
  cursor: pointer;
}
.toast[hidden] { display: none; }
.toast-mark { display: inline-grid; flex: none; place-items: center; width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--ok); color: var(--toast); }
.toast-mark .ico { width: 1rem; height: 1rem; stroke-width: 2.5; }
.toast.warning .toast-mark { background: var(--accent); }
.toast.error .toast-mark { background: var(--error); }
.toast-close { display: inline-flex; padding: 0.3rem; border: 0; background: none; color: inherit; opacity: 0.7; }
.toast-close:hover { opacity: 1; filter: none; }

@media (prefers-reduced-motion: no-preference) {
  button, .button, .list .row-main a, details.menu > summary { transition: background-color 0.12s, color 0.12s, border-color 0.12s; }
}

/* Optical vertical centring of button text: fonts (e.g. Segoe UI on Windows) leave more room
   below the letters than above, so the text looked too high. Where the browser supports it,
   the text box is cut to the letters (cap height to baseline) and the cut height is given back
   as equal padding (0.4em ≈ (line height 1.5 − cap height) / 2). Elsewhere nothing changes. */
@supports (text-box: trim-both cap alphabetic) {
  button:not(.icon):not(.with-icon):not(.toast-close):not(.ring):not(.say), .button { text-box: trim-both cap alphabetic; padding-block: calc(0.6rem + 0.4em); }
  .menu-items button:not(.icon):not(.with-icon):not(.toast-close):not(.ring) { padding-block: calc(0.5rem + 0.4em); }
  /* Links styled as buttons get the same height as the buttons next to them. */
  .actions .button { padding-block: calc(0.6rem + 0.4em); }
  .welcome button:not(.icon):not(.with-icon):not(.toast-close):not(.ring) { padding-block: calc(0.85rem + 0.4em); }
  button.link { padding-block: 0; }
  button .label { display: block; text-box: trim-both cap alphabetic; padding-block: 0.4em; }
  .badge { text-box: trim-both cap alphabetic; padding-block: 0.375em; }
}

/* Loading placeholder (skeleton) while a new screen loads; tokens work in both themes. */
.skeleton { display: grid; gap: 0.75rem; }
.skeleton .list { margin: 0.5rem 0 0; }
.sk { display: block; height: 1rem; border-radius: 6px; background: var(--soft); }
.sk-title { height: 1.9rem; }
.sk-meta { height: 0.85rem; }
.sk-row { display: flex; align-items: center; gap: 0.75rem; }
.sk-dot { flex: none; width: 2rem; height: 2rem; border-radius: 50%; }
@keyframes sk-in { from { opacity: 0; } }
@keyframes sk-sweep { from { background-position: 100% 0; } to { background-position: -150% 0; } }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: sk-in 0.2s ease-out; }
  .sk {
    background: linear-gradient(90deg, var(--soft) 0 40%, var(--bg) 50%, var(--soft) 60% 100%) var(--soft);
    background-size: 250% 100%;
    animation: sk-sweep 1.4s linear infinite;
  }
}

/* Set detail: dot after a word that gives trouble (weight 7–9), legend under the heading. */
.trouble { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--error-soft); margin: 0 0.1rem 0.1rem 0.4rem; vertical-align: middle; }
.trouble-note { display: flex; align-items: center; margin: -0.5rem 0 0.75rem; font-size: 0.85rem; color: var(--muted); }
.trouble-note[hidden] { display: none; }
.trouble-note .trouble { margin: 0 0.45rem 0 0; }

/* Reading a term aloud: quiet round speaker button, accent on hover and while speaking (.on). */
button.say { display: inline-grid; place-items: center; flex: none; width: 1.9rem; height: 1.9rem; margin: -0.3rem 0.3rem -0.3rem -0.2rem; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--muted); vertical-align: middle; }
/* middle = baseline + half the x-height; a slight lift centers it on the term (letters with ascenders). */
button.say { line-height: 0; position: relative; top: -0.1em; }
button.say .ico { display: block; width: 1.15rem; height: 1.15rem; }
button.say:hover { filter: none; background: var(--accent-soft); color: var(--accent); }
button.say.on { color: var(--accent); background: var(--accent-soft); }
.list .word-main button.say { top: -0.15em; } /* word list: center on the checkbox and the term */
.quiz-prompt button.say, .status button.say { margin: -0.3rem 0 -0.3rem 0.2rem; }
.quiz-say { margin: 0.75rem 0 0; }
/* On a flash card the speaker sits in the top right corner. */
.flip-face { position: relative; }
.flip-face > button.say { position: absolute; top: 0.6rem; right: 0.6rem; width: 2.5rem; height: 2.5rem; margin: 0; }
.flip-face > button.say .ico { width: 1.35rem; height: 1.35rem; }
@media (prefers-reduced-motion: no-preference) {
  button.say.on .ico { animation: say-pulse 0.9s ease-in-out infinite; }
}
@keyframes say-pulse { 50% { transform: scale(1.12); } }
.status button.say .ico { margin: 0; stroke-width: 1.75; }
