/* ---------------------------------------------------------------------------
   Community-Portal - Oberflaeche

   Farben, Schrift und Mark kommen aus der Docs-Site
   (docs-site/src/css/custom.css, Variante E vom 2026-08-16). Zwei Regeln von
   dort gelten hier genauso:

     Der Akzent traegt auf Dunkel #8E77FF, nicht das Editor-Blau. Das Blau ist
     ein Theme des Werkzeugs und kann die Marke nicht tragen.

     Inter Variable wird selbst ausgeliefert, nicht von Google geholt - die
     Wortmarke ist aus dieser Schrift gebaut.

   Aufbau und Maßstab (Karten, Seitenleiste, Pillen) folgen Meshy Creative Lab
   und der ElevenLabs-App.
--------------------------------------------------------------------------- */

@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/inter-var-latin.woff2') format('woff2-variations');
}

:root {
  /* Marke - der Akzent auf dunklem Grund */
  --accent: #8e77ff;
  --accent-strong: #a491ff;
  --accent-soft: rgba(142, 119, 255, 0.16);
  --accent-line: rgba(142, 119, 255, 0.38);
  --accent-ink: #120f1c;

  /* Grund und Tinte */
  --bg: #0e0d12;
  --bg-soft: #131218;
  --surface: #17161d;
  --surface-2: #211f2a;
  --line: #272531;
  --line-strong: #3a3747;
  --text: #eeecf3;
  --text-dim: #a9a4b6;
  /* 5.4:1 auf dem Grund, 5.0:1 auf einer Flaeche - vorher 3.6:1 bzw. 3.4:1,
     unter der WCAG-Grenze fuer genau den kleinen Text (Zahlen, Datum, Fuss),
     der diese Farbe traegt. */
  --text-faint: #8a8497;
  --surface-hover: #2a2836;

  /* Signale wie im Werkzeug: Gruen heisst "in Ordnung" */
  --ok: #3bd3a3;
  --warn: #fb923c;
  --danger: #f2706b;

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  /* HOEHEN. Geschichtete Schatten statt eines einzigen weichen Flecks: ein
     enger fuer die Kante, ein weiter fuer die Hoehe - so liegt eine Karte
     auf dem Grund, statt in einem Nebel zu schweben. Die Lichtkante oben
     (`--highlight`) gibt dunklen Flaechen eine Oberseite. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45), 0 4px 12px -4px rgba(0, 0, 0, 0.4);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 22px 44px -14px rgba(0, 0, 0, 0.7);
  --highlight: inset 0 1px 0 rgba(255, 255, 255, 0.045);
  --glow: 0 0 0 1px var(--accent-line), 0 18px 40px -14px rgba(142, 119, 255, 0.45);

  /* Signaltoene fuer Flaechen - vorher als rgba-Literale an elf Stellen. */
  --danger-soft: rgba(242, 112, 107, 0.12);
  --danger-line: rgba(242, 112, 107, 0.34);
  --scrim: rgba(6, 5, 10, 0.72);

  /* SCHRIFTGROESSEN. 22 verschiedene Pixelwerte standen im Stylesheet; die
     Grundbausteine lesen jetzt aus dieser Skala. */
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-md: 14px;
  --fs-base: 15px;
  --fs-lg: 17px;
  --fs-xl: 22px;
  --fs-2xl: 28px;
  --fs-3xl: 40px;

  /* Bewegung: kurz, ohne Nachfedern, am Ende weich. Wer weniger Bewegung
     eingestellt hat, bekommt alles auf einen Schlag (Abschnitt "Bewegung"
     ganz unten). */
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in-out: cubic-bezier(0.45, 0, 0.2, 1);
  --dur-fast: 120ms;
  --dur: 180ms;
  --dur-slow: 280ms;
  /* Breite des Inhalts. Der Katalog hebt sie fuer sich an - ein Gitter darf
     breiter stehen als ein Absatz, den jemand lesen soll. */
  --page: 1280px;
  --page-wide: 1640px;
  --gutter: 28px;

  /* Was vorher als Literal in einzelnen Regeln stand und in Hell etwas
     anderes sein muss. */
  --accent-lift: #b3a3ff;
  --accent-cast: rgba(142, 119, 255, 0.75);
  --accent-cast-strong: rgba(142, 119, 255, 0.9);
  --header-bg: rgba(14, 13, 18, 0.72);
  --row-hover: rgba(255, 255, 255, 0.02);
  --selection-bg: rgba(142, 119, 255, 0.38);
  --selection-ink: #ffffff;

  /* ── AUF DER BUEHNE ──────────────────────────────────────────────────
     Was auf der Vorschau liegt - die Dauerpille, die Schalter am Rand, der
     leere Rahmen, wenn ein Clip nicht laedt -, richtet sich nach der
     BUEHNE, nicht nach der Seite. Deshalb eigene Marken: ein Pillentext
     aus `--text-dim` stand in Hell dunkel auf der dunklen Pille.

     Bis 2026-09-25 blieb die Buehne in beiden Themen dunkel ("ein
     Viewport wie in Blender"). In Hell war sie damit auf jeder Karte ein
     dunkelvioletter Kasten; jetzt folgt sie dem Thema (stage.js,
     STAGE_LOOKS), und diese Marken folgen mit.

     `--stage-bg` ist der Himmel hinter der Figur - die Leinwand ist
     durchsichtig. Karte und grosse Buehne setzen die Mitte des Verlaufs
     verschieden hoch (20 % und 15 %), daher zwei. */
  --stage-bg: radial-gradient(120% 90% at 50% 15%, #1e1e23 0%, #0f0f12 70%);
  --stage-bg-card: radial-gradient(120% 90% at 50% 20%, #1e1e23 0%, #101013 70%);
  --stage-sheen: rgba(255, 255, 255, 0.045);
  --on-stage-ink: #eeecf3;
  --on-stage-dim: #a9a4b6;
  --on-stage-faint: #8a8497;
  --on-stage-line: #3a3747;
  --on-stage-accent: #8e77ff;
  --on-stage-accent-line: rgba(142, 119, 255, 0.38);
  --on-stage-accent-veil: rgba(142, 119, 255, 0.14);
  --on-stage-scrim: rgba(14, 13, 18, 0.72);
  --on-stage-scrim-strong: rgba(14, 13, 18, 0.84);
  --stage-void: #0e0d12;


  color-scheme: dark;
}

/* ══════════════════════════════════════════════════════════════════════
   HELL

   Kein zweites Stylesheet und keine Kopie der Regeln: derselbe Satz
   Marken, andere Werte. Was hier NICHT noch einmal steht, gilt weiter -
   Radien, Schriftgroessen, Bewegung.

   WER UMSCHALTET, STEHT IN `theme.js`. Das Attribut ist die einzige
   Weiche; eine zweite Fassung dieser Werte unter `prefers-color-scheme`
   waere dieselbe Palette an zwei Orten und liefe beim ersten Nachbessern
   auseinander.

   DIE ZAHLEN SIND GEMESSEN, nicht geschaetzt - der dunkle Satz traegt an
   `--text-faint` eine Notiz darueber, dass 3.6:1 zu wenig waren, und
   dieselbe Latte gilt hier. Auf `--bg`: Text 16.8:1, `--text-dim` 6.6:1,
   `--text-faint` 5.4:1, Akzent 6.2:1, Gruen 5.4:1, Orange 5.5:1, Rot
   5.4:1. Weiss auf dem Akzentknopf 6.6:1, auf seinem hellsten
   Verlaufsende noch 4.9:1.

   DER AKZENT IST EIN ANDERER. #8E77FF steht auf Weiss bei 2.6:1 - als
   Flaeche schoen, als Link unlesbar. Hell traegt deshalb ein dunkleres
   Violett derselben Familie. Die Marke selbst bleibt beim hellen Ton;
   sie liegt nie auf Weiss.
   ══════════════════════════════════════════════════════════════════════ */
:root[data-theme="light"] {
  --accent: #5f3fd6;
  --accent-strong: #6b4ae0;
  --accent-lift: #7358e6;
  --accent-soft: rgba(95, 63, 214, 0.10);
  --accent-line: rgba(95, 63, 214, 0.30);
  --accent-ink: #ffffff;
  --accent-cast: rgba(95, 63, 214, 0.30);
  --accent-cast-strong: rgba(95, 63, 214, 0.40);

  --bg: #f7f6fa;
  --bg-soft: #f1eff6;
  --surface: #ffffff;
  --surface-2: #f4f2f9;
  --surface-hover: #ebe8f3;
  --line: #e2dfec;
  --line-strong: #cdc8dc;
  --text: #17151f;
  --text-dim: #5b5570;
  --text-faint: #676180;

  --ok: #0a7355;
  --warn: #9a5205;
  --danger: #bd302b;
  --danger-soft: rgba(189, 48, 43, 0.10);
  --danger-line: rgba(189, 48, 43, 0.30);

  /* Schatten auf Hell sind eine Frage der Dosis: derselbe Schwarzanteil
     wie in Dunkel waere ein Schmutzrand. Ein Hauch Violett darin, damit
     sie neben dem Grund nicht grau stehen. */
  --shadow-sm: 0 1px 2px rgba(28, 22, 50, 0.06), 0 4px 12px -4px rgba(28, 22, 50, 0.10);
  --shadow: 0 1px 2px rgba(28, 22, 50, 0.06), 0 22px 44px -14px rgba(28, 22, 50, 0.16);
  /* Die Lichtkante dreht sich um: auf Dunkel hebt sie die Oberseite an,
     auf Hell ist sie das Weiss, mit dem eine Flaeche vom Grund abhebt. */
  --highlight: inset 0 1px 0 rgba(255, 255, 255, 0.75);
  --glow: 0 0 0 1px var(--accent-line), 0 18px 40px -14px rgba(95, 63, 214, 0.28);
  --scrim: rgba(24, 20, 40, 0.42);

  --header-bg: rgba(247, 246, 250, 0.78);
  --row-hover: rgba(24, 20, 40, 0.035);
  --selection-bg: rgba(95, 63, 214, 0.22);
  --selection-ink: #17151f;

  /* Die Buehne als Fotostudio: heller Himmel, der nach unten in dasselbe
     Grau laeuft wie der Boden am Horizont (`haze` in stage.js). Die Figur
     ist weiss, also darf der Grund nicht ganz weiss sein - sonst hat sie
     keine Kante. */
  --stage-bg: radial-gradient(120% 90% at 50% 15%, #f2f2f6 0%, #dddce4 72%);
  --stage-bg-card: radial-gradient(120% 90% at 50% 20%, #f2f2f6 0%, #dddce4 72%);
  --stage-sheen: rgba(255, 255, 255, 0.55);
  --on-stage-ink: #17151f;
  --on-stage-dim: #4f4a62;
  --on-stage-faint: #676180;
  --on-stage-line: rgba(23, 21, 31, 0.12);
  --on-stage-accent: #5f3fd6;
  --on-stage-accent-line: rgba(95, 63, 214, 0.30);
  --on-stage-accent-veil: rgba(95, 63, 214, 0.10);
  --on-stage-scrim: rgba(255, 255, 255, 0.72);
  --on-stage-scrim-strong: rgba(255, 255, 255, 0.88);
  --stage-void: #ebeaf0;

  color-scheme: light;
}

html { font-feature-settings: 'cv05' 1, 'cv08' 1, 'ss03' 1; }

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }
/* Unsichtbare Tooltips (`[data-tip]::after`) liegen mit voller Breite im
   Layout; an einem Knopf am rechten Rand schoben sie die Seite 35 px ueber
   den Bildschirm hinaus - ein waagerechter Scrollbalken auf jedem Telefon.
   `clip` statt `hidden`: es macht kein Scroll-Element daraus, der klebende
   Kopf klebt weiter. */
html { overflow-x: clip; scrollbar-color: var(--line-strong) transparent; }
::selection { background: var(--selection-bg); color: var(--selection-ink); }

body {
  /* Ein Schein im Akzent ganz oben - er gibt der Seite eine Lichtquelle, statt
     sie als flaches Schwarz stehen zu lassen. Er scrollt mit und ist nach
     einem Bildschirm vorbei. */
  background:
    radial-gradient(1100px 520px at 50% -200px, color-mix(in srgb, var(--accent) 12%, transparent), transparent 70%),
    var(--bg);
  color: var(--text);
  font: 16px/1.6 'Inter Variable', Inter, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.hidden { display: none !important; }

/* TASTATUR-FOKUS. Eingabefelder hatten einen eigenen Ring, Icon-Knoepfe,
   Schlagworte, Chips und Reiter nur den des Browsers - auf diesem Grund
   praktisch unsichtbar. Jetzt ein Ring fuer alles, was man anfassen kann,
   aber nur fuer die Tastatur (:focus-visible), nicht nach jedem Mausklick. */
a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -48px;
  z-index: 100;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.skip-link:focus-visible { top: 12px; }

/* Fuer Screenreader da, fuer das Auge nicht - die Seitenueberschrift von
   Katalog und Sammlungen, seit der Reiter oben sie sichtbar vertritt. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Kopfleiste ────────────────────────────────────────────────────────
   Oben statt links. Die feste Spalte links war das Muster einer App; das
   Portal ist aber das Schaufenster vor der App, und der Katalog ist die
   Ansicht, bei der jede gesparte Breite unmittelbar eine Karte mehr pro
   Reihe bedeutet. Meshy Creative Lab und Mixamo tragen ihre Navigation
   beide oben.

   Vier Blöcke in einer Zeile: Marke, Navigation, Suche, Konto. Die Suche
   nimmt den Platz, der übrig bleibt, und ist als einzige elastisch - bei
   wenig Raum schrumpft sie, statt dass etwas umbricht.
--------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--header-bg);
  backdrop-filter: saturate(150%) blur(16px);
  border-bottom: 1px solid var(--line);
}

/* KEINE Seitenbreite hier. Der Kopf ist ein Band ueber die volle Breite, und
   die Marke sitzt an seinem linken Rand. Vorher galt fuer ihn dieselbe
   `--page`-Breite wie fuer einen Absatz: auf einem 1600er Schirm stand die
   Marke damit 160 px eingerueckt und wirkte verrutscht - auf dem Katalog, der
   `--page-wide` nutzt, sogar gegenueber dem Inhalt DARUNTER. Ein Absatz
   braucht sein Lesemass, ein Band nicht. */
.header-inner {
  padding: 0 var(--gutter);
  height: 60px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  margin-right: 12px;
  color: var(--text);
}
.brand:hover { text-decoration: none; }

/* Das Lockup haelt seinen Freiraum: ein Viertel der eigenen Hoehe ringsum. */
/* Klein wie bei YouTube: das Zeichen fuehrt, die Schrift (Inter 600) steht
   nur wenig ueber der Navigation. Die erste Fassung war Inter 800 bei 25 px -
   sie schrie lauter als alles darunter. */
.brand-lockup { width: 123px; height: auto; display: block; }
.brand-mark { width: 28px; height: 28px; display: none; }

/* DIE MARKE IN TINTE. Die ausgelieferte Datei ist die weisse - sie steht auf
   dem dunklen Grund, und das ist der Normalfall. Auf Hell waere sie weiss auf
   fast weiss, also unsichtbar.

   `content` tauscht das Bild, statt ein zweites in den Kopf zu legen: so
   bleibt EIN Element im Dokument und der Browser holt nur die Fassung, die er
   zeigt. Die Adresse ist relativ zu DIESER Datei und traegt damit denselben
   Stempel wie alles andere unter /assets - eine absolute stuende ohne ihn da
   und laege nach dem naechsten Build im Cache fest. */
:root[data-theme="light"] .brand-lockup { content: url("brand/playmations-lockup-tinte.svg"); }
:root[data-theme="light"] .brand-mark { content: url("brand/playmations-mark-tinte.svg"); }

.site-nav { display: flex; align-items: center; gap: 2px; flex: none; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: 14.5px;
  font-weight: 500;
  white-space: nowrap;
}
.nav-item:hover { background: var(--surface); color: var(--text); text-decoration: none; }
.nav-item.active { background: var(--surface-2); color: var(--text); }
.nav-item.active .nav-icon { color: var(--accent); }
.nav-icon { width: 18px; height: 18px; flex: none; color: var(--text-faint); }

/* ── Suche im Kopf ─────────────────────────────────────────────────────
   Ein gewöhnliches GET-Formular auf den Katalog. Das `kbd` nennt die Taste,
   die hierher springt, und verschwindet, sobald das Feld den Fokus hat -
   dann ist die Auskunft erledigt.
--------------------------------------------------------------------------- */

.header-search {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 460px;
  margin-inline: auto;
  position: relative;
  display: flex;
  align-items: center;
}
.header-search svg {
  position: absolute;
  left: 13px;
  width: 17px;
  height: 17px;
  color: var(--text-faint);
  pointer-events: none;
}
.header-search input {
  width: 100%;
  min-height: 38px;
  padding: 0 38px 0 38px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  font-size: 14.5px;
}
.header-search input:focus { background: var(--bg-soft); }
.header-search kbd {
  position: absolute;
  right: 12px;
  font: inherit;
  font-size: 12px;
  line-height: 1;
  color: var(--text-faint);
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  padding: 3px 6px;
  pointer-events: none;
}
.header-search input:focus ~ kbd,
.header-search input:not(:placeholder-shown) ~ kbd { display: none; }

.header-account { flex: none; display: flex; align-items: center; gap: 8px; margin-left: 4px; }

/* DER UMSCHALTER. Er traegt beide Zeichen im Markup und zeigt immer das,
   WOHIN es geht - in Dunkel die Sonne, in Hell den Mond. Das spart das
   Nachmalen per Skript und damit die Trusted-Types-Frage; die Auswahl ist
   eine Regel, kein Austausch.

   `hidden` steht im HTML: ohne `theme.js` schaltet hier nichts, und ein
   Knopf, der nichts tut, ist schlimmer als keiner. Das Skript nimmt es
   weg, sobald es laeuft. */
.theme-toggle {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.theme-toggle:hover { color: var(--text); border-color: var(--line-strong); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .theme-moon { display: none; }
:root[data-theme="light"] .theme-toggle .theme-moon { display: block; }
:root[data-theme="light"] .theme-toggle .theme-sun { display: none; }

/* `position: relative` HIER und nicht an Glocke und Name: beide Kaesten
   haengen am rechten Rand des Kontoblocks. An der Glocke verankert, lief der
   breitere Nachrichtenkasten auf dem Telefon links aus dem Bild. */
.account { position: relative; display: flex; align-items: center; gap: 8px; }

.account-name {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 210px;
  padding: 4px 8px 4px 4px;
  border-radius: var(--radius-pill);
  color: var(--text);
  font-size: 14px;
}
.account-name:hover,
.account-name[aria-expanded="true"] { background: var(--surface); text-decoration: none; }
.account-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-chevron {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--text-faint);
  transition: transform var(--dur-fast) var(--ease-out);
}
.account-name[aria-expanded="true"] .account-chevron { transform: rotate(180deg); }

/* Die Glocke - dieselbe Kachel wie der Themenumschalter daneben. */
.header-icon {
  position: relative;
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-dim);
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.header-icon:hover,
.header-icon[aria-expanded="true"] { color: var(--text); border-color: var(--line-strong); text-decoration: none; }
.header-icon svg { width: 18px; height: 18px; }

.bell-count {
  position: absolute;
  top: -6px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  border: 2px solid var(--bg);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
}

/* ── Die Kaesten unter Glocke und Name ─────────────────────────────── */

.header-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 90;
  width: 300px;
  /* Beidseits der Seitenrand: der Kasten haengt am rechten Rand des
     Kontoblocks, der steht einen Rand vom Fensterrand entfernt. */
  max-width: calc(100vw - 2 * var(--gutter));
  background: var(--bg-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 6px;
  animation: aw-rise-small var(--dur) var(--ease-out) backwards;
}
.header-panel[hidden] { display: none; }

.account-menu-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 10px 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}
.account-menu-head .avatar { width: 40px; height: 40px; font-size: 16px; }
.account-menu-who { display: flex; flex-direction: column; min-width: 0; }
.account-menu-who strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.menu-row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  width: 100%;
  min-height: 0;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  box-shadow: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.menu-row:active { transform: none; }
.menu-row:hover, .menu-row:focus-visible { background: var(--surface-2); text-decoration: none; }
.menu-row svg { width: 18px; height: 18px; flex: none; color: var(--text-dim); }
.menu-row:hover svg { color: var(--accent); }
.menu-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.menu-text strong { font-weight: 600; font-size: 14px; }
.menu-text small { color: var(--text-faint); font-size: 12.5px; }
.menu-divider { height: 1px; margin: 4px 6px; background: var(--line); }

/* Der Nachrichtenkasten: breiter, mit Kopfzeile und eigener Rolle. */
.notifications-panel { width: 380px; padding: 0; overflow: hidden; }
.notifications-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--line);
}
.notifications-head strong { font-size: 14px; }
.notifications-head a { font-size: 13px; }
.notifications-scroll { max-height: min(60vh, 440px); overflow-y: auto; padding: 4px; }
.notifications-empty { margin: 0; padding: 18px 14px; color: var(--text-dim); font-size: 13.5px; }

/* ── Eine Nachricht ────────────────────────────────────────────────────
   Dieselbe Zeile im Kasten und auf der Kontoseite. Die ganze Zeile fuehrt
   zum Ziel (Clip, Sammlung, Profil) - ueber das `::after` des Ziel-Links,
   wie bei den Karten. Der Name darin ist ein eigener Link aufs Profil und
   liegt deshalb darueber. */
.notification {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 10px;
  border-radius: var(--radius-sm);
}
.notification:has(.notification-target):hover { background: var(--surface-2); }
.notification .avatar { width: 32px; height: 32px; font-size: 13px; }
.notification-kind {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text-dim);
}
.notification-kind .icon { width: 17px; height: 17px; }
.notification-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.notification-body p { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--text-dim); overflow-wrap: anywhere; }
.notification-actor { position: relative; z-index: 1; font-weight: 600; color: var(--text); }
.notification-body time { font-size: 12px; color: var(--text-faint); }
.notification-target::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.notification-target { color: inherit; }
.notification-target:hover { text-decoration: none; }
.notification.unread .notification-body p { color: var(--text); }
.notification.unread::before {
  content: "";
  position: absolute;
  top: 50%;
  right: 10px;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
.notification.unread { padding-right: 26px; }
.notification-list { display: flex; flex-direction: column; gap: 2px; }

.avatar {
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-weight: 700;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}

img.avatar { object-fit: cover; padding: 0; background: var(--surface-2); }

/* Schmale Fenster: die Wortmarke weicht der Bildmarke, die Beschriftungen der
   Navigation weichen ihren Symbolen. Die Suche bleibt - sie ist der Grund,
   warum die Leiste oben liegt. */
@media (max-width: 1080px) {
  .brand-lockup { display: none; }
  .brand-mark { display: block; }
  .nav-item span { display: none; }
  .nav-item { padding: 8px 10px; }
  .nav-icon { width: 20px; height: 20px; }
  .account-label { display: none; }
  .account-name { padding: 4px 6px 4px 4px; gap: 4px; }
}
/* Auf einem Telefon passt die Suche nicht neben Marke, Navigation und Konto -
   sie wurde vom Anmelde-Knopf ueberschrieben. Also zwei Zeilen: oben, wer und
   wohin, darunter die Suche ueber die ganze Breite. */
@media (max-width: 620px) {
  .header-inner {
    flex-wrap: wrap;
    height: auto;
    padding-block: 10px 12px;
    row-gap: 10px;
  }
  .header-search {
    order: 3;
    flex-basis: 100%;
    max-width: none;
    margin-inline: 0;
  }
  .header-search kbd { display: none; }
  .header-account { margin-left: auto; }
  .site-nav { gap: 0; }
  .header-account .button { padding: 0 14px; font-size: 14px; }

}

/* ── Seitengerüst ──────────────────────────────────────────────────────
   `--page` ist die Breite des Inhalts, `--gutter` sein Rand. Der Katalog
   setzt `--page` auf seinen eigenen Wert hoch: ein Gitter darf breiter
   stehen als ein Absatz, den man lesen soll.
--------------------------------------------------------------------------- */

main {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding: 36px var(--gutter) 80px;
  flex: 1;
}

/* Der Katalog (zugleich die Startseite) und die Sammlungen stellen Ware aus,
   keinen Fliesstext: dort bedeutet jede zusaetzliche Breite eine Karte mehr
   pro Reihe. */
main.wide { max-width: var(--page-wide); }

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: 13px;
}
/* Alles auf EINER Achse: "Powered by", darunter die Links, darunter der
   Build. Vorher standen die Links links und der Build rechts - die Zeile war
   als Ganzes zentriert, der Build zaehlte also mit, und die Links allein
   standen links von der Mitte, unter dem mittigen "Powered by" verrutscht.
   Den Build rechts zu lassen und nur die Links zu zentrieren traegt nicht:
   "Build 60 - af67710 - 2026-09-27 21:28 UTC" ist so lang, dass die Links
   unterhalb von gut 1400 px wieder aus der Mitte rutschen. */
.footer-inner {
  max-width: var(--page);
  margin-inline: auto;
  padding: 16px var(--gutter) 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.footer-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; }

/* "Powered by": mittig ueber den Links, leiser als die Marke oben - sie
   nennt, worauf das Portal laeuft, und soll nicht mit Playmations reden. */
.footer-powered {
  display: flex;
  justify-content: center;
  padding: 28px var(--gutter) 0;
}
.site-footer .powered-by {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-faint);
  font-size: 12px;
  white-space: nowrap;
}
.site-footer .powered-by:hover { color: var(--text-dim); text-decoration: none; }
.powered-lockup { width: 120px; height: auto; display: block; opacity: 0.8; }
.powered-by:hover .powered-lockup { opacity: 1; }
:root[data-theme="light"] .powered-lockup { content: url("brand/aw-lockup-tinte.svg"); }
.powered-by small {
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-left: 1px solid var(--line-strong);
  padding-left: 8px;
}
.site-footer a { color: var(--text-faint); }
.site-footer a:hover { color: var(--text-dim); }

/* ── Typografie ────────────────────────────────────────────────────────── */

h1 {
  font-size: var(--fs-3xl);
  line-height: 1.1;
  letter-spacing: -0.028em;
  font-weight: 800;
  margin: 0 0 10px;
}

h2 {
  font-size: 20px;
  line-height: 1.3;
  letter-spacing: -0.018em;
  font-weight: 800;
  margin: 36px 0 14px;
}

.lead { color: var(--text-dim); font-size: 16px; margin: 0 0 28px; max-width: 62ch; }
.muted { color: var(--text-dim); }
.faint { color: var(--text-faint); }
.small { font-size: var(--fs-sm); }

/* Ein Akzentstrich unter der Seitenüberschrift, wie im Kreativlabor. */
main > h1::after, .prose > h1::after {
  content: "";
  display: block;
  width: 64px;
  height: 3px;
  margin-top: 14px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent), transparent);
}

/* ── Knöpfe ────────────────────────────────────────────────────────────── */

.button, button {
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-base);
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  box-shadow: var(--highlight);
  color: var(--text);
  min-height: 40px;
  padding: 0 18px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.button:hover, button:hover { background: var(--surface-hover); border-color: var(--line-strong); text-decoration: none; }
.button:active, button:active { transform: translateY(1px); }

.button.primary, button.primary {
  background: linear-gradient(180deg, var(--accent-strong), var(--accent));
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 8px 22px -10px var(--accent-cast);
}
.button.primary:hover, button.primary:hover {
  background: linear-gradient(180deg, var(--accent-lift), var(--accent-strong));
  border-color: var(--accent-strong);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.26), 0 10px 28px -10px var(--accent-cast-strong);
}

.button.danger, button.danger { border-color: color-mix(in srgb, var(--danger) 50%, transparent); color: var(--danger); background: transparent; box-shadow: none; }
.button.danger:hover, button.danger:hover { background: var(--danger-soft); }

.button.ghost, button.ghost { background: transparent; border-color: var(--line); color: var(--text-dim); box-shadow: none; }
.button.ghost:hover, button.ghost:hover { color: var(--text); background: var(--surface); }

button:disabled { opacity: 0.45; cursor: default; transform: none; }

/* ── Felder ────────────────────────────────────────────────────────────── */

input, select, textarea {
  font: inherit;
  font-size: 15px;
  background: var(--bg-soft);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 9px 13px;
  min-height: 40px;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }
textarea { width: 100%; min-height: 100px; resize: vertical; line-height: 1.5; }

label.field { display: block; margin: 0 0 16px; }
label.field > span { display: block; color: var(--text-dim); font-size: 14px; margin-bottom: 6px; }
label.field input, label.field select { width: 100%; }
label.check { display: flex; gap: 12px; align-items: flex-start; margin: 12px 0; color: var(--text-dim); font-size: 15px; }
label.check input { min-height: 0; margin-top: 4px; accent-color: var(--accent); }

/* ── Flächen ───────────────────────────────────────────────────────────── */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--highlight);
  border-radius: var(--radius);
  padding: 22px 24px;
}

.notice {
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  margin: 14px 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  font-size: 15px;
}
.notice.error { border-left-color: var(--danger); }
.notice.ok { border-left-color: var(--ok); }
.notice.warn { border-left-color: var(--warn); }

/* ── Meldungen am unteren Rand (AW.toast) ─────────────────────────────── */
/* Unten mittig, ueber allem ausser einem offenen Dialog. Der Stapel selbst
   laesst Klicks durch; nur die Meldungen fangen sie. */
.toasts {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: max-content;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px 10px 12px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  color: var(--text);
  box-shadow: var(--shadow);
  font-size: 14px;
}
.toast .icon { width: 18px; height: 18px; flex: none; color: var(--ok); }
.toast.error .icon { color: var(--danger); }
.toast.leaving { opacity: 0; }
.toast-action {
  min-height: 0;
  padding: 2px 4px;
  margin-left: 4px;
  border: 0;
  background: none;
  color: var(--accent);
  font-weight: 600;
  cursor: pointer;
}

.tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.tag {
  background: var(--surface-2);
  color: var(--text-dim);
  border-radius: var(--radius-pill);
  padding: 4px 13px;
  font-size: 13px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.tag:hover { color: var(--text); background: var(--surface-hover); border-color: var(--line-strong); text-decoration: none; }
.tag.active {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent);
}
.tag-count { color: var(--text-faint); margin-left: 7px; font-size: 12px; font-variant-numeric: tabular-nums; }
.tag.active .tag-count { color: var(--accent); opacity: 0.7; }

/* ── Filter- und Schlagwortleiste ──────────────────────────────────────
   Die Sortierung links, was gerade gilt rechts daneben. Das Suchfeld ist
   hier weg - es steht im Kopf und gilt auf jeder Seite.
--------------------------------------------------------------------------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: center;
  margin: 0 0 14px;
}
.filter-state { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Was gerade einschraenkt, mit dem Weg heraus daran. Eine Einschraenkung, die
   man nicht sieht, liest sich als leerer Katalog. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  border-radius: var(--radius-pill);
  padding: 3px 12px;
  font-size: 13px;
  max-width: 320px;
}
.chip:hover { text-decoration: none; background: color-mix(in srgb, var(--accent) 26%, transparent); }
.chip-x { color: var(--text-faint); font-size: 15px; line-height: 1; }
.chip:hover .chip-x { color: var(--accent); }

.tag-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 26px; }

.segmented {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}
.segmented a, .segmented button {
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: var(--radius-pill);
  min-height: 32px;
  padding: 0 16px;
  font-size: 14px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.segmented a:hover, .segmented button:hover { background: var(--surface); color: var(--text); text-decoration: none; }
.segmented a.active, .segmented button.active { background: var(--surface-2); color: var(--text); box-shadow: var(--shadow-sm), var(--highlight); }

/* ── Katalog ───────────────────────────────────────────────────────────── */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(276px, 1fr));
  gap: 20px;
}

.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm), var(--highlight);
  border-radius: var(--radius-lg);
  overflow: hidden;
  color: var(--text);
  display: flex;
  flex-direction: column;
  transition: transform var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}
.card:hover {
  transform: translateY(-3px);
  border-color: var(--accent-line);
  box-shadow: var(--glow), var(--highlight);
  text-decoration: none;
}

/* Die Buehne traegt die Vorschau und was auf ihr liegt - Neu-Marke und Dauer.
   Vorher hingen beide am .card selbst, was sie an den Kartenrand band statt
   an das Bild. */
.card-stage { position: relative; }
.card canvas, .card .viewer-empty {
  width: 100%;
  height: 206px;
  background: var(--stage-bg-card);
  display: block;
}
.card .viewer-empty { display: flex; align-items: center; justify-content: center; color: var(--on-stage-faint); font-size: 13px; }

.card-body { padding: 13px 15px 16px; display: flex; flex-direction: column; gap: 5px; flex: 1; }

/* Der Titel ist der Link auf den Clip, und sein ::after deckt die ganze Karte
   ab - so bleibt die Flaeche anklickbar, ohne dass ein Link im Link stehen
   muss (was HTML nicht erlaubt). Der Autor daneben liegt darueber. */
.card-title {
  font-weight: 650;
  font-size: 15.5px;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}
.card-title::after { content: ""; position: absolute; inset: 0; }
.card-title:hover { text-decoration: none; }
.card:hover .card-title { color: var(--accent-strong); }

/* Ein Fokus, den man sieht: ohne ihn ist die Karte per Tastatur zwar
   erreichbar, aber nicht auffindbar. */
.card:focus-within { border-color: var(--accent-line); }
.card-title:focus-visible, .card-author:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}
.card-meta { color: var(--text-dim); font-size: var(--fs-sm); display: flex; gap: 7px; flex-wrap: wrap; align-items: center; justify-content: space-between; }
.card-meta .dot { color: var(--text-faint); }
/* Der Autor auf der Karte fuehrt zu allem anderen derselben Person. Er sieht
   erst beim Hinsehen wie ein Link aus - sonst konkurriert er mit dem Titel um
   die Aufmerksamkeit, und der ist das Angebot. */
/* Liegt ueber der Flaeche, die der Titel abdeckt - sonst waere er nicht zu
   treffen. */
.card-author { color: var(--text-dim); font-weight: 500; position: relative; z-index: 1; }
.card-author:hover { color: var(--accent); text-decoration: underline; }

.card-flag, .card-duration {
  position: absolute;
  top: 11px;
  background: var(--on-stage-scrim-strong);
  border: 1px solid var(--on-stage-line);
  color: var(--on-stage-ink);
  border-radius: var(--radius-pill);
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 600;
  /* Kein backdrop-filter: die Pille liegt auf einer Leinwand, die bis zu 30-mal
     in der Sekunde neu gezeichnet wird, und jede Pille muesste ihr Stueck
     jedes Mal neu weichzeichnen - bei 24 Karten 48 Mal. Bei 84 % Deckkraft
     sah man den Unterschied ohnehin kaum. */
}
.card-flag { left: 11px; }
/* Wie die Laufzeit auf einem Video: unten rechts, auf dem Bild. */
.card-duration {
  top: auto;
  bottom: 11px;
  right: 11px;
  font-variant-numeric: tabular-nums;
  /* Bühnenmarke, nicht `--text-dim`: die Pille liegt auf dem Bild, nicht auf
     der Seite. In Hell stand hier dunkler Text auf der dunklen Pille. */
  color: var(--on-stage-dim);
}

/* ── Wenn eine Adresse ins Leere fuehrt ────────────────────────────────
   Zwei Dinge muss eine Fehlerseite tun: sagen, was los ist, und einen Weg
   anbieten. Der Weg fuehrt in den Katalog, der zugleich die Startseite ist -
   wer einen Clip gesucht hat, sucht weiter Clips.
--------------------------------------------------------------------------- */

.notfound { padding: 60px 0 40px; max-width: 54ch; }
.notfound-code {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin: 0 0 8px;
}
.notfound h1 { font-size: 34px; }
.notfound h1::after { content: none; }
.notfound .lead { margin-bottom: 26px; }

.pager { display: flex; justify-content: center; align-items: center; gap: 12px; margin: 36px 0 0; }
.empty { text-align: center; color: var(--text-dim); padding: 56px 0; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.empty p { margin: 0; }

/* ── Clip-Seite ────────────────────────────────────────────────────────
   Links die Bewegung und das Gespräch darunter, rechts was man mitnimmt.
   Die rechte Spalte klebt beim Scrollen: durch ein langes Gespräch zu
   scrollen darf den Weg ins eigene Projekt nicht aus dem Bild schieben.
--------------------------------------------------------------------------- */

.clip-layout { display: grid; grid-template-columns: minmax(0, 1fr) 352px; gap: 32px; align-items: start; }
@media (max-width: 960px) { .clip-layout { grid-template-columns: 1fr; } }

.clip-main { min-width: 0; }
.clip-side { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 20px; }
@media (max-width: 960px) { .clip-side { position: static; } }

.clip-layout h1 { font-size: 27px; margin: 18px 0 0; }
.clip-layout h1::after { content: none; }

/* Wer, wann, und was man tun kann - eine Zeile unter dem Titel. */
.clip-byline {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 12px 0 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.clip-author { font-weight: 600; font-size: 15px; }
.clip-actions { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* Aufrufe und Downloads: Zeichen mit Zahl wie Herz und Stern, aber ohne
   Knopf - ablesen, nicht anfassen. Ein Strich trennt sie von den Knoepfen. */
.clip-stats {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  margin-right: 6px;
  padding-right: 16px;
  border-right: 1px solid var(--line);
  min-height: 36px;
}
.clip-stat { display: inline-flex; align-items: center; gap: 7px; color: var(--text-dim); font-size: 14px; }
.clip-stat .icon { width: 19px; height: 19px; color: var(--text-faint); }
.clip-stat b { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; }

/* Der Kasten unter der Kopfzeile, wie die Beschreibung bei YouTube: oben
   Aufrufe, wann und die Schlagworte mit #, darunter der Text. */
.clip-about {
  margin: 16px 0 0;
  padding: 12px 16px 14px;
  background: var(--surface-2);
  border-radius: var(--radius);
}
.clip-meta { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: 14.5px; }
.clip-when { color: var(--text); font-weight: 600; white-space: pre; }
.hashtag { color: var(--accent-strong); font-weight: 500; }
.hashtag:hover { color: var(--accent); }
.clip-description { color: var(--text-dim); margin: 6px 0 0; white-space: pre-wrap; max-width: 72ch; }

.get-panel { display: flex; flex-direction: column; gap: 14px; }
.get-panel .actions { display: flex; flex-direction: column; gap: 8px; margin: 0; }
.get-panel .actions .button, .get-panel .actions button { width: 100%; justify-content: center; }
.get-panel .actions p { margin: 0; }

/* EIN Download-Knopf, dahinter die Formate (clip-download.js). */
.download-button { width: 100%; justify-content: center; gap: 8px; }
.download-button .icon { width: 18px; height: 18px; }
.popover.format-popover { max-width: 360px; min-width: 300px; padding: 6px; }
.format-sheet { display: flex; flex-direction: column; gap: 2px; }
.format-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 0;
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.format-row:hover:not(:disabled) { background: var(--surface-2); border-color: var(--line); }
.format-row:disabled { cursor: default; opacity: 0.6; }
.format-row .icon { width: 18px; height: 18px; flex: none; color: var(--text-dim); }
.format-row:hover:not(:disabled) .icon { color: var(--accent); }
.format-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.format-text strong { font-weight: 600; font-size: 14px; }
.format-tag {
  flex: none;
  font-size: 11.5px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  color: var(--text-dim);
}

/* ── Nachbarschaft ─────────────────────────────────────────────────────
   Wer einen Laufzyklus ansieht, will meistens Laufzyklen sehen. Zeilen, keine
   Karten: die Spalte ist 352 px breit, und eine Vorschau je Nachbar wäre ein
   weiterer WebGL-Kontext für eine Nebensache.
--------------------------------------------------------------------------- */

.related h2 { font-size: 15px; margin: 0 0 10px; }
.related-list { display: flex; flex-direction: column; gap: 2px; }
.related-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--text);
}
.related-item:hover { background: var(--surface); text-decoration: none; }
.related-title { font-size: 14.5px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.related-meta { color: var(--text-faint); font-size: 12.5px; }

/* ── Das Gespräch ──────────────────────────────────────────────────────
   Flach, älteste zuerst. Der Avatar trägt die Spalte links, damit mehrere
   Kommentare als Gespräch lesbar bleiben und nicht als Liste von Abschnitten.
--------------------------------------------------------------------------- */

.comments { margin-top: 40px; max-width: 76ch; }
.comments h2 { margin: 0 0 16px; }

.comment-compose, .comment { display: flex; gap: 12px; }
.comment-compose { margin-bottom: 26px; }
.compose-body { flex: 1; min-width: 0; }
.compose-body textarea { min-height: 78px; margin: 0; }
.compose-foot { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 8px; }

.comment-signin {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 26px;
}

.comment-list { display: flex; flex-direction: column; gap: 20px; }
.comment-body { flex: 1; min-width: 0; }
.comment-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.comment-head strong, .comment-author { font-size: 14.5px; font-weight: 700; color: var(--text); }
.comment-author:hover { color: var(--accent); }
.comment-more { align-self: flex-start; }
.comment-text { margin: 4px 0 0; color: var(--text-dim); white-space: pre-wrap; overflow-wrap: anywhere; }
.comment-empty { margin: 0; }

/* Die eigenen Handlungen erscheinen erst beim Hinsehen - sie sind sonst so
   auffällig wie der Name darüber. */
.link-button {
  border: none;
  background: none;
  color: var(--text-faint);
  padding: 0;
  min-height: 0;
  font-size: 13px;
  font-weight: 500;
  opacity: 0;
}
.comment:hover .link-button, .link-button:focus-visible { opacity: 1; }
.link-button:hover { background: none; color: var(--text); text-decoration: underline; transform: none; }
@media (hover: none) { .link-button { opacity: 1; } }

.viewer {
  background: var(--stage-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.viewer .stage { position: relative; }
/* pan-y: senkrecht wischen scrollt die Seite, waagerecht dreht die Figur. Mit
   `none` war die Buehne auf dem Telefon eine 360 px hohe Wand, an der das
   Scrollen endete. */
/* WENIGER BREITBILD. Hier stand eine feste Hoehe von 480 px bei voller
   Spaltenbreite - auf einer breiten Seite wurde die Buehne damit 2,6:1, ein
   Streifen mit einer schmalen Figur in der Mitte. Jetzt ein Seitenverhaeltnis,
   gedeckelt auf die Fensterhoehe (Kopf, Abstand und Transportleiste abgezogen),
   damit Leiste und Figur zusammen im Bild bleiben. */
.viewer canvas {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  max-height: calc(100svh - 170px);
  min-height: 320px;
  display: block;
  cursor: grab;
  touch-action: pan-y;
}
.viewer > .viewer-empty { height: auto; aspect-ratio: 16 / 10; max-height: calc(100svh - 170px); min-height: 320px; }
.viewer canvas:active { cursor: grabbing; }
/* Mittlere Maustaste gedrueckt: die Kamera verschiebt (stage.js, panBy). */
.viewer canvas.is-panning { cursor: move; }

/* Tempo steht als Zahl im Knopf; alles ausser 1x ist hervorgehoben, damit
   niemand vergisst, dass er langsamer schaut. */
.speed-toggle { width: auto; min-width: 42px; padding: 0 8px; font-size: 12.5px; font-weight: 650;
  font-variant-numeric: tabular-nums; }
.speed-toggle.on { color: var(--accent); border-color: var(--accent-line); }

/* Vollbild: die Buehne nimmt alles, die Leiste bleibt unten. */
.viewer:fullscreen { display: flex; flex-direction: column; border-radius: 0; border: 0; background: var(--stage-void); }
.viewer:fullscreen .stage { flex: 1; min-height: 0; }
.viewer:fullscreen canvas { height: 100%; max-height: none; aspect-ratio: auto; }

/* Die Sichtschalter liegen AUF der Buehne, links unten, wie das HUD der
   Einzelclip-Ansicht im Werkzeug - und in derselben Reihenfolge. */
.stage-hud {
  position: absolute;
  left: 12px;
  bottom: 12px;
  display: flex;
  flex-direction: column-reverse;
  gap: 6px;
}

.hud-toggle {
  width: 34px;
  height: 34px;
  min-height: 0;
  padding: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--on-stage-line);
  border-radius: var(--radius-sm);
  background: var(--on-stage-scrim);
  color: var(--on-stage-dim);
  backdrop-filter: blur(6px);
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease;
}

.hud-toggle svg { width: 20px; height: 20px; }
.hud-toggle:hover { color: var(--on-stage-ink); border-color: var(--on-stage-accent-line); }
.hud-toggle[aria-pressed='true'] {
  color: var(--on-stage-accent);
  border-color: var(--on-stage-accent-line);
  background: var(--on-stage-accent-veil);
}

/* Die Proportionen liegen rechts unten - was links liegt, schaltet die
   ANSICHT um, was hier steht, aendert die FIGUR. Waagerecht, weil die vier
   nebeneinander eine Reihe zum Durchgehen sind und keine Liste von Schaltern. */
.stage-figures {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

/* Zwei Reihen uebereinander: oben, auf WEM der Clip laeuft, darunter die
   Masse des Mannequins. Bei einer eigenen Figur faellt die untere weg - sie
   hat ihre Proportionen. */
.stage-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: min(62vw, 420px);
}


/* Ein Schalter mit Wort statt Zeichen: dieselbe Schale wie `.hud-toggle`, nur
   so breit, wie das Wort es braucht. */
.hud-chip {
  width: auto;
  min-width: 34px;
  padding: 0 10px;
  font-size: 12px;
  letter-spacing: 0.02em;
}

@media (max-width: 720px) {
  .viewer canvas { height: 360px; }
  .stage-hud { left: 8px; bottom: 8px; }
  .stage-figures { right: 8px; bottom: 8px; gap: 4px; }
  .stage-row { gap: 4px; max-width: 70vw; }
  .hud-chip { padding: 0 8px; font-size: 11px; }
}
.viewer-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.viewer-controls button { min-height: 34px; padding: 0 14px; font-size: 14px; }
/* Der Wiedergabeknopf traegt dasselbe Zeichen wie die Schalter darueber, also
   auch dieselbe Form - nur steht er in der Leiste statt auf der Buehne. */
.viewer-controls .play-toggle { flex: none; padding: 0; }
.viewer-controls .time { flex: none; min-width: 4.5em; text-align: right; font-variant-numeric: tabular-nums; }

/* Die Zeitleiste zeichnen wir selbst: der Standard-Track ist hell und liegt
   auf dunklem Grund wie ein Fremdkoerper in der Leiste. */
.viewer-controls input[type=range] {
  flex: 1;
  /* Ohne das behaelt der Regler seine Eigenbreite von 129 px und schob auf
     einem Telefon den Vollbild-Knopf aus der Leiste. */
  min-width: 0;
  appearance: none;
  -webkit-appearance: none;
  height: 4px;
  min-height: 0;          /* sonst gewinnt die Mindesthoehe der Formularfelder */
  padding: 0;
  margin: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
  cursor: pointer;
}
.viewer-controls input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.viewer-controls input[type=range]::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.viewer-controls input[type=range]:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 4px; }
.viewer-empty { height: 480px; display: flex; align-items: center; justify-content: center; color: var(--on-stage-dim); }

dl.facts { display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; margin: 18px 0; font-size: 15px; }
dl.facts dt { color: var(--text-dim); }
dl.facts dd { margin: 0; }

.actions { display: flex; flex-direction: column; gap: 10px; margin: 18px 0 0; }
.actions .button, .actions button { width: 100%; }

/* EIN DIALOG-STIL. Es gab zwei: diesen (Flaeche, gestapelte Knoepfe) und
   `dialog.sheet` (tieferer Grund, Knoepfe rechts in einer Reihe) - welcher
   kam, hing davon ab, wer den Dialog gebaut hatte. Jetzt sehen alle aus wie
   das Sheet; die Meldung auf der Clip-Seite bekommt ihre Knoepfe in einer
   Reihe, Abbrechen links. */
dialog {
  background: var(--bg-soft);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  padding: 24px;
  width: min(480px, calc(100vw - 32px));
  box-shadow: var(--shadow), var(--highlight);
}
dialog::backdrop { background: var(--scrim); backdrop-filter: blur(3px); }
dialog .actions { flex-direction: row-reverse; justify-content: flex-start; }
dialog .actions .button, dialog .actions button { width: auto; }
dialog h2 { margin-top: 0; }

/* ── Listen ────────────────────────────────────────────────────────────── */

table.list { width: 100%; border-collapse: collapse; font-size: 15px; }
table.list th, table.list td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.list th { color: var(--text-faint); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
table.list tr:hover td { background: var(--row-hover); }

.status {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  border-radius: var(--radius-pill);
  padding: 2px 10px;
  background: var(--surface-2);
}
.status.PUBLISHED { color: var(--ok); }
.status.AUTO_HIDDEN { color: var(--warn); }
.status.REMOVED, .status.WITHDRAWN { color: var(--danger); }

.case { margin: 0 0 16px; }
.case header { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 8px; align-items: baseline; }
.case .buttons { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* Starter-Clips auf der Admin-Seite: eine Zeile je Datei, mit Ergebnis. */
.starter-log { margin: 12px 0 0; padding-left: 20px; display: grid; gap: 4px; }
.starter-log:empty { display: none; }
.danger-text { color: var(--danger); }

/* Die Herkunft eines Starter-Clips, unter der Zeile mit dem Ersteller. */
.clip-source { margin: 10px 0 0; color: var(--text-dim); font-size: var(--fs-sm); }
.clip-source a { color: var(--text); }
.case input.note { width: 100%; margin-top: 10px; }

/* ── Anmeldung ─────────────────────────────────────────────────────────── */

/* Die Knoepfe der Anbieter: im Stil der Seite, nicht in den Farben der
   Anbieter - ein violettes Portal mit einem blauen, einem schwarzen und einem
   weissen Knopf darin saehe aus wie drei Werbebanner. Die Farbe steckt im
   Zeichen, und daran erkennt man sie. */
.signin-options { display: flex; flex-direction: column; gap: 10px; max-width: 360px; margin: 0 0 26px; }
.signin-option { justify-content: flex-start; gap: 12px; min-height: 46px; padding: 0 18px; }
.provider-icon { width: 20px; height: 20px; flex: none; }

/* Die Anmeldeseite selbst: eine Karte in der Mitte, dahinter derselbe
   violette Schein wie unter den Figuren. Hierher wird umgeleitet - von der
   Kontoseite ohne Sitzung, von einem abgelaufenen Link aus der Workbench -,
   also soll sie aussehen wie ein Eingang. */
.signin-page {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: clamp(24px, 7vh, 72px);
  padding-bottom: 48px;
}
.signin-page::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 420px;
  background: radial-gradient(38% 60% at 50% 0%, var(--accent-soft), transparent 70%);
  pointer-events: none;
}
.signin-card {
  position: relative;
  width: 100%;
  max-width: 440px;
  padding: 34px 32px 26px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--highlight), var(--shadow);
}
.signin-mark { display: block; margin: 0 auto 18px; }
:root[data-theme="light"] .signin-mark { content: url("brand/playmations-mark-tinte.svg"); }
.signin-card h1 { margin: 0 0 6px; }
.signin-card h1::after { content: none; }
.signin-lead { color: var(--text-dim); margin: 0 0 22px; }
.signin-card .notice { text-align: left; margin: 0 0 18px; }
.signin-card .signin-options { max-width: none; margin: 0 0 22px; }
.signin-card .signin-option { justify-content: center; }
.signin-note { font-size: 13px; color: var(--text-dim); margin: 0 0 10px; }
.signin-note.faint { color: var(--text-faint); margin-bottom: 0; }
@media (max-width: 520px) {
  .signin-card { padding: 26px 18px 20px; border-radius: var(--radius); }
}

/* Die Rueckkehr vom Anbieter springt hierher (#sign-ins) - ohne Abstand
   laege die Ueberschrift unter dem festen Seitenkopf. */
#sign-ins, #notifications, #clips-title, #your-data, #close-account { scroll-margin-top: 110px; }

/* Die Kontoseite ist lang geworden - oben eine Zeile mit ihren Abschnitten. */
.page-sections { display: flex; flex-wrap: wrap; gap: 6px; margin: 18px 0 6px; }
.page-sections a {
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text-dim);
  font-size: 13px;
}
.page-sections a:hover { color: var(--text); border-color: var(--line-strong); text-decoration: none; }

.notification-page {
  max-width: 720px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.signin-row { flex-wrap: wrap; }
.signin-list { list-style: none; padding: 0; margin: 0 0 8px; max-width: 620px; }
.signin-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--line);
}
.signin-row-text { flex: 1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; min-width: 0; }
.signin-row .chip { padding: 1px 9px; font-size: 12px; }
.signin-row button { flex: none; }

.code-display {
  font: 700 38px/1.2 ui-monospace, "Cascadia Mono", Consolas, monospace;
  letter-spacing: 0.12em;
  text-align: center;
  margin: 18px 0;
  padding: 18px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.prose { max-width: 760px; }
.prose h2 { margin-top: 34px; }
.prose li { margin: 6px 0; }

/* ── /share.html: drei Schritte, zwei Ausgaben ──────────────────────── */
.share-steps { list-style: none; counter-reset: step; padding: 0; margin: 0 0 30px; }
.share-steps li {
  counter-increment: step;
  position: relative;
  padding: 2px 0 2px 46px;
  margin: 0 0 18px;
}
.share-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
}
.edition-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.edition-card { display: flex; flex-direction: column; gap: 10px; }
.edition-card h2 { margin: 0; font-size: 18px; }
.edition-card p { margin: 0; color: var(--text-dim); flex: 1; }
.edition-card .button { align-self: flex-start; }
.edition-tag {
  margin-left: 6px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
}

/* Unter dem Download-Knopf der Clip-Seite: wo es das Werkzeug fuer die .awclip gibt. */
.get-hint { margin: 10px 2px 0; line-height: 1.5; }
.todo {
  border: 1px dashed color-mix(in srgb, var(--warn) 45%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, transparent);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  color: var(--warn);
  margin: 12px 0;
  font-size: 14px;
}

/* Hier stand bis hierher ein Rest aus der Zeit der SEITENLEISTE: ein
   Grid-Raster fuer `body` (der laengst `flex` ist), eine Kopfzeile, die sich
   von senkrecht auf waagerecht drehte, und Regeln fuer `.sidebar-hint` und
   `.sidebar-foot` - Klassen, die es seit dem Umzug der Navigation nach oben
   nicht mehr gibt. Wirksam war davon nur zweierlei: ein zweiter Innenabstand
   am Kopf (neben dem des Bands) und `overflow-x: auto`, das aus dem Kopf bei
   Bedarf einen Schiebestreifen machte. Beides ist weg; wie der Kopf schmal
   wird, sagen die Bloecke bei 1080 und 620 Punkten. */
@media (max-width: 900px) {
  main { padding: 26px 18px 56px; }
  .site-footer { padding: 20px 18px; justify-content: center; }
  h1 { font-size: 30px; }
}

/*  Die Build-Marke steht im Fuss ganz unten und soll dort nicht mitreden:
    kleiner und blasser als die Links darueber. */
.site-footer .build {
  color: var(--text-faint);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* ── Knopfreihe der Fehlerseite ────────────────────────────────────────
   Hier stand die Startseite: Kopf, Zahlen, zeitweise eine Figur, Reihen mit
   Clips und Sammlungen, drei Schritte. Seit 2026-09-24 ist der Katalog selbst
   die Startseite, wie der Reiter "Animations" bei Mixamo. Uebrig ist nur die
   Knopfreihe, die die Fehlerseite mitbenutzt. */

.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.hero-actions .button { padding: 11px 20px; }

/* ── Zeichen, Tooltips, Icon-Knoepfe ───────────────────────────────────
   Weniger Wort, mehr Zeichen - und dafuer traegt JEDES Zeichen seinen Satz
   mit sich. `data-tip` legt ihn beim Hovern und beim Tastaturfokus darueber;
   derselbe Satz steht als `aria-label` am Knopf, damit ein Screenreader ihn
   vorliest statt "Schaltflaeche".

   Der Tooltip ist ein ::after am Element selbst. Das geht, weil kein Element
   mit `data-tip` sein ::after schon anderweitig benutzt - die Kartentitel tun
   das (sie decken damit die ganze Karte als Klickflaeche ab) und tragen
   deshalb keines.
---------------------------------------------------------------------------- */

.icon { width: 18px; height: 18px; flex: none; display: block; }
.icon.filled { fill: currentColor; }

/* Nur als Vorgabe (`:where` = keine Spezifitaet): ein Element, das seine Lage
   selbst setzt, behaelt sie. Vorher gewann diese Zeile gegen jede Klasse, die
   weiter oben in der Datei stand - die Marke "Unlisted" auf der
   Sammlungskarte (.card-flag, absolut oben links) rutschte dadurch unter das
   Bild und wurde abgeschnitten, "New" ohne Tooltip nicht. */
:where([data-tip]) { position: relative; }

[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%) translateY(3px);
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 5px 9px;
  font-size: 12.5px;
  line-height: 1.3;
  font-weight: 500;
  white-space: nowrap;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 60;
}

[data-tip]:hover::after,
[data-tip]:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%);
}

/* Am oberen Rand kippt er nach unten - sonst steht er ausserhalb des Bildes. */
[data-tip-below]::after { bottom: auto; top: calc(100% + 9px); }

/* Am Seitenrand haengt er nach innen statt mittig (app.js setzt das Attribut
   beim Hinzeigen) - sonst schnitte der Rand ihn ab. */
[data-tip-edge="end"]::after { left: auto; right: 0; transform: translateY(3px); }
[data-tip-edge="start"]::after { left: 0; transform: translateY(3px); }
[data-tip-edge]:hover::after, [data-tip-edge]:focus-visible::after { transform: none; }

/* Wer gerade einen Kasten geoeffnet hat, braucht keinen Zettel darueber. */
[data-tip].tip-off::after { content: none; }

/* Ein Knopf, der aus einem Zeichen besteht - mit seiner Zahl, wenn es eine gibt. */
.icon-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.icon-action:hover { background: var(--surface-2); color: var(--text); border-color: var(--line); text-decoration: none; }
.icon-action:disabled { opacity: 0.55; cursor: default; }
.icon-action:active { transform: none; }
.icon-action .count { line-height: 1; }

/* Gesetzt heisst gefuellt: das Herz rot, der Stern in der Akzentfarbe. */
.icon-action.on { color: var(--accent); }
.icon-action.like.on { color: var(--danger); }
.icon-action.danger { color: var(--danger); }
.icon-action.danger:hover { background: var(--danger-soft); border-color: var(--danger-line); }

/* In einer Aktionszeile tragen dieselben Knoepfe eine Kante - dort stehen sie
   allein und muessen ohne Nachbarn als Knopf erkennbar sein. */
.clip-actions .icon-action,
.profile-actions .icon-action,
.collection-actions .icon-action {
  border-color: var(--line);
  background: var(--surface);
  min-height: 36px;
  padding: 0 13px;
}
.clip-actions .icon-action:hover,
.profile-actions .icon-action:hover,
.collection-actions .icon-action:hover { border-color: var(--line-strong); }
.clip-actions .icon-action.on,
.profile-actions .icon-action.on { background: var(--accent-soft); border-color: var(--accent-line); }
.clip-actions .icon-action.like.on { background: var(--danger-soft); border-color: var(--danger-line); }

/* ── Karte: Autor links, Handgriffe rechts ────────────────────────────── */

.card-actions { display: flex; align-items: center; gap: 2px; position: relative; z-index: 1; }
.card-actions .icon-action { padding: 0 8px; min-height: 30px; }

/* ── Ein Kasten, der an einem Knopf haengt ────────────────────────────── */

.popover {
  position: absolute;
  z-index: 80;
  min-width: 268px;
  max-width: 320px;
  background: var(--bg-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 8px;
}

.popover-note { display: flex; flex-direction: column; gap: 10px; padding: 6px; }
.popover-note p { margin: 0; color: var(--text-dim); font-size: 13.5px; }

.picker { display: flex; flex-direction: column; gap: 6px; }

.picker-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-faint);
}
.picker-search input {
  flex: 1;
  border: 0;
  background: transparent;
  color: var(--text);
  padding: 8px 0;
  margin: 0;
  font-size: 14px;
  min-width: 0;
}
.picker-search input:focus { outline: none; }
.picker-search:focus-within { border-color: var(--accent-line); }

.picker-list { display: flex; flex-direction: column; gap: 2px; max-height: 232px; overflow: auto; }
.picker-list p { margin: 0; padding: 10px; }

.picker-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 36px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-dim);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}
.picker-row:hover { background: var(--surface); color: var(--text); }
.picker-row.on { color: var(--accent); }
.picker-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.picker-new {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.picker-new:hover { background: var(--surface); }

/* ── Der Dialog fuer eine Sammlung ────────────────────────────────────── */

dialog.sheet { width: min(560px, calc(100vw - 32px)); }
dialog.sheet h2 { margin: 0 0 18px; font-size: 20px; }
dialog.sheet h2::after { content: none; }
dialog.sheet .field { display: block; margin-bottom: 16px; }
dialog.sheet .counter { float: right; }
/* Der Text einer Rueckfrage (AW.confirmDialog) steht zwischen Titel und Knoepfen. */
dialog.sheet form > p { margin: 0 0 12px; line-height: 1.55; }
dialog.sheet form > p:last-of-type { margin-bottom: 20px; }

.choices { border: 0; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.choices legend { padding: 0 0 8px; color: var(--text-dim); font-size: 13.5px; }
.choices label { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--text-dim); }
.choices input[type="radio"] { margin: 0; width: 16px; height: 16px; accent-color: var(--accent); flex: none; }
.choices strong { color: var(--text); font-weight: 600; }

.dialog-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }

/* Ein Nebensatz im Dialog: der Weg woanders hin, abgesetzt von dem, was der
   Dialog selbst tut. */
.dialog-aside {
  margin: 0 0 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  line-height: 1.5;
}

/* ── Das Profil ────────────────────────────────────────────────────────
   Kopf, Zahlen, Reiter - in dieser Reihenfolge: erst WER das ist, dann WIE
   VIEL, dann die Sachen selbst.
---------------------------------------------------------------------------- */

.profile-head {
  display: flex;
  align-items: flex-start;
  gap: 22px;
  padding: 8px 0 24px;
  flex-wrap: wrap;
}

.profile-avatar {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  flex: none;
  object-fit: cover;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 34px;
  font-weight: 700;
  color: var(--accent);
}

.profile-identity { flex: 1 1 320px; min-width: 0; }
.profile-identity h1 { font-size: 30px; margin: 0 0 2px; }
.profile-identity h1::after { content: none; }
.profile-handle { color: var(--text-faint); font-size: 14px; }
.profile-bio { color: var(--text-dim); margin: 10px 0 0; max-width: 62ch; white-space: pre-wrap; }

.profile-role {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 10px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
}

.profile-numbers { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 14px 0 0; color: var(--text-dim); font-size: 13.5px; }
.profile-numbers > span, .profile-number { display: inline-flex; align-items: center; gap: 7px; }
/* Eine Zahl mit einer Liste dahinter (Follower, Gefolgte) - ein Knopf, der wie die anderen aussieht. */
.profile-number {
  min-height: 0;
  margin: -3px -7px;
  padding: 3px 7px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.profile-number:hover { background: var(--surface); color: var(--text); }
.profile-numbers b { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; }
.profile-numbers .icon { width: 16px; height: 16px; color: var(--text-faint); }

.profile-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Fuenf Reiter passen auf einem Telefon nicht nebeneinander - dann rollt die
   Leiste in sich, statt die Seite zu verbreitern. */
.profile-tabs { margin: 0 0 24px; max-width: 100%; overflow-x: auto; scrollbar-width: none; }

/* Die Auszeichnungen: eine Wand aus Zeichen, jedes mit seinem Satz im
   Tooltip. Was noch offen ist, steht blass daneben - aber nur auf dem
   eigenen Profil, sonst waere es eine fremde Aufgabenliste. */
.awards { display: flex; flex-wrap: wrap; gap: 12px; }

.award {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 232px;
  padding: 12px 16px 12px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.award .icon { width: 26px; height: 26px; color: var(--accent); }
.award.locked { opacity: 0.45; }
.award.locked .icon { color: var(--text-faint); }
.award-name { font-weight: 600; font-size: 14.5px; }
.award-sub { color: var(--text-faint); font-size: 12.5px; }
.award-tier { color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; }

/* ── Sammlungen ───────────────────────────────────────────────────────── */

.collection-head { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; margin-bottom: 22px; }
.collection-head h1 { margin: 0 0 6px; font-size: 30px; }
.collection-head h1::after { content: none; }
.collection-copy { flex: 1 1 420px; min-width: 0; }
.collection-copy p { margin: 8px 0 0; color: var(--text-dim); max-width: 70ch; white-space: pre-wrap; }
.collection-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.collection-card .card-duration { background: var(--on-stage-scrim-strong); }

/* ── Packs ────────────────────────────────────────────────────────────────
   Die Pack-Karte ist eine Clip-Karte mit einem Stapel dahinter: zwei Blaetter,
   nach rechts unten versetzt, wie bei Mixamo. Gezeichnet als Schatten und
   nicht als eigene Elemente, weil die Karte `overflow: hidden` traegt (runde
   Ecken, Vorschau) - einen Schatten schneidet sie nicht ab, ein Kind schon.
   Je Blatt zwei Schatten: die Flaeche, und einen Pixel groesser darunter der
   Rand. Der Stapel liegt im Abstand des Rasters (20 px) und braucht 10 davon -
   ohne eigenen Rand, damit die Karten einer Reihe gleich gross bleiben. */
.pack-card {
  --stack:
    5px 5px 0 -1px var(--surface-2), 5px 5px 0 0 var(--line-strong),
    10px 10px 0 -3px var(--surface-2), 10px 10px 0 -2px var(--line);
  box-shadow: var(--stack), var(--shadow-sm), var(--highlight);
}
.pack-card:hover { box-shadow: var(--stack), var(--glow), var(--highlight); }

/* Die Zahl auf dem Stapel sitzt, wo beim Clip die Dauer steht. */
.card-count { display: inline-flex; align-items: center; gap: 5px; color: var(--on-stage-ink); }
.card-count .icon { width: 14px; height: 14px; }

/* Ein Clip aus einem Pack sagt es unten links auf dem Bild - und fuehrt hin.
   Er liegt ueber der Flaeche, die der Titel abdeckt, sonst waere er nicht zu
   treffen. Lange Pack-Namen werden gekuerzt, die Dauer rechts bleibt frei. */
.card-pack {
  position: absolute;
  left: 11px;
  bottom: 11px;
  z-index: 1;
  max-width: calc(100% - 100px);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--on-stage-scrim-strong);
  border: 1px solid var(--on-stage-line);
  color: var(--on-stage-dim);
  border-radius: var(--radius-pill);
  padding: 2px 10px 2px 8px;
  font-size: 12px;
  font-weight: 600;
}
.card-pack span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-pack .icon { width: 14px; height: 14px; }
.card-pack:hover { color: var(--on-stage-ink); text-decoration: none; border-color: var(--accent-line); }

/* Auf der Clip-Seite: der Weg zu den Geschwistern. */
.clip-pack { margin: 10px 0 0; color: var(--text-dim); font-size: var(--fs-sm); display: flex; align-items: center; gap: 6px; }
.clip-pack .icon { width: 16px; height: 16px; color: var(--text-faint); }
.clip-pack a { color: var(--text); font-weight: 600; }

.pack-eyebrow { text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; margin-bottom: 4px; }
.pack-head .tags { margin-top: 12px; }
.pack-head .clip-source { margin-top: 6px; }
.filters .button .icon { width: 16px; height: 16px; margin-right: 6px; display: inline-block; vertical-align: -3px; }

/* Die Auswahl im Pack-Dialog: eine Liste zum Abhaken, die scrollt, statt den
   Dialog ueber den Bildschirm hinaus wachsen zu lassen. */
.pick-list {
  max-height: min(320px, 45vh);
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 4px;
  background: var(--surface-2);
}
.pick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-size: 14.5px;
}
.pick:hover { background: var(--surface); }
.pick input { min-height: 0; margin: 0; accent-color: var(--accent); flex: none; }
.pick-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick.taken { cursor: default; opacity: 0.55; }
.pick-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.pick-all { opacity: 1; }
.pick-all[hidden] { display: none; }
.pick.taken:hover { background: none; }
.starter-packs { margin: 6px 0 10px; padding-left: 18px; }

@media (max-width: 720px) {
  .profile-head { gap: 16px; }
  .profile-avatar { width: 64px; height: 64px; font-size: 26px; }
  .profile-identity h1 { font-size: 24px; }
  .award { min-width: 100%; }
}

/* ── Die eigenen Figuren ──────────────────────────────────────────────────
   Die Seite, auf der sie leben. Die Schalterreihe an der Buehne waehlt nur
   aus; hinzufuegen, nachsehen und loswerden passiert hier. */
.figure-drop {
  margin: 22px 0 18px;
  padding: 26px 20px;
  border: 2px dashed var(--line-strong);
  border-radius: var(--radius);
  text-align: center;
  transition: border-color 140ms ease, background-color 140ms ease;
}
.figure-drop p { margin: 0 0 6px; }
.figure-drop .button { margin-top: 10px; }
.figure-drop.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }

.figure-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
  margin: 18px 0 34px;
}

.figure-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.figure-card.active { border-color: var(--accent-line); }

/* Ein Standbild, kein zweiter Viewer: wer die Figur in Bewegung sehen will,
   schickt einen Clip darauf. */
.figure-shot {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  display: block;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%);
}

.figure-body { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 4px; }
.figure-body h3 { margin: 0; font-size: 15px; }
.figure-body p { margin: 0; }

.figure-actions { display: flex; gap: 8px; margin-top: 10px; }
.figure-actions .button { flex: 1; min-height: 32px; padding: 0 10px; font-size: 13px; }

.figure-empty {
  grid-column: 1 / -1;
  padding: 28px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
}
.figure-empty p { margin: 0 0 4px; }

.figure-how { margin-top: 30px; }

/* Eine geratene Zuordnung ist ein Vorschlag, und ein Vorschlag darf nicht
   aussehen wie eine Tatsache. Gelb: angesehen werden. Rot: geht so nicht. */
.figure-card.figure-unsure { border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.figure-card.figure-broken { border-color: color-mix(in srgb, var(--danger) 50%, transparent); }

.figure-flag {
  margin-top: 6px;
  padding-left: 9px;
  border-left: 2px solid var(--warn);
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.45;
}
.figure-flag.bad { border-left-color: var(--danger); }

/* ── Welcher Knochen welcher ist ──────────────────────────────────────────
   Die Maske zu einer geratenen Zuordnung. Sie kann 55 Zeilen lang werden,
   also darf sie scrollen - und Finger und Gesicht liegen zugeklappt, weil
   dort fast nie etwas zu korrigieren ist. */
dialog.bone-sheet { width: min(620px, calc(100vw - 32px)); }
dialog.bone-sheet form { display: flex; flex-direction: column; max-height: min(78vh, 760px); }
dialog.bone-sheet > form > .notice { margin: 14px 0 6px; flex: none; }
dialog.bone-sheet .dialog-actions {
  flex: none;
  padding-top: 14px;
  margin-top: 10px;
  border-top: 1px solid var(--line);
}

.bone-group {
  flex: none;
  padding: 12px 0 4px;
  border-top: 1px solid var(--line);
}
.bone-group:first-of-type { border-top: 0; }
.bone-group h3 { margin: 0 0 8px; font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim); }
.bone-group summary { cursor: pointer; font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim); }
.bone-group summary::marker { color: var(--text-dim); }

/* Der scrollende Teil ist die Liste, nicht der Dialog: Kopfzeile, Zaehlung
   und die Knoepfe sollen stehen bleiben, waehrend man 55 Zeilen durchgeht. */
dialog.bone-sheet > form { overflow: hidden; }
dialog.bone-sheet .bone-scroll { overflow-y: auto; flex: 1 1 auto; padding-right: 4px; }

.bone-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(0, 1.4fr);
  align-items: center;
  gap: 10px;
  padding: 3px 8px;
  margin: 0 -8px;
  border-radius: var(--radius-sm);
}
.bone-name { font-size: 13.5px; color: var(--text-dim); }
.bone-must { color: var(--accent); margin-left: 3px; }
.bone-pick { width: 100%; min-height: 30px; font-size: 13px; }

.bone-row.was-guessed .bone-name { color: var(--text); }
.bone-row.bone-gap { background: color-mix(in srgb, var(--danger) 10%, transparent); }
.bone-row.bone-gap .bone-pick { border-color: color-mix(in srgb, var(--danger) 55%, transparent); }
.bone-row.bone-clash { background: color-mix(in srgb, var(--warn) 10%, transparent); }
.bone-row.bone-clash .bone-pick { border-color: color-mix(in srgb, var(--warn) 55%, transparent); }

/* ── Bewegung ──────────────────────────────────────────────────────────── */
/* Alles hier ist Zugabe: nimmt man den Abschnitt heraus, funktioniert jede
   Seite genauso, nur ohne Uebergaenge. Die Regel dafuer: Bewegung sagt, was
   gerade passiert ist - etwas kam an, etwas wurde gesetzt, etwas ging -, und
   sie ist vorbei, bevor man darauf wartet. Keine Endlosschleifen ausser dem
   Schimmer, solange etwas wirklich laedt. */

@keyframes aw-rise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@keyframes aw-rise-small {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}
@keyframes aw-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes aw-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.28); }
  100% { transform: scale(1); }
}
@keyframes aw-sheen {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
@keyframes aw-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* Karten kommen gestaffelt, je 35 ms spaeter - ab der zwoelften alle
   zugleich, wer 24 Karten laedt, soll nicht zusehen muessen. `backwards`,
   nicht `both`: ein stehengebliebenes Endbild (`transform: none`) schlaege
   sonst das Anheben beim Hovern. */
.grid > .card { animation: aw-rise var(--dur-slow) var(--ease-out) backwards; }
.grid > .card:nth-child(2) { animation-delay: 35ms; }
.grid > .card:nth-child(3) { animation-delay: 70ms; }
.grid > .card:nth-child(4) { animation-delay: 105ms; }
.grid > .card:nth-child(5) { animation-delay: 140ms; }
.grid > .card:nth-child(6) { animation-delay: 175ms; }
.grid > .card:nth-child(7) { animation-delay: 210ms; }
.grid > .card:nth-child(8) { animation-delay: 245ms; }
.grid > .card:nth-child(9) { animation-delay: 280ms; }
.grid > .card:nth-child(10) { animation-delay: 315ms; }
.grid > .card:nth-child(11) { animation-delay: 350ms; }
.grid > .card:nth-child(12) { animation-delay: 385ms; }

/* Die Vorschau blendet ein, sobald ihr erstes Bild steht (`is-drawn` setzen
   card-stage.js und viewer.js). Darunter liegt derselbe Verlauf, den die
   Leinwand sonst selbst traegt - so blitzt beim Einblenden nichts auf. Solange
   sie laedt, zieht ein Schimmer darueber. */
.card-stage { background: var(--stage-bg-card); overflow: hidden; }
.card canvas.fade-in { opacity: 0; transition: opacity var(--dur-slow) var(--ease-out); }
.card canvas.fade-in.is-drawn { opacity: 1; }
.card-stage:has(> canvas.fade-in:not(.is-drawn))::after,
.card.placeholder .card-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, var(--stage-sheen) 50%, transparent 70%);
  animation: aw-sheen 1.5s var(--ease-in-out) infinite;
}

/* Platzhalter, solange eine Wand laedt (AW.placeholderCards): dieselbe Form
   wie eine Karte, damit nichts springt, wenn die echten kommen. */
.card.placeholder { pointer-events: none; }
.card.placeholder .card-stage { height: 206px; }
.card.placeholder .ph-line { display: block; height: 12px; width: 68%; border-radius: 6px; background: var(--surface-2); }
.card.placeholder .ph-line.short { width: 38%; margin-top: 6px; }

/* Was erst nach dem Laden sichtbar wird, taucht auf, statt hineinzuspringen. */
#clip:not(.hidden), #collection:not(.hidden), #profile:not(.hidden) {
  animation: aw-fade var(--dur-slow) var(--ease-out) backwards;
}

/* Dialoge, Kaesten und Meldungen gleiten ein. */
dialog[open] { animation: aw-dialog-in var(--dur) var(--ease-out) backwards; }
dialog[open]::backdrop { animation: aw-fade var(--dur) var(--ease-out) backwards; }
.popover { animation: aw-rise-small var(--dur) var(--ease-out) backwards; }
.toast {
  animation: aw-rise var(--dur) var(--ease-out) backwards;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.toast.leaving { transform: translateY(6px); }

/* Herz, Stern, Folgen: ein kurzer Puls, wenn etwas gesetzt wird. */
.icon-action.pulse .icon { animation: aw-pop 340ms var(--ease-out); }

/* SEITENWECHSEL. Das Portal besteht aus echten Seiten, und seit es sie gibt,
   koennen Browser zwischen zwei Seiten derselben Adresse ueberblenden - ohne
   eine Zeile Skript. Der Kopf traegt einen eigenen Namen und bleibt deshalb
   stehen, statt mitzublenden. Wer es nicht kann, laedt wie bisher. */
@view-transition { navigation: auto; }
.site-header { view-transition-name: site-header; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: var(--dur); animation-timing-function: var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  @view-transition { navigation: none; }
}

/* ── Das Schlagwortfeld (tag-input.js) ──────────────────────────────────
   Sieht aus wie ein Eingabefeld und verhaelt sich wie eins: Rahmen,
   Fokusring und Hoehe sind die von `input`. Darin stehen die Chips in
   Akzentfarbe - das, was schon gilt -, darunter gestrichelt die
   Vorschlaege: das, was gelten KOENNTE. Gestrichelt statt gefuellt, damit
   niemand einen Vorschlag fuer ein gewaehltes Schlagwort haelt. */

.field-label { display: block; color: var(--text-dim); font-size: 14px; margin-bottom: 6px; }

.tag-anchor { position: relative; }

.tag-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 5px 6px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: text;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.tag-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.tag-chips { display: contents; list-style: none; margin: 0; padding: 0; }

.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  height: 28px;
  padding: 0 3px 0 11px;
  background: var(--accent-soft);
  color: var(--text);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-pill);
  font-size: 13.5px;
  line-height: 1;
  white-space: nowrap;
  animation: aw-rise-small var(--dur) var(--ease-out) backwards;
}
.tag-chip.nudge { animation: aw-tag-nudge 360ms var(--ease-out); }

.tag-box .tag-chip-remove {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  box-shadow: none;
  color: var(--text-dim);
}
.tag-box .tag-chip-remove:hover { background: var(--surface-hover); color: var(--text); }
.tag-chip-remove .icon { width: 13px; height: 13px; }

.tag-box .tag-entry {
  flex: 1 1 140px;
  min-width: 140px;
  min-height: 28px;
  padding: 2px 6px;
  border: 0;
  background: transparent;
  box-shadow: none;
  font-size: 14.5px;
}
.tag-box .tag-entry:focus { border: 0; box-shadow: none; }

.tag-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 90;
  max-height: 272px;
  overflow-y: auto;
  padding: 6px;
  background: var(--bg-soft);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  animation: aw-rise-small var(--dur-fast) var(--ease-out) backwards;
}
/* In der obersten Ebene steht sie fest; Ort und Breite setzt das Skript. */
.tag-menu[popover] { position: fixed; inset: auto; margin: 0; }
.tag-menu[hidden] { display: none; }

.tag-option {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: 14px;
  cursor: pointer;
}
.tag-option:hover, .tag-option[aria-selected="true"] { background: var(--surface-hover); color: var(--text); }
.tag-option mark { background: none; color: var(--text); font-weight: 650; }
.tag-option-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-option-meta { color: var(--text-faint); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }

.tag-hint {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 6px;
  color: var(--text-faint);
  font-size: 12.5px;
}
.tag-hint.warn { color: var(--warn); }
.tag-room { margin-left: auto; font-variant-numeric: tabular-nums; }
.tag-room.full { color: var(--accent); }

.tag-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.tag-suggest[hidden] { display: none; }
.tag-suggest-label { color: var(--text-faint); font-size: 12.5px; margin-right: 4px; }

.tag-suggest .tag-suggestion {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  min-height: 0;
  padding: 0 11px 0 8px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  box-shadow: none;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 500;
  animation: aw-rise-small var(--dur) var(--ease-out) backwards;
}
.tag-suggest .tag-suggestion:hover {
  border-style: solid;
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--text);
}
.tag-suggestion .icon { width: 13px; height: 13px; }

@keyframes aw-tag-nudge {
  0% { transform: none; }
  35% { transform: scale(1.08); border-color: var(--accent); }
  100% { transform: none; }
}

/* Vorschaubilder auf der Admin-Seite: die zuletzt gerenderten, klein. */
.card-previews { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.card-previews figure { margin: 0; }
.card-previews img { display: block; width: 300px; height: auto; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.starter-log li.ok { color: var(--ok); }
.starter-log li.error { color: var(--danger); }

/* ── Stats (Admin) ─────────────────────────────────────────────────────
   Kacheln oben, zwei Kaesten, dann die Tabellen. Zahlen in Spalten mit
   gleich breiten Ziffern, in den Kacheln mit den normalen: eine grosse Zahl
   mit Tabellenziffern hat Luecken. */

.admin-tabs { margin: 0 0 20px; }

.stat-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin: 0 0 20px;
}
.stat-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--highlight);
  min-width: 0;
}
.stat-label { color: var(--text-dim); font-size: 13.5px; }
.stat-value { color: var(--text); font-size: 30px; font-weight: 650; line-height: 1.15; letter-spacing: -0.01em; }
.stat-sub { color: var(--text-faint); font-size: 12.5px; }

.stats-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px;
}
.stats-columns .panel h2 { margin-top: 0; }
.stats-columns dl.facts { margin-bottom: 0; }

.stats-section { margin-top: 36px; }
.stats-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.stats-heading h2 { margin: 0; }
.stats-heading input { max-width: 260px; }

/* Sechzehn Spalten passen auf kein Telefon - die Tabelle rollt in sich,
   die Seite bleibt schmal. */
.table-scroll { overflow-x: auto; margin-top: 12px; }
table.stats-table { font-size: 14px; }
table.stats-table th, table.stats-table td { padding: 10px 10px; }
table.stats-table .num { text-align: right; font-variant-numeric: tabular-nums; }
table.stats-table .zero { color: var(--text-faint); }
table.stats-table .nowrap { white-space: nowrap; }
table.stats-table th .sort-button {
  all: unset;
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  white-space: nowrap;
}
table.stats-table th .sort-button:hover { color: var(--text); }
table.stats-table th .sort-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
table.stats-table th[aria-sort] { color: var(--text); }
table.stats-table th[aria-sort="descending"] .sort-button::after { content: " ↓"; }
table.stats-table th[aria-sort="ascending"] .sort-button::after { content: " ↑"; }

.member-cell { min-width: 180px; }
.member-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.member-name .chip { height: 20px; padding: 0 8px; font-size: 11.5px; }
.member-banned, .member-closed { color: var(--danger); }
.member-restricted { color: var(--warn); }
.member-row.closed td { opacity: 0.55; }
