diff --git a/app.js b/app.js index 457d48a..e8bab9f 100644 --- a/app.js +++ b/app.js @@ -141,6 +141,7 @@ const LANG = { system: "System", oled_toggle: "OLED-Dark", oled_desc: "Reines Schwarz für den dunklen Modus.", + appearance_desc: "Theme, Akzentfarbe und OLED-Dark für deine App.", last_workout: "Letztes Training vorbefüllen", last_workout_desc: "Neue Session startet mit dem letzten abgeschlossenen Workout der Kategorie (nur ausgefüllte Sätze).", plan_prefill: "Plan-Gewichte vorbefüllen", @@ -249,6 +250,7 @@ const LANG = { system: "System", oled_toggle: "OLED dark", oled_desc: "Pure black for the dark mode.", + appearance_desc: "Theme, accent color and OLED dark for your app.", last_workout: "Prefill last workout", last_workout_desc: "New sessions start with the last completed workout of the category (only filled sets).", plan_prefill: "Prefill plan weights", @@ -594,12 +596,15 @@ function renderStrengthSession(card, a, model) { } const dayKeys = day.exercises.map(x => x.key); + const grid = el("div", "ex-grid"); + model.exGrid = grid; + card.appendChild(grid); for (const k of model.exKeys) { const ex = model.exByKey[k] || { key: k, name: k, sets: { count: 0 }, target: "", startKg: "", info: "", tags: [], }; - card.appendChild(buildExBlock(a, model, ex, !dayKeys.includes(k))); + grid.appendChild(buildExBlock(a, model, ex, !dayKeys.includes(k))); } } @@ -668,20 +673,23 @@ function sessionHead(a, model, dayTitle, day) { noteBox.appendChild(noteInput); head.appendChild(noteBox); + const actions = el("div", "session-actions"); if (a.type === "strength") { const resetAll = el("button", "btn btn-small", t("reset_all")); resetAll.type = "button"; resetAll.title = t("reset_all_title"); resetAll.addEventListener("click", () => resetAllSets(a, model)); - head.appendChild(resetAll); + actions.appendChild(resetAll); } - const fin = el("button", "btn btn-primary", t("finish_session")); fin.type = "button"; fin.addEventListener("click", () => finishSession(a, model)); - head.appendChild(fin); + actions.appendChild(fin); + head.appendChild(actions); - head.appendChild(discardBtn(a, model)); + const disc = discardBtn(a, model); + disc.classList.add("session-discard"); + head.appendChild(disc); return head; } @@ -720,8 +728,8 @@ function addExercise(a, model, exKey) { const count = cfg.list ? cfg.list.length : (cfg.count || 1); model.exercises[exKey] = Array.from({ length: count }, () => ({ id: null, weight: "", reps: "", done: 0 })); - const card = app.cards[model.activity]; - if (card) card.appendChild(buildExBlock(a, model, ex, true)); + const target = model.exGrid || app.cards[model.activity]; + if (target) target.appendChild(buildExBlock(a, model, ex, true)); model.dirtyEx.add(exKey); scheduleAutosave(model); } @@ -746,10 +754,10 @@ function reorderExercise(a, model, fromKey, toKey) { if (from < 0 || to < 0) return; keys.splice(from, 1); keys.splice(to, 0, fromKey); - const card = app.cards[model.activity]; - if (card) { + const target = model.exGrid || app.cards[model.activity]; + if (target) { const blocks = keys.map(k => model.exBlocks[k]).filter(Boolean); - for (const b of blocks) card.appendChild(b); + for (const b of blocks) target.appendChild(b); } model.fields = Object.assign({}, model.fields, { exerciseOrder: keys.slice() }); model.metaDirty = true; @@ -1761,9 +1769,7 @@ function renderWizardStep() { } else { // Letzter Schritt: Darstellung (Theme + OLED + Akzent) box.appendChild(el("h3", "wizard-title", t("appearance"))); - if (wizard.mode === "setup") { - box.appendChild(el("p", "auth-sub", t("color_server"))); - } + box.appendChild(el("p", "auth-sub", t("appearance_desc"))); box.appendChild(el("div", "picker-label", t("theme_label"))); const themeRow = el("div", "day-picker"); for (const [key, label] of [["dark", t("dark")], ["system", t("system")], ["light", t("light")]]) { @@ -2110,7 +2116,7 @@ function renderAccountSection() { sec.appendChild(el("h3", "", t("account"))); const body = el("div", "data-body"); body.appendChild(el("p", "", t("account_desc", { u: app.me.username }))); - const row = el("div", "data-row"); + const row = el("div", "form-row"); const cur = el("input", "file-input"); cur.type = "password"; cur.placeholder = t("current_pw"); @@ -2147,7 +2153,7 @@ function renderSetupUsersSection() { sec.appendChild(el("h3", "", t("setup_users"))); const body = el("div", "data-body"); body.appendChild(el("p", "", t("users_solo_desc"))); - const row = el("div", "data-row"); + const row = el("div", "form-row"); const name = el("input", "file-input"); name.type = "text"; name.placeholder = t("username"); @@ -2247,7 +2253,7 @@ function renderOwnerUsersSection() { } }; reload(); - const row = el("div", "data-row"); + const row = el("div", "form-row"); const name = el("input", "file-input"); name.type = "text"; name.placeholder = t("username"); diff --git a/styles.css b/styles.css index 1e8f0ae..b639cd8 100644 --- a/styles.css +++ b/styles.css @@ -14,11 +14,12 @@ --border: #333; --border-hover: #4d4d4d; --text: #e8e8e8; - --muted: #8f8f8f; + --muted: #a0a0a0; --accent: #ffffff; --accent-hover: #f2f2f2; --accent-active: #e6e6e6; --accent-ink: #141414; + --accent-border: var(--accent); --danger: #c0392b; --ok: #6fae5c; --font-ui: system-ui, -apple-system, "Segoe UI", sans-serif; @@ -26,6 +27,7 @@ } html[data-theme="light"] { + --muted: #5c5c59; --bg: #f2f2f0; --bg-panel: #ffffff; --bg-input: #ffffff; @@ -40,6 +42,7 @@ html[data-theme="light"] { } html[data-theme="oled"] { + --muted: #a0a0a0; --bg: #000000; --bg-panel: #050505; --bg-input: #000000; @@ -58,7 +61,7 @@ html[data-accent="cyan"] { --accent: #25b8cc; --accent-hover: #39c5d8; --accen html[data-accent="blue"] { --accent: #4a86c8; --accent-hover: #5a96d6; --accent-active: #4073b0; --accent-ink: #141414; } html[data-accent="violet"] { --accent: #9a6fd0; --accent-hover: #ab80e0; --accent-active: #875db7; --accent-ink: #141414; } html[data-accent="pink"] { --accent: #e0567f; --accent-hover: #eb6890; --accent-active: #c74b6e; --accent-ink: #141414; } -html[data-accent="white"] { --accent: #ffffff; --accent-hover: #f2f2f2; --accent-active: #e6e6e6; --accent-ink: #141414; } +html[data-accent="white"] { --accent: #ffffff; --accent-hover: #f2f2f2; --accent-active: #e6e6e6; --accent-ink: #141414; --accent-border: #9a9a9a; } html[data-theme="dark"], html[data-theme="oled"] { color-scheme: dark; } html[data-theme="light"] { color-scheme: light; } @@ -203,14 +206,14 @@ h3 { font-size: 15px; font-weight: 700; } .btn:active { background: var(--bg-hover); } .btn-primary { - border-color: var(--accent); + border-color: var(--accent-border, var(--accent)); background: var(--accent); color: var(--accent-ink); font-weight: 700; } -.btn-primary:hover { border-color: var(--accent-hover); background: var(--accent-hover); } -.btn-primary:active { border-color: var(--accent-active); background: var(--accent-active); } +.btn-primary:hover { background: var(--accent-hover); } +.btn-primary:active { background: var(--accent-active); } .btn-danger-ghost { border-color: var(--danger); @@ -304,6 +307,18 @@ h3 { font-size: 15px; font-weight: 700; } background: var(--accent-hover); } +/* Session-Aktionen: Hauptaktionen gebuendelt, Verwerfen abgesetzt */ + +.session-actions { + display: flex; + gap: 10px; + align-items: center; +} + +.session-discard { + margin-left: 28px; +} + /* Session-Kopf (laufende Session) */ .session-head { @@ -365,10 +380,19 @@ h3 { font-size: 15px; font-weight: 700; } .ex-block { border: 2px solid var(--border); - margin: 0 0 12px; + margin: 0; cursor: grab; } +.ex-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 14px; + align-items: start; +} + +.ex-grid .ex-block { margin: 0; } + .ex-block.drag-over { border-color: var(--accent); } .ex-head { @@ -398,7 +422,7 @@ h3 { font-size: 15px; font-weight: 700; } flex-wrap: wrap; gap: 8px; align-items: center; - padding: 8px 12px; + padding: 6px 10px; } .set-row.is-done { background: var(--bg-subtle); } @@ -764,6 +788,17 @@ h3 { font-size: 15px; font-weight: 700; } .data-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } +.form-row { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; +} + +.form-row input { flex: 1 1 0; min-width: 140px; } + +.form-row .btn { flex-shrink: 0; } + .file-input { max-width: 240px; color: var(--muted); @@ -792,8 +827,8 @@ h3 { font-size: 15px; font-weight: 700; } .toggle-row:last-child { border-bottom: 0; } .toggle-input { - width: 20px; - height: 20px; + width: 22px; + height: 22px; margin: 2px 0 0; accent-color: var(--accent); flex-shrink: 0; @@ -881,8 +916,9 @@ body.boot #setup-gate { visibility: hidden; } .auth-box { border: 2px solid var(--border); background: var(--bg-panel); - max-width: 460px; - padding: 36px; + width: 640px; + max-width: calc(100vw - 32px); + padding: 40px; text-align: left; } @@ -929,7 +965,7 @@ body.boot #setup-gate { visibility: hidden; } .auth-box .picker-label { margin: 0 0 12px; } -.auth-box .day-picker { margin-bottom: 16px; } +.auth-box .day-picker { gap: 12px; margin-bottom: 20px; } .auth-form { margin: 0 0 18px; } @@ -1016,20 +1052,20 @@ body.boot #setup-gate { visibility: hidden; } } .wp-step { - width: 36px; - height: 10px; + width: 40px; + height: 6px; border: 2px solid var(--border); background: transparent; } .wp-step.is-done { - border-color: var(--muted); - background: var(--muted); + border-color: var(--accent); + background: var(--accent); } .wp-step.is-current { border-color: var(--accent); - background: var(--accent); + background: transparent; } button:disabled {