/* Baustelle PWA — Mobile-first CSS */ * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html, body { margin: 0; padding: 0; height: 100%; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #1a1a1f; color: #f0f0f0; -webkit-font-smoothing: antialiased; overscroll-behavior-y: contain; } #app { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; } #topbar { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: #25252b; border-bottom: 1px solid #333; position: sticky; top: 0; z-index: 10; } #topbar h1 { flex: 1; margin: 0; font-size: 17px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .icon-btn { background: transparent; border: none; color: #f0f0f0; font-size: 22px; padding: 4px 8px; cursor: pointer; -webkit-appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: 4px; } /* Weisse Symbole statt Emojis (icon() in app.js) — folgen der Schriftfarbe */ .icon-btn svg { display: block; flex: 0 0 auto; } .icon-btn[hidden] { display: none; } /* inline-flex wuerde das hidden-Attribut sonst aushebeln */ #status-badge { font-size: 14px; } #main { flex: 1; padding: 16px; padding-bottom: 90px; /* Platz für FAB, damit letzter Listeneintrag nicht verdeckt wird */ overflow-y: auto; -webkit-overflow-scrolling: touch; } /* Untere Leiste klebt am unteren Rand wie die Kopfzeile oben (Eddy 20.10.2026: „mach die Leiste unten mal fest"). Bis dahin stand sie seit v1.0.0 am Seitenende — in einem Auftrag unter allen Fotos und Dokumenten, praktisch nie im Bild. Feste Hoehe (--nav-h), damit die Leiste „Geteiltes ablegen" genau darueber kleben kann; der FAB (fixed, 68px) liegt schon darueber. */ :root { --nav-h: 56px; } #bottom-nav { display: flex; background: #25252b; border-top: 1px solid #333; padding-bottom: env(safe-area-inset-bottom); position: sticky; bottom: 0; z-index: 30; } #bottom-nav button { flex: 1; background: transparent; border: none; color: #888; height: var(--nav-h); box-sizing: border-box; padding: 6px 2px; font-size: 11px; cursor: pointer; justify-content: center; /* Symbol ueber dem Wort, wie in Handy-Apps ueblich (vorher bunte Emojis) */ display: flex; flex-direction: column; align-items: center; gap: 3px; white-space: nowrap; } #bottom-nav button svg { display: block; opacity: 0.7; } #bottom-nav button.active svg { opacity: 1; } #bottom-nav button.active { color: #7aa2f7; } /* ----- FAB (Neuer Auftrag) ----- */ .fab { position: fixed; right: 18px; bottom: calc(68px + env(safe-area-inset-bottom, 0px)); width: 56px; height: 56px; border-radius: 50%; border: none; font-size: 30px; line-height: 1; font-weight: 300; background: rgba(122, 162, 247, 0.85); color: #fff; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); z-index: 50; cursor: pointer; transition: transform 0.1s ease, background 0.15s ease; } .fab:active { transform: scale(0.92); background: rgba(122, 162, 247, 1); } .fab[hidden] { display: none; } /* ----- Neuer Auftrag Modal (nutzt .fullscreen-modal) ----- */ .new-order-customer-row { display: flex; gap: 10px; padding: 10px 12px; background: #2a2a30; border: 1px solid #3a3a42; border-radius: 8px; margin-bottom: 10px; align-items: center; } .new-order-customer-row .nc-name { font-weight: 600; flex: 1; } .new-order-customer-row .nc-meta { color: #888; font-size: 12px; } .new-order-customer-row .nc-change { background: transparent; border: 1px solid #555; color: #7aa2f7; border-radius: 6px; padding: 4px 10px; cursor: pointer; } .new-order-defaults { font-size: 12px; color: #aaa; padding: 6px 12px; margin-bottom: 10px; border-left: 2px solid #7aa2f7; } .new-order-customer-search { display: block; width: 100%; padding: 12px; border-radius: 8px; border: 1px solid #444; background: #2a2a30; color: #eee; font-size: 15px; margin-bottom: 8px; } .new-order-customer-list { max-height: 45vh; overflow-y: auto; border: 1px solid #333; border-radius: 8px; background: #222228; } .new-order-customer-list .nc-item { padding: 12px; border-bottom: 1px solid #2a2a30; cursor: pointer; } .new-order-customer-list .nc-item:last-child { border-bottom: none; } .new-order-customer-list .nc-item:active { background: #2e2e35; } .new-order-customer-list .nc-item .nc-sub { color: #888; font-size: 12px; } .new-order-customer-list .nc-item.recent { background: rgba(122,162,247,0.06); } .new-order-empty { padding: 16px; color: #888; text-align: center; } /* ----- Login ----- */ .login-form { max-width: 360px; margin: 60px auto 0; text-align: center; } .login-form h2 { margin: 0 0 24px; font-weight: 600; } .login-form input { display: block; width: 100%; padding: 16px; margin-bottom: 12px; border-radius: 8px; border: 1px solid #444; background: #2a2a30; color: #f0f0f0; font-size: 16px; -webkit-appearance: none; } .login-form input:focus { outline: 2px solid #337ab7; } /* ----- Buttons ----- */ .btn { display: block; width: 100%; padding: 16px 20px; font-size: 16px; font-weight: 600; border-radius: 10px; border: none; cursor: pointer; background: #337ab7; color: #fff; margin: 8px 0; -webkit-appearance: none; transition: transform 0.1s; } .btn:active { transform: scale(0.97); } /* ---- Farbige Symbole (icon() in app.js, Klasse .ikon-) ---- Eddy 20.10.2026: Emojis erscheinen je nach Handy als Kaestchen, rein weisse Symbole waren „viel zu schlicht". Also: kleine Knoepfe = farbiges Symbol (--ikon-farbe), grosse Knoepfe = weisses Symbol im farbigen runden Feld (--ikon-grund). */ .ikon { color: var(--ikon-farbe, currentColor); } /* Linksbuendig: Symbole stehen untereinander in einer Spalte, der Text beginnt immer an derselben Stelle — liest sich wie eine Liste (Eddy 20.10.2026: „die Symbole alle linksbuendig") */ .btn:has(> .ikon) { display: flex; align-items: center; justify-content: flex-start; gap: 14px; padding-left: 16px; text-align: left; } .btn-small:has(> .ikon) { justify-content: center; padding-left: 10px; } /* kleiner Auswahl-Knopf bleibt mittig */ .btn > .ikon { flex: 0 0 auto; box-sizing: content-box; padding: 7px; border-radius: 50%; color: #fff; background: var(--ikon-grund, #555); } .btn-large > .ikon { background: rgba(255, 255, 255, 0.22); } /* blauer Hauptknopf: helles Feld */ .btn-small:has(> .ikon) { gap: 6px; } .btn-small > .ikon { padding: 3px; } .ikon-kamera { --ikon-farbe: #60a5fa; --ikon-grund: #3b82f6; } .ikon-galerie { --ikon-farbe: #4ade80; --ikon-grund: #16a34a; } .ikon-mikrofon { --ikon-farbe: #f87171; --ikon-grund: #dc2626; } .ikon-notizen { --ikon-farbe: #facc15; --ikon-grund: #ca8a04; } .ikon-liste { --ikon-farbe: #fb923c; --ikon-grund: #ea580c; } .ikon-bericht { --ikon-farbe: #c084fc; --ikon-grund: #9333ea; } .ikon-lieferung { --ikon-farbe: #2dd4bf; --ikon-grund: #0d9488; } .ikon-karte { --ikon-farbe: #34d399; --ikon-grund: #059669; } .ikon-zeichnen { --ikon-farbe: #fbbf24; --ikon-grund: #d97706; } .ikon-oeffnen { --ikon-farbe: #818cf8; --ikon-grund: #4f46e5; } .ikon-ansehen { --ikon-farbe: #a78bfa; --ikon-grund: #7c3aed; } .ikon-speichern { --ikon-farbe: #60a5fa; --ikon-grund: #2563eb; } .ikon-glocke { --ikon-farbe: #fbbf24; --ikon-grund: #d97706; } .ikon-schluessel { --ikon-farbe: #facc15; --ikon-grund: #ca8a04; } .ikon-sync { --ikon-farbe: #22d3ee; --ikon-grund: #0891b2; } .ikon-abmelden { --ikon-farbe: #f87171; --ikon-grund: #dc2626; } .ikon-loeschen { --ikon-farbe: #f87171; --ikon-grund: #dc2626; } .ikon-teilen { --ikon-farbe: #60a5fa; --ikon-grund: #2563eb; } .ikon-download { --ikon-farbe: #4ade80; --ikon-grund: #16a34a; } .ikon-auswahl { --ikon-farbe: #60a5fa; --ikon-grund: #2563eb; } .ikon-alle { --ikon-farbe: #c4b5fd; } .ikon-telefon { --ikon-farbe: #4ade80; } .ikon-hilfe { --ikon-farbe: #fbbf24; } .ikon-installieren { --ikon-farbe: #60a5fa; } .ikon-wechseln { --ikon-farbe: #93c5fd; } .ikon-blitzAus { --ikon-farbe: #d1d5db; } .ikon-blitzAuto, .ikon-blitzAn, .ikon-licht { --ikon-farbe: #facc15; } /* untere Leiste */ .ikon-heute { --ikon-farbe: #fbbf24; } .ikon-auftraege { --ikon-farbe: #60a5fa; } .ikon-kunden { --ikon-farbe: #4ade80; } .ikon-berichte { --ikon-farbe: #c084fc; } .ikon-einstellungen { --ikon-farbe: #cbd5e1; } .tel-link { display: inline-flex; align-items: center; gap: 6px; color: #7aa2f7; text-decoration: none; font-weight: 600; } .btn-secondary { background: #2a2a30; border: 1px solid #444; color: #f0f0f0; } .btn-large { padding: 22px; font-size: 18px; } .btn-danger { background: #d9534f; color: #fff; margin-top: 24px; } .btn-danger:active { background: #c9302c; } .hidden-input { display: none; } /* ----- Order List ----- */ .search-bar { margin-bottom: 12px; } .search-bar input[type="search"] { width: 100%; padding: 12px 16px; border-radius: 24px; border: 1px solid #444; background: #2a2a30; color: #f0f0f0; font-size: 15px; -webkit-appearance: none; } .filter-toggle { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 14px; color: #aaa; cursor: pointer; } .filter-toggle input[type="checkbox"] { width: 18px; height: 18px; accent-color: #7aa2f7; } .order-card { background: #25252b; border-radius: 10px; padding: 14px 16px; margin-bottom: 10px; cursor: pointer; transition: background 0.15s; } .order-card:active { background: #2f2f35; } .order-card .ref { font-weight: 600; color: #7aa2f7; font-size: 14px; } .order-card .ref-client { font-weight: 400; color: #aaa; font-size: 13px; } .order-card .name { font-size: 15px; margin-top: 4px; } .order-card .meta { display: flex; justify-content: space-between; margin-top: 6px; font-size: 12px; opacity: 0.7; } .order-card .badge { background: #337ab7; color: #fff; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 600; } /* ----- Order Detail ----- */ .detail-section { background: #25252b; border-radius: 10px; padding: 14px 16px; margin-bottom: 12px; } .detail-section h3 { margin: 0 0 8px; font-size: 15px; font-weight: 700; color: #7aa2f7; /* fett in normaler Schreibweise — keine Versalien (Eddy) */ } .detail-section p { margin: 4px 0; font-size: 14px; } .detail-section .label { opacity: 0.6; font-size: 12px; } .photo-grid, .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 6px; margin-top: 10px; max-width: 600px; } .photo-grid .thumb, .video-grid .thumb { aspect-ratio: 1; max-width: 160px; background: #2a2a30; border-radius: 6px; overflow: hidden; position: relative; cursor: pointer; } .photo-grid .thumb img, .photo-grid .thumb video { width: 100%; height: 100%; object-fit: cover; } .photo-grid .thumb-placeholder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 24px; opacity: 0.5; } /* Wartende Fotos am Auftrag — bewusst auffaellig (gelber Rand): das ist der Zustand, in dem man sonst glaubt, die Fotos seien weg. */ .pending-section { border: 1px solid #e0af68; background: #2b2820; cursor: pointer; } .pending-section h3 { color: #e0af68; } .pending-section p { line-height: 1.45; } .pending-grid .pending-thumb { cursor: pointer; } .pending-grid .pending-thumb img, .pending-grid .pending-thumb video { opacity: 0.7; width: 100%; height: 100%; object-fit: cover; display: block; } .pending-grid .pending-play, .video-grid .video-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 36px; height: 36px; border-radius: 50%; background: rgba(0, 0, 0, 0.55); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 16px; pointer-events: none; } .pending-grid .pending-mark { position: absolute; right: 4px; bottom: 4px; font-size: 16px; line-height: 1; padding: 3px 4px; border-radius: 6px; background: rgba(0, 0, 0, 0.6); } .pending-grid .pending-thumb.is-failed { outline: 2px solid #f7768e; outline-offset: -2px; } .pending-grid .pending-more { display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 600; color: #e0af68; } /* Foto-Section Kopfzeile mit Auswahl-Toggle */ .photo-section-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 6px; } .btn-small { padding: 6px 10px; font-size: 13px; border-radius: 6px; background: #2a2a30; color: #eee; border: 1px solid #444; cursor: pointer; } .btn-small:hover { background: #33333a; } /* Auswahl-Mode im Photo-Grid */ .photo-grid .thumb .thumb-check, .video-grid .thumb .thumb-check { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%; background: rgba(0,0,0,0.55); color: #fff; display: none; align-items: center; justify-content: center; font-size: 16px; font-weight: bold; border: 2px solid #fff; pointer-events: none; } .photo-grid.selecting .thumb-check, .video-grid.selecting .thumb-check { display: flex; opacity: 0.35; } .photo-grid.selecting .thumb.selected, .video-grid.selecting .thumb.selected { outline: 3px solid #5ab0ff; outline-offset: -3px; } .photo-grid.selecting .thumb.selected .thumb-check, .video-grid.selecting .thumb.selected .thumb-check { opacity: 1; background: #5ab0ff; border-color: #fff; } /* Auswahl-Mode in der Dokumenten-Liste (PDFs etc.) */ .doc-item .doc-check { display: none; width: 22px; height: 22px; border-radius: 50%; background: transparent; border: 2px solid #888; color: transparent; font-size: 14px; font-weight: bold; align-items: center; justify-content: center; flex-shrink: 0; } .doc-list.selecting .doc-item .doc-check { display: flex; } .doc-list.selecting .doc-item .doc-open { pointer-events: none; opacity: 0.4; } .doc-list.selecting .doc-item.selected { background: rgba(90,176,255,0.15); outline: 2px solid #5ab0ff; } .doc-list.selecting .doc-item.selected .doc-check { background: #5ab0ff; border-color: #5ab0ff; color: #fff; } /* Sticky Aktions-Bar am unteren Bildschirmrand */ .select-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 10px 14px; padding-bottom: calc(10px + env(safe-area-inset-bottom)); background: rgba(20,20,25,0.95); border-top: 1px solid #333; display: flex; align-items: center; gap: 12px; z-index: 90; backdrop-filter: blur(6px); } .select-bar .sb-info { flex: 1; color: #eee; font-size: 14px; } .select-bar .icon-btn { color: #fff; font-size: 20px; padding: 6px 10px; } .select-bar .icon-btn:disabled { opacity: 0.35; cursor: default; } /* ----- Toast ----- */ #toast-container { position: fixed; top: 16px; left: 16px; right: 16px; z-index: 100; pointer-events: none; } .toast { background: #5cb85c; color: #fff; padding: 14px 16px; border-radius: 8px; margin-bottom: 8px; text-align: center; box-shadow: 0 4px 16px rgba(0,0,0,0.4); animation: slide-down 0.2s; pointer-events: auto; } .toast.error { background: #d9534f; } .toast.warn { background: #f0ad4e; } @keyframes slide-down { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; } } .empty-state { text-align: center; padding: 40px 20px; opacity: 0.6; } .empty-state .icon { font-size: 48px; margin-bottom: 12px; } /* Loader */ .loader { text-align: center; padding: 40px; opacity: 0.6; } .status-draft { background: #6c757d; color: #fff; font-size: 10px; padding: 2px 6px; border-radius: 8px; margin-left: 6px; vertical-align: middle; } .status-final { background: #5cb85c; color: #fff; font-size: 10px; padding: 2px 6px; border-radius: 8px; margin-left: 6px; vertical-align: middle; } /* ============================================================ * Fullscreen Modals (Foto-Vollbild, Voice, Sketch) * ============================================================ */ .fullscreen-modal { position: fixed; inset: 0; background: #000; z-index: 1000; display: flex; flex-direction: column; padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); } .fs-header { display: flex; align-items: center; gap: 8px; padding: 10px 12px; background: rgba(0,0,0,0.7); color: #fff; border-bottom: 1px solid #222; flex-wrap: wrap; } .fs-header .fs-title { flex: 1; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .fs-header .icon-btn { color: #fff; } .fs-body { flex: 1; overflow: auto; display: flex; align-items: center; justify-content: center; padding: 12px; } .fs-body img { max-width: 100%; max-height: 100%; object-fit: contain; } /* Voice Modal */ .voice-modal .voice-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; gap: 16px; color: #fff; } .voice-indicator { font-size: 80px; color: #444; transition: color 0.3s; } .voice-indicator.recording { color: #d9534f; animation: pulse 1s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } .voice-time { font-size: 32px; font-variant-numeric: tabular-nums; color: #7aa2f7; } /* Sketch Modal */ .sketch-modal .sketch-body { flex: 1; background: #222; display: flex; align-items: center; justify-content: center; overflow: hidden; } .sketch-modal .sketch-body canvas { background: #fff; box-shadow: 0 0 20px rgba(0,0,0,0.5); touch-action: none; } .sketch-toolbar { display: flex; align-items: center; gap: 4px; padding: 8px 12px; background: #1a1a1f; border-bottom: 1px solid #333; overflow-x: auto; -webkit-overflow-scrolling: touch; } .sketch-toolbar button { background: #2a2a30; color: #fff; border: 1px solid #444; border-radius: 6px; padding: 8px 12px; font-size: 16px; cursor: pointer; flex-shrink: 0; } .sketch-toolbar button.active { background: #337ab7; border-color: #2868a0; } .sketch-toolbar .sep { width: 1px; background: #444; height: 24px; margin: 0 6px; flex-shrink: 0; } .sketch-toolbar input[type="color"] { width: 40px; height: 36px; border: 1px solid #444; background: #2a2a30; border-radius: 6px; padding: 2px; flex-shrink: 0; } .sketch-toolbar input[type="range"] { width: 100px; flex-shrink: 0; } /* Audio-Items in Auftrags-Detail */ .audio-list { display: flex; flex-direction: column; gap: 8px; } .audio-item { background: #2a2a30; border-radius: 6px; padding: 10px 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .audio-item .audio-name { flex: 1; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .audio-item .audio-play { background: #337ab7; color: #fff; border: none; border-radius: 50%; width: 36px; height: 36px; font-size: 14px; cursor: pointer; flex-shrink: 0; } .audio-item audio { width: 100%; flex-basis: 100%; } .audio-item .audio-transcribe { background: #2a2a30; color: #7aa2f7; border: 1px solid #444; border-radius: 50%; width: 36px; height: 36px; font-size: 14px; cursor: pointer; flex-shrink: 0; } .audio-transcript { flex-basis: 100%; background: #1a1a1f; padding: 10px 12px; margin-top: 6px; border-radius: 4px; border-left: 3px solid #7aa2f7; font-size: 13px; line-height: 1.5; color: #e0e0e0; white-space: pre-wrap; } .btn[disabled] { opacity: 0.5; cursor: not-allowed; } /* Weitere Dokumente (Auftrags-Detail) */ .doc-list { display: flex; flex-direction: column; gap: 8px; } .doc-item { background: #2a2a30; border-radius: 6px; padding: 10px 12px; display: flex; align-items: center; gap: 10px; cursor: pointer; transition: background 0.15s; } .doc-item:hover { background: #33333a; } .doc-item.loading { opacity: 0.6; pointer-events: none; } .doc-item .doc-icon { font-size: 22px; flex-shrink: 0; } .doc-item .doc-meta { flex: 1; min-width: 0; } .doc-item .doc-name { font-size: 14px; color: #e0e0e0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .doc-item .doc-sub { font-size: 11px; color: #888; margin-top: 2px; } .doc-item .doc-open { background: #337ab7; color: #fff; border: none; border-radius: 50%; width: 32px; height: 32px; font-size: 14px; cursor: pointer; flex-shrink: 0; } /* Doc-Viewer (Bilder) */ .doc-viewer-modal .dv-body { flex: 1; display: flex; align-items: center; justify-content: center; background: #1a1a1f; overflow: hidden; } .doc-viewer-modal .fs-header a.icon-btn { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; } /* PDF-Viewer */ .pdf-viewer-modal .fs-header { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .pdf-viewer-modal .fs-title { order: 4; } .pdf-viewer-modal .icon-btn:nth-of-type(1) { order: 1; } .pdf-viewer-modal .pdf-page-info { order: 2; font-size: 12px; color: #aaa; } .pdf-viewer-modal .icon-btn:nth-of-type(2) { order: 3; } .pdf-viewer-modal .icon-btn:nth-of-type(3) { order: 5; } /* close */ .pdf-viewer-modal .icon-btn:nth-of-type(4) { order: 6; } /* share */ .pdf-viewer-modal .icon-btn:nth-of-type(5) { order: 7; } /* download */ .pdf-viewer-modal .fs-header a { order: 7; } .pdf-body { flex: 1; display: flex; align-items: center; justify-content: center; background: #f5f5f5; overflow: auto; padding: 8px; } .pdf-body canvas { max-width: 100%; height: auto; box-shadow: 0 2px 8px rgba(0,0,0,0.2); } /* PIN-Modal */ .pin-modal .pin-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px; background: #1a1a1f; } .pin-modal .pin-icon { font-size: 56px; margin-bottom: 12px; } .pin-modal .pin-title { font-size: 18px; color: #e0e0e0; margin-bottom: 24px; } .pin-modal .pin-display { display: flex; gap: 16px; margin-bottom: 32px; } .pin-modal .pin-display span { width: 18px; height: 18px; border-radius: 50%; border: 2px solid #7aa2f7; background: transparent; transition: background 0.1s; } .pin-modal .pin-display span.filled { background: #7aa2f7; } .pin-modal .pin-keypad { display: grid; grid-template-columns: repeat(3, 72px); gap: 12px; } .pin-modal .pin-key { width: 72px; height: 72px; border-radius: 50%; background: #2a2a30; color: #fff; border: 1px solid #444; font-size: 24px; cursor: pointer; -webkit-appearance: none; } .pin-modal .pin-key:active { background: #3a3a40; transform: scale(0.97); } .pin-modal .pin-cancel { margin-top: 32px; background: transparent; border: none; color: #999; cursor: pointer; font-size: 14px; } /* Toggle-Row für Settings */ .toggle-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; cursor: pointer; } .toggle-row input[type="checkbox"] { width: 18px; height: 18px; accent-color: #337ab7; } /* Mini-Cards für Kundendetail (Aufträge/Rechnungen/Berichte) */ .mini-card { background: #2a2a30; border-radius: 6px; padding: 10px 12px; margin-bottom: 6px; cursor: pointer; transition: background 0.15s; } .mini-card:active { background: #35353b; } .mini-card .mini-ref { font-weight: 600; color: #7aa2f7; font-size: 13px; } .mini-card .mini-meta { font-size: 12px; opacity: 0.7; margin-top: 3px; } .customer-actions { display: flex; gap: 8px; margin-top: 12px; } .customer-actions a { text-decoration: none; text-align: center; flex: 1; } /* Report-Page-Thumb mit Nummer */ .report-page-thumb { position: relative; transition: transform 0.1s, opacity 0.1s; } .report-page-thumb.dragging { opacity: 0.6; transform: scale(1.05); box-shadow: 0 4px 20px rgba(51, 122, 183, 0.5); } .report-page-thumb .page-num { position: absolute; top: 4px; left: 4px; background: rgba(0,0,0,0.7); color: #fff; font-size: 11px; padding: 2px 6px; border-radius: 10px; font-weight: 600; } .report-page-thumb .page-title-badge { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.75); color: #fff; font-size: 10px; padding: 3px 6px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Unterschrift-Modal */ .signature-modal .signature-meta { padding: 12px 16px; background: #1a1a1f; border-bottom: 1px solid #333; display: flex; flex-direction: column; gap: 8px; } .signature-modal .signature-meta input[type="text"] { width: 100%; padding: 12px 14px; background: #2a2a30; color: #fff; border: 1px solid #444; border-radius: 6px; font-size: 15px; box-sizing: border-box; } .signature-modal .sig-gps-label { color: #e0e0e0; font-size: 13px; display: flex; align-items: center; gap: 8px; } .signature-modal .sig-legal { color: #999; font-size: 11px; line-height: 1.4; } .signature-modal .signature-toolbar { display: flex; align-items: center; gap: 12px; padding: 10px 16px; background: #1a1a1f; border-bottom: 1px solid #333; } .signature-modal .signature-toolbar button { background: #2a2a30; color: #fff; border: 1px solid #444; border-radius: 6px; padding: 8px 14px; cursor: pointer; } .signature-modal .sig-hint { opacity: 0.6; font-size: 13px; } .signature-modal .signature-body { flex: 1; background: #222; padding: 16px; display: flex; align-items: center; justify-content: center; } .signature-modal canvas { background: #fff; width: 100%; max-width: 900px; aspect-ratio: 2 / 1; border-radius: 6px; touch-action: none; box-shadow: 0 0 20px rgba(0,0,0,0.5); } /* Hilfe-Modal */ .help-modal .help-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 20px; color: #e0e0e0; max-width: 780px; margin: 0 auto; width: 100%; box-sizing: border-box; background: #1a1a1f; } .help-modal h2 { color: #7aa2f7; margin: 0 0 20px; font-size: 22px; } .help-modal section { background: #25252b; border-radius: 10px; padding: 14px 18px; margin-bottom: 14px; } .help-modal section h3 { color: #7aa2f7; font-size: 16px; margin: 0 0 10px; } .help-modal p { margin: 6px 0; line-height: 1.5; font-size: 14px; } .help-modal ul { margin: 6px 0 6px 20px; padding: 0; } .help-modal li { margin: 4px 0; font-size: 14px; line-height: 1.5; } .help-modal strong { color: #fff; } .help-modal .tip { background: rgba(122, 162, 247, 0.1); border-left: 3px solid #7aa2f7; padding: 10px 12px; border-radius: 4px; margin: 10px 0; font-size: 13px; } .help-modal .status-badge-help { background: #2a2a30; padding: 2px 8px; border-radius: 10px; font-size: 12px; border: 1px solid #444; } .help-modal .help-footer { margin-top: 24px; padding-top: 16px; border-top: 1px solid #333; text-align: center; opacity: 0.6; font-size: 12px; } /* help-btn in Topbar kleiner machen */ #help-btn { font-size: 18px; padding: 4px 8px; } /* ========== Photo Viewer mit Zoom + Swipe ========== */ .photo-viewer-modal .pv-body { flex: 1; display: flex; align-items: center; justify-content: center; overflow: hidden; touch-action: none; background: #000; } .photo-viewer-modal #pv-image { max-width: 100%; max-height: 100%; object-fit: contain; transform-origin: center center; transition: transform 0.15s ease-out, opacity 0.2s; cursor: grab; user-select: none; -webkit-user-drag: none; } .photo-viewer-modal #pv-image.dragging { cursor: grabbing; transition: none; } .photo-viewer-modal .pv-counter { font-size: 13px; color: #888; margin-left: auto; margin-right: 8px; } .photo-viewer-modal .pv-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 80px; border: none; background: rgba(255, 255, 255, 0.1); color: #fff; font-size: 32px; cursor: pointer; z-index: 10; display: flex; align-items: center; justify-content: center; border-radius: 4px; } .photo-viewer-modal .pv-nav:disabled { opacity: 0.2; cursor: default; } .photo-viewer-modal .pv-prev { left: 8px; } .photo-viewer-modal .pv-next { right: 8px; } .photo-viewer-modal .pv-zoom-btns { position: absolute; bottom: 16px; right: 12px; display: flex; gap: 8px; z-index: 10; } .photo-viewer-modal .pv-zoom-btns button { width: 40px; height: 40px; border: none; background: rgba(255, 255, 255, 0.15); color: #fff; font-size: 20px; cursor: pointer; border-radius: 6px; } .photo-viewer-modal .pv-zoom-btns button:active { background: rgba(255, 255, 255, 0.3); } @media (max-width: 600px) { .photo-viewer-modal .pv-nav { width: 40px; height: 60px; font-size: 24px; } .photo-viewer-modal .pv-zoom-btns button { width: 36px; height: 36px; font-size: 18px; } } /* ============================================================ * Lieferungen-Liste + Vollbild-Signatur-Modal * ============================================================ */ .ship-list { display: flex; flex-direction: column; gap: 10px; padding: 12px; } .ship-card { background: #25252b; border: 1px solid #333; border-radius: 10px; padding: 14px 16px; cursor: pointer; transition: background .15s; } .ship-card:active { background: #2e2e36; } .ship-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 6px; } .ship-ref { font-size: 16px; font-weight: 600; } .ship-badge { font-size: 12px; padding: 3px 9px; border-radius: 12px; } .ship-badge.signed { background: #214a2e; color: #9ae6a8; } .ship-badge.open { background: #4a3818; color: #f0c570; } .ship-meta { font-size: 13px; opacity: 0.75; } .pdf-inline-wrap { background: #fff; border-radius: 8px; padding: 8px; margin: 12px; text-align: center; } .pdf-inline-hint { color: #555; font-size: 12px; margin-bottom: 8px; } /* Vollbild-Querformat-Signatur */ .ship-sign-modal { background: #1a1a1f; z-index: 9999; } .ship-sign-grid { display: grid; grid-template-columns: minmax(220px, 30%) 1fr; height: 100vh; height: 100dvh; } .ship-sign-side { background: #25252b; border-right: 1px solid #333; padding: 18px; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; } .ss-title { font-size: 18px; font-weight: 700; } .ss-meta { font-size: 14px; line-height: 1.5; background: #1a1a1f; padding: 10px 12px; border-radius: 8px; } .ss-label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; } .ss-label input[type="text"] { padding: 10px 12px; border-radius: 8px; border: 1px solid #444; background: #1a1a1f; color: #fff; font-size: 16px; } .ss-gps { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 8px 0; } .ss-legal { font-size: 12px; line-height: 1.45; opacity: 0.7; margin: 0; } .ss-actions { display: flex; flex-direction: column; gap: 8px; margin-top: auto; } .ss-actions .btn-large { background: #5cb85c; color: #fff; border: none; padding: 14px; border-radius: 10px; font-size: 16px; font-weight: 600; } .ship-sign-pad { display: flex; flex-direction: column; align-items: center; justify-content: center; background: #f5f5f5; padding: 12px; overflow: hidden; } .ss-hint { font-size: 12px; color: #777; margin-bottom: 8px; } #ss-canvas { background: #fff; border: 2px dashed #bbb; border-radius: 8px; touch-action: none; cursor: crosshair; } @media (max-width: 700px) and (orientation: portrait) { .ship-sign-grid { grid-template-columns: 1fr; grid-template-rows: auto 1fr; } .ship-sign-side { border-right: none; border-bottom: 1px solid #333; } } /* ============================================================ * Live-Kamera (Schnellschuss + Filmstreifen) * ============================================================ */ .camera-modal { background: #000; } .camera-modal .cam-stage { position: relative; flex: 1; min-height: 0; background: #000; display: flex; align-items: center; justify-content: center; overflow: hidden; touch-action: none; /* zwei Finger zoomen die Kamera, nicht die Seite */ } /* contain: die Vorschau zeigt exakt das, was gespeichert wird (wichtig für Doku-Fotos) */ .camera-modal #cam-video { width: 100%; height: 100%; object-fit: contain; background: #000; } .camera-modal .cam-hint { position: absolute; color: #fff; font-size: 14px; opacity: 0.85; pointer-events: none; text-align: center; padding: 0 20px; } .camera-modal .cam-filmstrip { display: flex; gap: 8px; padding: 8px 10px; overflow-x: auto; background: rgba(0,0,0,0.85); -webkit-overflow-scrolling: touch; } .camera-modal .cam-filmstrip:empty { padding: 0; } .cam-thumb { position: relative; flex: 0 0 auto; width: 60px; height: 60px; border-radius: 8px; overflow: hidden; border: 2px solid #444; background: #222; } .cam-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } .cam-thumb .cam-thumb-badge { position: absolute; right: 2px; bottom: 2px; font-size: 11px; line-height: 1; padding: 1px 3px; border-radius: 6px; background: rgba(0,0,0,0.65); color: #fff; } .cam-thumb.saving { border-color: #888; } .cam-thumb.saving .cam-thumb-badge::after { content: '💾'; } .cam-thumb.pending { border-color: #e0a300; } .cam-thumb.pending .cam-thumb-badge::after { content: '⏳'; } .cam-thumb.done { border-color: #2ecc71; } .cam-thumb.done .cam-thumb-badge::after { content: '✓'; } .cam-thumb.error { border-color: #e74c3c; } .cam-thumb.error .cam-thumb-badge::after { content: '⚠'; } .cam-thumb .cam-thumb-del { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; background: rgba(200,30,30,0.78); color: #fff; border: none; font-size: 22px; cursor: pointer; } .cam-thumb.confirm-del .cam-thumb-del { display: flex; } .camera-modal .cam-controls { display: flex; align-items: center; gap: 12px; padding: 14px 20px calc(14px + env(safe-area-inset-bottom)); background: #000; } .camera-modal .cam-count { flex: 1; color: #bbb; font-size: 13px; text-align: left; } .camera-modal .cam-done-wrap { flex: 1; display: flex; justify-content: flex-end; } .cam-shutter { flex: 0 0 auto; width: 68px; height: 68px; border-radius: 50%; background: #fff; border: 4px solid rgba(255,255,255,0.35); box-shadow: 0 0 0 2px #000 inset; cursor: pointer; transition: transform 0.08s ease, background 0.08s ease; } .cam-shutter:active { transform: scale(0.92); } .cam-shutter.flash { background: #ffd34d; } /* Video: roter Knopf, während der Aufnahme ein rotes Quadrat im Ring */ .cam-shutter.video { background: #e53935; } .cam-shutter.video.laeuft { background: linear-gradient(#e53935, #e53935) center / 26px 26px no-repeat, #111; } /* Umschalter Foto | Video über dem Auslöser */ .camera-modal .cam-modus { display: flex; justify-content: center; gap: 8px; padding: 8px 0 0; background: #000; } .camera-modal .cam-modus-btn { background: transparent; border: none; color: #bbb; font-size: 15px; font-weight: 600; padding: 6px 16px; border-radius: 16px; cursor: pointer; } .camera-modal .cam-modus-btn.aktiv { color: #ffd34d; background: rgba(255, 255, 255, 0.12); } .camera-modal .cam-modus.gesperrt .cam-modus-btn { opacity: 0.4; pointer-events: none; } /* Laufzeit oben im Sucher */ .camera-modal .cam-rec { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.6); color: #fff; padding: 4px 12px; border-radius: 14px; font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; pointer-events: none; } .camera-modal .cam-rec::first-letter { color: #e53935; } #cam-flip:disabled { opacity: 0.35; } /* Video im Filmstreifen */ .cam-thumb .cam-thumb-leer { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 22px; background: #222; } .cam-thumb .cam-thumb-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: #fff; font-size: 16px; text-shadow: 0 0 4px #000; pointer-events: none; } /* Blitz-Knopf: Text statt nur Symbol, damit der Zustand lesbar ist (Aus/Auto/An/Licht) */ .camera-modal .cam-blitz { font-size: 15px; white-space: nowrap; } /* Kamera wechseln: weisses Symbol wie ✕, kein Emoji (das erschien als blaues Kaestchen) — Stil: .icon-btn */ /* Scharfstellen per Antippen */ .camera-modal .cam-fokus-ring { position: absolute; width: 72px; height: 72px; margin: -36px 0 0 -36px; border: 2px solid #fff; border-radius: 50%; pointer-events: none; opacity: 0.9; } .camera-modal .cam-fokus-ring.aktiv { animation: cam-fokus 0.35s ease-out; } .camera-modal .cam-fokus-ring.ok { border-color: #ffd34d; } @keyframes cam-fokus { from { transform: scale(1.5); opacity: 0.4; } to { transform: scale(1); opacity: 0.9; } } /* Zoomstufe unten mittig im Sucher; Antippen = zurück auf 1× */ .camera-modal .cam-zoom { position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%); min-width: 44px; height: 32px; padding: 0 10px; border-radius: 16px; border: 1px solid rgba(255, 255, 255, 0.5); background: rgba(0, 0, 0, 0.55); color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; } .camera-modal .cam-zoom.aktiv { color: #ffd34d; border-color: #ffd34d; } .camera-modal [hidden] { display: none !important; } /* ============================================================ Eigene Dialoge (Ersatz für confirm/alert/prompt) ============================================================ */ .dialog-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.65); z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 20px; padding-bottom: calc(20px + env(safe-area-inset-bottom)); } .dialog-box { width: 100%; max-width: 420px; background: #25252b; border: 1px solid #3a3a42; border-radius: 14px; padding: 20px; box-shadow: 0 12px 40px rgba(0,0,0,0.5); } .dialog-title { font-size: 17px; font-weight: 600; margin-bottom: 8px; } .dialog-text { font-size: 15px; line-height: 1.45; opacity: 0.85; } .dialog-input { width: 100%; margin-top: 14px; padding: 12px; font-size: 16px; /* < 16px lässt iOS beim Fokus zoomen */ background: #1a1a1f; color: #f0f0f0; border: 1px solid #3a3a42; border-radius: 8px; } .dialog-actions { display: flex; gap: 10px; margin-top: 20px; } .dialog-actions .btn { flex: 1; margin: 0; } /* Layout-Kennzeichen auf einer Bericht-Seitenkachel */ .page-layout-badge { position: absolute; top: 4px; right: 4px; font-size: 10px; padding: 2px 5px; border-radius: 4px; background: rgba(0,0,0,0.6); color: #fff; pointer-events: none; } /* Thumbnail liegt über dem Platzhalter, statt ihn im Fluss zu verdrängen — sonst hätte die Kachel kurzzeitig zwei Elemente mit je 100 % Höhe. */ .photo-grid .thumb img.thumb-img { position: absolute; inset: 0; opacity: 0; transition: opacity 0.15s ease; } .photo-grid .thumb img.thumb-img.is-loaded { opacity: 1; } /* ============================================================ Textnotizen ============================================================ */ .note-card { background: #25252b; border: 1px solid #33333a; border-radius: 10px; padding: 12px 14px; margin-bottom: 10px; cursor: pointer; } .note-card:active { background: #2c2c33; } .note-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; } .note-card-head strong { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .note-card-preview { font-size: 13px; line-height: 1.4; opacity: 0.75; /* Zwei Zeilen Vorschau reichen, um die Notiz wiederzuerkennen */ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .note-card-meta { margin-top: 6px; font-size: 11px; opacity: 0.5; } /* Kopf-/Rumpf-Aufbau der Modale. Die Klassen waren im Markup schon in Gebrauch (u. a. beim Löschen eines Berichts), hatten aber nie eine Regel — der Schließen-Knopf landete dadurch unter der Überschrift statt daneben. */ .modal-header { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: #25252b; border-bottom: 1px solid #333; flex: 0 0 auto; } .modal-header h2 { flex: 1; margin: 0; font-size: 17px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .close-btn { flex: 0 0 auto; width: 38px; height: 38px; font-size: 24px; line-height: 1; background: transparent; color: #f0f0f0; border: none; border-radius: 8px; cursor: pointer; } .close-btn:active { background: #33333a; } .modal-body { flex: 1; min-height: 0; overflow: auto; padding: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom)); } /* Editor */ .note-edit-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; padding: 12px; padding-bottom: calc(12px + env(safe-area-inset-bottom)); background: #1a1a1f; } .note-edit-body input, .note-edit-body textarea { width: 100%; background: #25252b; color: #f0f0f0; border: 1px solid #3a3a42; border-radius: 8px; padding: 12px; font-size: 16px; /* < 16px lässt iOS beim Fokus zoomen */ font-family: inherit; } .note-edit-body textarea { flex: 1; min-height: 0; resize: none; line-height: 1.5; } .note-edit-meta { font-size: 11px; opacity: 0.5; text-align: right; } /* Hinweis auf noch nicht abgelegte, geteilte Inhalte (Web Share Target) */ /* Offline-Band unter der Kopfzeile — zeigt an, dass die Daten von vorhin sind. Ohne sichtbaren Hinweis haelt man den alten Stand fuer den aktuellen. */ #offline-band { position: sticky; top: 52px; z-index: 9; padding: 9px 16px; background: #6b4b12; color: #ffd88a; border-bottom: 1px solid #8a6317; font-size: 13px; font-weight: 600; text-align: center; } /* Leiste in der App-Spalte über der Navigation (19.10.2026): klebt beim Scrollen am unteren Rand, * steht aber im Fluss — der Inhalt macht ihr Platz und lässt sich ganz darüber scrollen. Der FAB * (fixed, bottom 68px) liegt darüber und wird nicht mehr verdeckt. */ .shared-banner { position: sticky; bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px)); /* direkt ueber der festen Leiste */ z-index: 20; width: 100%; margin: 0; padding: 12px 16px; border: none; border-radius: 0; background: #7aa2f7; color: #10101a; font-size: 15px; font-weight: 600; box-shadow: 0 -2px 10px rgba(0,0,0,0.35); cursor: pointer; } .shared-banner:active { filter: brightness(0.95); } /* Symbol in Schriftfarbe (dunkel auf hellblau) — die Teilen-Farbe waere hier unsichtbar */ .shared-banner { display: flex; align-items: center; justify-content: center; gap: 8px; } .shared-banner .ikon { color: inherit; } /* Solange die Leiste da ist, sitzt der FAB eine Leistenhöhe höher — sonst ragt er hinein */ body.hat-geteiltes .fab { bottom: calc(112px + env(safe-area-inset-bottom, 0px)); } /* Zurück-Knopf: Pfeil UND Wort, ausreichend große Tippfläche (Handschuhe) */ .back-btn { display: inline-flex; align-items: center; gap: 2px; min-height: 44px; padding: 0 14px 0 6px; margin-right: 6px; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); border-radius: 22px; color: #f0f0f0; font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; -webkit-appearance: none; } .back-btn:active { background: rgba(255,255,255,0.2); } .back-btn[style*="display: none"] { display: none !important; } /* PDF-Betrachter mit Zoom */ .pdfv-modal { background: #222; } .pdfv-scroll { flex: 1; overflow: auto; background: #3a3a3a; padding: 8px 0; touch-action: pan-x pan-y; -webkit-overflow-scrolling: touch; } .pdfv-stack { margin: 0 auto; } .pdfv-page { display: block; background: #fff; margin: 0 auto 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.5); } .pdfv-bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: rgba(0,0,0,0.85); border-top: 1px solid #333; } .pdfv-btn { min-width: 52px; min-height: 48px; background: #2a2a30; color: #fff; border: 1px solid #555; border-radius: 8px; font-size: 22px; cursor: pointer; } .pdfv-btn.pdfv-wide { font-size: 15px; min-width: 84px; } .pdfv-info { margin-left: auto; color: #bbb; font-size: 13px; } .pdf-inline-wrap canvas { cursor: zoom-in; } /* Videos am Auftrag: erstes Bild als Vorschau, ▶ in der Mitte, Datum/Größe unten */ .video-grid .video-poster { width: 100%; height: 100%; object-fit: cover; display: block; background: #111; pointer-events: none; } .video-grid .video-meta { position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 5px; font-size: 11px; color: #fff; background: linear-gradient(transparent, rgba(0, 0, 0, 0.75)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; } /* Video-Player (Vollbild) */ .video-modal .fs-body { background: #000; } .video-modal video { width: 100%; height: 100%; object-fit: contain; background: #000; }