Im Reiter Rechnungen der Host-Detailansicht war die Laufzeit nie verlinkt, und in der Rechnungsliste ist diese Spalte erst ab 992 px sichtbar. Auf dem Telefon fuehrte damit kein Weg zu den Rechnungsformularen. Die Laufzeit ist jetzt ein Link und zugleich Ueberschrift der Karte; in der Liste bleibt sie auf dem Telefon sichtbar und entfaellt nur zwischen 768 und 992 px. Dafuer braucht es eine eigene Klasse: Bootstraps d-*-Hilfsklassen setzen display mit !important und ueberschreiben das Kartenlayout. Nebenbefund: Auch dieser Reiter rechnete den Einkauf ohne Rabatt - dritte Stelle nach #037 und #038. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
552 lines
12 KiB
CSS
552 lines
12 KiB
CSS
/*
|
||
* ProxLedger-Theme auf Basis von AdminLTE 4 (nur CSS) und Bootstrap 5.3.
|
||
* Farben laut Vorgabe; Info und Erfolg sind gegenüber AdminLTE abgedunkelt,
|
||
* damit weiße Schrift den Kontrast 4,5:1 erreicht.
|
||
*/
|
||
|
||
:root {
|
||
--pl-navy: #1e2a44;
|
||
--pl-primary: #007bff;
|
||
--pl-primary-dark: #0062cc;
|
||
--pl-info: #138496;
|
||
--pl-success: #1e7e34;
|
||
--pl-warning: #ffc107;
|
||
--pl-warning-text: #1f2d3d;
|
||
--pl-danger: #c82333;
|
||
--pl-neutral: #6c757d;
|
||
--pl-content-bg: #f4f6f9;
|
||
--pl-sidebar-bg: #343a40;
|
||
--pl-sidebar-text: #c2c7d0;
|
||
--pl-sidebar-divider: #4b545c;
|
||
--pl-font-mono: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
|
||
--pl-logo-p: #1e2a44;
|
||
--pl-logo-linien: #17a2b8;
|
||
|
||
--bs-primary: var(--pl-primary);
|
||
--bs-primary-rgb: 0, 123, 255;
|
||
--bs-link-color: var(--pl-primary);
|
||
--bs-link-color-rgb: 0, 123, 255;
|
||
--bs-link-hover-color: var(--pl-primary-dark);
|
||
--bs-link-hover-color-rgb: 0, 98, 204;
|
||
--bs-body-font-size: 1rem;
|
||
--lte-sidebar-width: 250px;
|
||
}
|
||
|
||
:root[data-bs-theme="dark"] {
|
||
--pl-content-bg: #1b1f24;
|
||
--pl-sidebar-bg: #22272d;
|
||
/* Auf dunklem Grund wäre das dunkle P unsichtbar. */
|
||
--pl-logo-p: #e9ecef;
|
||
}
|
||
|
||
.pl-logo-p {
|
||
fill: var(--pl-logo-p);
|
||
}
|
||
|
||
.pl-logo-linien {
|
||
stroke: var(--pl-logo-linien);
|
||
}
|
||
|
||
body {
|
||
background-color: var(--pl-content-bg);
|
||
font-size: 1rem;
|
||
}
|
||
|
||
/* ---------- Buttons und Links in Primärfarbe ---------- */
|
||
|
||
.btn-primary {
|
||
--bs-btn-bg: var(--pl-primary);
|
||
--bs-btn-border-color: var(--pl-primary);
|
||
--bs-btn-hover-bg: var(--pl-primary-dark);
|
||
--bs-btn-hover-border-color: var(--pl-primary-dark);
|
||
--bs-btn-active-bg: var(--pl-primary-dark);
|
||
--bs-btn-active-border-color: var(--pl-primary-dark);
|
||
--bs-btn-disabled-bg: var(--pl-primary);
|
||
--bs-btn-disabled-border-color: var(--pl-primary);
|
||
}
|
||
|
||
.btn-outline-primary {
|
||
--bs-btn-color: var(--pl-primary);
|
||
--bs-btn-border-color: var(--pl-primary);
|
||
--bs-btn-hover-bg: var(--pl-primary);
|
||
--bs-btn-hover-border-color: var(--pl-primary);
|
||
--bs-btn-active-bg: var(--pl-primary);
|
||
--bs-btn-active-border-color: var(--pl-primary);
|
||
}
|
||
|
||
/* ---------- Statusfarben (eigene Klassen wegen abgedunkelter Töne) ---------- */
|
||
|
||
.pl-bg-info,
|
||
.pl-bg-success,
|
||
.pl-bg-danger,
|
||
.pl-bg-neutral,
|
||
.pl-bg-primary {
|
||
color: #fff;
|
||
}
|
||
|
||
.pl-bg-info {
|
||
background-color: var(--pl-info);
|
||
}
|
||
.pl-bg-success {
|
||
background-color: var(--pl-success);
|
||
}
|
||
.pl-bg-danger {
|
||
background-color: var(--pl-danger);
|
||
}
|
||
.pl-bg-neutral {
|
||
background-color: var(--pl-neutral);
|
||
}
|
||
.pl-bg-primary {
|
||
background-color: var(--pl-primary);
|
||
}
|
||
.pl-bg-warning {
|
||
color: var(--pl-warning-text);
|
||
background-color: var(--pl-warning);
|
||
}
|
||
|
||
.pl-text-danger {
|
||
color: var(--pl-danger) !important;
|
||
}
|
||
.pl-text-success {
|
||
color: var(--pl-success) !important;
|
||
}
|
||
.pl-text-warning {
|
||
color: #9a7400 !important;
|
||
}
|
||
:root[data-bs-theme="dark"] .pl-text-warning {
|
||
color: var(--pl-warning) !important;
|
||
}
|
||
|
||
/* ---------- Sidebar ---------- */
|
||
|
||
.app-sidebar {
|
||
background-color: var(--pl-sidebar-bg);
|
||
--lte-sidebar-color: var(--pl-sidebar-text);
|
||
--lte-sidebar-hover-color: #fff;
|
||
--lte-sidebar-hover-bg: rgba(255, 255, 255, 0.08);
|
||
--lte-sidebar-menu-active-color: #fff;
|
||
--lte-sidebar-menu-active-bg: var(--pl-primary);
|
||
--lte-sidebar-header-color: #8a93a0;
|
||
--lte-sidebar-submenu-color: var(--pl-sidebar-text);
|
||
--lte-sidebar-submenu-hover-color: #fff;
|
||
--lte-sidebar-submenu-hover-bg: rgba(255, 255, 255, 0.08);
|
||
--bs-border-color: var(--pl-sidebar-divider);
|
||
}
|
||
|
||
.app-sidebar .sidebar-brand {
|
||
background-color: var(--pl-sidebar-bg);
|
||
}
|
||
|
||
.app-sidebar .brand-text {
|
||
font-weight: 300;
|
||
color: #fff;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
|
||
.app-sidebar .nav-link {
|
||
border-radius: 0.25rem;
|
||
}
|
||
|
||
.app-sidebar .nav-header {
|
||
padding-top: 1rem;
|
||
font-size: 0.75rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.06em;
|
||
}
|
||
|
||
.pl-sidebar-user {
|
||
display: flex;
|
||
gap: 0.75rem;
|
||
align-items: center;
|
||
padding: 0.85rem 0.9rem;
|
||
border-bottom: 1px solid var(--pl-sidebar-divider);
|
||
color: var(--pl-sidebar-text);
|
||
}
|
||
|
||
.pl-sidebar-user-avatar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 2.25rem;
|
||
height: 2.25rem;
|
||
font-weight: 600;
|
||
color: #fff;
|
||
background-color: var(--pl-info);
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.pl-sidebar-search {
|
||
padding: 0.75rem 0.9rem;
|
||
}
|
||
|
||
/* Im eingeklappten Zustand nur Icons zeigen */
|
||
.sidebar-collapse .pl-sidebar-user span,
|
||
.sidebar-collapse .pl-sidebar-search,
|
||
.sidebar-collapse .app-sidebar .brand-text {
|
||
display: none;
|
||
}
|
||
|
||
/*
|
||
* Fläche hinter dem geöffneten Menü auf schmalen Bildschirmen. Ein Knopf statt eines div,
|
||
* damit sie auch per Tastatur erreichbar ist.
|
||
*/
|
||
.pl-menu-hintergrund {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 1037; /* unter dem Menü (1038), über allem anderen */
|
||
padding: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
border: 0;
|
||
}
|
||
|
||
/* ---------- Inhaltsbereich ---------- */
|
||
|
||
.app-content-header {
|
||
padding: 1rem 0 0.5rem;
|
||
}
|
||
|
||
.app-main {
|
||
background-color: var(--pl-content-bg);
|
||
}
|
||
|
||
.pl-page-title {
|
||
margin: 0;
|
||
font-size: 1.5rem;
|
||
font-weight: 400;
|
||
}
|
||
|
||
/* ---------- Small Box ---------- */
|
||
|
||
.small-box {
|
||
overflow: hidden;
|
||
}
|
||
|
||
.small-box > .inner {
|
||
padding: 1rem 1rem 0.25rem;
|
||
}
|
||
|
||
.small-box h3 {
|
||
font-size: 2.2rem;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.small-box .small-box-icon {
|
||
position: absolute;
|
||
top: 0.75rem;
|
||
right: 1rem;
|
||
font-size: 3.25rem;
|
||
line-height: 1;
|
||
opacity: 0.25;
|
||
}
|
||
|
||
.small-box .small-box-footer {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.small-box .small-box-footer:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
/* ---------- Karten ---------- */
|
||
|
||
.pl-card-outline-primary {
|
||
border-top: 3px solid var(--pl-primary);
|
||
}
|
||
.pl-card-outline-warning {
|
||
border-top: 3px solid var(--pl-warning);
|
||
}
|
||
.pl-card-outline-danger {
|
||
border-top: 3px solid var(--pl-danger);
|
||
}
|
||
.pl-card-outline-info {
|
||
border-top: 3px solid var(--pl-info);
|
||
}
|
||
|
||
.card-title {
|
||
font-size: 1.05rem;
|
||
font-weight: 500;
|
||
margin: 0;
|
||
}
|
||
|
||
/* ---------- Aufgabenliste (AdminLTE-Todo) ---------- */
|
||
|
||
.pl-todo-list {
|
||
padding: 0;
|
||
margin: 0;
|
||
list-style: none;
|
||
}
|
||
|
||
.pl-todo-list > li {
|
||
display: flex;
|
||
gap: 0.75rem;
|
||
align-items: flex-start;
|
||
padding: 0.65rem 0.75rem;
|
||
margin-bottom: 0.4rem;
|
||
border-radius: 0.25rem;
|
||
border-left: 3px solid var(--pl-neutral);
|
||
background-color: var(--bs-secondary-bg);
|
||
}
|
||
|
||
.pl-todo-list > li.pl-todo-gefahr {
|
||
border-left-color: var(--pl-danger);
|
||
}
|
||
.pl-todo-list > li.pl-todo-warnung {
|
||
border-left-color: var(--pl-warning);
|
||
}
|
||
.pl-todo-list > li.pl-todo-info {
|
||
border-left-color: var(--pl-info);
|
||
}
|
||
|
||
.pl-todo-erledigt .pl-todo-text {
|
||
text-decoration: line-through;
|
||
opacity: 0.6;
|
||
}
|
||
|
||
/* ---------- Monospace-Werte mit Kopierfunktion ---------- */
|
||
|
||
.pl-mono {
|
||
font-family: var(--pl-font-mono);
|
||
font-size: 0.9375em;
|
||
}
|
||
|
||
.pl-copy-button {
|
||
padding: 0 0.25rem;
|
||
font-size: 0.85em;
|
||
line-height: 1;
|
||
color: var(--bs-secondary-color);
|
||
background: none;
|
||
border: 0;
|
||
}
|
||
|
||
.pl-copy-button:hover {
|
||
color: var(--pl-primary);
|
||
}
|
||
|
||
/* ---------- Tabellen ---------- */
|
||
|
||
.pl-table-card .table {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.pl-table-card .table > :not(caption) > * > * {
|
||
padding: 0.6rem 0.75rem;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
/* ---------- Jahresbahn ---------- */
|
||
|
||
.pl-timeline-row {
|
||
position: relative;
|
||
height: 2rem;
|
||
background: linear-gradient(to right, var(--bs-secondary-bg) 1px, transparent 1px) repeat-x;
|
||
background-size: calc(100% / 12) 100%;
|
||
}
|
||
|
||
.pl-timeline-bar {
|
||
position: absolute;
|
||
top: 0.4rem;
|
||
height: 1.2rem;
|
||
border-radius: 0.6rem;
|
||
color: #fff;
|
||
font-size: 0.75rem;
|
||
line-height: 1.2rem;
|
||
padding: 0 0.5rem;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.pl-timeline-heute {
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 2px;
|
||
background-color: var(--pl-danger);
|
||
}
|
||
|
||
/* ---------- Suchdialog (Strg+K) ---------- */
|
||
|
||
.pl-search-backdrop {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 1080;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
.pl-search-dialog {
|
||
position: fixed;
|
||
top: 12vh;
|
||
left: 50%;
|
||
z-index: 1085;
|
||
width: min(680px, 92vw);
|
||
transform: translateX(-50%);
|
||
}
|
||
|
||
/* Zeitleiste der Jahresbahn: Breiten als Klassen, damit sie auf dem Telefon kleiner ausfallen. */
|
||
.pl-timeline {
|
||
min-width: 820px;
|
||
}
|
||
|
||
.pl-timeline-kopf {
|
||
margin-left: 13rem;
|
||
}
|
||
|
||
.pl-timeline-name {
|
||
width: 13rem;
|
||
}
|
||
|
||
/* Klapplisten in der Kopfzeile (Warnungen, Benutzermenü). */
|
||
.pl-klappliste {
|
||
width: 22rem;
|
||
max-width: calc(100vw - 1rem);
|
||
}
|
||
|
||
/*
|
||
* Die Laufzeit-Spalte ist auf dem Telefon der einzige Weg zu den Rechnungsformularen, deshalb
|
||
* bleibt sie dort sichtbar. Zwischen 768 und 992 px ist die Tabelle am engsten – dort entfällt sie.
|
||
* Bewusst eine eigene Klasse statt der Bootstrap-Hilfsklassen: deren `display: … !important`
|
||
* überschreibt das Kartenlayout (#039).
|
||
*/
|
||
@media (min-width: 768px) and (max-width: 991.98px) {
|
||
.pl-spalte-laufzeit {
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
/* ---------- Mobil ---------- */
|
||
|
||
@media (max-width: 575.98px) {
|
||
.pl-touch-target {
|
||
min-height: 44px;
|
||
}
|
||
|
||
/*
|
||
* Ein Kontrollkästchen darf nicht selbst 44 px hoch werden – sonst steht in der Zeile ein
|
||
* großer leerer Kasten. Die Fläche zum Treffen bekommt stattdessen sein Umfeld (#035).
|
||
*/
|
||
.pl-haken {
|
||
min-width: 44px;
|
||
min-height: 44px;
|
||
}
|
||
|
||
.pl-haken .form-check-input {
|
||
width: 1.4rem;
|
||
height: 1.4rem;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Breite Tabellen auf dem Telefon: Jede Zeile wird zur Karte, jede Zelle bekommt ihre
|
||
* Beschriftung aus `data-label` davor. Das ersetzt das Scrollen nach rechts, bei dem die
|
||
* Hälfte der Angaben unsichtbar bleibt (#035).
|
||
*
|
||
* Zellen ohne `data-label` stehen für sich – etwa eine Zeile mit Knöpfen.
|
||
*/
|
||
@media (max-width: 767.98px) {
|
||
/*
|
||
* Auf dem Telefon ist die Klappliste breiter als das Fenster – der Browser zoomt dann die
|
||
* **ganze Seite** heraus, damit sie hineinpasst. Deshalb hier fest am Fenster ausrichten
|
||
* statt am Knopf (#038).
|
||
*/
|
||
.pl-klappliste {
|
||
position: fixed;
|
||
top: 3.5rem;
|
||
right: 0.5rem;
|
||
left: 0.5rem;
|
||
width: auto;
|
||
max-width: none;
|
||
max-height: 70vh;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/*
|
||
* Lange Schlüssel und Server-IDs dürfen umbrechen. Sonst machen sie die Seite breiter als das
|
||
* Fenster – und der Browser zoomt die ganze Seite heraus, damit sie hineinpasst (#038).
|
||
*/
|
||
.pl-mono {
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.pl-karten-tabelle,
|
||
.pl-karten-tabelle tbody,
|
||
.pl-karten-tabelle tr,
|
||
.pl-karten-tabelle td {
|
||
display: block;
|
||
width: 100%;
|
||
}
|
||
|
||
.pl-karten-tabelle thead {
|
||
display: none;
|
||
}
|
||
|
||
.pl-karten-tabelle tr {
|
||
padding: 0.35rem 0.25rem;
|
||
border-bottom: 1px solid var(--bs-border-color);
|
||
}
|
||
|
||
.pl-karten-tabelle tr:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
|
||
.pl-karten-tabelle td {
|
||
display: flex;
|
||
gap: 0.75rem;
|
||
align-items: baseline;
|
||
justify-content: space-between;
|
||
padding: 0.3rem 0.75rem;
|
||
text-align: right;
|
||
border: 0;
|
||
}
|
||
|
||
.pl-karten-tabelle td::before {
|
||
flex: 0 0 auto;
|
||
font-size: 0.8125rem;
|
||
color: var(--bs-secondary-color);
|
||
text-align: left;
|
||
content: attr(data-label);
|
||
}
|
||
|
||
/* Die erste Zelle trägt den Namen – sie steht als Überschrift der Karte für sich. */
|
||
.pl-karten-tabelle td.pl-karten-kopf {
|
||
display: block;
|
||
padding-top: 0.6rem;
|
||
font-size: 1.0625rem;
|
||
text-align: left;
|
||
}
|
||
|
||
.pl-karten-tabelle td.pl-karten-kopf::before {
|
||
content: none;
|
||
}
|
||
|
||
/* Lange Namen und Schlüssel sollen umbrechen, aber nicht Buchstabe für Buchstabe. */
|
||
.pl-karten-tabelle td a,
|
||
.pl-karten-tabelle td .pl-mono {
|
||
overflow-wrap: anywhere;
|
||
word-break: normal;
|
||
}
|
||
|
||
/* Auf dem Telefon bleibt mehr Platz für die Monate, wenn die Namensspalte schrumpft. */
|
||
.pl-timeline {
|
||
min-width: 560px;
|
||
}
|
||
|
||
.pl-timeline-kopf {
|
||
margin-left: 7rem;
|
||
}
|
||
|
||
.pl-timeline-name {
|
||
width: 7rem;
|
||
}
|
||
|
||
/* Kartenkopf mit Knöpfen: untereinander statt nebeneinander über den Rand hinaus. */
|
||
.card-header {
|
||
flex-wrap: wrap;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.card-header .card-tools {
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
}
|
||
}
|