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.
This commit is contained in:
root
2026-05-14 04:00:33 +00:00
parent e75bc05421
commit 24ac3ac058
3 changed files with 260 additions and 71 deletions
+47 -31
View File
@@ -19,17 +19,17 @@
<div class="header-row">
<div class="header-left">
<h1>Voice-Agent</h1>
<p class="sub">Sitzungsaufnahmen automatisch transkribieren und protokollieren</p>
<p class="sub desktop-only">Sitzungsaufnahmen automatisch transkribieren und protokollieren</p>
</div>
<div class="header-right">
<div id="mac-status" class="badge">Mac-Backend: prüfe …</div>
<div id="mac-status" class="badge desktop-only">Mac-Backend: prüfe …</div>
<div id="user-bar" class="user-bar hidden">
<span class="muted">Angemeldet als</span>
<span class="muted desktop-only">Angemeldet als</span>
<strong id="user-name"></strong>
<span id="user-admin-badge" class="badge admin-badge hidden">Admin</span>
<span id="header-profile-wrap" class="header-profile-wrap hidden">
<span class="muted">·</span>
<span class="muted">Profil:</span>
<span class="muted desktop-only">·</span>
<span class="muted desktop-only">Profil:</span>
<select id="header-profile" class="header-profile" title="Standard-Profil — wird sofort gespeichert"></select>
</span>
<button type="button" id="logout-btn" class="btn-link">Abmelden</button>
@@ -59,30 +59,16 @@
</div>
<main id="app" class="hidden">
<section class="card">
<h2>Neue Aufnahme hochladen</h2>
<section class="card upload-card">
<h2 class="desktop-only">Neue Aufnahme hochladen</h2>
<form id="upload-form">
<label>
Titel (optional)
<input type="text" name="title" id="title" placeholder="z. B. Monatsbesprechung" />
</label>
<label id="profile-label" class="hidden">
Verarbeitungs-Profil
<select id="profile-select"></select>
<small class="muted">Standard: <span id="default-profile-name">—</span> (in Einstellungen änderbar)</small>
</label>
<div class="audio-source">
<label class="audio-file-label">
<span>Audiodatei wählen <small class="muted">(MP3, WAV, M4A, MP4, OGG, FLAC, WebM)</small></span>
<input type="file" name="audio" id="audio" accept="audio/*,.mp3,.wav,.m4a,.mp4,.ogg,.flac,.webm" />
</label>
<div class="audio-or muted">— oder —</div>
<button type="button" id="record-toggle" class="btn-record">
<span class="rec-dot"></span>
<span id="record-toggle-label">Aufnahme starten</span>
</button>
</div>
<!-- HERO: Aufnahme-Button (auf Mobile groß und zentriert) -->
<button type="button" id="record-toggle" class="btn-record">
<span class="rec-dot"></span>
<span id="record-toggle-label">Aufnahme starten</span>
</button>
<!-- Aufnahme-Bühne -->
<div id="record-pane" class="record-pane hidden">
<div class="record-timer" id="record-timer">00:00</div>
<div class="record-status" id="record-status">Aufnahme läuft</div>
@@ -92,12 +78,35 @@
</div>
</div>
<!-- Aufnahme bereit -->
<div id="record-result" class="record-result hidden">
<span class="muted">Aufnahme bereit:</span>
<span id="record-filename"></span>
<button type="button" id="record-discard" class="btn-link btn-danger">Verwerfen</button>
</div>
<!-- Profil + Titel -->
<div class="upload-meta">
<label id="profile-label" class="hidden">
Verarbeitungs-Profil
<select id="profile-select"></select>
<small class="muted desktop-only">Standard: <span id="default-profile-name">—</span></small>
</label>
<label>
Titel <span class="muted">(optional)</span>
<input type="text" name="title" id="title" placeholder="z. B. Monatsbesprechung" />
</label>
</div>
<!-- Datei-Upload als Klappe (auf Mobile collapsed, auf Desktop offen) -->
<details class="audio-file-details" id="audio-file-details">
<summary>Lieber eine vorhandene Audio-Datei hochladen?</summary>
<label class="audio-file-label">
<span class="muted">MP3, WAV, M4A, MP4, OGG, FLAC, WebM</span>
<input type="file" name="audio" id="audio" accept="audio/*,.mp3,.wav,.m4a,.mp4,.ogg,.flac,.webm" />
</label>
</details>
<button type="submit" id="submit-btn">Hochladen &amp; verarbeiten</button>
</form>
<div id="upload-progress" class="hidden">
@@ -107,9 +116,10 @@
<p id="upload-msg" class="msg"></p>
</section>
<section class="card">
<section class="card jobs-card">
<h2>Jobs</h2>
<table id="jobs-table">
<!-- Desktop: Tabelle -->
<table id="jobs-table" class="desktop-only">
<thead>
<tr>
<th class="col-id">#</th>
@@ -124,11 +134,16 @@
<tr><td colspan="6" class="muted">Noch keine Jobs.</td></tr>
</tbody>
</table>
<!-- Mobile: Card-Liste -->
<div id="jobs-cards" class="jobs-cards mobile-only">
<div class="muted">Noch keine Jobs.</div>
</div>
</section>
<!-- Nur sichtbar für Admins -->
<section id="admin-card" class="card hidden">
<h2>Benutzer verwalten</h2>
<section id="admin-card" class="card hidden admin-collapsible">
<h2 class="admin-toggle" id="admin-toggle">Benutzer verwalten <span class="admin-toggle-icon">▾</span></h2>
<div class="admin-body">
<form id="user-form" class="user-form">
<label>
Benutzername
@@ -157,6 +172,7 @@
</thead>
<tbody id="users-body"></tbody>
</table>
</div>
</section>
</main>