Files
dogfather-universe/workspace/assets/css/chat.css
T
DogFatherGitandClaude Opus 5 e7cd1984d8 Ein Rollenname im ausgelieferten Code, die Seite zu breit, und drei Pruefungen, die den Umbau verschlafen hatten
Filipe: "falls es noch was gibt was fehlt oder nicht richtig funktioniert,
auf dem handy oder auf dem pc, oder als installiert, ich will dass du das
alles abcheckst und machst dass jede seite reibungslos klappt."

Gemessen wurde der ganze Bestand: 26 Pruefdateien einzeln, dazu drei neue
Messungen fuer Dinge, die keine Pruefung ansieht. Von 37 roten Meldungen
aus dem Nachtlauf sind nach dieser Runde die haelfte erledigt -- und die
Haelfte davon war gar nicht kaputt.

=== ECHTE FEHLER ===

1. EIN ROLLENNAME STAND IM AUSGELIEFERTEN QUELLTEXT.
   `aufgaben.js` sagte "Modis moechten das uebernehmen -- du
   entscheidest". Diese Datei bekommt JEDER, der die Seite oeffnet:
   jeder Manager, jeder Scout, jeder Creator im anderen Haus. Der
   verborgene Zugang haelt genau so lange, wie der Name dort nicht
   steht. Er stammte aus der Bewerbungsspalte von gestern -- einen Tag
   alt, gefunden von pruef-modi-wortleck. Jetzt: "Jemand moechte das
   uebernehmen". Wer es ist, steht ohnehin mit Namen auf den Karten
   darunter, und die sieht nur, wer sie sehen darf.

2. DIE SUPPORT-SEITE WAR AUF JEDER BREITE UNTER 1440 px ZU BREIT --
   13 px auf dem Handy, 41 px auf dem Tablet quer, 30 px auf dem
   Laptop. Schuld war das weiche Licht, das ich in der Nacht eingebaut
   habe: `inset: -8% -4% 0`. Die vier Prozent rechts sahen nach einer
   Kleinigkeit aus; ein absolut gesetztes Element zaehlt aber zur
   Scrollbreite, auch mit `pointer-events: none` und `z-index: -1`.

   `pruef-breiten` hat es gemeldet und konnte nicht sagen, WAS es ist
   ("13px Ueberstand []") -- ein Pseudoelement hat keine Box im DOM.
   Gefunden hat es eine neue Messung, die JEDES echte Element abfragt:
   keines ragte heraus, und genau das war der Hinweis.
   Jetzt: 0 px auf allen neun Breiten, 38 Seiten, 84 252 Elemente.

3. EIN AUFGABENLINK IM REPORT WAR 27 x 18 px GROSS. Mit der Maus gut,
   mit dem Daumen nicht -- eine Fingerkuppe ist rund 45 px breit.
   Jetzt fuellt der Link die Zeile und ist 44 px hoch, aber nur auf
   schmalen Bildschirmen und an groben Zeigegeraeten. Die zweite
   Bedingung habe ich beim ersten Anlauf vergessen, und der Link blieb
   27 x 21 -- eine Regel, die nur unter idealen Bedingungen greift,
   hilft niemandem auf dem halben Weg dorthin.

4. EINE SEITE LUD DAS FALSCHE MANIFEST. `anruf-probe.html` verwies
   fest auf `crew.webmanifest`; die Seite ist aber fuer ALLE Rollen
   offen und damit auf beiden Adressen erreichbar. Wer sie im
   Agenturhaus oeffnet und die App installiert, bekam "DogFather
   Universe" mit dem Crew-Symbol auf den Startbildschirm. Alle anderen
   38 Seiten machen es richtig: `app.webmanifest`, und die Adresse
   biegt es um.

5. DER KNOPF "+ GIF HINZUFUEGEN" WAR 40 px HOCH, und der Kommentar
   daneben nannte das "die Hausgroesse". Die Hausgroesse sind 44 --
   fuenfmal in derselben Datei so begruendet. Die erste Reparatur
   griff nicht: Die Fingerregel stand 400 Zeilen VOR der Grundregel,
   und bei gleicher Staerke gewinnt die spaetere. Jetzt steht sie
   direkt dahinter, und der Knopf misst 133 x 44 am Finger, 133 x 40
   an der Maus.

   KEINE PRUEFUNG KONNTE DAS FINDEN: Die GIF-Tafel ist zu, solange
   niemand sie aufmacht, und alle Rundgaenge messen, was auf dem
   Bildschirm steht. Dafuer gibt es jetzt server/mess-gifs-handy.mjs.

6. ZWEI KLEINIGKEITEN AUS DER NACHT: eine Fehlerkennung ohne Satz
   (`unbekannter_punkt`) und eine Stelle in support.js, die den
   Serverfehler roh anzeigte statt durch `fehlerText` -- die zwei
   anderen Stellen derselben Datei machen es richtig. So entsteht eine
   Ausnahme: nicht aus Absicht, sondern weil man die Hausregel beim
   Neuschreiben nicht danebenliegen hatte.

7. TOTES CSS (.e-leerwahl, vier Regeln). Der Leerkasten ist am
   24.09. auf Filipes Wunsch wieder verschwunden, sein Stil blieb
   einen Tag laenger stehen.

=== ROT, ABER NICHT KAPUTT ===

Drei Pruefungen haben den Umbau vom 24.09. nicht mitbekommen:

  pruef-anruf meldete 31 Fehler und "ein Gespraech entsteht (403)".
  Sie meldete DogFather auf der AGENTUR-Adresse an und liess ihn dann
  die rechte Hand anrufen -- die es dort seit der Haustrennung nicht
  gibt. Der Server hatte recht. Jetzt telefoniert Team Dogi auf crew.,
  und der Creator bleibt auf workspace. -- seine Gegenprobe ist damit
  sogar schaerfer als vorher (ein Fremder aus dem ANDEREN Haus).
  96 -> 127 Pruefungen, 0 Fehler.

  pruef-crew-wand-bild erwartete vier Rollen auf der Zugangswand. Es
  sind fuenf, seit die linke Hand am 21.09. dazukam. Die Zeile stand
  unter einem Kommentar, der wortwoertlich vor festen Namen in
  Pruefungen warnt ("eine Zeitbombe mit Datum") -- und war selbst
  einer. Jetzt leitet sie die Rollen aus `rollenImHaus("crew")` ab,
  derselben Quelle, aus der der Server die Wand baut.

  pruef-entwicklung-kacheln rechnete noch mit "x von 68". Seit
  Filipes Wunsch ("es sollen nur die menge angezeigt werden die wir
  zutragen") ist das Ganze das, was jemandem zugetragen ist. Sie baut
  jetzt BEIDE Faelle -- eine Person mit vier zugetragenen Punkten und
  eine ohne -- und misst Ring, Bogen, Zeile und Vorleseschild gegen
  die Zuteilung. Dazu eine Gegenprobe mit einer Einschaetzung auf
  einem NICHT zugetragenen Punkt: zaehlt die Uebersicht sie mit,
  stuende dort 2 statt 1. 31 -> 34 Pruefungen, 0 Fehler.

=== WAS DIE BILDSCHAU ANGEHT ===

Meine eigene Messung meldete erst "Mitte 174 von 640" -- die Schau sah
kaputt aus. Sie war es nicht: `querySelector("img")` nahm das
Husky-Zeichen in der Kopfzeile statt des Bildes. Nachgemessen am
richtigen Element steht es auf 195 von 195 (Handy) und 640 von 640
(Rechner), und ein GIF oeffnet sich als GIF. Ein Messfehler, der wie
ein Befund aussieht, kostet mehr Zeit als gar keine Messung -- deshalb
steht die Begruendung jetzt im Quelltext der Messung.

GEMESSEN: pruef-breiten (9 Breiten, 38 Seiten, 84 252 Elemente),
pruef-support 63/0, pruef-gifs 17/0, pruef-chat 63/0, pruef-chat-optik
62/0, pruef-tippziele 11/0, pruef-css-klassen, pruef-struktur,
pruef-meldungen, pruef-modi-wortleck, pruef-crew-adresse,
pruef-installieren, pruef-aufgabenbrett, pruef-entwicklung -- alle 0
Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-25 12:31:21 +02:00

5580 lines
237 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =====================================================================
chat.css — Gespräche im Workspace.
Wunsch Filipe, 06.09.2026: *"richtig krass, richtig hochwertig,
professionell und ultra geil."*
WAS DAS HIER HEISST — und was nicht:
Nicht mehr Effekte. Ein Chat wird täglich benutzt und oft lange
angesehen; was beim ersten Blick beeindruckt, stört beim hundertsten.
Die Wirkung kommt aus vier Dingen:
1. EINE FLÄCHE, kein scrollendes Dokument. Die Seite hat die Höhe
des Fensters, gescrollt wird nur INNERHALB der Spalten. Das
Eingabefeld steht immer an derselben Stelle -- man muss es nie
suchen.
2. RUHE IM VERLAUF. Fast schwarzer Grund, die eigenen Nachrichten
in einem gedeckten Blau, fremde in einem neutralen Grau. Kein
Farbverlauf in der Blase; er macht Text unruhig zu lesen.
3. GRUPPIERUNG. Mehrere Nachrichten derselben Person rücken
zusammen und wiederholen den Namen nicht. Ein Datumstrenner
gliedert den Verlauf.
4. GENUG LUFT. Zeilenhöhe 1.5, Blasen mit ordentlichem Innenabstand.
Enge sieht auf einem Bildschirmfoto ordentlich aus und liest
sich schlecht.
Augenschonend ist Hausregel: keine harten Weißflächen, keine
Neonränder, Bewegung nur als kurze Blende.
===================================================================== */
/* ---------- Die Fläche --------------------------------------------------- */
.chat-seite {
/* Der Rest des Hauses scrollt; hier soll die Seite stehen.
100dvh statt 100vh: Auf dem Handy ändert sich die sichtbare Höhe,
wenn die Adresszeile ein- und ausfährt -- mit vh springt das
Eingabefeld dabei aus dem Bild.
--kopf-hoehe WIRD GEMESSEN, nicht geraten (chat.js). Der erste
Entwurf hatte hier 62 px stehen; am Handy ist die Kopfleiste aber
zweizeilig und gut doppelt so hoch. Folge: Die Seite war zu lang,
und das Eingabefeld stand halb unterhalb des Bildschirmrands --
ausgerechnet das Feld, um das es geht. Der Rückfallwert bleibt
stehen für den Moment vor der ersten Messung. */
/* Der sichere Bereich unten wird ABGEZOGEN (09.09.2026): `100dvh` ist
die ganze Bildhoehe einschliesslich der Gestenleiste. Ohne den Abzug
liegt das Eingabefeld darunter -- ausgerechnet das Feld, um das es
geht. Auf Geraeten ohne Gestenleiste ist der Wert 0. */
height: calc(100dvh - var(--kopf-hoehe, 62px) - var(--ws-sicher-unten, 0px));
display: flex; flex-direction: column;
padding-bottom: 0;
overflow: hidden;
}
/* =====================================================================
AUS EINEM KASTEN WERDEN ZWEI TAFELN (25.09.2026)
=====================================================================
Filipe: „ich will wirklich dass du das ingesamte veränderst und so
krass geil machst dass die ganze community und team morgen total
überrascht sind und den chat nicht wieder erkennen."
WAS VORHER DA WAR: ein Rechteck mit einer Linie in der Mitte. Beide
Haelften teilten sich einen Rahmen, einen Grund, eine Ebene -- die
Seite war eine Tabelle mit zwei Spalten.
WAS JETZT DA IST: zwei getrennte Tafeln, die ueber der Buehne
schweben, mit einer Fuge dazwischen. Links das Verzeichnis, rechts
das Gespraech -- zwei Dinge, die man auch als zwei sieht. Das ist
der eine Griff, der die Seite am staerksten veraendert, und er
kostet keine einzige Zeile im Skript.
WARUM DAS MEHR IST ALS EIN ABSTAND: Zwischen den Tafeln scheint die
Buehne durch. Damit bekommt die Seite eine Tiefe, die ein einzelner
Kasten nie haben kann -- man sieht, dass etwas DAHINTER ist, und
dass die Tafeln DARUEBER liegen.
DIE FUGE IST 14 px UND NICHT MEHR: Breiter, und die beiden Haelften
verlieren den Zusammenhang; sie gehoeren ja zusammen. 14 px sind
genug, um zwei Koerper zu sehen, und wenig genug, um sie als Paar
zu lesen.
===================================================================== */
.chat {
flex: 1;
min-height: 0; /* sonst wächst das Raster über die Fläche */
display: grid;
grid-template-columns: minmax(250px, 340px) 1fr;
gap: 14px;
border: 0;
border-radius: 0;
/* ==== DAS BUEHNENBILD SCHEINT DURCH (20.09.2026) ==================
Filipe: „ich will auch ein krasses hintergrundbild fuer den treff
chat. und die texte sollen immer in einer kachel sein."
BEIDES ZUSAMMEN, und in dieser Reihenfolge -- sie bedingen
einander: Ein Bild hinter dem Chat geht nur, WENN der Text auf
einer deckenden Kachel steht. Sonst liegt Schrift auf einem Foto,
und das ist an der hellsten Stelle unlesbar. Genau deshalb ist der
zweite Satz kein Zusatzwunsch, sondern die Bedingung fuer den
ersten.
WARUM KEIN EIGENES BILD, SONDERN DAS DER SEITE: Hinter jeder Seite
steht ohnehin eine Buehne (start.css, neun Szenen, fuer den Chat
die Lounge). Sie lag bisher hinter einer deckenden Flaeche --
vorhanden, geladen, unsichtbar. Sie durchscheinen zu lassen kostet
KEINE einzige Datei mehr, und auf der Adresse von Team Dogi kommt
damit von selbst deren eigene Fassung (crew-buehne-lounge), ohne
dass hier eine zweite Liste von neun Bildern stuende. Eine solche
Liste waere die, die beim zehnten Motiv vergessen wird.
DER SCHLEIER IST NICHT DEKORATION. Ohne ihn waere die Liste links
(Namen, Vorschauzeilen) Text direkt auf dem Foto. Er ist deshalb
kraeftig und wird gemessen, nicht geschaetzt. */
background:
radial-gradient(120% 90% at 0% 0%, rgba(255, 255, 255, .03), transparent 55%),
color-mix(in srgb, var(--flaeche) 88%, transparent);
overflow: hidden;
/* ===================================================================
TIEFE STATT FLAECHE (25.09.2026)
Filipe: „ich will dass du die komplette seite viel geiler und
moderner machst … es soll komplett aus der rolle fahren und was
was wir noch nie hatten, ich will es wirklich uebertrieben krass."
WAS VORHER DA WAR: zwei Spalten in EINEM Kasten, flach, mit einem
Hauchrand. Alles darin lag auf derselben Ebene -- Liste, Verlauf,
Blasen, Eingabe. Es war ordentlich und sah nach Formular aus.
WAS JETZT DAS SYSTEM IST -- und es ist EINES, nicht drei Ideen:
1. LICHTKANTE. Jede Flaeche bekommt oben eine haardünne helle
Linie und unten eine dunkle. Das ist der ganze Trick, mit dem
eine Flaeche zu einem Koerper wird: Licht faellt von oben.
2. TIEFENSCHATTEN. Lang, weich, weit unterhalb -- kein harter
Kasten-Schatten. Er traegt, er umrandet nicht.
3. GLAS. Was ueber etwas liegt, ist leicht durchscheinend und
verwischt, was dahinter ist. Dadurch sieht man, WAS oben
liegt, ohne eine einzige Linie mehr.
DREI REGELN, DIE DABEI GELTEN:
* KEIN NEON. Alle Toene bleiben gedeckt; die Akzentfarbe kommt
nur als Saum vor, nie als Flaeche. Augenschonend ist Vorgabe.
* KEINE BEWEGUNG OHNE GRUND, und jede laesst sich abbestellen
(`prefers-reduced-motion` ganz unten in dieser Datei).
* DIE BLASENFARBE BLEIBT DECKEND. Sie haengt an einer
Kontrastmessung (pruef-chatkachel), die den Farbwert selbst
prueft -- ein Verlauf oder Glas darauf wuerde die Messung
still falsch machen. Deshalb bekommt die Blase Tiefe ueber
Kante und Schatten, nicht ueber den Untergrund.
=================================================================== */
/* Der Grund liegt jetzt an den Tafeln, nicht am Raster. */
background: none;
box-shadow: none;
overflow: visible;
}
/* ---- DIE TAFEL: der Koerper, aus dem beide Haelften bestehen -------
Eine Regel fuer beide statt zweier fast gleicher: Die Fase oben
links ist dieselbe wie an jeder Kachel im Haus, der Rest ist das
Licht-und-Tiefe-System dieser Seite. */
.chat__spalte {
position: relative;
border: 1px solid rgba(255, 255, 255, .07);
border-radius: 0;
clip-path: polygon(var(--fase, 18px) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase, 18px));
background:
radial-gradient(140% 100% at 0% 0%, rgba(255, 255, 255, .045), transparent 52%),
linear-gradient(168deg, rgba(17, 24, 36, .86) 0%, rgba(8, 12, 19, .9) 100%);
backdrop-filter: blur(22px) saturate(118%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .09),
inset 0 -1px 0 rgba(0, 0, 0, .55),
0 40px 80px -40px rgba(0, 0, 0, .96),
0 8px 22px -14px rgba(0, 0, 0, .8);
overflow: hidden;
}
/* Die Fuge zwischen den Spalten ist keine Linie, sondern eine Kante:
links dunkel, rechts hell -- so, wie zwei Bleche aneinanderstossen.
Eine Linie haette gesagt "hier ist eine Grenze"; die Kante sagt
"hier liegt eine Platte auf einer anderen". */
/* DIE FUGE VON GESTERN IST WEG (25.09.2026). Sie zeichnete eine
Kante zwischen zwei Haelften EINES Kastens. Seit es zwei Tafeln
gibt, liegt dort echter Abstand -- eine gemalte Kante daneben waere
eine Linie zu viel. Die Leuchtschiene links an der Liste bleibt
dagegen: Sie gehoert zur Tafel, nicht zur Fuge. */
.chat__spalte--liste::after {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg,
color-mix(in srgb, var(--akzent) 55%, #ffffff) 0%,
color-mix(in srgb, var(--akzent) 75%, transparent) 30%,
transparent 100%);
box-shadow: 0 0 14px -2px color-mix(in srgb, var(--akzent) 55%, transparent);
pointer-events: none; z-index: 3;
}
.chat__spalte {
display: flex; flex-direction: column;
min-height: 0; min-width: 0;
}
/* =====================================================================
AUS DEM TRENNER WIRD LICHT (25.09.2026)
Hier stand eine senkrechte Linie am linken Rand des Verlaufs – der
Trenner zwischen Liste und Verlauf, aus der Zeit, als beide noch
EIN Kasten waren. Seit dem Umbau auf zwei Tafeln liegt dort echter
Abstand; die Linie klebte seitdem ohne Aufgabe an der Kante der
rechten Tafel. Eine Linie, die nichts mehr trennt, ist eine Linie
zu viel.
An ihrer Stelle liegt jetzt ein sehr weicher Schein in der
Akzentfarbe, oben rechts – so, als stünde das Licht der Bühne
hinter der Tafel, und unten links ein Hauch Gegenlicht. Erst damit
sieht die große leere Fläche rechts nach einem Raum aus statt nach
einem leeren Kasten.
SCHWACH, UND ZWAR ABSICHTLICH: 13 % Akzent in einem Verlauf, der
nach 62 % ausläuft – am hellsten Punkt keine vier Prozent Deckung.
Er soll Tiefe machen, nicht leuchten. Ein Chat wird stundenlang
angesehen; was beim ersten Mal auffällt, nervt beim zwanzigsten
(Hausregel: augenschonend).
`z-index: -1` UND NICHT 0: `.chat__spalte` hat `backdrop-filter`
und bildet damit einen eigenen Stapelzusammenhang. Ein negativer
Wert legt den Schein darin über den Grund der Tafel, aber unter
alles, was darin steht. Mit `0` läge er über den Nachrichten – ein
Schleier über der Schrift, und genau das wäre der Fehler, den diese
Datei an anderer Stelle schon zweimal notiert hat.
===================================================================== */
.chat__spalte--verlauf { position: relative; }
.chat__spalte--verlauf::before {
content: ""; position: absolute; inset: 0;
background:
radial-gradient(72% 56% at 88% 0%,
color-mix(in srgb, var(--akzent) 13%, transparent), transparent 62%),
radial-gradient(60% 46% at 6% 100%,
rgba(255, 255, 255, .032), transparent 58%);
pointer-events: none;
z-index: -1;
}
.chat__kopf {
display: flex; align-items: center; gap: 12px;
padding: 16px 17px 15px;
/* KEINE LINIE, SONDERN EINE KANTE (25.09.2026) -- dieselbe
Ueberlegung wie an der Fuge zwischen den Spalten: Der Kopf liegt
UEBER dem, was darunter rollt. Unten dunkel, darueber ein Hauch
hell: Damit sieht man die Ebene, statt sie zu lesen. */
border-bottom: 0;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .06),
0 1px 0 0 rgba(0, 0, 0, .45),
0 2px 0 0 rgba(255, 255, 255, .035),
0 14px 22px -20px rgba(0, 0, 0, .9);
background: linear-gradient(180deg,
rgba(255, 255, 255, .035) 0%, rgba(255, 255, 255, .008) 100%);
position: relative; z-index: 2;
flex: none;
/* UMBRECHEN STATT DEN NAMEN ZERDRUECKEN (20.09.2026).
Gemessen am Handy, mit einem Gespraech namens "Team-Runde":
360 px -> 0 px sichtbar (98 noetig)
390 px -> 12 px
412 px -> 33 px
1280 px -> passt
Auf JEDEM Telefon stand also kein Name da. Man oeffnet ein
Gespraech und sieht nicht, mit wem man schreibt -- und weil die
Zeile nicht leer aussieht (Zurueck-Pfeil, fuenf Knoepfe), wirkt
sie nicht kaputt, sondern nur eng.
URSACHE: `.chat__kopf-text` hatte `min-width: 0` und keinen
Wachstumsanteil, durfte also bis auf null schrumpfen. Die
Knopfreihe daneben hat `flex: none` und schrumpft nie -- und seit
die Knoepfe am Finger 44 px breit sind, bleibt bei sechs Knoepfen
nichts uebrig.
KEINE NEUE SCHWELLE. Dieses Haus ist an festen Breiten schon
zweimal hereingefallen (siehe die Kopfleiste, 06.09.2026): Eine
Zahl, die heute aufgeht, geht beim naechsten Knopf nicht mehr auf,
und niemand rechnet sie nach. `flex-wrap` bricht genau dann um,
wenn der Platz wirklich nicht reicht -- es MISST, statt zu
rechnen. Kommt morgen ein siebter Knopf dazu, stimmt es weiter. */
flex-wrap: wrap;
}
/* DER NAME BEKOMMT DEN RESTPLATZ und hat eine Untergrenze: Unter
ungefaehr acht Zeichen ist ein Name keine Auskunft mehr, sondern ein
Rest. Wird er unterschritten, wandert die Knopfreihe eine Zeile
tiefer -- das ist der Umbruch oben. */
.chat__kopf-text { min-width: 0; flex: 1 1 8rem; }
/* ---- Das Gesicht im Kopf des Gesprächs (25.09.2026) -----------------
Es trägt die Klasse `.chat-raum__zeichen` und bekommt damit Farbe,
Licht, Saum und Profilbild der Liste geschenkt. Hier steht nur, was
am Kopf anders ist: eine Spur kleiner, damit es die Überschrift
nicht überragt.
`[hidden]` MUSS hier stehen. `.chat-raum__zeichen` setzt
`display: grid`, und eine Klassenregel schlägt das eingebaute
`display: none` des Browsers – ohne diese Zeile stünde ein leerer
Kreis da, solange kein Gespräch offen ist. Genau diese Falle hat
dieses Haus bei `hidden` schon einmal erwischt.
AM HANDY BLEIBT ES WEG (siehe die schmale Fassung am Dateiende).
Nachgerechnet bei 390 px: Zurück-Pfeil 44 + Zeichen 40 + drei
Knöpfe 132 + vier Abstände 48 = 264. Für den Namen blieben 126 px,
seine Untergrenze sind 128 (`flex: 1 1 8rem`) – die Knopfreihe
fiele also eine Zeile tiefer, und der Kopf würde 44 px höher.
Dafür ist es zu wenig wert: Am Handy kommt man aus der Liste, in
der man das Gesicht gerade angetippt hat. */
.chat__kopf-zeichen {
width: 40px; height: 40px;
font-size: .82rem;
}
.chat__kopf-zeichen[hidden] { display: none; }
/* DER TITEL WAR SO GROSS WIE DIE VORSCHAUZEILE DARUNTER (25.09.2026).
Im Bildschirmfoto stand „VanVan" in derselben Staerke wie „Du:
Perfekt, danke dir" in der Liste -- der Name des Gespraechs, in dem
man steht, war nicht wichtiger als eine Vorschau. Jetzt groesser,
fester und leicht enger gesetzt: Eine Ueberschrift darf wie eine
aussehen.
`letter-spacing` NEGATIV und nicht positiv: Gesperrte Schrift wirkt
bei grossen Graden ausgefranst; enger gesetzt wirkt sie gesetzt.
Unter 1 rem waere es andersherum -- deshalb steht es hier und nicht
an der Unterzeile. */
.chat__titel {
margin: 0;
font-size: 1.22rem; font-weight: 750; letter-spacing: -.015em;
color: #f4f8fd;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Die Unterzeile sagt, WER sonst dabei ist. Sie stand in derselben
Farbe wie jede andere Nebensache; jetzt leicht gesperrt und in
Versalien -- damit liest sie sich als Angabe zum Titel und nicht
als angefangener Satz. */
.chat__unter {
margin: 3px 0 0;
font-size: .72rem; color: var(--text-still);
letter-spacing: .05em; text-transform: uppercase; font-weight: 600;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* WIE VIELE WARTEN AUF MICH (24.09.2026).
Die Summe aller ungelesenen Nachrichten, direkt neben der
Überschrift. Sie steht nur da, wenn es etwas zu zählen gibt — eine
Null wäre jeden Tag im Weg für den einen Tag, an dem sie etwas sagt
(das Verstecken macht das Skript).
DIESELBE FORM WIE DIE ZAHL AN DER ZEILE, absichtlich: Wer sie oben
sieht und unten wiederfindet, muss nicht lernen, dass es dasselbe
ist. */
.chat__zaehler {
flex: none;
min-width: 22px; height: 22px; padding: 0 7px;
display: inline-grid; place-items: center;
border-radius: 999px;
font-size: .72rem; font-weight: 750;
font-variant-numeric: tabular-nums;
color: #0b0f16;
background: linear-gradient(160deg,
color-mix(in srgb, var(--akzent) 92%, #ffffff),
var(--akzent));
}
.chat__kopf .knopf { margin-left: auto; flex: none; }
/* Der Zurück-Pfeil gehört dem Handy. Am Rechner stehen beide Spalten
nebeneinander, da gibt es nichts, wohin man zurückkönnte. */
.chat__zurueck {
display: none;
flex: none;
/* 44px statt 34px (19.09.2026): Zwischen 761 und 860 px -- also auf
jedem Tablet hochkant -- greift die 44-px-Hausregel nicht, und
dieser Knopf war dort 34x34, also 40 Prozent weniger Flaeche als
noetig. Er ist der EINZIGE Weg von einem Gespraech zurueck in die
Liste; wer ihn verfehlt, sitzt fest. */
width: 44px; height: 44px;
align-items: center; justify-content: center;
border: 1px solid var(--rand); border-radius: var(--radius-klein);
background: rgba(255, 255, 255, .04);
color: var(--text-leise); cursor: pointer;
}
.chat__zurueck svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.chat__zurueck:hover { color: var(--text); border-color: var(--rand-hell); }
/* ---- Das Suchfeld ---------------------------------------------------
Vorher ein nackter Kasten in der Hausform. Er tat, was er sollte,
sah aber aus wie ein Eingabefeld in einem Formular — und dies ist
kein Formular, sondern eine Suche über einer Liste.
DIE LUPE STECKT IM HINTERGRUND und nicht als eigenes Element im
HTML: Ein Zeichen, das nichts tut und nichts sagt, braucht keinen
Platz im Dokument; manche Vorleseprogramme lesen es sonst als
„Grafik" mit. Das Feld selbst trägt seinen Namen über aria-label.
PILLENFORM, weil darunter Zeilen mit 14px-Ecken stehen — ein
scharfkantiger Kasten darüber wirkt wie von einer anderen Seite. */
/* =====================================================================
DIE DREI FAECHER (25.09.2026)
Filipe: „ich will 3 kategorien haben. chats mit einzelnen personen,
gruppen chats und kanäle."
EINE MULDE MIT DREI SCHALTERN, nicht drei freie Knoepfe: Drei Dinge
nebeneinander, die einander ausschliessen, liest man nur dann als
EINE Entscheidung, wenn sie in einer gemeinsamen Fassung sitzen.
Sonst sind es drei Sachen.
DAS GEWAEHLTE FACH LIEGT OBEN AUF -- heller Grund, Lichtkante,
Schatten darunter. Die anderen liegen IN der Mulde. Man sieht die
Wahl also an der Tiefe und nicht nur an der Farbe; das trennt auch
dann, wenn jemand Farben schlecht unterscheidet.
DIE ZAHL DER UNGELESENEN STEHT AM FACH und nicht nur an der Zeile:
Ein geschlossenes Fach waere sonst ein Ort, an dem Nachrichten
liegen bleiben, ohne dass es jemand sieht.
===================================================================== */
.chat-arten {
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 3px;
margin: 12px 12px 0;
padding: 3px;
border-radius: 14px;
border: 1px solid rgba(255, 255, 255, .06);
background: linear-gradient(180deg, rgba(0, 0, 0, .4) 0%, rgba(255, 255, 255, .02) 100%);
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .75),
0 1px 0 rgba(255, 255, 255, .05);
}
.chat-art {
position: relative;
display: flex; align-items: center; justify-content: center; gap: 6px;
min-height: 38px; padding: 6px 4px;
border: 1px solid transparent; border-radius: 11px;
background: none;
font: inherit; font-size: .78rem; font-weight: 650;
letter-spacing: .01em;
color: var(--text-still); cursor: pointer;
transition: color .16s ease, background-color .16s ease,
border-color .16s ease, box-shadow .16s ease;
}
.chat-art:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.chat-art:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
.chat-art[aria-selected="true"] {
color: #f2f7fd;
border-color: rgba(255, 255, 255, .1);
background: linear-gradient(180deg,
rgba(255, 255, 255, .1) 0%, rgba(255, 255, 255, .035) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .16),
0 6px 14px -10px rgba(0, 0, 0, .95);
}
/* Der Saum in der Akzentfarbe sagt, welches Fach offen ist -- er
sitzt UNTEN am Schalter, wie ein Reiter an einer Mappe. */
.chat-art[aria-selected="true"]::after {
content: ""; position: absolute; left: 22%; right: 22%; bottom: -1px; height: 2px;
border-radius: 2px 2px 0 0;
background: var(--akzent);
box-shadow: 0 0 10px -1px color-mix(in srgb, var(--akzent) 75%, transparent);
}
.chat-art__name { white-space: nowrap; }
.chat-art__zahl {
font-size: .72rem; font-weight: 700; opacity: .6;
font-variant-numeric: tabular-nums;
}
.chat-art[aria-selected="true"] .chat-art__zahl { opacity: .85; }
/* DAS @ AM FACH (25.09.2026).
Es sagt „hier ging es an dich" -- dieselbe Auskunft wie das @ an
der Zeile, nur eine Ebene hoeher, damit ein geschlossenes Fach sie
nicht verschluckt.
ES IST KEINE MARKE MIT FLAECHE. Neben der Ungelesen-Marke stuenden
sonst zwei gleich laute Punkte nebeneinander, und man muesste
lesen, um sie zu unterscheiden. So bleibt ein Zeichen in der
Akzentfarbe -- gleiche Bedeutung, andere Gestalt.
`text-shadow` STATT `box-shadow`: Der Schein soll am Buchstaben
haengen, nicht an einem Kasten darum. */
.chat-art__at {
flex: none;
font-size: .82rem; font-weight: 800; line-height: 1;
color: color-mix(in srgb, var(--akzent) 45%, #ffffff);
text-shadow: 0 0 9px color-mix(in srgb, var(--akzent) 70%, transparent);
}
/* Die Ungelesenen: klein, in der Warnfarbe, oben rechts am Schalter --
dort, wo man sie von jedem Programm her sucht. */
/* ENTWEDER ODER, NICHT BEIDES (25.09.2026). Im ersten Anlauf stand
die Ungelesen-Marke absolut oben rechts -- und lag damit genau auf
der Gesamtzahl. Zwei Zahlen uebereinander sind schlimmer als eine
zu wenig.
Was wartet, ist wichtiger als was da ist: Gibt es Ungelesene, tritt
die Gesamtzahl zurueck. `:has()` entscheidet das im Stilblatt, damit
beide Zahlen im Baum bleiben -- eine Vorlesehilfe liest so weiter
"Personen, 3 Gespräche, 2 ungelesene Nachrichten". */
.chat-art:has(.chat-art__neu) .chat-art__zahl { display: none; }
/* 0,72 rem UND NICHT 0,64 (nachgebessert 25.09.2026).
pruef-css-klassen hat es gemeldet: „43 Stellen unter 11,5 px – das
ist 1 MEHR als die Grundlinie 42." Die eine neue war genau diese
Marke: 0,64 rem sind 10,24 px. Die Hausgrenze liegt bei 11,5, weil
Schrift darunter auf einem Telefon zu flimmern anfängt – und eine
Zahl, die man nicht lesen kann, ist keine Auskunft.
DAS IST DER ZWEITE ANLAUF AM SELBEN TAG. Heute früh stand die
Fußzeile der Nachricht auf 0,66 rem und dieselbe Prüfung hat sie
zurückgeholt. Zweimal derselbe Reflex: „klein wirkt leise". Leise
macht in diesem Haus die Deckung und die Farbe, nicht die Größe.
DIE MARKE WÄCHST MIT: 18 px Höhe sind für 11,5-px-Schrift zu
knapp – bei „99+" stieße die Schrift oben und unten an. 20 px
lassen 4 px Luft, und die Marke bleibt kleiner als die 22 px des
Zählers an der Zeile (sie ist die kleinere Auskunft von beiden). */
.chat-art__neu {
flex: none;
min-width: 20px; height: 20px; padding: 0 5px;
display: grid; place-items: center;
border-radius: 999px;
font-size: .72rem; font-weight: 750; line-height: 1;
font-variant-numeric: tabular-nums;
color: #16060a;
background: linear-gradient(160deg,
color-mix(in srgb, var(--warn) 88%, #ffffff), var(--warn));
box-shadow:
0 0 0 1px rgba(0, 0, 0, .5),
0 3px 8px -3px color-mix(in srgb, var(--warn) 70%, transparent);
}
@media (max-width: 560px) {
.chat-art { font-size: .74rem; }
/* Die GESAMTZAHL faellt weg, nicht die Ungelesenen und nicht das @.
Wie viele Gespraeche es gibt, sieht man in der Liste darunter;
was darin auf einen wartet, nicht. */
.chat-art__zahl { display: none; }
}
.chat__suche { padding: 10px 12px 8px; flex: none; }
/* EINGELASSEN STATT AUFGELEGT. Ein Eingabefeld ist eine Vertiefung --
Licht faellt hinein, nicht darauf. Deshalb hier der Schatten INNEN
und oben, genau andersherum als bei allem, was obenauf liegt. Das
ist derselbe Gedanke wie ueberall auf dieser Seite, nur umgedreht:
Wo etwas liegt, liegt Licht oben; wo etwas fehlt, liegt Schatten
oben. */
.chat__suche input {
width: 100%;
padding-left: 38px;
border-radius: 999px;
border: 1px solid rgba(0, 0, 0, .45);
background-color: rgba(4, 7, 12, .5);
box-shadow:
inset 0 2px 4px -1px rgba(0, 0, 0, .65),
inset 0 -1px 0 rgba(255, 255, 255, .05);
transition: box-shadow .18s ease, border-color .18s ease;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a5bb' stroke-width='1.9' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6.2'/%3E%3Cpath d='m15.8 15.8 4 4'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: 12px 50%;
background-size: 16px 16px;
}
.chat__suche input:focus {
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
box-shadow:
inset 0 2px 4px -1px rgba(0, 0, 0, .65),
0 0 0 3px color-mix(in srgb, var(--akzent) 18%, transparent);
}
.chat__leer {
margin: 0; padding: 20px 18px;
font-size: .86rem; color: var(--text-still); line-height: 1.55;
}
/* ---- Der leere Raum rechts (24.09.2026) -----------------------------
Vorher stand der Satz oben links in einer Fläche von rund tausend
mal siebenhundert Pixeln. Das sah nicht ruhig aus, sondern unfertig
— als wäre die Seite nicht zu Ende geladen.
Der Satz ist Wort für Wort derselbe geblieben: Er sagt, was zu tun
ist, und das war nie das Problem. Er steht nur nicht mehr in der
Ecke.
DAS ZEICHEN IST SEHR LEISE: Es soll den Blick auffangen, nicht ihn
halten. Wer hierher sieht, will ein Gespräch öffnen — kein Bild
ansehen. */
.chat__leer--mitte {
flex: 1; min-height: 0;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
gap: 16px; padding: 30px;
text-align: center;
}
.chat__leer-text { max-width: 30ch; }
/* Der leere Verlauf ist die erste Flaeche, die man sieht, wenn man
hereinkommt -- und bis heute war sie das Blasseste auf der Seite.
Jetzt ein Koerper mit Licht, Saum und einem weichen Schein: Sie sagt
"hier ist Platz", nicht "hier fehlt etwas". */
.chat__leer-zeichen {
display: grid; place-items: center;
width: 92px; height: 92px;
border-radius: 50%;
border: 1px solid color-mix(in srgb, var(--akzent) 26%, transparent);
background:
radial-gradient(90% 90% at 50% 18%,
color-mix(in srgb, var(--akzent) 16%, transparent), transparent 72%),
linear-gradient(170deg, rgba(255, 255, 255, .05), rgba(0, 0, 0, .18));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .16),
inset 0 -6px 14px -8px rgba(0, 0, 0, .7),
0 0 0 8px color-mix(in srgb, var(--akzent) 5%, transparent),
0 22px 44px -24px rgba(0, 0, 0, .95);
}
.chat__leer-zeichen svg {
width: 34px; height: 34px;
fill: none; stroke: color-mix(in srgb, var(--akzent) 55%, var(--text-still));
stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
/* =====================================================================
DIE GESPRÄCHSLISTE (neu gebaut am 24.09.2026)
=====================================================================
Filipe, mit zwei Bildschirmfotos: „ich will dass die komplette
kachel viel krasser und geiler aussieht. der hintergrund der kachel
soll gleich bleiben aber ansonsten soll alles viel krasser schöner
und geiler sein, viel moderner. hau richtig rein und mach was
spezielles."
DER HINTERGRUND BLEIBT unangetastet – ausdrücklicher Wunsch, und er
ist ohnehin gemessen (siehe der Block weiter oben über die Deckkraft
der Fläche). Geändert wird alles, was darauf liegt.
WAS AUF SEINEM BILD NICHT STIMMTE, und zwar nicht als Geschmack:
1. Bei „Das Rudel" stand das „@" rechts oben und die orange „6"
eine ZEILE TIEFER, links unter dem Zeichen. Das Raster hatte
drei Spalten und bekam vier Kinder – das vierte fiel um.
Ausgerechnet die wichtigste Auskunft der Liste („hier warten
sechs") landete damit an der unauffälligsten Stelle, und die
Zeile war höher als alle anderen.
2. Die Zeilen hatten keine Kanten. Sieben Gespräche standen als
eine einzige graue Fläche da; was gerade offen ist, sah fast
aus wie der Rest.
3. Alles war gleich laut: Name, Uhrzeit und Vorschau in drei
Grautönen, die sich kaum unterscheiden.
WAS JETZT ANDERS IST
ZEILEN SIND KARTEN. Jede hat ihre eigene Fläche, die beim
Überfahren aufwacht. Das offene Gespräch trägt eine Schiene an der
linken Kante – man sieht auch nach dem Scrollen, wo man ist.
DREI ARTEN, DREI FORMEN. Ein Mensch ist rund, eine Gruppe ist ein
abgerundetes Quadrat, ein Kanal trägt die Raute. Auch ohne Farbe
auseinanderzuhalten – wer Farben schlecht unterscheidet, sieht die
Form.
UNGELESENES IST DAS LAUTESTE auf der Zeile, und sonst nichts: die
Zahl in der Akzentfarbe, der Name kräftiger, die Fläche eine Spur
heller. Alles andere tritt zurück.
AUGENSCHONEND (Hausregel): kein Leuchten, kein Blinken, keine
Bewegung außer einem kurzen Farbwechsel beim Überfahren. Ein Chat
wird stundenlang angesehen – was einmal auffällt, nervt beim
zwanzigsten Mal.
------------------------------------------------------------------- */
.chat__liste {
flex: 1; min-height: 0;
overflow-y: auto;
margin: 0; padding: 8px 8px 14px; list-style: none;
display: grid; gap: 4px; align-content: start;
/* Ein schmaler, ruhiger Balken statt des breiten Systemstreifens —
die Liste ist nur rund 300 px breit, da nimmt der Standardbalken
ein Zwanzigstel davon weg. */
scrollbar-width: thin;
scrollbar-color: color-mix(in srgb, var(--rand-hell) 70%, transparent) transparent;
}
.chat-raum__knopf {
--r: var(--akzent);
position: relative;
width: 100%;
/* DREI SPALTEN, UND ES BLEIBEN DREI. Alles, was rechts steht, sitzt
in `.chat-raum__rail` — käme morgen eine vierte Marke dazu, bricht
das Raster nicht wieder um (siehe Punkt 1 oben). */
display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center; gap: 11px;
padding: 11px 12px;
border: 1px solid transparent;
border-radius: 16px;
background: transparent;
color: inherit; font: inherit; text-align: left; cursor: pointer;
/* DIE ZEILE HEBT SICH, SIE FAERBT SICH NICHT (25.09.2026). Eine
Einfaerbung beim Ueberfahren sagt "markiert"; ein Anheben sagt
"anfassbar". Das ist der Unterschied zwischen einer Tabelle und
einer Bedienung -- und der Grund, warum `transform` hier steht.
Ein Pixel genuegt: Mehr wackelt, weniger sieht niemand. */
transition: background .18s ease, border-color .18s ease,
transform .18s ease, box-shadow .18s ease;
}
.chat-raum__knopf:hover {
background: linear-gradient(180deg,
rgba(255, 255, 255, .062) 0%, rgba(255, 255, 255, .022) 100%);
border-color: color-mix(in srgb, var(--rand-hell) 60%, transparent);
transform: translateY(-1px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 10px 20px -14px rgba(0, 0, 0, .9);
}
@media (prefers-reduced-motion: reduce) {
.chat-raum__knopf { transition: background .18s ease, border-color .18s ease; }
.chat-raum__knopf:hover { transform: none; }
}
.chat-raum__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
/* DIE SCHIENE AM OFFENEN GESPRÄCH.
Hier stand bis zum 24.09.2026 eine zweite, schönere Fassung dieser
Regel weiter unten in derselben Datei — mit dem Selektor
`.chat-raum__knopf[data-an="ja"]`. Den hat nie etwas gesetzt: Das
Skript schreibt `data-offen` an das <li>, nicht `data-an` an den
Knopf. Die Regel war also monatelang tote Gestaltung, und das
offene Gespräch bekam nur die blassere erste Fassung.
Jetzt gibt es eine Regel, und sie greift. */
.chat-raum[data-offen="ja"] .chat-raum__knopf {
background: linear-gradient(90deg,
color-mix(in srgb, var(--akzent) 17%, transparent),
color-mix(in srgb, var(--akzent) 5%, transparent) 62%,
rgba(255, 255, 255, .03));
border-color: color-mix(in srgb, var(--akzent) 34%, transparent);
}
/* DIESELBE KANTE WIE AN DER BLASE (25.09.2026) -- mit Schein und
Verlauf statt eines flachen Strichs. Eine Seite, eine Sprache: Wer
links die Kante sieht, sieht rechts dieselbe wieder. */
.chat-raum[data-offen="ja"] .chat-raum__knopf::before {
content: "";
position: absolute; left: -1px; top: 9px; bottom: 9px;
width: 3px; border-radius: 0 3px 3px 0;
background: linear-gradient(180deg,
color-mix(in srgb, var(--akzent) 55%, #ffffff) 0%,
var(--akzent) 45%,
color-mix(in srgb, var(--akzent) 70%, transparent) 100%);
box-shadow: 0 0 12px -1px color-mix(in srgb, var(--akzent) 75%, transparent);
}
/* Ungelesenes ist der Grund, warum man hier ist — die Zeile hebt sich
eine Spur, aber nur eine. */
.chat-raum[data-neu="ja"] .chat-raum__knopf {
background: rgba(255, 255, 255, .05);
border-color: color-mix(in srgb, var(--rand) 80%, transparent);
}
.chat-raum[data-neu="ja"][data-offen="ja"] .chat-raum__knopf {
border-color: color-mix(in srgb, var(--akzent) 34%, transparent);
}
/* ---- Das Zeichen: Mensch, Gruppe, Kanal ----------------------------- */
/* DAS ZEICHEN IST EIN KOERPER, KEIN KREIS (25.09.2026).
Vorher: ein flacher Kreis mit 13 % Farbe und einem Rand. Zwoelf
davon untereinander lasen sich wie eine Lochreihe.
Jetzt liegt Licht darauf (oben hell, unten dunkel), und darum sitzt
ein feiner Saum in der Rollenfarbe. Der Buchstabe bekommt einen
eigenen leichten Schatten, damit er auf der Flaeche steht statt
darin zu schwimmen. */
.chat-raum__zeichen {
flex: none;
position: relative;
width: 46px; height: 46px; border-radius: 50%;
display: grid; place-items: center;
font-size: .9rem; font-weight: 750; letter-spacing: .02em;
color: var(--r);
background:
linear-gradient(162deg,
color-mix(in srgb, var(--r) 26%, transparent) 0%,
color-mix(in srgb, var(--r) 9%, transparent) 55%,
rgba(0, 0, 0, .22) 100%);
border: 1px solid color-mix(in srgb, var(--r) 34%, transparent);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .16),
inset 0 -2px 4px -2px rgba(0, 0, 0, .6),
0 0 0 1px rgba(0, 0, 0, .35),
0 6px 14px -8px color-mix(in srgb, var(--r) 45%, transparent);
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
/* Ist ein Bild drin (Profilbild), fuellt es den Kreis randlos aus --
der Saum bleibt und haelt die Rollenfarbe. */
.chat-raum__zeichen img {
width: 100%; height: 100%; border-radius: 50%; object-fit: cover;
}
/* Dieselben Rollenfarben wie überall im Haus. */
.chat-raum__zeichen[data-rolle="admin"] { --r: var(--dogi-haupt); }
.chat-raum__zeichen[data-rolle="manager"] { --r: var(--manager-haupt); }
.chat-raum__zeichen[data-rolle="scout"] { --r: var(--scout-haupt); }
.chat-raum__zeichen[data-rolle="creator"] { --r: var(--creator-haupt); }
/* Eine Gruppe zeigt ihre Größe statt einer Initiale — der Name steht
ohnehin daneben. Eckiger als ein Mensch, runder als ein Kanal. */
.chat-raum__zeichen[data-gruppe="ja"] {
--r: #a0aec4;
border-radius: 14px;
font-size: .95rem;
font-variant-numeric: tabular-nums;
}
/* ---- Die Mitte ------------------------------------------------------ */
.chat-raum__mitte { min-width: 0; }
.chat-raum__oben { display: flex; align-items: baseline; gap: 8px; }
.chat-raum__name {
flex: 1; min-width: 0;
font-size: .92rem; font-weight: 620; color: var(--text-leise);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-raum__zeit {
flex: none;
font-size: .73rem; color: var(--text-still);
font-variant-numeric: tabular-nums;
}
.chat-raum__vorschau {
display: block; margin-top: 3px;
font-size: .79rem; line-height: 1.35; color: var(--text-still);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* WER GESCHRIEBEN HAT, eine Spur heller als der Satz. Beim Überfliegen
einer Gruppe sucht man den Namen, nicht den Text — vorher war beides
derselbe Grauton und man musste lesen. */
.chat-raum__wer {
color: color-mix(in srgb, var(--text-leise) 82%, transparent);
font-weight: 600;
}
.chat-raum__vorschau[data-weg="ja"] { font-style: italic; opacity: .78; }
/* Ungelesen: die Zahl UND ein kräftigerer Name. Nur eine Zahl übersieht
man beim Überfliegen. */
.chat-raum[data-neu="ja"] .chat-raum__name { color: var(--text); font-weight: 720; }
.chat-raum[data-neu="ja"] .chat-raum__vorschau { color: var(--text-leise); }
.chat-raum[data-neu="ja"] .chat-raum__zeit { color: var(--text-leise); }
/* ---- Die rechte Spalte ---------------------------------------------- */
/* Sie steht IMMER da, auch leer — sonst wäre die Mitte bei Zeilen ohne
Marke breiter als bei Zeilen mit, und die Namen stünden nicht mehr
untereinander. Eine Liste, deren Kanten wandern, wirkt unruhig, ohne
dass man sagen kann, warum. */
.chat-raum__rail {
flex: none;
display: flex; align-items: center; gap: 6px;
min-width: 22px; justify-content: flex-end;
}
.chat-raum__zahl {
flex: none;
min-width: 22px; height: 22px; padding: 0 7px;
display: grid; place-items: center;
border-radius: 999px;
font-size: .72rem; font-weight: 750;
font-variant-numeric: tabular-nums;
color: #0b0f16;
background: linear-gradient(160deg,
color-mix(in srgb, var(--akzent) 92%, #ffffff),
var(--akzent));
/* Der Saum ringsum trennt die Marke vom Untergrund, auch wenn sie
zufaellig auf einer gleich hellen Stelle liegt -- und der Schein
darunter macht aus dem Fleck eine Marke, die aufliegt. */
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .55),
0 0 0 1px rgba(0, 0, 0, .45),
0 4px 10px -4px color-mix(in srgb, var(--akzent) 60%, transparent);
}
/* ---------- Rechts: der Verlauf ------------------------------------------ */
/* =====================================================================
DER VERLAUF HAT EINEN SAUM (25.09.2026)
Oben und unten liefen die Nachrichten bisher an einer harten Kante
aus -- eine halbe Blase, dann Schluss. Das sieht aus wie ein
Fehler, nicht wie ein Rand.
`mask-image` blendet die letzten Pixel weich aus: Die Nachricht
laeuft UNTER den Kopf und unter die Konsole, statt an ihnen
abgeschnitten zu werden. Es ist derselbe Gedanke wie beim Glas --
man sieht, dass da noch etwas ist.
NUR 18 UND 14 PIXEL: Mehr, und der Text am Rand waere schlechter
lesbar; das waere ein Schoenheitsgewinn auf Kosten der Lesbarkeit,
und der geht in diesem Haus nie vor.
`-webkit-mask-image` daneben, weil Safari die Eigenschaft bis
heute nur mit Praefix kennt -- ohne sie hat Safari gar keinen
Saum (was harmlos ist: dann sieht es aus wie vorher). */
.chat__verlauf {
flex: 1; min-height: 0;
overflow-y: auto;
padding: 18px 18px 8px;
mask-image: linear-gradient(180deg,
transparent 0, #000 18px, #000 calc(100% - 14px), transparent 100%);
-webkit-mask-image: linear-gradient(180deg,
transparent 0, #000 18px, #000 calc(100% - 14px), transparent 100%);
display: flex; flex-direction: column; gap: 3px;
/* IM VERLAUF DARF MEHR DURCHKOMMEN als in der Liste links: Hier steht
jede Zeile auf einer eigenen, deckenden Kachel -- dazwischen ist
Luft, und durch die Luft sieht man den Raum. Links stehen Namen
ohne Kachel, dort bleibt es dichter.
Ein eigener Schleier statt einer Aenderung am Grund darueber: So
hat jede der beiden Spalten ihren Wert, und eine Aenderung an der
einen verstellt die andere nicht. */
background: linear-gradient(180deg,
color-mix(in srgb, var(--grund) 58%, transparent),
color-mix(in srgb, var(--grund) 34%, transparent));
/* Ein weicher Schleier am oberen Rand: Der Verlauf scrollt unter den
Kopf, statt an einer harten Kante abgeschnitten zu wirken. */
mask-image: linear-gradient(180deg, transparent, #000 14px);
}
/* KURZE GESPRÄCHE LIEGEN UNTEN AN.
Bei drei Nachrichten standen sie oben, und darunter klaffte der halbe
Bildschirm -- man sucht die neueste dann am falschen Ende. Jeder
Messenger legt sie ans untere Ende, direkt über das Eingabefeld, und
das ist kein Geschmack: Dort schaut man hin, wenn man antworten will.
`margin-top: auto` auf dem ERSTEN Kind statt `justify-content:
flex-end` am Behälter. Der naheliegende Weg hat einen bekannten
Haken: In einem scrollbaren Flex-Behälter wird der obere Teil damit
unerreichbar, sobald der Inhalt überläuft -- man käme an die ältesten
Nachrichten nicht mehr heran. */
.chat__verlauf > :first-child { margin-top: auto; }
/* Der Datumstrenner. */
.chat-tag {
display: flex; align-items: center; gap: 10px;
margin: 14px 0 10px;
color: var(--text-still);
}
.chat-tag::before, .chat-tag::after {
content: ""; flex: 1; height: 1px;
background: linear-gradient(90deg, transparent, var(--rand-hell), transparent);
}
/* Aus nacktem Text wird ein Schild auf der Linie: Es liegt darauf,
statt sie zu unterbrechen. Derselbe Glas-Gedanke wie ueberall auf
dieser Seite -- was obenauf liegt, ist leicht durchscheinend. */
.chat-tag__text {
flex: none;
padding: 4px 12px;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, .08);
background: rgba(8, 12, 19, .62);
backdrop-filter: blur(8px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 4px 12px -8px rgba(0, 0, 0, .9);
font-size: .72rem; font-weight: 700;
letter-spacing: .07em; text-transform: uppercase;
}
/* =====================================================================
DIE SCHRIFT DER BLASE GEHOERT DER BLASE (22.09.2026)
Filipe: „die schrift vom chat soll dan auch angepasst werden und die
namen so dass man sie gut erkennt."
WARUM DAS HIER STEHT UND NICHT BEI DEN FARBEN DER SEITE:
Die Blase ist die einzige Flaeche im Haus, deren Farbe der NUTZER
waehlt. Alles andere steht auf der Hausflaeche. Die Schrift der
Seite (--text-leise, #94a5bb) ist fuer diese Hausflaeche gerechnet
-- und sie war es, die die zwoelf Kacheln so dunkel gehalten hat:
Gegen ein leises Grau darf die Flaeche kaum Farbe haben, sonst
verschwindet die Fusszeile.
Also andersherum: erst die Schrift hell genug, dann darf die Flaeche
kraeftig werden. Beides haengt zusammen und wird deshalb ZUSAMMEN
gerechnet -- tools/chat-kacheln-rechnen.mjs liest genau diese beiden
Werte hier und rechnet daraus aus, wie stark die zwoelf Toene
ueberhaupt sein duerfen. Wer sie hier aendert, aendert dort das
Ergebnis; eine zweite Liste gibt es nicht. */
/* ---- ANFANG GERECHNET: chat-kacheln-rechnen.mjs ---- */
/* ERZEUGT VON tools/chat-kacheln-rechnen.mjs -- NICHT VON HAND AENDERN.
Der Ton, den eine Blase traegt, solange niemand etwas eingestellt
hat. Derselbe Wert wie der Eintrag Standard in CHAT_KACHELN. */
.chat-nachricht { --kachel-standard: #4f545c; }
/* ---- ENDE GERECHNET ---- */
.chat-nachricht {
/* ==== FEST UND NICHT MEHR JE KACHEL (25.09.2026) ================
Der Text steht seit heute auf dunklem Glas, nicht mehr auf der
persoenlichen Farbe. Damit ist sein Untergrund immer derselbe --
und zwei feste Werte sind richtiger als eine Rechnung fuer einen
Untergrund, den es nicht mehr gibt. Gemessen gegen den Grund der
Blase (#0b1019): 15,4:1 fuer den Text, 7,4:1 fuer die Fusszeile.
Verlangt sind 7 und 4,5 (pruef-chatkachel). */
--blase-text: #eef4fc;
--blase-leise: #a8bacf;
/* ==== DER GRUND, AUF DEM DER TEXT STEHT (25.09.2026) ============
Er steht als eigener Wert da, damit pruef-chatkachel ihn LESEN
kann statt ihn abzuschreiben. Eine Pruefung mit einer eigenen
Kopie dieser Farbe waere eine zweite Wahrheit -- und die faellt
erst auf, wenn eine der beiden geaendert wird.
92 PROZENT UND NICHT 84: Die Blase ist durchscheinend, also
haengt der wirkliche Untergrund des Textes davon ab, was dahinter
liegt -- und dahinter liegt ein Foto, das stellenweise hell ist.
Der schlimmste Fall ist WEISS dahinter. Nachgerechnet:
bei 84 % -> Grund #323a44, Fusszeile nur 3,9:1 (zu wenig)
bei 92 % -> Grund #1e242c, Fusszeile 5,9:1 (reicht)
Deshalb 92. Es ist der Punkt, an dem das Glas noch Glas ist und
die Schrift auch ueber der hellsten Stelle des Fotos traegt.
pruef-chatkachel rechnet genau diesen schlimmsten Fall nach. */
--blasengrund: #0b1019;
/* WIE STARK DER NAME AUFGEHELLT WIRD -- als Wert und nicht als Zahl
im Ausdruck, damit pruef-chatkachel ihn LESEN kann.
50 UND NICHT 58 (nachgemessen 25.09.2026): Mit 58 % schaffte der
Ton „Ziegel" als Name nur 4,31:1 gegen den hellsten denkbaren
Grund -- unter den noetigen 4,5. Gefunden hat das die Pruefung,
nicht das Auge: Auf dem Bildschirm sah der Name gut aus, weil
hinter der Blase gerade nichts Helles lag.
Mehr Weiss ginge auch -- dann aehneln sich die Toene aber
einander an, und die Farbe verliert genau das, wofuer sie da ist:
zu sagen, WER spricht. 50 % ist der Punkt, an dem beides noch
stimmt. */
--namen-anteil: 50%;
display: grid;
grid-template-columns: 30px 1fr;
gap: 9px;
align-items: flex-end;
/* 66 STATT 76 PROZENT (25.09.2026). Auf 1440 px war eine Blase
ueber 700 px breit -- ein Satz lief dann ueber die ganze Bahn, und
das Auge musste beim Zeilenwechsel zurueckspringen. Im Satz gilt
seit Jahrhunderten dieselbe Regel: Eine Zeile ist gut lesbar bis
etwa 75 Zeichen; darueber verliert man die naechste.
`ch` WAERE GENAUER ALS PROZENT -- aber die Blase soll auf dem
Handy trotzdem die Breite ausnutzen. Deshalb beides: Prozent fuer
klein, eine Obergrenze in Zeichen fuer gross. So stimmt es auf
jedem Geraet, ohne eine Schwelle dazwischen. */
max-width: min(66%, 62ch);
margin-top: 11px;
}
/* Folgt eine Nachricht derselben Person, rückt sie näher und lässt den
Kreis weg -- der Platz bleibt frei, damit die Blasen fluchten. */
.chat-nachricht[data-folge="ja"] { margin-top: 2px; }
.chat-nachricht[data-selbst="ja"] {
grid-template-columns: 1fr;
margin-left: auto;
}
/* Dasselbe Zeichen wie in der Liste links, nur kleiner: Licht oben,
Saum ringsum, Schatten darunter. Vorher waren es zwei verschiedene
Kreise fuer dieselbe Sache -- links ein Koerper, hier ein flacher
Fleck. */
.chat-nachricht__zeichen {
--r: #a0aec4;
grid-column: 1;
width: 32px; height: 32px; border-radius: 50%;
display: grid; place-items: center;
font-size: .76rem; font-weight: 750;
color: var(--r);
background: linear-gradient(162deg,
color-mix(in srgb, var(--r) 26%, transparent) 0%,
color-mix(in srgb, var(--r) 9%, transparent) 55%,
rgba(0, 0, 0, .25) 100%);
border: 1px solid color-mix(in srgb, var(--r) 32%, transparent);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .15),
0 0 0 1px rgba(0, 0, 0, .35),
0 5px 12px -7px color-mix(in srgb, var(--r) 50%, transparent);
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
.chat-nachricht__zeichen[data-rolle="admin"] { --r: var(--dogi-haupt); }
.chat-nachricht__zeichen[data-rolle="manager"] { --r: var(--manager-haupt); }
.chat-nachricht__zeichen[data-rolle="scout"] { --r: var(--scout-haupt); }
.chat-nachricht__zeichen[data-rolle="creator"] { --r: var(--creator-haupt); }
/* Ohne Kreis (Folgenachricht) bleibt die Spalte trotzdem stehen. */
.chat-nachricht[data-folge="ja"]:not([data-selbst="ja"]) .chat-nachricht__blase { grid-column: 2; }
/* =====================================================================
DIE BLASE BEKOMMT EINEN KOERPER (25.09.2026)
Filipe: „ich will es wirklich uebertrieben krass."
WAS SICH NICHT AENDERT -- UND WARUM NICHT: die FARBE. Sie ist die
persoenliche Kachel und wird von pruef-chatkachel gemessen; die
Pruefung rechnet mit dem FARBWERT selbst. Ein Verlauf, ein Glas
oder eine Beimischung darauf wuerde den gemessenen Wert und den
gesehenen auseinanderbringen -- und zwar still: Die Pruefung bliebe
gruen. Genau so lag die eigene Blase schon einmal ausserhalb jeder
Messung (siehe weiter unten, 22.09.2026). Also bleibt sie deckend.
WAS SICH AENDERT: alles um die Farbe herum.
* Eine helle Haarlinie oben INNEN -- Licht faellt von oben auf
einen Koerper. Sie liegt am oberen Rand, nicht hinter dem Text;
am gemessenen Untergrund aendert sie nichts.
* Eine dunkle unten innen -- die abgewandte Seite.
* Ein langer, weicher Schatten darunter, in der Farbe der Blase
selbst statt in Schwarz: Dadurch sieht die Blase aus, als
leuchte sie schwach auf den Untergrund, statt auf ihm zu
kleben. Das ist der eigentliche Unterschied zu vorher.
* Ein feiner schwarzer Saum ganz aussen. Er trennt die Blase vom
Hintergrundbild -- ohne ihn verschwimmt eine helle Kachel auf
einer hellen Stelle des Fotos.
===================================================================== */
/* =====================================================================
DIE BLASE IST KEINE FARBFLAECHE MEHR (25.09.2026)
=====================================================================
Filipe, nachdem der erste Anlauf nur poliert hatte: „alles soll
anders und geiler aussehen, moderner und spezieller."
WAS DAS PROBLEM WAR -- und es war nicht der Rand und nicht die
Rundung: Zwei Drittel jeder Nachricht waren eine deckende, kraeftige
Flaeche in der persoenlichen Farbe. Bei zwoelf Nachrichten
untereinander ist das eine Wand aus Farbe, auf der alles andere
-- Name, Text, Zeit, fuenf Handgriffe -- um Aufmerksamkeit kaempft.
Jede Feinheit, die man darauf legt, verschwindet.
WAS JETZT GILT: Die Blase ist dunkles Glas -- fuer JEDEN dieselbe.
Die persoenliche Farbe bleibt vollstaendig erhalten, sie sitzt nur
woanders:
* als KANTE an der Sprechseite (links beim Gegenueber, rechts bei
einem selbst) -- 3 px, leuchtend, mit weichem Schein;
* im NAMEN, aufgehellt, damit er auf dem dunklen Grund traegt;
* als HAUCH im oberen Verlauf der Blase;
* als SCHEIN unter der Blase, sehr schwach.
MAN ERKENNT DIE PERSON ALSO WEITERHIN AN DER FARBE -- und der Text
steht endlich auf einem ruhigen Grund.
WARUM DAS DIE KONTRASTMESSUNG NICHT AUSHEBELT, sondern verbessert:
Bisher garantierte pruef-chatkachel „Schrift X auf Flaeche Y" fuer
zwoelf verschiedene Flaechen -- eine Rechnung mit zwoelf Ergebnissen.
Jetzt gibt es EINEN Untergrund. Die Pruefung ist mitgezogen worden
(siehe dort) und misst ab sofort zwei Dinge: die feste Schrift auf
dem festen Grund, und dass JEDE der zwoelf Farben als Name auf
diesem Grund noch lesbar ist. Das ist weniger Rechnerei und mehr
Aussage.
`backdrop-filter` MIT VORBEHALT: Wo es fehlt (aeltere Browser),
bleibt die Blase schlicht deckend dunkel -- kein Schaden, nur
weniger Tiefe. Deshalb steht der deckende Ton als zweite Schicht
darunter und nicht als durchsichtige Flaeche allein.
===================================================================== */
.chat-nachricht__blase {
--ton: var(--kachel, var(--kachel-standard));
position: relative;
grid-column: 2;
padding: 12px 17px 9px;
border: 1px solid color-mix(in srgb, var(--ton) 24%, rgba(255, 255, 255, .07));
box-shadow:
inset 0 1px 0 color-mix(in srgb, var(--ton) 30%, rgba(255, 255, 255, .13)),
inset 0 -1px 0 rgba(0, 0, 0, .35),
0 0 0 1px rgba(0, 0, 0, .42),
0 20px 38px -22px rgba(0, 0, 0, .96),
0 0 30px -16px color-mix(in srgb, var(--ton) 55%, transparent);
backdrop-filter: blur(16px) saturate(125%);
/* RUNDER (22.09.2026). Filipe: „die chat bubble wo die text drin
sind sollen auch viel geiler aussehen, mit runden kanten."
22 px statt 14; nur die Ecke zur Person bleibt spitz -- sie ist
es, die sagt, WER spricht. Ohne sie waeren es Pillen ohne
Richtung. */
border-radius: 20px 20px 20px 6px;
/* Ein Lichtsaum oben innen und ein weicher Schatten aussen. KEIN
Verlauf in der Flaeche: Text auf einem Farbverlauf liest sich
unruhig, und diese Flaeche ist zum Lesen da. Der Saum ist 1 px
und beruehrt die Schrift nicht. */
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .16),
0 2px 10px rgba(0, 0, 0, .28);
/* DECKEND, NICHT DURCHSCHEINEND (20.09.2026).
Hier stand `rgba(255,255,255,.045)` -- praktisch durchsichtig. Das
war richtig, solange dahinter eine ruhige Flaeche lag. Seit das
Buehnenbild durchscheint, waere es Schrift auf einem Foto: an der
dunklen Stelle lesbar, an der hellen nicht, und beim Scrollen
wechselt es.
`--kachel` statt einer festen Farbe: Darueber personalisiert jeder
Account seine eigene Kachel (siehe weiter unten). Der Rueckfall
ist die Hausfarbe -- wer nichts einstellt, bekommt das, was vorher
auch da war, nur deckend. */
/* Zwei Schichten: oben ein Hauch der persoenlichen Farbe, darunter
der deckende dunkle Grund. Der Hauch laeuft nach 44 % aus -- er
liegt damit ueber dem Namen, nicht hinter dem Text. */
background:
linear-gradient(180deg,
color-mix(in srgb, var(--ton) 13%, transparent) 0%,
transparent 44%),
color-mix(in srgb, var(--blasengrund) 92%, transparent);
min-width: 0;
}
/* DIE FARBKANTE -- sie sagt, wer spricht. Links beim Gegenueber,
rechts bei einem selbst: dieselbe Richtung, die schon die spitze
Ecke angibt, nur jetzt sichtbar auf einen Blick. */
.chat-nachricht__blase::before {
content: ""; position: absolute;
left: 0; top: 11px; bottom: 11px; width: 3px;
border-radius: 0 3px 3px 0;
background: linear-gradient(180deg,
color-mix(in srgb, var(--ton) 55%, #ffffff) 0%,
var(--ton) 45%,
color-mix(in srgb, var(--ton) 70%, transparent) 100%);
box-shadow: 0 0 12px -1px color-mix(in srgb, var(--ton) 75%, transparent);
}
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase::before {
left: auto; right: 0; border-radius: 3px 0 0 3px;
}
.chat-nachricht[data-folge="ja"] .chat-nachricht__blase { border-radius: 22px 22px 22px 10px; }
/* Die eigenen: gedecktes Blau, Ecke rechts. Kein Verlauf in der Fläche
-- Text auf einem Farbverlauf liest sich unruhig. */
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase {
grid-column: 1;
border-radius: 20px 20px 6px 20px;
/* Auch die eigene deckt jetzt. `color-mix` auf `transparent` liesse
das Foto durch -- gemischt wird deshalb auf die Hausflaeche. */
/* DIESELBE FLAECHE WIE BEI ALLEN ANDEREN (22.09.2026).
Hier waren 16 % Akzentfarbe beigemischt. Damit hatte die eigene
Blase eine Farbe, die in CHAT_KACHELN nicht vorkommt -- und die
die Kontrastpruefung deshalb nie angesehen hat. Ausgerechnet die
eigene Blase, die man am haeufigsten liest, lag ausserhalb jeder
Messung. Woran man sie erkennt, steht unveraendert daneben: die
Seite, die spitze Ecke, der Rand und der Schein im Akzent. */
/* Die eigene Blase unterscheidet sich nicht mehr durch die Flaeche
-- sie ist dieselbe wie jede andere. Woran man sie erkennt, steht
unveraendert daneben: die Seite, die spitze Ecke, und seit heute
die Farbkante RECHTS statt links. */
border-color: color-mix(in srgb, var(--ton) 28%, rgba(255, 255, 255, .08));
}
.chat-nachricht[data-selbst="ja"][data-folge="ja"] .chat-nachricht__blase {
border-radius: 22px 22px 10px 22px;
}
/* DER NAME MUSS MAN ERKENNEN (22.09.2026).
Er stand auf var(--text-leise) mit 85 % Deckung -- also einem leisen
Grau, das zusaetzlich durchscheint. Auf einer kraeftigen Kachel war
das der schwaechste Text der ganzen Seite, ausgerechnet der, der
sagt, wer spricht. Jetzt hell, fett und minimal gesperrt; die Farbe
der Rolle sitzt daneben im Kreis und im Punkt davor, nicht in der
Schrift -- eine Rollenfarbe als Schriftfarbe waere bei zwoelf
waehlbaren Flaechen nicht mehr zu garantieren. */
/* NOCH EINMAL STAERKER (22.09.2026 abends).
---------------------------------------------------------------------
Filipe, zum zweiten Mal an derselben Stelle: "Namen viel spezieller
und besser erkennbar."
Am Nachmittag war der Name hell und fett geworden -- er stand aber
weiterhin als erste ZEILE in der Blase und las sich dadurch wie der
Anfang des Satzes. Jetzt ist er ein eigener Streifen mit einer Kante
darunter: Er gehoert sichtbar zur Blase, ist aber nicht mehr Teil
des Textes.
DER PUNKT WIRD EIN BALKEN. Sechs Pixel rund sind auf einem Handy
fast nichts; 3x14 senkrecht daneben liest sich als Markierung und
ist bei gleicher Flaeche deutlich besser zu sehen.
DIE SCHRIFTFARBE BLEIBT `--blase-text` -- und die wechselt seit
heute mit der Kachel. Auf Babyblau steht der Name also dunkel, auf
allen anderen hell. Eine feste Farbe waere genau hier der Fehler. */
/* DER NAME TRAEGT JETZT DIE FARBE (25.09.2026).
Vorher stand er in derselben hellen Schrift wie der Text und wurde
nur durch einen Balken davor unterschieden -- die Farbe steckte in
der Flaeche ringsum. Jetzt ist der Name selbst die Farbe.
AUFGEHELLT UND NICHT ROH: `color-mix(... 58%, #f2f8ff)` mischt
jeden Ton mit Weiss. Damit traegt AUCH ein dunkler Ton auf dem
dunklen Glas -- ohne diese Mischung waere eine dunkelblaue Kachel
als Name kaum zu lesen. pruef-chatkachel rechnet genau diese
Mischung nach, fuer jeden der zwoelf Toene. */
.chat-nachricht__von {
margin: 0 0 8px;
padding: 0 0 7px;
display: flex; align-items: center; gap: 8px;
font-size: .82rem; font-weight: 800;
letter-spacing: .04em; text-transform: uppercase;
color: color-mix(in srgb,
var(--ton, var(--kachel-standard)) var(--namen-anteil, 50%), #f2f8ff);
border-bottom: 1px solid color-mix(in srgb, var(--ton, var(--kachel-standard)) 26%, transparent);
}
.chat-nachricht__von::before {
content: ""; flex: none;
width: 3px; height: 14px; border-radius: 2px;
background: var(--rollenfarbe, color-mix(in srgb, var(--blase-text) 55%, transparent));
}
/* Dieselbe Zuordnung wie beim Kreis mit den Anfangsbuchstaben. Sie
steht zweimal, weil zwei verschiedene Eigenschaften gesetzt werden
(--r dort, --rollenfarbe hier); die FARBEN kommen beide aus
denselben Hausvariablen, es gibt also keinen zweiten Wert, der
auseinanderlaufen koennte. */
.chat-nachricht__von[data-rolle="admin"] { --rollenfarbe: var(--dogi-haupt); }
.chat-nachricht__von[data-rolle="manager"] { --rollenfarbe: var(--manager-haupt); }
.chat-nachricht__von[data-rolle="scout"] { --rollenfarbe: var(--scout-haupt); }
.chat-nachricht__von[data-rolle="creator"] { --rollenfarbe: var(--creator-haupt); }
/* Der Text ist das, wofuer die Seite da ist -- und er stand in
derselben Groesse wie die Vorschauzeile in der Liste. Jetzt etwas
groesser, mit mehr Durchschuss: Auf dunklem Grund braucht Schrift
mehr Luft zwischen den Zeilen als auf hellem, sonst laufen sie
optisch zusammen. */
.chat-nachricht__text {
margin: 0;
/* Etwas groesser als vorher (.92) -- der Chat ist die Seite, auf der
am laengsten gelesen wird, und die Blase hat jetzt den Platz. */
font-size: .97rem; color: var(--blase-text);
letter-spacing: .002em;
/* pre-wrap: Zeilenumbrüche aus der Eingabe bleiben erhalten, ohne
dass dafür HTML erzeugt werden müsste (das wäre der Weg, über den
jemand Auszeichnung einschleust). */
white-space: pre-wrap;
overflow-wrap: anywhere; /* eine lange Adresse sprengt nichts */
/* 1,62 STATT 1,55 (25.09.2026): Auf dunklem Grund braucht Schrift
mehr Durchschuss als auf hellem -- helle Buchstaben strahlen
optisch aus und laufen sonst von Zeile zu Zeile ineinander. Das
ist kein Geschmack; aus demselben Grund waren gedruckte
Nachtausgaben weiter gesetzt als Tagausgaben. Seit die Blase
dunkel ist statt bunt, gilt es hier. */
line-height: 1.62;
}
.chat-nachricht__weg { color: var(--text-still); font-style: italic; }
.chat-nachricht[data-weg="ja"] .chat-nachricht__blase {
background: transparent;
border-style: dashed;
}
/* EINE FARBE FÜR DIE GANZE FUSSZEILE — und zwar hier, an einer Stelle.
---------------------------------------------------------------------
Uhrzeit, "antworten", "zurücknehmen" und "kopieren" standen alle auf
var(--text-still) (#7f8fa6). Gemessen (pruef-chat-ausbau, Abschnitt 9)
ergibt das auf der eigenen Blase 3,68:1 -- unter den 4,5:1, die für
Text dieser Größe gelten. Es ist nie aufgefallen, weil niemand
nachgemessen hat; die Blase ist heller als der übrige Grund, und
genau dort wird eine leise Farbe zu leise.
var(--text-leise) (#94a5bb) bringt dieselbe Stelle auf 4,80:1 und
bleibt trotzdem deutlich ruhiger als der Nachrichtentext.
Die Kinder erben sie (color: inherit). Vier eigene Farbangaben wären
vier Stellen, die beim nächsten Mal auseinanderlaufen -- der Fehler,
der in diesem Haus am häufigsten vorkommt. */
/* VIER HANDGRIFFE PASSEN NICHT IN EINE ZEILE (10.09.2026).
Hier stand `display: flex` ohne Umbruch. Mit drei Eintraegen (Zeit,
antworten, kopieren) ging die Rechnung auf. Seit "anheften"
danebensteht, geht sie nicht mehr: Gemessen an echten Bildpunkten
stand "kopieren" bei 390 px -- der haeufigsten Handybreite -- 18 px
ueber der Blase, bei 320 px waren es 75. Die Zeile lief einfach
weiter, ueber ihren eigenen Rand hinaus.
DIE LEHRE IST NICHT "eine Schwelle einbauen". Das waere derselbe
Fehler wie in der Kopfleiste am 06.09., nur mit einer anderen Zahl
-- und beim fuenften Eintrag stuende sie wieder falsch da.
`flex-wrap: wrap` ist eine REGEL statt einer Rechnung: Sie bricht
genau dann um, wenn der Platz nicht reicht, und zwar unabhaengig
davon, wie viele Handgriffe es einmal sein werden.
`row-gap` kleiner als `column-gap`: Zwei Zeilen Fusstext sollen wie
ein Block wirken, nicht wie zwei Absaetze. */
/* =====================================================================
DIE FUSSZEILE WAR DIE UNRUHIGSTE STELLE DER SEITE (25.09.2026)
Fuenf Handgriffe und eine Uhrzeit, in derselben Groesse wie der
Text darueber und direkt darunter geklebt -- bei zwoelf Nachrichten
sind das sechzig Woerter, die keiner liest und alle sehen.
DREI DINGE, UND JEDES EINZELN BEGRUENDET:
1. EINE KANTE DARUEBER, in der Farbe der Person. Sie trennt das
Gesagte von dem, was man damit tun kann -- vorher lief beides
ineinander.
2. KLEINER UND GESPERRT. 0,66 rem in Versalien liest sich als
Beschriftung, nicht als Satz. Man erkennt die Woerter weiter,
ohne sie zu lesen.
3. GEDAEMPFT. Erst beim Ueberfahren der Blase werden sie
deutlich -- aber sie bleiben SICHTBAR (Entscheidung vom
23.09.2026: Auf dem Handy gibt es kein Ueberfahren, und ein
Knopf, den man dort nicht erreicht, gibt es dort nicht).
===================================================================== */
.chat-nachricht__fuss {
display: flex; align-items: center; flex-wrap: wrap;
column-gap: 4px; row-gap: 2px;
/* AUS DER KANTE WIRD EINE MULDE (25.09.2026). Eine Linie trennt;
eine Mulde sagt zusätzlich, dass die Handgriffe eine Ebene TIEFER
liegen als das Gesagte – sie gehören zur Nachricht, sind aber
nicht die Nachricht. Es ist dieselbe Form wie an der
Registerleiste links: eingesenkt = zur Auswahl, aufliegend =
gewählt. Eine Seite, eine Sprache.
DER GRUND WIRD DUNKLER, NIE HELLER. Das ist kein Geschmack,
sondern die Bedingung dafür, dass die Messung gültig bleibt:
pruef-chatkachel rechnet die leise Schrift gegen den HELLSTEN
denkbaren Grund (Blase zu 92 % über weißem Foto). 26 % Schwarz
darüber kann diesen Wert nur verbessern. Wer hier je etwas
Helles einsetzt, hebt die Zusage auf und muss neu messen.
DIE NEGATIVEN RÄNDER holen die Mulde in die Polsterung der Blase
hinein (12/17/9 px), damit sie nicht wie ein zweiter Kasten
wirkt, sondern wie eine Vertiefung IN der Blase. */
margin: 10px -9px -3px; padding: 6px 8px;
border-radius: 14px;
border-top: 0;
background: rgba(0, 0, 0, .26);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .045),
inset 0 0 0 1px color-mix(in srgb,
var(--ton, var(--kachel-standard)) 12%, transparent);
/* 0,72 rem = 11,52 px -- KNAPP UEBER DER HAUSGRENZE (25.09.2026).
Der erste Anlauf stand auf 0,66 rem (10,56 px). pruef-css-klassen
hat es gemeldet: "45 Stellen unter 11,5 px -- das sind 3 MEHR als
die Grundlinie 42." Die Grenze ist kein Geschmack; darunter faengt
Schrift an, auf einem Telefon zu flimmern.
Die Zeile wirkt trotzdem leise – das machen die Mulde, die
gedämpfte Deckung und die Zeichen davor, nicht die Größe.
KEINE VERSALIEN MEHR (25.09.2026). Sie waren richtig, solange
dort fünf nackte Wörter standen und sich als Beschriftung von
einem Satz abheben mussten. Seit jedes Wort ein Zeichen vor sich
hat, macht das Zeichen diese Arbeit – und gesperrte Versalien
kosten rund ein Viertel mehr Breite, also genau den Platz, den
die Zeichen brauchen. */
font-size: .72rem; letter-spacing: .01em;
opacity: .78;
transition: opacity .18s ease;
/* War var(--text-leise) (#94a5bb). Diese eine Farbe war die Bremse
fuer alle zwoelf Kachelfarben -- siehe der Block oben. */
color: var(--blase-leise);
}
/* Die Blase als Ganzes hebt die Fusszeile an -- nicht jeder Knopf
einzeln. Wer die Nachricht meint, meint alle Handgriffe daran. */
.chat-nachricht:hover .chat-nachricht__fuss,
.chat-nachricht:focus-within .chat-nachricht__fuss { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
.chat-nachricht__fuss { transition: none; }
}
/* DIE ZEIT WIRD EIN SCHILD. In einer Reihe mit fünf Knöpfen war sie
der einzige Text ohne Fläche – und sah dadurch aus wie ein
vergessener Knopf. Jetzt trägt sie ein eigenes kleines Feld: eine
Angabe, keine Bedienung. */
.chat-nachricht__zeit {
font-size: .72rem; color: inherit;
font-variant-numeric: tabular-nums;
letter-spacing: .02em;
padding: 2px 8px;
border-radius: 999px;
background: rgba(255, 255, 255, .05);
/* Die Zeit bleibt links, die Handgriffe ruecken nach rechts: Das
eine ist eine Angabe, das andere sind Knoepfe. Zusammen in einer
Reihe sahen sie aus wie sechs gleichwertige Dinge. */
margin-right: auto;
}
/* Der Zurücknehmen-Knopf erscheint erst beim Darüberfahren -- er ist
die seltene Handlung und soll nicht in jeder Zeile mitlaufen. Auf
Geräten ohne Zeiger steht er immer da (siehe unten). */
/* =====================================================================
DER LOESCHKNOPF IST SICHTBAR (23.09.2026)
=====================================================================
Hier stand `opacity: 0`, sichtbar erst beim Ueberfahren mit der
Maus. Das war vertretbar, solange er nur die EIGENE Nachricht
zuruecknahm: ein seltener, absichtlicher Griff, den man sucht.
Seit dem 22.09. traegt derselbe Knopf auch das Notfall-Loeschen
fuer DogFather und die rechte Hand. Und damit werden zwei Dinge
zum Problem:
1. AUF EINEM HANDY GIBT ES KEIN ÜBERFAHREN. Der Knopf war dort
dauerhaft unsichtbar -- eine Funktion, die man auf dem Geraet
nicht erreicht, gibt es auf dem Geraet nicht. Und Filipe
besteht bei jedem Auftrag darauf, dass es auf dem Handy
genauso gut sein muss.
2. ER BELEGTE TROTZDEM PLATZ. Im Bildschirmfoto vom 23.09. klafft
zwischen „reagieren" und „anheften" eine Luecke von 87 px --
genau die Breite von „löschen (Notfall)". Eine Luecke, die
nichts erklaert, sieht nach einem Fehler aus.
ER IST JETZT IMMER DA, aber leise -- wie die anderen Handgriffe
daneben. Was davor schuetzt, versehentlich zu loeschen, ist nicht
die Unsichtbarkeit, sondern die Rueckfrage: Sie steht seit dem
19.09. als eigener Dialog da und sagt ausdruecklich, was passiert.
Ein Knopf, den man nicht findet, schuetzt niemanden -- er
verhindert nur, dass jemand ihn absichtlich benutzt.
===================================================================== */
/* Nur noch das, was diesem Knopf allein gehoert: die Warnfarbe beim
Ueberfahren. Form, Polsterung und Rundung kommen aus der
gemeinsamen Marken-Regel weiter unten -- eine Form fuer vier
Handgriffe, nicht vier Formen. */
.chat-nachricht__weg-knopf:hover { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); border-color: color-mix(in srgb, var(--warn) 34%, transparent); }
.chat-nachricht__weg-knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* DAS NOTFALL-LOESCHEN SIEHT ANDERS AUS ALS DAS EIGENE -- ABER NICHT
UEBER DIE SCHRIFTFARBE.
Erster Anlauf, und er war messbar falsch: Der Knopf bekam den
Warnton, gedaempft gemischt mit der leisen Schrift. Nachgerechnet:
auf Babyblau 1,91:1 (noetig 4,5)
auf den dunklen Toenen 4,06 bis 4,13
Also unlesbar auf der hellen Kachel und knapp zu wenig auf allen
anderen. Die leise Schriftfarbe ist nicht irgendein Grau -- sie ist
genau der Wert, der auf JEDER Kachel 4,5:1 schafft (schriftFuer im
Server, gemessen von pruef-chatkachel). Wer daran mischt, gibt
genau diese Zusage auf.
DER PUNKT TRAEGT DIE FARBE, NICHT DIE SCHRIFT. Denselben Weg geht
das Haus schon beim Namen in der Blase: „Die Farbe der Rolle sitzt
im Punkt VOR dem Namen, nicht in der Schrift selbst: Bei zwoelf
waehlbaren Flaechen liesse sich fuer eine Schriftfarbe kein
Kontrast mehr garantieren, fuer einen 6-px-Punkt daneben ist das
egal." Genau dieselbe Lage, genau dieselbe Antwort.
BEIM UEBERFAHREN wird die Schrift HELLER (--blase-text, der Wert
mit dem hoechsten Kontrast der Blase) statt bunter. Wer den Knopf
gerade anvisiert, soll ihn am besten lesen koennen -- und nicht am
schlechtesten. */
.chat-nachricht__weg-knopf[data-notfall="ja"] {
display: inline-flex; align-items: center; gap: 5px;
}
/* AUS DEM PUNKT WIRD EIN PAPIERKORB (25.09.2026) -- die Überlegung
darüber gilt unverändert, nur trägt jetzt ein Zeichen die Warnfarbe
statt eines Flecks. Es ist dasselbe Zeichen wie am gewöhnlichen
Löschen daneben, nur rot: Man sieht auf einen Blick, dass es
dieselbe Handlung ist und dass sie hier anders wiegt.
DIE ALTE RECHNUNG IST ÜBERHOLT. Darüber steht „auf Babyblau
1,91:1" – das galt, als die Blase die Kachelfarbe trug. Seit dem
25.09.2026 ist sie für alle dunkles Glas (`--blasengrund`,
#0b1019); Lachs darauf liegt weit über den 3:1, die für ein
Zeichen gelten. Die Schrift daneben bleibt trotzdem `--blase-leise`
und wird nicht eingefärbt – der Grund dafür war nie der Kontrast
allein, sondern dass eine Schriftfarbe auf zwölf wählbaren Tönen
nicht zu garantieren ist.
`mask-size` MUSS MIT: Die gemeinsame Regel oben setzt 13 px über
die Kurzschreibweise `mask`. Wer hier nur Breite und Höhe ändert,
bekommt ein 13-px-Bild in einem 14-px-Kasten – oben links klebend,
nicht mittig. */
.chat-nachricht__weg-knopf[data-notfall="ja"]::before {
width: 14px; height: 14px; border-radius: 0;
background: var(--warn, #ff9aa2);
box-shadow: none;
-webkit-mask-size: 14px 14px;
mask-size: 14px 14px;
}
.chat-nachricht__weg-knopf[data-notfall="ja"]:hover { color: var(--blase-text); }
/* Unterwegs und gescheitert: siehe ganz unten in dieser Datei.
Hier stand bis zum 20.09.2026 eine Regel ohne Inhalt --
`.chat-nachricht__blase:has(+ *) { }` mit dem Kommentar
„Platzhalter, damit :has unterstützt bleibt". Sie hat nie etwas
getan, und darunter fehlte genau das, was der Kommentar darüber
versprach. */
/* ---------- Das Eingabefeld ---------------------------------------------- */
.chat__eingabe {
flex: none;
display: flex; align-items: flex-end; gap: 10px;
/* DIE ANTWORTLEISTE BRAUCHT IHRE EIGENE ZEILE (21.09.2026).
Sie ist ein Geschwister des Schreibfeldes in DIESER Reihe. Ohne
Umbruch nahm sie ihren Platz daneben -- und weil das Feld
`min-width: 0` hat, schrumpfte es auf die Breite eines einzigen
Buchstabens. Filipes Bildschirmfoto zeigt es: "defi / niti / v /
hah / a", ein Wort pro Zeile, senkrecht.
`flex-wrap` statt einer Schwelle: Es bricht genau dann um, wenn
der Platz nicht reicht -- und die Leiste unten nimmt sich mit
`flex-basis: 100%` immer die ganze Zeile. Eine feste Breite waere
wieder eine Rechnung von gestern. */
flex-wrap: wrap;
padding: 13px 14px 15px;
/* AUS EINER ZEILE WIRD EINE KONSOLE (25.09.2026).
Vorher: eine Linie oben und ein dunkler Streifen. Das las sich wie
"hier hoert die Seite auf". Jetzt liegt sie erkennbar VOR dem
Verlauf -- Lichtkante oben, Glas dahinter, ein Schatten nach oben,
der den Verlauf darunter durchscheinen laesst.
`backdrop-filter` und nicht einfach dunkler: Was hinter der
Konsole durchlaeuft, soll man ahnen, aber nicht lesen. Ein
deckender Streifen haette den Verlauf abgeschnitten; so wirkt die
Flaeche wie eine Scheibe darueber. */
border-top: 0;
background: linear-gradient(180deg,
rgba(10, 14, 22, .74) 0%, rgba(6, 9, 15, .86) 100%);
backdrop-filter: blur(14px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 -1px 0 0 rgba(0, 0, 0, .5),
0 -18px 28px -24px rgba(0, 0, 0, .95);
position: relative; z-index: 2;
}
.chat__eingabe-schild {
position: absolute; width: 1px; height: 1px; margin: -1px;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* DIE DREI WERKZEUGE ALS EINE GRUPPE (23.09.2026).
Sie standen einzeln in der Zeile. Mit dem dritten (GIF, heute
Nacht) blieben dem Schreibfeld auf 390 px noch 130 Pixel -- seine
Untergrenze --, und "Senden" rutschte allein auf eine eigene Zeile.
Als Gruppe bricht die Zeile an der richtigen Stelle: Die drei
wandern gemeinsam nach oben, Feld, Emoji und Senden bleiben
zusammen. Und ein viertes Werkzeug laesst kuenftig die Gruppe
wachsen, nicht das Schreibfeld schrumpfen.
`flex: none` -- die Gruppe gibt nichts ab. Wer hier schrumpfen
laesst, macht aus 40 px Zielflaeche 30, und darueber wacht
pruef-tippziele zu Recht. */
.chat__werkzeuge {
flex: none;
display: flex; align-items: center; gap: 10px;
}
/* SCHREIBEN UND ABSCHICKEN GEHOEREN ZUSAMMEN (23.09.2026).
Begruendung und Messung stehen im HTML daneben. `flex-wrap: wrap`
ist der Teil, der leicht uebersehen wird: Die Gestaltungsleiste
haengt sich beim Laden vor das Textfeld und wandert damit in diese
Gruppe -- ohne Umbruch quetscht sie sich in die Zeile.
`min-width: 0` an der Gruppe: Sonst koennte sie das Formular
breiter machen als den Bildschirm. Das Feld darin hat seine eigene
Untergrenze. */
.chat__schreibzeile {
flex: 1 1 18rem;
min-width: 0;
display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
}
.chat__eingabe textarea {
/* EIN SCHREIBFELD DARF NIE UNTER EINE LESBARE BREITE FALLEN.
`min-width: 0` hiess woertlich: schrumpf bis auf null, wenn der
Platz knapp wird. Genau das ist am 21.09. passiert.
VON 8 AUF 10 rem ANGEHOBEN (23.09.2026) -- und die Zahl ist
gemessen, nicht geschaetzt. Durchgespielt wurden 8, 10, 11, 12
und 13 rem auf 320, 390 und 412 px (das schmalste Geraet, das
iPhone und die haeufigste Android-Breite):
8 rem Feld 164 / 130 / 151 -- und "Senden" steht bei 390 und
412 ALLEIN auf einer eigenen Zeile
10 rem Feld 164 / 180 / 201 -- drei Zeilen ueberall, Senden
steht nie mehr allein
11-13 auf 320 px eine VIERTE Zeile, also schlechter dort, wo
der Platz ohnehin am knappsten ist
10 rem ist damit der einzige Wert, der 390 und 412 deutlich
verbessert, ohne 320 zu verschlechtern. Wer hier dreht, misst
bitte wieder nach -- die Zahl gehoert zu dem, was in der Zeile
steht, und das aendert sich. */
flex: 1 1 10rem; min-width: 10rem;
resize: none;
min-height: 42px; max-height: 160px;
line-height: 1.5;
/* ==== AUS DEM FELD WIRD EINE RINNE (25.09.2026) ==================
Es war ein flacher dunkler Kasten in der Hausform -- dasselbe
Feld wie in jedem Formular, an der Stelle, an der man auf dieser
Seite am häufigsten steht. Jetzt liegt es sichtbar TIEFER als
die Konsole ringsum: Lichtkante oben innen, Schatten darunter,
runde Enden.
Das ist dieselbe Sprache wie an der Registerleiste links und an
der Mulde unter jeder Nachricht: eingesenkt heißt „hier hinein",
aufliegend heißt „hier drücken". Drei Stellen, eine Regel.
KEINE POLSTERUNG UND KEINE RAHMENSTÄRKE ANGEFASST. Die Zeile ist
seit dem 23.09.2026 auf den Pixel voll -- zwei Pixel mehr am
Absendeknopf haben ihn damals unter das Feld geschoben. Geändert
wird hier nur, was nichts misst: Farbe, Rundung, Schatten. */
border-radius: 15px;
border-color: rgba(255, 255, 255, .07);
background: rgba(0, 0, 0, .34);
box-shadow:
inset 0 2px 6px -3px rgba(0, 0, 0, .95),
inset 0 1px 0 rgba(255, 255, 255, .04);
}
/* Beim Hineinschreiben hebt sich die Rinne nicht -- sie bekommt Licht.
Ein Feld, das beim Tippen die Zeile verschiebt, ist ein Feld, das
beim Tippen stört. */
.chat__eingabe textarea:focus {
background: rgba(0, 0, 0, .28);
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
box-shadow:
inset 0 2px 6px -3px rgba(0, 0, 0, .95),
0 0 0 3px color-mix(in srgb, var(--akzent) 13%, transparent);
}
/* Der eine Knopf, den man in diesem Fenster am haeufigsten drueckt --
und er sah aus wie die Bueroklammer daneben. Jetzt ist er der
hellste Punkt der Konsole: gefuellt statt umrandet, mit Lichtkante
und einem weichen Schein darunter. Gedeckt bleibt er trotzdem, die
Akzentfarbe ist entsaettigt gewaehlt (augenschonend ist Vorgabe). */
.chat__senden {
flex: none;
/* 42 UND NICHT 44 (nachgebessert 25.09.2026). Zwei Pixel mehr, und
auf 390 px passte die Reihe nicht mehr: "Senden" rutschte unter
das Schreibfeld (gemessen y 844 statt 820). Genau die Rechnung,
die am 23.09. schon einmal aufging -- die Zeile ist dort auf den
Pixel voll. Wer hier etwas breiter macht, misst es nach. */
width: 42px; height: 42px;
display: grid; place-items: center;
border: 1px solid color-mix(in srgb, var(--akzent) 55%, transparent);
border-radius: 14px;
background: linear-gradient(168deg,
color-mix(in srgb, var(--akzent) 42%, transparent) 0%,
color-mix(in srgb, var(--akzent) 22%, transparent) 100%);
color: color-mix(in srgb, var(--akzent) 30%, #ffffff);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .2),
inset 0 -2px 6px -3px rgba(0, 0, 0, .55),
0 10px 20px -12px color-mix(in srgb, var(--akzent) 65%, transparent);
cursor: pointer;
transition: background .16s ease, color .16s ease;
}
.chat__senden svg { width: 20px; height: 20px; fill: currentColor; }
/* DER EINE KNOPF, DER GEDRÜCKT WERDEN SOLL (25.09.2026). Er sah aus
wie die Werkzeuge daneben -- gleiche Größe, gleiche Ruhe. Jetzt
trägt er als einziges Bedienelement der Konsole eine gefüllte
Fläche in der Akzentfarbe und einen weichen Schein darunter; beim
Überfahren wird die Fläche kräftiger und der Schein weiter.
KEINE BEWEGUNG, KEIN WACHSEN. Ein Knopf, der beim Überfahren
springt, verschiebt in einer bis auf den Pixel vollen Zeile alles
daneben -- und er wird hundertmal am Tag überfahren (Hausregel:
augenschonend). */
.chat__senden:hover {
background: linear-gradient(168deg,
color-mix(in srgb, var(--akzent) 62%, transparent) 0%,
color-mix(in srgb, var(--akzent) 38%, transparent) 100%);
border-color: color-mix(in srgb, var(--akzent) 78%, transparent);
color: #fff;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .28),
0 12px 26px -12px color-mix(in srgb, var(--akzent) 85%, transparent);
}
.chat__senden:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* ---------- Die Wahl im Neu-Dialog --------------------------------------- */
.chat-wahl { margin: 4px 0 6px; max-height: 46vh; overflow-y: auto; }
.chat-wahl__gruppe + .chat-wahl__gruppe { margin-top: 13px; }
.chat-wahl__titel {
margin: 0 0 7px;
display: flex; align-items: center; gap: 7px;
font-size: .75rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase;
color: var(--text-still);
}
.chat-wahl__punkt {
width: 7px; height: 7px; border-radius: 50%;
background: var(--r, var(--text-still)); flex: none;
}
.chat-wahl__gruppe[data-rolle="admin"] { --r: var(--dogi-haupt); }
.chat-wahl__gruppe[data-rolle="manager"] { --r: var(--manager-haupt); }
.chat-wahl__gruppe[data-rolle="scout"] { --r: var(--scout-haupt); }
.chat-wahl__gruppe[data-rolle="creator"] { --r: var(--creator-haupt); }
.chat-wahl__liste { display: flex; flex-wrap: wrap; gap: 7px; }
.chat-wahl__knopf {
--r: rgba(255, 255, 255, .5);
display: inline-flex; align-items: center; gap: 9px;
min-height: 40px;
padding: 5px 14px 5px 6px;
border: 1px solid var(--rand); border-radius: 999px;
background: rgba(255, 255, 255, .035);
color: var(--text-leise); font: inherit; cursor: pointer;
transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.chat-wahl__knopf[data-rolle="admin"] { --r: var(--dogi-haupt); }
.chat-wahl__knopf[data-rolle="manager"] { --r: var(--manager-haupt); }
.chat-wahl__knopf[data-rolle="scout"] { --r: var(--scout-haupt); }
.chat-wahl__knopf[data-rolle="creator"] { --r: var(--creator-haupt); }
.chat-wahl__knopf:hover { color: var(--text); border-color: rgba(255, 255, 255, .24); }
.chat-wahl__knopf:focus-visible { outline: 2px solid var(--r); outline-offset: 2px; }
.chat-wahl__zeichen {
flex: none;
width: 28px; height: 28px; border-radius: 50%;
display: grid; place-items: center;
font-size: .74rem; font-weight: 700;
color: var(--r);
background: color-mix(in srgb, var(--r) 14%, transparent);
border: 1px solid color-mix(in srgb, var(--r) 34%, transparent);
}
.chat-wahl__name { font-size: .86rem; font-weight: 550; }
.chat-wahl__knopf[data-an="ja"] {
color: var(--text); font-weight: 600;
border-color: color-mix(in srgb, var(--r) 55%, transparent);
background: color-mix(in srgb, var(--r) 13%, transparent);
}
.chat-wahl__knopf[data-an="ja"] .chat-wahl__zeichen {
color: #12151b; background: var(--r); border-color: var(--r);
}
/* ---------- Handy --------------------------------------------------------
EINE Spalte, umgeschaltet über data-ansicht. Zwei Spalten auf 390
Pixeln hiessen zwei unbenutzbare Hälften. */
@media (max-width: 860px) {
.chat { grid-template-columns: 1fr; }
.chat__spalte--verlauf::before { display: none; }
.chat__zurueck { display: flex; }
.chat[data-ansicht="liste"] .chat__spalte--verlauf { display: none; }
.chat[data-ansicht="verlauf"] .chat__spalte--liste { display: none; }
/* Mehr Breite für die Blasen -- auf einem schmalen Schirm sind 76 %
drei Wörter je Zeile. */
.chat-nachricht { max-width: 88%; }
/* Ohne Zeiger gibt es kein "Darüberfahren": Der Knopf steht immer da,
sonst wäre er auf dem Handy gar nicht erreichbar. */
.chat-nachricht__weg-knopf { opacity: .75; }
}
@media (hover: none) {
.chat-nachricht__weg-knopf { opacity: .75; }
}
@media (prefers-reduced-motion: reduce) {
.chat-raum__knopf, .chat__senden, .chat-wahl__knopf,
.chat-nachricht__weg-knopf { transition: none; }
}
/* Ohne Farbverläufe tragen Kanten und Formen allein. Die eigenen
Nachrichten sind dann nur noch an der Ecke und der Ausrichtung zu
erkennen -- deshalb bekommen sie hier einen kräftigeren Rand. */
@media (forced-colors: active) {
.chat { border: 1px solid CanvasText; }
.chat__spalte--verlauf::before { background: CanvasText; }
.chat-nachricht__blase { border: 1px solid CanvasText; }
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase { border-width: 2px; }
.chat-raum__zeichen, .chat-nachricht__zeichen { border: 1px solid CanvasText; }
.chat-raum__zahl { border: 1px solid CanvasText; }
.chat-tag::before, .chat-tag::after { background: CanvasText; }
.chat__verlauf { mask-image: none; }
}
/* =====================================================================
DER CHAT (07.09.2026)
Wunsch Filipe: "mach die chat fenster auch viel geiler, viel
detaillierter und viel perfekter. ich will dass die leute auch bock
bekommen diesen chat zu benutzen."
---------------------------------------------------------------------
WORAN MAN EINEN GUTEN CHAT ERKENNT
Nicht an Effekten. An vier Dingen, die alle mit ORIENTIERUNG zu tun
haben -- und alle vier fehlten:
1. MAN SIEHT, MIT WEM MAN SCHREIBT. Initialen sind ein Platzhalter,
kein Gesicht. Die Bilder liefert der Server seit heute mit; hier
werden sie gezeichnet -- rund, mit einem feinen Rand in der Farbe
der Rolle.
2. EINE NACHRICHT HAT EINE RICHTUNG. Eigene Nachrichten kommen von
rechts und tragen den Hausakzent, fremde von links und bleiben
neutral. Die Ecke am Anfang einer Folge ist eckig, die übrigen
rund -- so sieht man, wo ein Gedanke anfängt, ohne den Namen zu
lesen.
3. EIN GESPRÄCH HAT EIN GEWICHT. Ungelesenes ist nicht "auch da",
sondern das, weshalb man die Seite geöffnet hat: kräftigerer
Grund, farbige Schiene, die Zahl als Marke.
4. DAS EINGABEFELD IST DAS WICHTIGSTE ELEMENT DER SEITE. Es war
eines von vielen. Jetzt sitzt es in einer eigenen Leiste, die
sich beim Hineinschreiben hebt.
Und was NICHT passiert ist: kein Blinken, kein Springen, keine
Verläufe im Text. Ein Chat wird stundenlang angesehen -- alles, was
einmal auffällt, nervt beim zwanzigsten Mal.
===================================================================== */
/* ---------- Das Gesicht ---------------------------------------------- */
.chat-raum__zeichen,
.chat-nachricht__zeichen {
position: relative;
overflow: hidden;
background: linear-gradient(150deg,
color-mix(in srgb, var(--rton, var(--akzent)) 30%, rgba(20, 27, 40, .9)),
rgba(12, 17, 26, .95));
box-shadow:
inset 0 0 0 1px color-mix(in srgb, var(--rton, var(--akzent)) 38%, transparent),
0 2px 6px -3px rgba(0, 0, 0, .8);
}
/* Die Farbe der Rolle -- dieselbe Zuordnung wie überall im Haus. */
.chat-raum__zeichen[data-rolle="spicy"],
.chat-nachricht__zeichen[data-rolle="spicy"] { --rton: var(--spicy-haupt); }
.chat-raum__zeichen[data-rolle="admin"],
.chat-nachricht__zeichen[data-rolle="admin"] { --rton: var(--dogi-haupt); }
.chat-raum__zeichen[data-rolle="manager"],
.chat-nachricht__zeichen[data-rolle="manager"] { --rton: var(--manager-haupt); }
.chat-raum__zeichen[data-rolle="scout"],
.chat-nachricht__zeichen[data-rolle="scout"] { --rton: var(--scout-haupt); }
.chat-raum__zeichen[data-rolle="creator"],
.chat-nachricht__zeichen[data-rolle="creator"] { --rton: var(--creator-haupt); }
/* Das Bild liegt ÜBER dem Buchstaben, nicht an seiner Stelle. Fällt es
aus, steht der Buchstabe weiterhin da. */
.chat-raum__zeichen img,
.chat-nachricht__zeichen img {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
border-radius: inherit;
}
/* ---------- Die Gesprächsliste --------------------------------------- */
/* HIER STAND EINE ZWEITE FASSUNG DERSELBEN REGELN (weg am 24.09.2026).
Sie hat `.chat-raum__knopf` ein zweites Mal beschrieben — Rundung,
Rand und Übergang — und dabei die erste Fassung weiter oben still
überschrieben. Zwei Beschreibungen derselben Sache in derselben
Datei: Wer eine davon ändert, ändert am Ergebnis nichts und sucht
danach den Fehler an der falschen Stelle.
Und die schönere der beiden griff gar nicht: Ihr Selektor hieß
`.chat-raum__knopf[data-an="ja"]`, gesetzt wird aber `data-offen`
am <li>. Das offene Gespräch trug deshalb monatelang die blasse
erste Fassung, während daneben eine Schiene beschrieben stand,
die nie jemand gesehen hat.
Alles steht jetzt EINMAL, weiter oben unter „Die Gesprächsliste
(neu gebaut am 24.09.2026)" — samt Schiene, und die greift. */
/* ---------- Die Nachrichten ------------------------------------------ */
/* HIER STAND DIE ZWEITE FASSUNG DERSELBEN BLASE — sie ist am
22.09.2026 weggefallen und in die erste (weiter oben) gewandert.
---------------------------------------------------------------------
Der Kommentar, der hier stand, hat den Zustand selbst beschrieben:
„Dass es zwei Stellen gibt, ist gewachsen (Grundform oben,
Feinschliff hier). Sie zusammenzulegen wäre ein größerer Umbau an
einer Datei, die heute schon viel abbekommen hat."
Am 22.09. hat genau das zweimal an einem Tag Schaden angerichtet:
1. Die runden Kanten, die Filipe ausdrücklich verlangt hat, wurden
oben auf 22 px gesetzt — und hier unten sofort wieder auf 16
zurückgestellt. Die Änderung wäre wirkungslos ausgeliefert worden,
und sie sähe im Quelltext richtig aus.
2. Die eigene Blase bekam ihre Farbe hier als VERLAUF mit 26 % bzw.
12 % Akzentfarbe hineingemischt. Damit hatte sie eine Farbe, die
in CHAT_KACHELN gar nicht vorkommt — und die die Kontrastprüfung
deshalb nie angesehen hat. Ausgerechnet die eigene Blase, die man
am häufigsten liest, lag außerhalb jeder Messung. Seit die zwölf
Töne kräftig sind, hätte die Beimischung sie zusätzlich aufgehellt
und das Versprechen „bei jedem derselbe Kontrast" gebrochen.
Der Akzent sitzt jetzt im Rand und im Schatten der eigenen Blase, wo
er sichtbar ist, ohne unter der Schrift zu liegen. Die Fläche selbst
ist bei allen dieselbe Rechnung. */
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .18),
0 2px 10px -2px color-mix(in srgb, var(--akzent) 45%, transparent);
}
/* Der Tagestrenner: eine Linie mit dem Datum darin statt eines Wortes
im Nichts. */
.chat-tag {
display: flex; align-items: center; gap: 12px;
margin: 18px 0 12px;
}
.chat-tag::before, .chat-tag::after {
content: ""; flex: 1 1 auto; height: 1px;
background: linear-gradient(90deg, transparent, rgba(150, 186, 220, .18), transparent);
}
/* ---------- Das Eingabefeld ------------------------------------------ */
/* Es ist das wichtigste Element der Seite und sah aus wie eines von
vielen. Eine eigene Leiste, die sich beim Hineinschreiben hebt. */
/* Sie heisst .chat__eingabe (chat.html), nicht .chat-neu -- ich hatte
den Namen aus dem Kopf geschrieben. pruef-struktur meldete es als
totes CSS: eine Regel, die auf nichts zeigt, sieht aus wie erledigte
Arbeit und ist keine. */
.chat__eingabe {
position: relative;
padding: 12px 14px;
border-top: 1px solid rgba(150, 186, 220, .12);
background: linear-gradient(180deg, rgba(13, 18, 28, .6), rgba(9, 12, 20, .92));
transition: box-shadow var(--tempo);
}
.chat__eingabe:focus-within {
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--akzent) 34%, transparent);
}
@media (prefers-reduced-motion: reduce) {
.chat-raum__knopf, .chat__eingabe { transition: none; }
}
@media (forced-colors: active) {
.chat-nachricht__blase,
.chat-raum__knopf[data-an="ja"] { box-shadow: none; border: 1px solid CanvasText; }
.chat-raum__zeichen, .chat-nachricht__zeichen { background: Canvas; box-shadow: none; }
}
/* =====================================================================
DREI DINGE, DIE DEM CHAT GEFEHLT HABEN (Punkt 15, 09.09.2026)
Filipe: "ich will dass du diese seite viel krasser und detaillierter
machst, ich will dass du dich informierst und alles reinsetzt was
wir noch gebrauchen könnten."
Nicht alles, sondern das, was hier täglich fehlt. Der Chat konnte
schon Räume, Verlauf, Gelesen-Stand, Live-Zustellung, Gruppen und
Zurücknehmen. Was fehlte:
1. SUCHE IN DEN NACHRICHTEN. Ein Chat ohne sie ist ab dem zweiten
Monat ein Archiv, in dem man nichts findet. Das Suchfeld gab es
— es durchsuchte aber nur die NAMEN der Gespräche.
2. ANTWORTEN MIT ZITAT. Zu zweit weiß man meist, worauf sich etwas
bezieht. In einer Gruppe laufen drei Fäden parallel, und "ja,
mach das" kann alles heißen.
3. DIE LINIE "AB HIER NEU". Wer nach zwei Tagen zurückkommt, sucht
sonst die Stelle, an der er aufgehört hat, indem er Uhrzeiten
liest.
Bewusst NICHT gebaut: Anhänge (dafür gibt es den Dateien-Bereich mit
Rechten und Ablauf), Reaktionen (eine vierte Sache, bevor die drei
sich bewährt haben) und Tipp-Anzeigen (sie kosten dauernd Verkehr
und sagen nichts, was man nicht in zwei Sekunden sieht).
===================================================================== */
/* ---- Das Zitat in der Blase ---------------------------------------- */
.chat-zitat {
display: block; width: 100%; text-align: left;
margin: 0 0 7px; padding: 6px 10px 6px 11px;
border: 0; border-radius: 0;
/* Der senkrechte Strich links ist das Zeichen für ein Zitat -- in
jedem Mailprogramm seit dreißig Jahren dasselbe. */
box-shadow: inset 3px 0 0 color-mix(in srgb, var(--akzent) 60%, transparent);
background: rgba(255, 255, 255, .05);
color: var(--text-leise);
font: inherit; cursor: pointer;
transition: background var(--tempo);
}
.chat-zitat:hover { background: rgba(255, 255, 255, .09); }
.chat-zitat__von {
display: block;
font-size: .74rem; font-weight: 700;
color: color-mix(in srgb, var(--akzent) 70%, #ffffff);
}
.chat-zitat__text {
display: block;
font-size: .8rem; line-height: 1.35;
/* Zwei Zeilen reichen: Es ist ein Hinweis auf die Stelle, nicht ihre
Wiederholung. */
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden;
}
/* Die zitierte Nachricht, wenn man hinspringt -- kurz hervorgehoben.
Ein Sprung ohne Markierung lässt einen raten, welche Zeile gemeint
war. */
.chat-nachricht[data-hervor="ja"] .chat-nachricht__blase {
box-shadow: 0 0 0 2px color-mix(in srgb, var(--akzent) 65%, transparent);
transition: box-shadow .4s ease;
}
@media (prefers-reduced-motion: reduce) {
.chat-nachricht[data-hervor="ja"] .chat-nachricht__blase { transition: none; }
}
/* ---- Die Linie "ab hier neu" --------------------------------------- */
.chat-neu {
display: flex; align-items: center; gap: 10px;
margin: 14px 2px 10px;
color: #ff8f98;
font-size: .72rem; font-weight: 700;
letter-spacing: .1em; text-transform: uppercase;
}
.chat-neu::before, .chat-neu::after {
content: ""; flex: 1; height: 1px;
background: linear-gradient(90deg, transparent, rgba(255, 143, 152, .5));
}
.chat-neu::after { background: linear-gradient(90deg, rgba(255, 143, 152, .5), transparent); }
.chat-neu__text { flex: none; }
/* ---- Die Antwortleiste über dem Eingabefeld ------------------------ */
.antwort-leiste {
display: flex; align-items: flex-start; gap: 10px;
/* GANZE ZEILE, IMMER. Sie gehoert ueber das Schreibfeld, nicht
daneben -- `margin-bottom` unten sagt das seit jeher, nur
durchgesetzt wurde es nie. */
flex: 1 0 100%;
margin-bottom: 8px; padding: 8px 10px 8px 11px;
box-shadow: inset 3px 0 0 var(--akzent);
background: rgba(255, 255, 255, .05);
}
.antwort-leiste[hidden] { display: none; }
.antwort-leiste__inhalt { min-width: 0; flex: 1; }
.antwort-leiste__schild {
/* 0,72 rem = 11,52 px. Mit 0,7 waeren es 11,2 und damit unter der
Grundlinie, die pruef-css-klassen haelt. */
font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
color: var(--text-still);
}
.antwort-leiste__von {
margin-left: 6px;
font-size: .78rem; font-weight: 700;
color: color-mix(in srgb, var(--akzent) 70%, #ffffff);
}
.antwort-leiste__text {
display: block;
font-size: .82rem; color: var(--text-leise);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.antwort-leiste__weg {
flex: none; width: 28px; height: 28px;
border: 0; border-radius: 50%;
background: rgba(255, 255, 255, .07);
color: var(--text-leise); font-size: .9rem; cursor: pointer;
}
.antwort-leiste__weg:hover { background: rgba(255, 255, 255, .13); color: var(--text); }
/* ---- Fundstellen in Nachrichten ------------------------------------ */
.chat-funde { padding: 4px 10px 12px; }
.chat-funde[hidden] { display: none; }
.chat-funde__schild {
margin: 8px 0 6px;
font-size: .72rem; font-weight: 700;
letter-spacing: .09em; text-transform: uppercase;
color: var(--text-still);
}
.chat-funde__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.chat-funde__leer { font-size: .84rem; color: var(--text-still); }
.chat-fund {
display: grid; gap: 2px;
width: 100%; padding: 8px 11px;
text-align: left; border: 0;
clip-path: polygon(7px 0, 100% 0, 100% calc(100% - 7px), calc(100% - 7px) 100%, 0 100%, 0 7px);
background: rgba(255, 255, 255, .045);
color: var(--text); font: inherit; cursor: pointer;
transition: background var(--tempo);
}
.chat-fund:hover { background: rgba(255, 255, 255, .09); }
.chat-fund__kopf { display: flex; justify-content: space-between; gap: 8px; }
.chat-fund__raum {
font-size: .78rem; font-weight: 700;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-fund__wann { flex: none; font-size: .72rem; color: var(--text-still); }
.chat-fund__von { font-size: .72rem; color: var(--text-still); }
.chat-fund__text {
font-size: .82rem; color: var(--text-leise); line-height: 1.35;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden;
}
/* Der Antworten-Knopf am Fuß einer Nachricht -- genauso leise wie
"zurücknehmen" daneben. Er ist ein Angebot, keine Aufforderung. */
/* "reagieren" steht seit dem 14.09.2026 daneben und sieht genauso aus
-- dieselbe Sorte Handgriff, dieselbe Zeile. Deshalb DIESELBE Regel
und keine vierte Abschrift: Neben antworten, anheften und kopieren
waere sie die vierte fast gleiche, und die vierte ist die, die
irgendwann eine Zeile anders hat. */
/* =====================================================================
DIE HANDGRIFFE SIND MARKEN, KEINE LINKS MEHR (25.09.2026)
Unter jeder Blase standen fuenf unterstrichene Woerter nebeneinander
-- „antworten reagieren loeschen anheften kopieren". Unterstrichener
Text heisst im Netz seit dreissig Jahren „das fuehrt woandershin",
und genau das tun sie nicht: Sie tun etwas HIER. Im Bildschirmfoto
war das die unruhigste Stelle der ganzen Seite.
SIE BLEIBEN SICHTBAR -- das ist keine Nebensache, sondern eine
Entscheidung vom 23.09.2026, die weiter gilt: Auf einem Handy gibt
es kein Ueberfahren, und ein Knopf, den man dort nicht erreicht,
gibt es dort nicht. Also nicht verstecken, sondern LEISER machen.
Als Marke: kein Unterstrich, ein kaum sichtbarer Rahmen, gedaempfte
Farbe. Beim Ueberfahren oder mit der Tastatur wird sie deutlich --
dann, wenn man sie meint. Die Flaeche waechst dabei auf ueber
24x24 px; vorher war ein Wort nur so hoch wie seine Schrift.
===================================================================== */
/* =====================================================================
DIE HANDGRIFFE BEKOMMEN ZEICHEN (25.09.2026)
Filipe: „ich will wirklich dass du das ingesamte veränderst und so
krass geil machst dass die ganze community und team morgen total
überrascht sind und den chat nicht wieder erkennen."
Unter jeder Blase standen fünf Wörter in Versalien. Sie waren leise
und ordentlich – und trotzdem fünf Wörter, die man in jeder
Nachricht wieder liest, ohne sie zu brauchen. Bei zwölf Nachrichten
sind das sechzig.
JETZT: Zeichen voran, Wort daneben, in Kleinbuchstaben. Ein Pfeil,
ein Gesicht, ein Papierkorb, eine Nadel, zwei Blätter – die kennt
jeder aus jedem Messenger, und das Auge findet sie, ohne zu lesen.
WARUM DIE WÖRTER TROTZDEM BLEIBEN: Reine Zeichenknöpfe wären
schöner und schlechter. „anheften" und „lösen" sehen als Nadel
gleich aus – wer sie verwechselt, verschiebt eine Ankündigung im
Kanal, ohne es zu merken. Und „löschen (Notfall)" darf nie ein
Rätsel sein: Es entfernt fremde Worte.
BREITER WIRD ES DADURCH NICHT. Versalien mit .07em Sperrung sind
rund ein Viertel breiter als dieselben Wörter klein gesetzt.
Nachgerechnet an „antworten" bei 11,5 px: vorher rund 66 px, jetzt
rund 50 px Schrift + 13 px Zeichen + 5 px Abstand = 68. Die Zeile
bleibt also so lang wie vorher und sagt mehr.
DIE ZEICHEN SIND MASKEN, KEINE BILDER. `mask-image` färbt sie mit
`currentColor`: Jedes Zeichen folgt damit der Schrift daneben – im
Ruhezustand leise, beim Überfahren hell, beim Notfall-Löschen in
der Warnfarbe. Ein <img> müsste man für jeden dieser Zustände neu
einfärben, und einer davon wäre irgendwann vergessen. Fehlt
`mask` (sehr alte Browser), bleibt schlicht das Wort stehen – kein
Schaden, nur weniger Bild.
===================================================================== */
.chat-nachricht__antwort-knopf,
.chat-nachricht__reag-knopf,
.chat-nachricht__kopie-knopf,
.chat-nachricht__weg-knopf {
display: inline-flex; align-items: center; gap: 5px;
border: 1px solid transparent;
background: none;
padding: 3px 9px 3px 7px;
border-radius: 999px;
font: inherit; font-size: .72rem; font-weight: 600;
line-height: 1.5;
color: inherit; cursor: pointer;
text-decoration: none;
opacity: .72;
transition: opacity .16s ease, background-color .16s ease,
border-color .16s ease, color .16s ease;
}
/* Eine Regel für alle fünf – die Familie steht an EINER Stelle
beieinander, wie schon die Form darüber. Wer einen sechsten
Handgriff baut, trägt ihn hier ein und bekommt sein Zeichen. */
.chat-nachricht__antwort-knopf::before,
.chat-nachricht__reag-knopf::before,
.chat-nachricht__kopie-knopf::before,
.chat-nachricht__pin-knopf::before,
.chat-nachricht__weg-knopf::before {
content: ""; flex: none;
width: 13px; height: 13px;
background: currentColor;
-webkit-mask: var(--zeichen) center / 13px 13px no-repeat;
mask: var(--zeichen) center / 13px 13px no-repeat;
}
.chat-nachricht__antwort-knopf {
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M9.5 5.5 3.5 11.5l6 6'/><path d='M3.5 11.5h9.5a7 7 0 0 1 7 7v.6'/></svg>");
}
.chat-nachricht__reag-knopf {
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M8.6 9.9h.01'/><path d='M15.4 9.9h.01'/><path d='M8.2 14.4a5 5 0 0 0 7.6 0'/></svg>");
}
.chat-nachricht__kopie-knopf {
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='8.5' y='8.5' width='12' height='12' rx='3'/><path d='M15.5 8.5v-2a3 3 0 0 0-3-3h-6a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h2'/></svg>");
}
.chat-nachricht__weg-knopf {
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4.5 7h15'/><path d='M10 7V4.8h4V7'/><path d='M6.6 7l.9 12.2h9L17.4 7'/></svg>");
}
.chat-nachricht__antwort-knopf:hover,
.chat-nachricht__reag-knopf:hover,
.chat-nachricht__kopie-knopf:hover,
.chat-nachricht__weg-knopf:hover {
opacity: 1;
color: var(--blase-text);
background: rgba(255, 255, 255, .14);
border-color: rgba(255, 255, 255, .22);
}
.chat-nachricht__antwort-knopf:focus-visible,
.chat-nachricht__reag-knopf:focus-visible,
.chat-nachricht__kopie-knopf:focus-visible,
.chat-nachricht__weg-knopf:focus-visible {
opacity: 1; outline: 2px solid var(--akzent); outline-offset: 1px;
}
.chat-nachricht__reag-knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* =====================================================================
CHAT: SECHS ERGÄNZUNGEN (09.09.2026)
Filipe: "die kategorie chat, boah ich will dass du die wirklich
überall perfektionierst. wirklich alles was gratis ist und
hinzugefügt werden kann ohne problem will ich drin haben."
Alle sechs kommen ohne fremde Bibliothek aus und laden nichts nach:
Links, Kopieren, Emoji-Auswahl, Zeichenzähler, ein Bildlauf der nicht
mehr wegreisst, und Entwürfe je Gespräch (dafür braucht es kein CSS).
===================================================================== */
/* Ein Link in einer Nachricht ist unterstrichen, nicht farbig -- eine
Blase hat schon eine Farbe, und zwei Farben in einer Blase lesen sich
wie zwei Sachen. */
.chat-nachricht__link {
color: inherit;
text-decoration: underline;
text-underline-offset: 3px;
text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
word-break: break-word;
}
.chat-nachricht__link:hover { text-decoration-color: currentColor; }
.chat-nachricht__link:focus-visible {
outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: 3px;
}
/* Der Kopier-Knopf sieht aus wie "antworten" -- es ist dieselbe Sorte
Handgriff an derselben Stelle. Ein anders gestalteter Knopf daneben
waere eine zweite Sprache in derselben Zeile. */
/* DIESER BLOCK STAND HIER UND HAT DEN NEUEN UEBERSCHRIEBEN
(bereinigt 25.09.2026). Er kam SPAETER in der Datei als die
gemeinsame Marken-Regel weiter oben und hat deren Rahmen, Polsterung
und Rundung wieder weggenommen -- ausgerechnet bei "kopieren".
Aufgefallen ist es nicht beim Lesen, sondern weil ein Knopf von
fuenfen anders aussah.
Was hier bleiben MUSS, ist `appearance: none` (Safari zeichnet
sonst seinen eigenen Knopf) und die Rundung des Fokusrahmens. Alles
andere steht oben, einmal, fuer alle vier. */
.chat-nachricht__kopie-knopf { appearance: none; }
.chat-nachricht__kopie-knopf:hover { color: var(--blase-text); }
.chat-nachricht__kopie-knopf:focus-visible {
outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: 4px;
}
/* ==== DIE VIER WERKZEUGE SPRECHEN EINE SPRACHE (25.09.2026) =========
Büroklammer, Mikrofon, GIF und Emoji standen in drei verschiedenen
Fassungen nebeneinander -- verschiedene Rundungen, verschiedene
Ränder, einer mit Fläche, einer ohne. Im Bildschirmfoto sah die
Konsole dadurch aus wie vier Knöpfe aus vier Programmen.
Sie bekommen jetzt dieselbe Mulde wie die Schalter der
Registerleiste: eingesenkt, mit Lichtkante oben. Beim Überfahren
heben sie sich in die Akzentfarbe.
NUR OBERFLÄCHE, KEINE MASSE. Breite, Höhe, Polsterung und Abstände
bleiben unangetastet -- die Zeile ist seit dem 23.09.2026 auf den
Pixel voll, und sechs Pixel haben dort schon einmal gereicht, um
„Senden" auf eine eigene Zeile zu schieben. Wer hier eine Maßzahl
ändert, misst auf 320, 390 und 412 px nach. */
.chat__eingabe :is(.chat__anhang, .chat__ton, .chat__gif, .chat__emoji) {
border-radius: 13px;
border-color: rgba(255, 255, 255, .07);
background: linear-gradient(180deg,
rgba(0, 0, 0, .34) 0%, rgba(255, 255, 255, .022) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .055),
inset 0 -2px 5px -3px rgba(0, 0, 0, .75);
}
.chat__eingabe :is(.chat__anhang, .chat__ton, .chat__gif, .chat__emoji):hover {
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 14%, transparent);
}
/* ==== DER SCHRIFTKNOPF (25.09.2026) ================================
Er sieht aus wie die vier Werkzeuge daneben -- es ist dieselbe Sorte
Handgriff, und eine eigene Gestalt waere ein fuenftes Muster in
einer Reihe von vier.
IST DIE LEISTE OFFEN, TRAEGT ER DIE AKZENTFARBE. Das ist der
Unterschied zu „gedrueckt" bei den anderen: GIF und Emoji machen
eine Tafel auf, die man sieht; diese Leiste steht darueber und ist
leicht zu uebersehen. Der Knopf sagt deshalb dauerhaft, in welchem
Zustand er ist.
`Aa` IST TEXT UND KEIN BILD, deshalb hier eine Schriftgroesse statt
einer Maske -- gross genug, um als Buchstabenpaar gelesen zu werden,
und fett, damit es neben den Strichzeichnungen daneben nicht
verschwindet. */
.chat__schriftknopf {
flex: none;
width: 40px; height: 40px;
display: flex; align-items: center; justify-content: center;
appearance: none;
border: 1px solid rgba(150, 186, 220, .18);
border-radius: 12px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise);
font: inherit; font-size: .95rem; font-weight: 700;
letter-spacing: -.02em;
cursor: pointer;
transition: color .16s ease, border-color .16s ease, background-color .16s ease;
}
.chat__schriftknopf:hover { color: var(--text); border-color: rgba(150, 186, 220, .34); }
.chat__schriftknopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat__schriftknopf[aria-expanded="true"] {
color: color-mix(in srgb, var(--akzent) 25%, #ffffff);
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
background: color-mix(in srgb, var(--akzent) 16%, transparent);
}
/* ZU HEISST WEG, nicht „unsichtbar an derselben Stelle". `display:
none` nimmt der Leiste auch ihren Platz -- genau darum geht es.
AM FORMULAR UND NICHT AN DER LEISTE SELBST: Die Leiste entsteht
erst, wenn ein Gespraech aufgeht (textform.js haengt sie dann ein).
Ein Merkmal an etwas, das es noch nicht gibt, kann man nicht setzen;
das Formular steht immer da. */
.chat__eingabe[data-schrift="zu"] .textform { display: none; }
@media (prefers-reduced-motion: reduce) {
.chat__schriftknopf { transition: none; }
}
/* ---- Emoji ---------------------------------------------------------- */
.chat__emoji {
flex: none;
width: 40px; height: 40px;
display: flex; align-items: center; justify-content: center;
appearance: none; border: 1px solid rgba(150, 186, 220, .18);
border-radius: 11px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise);
font-size: 1.15rem; line-height: 1; cursor: pointer;
transition: color var(--tempo), border-color var(--tempo);
}
.chat__emoji:hover { color: var(--text); border-color: rgba(150, 186, 220, .34); }
.chat__emoji:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Die Tafel steht ÜBER der Eingabe, nicht darunter: Darunter läge sie
auf dem Handy hinter der Bildschirmtastatur. */
.emoji-tafel {
position: absolute;
right: 14px; bottom: calc(100% - 6px);
z-index: 5;
display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px;
padding: 10px;
border-radius: 14px;
background: rgba(8, 12, 20, .97);
border: 1px solid rgba(150, 186, 220, .2);
box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .9);
}
.emoji-tafel__knopf {
appearance: none; border: 0; background: none;
/* FUELLT SEINE SPALTE, STATT 34 px BREIT ZU SEIN (19.09.2026).
Emojis stehen dicht an dicht: Bei 34 px Knopf und 2 px Abstand
liegt der Nachbar 36 px vom Mittelpunkt entfernt. Wer danebentippt,
verschickt ein anderes Zeichen -- und anders als ein Fehlgriff in
einem Menue ist das sofort abgeschickt. */
width: 100%; min-height: 44px; border-radius: var(--radius-klein);
font-size: 1.15rem; line-height: 1; cursor: pointer;
transition: background var(--tempo);
}
.emoji-tafel__knopf:hover { background: rgba(255, 255, 255, .1); }
.emoji-tafel__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
@media (max-width: 620px) {
.emoji-tafel { left: 14px; right: 14px; grid-template-columns: repeat(8, 1fr); }
}
/* ---- Zeichenzähler --------------------------------------------------- */
.chat__zeichen {
flex: none; align-self: center;
font-size: .72rem; font-weight: 700; letter-spacing: .04em;
color: var(--text-still);
font-variant-numeric: tabular-nums;
}
/* Eng heisst rot -- aber erst dann. Ein dauerhaft roter Zähler ist eine
Warnung, die niemand mehr liest. */
.chat__zeichen[data-eng="ja"] { color: var(--warn, #ff9aa2); }
/* ---- Zum neuesten ---------------------------------------------------- */
/* DIE 96 WAR EINE RECHNUNG VON GESTERN (20.09.2026).
Hier stand `bottom: 96px` -- die Höhe der Schreibleiste, gemessen
an dem Tag, an dem sie gebaut wurde. Das Textfeld wächst aber mit
dem Text, bis auf 160 Pixel. Wer einen langen Text tippt und
gleichzeitig weiter oben liest, hatte den Knopf HINTER der Leiste.
Jetzt sagt die Leiste selbst, wie hoch sie ist: `chat.js` schreibt
`--leiste` bei jeder Höhenänderung. Der Rückfallwert gilt nur, bis
das Skript einmal gerechnet hat. */
.chat__zum-neuesten {
position: absolute; left: 50%;
bottom: calc(var(--leiste, 96px) + 12px);
transform: translateX(-50%);
z-index: 4;
padding: 9px 18px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--akzent) 40%, transparent);
background: rgba(8, 12, 20, .95);
color: var(--text);
font: inherit; font-size: .8rem; font-weight: 700;
cursor: pointer;
box-shadow: 0 10px 26px -12px rgba(0, 0, 0, .9);
}
.chat__zum-neuesten:hover { border-color: var(--akzent); }
.chat__zum-neuesten:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
.chat__emoji, .emoji-tafel__knopf { transition: none; }
}
@media (forced-colors: active) {
.emoji-tafel, .chat__zum-neuesten { border: 1px solid CanvasText; background: Canvas; }
}
/* =====================================================================
ANHÄNGE, ABLAGE UND WEGRÄUMEN (09.09.2026)
Filipe: "man muss die chats auch gelöscht bekommen!!! am besten wäre
es auch wenn man da auch im chat pdfs schicken könnte. pdfs und
fotos."
===================================================================== */
/* Der Wegräum-Knopf sitzt im Kopf, rechts. Er ist absichtlich LEISE:
Löschen ist die seltene Handlung, und ein roter Knopf, der jeden Tag
danebensteht, wird irgendwann aus Versehen getroffen. Rot wird er
erst beim Darüberfahren -- dann, wenn jemand ihn wirklich meint. */
/* Der Behaelter schiebt, die Knoepfe stehen. Vorher schob sich jeder
Knopf mit `margin-left: auto` selbst -- bei zwei sichtbaren teilen
sich zwei auto-Raender den freien Platz und reissen sie auseinander.
Welche sichtbar sind, entscheidet der Server; eine Regel, die das
aushaelt, ist besser als eine Zahl, die fuer einen Fall stimmt. */
/* =====================================================================
REAKTIONEN (14.09.2026)
Filipe: "ich will dass man auf die nachrichten auch reagieren kann
mit einem emoji, die nachricht selbst ohne zu antworten."
GEDECKT, NICHT BUNT. Die Zeichen bringen ihre eigene Farbe mit --
ein farbiger Rahmen darum waere zu viel fuer eine Zeile, die unter
jeder zweiten Nachricht stehen kann. Die eigene Reaktion ist am
Rahmen zu erkennen, nicht an einem Leuchten.
===================================================================== */
.reaktionen {
display: flex; flex-wrap: wrap; gap: 5px;
margin: 7px 0 0;
}
.reaktionen__stueck {
display: inline-flex; align-items: center; gap: 5px;
padding: 2px 8px 3px;
border: 1px solid var(--rand); border-radius: 999px;
background: rgba(255, 255, 255, .04);
font: inherit; font-size: .8rem; line-height: 1.4;
color: var(--text-leise); cursor: pointer;
transition: border-color var(--tempo), background var(--tempo);
}
.reaktionen__stueck:hover { border-color: var(--rand-hell); }
/* Die EIGENE Reaktion: ein Rahmen in der Hausfarbe. Damit sieht man
auf einen Blick, wo man selbst schon geklickt hat -- und ein zweiter
Klick nimmt sie zurueck. */
.reaktionen__stueck[data-selbst="ja"] {
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
background: color-mix(in srgb, var(--akzent) 12%, transparent);
color: var(--text);
}
.reaktionen__stueck:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.reaktionen__zeichen { font-size: .95rem; line-height: 1; }
.reaktionen__zahl { font-variant-numeric: tabular-nums; }
/* Die Tafel: eine Karte, kein Pillenstreifen (14.09.2026).
Filipe: "soll viel besser und geiler sein und man soll auch
auswaehlen koennen, also paar als vorschlaege mit der moeglichkeit
andere auszuwaehlen und als favoriten zu speichern."
Die erste Fassung war eine Reihe von sechs Zeichen in einer Pille.
Das sah nach Notloesung aus -- und es WAR eine: Mehr ging nicht
hinein. Jetzt ist es eine Karte mit drei Teilen: Vorschlaege oben,
Suche, Katalog. Der Katalog rollt, die Vorschlaege bleiben stehen.
GEDECKT, NICHT GRELL: Die Zeichen bringen ihre eigene Farbe mit. Die
Karte darum ist dunkel und ruhig, damit die Zeichen die einzigen
bunten Punkte sind. */
.reagieren-tafel {
position: relative; z-index: 5;
/* SIE MUSS SAGEN, IN WELCHE SPALTE SIE GEHOERT (15.09.2026).
Filipe, mit einem Bildschirmfoto: "was ist das den fuer eine
scheisse verbesser das sofort." Darauf ein dreissig Pixel schmaler
Streifen mit sechs Zeichen untereinander.
.chat-nachricht ist ein RASTER aus zwei Spalten: dreissig Pixel
fuer den Kreis mit den Initialen, der Rest fuer die Blase. Ein
Kind ohne Spaltenangabe wird automatisch in die naechste freie
Zelle gesetzt -- und das ist die Spalte des Kreises. Die Tafel
bekam damit dreissig Pixel, `width: min(330px, 100%)` machte
brav 30 daraus, und die Zeichen stapelten sich.
BEI EIGENEN NACHRICHTEN FIEL ES NIE AUF: Dort hat das Raster nur
EINE Spalte (der Kreis entfaellt), die Tafel bekam die volle
Breite. Und genau diesen Fall hat die Pruefung gemessen -- sie war
gruen, waehrend es bei jeder fremden Nachricht kaputt war. */
grid-column: 2; justify-self: start;
margin: 8px 0 2px;
width: min(330px, 100%);
border: 1px solid var(--rand-hell, var(--rand));
border-radius: 16px;
background:
linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015)),
var(--flaeche-tief, #131a24);
box-shadow: 0 18px 40px -22px rgba(0, 0, 0, .95),
inset 0 1px 0 rgba(255, 255, 255, .06);
padding: 9px 9px 7px;
animation: tafel-auf .13s ease-out;
}
@keyframes tafel-auf {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.reagieren-tafel { animation: none; }
}
/* Die eigene Nachricht hat nur eine Spalte -- dort waere `2` eine
Spalte, die es nicht gibt, und das Raster legte still eine an. */
.chat-nachricht[data-selbst="ja"] .reagieren-tafel {
grid-column: 1; justify-self: end;
}
/* Kopf: die Vorschlaege nehmen den Platz, der Stern bleibt rechts. */
.reagieren-tafel__kopf {
display: flex; align-items: center; gap: 6px;
}
.reagieren-tafel__schnell {
flex: 1; min-width: 0;
display: flex; flex-wrap: wrap; gap: 2px;
}
.reagieren-tafel__stern {
flex: none;
appearance: none; border: 1px solid transparent; border-radius: 10px;
width: 30px; height: 30px;
background: none; cursor: pointer;
font-size: .95rem; line-height: 1;
color: var(--text-still);
transition: color var(--tempo), background var(--tempo), border-color var(--tempo);
}
.reagieren-tafel__stern:hover { color: var(--text-leise); background: rgba(255, 255, 255, .06); }
.reagieren-tafel__stern:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Im Merk-Modus ist der Stern AN -- und die ganze Tafel sagt es mit,
damit niemand aus Versehen reagiert, wenn er merken wollte. */
.reagieren-tafel[data-merken="ja"] .reagieren-tafel__stern {
color: var(--akzent);
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 14%, transparent);
}
.reagieren-tafel[data-merken="ja"] {
border-color: color-mix(in srgb, var(--akzent) 40%, var(--rand));
}
.reagieren-tafel__hinweis {
margin: 0; padding: 0 2px;
font-size: .72rem; line-height: 1.45;
color: var(--text-still);
}
.reagieren-tafel__hinweis:empty { display: none; }
.reagieren-tafel__suche {
width: 100%; box-sizing: border-box;
margin: 7px 0 6px;
padding: 6px 10px;
border: 1px solid var(--rand); border-radius: 10px;
background: rgba(0, 0, 0, .25);
font: inherit; font-size: .78rem;
color: var(--text);
}
.reagieren-tafel__suche::placeholder { color: var(--text-still); }
.reagieren-tafel__suche:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
/* Der Katalog rollt INNEN. Eine Tafel, die laenger wird als der
Bildschirm, schiebt den Chat weg und ihre eigene Suche nach oben
hinaus. */
.reagieren-tafel__katalog {
max-height: 210px; overflow-y: auto;
padding-right: 2px;
overscroll-behavior: contain;
}
.reagieren-tafel__gruppe {
margin: 6px 0 3px; padding: 0 2px;
/* .72rem = 11.52 px und damit knapp ueber der Lesbarkeitsgrenze von
11.5 px, die pruef-css-klassen zieht. Mein erster Wert (.66rem =
10.56 px) ist dort aufgeschlagen -- richtig so: Eine gesperrte
Versalzeile ist ohnehin schon schwerer zu lesen als normale
Schrift, da darf sie nicht auch noch die kleinste sein. */
font-size: .72rem; letter-spacing: .09em; text-transform: uppercase;
color: var(--text-still);
}
.reagieren-tafel__gruppe:first-child { margin-top: 0; }
.reagieren-tafel__reihe { display: flex; flex-wrap: wrap; gap: 2px; }
.reagieren-tafel__leer {
margin: 10px 2px; font-size: .76rem; color: var(--text-still);
}
.reagieren-tafel__zeichen {
position: relative;
appearance: none; border: 1px solid transparent; border-radius: 10px;
width: 34px; height: 32px;
padding: 0;
background: none; cursor: pointer;
font-size: 1.15rem; line-height: 1;
transition: background var(--tempo), transform var(--tempo), border-color var(--tempo);
}
.reagieren-tafel__zeichen:hover {
background: rgba(255, 255, 255, .09);
transform: scale(1.14);
}
.reagieren-tafel__zeichen:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
/* EIN FAVORIT TRAEGT EINEN PUNKT, keinen Rahmen: Der Rahmen gehoert im
Merk-Modus dem, was man gerade anfasst. Ein kleiner Punkt unten sagt
"gemerkt", ohne mit dem Zeichen zu konkurrieren. */
.reagieren-tafel__zeichen[data-favorit="ja"]::after {
content: ""; position: absolute;
left: 50%; bottom: 2px; transform: translateX(-50%);
width: 4px; height: 4px; border-radius: 50%;
background: var(--akzent);
}
/* Im Merk-Modus wird der Punkt zum Rahmen -- dort geht es genau darum. */
.reagieren-tafel[data-merken="ja"] .reagieren-tafel__zeichen[data-favorit="ja"] {
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
background: color-mix(in srgb, var(--akzent) 12%, transparent);
}
@media (prefers-reduced-motion: reduce) {
.reagieren-tafel__zeichen:hover { transform: none; }
.reagieren-tafel__zeichen, .reagieren-tafel__stern { transition: none; }
}
/* Am Handy darf die Tafel die ganze Breite nehmen -- 330 px neben
einer Sprechblase waeren dort ein Streifen. */
@media (max-width: 560px) {
.reagieren-tafel { width: 100%; }
.reagieren-tafel__katalog { max-height: 44vh; }
}
/* =====================================================================
VIER EINZELNE KNOEPFE WERDEN EINE GRUPPE (25.09.2026)
Rechts oben standen vier gleich aussehende Kaestchen mit vier
Abstaenden dazwischen -- Telefon, Video, Loeschen, Hilfe. Vier
Dinge, die nebeneinander nichts verbindet, liest man als vier
Sachen; als Gruppe liest man sie als EIN Werkzeug mit vier
Griffen.
DIE GRUPPE IST EINE MULDE: eingelassen, mit Lichtkante oben. Die
Knoepfe darin behalten ihre eigene Form und heben sich beim
Ueberfahren heraus -- derselbe Gedanke wie ueberall auf dieser
Seite, nur eine Ebene tiefer.
===================================================================== */
.chat__kopf-knoepfe {
flex: none; margin-left: auto;
display: flex; align-items: center; gap: 4px;
padding: 4px;
border-radius: 14px;
border: 1px solid rgba(255, 255, 255, .06);
background: linear-gradient(180deg,
rgba(0, 0, 0, .34) 0%, rgba(255, 255, 255, .025) 100%);
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .7),
0 1px 0 rgba(255, 255, 255, .05);
}
.chat__weg {
flex: none;
width: 34px; height: 34px;
display: grid; place-items: center;
border: 1px solid var(--rand); border-radius: 10px;
background: rgba(255, 255, 255, .03);
color: var(--text-leise); cursor: pointer;
transition: color var(--tempo), border-color var(--tempo);
}
.chat__weg svg {
width: 17px; height: 17px;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.chat__weg:hover { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.chat__weg:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* AUFLOESEN SIEHT ANDERS AUS ALS WEGRAEUMEN (11.09.2026). Zwei gleich
aussehende Knoepfe nebeneinander, von denen einer nur bei mir und
einer bei ALLEN loescht, waeren eine Falle. Anderes Zeichen, eigener
Rand -- aber gedeckt, nicht signalrot: Der Knopf steht im Kopf und
soll nicht den ganzen Tag schreien. */
.chat__weg--ganz {
border-color: color-mix(in srgb, var(--warn) 30%, var(--rand));
color: color-mix(in srgb, var(--warn) 55%, var(--text-leise));
}
.chat__weg--ganz:hover {
color: var(--warn);
border-color: color-mix(in srgb, var(--warn) 65%, transparent);
background: color-mix(in srgb, var(--warn) 9%, transparent);
}
/* Steht der Knopf da, braucht der Text daneben seinen eigenen Rand --
sonst hat .chat__kopf-text keine Grenze und schiebt ihn hinaus.
`1 1 8rem` UND NICHT `1` (berichtigt 20.09.2026). `flex: 1` heisst
ausgeschrieben `1 1 0%` -- Grundbreite NULL. Damit "passt" der Name
rechnerisch immer, egal wie eng es ist, und es bricht nie etwas um:
Am Handy blieben 0 bis 33 Pixel uebrig, und man sah nicht mehr, mit
wem man schreibt.
Diese Zeile ist spezifischer als die Grundregel weiter oben und hat
sie deshalb stillschweigend ueberstimmt -- die dortige Reparatur
wirkte bei 360 px und bei 390 px nicht. Zwei Stellen, eine Regel:
Sie muessen dieselbe Grundbreite nennen. */
.chat__kopf--verlauf .chat__kopf-text { min-width: 0; flex: 1 1 8rem; }
/* ---- Die Büroklammer ------------------------------------------------ */
.chat__anhang-feld {
/* Nicht display:none -- ein verstecktes Feld lässt sich in manchen
Browsern nicht mehr über click() öffnen. Es steht da, nur ohne
Fläche. */
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;
clip-path: inset(50%); border: 0;
}
.chat__anhang {
flex: none;
width: 40px; height: 40px;
display: flex; align-items: center; justify-content: center;
appearance: none; border: 1px solid rgba(150, 186, 220, .18);
border-radius: 11px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise); cursor: pointer;
transition: color var(--tempo), border-color var(--tempo);
}
.chat__anhang svg {
width: 19px; height: 19px;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.chat__anhang:hover { color: var(--text); border-color: rgba(150, 186, 220, .34); }
.chat__anhang:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat__anhang:disabled { opacity: .45; cursor: progress; }
/* ---- Ein Foto in der Blase ------------------------------------------ */
/* Die Höhe ist begrenzt, die Breite folgt dem Bild. Ein Hochformat
nähme sonst den halben Verlauf ein und schöbe alles darunter aus dem
Bild -- man scrollt dann durch ein Foto statt durch ein Gespräch. */
.chat-bild {
display: block;
width: 100%; /* die Hoechstbreite setzt das Skript */
margin: 0 0 6px;
border-radius: 12px;
overflow: hidden;
line-height: 0;
background: rgba(255, 255, 255, .04);
}
/* Die Groesse macht der Kasten (aspect-ratio + max-width, siehe
chat.js). Das Bild fuellt ihn nur aus. Stuende die Groesse hier am
Bild, waere sie erst bekannt, wenn das Bild da ist -- und genau das
war der Fehler, der den Verlauf um 323 px verschoben hat. */
.chat-bild img {
display: block;
width: 100%; height: 100%;
object-fit: contain;
}
/* Ohne bekannte Masse gibt es kein Verhaeltnis, an dem der Kasten
haengen koennte. Dann greift der alte Weg -- und der Zuhoerer auf
`load` in chat.js haelt den Bildlauf unten. */
.chat-bild:not([style*="aspect-ratio"]) img { height: auto; max-height: 340px; }
.chat-bild:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat-bild[data-kaputt="ja"] {
line-height: 1.5; padding: 12px 14px;
font-size: .84rem; color: var(--text-leise);
}
/* ---- Ein PDF als Karte ---------------------------------------------- */
.chat-datei {
display: flex; align-items: center; gap: 11px;
margin: 0 0 6px; padding: 10px 12px;
border: 1px solid rgba(150, 186, 220, .2);
border-radius: 12px;
background: rgba(255, 255, 255, .04);
color: inherit; text-decoration: none;
transition: border-color var(--tempo), background var(--tempo);
}
.chat-datei:hover {
border-color: rgba(150, 186, 220, .38);
background: rgba(255, 255, 255, .07);
}
.chat-datei:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat-datei__zeichen {
flex: none;
width: 38px; height: 38px; border-radius: 10px;
display: grid; place-items: center;
font-size: .72rem; font-weight: 800; letter-spacing: .04em;
color: #ff9aa2;
background: rgba(255, 154, 162, .12);
border: 1px solid rgba(255, 154, 162, .3);
}
.chat-datei__mitte { min-width: 0; display: grid; }
.chat-datei__name {
font-size: .86rem; font-weight: 600; color: var(--text);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-datei__mass { font-size: .74rem; color: var(--text-leise); }
/* ---- Die Ablagefläche beim Hineinziehen ------------------------------ */
.chat__ablage {
position: absolute; inset: 8px;
z-index: 6;
display: grid; place-items: center;
border: 2px dashed color-mix(in srgb, var(--akzent) 55%, transparent);
border-radius: 16px;
background: rgba(8, 12, 20, .82);
color: var(--text);
font-size: .95rem; font-weight: 650;
pointer-events: none; /* sonst frisst sie das drop-Ereignis */
}
/* ---- Zwischenstand statt Störung ------------------------------------ */
/* "wird geschickt …" ist keine Fehlermeldung. Rot ist hier das
Einzige, was Aufmerksamkeit verlangen darf -- wer es für
Zwischenstände mitbenutzt, macht es wertlos. */
.fehler[data-art="lauf"] { color: var(--text-leise); }
@media (prefers-reduced-motion: reduce) {
.chat__weg, .chat__anhang, .chat-datei { transition: none; }
}
@media (forced-colors: active) {
.chat-datei, .chat__ablage { border: 1px solid CanvasText; }
}
/* =====================================================================
KATEGORIE-KANÄLE UND ANGEHEFTETE ANKÜNDIGUNGEN (10.09.2026)
Kapitel 7.2 des Anforderungsdokuments: "Kategorie-Kanäle" und
"Ankündigungs-Funktion: Pin-Nachrichten von Owner/rechte Hand an
alle."
DER TON IST GEDÄMPFTES BERNSTEIN, nicht Signalgelb. Eine Ankündigung
steht dauerhaft oben im Bild – sie ist das Element, das am längsten
im Blick liegt, und genau deshalb darf es nicht das lauteste sein.
Auffallen soll sie durch ihre POSITION, nicht durch ihre Farbe.
===================================================================== */
.chat {
/* Bernstein, entsättigt. Auf dem dunklen Grund der Seite kommt es
als warmes Signal an, ohne zu blenden. */
--pin: #d9ae62;
}
/* ---- Ein Kanal in der Gesprächsliste -------------------------------- */
/* Die Raute statt einer Zahl oder Initiale: Ein Kanal hat keine feste
Größe (es kommen Leute dazu) und keinen Menschen dahinter. Eckiger
als ein Kreis, runder als eine Gruppe -- so sind die drei Arten auch
ohne Farbe auseinanderzuhalten. */
.chat-raum__zeichen[data-kanal="ja"] {
--r: var(--pin);
border-radius: 10px;
font-size: 1.05rem;
font-weight: 700;
}
/* ---- Die Pinnwand über dem Verlauf ---------------------------------- */
.chat-pins {
flex: none;
display: flex; flex-direction: column; gap: 6px;
padding: 8px 12px;
border-bottom: 1px solid var(--rand);
background: color-mix(in srgb, var(--pin) 6%, transparent);
}
/* Drei Aushänge sind das Höchste (PIN_MAX im Server). Selbst dann
bleibt die Wand niedrig genug, dass der Verlauf die Seite behält --
mehr als ein Drittel der Höhe darf sie nie nehmen. */
.chat-pin {
display: flex; align-items: stretch; gap: 8px;
border: 1px solid color-mix(in srgb, var(--pin) 26%, transparent);
border-radius: 10px;
background: rgba(255, 255, 255, .025);
}
.chat-pin__auf {
flex: 1; min-width: 0;
display: block; text-align: left;
appearance: none; border: 0; background: none;
padding: 7px 10px;
font: inherit; color: inherit; cursor: pointer;
border-radius: 10px 0 0 10px;
}
.chat-pin__auf:hover { background: rgba(255, 255, 255, .03); }
.chat-pin__auf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
.chat-pin__kopf {
display: flex; align-items: center; gap: 6px;
font-size: .72rem; line-height: 1.2;
}
.chat-pin__nadel { flex: none; width: 13px; height: 13px; color: var(--pin); }
.chat-pin__von { font-weight: 700; color: var(--pin); }
/* Wer angeheftet hat, steht daneben und nicht darunter: Es ist eine
Randnotiz, keine zweite Zeile. Am Handy fällt sie weg -- dort zählt
der Text der Ankündigung, nicht ihre Herkunft. */
/* .72rem und nicht .68 (10.09.2026, gefunden von pruef-css-klassen).
Unter 11,5 px wird Text auf einem Handy zur Zumutung -- und diese
Zeile steht dauerhaft im Bild. Sie soll leiser sein als der Text
daneben; das macht die FARBE, nicht die Groesse. */
.chat-pin__wer { color: var(--text-still); font-size: .72rem; }
.chat-pin__text {
display: block; margin-top: 2px;
font-size: .8rem; color: var(--text-leise);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-pin__los {
flex: none;
appearance: none; border: 0; border-left: 1px solid color-mix(in srgb, var(--pin) 20%, transparent);
background: none; padding: 0 10px;
font: inherit; font-size: .72rem;
color: var(--text-still); cursor: pointer;
border-radius: 0 10px 10px 0;
}
.chat-pin__los:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.chat-pin__los:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
@media (max-width: 560px) {
.chat-pin__wer { display: none; }
}
/* ---- Die angeheftete Nachricht im Verlauf --------------------------- */
/* Ein schmaler Streifen an der Blase, mehr nicht. Wer im Verlauf
zurückrollt, soll erkennen, dass genau DIESE Zeile oben hängt --
ohne dass sie sich wie eine andere Sorte Nachricht liest. */
.chat-nachricht[data-angeheftet="ja"] .chat-nachricht__blase {
box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pin) 70%, transparent);
}
/* Der Anheften-Knopf sieht aus wie "antworten" daneben -- dieselbe
Sorte Handgriff, dieselbe Zeile, dieselbe Lautstärke. */
/* „ANHEFTEN" GEHOERT ZUR SELBEN FAMILIE (25.09.2026).
Es war der fuenfte Handgriff unter der Blase -- und der einzige, der
nach dem Umbau noch unterstrichen dastand, weil er eine eigene
Klasse hat. Im Bildschirmfoto sah man genau das: vier ruhige Marken
und ein Link dazwischen.
Gelernt daran: Eine Familie erkennt man nicht am Aussehen, sondern
an der Aufzaehlung. Wer einen fuenften Knopf baut, muss ihn hier
eintragen -- deshalb stehen alle fuenf Namen jetzt an EINER Stelle
beieinander (siehe die gemeinsame Regel weiter oben). */
.chat-nachricht__pin-knopf {
/* Die Nadel steht in derselben Familie wie die vier daneben (siehe
die gemeinsame Zeichen-Regel weiter oben); hier steht nur ihr
eigenes Bild. Zwei Zustände, ein Zeichen: „anheften" und „lösen"
unterscheidet das WORT -- eine durchgestrichene Nadel wäre bei
13 px nicht mehr als ein Fleck. */
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 3.6h6'/><path d='M10.6 3.6v5.6L7.4 14.2h9.2L13.4 9.2V3.6'/><path d='M12 14.2v6.2'/></svg>");
display: inline-flex; align-items: center; gap: 5px;
appearance: none;
border: 1px solid transparent;
background: none;
padding: 3px 9px 3px 7px;
border-radius: 999px;
font: inherit; font-size: .72rem; font-weight: 600;
line-height: 1.5;
color: inherit; cursor: pointer;
text-decoration: none;
opacity: .72;
transition: opacity .16s ease, background-color .16s ease,
border-color .16s ease, color .16s ease;
}
.chat-nachricht__pin-knopf:hover {
opacity: 1; color: var(--pin);
background: color-mix(in srgb, var(--pin) 16%, transparent);
border-color: color-mix(in srgb, var(--pin) 34%, transparent);
}
.chat-nachricht__pin-knopf:focus-visible {
outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: 4px;
}
/* ---- Wer ist im Kanal ----------------------------------------------- */
/* Derselbe Knopf wie das Wegräumen, nur wird er beim Darüberfahren
nicht rot: Leute hinzuzunehmen ist keine gefährliche Handlung. */
.chat__leute { margin-left: auto; }
.chat__leute:hover {
color: var(--pin);
border-color: color-mix(in srgb, var(--pin) 45%, transparent);
}
/* ---- Die zwei Arten im Neu-Dialog ----------------------------------- */
.neu__art {
display: flex; gap: 6px;
margin: 0 0 9px;
padding: 4px;
border: 1px solid var(--rand); border-radius: 12px;
background: rgba(255, 255, 255, .02);
}
/* Die Erklaerung zum Umschalter (11.09.2026). Gedaempft und klein --
sie soll beim ERSTEN Mal gelesen werden und danach nicht im Weg sein.
Der Rand links fuehrt das Auge an beiden Zeilen entlang, ohne dass es
ein Kasten sein muss. */
.neu__erklaerung {
margin: 0 0 14px;
padding: 2px 0 2px 11px;
border-left: 2px solid color-mix(in srgb, var(--akzent) 34%, transparent);
font-size: .79rem; line-height: 1.55;
color: var(--text-still);
}
.neu__erklaerung p { margin: 0; }
.neu__erklaerung p + p { margin-top: 5px; }
.neu__erklaerung strong { color: var(--text-leise); font-weight: 650; }
.neu__erklaerung em { font-style: normal; color: var(--text-leise); }
.neu__art button {
flex: 1;
appearance: none; border: 0; border-radius: 9px;
padding: 8px 10px;
background: none;
font: inherit; font-size: .82rem; font-weight: 600;
color: var(--text-still); cursor: pointer;
transition: color var(--tempo), background var(--tempo);
}
.neu__art button[data-an="ja"] {
background: color-mix(in srgb, var(--akzent) 14%, transparent);
color: var(--text);
}
.neu__art button:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.neu__hinweis {
margin: 6px 0 0;
font-size: .78rem; color: var(--text-still);
}
@media (prefers-reduced-motion: reduce) {
.chat-pin__auf, .chat-pin__los, .neu__art button { transition: none; }
}
/* =====================================================================
TELEFONIEREN (18.09.2026)
Filipe: „kann man machen dass die modis, rechte hand und ich auch
telefonieren können im chat?"
DER KASTEN SCHWEBT UNTEN RECHTS und nimmt dem Gespräch nichts weg.
Ein Anruf ersetzt den Chat nicht -- man schreibt oft WÄHREND man
spricht („schick mir mal den Link"). Ein Vollbild-Anruf hätte genau
das unmöglich gemacht.
Am Handy geht er über die volle Breite: Dort ist daneben ohnehin
kein Platz, und ein halber Kasten wäre nur im Weg.
===================================================================== */
.anruf {
position: fixed;
right: 18px; bottom: 18px;
z-index: 60;
width: min(340px, calc(100vw - 36px));
padding: 14px 16px;
border: 1px solid color-mix(in srgb, var(--gut, #79d1a2) 40%, var(--rand));
border-radius: 14px;
/* Undurchsichtig gemischt: Ein Anrufkasten, durch den das
Bühnenbild scheint, ist genau dann schlecht lesbar, wenn es
schnell gehen muss. */
background: color-mix(in srgb, var(--tinte) 92%, #ffffff 8%);
box-shadow: 0 18px 44px -20px rgba(0, 0, 0, .9);
}
.anruf__kopf {
display: flex; align-items: baseline; gap: 10px;
margin-bottom: 10px;
}
.anruf__lage {
font-size: .86rem; font-weight: 600;
color: color-mix(in srgb, var(--gut, #79d1a2) 30%, #ffffff);
}
.anruf__zeit {
margin-inline-start: auto;
font-size: .82rem; color: var(--text-still);
/* Gleiche Ziffernbreite -- sonst zappelt die Uhr bei jedem Wechsel. */
font-variant-numeric: tabular-nums;
}
.anruf__leute {
display: flex; flex-wrap: wrap; gap: 8px;
margin-bottom: 12px;
}
.anruf__bild {
width: 100%; max-width: 150px; aspect-ratio: 4 / 3;
border-radius: 10px;
background: #05070e;
object-fit: cover;
}
/* Das eigene Bild kleiner -- man schaut die anderen an, nicht sich. */
.anruf__bild--ich { max-width: 88px; }
.anruf__name { font-size: .8rem; color: var(--text-leise); }
/* =====================================================================
WER IST DRAN (20.09.2026)
Filipe: „die soll auch viel besser geiler und spezieller aussehen,
aber nicht so raushängen."
„Nicht raushängen" ist dabei die schärfere der beiden Vorgaben, und
sie steht hier zuerst: Der Kasten ist 340 px breit und liegt in der
Ecke. Alles darin muss mit dieser Breite auskommen — bei einem
Gruppenanruf mit drei Leuten genauso wie bei einem Gespräch zu
zweit. Deshalb ein Raster mit `auto-fit`, das misst statt zu
rechnen, und ein Name, der umbricht statt zu schieben.
Vorher stand hier je Person das Wort „Verbunden" — bei dreien
dreimal dasselbe Wort, ohne Namen.
===================================================================== */
.anruf__leute:has(.anruf__gesicht) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
gap: 10px;
justify-items: center;
}
.anruf__gesicht {
display: flex; flex-direction: column; align-items: center; gap: 5px;
min-width: 0; max-width: 100%;
text-align: center;
}
.anruf__kreis {
display: grid; place-items: center;
width: 46px; height: 46px;
border-radius: 50%;
border: 1px solid color-mix(in srgb, var(--gut, #79d1a2) 45%, var(--rand));
background: color-mix(in srgb, var(--gut, #79d1a2) 14%, #0b1018);
color: color-mix(in srgb, var(--gut, #79d1a2) 35%, #ffffff);
font-size: .95rem; font-weight: 700;
letter-spacing: .02em;
}
/* Der Name darf umbrechen und wird notfalls gekürzt -- er ist das
Einzige hier, dessen Länge wir nicht kennen. */
.anruf__gesicht .anruf__name {
max-width: 100%;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-weight: 600; color: var(--text);
}
.anruf__stand { font-size: .72rem; color: var(--text-still); }
/* ---- Es klingelt noch -------------------------------------------------
EIN RUHIGER PULS, kein Blinken. Augenschonend ist hier keine
Geschmacksfrage: Der Kasten steht am Bildrand und läuft, solange das
Gespräch läuft. Ein Blinken dort wäre nach zwei Minuten
unerträglich. Deshalb ein weicher Ring, der nach außen ausläuft --
dieselbe Bewegung wie beim Punkt in der Kopfzeile. */
.anruf__gesicht[data-lage="wartet"] .anruf__kreis {
border-color: color-mix(in srgb, var(--akzent) 45%, var(--rand));
background: color-mix(in srgb, var(--akzent) 12%, #0b1018);
color: color-mix(in srgb, var(--akzent) 30%, #ffffff);
position: relative;
}
.anruf__gesicht[data-lage="wartet"] .anruf__kreis::after {
content: "";
position: absolute; inset: -5px;
border-radius: 50%;
border: 1px solid color-mix(in srgb, var(--akzent) 40%, transparent);
animation: anruf-ring 2.4s ease-out infinite;
}
@keyframes anruf-ring {
0% { transform: scale(.88); opacity: .75; }
70% { transform: scale(1.18); opacity: 0; }
100% { transform: scale(1.18); opacity: 0; }
}
/* Während es klingelt ist das Gesicht größer -- es ist in diesem
Moment das Einzige, worauf man schaut. */
.anruf__gesicht[data-lage="wartet"] .anruf__kreis { width: 58px; height: 58px; font-size: 1.1rem; }
@media (prefers-reduced-motion: reduce) {
.anruf__gesicht[data-lage="wartet"] .anruf__kreis::after { animation: none; opacity: .5; }
}
@media (forced-colors: active) {
.anruf__kreis { border: 2px solid CanvasText; }
.anruf__gesicht[data-lage="wartet"] .anruf__kreis { border-color: Highlight; }
.anruf__gesicht[data-lage="wartet"] .anruf__kreis::after { display: none; }
}
.anruf__knoepfe { display: flex; flex-wrap: wrap; gap: 8px; }
.anruf__knopf {
min-height: 40px;
padding: 8px 14px;
border: 1px solid var(--rand-hell);
border-radius: 999px;
background: color-mix(in srgb, var(--tinte) 88%, #ffffff 12%);
color: var(--text);
font: inherit; font-size: .84rem; font-weight: 600;
cursor: pointer;
}
.anruf__knopf:hover { border-color: var(--akzent); }
.anruf__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Aus heißt aus -- und zwar sichtbar. Ein stummes Mikrofon, das
aussieht wie ein offenes, ist der Grund, warum Leute in Konferenzen
ins Leere reden. */
.anruf__knopf[aria-pressed="false"] {
border-style: dashed;
color: var(--text-still);
}
.anruf__knopf--auf {
margin-inline-start: auto;
border-color: color-mix(in srgb, var(--warn, #ff9aa2) 55%, var(--rand));
color: color-mix(in srgb, var(--warn, #ff9aa2) 40%, #ffffff);
}
.anruf__knopf--auf:hover { border-color: var(--warn, #ff9aa2); }
/* Das Fragezeichen neben den Anrufknöpfen. Gleiche Größe wie sie,
damit die Reihe ruhig bleibt -- aber blass, weil es kein Angebot
ist, sondern ein Ausweg. */
.chat__probe {
display: inline-flex; align-items: center; justify-content: center;
color: var(--text-still);
font-weight: 700; font-size: .9rem;
text-decoration: none;
}
.chat__probe:hover { color: var(--text-leise); }
/* Der Weg zur Anruf-Probe. Bewusst unscheinbar: Wer gerade
telefoniert, soll ihn übersehen -- wer ratlos vor einem stillen
Kasten sitzt, findet ihn. In der installierten App ist er der
EINZIGE Weg dorthin, weil es dort keine Adresszeile gibt. */
.anruf__probe {
display: inline-block;
margin-top: 10px;
font-size: .78rem;
color: var(--text-still);
text-decoration: underline;
text-decoration-color: var(--rand-hell);
text-underline-offset: 3px;
}
.anruf__probe:hover { color: var(--text-leise); }
/* Wohin der Ton geht -- nur auf Rechnern, wo der Browser das wirklich
umstellen kann. Schmal gehalten: Geraetenamen wie „Kopfhoerer
(RODECaster Duo Main)" wuerden die Knopfreihe sonst sprengen. */
.anruf__ausgabe {
max-width: 11rem;
min-height: 40px;
padding: 6px 10px;
border: 1px solid var(--rand-hell);
border-radius: 999px;
background: color-mix(in srgb, var(--tinte) 88%, #ffffff 12%);
color: var(--text);
font: inherit; font-size: .8rem;
text-overflow: ellipsis;
}
.anruf__ausgabe:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* ---------------------------------------------------------------------
ES KLINGELT
MITTIG UND ÜBER ALLEM. Ein Anruf, den man übersieht, ist ein
verpasster -- das ist der eine Fall, in dem etwas den Bildschirm
unterbrechen darf.
--------------------------------------------------------------------- */
.anruf-klingelt {
position: fixed;
left: 50%; top: 24px;
transform: translateX(-50%);
z-index: 70;
width: min(380px, calc(100vw - 32px));
padding: 16px 18px;
border: 1px solid color-mix(in srgb, var(--akzent) 50%, var(--rand));
border-radius: 14px;
background: color-mix(in srgb, var(--tinte) 94%, #ffffff 6%);
box-shadow: 0 22px 50px -18px rgba(0, 0, 0, .95);
text-align: center;
}
.anruf-klingelt__wer {
margin: 0 0 12px;
font-size: .96rem; font-weight: 700;
}
.anruf-klingelt__knoepfe { display: flex; gap: 10px; justify-content: center; }
.anruf-klingelt__ja, .anruf-klingelt__nein {
min-height: 44px;
padding: 10px 20px;
border-radius: 999px;
font: inherit; font-size: .88rem; font-weight: 700;
cursor: pointer;
}
.anruf-klingelt__ja {
border: 1px solid color-mix(in srgb, var(--gut, #79d1a2) 60%, transparent);
background: color-mix(in srgb, var(--gut, #79d1a2) 18%, var(--tinte));
color: #ffffff;
}
.anruf-klingelt__nein {
border: 1px solid var(--rand-hell);
background: none;
color: var(--text-leise);
}
.anruf-klingelt__ja:focus-visible,
.anruf-klingelt__nein:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Die zwei Knöpfe im Kopf des Gesprächs. Gebaut wie die Nachbarn
daneben, damit die Zeile eine Sprache spricht. */
.chat__anruf svg {
width: 18px; height: 18px;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.chat__anruf:hover { color: color-mix(in srgb, var(--gut, #79d1a2) 40%, #ffffff); }
@media (max-width: 560px) {
.anruf {
right: 8px; left: 8px; bottom: 8px;
width: auto;
}
}
@media (prefers-reduced-motion: reduce) {
.anruf, .anruf-klingelt { transition: none; }
}
/* =====================================================================
DIE NACHTRUHE DES TREFFS (19.09.2026)
Filipe: „nach mitternacht bis morgens 6 uhr keiner schreiben kann
damit auch die privatsphäre berücksichtig wird über nacht."
---------------------------------------------------------------------
KEIN ROT, UND ZWAR AUS EINEM GRUND
Der schlafende Chat ist keine Störung und kein Fehler – er ist so
gewollt. Eine Warnfarbe würde sagen „hier stimmt etwas nicht", und
das ist das Gegenteil der Botschaft. Sie wäre außerdem die dritte
Signalfarbe auf dieser Seite, und ab der dritten bedeutet keine mehr
etwas.
Stattdessen ein tiefes, ruhiges Blau – die Farbe, die jedes
Betriebssystem für „Nicht stören" benutzt. Wer es sieht, weiß es
ohne zu lesen.
ZWEI ZUSTÄNDE, zwei Helligkeiten:
zu das Band steht ruhig da, der Mond gefüllt
gleich ein Hauch wärmer – es ist noch offen, aber nicht lange
AUGENSCHONEND heißt hier auch: keine Animation. Ein pulsierendes
Band über dem Eingabefeld, stundenlang, wäre genau die Art von
Unruhe, die diese Seite nicht haben soll.
===================================================================== */
.chat__nachtruhe {
display: flex; align-items: center; gap: 10px;
margin: 0; padding: 9px 14px;
border-top: 1px solid var(--rand);
background: color-mix(in srgb, var(--tinte) 88%, #2b4a7a 12%);
font-size: .82rem; line-height: 1.5;
color: var(--text-leise);
}
.chat__nachtruhe[data-lage="gleich"] {
background: color-mix(in srgb, var(--tinte) 90%, #7a5a2b 10%);
}
.chat__nachtruhe-zeichen {
flex: none; display: grid; place-items: center;
width: 22px; height: 22px;
}
.chat__nachtruhe-zeichen svg {
width: 17px; height: 17px;
fill: #9db4d8; stroke: none;
}
.chat__nachtruhe[data-lage="gleich"] .chat__nachtruhe-zeichen svg { fill: #d8a76a; }
.chat__nachtruhe-text { min-width: 0; }
/* Das Eingabefeld, wenn der Treff schläft. Sichtbar aus, nicht weg:
Ein verschwundenes Feld sieht aus wie ein Fehler, ein ausgegrautes
wie eine Entscheidung. */
.chat__eingabe #text:disabled,
.chat__eingabe .chat__senden:disabled {
opacity: .5;
cursor: not-allowed;
}
@media (forced-colors: active) {
.chat__nachtruhe { border: 1px solid CanvasText; }
.chat__nachtruhe-zeichen svg { fill: CanvasText; }
}
/* =====================================================================
DER ANRUFKASTEN, NEU GEBAUT — 19.09.2026
Filipe: „das soll viel besser und geiler aussehen bitte."
Vorher: vier gleich aussehende Pillen nebeneinander („Mikro an",
„Lautsprecher an", „Kamera an", „Auflegen"), darunter eine
Geräteauswahl, die das breiteste Element des Kastens war. Kein
Name, keine Ordnung, und der einzige Knopf mit Folgen sah aus wie
die anderen drei.
Jetzt drei Ebenen, und jede hat eine Aufgabe:
OBEN wen habe ich am Apparat, was macht die Verbindung gerade,
wie lange läuft es schon
MITTE die Gegenstellen (Ton oder Bild)
UNTEN zwei Schalter links, Auflegen rechts — als einziges mit
Farbe
AUGENSCHONEND BLEIBT AUGENSCHONEND: kein Neon, keine harte Kante,
der Puls ist eine ruhige Atembewegung und steht still, sobald
`prefers-reduced-motion` gesetzt ist.
===================================================================== */
/* ---- Oben: wer, was, wie lange ------------------------------------- */
.anruf__kopf {
display: flex; align-items: center; gap: 10px;
padding-bottom: 12px; margin-bottom: 12px;
border-bottom: 1px solid var(--rand);
}
.anruf__kopftext { flex: 1; min-width: 0; display: grid; gap: 1px; }
.anruf__wer {
font-size: 1rem; font-weight: 680; color: var(--text);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.anruf__lage { font-size: .8rem; color: var(--text-still); }
.anruf__zeit {
font-size: .9rem; color: var(--text-leise);
font-variant-numeric: tabular-nums;
}
/* Der Puls. Er ersetzt das, was vorher gar nichts sagte: Solange die
Verbindung noch nicht steht, atmet er; steht sie, wird er ruhig. */
.anruf__puls {
flex: none; width: 10px; height: 10px; border-radius: 999px;
background: color-mix(in srgb, var(--gut, #79d1a2) 75%, transparent);
box-shadow: 0 0 0 0 color-mix(in srgb, var(--gut, #79d1a2) 45%, transparent);
animation: anruf-puls 2s ease-out infinite;
}
.anruf[data-steht="ja"] .anruf__puls { animation: none; }
@keyframes anruf-puls {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--gut, #79d1a2) 40%, transparent); }
70% { box-shadow: 0 0 0 9px rgba(0, 0, 0, 0); }
100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) { .anruf__puls { animation: none; } }
/* ---- Unten: die Knopfreihe ----------------------------------------- */
.anruf__knoepfe {
display: flex; align-items: center; gap: 8px;
margin-top: 12px;
}
/* Die Schalter. Zeichen oben, Wort darunter — und der Zustand steckt
im Zeichen, nicht in der Aufschrift. Ein Knopf, auf dem „Mikro an"
steht, ist zweideutig; ein durchgestrichenes Mikrofon ist es nicht. */
.anruf__schalter {
display: grid; justify-items: center; gap: 3px;
min-width: 56px; min-height: 52px;
padding: 6px 8px;
border: 1px solid var(--rand); border-radius: var(--radius-klein);
background: rgba(255, 255, 255, .03);
color: var(--text-leise);
cursor: pointer;
transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.anruf__schalter:hover,
.anruf__schalter:focus-visible {
background: rgba(255, 255, 255, .07); color: var(--text);
}
.anruf__schalter-text { font-size: .68rem; letter-spacing: .02em; }
.anruf__zeichen {
width: 20px; height: 20px;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
/* Der Strich liegt immer im Zeichen und wird nur sichtbar, wenn der
Schalter aus ist — so muss das Zeichen nicht ausgetauscht werden. */
.anruf__strich { opacity: 0; transition: opacity .15s ease; }
.anruf__schalter[aria-pressed="false"] {
color: var(--text-still);
border-color: color-mix(in srgb, var(--warn, #d8a76a) 38%, var(--rand));
background: color-mix(in srgb, var(--warn, #d8a76a) 9%, transparent);
}
.anruf__schalter[aria-pressed="false"] .anruf__strich { opacity: 1; }
/* Die drei Punkte: alles, was man einmal im Jahr braucht. */
.anruf__mehr {
display: grid; place-items: center;
width: 38px; min-height: 52px;
border: 1px solid transparent; border-radius: var(--radius-klein);
background: none; color: var(--text-still); cursor: pointer;
}
.anruf__mehr:hover, .anruf__mehr:focus-visible {
color: var(--text-leise); border-color: var(--rand);
}
.anruf__mehr svg { width: 18px; height: 18px; fill: currentColor; }
/* Auflegen. Der einzige Knopf mit Farbe — weil er der einzige ist,
der etwas beendet. Ganz rechts, immer an derselben Stelle. */
.anruf__auf {
margin-inline-start: auto;
display: inline-flex; align-items: center; gap: 7px;
min-height: 52px; padding: 0 16px;
border: 1px solid color-mix(in srgb, #c96a6a 55%, transparent);
border-radius: var(--radius-klein);
background: color-mix(in srgb, #c96a6a 18%, transparent);
color: #f0c9c9; font-size: .88rem; font-weight: 640;
cursor: pointer;
transition: background .15s ease;
}
.anruf__auf:hover, .anruf__auf:focus-visible {
background: color-mix(in srgb, #c96a6a 28%, transparent);
}
/* Der Hörer zeigt nach unten — aufgelegt. */
.anruf__auf .anruf__zeichen {
width: 18px; height: 18px; fill: currentColor; stroke: none;
transform: rotate(133deg);
}
/* ---- Die Geräteauswahl, versteckt bis man sie sucht ---------------- */
.anruf__mehrzeile {
margin-top: 10px; padding-top: 10px;
border-top: 1px solid var(--rand);
display: grid; gap: 4px;
}
.anruf__mehrschild {
font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
color: var(--text-still);
}
.anruf__ausgabe { width: 100%; }
/* Auf schmalen Bildschirmen dürfen die Wörter unter den Zeichen weg —
die Zeichen bleiben, und der Zustand steckt ohnehin in ihnen. */
@media (max-width: 380px) {
.anruf__schalter { min-width: 48px; }
.anruf__schalter-text { display: none; }
.anruf__auf span { display: none; }
.anruf__auf { padding: 0 14px; }
}
/* Im Kontrastmodus trägt keine Farbe. Dann muss die Kante sagen, was
aus ist — sonst sehen an und aus gleich aus. */
@media (forced-colors: active) {
.anruf__schalter[aria-pressed="false"] { border-style: dashed; border-width: 2px; }
.anruf__auf { border-width: 2px; }
}
/* ---- Unterwegs und gescheitert -------------------------------------
Gemessen am 20.09.2026: BEIDE Zustände waren unsichtbar.
`markiereAlsGescheitert` setzte das Merkmal und zeichnete neu --
gelesen hat es niemand, weder Skript noch CSS. Eine gescheiterte
Nachricht sah genauso aus wie eine zugestellte.
Daneben stand im Code: „NICHT STILL VERSCHWINDEN LASSEN. Wer etwas
schreibt und es sieht, glaubt, es sei angekommen." Genau das ist
trotzdem passiert. Ein Kommentar, der eine Absicht beschreibt,
erfüllt sie nicht.
Unterwegs = blass, es passiert noch etwas.
Gescheitert = eine sichtbare Kante und ein Knopf daneben. Nicht
knallrot: Es ist ein Zustand, kein Alarm -- und meistens ist nur
das Netz kurz weg. */
.chat-nachricht[data-unterwegs="ja"] .chat-nachricht__blase { opacity: .62; }
.chat-nachricht[data-gescheitert="ja"] .chat-nachricht__blase {
border: 1px solid color-mix(in srgb, var(--warn) 52%, transparent);
background: color-mix(in srgb, var(--warn) 9%, transparent);
}
.chat-nachricht__nochmal {
display: block;
margin: 8px 0 0;
/* 44, weil man das hier mit dem Daumen trifft -- und zwar in dem
Moment, in dem man ohnehin schon genervt ist. */
min-height: 44px; padding: 0 14px;
font: inherit; font-size: .82rem; font-weight: 650;
color: var(--text);
background: transparent;
border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--rand));
border-radius: var(--radius, 10px);
cursor: pointer;
}
.chat-nachricht__nochmal:hover:not(:disabled) { border-color: var(--warn); }
.chat-nachricht__nochmal:disabled { opacity: .6; cursor: default; }
@media (forced-colors: active) {
.chat-nachricht[data-gescheitert="ja"] .chat-nachricht__blase {
border: 2px solid CanvasText;
}
}
/* =====================================================================
"@" IM CHAT (20.09.2026)
Filipe: "ich will das man die leute mit @ markieren kann im chat."
===================================================================== */
/* ---- DER NAME IM SATZ ----------------------------------------------
GEDECKT, NICHT GRELL. Ein markierter Name steht mitten in einem
Absatz, den man liest -- er soll auffallen, ohne den Satz zu
zerreissen. Deshalb eine leichte Unterlage und etwas mehr Gewicht
statt einer Signalfarbe: Wer in einem langen Gespraech blaettert,
sieht sonst nur noch die Markierungen. */
.chat-erwaehnung {
color: var(--akzent);
font-weight: 640;
padding: 0 3px;
margin: 0 -1px;
border-radius: 5px;
background: color-mix(in srgb, var(--akzent) 13%, transparent);
}
/* BIN ICH GEMEINT, WIRD ES DEUTLICHER. Das ist der ganze Zweck: In
einem Raum mit acht Leuten soll der eigene Name aus dem Absatz
herausspringen. Der Rahmen kommt dazu, damit es nicht NUR die Farbe
ist -- wer Farben schlecht unterscheidet, sieht trotzdem eine
Umrandung. */
.chat-erwaehnung[data-ich="ja"] {
background: color-mix(in srgb, var(--akzent) 26%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--akzent) 45%, transparent);
color: var(--text);
}
/* ---- "@RUDEL" -- ALLE AUF EINMAL (23.09.2026) ------------------------
Filipe: „dan will ich auch dass nur die modis, rechte hand, linke
hand und dogfather, alle auch auf einmal markieren können im chat
mit einem, @rudel ,dann sollen alle eine benarichtigung bekommen."
ES MUSS ANDERS AUSSEHEN ALS DER EIGENE NAME. „Alle sind gemeint"
ist etwas anderes als „du bist gemeint" -- sähen beide gleich aus,
verlöre das zweite genau die Wirkung, für die es da ist.
ABER NICHT ÜBER EINE FESTE FARBE, und das ist hier der Kern:
Eine Nachricht liegt in der Blase, deren Farbe ihr Absender
AUSGESUCHT hat -- babyblau, veilchen, tinte, siebzehn Möglichkeiten.
Eine feste Farbe darauf ist eine Wette. Genau die habe ich am
22.09.2026 beim Löschknopf verloren: 1,91:1 auf Babyblau, gemessen,
nachdem es schon live war.
`--blase-text` ist die Schriftfarbe, die schriftFuer() in
workspace-chat.js FÜR DIESE BLASE ausgerechnet hat, mit mindestens
7:1 gegen ihren Hintergrund. Wer sie nimmt, kann nicht unlesbar
werden -- auf keiner der siebzehn Farben und auf keiner, die morgen
dazukommt.
Unterschieden wird deshalb über FORM statt über Farbton: kräftigere
Tönung, geschlossene Kante, fetter, und ein Zeichen davor. Das
überlebt auch einen Farbmodus, in dem Tönungen wegfallen.
AUGENSCHONEND: eine Tönung und eine Kante, kein Leuchten, keine
Bewegung. Ein Ruf ans ganze Team wird oft geschrieben, wenn es eilt
-- der Bildschirm muss deswegen nicht blinken. */
.chat-erwaehnung[data-rudel="ja"] {
color: var(--blase-text, var(--text));
font-weight: 700;
background: color-mix(in srgb, var(--blase-text, var(--text)) 20%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--blase-text, var(--text)) 52%, transparent);
}
/* Das Zeichen davor trägt die Unterscheidung mit, falls jemand
Tönungen gar nicht sieht. Es steht in derselben Farbe wie die
Schrift -- eine zweite Farbe wäre dieselbe Wette wie oben. */
.chat-erwaehnung[data-rudel="ja"]::before {
content: "\25C9\A0";
opacity: .72;
}
/* ---- IN DER AUSWAHLLISTE --------------------------------------------
Hier DARF es einen eigenen Farbton haben, und der Unterschied zum
Absatz darüber ist kein Geschmack: Die Liste liegt auf der Fläche
des Hauses, deren Farbe feststeht. Eine Blase liegt auf einer Farbe,
die ihr Absender aussucht. Was auf einem bekannten Grund gerechnet
werden kann, muss auf einem unbekannten abgeleitet werden. */
.erwaehn-liste__eintrag[data-rudel="ja"] .erwaehn-liste__zeichen {
background: color-mix(in srgb, var(--rudel-farbe, #f0c987) 20%, transparent);
color: var(--rudel-farbe, #f0c987);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rudel-farbe, #f0c987) 45%, transparent);
}
.erwaehn-liste__eintrag[data-rudel="ja"] .erwaehn-liste__rolle {
color: color-mix(in srgb, var(--rudel-farbe, #f0c987) 78%, #ffffff);
letter-spacing: .04em;
}
/* ---- DAS ZEICHEN IN DER GESPRÄCHSLISTE ------------------------------ */
.chat-raum__erwaehnt {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
width: 22px; height: 22px;
border-radius: 50%;
font-size: .82rem; font-weight: 800; line-height: 1;
color: var(--akzent);
background: color-mix(in srgb, var(--akzent) 18%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--akzent) 40%, transparent);
}
/* ---- DIE AUSWAHL BEIM TIPPEN ---------------------------------------
ÜBER der Schreibzeile, linksbündig: Das "@" wird links getippt, und
eine Liste, die woanders aufgeht als dort, wo man schreibt, sucht man
beim ersten Mal.
Dieselbe Verankerung wie bei der Emoji-Tafel (`bottom: 100%`), damit
beide sich gleich verhalten -- nur die Seite ist eine andere. */
.erwaehn-liste {
position: absolute;
left: 14px; right: auto; bottom: calc(100% - 6px);
z-index: 6;
min-width: min(18rem, calc(100vw - 32px));
max-width: calc(100vw - 32px);
/* MEHR ALS SECHS EINTRÄGE WERDEN GEROLLT statt die halbe Seite zu
verdecken. Acht ist die Obergrenze im Skript; sechs passen ohne
Rollen auf ein Handy. */
max-height: 17rem; overflow-y: auto;
display: flex; flex-direction: column; gap: 2px;
padding: 6px;
border-radius: 14px;
background: rgba(8, 12, 20, .97);
border: 1px solid rgba(150, 186, 220, .2);
box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .9);
}
.erwaehn-liste__eintrag {
appearance: none; border: 0; background: none;
display: flex; align-items: center; gap: 10px;
/* 44 px, wie jedes Berührziel in diesem Haus. Hier besonders: Wer
danebentippt, spricht den Falschen an -- und merkt es erst, wenn
die Nachricht schon draussen ist. */
width: 100%; min-height: 44px;
padding: 6px 10px;
border-radius: var(--radius-klein);
color: var(--text);
font: inherit; font-size: .92rem;
text-align: left; cursor: pointer;
transition: background var(--tempo);
}
.erwaehn-liste__eintrag:hover { background: rgba(255, 255, 255, .08); }
/* VORGEMERKT heisst: Enter nimmt diesen. Das muss man sehen, sonst
waehlt man blind. */
.erwaehn-liste__eintrag[data-wahl="ja"] {
background: color-mix(in srgb, var(--akzent) 20%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--akzent) 42%, transparent);
}
.erwaehn-liste__eintrag:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
.erwaehn-liste__zeichen {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
width: 28px; height: 28px; border-radius: 50%;
font-size: .72rem; font-weight: 700; line-height: 1;
background: rgba(255, 255, 255, .08);
color: var(--text-leise);
}
.erwaehn-liste__name { flex: 1 1 auto; font-weight: 600; }
.erwaehn-liste__rolle {
flex: none;
font-size: .72rem; color: var(--text-still);
text-transform: uppercase; letter-spacing: .06em;
}
/* ---- KONTRASTMODUS --------------------------------------------------
Dort gelten die Farben des Systems, und `color-mix` fällt weg: Eine
Markierung, die nur aus einer Tönung besteht, verschwindet komplett.
Deshalb hier ein echter Rahmen -- er überlebt jeden Farbmodus. */
@media (forced-colors: active) {
.chat-erwaehnung,
.chat-erwaehnung[data-ich="ja"],
.chat-erwaehnung[data-rudel="ja"] { border: 1px solid CanvasText; }
.erwaehn-liste__eintrag[data-rudel="ja"] .erwaehn-liste__zeichen {
border: 1px solid CanvasText;
}
.chat-raum__erwaehnt { border: 1px solid CanvasText; }
.erwaehn-liste__eintrag[data-wahl="ja"] { border: 2px solid Highlight; }
}
/* ---- „Du hörst noch nichts" (20.09.2026) ----------------------------
Filipe: „es soll ohne lautsprecher anfangen das gespräch und nur wenn
man drauf klickt soll es laut werden."
Wörtlich umgesetzt — und deshalb braucht es diesen Balken. Ein
Gespräch, in dem man nichts hört und nicht weiß warum, ist die
nächste Sackgasse. Er steht zwischen Kopfzeile und Gesprächsteilnehmern,
also genau dort, wohin man zuerst schaut.
GEDÄMPFT, NICHT ALARMROT. Es ist kein Fehler, sondern ein Zustand,
den man selbst gewählt bekommt — und Alarmfarben für Normalzustände
sind der schnellste Weg, dass man Alarmfarben nicht mehr ernst
nimmt. Ein ruhiges Bernstein sagt „da ist etwas", ohne zu schreien. */
.anruf__stumm {
appearance: none;
display: flex; align-items: center; gap: 10px;
width: 100%; min-height: 44px;
margin: 0 0 10px;
padding: 9px 12px;
border: 1px solid color-mix(in srgb, #f0b429 42%, transparent);
border-radius: var(--radius-klein);
background: color-mix(in srgb, #f0b429 12%, transparent);
color: var(--text);
font: inherit; font-size: .88rem; font-weight: 600;
text-align: left; cursor: pointer;
transition: background var(--tempo), border-color var(--tempo);
}
.anruf__stumm:hover {
background: color-mix(in srgb, #f0b429 20%, transparent);
border-color: color-mix(in srgb, #f0b429 62%, transparent);
}
.anruf__stumm:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.anruf__stumm svg {
flex: none; width: 20px; height: 20px;
fill: none; stroke: #f0b429; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
/* Ein ruhiges Pulsieren, damit er im Augenwinkel auffällt -- und
nichts davon für jemanden, der weniger Bewegung eingestellt hat.
Das ist keine Deko: Wer den Balken übersieht, hört sein Gespräch
nicht. */
@media (prefers-reduced-motion: no-preference) {
.anruf__stumm { animation: stumm-atmen 2.6s ease-in-out infinite; }
@keyframes stumm-atmen {
0%, 100% { border-color: color-mix(in srgb, #f0b429 42%, transparent); }
50% { border-color: color-mix(in srgb, #f0b429 78%, transparent); }
}
}
@media (forced-colors: active) {
.anruf__stumm { border: 2px solid CanvasText; animation: none; }
}
/* =====================================================================
MEINE KACHEL (20.09.2026)
Filipe: „jeder account soll seine kachel personalisieren können."
Der Knopf ist ein FARBFLECK, kein Wort. Er zeigt, was eingestellt
ist — ein Knopf mit der Aufschrift „Kachel" müsste erst geöffnet
werden, damit man sieht, was gerade gilt.
===================================================================== */
/* RUND STATT ECKIG (24.09.2026).
Auf Filipes Bildschirmfoto stand hier ein blaues Quadrat mit
weichen Ecken — es sah aus wie ein Bauteil, das noch niemand
gestaltet hat, und nicht wie „so sehen deine Nachrichten aus".
Ein Kreis sagt es besser: Es ist die Farbe EINER PERSON, und
Personen sind in diesem Haus überall rund (Gesicht in der Liste, im
Verlauf, in der Kopfleiste). Der Ring darum ist derselbe wie am
Gesicht — man erkennt die Verwandtschaft, ohne sie zu lernen. */
/* Er zeigt die eigene Kachelfarbe. Vorher war das ein farbiger Fleck
mit einem Ring -- im Bildschirmfoto ein blauer Punkt, dem man nicht
ansah, dass er ein Knopf ist. Jetzt sitzt die Probe in einer
gefassten Mulde: Licht oben, Schatten innen, ein feiner Saum in der
Farbe selbst. Man sieht, dass etwas DRIN liegt. */
.chat__kachelknopf {
flex: 0 0 auto;
margin-left: auto;
width: 34px; height: 34px;
padding: 3px;
border: 1px solid rgba(255, 255, 255, .1);
border-radius: 50%;
background: linear-gradient(180deg,
rgba(0, 0, 0, .4) 0%, rgba(255, 255, 255, .04) 100%);
box-shadow:
inset 0 2px 4px -2px rgba(0, 0, 0, .8),
0 1px 0 rgba(255, 255, 255, .06);
cursor: pointer;
display: inline-flex; align-items: center; justify-content: center;
transition: border-color .16s ease, box-shadow .16s ease;
}
/* AM FINGER GROESSER (20.09.2026). Gemeldet von pruef-tippziele:
30x30 ist mit der Maus bequem und mit dem Daumen zu klein -- die
Grenze im Haus sind 44px. Angehoben wird NUR auf Fingergeraeten,
sonst stuende der Knopf am Rechner unnoetig gross neben einer Zeile,
die selbst nur 30 hoch ist. Das Sichtbare (Rahmen, Farbprobe) bleibt
klein; gewachsen ist die Flaeche, die den Finger annimmt. */
@media (pointer: coarse) {
.chat__kachelknopf { min-width: 44px; min-height: 44px; }
/* DIE NADEL AM FINGER (25.09.2026). Am Rechner sind 36 px breit
genug -- mit der Maus zielt man genau, und jedes Pixel mehr nimmt
dem Namen daneben Platz weg. Am Daumen gilt die Hausgroesse: 44.
Dieselbe Abwaegung wie beim Farbknopf eine Zeile darueber. */
.chat-raum__pin { min-width: 44px; min-height: 44px; }
/* Die zwei Knoepfe der Aufnahmeleiste standen bei 40 px -- vier zu
wenig. Gebaut wurden sie in der Nacht zum 23.09.2026; gefunden hat
es der Rundgang am Morgen. In der Aufnahmeleiste ist Platz, also
braucht es hier keine Abwaegung: volle Hausgroesse. */
.tonleiste__weg,
.tonleiste__senden { min-width: 44px; min-height: 44px; }
/* DER SCHRIFTKNOPF AM FINGER (25.09.2026). 40x40 ist mit der Maus
bequem; am Daumen sind es vier Pixel zu wenig, und pruef-tippziele
hat es sofort gemeldet -- „1 ungedeckt: .chat__schriftknopf
(40h 40w)". Dieselbe Abwaegung wie bei den vier Werkzeugen daneben,
die dort schon so stehen. */
.chat__schriftknopf { min-width: 44px; min-height: 44px; }
/* UNSICHTBAR GROESSER, SICHTBAR KLEIN.
Die Abwaegung beim Knopf selbst stimmt: 44 px sichtbar wuerden die
halbe Kachel verdecken. Sie war aber nur halb zu Ende gedacht --
ein Ziel, das man nicht trifft, hilft auch niemandem.
Deshalb waechst nicht der Knopf, sondern seine TREFFERFLAECHE:
28 + 2x8 = 44 px. Man sieht weiter einen kleinen Kreis in der Ecke
und trifft ihn trotzdem mit dem Daumen.
NUR AM FINGER. Mit einer Maus zielt man genau; eine unsichtbare
Flaeche, die acht Pixel ueber den Knopf hinausragt, waere dort
keine Hilfe, sondern eine Falle -- man traefe ihn, ohne ihn
anvisiert zu haben. */
.gif-kachel__weg::after {
content: ""; position: absolute; inset: -8px;
}
}
.chat__kachelknopf:hover {
border-color: var(--akzent);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--akzent) 14%, transparent);
}
.chat__kachelknopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* =====================================================================
AUS DEM FLECK WIRD EIN RING (25.09.2026)
Im Bildschirmfoto war das ein voller Kreis in der gewählten Farbe,
28 px groß, zwischen der Überschrift „Gespräche" und dem Knopf
„Neu". In dieser Umgebung liest man einen farbigen Vollkreis als
MARKE – als Zahl, die gerade keine Zahl hat. Genau daneben steht
ja auch eine (der Zähler der ungelesenen Nachrichten, gleiche
Größe, gleiche Form). Er meldet aber nichts, er ist ein SCHALTER.
Jetzt: ein Ring in der Farbe um einen dunklen Kern. Zwei Gründe,
und beide zählen mehr als der Geschmack:
1. DIESELBE SPRACHE WIE DIE GANZE SEITE. Farbe erscheint hier
überall als Kontur – die Kante an der Blase, die Schiene an
der offenen Zeile, der Saum am Zeichen. Eine gefüllte Scheibe
war der einzige Ort, an dem Farbe Fläche war.
2. EIN RING IST DIE FORM, in der jedes Zeichenprogramm eine
Farbwahl anbietet. Sie muss niemandem erklärt werden.
DAS SKRIPT BLEIBT UNBERÜHRT: Es setzt weiterhin nur `background`
auf den gewählten Ton. Der dunkle Kern liegt als `::after`
darüber – so bleibt die eine Zeile im Skript die eine Zeile im
Skript, und die Farbe ist trotzdem ein Ring.
`inset: 5px` auf 28 px ergibt einen Ring von 5 px Stärke. Dünner,
und ein dunkler Ton verschwindet gegen den dunklen Kern; dicker,
und es ist wieder ein Fleck. */
.chat__kachelknopf-probe {
display: block; position: relative;
width: 100%; height: 100%;
border-radius: 50%;
/* Eine feine Innenkante, damit ein sehr dunkler Ton nicht aussieht
wie ein Loch im Knopf. */
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}
.chat__kachelknopf-probe::after {
content: ""; position: absolute; inset: 5px;
border-radius: 50%;
background: rgba(8, 12, 19, .94);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .7);
}
/* „Neu" steht danach und schiebt sich nicht mehr selbst -- der
Farbfleck hat den auto-Rand übernommen. Zwei auto-Ränder
nebeneinander teilen sich den Platz und reißen die Knöpfe
auseinander; derselbe Fehler stand am 11.09. schon im Verlaufskopf. */
.chat__kopf #neu-oeffnen { flex: 0 0 auto; margin-left: 8px; }
.chat-kachelwahl__gitter {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(62px, 1fr));
gap: 8px;
margin: 14px 0 4px;
}
.chat-kachelwahl__ton {
position: relative;
min-height: 48px; /* am Finger treffbar */
border: 1px solid var(--rand);
border-radius: 12px;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
color: var(--text);
font: inherit; font-size: .84rem;
}
.chat-kachelwahl__wort { opacity: .9; }
.chat-kachelwahl__ton:hover { border-color: var(--rand-hell); }
.chat-kachelwahl__ton:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* DIE WAHL WIRD MIT EINEM HAKEN ANGEZEIGT, nicht nur mit einem
helleren Rahmen: Auf zwölf dunklen Feldern ist ein Rahmen mehr der
Unterschied, den man sucht — ein Haken ist der, den man sieht. */
.chat-kachelwahl__ton[aria-checked="true"] {
border-color: var(--akzent);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--akzent) 45%, transparent);
}
.chat-kachelwahl__ton[aria-checked="true"]::after {
content: "\2713";
position: absolute; top: 3px; right: 6px;
font-size: .8rem; font-weight: 700;
color: var(--akzent);
}
@media (forced-colors: active) {
.chat-kachelwahl__ton[aria-checked="true"] { border: 3px solid Highlight; }
.chat__kachelknopf { border: 1px solid CanvasText; }
/* Im Kontrastmodus gibt es keine Farbflächen -- dann sind die zwölf
Töne ununterscheidbar, und nur der Name trägt. Er steht ohnehin
im aria-label und im title. */
}
/* DIE REIHENFOLGE IN DER EINGABEZEILE (21.09.2026).
Drei Dinge liegen hier in einer umbrechenden Reihe, und die
Reihenfolge im HTML ist nicht die, die man sehen will: Die
Bueroklammer steht dort VOR dem Schreibfeld, die Gestaltungsleiste
kam danach. Beim ersten Versuch stand die Klammer deshalb allein in
der ersten Zeile und die Leiste darunter -- richtig gerechnet,
falsch gelesen.
`order` statt Umbauen: Die Reihenfolge im Quelltext bleibt die, die
ein Vorleseprogramm braucht (erst der Bezug, dann die Werkzeuge,
dann das Feld), und das Auge bekommt seine eigene.
-2 Antwortleiste worauf beziehe ich mich
-1 Gestaltung womit schreibe ich
0 Klammer, Feld, Emoji, Senden -- die eigentliche Zeile */
.chat__eingabe .antwort-leiste { order: -2; }
/* =====================================================================
DIE GESTALTUNGSLEISTE SITZT IN DER KONSOLE (25.09.2026)
Vorher: vier Buchstaben (F K U S) schwebten mittig ueber dem
Schreibfeld, ohne Flaeche, ohne Bezug. Man sah vier Zeichen und
nicht, wozu sie gehoeren -- im Bildschirmfoto war es die einzige
Stelle, an der etwas ohne Grund im Raum stand.
Jetzt eine Schaltergruppe links oben in der Konsole: eine eigene
kleine Flaeche mit Lichtkante, buendig mit dem Schreibfeld darunter.
Sie gehoert damit sichtbar zur Eingabe.
LINKS UND NICHT MITTIG: Sie gehoert zum Text, und der beginnt
links. Mittig stand sie ueber nichts. */
.chat__eingabe .textform {
/* DIE GANZE ZEILE BLEIBT SIE -- `flex: 1 0 100%` ist kein
Schoenheitswert, sondern die Sicherung von 23.09.2026: Ohne sie
nimmt die Leiste ihren Platz NEBEN dem Schreibfeld, und das
schrumpft dann auf Buchstabenbreite ("defi / niti / v"). Beim
ersten Anlauf heute habe ich genau das gemacht und die Konsole in
drei Zeilen zerlegt.
STATT EINER PLATTE EIN STREIFEN: Die Gruppe steht linksbuendig
ueber dem Schreibfeld, getrennt durch eine Haarlinie. Eine eigene
Flaeche haette ueber die ganze Breite gehen muessen -- und das
waere ein Balken ueber nichts. */
order: -1; flex: 1 0 100%;
justify-content: flex-start;
margin: 0 0 9px; padding: 0 0 9px;
/* 2 UND NICHT 4 (nachgemessen 25.09.2026). Vier Knoepfe zu je
44 px Mindestbreite haben drei Abstaende dazwischen -- aus 4
statt 2 Pixeln werden also SECHS Pixel mehr, die die schmalste
Stelle der Zeile braucht. Auf 390 px hat das gereicht, um
"Senden" unter das Schreibfeld zu schieben (gemessen y 844 statt
820). Sechs Pixel. Genau deshalb wird an dieser Zeile gemessen
und nicht geschaetzt; sie ist seit dem 23.09. auf den Pixel
voll. */
gap: 2px;
border: 0; border-bottom: 1px solid rgba(255, 255, 255, .07);
border-radius: 0; background: none; box-shadow: none;
}
/* Die vier Buchstaben werden Schalter: eine Mulde, in die sie
hineinpassen, statt vier nackter Zeichen im Raum. */
/* 44 UND NICHT 32 (nachgebessert 25.09.2026).
Der erste Entwurf setzte sie auf 32x28 -- huebscher, und genau
deshalb falsch: `pruef-chat-optik` misst jedes Bedienelement gegen
44x44 und meldete "textform__knopf 32x44". Das ist die Groesse,
unter der ein Daumen daneben trifft; sie steht in module.css seit
jeher an dieser Stelle und ist keine Empfehlung.
Die Mulde sieht trotzdem kleiner aus als die Flaeche ist: Der
Rahmen sitzt innen, der Rest ist Griffflaeche. So bleibt beides --
das ruhige Bild und der treffbare Knopf. */
.chat__eingabe .textform__knopf {
min-width: 44px; min-height: 44px;
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, .07);
background: linear-gradient(180deg,
rgba(255, 255, 255, .05) 0%, rgba(255, 255, 255, .012) 100%);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
.chat__eingabe .textform__knopf:hover {
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 14%, transparent);
}
/* =====================================================================
SPRACHNACHRICHTEN (23.09.2026)
Filipe: „dan will ich auch dass man im chat auch sprachnachrichten
und gifts reinschicken kann. also nur die modis rechte linke hand
und dogfather."
AUGENSCHONEND HEISST HIER: KEIN BLINKEN. Der naheliegende rote
Blinkpunkt während der Aufnahme ist genau das, was die Hausregel
ausschließt („keine aggressiven Flacker-/Strobe-Effekte"). Der Punkt
atmet stattdessen langsam (1,8 s, zwischen 45 % und 100 %
Deckkraft) -- man sieht, dass etwas läuft, ohne dass es zieht. Und
bei `prefers-reduced-motion` steht er ganz still; dann trägt die
laufende Zeit daneben die Auskunft allein, die sie ohnehin trägt.
===================================================================== */
/* ---- Der Mikrofonknopf in der Schreibzeile ------------------------- */
.chat__ton {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
/* 40 px wie die Büroklammer daneben -- zwei Knöpfe nebeneinander in
zwei Größen sehen aus, als hätte einer Vorrang. */
width: 40px; height: 40px;
border: 0; border-radius: 50%;
background: transparent;
color: var(--text-leise);
cursor: pointer;
transition: background var(--tempo, .18s) ease, color var(--tempo, .18s) ease;
}
.chat__ton svg {
width: 21px; height: 21px;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.chat__ton:hover { background: rgba(255, 255, 255, .07); color: var(--text); }
.chat__ton:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat__ton:disabled { opacity: .45; cursor: default; }
/* Läuft die Aufnahme, ist derselbe Knopf der Abschick-Knopf. Dass er
seine Bedeutung wechselt, muss man SEHEN. */
.chat__ton[data-laeuft="ja"] {
background: color-mix(in srgb, var(--akzent) 22%, transparent);
color: color-mix(in srgb, var(--akzent) 60%, #ffffff);
}
/* ---- Die Leiste während der Aufnahme ------------------------------- */
.tonleiste {
display: flex; align-items: center; gap: 10px;
margin: 0 0 8px;
padding: 9px 12px;
border: 1px solid color-mix(in srgb, var(--akzent) 30%, transparent);
border-radius: var(--radius-klein, 12px);
background: color-mix(in srgb, var(--akzent) 10%, rgba(12, 18, 28, .92));
}
.tonleiste__punkt {
flex: none; width: 10px; height: 10px; border-radius: 50%;
background: #e0736d;
animation: ton-atmen 1.8s ease-in-out infinite;
}
@keyframes ton-atmen {
0%, 100% { opacity: 1; }
50% { opacity: .45; }
}
.tonleiste__zeit {
flex: none;
font-variant-numeric: tabular-nums;
font-size: 1.02rem; font-weight: 700;
color: var(--text);
/* Feste Breite: Ohne sie springt alles rechts davon bei jedem
Zehnerwechsel der Sekunden. */
min-width: 3.1ch;
}
.tonleiste__wort {
flex: 1 1 auto;
font-size: .84rem; color: var(--text-leise);
}
.tonleiste__weg,
.tonleiste__senden {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
/* 40 px, damit ein Daumen beides trifft, ohne das Falsche zu
erwischen -- hier kostet ein Fehlgriff die ganze Aufnahme. */
width: 40px; height: 40px;
border: 1px solid var(--rand);
border-radius: 50%;
background: transparent;
font-size: 1rem; line-height: 1;
cursor: pointer;
}
.tonleiste__weg { color: var(--text-leise); }
.tonleiste__weg:hover { color: var(--text); border-color: var(--text-leise); }
.tonleiste__senden {
color: color-mix(in srgb, var(--akzent) 55%, #ffffff);
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 16%, transparent);
}
.tonleiste__senden:hover { background: color-mix(in srgb, var(--akzent) 26%, transparent); }
.tonleiste__weg:focus-visible,
.tonleiste__senden:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
.tonleiste__punkt { animation: none; }
}
/* ---- Die Sprachnachricht in der Blase ------------------------------ */
/* DIE SPRACHNACHRICHT BRAUCHT EINE MINDESTBREITE (25.09.2026).
Gefunden hat das pruef-chat-anhaenge, nicht ein Blick: „breit genug,
um den Schieber zu treffen (165 px)" -- verlangt sind 200.
URSACHE WAR EINE FOLGE, keine Aenderung an dieser Stelle: Die Blase
ist so breit wie ihr breitester Inhalt. Solange unter jeder
Nachricht fuenf WOERTER standen, war das die Handgriff-Reihe mit
ueber 400 px. Seit sie Zeichen sind (123 px), bestimmt das
Abspielgeraet selbst die Breite -- und das nimmt sich, was da ist.
Das ist die Sorte Nebenwirkung, die man nie vorhersieht und immer
misst: Eine Reihe kuerzer zu machen hat einen Schieber schmaler
gemacht, drei Bildschirme weiter.
240 UND NICHT 200: Die Zahl in der Pruefung ist die Untergrenze,
nicht das Ziel. Wer genau auf die Grenze baut, ist beim naechsten
Pixel wieder darunter.
KEIN `min(240px, 100%)` -- der erste Anlauf stand so da und hat
nichts getan. `100%` ist die Breite des Elternteils, und der ist ja
gerade der schmale: `min(240, 165)` ist 165. Eine Mindestbreite, die
sich am zu Schmalen orientiert, ist keine. Die feste Zahl zwingt die
Blase zu wachsen -- genau das ist gemeint.
AUF DEM HANDY WIRD SIE ZURUECKGENOMMEN (unten in der schmalen
Fassung): Dort ist die Blase selbst nur rund 250 px breit, und
240 px plus Polsterung passen nicht mehr hinein. */
.chat-ton {
min-width: 240px;
display: grid; gap: 6px;
/* So breit, dass der Schieber des Abspielgeräts bedienbar ist, und
nicht breiter als eine Blase am Handy. */
width: min(260px, 100%);
}
.chat-ton__zeile {
display: flex; align-items: baseline; gap: 8px;
font-size: .78rem;
/* DIE FARBE DER BLASE, NICHT EINE FESTE. Jede Blase trägt die Farbe,
die ihr Absender ausgesucht hat -- `--blase-leise` ist die dafür
ausgerechnete leise Schrift. Dieselbe Überlegung wie bei der
Rudel-Marke weiter oben, und derselbe Fehler, der am 22.09. beim
Löschknopf 1,91:1 auf Babyblau ergeben hat. */
color: var(--blase-leise, var(--text-leise));
}
.chat-ton__marke { font-weight: 600; letter-spacing: .02em; }
.chat-ton__dauer { font-variant-numeric: tabular-nums; }
.chat-ton__geraet {
width: 100%; height: 36px;
display: block;
border-radius: 999px;
}
.chat-ton[data-kaputt="ja"] .chat-ton__geraet { display: none; }
@media (forced-colors: active) {
.tonleiste { border: 1px solid CanvasText; }
.tonleiste__punkt { background: CanvasText; }
.chat__ton[data-laeuft="ja"] { border: 2px solid Highlight; }
}
/* =====================================================================
DIE GIF-KISTE (23.09.2026)
Filipe: „dan will ich auch dass man im chat auch sprachnachrichten
und gifts reinschicken kann."
AUGENSCHONEND IST HIER EINE ECHTE FRAGE, keine Formsache: Zwölf
gleichzeitig laufende Bildchen sind das Gegenteil von ruhig. Wer
`prefers-reduced-motion` gesetzt hat, bekommt deshalb stehende
Bilder (chat.js malt das erste Einzelbild auf eine Zeichenfläche)
und sieht eines erst laufen, wenn er es anfasst. Für alle anderen
laufen sie -- eine GIF-Auswahl, in der sich nichts bewegt, ist eine,
in der man nicht sieht, was man verschickt.
DIE TAFEL IST GEDECKELT (48 vh). Ohne Deckel wächst sie mit der
Kiste, und irgendwann steht sie über dem ganzen Verlauf.
===================================================================== */
.chat__gif {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
/* Dieselben 40 px wie Büroklammer und Mikrofon daneben. */
width: 40px; height: 40px;
border: 0; border-radius: 50%;
background: transparent;
color: var(--text-leise);
font: 700 .68rem/1 var(--schrift, inherit);
letter-spacing: .04em;
cursor: pointer;
transition: background var(--tempo, .18s) ease, color var(--tempo, .18s) ease;
}
.chat__gif:hover { background: rgba(255, 255, 255, .07); color: var(--text); }
.chat__gif:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat__gif[aria-expanded="true"] {
background: color-mix(in srgb, var(--akzent) 20%, transparent);
color: color-mix(in srgb, var(--akzent) 60%, #ffffff);
}
/* Dieselbe Verankerung wie Emoji-Tafel und Erwähnliste: über der
Schreibzeile, damit sie dort aufgeht, wo man schreibt. */
.gif-tafel {
position: absolute;
bottom: 100%; left: 0; right: 0;
z-index: 30;
margin-bottom: 8px;
padding: 10px;
max-height: 48vh;
overflow: auto;
border: 1px solid var(--rand);
border-radius: var(--radius-klein, 12px);
background: var(--flaeche, rgba(14, 20, 30, .98));
box-shadow: 0 12px 30px -12px rgba(0, 0, 0, .7);
}
.gif-tafel__kopf {
display: flex; align-items: center; gap: 8px;
margin: 0 0 9px;
}
.gif-tafel__suchschild {
/* Für Vorleseprogramme da, für das Auge nicht -- daneben steht schon
ein Platzhalter, und zwei Beschriftungen für ein Feld sind eine zu
viel. */
position: absolute; width: 1px; height: 1px;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.gif-tafel__suche {
flex: 1 1 auto; min-width: 0;
padding: 8px 10px;
border: 1px solid var(--rand);
border-radius: 9px;
background: rgba(255, 255, 255, .04);
color: var(--text);
font-size: .9rem;
}
.gif-tafel__suche:focus-visible { outline: 2px solid var(--akzent); outline-offset: -1px; }
.gif-tafel__dazu {
flex: none;
/* ==== 40 WAR NICHT DIE HAUSGROESSE (berichtigt 25.09.2026) ======
Hier stand „40 px hoch wie alles, was ein Daumen trifft" -- und
das stimmt nicht: Die Grenze im Haus sind 44, und in derselben
Datei steht das fuenfmal so (Kachelknopf, Pin, Aufnahmeleiste,
Schriftknopf). Der Kommentar hat den falschen Wert nicht nur
stehenlassen, sondern ihn als Regel ausgegeben -- das ist die
unangenehmere Sorte: Wer ihn liest, uebernimmt die 40 beim
naechsten Knopf.
WARUM ES KEINE PRUEFUNG GEFUNDEN HAT: Die GIF-Tafel ist zu,
solange niemand sie aufmacht. `pruef-tippziele` und der
Handy-Rundgang messen, was auf dem Bildschirm steht -- ein
zugeklappter Bereich steht dort nicht. Gefunden hat es eine
Messung, die die Tafel ausdruecklich AUFMACHT
(server/mess-gifs-handy.mjs).
AM RECHNER BLEIBT ES BEI 40: Mit der Maus zielt man genau, und
der Knopf steht neben einem Suchfeld, das selbst nur 40 hoch ist.
Dieselbe Abwaegung wie beim Kachelknopf daneben. */
min-height: 40px;
padding: 0 12px;
border: 1px solid color-mix(in srgb, var(--akzent) 40%, transparent);
border-radius: 9px;
background: color-mix(in srgb, var(--akzent) 14%, transparent);
color: color-mix(in srgb, var(--akzent) 58%, #ffffff);
font-size: .82rem; font-weight: 600;
cursor: pointer;
}
.gif-tafel__dazu:hover { background: color-mix(in srgb, var(--akzent) 24%, transparent); }
.gif-tafel__dazu:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* ==== 44 AM FINGER -- UND DIE REIHENFOLGE ENTSCHEIDET (25.09.2026) ===
Diese Regel stand zuerst 400 Zeilen weiter oben, in dem Block, in
dem auch Kachelknopf, Pin, Aufnahmeleiste und Schriftknopf ihre
Fingergroesse bekommen. Dort war sie wirkungslos: Sie und die
Grundregel darunter haben dieselbe Staerke (eine Klasse), und bei
Gleichstand gewinnt die SPAETERE -- also die 40.
Nachgemessen hat es mess-gifs-handy.mjs: Der Knopf blieb 133 x 40,
obwohl die Regel dastand. Eine Regel, die im Quelltext richtig
aussieht und nicht greift, ist schlimmer als eine fehlende -- man
hakt sie ab.
Deshalb steht sie jetzt DIREKT hinter dem, was sie ueberschreiben
soll. Wer die Grundregel verschiebt, verschiebt sie mit. */
@media (pointer: coarse) {
.gif-tafel__dazu { min-height: 44px; }
}
.gif-tafel__gitter {
display: grid;
/* auto-fill statt auto-fit: Bei zwei GIFs sollen zwei Kacheln
dastehen und nicht zwei auf halbe Bildschirmbreite gezogene --
derselbe Unterschied wie bei der Personenwahl am 22.09. */
grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
gap: 8px;
}
.gif-kachel { position: relative; }
.gif-kachel__knopf {
display: block; width: 100%;
padding: 0;
border: 1px solid var(--rand);
border-radius: 10px;
background: rgba(255, 255, 255, .03);
overflow: hidden;
cursor: pointer;
/* Feste Höhe: Ohne sie springt das Gitter, während die Bilder
nacheinander ankommen -- und man tippt auf das, was gerade
weggerutscht ist. */
aspect-ratio: 1 / 1;
}
.gif-kachel__knopf:hover { border-color: color-mix(in srgb, var(--akzent) 50%, transparent); }
.gif-kachel__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.gif-kachel__bild {
display: block; width: 100%; height: 100%;
object-fit: cover;
}
.gif-kachel__weg {
position: absolute; top: 4px; right: 4px;
/* 28 px, und das ist eine Abwägung: Ein Daumenziel von 44 px würde
hier die halbe Kachel verdecken und beim Verschicken im Weg
stehen. Ein Fehlgriff kostet nichts -- es kommt eine Rückfrage. */
width: 28px; height: 28px;
display: inline-flex; align-items: center; justify-content: center;
border: 0; border-radius: 50%;
background: rgba(8, 12, 20, .78);
color: #e6edf6;
font-size: .74rem; line-height: 1;
cursor: pointer;
}
.gif-kachel__weg:hover { background: rgba(8, 12, 20, .94); }
.gif-kachel__weg:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
.gif-tafel__leer {
margin: 10px 4px 4px;
font-size: .86rem; line-height: 1.55;
color: var(--text-leise);
}
@media (forced-colors: active) {
.gif-tafel { border: 1px solid CanvasText; }
.gif-kachel__knopf { border: 1px solid CanvasText; }
.chat__gif[aria-expanded="true"] { border: 2px solid Highlight; }
}
/* =====================================================================
DER FARBRING IN DER KACHELWAHL (23.09.2026)
Filipe: „kannst du nicht so eine art diagramm machen wo man mit
einem kreis herum gehen kann und sie die farbe ganz genau selber
auswählen kann? ... es soll richtig krass geil aussehen."
Der Ring wird in chat.js mit 360 fertig gerechneten Farben gefüllt.
Hier steht nur, wie er aussieht und wie man ihn anfasst.
WARUM ER RUHIG WIRKT UND NICHT GRELL: Alle 360 Töne liegen auf
derselben Leuchtdichte. Ein üblicher Farbkreis hat ein blendendes
Gelb und ein fast schwarzes Blau; dieser hier nicht. Das ist keine
Zurückhaltung im Geschmack, sondern die Bedingung dafür, dass die
Schrift auf JEDER dieser Farben lesbar bleibt — und nebenbei sieht
ein Ring gleicher Helligkeit deutlich edler aus als der bunte
Standardkreis, den man von überall kennt.
===================================================================== */
.kachelrad {
position: relative;
width: min(17rem, 68vw);
aspect-ratio: 1;
margin: 18px auto 6px;
/* Der Griff liegt auf dem Ring und darf nicht abgeschnitten werden. */
overflow: visible;
}
.kachelrad[hidden] { display: none; }
.kachelrad__ring {
position: absolute;
inset: 0;
border-radius: 50%;
/* Der Farbverlauf selbst kommt aus chat.js -- 360 Werte. */
/* DIE MITTE WIRD AUSGESTANZT statt mit einer Scheibe zugedeckt:
Eine Scheibe darüber würde die Zeigerbewegung abfangen, und der
Ring reagierte in der Mitte nicht mehr. */
-webkit-mask: radial-gradient(circle, #0000 0 56%, #000 57% 100%);
mask: radial-gradient(circle, #0000 0 56%, #000 57% 100%);
/* OHNE DAS SCROLLT DAS HANDY. Wer auf einem Berührungsbildschirm
im Kreis wischt, schiebt sonst die Seite weg, und der Ring
bekommt die Bewegung nie zu sehen. */
touch-action: none;
cursor: grab;
/* Eine leise Tiefe, damit der Ring auf dem dunklen Grund steht und
nicht schwebt. Kein Leuchten, kein Puls -- augenschonend gilt
hier genauso. */
box-shadow:
inset 0 0 0 1px color-mix(in srgb, #000 55%, transparent),
0 6px 20px -8px #000;
}
.kachelrad__ring:active { cursor: grabbing; }
.kachelrad__ring:focus-visible {
outline: 3px solid var(--akzent);
outline-offset: 4px;
}
/* Der Arm dreht sich, der Griff sitzt an seinem oberen Ende.
So braucht der Griff keine eigene Winkelrechnung -- er wird
einfach mitgedreht. */
.kachelrad__arm {
position: absolute;
inset: 0;
transform: rotate(var(--winkel, 0deg));
pointer-events: none;
}
.kachelrad__griff {
position: absolute;
top: 8.5%;
left: 50%;
width: 2.3rem;
height: 2.3rem;
margin: -1.15rem 0 0 -1.15rem;
border-radius: 50%;
border: 3px solid #fff;
background: transparent;
box-shadow:
0 0 0 2px color-mix(in srgb, #000 70%, transparent),
0 2px 8px -2px #000;
}
/* Die Mitte zeigt, wie die eigene Nachricht aussehen wird -- mit
echtem Text in der echten Schriftfarbe dieser Kachel. Ein reiner
Farbfleck beantwortet die Frage nicht, die man hier hat. */
.kachelrad__mitte {
position: absolute;
inset: 22%;
border-radius: 999px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
font-weight: 600;
pointer-events: none;
box-shadow: 0 0 0 1px color-mix(in srgb, #000 45%, transparent);
}
/* ==== DIE PROBE ZEIGT, WIE ES WIRKLICH AUSSIEHT (25.09.2026) ======
Hier stand eine gefuellte Flaeche mit heller Schrift darauf. So sah
die Blase bis zum 25.09. aus -- seither ist sie fuer alle dunkles
Glas, und der gewaehlte Ton ist der NAME darauf. Die Probe zeigte
also etwas, das es nicht mehr gibt.
Jetzt steht hier genau die Rechnung aus der Blase: derselbe
Blasengrund, und darauf der Ton, mit Weiss aufgehellt im selben
Verhaeltnis (`--namen-anteil`). Wer eine Farbe waehlt, sieht die
Schrift, die die anderen sehen werden.
UND ES IST DER GRUND, WARUM DIE SIEBEN HELLIGKEITEN GEHEN: Eine
gefuellte Flaeche muesste Schrift tragen, und bei sehr hellen Toenen
schafft das keine der beiden Schriftfarben mehr (gemessen 4,1 statt
noetiger 7). Als NAME auf dunklem Grund ist derselbe helle Ton
besonders gut lesbar (8,0). */
.kachelrad__mitte {
background: color-mix(in srgb, var(--blasengrund) 96%, transparent);
}
.kachelrad__probe {
opacity: 1;
font-weight: 800;
letter-spacing: .04em;
color: color-mix(in srgb,
var(--probe-ton, var(--akzent)) var(--namen-anteil, 50%), #f2f8ff);
}
/* ==== DIE HELLIGKEITSLEITER (25.09.2026) ==========================
Filipe: „ich will dass die leute auch heller und dunkler aussuchen
koennen … so dass die leute viel krassere moeglichkeiten haben."
SIEBEN FELDER IN IHRER ECHTEN FARBE, nicht sieben graue Kaestchen
mit Beschriftung: Man waehlt eine Farbe, also soll man Farben sehen.
Sie faerben sich beim Drehen am Ring mit.
EINE LEISTE UND KEIN ZWEITER KREIS: Farbton laeuft rund (359 grenzt
an 0), Helligkeit nicht -- sie hat ein dunkles und ein helles Ende.
Eine runde Form fuer etwas, das gerade verlaeuft, waere eine Form,
die luegt. */
.kachelhell {
margin: 14px auto 0;
max-width: 320px;
display: grid; gap: 7px;
}
.kachelhell__schild {
font-size: .74rem; font-weight: 700;
letter-spacing: .1em; text-transform: uppercase;
color: var(--text-still);
}
.kachelhell__leiter {
display: grid; grid-template-columns: repeat(7, 1fr);
gap: 4px;
padding: 5px;
border-radius: 14px;
background: rgba(0, 0, 0, .3);
box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, .9);
cursor: pointer;
}
.kachelhell__leiter:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* 44 px hoch: Hier tippt man mit dem Daumen, und sieben Felder
nebeneinander sind ohnehin schon schmal. */
.kachelhell__feld {
height: 44px;
border-radius: 9px;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08);
transition: transform .14s ease, box-shadow .14s ease;
}
/* DIE WAHL STEHT HOEHER, sie ist nicht nur umrandet: Bei sieben
benachbarten Farbfeldern ist ein Rahmen mehr die achte Farbe. Ein
angehobenes Feld mit Lichtkante liest sich als „das hier". */
.kachelhell__feld[data-an="ja"] {
transform: translateY(-3px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .5),
0 0 0 2px rgba(255, 255, 255, .85),
0 8px 16px -8px rgba(0, 0, 0, .9);
}
@media (prefers-reduced-motion: reduce) {
.kachelhell__feld { transition: none; }
}
@media (forced-colors: active) {
.kachelhell__feld { border: 1px solid CanvasText; }
.kachelhell__feld[data-an="ja"] { border: 3px solid Highlight; }
}
/* Ein Wechsel der Farbe soll nicht springen, aber auch nicht
nachlaufen -- 90 ms sind gerade so viel, dass es weich wirkt. */
@media (prefers-reduced-motion: no-preference) {
.kachelrad__arm { transition: transform .09s linear; }
.kachelrad__mitte { transition: background-color .09s linear; }
}
/* Im Kontrastmodus gibt es keine Farbflächen. Dann ist ein Farbring
sinnlos -- die Sonderknöpfe darunter tragen weiter, und der Ring
bekommt wenigstens einen sichtbaren Umriss statt zu verschwinden. */
@media (forced-colors: active) {
.kachelrad__ring { border: 1px solid CanvasText; }
.kachelrad__griff { border-color: Highlight; }
.kachelrad__mitte { border: 1px solid CanvasText; }
}
/* =====================================================================
=====================================================================
STILWECHSEL: „NACHTPRISMA" (25.09.2026)
=====================================================================
=====================================================================
Filipe, zum dritten Mal an derselben Sache und deutlich:
„du verstehst es wirklich nicht … ich will eine komplette aenderung
vom aussehen. vom hintergrund und von der grossen kachel. ich will
einen ganz anderen stil. ich will dass die ganze kachel sei es rand,
hintergrund oder alles andere … komplett anderes stil bitte. nochmal
die leute sollen morgen nichts mehr wieder erkennen vom aussehen
her."
---------------------------------------------------------------------
WARUM MEINE ZWEI ANLAEUFE DAVOR NICHT GEREICHT HABEN
Ich habe zweimal INNERHALB der vorhandenen Sprache gearbeitet --
Blasen, Zeilen, Knoepfe, Schatten. Die Sprache selbst blieb: Fase
oben links, Eckwinkel in Gold, Punktraster, harte Kanten. Genau die
erkennt man wieder, und zwar zuerst. Wer den Umriss nicht aendert,
aendert das Bild nicht -- man sieht neue Details in einem bekannten
Rahmen.
DER UMRISS KOMMT NICHT AUS DIESER DATEI. Er steht in `module.css`,
in einer Liste von 50 Klassen, und `.chat` ist eine davon. Dort
werden Fase (`clip-path`), Kantenlicht, Punktraster und die drei
goldenen Eckwinkel gesetzt. `module.css` wird NACH `chat.css`
geladen -- deshalb hat jede Regel hier bisher verloren, ohne dass
man es der Datei ansieht. Das ist der Grund, warum „ich habe den
Rand geaendert" und „der Rand ist derselbe" beide stimmten.
---------------------------------------------------------------------
WAS DIESER BLOCK TUT
Er nimmt den Chat aus dieser Sprache HERAUS und gibt ihm eine
eigene:
ALT NEU
Fase oben links rundum 26 px weich
drei goldene Eckwinkel keine -- der Koerper traegt sich selbst
Punktraster Farbverlauf aus drei Lichtern
1-px-Rahmen kein Rahmen, nur Lichtkante innen
harter Schlagschatten tiefer, weiter, farbiger Schatten
Gold als Leitfarbe Violett/Tuerkis, Gold nur als Akzent
Kaesten nebeneinander Koerper, die uebereinander liegen
DIE SELEKTOREN SIND ABSICHTLICH ZWEISTUFIG (`.inhalt.chat-seite .chat`).
`module.css` kommt spaeter in der Reihe; mit einer Klasse allein
gewinnt es. Zwei Klassen sind die kleinste Stufe, die reicht -- kein
`!important`, denn das waere eine Tuer, die man danach nie wieder
zubekommt.
ES IST EINE SCHICHT UND KEINE ZWEITE WAHRHEIT. Alles, was hier NICHT
steht, gilt unveraendert aus den Regeln darueber -- Kontrastzusagen
(`--blasengrund`, `--namen-anteil`), Tippziele, Schriftgroessen. Was
hier steht, ist der neue Umriss und die neue Farbe. Wer den Stil
wieder aendern will, aendert diesen einen Block.
AUGENSCHONEND BLEIBT PFLICHT (Hausregel). Die drei Lichter im
Hintergrund stehen zusammen unter sieben Prozent Deckung, es
blinkt nichts, und `prefers-reduced-motion` nimmt die letzte
Bewegung heraus.
===================================================================== */
/* ---- 1. DIE SEITE BEKOMMT EIGENE LUFT UND EIGENES LICHT -------------
„schieb das bisschen hoeher bitte, weil das ist unten zu nah am
rand." Die Tafeln endeten genau auf der Bildkante. 14 px Polsterung
unten -- die Hoehe ist `calc(100dvh - …)` mit `border-box`, die
Polsterung geht also nach INNEN und macht die Seite nicht laenger.
Sonst waere das Schreibfeld wieder unter den Rand gerutscht, und
genau darum ging es am 09.09. schon einmal. */
.inhalt.chat-seite {
padding-bottom: 14px;
position: relative;
isolation: isolate;
/* ==== DIE LEITFARBE WIRD AUSGETAUSCHT -- AN EINER STELLE =========
Im ersten Anlauf habe ich zehn Stellen einzeln umgefaerbt und dann
im Bild gesehen, dass Suchfeld, „Neu"-Knopf, Zaehler und
Fokusrahmen weiter golden waren. Kein Wunder: Sie nehmen alle
`--akzent` und `--rand`, und die stehen im Haus. Wer den Stil
aendern will, aendert die Variable, nicht zwanzig Regeln -- sonst
findet man immer noch eine einundzwanzigste.
NUR AUF DIESER SEITE. Die Variablen stehen am `<main>`, nicht am
`:root`: Uebersicht, Kalender und Aufgaben behalten ihr Gold. Der
Chat ist das, was nicht mehr wiederzuerkennen sein soll -- nicht
das ganze Haus.
WARUM #b9a7ff UND NICHT DAS SATTE #7a5cff: Die Akzentfarbe ist
hier nicht nur Zierde, sie ist auch FLAECHE unter dunkler Schrift
(die Ungelesen-Marke traegt #0b0f16 darauf). Nachgerechnet:
#7a5cff kommt dort auf 3,7:1 -- zu wenig fuer kleine Schrift.
#b9a7ff kommt auf 8,9:1 und traegt umgekehrt als SCHRIFT auf dem
dunklen Grund genauso. Eine Leitfarbe, die nur an einer von zwei
Stellen funktioniert, ist keine.
`--rand` WIRD NEUTRAL, nicht violett: Ein farbiger Rahmen an
jedem Feld waere laut. Die Farbe soll dort stehen, wo etwas
passiert -- nicht ueberall. */
--akzent: #b9a7ff;
--rand: rgba(255, 255, 255, .07);
--rand-hell: rgba(255, 255, 255, .15);
}
/* DREI LICHTER STATT EINES PUNKTRASTERS. Sie liegen HINTER den Tafeln
(z-index -1) und ueber dem Buehnenbild: Der Chat bekommt damit eine
eigene Stimmung, ohne dass eine andere Seite im Haus sich aendert.
Violett oben links, Tuerkis unten rechts, ein warmer Rest in der
Mitte -- zusammen keine sieben Prozent Deckung. */
.inhalt.chat-seite::before {
content: ""; position: absolute; inset: -10% -6% 0;
pointer-events: none; z-index: -1;
background:
radial-gradient(48% 42% at 14% 6%, rgba(122, 92, 255, .16), transparent 68%),
radial-gradient(52% 46% at 88% 92%, rgba(38, 200, 196, .12), transparent 70%),
radial-gradient(40% 34% at 62% 44%, rgba(255, 176, 92, .06), transparent 72%);
filter: blur(18px);
}
/* ---- 2. DER RAHMEN VON MODULE.CSS WIRD ABGELEGT -------------------- */
.inhalt.chat-seite .chat {
clip-path: none;
border-radius: 0;
box-shadow: none;
filter: none;
}
/* Kantenlicht, Punktraster und die drei goldenen Eckwinkel -- beide
Pseudoelemente kommen aus module.css und werden hier stillgelegt.
`content: none` und nicht `display: none`: Das Element entsteht dann
gar nicht erst, statt erzeugt und versteckt zu werden. */
.inhalt.chat-seite .chat::before,
.inhalt.chat-seite .chat::after { content: none; }
/* ---- 3. DIE TAFELN WERDEN KOERPER ---------------------------------- */
.inhalt.chat-seite .chat__spalte {
clip-path: none;
border: 0;
border-radius: 26px;
background:
linear-gradient(180deg, rgba(255, 255, 255, .055) 0%, transparent 18%),
linear-gradient(168deg, rgba(20, 24, 42, .82) 0%, rgba(8, 10, 18, .9) 100%);
backdrop-filter: blur(26px) saturate(135%);
-webkit-backdrop-filter: blur(26px) saturate(135%);
/* KEIN RAHMEN, SONDERN LICHT UND TIEFE. Ein 1-px-Strich zeichnet
einen Kasten; eine Lichtkante oben und ein weiter, farbiger
Schatten zeichnen einen KOERPER. Der Schatten traegt einen Hauch
Violett -- reines Schwarz wirkt auf einem farbigen Grund wie ein
Loch. */
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .1),
inset 0 0 0 1px rgba(255, 255, 255, .035),
0 2px 6px -3px rgba(0, 0, 0, .7),
0 44px 90px -46px rgba(10, 6, 30, .98);
overflow: hidden;
}
/* Die Leuchtschiene an der Liste wird ein SAUM oben statt eines
Striches links: Sie sagt jetzt „hier faengt der Koerper an" und
nicht mehr „hier ist eine Kante". */
.inhalt.chat-seite .chat__spalte--liste::after {
left: 0; right: 0; top: 0; bottom: auto;
width: auto; height: 2px;
border-radius: 0;
background: linear-gradient(90deg,
rgba(122, 92, 255, .85) 0%,
rgba(38, 200, 196, .7) 52%,
transparent 100%);
box-shadow: 0 0 18px -2px rgba(122, 92, 255, .6);
}
/* Und der Verlauf bekommt denselben Saum, nur andersherum gelesen --
zwei Koerper, ein Licht. */
.inhalt.chat-seite .chat__spalte--verlauf { position: relative; }
.inhalt.chat-seite .chat__spalte--verlauf::after {
content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
border-radius: 0; pointer-events: none; z-index: 3;
background: linear-gradient(270deg,
rgba(38, 200, 196, .8) 0%,
rgba(122, 92, 255, .6) 55%,
transparent 100%);
box-shadow: 0 0 18px -2px rgba(38, 200, 196, .5);
}
/* ---- 4. DIE KOEPFE WERDEN BAENDER, KEINE LEISTEN ------------------- */
.inhalt.chat-seite .chat__kopf {
padding: 18px 18px 16px;
background: linear-gradient(180deg,
rgba(122, 92, 255, .12) 0%, rgba(255, 255, 255, .01) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 18px 26px -26px rgba(0, 0, 0, .95);
}
.inhalt.chat-seite .chat__titel {
font-size: 1.34rem; font-weight: 800; letter-spacing: -.022em;
}
/* ---- 5. DIE REGISTERLEISTE: PILLEN STATT MULDE --------------------- */
/* Die Mulde war die Form des alten Stils -- eingesenkt, mit Kante.
Jetzt liegen die drei frei nebeneinander, und das gewaehlte Fach ist
das einzige mit Flaeche. Weniger Linien, mehr Aussage. */
.inhalt.chat-seite .chat-arten {
gap: 6px; padding: 0; margin: 14px 14px 0;
border: 0; border-radius: 0;
background: none; box-shadow: none;
}
.inhalt.chat-seite .chat-art {
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, .06);
background: rgba(255, 255, 255, .025);
}
.inhalt.chat-seite .chat-art[aria-selected="true"] {
border-color: transparent;
color: #0b0a18;
background: linear-gradient(140deg, #b9a7ff 0%, #7a5cff 55%, #5b8cff 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .45),
0 8px 20px -10px rgba(122, 92, 255, .8);
}
/* Der Saum unter dem Reiter gehoerte zur Mappe -- die gibt es nicht
mehr. */
.inhalt.chat-seite .chat-art[aria-selected="true"]::after { content: none; }
.inhalt.chat-seite .chat-art[aria-selected="true"] .chat-art__zahl { opacity: .75; }
.inhalt.chat-seite .chat-art[aria-selected="true"] .chat-art__at { color: #1a1030; text-shadow: none; }
/* ---- 6. DIE SUCHE ------------------------------------------------- */
.inhalt.chat-seite .chat__suche input {
border-radius: 999px;
border-color: rgba(255, 255, 255, .06);
background: rgba(0, 0, 0, .3);
box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, .9);
}
/* ---- 7. DIE ZEILEN ------------------------------------------------- */
/* Die Zeile ist jetzt ein Raster: links das Gespraech, rechts die
Nadel. Ohne diese Regel stuende die Nadel unter der Zeile -- ein
<li> ist von sich aus ein Block. */
/* DIE KARTE IST DIE ZEILE, NICHT DER KNOPF DARIN (25.09.2026).
Der erste Anlauf liess die Flaeche am Knopf und haengte die Nadel
daneben -- im Bild sass sie dann sichtbar AUSSERHALB der Karte, wie
ein Knopf, der danebengefallen ist. Die Karte muss beides umfassen,
sonst gehoert die Nadel nicht zur Zeile.
Also traegt jetzt das <li> die Flaeche, und der Knopf darin ist
durchsichtig. Die Farbkante des offenen Gespraechs bleibt am Knopf:
Sie markiert, WO das Gespraech anfaengt, und das ist der Knopf. */
.inhalt.chat-seite .chat-raum {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 0;
padding-right: 2px;
border-radius: 20px;
transition: background-color .18s ease, box-shadow .18s ease;
}
.inhalt.chat-seite .chat-raum:hover {
background: rgba(255, 255, 255, .055);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
.inhalt.chat-seite .chat-raum__knopf {
border: 0;
border-radius: 20px 0 0 20px;
padding: 12px 6px 12px 12px;
background: none;
box-shadow: none;
transform: none;
}
.inhalt.chat-seite .chat-raum__knopf:hover {
background: none;
box-shadow: none;
transform: none;
}
/* Das offene Gespraech traegt Farbe statt eines Rahmens -- an der
ganzen Zeile, damit die Nadel mit auf der Flaeche sitzt. */
.inhalt.chat-seite .chat-raum[data-offen="ja"] {
background: linear-gradient(100deg,
rgba(122, 92, 255, .28) 0%, rgba(122, 92, 255, .08) 62%, rgba(255, 255, 255, .02));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .12),
0 10px 24px -16px rgba(122, 92, 255, .9);
}
.inhalt.chat-seite .chat-raum[data-neu="ja"] .chat-raum__knopf {
background: none;
border-color: transparent;
}
.inhalt.chat-seite .chat-raum[data-neu="ja"]:not([data-offen="ja"]) {
background: rgba(255, 255, 255, .045);
}
.inhalt.chat-seite .chat-raum[data-offen="ja"] .chat-raum__knopf::before {
top: 14px; bottom: 14px; left: 0; width: 3px; border-radius: 3px;
background: linear-gradient(180deg, #d9cfff, #7a5cff);
box-shadow: 0 0 14px -1px rgba(122, 92, 255, .9);
}
/* Das Zeichen wird ein abgerundetes Quadrat -- der auffaelligste
Einzelgriff in der Liste. Runde Kreise hat jedes Programm; ein
„Squircle" liest sich als App-Symbol und gehoert zu den grossen
Radien ringsum. */
.inhalt.chat-seite .chat-raum__zeichen {
width: 44px; height: 44px;
border-radius: 15px;
border: 0;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .22),
inset 0 0 0 1px rgba(255, 255, 255, .07),
0 8px 18px -10px rgba(0, 0, 0, .9);
}
.inhalt.chat-seite .chat-raum__zeichen img { border-radius: 15px; }
.inhalt.chat-seite .chat-raum__zeichen[data-gruppe="ja"] { border-radius: 15px; }
/* ---- 8. DIE NADEL -------------------------------------------------- */
/* Sie steht immer da -- am Handy gibt es kein Ueberfahren, und eine
Spalte, die mal da ist und mal nicht, laesst die Namen daneben
wandern (dieselbe Ueberlegung wie bei `.chat-raum__rail`).
36 x 44: schmal genug, dass sie der Liste keinen Namen wegnimmt,
und hoch genug fuer die 44-px-Hausregel. Die Trefferflaeche ist
groesser als das Zeichen darin -- gewachsen ist die Flaeche, nicht
das Bild. */
.inhalt.chat-seite .chat-raum__pin {
flex: none;
width: 36px; height: 44px;
display: grid; place-items: center;
border: 0; border-radius: 14px;
background: none;
color: var(--text-still);
cursor: pointer;
opacity: .34;
transition: opacity .16s ease, color .16s ease, background-color .16s ease;
}
.inhalt.chat-seite .chat-raum__pin::before {
content: ""; width: 15px; height: 15px;
background: currentColor;
-webkit-mask: var(--nadel) center / 15px 15px no-repeat;
mask: var(--nadel) center / 15px 15px no-repeat;
--nadel: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 3.6h6'/><path d='M10.6 3.6v5.6L7.4 14.2h9.2L13.4 9.2V3.6'/><path d='M12 14.2v6.2'/></svg>");
}
.chat-raum:hover .chat-raum__pin,
.inhalt.chat-seite .chat-raum__pin:hover { opacity: .8; color: var(--text); }
.inhalt.chat-seite .chat-raum__pin:focus-visible {
opacity: 1; outline: 2px solid var(--akzent); outline-offset: -3px;
}
/* ANGEHEFTET: die Nadel steht aufrecht und traegt Farbe. Gedreht wird
sie um 35 Grad, wenn sie NICHT gesetzt ist -- so wie eine Nadel
liegt, die man noch nicht gesteckt hat. Das ist der Unterschied,
den man ohne Farbe sieht. */
.inhalt.chat-seite .chat-raum__pin[aria-pressed="false"]::before { transform: rotate(-38deg); }
.inhalt.chat-seite .chat-raum__pin[aria-pressed="true"] {
opacity: 1;
color: #cfc2ff;
background: rgba(122, 92, 255, .18);
}
/* Eine angeheftete Zeile bekommt einen leisen Schimmer -- sonst sieht
man oben in der Liste nicht, WARUM sie oben steht. Nur wenn sie
nicht ohnehin offen ist: zwei Flaechen uebereinander waeren eine
Farbe, die niemand mehr zuordnen kann. */
.inhalt.chat-seite .chat-raum[data-fixiert="ja"]:not([data-offen="ja"]) {
background: linear-gradient(100deg,
rgba(122, 92, 255, .11) 0%, rgba(255, 255, 255, .012) 70%);
}
@media (prefers-reduced-motion: reduce) {
.inhalt.chat-seite .chat-raum__pin { transition: none; }
}
/* ---- 9. DIE BLASEN ------------------------------------------------- */
/* DIE FLAECHE UND DIE SCHRIFT BLEIBEN, WIE SIE SIND. `--blasengrund`,
`--blase-text`, `--blase-leise` und `--namen-anteil` stehen weiter
oben und sind von pruef-chatkachel und pruef-chat-neu nachgerechnet
-- 360 Ringtoene und zwoelf Kacheln. Wer sie hier anfasst, hebt
diese Zusage auf. Geaendert wird die FORM. */
.inhalt.chat-seite .chat-nachricht__blase {
border: 0;
border-radius: 24px 24px 24px 8px;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .1),
inset 0 0 0 1px color-mix(in srgb, var(--ton, var(--kachel-standard)) 16%, rgba(255, 255, 255, .05)),
0 18px 40px -26px rgba(6, 4, 20, .95),
0 0 40px -22px color-mix(in srgb, var(--ton, var(--kachel-standard)) 60%, transparent);
}
.inhalt.chat-seite .chat-nachricht[data-selbst="ja"] .chat-nachricht__blase {
border-radius: 24px 24px 8px 24px;
}
/* EINE GESCHEITERTE NACHRICHT BLEIBT SICHTBAR ANDERS (25.09.2026).
Der neue Stil nimmt allen Blasen den Rahmen -- und damit versehentlich
auch den, mit dem eine nicht abgeschickte Nachricht markiert ist.
pruef-chat-optik hat es sofort gemeldet: „der Unterschied ist auch zu
SEHEN, nicht nur im Merkmal (Rand 0px)". Genau dafuer ist die Zeile
dort: Ein Merkmal im HTML, das man nicht sieht, hilft niemandem.
Der Warnton sitzt jetzt im inneren Saum statt im Rahmen -- dieselbe
Aussage, dieselbe Staerke, nur in der Sprache des neuen Stils. Der
Rahmen bleibt trotzdem stehen, weil die Pruefung ihn misst und weil
er im Kontrastmodus das Einzige ist, was traegt. */
.inhalt.chat-seite .chat-nachricht[data-gescheitert="ja"] .chat-nachricht__blase {
border: 1px solid color-mix(in srgb, var(--warn) 62%, transparent);
background: color-mix(in srgb, var(--warn) 11%, transparent);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .1),
inset 0 0 0 1px color-mix(in srgb, var(--warn) 45%, transparent),
0 18px 40px -26px rgba(6, 4, 20, .95),
0 0 40px -20px color-mix(in srgb, var(--warn) 70%, transparent);
}
.inhalt.chat-seite .chat-nachricht[data-folge="ja"] .chat-nachricht__blase { border-radius: 24px; }
/* Aus dem Strich wird eine Kapsel -- sie sitzt jetzt INNEN und hat
runde Enden, passend zu den grossen Radien ringsum. */
.inhalt.chat-seite .chat-nachricht__blase::before {
left: 5px; top: 14px; bottom: 14px; width: 3px;
border-radius: 3px;
}
.inhalt.chat-seite .chat-nachricht[data-selbst="ja"] .chat-nachricht__blase::before {
left: auto; right: 5px; border-radius: 3px;
}
.inhalt.chat-seite .chat-nachricht__zeichen {
border-radius: 12px;
border: 0;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .2),
0 6px 14px -8px rgba(0, 0, 0, .9);
}
/* Der Tagestrenner: aus der Linie mit Plakette wird eine schwebende
Kapsel ohne Linien. */
.inhalt.chat-seite .chat-tag::before,
.inhalt.chat-seite .chat-tag::after { content: none; }
.inhalt.chat-seite .chat-tag__text {
border-radius: 999px;
padding: 5px 14px;
border: 0;
background: rgba(122, 92, 255, .16);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
}
/* ---- 10. DIE KONSOLE ----------------------------------------------- */
/* KEINE MASSZAHL ANGEFASST. Breite, Hoehe, Polsterung und Abstaende
bleiben, wie sie sind -- die Zeile ist seit dem 23.09.2026 auf den
Pixel voll, und sechs Pixel haben dort schon einmal gereicht, um
„Senden" auf eine eigene Zeile zu schieben. Geaendert wird nur, was
nichts misst. */
.inhalt.chat-seite .chat__eingabe {
background: linear-gradient(180deg,
rgba(16, 14, 34, .72) 0%, rgba(7, 8, 16, .9) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .08),
0 -22px 34px -30px rgba(0, 0, 0, .95);
}
.inhalt.chat-seite .chat__eingabe textarea { border-radius: 18px; }
.inhalt.chat-seite .chat__senden {
border-radius: 16px;
border-color: transparent;
color: #0b0a18;
background: linear-gradient(140deg, #b9a7ff 0%, #7a5cff 58%, #5b8cff 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .45),
0 12px 26px -12px rgba(122, 92, 255, .85);
}
.inhalt.chat-seite .chat__senden:hover {
background: linear-gradient(140deg, #cabcff 0%, #8b70ff 58%, #6f9bff 100%);
border-color: transparent;
color: #07060f;
}
.inhalt.chat-seite .chat__eingabe
:is(.chat__anhang, .chat__ton, .chat__gif, .chat__emoji, .chat__schriftknopf) {
border-radius: 14px;
border-color: rgba(255, 255, 255, .05);
}
/* Offen traegt er die Leitfarbe der Seite -- dieselbe wie der
Absendeknopf, nur leiser. */
.inhalt.chat-seite .chat__schriftknopf[aria-expanded="true"] {
border-color: color-mix(in srgb, var(--akzent) 50%, transparent);
background: color-mix(in srgb, var(--akzent) 18%, transparent);
color: color-mix(in srgb, var(--akzent) 30%, #ffffff);
}
.inhalt.chat-seite .chat__eingabe .textform__knopf { border-radius: 12px; }
/* ---- 11. DIE KNOPFGRUPPE IM KOPF ----------------------------------- */
.inhalt.chat-seite .chat__kopf-knoepfe {
border-radius: 999px;
background: rgba(0, 0, 0, .28);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05);
}
.inhalt.chat-seite .chat__weg,
.inhalt.chat-seite .chat__zurueck { border-radius: 999px; }
/* ---- 12. AUF DEM HANDY ---------------------------------------------
Die Radien wachsen mit der Flaeche, nicht mit dem Geraet: Auf 412 px
ist eine Tafel 380 px breit, und 26 px Rundung nehmen dort spuerbar
mehr Inhalt weg als auf 1440. 20 px sind dieselbe Sprache, nur
massstabsgerecht. */
@media (max-width: 760px) {
.inhalt.chat-seite .chat__spalte { border-radius: 20px; }
.inhalt.chat-seite .chat-raum__pin { width: 34px; }
}
/* =====================================================================
DIE HANDGRIFFE WERDEN ZEICHEN (25.09.2026)
=====================================================================
Filipe: „diese optionen im chat. ich will dass du das viel geiler
machst und es soll viel kuerzer gestaltet sein. so dass es nicht zu
viel aufmerksamkeit auf sich zieht aber jeder sieht dass es da ist.
aber kurz und knapp was richtig geiles schnell benutzbar aber nicht
zu viel platzraubend."
---------------------------------------------------------------------
WAS DA STAND UND WAS ES GEKOSTET HAT
Heute frueh bekamen die fuenf Woerter Zeichen davor -- das war der
richtige Schritt und nur der halbe. Gemessen auf 412 px brauchte die
Reihe danach DREI Zeilen: „23. Sept. antworten reagieren" / „loeschen
(Notfall) anheften" / „kopieren". Unter zwei Zeilen Text standen also
drei Zeilen Bedienung.
WOERTER SIND HIER DER FALSCHE MASSSTAB. Man liest sie nicht -- man
sucht das eine, das man gerade braucht. Fuenf Woerter nebeneinander
sind fuenfmal Lesen fuer einen Griff; fuenf Zeichen sind ein Blick.
---------------------------------------------------------------------
DAS WORT IST NICHT WEG, ES IST NUR NICHT ZU SEHEN
`.chat-nachricht__wort` steht weiter im Dokument und wird
vorgelesen, steht als `title` unter dem Zeiger und ist das, was
`textContent` liefert (daran haengt pruef-chat-ausbau). Ein Knopf
ganz ohne Beschriftung waere kuerzer und schlechter.
---------------------------------------------------------------------
DIE MASSE, UND JEDES EINZELN
30 x 30 AM RECHNER: Das Zeichen ist 15 px, ringsum 7 px Luft. Kleiner
wird der Papierkorb zum Fleck; groesser braucht die Reihe mehr Platz,
als sie sagt.
44 x 44 AM FINGER (unten im coarse-Block): Hausregel, keine
Abwaegung. Fuenf mal 44 plus Abstaende sind 236 px -- eine Blase auf
412 px hat 251 px innen. Die Reihe passt damit auf dem Handy in EINE
Zeile statt in drei.
KEINE FLAECHE IM RUHEZUSTAND. Fuenf Kreise nebeneinander waeren
wieder ein Balken. Es gibt nur das Zeichen, gedaempft; die Flaeche
entsteht erst unter dem Zeiger. „Jeder sieht, dass es da ist" heisst
sichtbar, nicht laut.
===================================================================== */
/* Nur fuers Auge weg -- nicht fuer Vorleseprogramme, nicht fuer
`textContent`, nicht fuer die Suche im Browser. `clip-path` statt
`display: none`: Letzteres nimmt es auch aus dem Vorlesebaum. */
.chat-nachricht__wort {
position: absolute;
width: 1px; height: 1px;
margin: -1px; padding: 0; border: 0;
overflow: hidden; white-space: nowrap;
clip-path: inset(50%);
}
.inhalt.chat-seite .chat-nachricht__fuss {
/* EINE ZEILE, NICHT DREI. `nowrap` waere falsch -- bei einer sehr
schmalen Blase muss die Reihe umbrechen duerfen, sonst schiebt sie
die Blase auf. Sie braucht nur so wenig Platz, dass sie es fast
nie tut. */
column-gap: 1px; row-gap: 2px;
margin: 8px -6px -2px; padding: 3px 5px;
border-radius: 12px;
}
.inhalt.chat-seite .chat-nachricht__fuss button {
width: 30px; height: 30px;
min-width: 0;
padding: 0;
gap: 0;
border-radius: 999px;
border-color: transparent;
background: none;
opacity: .55;
}
.inhalt.chat-seite .chat-nachricht__fuss button::before {
width: 15px; height: 15px;
-webkit-mask-size: 15px 15px;
mask-size: 15px 15px;
}
/* DIE FLAECHE ENTSTEHT ERST UNTER DEM ZEIGER. Im Ruhezustand ist da
nur das Zeichen -- deshalb zieht die Reihe keine Aufmerksamkeit und
ist trotzdem sichtbar. */
.inhalt.chat-seite .chat-nachricht__fuss button:hover,
.inhalt.chat-seite .chat-nachricht__fuss button:focus-visible {
opacity: 1;
background: rgba(255, 255, 255, .12);
border-color: transparent;
}
/* Das Notfall-Loeschen bleibt das einzige, das im Ruhezustand Farbe
traegt: Wer fremde Worte entfernt, soll den Knopf nicht mit dem
daneben verwechseln. */
.inhalt.chat-seite .chat-nachricht__weg-knopf[data-notfall="ja"] { opacity: .7; }
.inhalt.chat-seite .chat-nachricht__weg-knopf[data-notfall="ja"]:hover {
background: color-mix(in srgb, var(--warn) 22%, transparent);
}
/* Angeheftet ist ein ZUSTAND, kein Griff -- die Nadel bleibt sichtbar,
auch wenn niemand hinzeigt. Sonst muesste man jede Nachricht
ueberfahren, um zu sehen, welche haengt. */
.inhalt.chat-seite .chat-nachricht__pin-knopf[data-gesetzt="ja"] {
opacity: 1; color: var(--pin);
}
/* „kopiert" hat kein eigenes Wort mehr, also braucht es ein eigenes
Zeichen: Der Knopf wird fuer anderthalb Sekunden gruen und traegt
einen Haken. Ohne das waere der Druck folgenlos -- man weiss nicht,
ob es geklappt hat. */
.inhalt.chat-seite .chat-nachricht__kopie-knopf[data-getan="ja"] {
opacity: 1;
color: #8fe3b0;
background: rgba(143, 227, 176, .16);
--zeichen: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M4.5 12.5 9.5 17.5 19.5 6.5'/></svg>");
}
/* Die Uhrzeit bleibt das einzige Wort in der Reihe -- sie ist die
Auskunft, alles andere ist Bedienung. Sie rueckt nach links, die
Zeichen nach rechts. */
.inhalt.chat-seite .chat-nachricht__zeit {
padding: 2px 7px;
margin-right: auto;
/* KEINE EIGENE GROESSE MEHR. Der erste Anlauf setzte .7rem = 11,2 px,
und pruef-css-klassen hat es sofort gemeldet -- die Hausgrenze
liegt bei 11,5. Sie erbt jetzt die .72rem der Reihe; leiser wird
sie durch die Deckung, nicht durch die Groesse. Das ist heute das
dritte Mal derselbe Reflex („klein wirkt leise"), und die Pruefung
hat ihn dreimal gefangen. */
opacity: .8;
}
@media (pointer: coarse) {
/* HAUSREGEL, KEINE ABWAEGUNG: 44 px am Daumen. Fuenf mal 44 plus
vier Abstaende sind 236 px -- eine Blase hat auf 412 px innen
251 px. Die Reihe bleibt damit einzeilig. */
.inhalt.chat-seite .chat-nachricht__fuss button {
width: 44px; height: 44px; min-width: 44px; min-height: 44px;
}
}
/* =====================================================================
AUF DEM HANDY RUECKT ALLES ENGER (25.09.2026)
Gemessen bei 412 px: Die Blase ist dort rund 270 px breit, und
fuenf Woerter plus Uhrzeit brauchen DREI Zeilen. Im Bildschirmfoto
stand unter zwei Zeilen Text ein dreizeiliger Block aus Handgriffen
-- mehr Bedienung als Inhalt.
ENGER, NICHT WENIGER: Kein Knopf faellt weg. Die Entscheidung vom
23.09.2026 gilt unveraendert -- auf dem Handy gibt es kein
Ueberfahren, und was man dort nicht erreicht, gibt es dort nicht.
Es werden nur Schrift, Abstand und Polsterung so weit
zurueckgenommen, dass zwei Zeilen reichen.
DIE BLASE DARF DAFUER BREITER WERDEN: 66 % sind auf einem
Telefonbildschirm keine gute Zeilenlaenge, sondern eine unnoetige
Verengung -- die Regel dafuer (62 Zeichen) greift dort ohnehin nie.
WARUM DIESER BLOCK GANZ AM ENDE DER DATEI STEHT: Eine Medienabfrage
erhoeht die Spezifitaet NICHT. Stand er weiter oben, gewann jede
spaetere Basisregel gegen ihn -- beim ersten Anlauf genau so
geschehen: `margin-right: auto` an der Uhrzeit kam danach und hat
die Handgriffe weiter in die dritte Zeile geschoben, obwohl hier
`margin-right: 0` stand. Aenderungen fuer kleine Schirme gehoeren
ans Ende, sonst greifen sie halb.
===================================================================== */
@media (max-width: 560px) {
.chat-nachricht { max-width: 86%; }
.chat-nachricht__fuss {
column-gap: 2px; row-gap: 0;
/* AUCH AUF DEM HANDY NICHT KLEINER (25.09.2026) -- dort erst
recht nicht. Was Platz spart, ist stattdessen der Verzicht auf
Versalien: Kleinbuchstaben sind schmaler, und die Zeile passt
damit in zwei statt drei Reihen, ohne dass die Schrift
schrumpft. */
font-size: .72rem; letter-spacing: .02em; text-transform: none;
/* DIE MULDE ZIEHT MIT (25.09.2026). Seit die Fusszeile eine
eingesenkte Flaeche ist, reicht es nicht mehr, oben Abstand
wegzunehmen -- die Polsterung der Mulde selbst gehoert dazu.
Bliebe hier `padding-top`, haette die Mulde auf dem Handy
unten 6 px und oben 6+6 px, und sie saesse schief. */
margin: 8px -7px -2px; padding: 5px 6px;
border-radius: 12px;
}
/* DIE ENGE FASSUNG VON HEUTE FRUEH IST UEBERHOLT (25.09.2026).
Hier standen kleinere Zeichen und engere Polsterung, damit die
fuenf WOERTER in zwei Zeilen passen. Es gibt keine Woerter mehr --
die Reihe ist einzeilig, und kleiner zu machen waere jetzt das
Gegenteil: Am Daumen gilt 44 px, und der Platz ist da.
Die Zeichen bleiben deshalb auch auf dem Handy 15 px. Ein
Papierkorb mit 12 px ist ein Fleck. */
.chat-nachricht__fuss button::before {
width: 15px; height: 15px;
-webkit-mask-size: 15px 15px;
mask-size: 15px 15px;
}
/* Die Mindestbreite der Sprachnachricht (240 px) gilt am Rechner.
Hier ist die Blase selbst nur rund 250 px breit -- 240 plus
Polsterung passen nicht mehr hinein und wuerden sie aufschieben. */
.chat-ton { min-width: 0; width: 100%; }
/* Die Uhrzeit gibt ihr Schild ab: Auf dem Handy zaehlt jede
Polsterung, und die Trennung zwischen Angabe und Knopf macht
hier ohnehin schon die Reihenfolge. */
.chat-nachricht__zeit { padding: 0 2px; background: none; }
/* KEIN `margin-right: auto` AUF DEM HANDY. Am Rechner schiebt es
die Handgriffe nach rechts und trennt sie von der Angabe -- gut.
Auf 412 px nimmt es die ganze erste Zeile fuer die Uhrzeit, und
die fuenf Woerter fangen erst darunter an und brauchen dann noch
zwei Zeilen. Gemessen: drei Zeilen statt zwei, und schuld war
eine Regel, die fuer den Rechner richtig ist. */
.chat-nachricht__zeit { letter-spacing: .04em; margin-right: 0; }
/* Die Knopfgruppe oben rechts: Auf 412 px schob ihre Polsterung
sie unter den Titel. Ohne sie passt sie wieder daneben. */
.chat__kopf-knoepfe { padding: 2px; gap: 2px; border-radius: 11px; }
/* DAS GESICHT IM KOPF BLEIBT AM HANDY WEG. Die Rechnung steht bei
`.chat__kopf-zeichen` weiter oben: Mit ihm blieben dem Namen
126 px, seine Untergrenze sind 128 -- die Knopfreihe fiele eine
Zeile tiefer und der Kopf waere 44 px hoeher. Zwei Klassen weit
genug (`.chat__kopf .chat__kopf-zeichen`), um die Grundregel
`.chat-raum__zeichen { display: grid }` zu schlagen; eine
Medienabfrage allein erhoeht die Spezifitaet nicht. */
.chat__kopf .chat__kopf-zeichen { display: none; }
}
/* =====================================================================
=====================================================================
DIE BILDSCHAU (25.09.2026)
=====================================================================
=====================================================================
Filipe: „wenn man bilder aufmacht, will ich dass die in der mitte
sind. beim hochformat soll links der husky sein und rechts der hase
und beim querformat soll oben dogfather und unten team dogi stehen
da wo platz ist. … ich will nicht dahin geschmissen sondern was
richtig geiles mit einem geilen hintergrund."
DER GRUND IST DREI SCHICHTEN, nicht eine Farbe: ein tiefer Verlauf,
drei weiche Lichter (violett, tuerkis, ein warmer Rest) und ein
Schleier ganz aussen. Zusammen unter zehn Prozent Deckung -- ein
Foto soll darauf liegen, nicht dagegen ankaempfen.
KEIN REINES SCHWARZ. Genau das zeigt der Browser von sich aus, und
genau daran hat Filipe es gemerkt. Schwarz ist keine Gestaltung,
sondern ihr Fehlen.
===================================================================== */
.bildschau {
width: 100vw; max-width: 100vw;
height: 100dvh; max-height: 100dvh;
padding: 0; margin: 0; border: 0;
background: none;
overflow: hidden;
color: var(--text, #e8f1fa);
}
.bildschau::backdrop { background: rgba(3, 4, 9, .86); backdrop-filter: blur(6px); }
.bildschau__grund {
position: absolute; inset: 0; z-index: 0;
background:
radial-gradient(70% 55% at 18% 8%, rgba(122, 92, 255, .16), transparent 66%),
radial-gradient(62% 52% at 84% 88%, rgba(38, 200, 196, .13), transparent 68%),
radial-gradient(48% 40% at 60% 46%, rgba(255, 176, 92, .06), transparent 70%),
linear-gradient(168deg, #0a0b14 0%, #070811 55%, #05060c 100%);
}
/* Ein Schleier von aussen nach innen -- er zieht den Blick in die
Mitte, ohne dass man ihn als Rahmen bemerkt. */
.bildschau__grund::after {
content: ""; position: absolute; inset: 0;
background: radial-gradient(120% 95% at 50% 50%, transparent 52%, rgba(0, 0, 0, .55) 100%);
}
/* ---- Die Buehne: das Bild sitzt in der MITTE ----------------------- */
.bildschau__buehne {
position: absolute; inset: 0; z-index: 2;
display: grid; place-items: center;
padding: 72px 4vw 56px;
}
.bildschau__bild {
max-width: 92vw; max-height: 82dvh;
width: auto; height: auto;
border-radius: 14px;
/* Ein feiner heller Saum trennt das Foto vom Grund, auch wenn seine
Raender selbst dunkel sind. Ohne ihn franst ein dunkles Foto in
den Hintergrund aus, und man sieht nicht mehr, wo es aufhoert. */
box-shadow:
0 0 0 1px rgba(255, 255, 255, .1),
0 40px 90px -40px rgba(0, 0, 0, .95),
0 0 90px -40px rgba(122, 92, 255, .5);
}
/* ---- Die Begleiter ------------------------------------------------- */
/* Sie liegen HINTER dem Bild (z-index 1 gegen 2) -- ein Husky, der
ueber einem Foto liegt, waere keine Zierde, sondern ein Hindernis. */
.bildschau__figur {
position: absolute; bottom: 0; z-index: 1;
height: min(78dvh, 720px);
width: auto;
opacity: 0;
pointer-events: none;
transition: opacity .32s ease;
}
.bildschau__figur--links { left: 0; }
/* NICHT SPIEGELN. Der erste Anlauf drehte den Hasen um, damit beide
„nach innen" schauen -- ein alter Reflex aus dem Plakatsatz. Auf dem
Probebild stand danach „Hasi Dog" seitenverkehrt auf seinem Hoodie.
Beide Figuren sehen ohnehin nach vorn; es gibt nichts zu spiegeln,
und Schrift im Bild spiegelt man nie. */
.bildschau__figur--rechts { right: 0; }
.bildschau[data-lage="hoch"] .bildschau__figur { opacity: .92; }
/* ---- Die zwei Schriftzuege ----------------------------------------- */
.bildschau__wort {
position: absolute; left: 0; right: 0; z-index: 1;
display: flex; align-items: center; justify-content: center; gap: 14px;
opacity: 0;
pointer-events: none;
transition: opacity .32s ease;
}
.bildschau__wort--oben { top: 18px; }
.bildschau__wort--unten { bottom: 16px; }
.bildschau[data-lage="quer"] .bildschau__wort { opacity: 1; }
.bildschau__zeichen { width: 34px; height: 34px; filter: invert(1) opacity(.72); }
/* GESPERRT UND GROSS: Ein Schriftzug ist kein Satz. Die Sperrung macht
aus zwei Woertern ein Zeichen -- man liest es nicht, man erkennt es. */
.bildschau__wort-text {
font-size: clamp(1.1rem, 2.6vw, 1.9rem);
font-weight: 800;
letter-spacing: .34em;
text-transform: uppercase;
color: rgba(232, 241, 250, .5);
text-shadow: 0 0 26px rgba(122, 92, 255, .45);
}
.bildschau__wort--unten .bildschau__wort-text {
font-size: clamp(.9rem, 2vw, 1.4rem);
letter-spacing: .42em;
color: rgba(232, 241, 250, .34);
}
/* ---- Die Leiste ---------------------------------------------------- */
.bildschau__leiste {
position: absolute; top: 0; left: 0; right: 0; z-index: 3;
display: flex; align-items: center; gap: 10px;
padding: 12px 14px;
background: linear-gradient(180deg, rgba(4, 5, 11, .78), transparent);
}
.bildschau__name {
flex: 1; min-width: 0;
font-size: .86rem; color: rgba(232, 241, 250, .7);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 44 px hoch, auch am Rechner: Der Schliessen-Knopf ist der einzige
Weg heraus, den man SIEHT (Escape kennt nicht jeder). */
.bildschau__knopf {
flex: none;
min-height: 44px; padding: 0 14px;
display: inline-flex; align-items: center;
border: 1px solid rgba(255, 255, 255, .12);
border-radius: 999px;
background: rgba(255, 255, 255, .06);
color: var(--text, #e8f1fa);
font: inherit; font-size: .84rem; font-weight: 600;
text-decoration: none;
cursor: pointer;
}
.bildschau__knopf:hover { background: rgba(255, 255, 255, .13); }
.bildschau__knopf:focus-visible { outline: 2px solid #b9a7ff; outline-offset: 2px; }
.bildschau__zu { min-width: 44px; justify-content: center; padding: 0; font-size: 1rem; }
@media (prefers-reduced-motion: reduce) {
.bildschau__figur, .bildschau__wort { transition: none; }
}
/* Auf einem Telefon fuellt ein Foto den Schirm -- dort gibt es keinen
Platz fuer Begleiter, und die Schau sagt das ueber `data-lage`
ohnehin selbst. Hier bleibt nur die Buehne enger. */
@media (max-width: 620px) {
.bildschau__buehne { padding: 64px 12px 24px; }
.bildschau__bild { max-width: 96vw; max-height: 78dvh; }
}