/* * Farb- und Schriftvorgaben aus dem HANSETRANS Brandbook. Vorgabe ist das * STADTBOTE-Erscheinungsbild: 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. * Das HANSETRANS-Erscheinungsbild wird weiter unten über data-brand * am Wurzelelement zugeschaltet. */ :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; /* Kopfzeile: Bild- und Wortmarke; bei STADTBOTE beide im Markenrot. */ --logo-mark: #ca0d38; --logo-word: #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; } } /* * HANSETRANS-Erscheinungsbild (HANSETRANS Brandbook 2025/10, Styleguide): * HANSETRANS Grün #68B022 (Pantone 361 C) als zentrale Akzentfarbe, * Dunkelgrün #3D821C, HANSETRANS Grau #4B4A4D als Farbe der Wortmarke, * Off-Black #222222 für Fließtext, Grauabstufungen #B4B4B5/#DCDCDD/#F6F6F6. * Umgeschaltet über data-brand am Wurzelelement (Bereich „Verbindung"). */ :root[data-brand='hansetrans'] { --brand: #68b022; --brand-strong: #3d821c; --brand-soft: rgb(104 176 34 / 10%); --accent: #68b022; --text-muted: #4b4a4d; --logo-mark: #68b022; --logo-word: #4b4a4d; } @media (prefers-color-scheme: dark) { :root[data-brand='hansetrans'] { --brand-soft: rgb(104 176 34 / 16%); --text-muted: #a4a7a8; /* Auf dunklen Flächen bleibt das Achteck grün, der Schriftzug wird weiß. */ --logo-word: #f1f1f2; } } * { 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 STADTBOTE-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; } /* HANSETRANS setzt Überschriften gemischt geschrieben mit leicht negativer Laufweite (Red Hat Display Semibold, Laufweite −20). */ :root[data-brand='hansetrans'] h1, :root[data-brand='hansetrans'] h2, :root[data-brand='hansetrans'] h3 { text-transform: none; letter-spacing: -0.02em; } 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); } .page__header-tools { display: flex; align-items: center; gap: 10px; } /* Marken-Umschalter im Badge-Stil, damit er neben dem Status nicht aus der Reihe fällt. Die Wahl gilt sofort und bleibt über Neustarts erhalten. */ .brand-switch { appearance: none; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text); font: inherit; font-size: 13px; cursor: pointer; } .brand-switch:hover { border-color: var(--border-strong); } .brand { display: flex; align-items: center; gap: 14px; color: var(--logo-mark); } .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(--logo-word); } /* Die HANSETRANS-Wortmarke steht kursiv („Brandon Grotesque Bold Italic" – hier mit der Hausschrift angenähert) in HANSETRANS Grau bzw. Weiß. */ :root[data-brand='hansetrans'] .brand__name { font-style: italic; letter-spacing: 0.02em; } .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; } /* Auch Links treten als Knopf auf (z. B. „Auftrag öffnen" im Anruf-Popup). */ a.button { display: inline-flex; align-items: center; text-decoration: none; } .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; } } .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; gap: 8px; margin-top: 20px; } /* Schiebt einen Knopf an den linken Rand der Aktionszeile („Anruf annehmen"). */ .dialog__actions-start { margin-right: auto; } /* Die Job-Knöpfe des Anruf-Popups: einer je Kennung, umbrechend. */ .dialog__jobs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; } .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; }