feat: redesign Step 8 with flat list layout matching room steps

Replace bordered card sections with flat rows using hairline dividers,
opacity dimming, and native radio controls to match the room step visual
pattern. Also includes structural refactors (step-sections, address-sections)
and running totals bar polish from the modernization branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-12 22:47:39 +09:00
parent 89bd555dc1
commit 2ca1f4ff54
4 changed files with 245 additions and 87 deletions

View File

@@ -183,19 +183,23 @@
right: 0;
z-index: 100;
background: var(--umzug-surface);
border-top: 3px solid var(--umzug-primary);
border: 1px solid var(--umzug-border);
border-radius: var(--umzug-radius);
padding: 12px 20px;
margin-bottom: 12px;
text-align: center;
font-size: 0.95rem;
font-weight: 500;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
box-shadow: var(--umzug-shadow-lg);
transform: translateY(100%);
transition: transform 0.3s;
opacity: 0;
transition: transform 0.3s, opacity 0.3s;
pointer-events: none;
}
.running-totals.visible {
transform: translateY(0);
opacity: 1;
pointer-events: auto;
}
@@ -251,7 +255,9 @@
.step-title {
font-size: 1.5rem;
font-weight: 700;
margin: 0 0 20px;
margin: 0 0 16px;
padding-bottom: 12px;
border-bottom: 1px solid var(--umzug-border);
color: var(--umzug-text);
}
@@ -274,6 +280,32 @@
border-bottom: 1px solid var(--umzug-border);
}
/* ===== Step Sections (inner dividers within a step-card) ===== */
.step-section {
padding-top: 16px;
margin-top: 16px;
border-top: 1px solid var(--umzug-border);
}
.step-section:first-of-type {
border-top: none;
padding-top: 0;
margin-top: 0;
}
/* ===== Address Sections (grid items within step-card) ===== */
.address-section {
background: var(--umzug-surface);
border: 1px solid var(--umzug-border);
border-radius: var(--umzug-radius);
padding: 16px 20px;
}
/* Summary sections inside step-card: lighter treatment */
.step-card #wizard-summary .summary-section {
box-shadow: none;
}
/* ===== Date Selector ===== */
.date-selector {
display: flex;
@@ -514,7 +546,7 @@
.item-cbm {
width: 52px;
text-align: right;
font-size: 0.85rem;
font-size: 13px;
color: var(--umzug-text-secondary);
flex-shrink: 0;
}
@@ -526,7 +558,14 @@
}
.montage-toggle .radio-label {
font-size: 0.8rem;
font-size: 13px;
}
.montage-label {
font-size: 13px;
font-weight: 600;
color: var(--umzug-text-secondary);
white-space: nowrap;
}
/* ===== Room Totals ===== */
@@ -627,6 +666,76 @@
box-shadow: 0 0 0 3px var(--umzug-primary-light);
}
/* ===== Step 8 Design ===== */
.additional-field input[type="checkbox"] {
accent-color: var(--umzug-primary);
}
.wizard-step[data-step="8"] .additional-field {
padding: 8px 0;
background: transparent;
border: none;
border-bottom: 1px solid #f0f0f0;
border-radius: 0;
opacity: 0.55;
transition: opacity 0.2s;
}
.wizard-step[data-step="8"] .additional-field:last-child {
border-bottom: none;
}
.wizard-step[data-step="8"] .additional-field:hover,
.wizard-step[data-step="8"] .additional-field:focus-within,
.wizard-step[data-step="8"] .additional-field:has(input:checked),
.wizard-step[data-step="8"] .additional-field:has(.qty-small:not(:placeholder-shown)) {
opacity: 1;
}
.wizard-step[data-step="8"] .additional-field-abbau .radio-group {
display: inline-flex;
gap: 16px;
background: transparent;
border: none;
border-radius: 0;
padding: 0;
}
.wizard-step[data-step="8"] .additional-field-abbau .radio-label {
padding: 0;
font-size: 0.9rem;
}
.wizard-step[data-step="8"] .additional-field-abbau .radio-label input[type="radio"] {
position: static;
opacity: 1;
width: auto;
height: auto;
margin: 0;
}
/* ===== Dev Auto-Fill ===== */
.dev-autofill-btn {
position: fixed;
bottom: 60px;
right: 16px;
z-index: 300;
background: #ff6b35;
color: #fff;
border: none;
border-radius: 20px;
padding: 6px 14px;
font-size: 0.75rem;
font-weight: 600;
cursor: pointer;
opacity: 0.6;
transition: opacity var(--umzug-transition);
}
.dev-autofill-btn:hover {
opacity: 1;
}
/* ===== Sonstiges ===== */
.sonstiges-textarea {
width: 100%;
@@ -839,6 +948,15 @@
padding-left: 0;
}
.montage-label {
flex-basis: 100%;
margin-bottom: -4px;
}
.wizard-step[data-step="8"] .additional-field {
padding: 6px 0;
}
.additional-field-abbau {
flex-direction: column;
align-items: flex-start;

View File

@@ -144,9 +144,8 @@ class Umzugsliste_Form_Renderer {
private static function render_step_1() {
?>
<div class="wizard-step active" data-step="1">
<h2 class="step-title"><?php echo esc_html__( 'Moving Date & Addresses', 'siegel-umzugsliste' ); ?></h2>
<div class="step-card">
<h2 class="step-title"><?php echo esc_html__( 'Moving Date & Addresses', 'siegel-umzugsliste' ); ?></h2>
<h3><?php echo esc_html__( 'Expected Moving Date', 'siegel-umzugsliste' ); ?></h3>
<div class="date-selector">
<?php
@@ -161,38 +160,55 @@ class Umzugsliste_Form_Renderer {
'<a href="http://siegel-umzug.de/datenschutz.html" target="_blank" rel="noopener">' . esc_html__( 'Privacy Policy', 'siegel-umzugsliste' ) . '</a>'
);
?></p>
</div>
<div class="address-grid">
<div class="step-card">
<h3><?php echo esc_html__( 'Loading Address', 'siegel-umzugsliste' ); ?></h3>
<?php
self::render_address_field( __( 'Name', 'siegel-umzugsliste' ), 'bName', true );
self::render_address_field( __( 'Street', 'siegel-umzugsliste' ), 'bStrasse', true );
self::render_address_field( __( 'ZIP/City', 'siegel-umzugsliste' ), 'bort', true );
self::render_address_field( __( 'Floor', 'siegel-umzugsliste' ), 'info[bGeschoss]' );
self::render_lift_field( 'info[bLift]' );
self::render_address_field( __( 'Phone', 'siegel-umzugsliste' ), 'bTelefon', true );
self::render_address_field( __( 'Fax', 'siegel-umzugsliste' ), 'info[bTelefax]' );
self::render_address_field( __( 'Mobile', 'siegel-umzugsliste' ), 'info[bMobil]' );
self::render_address_field( __( 'Email', 'siegel-umzugsliste' ), 'info[eE-Mail]', true, 'email' );
?>
</div>
<div class="step-card">
<h3><?php echo esc_html__( 'Unloading Address', 'siegel-umzugsliste' ); ?></h3>
<?php
self::render_address_field( __( 'Name', 'siegel-umzugsliste' ), 'eName', true );
self::render_address_field( __( 'Street', 'siegel-umzugsliste' ), 'eStrasse', true );
self::render_address_field( __( 'ZIP/City', 'siegel-umzugsliste' ), 'eort', true );
self::render_address_field( __( 'Floor', 'siegel-umzugsliste' ), 'info[eGeschoss]' );
self::render_lift_field( 'info[eLift]' );
self::render_address_field( __( 'Phone', 'siegel-umzugsliste' ), 'eTelefon' );
self::render_address_field( __( 'Fax', 'siegel-umzugsliste' ), 'info[eTelefax]' );
self::render_address_field( __( 'Mobile', 'siegel-umzugsliste' ), 'info[eMobil]' );
?>
<div class="address-grid">
<div class="address-section">
<h3><?php echo esc_html__( 'Loading Address', 'siegel-umzugsliste' ); ?></h3>
<?php
self::render_address_field( __( 'Name', 'siegel-umzugsliste' ), 'bName', true );
self::render_address_field( __( 'Street', 'siegel-umzugsliste' ), 'bStrasse', true );
self::render_address_field( __( 'ZIP/City', 'siegel-umzugsliste' ), 'bort', true );
self::render_address_field( __( 'Floor', 'siegel-umzugsliste' ), 'info[bGeschoss]' );
self::render_lift_field( 'info[bLift]' );
self::render_address_field( __( 'Phone', 'siegel-umzugsliste' ), 'bTelefon', true );
self::render_address_field( __( 'Fax', 'siegel-umzugsliste' ), 'info[bTelefax]' );
self::render_address_field( __( 'Mobile', 'siegel-umzugsliste' ), 'info[bMobil]' );
self::render_address_field( __( 'Email', 'siegel-umzugsliste' ), 'info[eE-Mail]', true, 'email' );
?>
</div>
<div class="address-section">
<h3><?php echo esc_html__( 'Unloading Address', 'siegel-umzugsliste' ); ?></h3>
<?php
self::render_address_field( __( 'Name', 'siegel-umzugsliste' ), 'eName', true );
self::render_address_field( __( 'Street', 'siegel-umzugsliste' ), 'eStrasse', true );
self::render_address_field( __( 'ZIP/City', 'siegel-umzugsliste' ), 'eort', true );
self::render_address_field( __( 'Floor', 'siegel-umzugsliste' ), 'info[eGeschoss]' );
self::render_lift_field( 'info[eLift]' );
self::render_address_field( __( 'Phone', 'siegel-umzugsliste' ), 'eTelefon' );
self::render_address_field( __( 'Fax', 'siegel-umzugsliste' ), 'info[eTelefax]' );
self::render_address_field( __( 'Mobile', 'siegel-umzugsliste' ), 'info[eMobil]' );
?>
</div>
</div>
<p class="required-note"><?php echo esc_html__( '* Required fields', 'siegel-umzugsliste' ); ?></p>
</div>
<p class="required-note"><?php echo esc_html__( '* Required fields', 'siegel-umzugsliste' ); ?></p>
<?php if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) : ?>
<button type="button" id="dev-autofill" class="dev-autofill-btn">&#9881; Fill</button>
<script>
document.getElementById('dev-autofill').addEventListener('click', function() {
var fields = {
'bName':'Max Mustermann','bStrasse':'Musterstr. 12',
'bort':'10115 Berlin','bTelefon':'030 12345678',
'eName':'Erika Musterfrau','eStrasse':'Zielweg 5',
'eort':'80331 München','info[eE-Mail]':'test@example.com'
};
for (var n in fields) {
var el = document.querySelector('[name="'+n+'"]');
if (el) { el.value = fields[n]; el.dispatchEvent(new Event('input',{bubbles:true})); }
}
document.getElementById('wizard-next').click();
});
</script>
<?php endif; ?>
</div>
<?php
}
@@ -214,8 +230,8 @@ class Umzugsliste_Form_Renderer {
}
?>
<div class="wizard-step" data-step="<?php echo esc_attr( $step_num ); ?>">
<h2 class="step-title"><?php echo esc_html( $room_label ); ?></h2>
<div class="step-card">
<h2 class="step-title"><?php echo esc_html( $room_label ); ?></h2>
<div class="furniture-list" data-room="<?php echo esc_attr( $room_key ); ?>">
<?php
foreach ( $items as $item ) {
@@ -241,10 +257,10 @@ class Umzugsliste_Form_Renderer {
$rooms = Umzugsliste_Furniture_Data::get_rooms();
?>
<div class="wizard-step" data-step="5">
<h2 class="step-title"><?php echo esc_html( $rooms['bad'] ); ?> &amp; <?php echo esc_html( $rooms['kueche_esszimmer'] ); ?></h2>
<div class="step-card">
<h3><?php echo esc_html( $rooms['bad'] ); ?></h3>
<h2 class="step-title"><?php echo esc_html( $rooms['bad'] ); ?> &amp; <?php echo esc_html( $rooms['kueche_esszimmer'] ); ?></h2>
<div class="step-section">
<h3><?php echo esc_html( $rooms['bad'] ); ?></h3>
<div class="furniture-list" data-room="bad">
<?php
$bad_items = Umzugsliste_Furniture_Data::get_furniture_items( 'bad' );
@@ -258,23 +274,23 @@ class Umzugsliste_Form_Renderer {
<span class="room-totals-sep">&middot;</span>
<span class="room-total-cbm">0,00</span> <?php echo esc_html__( 'cbm', 'siegel-umzugsliste' ); ?>
</div>
</div>
</div>
</div>
<div class="step-card">
<h3><?php echo esc_html( $rooms['kueche_esszimmer'] ); ?></h3>
<div class="furniture-list" data-room="kueche_esszimmer">
<?php
$kueche_items = Umzugsliste_Furniture_Data::get_furniture_items( 'kueche_esszimmer' );
foreach ( $kueche_items as $item ) {
self::render_furniture_item( 'Kueche_Esszimmer', 'kueche_esszimmer', $item );
}
?>
<div class="room-totals" data-room="kueche_esszimmer">
<span class="room-total-label"><?php echo esc_html__( 'Total', 'siegel-umzugsliste' ) . ' ' . esc_html( $rooms['kueche_esszimmer'] ); ?>:</span>
<span class="room-total-quantity">0</span> <?php echo esc_html__( 'Items', 'siegel-umzugsliste' ); ?>
<span class="room-totals-sep">&middot;</span>
<span class="room-total-cbm">0,00</span> <?php echo esc_html__( 'cbm', 'siegel-umzugsliste' ); ?>
<div class="step-section">
<h3><?php echo esc_html( $rooms['kueche_esszimmer'] ); ?></h3>
<div class="furniture-list" data-room="kueche_esszimmer">
<?php
$kueche_items = Umzugsliste_Furniture_Data::get_furniture_items( 'kueche_esszimmer' );
foreach ( $kueche_items as $item ) {
self::render_furniture_item( 'Kueche_Esszimmer', 'kueche_esszimmer', $item );
}
?>
<div class="room-totals" data-room="kueche_esszimmer">
<span class="room-total-label"><?php echo esc_html__( 'Total', 'siegel-umzugsliste' ) . ' ' . esc_html( $rooms['kueche_esszimmer'] ); ?>:</span>
<span class="room-total-quantity">0</span> <?php echo esc_html__( 'Items', 'siegel-umzugsliste' ); ?>
<span class="room-totals-sep">&middot;</span>
<span class="room-total-cbm">0,00</span> <?php echo esc_html__( 'cbm', 'siegel-umzugsliste' ); ?>
</div>
</div>
</div>
</div>
@@ -289,27 +305,29 @@ class Umzugsliste_Form_Renderer {
$sections = Umzugsliste_Furniture_Data::get_additional_work();
?>
<div class="wizard-step" data-step="8">
<h2 class="step-title"><?php echo esc_html__( 'Additional Work', 'siegel-umzugsliste' ); ?></h2>
<?php foreach ( $sections as $section_key => $section_data ) : ?>
<div class="step-card">
<h3><?php echo esc_html( $section_data['label'] ); ?></h3>
<div class="additional-work-section" data-section="<?php echo esc_attr( $section_key ); ?>">
<?php
foreach ( $section_data['fields'] as $field ) {
$field_key = self::get_field_key( $field );
$field_name = 'additional_work[' . $section_key . '][' . $field_key . ']';
self::render_additional_field( $field, $field_name, $field_key );
}
?>
</div>
</div>
<?php endforeach; ?>
<div class="step-card">
<h3><?php echo esc_html__( 'Other', 'siegel-umzugsliste' ); ?></h3>
<label for="sonstiges"><?php echo esc_html__( 'Additional notes or requests:', 'siegel-umzugsliste' ); ?></label>
<textarea name="sonstiges" id="sonstiges" rows="5" class="sonstiges-textarea" placeholder="<?php echo esc_attr__( 'Additional notes or requests...', 'siegel-umzugsliste' ); ?>"></textarea>
<h2 class="step-title"><?php echo esc_html__( 'Additional Work', 'siegel-umzugsliste' ); ?></h2>
<?php foreach ( $sections as $section_key => $section_data ) : ?>
<div class="step-section">
<h3><?php echo esc_html( $section_data['label'] ); ?></h3>
<div class="additional-work-section" data-section="<?php echo esc_attr( $section_key ); ?>">
<?php
foreach ( $section_data['fields'] as $field ) {
$field_key = self::get_field_key( $field );
$field_name = 'additional_work[' . $section_key . '][' . $field_key . ']';
self::render_additional_field( $field, $field_name, $field_key );
}
?>
</div>
</div>
<?php endforeach; ?>
<div class="step-section">
<h3><?php echo esc_html__( 'Other', 'siegel-umzugsliste' ); ?></h3>
<label for="sonstiges"><?php echo esc_html__( 'Additional notes or requests:', 'siegel-umzugsliste' ); ?></label>
<textarea name="sonstiges" id="sonstiges" rows="5" class="sonstiges-textarea" placeholder="<?php echo esc_attr__( 'Additional notes or requests...', 'siegel-umzugsliste' ); ?>"></textarea>
</div>
</div>
</div>
<?php
@@ -324,15 +342,17 @@ class Umzugsliste_Form_Renderer {
$captcha = Umzugsliste_Captcha::get_instance();
?>
<div class="wizard-step" data-step="9">
<h2 class="step-title"><?php echo esc_html__( 'Summary', 'siegel-umzugsliste' ); ?></h2>
<div id="wizard-summary"></div>
<?php
if ( $captcha->is_enabled() ) {
echo '<div class="step-card">';
echo $captcha->render_widget();
echo '</div>';
}
?>
<div class="step-card">
<h2 class="step-title"><?php echo esc_html__( 'Summary', 'siegel-umzugsliste' ); ?></h2>
<div id="wizard-summary"></div>
<?php
if ( $captcha->is_enabled() ) {
echo '<div class="captcha-section">';
echo $captcha->render_widget();
echo '</div>';
}
?>
</div>
<?php wp_nonce_field( 'umzugsliste_submit', 'umzugsliste_nonce' ); ?>
<input type="hidden" name="umzugsliste_submit" value="1">
<input type="hidden" name="umzugsliste_form_id" value="<?php echo esc_attr( $form_id ); ?>">
@@ -402,6 +422,7 @@ class Umzugsliste_Form_Renderer {
<input type="hidden" name="<?php echo esc_attr( $cbm_name ); ?>" value="<?php echo esc_attr( $cbm ); ?>">
<?php if ( $has_montage ) : ?>
<div class="montage-toggle">
<span class="montage-label"><?php echo esc_html__( 'Montage?', 'siegel-umzugsliste' ); ?></span>
<label class="radio-label"><input type="radio" name="<?php echo esc_attr( $montage_name ); ?>" value="nein" checked> <?php echo esc_html__( 'No', 'siegel-umzugsliste' ); ?></label>
<label class="radio-label"><input type="radio" name="<?php echo esc_attr( $montage_name ); ?>" value="ja"> <?php echo esc_html__( 'Yes', 'siegel-umzugsliste' ); ?></label>
</div>

View File

@@ -1137,3 +1137,22 @@ msgstr "Mobil (Beladeadresse)"
#: includes/class-cpt.php
msgid "Mobile (Unloading)"
msgstr "Mobil (Entladeadresse)"
#: includes/class-shortcode.php
#: templates/form-page.php
msgid "Step"
msgstr "Schritt"
#: includes/class-shortcode.php
#: templates/form-page.php
msgid "of"
msgstr "von"
#: includes/class-shortcode.php
#: templates/form-page.php
msgid "Edit"
msgstr "Bearbeiten"
#: includes/class-form-renderer.php
msgid "Montage?"
msgstr "Montage?"