Zwei Auftraege vom 23.09.2026.
SCREEN 1: "da steht links immer noch der treff anstatt das rudel"
Und er hatte recht, auf eine Art, die niemand sehen konnte:
TREFF_NAME stand schon seit der Umbenennung auf "Das Rudel". Nur
setzt treffRaumId() den Namen ausschliesslich BEIM ANLEGEN -- der
Raum existierte laengst, also blieb die Zeile in der Datenbank auf
"Der Treff" stehen. Im Code das eine, auf dem Bildschirm das andere.
Dieselbe Falle stand direkt nebenan schon beschrieben ("drei Stellen,
von denen die dritte vergessen wird") -- die Vorsorge galt aber nur
fuer die Teilnehmer, nicht fuer den Namen. Eine halbe Selbstheilung
heilt die andere Haelfte nicht. Jetzt gleicht treffAngleichen() auch
den Namen ab; eine kuenftige Umbenennung ist wieder eine Zeile.
(IS NOT statt !=: Bei NULL ergaebe != in SQLite NULL, und die Zeile
bliebe unveraendert liegen.)
"und wenn wir da im chat @rudel machen will ich dass jeder in dem
chat markiert wird. nicht nur team ... und sehr wichtig ich rede nur
von dem chat wo die ganze community auch drin ist."
Bis heute erreichte der Ruf ueberall nur Team Dogi. Die Begruendung
stand im Code und war nicht falsch -- im Rudel-Raum sitzt die
Community. Genau das will Filipe jetzt, und zwar nur dort:
im Rudel-Raum -> alle, die drin sind
ueberall sonst -> Team Dogi, unveraendert
Was die alte Sorge entschaerft: RUFEN darf weiterhin nur Team Dogi --
kein Zuschauer kann alle wecken. Und die Nachtruhe gilt dort ohnehin.
darf_rudel folgt derselben Frage. Sonst entstuende ein stiller
Widerspruch: Ein Modi mit neun Zuschauern und ohne zweites
Teammitglied traefe mit @rudel neun Leute -- der Vorschlag beim
Tippen waere aber ausgeblendet. Die Funktion gaebe es, und niemand
faende sie.
Das Schild sagt jetzt die Wahrheit: "alle in diesem Chat" statt
"alle im Team". Stuende dort weiter das alte, waere es im Rudel-Raum
gelogen -- und zwar nach unten, also in die Richtung, in der man
leichtfertig drueckt.
Gegenprobe in pruef-erwaehnung: In der Testgruppe sitzen DogFather
und zwei Scouts; ein @rudel dort ruft NIEMANDEN. Waere die Regel
versehentlich im ganzen Haus aktiv, waeren die Scouts markiert.
"sonst nichts anfassen" ist damit gemessen, nicht versprochen.
SCREEN 2: "so eine art diagramm, wo man mit einem kreis herum gehen
kann und die farbe ganz genau selber auswaehlen kann"
Der Haken daran ist nicht die Optik. Die zwoelf Kacheln waren
GERECHNET, damit niemand sich unlesbar machen kann -- alle auf
derselben Leuchtdichte. Ein Farbkreis, der einfach den Farbton dreht,
wirft das weg: Ein gesaettigtes Gelb ist um ein Vielfaches heller als
ein gesaettigtes Blau, und helle Schrift ist darauf nicht mehr zu
lesen.
Der Ring ist deshalb KEINE neue Rechnung, sondern dieselbe in 360
Schritten statt in zwoelf. tools/chat-kacheln-rechnen.mjs --kreis
schreibt server/chat-kreis.js; buntest() und die Kontrastpruefung
darin gelten unveraendert. Ergebnis: ein Ring gleicher Helligkeit --
kein blendendes Gelb, kein abgesoffenes Blau. Das sieht ruhiger aus
als der uebliche Farbkreis, und genau das ist der Punkt.
Der Browser rechnet nichts. Er bekommt die 360 fertigen Farben und
legt sie in dieselbe Tabelle wie die Kacheln -- ab da ist "ton-214"
ein Schluessel wie "veilchen", und jede Stelle, die eine Farbe
nachschlaegt, funktioniert unveraendert.
Welche Kacheln neben dem Ring bleiben, wird ABGELEITET statt
aufgezaehlt: Grau hat keinen Farbton, Babyblau ist die eine helle mit
eigener Schrift. Nachgemessen liegen die elf bunten zwischen 0,0 und
2,4 von ihrer Ringfarbe entfernt, Grau bei 75,4 und Babyblau bei
192,9 -- zwischen 2,4 und 75 ist so viel Luft, dass die Schwelle
nicht knapp ist.
Gespeichert wird erst beim Loslassen. Wer einmal um den Ring fuehrt,
erzeugte sonst dreihundert Anfragen.
Gemessen (pruef-chat-neu, jetzt 32 Pruefungen, als Modi auf crew. mit
dem Finger): 265 px gross, aus 361 Farben gemalt, touch-action none
(sonst schiebt das Handy die Seite weg statt zu drehen), Drehen auf
drei Uhr ergibt genau Winkel 90, die Mitte zeigt exakt #675102,
vorgelesen als "Goldbraun, 90 Grad", in der Datenbank steht ton-90,
Pfeiltaste dreht ein Grad weiter. Und das eigentliche Versprechen:
alle 360 Toene tragen die Schrift der Blase, knappster Faktor 1,000.
Dabei zwei eigene Fehler, beide aufgeschrieben: Der erste Anlauf
wartete 30 Sekunden auf den Farbknopf -- am Handy weicht die Spalte
mit den Gespraechen zur Seite, sobald ein Chat offen ist. "Ist im
HTML" und "ist erreichbar" sind zwei Aussagen. Und die Schriftfarben
wurden an der falschen Klasse gemessen, was einen roten Haken an
einer heilen Stelle ergab.
Ausserdem: Das native confirm() beim Herausnehmen eines GIFs ist
weg -- meine eigene Abkuerzung vom Morgen. Gemeldet hat es
pruef-nachfrage, allerdings erst, nachdem der verlorene Backslash in
derselben Datei repariert war.
Zahlen: pruef-erwaehnung 122 (vorher 119), pruef-chat-neu 32
(vorher 19), pruef-nachfrage 46 bestanden.
Co-Authored-By: Claude Opus 5 <[email protected]>
3150 lines
126 KiB
CSS
3150 lines
126 KiB
CSS
/* =====================================================================
|
||
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;
|
||
}
|
||
|
||
.chat {
|
||
flex: 1;
|
||
min-height: 0; /* sonst wächst das Raster über die Fläche */
|
||
display: grid;
|
||
grid-template-columns: minmax(240px, 320px) 1fr;
|
||
gap: 0;
|
||
border: 1px solid var(--rand);
|
||
border-radius: var(--radius);
|
||
/* ==== 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;
|
||
}
|
||
|
||
.chat__spalte {
|
||
display: flex; flex-direction: column;
|
||
min-height: 0; min-width: 0;
|
||
}
|
||
/* Der Trenner zwischen Liste und Verlauf. Läuft oben und unten aus --
|
||
eine durchgehende Linie zerschneidet die Kachel in zwei. */
|
||
.chat__spalte--verlauf { position: relative; }
|
||
.chat__spalte--verlauf::before {
|
||
content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 1px;
|
||
background: linear-gradient(180deg,
|
||
transparent, var(--rand-hell) 15%, var(--rand-hell) 85%, transparent);
|
||
}
|
||
|
||
.chat__kopf {
|
||
display: flex; align-items: center; gap: 12px;
|
||
padding: 15px 17px;
|
||
border-bottom: 1px solid var(--rand);
|
||
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; }
|
||
.chat__titel {
|
||
margin: 0;
|
||
font-size: 1.02rem; font-weight: 650; color: var(--text);
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
.chat__unter {
|
||
margin: 2px 0 0;
|
||
font-size: .78rem; color: var(--text-still);
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
.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); }
|
||
|
||
.chat__suche { padding: 10px 14px 4px; flex: none; }
|
||
.chat__suche input { width: 100%; }
|
||
|
||
.chat__leer {
|
||
margin: 0; padding: 20px 18px;
|
||
font-size: .86rem; color: var(--text-still); line-height: 1.55;
|
||
}
|
||
|
||
/* ---------- Links: die Gespräche ----------------------------------------- */
|
||
|
||
.chat__liste {
|
||
flex: 1; min-height: 0;
|
||
overflow-y: auto;
|
||
margin: 0; padding: 8px; list-style: none;
|
||
display: grid; gap: 3px; align-content: start;
|
||
}
|
||
|
||
.chat-raum__knopf {
|
||
--r: var(--akzent);
|
||
width: 100%;
|
||
display: grid; grid-template-columns: auto 1fr auto;
|
||
align-items: center; gap: 11px;
|
||
padding: 10px 11px;
|
||
border: 1px solid transparent; border-radius: 12px;
|
||
background: transparent;
|
||
color: inherit; font: inherit; text-align: left; cursor: pointer;
|
||
transition: background .16s ease, border-color .16s ease;
|
||
}
|
||
.chat-raum__knopf:hover { background: rgba(255, 255, 255, .04); }
|
||
.chat-raum__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
|
||
|
||
/* Das offene Gespräch bleibt sichtbar markiert -- sonst weiß man nach
|
||
dem Scrollen nicht mehr, wo man ist. */
|
||
.chat-raum[data-offen="ja"] .chat-raum__knopf {
|
||
background: color-mix(in srgb, var(--akzent) 11%, transparent);
|
||
border-color: color-mix(in srgb, var(--akzent) 32%, transparent);
|
||
}
|
||
|
||
.chat-raum__zeichen {
|
||
flex: none;
|
||
width: 38px; height: 38px; border-radius: 50%;
|
||
display: grid; place-items: center;
|
||
font-size: .82rem; font-weight: 700;
|
||
color: var(--r);
|
||
background: color-mix(in srgb, var(--r) 13%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--r) 30%, transparent);
|
||
}
|
||
/* 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 der
|
||
Gruppe steht ohnehin daneben. */
|
||
.chat-raum__zeichen[data-gruppe="ja"] {
|
||
--r: #a0aec4;
|
||
border-radius: 12px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.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: .89rem; font-weight: 600; color: var(--text-leise);
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
.chat-raum__zeit {
|
||
flex: none;
|
||
font-size: .75rem; color: var(--text-still);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.chat-raum__vorschau {
|
||
display: block; margin-top: 2px;
|
||
font-size: .78rem; color: var(--text-still);
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
.chat-raum__vorschau[data-weg="ja"] { font-style: italic; opacity: .8; }
|
||
|
||
/* 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: 700; }
|
||
.chat-raum[data-neu="ja"] .chat-raum__vorschau { color: var(--text-leise); }
|
||
.chat-raum__zahl {
|
||
flex: none;
|
||
min-width: 21px; height: 21px; padding: 0 6px;
|
||
display: grid; place-items: center;
|
||
border-radius: 999px;
|
||
font-size: .72rem; font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
color: #0b0f16;
|
||
background: var(--akzent);
|
||
}
|
||
|
||
/* ---------- Rechts: der Verlauf ------------------------------------------ */
|
||
|
||
.chat__verlauf {
|
||
flex: 1; min-height: 0;
|
||
overflow-y: auto;
|
||
padding: 18px 18px 8px;
|
||
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);
|
||
}
|
||
.chat-tag__text {
|
||
flex: none;
|
||
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 {
|
||
--blase-text: #f3f7fc;
|
||
--blase-leise: #c4d2e2;
|
||
display: grid;
|
||
grid-template-columns: 30px 1fr;
|
||
gap: 9px;
|
||
align-items: flex-end;
|
||
max-width: 76%;
|
||
margin-top: 9px;
|
||
}
|
||
/* 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;
|
||
}
|
||
|
||
.chat-nachricht__zeichen {
|
||
--r: #a0aec4;
|
||
grid-column: 1;
|
||
width: 30px; height: 30px; border-radius: 50%;
|
||
display: grid; place-items: center;
|
||
font-size: .75rem; font-weight: 700;
|
||
color: var(--r);
|
||
background: color-mix(in srgb, var(--r) 13%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--r) 28%, transparent);
|
||
}
|
||
.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; }
|
||
|
||
.chat-nachricht__blase {
|
||
grid-column: 2;
|
||
padding: 11px 15px 8px;
|
||
border: 1px solid rgba(255, 255, 255, .13);
|
||
/* 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: 22px 22px 22px 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. */
|
||
background: var(--kachel, var(--kachel-standard));
|
||
min-width: 0;
|
||
}
|
||
.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: 22px 22px 6px 22px;
|
||
/* 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. */
|
||
background: var(--kachel, var(--kachel-standard));
|
||
border-color: color-mix(in srgb, var(--akzent) 30%, transparent);
|
||
}
|
||
.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. */
|
||
.chat-nachricht__von {
|
||
margin: 0 0 7px;
|
||
padding: 0 0 6px;
|
||
display: flex; align-items: center; gap: 8px;
|
||
font-size: .84rem; font-weight: 800;
|
||
letter-spacing: .02em;
|
||
color: var(--blase-text);
|
||
border-bottom: 1px solid color-mix(in srgb, var(--blase-text) 18%, 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); }
|
||
.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: .95rem; color: var(--blase-text);
|
||
/* 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 */
|
||
line-height: 1.55;
|
||
}
|
||
.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. */
|
||
.chat-nachricht__fuss {
|
||
display: flex; align-items: center; flex-wrap: wrap;
|
||
column-gap: 9px; row-gap: 2px;
|
||
margin-top: 5px;
|
||
/* War var(--text-leise) (#94a5bb). Diese eine Farbe war die Bremse
|
||
fuer alle zwoelf Kachelfarben -- siehe der Block oben. */
|
||
color: var(--blase-leise);
|
||
}
|
||
.chat-nachricht__zeit {
|
||
font-size: .75rem; color: inherit;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
/* 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.
|
||
===================================================================== */
|
||
.chat-nachricht__weg-knopf {
|
||
padding: 0; border: 0; background: none;
|
||
font: inherit; font-size: .75rem;
|
||
color: inherit; cursor: pointer;
|
||
transition: color .16s ease;
|
||
}
|
||
.chat-nachricht__weg-knopf:hover { color: var(--warn); }
|
||
.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;
|
||
}
|
||
.chat-nachricht__weg-knopf[data-notfall="ja"]::before {
|
||
content: ""; flex: none;
|
||
width: 6px; height: 6px; border-radius: 50%;
|
||
background: var(--warn, #ff9aa2);
|
||
/* Ein duenner dunkler Saum, damit der Punkt auch auf der hellen
|
||
Kachel eine Kante hat -- sonst verschwimmt Lachs auf Babyblau. */
|
||
box-shadow: 0 0 0 1px rgba(0, 0, 0, .35);
|
||
}
|
||
.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: 12px 14px 14px;
|
||
border-top: 1px solid var(--rand);
|
||
background: rgba(0, 0, 0, .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;
|
||
}
|
||
.chat__senden {
|
||
flex: none;
|
||
width: 42px; height: 42px;
|
||
display: grid; place-items: center;
|
||
border: 1px solid color-mix(in srgb, var(--akzent) 40%, transparent);
|
||
border-radius: 12px;
|
||
background: color-mix(in srgb, var(--akzent) 18%, transparent);
|
||
color: color-mix(in srgb, var(--akzent) 55%, #ffffff);
|
||
cursor: pointer;
|
||
transition: background .16s ease, color .16s ease;
|
||
}
|
||
.chat__senden svg { width: 20px; height: 20px; fill: currentColor; }
|
||
.chat__senden:hover {
|
||
background: color-mix(in srgb, var(--akzent) 28%, transparent);
|
||
color: #fff;
|
||
}
|
||
.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 --------------------------------------- */
|
||
.chat-raum__knopf {
|
||
position: relative;
|
||
border-radius: 12px;
|
||
margin: 0 8px 4px;
|
||
transition: background var(--tempo), box-shadow var(--tempo);
|
||
}
|
||
/* Das offene Gespräch trägt eine Schiene -- man sieht auch beim Scrollen
|
||
der Liste, wo man gerade ist. */
|
||
.chat-raum__knopf[data-an="ja"] {
|
||
background: linear-gradient(90deg,
|
||
color-mix(in srgb, var(--akzent) 16%, transparent),
|
||
rgba(255, 255, 255, .03) 55%);
|
||
box-shadow: inset 3px 0 0 var(--akzent);
|
||
}
|
||
/* Ungelesenes ist der Grund, warum man hier ist. */
|
||
.chat-raum__knopf:has(.chat-raum__zahl) {
|
||
background: rgba(255, 255, 255, .045);
|
||
}
|
||
|
||
/* ---------- 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. */
|
||
.chat-nachricht__antwort-knopf,
|
||
.chat-nachricht__reag-knopf {
|
||
border: 0; background: none; padding: 0;
|
||
font: inherit; font-size: .72rem;
|
||
color: inherit; cursor: pointer;
|
||
text-decoration: underline; text-underline-offset: 2px;
|
||
}
|
||
.chat-nachricht__antwort-knopf:hover,
|
||
.chat-nachricht__reag-knopf:hover { color: var(--text); }
|
||
.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. */
|
||
.chat-nachricht__kopie-knopf {
|
||
appearance: none; border: 0; background: none; padding: 0;
|
||
font: inherit; font-size: .72rem; font-weight: 600;
|
||
color: inherit; cursor: pointer;
|
||
text-decoration: underline; text-underline-offset: 2px;
|
||
}
|
||
.chat-nachricht__kopie-knopf:hover { color: var(--text); }
|
||
.chat-nachricht__kopie-knopf:focus-visible {
|
||
outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: 4px;
|
||
}
|
||
|
||
/* ---- 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; }
|
||
}
|
||
|
||
.chat__kopf-knoepfe {
|
||
flex: none; margin-left: auto;
|
||
display: flex; align-items: center; gap: 6px;
|
||
}
|
||
.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. */
|
||
.chat-nachricht__pin-knopf {
|
||
appearance: none; border: 0; background: none; padding: 0;
|
||
font: inherit; font-size: .72rem; font-weight: 600;
|
||
color: inherit; cursor: pointer;
|
||
text-decoration: underline; text-underline-offset: 2px;
|
||
}
|
||
.chat-nachricht__pin-knopf:hover { color: var(--pin); }
|
||
.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.
|
||
===================================================================== */
|
||
.chat__kachelknopf {
|
||
flex: 0 0 auto;
|
||
margin-left: auto;
|
||
width: 30px; height: 30px;
|
||
padding: 3px;
|
||
border: 1px solid var(--rand-hell);
|
||
border-radius: 9px;
|
||
background: transparent;
|
||
cursor: pointer;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
}
|
||
/* 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; }
|
||
}
|
||
.chat__kachelknopf:hover { border-color: var(--akzent); }
|
||
.chat__kachelknopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
|
||
.chat__kachelknopf-probe {
|
||
display: block; width: 100%; height: 100%;
|
||
border-radius: 6px;
|
||
/* 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, .10);
|
||
}
|
||
/* „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; }
|
||
.chat__eingabe .textform { order: -1; flex: 1 0 100%; margin-bottom: 2px; }
|
||
|
||
/* =====================================================================
|
||
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 ------------------------------ */
|
||
.chat-ton {
|
||
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 px hoch wie alles, was ein Daumen trifft. */
|
||
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; }
|
||
|
||
.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);
|
||
}
|
||
.kachelrad__probe { opacity: .95; }
|
||
|
||
/* 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; }
|
||
}
|