/* roodle - Brand-System "R Pack Heart" (Investoren-Vorgabe 16.08.2026, verbindlich).
   Palette EXAKT nach Brand-Sheet - keine Abweichung ohne Rücksprache:
   yellow #FFD56B (Primäraktion, Hund 1) · blue #B7D6F2 (Sekundär, Hund 2) ·
   green #BFD6B5 (Akzent/Erfolg/Herz - NICHT #BFD8B5!) · cream #FFF6E1 (Fläche) ·
   ink #2F2F2F (Text, Wortmarke - NICHT #2A2B26!).
   Typografie: Nunito Bold/ExtraBold (Variable Font, SIL OFL - App-Embedding erlaubt;
   damit ist die im Prompt angeforderte Lizenzprüfung bestätigt).
   Kontrast-Regel aus dem Sheet: Textfarbe ist IMMER ink, nie die Pastelltöne. */
@font-face {
  font-family: "Nunito";
  src: url("assets/fonts/nunito-700-latin.woff2") format("woff2");
  font-weight: 700 800;
  font-display: swap;
}
:root{
  --sun:#FFD56B; --sun-deep:#F2C24F; --sun-tint:#FFF2D3;
  --sky:#B7D6F2; --sky-deep:#9CC4EA; --sky-tint:#E6F0FA;
  --meadow:#BFD6B5; --meadow-deep:#A9C99C; --meadow-tint:#EAF1E6;
  --cream:#FFF6E1; --surface:#FFFFFF; --fog:#F2F2F2;
  --ink:#2F2F2F; --ink2:#6B675C; --edge:#EBE4D2; --alert:#8F3B32;
  --scrim:rgba(47,47,47,.5);
}
*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
/* Die iPhone-Einstellung „Größere Schrift" bewirkte in roodle nichts: 73
   Schriftgrößen in px, null rem. In einer WKWebView ist -apple-system-body die
   einzige Stelle, an der die System-Textgröße ankommt - sie setzt hier die
   Wurzel, und jedes rem im Dokument folgt. Der Browser-Fallback bleibt 100 %.
   Deckel bei 130 %: darüber bricht das Wisch-Deck auf dem SE, und wer so groß
   liest, ist mit dem Zoom-Regler von iOS besser bedient als mit einer Karte,
   auf der nichts mehr zusammenpasst. */
html{ color-scheme:light; font-size:100%; }
@supports (font: -apple-system-body) {
  /* Der Shorthand setzt Familie und Zeilenhöhe mit - body stellt beides wieder
     her. Die Größe selbst bleibt: das ist die System-Textgröße in px. */
  html{ font: -apple-system-body; }
} /* App ist bewusst hell - verhindert Dark-Mode-Invertierungen (Formulare, Scrollbars) */
html,body{ margin:0; padding:0; background:var(--cream); color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,sans-serif;
  line-height:1.5; -webkit-font-smoothing:antialiased;
  overscroll-behavior:none; }
/* Nur body, nie html: auf html wäre 1rem = sich selbst und würde die System-
   Größe sofort wieder überschreiben. */
body{ font-size:1rem; }
body{ background-image:
  radial-gradient(560px 420px at 12% 8%, var(--sun-tint), transparent 70%),
  radial-gradient(520px 400px at 80% 12%, var(--meadow-tint), transparent 70%);
  background-attachment:fixed; }
.app{ max-width:430px; margin:0 auto; min-height:100vh; min-height:100dvh; display:flex; flex-direction:column; }
.disp{ font-family:"Nunito","Trebuchet MS",Avenir,"Segoe UI",sans-serif; font-weight:800; letter-spacing:-.01em; }
.claim{ font-family:"Nunito",sans-serif; font-weight:700; letter-spacing:.34em; text-transform:uppercase;
  font-size:0.8125rem; color:var(--ink); }
.claim .punkt{ color:var(--meadow-deep); }
.logo-bild{ display:block; }
/* .caps kann auch auf einem h2 sitzen: die Abschnittskoepfe der Seiten sind seit
   dem 06.09. echte Ueberschriften. Optisch aendert sich nichts - margin und
   font-size des h2 werden hier zurueckgesetzt. Grund: die Community-Seite hatte
   auf 2353 Pixeln keine einzige Ueberschrift, elf waren nur optisch als solche
   gesetzt; wer mit VoiceOver nach Ueberschriften springt, fand nichts. */
.caps{ font-size:0.625rem; letter-spacing:.15em; text-transform:uppercase; color:var(--ink2); font-weight:600; }
h2.caps, h3.caps{ margin:0; font-size:0.625rem; }
.klein{ font-size:0.7812rem; color:var(--ink2); }
.fehler{ color:var(--alert); font-size:0.7812rem; font-weight:600; }

header.kopf{ padding:calc(10px + env(safe-area-inset-top)) 16px 8px;
  display:flex; align-items:center; justify-content:space-between; gap:10px; }
.marke{ display:flex; align-items:center; gap:7px; }
.marke b{ font-size:1.3125rem; }
main{ flex:1; padding:4px 16px calc(92px + env(safe-area-inset-bottom)); }

.card{ background:var(--surface); border:1px solid var(--edge); border-radius:22px; overflow:hidden; }
/* max-width + Ellipse: „Los - <sehr langer Hundename> wartet" lief sonst über den
   rechten Bildrand hinaus (Flotten-Fund). flex-shrink bleibt 0, damit Knöpfe
   nebeneinander nicht zerdrückt werden - die Breite deckelt jetzt max-width. */
/* Kein nowrap/ellipsis mehr: bei großer System-Schrift stand „Weiterschnü…"
   auf dem Knopf - ein abgeschnittener Knopf ist schlimmer als ein zweizeiliger.
   Die Höhe wächst mit, die Tippfläche bleibt ≥ 46 px. */
.btn{ border:0; border-radius:999px; padding:13px 18px; font-size:0.9375rem; font-weight:700;
  font-family:inherit; cursor:pointer; transition:transform .12s; min-height:46px;
  white-space:normal; line-height:1.2; flex-shrink:0; max-width:100%; overflow:visible;
  /* „Weiterschnüffeln" ist EIN Wort - bei großer System-Schrift ragt es über den
     Rand, weil nichts umbrechen kann. Silbentrennung als Notnagel (lang="de" steht
     im HTML, also trennt der Browser richtig), und das Polster weicht bei Bedarf. */
  hyphens:auto; -webkit-hyphens:auto; overflow-wrap:anywhere; padding-inline:clamp(8px, 3vw, 18px); }
.btn:active{ transform:scale(.97); }
/* Bewegung wirklich aus, wenn das System es verlangt - die Transform-Transition
   auf allen Knöpfen lief bisher weiter (Flotten-Fund). */
@media (prefers-reduced-motion: reduce){
  .btn{ transition:none; } .btn:active{ transform:none; }
  .ovl .sheet{ animation:none; }
}
.btn:disabled{ opacity:.45; }
.btn-sun{ background:var(--sun); color:var(--ink); }
.btn-ghost{ background:transparent; color:var(--ink); border:1px solid var(--edge); }
.btn-breit{ width:100%; }
.chip{ display:inline-block; border:1px solid var(--edge); background:var(--surface);
  border-radius:999px; padding:11px 14px; font-size:0.8438rem; margin:0 6px 8px 0;
  font-family:inherit; cursor:pointer; color:var(--ink); min-height:44px; }
.chip-on{ background:var(--sun); border-color:var(--sun-deep); font-weight:600; }
/* Runden-Stapel (Community): eine Karte, Pfeile links und rechts. touch-action lässt das senkrechte Scrollen
   dem Browser, damit ein Wisch seitwärts blättert und die Seite nie seitwärts wandert. */
.stapel-kopf{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin:0 0 6px; }
.stapel-zaehler{ flex:1; text-align:center; }
.stapel-pfeil{ flex:none; width:44px; height:44px; border:1px solid var(--edge); border-radius:50%;
  background:var(--surface); color:var(--ink); font:inherit; font-size:1.5rem; line-height:1; cursor:pointer; padding:0; }
.stapel-pfeil:disabled{ opacity:.35; cursor:default; }
.stapel-karte{ touch-action:pan-y; user-select:none; -webkit-user-select:none; overflow-x:hidden;
  border:1px solid var(--edge); border-radius:18px; background:var(--cream); padding:12px 14px; outline:none; }
.stapel-zahlen{ display:flex; gap:22px; margin:6px 0 4px; }
.stapel-zahlen b{ display:block; font-size:1.75rem; line-height:1.1; font-weight:800; }
.stapel-zahlen span{ display:block; font-size:0.75rem; color:var(--ink2); }
/* Satzanfänge im Onboarding sind Textbausteine, keine Auswahl: gestrichelter Rand, kein Füllton,
   kursiv und ein Auslassungszeichen am Ende. Sie sehen so nicht mehr aus wie die Chips darüber,
   die man an- und abwählt. */
[data-bioanfang]{ background:transparent; border-style:dashed; font-style:italic; color:var(--ink2); }
[data-bioanfang]::after{ content:" …"; font-style:normal; }
.beispiel{ display:inline-block; background:var(--fog); border-radius:999px; padding:2px 8px;
  font-size:0.5938rem; letter-spacing:.1em; text-transform:uppercase; color:var(--ink2); font-weight:700; }

/* Formulare (Onboarding + Profil) - Onboarding v2: warm statt Behördenformular. */
.feld{ margin:0 0 16px; }
.feld label{ display:block; font-size:0.8438rem; font-weight:600; color:var(--ink); margin:0 0 6px; }
.feld .optional{ font-weight:400; color:var(--ink2); font-size:0.75rem; }
.feld input, .feld textarea{ width:100%; border:1.5px solid var(--edge); border-radius:16px; padding:13px 15px;
  font-size:1rem; font-family:inherit; background:var(--surface); color:var(--ink);
  transition:border-color .15s, box-shadow .15s; }
.feld textarea{ resize:vertical; min-height:64px; line-height:1.4; }
.feld input::placeholder, .feld textarea::placeholder{ color:var(--ink2); opacity:.55; }
.feld input:focus, .feld textarea:focus{ outline:none; border-color:var(--sun-deep);
  box-shadow:0 0 0 3px var(--sun-tint); }
.feld.zeigt-fehler input{ border-color:var(--alert); box-shadow:0 0 0 3px rgba(143,59,50,.12); }
.feld .pflicht{ color:var(--alert); }

/* Beschrifteter Stepper: „Der Hund - Du" statt anonymer Punkte. */
.stepper{ display:flex; align-items:center; justify-content:center; gap:10px; margin:8px 0 18px; }
.stepper .stufe{ font-size:0.6875rem; letter-spacing:.12em; text-transform:uppercase; font-weight:700;
  color:var(--ink2); padding:5px 12px; border-radius:999px; border:1px solid var(--edge); background:var(--surface); }
.stepper .stufe.an{ background:var(--sun); border-color:var(--sun-deep); color:var(--ink); }
.stepper .stufe.fertig{ background:var(--meadow-tint); border-color:var(--meadow-deep); color:var(--ink); }
.stepper .steg{ width:22px; height:1.5px; background:var(--edge); }

/* Jeder Schritt gleitet sanft herein (und respektiert reduced-motion). */
.ob-schritt{ animation:auftauchen .32s cubic-bezier(.2,.7,.3,1); }
@keyframes auftauchen{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce){ .ob-schritt{ animation:none; } }

/* Deck */
/* Entdecken ist EIN Bildschirm (Felix, 16.10.2026: „statisch an die Benutzeroberfläche
   gekoppelt, nicht scrollbar"). Solange eine Karte da ist, trägt body die Klasse
   deck-fest: die App ist genau so hoch wie das Fenster, die Karte nimmt die
   Restfläche zwischen Kopf und Knöpfen, und nichts scrollt. Vorher rechnete eine
   fest verdrahtete Summe (330 px, 246 px, dazu der Willkommens-Banner) die
   Kartenhöhe aus, und die Seite war doch 7 px zu hoch. Jetzt rechnet die
   Flex-Spalte; die Tab-Leiste hält main über --leiste-h frei, das app.js misst.
   Die Details stehen im Blatt (.sheet.details), nicht mehr in der Karte. */
body.deck-fest{ overflow:hidden; }
body.deck-fest .app{ height:100vh; height:100dvh; min-height:0; overflow:hidden; }
body.deck-fest main{ display:flex; flex-direction:column; min-height:0;
  padding:4px 16px calc(var(--leiste-h) + 12px); }
body.deck-fest .aktionen{ flex:none; margin-top:10px; }
/* overflow:hidden - die weggewischte Karte steht mit translateX(620px) im DOM,
   bis das Deck neu rendert. Ohne diese Zeile wuchs die Seite auf 994 px Breite:
   Gruß- und Match-Overlay wurden seitlich abgeschnitten, „Abbrechen" war nicht
   mehr tippbar (Flotten-Fund HOCH). min-height:0, damit die Karte auf kleinen
   Schirmen schrumpft statt die Knöpfe unter die Leiste zu drücken. */
.stack{ position:relative; margin-top:4px; overflow:hidden; flex:1 1 0; min-height:0; }
.wischhinweis{ flex:none; text-align:center; margin:6px 0 0; }
/* Querformat und sehr flache Fenster: die Karte bekommt, was übrig bleibt. */
@media (max-height: 520px) {
  .foto{ min-height:60px; }
  main{ padding-top:2px; }
}
.swipe{ position:absolute; inset:0; background:var(--surface); border:1px solid var(--edge);
  border-radius:22px; overflow:hidden; touch-action:pan-y; user-select:none; -webkit-user-select:none;
  transition:transform .28s cubic-bezier(.2,.7,.3,1), opacity .28s; display:flex; flex-direction:column; }
/* Das Foto IST die Karte: es füllt alles, Name und Zeile liegen darauf. Bild und
   Ersatztext liegen absolut im Feld, damit die Höhe allein vom Flex kommt. */
.foto{ position:relative; flex:1 1 0; min-height:90px; background:var(--fog); }
.foto img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.foto .leer{ position:absolute; inset:0; display:grid; place-items:center; color:var(--ink2); font-size:0.8125rem; }
.foto .oben{ position:absolute; left:10px; top:10px; }
.foto .unten{ position:absolute; left:0; right:0; bottom:0; padding:34px 66px 14px 14px; color:#fff;
  background:linear-gradient(to top, rgba(0,0,0,.72), transparent);
  /* Harter Riegel gegen die obere Reihe: Die 2-Zeilen-Begrenzung des Namens
     allein reichte nicht - bei 130 % Systemschrift auf dem iPhone SE lief der
     weiße Name quer durch die BEISPIEL-Marke und die Passungs-Plakette
     (Zielnutzer-Fund Kollateralprüfung, 25.08.). Ausgerechnet das Etikett, auf
     dem die Ehrlichkeit der App ruht, war dann unlesbar. 46 px sind 10 px
     Abstand plus die höchste gemessene Plakette plus Luft. */
  max-height:calc(100% - 46px); overflow:hidden; }
/* Ohne Bild ist der dunkle Verlauf sinnlos - er ist dafür da, weißen Text auf
   einem Foto lesbar zu machen. Auf grauem Grund wirkt er wie ein Fehler.
   Kein :has(): das kennt iOS 15 nicht, auf das diese App zielt. */
.foto.ohne-bild .unten{ background:none; color:var(--ink); padding-top:12px; }
.foto.ohne-bild .unten p{ opacity:1; color:var(--ink2); }
.foto.ohne-bild .leer{ align-content:start; padding-top:14px; }
.foto .unten h2{ margin:0; font-size:1.5rem;
  /* Höchstens zwei Zeilen: bei großer System-Schrift auf 320 px wuchs der Name
     nach oben über die BEISPIEL-Marke und die Passungs-Plakette (Rückkehr-Fund).
     Der volle Name steht in „Über X" und auf dem Match-Bildschirm. */
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.foto .unten p{ margin:2px 0 0; font-size:0.7812rem; opacity:.92; }
.badge{ position:absolute; right:10px; top:10px; background:var(--sun); color:var(--ink);
  border-radius:999px; padding:5px 10px; font-size:0.75rem; font-weight:800; }
.karteninhalt{ padding:12px 14px 14px; overflow-y:auto; flex:1; position:relative;
  -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
  mask-image:linear-gradient(to bottom, #000 calc(100% - 22px), transparent); }
/* h3 statt h4: die Karte beginnt mit h2, h4 uebersprang eine Ebene. */
.karteninhalt h3, .karteninhalt h4{ margin:0 0 4px; font-size:0.6875rem; letter-spacing:.13em; text-transform:uppercase; color:var(--ink2); }
.karteninhalt p{ margin:0 0 10px; font-size:0.8438rem; }
.stempel{ position:absolute; top:22px; left:18px; border:3px solid var(--sun-deep); color:var(--ink);
  background:rgba(255,255,255,.9); border-radius:16px; padding:5px 13px; font-size:1.3125rem; font-weight:800;
  transform:rotate(-12deg); opacity:0; pointer-events:none; }
.stempel.nope{ left:auto; right:18px; border-color:var(--ink2); transform:rotate(12deg); }
/* flex-wrap + min-width:0: auf 320-px-Geräten (iPhone SE 1. Gen) lief die
   Aktionsleiste rechts aus dem Bild - der Primärknopf „Wuff mit Gruß" war
   angeschnitten und die Seite scrollte seitlich (Flotten-Fund). */
.aktionen{ display:flex; flex-wrap:wrap; gap:9px; margin-top:14px; }
.aktionen .btn{ flex:1 1 140px; min-width:0; }

/* Kleine Geräte (iPhone SE & Co.): jede Zeile unter der Karte kostet dort Foto.
   Die zwei Aktionsknöpfe untereinander kosteten allein 101 px Höhe. Nebeneinander
   und ohne den Gesten-Hinweis bekommt die Karte rund 80 px zurück. Die Knöpfe
   bleiben ≥44 px hoch - die Tippfläche wird nicht angetastet. */
@media (max-height: 700px) {
  .aktionen{ margin-top:10px; }
  .aktionen .btn{ flex:1 1 0; }
  .wischhinweis{ display:none; }
  /* Nebeneinander wird es eng: mit 18 px Seitenpolster und nowrap stand auf einem
     320-px-Gerät „Weiterschn…" und „Wuff mit Gr…" - ein abgeschnittener Knopf ist
     schlimmer als ein zweizeiliger, gerade für Augen, die ohnehin anstrengen.
     Also: schmaleres Polster, etwas kleinere Schrift, und umbrechen darf er. */
  .aktionen .btn{ padding:9px 10px; font-size:0.875rem; white-space:normal;
    overflow:visible; text-overflow:clip; line-height:1.2; }
}
/* Der Ausweg aus dem Bearbeiten-Modus. Er sitzt im Stepper, wo der Blick beim
   Orientieren zuerst landet, und ist eine echte 44-px-Tippfläche. */
.ob-abbruch{ float:right; min-height:44px; padding:0 12px; border:0; background:transparent;
  color:var(--ink2); font:inherit; font-size:0.875rem; font-weight:700; cursor:pointer;
  text-decoration:underline; text-underline-offset:3px; }
.ob-abbruch:active{ color:var(--ink); }

/* Der Sicherheitssatz vor dem Terminvorschlag. Bewusst KEIN .klein: 12,5 px in
   Grau war genau die Größe, in der ihn niemand las. Lesbar, dunkel, mit Rand. */
.sicher{ font-size:0.875rem; line-height:1.45; color:var(--ink); background:var(--sun-tint);
  border-left:3px solid var(--sun-deep); border-radius:0 12px 12px 0; padding:8px 11px; }

/* Der Hinweis auf der Deck-Karte - dort fällt die Entscheidung. Eine kleine Pille
   in Ink statt eines roten Kastens: sie sagt ruhig, WAS zu beachten ist („Erst an
   der Leine"); der ganze Satz steht im Blatt unter „Hinweis". Hell auf Ink wie
   das Status-Band, es trägt keine Pastellfläche. */
.karten-hinweis{ background:var(--ink); color:var(--cream);
  display:inline-block; max-width:100%; margin:0 0 6px; padding:4px 11px; border-radius:999px;
  font-size:0.75rem; font-weight:700; line-height:1.3; }
/* Der Pfeil zum Aufklappen: eine 44-px-Fläche unten rechts auf dem Foto. */
.details-auf{ position:absolute; right:10px; bottom:10px; z-index:2; width:44px; height:44px; padding:0;
  border:0; border-radius:50%; background:rgba(255,255,255,.92); color:var(--ink);
  display:grid; place-items:center; cursor:pointer; }
.details-auf svg{ display:block; }
.details-auf:active{ transform:scale(.94); }

/* Die Brücke zu den Gassirunden (Karte „Heute empfohlen"). */
.gassi-bruecke{ width:100%; text-align:left; padding:13px 15px; margin-top:14px; border:1px solid var(--edge);
  font-family:inherit; cursor:pointer; display:flex; gap:12px; align-items:center; background:var(--surface); }
.gassi-bruecke .pfeil{ color:var(--ink2); font-size:1.25rem; }

.deck-leer{ text-align:center; padding:38px 20px; color:var(--ink2); }
.deck-leer .gross{ font-size:1.0625rem; color:var(--ink); font-weight:600; }

/* Overlays */
.ovl{ position:fixed; inset:0; background:var(--scrim); display:grid; place-items:end center;
  z-index:50; }
.ovl.mitte{ place-items:center; padding:20px; }
.ovl .sheet{ background:var(--surface); border-radius:26px 26px 0 0; padding:20px 18px calc(18px + env(safe-area-inset-bottom));
  width:100%; max-width:430px; max-height:88vh; max-height:88dvh; overflow-y:auto; }
.ovl.mitte .sheet{ border-radius:26px; padding-bottom:20px; }
/* Die Knopfzeile klebt am unteren Rand des Dialogs. Beim Doppel-Wuff standen auf
   dem kleinsten Schirm mit grosser Systemschrift BEIDE Knoepfe unter der
   Sheet-Unterkante - 25 von 25 Kandidaten, sichtbare Hoehe null: ein Erfolgsmoment
   ohne sichtbaren Ausweg (Zielnutzer-Fund 06.09.). Sticky loest das, ohne zwischen
   Kopfzeile und Knoepfen waehlen zu muessen: der Inhalt scrollt dahinter, der
   Ausweg steht immer da. */
.ovl.mitte .sheet > .aktionen{ position:sticky; bottom:-20px; z-index:1;
  background:var(--surface); padding-bottom:20px; margin-bottom:-20px; }
/* Das Detail-Blatt der Deck-Karte: kommt von unten, 85 % hoch, Kopf und Knöpfe
   stehen fest, nur der Inhalt dazwischen scrollt. Wisch nach unten, Escape, das
   Kreuz und der Tipp daneben schließen es. */
.ovl .sheet.details{ display:flex; flex-direction:column; text-align:left; overflow:hidden;
  height:85vh; height:85dvh; max-height:85vh; max-height:85dvh;
  padding:8px 18px calc(14px + env(safe-area-inset-bottom));
  animation:blatt-hoch .26s cubic-bezier(.2,.7,.3,1); }
@keyframes blatt-hoch{ from{ transform:translateY(36px); opacity:0; } to{ transform:none; opacity:1; } }
@media (prefers-reduced-motion: reduce){ .ovl .sheet.details{ animation:none; } }
.sheet.details .griff{ flex:none; width:40px; height:5px; border-radius:999px; background:var(--edge); margin:4px auto 8px; }
.sheet.details .blatt-kopf{ flex:none; display:flex; align-items:flex-start; gap:10px; }
.sheet.details .blatt-kopf > div{ flex:1; min-width:0; }
.sheet.details .blatt-kopf h2{ margin:0; font-size:1.25rem; line-height:1.25; overflow-wrap:anywhere; }
.sheet.details .blatt-kopf p{ margin:2px 0 0; }
.sheet.details .blatt-zu{ flex:none; width:44px; height:44px; padding:0; border:0; border-radius:50%;
  background:var(--fog); color:var(--ink); font-size:1.5rem; line-height:1; cursor:pointer; }
.sheet.details .karteninhalt{ flex:1 1 auto; min-height:0; padding:10px 2px 18px; }
.sheet.details > .aktionen{ flex:none; margin-top:8px; }
.paarfotos{ display:flex; justify-content:center; margin-bottom:8px; }
.paarfotos img, .paarfotos .fotoleer{ width:66px; height:66px; border-radius:50%; object-fit:cover;
  border:3px solid var(--surface); box-sizing:border-box; }
/* Ohne Foto ein Pfoten-Kreis statt gar nichts: „Doppel-Wuff" heißt zwei Hunde,
   auch wenn der Nutzer das optionale Foto übersprungen hat (Flotten-Fund). */
.paarfotos .fotoleer{ display:grid; place-items:center; background:var(--sun-tint); }
.paarfotos > * + *{ margin-left:-16px; }
.grund{ text-align:left; background:var(--meadow-tint); border-radius:14px; padding:10px 12px; margin:10px 0 0; }
.grund li{ font-size:0.8125rem; margin:3px 0; }

/* Chat */
.blase{ max-width:78%; padding:9px 13px; border-radius:18px; font-size:0.875rem; margin:6px 0; word-break:break-word; }
.von-mir{ background:var(--sun); margin-left:auto; border-bottom-right-radius:5px; }
.von-ihm{ background:var(--sky-tint); border-bottom-left-radius:5px; }
/* Der Verlauf bekommt einen eigenen Scroll-Bereich, das Eingabefeld klebt
   darunter: vorher wuchs die Chatkarte mit jeder Nachricht, das Feld wanderte
   pro Wortwechsel ~100 px nach unten und lag nach drei Nachrichten hinter der
   Tab-Leiste - der Chat wurde unbenutzbar (Flotten-Fund HOCH). */
/* 46vh waren zu viel, sobald unter dem Verlauf mehr steht als ein Eingabefeld:
   mit Sicherheitssatz, drei Termin-Chips und „Kontakt beenden" wurde die Karte
   898 px hoch in einem 900-px-Fenster, und das Eingabefeld rutschte hinter die
   Tab-Leiste. Der Verlauf ist scrollbar - er darf der Karte Platz lassen. */
/* Seit 17.10.2026 steht hier EIN Gespräch auf dem Schirm (die Liste davor), nicht zwölf: der Verlauf folgt
   der Höhe des Schirms statt fester 34vh. Der Abzug von 640 px ist die Höhe von Kopfzeile, Rückleiste,
   Chatkopf, Spieltreff-Wahl, Eingabefeld und Tab-Leiste: so bleibt das Eingabefeld auf dem iPhone
   ohne Scrollen über der Leiste, und auf größeren Schirmen wächst der Verlauf mit. */
.chatlauf{ max-height:clamp(160px, calc(100vh - 640px), 480px); overflow-y:auto; overscroll-behavior:contain; }

/* Chat-Liste (wie bei Tinder): Foto, Name, eine Zeile Vorschau, rechts der Punkt für Ungelesenes.
   Sonnengelb statt Rot, kein Pulsieren (AGENTS.md: keine Suchtmechanik). */
.chatliste{ list-style:none; margin:0; padding:0; }
.chatliste li + li{ border-top:1px solid var(--edge); }
.chatzeile{ display:flex; align-items:center; gap:12px; width:100%; min-height:72px; padding:9px 2px;
  background:transparent; border:0; border-radius:14px; text-align:left; font:inherit; color:var(--ink); cursor:pointer; }
.chatzeile:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }
.chatzeile .zfoto{ flex:none; width:54px; height:54px; border-radius:50%; object-fit:cover; }
.chatzeile .zleer{ display:grid; place-items:center; background:var(--sun-tint); }
.chatzeile .ztext{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.chatzeile .zname{ font-family:"Nunito","Trebuchet MS",Avenir,"Segoe UI",sans-serif; font-weight:800; font-size:1rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.chatzeile .zvorschau{ font-size:0.875rem; color:var(--ink2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.chatzeile.neu .zvorschau{ color:var(--ink); font-weight:700; }
.chatzeile .zrechts{ flex:none; display:flex; flex-direction:column; align-items:flex-end; gap:6px; }
.chatzeile .zpunkt{ min-width:22px; height:22px; padding:0 6px; border-radius:999px; background:var(--sun);
  border:1px solid rgba(47,47,47,.16); display:grid; place-items:center; font-size:0.75rem; font-weight:800;
  color:var(--ink); line-height:1; }
.chatleiste{ margin:0 0 6px -8px; }
.chat-zurueck{ min-height:44px; padding:0 12px; border:0; border-radius:999px; background:transparent;
  font:inherit; font-weight:700; color:var(--ink); cursor:pointer; }
.chat-zurueck:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }
#chat-titel:focus{ outline:none; }
.eingabe{ display:flex; gap:8px; margin-top:12px; position:sticky; bottom:0;
  background:var(--surface); padding-top:6px; }
.eingabe input{ flex:1; min-width:0; border:1px solid var(--edge); border-radius:999px; padding:12px 15px;
  font-size:1rem; font-family:inherit; background:var(--surface); color:var(--ink); }

/* Community */
.karte-svg{ width:100%; display:block; background:var(--meadow-tint); }
.pool{ display:flex; gap:9px; overflow-x:auto; padding-bottom:4px; }
.pool .p{ width:128px; flex:0 0 auto; background:var(--surface); border:1px solid var(--edge);
  border-radius:16px; overflow:hidden; }
.pool .p img{ width:100%; height:92px; object-fit:cover; display:block; }
.pool .p div{ padding:7px 8px; }
.pool .p span{ display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Live-Punkt im Pool-Streifen - hieß mal ".punkt" und kollidierte mit dem
   Claim-Punkt (Flotten-Fund: der Satzpunkt in "Find your pack." pulsierte als
   schwebender 8x8-Kreis). Der Claim behält .punkt als reine Textfarbe. */
.livepunkt{ display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--meadow-deep);
  animation:puls 1.4s ease-in-out infinite; }
@keyframes puls{ 0%,100%{opacity:.5} 50%{opacity:1} }
@media (prefers-reduced-motion: reduce){ .livepunkt{ animation:none } .swipe{ transition:none } }

/* Community-Umschalter (16.10.2026, Felix: Umschalten statt Scrollen). Drei Reiter in einer
   Leiste ganz oben auf der Seite, bewusst NICHT klebend: ein klebender Streifen deckte beim
   Scrollen die Oberkante der Karte samt Knöpfen zu. Der gewählte trägt die Sonnenfarbe, die
   anderen bleiben still. Der Punkt am Reiter „Spontan" ist derselbe ruhige Punkt wie im Streifen. */
.reiter{ display:flex; gap:4px; padding:6px 0 8px; margin:0 0 6px; }
.reiter button{ flex:1 1 0; min-width:0; min-height:44px; border:1px solid var(--edge); background:var(--surface);
  border-radius:999px; font-family:inherit; font-size:0.75rem; font-weight:600; color:var(--ink);
  cursor:pointer; display:inline-flex; align-items:center; justify-content:center; gap:6px; padding:0 4px; }
.reiter button[aria-selected="true"]{ background:var(--sun); border-color:var(--sun-deep); font-weight:800; }
.reiter button:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
.reiterfeld[hidden]{ display:none; }
/* Mit dem Dogwalker-Reiter sind es sechs: die Leiste scrollt seitlich, statt die Namen zu quetschen. */
.reiter[data-viele]{ overflow-x:auto; }
.reiter[data-viele] button{ flex:1 0 auto; padding:0 10px; }
/* Die kleine Zahl am Chat-Reiter (Playmatches, Dogwalker): Chats mit Ungelesenem. Sonnengelb wie der Punkt
   in der Chat-Liste, kein Rot, keine Bewegung. Auf dem gewählten (gelben) Reiter steht sie auf hellem Grund. */
.reiter .rzahl{ min-width:20px; height:20px; padding:0 5px; border-radius:999px; background:var(--sun);
  border:1px solid rgba(47,47,47,.16); display:inline-grid; place-items:center; font-size:0.6875rem;
  font-weight:800; color:var(--ink); line-height:1; }
.reiter button[aria-selected="true"] .rzahl{ background:var(--surface); }

/* Profil */
/* Deck-Vorschau im Profil: dieselbe Foto-Karte wie im Deck, nur fest und nicht wischbar. */
.vorschau{ display:flex; flex-direction:column; height:clamp(200px, 30vh, 280px); }
.vorschau .foto{ border-radius:22px 22px 0 0; overflow:hidden; }
/* Ein langer Hundename bricht um, statt die Karte zu sprengen (Flotten-Fund, ab 18 Zeichen). */
.vorschau .unten h2, .vorschau-fuss p{ overflow-wrap:anywhere; }
.vorschau-fuss{ padding:12px 16px 14px; }
.vorschau-fuss p{ margin:5px 0 0; font-size:0.8125rem; }
.vorschau-fuss p:first-child{ margin-top:0; }
/* Aufklapper („Über roodle"): leise Zeilen, die Pfeilspitze dreht sich. */
details.auf{ border-bottom:1px solid var(--edge); }
details.auf:last-of-type{ border-bottom:0; }
details.auf summary{ list-style:none; display:flex; justify-content:space-between; align-items:center;
  min-height:44px; padding:6px 2px; cursor:pointer; font-weight:700; font-size:0.9062rem; }
details.auf summary::-webkit-details-marker{ display:none; }
details.auf summary::after{ content:"›"; color:var(--ink2); transition:transform .15s; }
details.auf[open] summary::after{ transform:rotate(90deg); }
details.auf summary:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
details.auf > p{ font-size:0.8438rem; margin:0 0 12px; }
@media (prefers-reduced-motion: reduce){ details.auf summary::after{ transition:none; } }
/* Kopfzeile im Chat mit „…"-Menü. */
.chatkopf{ display:flex; align-items:center; gap:10px; position:relative; }
.chatkopf .kopftext{ flex:1; min-width:0; }
.menue-auf{ flex:none; width:44px; height:44px; border:0; border-radius:50%; background:transparent;
  color:var(--ink); font-size:1.5rem; line-height:1; cursor:pointer; font-family:inherit; }
.menue-auf:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
.chatmenue{ position:absolute; right:0; top:46px; z-index:5; background:var(--surface); border:1px solid var(--edge);
  border-radius:14px; padding:4px; min-width:190px; box-shadow:0 6px 20px rgba(47,47,47,.14); }
.chatmenue[hidden]{ display:none; }
.chatmenue button{ display:block; width:100%; text-align:left; min-height:44px; padding:0 12px; border:0;
  background:transparent; font-family:inherit; font-size:0.9062rem; color:var(--ink); cursor:pointer; border-radius:10px; }
.chatmenue button:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }
.zeile{ display:flex; justify-content:space-between; align-items:center; gap:10px;
  padding:13px 2px; border-bottom:1px solid var(--edge); }
.zeile:last-child{ border-bottom:0; }
.zeile .t b{ font-size:0.9062rem; display:block; }
.zeile .t span{ font-size:0.75rem; color:var(--ink2); }

/* Nav - Emblem über Label; aktiver Tab doppelt markiert (Sun-Pill am Icon + boldes
   Label), damit die Markierung auch ohne Farbsehen funktioniert. */
/* Die Höhe der Tab-Leiste steht als Variable, weil der Kartenfuß sich darüber
   halten muss. Wer hier etwas ändert, muss --leiste-h mitziehen. */
/* Der untere Sicherheitsabstand steht als eigene Variable, damit Leiste und
   Kartenfuss GARANTIERT denselben Wert benutzen - und damit eine Pruefung ihn
   setzen kann. Ein Headless-Browser misst env(safe-area-inset-bottom) als 0; auf
   einem iPhone 14 sind es 34 px, die Leiste wird 96 statt 62 px hoch. Ohne diese
   Variable haette jede Messung ein Geraet ohne Notch geprueft (Skeptiker-Fund
   05.09.: genau daran sah die verdeckte ODbL-Zeile im Test unauffaellig aus).
   --leiste-h ist nur der ANFANGSWERT: die echte Hoehe misst app.js beim Start und
   bei jeder Aenderung nach (bei 24 px Systemschrift wird die Leiste 68 px hoch). */
:root{ --leiste-h:62px; --sicher-unten:env(safe-area-inset-bottom, 0px); }
nav.leiste{ position:fixed; left:0; right:0; bottom:0; background:var(--surface);
  border-top:1px solid var(--edge); display:flex; justify-content:center; gap:2px;
  padding:5px 6px calc(5px + var(--sicher-unten)); z-index:40; }
nav.leiste .n{ flex:1 1 0; max-width:105px; min-width:0; border:0; background:transparent; font-family:inherit;
  font-size:0.6875rem; color:var(--ink2); padding:3px 2px 4px; border-radius:14px; cursor:pointer; font-weight:600;
  min-height:48px; display:flex; flex-direction:column; align-items:center; gap:2px; }
/* Bei starkem Seitenzoom wurden „Entdecken" und „Profil" auf 10 bzw. 2 px
   zusammengequetscht, weil die längeren Labels den Platz nahmen. Ab hier bekommt
   jeder Tab dieselbe Breite und nur noch das Emblem - lieber ohne Beschriftung
   als mit fünf unlesbaren Resten (Flotten-Fund). */
@media (max-width: 340px) {
  /* Vorher font-size:0 - fünf Embleme ohne ein einziges Wort. Wer die Symbole
     nicht kennt (Rückkehr-Fund Renate, 68), musste raten. Kleine Wörter sind
     besser als keine. Bewusst feste 10 px statt rem: mit skalierender Schrift
     passte „Entdecken" nicht mehr in ein Fünftel von 320 px - wer größer liest,
     hat die Wörter in jeder anderen Ansicht; hier zählt, dass sie DA sind. */
  nav.leiste .n{ font-size:10px; gap:0; letter-spacing:0; }
  nav.leiste .n .emblem{ width:100%; }
  /* Der Hundename im Foto-Kopf: bei großer Schrift wuchs er über Marke und
     Plakette. Feste Obergrenze auf dem schmalen Gerät - der volle Name steht
     in „Über X" in skalierender Größe. */
  .foto .unten h2{ font-size:min(1.5rem, 19px); }
  .foto .unten{ padding-top:26px; }
}
nav.leiste .n .emblem{ display:grid; place-items:center; height:29px; width:50px;
  border-radius:999px; color:var(--ink2); transition:background .2s; position:relative; }
nav.leiste .n .mzahl{ position:absolute; top:-3px; right:2px; min-width:16px; height:16px;
  display:grid; place-items:center; background:var(--sun); border:1px solid rgba(47,47,47,.16);
  border-radius:999px; font-size:0.625rem; font-weight:800; color:var(--ink); padding:0 4px; line-height:1; }
nav.leiste .n svg{ display:block; }
nav.leiste .n.an{ color:var(--ink); font-weight:800; }
nav.leiste .n.an .emblem{ background:var(--sun); color:var(--ink); }

/* Fehlende Chip-Auswahl SICHTBAR machen (Flotten-Fund: die Gruppe wurde nur
   angescrollt - ohne Rahmen, ohne Farbe; der Tap auf „Weiter" erzeugte einen
   Scroll-Sprung und sonst null Rückmeldung). */
.feld.zeigt-fehler [data-chips]{ outline:2px solid var(--alert); outline-offset:6px; border-radius:18px; }
.feld.zeigt-fehler .chip{ border-color:var(--alert); }

/* Gassi: Fortschritt der laufenden Runde - ruhig, kein Fortschritts-Druck */
.fortschritt{ height:7px; border-radius:999px; background:var(--fog); overflow:hidden; }
.fortschritt span{ display:block; height:100%; border-radius:999px; background:var(--sun-deep);
  transition:width .6s ease; }
@media (prefers-reduced-motion: reduce){ .fortschritt span{ transition:none } }

/* Gassi-Karte: Puls der Unterwegs-Punkte (Uhr, kein Engagement-Pull) */
@keyframes gassi-puls { 0%,100%{ transform:scale(1); opacity:.55; } 50%{ transform:scale(2.1); opacity:.15; } }
.puls{ animation:gassi-puls 2s ease-in-out infinite; transform-box:fill-box; transform-origin:center; }
@media (prefers-reduced-motion: reduce){ .puls{ animation:none; opacity:.35; } }

.banner{ background:var(--sky-tint); border:1px solid var(--edge); border-radius:16px;
  padding:11px 13px; font-size:0.8125rem; margin:0 0 12px; }
.hinweis{ background:var(--meadow-tint); border:1px solid var(--edge); border-radius:16px;
  padding:11px 13px; font-size:0.8125rem; margin:0 0 12px; }
/* OBEN, nicht unten: unten lag das Band auf dem iPhone SE genau auf
   „Weiterschnüffeln" und „Wuff mit Gruß" - das Zurückholen-Band erzeugte damit
   selbst die Fehltipps, die es heilen soll (Rückkehr-Fund HOCH). Unter dem Kopf
   liegt im Deck nichts Tippbares. */
.status-band{ position:fixed; left:50%; transform:translateX(-50%); top:calc(58px + env(safe-area-inset-top));
  background:var(--ink); color:var(--cream); border-radius:999px; padding:9px 16px; font-size:0.8125rem;
  max-width:88%; z-index:45; display:flex; align-items:center; gap:10px; }
/* Der Rückweg im Band: 44 px hohe Tippfläche wie überall, heller Rahmen auf dunklem
   Grund (Kontrast cream auf ink liegt weit über AA). */
.band-zurueck{ flex:0 0 auto; min-height:44px; padding:0 14px; border-radius:999px;
  border:1.5px solid var(--cream); background:transparent; color:var(--cream);
  font:inherit; font-weight:700; cursor:pointer; }
.band-zurueck:active{ background:rgba(255,255,255,.16); }

/* Der Datei-Knopf war das EINZIGE Bedienelement der App, das der Browser malt
   und nicht wir: ein grauer „Choose File"-Kasten mit englischer Beschriftung,
   mitten in einer deutschen App. Auf einem deutschen iPhone stünde dort Deutsch
   - aber verlassen wollen wir uns darauf nicht, und aussehen soll er wie alles
   andere hier. Das Feld bleibt im Baum und fokussierbar (nicht display:none),
   sonst kommt niemand mehr mit der Tastatur hin. */
/* fixed, nicht absolute: ohne positionierten Vorfahren stand das Feld an seiner
   statischen Stelle und ragte 15 px rechts aus dem Fenster - die eigene Prüfung
   „kein waagerechter Überlauf" hat es gefunden. Fixed nimmt es aus dem Fluss und
   heftet es in die Ecke, wo es niemandem im Weg ist und trotzdem fokussierbar
   bleibt. */
.feld input.datei-echt, .datei-echt{ position:fixed; top:0; left:0;
  width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
  border:0; opacity:0;
  /* Ohne das lag das unsichtbare 1×1-Feld ÜBER dem Knopf und fing die Klicks ab
     - der Knopf sah richtig aus und tat nichts. Die Label-Verknüpfung braucht
     keine Zeigerereignisse am Feld, sie ist eine DOM-Beziehung. */
  pointer-events:none; }
/* .feld label ist display:block - ohne die höhere Spezifität wurde aus dem Knopf
   ein breiter Balken, der aussah wie ein leeres Textfeld. */
.feld label.datei-knopf, .datei-knopf{ display:inline-flex; align-items:center; gap:8px;
  width:auto; min-height:44px; margin:0; padding:11px 17px; border-radius:999px;
  border:1.5px solid var(--edge); background:var(--surface); color:var(--ink);
  font-weight:700; font-size:0.9375rem; cursor:pointer; }
.datei-echt:focus-visible + .datei-knopf{ outline:2px solid var(--ink); outline-offset:2px; }
.datei-knopf:active{ transform:scale(.97); }

/* Die Karte ist seit dem 30.08. bedienbar: ziehen, mit zwei Fingern zoomen,
   doppelt tippen. Die Knöpfe liegen NEBEN dem SVG (absolut darüber), nicht darin
   - im SVG würden sie mitzoomen und mitwandern. 44 px wie überall. */
/* 44 px Tippfläche wie überall - aber sichtbar leichter: Die erste Fassung waren
   drei große weiße Kästen, die ein Drittel der Karte zudeckten. Der sichtbare
   Kasten ist jetzt kleiner als die Tippfläche. */
.karte-knoepfe{ position:absolute; right:6px; top:6px; display:flex; flex-direction:column;
  gap:2px; z-index:2; }
.karte-knoepfe button{ min-width:44px; min-height:44px; padding:0; border:0; background:none;
  color:var(--ink); font:700 1.125rem/1 -apple-system,system-ui,sans-serif; cursor:pointer;
  display:flex; align-items:center; justify-content:center; }
/* Der gemalte Knopf sitzt IN der Tippfläche und ist kleiner als sie. */
.karte-knoepfe button::before{ content:""; position:absolute; width:32px; height:32px;
  border-radius:10px; background:rgba(255,246,225,.92); border:1px solid var(--edge);
  box-shadow:0 1px 2px rgba(47,47,47,.12); }
.karte-knoepfe button > *, .karte-knoepfe button{ position:relative; }
.karte-knoepfe button span{ position:relative; z-index:1; }
/* „Stadt" braucht mehr Platz als ein Zeichen - der gemalte Knopf wächst mit. */
.karte-knoepfe button[data-karte="ganz"]{ min-width:58px; font-size:0.6875rem; }
.karte-knoepfe button[data-karte="ganz"]::before{ width:52px; }
.karte-knoepfe button[hidden]{ display:none; }
.karte-knoepfe button:active{ transform:scale(.95); }
.karte-knoepfe button[disabled]{ opacity:.4; }
#gassi-svg{ touch-action:pan-y; }
#gassi-svg:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }

/* Der Kartenfuß: Maßstab links, ODbL-Attribution rechts, in EINER Zeile.
   Vorher lagen beide einzeln absolut am unteren Rand - und überlappten sich,
   sobald der Balken breit wurde oder die Systemschrift wuchs (bei 24 px stand
   dort wörtlich „2 k", das „m" lag unter der Attribution). In einer flex-Zeile
   mit Abstand ist das ausgeschlossen; wird es eng, weicht der Maßstab in die
   nächste Zeile aus, statt sich unter die Lizenzangabe zu schieben.
   STICKY, nicht absolut: die Karte ist höher als der sichtbare Rest der Seite,
   also lag die Attribution beim Ankommen im Community-Tab komplett hinter der
   festen Tab-Leiste - 78 % der Karte zu sehen, ihre Pflichtangabe nicht
   (Zielnutzer-Fund 05.09.). Sticky hält den Fuß am unteren Bildrand, solange
   irgendein Teil der Karte im Bild ist, und setzt ihn am Kartenende ab. */
.karte-feld{ position:relative; }
.karte-clip{ overflow:hidden; border-radius:21px 21px 0 0; margin-bottom:-28px; }
.karte-karte{ overflow:visible; }
.karte-fuss{ position:sticky; z-index:2; bottom:calc(var(--leiste-h) + var(--sicher-unten));
  display:flex; align-items:flex-end; justify-content:space-between; flex-wrap:wrap-reverse;
  gap:4px 8px; padding:0 8px; margin:0 0 6px; min-height:22px; pointer-events:none; }
.karte-quelle{ margin:0; font-size:0.6875rem; color:var(--ink2);
  background:rgba(255,246,225,.82); padding:2px 6px; border-radius:8px; }

/* Maßstab: Eine Karte, die man zoomen kann, braucht einen Bezug. Die Zahl ist
   aus der Bounding-Box der eingebackenen Geometrie gerechnet, nicht geschätzt. */
.karte-massstab{ box-sizing:content-box; flex:0 0 auto; height:16px;
  border-left:2px solid var(--ink2); border-right:2px solid var(--ink2);
  border-bottom:2px solid var(--ink2); border-radius:0 0 2px 2px;
  font:600 0.625rem/1 -apple-system,system-ui,sans-serif; color:var(--ink2);
  text-align:center; padding-top:2px; background:rgba(255,246,225,.72);
  pointer-events:none; }
.karte-massstab[hidden]{ display:none; }

/* Nur fuer Screenreader: die Zoom-Knoepfe meldeten gar nichts zurueck, und der
   Maszstab traegt aria-hidden. Hier steht nach jedem Zoom, was jetzt gilt. */
.nurlesen{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }

/* Wuff-Zähler bei den Matches (16.10.2026): eine ruhige Kachel, Zahl links, kein Glanz, kein Antippen. */
.wuff-kachel{ display:flex; align-items:center; gap:12px; background:var(--surface); border:1px solid var(--edge); border-radius:22px; padding:12px 14px; margin-bottom:14px; }
.wuff-zahl{ flex:0 0 auto; min-width:46px; height:46px; border-radius:14px; background:var(--sun); color:var(--ink); display:flex; align-items:center; justify-content:center; font-weight:800; font-size:1.25rem; }
.wuff-text{ line-height:1.3; }
.wuff-text .klein{ margin:0; }
