feat(fristenrechner): Slice S3 — Mode A direct search (m/paliad#146)
Mode A "⚡ Direkt suchen" — the power-user entry path defined in docs/design-fristenrechner-overhaul-2026-05-26.md §3.1. Renders above the §4 result view; clicking a result row locks the trigger event and transitions to the shared result surface from S2. Frontend: * `fristenrechner-mode-a.ts` — filter strip (Forum / Verfahren / Was passierte / Partei) + free-text search input + result list. Section-split visual hierarchy per m §11.Q3: filter chips in a bordered "Filter (eingrenzen)" strip on top, result list below. Inbox channel chip lives behind an "Erweitert" details summary per §3.3; picking CMS / beA auto-nudges the Forum chip. Party chip retains a "Beide" option (Mode A is filter mode per §11.Q8; Mode B drops it in S4). * `fristenrechner-result.ts` — new `mountModeShell(activeTab)` renders the two mode tabs per §11.Q2 and lazy-imports Mode A. Mode B tab is a placeholder until S4 lands. * `fristenrechner.ts` boot — when `?overhaul=1` is set and `?event` is empty, mountModeShell takes over (default tab = search; `?mode= wizard` opens the wizard tab when S4 ships). With `?event=` the flow still jumps straight to the result view. URL state syncs forum / pt / kind / party / q on every chip click. * 28 i18n keys added (DE + EN parity), 310-line CSS block for the mode tabs + Mode A surface. Backend: * New `ProceedingListOptions { Jurisdiction, Kind }` + service method `ListProceedings(ctx, opts)`. Legacy `ListFristenrechnerTypes` keeps the no-filter signature for existing callers. Handler `/api/tools/proceeding-types` accepts `?jurisdiction=` and `?kind=` query params. * `kind=proceeding` filter targets the taxonomy column landed in mig 153 (parallel branch t-paliad-325, m/paliad#147). Sequenced per the taxonomy doc §7 option (c): mig 153 merges before S3 ships to main, so the filter is never false-positive (no phase / side_action / meta rows leak into the chip strip). Verified — bun build clean (2955 i18n keys, data-i18n attributes clean), 249 frontend tests pass, go build + vet clean. New TestListProceedings — 4 PASS (no-filter, jurisdiction=UPC, jurisdiction=DE, ListFristenrechnerTypes alias) + 1 SKIP for the kind=proceeding case that probes the column and skips when mig 153 hasn't landed yet. S1 + S2 live tests still green.
This commit is contained in:
@@ -19226,3 +19226,313 @@ a.fristen-overhaul-rule-source {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* === Fristenrechner overhaul Mode A + mode tabs (t-paliad-323 S3) ===
|
||||
*
|
||||
* Mode tab pair + filter strip + search box + result list per
|
||||
* docs/design-fristenrechner-overhaul-2026-05-26.md §3.1.
|
||||
* Section-split visual hierarchy per m §11.Q3: filter strip on top
|
||||
* ("Filter (eingrenzen)" header), result list below (clicking a row
|
||||
* IS the qualifier commit).
|
||||
* ==================================================================== */
|
||||
|
||||
.fristen-mode-tabs {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
margin: 0 0 1rem 0;
|
||||
border-bottom: 2px solid #e3e3da;
|
||||
}
|
||||
|
||||
.fristen-mode-tab {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.55rem 1.1rem;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 3px solid transparent;
|
||||
margin-bottom: -2px;
|
||||
color: #555;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-radius: 0.4rem 0.4rem 0 0;
|
||||
}
|
||||
|
||||
.fristen-mode-tab:hover {
|
||||
background: #f5f5ef;
|
||||
color: #1f1f1f;
|
||||
}
|
||||
|
||||
.fristen-mode-tab.is-active {
|
||||
color: #2a2a2a;
|
||||
border-bottom-color: #c6f41c;
|
||||
background: #fbfdf3;
|
||||
}
|
||||
|
||||
.fristen-mode-tab-icon {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.fristen-mode-tab-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fristen-mode-a-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-filters {
|
||||
background: #f7f8f2;
|
||||
border: 1px solid #e2e3d7;
|
||||
border-radius: 0.7rem;
|
||||
padding: 0.8rem 1rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-filters-header {
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.05em;
|
||||
color: #6e7256;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.6rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-axis-label {
|
||||
font-size: 0.85rem;
|
||||
color: #555;
|
||||
min-width: 7rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
padding: 0.25rem 0.65rem;
|
||||
border: 1px solid #d4d4c9;
|
||||
background: #fff;
|
||||
color: #2a2a2a;
|
||||
border-radius: 1rem;
|
||||
font-size: 0.85rem;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip:hover {
|
||||
border-color: #b9c98f;
|
||||
background: #f6fae5;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip.is-active {
|
||||
background: #d8ed90;
|
||||
border-color: #98b545;
|
||||
color: #2c3d10;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip-icon {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-chip-loading,
|
||||
.fristen-mode-a-chip-empty {
|
||||
color: #888;
|
||||
font-size: 0.85rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fristen-mode-a-inbox {
|
||||
margin-top: 0.5rem;
|
||||
padding-top: 0.4rem;
|
||||
border-top: 1px dashed #d8d8cd;
|
||||
}
|
||||
|
||||
.fristen-mode-a-inbox-summary {
|
||||
cursor: pointer;
|
||||
color: #5f664a;
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 0.3rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fristen-mode-a-inbox-summary:hover {
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
.fristen-mode-a-search {
|
||||
background: #fff;
|
||||
border: 1px solid #d8d8ce;
|
||||
border-radius: 0.7rem;
|
||||
padding: 0.6rem 0.9rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-search-input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-search-icon {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.fristen-mode-a-search-input {
|
||||
flex: 1 1 auto;
|
||||
border: 0;
|
||||
outline: none;
|
||||
font-size: 1rem;
|
||||
background: transparent;
|
||||
padding: 0.3rem 0;
|
||||
color: #1f1f1f;
|
||||
}
|
||||
|
||||
.fristen-mode-a-results {
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0d4;
|
||||
border-radius: 0.7rem;
|
||||
padding: 0.7rem 0.9rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-results-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-results-title {
|
||||
font-weight: 600;
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
.fristen-mode-a-results-count {
|
||||
font-size: 0.85rem;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
gap: 0.7rem;
|
||||
align-items: center;
|
||||
padding: 0.55rem 0.7rem;
|
||||
background: #fafaf6;
|
||||
border: 1px solid #ececde;
|
||||
border-radius: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result:hover,
|
||||
.fristen-mode-a-result:focus {
|
||||
background: #f1f7d8;
|
||||
border-color: #c2d182;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-icon {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-body {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-title {
|
||||
font-weight: 600;
|
||||
color: #1f1f1f;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
align-items: center;
|
||||
font-size: 0.8rem;
|
||||
color: #555;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-pt {
|
||||
font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
|
||||
padding: 0.05rem 0.45rem;
|
||||
background: #efefe6;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-pt-name {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-juris {
|
||||
padding: 0.05rem 0.45rem;
|
||||
background: #d3edb7;
|
||||
color: #38531a;
|
||||
border-radius: 0.3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-followups {
|
||||
color: #4a6f1f;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-cta {
|
||||
color: #88a554;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-loading,
|
||||
.fristen-mode-a-result-empty,
|
||||
.fristen-mode-a-result-error {
|
||||
list-style: none;
|
||||
padding: 0.7rem 0.5rem;
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.fristen-mode-a-result-error {
|
||||
color: #732f25;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.fristen-mode-a-axis-label {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.fristen-mode-a-result {
|
||||
grid-template-columns: auto 1fr;
|
||||
}
|
||||
.fristen-mode-a-result-cta {
|
||||
grid-column: 1 / -1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user