Fristenrechner: complete UX overhaul — dual-mode (direct search/filter + guided wizard) with project-file write-back #146

Open
opened 2026-05-26 19:23:00 +00:00 by mAi · 2 comments
Collaborator

Background

The current /tools/fristenrechner form (frontend/src/client/fristenrechner.ts buildRowStack at L2848) conflates two distinct use cases into one row-stack, producing several visible UX bugs:

  1. "Beide" as default perspective — defaulting perspective to "both sides" treats the row like a filter. But for the headline use case ("Frist eintragen aufgrund Ereignis" — file a deadline because something happened), the user IS one side. "Both" is incoherent.
  2. R2 (inbox channel) does not constrain R3 (event-kind cascade) — picking "CMS" as the inbox and then being offered "Mündliche Verhandlung" / "Frist verpasst" in the next step is inconsistent: those are not CMS-arrival events.
  3. Mixed axes — the form mixes filters (forum, inbox channel) with qualifiers (event-kind, perspective, proceeding_type) without making the distinction visible. Users can't tell which picks narrow and which define.
  4. Trigger vs follow-up confusion — the wizard's purpose is to find the trigger event ("Klageschrift wurde eingereicht", "Hinweisbeschluss kam rein"), then surface the follow-up deadlines that depend on it. Today this distinction isn't reflected in the form structure.

m's verdict (2026-05-26, 21:21): "complete overhaul. Should be easy to use."

Vision

Two complementary paths, both lead to the same outcome ("these are the follow-up deadlines, optionally file them into a project"):

A — Direct search + filter

Keep the existing search form (text search across procedural_events) plus filter chips (forum / proceeding_type / event_kind / party). Power-user path: "I already know what I'm looking for."

B — Guided wizard

A short Q&A (3-5 questions max) that narrows from broad to specific to identify the trigger event. The wizard's only job is to land on one procedural_events row. Once that's locked in, the result view takes over.

Result view (shared by A and B)

Given a trigger event:

  • Show all sequencing_rules with that event as trigger (the follow-ups).
  • Group by mandatory (default) vs optional / conditional / spawned.
  • For each rule: title, duration, party stance, citation, computed deadline date (when a trigger date is entered).
  • Project write-back: button "Frist(en) in Akte eintragen" — if there's an active project context, write the picked rules' deadlines into paliad.deadlines for that project. Multi-select: user can take all mandatory, deselect optional, or pick & choose.

Axis taxonomy (to be ratified in the design pass)

Axis Role Source Constrains
forum filter derived from proceeding_types.code (upc.* / de.* / epa.* / dpma.*) inbox options, event-kinds reachable
proceeding_type qualifier (event-defining) sequencing_rules.proceeding_type_idproceeding_types which sequencing_rules apply
inbox channel filter user pick (CMS / beA / Postal / Egal) event-kinds (CMS arrivals ≠ oral hearing)
perspective (party) qualifier in file-mode, filter in explore project.our_side OR user pick sequencing_rules.primary_party
event_kind qualifier procedural_events.event_kind (filing / hearing / decision / order / …) which trigger event is reachable

Rule: a filter narrows the visible options without committing to a deadline answer; a qualifier is part of the resulting deadline calculation. Filters must propagate forward (R2 narrows R3). Qualifiers are picked once and locked.

Wizard sketch (3-5 questions, branchy)

The wizard's branching depends on whether there's a project context. With a project, half the questions are pre-filled from project.forum / project.proceeding_type / project.our_side and rendered as prefilled rows the user can override. Without a project, all questions are asked.

Strawman question order (inventor to refine):

  1. Was ist passiert? (event_kind) — "Schriftsatz eingereicht" / "Schriftsatz empfangen" / "Termin stattgefunden" / "Entscheidung ergangen" / "Frist verpasst" / "Sonstiges".
  2. Vor welchem Gericht / bei welchem Amt? (forum) — UPC / LG/OLG/BGH / EPA / DPMA. Pre-filled from project. Skip if event_kind narrows to one forum.
  3. In welchem Verfahren? (proceeding_type) — only the proceedings valid under the chosen forum. Pre-filled from project. Skip if forum narrows to one.
  4. Welches Schriftstück / Welcher Termin konkret? (procedural_event slug) — narrowed to the events with the chosen event_kind + proceeding_type. This is where the wizard lands. If the narrowed scope has only one candidate, auto-select and skip the question.
  5. (only if needed) Vertreten Sie Kläger- oder Beklagtenseite? (perspective) — pre-filled from project.our_side. Asked only when the trigger event's follow-ups differ by side.

Open design questions (for the inventor)

  1. Single page or stepper? — keep current single-page row-stack with state, or switch to a real multi-step UI (wizard route, back/forward buttons, URL-encoded state)?
  2. Mode switcher — where does "Direkt suchen" (A) vs "Wizard" (B) live? Tab at top? Two CTAs on the page header?
  3. Filter-vs-qualifier UX — how do we visually communicate "this is a filter, you can leave it open" vs "this is a qualifier, you must commit"? Different chip styles? Required asterisk vs optional placeholder?
  4. Cascade tree — keep event_categories tree (the "Was ist passiert?" hierarchical picker) or replace with flat event_kind + free-text search? Tree adds visual structure but burns clicks.
  5. Result grouping — mandatory / optional / conditional / spawned: 4 groups, or 2 (mandatory vs everything-else with sub-grouping)?
  6. Project write-back — single button "all selected → into Akte", per-rule inline "+" buttons, or batch confirm-and-edit-dates modal? What about deadlines that need a trigger-date input (most do)?
  7. No-project mode — what does the write-back button do when no project is active? Disabled with hint? Open project picker? Just hide?
  8. Perspective as filter vs qualifier — in explore mode "Beide" is fine because the user is researching. In file mode it's nonsense. Does the mode-switch swap the row entirely, or just the validation?
  9. Trigger-date input — when do we ask? In the wizard before showing results, or in the result view per-rule, or in the write-back modal?
  10. Backward navigation — clicking "ändern" on an earlier row resets the cascade. Should it preserve compatible picks downstream, or fully reset?
  11. Deep link — every wizard state needs a URL so users can share "trigger=X, project=Y, follow-ups=[a,b,c]" with colleagues. Where do the picks live — query string? Pathname?
  12. Search ranking — when the direct-search box returns 21 hits (as in m's example for "Klageerhebung"), how do we rank? By proceeding_type popularity? Project context? Most-recently-used in this project?

Acceptance for the inventor design pass

Deliverable: docs/design-fristenrechner-overhaul-2026-05-NN.md covering:

  • Mode taxonomy (direct vs wizard) with a state-machine sketch
  • Axis taxonomy ratified (filters vs qualifiers — table above expanded)
  • Wizard question order and branching rules (with the 12 PRD questions ratified by m)
  • Result-view shape (grouping, columns, per-rule actions)
  • Project write-back flow (UI + which deadlines table the writes hit + audit_reason wording)
  • URL/state representation
  • Migration plan from the current row-stack: which pieces survive, which get replaced, deprecation of current buildRowStack and the event_categories tree
  • One concrete worked example: "PA at LG Düsseldorf gets a Hinweisbeschluss via CMS in an active case" → exact wizard path + result page + write-back outcome
  • Out-of-scope notes: anything explicitly deferred (e.g. paliadin-driven semantic search, voice input)

No code yet — design only. Coder shift comes after m ratifies the design (per inventor→coder gate in head SKILL).

Data quality preconditions (already in flight or fixed)

  • 5 identical Mängelbeseitigung / Zahlung sequencing_rule clones being archived in mig 152 (curie, in progress).
  • Zwischenverfahren renamed to Zwischenanhörung for upc.inf/rev/dmgs.cfi.interim (2026-05-26).
  • 5 orphan deadline_concepts staged as drafts in t-paliad-320 (m to publish via /admin/procedural-events).

Out of scope

  • Replacing the underlying sequencing_rules model (Phase 3 schema is fine for this UX).
  • Paliadin-AI integration into the wizard (separate track; the wizard can call out to paliadin later as a Phase 2).
  • Calendar / outlook sync of created deadlines (separate t-paliad-... — see project-status.md long-term goals).
## Background The current `/tools/fristenrechner` form (`frontend/src/client/fristenrechner.ts` `buildRowStack` at L2848) conflates two distinct use cases into one row-stack, producing several visible UX bugs: 1. **"Beide" as default perspective** — defaulting perspective to "both sides" treats the row like a filter. But for the headline use case ("Frist eintragen aufgrund Ereignis" — file a deadline because something happened), the user IS one side. "Both" is incoherent. 2. **R2 (inbox channel) does not constrain R3 (event-kind cascade)** — picking "CMS" as the inbox and then being offered "Mündliche Verhandlung" / "Frist verpasst" in the next step is inconsistent: those are not CMS-arrival events. 3. **Mixed axes** — the form mixes filters (forum, inbox channel) with qualifiers (event-kind, perspective, proceeding_type) without making the distinction visible. Users can't tell which picks narrow and which define. 4. **Trigger vs follow-up confusion** — the wizard's purpose is to find the *trigger* event ("Klageschrift wurde eingereicht", "Hinweisbeschluss kam rein"), then surface the *follow-up* deadlines that depend on it. Today this distinction isn't reflected in the form structure. m's verdict (2026-05-26, 21:21): "complete overhaul. Should be easy to use." ## Vision **Two complementary paths**, both lead to the same outcome ("these are the follow-up deadlines, optionally file them into a project"): ### A — Direct search + filter Keep the existing search form (text search across procedural_events) plus filter chips (forum / proceeding_type / event_kind / party). Power-user path: "I already know what I'm looking for." ### B — Guided wizard A short Q&A (3-5 questions max) that narrows from broad to specific to identify the **trigger event**. The wizard's only job is to land on one `procedural_events` row. Once that's locked in, the result view takes over. ### Result view (shared by A and B) Given a trigger event: - Show all sequencing_rules with that event as trigger (the follow-ups). - Group by mandatory (default) vs optional / conditional / spawned. - For each rule: title, duration, party stance, citation, computed deadline date (when a trigger date is entered). - **Project write-back**: button "Frist(en) in Akte eintragen" — if there's an active project context, write the picked rules' deadlines into `paliad.deadlines` for that project. Multi-select: user can take all mandatory, deselect optional, or pick & choose. ## Axis taxonomy (to be ratified in the design pass) | Axis | Role | Source | Constrains | |---|---|---|---| | forum | filter | derived from `proceeding_types.code` (`upc.*` / `de.*` / `epa.*` / `dpma.*`) | inbox options, event-kinds reachable | | proceeding_type | qualifier (event-defining) | `sequencing_rules.proceeding_type_id` → `proceeding_types` | which sequencing_rules apply | | inbox channel | filter | user pick (CMS / beA / Postal / Egal) | event-kinds (CMS arrivals ≠ oral hearing) | | perspective (party) | qualifier in file-mode, filter in explore | `project.our_side` OR user pick | `sequencing_rules.primary_party` | | event_kind | qualifier | `procedural_events.event_kind` (filing / hearing / decision / order / …) | which trigger event is reachable | Rule: a **filter** narrows the visible options without committing to a deadline answer; a **qualifier** is part of the resulting deadline calculation. Filters must propagate forward (R2 narrows R3). Qualifiers are picked once and locked. ## Wizard sketch (3-5 questions, branchy) The wizard's branching depends on whether there's a project context. With a project, half the questions are pre-filled from project.forum / project.proceeding_type / project.our_side and rendered as `prefilled` rows the user can override. Without a project, all questions are asked. Strawman question order (inventor to refine): 1. **Was ist passiert?** (event_kind) — "Schriftsatz eingereicht" / "Schriftsatz empfangen" / "Termin stattgefunden" / "Entscheidung ergangen" / "Frist verpasst" / "Sonstiges". 2. **Vor welchem Gericht / bei welchem Amt?** (forum) — UPC / LG/OLG/BGH / EPA / DPMA. Pre-filled from project. Skip if event_kind narrows to one forum. 3. **In welchem Verfahren?** (proceeding_type) — only the proceedings valid under the chosen forum. Pre-filled from project. Skip if forum narrows to one. 4. **Welches Schriftstück / Welcher Termin konkret?** (procedural_event slug) — narrowed to the events with the chosen event_kind + proceeding_type. This is where the wizard lands. If the narrowed scope has only one candidate, auto-select and skip the question. 5. (only if needed) **Vertreten Sie Kläger- oder Beklagtenseite?** (perspective) — pre-filled from project.our_side. Asked only when the trigger event's follow-ups differ by side. ## Open design questions (for the inventor) 1. **Single page or stepper?** — keep current single-page row-stack with state, or switch to a real multi-step UI (wizard route, back/forward buttons, URL-encoded state)? 2. **Mode switcher** — where does "Direkt suchen" (A) vs "Wizard" (B) live? Tab at top? Two CTAs on the page header? 3. **Filter-vs-qualifier UX** — how do we visually communicate "this is a filter, you can leave it open" vs "this is a qualifier, you must commit"? Different chip styles? Required asterisk vs optional placeholder? 4. **Cascade tree** — keep `event_categories` tree (the "Was ist passiert?" hierarchical picker) or replace with flat event_kind + free-text search? Tree adds visual structure but burns clicks. 5. **Result grouping** — mandatory / optional / conditional / spawned: 4 groups, or 2 (mandatory vs everything-else with sub-grouping)? 6. **Project write-back** — single button "all selected → into Akte", per-rule inline "+" buttons, or batch confirm-and-edit-dates modal? What about deadlines that need a trigger-date input (most do)? 7. **No-project mode** — what does the write-back button do when no project is active? Disabled with hint? Open project picker? Just hide? 8. **Perspective as filter vs qualifier** — in explore mode "Beide" is fine because the user is researching. In file mode it's nonsense. Does the mode-switch swap the row entirely, or just the validation? 9. **Trigger-date input** — when do we ask? In the wizard before showing results, or in the result view per-rule, or in the write-back modal? 10. **Backward navigation** — clicking "ändern" on an earlier row resets the cascade. Should it preserve compatible picks downstream, or fully reset? 11. **Deep link** — every wizard state needs a URL so users can share "trigger=X, project=Y, follow-ups=[a,b,c]" with colleagues. Where do the picks live — query string? Pathname? 12. **Search ranking** — when the direct-search box returns 21 hits (as in m's example for "Klageerhebung"), how do we rank? By proceeding_type popularity? Project context? Most-recently-used in this project? ## Acceptance for the inventor design pass Deliverable: `docs/design-fristenrechner-overhaul-2026-05-NN.md` covering: - Mode taxonomy (direct vs wizard) with a state-machine sketch - Axis taxonomy ratified (filters vs qualifiers — table above expanded) - Wizard question order and branching rules (with the 12 PRD questions ratified by m) - Result-view shape (grouping, columns, per-rule actions) - Project write-back flow (UI + which deadlines table the writes hit + audit_reason wording) - URL/state representation - Migration plan from the current row-stack: which pieces survive, which get replaced, deprecation of current `buildRowStack` and the `event_categories` tree - One concrete worked example: "PA at LG Düsseldorf gets a Hinweisbeschluss via CMS in an active case" → exact wizard path + result page + write-back outcome - Out-of-scope notes: anything explicitly deferred (e.g. paliadin-driven semantic search, voice input) No code yet — design only. Coder shift comes after m ratifies the design (per inventor→coder gate in head SKILL). ## Data quality preconditions (already in flight or fixed) - 5 identical `Mängelbeseitigung / Zahlung` sequencing_rule clones being archived in mig 152 (curie, in progress). - `Zwischenverfahren` renamed to `Zwischenanhörung` for upc.inf/rev/dmgs.cfi.interim (2026-05-26). - 5 orphan deadline_concepts staged as drafts in t-paliad-320 (m to publish via /admin/procedural-events). ## Out of scope - Replacing the underlying `sequencing_rules` model (Phase 3 schema is fine for this UX). - Paliadin-AI integration into the wizard (separate track; the wizard can call out to paliadin later as a Phase 2). - Calendar / outlook sync of created deadlines (separate t-paliad-... — see project-status.md long-term goals).
mAi self-assigned this 2026-05-26 19:23:00 +00:00
Author
Collaborator

S1-S6 train shipped

Fristenrechner overhaul fully landed across six slices per design doc:

Slice Commit What
S1 7ea4151 backend GET /search?kind=events + new GET /follow-ups
S2 9ab8dd8 result view under ?overhaul=1 — sticky trigger card, 4 priority groups + SPAWNED badge, per-rule rows, write-back footer conditional on ?project=
S3 2a2c5b8 Mode A "Direkt suchen" — filter strip + search + result list, mode tab pair, inbox secondary chip per §3.3
S4 70985d8 Mode B 5-row wizard — R1 event_kind / R2 forum / R3 proceeding (auto-skip + EventKind filter) / R4 procedural_event / R5 perspective (only when follow-ups differ)
S5 4571bd4 flip ?overhaul=1 default; legacy reachable via ?legacy=1 for the 2-week deprecation window
S6 ba3e079 drop cascade endpoint + handler, neutralize legacy Pathway B init (row-stack subtree retained as dead code for one follow-up cleanup)

Sequenced together with m/paliad#147 — mig 153 (taxonomy kind discriminator) landed before S3 so Mode A's chip query and Mode B's R3 EventKind filter exclude phase / side_action / meta rows from day one.

Verified at every slice boundary: bun build clean (2971 i18n keys, data-i18n attributes clean), 256 frontend tests pass (incl. 9 + 7 new helpers for groupFollowUps / defaultChecked / followUpsDifferByParty), go build + vet clean, live-DB tests against youpc Postgres pass (6 subtests across TestListProceedings + TestSearchEvents + TestLookupFollowUps).

Follow-up scope: drop the legacy concept-card response shape from /search together with the upper-half Pathway B B2 search wiring (runSearch / renderConceptCard / renderSearchResults / SearchResponse types in fristenrechner.ts). The dead-code row-stack helpers (buildRowStack, renderRowStack, runB1Search, etc.) get lifted out in the same follow-up — they're unreachable today but bulk up the file.

m/paliad#147 taxonomy work covered the proceeding_types cleanup that load-bears this overhaul.

## S1-S6 train shipped Fristenrechner overhaul fully landed across six slices per [design doc](https://mgit.msbls.de/m/paliad/src/branch/main/docs/design-fristenrechner-overhaul-2026-05-26.md): | Slice | Commit | What | |---|---|---| | S1 | [`7ea4151`](https://mgit.msbls.de/m/paliad/commit/7ea4151) | backend `GET /search?kind=events` + new `GET /follow-ups` | | S2 | [`9ab8dd8`](https://mgit.msbls.de/m/paliad/commit/9ab8dd8) | result view under `?overhaul=1` — sticky trigger card, 4 priority groups + SPAWNED badge, per-rule rows, write-back footer conditional on `?project=` | | S3 | [`2a2c5b8`](https://mgit.msbls.de/m/paliad/commit/2a2c5b8) | Mode A "Direkt suchen" — filter strip + search + result list, mode tab pair, inbox secondary chip per §3.3 | | S4 | [`70985d8`](https://mgit.msbls.de/m/paliad/commit/70985d8) | Mode B 5-row wizard — R1 event_kind / R2 forum / R3 proceeding (auto-skip + EventKind filter) / R4 procedural_event / R5 perspective (only when follow-ups differ) | | S5 | [`4571bd4`](https://mgit.msbls.de/m/paliad/commit/4571bd4) | flip `?overhaul=1` default; legacy reachable via `?legacy=1` for the 2-week deprecation window | | S6 | [`ba3e079`](https://mgit.msbls.de/m/paliad/commit/ba3e079) | drop cascade endpoint + handler, neutralize legacy Pathway B init (row-stack subtree retained as dead code for one follow-up cleanup) | Sequenced together with [`m/paliad#147`](https://mgit.msbls.de/m/paliad/issues/147) — mig 153 (taxonomy `kind` discriminator) landed before S3 so Mode A's chip query and Mode B's R3 EventKind filter exclude phase / side_action / meta rows from day one. **Verified at every slice boundary:** bun build clean (2971 i18n keys, data-i18n attributes clean), 256 frontend tests pass (incl. 9 + 7 new helpers for `groupFollowUps` / `defaultChecked` / `followUpsDifferByParty`), go build + vet clean, live-DB tests against youpc Postgres pass (6 subtests across `TestListProceedings` + `TestSearchEvents` + `TestLookupFollowUps`). **Follow-up scope:** drop the legacy concept-card response shape from `/search` together with the upper-half Pathway B B2 search wiring (`runSearch` / `renderConceptCard` / `renderSearchResults` / `SearchResponse` types in `fristenrechner.ts`). The dead-code row-stack helpers (`buildRowStack`, `renderRowStack`, `runB1Search`, etc.) get lifted out in the same follow-up — they're unreachable today but bulk up the file. m/paliad#147 taxonomy work covered the proceeding_types cleanup that load-bears this overhaul.
Author
Collaborator

Fixer (brunel, t-paliad-326): dark-mode token migration for Fristenrechner overhaul CSS — COMPLETE

The S2/S3/S4 additions (~121 hardcoded hex literals across the result view, Mode A search, Mode B wizard) bypassed the :root[data-theme="dark"] flip and left the whole Fristenrechner stuck in light colors when the theme toggle ran.

All hex literals in those sections are now consumed from the design-token system that the rest of paliad uses (PWAHead.tsx flips data-theme from localStorage[paliad-theme]):

  • Surfaces / borders / text → existing --color-surface{,-2} / --color-border{,-strong} / --color-text{,-muted,-subtle} tokens.
  • Status badges (error / spawn / cond / ok / court-set / party-claimant / party-defendant / filter+qualifier wizard badges) → existing --status-{red,amber,green,blue}-* tokens.
  • Brand-lime cues (mandatory group stripe, mode-tab active underline, wizard row-number circle) → existing --color-accent / --color-accent-dark.
  • Accent links (rule-source, edit-date, result-cta, wizard-edit, mode-A result-followups) → existing --color-accent-fg (midnight in light, lime in dark).
  • Trigger card shadow → var(--shadow) (auto-deepens in dark).

Ten new tokens introduced in :root + mirrored in :root[data-theme="dark"]:

  • --color-accent-soft-{bg,fg,border} — pale lime tints for nudges, footers, hover bgs, success messages, is-from-project wizard rows, lime hover.
  • --color-accent-strong-{bg,fg,border} — saturated lime pills for active chip, jurisdiction badge, wizard is-active outline.
  • --status-blue-border — missing primary on the existing blue bucket, now used for the Recommended-group stripe.
  • --status-purple-{bg,fg,border} — new bucket for the court party stance (no existing purple status palette to lean on).

Wizard active-row glow rgba(198, 244, 28, 0.15) rewritten as rgb(var(--hlc-lime-rgb) / 0.15) so it also follows the channel token.

Verification (CSS-only change, no DOM / no JS / no layout touched): built frontend/dist/assets/global.css via bun run build and mounted it against a representative static DOM (all four group stripes, every party stance, mode-A filter+result list, mode-B wizard with filter+qualifier badges, trigger card, write-back footer, kontextfrei nudge, ok+error messages). Toggled data-theme="dark" via JS — every surface, border, chip, badge, status pill flipped to its dark counterpart and getComputedStyle confirms each token resolves through both modes (e.g. --color-accent-soft-bg#f7fbe6 light, rgb(191 243 85 / 0.08) dark; defendant party → rgb(239 68 68 / 0.18) + #fca5a5; court party → rgb(168 85 247 / 0.18) + #d8b4fe).

bun run build + go vet ./... clean. Single commit. Layout / spacing / sizing untouched (colours, borders, shadows only).

Commit: https://mgit.msbls.de/m/paliad/commit/76d38c4
Branch: mai/brunel/fixer-dark-mode-support

**Fixer (brunel, t-paliad-326): dark-mode token migration for Fristenrechner overhaul CSS — COMPLETE** The S2/S3/S4 additions (~121 hardcoded hex literals across the result view, Mode A search, Mode B wizard) bypassed the `:root[data-theme="dark"]` flip and left the whole Fristenrechner stuck in light colors when the theme toggle ran. All hex literals in those sections are now consumed from the design-token system that the rest of paliad uses (`PWAHead.tsx` flips `data-theme` from `localStorage[paliad-theme]`): - Surfaces / borders / text → existing `--color-surface{,-2}` / `--color-border{,-strong}` / `--color-text{,-muted,-subtle}` tokens. - Status badges (error / spawn / cond / ok / court-set / party-claimant / party-defendant / filter+qualifier wizard badges) → existing `--status-{red,amber,green,blue}-*` tokens. - Brand-lime cues (mandatory group stripe, mode-tab active underline, wizard row-number circle) → existing `--color-accent` / `--color-accent-dark`. - Accent links (rule-source, edit-date, result-cta, wizard-edit, mode-A result-followups) → existing `--color-accent-fg` (midnight in light, lime in dark). - Trigger card shadow → `var(--shadow)` (auto-deepens in dark). **Ten new tokens** introduced in `:root` + mirrored in `:root[data-theme="dark"]`: - `--color-accent-soft-{bg,fg,border}` — pale lime tints for nudges, footers, hover bgs, success messages, `is-from-project` wizard rows, lime hover. - `--color-accent-strong-{bg,fg,border}` — saturated lime pills for active chip, jurisdiction badge, wizard `is-active` outline. - `--status-blue-border` — missing primary on the existing blue bucket, now used for the Recommended-group stripe. - `--status-purple-{bg,fg,border}` — new bucket for the court party stance (no existing purple status palette to lean on). Wizard active-row glow `rgba(198, 244, 28, 0.15)` rewritten as `rgb(var(--hlc-lime-rgb) / 0.15)` so it also follows the channel token. **Verification (CSS-only change, no DOM / no JS / no layout touched):** built `frontend/dist/assets/global.css` via `bun run build` and mounted it against a representative static DOM (all four group stripes, every party stance, mode-A filter+result list, mode-B wizard with filter+qualifier badges, trigger card, write-back footer, kontextfrei nudge, ok+error messages). Toggled `data-theme="dark"` via JS — every surface, border, chip, badge, status pill flipped to its dark counterpart and `getComputedStyle` confirms each token resolves through both modes (e.g. `--color-accent-soft-bg` → `#f7fbe6` light, `rgb(191 243 85 / 0.08)` dark; defendant party → `rgb(239 68 68 / 0.18)` + `#fca5a5`; court party → `rgb(168 85 247 / 0.18)` + `#d8b4fe`). `bun run build` + `go vet ./...` clean. Single commit. Layout / spacing / sizing untouched (colours, borders, shadows only). Commit: https://mgit.msbls.de/m/paliad/commit/76d38c4 Branch: `mai/brunel/fixer-dark-mode-support`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#146
No description provided.