diff --git a/webapp/app.js b/webapp/app.js
index 82d9f23..6c9c658 100644
--- a/webapp/app.js
+++ b/webapp/app.js
@@ -268,6 +268,7 @@ const setsLabel = document.getElementById("sets-label");
const setsList = document.getElementById("sets-list");
const repsInput = document.getElementById("inp-reps");
const weightInput = document.getElementById("inp-weight");
+const btnWeightSign = document.getElementById("btn-weight-sign");
const btnAddSet = document.getElementById("btn-add-set");
const btnSaveWorkout = document.getElementById("btn-save-workout");
const workoutExercises = document.getElementById("workout-exercises");
@@ -351,6 +352,7 @@ function startExercise(name) {
nameInput.value = "";
repsInput.value = "";
weightInput.value = "";
+ syncWeightSignUI();
repsInput.focus();
notesSection.classList.remove("hidden");
stopRestTimer();
@@ -420,6 +422,7 @@ function addSet() {
repsInput.value = "";
weightInput.value = weight ? String(weight) : "";
+ syncWeightSignUI();
repsInput.focus();
tg.HapticFeedback.impactOccurred("light");
saveDraft();
@@ -427,6 +430,30 @@ function addSet() {
btnAddSet.addEventListener("click", addSet);
+function syncWeightSignUI() {
+ const v = weightInput.value.trim();
+ const negative = v.startsWith("-");
+ btnWeightSign.classList.toggle("active", negative);
+}
+
+btnWeightSign.addEventListener("click", () => {
+ // Flip the sign of the current weight value. If empty, start with "-"
+ // so the user can type digits after it (iOS numeric keypad has no minus).
+ const v = weightInput.value.trim();
+ if (v === "" || v === "-") {
+ weightInput.value = v === "-" ? "" : "-";
+ } else if (v.startsWith("-")) {
+ weightInput.value = v.slice(1);
+ } else {
+ weightInput.value = "-" + v;
+ }
+ syncWeightSignUI();
+ weightInput.focus();
+ tg.HapticFeedback.selectionChanged();
+});
+
+weightInput.addEventListener("input", syncWeightSignUI);
+
repsInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
@@ -561,6 +588,7 @@ function editExercise(idx) {
// Pre-fill weight input with last set's weight for convenience
const lastWeight = ex.sets_detail?.length ? ex.sets_detail[ex.sets_detail.length - 1].weight_kg : 0;
weightInput.value = lastWeight ? String(lastWeight) : "";
+ syncWeightSignUI();
repsInput.value = "";
repsInput.focus();
diff --git a/webapp/index.html b/webapp/index.html
index 7e8958d..6efa8a4 100644
--- a/webapp/index.html
+++ b/webapp/index.html
@@ -42,6 +42,7 @@
x
+
diff --git a/webapp/style.css b/webapp/style.css
index e9a57ab..5e5e144 100644
--- a/webapp/style.css
+++ b/webapp/style.css
@@ -107,6 +107,26 @@ body {
.btn-icon:active { opacity: 0.7; }
+.btn-sign {
+ width: 36px;
+ height: 44px;
+ border-radius: 10px;
+ border: 1px solid var(--tg-theme-hint-color, #999)55;
+ background: var(--tg-theme-secondary-bg-color, #f0f0f0);
+ color: var(--tg-theme-text-color, #000);
+ font-size: 18px;
+ cursor: pointer;
+ flex-shrink: 0;
+}
+
+.btn-sign:active { opacity: 0.6; }
+
+.btn-sign.active {
+ background: var(--tg-theme-button-color, #3390ec);
+ color: var(--tg-theme-button-text-color, #fff);
+ border-color: var(--tg-theme-button-color, #3390ec);
+}
+
.btn-link {
background: none;
border: none;