Layout-Fix Satz-Zeile (mobil), README knapp/oeffentlich, Roadmap aktualisiert
Image bauen und in die Registry schieben / build (push) Successful in 6s
Image bauen und in die Registry schieben / build (push) Successful in 6s
- ex-grid: minmax(min(460px,100%),1fr) -> keine 460px-Mindestspalte auf dem Handy mehr; Block und X-Button nicht mehr abgeschnitten - Satz-Zeile: Aktionen (Reset/X) rechtsbuendig per flexiblem Spacer; auf sehr schmalen Handys kompaktere Felder (72px) - README: gekuerzt, bodenstaendiger Ton, interne CI/CD-/Infra-Notizen raus - ROADMAP: Umgesetztes markiert, veraltete Punkte entfernt, gestrafft - Tests: 169 Checks gruen (39+18+52+32+28)
This commit is contained in:
1 parent
1759da8437
commit
7c5045cec8
4 files changed
+92
-136
No files matched your search
@@ -1,135 +1,85 @@
|
||||
# REKORD
|
||||
|
||||
**Rekord & Record: dein Training, festgehalten.**
|
||||
Selbstgehosteter Trainings-Tracker für Gym, Laufen und Radfahren. Läuft im
|
||||
Browser, speichert auf deinem Server, gehört dir.
|
||||
|
||||
Ein leichtgewichtiger, selbst gehosteter Trainings-Tracker fürs Gym, Laufen
|
||||
und Radfahren. Läuft in jedem modernen Browser, speichert auf deiner Platte
|
||||
und wertet deine Fitnessdaten nicht aus. Kein Abo, kein Konto bei einem
|
||||
Anbieter, keine Datenkraken.
|
||||
Eine SQLite-Datei als Zustand, ein Python-Backend aus der Standardbibliothek,
|
||||
ein HTML/CSS/JS-Frontend ohne Framework. Kein Cloud-Konto, keine Telemetrie.
|
||||
|
||||
## Warum REKORD?
|
||||
|
||||
- **Kein Vendor Lock-in.** Alles läuft bei dir: Backend auf deinem Server,
|
||||
Zustand in einer portablen SQLite-Datei. Export jederzeit als JSON oder
|
||||
CSV, Import genauso. Zieh um oder hör auf - deine Daten gehören dir.
|
||||
- **Leichtgewichtig.** Python-Standardbibliothek + SQLite im Backend, ein
|
||||
HTML-, ein CSS-, ein JS-File im Frontend. Kein Framework, kein
|
||||
Build-Schritt, keine Node-Installation. Läuft auf einem Mini-PC, einem
|
||||
alten Laptop oder in einem Container.
|
||||
- **Browserbasiert.** Keine App, kein Store, keine Installation. Aufschlagen,
|
||||
loslegen - auf jedem Gerät mit Browser.
|
||||
- **Cross-Device Sync.** Der Zustand liegt serverseitig. Öffne die App am
|
||||
Handy, am Laptop oder am Desktop-Rechner - es ist derselbe Stand. Mehrere
|
||||
Benutzer mit eigenen Konten und getrennten Daten sind eingebaut.
|
||||
- **UX zuerst.** Sätze eintragen mit einer Box (Zahl + Einheit in einem
|
||||
Feld), Set-Kette durch Abhaken, "Alles zurücksetzen", Verlauf inline
|
||||
bearbeiten, Wochenübersicht, Statistik mit Differenz zur ersten Messung.
|
||||
Der Tracker reibt sich nicht in den Weg zwischen dich und die Übung.
|
||||
- **Dein Take aufs Aufzeichnen.** Die App zeichnet auf - Gewichte, Reps,
|
||||
Cardio-Felder - und zeigt die Entwicklung über die Zeit. Sie verkauft
|
||||
nichts, personalisiert nichts und schickt nichts nach Hause.
|
||||
- **Open Source.** AGPL-3.0. Nachvollziehbar, erweiterbar, auditierbar.
|
||||
|
||||
## Features im Überblick
|
||||
## Was es kann
|
||||
|
||||
**Training erfassen**
|
||||
|
||||
- Gym mit Push/Pull/Legs (frei konfigurierbar) plus Laufen und Radfahren
|
||||
- Gym mit Push/Pull/Legs (frei konfigurierbar), dazu Laufen und Radfahren
|
||||
- Eingabe als eine Box: Zahl links, Einheit fest rechts (kg, reps, km, min,
|
||||
min/km, bpm, m)
|
||||
- Set-Abhaken als "Set n [ ]": der ganze Button ist klickbar, das Set hakt
|
||||
eine Kette ab - ohne Lücken
|
||||
- Reset-Satz und "Alles zurücksetzen" laden das letzte abgeschlossene
|
||||
Training
|
||||
- Vorbefüllung beim Start (optional): "Letztes Training vorbefüllen" oder
|
||||
"Plan-Gewichte vorbefüllen" (startKg aus der Config, auch ohne Verlauf)
|
||||
- Sätze abhaken als "Set n [ ]"; der ganze Button ist klickbar, die Kette
|
||||
hakt ohne Lücken ab
|
||||
- "Reset-Satz" und "Alles zurücksetzen" holen das letzte abgeschlossene
|
||||
Training; optional startet eine Session direkt mit dem letzten Workout
|
||||
oder mit den Plan-Gewichten
|
||||
- Übungen per Drag & Drop sortieren, Übungen aus anderen Tagen spontan
|
||||
hinzufügen
|
||||
- Fragezeichen pro Übung: Erklärung plus die passende Maschine
|
||||
- Fragezeichen pro Übung: kurze Erklärung (herstellerunabhängig)
|
||||
|
||||
**Sessions & Verlauf**
|
||||
**Verlauf & Statistik**
|
||||
|
||||
- "Session starten" / "Session abschließen", mehrere Sessions am Tag
|
||||
- Keine Geister: erst abgeschlossene Sessions erscheinen im Verlauf
|
||||
- Verlauf als Liste oder Wochenübersicht, inline bearbeitbar (Datum, Zeiten,
|
||||
Abhak-Status, Werte) und löschbar
|
||||
- Statistik: bestes Gewicht je Trainingstag mit Balken, Differenz zur ersten
|
||||
Messung
|
||||
- Verlauf als Liste oder Wochenübersicht; inline bearbeitbar und löschbar
|
||||
- Statistik: bestes Gewicht je Trainingstag, Differenz zur ersten Messung
|
||||
|
||||
**Ansicht & Einstellungen**
|
||||
|
||||
- Deutsch und Englisch (Server-Standard und pro Benutzer)
|
||||
- Farbthema: Dunkel, System (folgt dem Gerät), Hell - plus OLED-Dark-Schalter
|
||||
- Akzentfarbe aus zehn Farben (inklusive Weiß)
|
||||
- Gewichtseinheit kg oder lb, Start-Ansicht wählbar
|
||||
- Einstellungen serverseitig, gelten auf allen Geräten
|
||||
- Deutsch und Englisch
|
||||
- Themes: Dunkel, System, Hell - plus OLED-Dark-Schalter
|
||||
- Akzentfarbe aus zehn Farben, Gewichtseinheit kg/lb, Start-Ansicht wählbar
|
||||
- Einstellungen liegen serverseitig, gelten auf allen Geräten
|
||||
|
||||
**Mehrbenutzer**
|
||||
|
||||
- Eigene Konten mit Kennwort (gehasht), Daten strikt getrennt
|
||||
- Konten mit Kennwort (gehasht), Daten getrennt pro Benutzer
|
||||
- Der erste Benutzer ist Administrator und verwaltet Konten und Kennwörter
|
||||
- Einmaliger Einrichtungs-Wizard beim ersten Start (Sprache, Modus,
|
||||
Darstellung)
|
||||
|
||||
**Daten**
|
||||
|
||||
- Export/Import als JSON und CSV (Backup, Umzug, Tabellen-Auswertung)
|
||||
- Workouts über eine kleine API abrufbar (`/api/workouts`)
|
||||
- Demo-Daten (`demo-data.json`) zum direkten Ausprobieren
|
||||
- Workouts über eine kleine API (`/api/workouts`)
|
||||
- Demo-Verlauf (`demo-data.json`) zum Ausprobieren
|
||||
|
||||
## Schnellstart
|
||||
## Starten
|
||||
|
||||
Python (nur Standardbibliothek, kein `pip install`):
|
||||
Python (nur Standardbibliothek):
|
||||
|
||||
```bash
|
||||
python3 server.py 8080
|
||||
```
|
||||
|
||||
Oder mit Docker:
|
||||
Oder Docker:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Danach im Browser: `http://<host>:8080/`
|
||||
Danach im Browser: `http://<host>:8080/`. Beim ersten Start führt ein kurzer
|
||||
Wizard durch Sprache, Einzel- oder Mehrbenutzermodus und Darstellung.
|
||||
|
||||
Beim ersten Start führt dich ein kurzer Wizard durch Sprache, Einzel- oder
|
||||
Mehrbenutzermodus und Darstellung - danach ist die App einsatzbereit.
|
||||
## Plan anpassen
|
||||
|
||||
## Den Übungsplan anpassen
|
||||
Übungen, Sätze, Gewichte und Erklärungen stehen in `config.json` - ohne
|
||||
Code-Eingriff. Schema: [TECH.md](TECH.md).
|
||||
|
||||
Alle Übungen, Sätze, Gewichte, Maschinen und Erklärungen stehen in
|
||||
`config.json` - ohne Code-Eingriff. Das komplette Schema steht in der
|
||||
[technischen Dokumentation](TECH.md).
|
||||
|
||||
## Automatischer Build (CI/CD)
|
||||
|
||||
Ein Push auf `main` baut automatisch ein Docker-Image und legt es in der
|
||||
Gitea-Registry ab (`git.somantis.net/j4stmarkus/trainingsplan`). Dafür läuft
|
||||
ein Gitea-Actions-Runner auf dem Server; die Workflow-Datei liegt unter
|
||||
`.gitea/workflows/build-image.yml`. Die CasaOS-Installation
|
||||
(`docker-compose.casaos.yml`) bezieht die App aus diesem Registry-Image.
|
||||
Fürs lokale Entwickeln bleibt `docker-compose.yml` mit `build: .` bestehen.
|
||||
|
||||
## Daten & Privatsphäre
|
||||
## Daten
|
||||
|
||||
- Alles liegt in `data/state.db` (SQLite) - backupbar, überlebt Neustart und
|
||||
Container-Rebuild
|
||||
- Datenverzeichnis frei wählbar (`TRAINING_STATE_DIR`)
|
||||
- Keine externen Dienste, keine Telemetrie, keine Analyse deiner Daten
|
||||
- Datenverzeichnis per `TRAINING_STATE_DIR` frei wählbar
|
||||
- Keine externen Dienste, keine Telemetrie
|
||||
|
||||
## Roadmap
|
||||
## Mehr
|
||||
|
||||
Die geplante Weiterentwicklung (Übungskatalog in der App bearbeiten,
|
||||
herstellerunabhängige Info-Texte mit Bildern/Schritten, Plugin-System mit
|
||||
Ollama/Cloud-Coach, Wearable-Import, CLI-Harness) steht in
|
||||
[ROADMAP.md](ROADMAP.md).
|
||||
|
||||
## Design
|
||||
|
||||
Die verbindliche Design-Sprache (Tokens, Komponenten, Zustaende, Anti-
|
||||
Patterns) steht in [DESIGN.md](DESIGN.md) - wiederverwendbar für weitere
|
||||
Projekte.
|
||||
- [TECH.md](TECH.md) - Architektur, API, Datenmodell
|
||||
- [DESIGN.md](DESIGN.md) - Design-Sprache (Tokens, Komponenten, Anti-Patterns)
|
||||
- [ROADMAP.md](ROADMAP.md) - geplante Erweiterungen
|
||||
|
||||
## Lizenz
|
||||
|
||||
|
||||
+46
-47
@@ -1,63 +1,62 @@
|
||||
# REKORD - Roadmap
|
||||
|
||||
Interne Roadmap. Prioritaeten: P1 = naechste Iterationen, P2 = bald, P3 =
|
||||
spaeter. Status: Idee / Geplant / In Arbeit / Fertig.
|
||||
Was geplant ist, und was schon steht. Priorität: P1 = als Nächstes, P2 = bald,
|
||||
P3 = später. Status: Fertig / Teilweise / Geplant.
|
||||
|
||||
Zielrichtung: breiteres Feature-Set, einfachere Erweiterung des
|
||||
Uebungs-/Maschinen-Katalogs, herstellerunabhaengige Inhalte, sanfte
|
||||
Integration (Plugins, lokale Modelle) statt Monolithen. Architektur-Leitplanken
|
||||
bleiben: Config-getrieben, leichtgewichtig, Daten lokal, keine Telemetrie.
|
||||
Leitplanken bleiben: config-getrieben, leichtgewichtig, Daten lokal, keine
|
||||
Telemetrie.
|
||||
|
||||
---
|
||||
## Umgesetzt
|
||||
|
||||
## Phase 1 - Inhalte & Bedienbarkeit
|
||||
- Config-getriebener Plan (`config.json`), SQLite-Zustand serverseitig
|
||||
- Gym (Push/Pull/Legs), Laufen, Radfahren; Cardio-Felder aus der Config
|
||||
- Set-Kette, Reset-Satz, "Alles zurücksetzen", Vorbefüllung (letztes Workout
|
||||
oder Plan-Gewichte)
|
||||
- Übungen per Drag & Drop sortieren, Übungen aus anderen Tagen hinzufügen
|
||||
- Verlauf als Liste und Wochenübersicht, Inline-Bearbeitung, Löschen
|
||||
- Statistik: bestes Gewicht je Tag, Differenz zur ersten Messung
|
||||
- Mehrbenutzer mit Admin, Kennwort ändern/zurücksetzen, Server-Reset
|
||||
- Einrichtungs-Wizard (Sprache, Darstellung, Modus)
|
||||
- i18n de/en, Themes dunkel/system/hell + OLED, zehn Akzentfarben
|
||||
- Export/Import JSON/CSV, Workouts-API, Demo-Daten
|
||||
- Übungs-Infos herstellerunabhängig; mobile-taugliche Satz-Zeile
|
||||
|
||||
| Prioritaet | Thema | Status | Notiz |
|
||||
## Offen
|
||||
|
||||
### Inhalte & Bedienbarkeit
|
||||
|
||||
| Prio | Thema | Status | Notiz |
|
||||
|---|---|---|---|
|
||||
| P1 | **Uebungen/Maschinen in der App bearbeiten** | Idee | Heute aendert man `config.json` von Hand. Ziel: Uebungen, Tage, Maschinen und Info-Texte direkt in der App anlegen/bearbeiten (persistiert neben der Config), damit ein Nicht-Programmierer den Plan ohne Dateieditor pflegt. |
|
||||
| P1 | **Info-Texte erweitern** | Idee | Neben dem Freitext: optionale Bilder (URL oder Upload), Schritte als Checkliste, ein "wertvoller Link" (z.B. zu einer neutralen Anatomie-/Form-Quelle). Wichtig: **nicht hersteller-spezifisch** - die Technogym-Referenzen aus der Config sind nur Platzhalter; der Katalog soll generisch sein. |
|
||||
| P1 | **Uebungsvarianten & Maschinen-Tags** | Idee | Eine Uebung mit mehreren Varianten (KH, Maschine, Kabel) und deren Verfuegbarkeit; beim Training schnell zwischen den Geräten wechseln, die im Studio stehen. |
|
||||
| P1 | **Set-Vorlagen pro Uebung** | Idee | Im Plan definierte Satz-Vorlagen (Anzahl, Ziel-Reps, Pause) als Startpunkt - schon teilweise da ("Plan-Gewichte vorbefuellen"), aber noch nicht pro Satz steuerbar. |
|
||||
| P2 | **Gewichtseinheiten pro Uebung** | Idee | z.B. Bodyweight (kein kg), Bandwiderstand, Maschinen-Gewicht inkl. Hebel - neben dem globalen kg/lb. |
|
||||
| P1 | Übungen/Maschinen in der App bearbeiten | Geplant | Statt `config.json` von Hand: Übungen, Tage und Info-Texte direkt in der App pflegen. |
|
||||
| P1 | Info-Texte erweitern | Geplant | Optional Bilder, Schritte als Checkliste, ein Link (neutral, nicht herstellerspezifisch). |
|
||||
| P1 | Übungsvarianten & Maschinen-Tags | Geplant | Eine Übung mit Varianten (KH, Maschine, Kabel) und schnellem Wechsel im Training. |
|
||||
| P2 | Set-Vorlagen pro Übung | Teilweise | Plan-Gewichte vorbefüllen gibt es; noch nicht pro Satz steuerbar (Ziel-Reps, Pause). |
|
||||
| P2 | Einheiten pro Übung | Geplant | Bodyweight, Band, Maschinen-Gewicht - neben dem globalen kg/lb. |
|
||||
|
||||
## Phase 2 - Integration & Automation
|
||||
### Integration
|
||||
|
||||
| Prioritaet | Thema | Status | Notiz |
|
||||
| Prio | Thema | Status | Notiz |
|
||||
|---|---|---|---|
|
||||
| P1 | **Plugin-System** | Idee | Kleine Plugins (JS im Browser und/oder Server-Skripte) mit klaren Hooks: nach Session-Speichern, beim Export, beim Anzeigen einer Uebung, beim Abschluss. Registrierung in der Config. So bleiben Erweiterungen ausserhalb des Kerns. |
|
||||
| P1 | **Ollama/Cloud-Coach** | Idee | Plugin, das Form-Tipps/Zusammenfassungen per API generiert - **local-first** (Ollama), Cloud nur mit expliziter Zustimmung und eigener Wahl des Anbieters/Keys. Keine Daten gehen ohne Erlaubnis nach aussen. |
|
||||
| P2 | **Webhooks bei Events** | Idee | Nach "Session abgeschlossen", "Benutzer angelegt" etc. - fuer eigene Automation (Backup, Benachrichtigungen, Hausautomation). |
|
||||
| P2 | **API-Keys pro Benutzer** | Idee | Neben den Login-Tokens: eigene read/write Keys pro Benutzer fuer Scripts, ohne das Konto freizugeben. |
|
||||
| P2 | **Effizienter Harness (CLI)** | Idee | Kleines Kommandozeilen-/Script-Interface (`rekord`-CLI oder Python-Client) gegen die API: Workouts eintragen/abrufen, Statistiken ziehen - fuer Cron-Jobs, TUI, Automation. |
|
||||
| P3 | **Wearable-Import** | Idee | Garmin/Apple/Fitbit/Samsung-Health-Exporte (CSV/JSON) als Plugin importieren; Puls etc. an Cardio-Sessions anhaengen. Kein Live-Sync in Phase 1. |
|
||||
| P1 | Plugin-System | Geplant | Kleine Plugins mit Hooks (nach Session-Speichern, beim Export, beim Anzeigen). |
|
||||
| P1 | Ollama/Cloud-Coach | Geplant | Form-Tipps/Zusammenfassungen per API - local-first (Ollama), Cloud nur auf Wunsch. |
|
||||
| P2 | Webhooks bei Events | Geplant | Nach "Session abgeschlossen" o.ä. für eigene Automation. |
|
||||
| P2 | API-Keys pro Benutzer | Geplant | Read/write Keys für Scripts, ohne das Konto freizugeben. |
|
||||
| P2 | CLI-Harness | Geplant | Kleines Kommandozeilen-Interface gegen die API (Cron, TUI). |
|
||||
| P3 | Wearable-Import | Geplant | Garmin/Apple/Fitbit/Samsung-Exporte (CSV/JSON) als Plugin. |
|
||||
|
||||
## Phase 3 - Analyse & UX
|
||||
### Analyse & UX
|
||||
|
||||
| Prioritaet | Thema | Status | Notiz |
|
||||
| Prio | Thema | Status | Notiz |
|
||||
|---|---|---|---|
|
||||
| P1 | **Volumen & 1RM-Schaetzung** | Idee | Trainingsvolumen (kg × Reps) je Uebung/Tag, 1RM-Schaetzung (z.B. Epley) als zusaetzliche Statistik-Kennzahl. |
|
||||
| P2 | **Wochenvergleich & Trends** | Idee | Statistik ueber Wochen hinweg (nicht nur "Differenz zur ersten Messung"): gleitende Durchschnitte, PR-Markierungen, Verlaufs-Graph (ohne externe Chart-Lib, wenn moeglich). |
|
||||
| P2 | **PWA / Offline** | Idee | Als installierbare App (Service Worker, App-Icon) - nicht kritisch, da serverseitig, aber schoener auf dem Handy. |
|
||||
| P2 | **Sessions am selben Tag bessern** | Idee | Mehrere Sessions pro Tag sind drin; UX fuer "morgens laufen, abends Gym" vereinfachen (schneller Aktivitaets-/Tag-Wechsel). |
|
||||
| P1 | Volumen & 1RM-Schätzung | Geplant | kg × Reps je Übung/Tag, 1RM-Schätzung als zusätzliche Kennzahl. |
|
||||
| P2 | Wochenvergleich & Trends | Geplant | Gleitende Durchschnitte, PR-Markierungen, Verlauf ohne Chart-Lib. |
|
||||
| P2 | PWA / Offline | Geplant | Installierbar auf dem Handy (Service Worker, Icon). |
|
||||
| P2 | Mehrere Sessions am Tag | Teilweise | Funktioniert; Aktivitäts-/Tag-Wechsel im UI vereinfachen. |
|
||||
|
||||
## Phase 4 - Qualitaet & Betrieb
|
||||
### Qualität
|
||||
|
||||
| Prioritaet | Thema | Status | Notiz |
|
||||
| Prio | Thema | Status | Notiz |
|
||||
|---|---|---|---|
|
||||
| P2 | **Barrierefreiheit (a11y)** | Idee | Tastatur-Navigation, Kontraste, Screenreader-Labels systematisch pruefen. |
|
||||
| P2 | **Backup/Retention** | Idee | Automatische Export-Erinnerung oder in-App-Backup-Timer; Dokumentation fuer Rotation. |
|
||||
| P3 | **Mehrsprachigkeit ausbauen** | Idee | i18n-Architektur ist da (de/en); weitere Sprachen als Community-Beitrag. |
|
||||
| P3 | **Mehr-Server / Replikation** | Idee | Datenhaltung bleibt SQLite; falls noetig: Import/Export als Synchronisationsweg dokumentieren statt Live-Replikation. |
|
||||
|
||||
---
|
||||
|
||||
## Konzepte in einem Satz
|
||||
|
||||
- **Content in der App statt in der Datei** - der Uebungskatalog wird Teil des
|
||||
Produkts, nicht des Repos.
|
||||
- **Herstellerunabhaengig** - Maschinen-Referenzen sind Hinweise, keine
|
||||
Abhaengigkeit; Links/Medien sind optional und austauschbar.
|
||||
- **Plugins statt Kern-Zerfaserung** - alles, was nicht jeder braucht
|
||||
(Coach, Sync, Import), wird Plugin.
|
||||
- **Local-first** - lokale Modelle (Ollama) sind der Default, Cloud nur auf
|
||||
ausdruecklichen Wunsch.
|
||||
| P2 | Barrierefreiheit | Teilweise | Fokus, Kontraste, Labels gepflegt; systematischer Test offen. |
|
||||
| P2 | Backup/Erinnerung | Geplant | Export gibt es; automatische Backup-Erinnerung offen. |
|
||||
| P3 | Weitere Sprachen | Geplant | i18n-Architektur (de/en) steht; weitere Sprachen als Beitrag. |
|
||||
@@ -931,6 +931,7 @@ function buildSetRow(a, model, ex, entry, i) {
|
||||
row.appendChild(rBox);
|
||||
entry.wInput = wBox.querySelector("input");
|
||||
entry.rInput = rBox.querySelector("input");
|
||||
row.appendChild(el("span", "set-gap"));
|
||||
|
||||
const reset = el("button", "icon-btn", "");
|
||||
reset.type = "button";
|
||||
|
||||
+8
-2
@@ -405,7 +405,7 @@ h3 { font-size: 15px; font-weight: 700; }
|
||||
|
||||
.ex-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(460px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(min(460px, 100%), 1fr));
|
||||
gap: 14px;
|
||||
align-items: start;
|
||||
}
|
||||
@@ -438,12 +438,18 @@ h3 { font-size: 15px; font-weight: 700; }
|
||||
|
||||
.set-row {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto auto;
|
||||
grid-template-columns: auto auto auto 1fr auto auto;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.set-gap { min-width: 0; }
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.field-box { width: 72px; }
|
||||
}
|
||||
|
||||
.set-rows { overflow: hidden; }
|
||||
|
||||
.set-row.is-done { background: var(--bg-subtle); }
|
||||
|
||||
Reference in new issue
Block a user