/* Husa — husa.app. One stylesheet for every page.

   The look comes from the app icon, not from the app's screens: a deep navy
   ground, the icon's three blues, and its ribbon — the one gradient on the
   site, used only where the page is talking about memory or progress. Every
   colour the site uses is defined in the blocks right below, for both schemes,
   and nowhere else: a literal colour further down this file is a bug. */

/* --- the typeface -------------------------------------------------------------

   Onest, self-hosted (the CSP names no third-party origin; see _headers). One
   variable file per script covers every weight. The ranges are Google Fonts'
   subsets, so a page in Russian never downloads the Polish letters until a
   Polish word appears. Onest has no ʂ, which is why the transcription on the
   home page is set in the system face (.word-ipa). License: fonts/OFL.txt. */
@font-face {
  font-family: "Onest";
  src: url("fonts/onest-cyrillic.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Onest";
  src: url("fonts/onest-latin-ext.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Onest";
  src: url("fonts/onest-latin.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- colours -------------------------------------------------------------------

   Light is the default here and dark overrides it, under two selectors: dark
   follows the browser unless the visitor picked light, and a picked dark
   applies whatever the browser says. Every text pair
   below holds 4.5:1 on the grounds it is used on, and every control border
   3:1 — measured, not eyeballed. */
:root {
  --ground: #f3f6fc;
  --ground-lift: #ffffff;            /* the centre of the masthead's light */
  --card: #ffffff;
  --line: #d5dcec;                   /* hairlines between rows */
  --line-strong: #b9c3dc;            /* the rule that opens a section */
  --ink: #0a1128;
  --ink-2: #3d4a6b;
  --ink-3: #5b6a92;
  --control-line: #5b6a92;           /* input and outline-button borders, 3:1+ */
  --link: #1a59fd;
  --action: #1a59fd;                 /* filled buttons; white on it is 5.4:1 */
  --on-action: #ffffff;
  --note-ground: #e3ecfd;
  --note-ink: #12305e;
  --ins-ground: #e3f2e8;
  --ins-ink: #1b6e37;
  --del-ink: #b52222;
  --header-glass: rgba(243, 246, 252, 0.88);
  --chart-none: #6b7898;
  --focus: #1a59fd;

  /* The rating chips carry white labels in both schemes; the app's own rating
     hues are too light for that, so these are the same hues darkened past
     4.5:1. The -ink values are the names set as text on the page ground. */
  --rating-again: #c42525;
  --rating-hard: #ad6013;
  --rating-good: #238643;
  --rating-easy: #0b7e9e;
  --rating-again-ink: #b52222;
  --rating-hard-ink: #9a5510;
  --rating-good-ink: #1d7a3b;
  --rating-easy-ink: #0a7090;

  /* An unfilled legal blank, in both schemes: it must be impossible to miss (#498). */
  --blank-ground: #ffcc00;
  --blank-ink: #3d2f00;

  /* The theme switch's cover (.theme-veil): each theme's ground, fixed, since
     the cover shows the theme being switched to, not the current one. */
  --veil-light: #f3f6fc;
  --veil-dark: #0a1128;

  /* The icon's three blues, the same in both schemes: its highlight, its
     middle and its deepest. */
  --ribbon-start: #30bafe;
  --ribbon-mid: #2891fd;
  --ribbon-end: #1a58fd;

  --site-max: 1440px;
  --gutter: 120px;
  --section: 128px;
  --section-gap: 48px;
  --header-h: 88px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #0a1128;
    --ground-lift: #131f44;
    --card: #111a3a;
    --line: #1e2a52;
    --line-strong: #2e3b66;
    --ink: #ffffff;
    --ink-2: #b4bed8;
    --ink-3: #8c98b8;
    --control-line: #5b6a92;
    --link: #5cc8ff;
    --note-ground: #12305e;
    --note-ink: #bfe6ff;
    --ins-ground: #123d2a;
    --ins-ink: #4ade80;
    --del-ink: #ff6961;
    --header-glass: rgba(10, 17, 40, 0.88);
    --chart-none: #5b6a92;
    --focus: #5cc8ff;
    --rating-again-ink: #ff6961;
    --rating-hard-ink: #ffb340;
    --rating-good-ink: #30d158;
    --rating-easy-ink: #64d2ff;
  }
}
:root[data-theme="dark"] {
  --ground: #0a1128;
  --ground-lift: #131f44;
  --card: #111a3a;
  --line: #1e2a52;
  --line-strong: #2e3b66;
  --ink: #ffffff;
  --ink-2: #b4bed8;
  --ink-3: #8c98b8;
  --control-line: #5b6a92;
  --link: #5cc8ff;
  --note-ground: #12305e;
  --note-ink: #bfe6ff;
  --ins-ground: #123d2a;
  --ins-ink: #4ade80;
  --del-ink: #ff6961;
  --header-glass: rgba(10, 17, 40, 0.88);
  --chart-none: #5b6a92;
  --focus: #5cc8ff;
  --rating-again-ink: #ff6961;
  --rating-hard-ink: #ffb340;
  --rating-good-ink: #30d158;
  --rating-easy-ink: #64d2ff;
}

:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

@media (max-width: 1199px) {
  :root { --gutter: 48px; --section: 96px; }
}
@media (max-width: 767px) {
  :root { --gutter: 16px; --section: 56px; --section-gap: 24px; --header-h: 64px; }
}

/* --- base ------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

/* In-page links (/#course, /#exam) land below the sticky header, not under it. */
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 16px); }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
html.menu-open { overflow: hidden; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: "Onest", system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 6px; }

/* Language switching without a build step or a redirect: every language lives in
   the DOM, and the one to show is chosen by an attribute on <html>. Without
   JavaScript the attribute keeps its served value, so the page still reads.
   Only the three interface languages are listed, so a Polish word marked
   lang="pl" is never hidden. */
[data-lang="ru"] [lang="uk"], [data-lang="ru"] [lang="en"],
[data-lang="uk"] [lang="ru"], [data-lang="uk"] [lang="en"],
[data-lang="en"] [lang="ru"], [data-lang="en"] [lang="uk"] { display: none; }

.container {
  width: 100%;
  max-width: var(--site-max);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 16px; top: 16px; z-index: 30;
  background: var(--card); color: var(--ink);
  padding: 8px 12px; border-radius: 8px;
}

/* The gradient definitions Base.astro carries for the progress bars. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.ribbon-stop-start { stop-color: var(--ribbon-start); }
.ribbon-stop-mid { stop-color: var(--ribbon-mid); }
.ribbon-stop-end { stop-color: var(--ribbon-end); }

/* --- type ------------------------------------------------------------------- */

h1, h2 { text-wrap: balance; }
p, dd { text-wrap: pretty; }

.display { font-size: 80px; line-height: 82px; font-weight: 700; letter-spacing: -0.035em; }
.display-page { font-size: 72px; line-height: 76px; max-width: 960px; }
.h2 { font-size: 56px; line-height: 60px; font-weight: 700; letter-spacing: -0.035em; }
.h2-sm { font-size: 44px; line-height: 48px; letter-spacing: -0.03em; }
.h2-statement { font-size: 40px; line-height: 46px; letter-spacing: -0.03em; }
.h2-narrow { max-width: 760px; }
.h3-item { font-size: 19px; line-height: 26px; font-weight: 600; }
.hero-lead { font-size: 21px; line-height: 32px; color: var(--ink-2); max-width: 640px; }
.lead { font-size: 17px; line-height: 26px; color: var(--ink-2); }
.muted { font-size: 16px; line-height: 24px; color: var(--ink-2); }
.small { font-size: 14px; line-height: 21px; }
.caption { font-size: 13px; line-height: 19px; color: var(--ink-3); }
.caption-above { padding-bottom: 12px; }

@media (max-width: 1199px) {
  .display { font-size: 60px; line-height: 64px; }
  .display-page { font-size: 56px; line-height: 60px; }
  .h2 { font-size: 44px; line-height: 48px; }
}
@media (max-width: 767px) {
  .display { font-size: 44px; line-height: 48px; }
  .display-page { font-size: 38px; line-height: 42px; }
  .h2, .h2-sm { font-size: 30px; line-height: 34px; letter-spacing: -0.03em; }
  .h2-statement { font-size: 28px; line-height: 33px; }
  .hero-lead { font-size: 17px; line-height: 26px; }
  .lead, .muted { font-size: 15px; line-height: 22px; }
  .h3-item { font-size: 17px; line-height: 24px; }
}

/* --- buttons and links -------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px; padding: 0 28px; border-radius: 16px;
  font-size: 16px; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: filter 150ms ease, background-color 150ms ease, transform 150ms ease;
}
.btn:hover { text-decoration: none; }
.btn:not(.btn-soon):active { transform: scale(0.98); }
.btn-primary { background: var(--action); color: var(--on-action); }
.btn-primary:hover { filter: brightness(1.12); }
.btn-outline { border: 1px solid var(--control-line); color: var(--ink); }
.btn-outline:hover { background: var(--card); }
/* Not a link and not a button: there is nothing to install yet. It looks like
   the store button it will become, minus anything that invites a click. */
.btn-soon { border: 1px solid var(--control-line); color: var(--ink-2); cursor: default; }

.arrow-link {
  display: inline-flex; align-items: center; gap: 8px; align-self: flex-start;
  font-size: 16px; font-weight: 500;
}
.arrow-link svg { flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:not(.btn-soon):active { transform: none; }
}

/* --- header -------------------------------------------------------------------- */

/* The header sticks to the top. Transparent over the masthead, it takes on a
   blurred ground once the page has scrolled, so it stays legible over whatever
   passes under it. Transparent only once site.js tracks the scroll
   (.is-tracked), because only site.js can give the ground back: a site.js that
   failed to load must not leave the header see-through over the page. */
.site-header {
  position: sticky; top: 0; z-index: 15;
  background: var(--ground);
  transition: background-color 200ms ease, box-shadow 200ms ease;
}
.site-header.is-tracked:not(.is-stuck) { background: transparent; }
.site-header.is-stuck {
  background: var(--header-glass);
  -webkit-backdrop-filter: saturate(1.4) blur(16px);
  backdrop-filter: saturate(1.4) blur(16px);
  box-shadow: 0 1px 0 var(--line);
}
@media (prefers-reduced-motion: reduce) {
  .site-header { transition: none; }
}
.site-header-inner { display: flex; align-items: center; gap: 48px; min-height: var(--header-h); }
.brand { display: flex; align-items: center; gap: 12px; color: var(--ink); }
.brand:hover { text-decoration: none; }
.brand img { width: 36px; height: 36px; border-radius: 9px; }
.brand span { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; }

.site-nav { display: flex; align-items: center; gap: 32px; flex-grow: 1; }
.site-nav a, .menu-nav a { color: var(--ink-2); font-size: 15px; }
.site-nav a:hover, .menu-nav a:hover { color: var(--ink); text-decoration: none; }
.site-nav a[aria-current="page"], .menu-nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }

.langs { display: flex; align-items: center; gap: 4px; }
.langs button {
  min-width: 44px; min-height: 44px; padding: 0 6px;
  background: none; border: 0; cursor: pointer;
  color: var(--ink-2); font-size: 14px;
}
.langs button:hover { color: var(--ink); }
.langs button[aria-current="true"] { color: var(--ink); font-weight: 600; }

.theme-toggle {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 44px; height: 44px; padding: 0; cursor: pointer;
  border: 1px solid var(--control-line); border-radius: 22px;
  background: transparent; color: var(--ink);
}
:root:not(.has-js) .theme-toggle { display: none; }
.theme-toggle:hover { background: var(--card); }
/* The icon is the theme a click goes to: the moon in light, the sun in dark. */
.theme-icon-sun { display: none; }
:root[data-theme="dark"] .theme-icon-sun { display: block; }
:root[data-theme="dark"] .theme-icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-icon-sun { display: block; }
  :root:not([data-theme="light"]) .theme-icon-moon { display: none; }
}
/* The theme change, drawn the way the sun on the button would (lang.js).
   Sunrise: a disc of the light ground grows out of the button until it covers
   the screen. Sunset: the dark closes in from the edges onto the button — a
   hole in a dark field, shrinking to nothing. Either way the theme switches
   under the cover and the cover then fades, so the new page shows through.
   A fixed element rather than a view transition: it lives in the same
   coordinates as the button in every engine, where the snapshots of a view
   transition do not. The page's own transitions are off while it runs
   (.theme-switching), so nothing fades on its own schedule under it. */
.theme-veil {
  position: fixed; z-index: 50; pointer-events: none;
  width: 0; height: 0; border-radius: 50%;
  transform: translate(-50%, -50%);
}
.theme-veil-sunrise { background: var(--veil-light); }
.theme-veil-sunset { box-shadow: 0 0 0 200vmax var(--veil-dark); }
.theme-switching *, .theme-switching *::before, .theme-switching *::after { transition: none !important; }
/* The icon turns in while the cover fades, and finishes a little before it:
   lang.js ends the switch when the fade ends (FADE_MS, 260ms), and a turn cut
   off there would snap into place in plain view. */
@media (prefers-reduced-motion: no-preference) {
  .theme-switching .theme-toggle svg { animation: theme-icon-in 220ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
}
@keyframes theme-icon-in {
  from { transform: rotate(-120deg) scale(0.6); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.burger {
  display: none; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-left: auto; padding: 0;
  background: none; border: 0; color: var(--ink); cursor: pointer;
}

.menu {
  position: fixed; inset: 0; z-index: 20; overflow-y: auto;
  background: var(--ground);
  display: flex; flex-direction: column; gap: 24px;
}
.menu[hidden] { display: none; }
.menu-top { display: flex; align-items: center; min-height: 64px; }
.menu-top .brand img { width: 30px; height: 30px; border-radius: 8px; }
.menu-top .brand span { font-size: 19px; }
.menu-top .burger { display: flex; }
.menu-nav { display: flex; flex-direction: column; }
.menu-nav a { font-size: 24px; line-height: 32px; padding: 12px 0; font-weight: 600; }
.menu-langs { gap: 16px; }

@media (max-width: 1199px) {
  .site-header-inner { gap: 20px; }
  .site-nav { gap: 16px; }
  .site-header .langs { gap: 0; }
}
@media (max-width: 767px) {
  .site-header-inner { gap: 8px; }
  .site-header .brand img { width: 30px; height: 30px; border-radius: 8px; }
  .site-header .brand span { font-size: 19px; }
  .site-header .site-nav, .site-header .langs { display: none; }
  .site-header .burger { display: flex; margin-left: 0; }
  .site-header .theme-toggle { margin-left: auto; }
}

/* --- masthead ------------------------------------------------------------------ */

/* Pulled up under the sticky header, so at the top of the page the header sits
   on the masthead's light. Lit from the centre, as the icon is. */
.masthead {
  position: relative;
  margin-top: calc(-1 * var(--header-h));
  padding-top: var(--header-h);
  background: radial-gradient(90% 80% at 50% 25%, var(--ground-lift) 0%, var(--ground) 70%);
}
/* The legal pages have no hero: the header alone, on the page's own ground. */
.masthead.masthead-bare { background: none; }

.hero {
  display: grid; grid-template-columns: minmax(0, 1fr) 500px; gap: 96px; align-items: center;
  padding-top: 88px; padding-bottom: 120px;
}
.hero-copy { display: flex; flex-direction: column; gap: 32px; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; }
/* Beside the button, on its centre line; elsewhere an arrow link sits at the start. */
.hero-actions .arrow-link { align-self: center; }
.hero-facts { display: flex; flex-wrap: wrap; gap: 8px 28px; font-size: 14px; color: var(--ink-3); }

.page-hero { display: flex; flex-direction: column; gap: 28px; padding-top: 96px; padding-bottom: 120px; }
.page-hero .hero-lead { max-width: 720px; }

@media (max-width: 1199px) {
  .hero { grid-template-columns: minmax(0, 1fr); gap: 56px; padding-top: 56px; padding-bottom: 96px; }
  .hero .word { max-width: 560px; }
}
@media (max-width: 767px) {
  .hero { gap: 40px; padding-top: 40px; padding-bottom: 56px; }
  .hero-copy { gap: 20px; }
  .hero-actions { flex-direction: column; align-items: stretch; gap: 8px; }
  .hero-actions .arrow-link { align-self: flex-start; padding: 10px 0; }
  .hero-facts { font-size: 13px; }
  .page-hero { padding-top: 40px; padding-bottom: 56px; gap: 18px; }
}

/* --- cards and the word -------------------------------------------------------- */

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: 28px;
  padding: 40px; display: flex; flex-direction: column; gap: 24px;
}
@media (max-width: 767px) {
  .card { padding: 22px; gap: 18px; border-radius: 24px; }
}

.word { display: flex; flex-direction: column; gap: 12px; }
.word-card { gap: 28px; }
.word-meta { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.word-head { display: flex; flex-direction: column; gap: 6px; }
.word-polish { font-size: 60px; line-height: 64px; font-weight: 700; letter-spacing: -0.03em; overflow-wrap: anywhere; }
.word-ipa { font-family: system-ui, sans-serif; font-size: 16px; color: var(--ink-3); }
.word-gloss { display: flex; flex-direction: column; gap: 4px; }
.word-translation { font-size: 21px; font-weight: 600; }
.word-example { display: flex; flex-direction: column; gap: 4px; padding-top: 20px; border-top: 1px solid var(--line); }
.word-example p[lang="pl"] { font-size: 19px; font-weight: 500; }
@media (max-width: 767px) {
  .word-card { gap: 20px; }
  .word-polish { font-size: 42px; line-height: 46px; }
  .word-translation { font-size: 19px; }
  .word-example { padding-top: 16px; }
  .word-example p[lang="pl"] { font-size: 17px; }
}

.ratings { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.rating {
  border-radius: 14px; padding: 10px 4px; text-align: center;
  color: var(--on-action); display: flex; flex-direction: column; gap: 2px;
}
.rating-name { font-size: 15px; font-weight: 600; }
.rating-interval { font-size: 12px; }
.rating-again { background: var(--rating-again); }
.rating-hard { background: var(--rating-hard); }
.rating-good { background: var(--rating-good); }
.rating-easy { background: var(--rating-easy); }
.ratings-names .rating { padding: 12px 2px; }
@media (max-width: 767px) {
  .ratings { gap: 6px; }
  .rating { padding: 8px 2px; border-radius: 12px; }
  .rating-name { font-size: 13px; }
  .rating-interval { font-size: 11px; }
}

/* --- sections ------------------------------------------------------------------ */

.section { display: flex; flex-direction: column; gap: var(--section-gap); padding-bottom: var(--section); }
/* The numbered rule that opens a section (SectionLabel.astro). */
.section-label {
  border-top: 1px solid var(--line-strong); padding-top: 16px;
  font-size: 13px; font-weight: 500; color: var(--ink-3);
}
@media (max-width: 767px) {
  .section-label { padding-top: 12px; font-size: 12px; }
}

.split { display: grid; gap: 96px; }
.split-why, .split-side, .split-card { grid-template-columns: 440px minmax(0, 1fr); }
.split-limits { grid-template-columns: 480px minmax(0, 1fr); }
.split-aside { grid-template-columns: minmax(0, 1fr) 480px; align-items: start; }
.split-end { grid-template-columns: minmax(0, 1fr) 480px; align-items: end; }
.split-card { align-items: start; }
.stack-text { display: flex; flex-direction: column; gap: 20px; }
@media (max-width: 1099px) {
  .split { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .split-end { gap: 20px; }
}
@media (max-width: 767px) {
  .split { gap: 24px; }
  .split-end { gap: 12px; }
  .stack-text { gap: 12px; }
}

/* 01 — Why not a game: a comparison, so a table. */
.compare-why { width: 100%; border-collapse: collapse; font-size: 16px; line-height: 24px; }
.compare-why thead th, .compare-why thead td { padding: 0 24px 14px 0; font-size: 13px; font-weight: 500; color: var(--ink-3); text-align: left; }
.compare-why thead td { width: 180px; }
.compare-why .compare-why-husa { color: var(--link); font-weight: 600; padding-right: 0; }
.compare-why tbody tr { border-top: 1px solid var(--line); vertical-align: top; }
.compare-why tbody tr:last-child { border-bottom: 1px solid var(--line); }
.compare-why tbody th { padding: 20px 24px 20px 0; text-align: left; font-weight: 600; }
.compare-why tbody td { padding: 20px 24px 20px 0; }
.compare-why tbody td:last-child { padding-right: 0; }
.compare-why .muted-cell { color: var(--ink-3); }
/* On a phone three columns are too narrow to read; each row becomes a block. */
@media (max-width: 767px) {
  .compare-why thead { display: none; }
  .compare-why, .compare-why tbody, .compare-why tr, .compare-why th, .compare-why td { display: block; }
  .compare-why tbody tr { padding: 16px 0; }
  .compare-why tbody th, .compare-why tbody td { padding: 0; font-size: 15px; line-height: 22px; }
  .compare-why tbody th { font-size: 16px; padding-bottom: 6px; }
  .compare-why tbody td + td { padding-top: 6px; }
}

/* 02 — the memory chart (MemoryChart.astro). */
.memory-chart { display: flex; flex-direction: column; gap: 16px; }
.memory-chart svg { width: 100%; height: auto; }
.memory-chart-narrow { display: none; }
.memory-chart figcaption { font-size: 14px; line-height: 21px; color: var(--ink-3); max-width: 900px; }
.chart-threshold { stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 2 6; }
.chart-axis { stroke: var(--line-strong); stroke-width: 1; }
.chart-none { fill: none; stroke: var(--chart-none); stroke-width: 2; stroke-dasharray: 6 6; }
.chart-ribbon { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.chart-ribbon-wide { stroke-width: 7; }
.chart-ribbon-narrow { stroke-width: 5; }
.chart-labels text { font-family: "Onest", system-ui, sans-serif; font-size: 13px; fill: var(--ink-3); }
.chart-labels .chart-label-day { fill: var(--ink-2); }
.chart-labels-narrow text { font-size: 11px; }
@media (max-width: 767px) {
  .memory-chart-wide { display: none; }
  .memory-chart-narrow { display: block; }
  .memory-chart figcaption { font-size: 13px; line-height: 19px; }
}

.facts-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px; }
.facts-row div { border-top: 1px solid var(--line); padding-top: 24px; display: flex; flex-direction: column; gap: 8px; }
.facts-row dt { font-size: 40px; line-height: 44px; font-weight: 700; letter-spacing: -0.03em; }
.facts-row dd { font-size: 15px; line-height: 23px; color: var(--ink-2); }
@media (max-width: 1099px) {
  .facts-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .facts-row div { padding: 18px 0; }
  .facts-row div:last-child { border-bottom: 1px solid var(--line); }
}
@media (max-width: 767px) {
  .facts-row dt { font-size: 32px; line-height: 36px; }
}

/* 03 — what's inside */
.demos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
.demo-item { display: flex; flex-direction: column; gap: 20px; }
.demo-text { display: flex; flex-direction: column; gap: 6px; }
.demo { min-height: 300px; justify-content: center; gap: 20px; }
.demo-label { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.tiles { display: flex; flex-wrap: wrap; gap: 8px; }
.tiles-placed { align-items: center; min-height: 52px; padding-bottom: 12px; border-bottom: 1px solid var(--line-strong); }
.tile { font-size: 21px; font-weight: 500; padding: 8px 16px; border-radius: 14px; border: 1px solid var(--control-line); }
.tile-placed { background: var(--action); color: var(--on-action); border-color: var(--action); }
.demo-letter { font-size: 21px; line-height: 34px; }
.demo-letter del { color: var(--del-ink); text-decoration-thickness: 2px; }
.demo-letter ins {
  padding: 0 6px; border-radius: 8px; text-decoration: none; font-weight: 600;
  background: var(--ins-ground); color: var(--ins-ink);
}
.note {
  font-size: 15px; line-height: 22px; border-radius: 14px; padding: 12px 16px;
  background: var(--note-ground); color: var(--note-ink);
}
.note-icon { display: flex; gap: 12px; align-items: flex-start; padding: 16px 20px; }
.note-icon svg { flex-shrink: 0; margin-top: 2px; }

.feature-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
.feature-list li { border-top: 1px solid var(--line); padding: 24px 0; display: flex; flex-direction: column; gap: 4px; }
.feature-list li:nth-last-child(-n+2) { border-bottom: 1px solid var(--line); }
@media (max-width: 767px) {
  .demos, .feature-list { grid-template-columns: minmax(0, 1fr); }
  .demos { gap: 32px; }
  .demo { min-height: 0; }
  .tile { font-size: 18px; padding: 6px 12px; }
  .demo-letter { font-size: 18px; line-height: 28px; }
  .feature-list li { padding: 18px 0; }
  .feature-list li:nth-last-child(-n+2) { border-bottom: 0; }
  .feature-list li:last-child { border-bottom: 1px solid var(--line); }
}

/* Progress bars (Bar.astro), filled with the icon's ribbon. */
.bar { width: 100%; height: 6px; overflow: visible; }
.bar-md { height: 8px; }
.bar-track { fill: var(--line); }
.bar-fill { fill: url(#husa-ribbon); }

/* 04 — the course: one list, not a grid of cards. */
.topic {
  display: grid; grid-template-columns: 40px minmax(0, 1fr) 140px 230px; gap: 16px; align-items: center;
  min-height: 60px; border-top: 1px solid var(--line);
}
.topic:last-child { border-bottom: 1px solid var(--line); }
.topic-level { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.topic-name { font-size: 16px; font-weight: 500; }
.topic-locked .topic-name { color: var(--ink-3); }
.topic-note { font-size: 14px; color: var(--ink-3); text-align: right; }
@media (max-width: 767px) {
  .topic {
    grid-template-columns: 32px minmax(0, 1fr) auto; gap: 6px 10px;
    grid-template-areas: "level name note" "bar bar bar"; padding: 12px 0; min-height: 0;
  }
  .topic-level { grid-area: level; }
  .topic-name { grid-area: name; font-size: 15px; }
  .topic-note { grid-area: note; font-size: 13px; }
  .topic .bar { grid-area: bar; }
}

/* 05 — the exam plan */
.plan-card { padding: 32px; gap: 20px; }
.plan-countdown { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 15px; color: var(--ink-2); }
.plan-days { font-size: 56px; line-height: 60px; font-weight: 700; letter-spacing: -0.03em; color: var(--ink); white-space: nowrap; }
.plan-rows div { display: flex; justify-content: space-between; gap: 12px; padding: 12px 0; border-top: 1px solid var(--line); font-size: 16px; }
.plan-rows dt { color: var(--ink-2); }
.plan-rows dd { font-weight: 600; font-variant-numeric: tabular-nums; }
figure > .card + .caption { margin-top: 12px; }
@media (max-width: 767px) {
  .plan-card { padding: 22px; }
  .plan-days { font-size: 40px; line-height: 44px; }
}

/* 06 — in the app */
.shots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.shot img {
  width: 100%; height: auto; aspect-ratio: 640 / 1388;
  border-radius: 40px; border: 1px solid var(--line); background: var(--card);
  /* Transparent text hides the alt text while an image is still loading. */
  color: transparent;
}
.shots figcaption { margin-top: 16px; font-size: 15px; line-height: 22px; color: var(--ink-2); }
.shots strong { color: var(--ink); font-weight: 600; }
/* On a phone, a strip that scrolls sideways rather than three full-height
   screens stacked. The strip scrolls, the page never does. */
@media (max-width: 767px) {
  .shots {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 72%;
    gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory;
    margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter) 4px;
  }
  .shots li { scroll-snap-align: start; }
  .shot img { border-radius: 28px; }
  .shots figcaption { font-size: 14px; line-height: 20px; }
}

/* 07 — plans, three columns on hairlines */
.plans {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line-strong); border-bottom: 1px solid var(--line);
}
.plan { padding: 32px; display: flex; flex-direction: column; gap: 12px; }
.plan:first-child { padding-left: 0; }
.plan:last-child { padding-right: 0; }
.plan + .plan { border-left: 1px solid var(--line); }
.plan-name { font-size: 17px; font-weight: 600; }
.plan-discount { font-size: 14px; font-weight: 600; color: var(--link); padding-left: 6px; }
.price { font-size: 48px; line-height: 52px; font-weight: 700; letter-spacing: -0.03em; }
.price-unit { font-size: 17px; font-weight: 400; letter-spacing: 0; color: var(--ink-3); }
.plan .muted { font-size: 15px; line-height: 23px; }
/* The pricing page: every row of a plan lines up with its neighbours'. */
.plans-full { grid-template-rows: repeat(5, auto); }
.plans-full .plan { display: grid; grid-row: span 5; grid-template-rows: subgrid; row-gap: 16px; padding-top: 36px; padding-bottom: 36px; }
.plans-full .price { font-size: 56px; line-height: 60px; }
.plans-full .btn { width: 100%; }
.plan-features { display: flex; flex-direction: column; gap: 10px; padding-top: 8px; font-size: 15px; line-height: 22px; color: var(--ink-2); }
@media (max-width: 999px) {
  .plans, .plans-full { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; border-top: 0; }
  .plan, .plans-full .plan { padding: 24px 0; border-top: 1px solid var(--line); }
  .plan:first-child { border-top-color: var(--line-strong); }
  .plan + .plan { border-left: 0; }
  .plans-full .plan { display: flex; grid-row: auto; row-gap: 0; gap: 12px; }
  .plans-full .btn { order: 5; margin-top: 4px; }
  .price, .plans-full .price { font-size: 44px; line-height: 48px; }
}

/* The pricing page's comparison */
.compare { width: 100%; border-collapse: collapse; font-size: 16px; line-height: 24px; font-variant-numeric: tabular-nums; }
.compare thead th { padding: 0 0 16px; font-size: 14px; font-weight: 600; color: var(--ink-2); }
.compare thead th:first-child { text-align: left; font-weight: 500; color: var(--ink-3); }
.compare thead th.compare-pro { color: var(--link); }
.compare tbody tr { border-top: 1px solid var(--line); }
.compare tbody tr:last-child { border-bottom: 1px solid var(--line); }
.compare tbody th { padding: 18px 0; text-align: left; font-weight: 500; }
.compare td { padding: 18px 0; width: 240px; text-align: center; color: var(--ink-2); }
.compare td.compare-pro { color: var(--ink); font-weight: 600; }
.compare .tick { display: inline-block; vertical-align: middle; color: var(--ink-2); }
.compare .compare-pro .tick { color: var(--link); }
@media (max-width: 767px) {
  .compare { font-size: 15px; line-height: 21px; }
  .compare td { width: 84px; padding: 14px 0; font-size: 14px; }
  .compare tbody th { padding: 14px 8px 14px 0; }
  .compare thead th { font-size: 13px; }
}

/* 08 — questions: all open, two columns */
.faq { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 96px; }
.faq dt { font-size: 19px; line-height: 26px; font-weight: 600; }
.faq dd { margin-top: 8px; font-size: 16px; line-height: 24px; color: var(--ink-2); }
@media (max-width: 767px) {
  .faq { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .faq dt { font-size: 17px; line-height: 24px; }
  .faq dd { margin-top: 6px; font-size: 15px; line-height: 22px; }
}

/* The page ends on the icon. */
.final {
  display: grid; grid-template-columns: 128px minmax(0, 1fr) auto; gap: 48px; align-items: center;
  border-top: 1px solid var(--line-strong); padding-top: 72px;
}
.final-icon { width: 128px; height: 128px; border-radius: 29px; }
@media (max-width: 999px) {
  .final { grid-template-columns: 96px minmax(0, 1fr); }
  .final-icon { width: 96px; height: 96px; border-radius: 22px; }
  .final .btn { grid-column: 1 / -1; justify-self: start; }
}
@media (max-width: 767px) {
  .final { grid-template-columns: minmax(0, 1fr); gap: 20px; padding-top: 40px; }
  .final-icon { width: 72px; height: 72px; border-radius: 17px; }
  .final .btn { justify-self: stretch; }
}

/* --- the method page ------------------------------------------------------------- */

/* One track, three stretches: dotted, thin, the ribbon. On a phone it turns
   vertical and runs down the left of the three states.
   The line and the marker are separate elements placed on one axis and centred
   on it with a transform, so they stay centred whatever their thickness; each
   line runs on to the centre of the next state's marker, which sits above it. */
.states { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.state { position: relative; padding-top: 44px; padding-right: 24px; display: flex; flex-direction: column; gap: 10px; }
.state-track, .state-dot { position: absolute; top: 20px; left: 0; }
.state-track { right: -32px; transform: translateY(-50%); }
.state:last-child .state-track { right: 0; }
.state-new .state-track { height: 0; border-top: 3px dotted var(--control-line); }
.state-learning .state-track { height: 4px; border-radius: 2px; background: var(--ribbon-start); }
.state-known .state-track { height: 12px; border-radius: 6px; background: linear-gradient(90deg, var(--ribbon-start), var(--ribbon-mid), var(--ribbon-end)); }
.state-dot {
  z-index: 1; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--ink-3); background: var(--ground);
  transform: translateY(-50%);
}
.state-learning .state-dot { border-color: var(--ribbon-start); }
.state-known .state-dot { width: 18px; height: 18px; border: 0; background: var(--ribbon-start); }
.state-when { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.state-known .state-when { color: var(--link); }
.state-name { font-size: 32px; line-height: 36px; font-weight: 700; letter-spacing: -0.03em; }
@media (max-width: 767px) {
  .states { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .state { padding: 0 0 28px 40px; gap: 6px; }
  .state:last-child { padding-bottom: 0; }
  /* The axis: x = 12px, and each marker level with its first line of text. */
  .state-track, .state-dot { top: 10px; left: 12px; }
  .state-track, .state:last-child .state-track { right: auto; bottom: -10px; transform: translateX(-50%); }
  .state:last-child .state-track { bottom: 0; }
  .state-new .state-track { width: 0; height: auto; border-top: 0; border-left: 3px dotted var(--control-line); }
  .state-learning .state-track { width: 4px; height: auto; }
  .state-known .state-track { width: 8px; height: auto; border-radius: 4px; background: linear-gradient(180deg, var(--ribbon-start), var(--ribbon-end)); }
  .state-dot { transform: translate(-50%, -50%); }
  .state-name { font-size: 24px; line-height: 28px; }
}

.fact-list div { border-top: 1px solid var(--line); padding: 24px 0; display: flex; flex-direction: column; gap: 6px; }
.fact-list div:last-child { border-bottom: 1px solid var(--line); }
.fact-list dt { font-size: 21px; font-weight: 600; }
.fact-list dd { font-size: 16px; line-height: 24px; color: var(--ink-2); }
@media (max-width: 767px) {
  .fact-list div { padding: 18px 0; }
  .fact-list dt { font-size: 18px; }
  .fact-list dd { font-size: 15px; line-height: 22px; }
}

.examples { padding: 36px; gap: 0; }
.examples-title { font-size: 15px; font-weight: 600; padding-bottom: 12px; }
.examples li { border-top: 1px solid var(--line); padding: 20px 0; display: flex; flex-direction: column; gap: 10px; }
.examples li:last-child { padding-bottom: 0; }
.example-head { display: flex; align-items: baseline; justify-content: space-between; gap: 4px 12px; flex-wrap: wrap; }
.example-word { font-size: 26px; line-height: 30px; font-weight: 700; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.example-due { font-size: 14px; color: var(--ink-3); }
.example-due-soon { color: var(--link); }
@media (max-width: 767px) {
  .examples { padding: 22px; }
  .example-word { font-size: 21px; line-height: 26px; }
}

.flashcard { padding: 36px; gap: 28px; }
.flashcard-face { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 12px 0; text-align: center; }
.flashcard-word { font-size: 52px; line-height: 56px; font-weight: 700; letter-spacing: -0.03em; }
.flashcard-gloss { font-size: 19px; font-weight: 600; }
.speak {
  width: 48px; height: 48px; padding: 0; border-radius: 24px;
  border: 1px solid var(--line-strong); background: var(--ground); color: var(--link);
  display: flex; align-items: center; justify-content: center;
}
@media (max-width: 767px) {
  .flashcard { padding: 22px; gap: 20px; }
  .flashcard-word { font-size: 40px; line-height: 44px; }
  .flashcard-gloss { font-size: 17px; }
}

.explain div { border-top: 1px solid var(--line); padding: 22px 0; }
.explain div:last-child { border-bottom: 1px solid var(--line); }
.explain dt { display: flex; justify-content: space-between; gap: 12px; font-size: 19px; font-weight: 700; }
.explain-interval { font-size: 16px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.explain dd { margin-top: 6px; font-size: 16px; line-height: 24px; color: var(--ink-2); }
.rating-ink-again { color: var(--rating-again-ink); }
.rating-ink-hard { color: var(--rating-hard-ink); }
.rating-ink-good { color: var(--rating-good-ink); }
.rating-ink-easy { color: var(--rating-easy-ink); }
@media (max-width: 767px) {
  .explain div { padding: 16px 0; }
  .explain dt { font-size: 17px; }
  .explain dd { font-size: 15px; line-height: 22px; }
}

.limits li { border-top: 1px solid var(--line); padding: 28px 0; display: grid; grid-template-columns: 64px minmax(0, 1fr); }
.limits li:last-child { border-bottom: 1px solid var(--line); }
.limits li > div { display: flex; flex-direction: column; gap: 6px; }
.limit-number { font-size: 32px; line-height: 32px; font-weight: 700; color: var(--link); }
@media (max-width: 767px) {
  .limits li { padding: 18px 0; grid-template-columns: 32px minmax(0, 1fr); }
  .limit-number { font-size: 24px; line-height: 26px; }
}

/* --- the 404 --------------------------------------------------------------------- */

/* A page nobody remembers any more, so the one place outside the method where
   the number itself is drawn in the ribbon. Decorative: the heading says it. */
.notfound-code {
  font-size: 120px; line-height: 112px; font-weight: 700; letter-spacing: -0.05em;
  background: linear-gradient(90deg, var(--ribbon-start), var(--ribbon-mid) 55%, var(--ribbon-end));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-notfound .hero-copy { gap: 24px; }
.hero-notfound .hero-actions { padding-top: 8px; }
.word-phrase { font-size: 48px; line-height: 52px; }

.notfound-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
.notfound-links li { border-top: 1px solid var(--line); }
.notfound-links li:nth-last-child(-n+2) { border-bottom: 1px solid var(--line); }
.notfound-links a {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 64px; color: var(--ink); font-size: 19px; font-weight: 600;
}
.notfound-links a:hover { color: var(--link); text-decoration: none; }
.notfound-links svg { flex-shrink: 0; color: var(--link); }
@media (max-width: 767px) {
  .notfound-code { font-size: 88px; line-height: 84px; }
  .word-phrase { font-size: 34px; line-height: 38px; }
  .notfound-links { grid-template-columns: minmax(0, 1fr); }
  .notfound-links li:nth-last-child(-n+2) { border-bottom: 0; }
  .notfound-links li:last-child { border-bottom: 1px solid var(--line); }
  .notfound-links a { min-height: 56px; font-size: 17px; }
}

/* --- footer ---------------------------------------------------------------------- */

.site-footer { border-top: 1px solid var(--line); padding: 32px 0 40px; }
.site-footer .container { display: flex; align-items: center; gap: 32px; }
.footer-brand { font-size: 15px; font-weight: 700; color: var(--ink); }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 0 28px; flex-grow: 1; }
.site-footer nav a { color: var(--ink-2); font-size: 14px; line-height: 44px; }
.site-footer nav a:hover { color: var(--ink); }
.site-footer p { font-size: 14px; color: var(--ink-3); }
.site-footer p a { color: inherit; }
@media (max-width: 1199px) {
  .site-footer .container { flex-wrap: wrap; }
}
@media (max-width: 767px) {
  .site-footer { padding: 16px 0 32px; }
  .site-footer .container { flex-direction: column; align-items: flex-start; gap: 4px; }
  .site-footer nav { gap: 0 20px; }
}

/* --- legal pages and the 404 ------------------------------------------------------ */

main.doc {
  max-width: calc(66ch + 2 * var(--gutter));
  margin: 0 auto; padding: 40px var(--gutter) 72px;
}
.doc { line-height: 1.6; }
.doc h1 { font-size: 34px; line-height: 40px; letter-spacing: -0.02em; margin: 0 0 8px; }
.doc .updated { color: var(--ink-3); font-size: 14px; margin: 0 0 32px; }
.doc h2 { font-size: 19px; margin: 36px 0 8px; letter-spacing: -0.01em; }
.doc h3 { font-size: 16px; margin: 24px 0 6px; }
.doc p { margin: 0 0 16px; }
.doc ul { padding-left: 20px; list-style: disc; margin: 0 0 16px; }
.doc li { margin: 4px 0; }
.doc table { border-collapse: collapse; width: 100%; margin: 14px 0; font-size: 15px; display: block; overflow-x: auto; }
.doc th, .doc td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; vertical-align: top; }
.doc th { background: var(--card); font-weight: 600; }
.doc a { text-decoration: underline; }
@media (max-width: 767px) {
  .doc h1 { font-size: 28px; line-height: 34px; }
}

/* An unfilled legal blank must be impossible to miss on the rendered page, not
   only in the source — see #498. */
.blank {
  background: var(--blank-ground); color: var(--blank-ink);
  padding: 1px 6px; border-radius: 6px;
  font-weight: 600; text-decoration: none;
}
