diff --git a/assets/css/form.css b/assets/css/form.css index ba48d77..97c94d8 100644 --- a/assets/css/form.css +++ b/assets/css/form.css @@ -167,6 +167,14 @@ font-size: 0; } +/* ===== Step Counter ===== */ +.progress-counter { + text-align: center; + font-size: 0.8rem; + color: var(--umzug-text-secondary); + margin-bottom: 16px; +} + /* ===== Running Totals Bar ===== */ .running-totals { position: sticky; @@ -181,11 +189,14 @@ font-size: 0.95rem; font-weight: 500; box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1); - display: none; + transform: translateY(100%); + transition: transform 0.3s; + pointer-events: none; } .running-totals.visible { - display: block; + transform: translateY(0); + pointer-events: auto; } .running-totals-label { @@ -219,6 +230,24 @@ to { opacity: 1; transform: translateY(0); } } +@keyframes slideInForward { + from { opacity: 0; transform: translateX(30px); } + to { opacity: 1; transform: translateX(0); } +} + +@keyframes slideInBackward { + from { opacity: 0; transform: translateX(-30px); } + to { opacity: 1; transform: translateX(0); } +} + +.wizard-step.active.forward { + animation: slideInForward 0.3s ease; +} + +.wizard-step.active.backward { + animation: slideInBackward 0.3s ease; +} + .step-title { font-size: 1.5rem; font-weight: 700; @@ -394,27 +423,78 @@ gap: 12px; padding: 8px 0; border-bottom: 1px solid #f0f0f0; + opacity: 0.55; + transition: opacity 0.2s; +} + +.furniture-item.has-quantity, +.furniture-item:hover, +.furniture-item:focus-within { + opacity: 1; +} + +.furniture-item .montage-toggle { + display: none; +} + +.furniture-item.has-quantity .montage-toggle { + display: flex; } .furniture-item:last-of-type { border-bottom: none; } -.quantity-input { - width: 56px; - height: 36px; - padding: 0 8px; +.quantity-stepper { + display: inline-flex; + align-items: center; border: 1px solid var(--umzug-border); - border-radius: var(--umzug-radius-sm); + border-radius: var(--umzug-radius); + overflow: hidden; + flex-shrink: 0; +} + +.qty-btn { + width: 36px; + height: 36px; + border: none; + background: var(--umzug-bg); + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background var(--umzug-transition); + color: var(--umzug-text); + padding: 0; + line-height: 1; +} + +.qty-btn:hover { + background: var(--umzug-border); +} + +.qty-btn:active { + background: var(--umzug-primary-light); +} + +.quantity-stepper .quantity-input { + border: none; + border-left: 1px solid var(--umzug-border); + border-right: 1px solid var(--umzug-border); + border-radius: 0; + width: 48px; + height: 36px; + padding: 0 4px; font-size: 0.95rem; text-align: center; - flex-shrink: 0; color: var(--umzug-text); background: var(--umzug-surface); transition: border-color var(--umzug-transition), box-shadow var(--umzug-transition); } -.quantity-input:focus { +.quantity-stepper .quantity-input:focus { outline: none; border-color: var(--umzug-primary); box-shadow: 0 0 0 3px var(--umzug-primary-light); @@ -630,6 +710,19 @@ font-size: 0.8rem; } +.summary-edit { + float: right; + font-size: 0.8rem; + font-weight: 500; + color: var(--umzug-primary); + cursor: pointer; + text-decoration: none; +} + +.summary-edit:hover { + text-decoration: underline; +} + #wizard-summary .summary-grand-total { background: var(--umzug-primary); color: #fff; @@ -730,7 +823,8 @@ flex-basis: calc(100% - 80px); } - .quantity-input { + .quantity-input, + .quantity-stepper { order: 2; } @@ -769,18 +863,34 @@ font-size: 0.95rem; } + .progress-dot { + min-width: 44px; + min-height: 44px; + display: flex; + align-items: center; + justify-content: center; + } + .dot-label { display: none; } + .progress-dot.active .dot-label { + display: block; + font-size: 0.6rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .dot-number { - width: 28px; - height: 28px; + width: 36px; + height: 36px; font-size: 0.7rem; } .progress-track { - top: 14px; + top: 18px; } } diff --git a/assets/js/form.js b/assets/js/form.js index 687990f..2232214 100644 --- a/assets/js/form.js +++ b/assets/js/form.js @@ -48,14 +48,20 @@ function showStep(n) { if (n < 1 || n > TOTAL_STEPS) return; - // Hide all steps + // Determine direction + var direction = n > currentStep ? 'forward' : 'backward'; + + // Hide all steps and remove direction classes qsa('.wizard-step').forEach(function(el) { - el.classList.remove('active'); + el.classList.remove('active', 'forward', 'backward'); }); - // Show target step + // Show target step with direction var target = qs('.wizard-step[data-step="' + n + '"]'); - if (target) target.classList.add('active'); + if (target) { + target.classList.add(direction); + target.classList.add('active'); + } currentStep = n; if (n > highestStep) highestStep = n; @@ -103,6 +109,12 @@ var pct = ((highestStep - 1) / (TOTAL_STEPS - 1)) * 100; fill.style.width = pct + '%'; } + + // Update step counter + var counter = qs('#progress-counter'); + if (counter) { + counter.textContent = (l10n.stepLabel || 'Step') + ' ' + currentStep + ' ' + (l10n.stepOf || 'of') + ' ' + TOTAL_STEPS; + } } function updateNavButtons() { @@ -271,6 +283,11 @@ // ===== Summary Generation ===== + function summaryHeading(text, gotoStep) { + var editLabel = escHtml(l10n.summaryEdit || 'Edit'); + return '
' + escHtml(sonstiges) + '
'; html += '