Files
swyxweb/frontend/src/index.css
T
SvenandClaude Fable 5 715720fbb3 Erfolgreiche Verbindung merken und automatisch wieder aufbauen; Hinweistexte gekürzt
Die zuletzt erfolgreich verbundene SwyxTray-Adresse landet im localStorage;
beim Laden der Seite wird damit sofort wieder verbunden, manuelles Trennen
vergisst sie. Untertitel, Backend-Hinweis und Webhook-Erklärtexte entfernt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:36:24 +02:00

872 lines
15 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Farb- und Schriftvorgaben aus dem STADTBOTE-Styleguide (HANSETRANS Brandbook):
* Primär Rot #CA0D38 (Pantone 185 C) und Grau #7C7F7E (Pantone 424 C),
* Off-Black #222222 für Fließtext, Grauabstufungen als Flächen.
* Schrift: Red Hat Display (Überschriften, Versalien, Laufweite 4 %) und
* Red Hat Text (Fließtext). Buttons: primär vollflächig, sekundär mit Rahmen,
* Kästen und Linien mit leichter Abrundung.
*/
:root {
--bg: #ffffff;
--surface: #ffffff;
--surface-2: #f6f6f6;
--border: #dcdcdd;
--border-strong: #b4b4b5;
--text: #222222;
--text-muted: #7c7f7e;
/* Markenrot laut Styleguide (RGB 202/13/56, Pantone 185 C) in beiden
Farbmodi identisch, das Brandbook kennt nur diesen einen Rotwert. */
--brand: #ca0d38;
--brand-strong: #a30a2d;
--brand-soft: rgb(202 13 56 / 8%);
--accent: #ca0d38;
--ok: #2f9e6e;
--warn: #b98a1c;
--err: #d92b1f;
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #17181a;
--surface: #1f2023;
--surface-2: #28292d;
--border: #3a3b40;
--border-strong: #55565c;
--text: #f1f1f2;
--text-muted: #a4a7a8;
--brand-soft: rgb(202 13 56 / 14%);
--ok: #43c78f;
--warn: #e0b341;
--err: #f2665b;
color-scheme: dark;
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: 'Red Hat Text', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
font-size: 15px;
line-height: 1.4;
}
h1,
h2,
h3 {
/* Überschriften laut Styleguide: Red Hat Display Semibold in Versalien,
Laufweite 4 %, Zeilenabstand 100 %. */
font-family: 'Red Hat Display', 'Red Hat Text', system-ui, sans-serif;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
line-height: 1;
}
code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.9em;
}
.page {
max-width: 900px;
margin: 0 auto;
padding: 32px 20px 48px;
display: flex;
flex-direction: column;
gap: 20px;
}
.page__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
/* Abgerundete Linie als Trennlinie unter dem Kopf Gestaltungselement des CI. */
.page__header::after {
content: '';
flex-basis: 100%;
height: 3px;
border-radius: 999px;
background: var(--brand);
}
.brand {
display: flex;
align-items: center;
gap: 14px;
color: var(--accent);
}
.brand__signet {
width: 46px;
height: 46px;
flex: 0 0 auto;
}
.brand__name {
margin: 0;
font-weight: 700;
font-size: 24px;
letter-spacing: 0.06em;
color: var(--accent);
}
.page__subtitle {
margin: 4px 0 0;
color: var(--text-muted);
}
.page__main {
display: flex;
flex-direction: column;
gap: 16px;
}
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 18px;
display: flex;
flex-direction: column;
gap: 14px;
}
.card h2 {
margin: 0;
font-size: 15px;
color: var(--text);
}
.card__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.row {
display: flex;
align-items: flex-end;
gap: 10px;
flex-wrap: wrap;
}
.row__actions {
display: flex;
gap: 8px;
}
.field {
display: flex;
flex-direction: column;
gap: 6px;
flex: 1 1 260px;
min-width: 0;
}
.field__label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
}
.field__input {
width: 100%;
padding: 9px 12px;
border-radius: 6px;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--text);
font: inherit;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 14px;
}
.field__input:focus {
outline: 2px solid var(--brand);
outline-offset: 1px;
border-color: var(--brand);
}
.field__input:disabled {
opacity: 0.55;
background: var(--surface-2);
}
/* Sekundärbutton laut Styleguide: schlichter roter Rahmen, leichte Abrundung. */
.button {
padding: 9px 16px;
border-radius: 6px;
border: 1px solid var(--accent);
background: transparent;
color: var(--accent);
font: inherit;
font-weight: 500;
cursor: pointer;
}
.button:hover:not(:disabled) {
background: var(--brand-soft);
}
.button:disabled {
opacity: 0.45;
cursor: not-allowed;
}
/* Primärbutton laut Styleguide: vollflächig im Markenrot. */
.button--primary {
background: var(--brand);
border-color: var(--brand);
color: #fff;
}
.button--primary:hover:not(:disabled) {
background: var(--brand-strong);
border-color: var(--brand-strong);
}
.button--ghost {
border-color: transparent;
background: transparent;
padding: 5px 10px;
font-size: 13px;
}
.note {
margin: 0;
font-size: 13px;
color: var(--text-muted);
}
.note--error {
color: var(--err);
}
.note--success {
color: var(--ok);
}
.tabs {
display: flex;
gap: 18px;
border-bottom: 1px solid var(--border);
flex-wrap: wrap;
}
.tabs__button {
padding: 10px 2px;
border: none;
border-bottom: 3px solid transparent;
margin-bottom: -1px;
border-radius: 0;
background: transparent;
color: var(--text-muted);
font: inherit;
font-family: 'Red Hat Display', 'Red Hat Text', system-ui, sans-serif;
font-weight: 600;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.04em;
cursor: pointer;
}
.tabs__button:hover:not(.tabs__button--active) {
color: var(--text);
}
.tabs__button--active {
color: var(--accent);
border-bottom-color: var(--brand);
}
[role='tabpanel'] {
display: flex;
flex-direction: column;
gap: 16px;
}
/* Muss nach der Regel oben stehen: display:flex schlägt sonst das hidden-Attribut. */
[role='tabpanel'][hidden] {
display: none;
}
.badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
border-radius: 999px;
border: 1px solid var(--border);
background: var(--surface);
font-size: 13px;
font-weight: 500;
white-space: nowrap;
}
.badge__dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--text-muted);
}
.badge--open .badge__dot {
background: var(--ok);
}
.badge--connecting .badge__dot,
.badge--closing .badge__dot {
background: var(--warn);
animation: pulse 1.1s ease-in-out infinite;
}
.badge--error .badge__dot,
.badge--closed .badge__dot {
background: var(--err);
}
@keyframes pulse {
50% {
opacity: 0.25;
}
}
@media (prefers-reduced-motion: reduce) {
.badge__dot {
animation: none;
}
}
/* --- Eingehender Anruf --- */
.card--ringing {
border-color: var(--ok);
box-shadow: 0 0 0 1px var(--ok);
}
.ringing {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.ringing__icon {
font-size: 30px;
animation: shake 1s ease-in-out infinite;
}
.ringing__text {
flex: 1 1 200px;
min-width: 0;
}
.ringing__label {
margin: 0;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
}
.ringing__number {
margin: 2px 0 0;
font-size: 22px;
font-weight: 600;
word-break: break-all;
}
.ringing__meta {
margin: 2px 0 0;
color: var(--text-muted);
font-size: 13px;
}
.ringing__actions {
display: flex;
gap: 8px;
}
@keyframes shake {
25% {
transform: rotate(-14deg);
}
75% {
transform: rotate(14deg);
}
}
@media (prefers-reduced-motion: reduce) {
.ringing__icon {
animation: none;
}
}
.button--accept {
background: var(--ok);
border-color: var(--ok);
color: #fff;
}
.button--accept:hover:not(:disabled) {
background: var(--ok);
opacity: 0.9;
}
.button--reject {
background: var(--err);
border-color: var(--err);
color: #fff;
}
.button--reject:hover:not(:disabled) {
background: var(--err);
opacity: 0.9;
}
.button--small {
padding: 5px 12px;
font-size: 13px;
}
/* --- Anruflisten --- */
.calls,
.history {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.calls__item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface-2);
}
.calls__item--incoming {
border-color: var(--ok);
}
.calls__line,
.history__line {
flex: 0 0 auto;
padding: 2px 8px;
border-radius: 4px;
background: var(--border);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
font-weight: 600;
}
.calls__info {
display: flex;
flex-direction: column;
min-width: 0;
}
.calls__number {
font-weight: 600;
word-break: break-all;
}
.calls__state {
font-size: 13px;
color: var(--text-muted);
}
.calls__actions {
display: flex;
gap: 8px;
}
.history__item {
display: flex;
align-items: baseline;
gap: 10px;
flex-wrap: wrap;
font-size: 14px;
}
.history__time {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 13px;
color: var(--text-muted);
min-width: 68px;
}
.history__badge {
padding: 1px 8px;
border-radius: 999px;
border: 1px solid var(--border);
font-size: 12px;
white-space: nowrap;
}
.history__badge--incoming {
border-color: var(--ok);
color: var(--ok);
}
.history__badge--connected,
.history__badge--outgoing {
border-color: var(--accent);
color: var(--accent);
}
.history__badge--ended {
border-color: var(--border-strong);
color: var(--text-muted);
}
.history__number {
word-break: break-all;
}
.history__meta {
color: var(--text-muted);
font-size: 13px;
}
/* --- Tabs des Firefox-Plugins --- */
.tablist {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.tablist__item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface-2);
}
.tablist__item--active {
border-color: var(--accent);
}
.tablist__id {
flex: 0 0 auto;
padding: 2px 8px;
border-radius: 4px;
background: var(--border);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
font-weight: 600;
}
.tablist__info {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-width: 0;
}
.tablist__title {
display: flex;
align-items: baseline;
gap: 8px;
font-weight: 600;
/* Lange Titel dürfen die Zeile nicht sprengen. */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tablist__flag {
flex: 0 0 auto;
padding: 1px 8px;
border-radius: 999px;
border: 1px solid var(--accent);
color: var(--accent);
font-size: 12px;
font-weight: 500;
}
.tablist__url {
font-size: 13px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.overlay {
position: fixed;
inset: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: rgb(0 0 0 / 55%);
}
.dialog {
width: min(420px, 100%);
padding: 24px;
border-radius: 8px;
border: 1px solid var(--border);
background: var(--surface);
box-shadow: 0 24px 60px rgb(0 0 0 / 25%);
}
.dialog__title {
margin: 0 0 16px;
font-size: 17px;
}
.dialog__status {
margin: 12px 0 0;
font-size: 14px;
color: var(--text-muted);
}
.dialog__detail {
display: block;
}
.dialog__actions {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
.progress {
height: 8px;
border-radius: 999px;
background: var(--surface-2);
border: 1px solid var(--border);
overflow: hidden;
}
.progress__bar {
height: 100%;
border-radius: 999px;
background: var(--brand);
transition: width 120ms linear;
}
/* Umfang noch unbekannt: ein wanderndes Stück statt eines Füllstands. */
.progress__bar--unknown {
width: 35%;
animation: progress-slide 1.1s ease-in-out infinite;
}
@keyframes progress-slide {
from {
transform: translateX(-100%);
}
to {
transform: translateX(300%);
}
}
.contacts {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
/* Mehrere hundert Einträge die Liste darf die Seite nicht sprengen. */
max-height: 520px;
overflow-y: auto;
}
.contacts__item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface-2);
}
.contacts__info {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-width: 0;
}
.contacts__name {
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.contacts__description {
font-size: 13px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.contacts__number {
flex: 0 0 auto;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 14px;
font-weight: 600;
}
.log {
height: 300px;
overflow-y: auto;
padding: 12px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface-2);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 13px;
display: flex;
flex-direction: column;
gap: 4px;
}
.log--empty {
align-items: center;
justify-content: center;
color: var(--text-muted);
margin: 0;
}
.log__entry {
display: grid;
grid-template-columns: auto auto 1fr;
gap: 8px;
align-items: baseline;
}
.log__time {
color: var(--text-muted);
}
.log__text {
word-break: break-word;
white-space: pre-wrap;
}
.log__entry--in .log__arrow {
color: var(--ok);
}
.log__entry--out .log__arrow {
color: var(--accent);
}
.log__entry--system {
color: var(--text-muted);
}
/* Webhook: eingegangene Nachrichten, jüngste zuerst. */
.webhook {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.webhook__item {
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface-2);
}
.webhook__meta {
display: flex;
align-items: baseline;
gap: 8px;
/* Bei schmalem Fenster darf die Kopfzeile umbrechen, statt zu überlaufen. */
flex-wrap: wrap;
}
.webhook__time {
font-variant-numeric: tabular-nums;
color: var(--text-muted);
font-size: 13px;
}
.webhook__id {
padding: 1px 8px;
border-radius: 4px;
background: var(--border);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
font-weight: 600;
}
.webhook__summary {
flex: 1 1 auto;
min-width: 0;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.webhook__json {
margin: 0;
padding: 10px 12px;
border-radius: 4px;
background: var(--surface);
border: 1px solid var(--border);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 13px;
line-height: 1.45;
/* Lange Zeilen scrollen im Block, statt die Seite breit zu ziehen. */
overflow-x: auto;
/* Ein einzelner Riesenwert soll die Karte nicht sprengen. */
max-height: 320px;
overflow-y: auto;
}
.tabs__badge {
margin-left: 8px;
padding: 1px 7px;
border-radius: 999px;
background: var(--brand);
color: #fff;
font-size: 12px;
font-weight: 700;
font-variant-numeric: tabular-nums;
}