Files
Rotatory/public/style.css
T
ferdi2goandClaude Fable 5.1 3aa37033fd Logo in die Kopfzeile aufnehmen
Animierte Marke aus zwei Bögen mit Pfeilspitzen: dreht sich beim Laden einmal
abbremsend und bleibt in der symmetrischen Endstellung; bei reduzierter
Bewegung sofort statisch. Farbe folgt dem Text (Weiß auf tradeo-Blau).
Statische, animierte und Favicon-Variante unter public/logo.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:08:21 +00:00

266 lines
16 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.
/*
* Rotatory – Oberfläche nach dem tradeo Corporate Design System (docs/DESIGN.md, Stand 0.1).
* Farben: ausschließlich tradeo Blue #122E45 und Weiß. Neutraltöne sind Abstufungen von tradeo Blue
* über Deckkraft – eine offene Designentscheidung, bis das CDS Grautöne definiert (Abschnitt 3.3).
* Ebenso offen: Radius (hier 6 px), funktionale Statusfarbe (hier #B42318, nur für Fehler/Konflikte),
* Icon-Familie (hier schlichte Linien-SVGs, 1,75 px Strich). Kein Dark Mode, da im CDS nicht definiert.
*/
:root {
--tradeo-blue: #122E45;
--white: #FFFFFF;
--text: #122E45;
--text-2: rgba(18, 46, 69, .72);
--text-3: rgba(18, 46, 69, .56);
--line: rgba(18, 46, 69, .14);
--line-2: rgba(18, 46, 69, .32);
--tint-1: rgba(18, 46, 69, .04);
--tint-2: rgba(18, 46, 69, .08);
--tint-3: rgba(18, 46, 69, .16);
--danger: #B42318;
--radius: 6px;
--font-title: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
--font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
--avatar-main: 52px;
--avatar-co: 44px;
--cell-min: 104px;
}
* { box-sizing: border-box; }
html { color-scheme: light; }
body {
margin: 0;
font: 400 15px/1.5 var(--font-ui);
color: var(--text);
background: var(--white);
-webkit-font-smoothing: antialiased;
}
h1, h2, h3 { margin: 0; font-family: var(--font-title); line-height: 1.25; }
h1 { font-size: 18px; font-weight: 600; }
h2 { font-size: 22px; font-weight: 600; }
h3 { font-size: 16px; font-weight: 500; }
a { color: var(--tradeo-blue); }
[hidden] { display: none !important; }
svg.icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
/* Kopfzeile: Markenfläche in tradeo Blue mit weißer Wortmarke */
.topbar {
display: flex; flex-wrap: wrap; align-items: center; gap: 8px 32px;
padding: 0 24px; min-height: 56px;
background: var(--tradeo-blue); color: var(--white);
position: sticky; top: 0; z-index: 5;
}
.topbar h1 { color: var(--white); padding: 14px 0; display: inline-flex; align-items: center; gap: 10px; }
/* Logo: zwei Bögen, die beim Laden einmal abbremsend rotieren und in der symmetrischen Endstellung stehen bleiben */
.logo { width: 28px; height: 28px; display: block; overflow: visible; }
.logo .arc { transform-box: view-box; transform-origin: 400px 400px; animation: 7.04s cubic-bezier(.176, .23, .833, .833) 1 forwards; }
.logo .arc-a { animation-name: logo-spin-a; }
.logo .arc-b { animation-name: logo-spin-b; }
@keyframes logo-spin-a { from { transform: rotate(-538deg); } to { transform: rotate(1481.105deg); } }
@keyframes logo-spin-b { from { transform: rotate(-358.8deg); } to { transform: rotate(1660.305deg); } }
@media (prefers-reduced-motion: reduce) { .logo .arc { animation: none; } }
.topbar nav { display: flex; gap: 4px; flex-wrap: wrap; align-self: stretch; }
.topbar nav a {
display: inline-flex; align-items: center; padding: 0 12px; min-height: 56px;
text-decoration: none; color: rgba(255, 255, 255, .76); font-weight: 500; font-size: 14px;
border-bottom: 2px solid transparent;
}
.topbar nav a:hover { color: var(--white); }
.topbar nav a[aria-current="page"] { color: var(--white); border-bottom-color: var(--white); }
.topbar nav a:focus-visible { outline: 2px solid var(--white); outline-offset: -4px; }
.topbar-action { margin-left: auto; background: transparent; color: var(--white); border-color: rgba(255, 255, 255, .4); min-height: 34px; padding: 0 12px; font-size: 13px; }
.topbar-action:hover { background: rgba(255, 255, 255, .1); }
.topbar-action:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }
/* Betrachtermodus: Kalender ansehen, nichts bearbeiten */
.viewer .day { cursor: default; }
.viewer .day:hover:not(.outside) { background: var(--white); }
@media (max-width: 560px) {
.topbar { padding: 0 16px; gap: 0 16px; }
.topbar h1 { padding: 12px 0; }
.topbar nav { flex-wrap: nowrap; overflow-x: auto; width: 100%; margin: 0 -16px; padding: 0 8px; scrollbar-width: none; }
.topbar nav::-webkit-scrollbar { display: none; }
.topbar nav a { min-height: 44px; padding: 0 10px; font-size: 13px; white-space: nowrap; }
.topbar-action { margin-left: auto; margin-block: 8px; }
}
button:focus-visible, input:focus-visible, select:focus-visible, .button:focus-visible, .day:focus-visible, .avatar[tabindex]:focus-visible {
outline: 2px solid var(--tradeo-blue); outline-offset: 2px;
}
main { padding: 24px 16px 48px; max-width: 1120px; margin: 0 auto; }
@media (min-width: 720px) { main { padding: 32px 24px 64px; } }
.view > h2 { margin-bottom: 24px; }
h3 { margin: 32px 0 12px; }
/* Karten und Formulare */
.card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; margin-bottom: 24px; }
.form-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .form-grid { grid-template-columns: 1fr 1fr; } .form-grid .wide, .form-grid fieldset, .form-grid .form-actions, .form-grid .hint, .form-grid h3 { grid-column: 1 / -1; } }
.form-grid h3 { margin: 0; }
label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; font-weight: 500; color: var(--text-2); }
label.inline { flex-direction: row; align-items: center; gap: 10px; color: var(--text); font-weight: 400; font-size: 14px; }
label > input:not([type="checkbox"]), label > select { width: 100%; min-width: 0; max-width: 100%; }
.form-grid > *, .dialog-form > *, .row > label { min-width: 0; }
input, select, button, .button {
font: inherit; font-size: 15px; color: var(--text); background: var(--white);
border: 1px solid var(--line-2); border-radius: var(--radius); padding: 8px 12px; min-height: 40px;
}
input::placeholder { color: var(--text-3); }
input[type="checkbox"] { min-height: 0; width: 18px; height: 18px; margin: 0; accent-color: var(--tradeo-blue); }
fieldset.checks { border: 1px solid var(--line); border-radius: var(--radius); display: flex; flex-wrap: wrap; gap: 12px 24px; padding: 12px 16px 16px; margin: 0; }
fieldset.checks legend { font-size: 13px; font-weight: 500; color: var(--text-2); padding: 0 4px; }
fieldset.checks label { flex-direction: row; align-items: center; gap: 8px; color: var(--text); font-weight: 400; font-size: 14px; }
.row { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: end; margin-bottom: 16px; }
.row > label { flex: 1 1 180px; }
.row > button { flex: 0 0 auto; }
.hint { color: var(--text-2); font-size: 13px; margin: 4px 0 16px; }
.result { padding: 12px 16px; border-radius: var(--radius); background: var(--tint-1); font-size: 14px; white-space: pre-line; }
.result.error { color: var(--danger); }
/* Schaltflächen: primär in tradeo Blue, sekundär zurückhaltend, destruktiv nur funktional */
button, .button {
cursor: pointer; font-weight: 500; font-size: 14px; text-decoration: none; color: var(--tradeo-blue);
display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 0 16px; white-space: nowrap;
}
button:hover, .button:hover { background: var(--tint-1); }
button.primary { background: var(--tradeo-blue); color: var(--white); border-color: var(--tradeo-blue); }
button.primary:hover { box-shadow: inset 0 0 0 999px rgba(255, 255, 255, .1); background: var(--tradeo-blue); }
button.ghost, .button.ghost { border-color: transparent; }
button.danger { color: var(--danger); }
button.icon-button { width: 40px; padding: 0; }
button:disabled { opacity: .45; cursor: default; }
.form-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.form-actions .spacer { flex: 1; }
/* Kalender */
.toolbar { display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.month-nav { display: flex; align-items: center; gap: 8px; }
.month-nav h2 { min-width: 11ch; font-size: 20px; }
.actions { display: flex; gap: 8px; flex-wrap: wrap; }
.calendar { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.weekdays, .days { display: grid; grid-template-columns: repeat(5, 1fr); }
.weekdays div { font-size: 12px; font-weight: 500; color: var(--text-3); padding: 8px 10px; border-bottom: 1px solid var(--line); }
.day {
min-height: var(--cell-min); padding: 8px; border: 0; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); border-radius: 0;
display: flex; flex-direction: column; gap: 6px; align-items: stretch; justify-content: flex-start; text-align: left;
background: var(--white); color: inherit; cursor: pointer; font-weight: 400; white-space: normal;
}
.day:nth-child(5n) { border-right: 0; }
.day.outside { background: var(--tint-1); cursor: default; }
.day.outside .num { opacity: .5; }
.day.holiday { background: var(--tint-1); }
.day.past:not(.outside) { opacity: .6; }
.day:hover:not(.outside) { background: var(--tint-1); }
.day:focus-visible { outline-offset: -2px; }
.day .num { font-size: 13px; font-weight: 500; color: var(--text-3); display: flex; justify-content: space-between; align-items: center; min-height: 24px; }
.day.today .num > span:first-child { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: var(--tradeo-blue); color: var(--white); font-weight: 600; }
.day .num .lock { display: inline-flex; color: var(--text-2); }
.day .num .lock svg { width: 14px; height: 14px; }
.day .label { font-size: 12px; color: var(--text-2); line-height: 1.3; overflow-wrap: anywhere; }
.day .label.off { font-weight: 500; }
.day .pair { display: flex; gap: 8px; align-items: flex-end; justify-content: center; flex-wrap: wrap; margin-top: auto; margin-bottom: auto; }
.slot { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.slot .name { font-size: 12px; line-height: 1.2; text-align: center; max-width: 6rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); }
.slot .name.absent { color: var(--danger); text-decoration: line-through; }
.slot .avatar-wrap { position: relative; display: inline-block; }
/* Avatare: Hauptmoderation mit gefülltem, Nebenmoderation mit umrandetem Kennzeichen – eine Farbe, zwei Gewichte */
.avatar {
width: var(--avatar-main); height: var(--avatar-main); border-radius: 50%; object-fit: cover;
display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
background: var(--tint-2); color: var(--text); font-family: var(--font-title); font-weight: 600; font-size: 15px;
border: 2px solid var(--tradeo-blue);
}
.avatar.co { width: var(--avatar-co); height: var(--avatar-co); border-color: var(--line-2); font-size: 13px; }
.avatar.plain { border-color: var(--line); }
.avatar.empty { border-style: dashed; border-color: var(--line-2); color: var(--text-3); background: transparent; }
.avatar.small { width: 24px; height: 24px; border-width: 1px; font-size: 10px; }
.avatar.absent { border-color: var(--danger); }
.badge {
display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%;
font-family: var(--font-title); font-size: 10px; font-weight: 600; line-height: 1;
background: var(--tradeo-blue); color: var(--white); border: 1.5px solid var(--tradeo-blue);
}
.badge.co { background: var(--white); color: var(--tradeo-blue); }
.slot .badge { position: absolute; bottom: -3px; right: -5px; box-shadow: 0 0 0 2px var(--white); }
.legend { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 16px 0 0; font-size: 13px; color: var(--text-2); align-items: center; }
.legend > span { display: inline-flex; align-items: center; gap: 8px; }
.legend .lock { display: inline-flex; color: var(--text-2); }
.legend .lock svg { width: 16px; height: 16px; }
.stats { margin-top: 32px; }
.stats h3 { margin-top: 0; }
#stats { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; border: 1px solid var(--line); border-radius: var(--radius); font-size: 13px; }
.chip .avatar { width: 28px; height: 28px; border-width: 1px; font-size: 11px; }
.chip .count { color: var(--text-3); font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
:root { --cell-min: 88px; --avatar-main: 36px; --avatar-co: 30px; }
.avatar { font-size: 12px; } .avatar.co { font-size: 10px; }
.slot .badge { width: 16px; height: 16px; font-size: 9px; }
.slot .name { display: none; }
.day { padding: 6px 4px; gap: 4px; }
.day .pair { flex-direction: column; align-items: center; gap: 6px; }
.weekdays div { padding: 8px 6px; }
.month-nav h2 { min-width: 0; }
}
/* Fotofeld im Personenformular: Ablagefläche für Datei, Drag & Drop und Zwischenablage */
.photo-field { display: flex; gap: 16px; align-items: center; padding: 16px; border: 1px dashed var(--line-2); border-radius: var(--radius); }
.photo-field.dragover { border-color: var(--tradeo-blue); background: var(--tint-1); }
.photo-field:focus-visible { outline: 2px solid var(--tradeo-blue); outline-offset: 2px; border-style: solid; }
.photo-field .photo-preview { width: 64px; height: 64px; font-size: 18px; cursor: default; }
.photo-field .photo-preview.empty { border-style: dashed; }
.photo-text { display: grid; gap: 8px; min-width: 0; flex: 1; }
.photo-text strong { font-family: var(--font-title); font-weight: 500; font-size: 14px; }
.photo-text .hint { margin: 0; }
.photo-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.photo-actions button { min-height: 34px; padding: 0 12px; font-size: 13px; }
.list-tools { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 0 0 8px; }
.list-tools .hint { margin: 0; }
/* Listen: Zeilen mit dezenten Trennlinien statt einzelner Kästen */
.list, .person-list, .contacts-list { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--line); }
.list li, .person-list li, .contacts-list li { display: flex; align-items: center; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.list.compact li { padding: 8px 0; }
.person-list .avatar { width: 48px; height: 48px; cursor: pointer; }
.person-list .avatar.plain:hover { border-color: var(--tradeo-blue); }
.person-list .who { flex: 1; min-width: 180px; }
.person-list .who strong { display: block; font-family: var(--font-title); font-weight: 500; font-size: 15px; }
.person-list .who small, .list small, .contacts-list small { color: var(--text-2); font-size: 13px; }
.tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.tag { font-size: 12px; font-weight: 500; padding: 2px 8px; border-radius: 4px; background: var(--tint-2); color: var(--text); border: 1px solid transparent; }
.tag.main { background: var(--tradeo-blue); color: var(--white); }
.tag.co { background: var(--white); border-color: var(--tradeo-blue); }
.tag.off { background: var(--tint-3); }
.tag.conflict { background: var(--white); border-color: var(--danger); color: var(--danger); }
.list li .grow { flex: 1; min-width: 180px; }
.list li button, .person-list li button { min-height: 34px; padding: 0 12px; font-size: 13px; }
.person-list li.inactive { opacity: .55; }
.type-krankheit { color: var(--danger); }
label.inline#absence-toggle { margin-bottom: 8px; }
/* Dialoge */
dialog {
border: 1px solid var(--line); border-radius: var(--radius); padding: 0; background: var(--white); color: var(--text);
width: min(92vw, 520px); max-width: calc(100vw - 32px); box-shadow: 0 8px 24px rgba(18, 46, 69, .16);
}
dialog::backdrop { background: rgba(18, 46, 69, .4); }
.dialog-form { display: grid; gap: 16px; padding: 24px; }
.dialog-form h2 { font-size: 18px; }
.dialog-form .form-actions { margin-top: 8px; }
.contacts-list { max-height: 50vh; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.contacts-list li { padding: 8px 12px; gap: 12px; }
.contacts-list li:last-child { border-bottom: 0; }
.contacts-list li.exists { opacity: .5; }
.contacts-list label { flex-direction: row; align-items: center; gap: 12px; color: var(--text); flex: 1; cursor: pointer; font-weight: 400; font-size: 14px; }
.contacts-tools { display: flex; gap: 8px; }
.toast {
position: fixed; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); left: 50%; transform: translateX(-50%);
background: var(--tradeo-blue); color: var(--white); padding: 10px 16px; border-radius: var(--radius); font-size: 14px; z-index: 20; max-width: 90vw;
}
.toast.error { background: var(--danger); }
.status-ok, .status-warn { font-weight: 500; }
.status-warn { color: var(--danger); }
code { background: var(--tint-1); padding: 1px 6px; border-radius: 4px; font-size: .9em; }