Files
paliad/frontend/src/fristenrechner.tsx
mAi f8af389134 fix(a11y): drop label htmlFor=trigger-event — span isn't labelable
m/paliad#60 (t-paliad-221) — Chrome's Issues tab flagged a label/for
violation on the timeline wizard: <label for="trigger-event"> pointed
at a <span> showing the selected trigger event name. <label for=…>
must target a labelable form control (input/select/textarea/…), never
a span; the browser strips the association and a11y tooling sees a
dangling reference.

Audit found two occurrences — verfahrensablauf.tsx and fristenrechner.tsx
both use the same wizard markup. Switch both captions to plain
<span class="date-label">; the .date-label rule already targets by
class only, so visual styling is unchanged. No other label-for
mismatches surfaced (194 label-fors scanned across frontend/src).
2026-05-20 14:42:49 +02:00

658 lines
38 KiB
TypeScript

import { h } from "./jsx";
import { Sidebar } from "./components/Sidebar";
import { PaliadinWidget } from "./components/PaliadinWidget";
import { BottomNav } from "./components/BottomNav";
import { Footer } from "./components/Footer";
import { PWAHead } from "./components/PWAHead";
interface ProceedingDef {
code: string;
i18nKey: string;
name: string;
}
function proceedingBtn(p: ProceedingDef): string {
return (
<button type="button" className="proceeding-btn" data-code={p.code}>
<strong data-i18n={p.i18nKey}>{p.name}</strong>
</button>
);
}
// Quick-pick chip definition. Each chip targets ONE deadline_concepts
// slug — clicking sets the search query to the concept's name in the
// active language so trigram search lands on the right concept card.
// Single source of truth for both fork-shortcut and B2-search-bar
// chip rows. Dedup invariant: no two chips share a slug. Label flips
// per language via the chip wiring in client/fristenrechner.ts.
interface QuickChip {
slug: string;
name_de: string;
name_en: string;
}
const QUICK_CHIPS: QuickChip[] = [
{ slug: "statement-of-defence", name_de: "Klageerwiderung", name_en: "Statement of Defence" },
{ slug: "notice-of-appeal", name_de: "Berufungsschrift", name_en: "Notice of Appeal" },
{ slug: "opposition", name_de: "Einspruchsfrist", name_en: "Opposition" },
{ slug: "reply-to-defence", name_de: "Replik", name_en: "Reply to Defence" },
{ slug: "nichtzulassungsbeschwerde", name_de: "Nichtzulassungsbeschwerde", name_en: "Non-admission Appeal (NZB)" },
{ slug: "application-for-determination-of-damages",name_de: "Antrag auf Schadensbemessung", name_en: "Application for Determination of Damages" },
{ slug: "wiedereinsetzung", name_de: "Wiedereinsetzung", name_en: "Re-establishment of Rights" },
];
function quickChip(c: QuickChip): string {
return (
<button type="button" className="fristen-search-chip"
data-chip-slug={c.slug}
data-chip-name-de={c.name_de}
data-chip-name-en={c.name_en}
data-q={c.name_de}>
{c.name_de}
</button>
);
}
const UPC_TYPES: ProceedingDef[] = [
{ code: "upc.inf.cfi", i18nKey: "deadlines.upc.inf.cfi", name: "Verletzungsverfahren" },
{ code: "upc.rev.cfi", i18nKey: "deadlines.upc.rev.cfi", name: "Nichtigkeitsklage" },
{ code: "upc.ccr.cfi", i18nKey: "deadlines.upc.ccr.cfi", name: "Widerklage auf Nichtigkeit" },
{ code: "upc.pi.cfi", i18nKey: "deadlines.upc.pi.cfi", name: "Einstw. Ma\u00dfnahmen" },
{ code: "upc.apl.merits", i18nKey: "deadlines.upc.apl.merits", name: "Berufung" },
{ code: "upc.dmgs.cfi", i18nKey: "deadlines.upc.dmgs.cfi", name: "Schadensbemessung" },
{ code: "upc.disc.cfi", i18nKey: "deadlines.upc.disc.cfi", name: "Bucheinsicht" },
{ code: "upc.apl.cost", i18nKey: "deadlines.upc.apl.cost", name: "Berufung Kosten" },
{ code: "upc.apl.order", i18nKey: "deadlines.upc.apl.order", name: "Berufung Anordnungen" },
];
// DE proceedings split by type (Verletzung / Nichtigkeit) per m's
// 2026-05-18 ask. Labels are parallel: <court> (<procedural role>),
// so a user scanning the picker sees the instance-and-role at a glance
// without one tile reading "Berufung OLG" and another "Nichtigkeits-
// verfahren". Sub-group headers convey the type grouping. Combined-
// timeline behaviour (LG→OLG→BGH as one calc) is filed as m/paliad#41.
const DE_INF_TYPES: ProceedingDef[] = [
{ code: "de.inf.lg", i18nKey: "deadlines.de.inf.lg", name: "LG (1. Instanz)" },
{ code: "de.inf.olg", i18nKey: "deadlines.de.inf.olg", name: "OLG (Berufung)" },
{ code: "de.inf.bgh", i18nKey: "deadlines.de.inf.bgh", name: "BGH (Revision / NZB)" },
];
const DE_NULL_TYPES: ProceedingDef[] = [
{ code: "de.null.bpatg", i18nKey: "deadlines.de.null.bpatg", name: "BPatG (1. Instanz)" },
{ code: "de.null.bgh", i18nKey: "deadlines.de.null.bgh", name: "BGH (Berufung)" },
];
const EPA_TYPES: ProceedingDef[] = [
{ code: "epa.opp.opd", i18nKey: "deadlines.epa.opp.opd", name: "Einspruchsverfahren" },
{ code: "epa.opp.boa", i18nKey: "deadlines.epa.opp.boa", name: "Beschwerdeverfahren" },
{ code: "epa.grant.exa", i18nKey: "deadlines.epa.grant.exa", name: "EP-Erteilungsverfahren" },
];
const DPMA_TYPES: ProceedingDef[] = [
{ code: "dpma.opp.dpma", i18nKey: "deadlines.dpma.opp.dpma", name: "Einspruch DPMA" },
{ code: "dpma.appeal.bpatg", i18nKey: "deadlines.dpma.appeal.bpatg", name: "Beschwerde BPatG (DPMA)" },
{ code: "dpma.appeal.bgh", i18nKey: "deadlines.dpma.appeal.bgh", name: "Rechtsbeschwerde BGH" },
];
export function renderFristenrechner(): string {
const today = new Date().toISOString().split("T")[0];
return "<!DOCTYPE html>" + (
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="theme-color" content="#BFF355" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<PWAHead />
<title data-i18n="deadlines.title">Fristenrechner &mdash; Paliad</title>
<link rel="stylesheet" href="/assets/global.css" />
</head>
<body className="has-sidebar">
<Sidebar currentPath="/tools/fristenrechner" />
<BottomNav currentPath="/tools/fristenrechner" />
<main>
<section className="tool-page">
<div className="container">
<div className="tool-header">
<h1 data-i18n="deadlines.heading">Fristenrechner</h1>
<p className="tool-subtitle" data-i18n="deadlines.subtitle">
Berechnung von Verfahrensfristen f&uuml;r UPC-, deutsche und EPA-Verfahren.
</p>
</div>
{/* m's 2026-05-08 18:08 Determinator redesign — Step 1: pick the
Akte (project) that scopes the rest of the flow. Filtered
list of visible projects + "Neue Akte anlegen" link +
four ad-hoc explore-mode chips for users who just want to
look up a rule without saving anywhere. */}
<div className="fristen-step1" id="fristen-step1" role="group" aria-label="Akte picker">
<h2 className="fristen-step-heading" data-i18n="deadlines.step1.heading">
Schritt 1 &mdash; Welche Akte?
</h2>
<div className="fristen-step1-search-row">
<svg className="fristen-search-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="7"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
<input type="search" id="fristen-akte-search"
className="fristen-akte-search" autocomplete="off"
data-i18n-placeholder="deadlines.step1.search.placeholder"
placeholder="Akte suchen&hellip;" />
</div>
<ul className="fristen-akte-list" id="fristen-akte-list" role="listbox" aria-label="Akten"></ul>
<div className="fristen-step1-divider">
<span data-i18n="deadlines.step1.divider.new">oder eine neue Akte</span>
</div>
{/* return-bounce: projects-new.ts honours ?return= and
redirects back to /tools/fristenrechner?project=<new_uuid>
so the new Akte preselects itself in Step 1. */}
<a href="/projects/new?return=/tools/fristenrechner" className="fristen-step1-new" id="fristen-step1-new"
data-i18n="deadlines.step1.new.cta">
+ Neue Akte anlegen
</a>
<div className="fristen-step1-divider">
<span data-i18n="deadlines.step1.divider.adhoc">oder ad-hoc, ohne Akte</span>
</div>
<div className="fristen-adhoc-chips" role="group" aria-label="Ad-hoc proceeding">
<button type="button" className="fristen-adhoc-chip" data-ad-hoc="upc"
data-i18n="deadlines.step1.adhoc.upc">
Custom UPC proceeding
</button>
<button type="button" className="fristen-adhoc-chip" data-ad-hoc="de"
data-i18n="deadlines.step1.adhoc.de">
Custom DE proceeding
</button>
<button type="button" className="fristen-adhoc-chip" data-ad-hoc="epa"
data-i18n="deadlines.step1.adhoc.epa">
Custom EPA proceeding
</button>
<button type="button" className="fristen-adhoc-chip" data-ad-hoc="dpma"
data-i18n="deadlines.step1.adhoc.dpma">
Custom DPMA proceeding
</button>
</div>
</div>
{/* Step 1 collapsed summary, shown after a pick. Mirrors the
proceeding-summary collapse pattern from 097e21c. */}
<div className="fristen-step1-summary" id="fristen-step1-summary" style="display:none" role="group">
<span className="fristen-step1-summary-label" data-i18n="deadlines.step1.selected">Akte:</span>
<strong className="fristen-step1-summary-name" id="fristen-step1-summary-name">&mdash;</strong>
<span className="fristen-step1-summary-meta" id="fristen-step1-summary-meta"></span>
<button type="button" className="fristen-step1-summary-reselect" id="fristen-step1-summary-reselect"
data-i18n="deadlines.step1.reselect">
Andere Akte
</button>
</div>
{/* Step 2 — Do / Happened bifurcation. Hidden until Step 1 is
satisfied. Click on a card routes to the existing Pathway A
(Verfahrensablauf wizard) or Pathway B (cascade) shells —
we keep the routing primitive in showPathway()/showBMode(). */}
<div className="fristen-step2" id="fristen-step2" hidden>
<h2 className="fristen-step-heading" data-i18n="deadlines.step2.heading">
Schritt 2 &mdash; Was m&ouml;chten Sie tun?
</h2>
<div className="fristen-step2-cards">
<button type="button" className="fristen-step2-card" data-action="file" id="fristen-step2-file">
<span className="fristen-step2-card-icon" aria-hidden="true">&#9999;&#65039;</span>
<span className="fristen-step2-card-title" data-i18n="deadlines.step2.file.title">
Etwas einreichen
</span>
<span className="fristen-step2-card-desc" data-i18n="deadlines.step2.file.desc">
Outgoing &mdash; eine Frist tritt aus eigener Handlung ein.
</span>
</button>
<button type="button" className="fristen-step2-card" data-action="happened" id="fristen-step2-happened">
<span className="fristen-step2-card-icon" aria-hidden="true">&#128229;</span>
<span className="fristen-step2-card-title" data-i18n="deadlines.step2.happened.title">
Etwas ist passiert
</span>
<span className="fristen-step2-card-desc" data-i18n="deadlines.step2.happened.desc">
Incoming &mdash; ein Ereignis hat eine Frist ausgel&ouml;st.
</span>
</button>
{/* t-paliad-179 Slice 1: the third "Verfahrensablauf
einsehen" card retired — abstract-browse intent now
owns its own route at /tools/verfahrensablauf. */}
</div>
<div className="fristen-step2-shortcut">
<div className="fristen-pathway-fork-shortcut-label" data-i18n="deadlines.pathway.shortcut.label">
oder direkt zu einer Frist springen:
</div>
<div className="fristen-search-chips" id="fristen-fork-chips" role="group" aria-label="Schnellzugriff">
{QUICK_CHIPS.map((c) => quickChip(c))}
</div>
</div>
</div>
{/* Pathway B container — search bar relocates here from the page top.
Mode toggle (B1 tree / B2 filter) sits above the panels.
Hidden until ?path=b. */}
<div className="fristen-pathway-shell" id="fristen-pathway-b" data-path="b" hidden>
<button type="button" className="fristen-pathway-back" id="fristen-pathway-b-back">
<span aria-hidden="true">&larr;</span>{" "}
<span data-i18n="deadlines.pathway.back">zur&uuml;ck zur Auswahl</span>
</button>
<h2 className="fristen-pathway-heading">
<span aria-hidden="true">&#128197;</span>{" "}
<span data-i18n="deadlines.pathway.b.title">Frist eintragen aufgrund Ereignis</span>
</h2>
{/* B1 panel — row-stack cascade.
`#fristen-row-stack` hosts the perspective / inbox /
cascade rows (t-paliad-180 Slice 1; t-paliad-197 Slice 2
added project-driven prefills + auto-walk). The
stack-header above carries the inline-search trigger
(t-paliad-198 Slice 3 — clicking expands
`#fristen-row-search-panel` over the row stack instead
of routing to the legacy B2 surface) and the reset link.
`#fristen-b1-results` is unchanged — it renders concept
cards for both cascade-narrowing AND inline-search
results, so users see the same card layout regardless
of how they reached a deadline rule. */}
<div className="fristen-b1-panel" id="fristen-b1-panel" data-mode="tree" hidden>
<div className="fristen-row-stack-header" id="fristen-row-stack-header">
<button type="button" className="fristen-row-search-link" id="fristen-row-search-link"
data-i18n-title="deadlines.row.search.link.title"
aria-expanded="false"
aria-controls="fristen-row-search-panel"
title="Direkt nach einer Frist suchen">
<span aria-hidden="true">&#128269;</span>{" "}
<span data-i18n="deadlines.row.search.link">Direkt suchen</span>
</button>
<button type="button" className="fristen-row-reset-link" id="fristen-row-reset"
data-i18n-title="deadlines.row.reset.title"
title="Pfad zur&uuml;cksetzen — alle Cascade-Antworten verwerfen">
<span aria-hidden="true">&#8634;</span>{" "}
<span data-i18n="deadlines.row.reset">Pfad zur&uuml;cksetzen</span>
</button>
</div>
{/* Inline search overlay (t-paliad-198 Slice 3). Hidden by
default; the search icon-button in the stack header
toggles it open / closed. While open, the row stack is
hidden and the search input drives `#fristen-b1-results`
directly — same surface the cascade leaf populates so
the user sees one consistent concept-card list. */}
<div className="fristen-row-search-panel" id="fristen-row-search-panel" hidden role="search">
<button type="button" className="fristen-row-search-panel-back" id="fristen-row-search-panel-back"
data-i18n-title="deadlines.row.search.panel.back.title"
title="Zur&uuml;ck zum Entscheidungsbaum">
<span aria-hidden="true">&larr;</span>{" "}
<span data-i18n="deadlines.row.search.panel.back">Zur&uuml;ck zum Entscheidungsbaum</span>
</button>
<div className="fristen-row-search-panel-input-wrap">
<svg className="fristen-row-search-panel-icon" width="18" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="7"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
<input
type="search"
id="fristen-row-search-panel-input"
className="fristen-row-search-panel-input"
autocomplete="off"
spellcheck="false"
data-i18n-placeholder="deadlines.row.search.panel.placeholder"
placeholder="Frist suchen&hellip;"
aria-label="Frist suchen"
/>
<button type="button" className="fristen-row-search-panel-clear" id="fristen-row-search-panel-clear"
data-i18n-title="deadlines.row.search.panel.clear" title="Eingabe leeren" hidden>
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
<div className="fristen-row-stack" id="fristen-row-stack" aria-live="polite"></div>
<div className="fristen-b1-results" id="fristen-b1-results" aria-live="polite"></div>
</div>
{/* B2 panel — search bar + chips + concept-card results.
The search input + chips + results host live here so
fristenrechner.ts can drive both Phase D (today) and the
B1↔B2 state-share in Phase D (forum filter). */}
<div className="fristen-b2-panel" id="fristen-b2-panel" data-mode="filter">
<div className="fristen-search">
<label htmlFor="fristen-search-input" className="visually-hidden" data-i18n="deadlines.search.label">Frist suchen</label>
<div className="fristen-search-row">
<svg className="fristen-search-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="7"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
<input
type="search"
id="fristen-search-input"
className="fristen-search-input"
autocomplete="off"
spellcheck="false"
data-i18n-placeholder="deadlines.search.placeholder"
placeholder="Klageerwiderung, RoP 23, § 82, Wiedereinsetzung&hellip;"
/>
<button type="button" id="fristen-search-clear" className="fristen-search-clear" aria-label="Suche leeren" data-i18n-aria-label="deadlines.search.clear" hidden>
&times;
</button>
</div>
<div className="fristen-search-chips" id="fristen-search-chips" role="group" aria-label="Schnellzugriff">
<span className="fristen-search-chips-label" data-i18n="deadlines.search.chips.label">Schnellzugriff:</span>
{QUICK_CHIPS.map((c) => quickChip(c))}
</div>
{/* Forum filter row — populated by Phase D. */}
<div className="fristen-forum-filter" id="fristen-forum-filter" hidden>
<span className="fristen-forum-filter-label" data-i18n="deadlines.filter.forum.label">Gericht / System:</span>
<div className="fristen-forum-chips" id="fristen-forum-chips"></div>
</div>
<div id="fristen-search-results" className="fristen-search-results" aria-live="polite"></div>
</div>
</div>
</div>
{/* Step 3a — outgoing-intent chooser. Reached when the user
picks "Etwas einreichen" on Step 2. Three options per
m's 2026-05-08 18:09 spec: File (drives the Pathway A
wizard), Draft (future drafting surface; v1
placeholder), Enter (routes to the existing manual-
create form). */}
<div className="fristen-pathway-shell" id="fristen-step3a" data-path="outgoing" hidden>
<button type="button" className="fristen-pathway-back" id="fristen-step3a-back">
<span aria-hidden="true">&larr;</span>{" "}
<span data-i18n="deadlines.step3a.back">zur&uuml;ck zur Auswahl</span>
</button>
<h2 className="fristen-pathway-heading">
<span aria-hidden="true">&#9999;&#65039;</span>{" "}
<span data-i18n="deadlines.step3a.heading">Was m&ouml;chten Sie einreichen?</span>
</h2>
<div className="fristen-step2-cards">
<button type="button" className="fristen-step2-card" id="fristen-step3a-file" data-action="file">
<span className="fristen-step2-card-icon" aria-hidden="true">&#128221;</span>
<span className="fristen-step2-card-title" data-i18n="deadlines.step3a.file.title">
Schriftsatz einreichen
</span>
<span className="fristen-step2-card-desc" data-i18n="deadlines.step3a.file.desc">
Verfahrensablauf laden &mdash; Frist berechnen und zur Akte hinzuf&uuml;gen.
</span>
</button>
<button type="button" className="fristen-step2-card fristen-step2-card--soon" id="fristen-step3a-draft" data-action="draft" disabled
data-i18n-title="deadlines.step3a.soon">
<span className="fristen-step2-card-icon" aria-hidden="true">&#128393;</span>
<span className="fristen-step2-card-title" data-i18n="deadlines.step3a.draft.title">
Schriftsatz entwerfen
</span>
<span className="fristen-step2-card-desc" data-i18n="deadlines.step3a.draft.desc">
Vorbereitung &mdash; sp&auml;ter mit Drafting-Surface verkn&uuml;pft.
</span>
<span className="fristen-step2-card-soon" data-i18n="deadlines.step3a.soon">kommt bald</span>
</button>
<button type="button" className="fristen-step2-card" id="fristen-step3a-enter" data-action="enter">
<span className="fristen-step2-card-icon" aria-hidden="true">&#128190;</span>
<span className="fristen-step2-card-title" data-i18n="deadlines.step3a.enter.title">
Frist manuell erfassen
</span>
<span className="fristen-step2-card-desc" data-i18n="deadlines.step3a.enter.desc">
Direkt eintragen &mdash; bereits bekanntes Datum / bekannter Typ.
</span>
</button>
</div>
</div>
{/* Pathway A container — wraps the existing wizard.
Hidden until ?path=a. */}
<div className="fristen-pathway-shell" id="fristen-pathway-a" data-path="a" hidden>
<button type="button" className="fristen-pathway-back" id="fristen-pathway-a-back">
<span aria-hidden="true">&larr;</span>{" "}
<span data-i18n="deadlines.pathway.back">zur&uuml;ck zur Auswahl</span>
</button>
<h2 className="fristen-pathway-heading">
<span aria-hidden="true">&#128214;</span>{" "}
<span data-i18n="deadlines.pathway.a.title">Verfahrensablauf informieren</span>
</h2>
{/* v3: legacy mode tabs retired (m's spec lock §10 Q1, 2026-05-05).
Pathway A is Verfahrensablauf-only; trigger-event drill-in
surfaces via concept-card pills with ?path=a&trigger=N URL,
which resurfaces mode-event-panel programmatically below. */}
<div className="fristen-wizard mode-panel" id="mode-procedure-panel" data-mode="procedure" role="tabpanel">
<div className="wizard-step" id="step-1">
<h3 className="wizard-step-label">
<span className="step-number">1</span>
<span data-i18n="deadlines.step1">Verfahrensart w&auml;hlen</span>
</h3>
<div className="proceeding-group" data-forum="upc">
<h4 data-i18n="deadlines.upc">UPC</h4>
<div className="proceeding-btns">
{UPC_TYPES.map((p) => proceedingBtn(p))}
</div>
</div>
<div className="proceeding-group" data-forum="de">
<h4 data-i18n="deadlines.de">Deutsche Gerichte</h4>
<div className="proceeding-subgroup">
<h5 className="proceeding-subgroup-heading" data-i18n="deadlines.de.group.inf">Verletzungsverfahren</h5>
<div className="proceeding-btns">
{DE_INF_TYPES.map((p) => proceedingBtn(p))}
</div>
</div>
<div className="proceeding-subgroup">
<h5 className="proceeding-subgroup-heading" data-i18n="deadlines.de.group.null">Nichtigkeitsverfahren</h5>
<div className="proceeding-btns">
{DE_NULL_TYPES.map((p) => proceedingBtn(p))}
</div>
</div>
</div>
<div className="proceeding-group" data-forum="epa">
<h4 data-i18n="deadlines.epa">EPA</h4>
<div className="proceeding-btns">
{EPA_TYPES.map((p) => proceedingBtn(p))}
</div>
</div>
<div className="proceeding-group" data-forum="dpma">
<h4 data-i18n="deadlines.dpma">DPMA</h4>
<div className="proceeding-btns">
{DPMA_TYPES.map((p) => proceedingBtn(p))}
</div>
</div>
{/* m's 2026-05-08 18:26: collapse the proceeding picker once
a choice is made; this summary line replaces the four
group blocks with a one-line "Selected: X [Reselect]"
affordance. JS toggles `.proceeding-summary` visibility
in lockstep with `.proceeding-group` blocks. */}
<div className="proceeding-summary" id="proceeding-summary" style="display:none" role="group">
<span className="proceeding-summary-label" data-i18n="deadlines.proceeding.selected">Verfahren:</span>
<strong className="proceeding-summary-name" id="proceeding-summary-name">&mdash;</strong>
<button type="button" className="proceeding-summary-reselect" id="proceeding-summary-reselect"
data-i18n="deadlines.proceeding.reselect">
Anderes Verfahren w&auml;hlen
</button>
</div>
</div>
<div className="wizard-step" id="step-2" style="display:none">
<h3 className="wizard-step-label">
<span className="step-number">2</span>
<span data-i18n="deadlines.step2">Ausgangsdatum eingeben</span>
</h3>
<div className="date-input-group">
<div className="date-field-row">
{/* Read-only caption labelling the value <span>. Not a
<label htmlFor> — m/paliad#60: <label for=…> must
point at a labelable form control, never a span. */}
<span className="date-label" data-i18n="deadlines.trigger.event">Ausl&ouml;sendes Ereignis:</span>
<span id="trigger-event" className="trigger-event-name">&mdash;</span>
</div>
<div className="date-field-row">
<label htmlFor="trigger-date" className="date-label" data-i18n="deadlines.trigger.date">Datum:</label>
<input type="date" id="trigger-date" className="date-input" value={today} />
</div>
<div className="date-field-row" id="court-picker-row" style="display:none">
<label htmlFor="court-picker" className="date-label" data-i18n="deadlines.court.label">Gericht:</label>
<select id="court-picker" className="date-input"></select>
</div>
<div className="date-field-row" id="priority-date-row" style="display:none">
<label htmlFor="priority-date" className="date-label" data-i18n="deadlines.priority.date">Priorit&auml;tstag (optional):</label>
<input type="date" id="priority-date" className="date-input" />
</div>
<div className="date-field-row" id="ccr-flag-row" style="display:none">
<label className="date-label">
<input type="checkbox" id="ccr-flag" />
<span data-i18n="deadlines.flag.ccr">Mit Widerklage auf Nichtigkeit</span>
</label>
</div>
<div className="date-field-row date-field-row--nested" id="inf-amend-flag-row" style="display:none">
<label className="date-label">
<input type="checkbox" id="inf-amend-flag" />
<span data-i18n="deadlines.flag.inf_amend">Mit Antrag auf Patent&auml;nderung (R.30)</span>
</label>
</div>
<div className="date-field-row" id="rev-amend-flag-row" style="display:none">
<label className="date-label">
<input type="checkbox" id="rev-amend-flag" />
<span data-i18n="deadlines.flag.rev_amend">Mit Antrag auf Patent&auml;nderung (R.49.2.a)</span>
</label>
</div>
<div className="date-field-row" id="rev-cci-flag-row" style="display:none">
<label className="date-label">
<input type="checkbox" id="rev-cci-flag" />
<span data-i18n="deadlines.flag.rev_cci">Mit Verletzungswiderklage (R.49.2.b)</span>
</label>
</div>
<button type="button" id="calculate-btn" className="calculate-btn" data-i18n="deadlines.calculate">
Fristen berechnen
</button>
</div>
</div>
<div className="wizard-step" id="step-3" style="display:none">
<h3 className="wizard-step-label">
<span className="step-number">3</span>
<span data-i18n="deadlines.step3">Ergebnis</span>
</h3>
<div className="fristen-view-toggle" id="fristen-view-toggle" role="radiogroup" aria-label="Ansicht">
<span className="fristen-view-label" data-i18n="deadlines.view.label">Ansicht:</span>
<label className="fristen-view-option">
<input type="radio" name="fristen-view" value="columns" checked />
<span data-i18n="deadlines.view.columns">Spalten</span>
</label>
<label className="fristen-view-option">
<input type="radio" name="fristen-view" value="timeline" />
<span data-i18n="deadlines.view.timeline">Zeitstrahl</span>
</label>
<label className="fristen-notes-option">
<input type="checkbox" id="fristen-notes-show" />
<span data-i18n="deadlines.notes.show">Hinweise anzeigen</span>
</label>
</div>
<div id="timeline-container">
</div>
<div className="fristen-result-actions">
<button type="button" id="fristen-save-cta" className="btn-primary btn-cta-lime" style="display:none" data-i18n="deadlines.save.cta">
Als Frist(en) speichern
</button>
<button type="button" id="fristen-print-btn" className="print-btn" style="display:none">
<svg className="print-btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<polyline points="6 9 6 2 18 2 18 9"></polyline>
<path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
<rect x="6" y="14" width="12" height="8"></rect>
</svg>
<span data-i18n="deadlines.print">Drucken</span>
</button>
</div>
</div>
<button type="button" id="reset-btn" className="reset-btn" style="display:none" data-i18n="deadlines.reset">
&larr; Neu berechnen
</button>
</div>
<div className="fristen-wizard mode-panel" id="mode-event-panel" data-mode="event" role="tabpanel" hidden>
<div className="wizard-step" id="event-step-1">
<h3 className="wizard-step-label">
<span className="step-number">1</span>
<span data-i18n="deadlines.event.step1">Trigger-Ereignis w&auml;hlen</span>
</h3>
<p className="wizard-step-hint" data-i18n="deadlines.event.step1.hint">
Welches Ereignis ist eingetreten? (z.B. Klageerhebung, Entscheidung des EPA, Zustellung einer Verf&uuml;gung)
</p>
<div className="event-picker-row">
<label htmlFor="event-search" className="visually-hidden" data-i18n="deadlines.event.search.label">Trigger-Ereignis suchen</label>
<input
type="search"
id="event-search"
className="event-search-input"
autocomplete="off"
data-i18n-placeholder="deadlines.event.search.placeholder"
placeholder="Tippe, um zu suchen&hellip;"
/>
<ul id="event-list" className="event-list" role="listbox" aria-label="Trigger-Ereignisse"></ul>
</div>
</div>
<div className="wizard-step" id="event-step-2" style="display:none">
<h3 className="wizard-step-label">
<span className="step-number">2</span>
<span data-i18n="deadlines.event.step2">Datum des Ereignisses</span>
</h3>
<div className="date-input-group">
<div className="date-field-row">
<label className="date-label" data-i18n="deadlines.event.selected">Gew&auml;hltes Ereignis:</label>
<span id="event-selected-name" className="trigger-event-name">&mdash;</span>
</div>
<div className="date-field-row">
<label htmlFor="event-date" className="date-label" data-i18n="deadlines.event.date">Eintrittsdatum:</label>
<input type="date" id="event-date" className="date-input" value={today} />
</div>
<button type="button" id="event-calculate-btn" className="calculate-btn" data-i18n="deadlines.event.calculate">
Folgefristen berechnen
</button>
</div>
</div>
<div className="wizard-step" id="event-step-3" style="display:none">
<h3 className="wizard-step-label">
<span className="step-number">3</span>
<span data-i18n="deadlines.event.step3">Folgefristen</span>
</h3>
<div id="event-results-container"></div>
<div className="fristen-result-actions">
<button type="button" id="event-print-btn" className="print-btn" style="display:none">
<svg className="print-btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<polyline points="6 9 6 2 18 2 18 9"></polyline>
<path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
<rect x="6" y="14" width="12" height="8"></rect>
</svg>
<span data-i18n="deadlines.print">Drucken</span>
</button>
</div>
</div>
<button type="button" id="event-reset-btn" className="reset-btn" style="display:none" data-i18n="deadlines.reset">
&larr; Neu berechnen
</button>
</div>
</div>{/* /pathway-a */}
</div>
</section>
</main>
<Footer />
<PaliadinWidget />
<script src="/assets/fristenrechner.js"></script>
</body>
</html>
);
}