# coalFeeding.vue Motor Grid Alignment Refinement

## Overview

This design refines the already approved block-based right-panel layout in `src/views/coalFeeding.vue`.
It does not change the overall removal of `<table>`.
Instead, it adjusts the motor areas so they better match the desired visual structure.

The refinement introduces two requirements:

- both `中间侧` and `回车侧` motor areas should render motors two per row instead of one per row
- the left-side label blocks for those motor areas must stay height-aligned with the corresponding right-side motor blocks

## Goals

- Render motor items in a 2-column layout for both motor sections
- Keep odd motor counts left-aligned on the final row
- Keep the left label block height aligned with the right motor block height
- Preserve all existing drag-and-drop, click, and status-display logic
- Avoid reworking the surrounding block layout

## Non-Goals

- Do not change the current block layout order
- Do not change time-field rendering
- Do not change temperature or car-number sections
- Do not switch to a new backend data structure
- Do not introduce DOM measurement logic unless strictly necessary

## Chosen Approach

Use a CSS grid for motor layout plus shared computed heights for label and motor sections.

Why this approach:

- It preserves the current block-based layout structure
- It keeps the change small and local to the motor sections
- It avoids fragile DOM measurement code
- It guarantees left/right alignment by making both sides use the same computed height source

## Motor Layout Rules

Both `中间侧` and `回车侧` motor groups will render with:

- two columns per row
- consistent gaps between motor items
- left-aligned final item when the count is odd

Implementation shape:

- wrap each motor list in a dedicated grid container
- use `grid-template-columns: repeat(2, minmax(0, 1fr))`
- allow each motor item to occupy one cell
- do not center or span the final odd item

Expected examples:

- 2 motors -> 1 row of 2
- 3 motors -> 2 rows, with the last item on the left of the second row
- 4 motors -> 2 rows of 2

## Height Alignment Rules

The left labels for `中间侧` and `回车侧` must visually align with the height of their corresponding motor blocks across all unit columns.

To achieve this, compute two shared height values:

- `middleMotorHeight`
- `returnMotorHeight`

These values will be derived from the largest motor-group row count in the current data.

Row count formula:

- `Math.ceil(motorCount / 2)`

Height formula:

- `sectionPaddingTop + sectionPaddingBottom + rows * itemHeight + (rows - 1) * rowGap`

Also enforce a minimum height so single-row sections do not become too short.

Both the left label block and the right motor block must use the same computed height source for each section.

## Rendering Changes

Keep the existing right-panel block structure.
Only refine the motor section internals and the matching left labels.

Changes:

- `中间侧` label gets `:style="{ minHeight: middleMotorHeight }"`
- `回车侧` label gets `:style="{ minHeight: returnMotorHeight }"`
- upper motor section gets `:style="{ minHeight: middleMotorHeight }"`
- lower motor section gets `:style="{ minHeight: returnMotorHeight }"`
- motor items render inside a `control-panel__motor-grid` container

The individual motor cards keep their current:

- drag-and-drop handlers
- run/stop toggles
- local/remote badges
- fault/normal text

## Styling Changes

Add a motor-grid wrapper class with:

- `display: grid`
- two equal-width columns
- fixed row gap
- fixed column gap
- left-aligned item flow

The motor section wrapper should:

- keep the current blue-tinted background
- use the shared computed minimum height
- align its content to the top instead of stretching awkwardly

The left label blocks should:

- continue using the current label styling
- adopt the same computed minimum height as their corresponding right-side section

## Risks and Mitigations

### Risk 1: heights drift if units have different motor counts

Mitigation:

- compute height from the maximum row count across all units for each motor section

### Risk 2: odd counts look visually off

Mitigation:

- keep the final odd item left-aligned and do not stretch it to full width

### Risk 3: click and drag interactions break during markup changes

Mitigation:

- keep the motor card markup intact
- move only the grouping wrapper and layout styles

## Testing Plan

After implementation, verify:

- `中间侧` motors render two per row
- `回车侧` motors render two per row
- odd motor counts leave the last motor on the left side
- left label heights align with right motor-section heights
- motor clicks still toggle state
- drag-and-drop still works on motor items
- the surrounding right-panel layout remains unchanged

## Open Constraints

- The workspace is still not a Git repository, so this design file cannot be committed here.
- This refinement assumes the existing block-based right-panel layout remains the baseline for implementation.
