30x30 ist mit der Maus bequem und am Handy zu klein; die Grenze im Haus sind 44px. Angehoben wird nur auf Fingergeraeten (pointer: coarse), sonst staende der Knopf am Rechner unnoetig gross neben einer Zeile, die selbst nur 30 hoch ist. Sichtbar bleibt die Kachel gleich gross -- gewachsen ist die Flaeche, die den Finger annimmt. Co-Authored-By: Claude Opus 5 <[email protected]>
2445 lines
97 KiB
CSS
2445 lines
97 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;
|
||
}
|
||
|
||
.chat-nachricht {
|
||
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: 10px 13px 7px;
|
||
border: 1px solid var(--rand);
|
||
border-radius: 14px 14px 14px 4px;
|
||
/* 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, #131a25);
|
||
min-width: 0;
|
||
}
|
||
.chat-nachricht[data-folge="ja"] .chat-nachricht__blase { border-radius: 14px 14px 14px 8px; }
|
||
|
||
/* 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: 14px 14px 4px 14px;
|
||
/* Auch die eigene deckt jetzt. `color-mix` auf `transparent` liesse
|
||
das Foto durch -- gemischt wird deshalb auf die Hausflaeche. */
|
||
background: var(--kachel,
|
||
color-mix(in srgb, var(--akzent) 16%, #131a25));
|
||
border-color: color-mix(in srgb, var(--akzent) 30%, transparent);
|
||
}
|
||
.chat-nachricht[data-selbst="ja"][data-folge="ja"] .chat-nachricht__blase {
|
||
border-radius: 14px 14px 8px 14px;
|
||
}
|
||
|
||
.chat-nachricht__von {
|
||
margin: 0 0 3px;
|
||
font-size: .74rem; font-weight: 700;
|
||
color: color-mix(in srgb, var(--text-leise) 85%, transparent);
|
||
}
|
||
.chat-nachricht__text {
|
||
margin: 0;
|
||
font-size: .92rem; color: var(--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.5;
|
||
}
|
||
.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: 4px;
|
||
color: var(--text-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). */
|
||
.chat-nachricht__weg-knopf {
|
||
padding: 0; border: 0; background: none;
|
||
font: inherit; font-size: .75rem;
|
||
color: inherit; cursor: pointer;
|
||
opacity: 0; transition: opacity .16s ease, color .16s ease;
|
||
}
|
||
.chat-nachricht:hover .chat-nachricht__weg-knopf,
|
||
.chat-nachricht__weg-knopf:focus-visible { opacity: 1; }
|
||
.chat-nachricht__weg-knopf:hover { color: var(--warn); }
|
||
|
||
/* 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;
|
||
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;
|
||
}
|
||
.chat__eingabe textarea {
|
||
flex: 1; min-width: 0;
|
||
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 ------------------------------------------ */
|
||
.chat-nachricht__blase {
|
||
border-radius: 16px 16px 16px 5px;
|
||
box-shadow:
|
||
inset 0 1px 0 rgba(255, 255, 255, .06),
|
||
0 2px 6px -3px rgba(0, 0, 0, .55);
|
||
}
|
||
/* Die erste Blase einer Folge bekommt oben eine eckige Ecke -- dort
|
||
fängt der Gedanke an. Die folgenden sind rundum weich. */
|
||
.chat-nachricht[data-folge="ja"] .chat-nachricht__blase {
|
||
border-top-left-radius: 8px;
|
||
}
|
||
.chat-nachricht[data-selbst="ja"] .chat-nachricht__blase {
|
||
border-radius: 16px 16px 5px 16px;
|
||
/* DIESE REGEL IST DIE ZWEITE FÜR DIESELBE KACHEL (20.09.2026).
|
||
|
||
Weiter oben steht schon eine -- und genau daran wäre die eigene
|
||
Kachel beinahe transparent geblieben: Dort wurde `--kachel`
|
||
eingebaut, hier gewinnt der Verlauf, und der kannte die Farbe
|
||
nicht. Gemessen am Bildschirm: rgba(0,0,0,0), also nichts.
|
||
|
||
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 -- deshalb
|
||
stattdessen: BEIDE kennen `--kachel`, und diese Zeile hier sagt
|
||
es dazu.
|
||
|
||
.95 ist zu .99 geworden: Seit das Bühnenbild durchscheint, sind
|
||
fünf Prozent Foto in der Schriftfläche sichtbar -- und zwar
|
||
wandernd, weil das Bild fest steht und die Kachel scrollt. */
|
||
background: linear-gradient(160deg,
|
||
color-mix(in srgb, var(--akzent) 26%, var(--kachel, rgba(17, 24, 37, .99))),
|
||
color-mix(in srgb, var(--akzent) 12%, var(--kachel, rgba(12, 17, 27, .99))));
|
||
box-shadow:
|
||
inset 0 1px 0 rgba(255, 255, 255, .10),
|
||
0 2px 8px -3px color-mix(in srgb, var(--akzent) 45%, transparent);
|
||
}
|
||
.chat-nachricht[data-selbst="ja"][data-folge="ja"] .chat-nachricht__blase {
|
||
border-top-right-radius: 8px;
|
||
border-top-left-radius: 16px;
|
||
}
|
||
|
||
/* 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;
|
||
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);
|
||
}
|
||
|
||
/* ---- 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"] { 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: "¹3";
|
||
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. */
|
||
}
|