/* Talkuma Kuma: the marketing pages (landing, Funktionen, Preise) and the
   two form pages (login, sign-up/invite). Built from design/tokens.css and
   design/components (bundle.css, nav.css, footer*.html); the design folder is
   the system of record, this file is its copy for the live app. No other
   stylesheet loads on these pages, so nothing from the old talkuma.css (deleted 2026-10-11) leaked in.

   Fonts are self-hosted: the CSP allows fonts from 'self' only. Atkinson
   Hyperlegible Next and Bricolage Grotesque are both SIL Open Font License. */
@font-face { font-family: 'Atkinson Hyperlegible Next'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('/static/fonts/atkinson-hyperlegible-next-latin.woff2') format('woff2');
  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; }
@font-face { font-family: 'Atkinson Hyperlegible Next'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('/static/fonts/atkinson-hyperlegible-next-latin-ext.woff2') format('woff2');
  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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Bricolage Grotesque'; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('/static/fonts/bricolage-grotesque-latin.woff2') format('woff2');
  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; }
@font-face { font-family: 'Bricolage Grotesque'; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('/static/fonts/bricolage-grotesque-latin-ext.woff2') format('woff2');
  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; }

/* ── Tokens (design/tokens.css). Dark follows the toggle (data-theme) and,
   with no stored choice, the system, like the rest of the app. */
/* A sun stage (.tk-on-sun: the hello, the known moment, the landing hero)
   keeps the light tokens in both themes (open point 41): sun is the same
   yellow day and night, so everything on it, Kuma's card and the terra
   button too, is the same as well. Kuma's own card (.tk-card) takes the
   light tokens too: the same white bear with dark eyes on every page
   (Olivier, 2026-10-11: the chalk eyes on a dark page read as a bug). */
:root, [data-theme="light"], .tk-on-sun, .tk-card, .st-card, .tk-chorus li {
  --paper: #f7f4ec; --surface: #ffffff; --surface-2: #f0e9dc;
  --ink: #1e1a16; --on-ink: #f7f4ec; --ink-muted: #5f665b; --outline: #1e1a16;
  --terra: #b4533a; --on-terra: #ffffff; --terra-soft: #f8ece7;
  --moss: #12705a; --on-moss: #ffffff;
  --sun: #f4c34a; --on-sun: #1e1a16; --mint: #d6ece5; --blush: #f2a58e;
  --focus: var(--ink);
  --kuma-eye: #1e1a16; --kuma-shine: #ffffff;
  --shadow-sticker: 3px 3px 0 #1e1a16; --shadow-button: 0 5px 0 #1e1a16; --shadow-card: 8px 10px 0 #1e1a16;
  color-scheme: light;
}
[data-theme="dark"] {
  --paper: #141311; --surface: #1e1b17; --surface-2: #262220;
  --ink: #f3ede5; --on-ink: #141311; --ink-muted: #ada398; --outline: #e9e1d6;
  --terra: #e28f75; --on-terra: #1c120d; --terra-soft: #4e362d;
  --moss: #4fd9b0; --on-moss: #0e2a22;
  --sun: #f4c34a; --on-sun: #1e1a16; --mint: #1d3a33; --blush: #f2a58e;
  --shadow-sticker: 3px 3px 0 #e9e1d6; --shadow-button: 0 5px 0 #e9e1d6; --shadow-card: 8px 10px 0 #e9e1d6;
  --kuma-eye: #e9e1d6; --kuma-shine: transparent;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #141311; --surface: #1e1b17; --surface-2: #262220;
    --ink: #f3ede5; --on-ink: #141311; --ink-muted: #ada398; --outline: #e9e1d6;
    --terra: #e28f75; --on-terra: #1c120d; --terra-soft: #4e362d;
    --moss: #4fd9b0; --on-moss: #0e2a22;
    --sun: #f4c34a; --on-sun: #1e1a16; --mint: #1d3a33; --blush: #f2a58e;
    --shadow-sticker: 3px 3px 0 #e9e1d6; --shadow-button: 0 5px 0 #e9e1d6; --shadow-card: 8px 10px 0 #e9e1d6;
    --kuma-eye: #e9e1d6; --kuma-shine: transparent;
    color-scheme: dark;
  }
}
/* --page-outline (open point 107, Olivier 2026-10-21: "light shadow in dark"):
   the outline colour of the PAGE, taken before a card re-scopes the tokens.
   The KumaCard keeps its light colours on every theme (white bear, dark
   eyes), but its outline, its ears' outline and its hard shadow follow the
   page: dark ink on a light page, chalk on a dark one. Set where the theme
   is set, so it is read before .tk-card takes the light tokens; on the sun
   (.tk-on-sun, the known moment) the page is light, so it stays ink. */
:root, [data-theme="light"], [data-theme="dark"], .tk-on-sun { --page-outline: var(--outline); }
:root {
  --space-1: 6px; --space-2: 10px; --space-3: 16px; --space-4: 20px; --space-5: 34px;
  --kuma-ear: #b4533a; --kuma-snout: #f0e9dc; --kuma-nose: #1e1a16; /* Kuma's own colours, the same on every theme */
  --radius-tail: 6px; --radius-tile: 18px; --radius-bubble: 22px; --radius-card: 30px; --radius-pill: 999px;
  --stroke-2: 2px; --stroke-3: 3px;
  --font-display: 'Bricolage Grotesque', 'Manrope', var(--font-thai), system-ui, sans-serif;
  --font-body: 'Atkinson Hyperlegible Next', Manrope, var(--font-thai), system-ui, sans-serif;
  /* Neither web font has Thai. A browser picks a font per letter, so Latin
     stays Atkinson/Bricolage and only Thai letters reach these: the
     system's own Thai fonts (Android and Linux, Apple, Windows), no web
     font to download, the same as Japanese and Korean. */
  --font-thai: 'Noto Sans Thai', 'Noto Sans Thai UI', Thonburi, 'Sukhumvit Set', 'Leelawadee UI', Leelawadee, Tahoma;
}

/* ── Base */
body.kuma { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--font-body);
  -webkit-text-size-adjust: 100%; overflow-x: clip; }
.kuma a { color: var(--ink); }
.kuma a:hover { color: var(--terra); }
.kuma a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
:where(.kuma a:focus-visible) { border-radius: 6px; }
.kuma p b, .kuma figcaption b { font-weight: 800; }
.kuma img { max-width: 100%; }
:where(.kuma) input, :where(.kuma) button { font: inherit; }
.kuma input:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* The site-wide notices (nav_banners) keep their meaning here without
   the old talkuma.css: a quiet strip above the nav. */
.kuma .beta-banner { display: block; margin: 0; padding: 10px 20px; text-align: center; font-size: 16px; font-weight: 700;
  background: var(--surface-2); color: var(--ink); border-bottom: var(--stroke-2) solid var(--outline); text-decoration: none; }
.kuma .maintenance-banner.active { background: var(--terra-soft); }
.kuma .maintenance-banner::after { content: " \2192"; }

/* ── Components (design/components/bundle.css) */
.tk-button, .tk-bubble, .tk-me, .tk-choice, .tk-chip, .tk-card, .tk-card .tk-face { box-sizing: border-box; }
.tk-button:focus-visible, .tk-chip:focus-visible, .tk-choice:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-button { display: flex; align-items: center; justify-content: center; gap: var(--space-2); max-width: 100%; text-align: center;
  min-height: 62px; width: 100%; padding: 0 var(--space-4); border-radius: var(--radius-pill);
  background: var(--terra); color: var(--on-terra); border: var(--stroke-2) solid var(--outline);
  box-shadow: var(--shadow-button); font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1.1;
  cursor: pointer; transition: transform .08s, box-shadow .08s; text-decoration: none; }
.kuma a.tk-button, .kuma a.tk-button:hover { color: var(--on-terra); }
.tk-button:active { transform: translateY(3px); box-shadow: 0 2px 0 var(--outline); }
.tk-button.tk-quiet, .kuma a.tk-button.tk-quiet, .kuma a.tk-button.tk-quiet:hover { background: var(--surface); color: var(--ink); }
.tk-button.tk-moss { background: var(--moss); color: var(--on-moss); }
.tk-button.tk-auto { width: auto; padding: 0 28px; }
span.tk-button { cursor: default; }

.tk-row { display: flex; gap: var(--space-2); align-items: flex-end; }
.tk-bubble { background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-bubble) var(--radius-bubble) var(--radius-bubble) var(--radius-tail);
  box-shadow: var(--shadow-sticker); padding: 12px var(--space-3); max-width: 280px; margin: 0;
  font-size: 18px; font-weight: 600; line-height: 1.3; }
.tk-me { align-self: flex-end; margin-left: auto; background: var(--ink); color: var(--on-ink);
  border-radius: var(--radius-bubble) var(--radius-bubble) var(--radius-tail) var(--radius-bubble);
  padding: 11px var(--space-3); max-width: 280px; font-size: 17px; font-weight: 700; }
/* Say: the KI's line in the language you learn, under a line you typed in
   your own (#103). A plain card under your bubble: surface, 2 px outline, no
   shadow (it is not a speaker), its square corner points up at your bubble.
   The KI badge sits first; the line keeps its own lang. */
.tk-say { box-sizing: border-box; align-self: flex-end; display: flex; align-items: baseline; gap: 10px; margin: 0; max-width: 280px;
  padding: 10px 14px; background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-tile) var(--radius-tail) var(--radius-tile) var(--radius-tile);
  font-family: var(--font-body); font-size: 19px; font-weight: 700; line-height: 1.3; overflow-wrap: anywhere; }
.tk-say .ob-ki, .tk-say .ki { flex: none; margin: 0; position: relative; top: -2px; }
.tk-kuma { flex: none; width: 46px; height: auto; }

/* KumaCard: the big card with ears and the bear face. The face is drawn in
   face units (--ku): 1 px on every phone, so the phone face is the drawn
   one; past 960 px the card is a size container and --ku grows with its
   width (1 px at 342 px, the phone hello, up to 1.5 px), so ears, eyes,
   cheeks and snout keep the phone's proportions on a wide card (ISC-254,
   Olivier 2026-10-11: on the wide Heute card the face "looks cramped").
   Strokes stay 3 px. */
.tk-card { --ku: 1px; position: relative; display: block; width: 300px; max-width: 100%; margin: 32px auto 12px;
  padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
@media (min-width: 960px) {
  .tk-card { container-type: inline-size; --ku: clamp(1px, 100cqi / 342, 1.5px); }
}
.tk-card:focus-visible { outline: none; }
.tk-card:focus-visible .tk-face { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-card .tk-ear { position: absolute; top: calc(-26 * var(--ku)); width: calc(62 * var(--ku)); height: calc(62 * var(--ku)); border-radius: var(--radius-pill);
  background: var(--kuma-ear); border: var(--stroke-3) solid var(--page-outline, var(--outline)); }
.tk-card .tk-ear::after { content: ""; position: absolute; top: calc(12 * var(--ku)); left: 50%; width: calc(22 * var(--ku)); height: calc(22 * var(--ku)); margin-left: calc(-11 * var(--ku));
  border-radius: var(--radius-pill); background: var(--blush); }
.tk-card .tk-ear.l { left: calc(24 * var(--ku)); } .tk-card .tk-ear.r { right: calc(24 * var(--ku)); }
.tk-card .tk-face { position: relative; display: flex; min-height: 360px; background: var(--surface); color: var(--ink);
  border: var(--stroke-3) solid var(--page-outline, var(--outline)); border-radius: var(--radius-card); box-shadow: 8px 10px 0 var(--page-outline, var(--outline));
  flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: calc(124 * var(--ku)) 26px 60px; }
.tk-card .tk-eyes { position: absolute; top: calc(32 * var(--ku)); left: 0; right: 0; display: flex; justify-content: center; gap: calc(60 * var(--ku)); }
.tk-card .tk-eyes i { position: relative; width: calc(16 * var(--ku)); height: calc(16 * var(--ku)); border-radius: 50%; background: var(--kuma-eye); }
.tk-card .tk-eyes i::after { content: ""; position: absolute; top: calc(3 * var(--ku)); right: calc(3 * var(--ku)); width: calc(5 * var(--ku)); height: calc(5 * var(--ku)); border-radius: 50%; background: var(--kuma-shine); }
.tk-card .tk-cheek { position: absolute; top: calc(62 * var(--ku)); width: calc(28 * var(--ku)); height: calc(14 * var(--ku)); border-radius: 50%; background: var(--blush); }
/* Cheeks: 44 face units from the edges; past the 1.5 px cap they hold to
   the centre (open point 41), never further out. */
.tk-card .tk-cheek.l { left: max(calc(44 * var(--ku)), calc(50% - 127 * var(--ku))); } .tk-card .tk-cheek.r { right: max(calc(44 * var(--ku)), calc(50% - 127 * var(--ku))); }
.tk-card .tk-snout { position: absolute; top: calc(50 * var(--ku)); left: 50%; width: calc(68 * var(--ku)); height: calc(46 * var(--ku)); margin-left: calc(-34 * var(--ku)); box-sizing: border-box;
  border-radius: 50%; background: var(--kuma-snout); }
.tk-card .tk-snout::before { content: ""; position: absolute; top: calc(8 * var(--ku)); left: 50%; width: calc(22 * var(--ku)); height: calc(15 * var(--ku)); margin-left: calc(-11 * var(--ku));
  border-radius: 50% 50% 50% 50% / 40% 40% 60% 60%; background: var(--kuma-nose); }
.tk-card .tk-snout::after { content: ""; position: absolute; top: calc(21 * var(--ku)); left: 50%; width: calc(2.5 * var(--ku)); height: calc(7 * var(--ku)); margin-left: calc(-1.25 * var(--ku)); background: var(--kuma-nose); }
.tk-card .tk-snout i { position: absolute; top: calc(25 * var(--ku)); width: calc(12 * var(--ku)); height: calc(9 * var(--ku)); box-sizing: border-box;
  border: calc(2.5 * var(--ku)) solid var(--kuma-nose); border-top: 0; border-radius: 0 0 15px 15px; }
.tk-card .tk-snout i:first-child { left: calc(50% - 13.25 * var(--ku)); } .tk-card .tk-snout i:last-child { left: calc(50% + 1.25 * var(--ku)); }
.tk-card .tk-word { font-family: var(--font-body); font-weight: 800; font-size: 48px; line-height: 1.05; text-wrap: balance; overflow-wrap: anywhere; }
.tk-card .tk-sub { margin-top: var(--space-2); font-size: 18px; font-weight: 600; color: var(--ink-muted); }
.tk-card .tk-lang { position: absolute; bottom: 22px; font-size: 16px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-muted); }
/* The hero card turns over on a tap: front the sentence, back its meaning. */
.tk-card .tk-front { display: contents; }
.tk-card .tk-word, .tk-card .tk-sub { display: block; }
.tk-card .tk-back { display: none; }
.tk-card[aria-pressed="true"] .tk-front { display: none; }
.tk-card[aria-pressed="true"] .tk-back { display: contents; }
.tk-card[aria-pressed="true"] .tk-face { animation: tk-turn 320ms cubic-bezier(.34,1.6,.5,1); }
@keyframes tk-turn { 0% { transform: rotateY(90deg); } 100% { transform: none; } }
/* Kuma's idle life (ISC-247): static/kuma-idle.js puts one kz-* class on a
   Kuma now and then, at random; the moves are here. Slim: a blink closes
   in about 70 ms, an ear flicks (12 degrees, a slight squash), the snout moves 1.5 px, a
   breath lifts the face 1.2 %. .kz-live (from the first idle move on)
   retires the entrance's finished pops and its fixed blink loop, so taking
   a move's class off never replays an entrance. The #kz in :not() only
   lifts the rules above the page CSS (app-first.css, app-learn.css). No
   idle motion at all under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .tk-card.kz-live:not(#kz) .tk-ear, .tk-card.kz-live:not(#kz) .tk-eyes i { animation: none; }
  .tk-card.kz-blink:not(#kz) .tk-eyes i { animation: kz-blink 170ms ease-in-out; }
  .tk-card.kz-blink2:not(#kz) .tk-eyes i { animation: kz-blink2 420ms ease-in-out; }
  .tk-card.kz-ear-l:not(#kz) .tk-ear.l { transform-origin: 70% 90%; animation: kz-ear-l 460ms cubic-bezier(.3,1.4,.5,1); }
  .tk-card.kz-ear-r:not(#kz) .tk-ear.r { transform-origin: 30% 90%; animation: kz-ear-r 460ms cubic-bezier(.3,1.4,.5,1); }
  .tk-card.kz-snout:not(#kz) .tk-snout { animation: kz-snout 560ms ease-in-out; }
  .tk-card.kz-snout:not(#kz) .tk-snout i { transform-origin: 50% 0; animation: kz-mouth 560ms ease-in-out; }
  .tk-card.kz-breath:not([aria-pressed="true"]):not(#kz) .tk-face { transform-origin: 50% 100%; animation: kz-breath 2600ms ease-in-out; }
  .tk-card.kz-breath:not([aria-pressed="true"]):not(#kz) .tk-ear { animation: kz-breath-ear 2600ms ease-in-out; }
  img.tk-kuma.kz-breath { transform-origin: 50% 100%; animation: kz-breath-small 2600ms ease-in-out; }
  img.tk-kuma.kz-tilt { transform-origin: 50% 100%; animation: kz-tilt 600ms cubic-bezier(.3,1.4,.5,1); }
}
@keyframes kz-blink { 0%, 100% { transform: none; } 40%, 55% { transform: scaleY(.1); } }
@keyframes kz-blink2 { 0%, 42%, 100% { transform: none; } 18%, 24%, 64%, 70% { transform: scaleY(.1); } }
@keyframes kz-ear-l { 0%, 100% { transform: none; } 20% { transform: rotate(-12deg) scale(.94, .86); } 45% { transform: rotate(5deg); } 70% { transform: rotate(-2deg); } }
@keyframes kz-ear-r { 0%, 100% { transform: none; } 20% { transform: rotate(12deg) scale(.94, .86); } 45% { transform: rotate(-5deg); } 70% { transform: rotate(2deg); } }
@keyframes kz-snout { 0%, 100% { transform: none; } 22% { transform: translateY(-1.5px) scale(1.05); } 50% { transform: translateY(.5px) scale(.98); } 75% { transform: translateY(-.5px); } }
@keyframes kz-mouth { 0%, 100% { transform: none; } 22%, 50% { transform: scaleY(1.4); } }
@keyframes kz-breath { 0%, 100% { transform: none; } 45% { transform: translateY(-1px) scale(1.012); } }
@keyframes kz-breath-ear { 0%, 100% { transform: none; } 45% { transform: translateY(-4px); } }
@keyframes kz-breath-small { 0%, 100% { transform: none; } 45% { transform: translateY(-1px) scale(1.03); } }
@keyframes kz-tilt { 0%, 100% { transform: none; } 30% { transform: rotate(-6deg); } 60% { transform: rotate(2deg); } }

/* ChoiceCard and GreetingChip. */
.tk-choice { display: flex; gap: var(--space-3); align-items: center; width: 100%; text-align: left;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-tile); box-shadow: var(--shadow-sticker); padding: var(--space-3); font: inherit; }
.tk-choice b { display: block; font-family: var(--font-display); font-size: 20px; font-weight: 800; line-height: 1.15; }
.tk-choice .tk-desc { display: block; margin-top: 4px; font-size: 16px; font-weight: 500; color: var(--ink-muted); line-height: 1.4; }
.tk-choice .tk-num { flex: none; width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center;
  background: var(--sun); color: var(--on-sun); border: var(--stroke-2) solid var(--outline); font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.tk-choice[aria-disabled="true"] { background: var(--paper); box-shadow: none; cursor: default; }
.tk-choice[aria-disabled="true"] .tk-num { background: var(--surface-2); color: var(--ink-muted); }
.tk-chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.tk-chip { display: grid; justify-items: start; align-content: center; gap: 6px; min-height: 88px; padding: 16px 22px; text-align: left; overflow-wrap: anywhere;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-pill); box-shadow: var(--shadow-sticker); font: inherit; }
.tk-chip b { font-family: var(--font-body); font-size: 30px; font-weight: 800; line-height: 1.05; }
.tk-chip span { font-size: 18px; font-weight: 700; line-height: 1.25; color: var(--ink); }
.tk-chip.tk-small { min-height: 52px; padding: 10px 18px; }
.tk-chip.tk-small span { font-size: 18px; font-weight: 800; }

/* Press (components/press.js, run by kuma.js). */
.tk-button { --tk-rest: var(--shadow-button); }
.tk-chip, .tk-choice { --tk-rest: var(--shadow-sticker); }
@keyframes tk-press {
  0% { transform: none; box-shadow: var(--tk-rest), 0 0 0 0 rgba(244,195,74,0); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  15%, 30% { transform: translateY(4px) scale(.96); box-shadow: 0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  45%, 55% { transform: translateY(4px) scale(.96); box-shadow: 0 0 0 var(--outline), 0 0 0 10px rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.34,1.8,.5,1); }
  100% { transform: none; box-shadow: var(--tk-rest), 0 0 0 22px rgba(244,195,74,0); }
}
/* !important: a tap beats any entrance animation on the same element
   (same rule the old talkuma.css had). */
.tk-pressed { animation: tk-press 460ms both !important; }
/* A tab has no shape of its own: its round icon dips and rings, the tab
   stays where the finger is (Olivier, 2026-10-12: "looks buggy"). */
.ap-tab.tk-pressed { animation: none !important; }
.ap-tab.tk-pressed .ic { --tk-rest: 0 0 0 transparent; animation: tk-press 460ms both; }

/* Highlight: one marker stroke under one keyword per heading. */
.tk-hl { background: linear-gradient(transparent 55%, var(--sun) 55%, var(--sun) 90%, transparent 90%);
  padding: 0 .08em; -webkit-box-decoration-break: clone; box-decoration-break: clone; color: var(--ink); }
/* Dark: the word keeps its on-sun ink, so the yellow sits behind all of it. A
   half stroke left the top of every letter dark on the dark page. */
[data-theme="dark"] .tk-hl { color: var(--on-sun); background: var(--sun); border-radius: 6px; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .tk-hl { color: var(--on-sun); background: var(--sun); border-radius: 6px; } }
:root .tk-on-sun .tk-hl { background: linear-gradient(transparent 55%, #fff 55%, #fff 90%, transparent 90%); color: var(--on-sun); border-radius: 0; }

/* Said: the learner's own line, under a question they ask at the price
   ("Zu teuer?"). A mint ground (practice), a 2 px outline, no shadow: it
   reads as a quote, never as one of Kuma's bubbles (round tile, no tail, a
   label above) and never as a button (the link is its only target). The
   line is Bricolage 800 so it is seen from across the page; the link under
   it says where it leads. Built in #197 (Hilfe, Preise, /upgrade). */
.tk-said { box-sizing: border-box; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1);
  width: 100%; padding: var(--space-3) var(--space-4) var(--space-2); background: var(--mint); color: var(--ink);
  border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-tile); }
.tk-said-q { font-family: var(--font-body); font-size: 16px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.tk-said-l { margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1.2; overflow-wrap: anywhere; }
.tk-said a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); font-size: 17px; font-weight: 800;
  text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.tk-said a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.pr-plan .tk-said { margin-top: var(--space-1); }

/* Grids on a 12-column rhythm. */
.tk-grid-2, .tk-grid-3 { display: grid; gap: 28px; }
.tk-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tk-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tk-grid-2 .tk-choice { padding: 26px 28px; gap: 22px; }
.tk-chips.tk-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
@media (max-width: 900px) { .tk-chips.tk-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .tk-grid-3 { grid-template-columns: 1fr; } }
@media (max-width: 700px) { .tk-grid-2 { grid-template-columns: 1fr; } }
@media (max-width: 420px) { .tk-chips.tk-grid-4 { gap: 14px; } .tk-chip { padding: 14px 16px; } .tk-chip b { font-size: 26px; } }

/* ── Nav (design/components/nav.css). One bar for every marketing page. */
.nv{position:relative;max-width:1200px;margin:0 auto;padding:16px 20px;box-sizing:border-box;display:flex;align-items:center;gap:24px;font-family:var(--font-body)}
.nv a{color:var(--ink);text-decoration:none}
.nv a:hover{color:var(--terra)}
.nv a.tk-button,.nv a.tk-button:hover{color:var(--on-terra)}
.nv a.tk-button.tk-quiet,.nv a.tk-button.tk-quiet:hover{color:var(--ink)}
.nv-form{justify-content:space-between}
.nv-form-end{display:flex;align-items:center;gap:16px}
.nv a:focus-visible,.nv summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
:where(.nv a:focus-visible,.nv summary:focus-visible){border-radius:10px}
.nv-brand{display:flex;align-items:center;gap:10px;min-height:44px;flex:none}
.nv-brand img{width:38px;height:auto}
.nv-brand span{font-family:var(--font-display);font-weight:800;font-size:24px;line-height:1}
.nv-links{display:flex;gap:8px;flex:1 1 auto;justify-content:center}
.nv-links a{display:inline-flex;align-items:center;min-height:44px;padding:0 10px;font-weight:700;font-size:17px;white-space:nowrap}
.nv-links a[aria-current="page"],.nv-row[aria-current="page"]{text-decoration:underline;text-decoration-thickness:4px;text-underline-offset:8px}
.nv-end{display:flex;align-items:center;gap:16px;flex:none}
.nv-login{display:inline-flex;align-items:center;min-height:44px;padding:0 6px;font-weight:700;font-size:17px;white-space:nowrap}
.nv-cta.tk-button{width:auto;min-height:48px;padding:0 22px;font-size:17px;white-space:nowrap}
.nv-lang{display:inline-flex;align-items:center;gap:0;flex:none}
.nv-globe{margin-right:8px;flex:none}
.kuma .nv-lang a{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 14px;font-weight:700;font-size:16px;white-space:nowrap;background:var(--surface);color:var(--ink);text-decoration:none;border:var(--stroke-2) solid var(--outline)}
.nv-lang a:first-of-type{border-radius:var(--radius-pill) 0 0 var(--radius-pill)}
.nv-lang a:last-of-type{border-radius:0 var(--radius-pill) var(--radius-pill) 0;margin-left:-2px}
.kuma .nv-lang a[aria-current="true"]{background:var(--ink);color:var(--on-ink);pointer-events:none}
.nv-lang a:focus-visible{position:relative;z-index:1}
.nv-menu{display:none;margin-left:auto}
.nv-menu summary{list-style:none;display:inline-flex;align-items:center;gap:10px;min-height:48px;padding:0 18px;border:var(--stroke-2) solid var(--outline);border-radius:var(--radius-pill);background:var(--surface);box-shadow:var(--shadow-sticker);font-weight:800;font-size:17px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.nv-menu summary::-webkit-details-marker{display:none}
.nv-burger{position:relative;width:18px;height:2px;background:var(--ink);box-shadow:0 -6px 0 var(--ink),0 6px 0 var(--ink)}
.nv-menu[open] .nv-burger{height:0;box-shadow:none}
.nv-menu[open] .nv-burger::before,.nv-menu[open] .nv-burger::after{content:"";position:absolute;left:0;top:-1px;width:18px;height:2px;background:var(--ink);transform:rotate(45deg)}
.nv-menu[open] .nv-burger::after{transform:rotate(-45deg)}
.nv-say-close,.nv-menu[open] .nv-say-open{display:none}
.nv-menu[open] .nv-say-close{display:inline}
.nv-menu:not([open]) .nv-panel{display:none}
.nv-panel{position:absolute;z-index:20;left:12px;right:12px;top:calc(100% - 4px);display:flex;flex-direction:column;gap:6px;padding:18px 20px 22px;box-sizing:border-box;background:var(--surface);border:var(--stroke-2) solid var(--outline);border-radius:var(--radius-tile);box-shadow:var(--shadow-card)}
.nv-label{margin:0;font-size:16px;font-weight:700;color:var(--ink)}
.nv-lang-wide{display:flex;margin-bottom:10px}
.kuma .nv-lang-wide a{flex:1 1 0;min-height:52px;font-size:18px}
.nv-row{display:flex;align-items:center;min-height:52px;padding:0 4px;font-weight:800;font-size:20px;border-top:var(--stroke-2) solid var(--surface-2)}
.nv-panel-btn.tk-button{min-height:54px;font-size:19px;margin-top:6px}
/* The other door in the form nav (login / sign-up). */
.kuma .lg-navbtn{min-height:44px;display:inline-flex;align-items:center;padding:0 18px;box-sizing:border-box;border:2px solid var(--outline);border-radius:var(--radius-pill);background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sticker);font-family:var(--font-display);font-weight:800;font-size:17px;text-decoration:none;white-space:nowrap}
.lg-navbtn:focus-visible{border-radius:var(--radius-pill)}
@media (max-width:1099px){
  .nv{padding:12px 20px;gap:12px}
  .nv-links,.nv-end{display:none}
  .nv-menu{display:block}
  .nv-form .nv-globe{display:none}
  .kuma .nv-form .nv-lang a{padding:0 12px}
}
/* The other door sits in the nav on desktop only. Below the nav's desktop
   width the big box under the heading is the one way (Olivier, 2026-10-11:
   two "Konto erstellen" on the phone felt overloaded). */
@media (max-width:1099px){.kuma .lg-navbtn{display:none}}

/* ── Footer (design/components/footer.html, footer-form.html). */
.ft{border-top:2px solid var(--outline);background:var(--paper);color:var(--ink)}
.ft-in{max-width:1200px;margin:0 auto;padding:44px 20px 0;box-sizing:border-box;display:flex;flex-wrap:wrap;gap:28px 64px;justify-content:space-between}
.ft-brand{display:flex;flex-direction:column;gap:10px;max-width:34ch}
.kuma .ft-logo{display:inline-flex;align-items:center;gap:10px;min-height:44px;text-decoration:none;color:var(--ink);align-self:flex-start}
.ft-logo img{width:32px;height:auto}
.ft-logo span{font-family:var(--font-display);font-weight:800;font-size:22px}
.ft-line{margin:0;font-size:16px;font-weight:600;line-height:1.5;color:var(--ink-muted)}
.ft-nav{display:flex;flex-wrap:wrap;gap:0 56px;font-size:17px;font-weight:700}
.ft-col{display:flex;flex-direction:column;align-items:flex-start}
.ft-col > a,.ft-legal > a{min-height:44px;min-width:44px;display:inline-flex;align-items:center}
.ft-col .nv-lang{margin-top:6px}
.ft-legal{box-sizing:border-box;width:calc(100% - 40px);max-width:1160px;margin:28px auto 0;padding:16px 0 40px;border-top:2px solid var(--surface-2);display:flex;flex-wrap:wrap;align-items:center;gap:0 24px;font-size:16px;font-weight:700}
.ft-legal span{min-height:44px;display:inline-flex;align-items:center;font-weight:600;color:var(--ink-muted)}
/* The language and the Hell/Dunkel switch sit under the second link column
   on wide screens and across the whole width on the phone, so the two link
   columns stay side by side at 360-390 px (the switch is wider than a
   column). */
.ft-nav{display:grid;grid-template-columns:auto auto;grid-template-areas:"c1 c2" "c1 set";align-items:start;justify-content:start}
.ft-nav > .ft-col:first-child{grid-area:c1}
.ft-nav > .ft-col + .ft-col{grid-area:c2}
.ft-set{grid-area:set;display:flex;flex-direction:column;align-items:flex-start;gap:16px}
.ft-set .nv-lang{margin-top:18px}
@media (max-width:560px){.ft-nav{grid-template-areas:"c1 c2" "set set"}}

/* Hell / Dunkel (open point 36; boards "Hell/Dunkel ·"). What is on comes
   from <html data-theme>, or the system when nothing is stored, so the knob
   and the marked word are right on the first frame. Light is the base;
   the two dark selectors below are the same pair kuma.css uses for the
   tokens. Only the knob moves (a 100 ms spring); sun and moon fade. */
.th{display:flex;flex-wrap:wrap;align-items:center;column-gap:6px;row-gap:4px;color:var(--ink)}
.ft-brand .th{margin-top:6px}
.th-lbl{font-size:17px;font-weight:600;margin-right:8px}
.kuma .th-w{display:inline-flex;align-items:center;justify-content:center;min-height:48px;min-width:48px;padding:0;border:0;background-color:transparent;color:var(--ink);font:inherit;font-size:17px;font-weight:600;cursor:pointer;-webkit-tap-highlight-color:transparent;border-radius:10px}
.th-w > span{padding:0 3px;border-radius:6px}
.th-w:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.th-flip{display:inline-flex;align-items:center;min-height:48px;min-width:48px;padding:0 2px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.th-track{position:relative;flex:none;width:60px;height:34px;box-sizing:border-box;border:var(--stroke-2) solid var(--outline);border-radius:var(--radius-pill);background:var(--surface-2);box-shadow:var(--shadow-sticker)}
.th-knob{position:absolute;top:2px;left:2px;width:26px;height:26px;box-sizing:border-box;display:grid;place-items:center;border:var(--stroke-2) solid var(--outline);border-radius:50%;background:var(--sun);color:var(--on-sun);transition:transform 100ms cubic-bezier(.34,1.8,.5,1)}
.th-knob > span{grid-area:1/1;display:grid;transition:opacity 100ms}
.th-moon{opacity:0}
/* Light is on: Hell carries the marker (tk-hl's light stroke). */
.kuma .th-w[data-theme-set="light"]{font-weight:800;cursor:default}
.th-w[data-theme-set="light"] > span{background:linear-gradient(transparent 55%, var(--sun) 55%, var(--sun) 90%, transparent 90%)}
/* Dark is on: the knob slides, Dunkel is filled (tk-hl in dark, ed7b479). */
[data-theme="dark"] .th-knob{transform:translateX(26px)}
[data-theme="dark"] .th-sun{opacity:0}
[data-theme="dark"] .th-moon{opacity:1}
[data-theme="dark"] .kuma .th-w[data-theme-set="light"]{font-weight:600;cursor:pointer}
[data-theme="dark"] .th-w[data-theme-set="light"] > span{background:none}
[data-theme="dark"] .kuma .th-w[data-theme-set="dark"]{font-weight:800;cursor:default}
[data-theme="dark"] .th-w[data-theme-set="dark"] > span{color:var(--on-sun);background:var(--sun)}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .th-knob{transform:translateX(26px)}
  :root:not([data-theme="light"]) .th-sun{opacity:0}
  :root:not([data-theme="light"]) .th-moon{opacity:1}
  :root:not([data-theme="light"]) .kuma .th-w[data-theme-set="light"]{font-weight:600;cursor:pointer}
  :root:not([data-theme="light"]) .th-w[data-theme-set="light"] > span{background:none}
  :root:not([data-theme="light"]) .kuma .th-w[data-theme-set="dark"]{font-weight:800;cursor:default}
  :root:not([data-theme="light"]) .th-w[data-theme-set="dark"] > span{color:var(--on-sun);background:var(--sun)}
}
@media (prefers-reduced-motion: reduce){.th-knob{transition:none}}

/* ── Page building blocks */
.mk-wrap{max-width:1200px;margin:0 auto;padding:80px 20px;box-sizing:border-box}
.mk-col{display:flex;flex-direction:column;gap:28px}
.mk-band{background:var(--surface);border-top:2px solid var(--outline);border-bottom:2px solid var(--outline)}
.mk-band + .mk-band, .mk-band + .ft{border-top:0}
.mk-eye{font-size:16px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-muted)}
.mk-h1{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(40px,5.5vw,64px);line-height:1;text-wrap:balance}
.mk-h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(34px,4.5vw,52px);line-height:1.02;text-wrap:balance}
.mk-p{margin:0;font-size:19px;font-weight:600;line-height:1.5;max-width:52ch}
.mk-lead{margin:0;font-size:20px;font-weight:600;line-height:1.45;max-width:52ch}
.kuma a.mk-more{font-weight:800;font-size:17px;align-self:flex-start;min-height:44px;display:inline-flex;align-items:center}
.mk-head{max-width:1200px;margin:0 auto;padding:48px 20px;box-sizing:border-box;display:flex;flex-direction:column;gap:18px}
/* Demos wait until they scroll into view (kuma.js adds and removes .wait). */
.wait,.wait *{animation-play-state:paused !important}

/* ── Landing (Main.dc.html) */
.hm-hero{background:var(--sun);color:var(--on-sun);border-top:2px solid var(--outline);border-bottom:2px solid var(--outline)}
.hm-hero-in{max-width:1200px;margin:0 auto;padding:64px 20px 72px;box-sizing:border-box;display:flex;flex-wrap:wrap;align-items:center;gap:48px}
.hm-copy{flex:1 1 460px;min-width:0;display:flex;flex-direction:column;gap:22px}
.hm-eye{font-size:16px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
.hm-h1{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(44px,6vw,76px);line-height:.98;letter-spacing:-.02em;text-wrap:balance}
.hm-sticker{align-self:flex-start;background:var(--surface);color:var(--ink);border:2px solid var(--outline);border-radius:999px;box-shadow:var(--shadow-sticker);padding:10px 20px;font-family:var(--font-display);font-weight:800;font-size:24px;transform:rotate(-2deg)}
.hm-lead{margin:0;font-size:20px;font-weight:600;line-height:1.45;max-width:30ch}
.hm-ctas{display:flex;flex-wrap:wrap;gap:14px;align-items:center}
.hm-kuma{flex:1 1 340px;min-width:0;display:flex;flex-direction:column;gap:6px;align-items:center}
.hm-kuma .tk-row{align-self:flex-start}
.hm-split{display:flex;flex-wrap:wrap;gap:48px;align-items:center}
.hm-split-txt{flex:1 1 420px;min-width:0;display:flex;flex-direction:column;gap:20px}
.hm-demo{flex:1 1 360px;min-width:0;display:flex;flex-direction:column;gap:22px;padding:28px;background:var(--mint);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.hm-demo-note{margin:0;font-size:18px;font-weight:700}
.hm-kuma-row{display:flex;flex-wrap:wrap;gap:40px;align-items:center}
.hm-kuma-row > img{flex:0 0 auto;width:150px;height:auto}
.hm-kuma-row > div{flex:1 1 480px;min-width:0;display:flex;flex-direction:column;gap:16px}
.hm-kuma-row .mk-h2{font-size:clamp(32px,4vw,46px);line-height:1.05}
.hm-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px}
.hm-plan{display:flex;flex-direction:column;gap:12px;padding:26px;background:var(--paper);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.hm-plan.plus{box-shadow:6px 6px 0 var(--terra)}
.hm-plan-name{font-family:var(--font-display);font-weight:800;font-size:24px}
.hm-plan-price{font-family:var(--font-display);font-weight:800;font-size:44px;line-height:1.05}
.hm-plan-price small{font-size:18px}
.hm-plan p{margin:0;font-size:17px;font-weight:600;line-height:1.45}
@media (max-width:480px){.hm-hero-in{padding:44px 20px 56px;gap:36px}.mk-wrap{padding:64px 20px}.hm-demo{padding:20px}}

/* Wiederholen: Gewusst five times climbs the real ladder (srs.go: 15 Min.,
   1 Tag, 6, 15, 38 Tage); Nochmals drops it back to 1 Min. 14 s loop. */
.lad-b{animation:14s linear infinite}.lad-b.gw{animation-name:gw}.lad-b.nm{animation-name:nm}
@keyframes gw{0%,100%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}0.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}0.643%,0.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}1.214%,1.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}3.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}3.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}14.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}14.643%,14.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}15.214%,15.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}17.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}17.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}28.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}28.643%,28.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}29.214%,29.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}31.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}31.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}42.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}42.643%,42.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}43.214%,43.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}45.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}45.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}57.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}57.643%,57.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}58.214%,58.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}60.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}60.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}}
@keyframes nm{0%,100%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}71.143%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}71.643%,71.857%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}72.214%,72.929%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}74.5%{transform:none;box-shadow:0 5px 0 var(--outline), 0 0 0 26px rgba(244,195,74,0)}74.786%{box-shadow:0 5px 0 var(--outline), 0 0 0 0 rgba(244,195,74,0)}}
@keyframes c1{0%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}2%{background:var(--moss);color:var(--on-moss);transform:scale(1.35) rotate(-5deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}3.929%,72.214%{background:var(--moss);color:var(--on-moss);transform:none;opacity:1;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73%{background:var(--moss);color:var(--on-moss);transform:scale(.6) rotate(8deg);opacity:.3}73.857%,100%{background:var(--paper);color:var(--ink-muted);transform:none;opacity:1}}
@keyframes c2{0%,15.214%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}16%{background:var(--moss);color:var(--on-moss);transform:scale(1.35) rotate(-5deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}17.929%,72.214%{background:var(--moss);color:var(--on-moss);transform:none;opacity:1;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73%{background:var(--moss);color:var(--on-moss);transform:scale(.6) rotate(8deg);opacity:.3}73.857%,100%{background:var(--paper);color:var(--ink-muted);transform:none;opacity:1}}
@keyframes c3{0%,29.214%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}30%{background:var(--moss);color:var(--on-moss);transform:scale(1.35) rotate(-5deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}31.929%,72.214%{background:var(--moss);color:var(--on-moss);transform:none;opacity:1;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73%{background:var(--moss);color:var(--on-moss);transform:scale(.6) rotate(8deg);opacity:.3}73.857%,100%{background:var(--paper);color:var(--ink-muted);transform:none;opacity:1}}
@keyframes c4{0%,43.214%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}44%{background:var(--moss);color:var(--on-moss);transform:scale(1.35) rotate(-5deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}45.929%,72.214%{background:var(--moss);color:var(--on-moss);transform:none;opacity:1;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73%{background:var(--moss);color:var(--on-moss);transform:scale(.6) rotate(8deg);opacity:.3}73.857%,100%{background:var(--paper);color:var(--ink-muted);transform:none;opacity:1}}
@keyframes c5{0%,58.214%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}59%{background:var(--moss);color:var(--on-moss);transform:scale(1.35) rotate(-5deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}60.929%,72.214%{background:var(--moss);color:var(--on-moss);transform:none;opacity:1;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73%{background:var(--moss);color:var(--on-moss);transform:scale(.6) rotate(8deg);opacity:.3}73.857%,100%{background:var(--paper);color:var(--ink-muted);transform:none;opacity:1}}
@keyframes c0{0%,73%{background:var(--paper);color:var(--ink-muted);transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}73.786%{background:var(--terra);color:var(--on-terra);transform:scale(1.5) rotate(7deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}76.143%,100%{background:var(--terra);color:var(--on-terra);transform:none}}
@keyframes shake{0%,72.214%,74.786%,100%{transform:none}72.643%{transform:translateX(-10px)}73.286%{transform:translateX(9px)}73.929%{transform:translateX(-5px)}74.429%{transform:translateX(3px)}}
.lad-pair{gap:16px}
.lad-pair > div{display:flex;flex-direction:column;gap:8px}
.lad-pair > div > span:last-child{font-size:17px;font-weight:700;text-align:center}
.lad{display:flex;flex-direction:column;gap:10px;padding:16px;background:var(--surface);border:2px solid var(--outline);border-radius:18px}
.lad-l{font-size:16px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}
.lad-row{display:flex;flex-wrap:wrap;gap:10px;animation:shake 14s linear infinite}
.lad-c{display:inline-flex;align-items:center;min-height:40px;padding:0 12px;border-radius:999px;border:2px solid var(--outline);background:var(--paper);color:var(--ink-muted);font-size:16px;font-weight:800;white-space:nowrap;animation:14s linear infinite}
.lad-c.c0{animation-name:c0}.lad-c.c1{animation-name:c1}.lad-c.c2{animation-name:c2}.lad-c.c3{animation-name:c3}.lad-c.c4{animation-name:c4}.lad-c.c5{animation-name:c5}.lad-c.c1{background:var(--moss);color:var(--on-moss)}

/* ── Funktionen (Features.dc.html) */
.fx{border-top:2px solid var(--outline)}
.fx.alt{background:var(--surface)}
.fx.mint{background:var(--mint)}
.fx-in{max-width:1200px;margin:0 auto;padding:72px 20px;box-sizing:border-box;display:flex;flex-wrap:wrap;gap:40px 56px;align-items:center}
.fx.flip .fx-in{flex-direction:row-reverse}
.fx-in.stack{flex-direction:column;align-items:stretch}
.fx-txt{flex:1 1 360px;min-width:0;display:flex;flex-direction:column;gap:16px}
.fx-demo{flex:1 1 460px;min-width:0}
.fx-eye{font-size:16px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-muted)}
.fx-eye .plus{margin-left:8px;padding:3px 10px;border:2px solid var(--outline);border-radius:999px;background:var(--sun);color:var(--on-sun);letter-spacing:.06em}
.fx h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(32px,4vw,48px);line-height:1.04;text-wrap:balance}
.fx-txt p,.fx-in > p{margin:0;font-size:19px;font-weight:600;line-height:1.5;max-width:44ch}
.fx-chips{display:flex;flex-wrap:wrap;gap:10px}
.fx-panel{display:flex;flex-direction:column;gap:16px;padding:26px;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.fx.alt .fx-panel{background:var(--paper)}
.fx-panel.tall{min-height:400px}
.hp{border-top:2px solid var(--outline);background:var(--surface-2)}
.hp-in{max-width:1200px;margin:0 auto;padding:44px 20px;box-sizing:border-box;display:flex;flex-wrap:wrap;align-items:center;gap:28px 56px}
.hp-txt{flex:1 1 340px;min-width:0;display:flex;flex-direction:column;gap:10px}
.hp-tag{align-self:flex-start;padding:5px 12px;border:2px solid var(--outline);border-radius:999px;background:var(--surface);font-size:16px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.hp-h{margin:0;font-family:var(--font-display);font-weight:800;font-size:30px;line-height:1.08}
.hp-p{margin:0;font-size:18px;font-weight:600;line-height:1.5;max-width:42ch}
.hp-vis{flex:1 1 420px;min-width:0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:14px}
.hp-stack{display:flex;flex-direction:column;gap:10px}
.mc{display:flex;flex-direction:column;justify-content:center;gap:6px;min-height:92px;min-width:150px;padding:14px 18px;box-sizing:border-box;background:#fff;color:#1e1a16;border:2px solid var(--outline);border-radius:16px;box-shadow:4px 4px 0 var(--outline);font-weight:800;font-size:17px}
.mc small{font-size:14px;font-weight:700;color:#5f665b}
.mc.narrow{min-width:110px}
.mc.mint{background:var(--mint);color:var(--ink)}
.mc.mint small{color:var(--ink)}
.mc.gone{opacity:.6;border-style:dashed}
.mc.tilt{transform:rotate(-3deg)}.mc.tilt2{transform:rotate(2.5deg)}
.mpill{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;box-sizing:border-box;border:2px solid var(--outline);border-radius:999px;background:var(--surface);box-shadow:var(--shadow-sticker);font-size:16px;font-weight:800}
.hp-stack .mpill .ki{align-self:center}
.mpill.go{background:var(--moss);color:var(--on-moss)}
.mflag{align-self:flex-start;padding:3px 10px;border-radius:999px;background:#f8ece7;border:2px solid #b4533a;color:#1e1a16;font-size:13px;font-weight:800}
.marrow{font-family:var(--font-display);font-size:34px;font-weight:800}
.ki{display:inline-flex;align-items:center;margin-left:8px;padding:3px 10px;border:2px solid var(--outline);border-radius:999px;background:var(--ink);color:var(--on-ink);font-size:16px;font-weight:800;letter-spacing:.08em}
.ty{display:flex;align-items:center;min-height:56px;padding:0 16px;box-sizing:border-box;border:2px solid var(--outline);border-radius:18px;background:var(--paper);font-size:18px;font-weight:600;overflow:hidden}
.ty.own{flex:1 1 240px;max-width:300px;background:var(--surface)}
.ty-t{display:inline-block;overflow:hidden;white-space:nowrap;max-width:0;vertical-align:middle;animation:ty 8s steps(40,end) infinite}
.ty-c{display:inline-block;width:2px;height:24px;margin-left:2px;background:var(--ink);animation:blink .5s step-end infinite}
@keyframes ty{0%,4%{max-width:0}34%,96%{max-width:100%}100%{max-width:0}}
@keyframes blink{50%{opacity:0}}
.sx-b{animation:sxb 8s linear infinite}
@keyframes sxb{0%,37%,100%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 0 rgba(244,195,74,0)}38.2%,39.6%{transform:translateY(5px) scale(.94);box-shadow:0 0 0 var(--outline),0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}40.4%,41.6%{transform:translateY(5px) scale(.94);box-shadow:0 0 0 var(--outline),0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}44.5%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 26px rgba(244,195,74,0)}}
.sx-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.sx-card{display:flex;align-items:center;justify-content:center;min-height:84px;padding:10px;text-align:center;background:#fff;color:#1e1a16;border:2px solid var(--outline);border-radius:14px;box-shadow:var(--shadow-sticker);font-size:15px;font-weight:800;opacity:0;animation:8s linear infinite;overflow-wrap:anywhere}
.sx-card.k1{animation-name:k1}.sx-card.k2{animation-name:k2}.sx-card.k3{animation-name:k3}
@keyframes k1{0%,43%{opacity:0;transform:translateY(24px) scale(.6) rotate(-6deg);animation-timing-function:cubic-bezier(.2,.9,.25,1)}44.5%{opacity:1;transform:scale(1.12) rotate(2deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}48%,94%{opacity:1;transform:none}97%,100%{opacity:0}}
@keyframes k2{0%,46%{opacity:0;transform:translateY(24px) scale(.6) rotate(5deg);animation-timing-function:cubic-bezier(.2,.9,.25,1)}47.5%{opacity:1;transform:scale(1.12) rotate(-2deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}51%,94%{opacity:1;transform:none}97%,100%{opacity:0}}
@keyframes k3{0%,49%{opacity:0;transform:translateY(24px) scale(.6) rotate(-4deg);animation-timing-function:cubic-bezier(.2,.9,.25,1)}50.5%{opacity:1;transform:scale(1.12) rotate(2deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}54%,94%{opacity:1;transform:none}97%,100%{opacity:0}}
.sx-n{font-size:16px;font-weight:800;opacity:0;animation:sxn 8s linear infinite}
@keyframes sxn{0%,52%{opacity:0}55%,94%{opacity:1}97%,100%{opacity:0}}
@keyframes m1{0%,5%{opacity:0;transform:translateY(30px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}6.167%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}8.5%,91.667%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}93.75%,100%{opacity:0;transform:none}}
@keyframes m2{0%,22.5%{opacity:0;transform:translateX(50px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}23.667%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}26%,91.667%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}93.75%,100%{opacity:0;transform:none}}
@keyframes m3{0%,40%{opacity:0;transform:translateY(30px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}41.167%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}43.5%,91.667%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}93.75%,100%{opacity:0;transform:none}}
@keyframes m4{0%,57.5%{opacity:0;transform:translateX(50px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}58.667%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}61%,91.667%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}93.75%,100%{opacity:0;transform:none}}
.chat-m{display:flex;flex-direction:column;align-items:flex-start;gap:4px;opacity:0;animation:12s linear infinite}
.chat-m.me{align-items:flex-end}
.chat-m .tk-bubble{max-width:340px}
.chat-m .gl{font-size:16px;font-weight:600;color:var(--ink-muted);padding:0 6px}
.chat-m.m1{animation-name:m1}.chat-m.m2{animation-name:m2}.chat-m.m3{animation-name:m3}.chat-m.m4{animation-name:m4}
/* #103: the line in the language you learn pops in a beat after your own (110 ms on a spring). */
.chat-m .tk-say{max-width:340px;transform-origin:100% 0;animation:m4s 12s linear infinite}
@keyframes m4s{0%,64%{opacity:0;transform:scale(.7);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}64.9%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.2,.9,.25,1)}65.6%,100%{opacity:1;transform:none}}
/* Druck: a printed card from html/print.html, flipping by itself. 6 s loop. */
.pd{display:flex;flex-direction:column;align-items:center;gap:16px}
.pd-stage{position:relative;width:min(calc(100% - 24px),400px);aspect-ratio:105/74;perspective:1400px;margin:14px 0 6px}
.pd-under{position:absolute;inset:0;transform:translate(16px,14px) rotate(3deg);background:#fff;border:2px dashed #5f665b;border-radius:6px}
.pd-flip{position:absolute;inset:0;transform-style:preserve-3d;animation:pdflip 6s linear infinite}
.pd-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;background:#fff;color:#111;border:2px dashed #5f665b;border-radius:6px;box-shadow:6px 6px 0 rgba(30,26,22,.18);display:flex;align-items:center;justify-content:center;padding:28px;box-sizing:border-box}
.pd-back{transform:rotateY(180deg)}
.pd-text{font-family:var(--font-body);font-weight:800;font-size:clamp(32px,8vw,44px);line-height:1.1;text-align:center}
.pd-foot{position:absolute;left:20px;right:20px;bottom:16px;display:flex;justify-content:space-between;align-items:center;font-size:13px;font-weight:700;color:#666}
.pd-mark{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-display);font-weight:800;color:#b4533a;font-size:15px}
.pd-mark img{width:16px;height:auto}
.pd-sides{display:flex;gap:8px}
.pd-s{min-height:36px;display:inline-flex;align-items:center;padding:0 14px;border:2px solid var(--outline);border-radius:999px;font-size:15px;font-weight:800;background:var(--paper);color:var(--ink-muted);animation:6s linear infinite}
.pd-s1{animation-name:pds1;background:var(--ink);color:var(--on-ink)}.pd-s2{animation-name:pds2}
@keyframes pdflip{0%,43.3%{transform:rotateY(0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}46.3%{transform:rotateY(196deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}49%,93.3%{transform:rotateY(180deg);animation-timing-function:cubic-bezier(.2,.9,.25,1)}96.3%{transform:rotateY(-16deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}99%,100%{transform:rotateY(0)}}
@keyframes pds1{0%,44.5%,95.5%,100%{background:var(--ink);color:var(--on-ink)}45%,95%{background:var(--paper);color:var(--ink-muted)}}
@keyframes pds2{0%,44.5%,95.5%,100%{background:var(--paper);color:var(--ink-muted)}45%,95%{background:var(--ink);color:var(--on-ink)}}
/* Stimme: the speaker is pressed, waves play, the sentence lights up. 4 s. */
.vx{display:flex;flex-direction:column;align-items:center;gap:18px;padding:30px 26px}
.vx-card{display:flex;align-items:center;gap:18px;padding:20px 24px;background:#fff;color:#1e1a16;border:2px solid var(--outline);border-radius:22px;box-shadow:6px 6px 0 var(--outline)}
.vx-w{font-family:var(--font-body);font-weight:800;font-size:40px;animation:vxw 4s linear infinite}
@keyframes vxw{0%,14%,70%,100%{color:#1e1a16}17%,66%{color:#12705a}}
.vx-b{flex:none;display:grid;place-items:center;width:64px;height:64px;border-radius:50%;background:var(--terra);border:2px solid var(--outline);animation:vxb 4s linear infinite}
.vx-b svg{width:28px;height:28px;fill:none;stroke:var(--on-terra);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
@keyframes vxb{0%,8%,100%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 0 rgba(244,195,74,0)}10.2%,11.5%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}13%,15.5%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}22%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 26px rgba(244,195,74,0)}}
.vx-wave{display:flex;align-items:center;gap:6px;height:48px}
.vx-wave i{width:8px;height:48px;border-radius:4px;background:var(--moss);transform:scaleY(.15);animation:4s linear infinite}
.vx-wave i:nth-child(1){animation-name:w1}.vx-wave i:nth-child(2){animation-name:w2}.vx-wave i:nth-child(3){animation-name:w3}.vx-wave i:nth-child(4){animation-name:w2}.vx-wave i:nth-child(5){animation-name:w1}
@keyframes w1{0%,15%,68%,100%{transform:scaleY(.15)}20%,35%,50%{transform:scaleY(.7)}27%,42%,58%{transform:scaleY(.3)}}
@keyframes w2{0%,15%,68%,100%{transform:scaleY(.15)}22%,37%,52%{transform:scaleY(1)}29%,44%,60%{transform:scaleY(.4)}}
@keyframes w3{0%,15%,68%,100%{transform:scaleY(.15)}18%,33%,48%,62%{transform:scaleY(.55)}25%,40%,55%{transform:scaleY(.9)}}
@media (max-width:480px){.fx-in{padding:56px 20px}.fx-panel{padding:20px}.sx-cards{grid-template-columns:1fr}.vx-w{font-size:32px}.hp-in{padding:40px 20px}}

/* ── Preise (Pricing.dc.html). Calm: no demo, no switch. */
.pr-plans{max-width:1200px;margin:0 auto;padding:8px 20px 48px;box-sizing:border-box}
.pr-plan{display:flex;flex-direction:column;gap:14px;padding:30px;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker);min-width:0}
.pr-plan.plus{border-width:3px;box-shadow:10px 10px 0 var(--terra)}
.pr-name{font-family:var(--font-display);font-weight:800;font-size:26px}
.pr-top{display:flex;justify-content:space-between;align-items:center;gap:10px}
.pr-rec{font-size:13px;font-weight:800;padding:6px 12px;border:2px solid var(--outline);border-radius:999px;background:var(--sun);color:var(--on-sun)}
.pr-price{font-family:var(--font-display);font-weight:800;font-size:clamp(44px,6vw,72px);line-height:1;letter-spacing:-.02em;display:flex;flex-wrap:wrap;align-items:baseline;column-gap:10px}
.pr-price > span{white-space:nowrap}
.pr-price small{font-size:20px;letter-spacing:0}
.pr-cad{font-size:16px;font-weight:700;color:var(--ink-muted)}
.pr-list{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px;font-size:17px;font-weight:600;line-height:1.4}
.pr-list li{position:relative;padding-left:22px}
.pr-list li::before{content:"";position:absolute;left:2px;top:.5em;width:9px;height:9px;border-radius:50%;background:var(--moss)}
.pr-list li.lead{padding-left:0;font-weight:800}
.pr-list li.lead::before{display:none}
.pr-plan .tk-button{margin-top:auto}
.pr-app{margin:auto 0 0;font-size:16px;font-weight:700}
.yr-hl{display:inline-block;padding:0 5px;border-radius:7px;color:var(--on-sun);font-weight:800;background-image:linear-gradient(var(--sun),var(--sun));background-repeat:no-repeat;background-position:0 88%;background-size:0% 45%;transform-origin:30% 60%;animation:yr-draw 1000ms 250ms both}
[data-theme="dark"] .yr-hl{background-color:var(--sun)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .yr-hl{background-color:var(--sun)}}
@keyframes yr-draw{0%{background-size:0% 45%;transform:none;box-shadow:0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}22%{background-size:100% 45%;transform:none;box-shadow:0 0 0 0 rgba(244,195,74,0);animation-timing-function:cubic-bezier(.2,.9,.25,1)}33%{background-size:100% 100%;transform:scale(1.35) rotate(-5deg);box-shadow:0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}48%{background-size:100% 100%;transform:scale(.94) rotate(2deg);box-shadow:0 0 0 20px rgba(244,195,74,.4)}62%,100%{background-size:100% 100%;transform:none;box-shadow:0 0 0 30px rgba(244,195,74,0)}}
.pr-goal{max-width:1200px;margin:0 auto;padding:0 20px 56px;box-sizing:border-box}
.pr-table-sec{max-width:1200px;margin:0 auto;padding:0 20px 80px;box-sizing:border-box;display:flex;flex-direction:column;gap:16px}
.pr-h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:32px}
.pr-tab-wrap{overflow-x:auto;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.pr-tab{width:100%;min-width:560px;border-collapse:collapse;font-size:17px}
.pr-tab th{padding:16px 20px;text-align:left;font-size:16px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}
.pr-tab td{padding:14px 20px}
.pr-tab td:first-child{font-weight:700}
.pr-tab tbody tr{border-top:2px solid var(--surface-2)}
.pr-tab td:nth-child(3),.pr-tab th:nth-child(3){background:var(--terra-soft);color:var(--ink);font-weight:800}
.pr-note{margin:0;font-size:16px;font-weight:600;color:var(--ink-muted);max-width:70ch;line-height:1.45}
.qa{display:flex;flex-direction:column;gap:12px;padding:26px 28px;background:var(--paper);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.qa h3{margin:0;font-family:var(--font-display);font-weight:800;font-size:24px;line-height:1.15}
.qa p{margin:0;font-size:18px;font-weight:600;line-height:1.55}
@media (max-width:480px){.pr-plan{padding:24px 20px}.pr-tab-wrap{margin:0 -4px}}

/* ── Login and sign-up (Login.dc.html, Join.dc.html and their states).
   Words left, the form card right; on a phone the form comes first, because
   the phone app opens straight onto the login. */
.lg-main{max-width:1200px;margin:0 auto;padding:32px 20px 72px;box-sizing:border-box;display:flex;flex-wrap:wrap;gap:48px;align-items:flex-start}
.lg-intro{flex:1 1 360px;min-width:0;display:flex;flex-direction:column;gap:16px;padding-top:24px}
.lg-intro .mk-h2{font-size:clamp(32px,4.5vw,52px)}
.lg-intro p{margin:0;font-size:19px;font-weight:600;line-height:1.5;max-width:34ch}
.lg-card{flex:1 1 420px;min-width:0;max-width:520px;display:flex;flex-direction:column;gap:18px;padding:30px;box-sizing:border-box;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-sticker)}
.lg-card form{display:flex;flex-direction:column;gap:18px;margin:0}
@media (max-width:720px){.lg-main{gap:32px;padding-top:12px}.lg-intro{order:2;padding-top:0}.lg-card{padding:24px 20px}}
.lg-h1{margin:0;font-family:var(--font-display);font-weight:800;font-size:36px;line-height:1.05}
.lg-or{display:flex;align-items:center;gap:12px;font-size:15px;font-weight:800;color:var(--ink-muted)}
.lg-or span{flex:1;height:2px;background:var(--surface-2)}
/* The phone app's own Google button (google_native.go): once shown, its box
   lays out like the website's button and «oder» line. */
.lg-native:not([hidden]){display:contents}
.lg-native-err{margin:0;color:var(--terra);font-weight:700}
.lg-field{display:flex;flex-direction:column;gap:8px;font-size:16px;font-weight:800}
.lg-row{display:flex;align-items:center;justify-content:space-between;gap:12px}
.lg-row a{font-size:16px;font-weight:700;min-height:44px;display:inline-flex;align-items:center}
.lg-input{min-height:52px;padding:0 16px;border:2px solid var(--outline);border-radius:var(--radius-tile);background:var(--paper);color:var(--ink);font-size:18px;box-sizing:border-box;width:100%}
.lg-input.lg-bad{border-width:3px;border-color:var(--terra)}
.lg-hint{font-size:16px;font-weight:600;color:var(--ink)}
.lg-text{margin:0;font-size:18px;font-weight:600;line-height:1.45}
.lg-small{margin:0;font-size:16px;font-weight:600}
/* The one message slot (Error or Notice). Terra-soft when something went
   wrong, surface-2 when it is good news. */
.lg-msg{margin:0;padding:14px 16px;border:2px solid var(--outline);border-radius:var(--radius-tile);background:var(--terra-soft);color:var(--ink);font-size:17px;font-weight:600;line-height:1.4}
.lg-msg.lg-ok{background:var(--surface-2)}
.lg-msg b{display:block;font-weight:800}
/* Sign-in buttons (lg-idp): Google and Apple, one size (memo C1). */
.kuma a.lg-idp,.kuma button.lg-idp{display:flex;align-items:center;justify-content:center;gap:10px;text-decoration:none;font-size:19px}
/* The other door: never a small link. */
.lg-door{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px;padding:12px 12px 12px 18px;background:var(--surface-2);border:2px solid var(--outline);border-radius:var(--radius-tile)}
.lg-door p{margin:0;font-size:19px;font-weight:800;line-height:1.25}
.kuma .lg-door a{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:52px;padding:0 22px;box-sizing:border-box;border:2px solid var(--outline);border-radius:var(--radius-pill);background:var(--surface);box-shadow:var(--shadow-sticker);font-family:var(--font-display);font-size:20px;font-weight:800;text-decoration:none;color:var(--ink)}
.kuma .lg-door a:hover{color:var(--ink);background:var(--paper)}
.kuma .lg-door a:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:var(--radius-pill)}
@media (max-width:420px){.lg-door{padding:14px}.kuma .lg-door a{flex:1 1 100%}}
.cf-turnstile{min-height:65px}

/* Under reduced motion every demo shows its end state and stays still. */
@media (prefers-reduced-motion: reduce){
  .tk-button{transition:none}
  .tk-pressed,.ap-tab.tk-pressed .ic{animation:none!important}
  .tk-card[aria-pressed="true"] .tk-face{animation:none}
  .nv *{transition:none!important}
  .lad-b,.lad-c,.lad-row{animation:none}
  .chat-m,.chat-m .tk-say{animation:none;opacity:1}
  .pd-flip,.pd-s{animation:none}
  .ty-t{animation:none;max-width:100%}.ty-c,.sx-b,.vx-b,.vx-w,.vx-wave i{animation:none}.sx-card,.sx-n{animation:none;opacity:1}
  .yr-hl{animation:none;background-size:100% 100%}
}

/* Sticker flags on every language pill (open point 35, Olivier 2026-10-11:
   "words unchanged"). Drawn by flags.go; on the pill's top edge, top-right
   corner, never over the words. .sm for switches and pills under 56 px. */
.ob-flags{position:absolute;top:-10px;right:18px;display:flex;gap:5px;pointer-events:none}
.ob-flag{display:block;height:22px;width:auto;filter:drop-shadow(2px 2px 0 var(--outline))}
.ob-flags.sm{top:-9px;right:6px;gap:3px}
.ob-flags.sm .ob-flag{height:16px}
.nv-lang a,.tk-chips .tk-chip{position:relative}
.tk-chips .tk-chip:has(.ob-flags){padding-top:20px}
.nv-lang a:focus-visible{z-index:1}
.nv-lang-wide{margin-top:12px}
.ft-col .nv-lang{margin-top:18px}

/* Über Talkuma (design-kuma, 2026-10-11). Olivier's note, his story first:
   the gas station plays as a chat, then who he is, then the short answers. */
.ab-in{max-width:1200px;margin:0 auto;padding:72px 20px;box-sizing:border-box;display:flex;flex-wrap:wrap;gap:40px 56px;align-items:center}
.ab-flip .ab-in{flex-direction:row-reverse}
.ab-sec{border-top:2px solid var(--outline)}
.ab-alt{background:var(--surface)}
.ab-txt{flex:1 1 360px;min-width:0;display:flex;flex-direction:column;gap:16px}
.ab-vis{flex:1 1 440px;min-width:0}
.ab-eye{font-size:16px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-muted)}
.ab-h1{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(40px,5.5vw,64px);line-height:1;text-wrap:balance}
.ab-h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(32px,4vw,48px);line-height:1.04;text-wrap:balance}
.ab-txt p{margin:0;font-size:19px;font-weight:600;line-height:1.5;max-width:44ch}
.ab-lol{font-family:var(--font-display);font-weight:800;font-size:28px;letter-spacing:.02em}
.ab-panel{display:flex;flex-direction:column;gap:14px;padding:26px;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:3px 3px 0 var(--outline);box-sizing:border-box}
.ab-alt .ab-panel{background:var(--paper)}
.ab-lbl{font-size:16px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}

/* Die Tankstelle: plays by itself when it scrolls into view. Six lines pop in
   (in within ~100 ms, out on a spring), the last one shakes with the yellow
   ring: "Non capisco…". 14 s loop; only opacity and transform move. */
.gs-m{display:flex;flex-direction:column;align-items:flex-start;gap:4px;opacity:0;animation:14s linear infinite}
.gs-m.me{align-items:flex-end}
.gs-m .tk-bubble,.gs-m .tk-me{max-width:100%}
.gs-m .gl{font-size:16px;font-weight:600;color:var(--ink);padding:0 6px}
.gs-who{font-size:14px;font-weight:800;color:var(--ink);padding:0 6px}
.gs-blur{display:flex;flex-direction:column;gap:7px;padding:4px 0;width:200px;max-width:100%}
.gs-blur i{display:block;height:9px;border-radius:9px;background:var(--surface-2);border:2px solid var(--outline)}
.gs-blur i:nth-child(2){width:78%}.gs-blur i:nth-child(3){width:56%}
.gs-m.g1{animation-name:g1}.gs-m.g2{animation-name:g2}.gs-m.g3{animation-name:g3}.gs-m.g4{animation-name:g4}.gs-m.g5{animation-name:g5}.gs-m.g6{animation-name:g6}
.gs-m.g6 .tk-me{animation:gs-shake 14s linear infinite}
@keyframes g1{0%,3%{opacity:0;transform:translateY(30px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}3.75%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}4.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes g2{0%,12%{opacity:0;transform:translateX(50px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}12.75%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}13.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes g3{0%,21%{opacity:0;transform:translateX(50px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}21.75%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}22.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes g4{0%,30%{opacity:0;transform:translateY(30px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}30.75%{opacity:1;transform:scale(1.08);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}31.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes g5{0%,44%{opacity:0;transform:translateY(30px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}44.75%{opacity:1;transform:scale(1.12) rotate(-2deg);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}45.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes g6{0%,58%{opacity:0;transform:translateX(50px) scale(.7);animation-timing-function:cubic-bezier(.2,.9,.25,1)}58.75%{opacity:1;transform:scale(1.12);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}59.75%,93%{opacity:1;transform:none;animation-timing-function:cubic-bezier(.2,.9,.25,1)}95%,100%{opacity:0;transform:none}}
@keyframes gs-shake{0%,61%,65%,100%{transform:none;box-shadow:0 0 0 0 rgba(244,195,74,0)}61.6%{transform:translateX(-10px);box-shadow:0 0 0 12px rgba(244,195,74,.95)}62.4%{transform:translateX(9px);box-shadow:0 0 0 16px rgba(244,195,74,.7)}63.2%{transform:translateX(-5px);box-shadow:0 0 0 22px rgba(244,195,74,.35)}64%{transform:translateX(3px);box-shadow:0 0 0 28px rgba(244,195,74,0)}}

@media (prefers-reduced-motion: reduce){.ab-chat .gs-m,.ab-chat .gs-m.g6 .tk-me{animation:none;opacity:1}}

/* Before → after: the moment, then the practice. Built from bubble, card and pill. */
.ab-ba{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:16px 18px}
.ab-arrow{font-family:var(--font-display);font-size:34px;font-weight:800}
.ab-mc{display:flex;flex-direction:column;gap:10px;min-width:0;max-width:300px;padding:18px 20px;background:var(--surface);border:2px solid var(--outline);border-radius:18px;box-shadow:4px 4px 0 var(--outline);font-size:17px;font-weight:700;line-height:1.35;box-sizing:border-box}
.ab-mc.tilt{transform:rotate(-2.5deg)}
.ab-mc.mint{background:var(--mint);transform:rotate(2deg)}
.ab-mc small{font-size:15px;font-weight:700;color:var(--ink)}
.ki{display:inline-flex;align-items:center;align-self:flex-start;padding:3px 10px;border:2px solid var(--outline);border-radius:999px;background:var(--ink);color:var(--on-ink);font-size:16px;font-weight:800;letter-spacing:.08em}

/* Wer ich bin: the age as a big sticker, the languages as pills with flags. */
.ab-age{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;width:260px;max-width:100%;padding:26px 24px;box-sizing:border-box;margin:0 auto;text-align:center;background:var(--surface);color:var(--ink);border:3px solid var(--outline);border-radius:var(--radius-card);box-shadow:var(--shadow-card);transform:rotate(-3deg)}
.ab-age b{font-family:var(--font-display);font-weight:800;font-size:110px;line-height:.9}
.ab-age span{font-size:17px;font-weight:700;line-height:1.35}
.ab-who{display:flex;flex-direction:column;gap:30px;align-items:center}
.lp-row{display:flex;flex-wrap:wrap;justify-content:center;gap:18px 16px}
.lp{position:relative;display:inline-flex;align-items:center;min-height:52px;padding:0 44px 0 20px;border:2px solid var(--outline);border-radius:999px;background:var(--surface);box-shadow:var(--shadow-sticker);font-size:18px;font-weight:800;white-space:nowrap}
.lp .ob-flags{right:10px}
.lp small{margin-left:8px;font-size:14px;font-weight:700;color:var(--ink)}

/* The one statement. */
.ab-band{border-top:2px solid var(--outline);background:var(--surface-2)}
.ab-band .in{max-width:1200px;margin:0 auto;padding:64px 20px;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}
.ab-band h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:clamp(34px,5vw,60px);line-height:1.02}
.ab-band p{margin:0;font-size:21px;font-weight:700;line-height:1.5}

/* Short answers: each its own card, like Preise. */
.tk-grid-3:has(>.qa){align-items:start}
.qa{display:flex;flex-direction:column;gap:12px;padding:26px 28px;background:var(--paper);border:2px solid var(--outline);border-radius:22px;box-shadow:3px 3px 0 var(--outline);min-width:0}
.qa h3{margin:0;font-family:var(--font-display);font-weight:800;font-size:24px;line-height:1.15}
.qa p{margin:0;font-size:18px;font-weight:600;line-height:1.55}
.qa .lp-row{justify-content:flex-start;margin-top:8px}
.qa .lp{font-family:var(--font-body)}

/* Die Methode: the two buttons the learner presses, standing still. */
.mb{display:flex;flex-direction:column;gap:18px}
.mb-say{margin:0;font-size:18px;font-weight:700;line-height:1.4;color:var(--ink)}
/* The two buttons press themselves (7 s loop): down in 70 ms, a slim beat, the
   yellow ring, back on a spring; Nochmals also shakes. Waits until in view. */
.mb-gw,.mb-nm{animation:7s linear infinite}.mb-gw{animation-name:mb-press}.mb-nm{animation-name:mb-press2}
@keyframes mb-press{0%,10%,100%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 0 rgba(244,195,74,0)}11%,11.6%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}12.6%,14.5%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}19%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 26px rgba(244,195,74,0)}}
@keyframes mb-press2{0%,55%,100%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 0 rgba(244,195,74,0)}56%,56.6%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 0 rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.2,.9,.25,1)}57.6%,59.5%{transform:translateY(5px) scale(.92);box-shadow:0 0 0 var(--outline),0 0 0 12px rgba(244,195,74,.95);animation-timing-function:cubic-bezier(.34,1.8,.5,1)}61%{transform:translateX(-9px);box-shadow:0 5px 0 var(--outline),0 0 0 20px rgba(244,195,74,.4)}62%{transform:translateX(8px)}63%{transform:translateX(-4px)}64%{transform:none;box-shadow:0 5px 0 var(--outline),0 0 0 26px rgba(244,195,74,0)}}
@media (prefers-reduced-motion: reduce){.mb-gw,.mb-nm{animation:none}}
.mb-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px}
.mb-row .tk-button{width:auto;min-width:170px;padding:0 24px;cursor:default}
.mb-row span{font-size:18px;font-weight:700}
.ab-src{margin:0;font-size:16px;font-weight:600;line-height:1.5;color:var(--ink)}
.ab-links{display:flex;flex-wrap:wrap;gap:0 22px}
.ab-links a{display:inline-flex;align-items:center;min-height:44px;font-size:17px;font-weight:700}
.ab-txt a:focus-visible,.ab-links a:focus-visible,.ab-end a:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

/* Signed by hand, then the one action. */
.ab-end{border-top:2px solid var(--outline)}
.ab-end .in{max-width:760px;margin:0 auto;padding:72px 20px 88px;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:22px;text-align:center}
.ab-sign{display:flex;align-items:center;gap:16px}
.ab-sign{padding:22px 30px;background:var(--paper);border:2px solid var(--outline);border-radius:22px;box-shadow:var(--shadow-card);transform:rotate(-1.5deg)}
.ab-sign b{display:block;font-family:var(--font-display);font-weight:800;font-size:52px;line-height:1;text-align:left}
.ab-sign span{display:block;font-size:18px;font-weight:700;text-align:left}
.ab-end p{margin:0;font-size:19px;font-weight:600;line-height:1.5}
.ab-end .tk-button{width:auto;padding:0 28px;text-decoration:none}

@media (max-width:700px){
  .ab-in{padding:48px 20px;gap:32px}
  .ab-age b{font-size:88px}
  .ab-band .in{padding:44px 20px}
  .ab-end .in{padding:56px 20px 64px}
  .mb-row .tk-button{flex:1 1 100%}
  .ab-ba{flex-direction:column}
  .ab-arrow{transform:rotate(90deg)}
}

/* Impressum (open point 7): one calm card. */
.im-card{display:flex;flex-direction:column;gap:18px;padding:30px;background:var(--surface);border:2px solid var(--outline);border-radius:22px;box-shadow:3px 3px 0 var(--outline);min-width:0}
.im-card h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:26px;line-height:1.1}
.im-dl{margin:0;display:flex;flex-direction:column;gap:16px}
.im-dl div{display:flex;flex-direction:column;gap:4px}
.im-dl dt{font-size:16px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}
.im-dl dd{margin:0;font-size:19px;font-weight:600;line-height:1.5;overflow-wrap:anywhere}
.im-dl a{display:inline-flex;align-items:center;min-height:44px}
.im-dl a:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
/* The board's inline styles, as classes. */
.ab-in.ab-first{padding-top:48px}
.ab-chat{min-height:520px}
.ab-stack{max-width:1200px;margin:0 auto;padding:72px 20px 88px;box-sizing:border-box;display:flex;flex-direction:column;gap:28px}
.mb-end{margin:0;font-size:18px;font-weight:700;line-height:1.45}
.im-head{max-width:1200px;margin:0 auto;padding:48px 20px 32px;box-sizing:border-box;display:flex;flex-direction:column;gap:16px}
.im-lead{margin:0;font-size:20px;font-weight:600;line-height:1.45;max-width:46ch}
.im-body{max-width:1200px;margin:0 auto;padding:8px 20px 72px;box-sizing:border-box}
.im-card{max-width:640px}
.im-more{max-width:1200px;margin:0 auto;padding:56px 20px 72px;box-sizing:border-box;display:flex;flex-direction:column;gap:18px}
.im-more h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:28px}

/* Greeting chips that speak (2026-10-11, Olivier: "pressing on the chip
   triggers the TTS. Need voice animation badge"). While the clip plays the
   chip wears a sun sticker on its top-left edge (the flags hold the right)
   with four ink bars jumping, fast like the demo motion. Reduced motion: the
   bars stand still at four heights, the badge still says "speaking". */
.gr-say{cursor:pointer;-webkit-tap-highlight-color:transparent}
.gr-wave{display:none;position:absolute;top:-13px;left:16px;align-items:center;gap:3px;height:26px;padding:0 8px;box-sizing:border-box;background:var(--sun);border:var(--stroke-2) solid var(--outline);border-radius:var(--radius-pill);box-shadow:2px 2px 0 var(--outline);pointer-events:none}
.gr-say.gr-on .gr-wave{display:inline-flex}
.gr-wave i{display:block;width:3px;height:14px;border-radius:2px;background:var(--on-sun);transform-origin:50% 50%;animation:gr-bar 280ms ease-in-out infinite}
/* Four lengths that never line up, so the bars read as a voice, not a pulse. */
.gr-wave i:nth-child(2){animation-duration:340ms;animation-delay:-90ms}
.gr-wave i:nth-child(3){animation-duration:250ms;animation-delay:-170ms}
.gr-wave i:nth-child(4){animation-duration:310ms;animation-delay:-40ms}
@keyframes gr-bar{0%,100%{transform:scaleY(.25)}50%{transform:scaleY(1)}}
@media (prefers-reduced-motion: reduce){
  .gr-wave i{animation:none}
  .gr-wave i:nth-child(1),.gr-wave i:nth-child(4){transform:scaleY(.5)}
  .gr-wave i:nth-child(3){transform:scaleY(.75)}
}
/* Bedingungen (open point 8): one calm column, a line between sections,
   one marker per heading. */
.tm-date{margin:0;font-size:16px;font-weight:700}
.tm-body{max-width:1200px;margin:0 auto;padding:0 20px 72px;box-sizing:border-box}
.tm-sec{max-width:720px;display:flex;flex-direction:column;gap:12px;padding:32px 0;border-top:2px solid var(--outline)}
.tm-sec h2{margin:0;font-family:var(--font-display);font-weight:800;font-size:26px;line-height:1.15}
.tm-sec p{margin:0;font-size:18px;font-weight:600;line-height:1.55;overflow-wrap:anywhere}
.tm-sec p a{font-weight:700}
/* Kontakt: the Impressum card, two or three of them. */
.ct-cards{display:flex;flex-wrap:wrap;gap:24px;align-items:flex-start}
.ct-cards .im-card{flex:1 1 280px;max-width:400px}
.ct-mail{margin:0;font-size:20px;font-weight:700;overflow-wrap:anywhere}
.ct-mail a{display:inline-flex;align-items:center;min-height:44px}
.ct-p{margin:0;font-size:19px;font-weight:600;line-height:1.5}
.ct-btn{width:auto;align-self:flex-start;padding:0 24px;text-decoration:none}
/* Preise: the terms, next to the Plus button (website only). */
.pr-terms{display:inline-flex;align-items:center;justify-content:center;min-height:44px;font-size:17px;font-weight:700}

/* ── The Android release page (/android, html/android.html; mockup
   design/release/mockup.html). The tk-* pieces are design/components/bundle.css's,
   copied as they are; the rl-* layout is the mockup's page style. */
/* Note: one thing the reader must know before acting (here: Plus is bought
   on the website). Flat, no outline: it is text, not a target. surface-2
   ground, a sun bar on the leading edge, the key line bold in ink. */
.tk-note { box-sizing: border-box; display: flex; flex-direction: column; gap: var(--space-2);
  padding: 20px 22px 20px 26px; border-radius: var(--radius-tile); background: var(--surface-2); color: var(--ink);
  box-shadow: inset 8px 0 0 var(--sun); font-size: 18px; font-weight: 500; line-height: 1.45; }
.tk-note b { font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1.15; }
.tk-note p { margin: 0; }
.tk-note p b { font-family: var(--font-body); font-size: inherit; font-weight: 800; }
.tk-note a { align-self: flex-start; display: inline-flex; align-items: center; min-height: 44px;
  color: var(--ink); font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
/* Download card: the version, the one button, the file and its check code.
   Same frame as the price page's plan card (pr-plan). */
.tk-dl { box-sizing: border-box; display: flex; flex-direction: column; gap: var(--space-3); min-width: 0;
  padding: 28px; background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: 22px; box-shadow: var(--shadow-sticker); }
.tk-dl-ver { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 34px; line-height: 1; }
.tk-dl-meta { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.4; color: var(--ink-muted); overflow-wrap: anywhere; }
/* Check code (SHA-256): skippable, so ink-muted; groups of four so a person
   can compare by eye; one quiet copy button, 48 px. */
.tk-hash { display: flex; flex-direction: column; gap: 8px; padding-top: var(--space-3); border-top: var(--stroke-2) solid var(--surface-2); }
.tk-hash p { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.4; color: var(--ink-muted); }
.tk-hash p b { color: var(--ink); }
.tk-hash code { display: block; padding: 12px 14px; border-radius: 14px; background: var(--surface-2); color: var(--ink-muted);
  font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.5; letter-spacing: .04em; word-spacing: .2em; overflow-wrap: anywhere; text-wrap: balance; }
.tk-button.tk-s { min-height: 48px; width: auto; align-self: flex-start; padding: 0 22px; font-size: 18px; box-shadow: var(--shadow-sticker); --tk-rest: var(--shadow-sticker); }
/* Steps: WHAT, then HOW, numbered. Not tappable, so no outline on the row;
   the number is a sun disc like the choice card's tk-num. */
.tk-steplist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 22px; }
.tk-steplist li { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 16px; align-items: start; }
.tk-steplist .tk-num { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center;
  background: var(--sun); color: var(--on-sun); border: var(--stroke-2) solid var(--outline);
  font-family: var(--font-display); font-weight: 800; font-size: 20px; }
.tk-steplist b { display: block; margin-top: 8px; font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1.15; }
.tk-steplist p { margin: 6px 0 0; font-size: 18px; font-weight: 500; line-height: 1.45; }
.tk-steplist small { display: block; margin-top: 8px; font-size: 16px; font-weight: 600; line-height: 1.45; color: var(--ink-muted); }
.tk-steplist small a { display: flex; width: fit-content; align-items: center; min-height: 44px; color: var(--ink); font-weight: 800; }
.rl { max-width: 1200px; margin: 0 auto; padding: 32px 20px 72px; box-sizing: border-box;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px;
  grid-template-areas: "head" "note" "dl" "steps" "facts"; }
.rl-head { grid-area: head; display: flex; flex-direction: column; gap: 16px; }
.rl-note { grid-area: note; }
.rl-dl { grid-area: dl; display: flex; flex-direction: column; gap: 28px; }
.rl-steps { grid-area: steps; display: flex; flex-direction: column; gap: 24px; }
.rl-facts { grid-area: facts; }
.rl-play { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.45; max-width: 52ch; }
.rl-head .tk-s { margin-top: -4px; }
.rl .tk-dl-ver.rl-wait { font-size: 26px; line-height: 1.15; }
.rl-fact { display: flex; flex-direction: column; gap: 8px; }
.rl-fact h3 { margin: 0; font-family: var(--font-display); font-size: 24px; font-weight: 800; line-height: 1.15; }
.rl-fact p { margin: 0; font-size: 18px; font-weight: 500; line-height: 1.45; }
/* "Auf dem Handy öffnen": only on a computer, where the phone is the
   other device. The QR code keeps a white ground in dark too, so any
   camera reads it. */
.rl-phone { display: none; }
.rl-qr { flex: none; width: 132px; height: 132px; border-radius: 14px; overflow: hidden; border: var(--stroke-2) solid var(--outline); background: #fff; }
.rl-qr svg { display: block; width: 100%; height: 100%; }
.rl-phone h3 { margin: 0 0 6px; font-family: var(--font-display); font-size: 22px; font-weight: 800; }
.rl-phone p { margin: 0; font-size: 17px; font-weight: 500; line-height: 1.45; }
.rl-phone p + p { margin-top: 8px; }
.rl-phone .rl-url { display: block; margin-top: 6px; font-weight: 800; font-size: 18px; }
@media (min-width: 960px) {
  .rl { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: 64px; row-gap: 40px; padding-top: 56px;
    grid-template-areas: "head dl" "note dl" "steps dl" "facts facts"; }
  .rl-dl { position: sticky; top: 24px; align-self: start; }
  .rl-phone { display: flex; gap: 20px; align-items: center; }
}

/* tk-ask-bar: the consent question as a bar at the foot of the screen (Olivier, 2026-10-16: "the banner should be in the footer"; law-kuma Rev 5).
   It is the LAST block of the page and position:sticky, so it holds the bottom edge of the screen while the page scrolls above it, and
   at the end of the page it sits after the footer: the room it needs is real room (not padding I have to guess) and it can never cover
   the last link on the page, collapsed or open. No backdrop, no scroll lock, no inert, no aria-modal, no focus trap, nothing moves. */
.tk-ask-bar{--tk-ask-bottom:0px;--tk-ask-safe:env(safe-area-inset-bottom,0px);
  position:sticky;bottom:var(--tk-ask-bottom);margin-bottom:var(--tk-ask-bottom);z-index:15;box-sizing:border-box;width:100%;
  background:var(--sun);color:var(--ink);border-top:var(--stroke-2) solid var(--outline);
  padding:4px 12px calc(2px + var(--tk-ask-safe))}
/* small phones (360 x 640): law Rev 5 caps the collapsed bar at 40 % of the screen, so the type steps down one size here */
@media(max-width:374px),(max-height:700px){.tk-ask-p{font-size:14px}.tk-ask-h{font-size:15px}.tk-ask-top{font-size:14px}}
/* signed in, on the phone: the tab bar (80 px: 2 line + 8 + tabs + 10 or the safe area) is fixed at the very bottom; the bar docks right above it.
   Its margin-bottom is the tab bar's room, so the page's own 110 px of tab-bar room (.ap-main) is handed over to the bar: no double gap, nothing hidden at the end. */
body.app:has(> .ap-tabs) .tk-ask-bar{--tk-ask-bottom:calc(70px + max(10px,env(safe-area-inset-bottom,0px)));--tk-ask-safe:0px}
body.app:has(> .ap-tabs):has(> .tk-ask-bar) .ap-main{padding-bottom:24px}
/* a short screen (Bibliothek): the page fills the screen, so the bar still ends up at the bottom edge and not under a short page */
body.app:has(> .tk-ask-bar){display:flex;flex-direction:column}
body.app:has(> .tk-ask-bar) > .ap-main{flex:1 0 auto}
/* never on a form field or the keyboard (law Rev 5 C21 (5)): while a field has focus the bar is not drawn */
body:has(input:not(.tk-ask-x):focus, textarea:focus, select:focus) .tk-ask-bar{display:none}
/* "Später" (the x): hides the bar for this page view, is NOT an answer, sets nothing. Mockup: a checkbox drawn as the x. Build: a link ?later=1 or a button + one line of script. */
.tk-ask-bar:has(.tk-ask-x:checked){display:none}
/* the two grid rows: text, buttons; then the "Mehr dazu" drawer. Expanded, the bar is at most 60 % of the screen: text and buttons keep their place,
   the drawer scrolls inside (its summary stays at its top, so "Weniger" is always there). */
.tk-ask-in{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:4px;max-width:1160px;margin:0 auto;max-height:calc(60vh - 14px - var(--tk-ask-safe))}
.tk-ask-top{margin:0 0 4px;font-size:15px;font-weight:800;line-height:1.3}
.tk-ask-p{margin:0;font-family:var(--font-body);font-size:15px;font-weight:600;line-height:1.26}
.tk-ask-txt .tk-ask-p{display:inline}
.tk-ask-h{display:inline;margin:0 4px 0 0;font-family:var(--font-body);font-weight:800;font-size:16px;line-height:1.26}
.tk-ask-btns{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2);margin:0 0 2px}
.tk-ask-btns .tk-button{min-height:44px;padding:4px 6px;font-size:16px;box-shadow:var(--shadow-button)}
.tk-ask-det{grid-row:3;grid-column:1;min-width:0;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.tk-ask-det summary{position:sticky;top:0;z-index:1;background:var(--surface);display:flex;align-items:center;justify-content:flex-start;min-height:44px;padding-right:52px;
  font-size:16px;font-weight:700;color:var(--ink);text-decoration:underline;text-underline-offset:3px;cursor:pointer;list-style:none}
.tk-ask-det summary::-webkit-details-marker{display:none}
.tk-ask-det summary .l{display:none}.tk-ask-det[open] summary .l{display:inline}.tk-ask-det[open] summary .m{display:none}
.tk-ask-det summary::after{content:"+";margin-left:8px;font-weight:800;text-decoration:none}
.tk-ask-det[open] summary::after{content:"\2212"}
.tk-ask-det summary:focus-visible,.tk-ask-more:focus-visible,.tk-ask-x:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:6px}
.tk-ask-extra{display:grid;gap:var(--space-2);padding:2px 0 6px}
.tk-ask-extra .tk-ask-p{display:block;font-weight:500}
.tk-ask-link{grid-row:3;grid-column:1;justify-self:start;padding-right:52px}
.tk-ask-more{display:inline-flex;align-items:center;min-height:44px;font-size:16px;font-weight:700;text-decoration:underline;text-underline-offset:3px}
.tk-ask-bar a.tk-ask-more,.kuma .tk-ask-bar a.tk-ask-more{color:var(--ink)}
/* Später: 44 x 44, text-style (an x, no outline box: never a third button of equal rank), at the right end of the "Mehr dazu" row */
.tk-ask-x{appearance:none;-webkit-appearance:none;grid-row:3;grid-column:1;justify-self:end;align-self:start;z-index:2;position:relative;width:44px;height:44px;margin:0;padding:0;border:0;background:none;color:var(--ink);cursor:pointer}
.tk-ask-x::before{content:"\00d7";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font:800 28px/1 var(--font-body)}
@media(min-width:960px){
  .tk-ask-bar,body.app:has(> .ap-tabs) .tk-ask-bar{--tk-ask-bottom:0px;--tk-ask-safe:env(safe-area-inset-bottom,0px);padding:8px 24px calc(14px + var(--tk-ask-safe))}
  body.app:has(> .tk-ask-bar){display:grid;grid-template-rows:1fr auto}
  body.app > .tk-ask-bar{grid-column:2}  /* signed in: the page's grid has the side menu in column 1; the bar stays over the page only, the menu stays whole */
  /* desktop: one row, left to right: question, Ja, Nein, Mehr dazu, x (Olivier, 2026-10-16) */
  .tk-ask-in{grid-template-columns:minmax(0,1fr) auto auto auto;grid-template-rows:auto;column-gap:24px;align-items:center}
  .tk-ask-txt{grid-column:1;grid-row:1}
  .tk-ask-btns{grid-column:2;grid-row:1;align-self:center;grid-template-columns:150px 150px;margin:0}
  .tk-ask-link{grid-column:3;grid-row:1;padding-right:0;white-space:nowrap}
  .tk-ask-x{grid-column:4;grid-row:1;align-self:center}
}
@media print{.tk-ask-bar{display:none}}

/* Road (tk-road, #49 talkuma.app before the launch): stops on a dashed
   road, each a dot and a card. Without JS the road is a straight dashed
   line and the stops given is-past / is-here have a sun dot, Kuma standing
   in the is-here dot. static/soon.js draws a winding path through the dots
   (.has-path) and walks Kuma along it as the page scrolls; a dot turns sun
   when he reaches it (is-lit, a 100 ms pop). Phones: dots left, cards right.
   From 900 px: dots in the middle, cards left and right in turn. */
.tk-road{position:relative;list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:44px}
.tk-road::before{content:"";position:absolute;left:26px;top:28px;bottom:28px;border-left:4px dashed var(--outline)}
.tk-road.has-path::before{display:none}
.tk-road-path{position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
.tk-road-path path{fill:none;stroke:var(--outline);stroke-width:4;stroke-dasharray:10 10;stroke-linecap:round}
.tk-stop{position:relative;display:grid;grid-template-columns:56px minmax(0,1fr);gap:20px;align-items:start}
.tk-stop-dot{position:relative;z-index:1;box-sizing:border-box;width:56px;height:56px;margin-top:6px;border-radius:50%;border:var(--stroke-2) solid var(--outline);background:var(--surface);box-shadow:var(--shadow-sticker);display:grid;place-items:center}
.tk-road:not(.has-path) .tk-stop.is-past .tk-stop-dot,.tk-road:not(.has-path) .tk-stop.is-here .tk-stop-dot,.tk-stop.is-lit .tk-stop-dot{background:var(--sun)}
.tk-road-kuma{width:40px;height:auto;display:block}
.tk-road-kuma.is-walking{position:absolute;left:0;top:0;z-index:2;width:52px;margin:0;will-change:transform;pointer-events:none}
.tk-stop-card{box-sizing:border-box;min-width:0;padding:22px 24px;background:var(--surface);color:var(--ink);border:var(--stroke-2) solid var(--outline);border-radius:var(--radius-tile);box-shadow:var(--shadow-sticker)}
.tk-stop.is-here .tk-stop-card{box-shadow:var(--shadow-card)}
.tk-stop-card h3{margin:0 0 12px;font-family:var(--font-display);font-weight:800;font-size:26px;line-height:1.1}
.tk-stop-card ul{margin:0;padding:0 0 0 1.1em;display:grid;gap:10px;font-size:18px;font-weight:600;line-height:1.4}
.tk-stop-card .ki{margin-left:6px;vertical-align:2px}
@media (min-width:900px){
  .tk-road{gap:56px}
  .tk-road::before{left:50%;margin-left:-2px}
  .tk-stop{grid-template-columns:minmax(0,1fr) 72px minmax(0,1fr);gap:0 28px}
  .tk-stop-dot{grid-column:2;grid-row:1;justify-self:center}
  .tk-stop-card{grid-column:1;grid-row:1}
  .tk-stop:nth-of-type(even) .tk-stop-card{grid-column:3}
}
@media (prefers-reduced-motion:no-preference){
  .tk-stop.is-lit .tk-stop-dot{animation:tk-stop-pop 100ms cubic-bezier(.34,1.8,.5,1)}
}
@keyframes tk-stop-pop{0%{transform:scale(.8)}100%{transform:none}}

/* The front nav and footer on talkuma.app (#49): logo and language only;
   loaded on the page and the four legal pages there. */
.nv-front{justify-content:space-between}
.nv-front .nv-end{display:flex}
@media (max-width:560px){.nv-front .nv-globe{display:none}.kuma .nv-front .nv-lang a{padding:0 12px}}
.ft-front .ft-in{align-items:center}
.ft-front .ft-set .nv-lang{margin-top:0}
/* tk-meter: one shared count filling toward a number (design/voice-free,
   issue #37, 2026-10-21; replaces the glass on /upgrade). Not a target, so
   no shadow; a 2 px ink outline, an ink fill, no gradient. The fill keeps a
   4 % sliver so an empty month still reads as a bar. The number is always
   in the text next to it too, never only in the bar. Ink, not terra: terra
   is the one action, and on /upgrade the buy buttons are. tk-s is the
   12 px Konto size (the live kt-meter is this same thing; open point 95).
   The learning bar ap-bar is now the split bar, issue #67, app-learn.css. */
.tk-meter { box-sizing: border-box; display: block; width: 100%; height: 20px; border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-pill); background: var(--surface-2); overflow: hidden; }
.tk-meter i { display: block; height: 100%; min-width: 4%; max-width: 100%; border-radius: var(--radius-pill); background: var(--ink); }
.tk-meter.tk-s { height: 12px; }

/* tk-goal: the free read-aloud goal on the public pages (issue #48,
   Olivier 2026-10-21 "Take B": start page, Funktionen, Preise). The
   question, the goal sentence, law-kuma's line right under it (16 px ink,
   never fine print; the .tk-goal prefix beats a page rule such as .fx-txt p), then the count and a tk-meter. Not a target, so no
   shadow and no link. It stacks in a narrow column (Funktionen) and puts
   the count beside the words when its own box is 720 px or wider. */
.tk-goal { box-sizing: border-box; container-type: inline-size; min-width: 0; padding: 24px; background: var(--surface); color: var(--ink);
  border: var(--stroke-2) solid var(--outline); border-radius: 22px; }
.tk-goal-in { display: grid; gap: 18px; }
.tk-goal-txt { display: grid; gap: 8px; min-width: 0; }
.tk-goal .tk-goal-h { margin: 0; font-family: var(--font-display); font-size: 24px; font-weight: 800; line-height: 1.2; }
.tk-goal .tk-goal-say { margin: 0; font-family: var(--font-body); font-size: 18px; font-weight: 600; line-height: 1.45; max-width: 44ch; }
.tk-goal .tk-goal-terms { margin: 0; font-family: var(--font-body); font-size: 16px; font-weight: 400; line-height: 1.45; color: var(--ink); max-width: 52ch; }
.tk-goal-num { display: grid; gap: 10px; align-content: start; min-width: 0; }
.tk-goal .tk-goal-num p { margin: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; font-family: var(--font-body); font-size: 17px; font-weight: 700; }
.tk-goal .tk-goal-num big { font-family: var(--font-display); font-size: 40px; font-weight: 800; line-height: 1; }
@container (min-width: 720px) { .tk-goal-in { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); column-gap: 40px; align-items: start; } }

/* tk-ring: how many of a small number are left (Konto's "Neue Sätze
   hören", issue #37; Olivier picked it 2026-10-21 over a tile and a big
   number). A 48 px ring, the arc in ink for what is left, the number in
   the middle. The words beside it say the same ("von 2 gratis"), and the
   ring's aria-label says it whole. Not a target, so no shadow. */
.tk-ring { position: relative; display: inline-grid; place-items: center; flex: none; width: 48px; height: 48px; }
.tk-ring svg { position: absolute; inset: 0; transform: rotate(-90deg); }
.tk-ring .tr { fill: none; stroke: var(--outline); stroke-opacity: .2; stroke-width: 6; } /* seen on surface in both themes */
.tk-ring .fl { fill: none; stroke: var(--ink); stroke-width: 6; stroke-linecap: round; }
.tk-ring b { position: relative; font-family: var(--font-display); font-size: 20px; font-weight: 800; color: var(--ink); }

/* Locked tile (issue #55, ISC-290): a tile Free sees but cannot use (a
   sentence it cannot add, the grey placeholder for the rest). It looked
   tappable and did nothing, so now it is a button. A short tile lets the
   note grow down over its neighbour; a wide one keeps it to one line. a tap
   wiggles the tile once (240 ms, as "Anhören" failing), then a short note
   arrives in the tile's own box (90 ms spring), "Mit Plus." and a link. The
   box is the tile's, not a bubble: no tail, no Kuma, no sun. The note leaves
   after 4 s (the page's script); the page keeps a permanent Plus line, so
   nothing depends on the timer. Reduced motion: no wiggle, no pop. */
.tk-lock-wrap { position: relative; container-type: inline-size; }
.tk-lock-wrap[data-open] { z-index: 3; }
.tk-lock { box-sizing: border-box; display: block; width: 100%; min-height: 64px; margin: 0; padding: 14px 16px;
  border: 0; border-radius: inherit; background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.tk-lock:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-lock-bars { display: grid; gap: 8px; }
.tk-lock-bars .bar { display: block; height: 12px; width: 80%; border-radius: var(--radius-pill); background: var(--surface-2); }
.tk-lock-bars .bar.short { width: 50%; }
.tk-lock-note { box-sizing: border-box; position: absolute; top: -2px; left: -2px; right: -2px; min-height: calc(100% + 4px);
  display: flex; flex-wrap: wrap; align-items: center; align-content: center; column-gap: 20px; row-gap: 2px; margin: 0; padding: 10px 16px 4px;
  border: var(--stroke-2) solid var(--outline); border-radius: inherit; background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-sticker); font-size: 17px; font-weight: 600; line-height: 1.3; pointer-events: none; }
.tk-lock-note .tk-lock-l { flex: 1 0 100%; }
/* A wide tile has room for one line: the note then fits the tile and covers no neighbour. */
@container (min-width: 620px) { .tk-lock-note .tk-lock-l { flex: 0 1 auto; } }
.tk-lock-note[hidden] { display: none; }
.tk-lock-note b { font-family: var(--font-display); font-size: 19px; font-weight: 800; }
.tk-lock-note a { display: inline-flex; align-items: center; min-height: 44px; pointer-events: auto;
  color: var(--ink); font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.kuma .tk-lock-note a:hover { color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .tk-lock-wrap[data-open] { animation: tk-lock-no 240ms cubic-bezier(.2,.9,.25,1) both; }
  .tk-lock-wrap[data-open] .tk-lock-note { animation: tk-lock-pop 90ms cubic-bezier(.34,1.8,.5,1) 170ms both; }
}
@keyframes tk-lock-no { 0%, 100% { transform: none; } 20% { transform: translateX(-8px); } 45% { transform: translateX(6px); } 70% { transform: translateX(-3px); } }
@keyframes tk-lock-pop { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
/* tk-lang-jump: the flat pill that jumps to a language (#312; Bibliothek's
   row, 2026-10-18, and Schwierige Karten's, 2026-11-01, one look for both).
   A plain anchor: the sticker flags (ob-flags.sm) and the language's name,
   48 px high, 17 px 800, a 2 px outline, no shadow. The row around it is the
   page's own (one line that scrolls inside itself, wrapping from 960 px). */
.tk-lang-jump { flex: none; box-sizing: border-box; display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 18px 0 14px;
  border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-pill); background: var(--surface); color: var(--ink); text-decoration: none;
  font-size: 17px; font-weight: 800; white-space: nowrap; }
.kuma a.tk-lang-jump:hover { color: var(--ink); }
.tk-lang-jump:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-lang-jump .ob-flags { position: static; flex: none; }

/* tk-dbar and tk-pile: Learn's day (issue #85 round 5, option C, Olivier
   2026-10-21: "the user DOESN'T SEE THAT HE IS DOING WORK"; colours and
   pile rule after his "yellow / green" and "like when are using cards in
   real"). tk-dbar is a slim bar of two fills over the day's cards: sun
   (yellow) is every card answered today, moss (green, drawn over it) the
   cards known today (Gewusst at least once). Neither goes down. Sun on white
   is 1.65:1, under the 3:1 a graphic needs, so an ink divider (the surface
   in dark) ends each fill; a fill that is full drops it. The widths are set
   inline; the script tweens them from the last page's values. tk-pile is a
   slim, crooked heap of card edges behind the panel of an end screen (the
   short break, done for the day), never on the learning screens: one edge
   per answer of the cycle that just ended, at most 30. A pile ends at a
   short break or at 30 edges, and the next answer starts a new one from 0.
   The newest edge is nearest the panel; only the newest three carry their
   answer's colour (Gewusst green, Nochmals yellow: c1 in full, c2 and c3 in
   two tints); older edges are plain paper; each has a 2 px ink outline. Each
   is a few px off and tilted up to 2.5 degrees by the pile's seed and its
   own number. The heap's depth is a share of --pile-h, 4 % for one edge and
   100 % for thirty. It drops once (.drop) when the page comes up after an
   answer, the farther the more edges (--pile-n), and not under reduced
   motion. */
.tk-dbar { --seg-div: var(--outline); position: relative; display: block; flex: none; width: 100%; max-width: 160px; height: 14px;
  box-sizing: border-box; overflow: hidden; border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-pill); background: var(--surface); }
.tk-dbar.big { max-width: none; height: 18px; }
.tk-dbar i { position: absolute; top: 0; bottom: 0; left: 0; display: block; transition: width 240ms cubic-bezier(.22, .9, .3, 1); }
.tk-dbar .s { background: linear-gradient(to right, var(--sun) calc(100% - 3px), var(--seg-div) calc(100% - 3px)); }
.tk-dbar .k { background: linear-gradient(to right, var(--moss) calc(100% - 3px), var(--seg-div) calc(100% - 3px)); }
.tk-dbar .s.full { background: var(--sun); }
.tk-dbar .k.full { background: var(--moss); }
.tk-dbar .has { min-width: 8px; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .tk-dbar { --seg-div: var(--surface); } }
:root[data-theme="dark"] .tk-dbar { --seg-div: var(--surface); }
@media (prefers-reduced-motion: reduce) { .tk-dbar i { transition: none; } }

.tk-pile { position: relative; display: block; isolation: isolate; }
.tk-pile > :not(.tk-edge) { position: relative; z-index: 100; }
.tk-edge { position: absolute; inset: 0; box-sizing: border-box; background: var(--surface);
  border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-card); }
.tk-pile.is-panel .tk-edge { border-radius: var(--radius-tile); }
/* Colour = what you just did: the newest edge in full, the next two in two
   stepped tints (a mix of the token with the surface, 65 % and 35 %), older
   edges plain paper. color-mix of two palette tokens is the one thing here
   that is not a token itself; a browser without it shows the plain edge. */
.tk-edge.known.c1 { background: var(--moss); }
.tk-edge.again.c1 { background: var(--sun); }
.tk-edge.known.c2 { background: color-mix(in srgb, var(--moss) 65%, var(--surface)); }
.tk-edge.again.c2 { background: color-mix(in srgb, var(--sun) 65%, var(--surface)); }
.tk-edge.known.c3 { background: color-mix(in srgb, var(--moss) 35%, var(--surface)); }
.tk-edge.again.c3 { background: color-mix(in srgb, var(--sun) 35%, var(--surface)); }
@keyframes tk-pile-drop { from { translate: 0 calc(-2px - var(--pile-n, 1) * .4px); } to { translate: 0 0; } }
@media (prefers-reduced-motion: no-preference) {
  .tk-pile.drop { animation: tk-pile-drop 160ms cubic-bezier(.34, 1.56, .64, 1) 1; }
}

/* KumaCard moods and the end card (issue #85 round 7; Olivier 2026-10-21:
   "It is a kuma like the main page. Just different emotion. It can also be
   added to design system it should not BE different").
   The same KumaCard as Heute and the hello (.tk-card with .tk-ear, .tk-face,
   .tk-eyes, .tk-cheek, .tk-snout): no new drawing. A mood only changes the
   eyes, the mouth (the snout's two arcs), the cheeks and, while idle, how
   the card moves. No data-mood is the neutral main-page Kuma.
   API: <div class="tk-card" data-mood="neugierig|zufrieden|stemmt|wackelt|strahlt|schlaeft">
   Face units (--ku) and Kuma's own colours as the KumaCard; tokens only.
   Source: design/components/bundle.css. Live copy: static/kuma.css (copy
   this block in when it is built). */

/* ── The end card: the KumaCard as the top card of the pile on the short
   break and done for today, the same size as Heute's card ("Dieselbe
   Karte", static/app-today.css .td-card): full width, the face's 104 face
   units on top, a say area of at least 150 px, the quiet foot (84 px) for
   what comes next, the face clipped and its hard shadow 0 10 px. Words in
   the say area: the bar, then the day's line, centred. */
.tk-card.tk-end { width: 100%; max-width: none; margin: 0; cursor: default; }
.tk-card.tk-end .tk-face { min-height: 0; padding: calc(104 * var(--ku)) 22px 0; justify-content: flex-start; overflow: hidden;
  box-shadow: 0 10px 0 var(--page-outline, var(--outline)); transform-origin: 50% 100%; }
.tk-card.tk-end .tk-end-say { display: grid; align-content: center; justify-items: center; gap: 12px; width: 100%; min-height: 150px; padding: 4px 0 24px; box-sizing: border-box; }
.tk-card.tk-end .tk-end-say p { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.35; color: var(--ink); text-wrap: pretty; }
.tk-card.tk-end .tk-dbar { width: 100%; max-width: none; height: 18px; }
.tk-card.tk-end .tk-end-foot { align-self: stretch; margin: 0 -22px; display: flex; align-items: center; justify-content: center; min-height: 84px; padding: 0 16px;
  box-sizing: border-box; background: var(--surface-2); color: var(--ink); border-top: var(--stroke-3) solid var(--outline); font: 800 20px/1.2 var(--font-body); text-align: center; }
/* A short screen (under 700 px high, e.g. 360 x 640): the say area takes only
   what its words need, so card, pile, note and button fit without scroll. */
@media (max-height: 700px) { .tk-card.tk-end .tk-end-say { min-height: 0; padding: 14px 0 18px; } }

/* ── The six moods. Eyes are the KumaCard's two 16-unit dots; a mood
   reshapes them with borders only. The mouth is the snout's two arcs (the
   small "w"); a mood restyles the first and hides the second. */
/* Neugierig: wider eyes, a bigger shine, a small round "o". */
.tk-card[data-mood="neugierig"] .tk-eyes i { width: calc(19 * var(--ku)); height: calc(19 * var(--ku)); margin-top: calc(-1.5 * var(--ku)); }
.tk-card[data-mood="neugierig"] .tk-eyes i::after { width: calc(6 * var(--ku)); height: calc(6 * var(--ku)); }
.tk-card[data-mood="neugierig"] .tk-snout i:first-child { left: calc(50% - 4.5 * var(--ku)); top: calc(27 * var(--ku)); width: calc(9 * var(--ku)); height: calc(9 * var(--ku));
  border: 0; border-radius: 50%; background: var(--kuma-nose); }
/* Zufrieden and Strahlt: happy closed eyes, two arcs. */
.tk-card:is([data-mood="zufrieden"], [data-mood="strahlt"]) .tk-eyes i { height: calc(9 * var(--ku)); margin-top: calc(4 * var(--ku)); background: none;
  border: calc(3.5 * var(--ku)) solid var(--kuma-eye); border-bottom: 0; border-radius: calc(9 * var(--ku)) calc(9 * var(--ku)) 0 0; }
.tk-card:is([data-mood="zufrieden"], [data-mood="strahlt"], [data-mood="stemmt"], [data-mood="schlaeft"]) .tk-eyes i::after { content: none; }
/* Strahlt: an open smile, fuller cheeks. */
.tk-card[data-mood="strahlt"] .tk-snout i:first-child { left: calc(50% - 9 * var(--ku)); top: calc(27 * var(--ku)); width: calc(18 * var(--ku)); height: calc(11 * var(--ku));
  border: 0; border-radius: 0 0 calc(10 * var(--ku)) calc(10 * var(--ku)); background: var(--kuma-nose); }
.tk-card:is([data-mood="strahlt"], [data-mood="stemmt"]) .tk-cheek { scale: 1.2; }
/* Stemmt: eyes pressed shut (> <), a firm flat mouth. */
.tk-card[data-mood="stemmt"] .tk-eyes i { width: calc(13 * var(--ku)); height: calc(13 * var(--ku)); margin-top: calc(1.5 * var(--ku)); background: none;
  border: 0 solid var(--kuma-eye); border-radius: 2px; rotate: 45deg; }
.tk-card[data-mood="stemmt"] .tk-eyes i:first-child { border-top-width: calc(3.5 * var(--ku)); border-right-width: calc(3.5 * var(--ku)); }
.tk-card[data-mood="stemmt"] .tk-eyes i:last-child { border-bottom-width: calc(3.5 * var(--ku)); border-left-width: calc(3.5 * var(--ku)); }
.tk-card[data-mood="stemmt"] .tk-snout i:first-child { left: calc(50% - 8 * var(--ku)); top: calc(29 * var(--ku)); width: calc(16 * var(--ku)); height: 0;
  border: 0; border-top: calc(2.5 * var(--ku)) solid var(--kuma-nose); border-radius: 2px; }
/* Wackelt: one eye a little higher, a wider wobbly "w". */
.tk-card[data-mood="wackelt"] .tk-eyes i:first-child { margin-top: calc(-3 * var(--ku)); }
.tk-card[data-mood="wackelt"] .tk-snout i { width: calc(15 * var(--ku)); }
.tk-card[data-mood="wackelt"] .tk-snout i:first-child { left: calc(50% - 16.25 * var(--ku)); }
/* Schläft: the sleeping eyes of Heute (tb-sleep): two thin slits, no shine. */
.tk-card[data-mood="schlaeft"] .tk-eyes i { height: calc(3.5 * var(--ku)); margin-top: calc(6.25 * var(--ku)); border-radius: var(--radius-pill); }
.tk-card:is([data-mood="neugierig"], [data-mood="strahlt"], [data-mood="stemmt"]) .tk-snout i:last-child { display: none; }

/* ── Idle. The system's idle life stays as it is (kuma-idle.js picks a
   blink, an ear, the snout or a breath now and then: kz-* in this file).
   NEW for every KumaCard with a mood: one quiet loop per mood on the card
   itself, on one beat (--kz-beat, the system's breath, 2600 ms), using
   translate / rotate / scale so it never fights the kz-* moves (those use
   transform on the face, eyes, ears and snout). Small: at most 3 px or
   1.5 degrees. Pressed-shut and slit eyes do not blink. Nothing under
   reduced motion: the still face only. */
.tk-card[data-mood] { --kz-beat: 2600ms; transform-origin: 50% 100%; }
@media (prefers-reduced-motion: no-preference) {
  .tk-card[data-mood="neugierig"] { animation: kz-m-tilt calc(2 * var(--kz-beat)) ease-in-out infinite; }
  .tk-card[data-mood="neugierig"] .tk-eyes { animation: kz-m-look calc(2 * var(--kz-beat)) ease-in-out infinite; }
  .tk-card[data-mood="zufrieden"] { animation: kz-m-breath var(--kz-beat) ease-in-out infinite; }
  .tk-card[data-mood="stemmt"] { animation: kz-m-strain var(--kz-beat) linear infinite; }
  .tk-card[data-mood="wackelt"] { animation: kz-m-wobble var(--kz-beat) ease-in-out infinite; }
  .tk-card[data-mood="strahlt"] { animation: kz-m-bounce var(--kz-beat) cubic-bezier(.34, 1.56, .64, 1) infinite; }
  .tk-card[data-mood="schlaeft"] { animation: kz-m-sleep calc(2 * var(--kz-beat)) ease-in-out infinite; }
  .tk-card:is([data-mood="stemmt"], [data-mood="schlaeft"]).kz-blink:not(#kz) .tk-eyes i,
  .tk-card:is([data-mood="stemmt"], [data-mood="schlaeft"]).kz-blink2:not(#kz) .tk-eyes i { animation: none; }
}
@keyframes kz-m-tilt { 0%, 100% { rotate: 0deg; } 50% { rotate: -1.5deg; } }
@keyframes kz-m-look { 0%, 100% { translate: 0 0; } 30% { translate: calc(-2 * var(--ku)) calc(1 * var(--ku)); } 65% { translate: calc(2 * var(--ku)) calc(1 * var(--ku)); } }
@keyframes kz-m-breath { 0%, 100% { translate: 0 0; scale: 1; } 45% { translate: 0 -1px; scale: 1 1.012; } }
@keyframes kz-m-strain { 0%, 14%, 100% { translate: 0 0; } 2% { translate: .7px 0; } 5% { translate: -.7px 0; } 8% { translate: .7px 0; } 11% { translate: -.5px 0; } }
@keyframes kz-m-wobble { 0%, 100% { rotate: 0deg; } 25% { rotate: 1.2deg; } 75% { rotate: -1.2deg; } }
@keyframes kz-m-bounce { 0%, 40%, 100% { translate: 0 0; } 14% { translate: 0 -3px; } 26% { translate: 0 0; } }
@keyframes kz-m-sleep { 0%, 100% { translate: 0 0; scale: 1; } 50% { translate: 0 -1.5px; scale: 1 1.02; } }

/* ── The landing (one shot, after the answer that ends a pile; Olivier
   2026-10-21: "it should really fall down and land on the pile"). The card
   sits in a .tk-end-fall wrapper (so its idle loop keeps running) and falls
   onto the pile:
     0 to 180 ms   falls 260 px, speeding up (ease-in, cubic-bezier(.5, 0, 1, .5));
     180 ms        impact: the pile's edges take the thump (tk-end-thump: down
                   2 px + 0.15 px per card, back on a spring, 140 ms) and the
                   face squashes from its bottom edge (tk-end-squash: scale(1.04,
                   --sq) at 35 %, 90 ms; --sq .97 / .95 / .93 / .90 for 1-5,
                   6-14, 15-29, 30 cards);
     180 to 240 ms rebound 6 px (ease-out); 240 to 320 ms settle (ease-in).
   The script shows Neugierig while he falls and the pile's mood from the
   impact on. Reduced motion: no fall, the still face. */
@keyframes tk-end-fall {
  0% { translate: 0 -260px; animation-timing-function: cubic-bezier(.5, 0, 1, .5); }
  56.25% { translate: 0 0; animation-timing-function: cubic-bezier(0, .5, .5, 1); }
  75% { translate: 0 -6px; animation-timing-function: cubic-bezier(.5, 0, 1, .5); }
  100% { translate: 0 0; } }
@keyframes tk-end-squash { 0% { transform: none; } 35% { transform: scale(1.04, var(--sq, .95)); } 100% { transform: none; } }
@keyframes tk-end-thump { 0%, 100% { translate: 0 0; } 30% { translate: 0 calc(2px + var(--pile-n, 1) * .15px); } }
.tk-end-fall { display: block; }
/* The pile with Kuma on top does not take the built early drop: the thump comes at the impact. */
.tk-pile.drop:has(> .tk-end-fall) { animation: none; }
@media (prefers-reduced-motion: no-preference) {
  .tk-pile.drop .tk-end-fall { animation: tk-end-fall 320ms 1 both; }
  .tk-pile.drop .tk-card.tk-end .tk-face { animation: tk-end-squash 90ms cubic-bezier(.34, 1.56, .64, 1) 180ms 1 both; }
  .tk-pile.drop > .tk-edge { animation: tk-end-thump 140ms cubic-bezier(.34, 1.56, .64, 1) 180ms 1 both; }
}

/* The tip page /tipp (issue #118, design/ohne/mockup.html): tk-sheet as in components/bundle.css, oh-* the page. */
/* Sheet (tk-sheet, issue #18 "Lern mit deinen eigenen Sätzen"): a picture of a spreadsheet, two columns
   (the sentence, its meaning) and a header row. Not a target, so the
   rows have no shadow; the frame is a sticker like every card. Each row
   is at least 56 px (--tk-row); a demo that moves whole rows sets a fixed height (.tk-fixed) so a row moves by exactly --tk-row.
   .tk-cover is the hand on the meaning: a surface-2 block with a dashed
   outline, no text. */
.tk-sheet { --tk-row: 56px; box-sizing: border-box; position: relative; overflow: hidden; min-width: 0; margin: 0;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-tile); box-shadow: var(--shadow-sticker); }
.tk-sheet-h, .tk-sheet-r { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.tk-sheet-h { background: var(--surface-2); border-bottom: var(--stroke-2) solid var(--outline); }
.tk-sheet-h span { padding: 10px 12px; font-size: 16px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.tk-sheet-r { position: relative; min-height: var(--tk-row); box-sizing: border-box; background: var(--surface); border-bottom: 1px solid var(--surface-2); }
.tk-sheet.tk-fixed .tk-sheet-r { height: var(--tk-row); }
.tk-sheet.tk-fixed .tk-sheet-r span { overflow: hidden; }
.tk-sheet.tk-fixed .tk-sheet-r { border-bottom: 0; }
.tk-sheet.tk-fixed .tk-sheet-r + .tk-sheet-r { border-top: 1px solid var(--surface-2); }
.tk-sheet-r:last-child { border-bottom: 0; }
.tk-sheet-r span { display: flex; align-items: center; min-width: 0; padding: 0 14px; font-size: 17px; font-weight: 600; line-height: 1.2; }
.tk-sheet-h span + span, .tk-sheet-r span + span { border-left: 1px solid var(--surface-2); }
.tk-sheet-r span:first-child { font-weight: 800; }
.tk-sheet .tk-cover { position: absolute; top: 6px; bottom: 6px; right: 6px; width: calc(50% - 12px); box-sizing: border-box;
  background: var(--surface-2); border: var(--stroke-2) dashed var(--outline); border-radius: 12px; }

body { margin: 0; }
/* Page-only layout (oh-* in static/kuma.css when built). */
.oh { max-width: 1200px; margin: 0 auto; padding: 48px 20px 72px; box-sizing: border-box; display: flex; flex-direction: column; gap: 40px; }
.oh-what { display: flex; flex-direction: column; gap: 16px; max-width: 760px; }
.oh-step { display: flex; flex-direction: column; gap: 18px; min-width: 0; padding: 24px; box-sizing: border-box;
  background: var(--surface); border: 2px solid var(--outline); border-radius: 22px; }
.oh-step.mint { background: var(--mint); }
.oh-step .tk-steplist p { max-width: 44ch; }
.oh-step .tk-steplist p + p { margin-top: 10px; }
.oh-step .tk-steplist p b { display: inline; margin: 0; font-family: var(--font-body); font-size: inherit; font-weight: 800; }
@media (max-width: 480px) { .oh-step { padding: 20px 16px; } .oh-pic { padding: 12px; } .oh-pic.oh-d4 .tk-sheet { --tk-row: 76px; } }
.oh-pic { display: flex; flex-direction: column; gap: 12px; flex: 1; justify-content: center; padding: 18px; border-radius: 18px;
  background: var(--paper); border: 2px solid var(--outline); }
.oh-pic .tk-bubble, .oh-pic .tk-me { animation: none; font-size: 18px; }
.oh-pic .tk-me { margin-left: auto; max-width: 92%; }
.oh-pic .tk-bubble { max-width: 92%; }
.oh-pic .tk-sheet { box-shadow: none; }
.oh-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.oh-btns .tk-button { min-height: 52px; font-size: 19px; }
.oh-end { margin: 0; font-family: var(--font-display); font-size: clamp(26px, 3.2vw, 34px); font-weight: 800; line-height: 1.15; text-align: center; }
@media (min-width: 960px) { .oh { padding-top: 72px; gap: 48px; } .oh-step { padding: 28px; } }
/* Motion: every arrival 70 to 110 ms on a spring, long rests between;
   [data-play] holds each demo until it scrolls into view (kuma.js). */
.oh-d1 .tk-bubble { animation: oh-pop 6s infinite both; transform-origin: 10% 100%; }
.oh-d2 .tk-me { animation: oh-pop 8s infinite both; transform-origin: 90% 100%; }
.oh-d2 .tk-bubble { animation: oh-pop2 8s infinite both; transform-origin: 10% 100%; }
@keyframes oh-pop { 0%, 8% { opacity: 0; transform: translateY(18px) scale(.7); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  9.3% { opacity: 1; transform: scale(1.06); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 10.6%, 95% { opacity: 1; transform: none; } 96.5%, 100% { opacity: 0; } }
@keyframes oh-pop2 { 0%, 30% { opacity: 0; transform: translateY(18px) scale(.7); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  31.2% { opacity: 1; transform: scale(1.06); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 32.4%, 95% { opacity: 1; transform: none; } 96.5%, 100% { opacity: 0; } }
.oh-d3 .tk-sheet-r { animation: oh-row 8s infinite both; }
.oh-d3 .tk-sheet-r:nth-child(3) { animation-name: oh-row2; }
.oh-d3 .tk-sheet-r:nth-child(4) { animation-name: oh-row3; }
@keyframes oh-row  { 0%, 12% { opacity: 0; transform: translateY(-18px) rotate(-2deg) scale(.8); animation-timing-function: cubic-bezier(.2,.9,.25,1); } 13.2% { opacity: 1; transform: scale(1.05); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 14.5%, 94% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; } }
@keyframes oh-row2 { 0%, 20% { opacity: 0; transform: translateY(-18px) rotate(2deg) scale(.8); animation-timing-function: cubic-bezier(.2,.9,.25,1); } 21.2% { opacity: 1; transform: scale(1.05); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 22.5%, 94% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; } }
@keyframes oh-row3 { 0%, 28% { opacity: 0; transform: translateY(-18px) rotate(-2deg) scale(.8); animation-timing-function: cubic-bezier(.2,.9,.25,1); } 29.2% { opacity: 1; transform: scale(1.05); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 30.5%, 94% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; } }
/* Demo 4 (10 s): the cover lifts (12 %), then Gewusst presses (15 %), the row goes to
   the end (30 %), covered again; the cover lifts (47 %), Nochmals presses (50 %),
   the row shakes and stays on top. One step = 1 % = 100 ms. */
.oh-d4 .tk-sheet { --tk-row: 60px; }
.oh-d4 .tk-sheet-r { will-change: transform; }
.oh-d4 .r1 { animation: oh-r1 10s infinite both; }
.oh-d4 .r2 { animation: oh-r2 10s infinite both; }
.oh-d4 .r3 { animation: oh-r3 10s infinite both; }
.oh-d4 .r1 .tk-cover { animation: oh-c1 10s infinite both; }
.oh-d4 .r2 .tk-cover { animation: oh-c2 10s infinite both; }
.oh-d4 .oh-k { animation: oh-pk 10s infinite both; --tk-rest: var(--shadow-button); }
.oh-d4 .oh-n { animation: oh-pn 10s infinite both; --tk-rest: var(--shadow-button); }
@keyframes oh-r1 { 0%, 30% { transform: none; animation-timing-function: cubic-bezier(.2,.9,.25,1); } 31.1% { transform: translateY(calc(2 * var(--tk-row) + 6px)); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 32.5%, 95% { transform: translateY(calc(2 * var(--tk-row))); opacity: 1; } 97% { opacity: 0; transform: translateY(calc(2 * var(--tk-row))); } 97.1%, 100% { opacity: 0; transform: none; } }
@keyframes oh-r2 { 0%, 30% { transform: none; animation-timing-function: cubic-bezier(.2,.9,.25,1); } 31.1% { transform: translateY(calc(-1 * var(--tk-row) - 6px)); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 32.5%, 56% { transform: translateY(calc(-1 * var(--tk-row))); }
  56.6% { transform: translateY(calc(-1 * var(--tk-row))) translateX(-9px); } 57.2% { transform: translateY(calc(-1 * var(--tk-row))) translateX(8px); } 57.8% { transform: translateY(calc(-1 * var(--tk-row))) translateX(-5px); } 58.4% { transform: translateY(calc(-1 * var(--tk-row))) translateX(3px); }
  59%, 95% { transform: translateY(calc(-1 * var(--tk-row))); opacity: 1; } 97% { opacity: 0; transform: translateY(calc(-1 * var(--tk-row))); } 97.1%, 100% { opacity: 0; transform: none; } }
@keyframes oh-r3 { 0%, 30% { transform: none; animation-timing-function: cubic-bezier(.2,.9,.25,1); } 31.1% { transform: translateY(calc(-1 * var(--tk-row) - 6px)); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 32.5%, 95% { transform: translateY(calc(-1 * var(--tk-row))); opacity: 1; } 97% { opacity: 0; transform: translateY(calc(-1 * var(--tk-row))); } 97.1%, 100% { opacity: 0; transform: none; } }
@keyframes oh-c1 { 0%, 11% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.2,.9,.25,1); } 12% { opacity: 0; transform: translateY(-10px) rotate(-4deg); } 33% { opacity: 0; transform: translateY(-10px); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 34%, 100% { opacity: 1; transform: none; } }
@keyframes oh-c2 { 0%, 46% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.2,.9,.25,1); } 47% { opacity: 0; transform: translateY(-10px) rotate(4deg); } 80% { opacity: 0; transform: translateY(-10px); animation-timing-function: cubic-bezier(.34,1.8,.5,1); } 81%, 100% { opacity: 1; transform: none; } }
@keyframes oh-pk { 0%, 15% { transform: none; box-shadow: var(--tk-rest), 0 0 0 0 rgba(244,195,74,0); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  15.7%, 16.2% { transform: translateY(5px) scale(.94); box-shadow: 0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  16.8%, 17.2% { transform: translateY(5px) scale(.94); box-shadow: 0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.34,1.8,.5,1); }
  19.5%, 100% { transform: none; box-shadow: var(--tk-rest), 0 0 0 24px rgba(244,195,74,0); } }
@keyframes oh-pn { 0%, 50% { transform: none; box-shadow: var(--tk-rest), 0 0 0 0 rgba(244,195,74,0); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  50.7%, 51.2% { transform: translateY(5px) scale(.94); box-shadow: 0 0 0 var(--outline), 0 0 0 0 rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.2,.9,.25,1); }
  51.8%, 52.2% { transform: translateY(5px) scale(.94); box-shadow: 0 0 0 var(--outline), 0 0 0 12px rgba(244,195,74,.95); animation-timing-function: cubic-bezier(.34,1.8,.5,1); }
  54.5%, 100% { transform: none; box-shadow: var(--tk-rest), 0 0 0 24px rgba(244,195,74,0); } }
@media (prefers-reduced-motion: reduce) {
  .oh-pic .tk-bubble, .oh-pic .tk-me, .oh-pic .tk-sheet-r, .oh-pic .tk-cover, .oh-pic .tk-button { animation: none; opacity: 1; }
}

/* ── Kuma speaks (2-12, redesigned ISC-252, Olivier 2026-10-11: "not
   smooth or not ... coherent"). One object changes state, nothing else on
   the screen moves: the "Anhören" pill keeps its size and place, its
   speaker glyph turns into four ink bars, and while the sentence plays the
   pill is sun and a pale veil sweeps across it with the sound's own
   clock, so its end is the sweep's end. Sun with four ink bars is how every
   "Kuma speaks" moment looks (the greeting chips' badge: same bars, same
   speeds, gr-bar in kuma.css). States sit in data-state on the button:
     idle      the plain pill.
     loading   only past 150 ms without sound: the bars sit low and ripple
               calmly; aria-busy.
     playing   sun, bars jump, the veil sweeps; aria-disabled (no second clip).
     failed    greyed like "Anhören · Plus", the speaker crossed out, one
               short shake; aria-disabled, the reason in its title.
   Colours switch at once (a fade from ink to sun passes through mud in
   dark mode); the glyph and the bars pop in 100 ms on a spring; the bars
   and the sweep are the calm loop while sound plays. Reduced motion: no pops, no shake,
   no sweep, the bars stand at four heights. */
.vx-say { position: relative; overflow: hidden; isolation: isolate; min-width: 0; }
.vx-say .vx-ico { position: relative; display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px; }
.vx-say .vx-ico > * { grid-area: 1 / 1; }
.vx-say .vx-x { display: none; }
.vx-bars { display: none; align-items: center; justify-content: center; gap: 2px; height: 18px; }
.vx-bars i { display: block; width: 3px; height: 16px; border-radius: 2px; background: currentColor; transform: scaleY(.25); }
.vx-veil { position: absolute; inset: 0; z-index: -1; background: rgba(255,255,255,.5);
  transform-origin: 0 50%; transform: scaleX(var(--vx-p, 0)); opacity: 0; pointer-events: none; }
/* loading and playing: the glyph gives way to the bars. */
.vx-say[data-state="loading"] svg, .vx-say[data-state="playing"] svg { display: none; }
.vx-say[data-state="loading"] .vx-bars, .vx-say[data-state="playing"] .vx-bars { display: inline-flex; animation: vx-pop 100ms cubic-bezier(.34,1.8,.5,1) both; }
.vx-say.vx-was[data-state="idle"] svg { animation: vx-pop 100ms cubic-bezier(.34,1.8,.5,1) both; }
.vx-say[data-state="loading"] { cursor: progress; }
.vx-say[data-state="loading"] .vx-bars i { animation: vx-wait 900ms ease-in-out infinite; }
.vx-say[data-state="loading"] .vx-bars i:nth-child(2) { animation-delay: 120ms; }
.vx-say[data-state="loading"] .vx-bars i:nth-child(3) { animation-delay: 240ms; }
.vx-say[data-state="loading"] .vx-bars i:nth-child(4) { animation-delay: 360ms; }
/* playing: the pill itself is sun. on-sun is ink in both themes. */
.vx-say[data-state="playing"] { background: var(--sun); color: var(--on-sun); border-color: var(--outline); cursor: default; }
.vx-say[data-state="playing"] .vx-veil { opacity: 1; }
.vx-say[data-state="playing"] .vx-bars i { animation: gr-bar 280ms ease-in-out infinite; }
.vx-say[data-state="playing"] .vx-bars i:nth-child(2) { animation-duration: 340ms; animation-delay: -90ms; }
.vx-say[data-state="playing"] .vx-bars i:nth-child(3) { animation-duration: 250ms; animation-delay: -170ms; }
.vx-say[data-state="playing"] .vx-bars i:nth-child(4) { animation-duration: 310ms; animation-delay: -40ms; }
/* failed: quiet like "Anhören · Plus", crossed out, one shake. */
.vx-say[data-state="failed"] { color: var(--ink-muted); background: var(--surface-2); border-color: var(--ink-muted); box-shadow: none; cursor: default;
  animation: vx-no 240ms cubic-bezier(.2,.9,.25,1) both; }
.vx-say[data-state="failed"] svg { opacity: .7; }
.vx-say[data-state="failed"] .vx-sw { display: none; }
.vx-say[data-state="failed"] .vx-x { display: inline; }
@keyframes vx-pop { from { transform: scale(.4); } to { transform: none; } }
@keyframes vx-wait { 0%, 100% { transform: scaleY(.25); } 40% { transform: scaleY(.5); } }
@keyframes vx-no { 0%, 100% { transform: none; } 20% { transform: translateX(-6px); } 45% { transform: translateX(5px); } 70% { transform: translateX(-3px); } }
@media (prefers-reduced-motion: reduce) {
  .vx-say[data-state] svg, .vx-say[data-state] .vx-bars, .vx-say[data-state] .vx-bars i, .vx-say[data-state="failed"] { animation: none; }
  .vx-say[data-state="playing"] .vx-veil { opacity: 0; }
  .vx-say[data-state="playing"] .vx-bars i:nth-child(1), .vx-say[data-state="playing"] .vx-bars i:nth-child(4) { transform: scaleY(.5); }
  .vx-say[data-state="playing"] .vx-bars i:nth-child(2) { transform: scaleY(1); }
  .vx-say[data-state="playing"] .vx-bars i:nth-child(3) { transform: scaleY(.75); }
  .vx-say[data-state="loading"] .vx-bars i { transform: scaleY(.35); }
}

/* Tip mark (tk-tipmark, issue #146, mockup design/endings/, design-kuma
   2026-10-23, not built yet; first named tk-ending, renamed with no visual change,
   Olivier 2026-10-23: "yes"). Marks the pattern a language's Tipp is about,
   e.g. Turkish arı<span class="tk-tipmark">yorum</span>, Thai ครับ, คน. The learning
   card's sentence is already 800, so bold would not show: the mark is a thick
   ink underline, no new colour. On the tip card's paper (600 italic) the
   pattern also turns 800. A screen reader does not hear the mark: the card
   carries the rule as sr-only text next to it. The underline draws in once
   (90 ms spring) on the first marked card; reduced motion shows it at once.
   .tk-tipmark-n is the arrival class. It always sits on a whole word or ending,
   never on a lone tone mark or vowel sign (a span there breaks the Thai letter).
   Thai below-signs would meet the line: no example uses one under the mark. */
.tk-tipmark { font-weight: 800; text-decoration: underline; text-decoration-color: currentColor;
  text-decoration-thickness: max(3px, .08em); text-underline-offset: .16em; text-decoration-skip-ink: none; }
@media (prefers-reduced-motion: no-preference) {
  .tk-tipmark.tk-tipmark-n { animation: tk-tipmark-in 90ms cubic-bezier(.34, 1.56, .64, 1) 160ms both; }
}
@keyframes tk-tipmark-in { from { text-decoration-color: transparent; text-underline-offset: .5em; } to { text-decoration-color: currentColor; text-underline-offset: .16em; } }

/* Reference entry (tk-ref, issue #146, Olivier 2026-10-23: a language's Tipps, tile "Tipps" (first "ending notes")
   "in library next to language (pro feature)", "to look through all of
   them"; mockup design/endings/library.html, not built yet). The last tile
   of a language's decks in the Library: a way to look something up, not a
   deck. A square mark with the ending in display type stands where a deck
   has nothing, so it never reads as one more deck; no count (nothing to
   collect), the line shows a few patterns. One link for Free and Plus alike
   (Olivier 2026-10-23, point 131 A): Free finds the Plus tips locked on the
   page (.tk-notes-lock), not on the tile. The old Free tile (tk-ref-lock, one
   sample and a lock) is retired. */
.tk-ref { box-sizing: border-box; display: flex; align-items: center; gap: 14px; min-height: 64px; width: 100%;
  padding: 12px 16px; background: var(--surface); color: var(--ink); text-decoration: none; text-align: left;
  border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-tile); box-shadow: var(--shadow-sticker); }
.kuma a.tk-ref:hover { color: var(--ink); }
.tk-ref:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-ref-mark { flex: none; display: grid; place-items: center; width: 48px; height: 48px; box-sizing: border-box;
  border: var(--stroke-2) solid var(--outline); border-radius: 12px; background: var(--surface-2);
  font-family: var(--font-display); font-size: 17px; font-weight: 800; letter-spacing: -.02em; }
.tk-ref-t { flex: 1; min-width: 0; display: grid; gap: 2px; }
.tk-ref-t b { font-size: 19px; font-weight: 800; line-height: 1.2; }
.tk-ref-t > span { font-size: 16px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.tk-ref .go { flex: none; font-family: var(--font-display); font-size: 24px; font-weight: 800; }
.lb-decks > .tk-ref { grid-column: 1 / -1; }

/* Notes list (tk-notes, issue #146): every Tipp of one language, one fold per
   tip, in the alphabet's order (no levels, no path, no "N von M", no mark
   for seen or unseen). <details>/<summary>, so it opens without a script and
   the browser says "collapsed / expanded". The summary is the ending, 56 px,
   with the › turned down when open. Open: the rule, as in Learn, then one
   sentence with the pattern marked (tk-tipmark)
   and its meaning. The body pops in on a 90 ms spring; reduced motion shows
   it at once. */
.tk-notes { display: grid; margin: 0; padding: 0; background: var(--surface); border: var(--stroke-2) solid var(--outline);
  border-radius: var(--radius-tile); box-shadow: var(--shadow-sticker); }
.tk-notes > details + details { border-top: var(--stroke-2) solid var(--surface-2); }
.tk-notes summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 6px 16px;
  box-sizing: border-box; list-style: none; cursor: pointer; font-family: var(--font-display); font-size: 20px; font-weight: 800; line-height: 1.2; }
.tk-notes summary::-webkit-details-marker { display: none; }
.tk-notes summary > span { min-width: 0; overflow-wrap: anywhere; }
.tk-notes summary::after { content: "›"; flex: none; font-size: 24px; transition: transform 90ms cubic-bezier(.34, 1.56, .64, 1); }
.tk-notes details[open] > summary::after { transform: rotate(90deg); }
.tk-notes summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 14px; position: relative; z-index: 1; }
.tk-notes > details:first-child > summary { border-radius: calc(var(--radius-tile) - 2px) calc(var(--radius-tile) - 2px) 0 0; }
.tk-notes > details:last-child:not([open]) > summary { border-radius: 0 0 calc(var(--radius-tile) - 2px) calc(var(--radius-tile) - 2px); }
.kuma .tk-notes summary:hover { background: var(--paper); }
.tk-notes-b { display: grid; gap: 12px; padding: 2px 16px 16px; }
.tk-notes-r { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.45; }
.tk-notes-ex { display: grid; gap: 2px; margin: 0; padding: 12px 14px; border-radius: 12px; background: var(--surface-2); }
.tk-notes-ex b { font-size: 19px; font-weight: 800; line-height: 1.3; overflow-wrap: anywhere; }
.tk-notes-ex > span { font-size: 16px; font-weight: 600; line-height: 1.35; }
@media (prefers-reduced-motion: no-preference) {
  .tk-notes details[open] > .tk-notes-b { animation: tk-notes-in 90ms cubic-bezier(.34, 1.56, .64, 1) both; }
  .tk-notes summary:active { transform: translateY(2px); transition: transform 70ms; }
}
@media (prefers-reduced-motion: reduce) { .tk-notes summary::after { transition: none; } }
@keyframes tk-notes-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
/* A Plus tip on Free's tips page (tk-notes-lock, issue #146, Olivier 2026-10-23,
   point 131 A: "yes"). A row of the list, never a fold: the tip's name and a
   dashed "Plus" tag where a fold has its ›. A tk-lock: a tap wiggles the row
   (240 ms) and the line "Diesen Tipp gibt es mit Plus." pops in under the row
   (90 ms spring) for 4 s; reduced motion: no wiggle, no pop. No rule, no
   sentence, no Anhören (nothing shows that Free cannot have). The way to Plus
   is the one permanent line under the list (.tk-notes-plus), so nothing
   depends on the timer: web, the price link at the point of choice; app, no
   link and no price. */
.tk-notes > details + .tk-notes-lock, .tk-notes > .tk-notes-lock + details, .tk-notes > .tk-notes-lock + .tk-notes-lock { border-top: var(--stroke-2) solid var(--surface-2); }
.tk-notes-lock .tk-lock { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; min-height: 56px; padding: 6px 16px; }
.tk-notes-lock .tk-lock > span[lang], .tk-notes-lock .tk-lock > .tk-notes-n { font-family: var(--font-display); font-size: 20px; font-weight: 800; line-height: 1.2; }
.tk-notes-tag { display: inline-flex; align-items: center; flex: none; padding: 2px 10px; border-radius: var(--radius-pill);
  border: var(--stroke-2) dashed var(--outline); font-family: var(--font-body); font-size: 16px; font-weight: 800; line-height: 1.2; }
.tk-notes-lock .tk-lock-note { position: static; min-height: 0; margin-top: -6px; padding: 0 16px 12px; border: 0; box-shadow: none; background: none; }
.tk-notes-lock .tk-lock-note b { font-family: var(--font-body); font-size: 17px; font-weight: 700; }
.tk-notes-lock:first-child .tk-lock { border-radius: calc(var(--radius-tile) - 2px) calc(var(--radius-tile) - 2px) 0 0; }
.tk-notes-lock:last-child .tk-lock { border-radius: 0 0 calc(var(--radius-tile) - 2px) calc(var(--radius-tile) - 2px); }
.tk-notes-plus { display: flex; flex-wrap: wrap; align-items: center; column-gap: 12px; margin: 0; font-size: 17px; font-weight: 600; line-height: 1.35; }
.tk-notes-plus a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); font-weight: 800;
  text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.kuma .tk-notes-plus a:hover { color: var(--ink); }

/* A Tipp's Anhören (tk-tiphear, issue #146, Olivier 2026-10-23: "Also add
   anhören. That people can listen to the word in foreign. Maybe they cannot
   read it" and "B always free listen. They are cached fast."). The button is
   the learning card's own Anhören (.ob-pill.vx-say with veil, icon and bars,
   html/learn.html; states idle, loading, playing, failed in
   static/app-learn.css), so it looks and moves the same. It plays the tip's
   example sentence in the studied language. Always free, Free and Plus alike:
   never the sun badge (.ap-gratis), never "noch N gratis" in its name, never
   the locked "Anhören: Plus"; it does not count. This wrapper only places it:
   centred under the paper on the tip card, at the start under the meaning in
   an open fold. Its own 17 px, so the card's 15 px door rule never reaches it.
   Its name is "Anhören"; aria-describedby points at the sentence it plays. */
.tk-tiphear { display: flex; justify-content: center; }
.tk-notes-ex .tk-tiphear { justify-content: flex-start; margin-top: 10px; }
.tk-tiphear > .ob-pill { min-height: 48px; padding: 0 18px; font-size: 17px; }
/* An ending never breaks at its own hyphen ("- / eceksin"). */
.tk-notes-r [lang], .tk-ref-t [lang] { white-space: nowrap; }
.tk-ref-t > span[lang] { white-space: normal; }

/* Ideen (issue #184 design, #189 build): tk-idea (one idea: words, count, one vote), tk-vote (the toggle),
   tk-list, tk-askrow (the daily question on Learn's "Fertig für heute" only). */
/* One idea: its words, its count, one vote button. A sticker tile like tk-ref, but not a link. */
.tk-idea { box-sizing: border-box; display: grid; gap: 14px; width: 100%; padding: 16px; background: var(--surface); color: var(--ink);
  border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-tile); box-shadow: var(--shadow-sticker); }
.tk-idea-t { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.4; overflow-wrap: anywhere; }
.tk-idea-f { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 16px; }
.tk-idea-n { font-size: 17px; font-weight: 800; }
/* The vote: a toggle (aria-pressed). Off: paper. On: ink, and the words change, so colour is never alone. */
.tk-vote { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; min-height: 48px; min-width: 44px; padding: 0 22px;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-pill);
  font: 800 18px/1.1 var(--font-display); box-shadow: var(--shadow-button); cursor: pointer; text-decoration: none; }
.tk-vote[aria-pressed=true] { background: var(--ink); color: var(--on-ink); }
.tk-vote:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.tk-list { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }

/* The daily question on Learn's "Fertig für heute" screen, between the words panel and the way on: flat, dashed. Never a sticker, never a bubble, never terra. */
.tk-askrow { box-sizing: border-box; display: grid; gap: 12px; margin-top: 22px; padding: 16px; background: transparent; color: var(--ink);
  border: var(--stroke-2) dashed var(--outline); border-radius: var(--radius-tile); }
.tk-askrow-q { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.4; }
.tk-askrow-a { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; }
.tk-askrow-no { margin: 0; background: none; border: 0; font-family: inherit; cursor: pointer; display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; padding: 0 4px; font-size: 17px; font-weight: 700;
  color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.tk-askrow-no:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) { .tk-vote { transition: transform 70ms cubic-bezier(.34,1.6,.5,1); } .tk-vote:active { transform: translateY(3px); } }

/* The story on the start page (#201), design/story/. The two people are bears drawn like the crowd's (design/crowd/). One bear. Same drawing as design/kuma.svg (ears, body, snout, cheeks), in a
   stage colour, with a hard shadow and 2 px strokes. Never white, never
   cream: the one white bear is Kuma on the cards. */
.tk-pal { --c: var(--sun); --on: var(--on-sun); --k: 1; --r: 0;
  display: block; flex: none; width: calc(var(--pal-w) * var(--k)); height: auto; overflow: visible; transform-origin: 50% 100%; rotate: calc(var(--r) * 1deg); }
.tk-pal[data-c="sun"]   { --c: var(--sun);  --on: var(--on-sun); }
.tk-pal[data-c="mint"]  { --c: var(--mint); --on: var(--ink); }
.tk-pal[data-c="terra"] { --c: var(--terra); --on: var(--on-terra); }
.tk-pal[data-c="moss"]  { --c: var(--moss); --on: var(--on-moss); }
.tk-pal :is(path, circle, rect, ellipse) { vector-effect: non-scaling-stroke; }
.tk-pal .sh { fill: var(--outline); }
.tk-pal .b  { fill: var(--c); stroke: var(--outline); stroke-width: 2px; }
.tk-pal .in { fill: var(--blush); }
.tk-pal .ch { fill: var(--blush); }
.tk-pal .sn { fill: var(--kuma-snout); }
.tk-pal .no { fill: var(--kuma-nose); }
.tk-pal .mo { fill: none; stroke: var(--kuma-nose); stroke-width: 1.6px; stroke-linecap: round; stroke-linejoin: round; }
.tk-pal .mo.open { fill: var(--kuma-nose); }
.tk-pal .tg { fill: var(--blush); }
.tk-pal .ey { fill: var(--on); }
.tk-pal .hp { fill: none; stroke: var(--on); stroke-width: 2.4px; stroke-linecap: round; }
/* Drawn accessories: a different stage colour than the body, same 2 px outline. */
.tk-pal .ac { fill: var(--a, var(--terra)); stroke: var(--outline); stroke-width: 2px; stroke-linejoin: round; }
.tk-pal .cr { fill: var(--surface-2); stroke: var(--outline); stroke-width: 2px; }
.tk-pal .gl { fill: none; stroke: var(--on); stroke-width: 2.2px; stroke-linecap: round; }
.tk-pal .rb { fill: none; stroke: var(--outline); stroke-width: 1.6px; stroke-linecap: round; }
.tk-pal .bd { fill: none; stroke: var(--outline); stroke-width: 6px; stroke-linecap: round; }
.tk-pal .bc { fill: none; stroke: var(--a, var(--terra)); stroke-width: 2.4px; stroke-linecap: round; }

.st { gap: 22px; }
.st-lead { margin: 0; font-size: 19px; font-weight: 600; line-height: 1.5; max-width: 52ch; }

.st-frames { list-style: none; margin: 18px 0 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 34px 24px; }
@media (min-width: 900px) {
  .st-frames { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .st-f { grid-column: span 6; }
  .st-f.hero { grid-column: 1 / -1; }
  .st-f.hero .tk-bubble { max-width: 88%; }
}

/* One frame: a sticker with its number on the corner, the scene, one caption. */
.st-f { position: relative; box-sizing: border-box; display: flex; flex-direction: column; gap: 16px; min-width: 0; padding: 26px 18px 20px;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline); border-radius: 22px; box-shadow: var(--shadow-sticker); }
.st-n { position: absolute; top: -20px; left: 16px; display: grid; place-items: center; width: 44px; height: 44px; box-sizing: border-box;
  background: var(--ink); color: var(--on-ink); border: var(--stroke-2) solid var(--outline); border-radius: 50%;
  font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 1; }
.st-scene { flex: 1; justify-content: center; display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 16px 14px 18px; background: var(--surface-2); border-radius: var(--radius-tile); }
.st-place { font-size: 16px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }
.st-cap { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 1.15; text-wrap: balance; }

/* Bubbles reuse tk-bubble / tk-me. In a frame they fill the plate and may grow. */
.st-scene .tk-bubble, .st-scene .tk-me { max-width: 100%; box-sizing: border-box; overflow-wrap: anywhere; align-self: flex-start; }
.st-scene .tk-me { align-self: flex-end; margin-left: 0; }
.st-gl { display: block; margin: 4px 6px 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.st-scene .tk-say { align-self: flex-end; max-width: 100%; }
.st-grp { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.st-grp.me { align-items: flex-end; }

/* Frame 1: the learner's own card, plain white (a deck card, not Kuma). */
.st-card { align-self: center; box-sizing: border-box; display: flex; flex-direction: column; gap: 8px; width: min(100%, 300px); padding: 20px 20px 18px; transform: rotate(-1.5deg);
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--page-outline, var(--outline)); border-radius: 22px; box-shadow: 8px 10px 0 var(--page-outline, var(--outline)); }
.st-card b { font-family: var(--font-body); font-weight: 800; font-size: 26px; line-height: 1.15; }
.st-card span { font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ink-muted); }

/* Frame 3: her lines grow, yours stays one small bubble. The comedy is this size. */
.st-big1 { font-size: 20px; padding: 14px 18px; }
.st-big2 { font-size: 25px; padding: 16px 20px; line-height: 1.2; }
.st-big3 { font-size: clamp(27px, 4vw, 50px); padding: 18px 24px; line-height: 1.12; font-weight: 700; }
.st-big1, .st-big2, .st-big3 { border-radius: 30px 30px 30px var(--radius-tail); }
.st-tiny { font-size: 18px; padding: 8px 18px; letter-spacing: .12em; }
.st-scene.flood { justify-content: center; }

/* Frame 4 holds the app, so it says so: the practice talk with the KI badge. */
.st-keep { align-self: flex-end; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 22px; box-sizing: border-box;
  background: var(--surface); color: var(--ink); border: var(--stroke-2) solid var(--outline); border-radius: var(--radius-pill); box-shadow: var(--shadow-sticker);
  font-family: var(--font-display); font-weight: 800; font-size: 17px; }

.st-end { margin: 8px 0 0; font-family: var(--font-display); font-weight: 800; font-size: clamp(24px, 3vw, 32px); line-height: 1.12; max-width: 28ch; text-wrap: balance; }

/* Arrival. Every move is in within 70 to 110 ms on a spring; only the pauses are long.
   Each frame has its own data-play, so it starts when it scrolls into view (kuma.js adds
   and removes .wait). Played once, no loop. Without script it just plays. */
@keyframes st-in   { from { opacity: 0; transform: translateY(22px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes st-pop  { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } }
@keyframes st-grow { from { opacity: 0; transform: scale(.5) translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes st-shrink { 0% { transform: scale(1.35); } 100% { transform: none; } }
@keyframes st-shake  { 0%, 100% { translate: 0 0; } 25% { translate: -6px 0; } 50% { translate: 6px 0; } 75% { translate: -3px 0; } }
.st-f[data-play] { animation: st-in 110ms cubic-bezier(.3, 1.5, .5, 1) both; }
.st-a { transform-origin: 0 100%; animation: st-pop 100ms cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: var(--d, 300ms); }
.st-a.me { transform-origin: 100% 100%; }
.st-a.grow { animation-name: st-grow; animation-duration: 110ms; }
.st-a.tiny { animation: st-pop 100ms cubic-bezier(.3, 1.5, .5, 1) both var(--d), st-shake 220ms ease-out both calc(var(--d) + 160ms); }
.st-a.say { transform-origin: 100% 0; }
@media (prefers-reduced-motion: reduce) {
  .st-f, .st-a { animation: none !important; opacity: 1 !important; transform: none !important; translate: none !important; }
}

/* The two people: one bear per side, aria-hidden. Her stands left where her bubbles are, you right. */
.st .tk-pal { --pal-w: 66px; }
.st-who { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; min-height: 40px; }
.st-w { display: flex; align-items: flex-end; min-width: 0; }
.st-w.r { margin-left: auto; }
@media (min-width: 900px) { .st .tk-pal { --pal-w: 84px; } .st-f.hero .tk-pal { --pal-w: 100px; } }

/* Wort für Wort (issue #209; design/wort-fuer-wort/README.md): tk-pieces and
   tk-psheet (the sheet), tk-echo-link (the quiet link under the sentence),
   tk-faces (both faces of the card share one grid cell, so the grades never
   move). Tokens only. A piece is read, never pressed. */
.tk-pieces { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 20px 18px; margin: 0; padding: 0; list-style: none; }
.tk-piece { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.tk-piece b { font-family: var(--font-body); font-size: 24px; font-weight: 700; line-height: 1.2; padding-bottom: 8px; border-bottom: var(--stroke-2) solid var(--ink); overflow-wrap: anywhere; }
.tk-piece > span { font-family: var(--font-body); font-size: 20px; font-weight: 500; line-height: 1.25; overflow-wrap: anywhere; }

/* A dim is dark on every page: on-sun is ink in both themes, and the desktop app stays light in a dark system (point 129), so the page's own --ink or --paper would give a pale wash. */
.tk-psheet-scrim { position: fixed; inset: 0; background: color-mix(in srgb, var(--on-sun) 55%, transparent); z-index: 20; }
.tk-psheet { position: fixed; z-index: 21; left: 0; right: 0; bottom: 0; box-sizing: border-box; max-width: 560px; margin: 0 auto; max-height: 86dvh; overflow: auto;
  display: flex; flex-direction: column; gap: 18px; padding: 22px 20px 24px; background: var(--surface); color: var(--ink);
  border: var(--stroke-3) solid var(--outline); border-bottom: 0; border-radius: var(--radius-card) var(--radius-card) 0 0; box-shadow: var(--shadow-sticker); }
.tk-psheet-h { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.tk-psheet-h h2:focus { outline: none; }
.tk-psheet-h h2 { margin: 0; font-family: var(--font-display); font-size: 26px; font-weight: 800; line-height: 1.1; }
.tk-psheet-note { margin: 0; font-size: 18px; line-height: 1.35; }
.tk-psheet-mean { margin: 0; font-family: var(--font-body); font-size: 28px; font-weight: 800; line-height: 1.15; }
.tk-psheet-lead { margin: 0; font-family: var(--font-body); font-size: 24px; font-weight: 800; line-height: 1.2; }
.tk-psheet-fine { margin: 0; font-size: 16px; font-weight: 700; text-align: center; }
.tk-psheet-foot { display: flex; justify-content: center; }
.tk-psheet-fine a { display: inline-flex; align-items: center; min-height: 44px; color: inherit; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.tk-psheet-fine a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (min-width: 960px) { .tk-psheet { bottom: 50%; transform: translateY(50%); border-bottom: var(--stroke-3) solid var(--outline); border-radius: var(--radius-card); max-width: 600px; } }
@media (prefers-reduced-motion: no-preference) {
  .tk-psheet { animation: tk-psheet-in 90ms cubic-bezier(.2,1.3,.4,1) both; }
  @keyframes tk-psheet-in { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
  @media (min-width: 960px) { .tk-psheet { animation-name: tk-psheet-in-c; } @keyframes tk-psheet-in-c { from { transform: translateY(calc(50% + 24px)); opacity: 0; } to { transform: translateY(50%); opacity: 1; } } }
}

/* The door (Olivier, 2026-10-26: "L2 is good"): a quiet underlined link under
   the echo sentence on the back. No box. The sentence above stays plain, so
   the Tipp's underline (tk-tipmark) sits in it untouched. On a reverse card the
   link sits under the big target sentence. 44 px high, so it is a real target. */
.tk-echo-link { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px 8px; min-height: 44px; max-width: 100%; margin: 0; padding: 0 8px;
  border: 0; background: none; color: var(--ink); font: inherit; font-size: 16px; font-weight: 800; text-align: center; text-decoration: none; cursor: pointer; }
.tk-echo-link .t { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.tk-echo-link:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* On a forward card the link sits under the scrolling words, in the card's own gap; on a phone the spacing gives way at every height, never the sentence, and the sentence never shrinks as the phone gets taller (design-kuma, 2026-10-26; #325). */
.ap-card > .tk-echo-link { margin-top: -14px; }
@media (max-width: 959px) {
  .ap-card.b-only:has(> .tk-echo-link) { padding-top: 54px; }
  .ap-card.b-only:has(> .tk-echo-link) > .ap-text { gap: var(--space-2); }
}
.tk-echo-link.locked .t { text-decoration-style: dotted; }
.tk-echo-link .ap-gratis { flex: none; min-width: 28px; box-sizing: border-box; padding: 0 8px; text-align: center; border-radius: var(--radius-pill);
  background: var(--sun); color: var(--on-sun); border: var(--stroke-2) solid var(--outline); font-family: var(--font-display); font-size: 17px; font-weight: 800; line-height: 24px; }

/* Both faces of the card share one grid cell, so the card is always as high as the
   taller face and the grades never move when it turns (Olivier, 2026-10-26: "Make
   bigger that it does not jump"). The hidden face keeps its height, not its look. */
.tk-faces { display: grid; }
.tk-faces > .ap-card { grid-area: 1 / 1; }
.lr .tk-faces > .ap-card.f-only, .lr .tk-faces > .ap-card.b-only { display: flex !important; }
.lr:not(.is-back) .tk-faces > .b-only, .lr.is-back .tk-faces > .f-only { visibility: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .tk-echo-link.wig { animation: tk-lock-no 240ms cubic-bezier(.2,.9,.25,1) both; }
}
.tk-notes-b .tk-pieces { margin: 4px 0 8px; gap: 14px 14px; }

/* The KI ask (issue #253, design/ki-ask/README.md): tk-psheet holding the two equal
   buttons (tk-ask-btns, both tk-button tk-quiet, never terra) and the sheet's fine
   line. No Kuma face, no KI badge. On a page of its own (no script) the same class
   sits on .ki-page. Copied from design/components/bundle.css; keep both in step. */
.tk-kiask .tk-ask-top { margin: 0; font-size: 16px; font-weight: 800; line-height: 1.35; }
.tk-kiask .tk-ask-p { font-size: 18px; }
.tk-kiask .tk-ask-p + .tk-ask-p { margin-top: -8px; }
.tk-kiask .tk-ask-btns { box-sizing: border-box; align-self: stretch; width: 100%; max-width: none; margin: 0; grid-template-columns: 1fr 1fr; grid-column: auto; grid-row: auto; }
.tk-kiask .tk-ask-btns .tk-button { width: 100%; }
.tk-kiask .tk-psheet-fine { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; column-gap: 14px; }
.ki-page { box-sizing: border-box; max-width: 560px; margin: 0 auto; padding: 40px 20px; display: flex; flex-direction: column; gap: 18px; }
.ki-page h1 { margin: 0; font-family: var(--font-display); font-size: 30px; font-weight: 800; line-height: 1.1; }
.ki-page h1:focus { outline: none; }

/* The page break «Talkuma ist für die Leute.» with the crowd (issues #209 and
   #188; design/wort-fuer-wort/, design/crowd/). On Funktionen and the start
   page only. Tokens only; decorative, aria-hidden; still under reduced motion. */
/* Community break (Olivier, 2026-10-26): a page breaker between sections on
   Funktionen and on the start page. Type only, no picture, no Kuma. One
   marker (tk-hl) in the heading. */
.tk-break { border-top: var(--stroke-2) solid var(--outline); border-bottom: var(--stroke-2) solid var(--outline); background: var(--paper); }
.tk-break-in { box-sizing: border-box; max-width: 760px; margin: 0 auto; padding: 56px 20px; display: flex; flex-direction: column; gap: 14px; text-align: center; align-items: center; }
.tk-break h2 { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: clamp(32px, 4vw, 48px); line-height: 1.04; text-wrap: balance; }
.tk-break p { margin: 0; font-size: 19px; font-weight: 600; line-height: 1.5; max-width: 44ch; }

/* The grand break (Olivier, 2026-10-26: "make it HOLY SHIT WE ARE FOR THE PEOPLE").
   Bold from layout, colour and motion, never from more words. Ink band (it follows the
   theme), one huge line on a sun marker, a wall of sticker sentences that pop in once
   when the band scrolls into view (70 to 110 ms springs, 60 ms apart; still under
   reduced motion). The bears of #188 stand at its bottom; no emoji, no number nobody can check. */
/* The sentence stickers are light cards on every page (like Kuma's card): they take the light tokens, and their edge takes the band's text colour from here. */
.tk-break.grand { --sticker-edge: var(--on-ink); background: var(--ink); color: var(--on-ink); border-color: var(--ink); overflow: hidden; }
.tk-break.grand .tk-break-in { max-width: 1240px; padding: clamp(72px, 12vw, 144px) 20px clamp(64px, 10vw, 120px); gap: clamp(20px, 3vw, 36px); }
.tk-break.grand .tk-break-eye { font-size: 16px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.tk-break.grand h2 { display: flex; flex-direction: column; align-items: center; gap: .08em; font-size: clamp(34px, 6vw, 72px); line-height: 1; }
.tk-break.grand h2 .big { font-size: clamp(60px, 14vw, 176px); line-height: .94; letter-spacing: -.025em; }
.tk-break.grand .tk-hl { background: var(--sun); color: var(--on-sun); border-radius: 18px; padding: 0 .14em .04em; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.tk-break.grand p { font-size: clamp(19px, 2.2vw, 26px); max-width: 38ch; }
.tk-chorus { display: flex; flex-wrap: wrap; justify-content: center; gap: 18px 16px; margin: clamp(8px, 2vw, 24px) 0; padding: 0; list-style: none; }
.tk-chorus li { --r: 0deg; display: flex; flex-direction: column; gap: 4px; min-width: 150px; padding: 14px 18px; box-sizing: border-box; background: var(--surface); color: var(--ink); text-align: left;
  border: var(--stroke-2) solid var(--sticker-edge); border-radius: 16px; box-shadow: 4px 4px 0 var(--sticker-edge); transform: rotate(var(--r)); }
.tk-chorus li:nth-child(odd) { --r: -2deg; } .tk-chorus li:nth-child(even) { --r: 2.5deg; } .tk-chorus li:nth-child(3n) { --r: -1deg; }
.tk-chorus b { font-family: var(--font-body); font-size: 22px; font-weight: 700; line-height: 1.15; }
.tk-chorus small { font-size: 16px; font-weight: 700; color: var(--ink); }
.tk-chorus i { font-style: normal; font-size: 16px; font-weight: 800; letter-spacing: .1em; color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .tk-break.grand .tk-chorus li { animation: tk-chorus-in 90ms cubic-bezier(.34, 1.56, .64, 1) both; animation-delay: calc(var(--n, 0) * 60ms); }
  .tk-break.grand h2 .big { animation: tk-chorus-big 110ms cubic-bezier(.34, 1.56, .64, 1) both; }
  .tk-break.grand.wait *, [data-play].wait .tk-chorus li, [data-play].wait h2 .big { animation-play-state: paused; }
  @keyframes tk-chorus-in { from { opacity: 0; transform: translateY(14px) scale(.9) rotate(var(--r)); } to { opacity: 1; transform: rotate(var(--r)); } }
  @keyframes tk-chorus-big { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
}
.tk-break.grand h2 > .de, .tk-break.grand h2 > .en { display: flex; flex-direction: column; align-items: center; gap: .1em; }
.tk-break.grand h2 .big { font-size: clamp(56px, 12vw, 150px); }
@media (max-width: 640px) {
  .tk-chorus { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; gap: 16px 14px; }
  .tk-chorus li { min-width: 0; padding: 12px 14px; } .tk-chorus b { font-size: 19px; overflow-wrap: anywhere; } .tk-chorus small { font-size: 16px; }
}
.tk-chorus b:lang(ja), .tk-chorus b:lang(ko) { word-break: auto-phrase; line-break: strict; text-wrap: balance; }
/* The stage is the page break's ink band (chalk on the light page, dark on the dark page): the bears stand on its bottom edge, which is the ground. The outline is the band's text colour, so the bears keep a chalk outline on ink and a dark one on chalk. */
.tk-break-crowd { padding: 0 20px; box-sizing: border-box; overflow-x: clip; --outline: var(--on-ink); }

/* Two rows share one cell. The front row stands on the ground; the back row
   stands a step higher and a step smaller, so the front hides its feet. */
.tk-crowd { --pal-w: 82px; --amp: 0; --wave: 0; display: grid; justify-items: center; align-items: end; max-width: 1120px; margin: 0 auto;
  clip-path: inset(-48px -4px 0 -4px); }
.tk-crowd-row { grid-area: 1 / 1; display: flex; justify-content: center; align-items: flex-end; width: 100%; }
.tk-crowd-row > .tk-pal + .tk-pal { margin-left: calc(var(--pal-w) * -0.04); }
.tk-crowd-row.back { margin-bottom: calc(var(--pal-w) * 0.72); --pal-w: 62px; }
.tk-crowd-row.front { position: relative; z-index: 1; }
@media (min-width: 700px) { .tk-crowd { --pal-w: 124px; } .tk-crowd-row.back { --pal-w: 100px; } }
@media (max-width: 699px) { .tk-pal.wide { display: none; } }

/* One bear. Same drawing as design/kuma.svg (ears, body, snout, cheeks), in a
   stage colour, with a hard shadow and 2 px strokes. Never white, never
   cream: the one white bear is Kuma on the cards. */
.tk-pal { --c: var(--sun); --on: var(--on-sun); --k: 1; --r: 0; --ph: 0; --i: 0;
  display: block; flex: none; width: calc(var(--pal-w) * var(--k)); height: auto; overflow: visible; transform-origin: 50% 100%; }
.tk-pal[data-c="sun"]   { --c: var(--sun);  --on: var(--on-sun); }
.tk-pal[data-c="mint"]  { --c: var(--mint); --on: var(--ink); }
.tk-pal[data-c="terra"] { --c: var(--terra); --on: var(--on-terra); }
.tk-pal[data-c="moss"]  { --c: var(--moss); --on: var(--on-moss); }
.tk-pal :is(path, circle, rect, ellipse) { vector-effect: non-scaling-stroke; }
.tk-pal .sh { fill: var(--outline); }
.tk-pal .b  { fill: var(--c); stroke: var(--outline); stroke-width: 2px; }
.tk-pal .in { fill: var(--blush); }
.tk-pal .ch { fill: var(--blush); }
.tk-pal .sn { fill: var(--kuma-snout); }
.tk-pal .no { fill: var(--kuma-nose); }
.tk-pal .mo { fill: none; stroke: var(--kuma-nose); stroke-width: 1.6px; stroke-linecap: round; stroke-linejoin: round; }
.tk-pal .mo.open { fill: var(--kuma-nose); }
.tk-pal .tg { fill: var(--blush); }
.tk-pal .ey { fill: var(--on); }
.tk-pal .hp { fill: none; stroke: var(--on); stroke-width: 2.4px; stroke-linecap: round; }
/* Drawn accessories: a different stage colour than the body, same 2 px outline. */
.tk-pal .ac { fill: var(--a, var(--terra)); stroke: var(--outline); stroke-width: 2px; stroke-linejoin: round; }
.tk-pal .cr { fill: var(--surface-2); stroke: var(--outline); stroke-width: 2px; }
.tk-pal .gl { fill: none; stroke: var(--on); stroke-width: 2.2px; stroke-linecap: round; }
.tk-pal .rb { fill: none; stroke: var(--outline); stroke-width: 1.6px; stroke-linecap: round; }
.tk-pal .bd { fill: none; stroke: var(--outline); stroke-width: 6px; stroke-linecap: round; }
.tk-pal .bc { fill: none; stroke: var(--a, var(--terra)); stroke-width: 2.4px; stroke-linecap: round; }

/* Resting pose: a small tilt. */
.tk-pal { rotate: calc(var(--r) * 1deg); }

/* Scroll movement. Script-free, the crowd stands still in this pose. crowd.js
   only writes --amp (how hard the scroll pushes, 0 to 1, settles to 0 on its
   own) and --wave (how far the page has scrolled, in turns). Each bear hops
   on sin(x)^2, so it only ever goes up from the ground, and tilts on sin(x);
   --ph sets who is ahead of whom, so a wave runs through the crowd. */
@supports (translate: calc(sin(1turn) * 1px)) {
  .tk-pal {
    --x: calc((var(--wave) + var(--ph)) * 1turn);
    translate: 0 calc(sin(var(--x)) * sin(var(--x)) * var(--amp) * -14px);
    rotate: calc(var(--r) * 1deg + sin(var(--x)) * var(--amp) * 6deg);
  }
}

/* Arrival, once, when the crowd scrolls into view (kuma.js removes .wait from
   [data-play]): each bear rises from behind the ground line, 110 ms on a
   spring, 45 ms after the one before. Without the script it plays on load. */
@keyframes tk-pal-in { from { transform: translateY(104%) scale(.92); } 62% { transform: translateY(-7%) scale(1.03); } to { transform: none; } }
.tk-pal { animation: tk-pal-in 110ms cubic-bezier(.3, 1.5, .5, 1) backwards; animation-delay: calc(var(--i) * 45ms); }

@media (prefers-reduced-motion: reduce) {
  .tk-pal { animation: none; translate: none; rotate: calc(var(--r) * 1deg); }
}

/* The break's text block leaves room above the bears. */
.tk-break.grand .tk-break-in.crowded { padding-bottom: clamp(40px, 6vw, 72px); }
.hp-vis .tk-pieces { justify-content: center; }
.hp-vis .tk-piece b { font-size: 22px; } .hp-vis .tk-piece > span { font-size: 18px; }
.hp-pieces { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
