Files
skrift-app/src/styles/global.css

1163 lines
36 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.
/**
* Skrift – Basis-Styles
* Work Sans wird lokal ausgeliefert (DSGVO: keine Google-CDN-Anfrage).
*/
@font-face {
font-family: 'Work Sans';
src:
url('/fonts/work-sans-variable.woff2') format('woff2'),
url('/fonts/WorkSans-VariableFont_wght.ttf') format('truetype');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
*,
*::before,
*::after { box-sizing: border-box; }
html, body, #root { height: 100%; }
body {
margin: 0;
background: var(--sk-bg);
color: var(--sk-text);
font-family: var(--sk-font);
font-size: var(--sk-size-base);
font-weight: var(--sk-weight-normal);
line-height: var(--sk-leading);
-webkit-font-smoothing: antialiased;
}
h1, h2, h3 {
margin: 0;
line-height: var(--sk-leading-tight);
font-weight: var(--sk-weight-semibold);
letter-spacing: -0.01em;
}
h1 { font-size: var(--sk-size-2xl); }
h2 { font-size: var(--sk-size-xl); }
h3 { font-size: var(--sk-size-lg); }
p { margin: 0; }
a { color: var(--sk-primary); text-underline-offset: 3px; }
a:hover { color: var(--sk-primary-hover); }
button { font-family: inherit; }
/* ══ Shell – volle Breite, dunkle Navigation ═════════════ */
/* Kopfleiste und Seitenleiste stehen fest; gescrollt wird ausschließlich
der Inhaltsbereich. Deshalb feste Viewport-Höhe statt min-height. */
.sk-page { height: 100%; }
.sk-app {
height: 100vh;
overflow: hidden;
display: grid;
grid-template-columns: var(--sk-sidebar-width) 1fr;
grid-template-rows: auto minmax(0, 1fr);
grid-template-areas:
'top top'
'side main';
}
/* ── Kopfleiste (über die volle Breite) ─────────────────── */
.sk-topbar {
grid-area: top;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--sk-space-4);
padding: var(--sk-space-3) var(--sk-space-5);
background: var(--sk-nav);
color: var(--sk-nav-text);
}
.sk-topbar-left { display: flex; align-items: center; gap: var(--sk-space-3); }
.sk-topbar-right {
display: flex;
align-items: center;
gap: var(--sk-space-3);
position: relative;
}
.sk-wordmark {
display: inline-flex;
align-items: center;
font-size: 22px;
font-weight: var(--sk-weight-semibold);
color: var(--sk-text-on-primary);
letter-spacing: -0.02em;
text-decoration: none;
}
.sk-wordmark:hover { color: var(--sk-text-on-primary); }
.sk-logo { display: block; height: 47px; width: auto; }
/* Menü-Umschalter nur auf schmalen Geräten.
Selektor mit .sk-topbar, sonst überschreibt das spätere `.sk-icon-btn
{ display: inline-flex }` dieses `display: none` und der Button erscheint
auch auf dem Desktop. */
.sk-topbar .sk-menu-toggle { display: none; }
/* Konto-Button + Dropdown */
.sk-user {
display: flex;
align-items: center;
gap: var(--sk-space-2);
padding: 4px var(--sk-space-2);
border: none;
background: transparent;
border-radius: var(--sk-radius);
color: var(--sk-nav-text);
cursor: pointer;
}
.sk-user:hover { background: rgba(255, 255, 255, 0.12); }
.sk-user-avatar {
width: 30px;
height: 30px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.16);
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 30px;
}
.sk-user-name { font-size: 14px; font-weight: 500; }
.sk-user-caret { opacity: 0.8; }
.sk-menu-backdrop { position: fixed; inset: 0; z-index: 29; }
.sk-popover--menu { padding: 0; overflow: hidden; }
.sk-menu-head { padding: var(--sk-space-4); border-bottom: 1px solid var(--sk-border); }
.sk-menu-name { font-size: 14px; font-weight: 600; color: var(--sk-text); }
.sk-menu-sub { font-size: 12px; color: var(--sk-muted); margin-top: 2px; }
.sk-menu-item {
display: block;
width: 100%;
text-align: left;
padding: var(--sk-space-3) var(--sk-space-4);
border: none;
background: transparent;
font: inherit;
font-size: 14px;
color: var(--sk-text);
cursor: pointer;
}
.sk-menu-item:hover { background: var(--sk-bg-1); }
.sk-icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 34px;
height: 34px;
border: 1px solid transparent;
border-radius: var(--sk-radius);
background: transparent;
color: inherit;
cursor: pointer;
}
.sk-icon-btn:hover { background: rgba(255, 255, 255, 0.12); }
/* In hellen Flächen (Vorschau-Navigation) wieder neutral */
.sk-preview .sk-icon-btn:hover { background: var(--sk-bg-1); border-color: var(--sk-border); }
.sk-popover {
position: absolute;
top: 42px;
right: 0;
min-width: 300px;
max-width: 360px;
max-height: 60vh;
overflow: auto;
background: var(--sk-white);
/* Zwingend: Das Popover hängt in der dunklen Kopfleiste und würde sonst deren
weiße Schriftfarbe erben (weiß auf weiß). */
color: var(--sk-text);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
padding: var(--sk-space-4);
z-index: 30;
}
/* Ungelesen-Punkt an der Glocke */
.sk-icon-btn { position: relative; }
.sk-dot {
position: absolute;
top: 6px;
right: 6px;
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--sk-primary);
border: 2px solid var(--sk-white);
}
.sk-notif-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.sk-notif { padding: var(--sk-space-3) 0; border-bottom: 1px solid var(--sk-border); }
.sk-notif:last-child { border-bottom: none; padding-bottom: 0; }
.sk-notif-title { font-size: var(--sk-size-sm); font-weight: var(--sk-weight-medium); }
.sk-notif-note { font-size: var(--sk-size-xs); color: var(--sk-text-muted); margin-top: 2px; }
.sk-notif-time { font-size: var(--sk-size-xs); color: var(--sk-text-muted); margin-top: 2px; }
/* ── Statusverlauf (Auftragsdetail) ─────────────────────── */
.sk-timeline { list-style: none; margin: var(--sk-space-3) 0 0; padding: 0; }
.sk-timeline-item {
display: flex;
gap: var(--sk-space-3);
padding-bottom: var(--sk-space-3);
position: relative;
}
.sk-timeline-item::before {
content: '';
position: absolute;
left: 5px;
top: 16px;
bottom: 0;
width: 1px;
background: var(--sk-border);
}
.sk-timeline-item:last-child::before { display: none; }
.sk-timeline-mark {
width: 11px;
height: 11px;
flex: 0 0 11px;
margin-top: 5px;
border-radius: 50%;
border: 1px solid var(--sk-border-strong);
background: var(--sk-white);
z-index: 1;
}
.sk-timeline-item:first-child .sk-timeline-mark {
background: var(--sk-primary);
border-color: var(--sk-primary);
}
.sk-timeline-body { font-size: var(--sk-size-sm); }
.sk-timeline-time { font-size: var(--sk-size-xs); color: var(--sk-text-muted); }
.sk-order--clickable { cursor: pointer; width: 100%; text-align: left; font: inherit; }
.sk-order--clickable:hover { border-color: var(--sk-accent); background: rgba(30, 58, 106, 0.02); }
.sk-order-caret { color: var(--sk-muted); transition: transform 0.15s ease; flex: 0 0 auto; }
.sk-order-caret--open { transform: rotate(180deg); }
/* ── Seitenleiste (dunkel, volle Höhe) ──────────────────── */
.sk-sidebar-wrap { grid-area: side; min-height: 0; }
.sk-sidebar {
height: 100%;
background: var(--sk-nav);
color: var(--sk-nav-text);
padding: var(--sk-space-4) var(--sk-space-3);
display: flex;
flex-direction: column;
gap: var(--sk-space-4);
overflow-y: auto;
}
.sk-nav-section--divider {
border-top: 1px solid rgba(255, 255, 255, 0.16);
padding-top: var(--sk-space-4);
}
.sk-nav { display: flex; flex-direction: column; gap: 2px; }
.sk-nav-item {
display: flex;
align-items: center;
gap: var(--sk-space-3);
width: 100%;
padding: var(--sk-space-3);
border: none;
border-radius: var(--sk-radius);
background: transparent;
/* Kräftiger für bessere Lesbarkeit auf dunklem Grund. */
color: rgba(255, 255, 255, 0.9);
font-size: 14px;
font-weight: 500;
text-decoration: none;
text-align: left;
cursor: pointer;
}
.sk-nav-item:hover {
background: rgba(255, 255, 255, 0.1);
color: var(--sk-text-on-primary);
}
.sk-nav-item--active {
background: rgba(255, 255, 255, 0.14);
color: var(--sk-text-on-primary);
font-weight: var(--sk-weight-medium);
}
.sk-nav-item--quiet { color: var(--sk-nav-text-faint); }
.sk-nav-section { display: flex; flex-direction: column; gap: var(--sk-space-2); }
.sk-nav-label {
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--sk-nav-text-faint);
padding: 0 var(--sk-space-3);
}
.sk-nav-hint {
font-size: var(--sk-size-xs);
color: var(--sk-nav-text-faint);
padding: 0 var(--sk-space-3);
}
/* ── Ablauf/Prozess in der Seitenleiste ─────────────────── */
.sk-process { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.sk-process-item {
display: flex;
align-items: center;
gap: var(--sk-space-3);
width: 100%;
padding: var(--sk-space-2) var(--sk-space-3);
font: inherit;
font-size: var(--sk-size-sm);
color: var(--sk-nav-text-faint);
border: none;
background: transparent;
border-radius: var(--sk-radius);
text-align: left;
}
/* Erledigte Schritte sind anklickbar (Rücksprung). */
.sk-process-item--clickable { cursor: pointer; }
.sk-process-item--clickable:hover {
background: rgba(255, 255, 255, 0.1);
color: var(--sk-text-on-primary);
}
.sk-process-mark {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
flex: 0 0 22px;
border-radius: 50%;
border: 1px solid rgba(255, 255, 255, 0.5);
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.sk-process-item--current { color: var(--sk-text-on-primary); font-weight: var(--sk-weight-medium); }
.sk-process-item--current .sk-process-mark {
border-color: #ffffff;
color: #ffffff;
}
.sk-process-item--done { color: var(--sk-nav-text); }
.sk-process-item--done .sk-process-mark {
background: #ffffff;
border-color: #ffffff;
color: var(--sk-primary);
}
.sk-sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 2px; }
/* ── Inhalt ─────────────────────────────────────────────── */
/* Der einzige scrollbare Bereich. */
.sk-content {
grid-area: main;
min-width: 0;
background: var(--sk-bg);
overflow-y: auto;
overflow-x: hidden;
}
/* Inhalte laufen nicht über die volle Breite auseinander, sondern stehen
mittig in angenehmer Lesebreite – die App selbst bleibt full width. */
.sk-view {
padding: var(--sk-space-6);
max-width: var(--sk-read-width);
margin: 0 auto;
}
/* ══ Preisleiste ═════════════════════════════════════════ */
.sk-pricebar {
position: sticky;
top: 0;
/* Muss ÜBER der (ebenfalls sticky) Vorschau liegen, sonst schiebt sich die
Vorschau beim Scrollen über die Preiszeile (Kopfzeile). */
z-index: 30;
background: var(--sk-white);
border-bottom: 1px solid var(--sk-border);
padding: var(--sk-space-3) var(--sk-space-6);
}
/* Der Inhalt der Preisleiste steht bündig über der Karte darunter –
sonst kleben Preis und Summe an den Bildschirmrändern. */
.sk-pricebar-inner {
max-width: var(--sk-read-width);
margin: 0 auto;
display: flex;
justify-content: flex-end; /* Preis steht rechts */
}
.sk-price-block { text-align: right; }
.sk-price-label {
font-size: 12px;
color: var(--sk-muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.sk-price-unit {
font-size: 24px;
font-weight: 750;
color: var(--sk-text);
font-variant-numeric: tabular-nums;
line-height: 1.2;
}
.sk-price-note { font-size: 12px; color: var(--sk-muted); margin-top: 2px; }
.sk-price-side { text-align: right; font-size: 12px; color: var(--sk-muted); }
/* ══ Konfigurator: Formular + Live-Vorschau ══════════════ */
/* Ohne Vorschau (alle Schritte außer „Text") steht das Formular allein. */
.sk-konf {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: var(--sk-space-5);
padding: var(--sk-space-6);
align-items: start;
max-width: var(--sk-read-width);
margin: 0 auto;
}
/* Im Text-Schritt läuft die Vorschau daneben mit. */
.sk-konf:has(.sk-preview) {
grid-template-columns: minmax(0, 1fr) 340px;
max-width: calc(var(--sk-read-width) + 340px + var(--sk-space-5));
}
.sk-konf-form { min-width: 0; }
.sk-preview {
position: sticky;
/* Unterhalb der sticky Preisleiste parken, damit beide sich nicht überlagern. */
top: 84px;
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
padding: var(--sk-space-4);
background: var(--sk-white);
/* Über den (sticky) Tabellenzellen, damit die Platzhalter-Tabelle nicht in
die Vorschau-Spalte hineinmalt – aber UNTER der Preisleiste (z-index 30). */
z-index: 20;
}
.sk-preview-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--sk-space-3);
margin-bottom: var(--sk-space-3);
}
.sk-preview-title { font-size: var(--sk-size-sm); font-weight: var(--sk-weight-semibold); }
.sk-preview-sub { font-size: var(--sk-size-xs); color: var(--sk-text-muted); }
.sk-preview-sheet {
aspect-ratio: 210 / 297;
border: 1px dashed var(--sk-border-strong);
border-radius: var(--sk-radius);
background: var(--sk-bg-1);
display: flex;
align-items: center;
justify-content: center;
padding: var(--sk-space-3);
overflow: hidden;
}
.sk-preview-img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* ── Schriftstück + Umschlag gemeinsam (oben/unten) ─────── */
.sk-preview-docs { display: flex; flex-direction: column; gap: var(--sk-space-4); }
.sk-preview-doc { margin: 0; display: flex; flex-direction: column; gap: 6px; cursor: zoom-in; }
.sk-preview-doc-label {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--sk-muted);
}
/* Kugelschreiber-Optik (blau, dickere Striche, Wobble) kommt aus inkify();
der Untergrund ist weiß (das SVG bringt seinen weißen Grund selbst mit). */
.sk-preview-doc-sheet {
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius);
background: var(--sk-white);
padding: var(--sk-space-2);
overflow: hidden;
}
.sk-preview-doc-sheet svg { display: block; width: 100%; height: auto; }
.sk-preview-doc:hover .sk-preview-doc-sheet { border-color: var(--sk-accent); }
/* ── Blättern: Pfeile als klare Buttons + deutliche Nummer ─ */
.sk-preview-pager {
display: flex;
align-items: center;
justify-content: center;
gap: var(--sk-space-3);
margin: var(--sk-space-3) 0;
}
.sk-pager-btn {
width: 34px;
height: 34px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid var(--sk-border-strong);
border-radius: var(--sk-radius);
background: var(--sk-white);
color: var(--sk-text);
font-size: 20px;
line-height: 1;
cursor: pointer;
transition: background-color 0.12s ease, border-color 0.12s ease;
}
.sk-pager-btn:hover:not(:disabled) { background: var(--sk-bg-1); border-color: var(--sk-accent); color: var(--sk-accent); }
.sk-pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.sk-pager-label {
font-size: 13px;
font-weight: 600;
font-variant-numeric: tabular-nums;
min-width: 128px;
text-align: center;
}
/* ── Motivkatalog ───────────────────────────────────────── */
.sk-motifs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: var(--sk-space-3);
margin-top: var(--sk-space-3);
}
.sk-motif {
display: flex;
flex-direction: column;
gap: var(--sk-space-2);
padding: var(--sk-space-2);
background: var(--sk-white);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
cursor: pointer;
font: inherit;
text-align: left;
}
.sk-motif:hover { border-color: var(--sk-border-strong); }
.sk-motif--selected { border-color: var(--sk-primary); background: var(--sk-bg-1); }
.sk-motif img {
width: 100%;
aspect-ratio: 3 / 2;
object-fit: cover;
border-radius: var(--sk-radius-sm);
display: block;
}
.sk-motif-name { font-size: var(--sk-size-xs); }
/* Großansicht des gewählten Motivs unter dem Katalog */
.sk-motif-large {
margin: var(--sk-space-4) 0 0;
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
background: var(--sk-bg-1);
padding: var(--sk-space-3);
text-align: center;
}
.sk-motif-large img {
max-width: 100%;
max-height: 360px;
height: auto;
border-radius: var(--sk-radius);
display: inline-block;
}
.sk-motif-large-name {
margin-top: var(--sk-space-2);
font-size: var(--sk-size-sm);
color: var(--sk-muted);
}
.sk-preview-quota {
text-align: center;
font-size: var(--sk-size-xs);
background: var(--sk-bg-2);
border-radius: var(--sk-radius);
padding: var(--sk-space-2);
margin-bottom: var(--sk-space-2);
}
/* ── Checkbox-Zeile ─────────────────────────────────────── */
.sk-check {
display: flex;
align-items: flex-start;
gap: var(--sk-space-3);
font-size: var(--sk-size-sm);
cursor: pointer;
}
/* an der ersten Textzeile ausrichten */
.sk-check input { margin-top: 2px; }
/* Karten-Variante (wie die Auswahl-Optionen) – z. B. rechtliche Checkboxen im Checkout */
.sk-check--card {
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius, 10px);
padding: var(--sk-space-4);
background: var(--sk-surface, #fff);
transition: border-color .15s, background .15s;
}
.sk-check--card:hover { border-color: var(--sk-border-strong); }
.sk-check--card + .sk-check--card { margin-top: var(--sk-space-3); }
/* ── Empfängerzeilen ────────────────────────────────────── */
.sk-entries { display: flex; flex-direction: column; gap: var(--sk-space-3); margin-top: var(--sk-space-4); }
.sk-entry { display: flex; gap: var(--sk-space-3); align-items: flex-start; }
.sk-entry-no {
flex: 0 0 26px;
height: 26px;
border-radius: 50%;
background: var(--sk-bg-2);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--sk-size-xs);
font-variant-numeric: tabular-nums;
margin-top: 4px;
}
.sk-entry-grid {
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--sk-space-2);
}
/* ── Empfänger-Tabelle ──────────────────────────────────── */
.sk-table-wrap {
overflow: auto;
max-height: 500px;
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius);
margin: 12px 0;
}
.sk-table {
width: 100%;
min-width: 600px;
border-collapse: separate;
border-spacing: 0;
background: var(--sk-card);
}
.sk-table th {
text-align: left;
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--sk-text);
padding: 10px 12px;
white-space: nowrap;
background: var(--sk-card);
/* bleibt beim Scrollen stehen – wie im bestehenden Konfigurator.
Niedriger z-index als Vorschau/Preisleiste, damit die Tabelle nicht
über benachbarte Panels malt. */
position: sticky;
top: 0;
z-index: 3;
border-bottom: 2px solid rgba(15, 23, 42, 0.1);
}
.sk-table td {
padding: 0;
font-size: 13px;
vertical-align: middle;
border-bottom: 1px solid rgba(15, 23, 42, 0.06);
}
.sk-table tr:last-child td { border-bottom: none; }
.sk-table-no {
padding: 8px 2px !important;
width: 32px;
min-width: 32px;
text-align: center;
font-weight: 600;
font-size: 13px;
color: var(--sk-muted);
background: var(--sk-card);
/* bleibt beim horizontalen Scrollen sichtbar */
position: sticky;
left: 0;
z-index: 2;
}
.sk-cell {
width: 100%;
min-width: 120px;
border: none;
background: transparent;
font: inherit;
font-size: 13px;
color: inherit;
padding: 10px 12px;
resize: vertical;
}
.sk-cell:focus {
outline: 2px solid var(--sk-primary);
outline-offset: -2px;
background: var(--sk-white);
}
/* ── Vergrößerte Vorschau ───────────────────────────────── */
.sk-lightbox {
position: fixed;
inset: 0;
background: rgba(26, 26, 26, 0.72);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--sk-space-4);
padding: var(--sk-space-5);
z-index: 60;
}
.sk-lightbox-sheet {
background: var(--sk-white);
border-radius: var(--sk-radius);
padding: var(--sk-space-4);
box-sizing: border-box;
/* Das Seitenverhältnis wird inline aus der viewBox gesetzt (aspectRatio).
Zusammen mit beiden Grenzen skaliert das Blatt IMMER proportional in die
jeweils kleinere Grenze – nie verzerrt, egal welche Fenstergröße. */
max-width: min(92vw, 720px);
max-height: 80vh;
width: auto;
height: auto;
overflow: hidden;
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);
}
.sk-lightbox-sheet svg {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
/* Aktionszeile (Bild speichern / Schließen) unter dem Blatt. */
.sk-lightbox-actions { display: flex; gap: var(--sk-space-3); }
.sk-lightbox-close {
font: inherit;
font-size: var(--sk-size-sm);
padding: var(--sk-space-2) var(--sk-space-4);
border-radius: var(--sk-radius);
border: 1px solid rgba(255, 255, 255, 0.5);
background: transparent;
color: #fff;
cursor: pointer;
}
/* ── Kostenübersicht ────────────────────────────────────── */
.sk-summary { list-style: none; margin: var(--sk-space-3) 0 0; padding: 0; font-size: var(--sk-size-sm); }
.sk-summary li {
display: flex;
justify-content: space-between;
gap: var(--sk-space-4);
padding: 3px 0;
}
.sk-summary li span:last-child { font-variant-numeric: tabular-nums; }
.sk-summary-sum {
border-top: 1px solid var(--sk-border);
margin-top: var(--sk-space-2);
padding-top: var(--sk-space-2) !important;
font-weight: var(--sk-weight-semibold);
}
.sk-summary-note { color: var(--sk-text-muted); font-size: var(--sk-size-xs); }
@media (max-width: 1100px) {
.sk-konf { grid-template-columns: 1fr; }
/* Vorschau steht dann UNTER dem Formular (nicht mehr sticky, kein Überlappen). */
.sk-konf:has(.sk-preview) { grid-template-columns: 1fr; }
.sk-preview { position: static; order: 1; }
}
@media (max-width: 560px) {
.sk-entry-grid { grid-template-columns: 1fr; }
}
/* ══ Flächen & Formular ══════════════════════════════════ */
.sk-card {
background: var(--sk-white);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
padding: 24px;
margin-bottom: 20px;
}
/* Karte mit abgesetzter Kopfzeile (Titel + Unterzeile), wie im Vorbild. */
.sk-card--head { padding: 0; overflow: hidden; margin-bottom: 20px; }
.sk-card-head {
padding: 20px 24px;
border-bottom: 1px solid rgba(15, 23, 42, 0.06);
}
.sk-card-head h2, .sk-card-head h3 { font-size: 16px; font-weight: 700; }
.sk-card-head p { font-size: 14px; color: var(--sk-muted); margin-top: 4px; }
.sk-card-body { padding: 24px; }
/* Trenner zwischen zwei Optionsgruppen in derselben Karte */
.sk-group-split {
border: none;
border-top: 1px solid var(--sk-border);
margin: var(--sk-space-4) 0;
}
/* Datei-Ablagefläche */
.sk-drop {
display: block;
width: 100%;
border: 2px dashed var(--sk-border-strong);
border-radius: var(--sk-radius);
background: transparent;
padding: 32px 24px;
text-align: center;
cursor: pointer;
font: inherit;
color: inherit;
}
.sk-drop:hover { border-color: var(--sk-accent); background: rgba(30, 58, 106, 0.03); }
.sk-drop-title { font-size: 14px; font-weight: 600; }
.sk-drop-sub { font-size: 12px; color: var(--sk-muted); margin-top: 4px; }
.sk-drop input { display: none; }
/* Auswahlfeld (Schriftart) */
select.sk-input {
appearance: none;
background-image: linear-gradient(45deg, transparent 50%, var(--sk-text-muted) 50%),
linear-gradient(135deg, var(--sk-text-muted) 50%, transparent 50%);
background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%;
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
padding-right: var(--sk-space-6);
}
.sk-field { margin-bottom: var(--sk-space-4); }
.sk-label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 8px;
}
.sk-label--required::after { content: '*'; color: var(--sk-error); margin-left: 4px; }
.sk-input {
width: 100%;
font: inherit;
font-size: 14px;
color: inherit;
padding: 10px 12px;
background: var(--sk-card);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius);
}
.sk-input:focus {
outline: none;
border-color: var(--sk-primary);
box-shadow: 0 0 0 3px rgba(30, 58, 106, 0.1);
}
.sk-input--code {
font-size: var(--sk-size-xl);
letter-spacing: 0.35em;
text-align: center;
}
.sk-input--number { max-width: 160px; font-variant-numeric: tabular-nums; }
textarea.sk-input { resize: vertical; }
/* ── Buttons ────────────────────────────────────────────── */
.sk-btn {
font: inherit;
font-size: 14px;
font-weight: 600;
padding: 10px 16px;
border-radius: var(--sk-radius);
border: 1px solid var(--sk-border);
cursor: pointer;
transition: background-color 0.15s ease, border-color 0.15s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--sk-space-2);
}
.sk-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.sk-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.sk-btn--primary { background: var(--sk-accent); border-color: var(--sk-accent); color: #fff; font-weight: 700; }
.sk-btn--primary:hover:not(:disabled) { background: var(--sk-accent-hover); border-color: var(--sk-accent-hover); }
.sk-btn--ghost { background: var(--sk-card); color: var(--sk-text); border-color: var(--sk-border-strong); }
.sk-btn--ghost:hover:not(:disabled) { background: var(--sk-bg-1); }
/* Auf dunklem Grund (Kopfleiste) muss der Ghost-Button transparent + hell sein.
Ohne transparenten Hintergrund entsteht sonst ein weißer Kasten mit weißer
Schrift – unsichtbar. */
.sk-topbar .sk-btn--ghost,
.sk-sidebar .sk-btn--ghost {
background: transparent;
color: var(--sk-nav-text);
border-color: rgba(255, 255, 255, 0.5);
}
.sk-topbar .sk-btn--ghost:hover:not(:disabled),
.sk-sidebar .sk-btn--ghost:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.14);
transform: none;
box-shadow: none;
}
.sk-btn--block { width: 100%; }
/* ══ Auswahl-Steuerelemente ══════════════════════════════
Native Checkboxen/Radios lassen sich nur einfärben, nicht formen – sie
fallen dadurch optisch aus dem Rahmen. Deshalb eigene Darstellung. */
.sk-app input[type='checkbox'],
.sk-app input[type='radio'] {
appearance: none;
-webkit-appearance: none;
width: 18px;
height: 18px;
flex: 0 0 18px;
margin: 0;
/* Klar sichtbarer Rand auf hellem Grund. */
border: 2px solid #64748b;
background: #ffffff;
cursor: pointer;
display: inline-block;
position: relative;
transition: background-color 0.12s ease, border-color 0.12s ease;
}
.sk-app input[type='checkbox'] { border-radius: var(--sk-radius-sm); }
.sk-app input[type='radio'] { border-radius: 50%; }
.sk-app input[type='checkbox']:hover:not(:disabled),
.sk-app input[type='radio']:hover:not(:disabled) { border-color: var(--sk-primary); }
.sk-app input[type='checkbox']:checked {
background-color: var(--sk-primary);
border-color: var(--sk-primary);
/* Haken als Grafik – zuverlässiger als Pseudoelemente auf Formularfeldern. */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-6'/%3E%3C/svg%3E");
background-size: 14px 14px;
background-position: center;
background-repeat: no-repeat;
}
.sk-app input[type='radio']:checked {
background-color: var(--sk-primary);
border-color: var(--sk-primary);
/* Weißer Ring innen lässt einen Punkt in der Mitte stehen. */
box-shadow: inset 0 0 0 3.5px var(--sk-white);
}
.sk-app input[type='checkbox']:focus-visible,
.sk-app input[type='radio']:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(30, 58, 106, 0.22);
}
.sk-app input[type='radio']:checked:focus-visible {
box-shadow: inset 0 0 0 3.5px var(--sk-white), 0 0 0 3px rgba(30, 58, 106, 0.22);
}
.sk-app input[type='checkbox']:disabled,
.sk-app input[type='radio']:disabled { opacity: 0.45; cursor: not-allowed; }
/* Auf dunklem Grund (Seitenleiste) heller Rand statt fast unsichtbarem */
.sk-sidebar input[type='checkbox'],
.sk-sidebar input[type='radio'] { border-color: rgba(255, 255, 255, 0.5); background: transparent; }
/* ── Auswahlkarten ──────────────────────────────────────── */
.sk-options { display: flex; flex-direction: column; gap: 10px; }
.sk-option {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 14px;
background: var(--sk-card);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius);
cursor: pointer;
transition: all 0.2s ease;
}
.sk-option:hover { border-color: var(--sk-border-strong); background: rgba(15, 23, 42, 0.02); }
.sk-option--selected { border-color: var(--sk-accent); background: rgba(30, 58, 106, 0.04); }
/* Radio in Auswahlkarten visuell verbergen (bleibt für Tastatur/AT nutzbar);
die Auswahl zeigt sich über Rahmen, Hintergrund und Icon-/Titelfarbe. */
.sk-app input[type='radio'].sk-option-input,
.sk-app input[type='checkbox'].sk-option-input {
position: absolute;
opacity: 0;
width: 1px;
height: 1px;
margin: 0;
pointer-events: none;
}
.sk-option:focus-within {
border-color: var(--sk-accent);
box-shadow: 0 0 0 3px rgba(30, 58, 106, 0.15);
}
/* Sichtbares Auswahlsymbol (Radio/Checkbox) in Karten – an der ersten
Textzeile ausgerichtet. Nur Schritt 1 („Sie sind") verbirgt es und zeigt
stattdessen ein Icon. */
.sk-option > input[type='radio']:not(.sk-option-input),
.sk-option > input[type='checkbox']:not(.sk-option-input) { margin-top: 1px; }
.sk-option-icon {
flex: 0 0 auto;
display: flex;
align-items: center;
color: var(--sk-muted);
}
.sk-option--selected .sk-option-icon,
.sk-option--selected .sk-option-title { color: var(--sk-accent); }
.sk-option-body { flex: 1; min-width: 0; }
.sk-option-title { font-weight: 500; font-size: 14px; line-height: 1.5; }
.sk-option-desc { font-size: 13px; color: var(--sk-muted); margin-top: 4px; line-height: 1.5; }
/* Aufpreis rechts an der Option: Betrag oben, Einheit klein darunter. */
.sk-option-price {
display: flex;
flex-direction: column;
align-items: flex-end;
text-align: right;
white-space: nowrap;
flex: 0 0 auto;
}
.sk-option-price-amount {
font-size: 14px;
font-weight: 600;
font-variant-numeric: tabular-nums;
color: var(--sk-text);
}
.sk-option-price-unit { font-size: 11px; color: var(--sk-muted); margin-top: 1px; }
.sk-wizard-nav { display: flex; justify-content: space-between; gap: var(--sk-space-3); margin-top: var(--sk-space-5); }
/* ── Chips, Meldungen ───────────────────────────────────── */
.sk-chip {
display: inline-block;
font-size: var(--sk-size-xs);
font-weight: var(--sk-weight-medium);
padding: 2px var(--sk-space-3);
border-radius: var(--sk-radius-sm);
background: var(--sk-bg-2);
border: 1px solid var(--sk-border);
white-space: nowrap;
}
.sk-note { font-size: 12px; color: var(--sk-muted); line-height: 1.5; }
.sk-error { font-size: 14px; color: var(--sk-error); margin-top: 8px; }
/* ── Auftragsliste ──────────────────────────────────────── */
.sk-order-list { display: flex; flex-direction: column; gap: var(--sk-space-2); list-style: none; margin: 0; padding: 0; }
.sk-order {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--sk-space-4);
background: var(--sk-white);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius-lg);
padding: var(--sk-space-4);
}
.sk-order-no { font-weight: var(--sk-weight-medium); font-variant-numeric: tabular-nums; }
.sk-order-meta { font-size: var(--sk-size-sm); color: var(--sk-text-muted); }
.sk-order-total { font-variant-numeric: tabular-nums; white-space: nowrap; }
.sk-empty {
border: 1px dashed var(--sk-border-strong);
border-radius: var(--sk-radius-lg);
padding: var(--sk-space-6) var(--sk-space-5);
text-align: center;
color: var(--sk-text-muted);
background: var(--sk-bg-1);
}
/* ── Overlay / Dialog ───────────────────────────────────── */
.sk-overlay {
position: fixed;
inset: 0;
background: rgba(26, 26, 26, 0.35);
display: flex;
align-items: center;
justify-content: center;
padding: var(--sk-space-5);
z-index: 50;
}
.sk-dialog {
background: var(--sk-white);
/* Zwingend nötig: Der Dialog hängt im DOM unter der dunklen Seitenleiste und
würde sonst deren weiße Schriftfarbe erben – weiß auf weiß. */
color: var(--sk-text);
border-radius: var(--sk-radius-lg);
border: 1px solid var(--sk-border);
padding: var(--sk-space-5);
width: 100%;
max-width: 460px;
max-height: 90vh;
overflow: auto;
}
.sk-dialog-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--sk-space-4);
margin-bottom: var(--sk-space-3);
}
.sk-contact { display: flex; flex-direction: column; gap: var(--sk-space-2); margin-top: var(--sk-space-4); }
.sk-contact-row {
display: flex;
align-items: center;
gap: var(--sk-space-3);
padding: var(--sk-space-3);
border: 1px solid var(--sk-border);
border-radius: var(--sk-radius);
text-decoration: none;
color: var(--sk-text);
font-size: var(--sk-size-sm);
}
.sk-contact-row:hover { background: var(--sk-bg-1); color: var(--sk-text); }
.sk-legal-links {
display: flex;
flex-wrap: wrap;
gap: var(--sk-space-4);
margin-top: var(--sk-space-4);
padding-top: var(--sk-space-4);
border-top: 1px solid var(--sk-border);
font-size: 13px;
}
/* Reset-Hinweis + Button: eigener, abgesetzter Block mit Luft (sonst gequetscht). */
.sk-help-reset {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--sk-space-3);
margin-top: var(--sk-space-5);
padding-top: var(--sk-space-4);
border-top: 1px solid var(--sk-border);
}
.sk-help-reset .sk-note { margin: 0; }
/* Kontakt-Produkt: sieht aus wie eine Option, führt aber zum Angebot. */
.sk-option--contact { cursor: pointer; }
.sk-option--contact .sk-option-price-unit { color: var(--sk-accent); font-weight: 600; }
/* ══ Schmale Ansichten ═══════════════════════════════════ */
@media (max-width: 900px) {
/* Ein Spalten-Layout; die Seitenleiste wird zum ausklappbaren Menü. */
.sk-app {
height: auto;
min-height: 100vh;
overflow: visible;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr;
grid-template-areas:
'top'
'main';
}
.sk-content { overflow: visible; }
/* Menü-Umschalter sichtbar */
.sk-topbar .sk-menu-toggle { display: inline-flex; }
/* Seitenleiste als Off-Canvas-Drawer von links */
.sk-sidebar-wrap {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 280px;
max-width: 82vw;
z-index: 60;
transform: translateX(-100%);
transition: transform 0.22s ease;
}
.sk-sidebar-wrap--open { transform: translateX(0); box-shadow: 0 0 40px rgba(0, 0, 0, 0.4); }
.sk-sidebar { overflow-y: auto; }
.sk-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
z-index: 55;
}
.sk-view, .sk-pricebar, .sk-konf {
padding-left: var(--sk-space-4);
padding-right: var(--sk-space-4);
}
/* Konto-Name im Dropdown, nicht in der Leiste */
.sk-user-name, .sk-user-caret { display: none; }
}
@media (max-width: 640px) {
:root { --sk-size-2xl: 24px; --sk-size-xl: 21px; }
.sk-order { flex-direction: column; align-items: flex-start; gap: var(--sk-space-2); }
}