feat(timeline): add live filter, actor chips, group headers, copy button, source toggle, count badge

- Live search/filter bar: filters events by keyword across event, actor, source_excerpt, date
- Actor filter chips: click to filter by actor, multi-select, teal active state
- Year/month group headers when sorted chronologically (── 2023 ──, Mar 2024 ──)
- Per-event copy button (hover-revealed 📋): copies "date · actor · event" to clipboard
- "Hide/show sources" toggle: collapses all source excerpts without re-rendering
- Count badge: "23 events · 3 actors · 2022–2025" above the list
- applyTimelineFilters() unifies sort + actor + text filters in one re-render pass
- CSV export now includes end_date column
- Reset all filter state on each new run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 15:46:59 +02:00
parent 59b39ff85b
commit ffcf887428
7 changed files with 807 additions and 49 deletions
+167
View File
@@ -1737,6 +1737,118 @@ p {
color: var(--ink);
}
/* Timeline count badge */
.timeline-count-badge {
font-size: 0.8rem;
color: var(--muted);
margin: 0 0 0.6rem;
font-variant-numeric: tabular-nums;
}
/* Actor filter chips */
.timeline-actor-chips {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-bottom: 0.75rem;
}
.timeline-actor-chip {
font-size: 0.75rem;
font-weight: 500;
padding: 0.2rem 0.65rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--bg);
color: var(--muted);
cursor: pointer;
transition: background 0.12s, color 0.12s, border-color 0.12s;
white-space: nowrap;
}
.timeline-actor-chip:hover { background: var(--soft-teal); color: var(--teal-dark); border-color: var(--teal); }
.timeline-actor-chip.is-active { background: var(--teal); color: #fff; border-color: var(--teal); }
/* Search + source toggle toolbar */
.timeline-toolbar {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.75rem;
}
.timeline-search {
flex: 1;
min-width: 0;
font-size: 0.83rem;
padding: 0.28rem 0.65rem;
border: 1px solid var(--line);
border-radius: 6px;
background: var(--bg);
color: var(--ink);
outline-offset: 2px;
}
.timeline-search:focus { border-color: var(--teal); outline: 2px solid color-mix(in srgb, var(--teal) 25%, transparent); }
.source-toggle-btn {
flex-shrink: 0;
font-size: 0.75rem;
font-weight: 500;
padding: 0.28rem 0.7rem;
border-radius: 6px;
border: 1px solid var(--line);
background: transparent;
color: var(--muted);
cursor: pointer;
white-space: nowrap;
transition: background 0.12s, color 0.12s;
}
.source-toggle-btn:hover { background: var(--bg); color: var(--ink); }
/* Year/month group headers */
.timeline-group-header {
list-style: none;
display: flex;
align-items: center;
gap: 0.6rem;
margin: 0.9rem 0 0.4rem;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
}
.timeline-group-header:first-child { margin-top: 0; }
.timeline-group-header::before,
.timeline-group-header::after {
content: '';
flex: 1;
height: 1px;
background: var(--line);
}
/* Per-event copy button */
.timeline-copy-btn {
margin-left: auto;
flex-shrink: 0;
font-size: 0.8rem;
line-height: 1;
padding: 0.15rem 0.35rem;
border: none;
background: transparent;
color: var(--muted);
cursor: pointer;
border-radius: 4px;
opacity: 0;
transition: opacity 0.1s, background 0.1s;
}
.timeline-item:hover .timeline-copy-btn { opacity: 1; }
.timeline-copy-btn:hover { background: var(--soft-teal); color: var(--teal-dark); }
.timeline-copy-btn:focus-visible { opacity: 1; outline: 2px solid var(--teal); outline-offset: 1px; }
/* Empty state when filters yield nothing */
.timeline-empty {
color: var(--muted);
font-style: italic;
padding: 0.5rem 0;
}
.date-type-badge {
display: inline-block;
font-size: 0.68rem;
@@ -5891,3 +6003,58 @@ body.lt-landing {
.adv-slice-hint button { font-size:.8rem; padding:2px 10px; border-radius:4px; cursor:pointer; }
#advSliceHintEnable { background:var(--teal); color:#fff; border:none; }
#advSliceHintDismiss { background:transparent; border:1px solid var(--line); color:var(--muted); }
/* === Advocate UX additions — F1/F3/F5/F6/F7 === */
/* Brief action buttons */
.adv-brief-actions { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.adv-result-actions { display:flex; align-items:center; gap:8px; justify-content:flex-end; margin-bottom:16px; }
/* Strength branch button */
.adv-strengths__item { display:flex; align-items:flex-start; gap:6px; }
.dr-strength-branch-btn { flex-shrink:0; font-size:.75rem; padding:1px 6px; border:1px solid var(--line); border-radius:3px; background:var(--bg); color:var(--teal); cursor:pointer; margin-top:1px; }
.dr-strength-branch-btn:hover { background:var(--soft-teal); }
/* Flip-brief bar */
.adv-flip-bar { display:flex; align-items:center; gap:10px; padding:8px 14px; margin-bottom:12px; background:var(--bg); border:1px solid var(--line); border-radius:6px; font-size:.85rem; flex-wrap:wrap; }
.adv-flip-bar__label { color:var(--muted); }
.adv-flip-bar__role { font-weight:600; color:var(--ink); }
.adv-flip-btn { margin-left:auto; font-size:.82rem; padding:3px 12px; border:1px solid var(--teal); border-radius:4px; background:var(--soft-teal); color:var(--teal-dark); cursor:pointer; }
.adv-flip-btn:hover { background:var(--teal); color:#fff; }
/* Sub-Q preview panel */
.adv-subq-preview { background:var(--bg); border:1px solid var(--line); border-radius:8px; padding:16px; margin:12px 0; }
.adv-subq-preview__head { margin:0 0 4px; font-size:.95rem; }
.adv-subq-preview-item { margin-bottom:14px; }
.adv-subq-preview-label { display:block; font-size:.8rem; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; margin-bottom:4px; }
.adv-subq-edit { width:100%; font-size:.88rem; padding:8px 10px; border:1px solid var(--line); border-radius:5px; background:var(--panel); color:var(--ink); resize:vertical; font-family:inherit; box-sizing:border-box; }
.adv-subq-edit:focus { outline:2px solid var(--teal); border-color:var(--teal); }
.adv-subq-rationale { font-size:.8rem; color:var(--muted); margin:3px 0 0; font-style:italic; }
.adv-subq-preview__actions { display:flex; gap:10px; margin-top:12px; flex-wrap:wrap; }
.adv-subq-preview__actions button { font-size:.85rem; padding:5px 16px; border-radius:5px; cursor:pointer; }
#advRunWithAngles { background:var(--teal); color:#fff; border:none; }
#advRunWithAngles:hover { background:var(--teal-dark); }
.adv-discard-btn { background:transparent; border:1px solid var(--line); color:var(--muted); }
/* Form footer with two buttons */
.form-footer__btns { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.adv-preview-btn { font-size:.82rem; padding:5px 14px; border:1px solid var(--line); border-radius:5px; background:var(--bg); color:var(--muted); cursor:pointer; }
.adv-preview-btn:hover { border-color:var(--teal); color:var(--teal); background:var(--soft-teal); }
/* Print styles */
@media print {
.tool-rail, .reasoning-panel, .topbar, .tool-form,
.adv-result-actions, .adv-flip-bar, .adv-brief-actions,
.dr-branch-btn, .dr-strength-branch-btn,
.adv-restore-banner, .adv-subq-preview,
.dr-source-modal { display:none !important; }
.workspace { display:block !important; }
.tool-panel { max-width:100%; border:none; box-shadow:none; padding:0; }
.results { padding:0; }
.adv-banner { border:1px solid #000; padding:8px 12px; margin-bottom:12px; }
details { display:block !important; }
details > * { display:block !important; }
.dr-result-block { border:1px solid #ccc; margin-bottom:12px; padding:12px; break-inside:avoid; }
.dr-source-card { break-inside:avoid; }
.dr-brief { line-height:1.75; }
summary { display:none; }
}