/* Design tokens, duplicated from webapp/index.html on purpose.

   The app is deliberately ONE self-contained file - no CDN, no external
   assets, so it works from a file:// URL and survives being copied around
   (see danish-vocab-web/README.md). That rules out it sharing this
   stylesheet. The site pages have the opposite need: five documents that
   should not each carry their own copy of the CSS, on a host that can cache
   one file across all of them.

   So the tokens live in two places, and that is a real drift risk. Keep the
   :root block below identical to the one in webapp/index.html (the app adds
   --danger/--good on top).

   The typefaces are system stacks on purpose - same no-external-assets rule.
   ui-serif resolves to New York on Apple devices and falls through to
   Iowan/Palatino/Georgia elsewhere, which is what gives the headings their
   editorial feel without shipping a font. */

:root {
  --bg: #faf7f1;
  --card: #fffdf9;
  --ink: #1c1712;
  --muted: #75695e;
  --accent: #b93a2b;
  --accent-2: #2f6b4c;
  --border: #e9e1d4;
  --font-display: ui-serif, "New York", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --shadow-sm: 0 1px 2px rgba(28, 23, 18, 0.04), 0 2px 8px rgba(28, 23, 18, 0.04);
  --shadow-md: 0 2px 6px rgba(28, 23, 18, 0.06), 0 14px 32px -14px rgba(28, 23, 18, 0.28);
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141110;
    --card: #1d1916;
    --ink: #f2ede5;
    --muted: #a3988b;
    --accent: #e6816d;
    --accent-2: #74bd90;
    --border: #2e2822;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.2);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.3), 0 14px 32px -14px rgba(0, 0, 0, 0.6);
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.7;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  /* Nothing here is wider than its column: a long Danish compound in a narrow
     phone column wraps mid-word rather than pushing the layout sideways. */
  overflow-wrap: break-word;
}

/* Hyphenation on running text only. Headings stay unhyphenated - a broken
   word in a 3rem headline is far more noticeable than a ragged edge. */
p, li, dd, blockquote, td { hyphens: auto; -webkit-hyphens: auto; }
h1, h2, h3, .brand, .cta, .site-nav a, th { hyphens: none; -webkit-hyphens: none; }

::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); }

/* One container, everywhere: the header, the footer, and every band on every
   page line up on the same edges. Article text used to sit in a narrower
   .prose variant; it doesn't any more, so a paragraph runs the full width the
   nav above it does. */
.wrap { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 28px; }

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-top: 14px;
  padding-bottom: 14px;
}
.brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.brand .flag { margin-right: 7px; font-size: 0.95em; }
.site-nav { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; }
.site-nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  transition: color 0.15s;
}
.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }
/* The last nav entry is always "Start learning" (see build_site.py) - it is
   the one action the whole site funnels toward, so it dresses as a button. */
.site-nav a:last-child {
  color: #fff;
  background: var(--accent);
  font-weight: 600;
  padding: 7px 16px;
  border-radius: 999px;
  transition: background 0.15s, box-shadow 0.15s;
}
.site-nav a:last-child:hover {
  color: #fff;
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
  box-shadow: var(--shadow-sm);
}
.site-nav a:last-child[aria-current="page"] { color: #fff; }

/* ---------- content ---------- */

main { flex: 1 0 auto; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2.1rem, 5.4vw, 3rem);
  line-height: 1.1;
  margin: 0 0 20px;
  letter-spacing: -0.02em;
}
h1 em, h2 em { font-style: italic; color: var(--accent); }
h2 {
  font-size: 1.55rem;
  line-height: 1.25;
  margin: 80px 0 14px;
  letter-spacing: -0.015em;
}
h3 { font-size: 1.12rem; margin: 32px 0 8px; }

/* Every page is built from bands (see below), so an h2 never has to separate
   itself - the band it opens does that. The only h2 left carrying its own top
   margin is one nested inside a section's copy, which is rare. */

/* Justified body copy. This leans on the hyphens: auto rule above - without
   hyphenation, justifying this measure opens rivers of white space between
   words. Single-line paragraphs (.eyebrow, .cta-note) are unaffected:
   justify never stretches a last line. */
p { margin: 0 0 18px; text-align: justify; }
a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover { text-decoration-thickness: 2px; }
strong { font-weight: 650; }

.eyebrow {
  font-size: 0.8rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin: 0 0 14px;
}

.lede {
  font-size: 1.18rem;
  line-height: 1.6;
  color: var(--muted);
  margin-bottom: 30px;
  max-width: 56ch;
}

ul, ol { margin: 0 0 18px; padding-left: 22px; }
li { margin-bottom: 8px; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 5px;
}

blockquote {
  margin: 0 0 18px;
  padding: 2px 0 2px 18px;
  border-left: 2px solid var(--accent);
  color: var(--muted);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05em;
}

/* ---------- landing page bands ---------- */

/* Each section is a full-width strip with its own background, so where one
   section ends and the next begins is visible without reading anything. */
.band { padding: 112px 0; border-top: 1px solid var(--border); }
main > .band:first-child { border-top: none; }
.band-hero { padding: 64px 0 116px; }
.band-tint { background: var(--card); }
/* A tinted band is painted in --card, so anything that is itself a --card
   panel has to flip to --bg inside one or it dissolves into the strip it was
   meant to sit on top of. */
.band-tint .card,
.band-tint .callout,
.band-tint .steps li,
.band-tint code { background: var(--bg); }
.band-invert {
  background: var(--ink);
  color: var(--bg);
  text-align: center;
  padding: 108px 0 116px;
}
.band-invert .section-title { color: var(--bg); }
/* The closing band is centred, so its copy opts back out of justification. */
.band-invert .section-note {
  color: color-mix(in srgb, var(--bg) 68%, var(--ink));
  margin: 0 auto 30px;
  text-align: center;
}

/* The band's own padding sets the gap under a section; the last block inside
   it must not quietly add its margin on top. */
.band .wrap > :last-child { margin-bottom: 0; }

.section-eyebrow {
  font-size: 0.78rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin: 0 0 10px;
}
.section-title {
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.2;
  margin: 0 0 30px;
  letter-spacing: -0.015em;
}
.section-note {
  color: var(--muted);
  max-width: 62ch;
  margin: 0;
}

.hero-grid { display: grid; gap: 44px; align-items: center; }
@media (min-width: 900px) {
  /* The copy column takes the larger share so the two calls to action sit on
     one line at common desktop widths; below that the row wraps, which is a
     fine second-best. */
  .hero-grid { grid-template-columns: 1.1fr 0.9fr; gap: 60px; }
}
.hero-copy .lede { max-width: 46ch; }

.two-col { display: grid; gap: 40px; }
@media (min-width: 860px) {
  .two-col { grid-template-columns: 1fr 1fr; gap: 60px; }
}
.two-col .section-title { font-size: 1.45rem; margin-bottom: 14px; }
.two-col p:last-child { margin-bottom: 0; }

/* ---------- app preview ---------- */

/* A still of the app's study list, rows supplied by build_site.py from the
   real word list. Decorative only - the app itself is one click away. */
.app-preview {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 18px 18px 14px;
  box-shadow: var(--shadow-md);
}
.pv-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 10px;
}
.pv-progress {
  height: 5px;
  background: var(--border);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 14px;
}
.pv-progress span {
  display: block;
  width: 22%;
  height: 100%;
  background: var(--accent-2);
}
.pv-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pv-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 11px 13px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 13px;
}
.pv-mark {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 2px solid var(--border);
  flex: none;
}
.pv-da { font-weight: 700; font-size: 1rem; min-width: 0; }
.pv-pos {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: color-mix(in srgb, var(--muted) 12%, transparent);
  padding: 1px 7px;
  border-radius: 999px;
}
.pv-ipa { font-size: 0.8rem; font-style: italic; color: var(--muted); }
.pv-en {
  margin-left: auto;
  padding-left: 8px;
  font-size: 0.85rem;
  color: var(--muted);
  text-align: right;
}
.pv-foot {
  margin: 12px 0 0;
  text-align: center;
  font-size: 0.75rem;
  color: var(--muted);
}

/* ---------- components ---------- */

.cta-row {
  display: flex;
  align-items: center;
  gap: 18px 20px;
  flex-wrap: wrap;
  margin: 4px 0 12px;
}

.cta {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  font-weight: 650;
  font-size: 1.02rem;
  padding: 14px 28px;
  border-radius: 999px;
  box-shadow: var(--shadow-md);
  transition: transform 0.15s, background 0.15s;
}
.cta:hover {
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
  transform: translateY(-1px);
}
.cta:active { transform: translateY(0); }

.cta-secondary {
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.98rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 2px;
  transition: border-color 0.15s;
}
.cta-secondary:hover { border-color: var(--ink); text-decoration: none; }
.cta-secondary::after { content: " \2192"; }

/* A meta line, not prose - justifying it spaces out "Free · No account" into
   something that reads like a mistake once it wraps on a phone. */
.cta-note {
  color: var(--muted);
  font-size: 0.92rem;
  margin-bottom: 0;
  text-align: left;
}
.cta-note .sep { margin: 0 7px; opacity: 0.5; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px 24px;
  margin: 0 0 16px;
  box-shadow: var(--shadow-sm);
}
.card h3 { margin-top: 0; }
.card p:last-child { margin-bottom: 0; }

/* Several cards in a row read as one set rather than a stack of blocks - the
   same move .steps makes on the landing page.

   The grid takes its shape from how many cards there are, because the thing
   that makes a card section look unfinished is a half-empty last row. Pairs by
   default; exactly three cards get a row of three once there is room for it,
   the way the landing page's three steps do. Whatever is left over alone on
   the final row spans it rather than sitting beside a hole.

   The :has() test reads "the last card is also the third one", i.e. there are
   exactly three of them. */
.card-grid { display: grid; gap: 20px; margin: 0 0 8px; }
@media (min-width: 720px) {
  .card-grid { grid-template-columns: repeat(2, 1fr); }
  .card-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 940px) {
  .card-grid:has(> :last-child:nth-child(3)) { grid-template-columns: repeat(3, 1fr); }
  .card-grid:has(> :last-child:nth-child(3)) > :last-child { grid-column: auto; }
}
.card-grid .card { margin: 0; }

/* Stats read as one quiet strip, not four boxes. */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 28px 24px;
  margin: 0 0 30px;
  padding: 28px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.stat .num {
  display: block;
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.stat .label {
  display: block;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--muted);
  margin-top: 6px;
}

/* On the landing page the three steps sit side by side as cards; on the
   article pages an .steps list is still a plain numbered column. */
.steps {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: step;
  display: grid;
  gap: 20px;
}
@media (min-width: 860px) {
  .steps { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}
.steps li {
  counter-increment: step;
  margin: 0;
  padding: 24px 24px 26px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-sm);
}
.steps li::before {
  content: counter(step);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
}
.steps h3 { margin: 16px 0 8px; font-size: 1.08rem; }
.steps p { margin: 0; color: var(--muted); font-size: 0.96rem; }

/* Wide content must scroll inside its own box, never the page body. */
.table-scroll { overflow-x: auto; margin: 0 0 24px; }
table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.93rem;
}
th, td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
th {
  font-weight: 650;
  white-space: nowrap;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}
td.num, th.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

.callout {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-2);
  border-radius: 12px;
  padding: 18px 20px;
  margin: 0 0 20px;
  box-shadow: var(--shadow-sm);
}
.callout p:last-child { margin-bottom: 0; }

.sources { font-size: 0.92rem; color: var(--muted); }
.sources li { margin-bottom: 10px; }

/* ---------- the pronunciation page ---------- */

/* IPA is set in the body font, not the display serif: a transcription is read
   symbol by symbol, and a serif italic-ish 'ɡ' or 'ɐ' is exactly the kind of
   letterform ambiguity that matters here. */
.ipa-inline, .sound-ipa, .chip-ipa, .pair-ipa, .w-ipa {
  font-family: var(--font-body);
  font-variant-ligatures: none;
}
.ipa-inline {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0 5px;
}
.band-tint .ipa-inline { background: var(--bg); }
/* A transcription is a single unit of meaning: better to let it scroll its own
   row than to break [ˈspœɐ̯sˌmɔˀl] across two lines. */
.w-ipa, .pair-ipa { white-space: nowrap; }

/* The play control. A button, so it is reachable by keyboard and announced as
   one; the accessible name is written per word by sounds.py. */
.play {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--accent);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
}
.play svg { width: 17px; height: 17px; fill: currentColor; stroke: currentColor; }
.play:hover { border-color: var(--accent); background: var(--bg); }
.play:active { transform: scale(0.94); }
.play:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Sounding right now: filled, so at a glance you can tell which of forty
   buttons you actually pressed. */
.play.is-playing { background: var(--accent); border-color: var(--accent); color: #fff; }
.play.is-dead { color: var(--muted); border-style: dashed; cursor: not-allowed; }
.play-sm { width: 26px; height: 26px; }
.play-sm svg { width: 13px; height: 13px; }
.play-lg { width: 42px; height: 42px; }
.play-lg svg { width: 20px; height: 20px; }

/* A word playable from the middle of a sentence, without the line it sits in
   growing taller than its neighbours. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: middle;
  margin: 2px 1px;
  padding: 2px 4px 2px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  font-size: 0.92rem;
  line-height: 1.3;
  white-space: nowrap;
  text-align: left;
}
.band-tint .chip { background: var(--bg); }
.chip [lang="da"] { font-weight: 650; }
.chip-ipa { color: var(--muted); }
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 14px; }
.chip-row .chip { font-size: 1rem; padding: 4px 6px 4px 14px; margin: 0; }

/* One card per symbol. Same breakpoints as .card-grid, so the two kinds of
   grid on the site step at the same widths. */
.sound-grid { display: grid; gap: 14px; margin: 0 0 24px; }
@media (min-width: 620px) {
  .sound-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 940px) {
  .sound-grid { grid-template-columns: repeat(3, 1fr); }
}
.sound {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 16px 16px;
  box-shadow: var(--shadow-sm);
}
.band-tint .sound { background: var(--bg); }
.sound-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
/* The symbol is the heading of its card, so it is sized like one. */
.sound-sym {
  font-size: 1.9rem;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.sound-hint {
  margin: 0 0 10px;
  font-size: 0.93rem;
  line-height: 1.55;
  color: var(--muted);
  text-align: left;
  hyphens: none;
}
.sound-eg {
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 0.93rem;
  text-align: left;
}
.sound-eg [lang="da"] { font-weight: 650; }
.sound-ipa { color: var(--muted); }
/* The symbol the card is about, picked out inside the example's transcription
   - the one place on the site where bold is doing indexing rather than
   emphasis, hence the colour rather than more weight. */
.sound-ipa b { color: var(--accent); font-weight: 650; }
.sound-en { color: var(--muted); font-style: italic; }
.sound-en::before { content: "· "; font-style: normal; }

/* A minimal pair: two words side by side that differ by one thing. Stacked on
   a phone, because comparing them means playing one then the other, and the
   two buttons should not be a thumb-stretch apart. */
.pair {
  display: grid;
  gap: 12px;
  margin: 0 0 16px;
}
@media (min-width: 620px) {
  .pair { grid-template-columns: repeat(2, 1fr); }
}
.pair-side {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 18px;
  box-shadow: var(--shadow-sm);
}
.band-tint .pair-side { background: var(--bg); }
.pair-da { font-weight: 700; font-size: 1.15rem; margin-right: 10px; }
.pair-ipa { color: var(--muted); }
.pair-ipa b { color: var(--accent); font-weight: 650; }
.pair-en { display: block; font-size: 0.9rem; color: var(--muted); font-style: italic; }

/* Word tables: the notation examples and the closing exercise. The play
   button sits with the word in the first cell - these tables scroll sideways
   on a phone, and the control has to be in the part that is on screen. */
.w-da { font-weight: 650; white-space: nowrap; }
.w-da .play { margin-left: 10px; vertical-align: middle; }
.w-en { color: var(--muted); }

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

.site-footer {
  border-top: 1px solid var(--border);
  padding: 26px 0 40px;
  font-size: 0.88rem;
  color: var(--muted);
}
.site-footer .wrap {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}
.site-footer a { color: var(--muted); }
.site-footer a:hover { color: var(--ink); }

@media (max-width: 560px) {
  body { font-size: 16px; }
  .wrap { padding: 0 20px; }
  .band { padding: 76px 0; }
  .band-hero { padding: 40px 0 80px; }
  .band-invert { padding: 76px 0 80px; }
  h2 { margin-top: 58px; }
  .lede { font-size: 1.08rem; }
  .cta { width: 100%; text-align: center; }
  .cta-row { gap: 16px; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 22px 16px; }
}
