/* Nur Typing-Illustrationen. Seitengerüst, Tokens, Tarife und Abstände: zack.css. */
.logo-cursor { fill: var(--accent); stroke: var(--bg); stroke-width: 1.6; paint-order: stroke fill; }
.typing-hero-visual { position: relative; margin: 0; min-width: 0; }
.typing-preview-frame { width: min(100%, var(--preview-width) * 1px); aspect-ratio: var(--preview-width) / var(--preview-height); margin-inline: auto; }
/* Der Rahmen ist das Fenster selbst: kein eigener Rand oder Grund, der neben
   der App hervorblitzt. Radius wie --ca-r-window; der Ring ersetzt die Kante,
   die Windows um das Fenster zeichnet. */
.typing-preview { display: block; border: 0; width: 100%; height: 100%; background: transparent; pointer-events: none; color-scheme: normal; }
.typing-preview--app { border-radius: 8px; box-shadow: 0 0 0 1px var(--edge), var(--shadow-lg); }
.typing-preview-frame--pill { filter: drop-shadow(0 8px 10px rgba(0,0,0,.15)); }
.typing-preview--pill { border: 0; background: transparent; }
.typing-caret { display: inline-block; width: 2px; height: 1em; margin-left: 2px; vertical-align: -0.15em; background: var(--fg); }
.typing-section-title { text-align: center; margin-bottom: var(--sp-7); }

/* Funktionen: je ein Name, ein Satz und ein Beispiel zum Anfassen, als
   gemeinsame Kachelzeile (.showcase in zack.css). Die Beispiele sind
   Website-Illustrationen; nur die Kapsel darin ist die App (iframe mit
   App-CSS, typing-preview.js). typing.js führt die Fenster nach. */

/* Ein Bildschirm: die Kapsel schwebt oben mittig über einem beliebigen
   Programm, wie in der App. Eingeklappt steht sie über dem Fenster,
   aufgeklappt reicht sie hinein. --pill-w gilt für Breite und Abstand,
   beides bezogen auf die Bildschirmbreite (340 × 94 ist das Kapselfenster). */
.demo-screen { --pill-w: min(78%, 440px); }
.demo-screen .typing-preview-frame { position: absolute; z-index: 2; top: var(--sp-3); left: 50%; width: var(--pill-w); transform: translateX(-50%); filter: drop-shadow(0 10px 14px rgba(0, 0, 0, .16)); }
.typing-preview--live { pointer-events: auto; }
.demo-window { margin-top: calc(var(--pill-w) * .16); overflow: hidden; background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-sm); box-shadow: var(--shadow-md); }
/* Die fertige Pill im Chip-Beispiel steht immer offen; das Fenster beginnt darunter. */
.chips-demo .demo-window { margin-top: calc(var(--pill-w) * .26); }
.demo-titlebar { display: flex; align-items: center; height: 34px; padding-left: var(--sp-4); background: var(--surface-2); border-bottom: 1px solid var(--edge); font-size: .78rem; font-weight: 600; color: var(--fg-muted); }
.demo-controls { display: flex; height: 100%; margin-left: auto; }
.demo-controls svg { width: 40px; height: 100%; padding: 11px 14px; fill: none; stroke: var(--fg-subtle); stroke-width: 1.1; }

/* Umschalter über dem Wörterbuch-Beispiel. Ohne Skript verborgen. */
.demo-switch { display: flex; gap: 2px; width: fit-content; margin: 0 auto var(--sp-5); padding: 3px; background: var(--surface-2); border: 1px solid var(--edge); border-radius: var(--r-pill); }
.demo-switch[hidden] { display: none; }
.demo-switch-option { padding: 6px 14px; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--fg-muted); font: inherit; font-size: .82rem; font-weight: 600; cursor: pointer; transition: background-color .2s var(--ease), color .2s var(--ease); }
.demo-switch-option:hover { color: var(--fg); }
.demo-switch-option[aria-pressed="true"] { background: var(--surface); color: var(--fg); box-shadow: var(--shadow-sm); }

/* Neuer Text läuft mit weicher Kante von links ein (typing.js). */
.is-wiping { -webkit-mask-image: linear-gradient(90deg, #000 40%, transparent 60%); mask-image: linear-gradient(90deg, #000 40%, transparent 60%); -webkit-mask-size: 250% 100%; mask-size: 250% 100%; animation: demo-wipe 700ms var(--ease) both; }
@keyframes demo-wipe { from { -webkit-mask-position: 100% 0; mask-position: 100% 0; } to { -webkit-mask-position: 0 0; mask-position: 0 0; } }

/* Aufnahme-Pill: ein Chat, in dessen Eingabefeld der Text landet. */
.chat-thread { padding: var(--sp-5) var(--sp-5) var(--sp-4); }
.chat-message { display: flex; align-items: flex-start; gap: var(--sp-3); }
.chat-avatar { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--ok-soft); color: var(--ok); font-size: .85rem; font-weight: 700; }
.chat-message strong { font-size: .8rem; }
.chat-message p { margin: 2px 0 0; padding: 8px 12px; border-radius: 4px 14px 14px; background: var(--surface-2); font-size: .92rem; }
.chat-compose { display: flex; align-items: flex-end; gap: var(--sp-2); margin: 0 var(--sp-4) var(--sp-4); padding: 10px 10px 10px 14px; border: 1px solid var(--edge-strong); border-radius: var(--r-sm); }
.chat-input { flex: 1; min-height: calc(1.6em * 3); margin: 0; font-size: .92rem; line-height: 1.6; color: var(--fg); }
.chat-input:not(.has-text)::after { content: attr(data-placeholder); color: var(--fg-subtle); }
.chat-send { display: grid; place-items: center; flex: none; width: 30px; height: 30px; border-radius: var(--r-xs); background: var(--accent); color: var(--on-accent); transition: background-color .3s var(--ease), color .3s var(--ease); }
.chat-send .icon { width: 16px; height: 16px; }
.chat-input:not(.has-text) + .chat-send { background: var(--surface-3); color: var(--fg-subtle); }
.chat-input .typing-caret { animation: caret-blink 1.1s steps(1) infinite; }
@keyframes caret-blink { 50% { opacity: 0; } }

/* Textaktionen: eine E-Mail. Alle Fassungen liegen übereinander, damit das
   Fenster beim Wechseln nicht springt; sichtbar ist die gewählte. */
.mail-fields p { display: flex; align-items: center; gap: var(--sp-3); margin: 0; padding: 9px var(--sp-5); border-bottom: 1px solid var(--edge); font-size: .88rem; }
.mail-fields p > span:first-child { width: 4.5em; color: var(--fg-subtle); }
.mail-to { padding: 1px 10px; border-radius: var(--r-pill); background: var(--accent-soft); color: var(--accent-text); font-size: .82rem; font-weight: 600; }
.mail-body { display: grid; padding: var(--sp-5); }
.mail-variant { grid-area: 1 / 1; display: flex; flex-direction: column; visibility: hidden; }
.mail-variant.is-active { visibility: visible; }
.mail-text { margin: 0 0 var(--sp-5); font-size: .98rem; line-height: 1.65; }
.mail-text mark { padding: 0 3px; border-radius: 4px; }
/* Im Original die Füllwörter, beim Korrigieren die Korrekturen. */
.mail-text--0 mark { background: var(--warn-soft); color: var(--warn); }
.mail-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin: auto 0 0; padding-top: var(--sp-3); border-top: 1px dashed var(--edge-strong); font-size: .8rem; color: var(--fg-subtle); }
.mail-note { color: var(--accent-text); font-weight: 600; }
.mail-count { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Anleitungen: alle vier Fassungen nebeneinander statt des Umschalters. */
.variant-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); width: 100%; }
.variant-card { padding: var(--sp-4); border: 1px solid var(--edge); border-radius: var(--r-md); background: var(--surface); }
.variant-card:not(.is-original) { border-color: var(--accent-line); }
.prose .variant-label { margin: 0 0 var(--sp-2); font-size: .78rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-subtle); }
.prose .variant-card .mail-text { margin: 0 0 var(--sp-2); font-size: .95rem; line-height: 1.6; color: var(--fg); }
.prose .variant-note { margin: 0; font-size: .82rem; color: var(--accent-text); font-weight: 600; }

/* Wörterbuch: derselbe Satz ohne und mit; die Einträge darunter zeigen,
   was hineingehört. data-state steht am Beispiel (typing.js). */
.dict-doc { padding: var(--sp-5); background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-md); box-shadow: var(--shadow-md); }
.dict-label { display: flex; align-items: center; gap: 6px; margin: 0 0 var(--sp-3); font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-subtle); }
.dict-label .icon { width: 15px; height: 15px; }
.dict-sentence { margin: 0; font-size: 1.12rem; line-height: 1.75; }
/* Der Innenabstand der Markierung ragt in den Wortabstand, statt ihn zu verbreitern. */
.dict-term { display: inline-grid; margin-inline: -3px; vertical-align: bottom; }
.dict-term > span { grid-area: 1 / 1; padding: 0 3px; border-radius: 5px; transition: opacity .35s var(--ease), transform .35s var(--ease); }
.dict-term[data-term="1"] > span { transition-delay: .12s; }
.dict-term[data-term="2"] > span { transition-delay: .24s; }
.dict-wrong { color: var(--danger); text-decoration: underline wavy; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.dict-right { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
.dict-demo[data-state="without"] .dict-right { opacity: 0; transform: translateY(.4em); }
.dict-demo[data-state="with"] .dict-wrong { opacity: 0; transform: translateY(-.4em); }
.dict-status { margin: var(--sp-4) 0 0; font-size: .85rem; font-weight: 600; }
.dict-status > span { display: none; align-items: center; gap: 6px; }
.dict-status .icon { width: 16px; height: 16px; }
.dict-demo[data-state="without"] .dict-status-without { display: inline-flex; color: var(--danger); }
.dict-demo[data-state="with"] .dict-status-with { display: inline-flex; color: var(--ok); }
.dict-list { margin-top: var(--sp-5); }
.dict-list-title { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); font-size: .95rem; font-weight: 650; }
.dict-list-title .icon { width: 18px; height: 18px; color: var(--accent); }
.dict-groups { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
.dict-group { padding: var(--sp-3) var(--sp-4); background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-sm); }
.dict-group > p { margin: 0 0 var(--sp-2); font-size: .75rem; font-weight: 600; color: var(--fg-subtle); }
.dict-group > div { display: flex; flex-wrap: wrap; gap: 6px; }
.dict-entry { padding: 3px 10px; border: 1px solid var(--edge); border-radius: var(--r-pill); background: var(--surface-2); font-size: .82rem; font-weight: 600; transition: background-color .35s var(--ease), color .35s var(--ease), border-color .35s var(--ease); }
.dict-demo[data-state="with"] .dict-entry[data-term] { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent-line); }
@media (prefers-reduced-motion: reduce) {
  .chat-input .typing-caret { animation: none; }
  .dict-term > span, .dict-entry { transition: none; }
}

/* Tempovergleich: zwei Tachos auf derselben Skala (0–150 Wörter pro Minute).
   --gauge-share ist der Anteil am Skalenende (0…1), --gauge-turn der Zeigerwinkel. */
.speed { max-width: 820px; margin: auto; }
.speed-gauges { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
.gauge { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: center; padding: var(--sp-5) var(--sp-5) var(--sp-6); background: var(--bg-tint); border: 1px solid var(--edge); border-radius: var(--r-lg); }
.gauge--voice { border-color: var(--accent-line); background: radial-gradient(120% 90% at 50% 0%, var(--accent-soft), transparent 70%), var(--bg-tint); }
.gauge-title { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; font-size: 1.05rem; color: var(--fg-muted); }
.gauge-title .icon { width: 20px; height: 20px; }
.gauge--voice .gauge-title { color: var(--accent-text); }
.gauge-dial { display: block; width: 100%; max-width: 300px; margin-top: var(--sp-3); overflow: visible; font-family: inherit; }
.gauge-track, .gauge-arc { fill: none; stroke-width: 9; stroke-linecap: round; }
.gauge-track { stroke: var(--surface-3); }
.gauge-arc { stroke: var(--edge-strong); stroke-dasharray: 100 200; stroke-dashoffset: calc((1 - var(--gauge-share)) * 100); }
.gauge--voice .gauge-arc { stroke: var(--accent); filter: drop-shadow(0 0 5px var(--accent-line)); }
.gauge-tick { stroke: var(--edge-strong); stroke-width: 1.2; stroke-linecap: round; }
.gauge-tick.is-major { stroke: var(--fg-subtle); stroke-width: 2; }
.gauge-labels { fill: var(--fg-subtle); font-size: 10px; font-weight: 600; text-anchor: middle; font-variant-numeric: tabular-nums; }
.gauge-needle { transform-box: view-box; transform-origin: 100px 104px; transform: rotate(var(--gauge-turn)); }
.gauge-needle-idle { transform-box: view-box; transform-origin: 100px 104px; }
.gauge-needle path { fill: var(--fg-muted); }
.gauge--voice .gauge-needle path { fill: var(--accent); }
.gauge-hub { fill: var(--surface); stroke: var(--fg-muted); stroke-width: 3; }
.gauge--voice .gauge-hub { stroke: var(--accent); }
.gauge-value { fill: var(--fg); font-size: 38px; font-weight: 750; letter-spacing: -.02em; text-anchor: middle; font-variant-numeric: tabular-nums; }
.gauge--voice .gauge-value { fill: var(--accent-text); }
.gauge-unit { margin: var(--sp-1) 0 0; font-size: .85rem; font-weight: 600; color: var(--fg-muted); }
/* Hochlaufen (zack.js initSpeed): beide Zeiger starten gleichzeitig bei 0,
   schwingen kurz über und kommen zur Ruhe; danach zittern sie leicht wie ein
   laufendes Instrument. Ohne Skript oder bei reduzierter Bewegung: Endbild. */
.speed.is-ready .gauge-needle { transform: rotate(-120deg); }
.speed.is-ready .gauge-arc { stroke-dashoffset: 100; }
.speed.is-run .gauge-needle { transform: rotate(var(--gauge-turn)); transition: transform 1.9s cubic-bezier(.3, 1.35, .45, 1); }
.speed.is-run .gauge-arc { stroke-dashoffset: calc((1 - var(--gauge-share)) * 100); transition: stroke-dashoffset 1.9s cubic-bezier(.3, 1.35, .45, 1); }
.speed.is-live .gauge-needle-idle { animation: gauge-idle 2.6s ease-in-out infinite; }
.speed.is-live .gauge--keys .gauge-needle-idle { animation-duration: 1.7s; animation-timing-function: steps(6, jump-none); }
@keyframes gauge-idle { 0%, 100% { transform: rotate(-1.4deg); } 50% { transform: rotate(1.4deg); } }
.speed figcaption { margin-top: var(--sp-6); text-align: center; }
.speed-tagline { max-width: 560px; margin: 0 auto; font-size: 1.2rem; font-weight: 600; line-height: 1.45; color: var(--fg); text-wrap: balance; }
.speed-assumption { margin: var(--sp-3) 0 0; font-size: .75rem; color: var(--fg-subtle); }

/* Offline: Eine Aufnahme, zwei Wege. Links der Zack-Dienst, rechts das lokale
   Sprachmodell, dazwischen das Mikrofon. Ohne Animation steht der
   Offline-Zustand: Cloud-Weg getrennt, lokaler Weg aktiv. Mit Animation
   wechselt der Verbindungsstatus oben alle paar Sekunden und mit ihm der
   aktive Weg. */
.offline-flow { --disk: 76px; --source: 48px; --cycle: 9s; margin: 0; padding: var(--sp-6) var(--sp-5) var(--sp-7); }
/* Verbindungsstatus: beide Zustände liegen übereinander. */
.offline-net { display: grid; justify-items: center; margin-bottom: var(--sp-6); }
.offline-net-state { grid-area: 1 / 1; display: inline-flex; align-items: center; gap: var(--sp-2); padding: 6px 14px; border: 1px solid; border-radius: var(--r-pill); background: var(--surface); font-size: .85rem; font-weight: 600; }
.offline-net-state .icon { width: 18px; height: 18px; }
.offline-net-state--on { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, transparent); opacity: 0; }
.offline-net-state--off { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.offline-routes { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(20px, .7fr) var(--source) minmax(20px, .7fr) minmax(0, 1.3fr); align-items: start; }
.offline-source { display: grid; place-items: center; width: var(--source); height: var(--source); margin-top: calc((var(--disk) - var(--source)) / 2); border-radius: 50%; background: var(--surface); border: 1px solid var(--edge-strong); color: var(--fg-muted); }
.offline-source .icon { width: 22px; height: 22px; }
/* Wege: graue Grundlinie, darüber laufende Striche vom Mikrofon weg. */
.offline-link { position: relative; height: 2px; margin-top: calc(var(--disk) / 2 - 1px); background: var(--edge-strong); }
.offline-link::before { content: ""; position: absolute; inset: -1px 0; background: repeating-linear-gradient(90deg, var(--accent) 0 8px, transparent 8px 16px); }
.offline-link--cloud::before { opacity: 0; transform: scaleX(-1); }
.offline-cut { position: absolute; top: 50%; left: 50%; display: grid; place-items: center; width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%; background: var(--bg-tint); border: 2px solid var(--danger); color: var(--danger); }
.offline-cut .icon { width: 14px; height: 14px; stroke-width: 3; }
.offline-node { display: flex; flex-direction: column; align-items: center; gap: 2px; padding-inline: var(--sp-1); text-align: center; }
.offline-disk { position: relative; display: grid; place-items: center; width: var(--disk); height: var(--disk); margin-bottom: var(--sp-3); border-radius: 50%; background: var(--surface); border: 1px solid var(--edge); box-shadow: var(--shadow-sm); color: var(--accent); }
.offline-disk::after { content: ""; position: absolute; inset: -1px; border-radius: 50%; border: 1px solid var(--accent-line); background: var(--accent-soft-strong); box-shadow: 0 0 0 6px var(--accent-soft); }
.offline-disk > * { position: relative; z-index: 1; }
.offline-disk .icon { width: 28px; height: 28px; }
.offline-node strong { font-size: .95rem; line-height: 1.3; }
.offline-note { font-size: .8rem; color: var(--fg-muted); }
.offline-node--cloud { opacity: .45; }
.offline-node--cloud .offline-disk::after { opacity: 0; }
.offline-disk .typing-wave { display: flex; align-items: center; gap: 3px; height: 30px; }
.offline-disk .typing-wave-bar { display: block; width: 4px; height: calc(var(--bar) * 100%); border-radius: 4px; background: var(--accent); transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
  .offline-net-state--on, .offline-link--cloud::before, .offline-node--cloud .offline-disk::after { animation: offline-online var(--cycle) ease-in-out infinite; }
  .offline-net-state--off, .offline-cut, .offline-link--local::before, .offline-node--local .offline-disk::after { animation: offline-offline var(--cycle) ease-in-out infinite; }
  .offline-node--cloud { animation: offline-fade var(--cycle) ease-in-out infinite; }
  .offline-node--local { animation: offline-rise var(--cycle) ease-in-out infinite; }
  .offline-link::before { background-size: 32px 100%; }
  .offline-link--cloud::before, .offline-link--local::before { animation-name: offline-offline, offline-march; animation-duration: var(--cycle), .8s; animation-timing-function: ease-in-out, linear; animation-iteration-count: infinite; }
  .offline-link--cloud::before { animation-name: offline-online, offline-march; }
  .offline-disk .typing-wave-bar { animation: offline-bar 1.4s ease-in-out infinite alternate; }
  .offline-disk .typing-wave-bar:nth-child(2n) { animation-delay: -.5s; }
  .offline-disk .typing-wave-bar:nth-child(3n) { animation-delay: -.9s; }
}
/* Online bis 42 %, Umschalten, offline bis 92 %, zurück. */
@keyframes offline-online { 0%, 42% { opacity: 1; } 50%, 92% { opacity: 0; } 100% { opacity: 1; } }
@keyframes offline-offline { 0%, 42% { opacity: 0; } 50%, 92% { opacity: 1; } 100% { opacity: 0; } }
@keyframes offline-fade { 0%, 42% { opacity: 1; } 50%, 92% { opacity: .45; } 100% { opacity: 1; } }
@keyframes offline-rise { 0%, 42% { opacity: .45; } 50%, 92% { opacity: 1; } 100% { opacity: .45; } }
@keyframes offline-march { from { background-position: 0 0; } to { background-position: 16px 0; } }
@keyframes offline-bar { from { transform: scaleY(1); } to { transform: scaleY(.45); } }
@media (max-width: 520px) {
  .offline-flow { --disk: 60px; --source: 40px; padding-inline: var(--sp-3); }
  .offline-disk .icon { width: 24px; height: 24px; }
  .offline-disk .typing-wave { height: 24px; gap: 2px; }
  .offline-disk .typing-wave-bar { width: 3px; }
  .offline-node strong { font-size: .85rem; }
  .variant-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
  .demo-screen { --pill-w: min(92%, 400px); }
  .dict-doc { padding: var(--sp-4); }
  .dict-sentence { font-size: 1.02rem; }
  .chat-thread { padding: var(--sp-4); }
  .mail-fields p, .mail-body { padding-inline: var(--sp-4); }
  .speed-gauges { gap: var(--sp-3); }
  .gauge { padding: var(--sp-4) var(--sp-2) var(--sp-5); }
  .gauge-title { font-size: .95rem; }
  .gauge-unit { font-size: .75rem; text-align: center; }
  .speed-tagline { font-size: 1.05rem; }
  .offline-flow { --disk: 60px; padding: var(--sp-5) var(--sp-2) var(--sp-6); }
  .offline-disk .icon { width: 24px; height: 24px; }
  .offline-disk .typing-wave { height: 24px; gap: 2px; }
  .offline-disk .typing-wave-bar { width: 3px; }
  .offline-node strong { font-size: .85rem; }
  .offline-model { font-size: .72rem; }
  .offline-service { font-size: .78rem; padding: 5px 12px; }
}
