root 24ac3ac058 ui: echte Mobile-First-Variante — Recording-Hero, Job-Cards, Admin-Klappe
Mobile-Layout ab <700px komplett umgebaut, nicht mehr nur Desktop-Verkleinerung:

- Header: nur Logo + User + Profil-Mini-Dropdown + Logout
- Upload-Card: großer roter Aufnahme-Button als Hero-Element
  - Profil und Titel darunter, kompakt
  - Datei-Upload in <details>-Klappe (auf Desktop offen, Mobile zu)
- Jobs: Card-Liste statt Tabelle (Tabelle nur Desktop, Cards nur Mobile)
- Admin: H2 als Toggle, Body kollabiert (auf Desktop immer offen)
- Inputs auf Mobile mit font-size:16px → kein iOS-Zoom-on-Focus
- Recording-Pane: Timer 64px, Buttons full-width
- safe-area-inset für iPhone-Notch + Bottom-Bar

Ohne JS-Mode-Switch — alles via CSS Media Query +
.desktop-only / .mobile-only Helfer-Klassen. JS rendert beide
Job-Repräsentationen, CSS schaltet die richtige sichtbar.
2026-05-14 04:00:33 +00:00

546 lines
14 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.

:root {
--bg: #0f1115;
--card: #181c24;
--border: #262b36;
--text: #e6e8eb;
--muted: #8b93a3;
--accent: #4f8cff;
--accent-hover: #3a78f0;
--ok: #2ecc71;
--warn: #f1c40f;
--err: #e74c3c;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
}
header {
padding: 32px 24px 16px;
text-align: center;
border-bottom: 1px solid var(--border);
}
header h1 { margin: 0 0 4px; font-size: 28px; letter-spacing: .3px; }
.sub { color: var(--muted); margin: 0 0 12px; }
.badge {
display: inline-block;
padding: 4px 10px;
border-radius: 999px;
background: var(--card);
border: 1px solid var(--border);
font-size: 12px;
color: var(--muted);
}
.badge.ok { color: var(--ok); border-color: rgba(46,204,113,.4); }
.badge.err { color: var(--err); border-color: rgba(231,76,60,.4); }
main {
max-width: 1000px;
margin: 24px auto;
padding: 0 16px;
display: grid;
gap: 20px;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 20px 22px;
}
.card h2 { margin-top: 0; font-size: 18px; }
form { display: grid; gap: 12px; }
label { display: grid; gap: 6px; font-size: 14px; color: var(--muted); }
input[type=text], input[type=file] {
background: #0f1219;
border: 1px solid var(--border);
color: var(--text);
padding: 10px 12px;
border-radius: 8px;
font-size: 14px;
}
button {
background: var(--accent);
color: white;
border: 0;
padding: 10px 16px;
border-radius: 8px;
font-size: 14px;
cursor: pointer;
justify-self: start;
}
button:hover { background: var(--accent-hover); }
button:disabled { opacity: .6; cursor: not-allowed; }
.hidden { display: none !important; }
.msg { min-height: 1em; margin: 8px 0 0; font-size: 13px; }
.msg.ok { color: var(--ok); }
.msg.err { color: var(--err); }
.muted { color: var(--muted); }
.bar {
width: 100%;
height: 8px;
background: #0f1219;
border-radius: 4px;
overflow: hidden;
margin-top: 6px;
}
.bar-fill {
height: 100%;
width: 0%;
background: var(--accent);
transition: width .25s ease;
}
table { width: 100%; border-collapse: collapse; font-size: 14px; table-layout: fixed; }
th, td { padding: 10px 8px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
/* Spaltenbreiten — Status bleibt schmal, Downloads bekommen Platz */
.col-id { width: 56px; }
.col-status { width: 110px; }
.col-progress { width: 130px; }
.col-updated { width: 130px; }
.col-dl { width: 280px; }
/* col-title nimmt den Rest */
.col-title { word-break: break-word; }
.status-pill {
display: inline-block;
padding: 2px 10px;
border-radius: 999px;
font-size: 12px;
border: 1px solid var(--border);
white-space: nowrap;
}
.status-queued { color: var(--muted); }
.status-transcribing, .status-summarizing, .status-protocolling, .status-exporting { color: var(--warn); border-color: rgba(241,196,15,.4); }
.status-done { color: var(--ok); border-color: rgba(46,204,113,.4); }
.status-failed { color: var(--err); border-color: rgba(231,76,60,.4); }
/* Fehlertext unter dem Pill — bricht um, max. 3 Zeilen */
.status-error {
margin-top: 6px;
font-size: 11px;
color: var(--err);
line-height: 1.35;
word-break: break-word;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Download-Buttons — sauberes 2×2-Grid, alle gleich breit */
.dl {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
}
.btn-dl {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 5px 10px;
border-radius: 6px;
background: rgba(79,140,255,.12);
border: 1px solid rgba(79,140,255,.4);
color: var(--accent);
text-decoration: none;
font-size: 12px;
font-weight: 500;
white-space: nowrap;
transition: background .15s ease, border-color .15s ease;
}
.btn-dl:hover { background: rgba(79,140,255,.22); border-color: var(--accent); }
.btn-dl.disabled {
color: var(--muted);
background: transparent;
border-color: var(--border);
pointer-events: none;
opacity: .55;
}
footer { text-align: center; padding: 24px 16px 32px; }
/* ── Header-Layout ─────────────────────────────────────────────── */
.header-row {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
max-width: 1000px;
margin: 0 auto;
}
.header-left { text-align: left; }
.header-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.user-bar {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
}
.user-bar strong { color: var(--text); }
.btn-link {
background: transparent;
color: var(--accent);
border: 0;
padding: 2px 6px;
font-size: 13px;
cursor: pointer;
text-decoration: underline;
}
.btn-link:hover { color: var(--accent-hover); }
.btn-link.btn-danger { color: var(--err); }
.admin-badge {
background: rgba(79,140,255,.18);
color: var(--accent);
border-color: rgba(79,140,255,.45);
text-transform: uppercase;
font-size: 11px;
letter-spacing: .5px;
padding: 2px 8px;
}
/* ── Auth-Overlay ──────────────────────────────────────────────── */
.overlay {
position: fixed;
inset: 0;
background: rgba(15, 17, 21, .92);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
padding: 20px;
}
.auth-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 28px 28px 22px;
width: 100%;
max-width: 380px;
box-shadow: 0 20px 60px rgba(0,0,0,.4);
}
.auth-card h2 { margin: 0 0 8px; font-size: 20px; }
.auth-card #auth-info { font-size: 13px; margin: 0 0 14px; }
.auth-card form { display: grid; gap: 12px; }
.auth-card button { justify-self: stretch; }
/* ── Admin: Benutzer-Verwaltung ────────────────────────────────── */
.user-form {
display: grid;
grid-template-columns: 1fr 1fr auto auto;
gap: 12px;
align-items: end;
}
.user-form label { font-size: 13px; }
.inline-check {
display: flex !important;
flex-direction: row !important;
align-items: center;
gap: 6px;
color: var(--text);
}
.inline-check input { margin: 0; }
#users-table .user-actions {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
@media (max-width: 700px) {
.user-form { grid-template-columns: 1fr; }
}
/* Select-Felder im selben Stil wie Inputs */
select {
background: #0f1219;
border: 1px solid var(--border);
color: var(--text);
padding: 10px 12px;
border-radius: 8px;
font-size: 14px;
font-family: inherit;
}
/* Kompakter Profil-Selector im Header */
.header-profile-wrap {
display: inline-flex;
align-items: center;
gap: 6px;
}
.header-profile {
padding: 3px 6px;
font-size: 12px;
border-radius: 5px;
background: #0f1219;
border: 1px solid var(--border);
color: var(--text);
max-width: 180px;
}
.header-profile:disabled { opacity: .5; }
/* Aufnahme-Button (groß, rot, touch-tauglich) */
.btn-record {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
padding: 14px 18px;
background: rgba(231,76,60,.12);
color: var(--err);
border: 1px solid rgba(231,76,60,.5);
border-radius: 10px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
min-height: 48px;
}
.btn-record:hover { background: rgba(231,76,60,.22); }
.rec-dot {
width: 12px; height: 12px;
background: var(--err);
border-radius: 50%;
}
/* Aufnahme-Bühne */
.record-pane {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 20px;
border: 1px solid rgba(231,76,60,.4);
background: rgba(231,76,60,.06);
border-radius: 12px;
margin-top: 6px;
}
.record-timer {
font-size: 44px;
font-variant-numeric: tabular-nums;
font-weight: 600;
color: var(--err);
letter-spacing: .04em;
}
.record-status { color: var(--muted); font-size: 13px; }
.record-status::before {
content: "● ";
color: var(--err);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .25; } }
.record-controls { display: flex; gap: 10px; margin-top: 6px; }
.btn-record-ctrl {
padding: 12px 22px;
border-radius: 8px;
background: var(--card);
color: var(--text);
border: 1px solid var(--border);
font-size: 15px;
cursor: pointer;
min-height: 44px;
min-width: 100px;
}
.btn-record-ctrl.danger {
background: var(--err);
color: white;
border-color: var(--err);
}
/* Aufnahme-Ergebnis */
.record-result {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
background: rgba(46,204,113,.08);
border: 1px solid rgba(46,204,113,.4);
border-radius: 8px;
font-size: 13px;
}
/* ── Sichtbarkeit-Helfer ───────────────────────────────────────── */
.mobile-only { display: none; }
/* Upload-Form Layout (Desktop) */
.upload-meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.audio-file-details summary {
cursor: pointer;
padding: 8px 4px;
color: var(--muted);
font-size: 13px;
user-select: none;
}
.audio-file-details summary:hover { color: var(--text); }
.audio-file-details[open] summary { color: var(--text); margin-bottom: 8px; }
.audio-file-label {
display: grid;
gap: 6px;
}
/* Admin-Toggle (auf Desktop deaktiviert) */
.admin-toggle { cursor: default; }
.admin-toggle-icon { display: none; }
/* ── Mobile-Optimierung (echte Mobile-First-UI) ────────────────── */
@media (max-width: 700px) {
.desktop-only { display: none !important; }
.mobile-only { display: block; }
body { font-size: 15px; }
/* HEADER: nur Logo + User */
header {
padding: 10px 14px;
text-align: left;
border-bottom: 1px solid var(--border);
}
header h1 { font-size: 18px; margin: 0; }
.header-row {
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.header-left, .header-right { align-items: center; }
.header-right { flex-direction: row; gap: 8px; flex: 1; justify-content: flex-end; }
.user-bar {
display: flex;
flex-direction: row;
align-items: center;
gap: 6px;
font-size: 13px;
flex-wrap: nowrap;
}
.user-bar strong { font-size: 14px; max-width: 90px; overflow: hidden; text-overflow: ellipsis; }
.header-profile { max-width: 130px; padding: 4px 6px; font-size: 12px; }
.btn-link { font-size: 12px; padding: 4px 6px; }
main { padding: 14px 12px 90px; gap: 14px; }
.card { padding: 16px; border-radius: 12px; }
.card h2 { font-size: 16px; margin-bottom: 10px; }
/* UPLOAD-CARD: Recording-Hero-Style */
.upload-card form { display: flex; flex-direction: column; gap: 14px; }
.btn-record {
/* HERO: groß und auffällig */
padding: 26px;
font-size: 19px;
min-height: 90px;
border-radius: 14px;
box-shadow: 0 4px 20px rgba(231,76,60,.15);
}
.btn-record .rec-dot { width: 16px; height: 16px; animation: pulse 1.5s ease-in-out infinite; }
.upload-meta { grid-template-columns: 1fr; gap: 10px; }
.upload-meta select,
.upload-meta input[type=text] {
padding: 14px 12px;
font-size: 16px; /* iOS: ≥16px verhindert Zoom-on-Focus */
min-height: 48px;
}
.audio-file-details summary { padding: 12px 4px; font-size: 14px; }
button[type="submit"] {
padding: 16px;
font-size: 16px;
min-height: 52px;
border-radius: 10px;
width: 100%;
}
/* Aufnahme-Bühne: noch größer auf Mobile */
.record-pane { padding: 24px 16px; }
.record-timer { font-size: 64px; line-height: 1; }
.record-controls { width: 100%; gap: 12px; }
.btn-record-ctrl {
flex: 1;
padding: 18px;
font-size: 17px;
min-height: 56px;
min-width: 0;
}
/* JOBS-CARDS statt Tabelle */
.jobs-cards { display: flex; flex-direction: column; gap: 10px; }
.jc {
background: #0f1219;
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px 14px;
}
.jc-head {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 8px;
margin-bottom: 6px;
}
.jc-id { color: var(--muted); font-size: 12px; }
.jc-title { font-weight: 600; font-size: 15px; line-height: 1.3; word-break: break-word; }
.jc-sub { color: var(--muted); font-size: 12px; margin-top: 2px; }
.jc-status-row {
display: flex;
align-items: center;
gap: 8px;
margin: 8px 0 6px;
}
.jc-progress { flex: 1; }
.jc-error {
color: var(--err);
font-size: 12px;
margin: 4px 0;
word-break: break-word;
}
.jc-dl {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
margin-top: 8px;
}
.jc-dl .btn-dl { padding: 8px; font-size: 12px; min-height: 36px; }
/* Admin-Bereich: collapsible */
.admin-collapsible .admin-toggle {
cursor: pointer;
user-select: none;
display: flex;
justify-content: space-between;
align-items: center;
margin: 0;
}
.admin-toggle-icon { display: inline; transition: transform .2s; }
.admin-collapsible:not(.open) .admin-body { display: none; }
.admin-collapsible.open .admin-toggle-icon { transform: rotate(180deg); }
.user-form { grid-template-columns: 1fr; }
.user-form input { font-size: 16px; }
}
/* iOS PWA: oberer Sicherheitsbereich (Notch) respektieren */
@supports (padding: max(0px)) {
header { padding-top: max(10px, env(safe-area-inset-top)); }
main { padding-bottom: max(20px, env(safe-area-inset-bottom)); }
}
/* Profile-Tag in der Job-Zeile */
.tag-profile {
display: inline-block;
padding: 1px 8px;
margin-left: 6px;
border-radius: 4px;
background: rgba(46,204,113,.12);
border: 1px solid rgba(46,204,113,.4);
color: var(--ok);
font-size: 11px;
text-transform: lowercase;
vertical-align: middle;
}