Files
projax/web/static
mAi 1af0990108 feat(detail): reorder fields general→specific, divider before auxiliary
m's report: detail page (/i/{path}) shows Tasks / Issues / Documents
above the edit form, and the form's 9 flat fields read as a wall of
labels rather than a flow. He wants the form first, fields grouped, then
auxiliary read-only sections below a clear visual break.

Reordered top-to-bottom flow:

  h1 + meta
  ▸ form
      General        — Title → Slug → Parents → Status
      Classification — Tags → Management
      Flags          — pinned + archived (inline pair)
      Content        — markdown textarea
      Public listing <details>            (stays inside form: save coherence)
      Timeline behaviour <details>        (stays inside form: save coherence)
      Save / Cancel actions
  ◂ /form
  <hr class="aux-divider">
  ▸ section.aux-sections "Related"
      Tasks <details>      (was above form)
      Issues <details>     (was above form)
      Documents <details>  (was above form)
      reset section state link

web/templates/detail.tmpl:
- Three <section class="form-group"> blocks each with a <h2
  class="form-group-heading"> ID-anchored for aria-labelledby + the
  ordering test. The headings render as small uppercase muted labels —
  visual hierarchy without screaming "FORM".
- Form-bound collapsibles (Public Listing + Timeline behaviour) stay
  inside the form; moving them out would require a separate POST
  endpoint, which the brief explicitly puts out of scope.
- Tasks / Issues / Documents collapsibles moved out of the form, into a
  new <section class="aux-sections"> after a thematic <hr>.
- Reset-section-state link relocated to .aux-reset under the auxiliary
  section since that's where most collapsible state lives now.
- All data-section / data-item-id / proj-section class hooks preserved
  exactly — Phase 4e smart-default + localStorage state semantics
  unchanged.

web/static/style.css:
- .detail-form: column flex, gap 20px between groups for breathing room.
- .form-group-heading: 0.78em uppercase muted with dotted-border-bottom
  separator — looks like an admin-form group header without being
  shouty.
- .form-group-flags: row-flex so pinned + archived sit inline.
- .aux-divider: full-width 1px solid border-top with 32px margin above,
  16px below — the explicit "this is where editable ends" break.
- .aux-sections + .aux-heading + .aux-reset: matched flex layout +
  small "Related" header so the change-of-mode reads without
  squinting.

Tests:
- TestDetailFieldsRenderInOrder (new) — strict-greater index walk
  through every documented anchor: General → Title → Slug → Parents →
  Status → Classification → Tags → Management → Flags → pinned →
  archived → Content → content_md → Save → aux-divider → Related →
  Documents. Catches any future regression that re-tangles the order.
- TestDetailFormGroupHeadings (new) — pins the five visible group
  headings (General / Classification / Flags / Content / Related) so
  a string-cleanup pass can't silently strip them.
- TestDetailAuxSectionsAfterForm (new) — Documents <details> lives
  AFTER the detail form's </form>, while Public listing stays INSIDE
  the form for save-coherence. Skips the sidebar's logout-form </form>
  by anchoring on the detail-form's action="/i/dev" start tag.
- TestDetailIncludesSectionToggleScript / TestDetailSectionsWrappedInDetails /
  TestDetailDocumentsClosedDefaultsWhenManyItems still pass — the
  Phase 4e collapsible semantics are untouched.

Net: +298 / -92.
2026-05-26 13:15:39 +02:00
..