Files
paliad/frontend/src/styles/global.css
m f79dbdba4a fix(t-paliad-120): /events Termin-Typ chip — dark-mode text invisible
Add dark-mode rules for `.termin-type-chip.termin-type-XYZ`. Without them
the chip inherited the bare `.termin-type-XYZ` swatch rule (line 8407+),
which intentionally paints text the same colour as the background for
the dot/border-left swatch use case → text invisible in the chip context.

Mirror the existing badge dark rules (lines 8413-8415) so chip and badge
share the same colour family. Adds the missing `consultation` variant for
the chip (badge consultation dark is also missing but out of scope).
2026-05-04 18:25:59 +02:00

8975 lines
203 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Paliad — Patent Knowledge platform.
Firm name is rendered at runtime from FIRM_NAME (see internal/branding +
frontend/src/branding.ts). Default: "HLC". */
:root {
/* Brand palette (4 colors). Token names use the --hlc- prefix as a
stable internal identifier — not a firm-specific reference; renaming
the prefix would touch every CSS rule for no user-visible benefit.
Lime + midnight are the primary pair. Cyan + cream are supporting. */
--hlc-lime: #BFF355;
--hlc-midnight: #002236;
--hlc-cyan: #9FE3D9;
--hlc-cream: #EEE5E1;
/* Channel tokens enable rgb(var(--*-rgb) / a) for tints without
hard-coded rgba values elsewhere. */
--hlc-lime-rgb: 191 243 85;
--hlc-midnight-rgb: 0 34 54;
--hlc-cyan-rgb: 159 227 217;
--hlc-cream-rgb: 238 229 225;
/* Surface + semantic tokens — re-pointed onto the brand palette.
Light mode is the default. Dark mode overrides every token below
in the :root[data-theme="dark"] block further down. Components
that read these tokens (instead of palette/hex literals) get the
theme swap for free. */
--color-bg: var(--hlc-cream);
--color-bg-subtle: #f7f3f0; /* slightly off-cream for table headers / soft surfaces */
--color-bg-lime-tint: rgb(var(--hlc-lime-rgb) / 0.10);
--color-surface: #ffffff; /* cards stay white for contrast */
--color-surface-2: #fafafa; /* slightly raised surface (alt rows, code blocks) */
--color-surface-muted: #f3f4f6; /* nested muted surfaces (chips, soft fills) */
/* Form inputs render on white in light mode (m: 2026-04-30 — the
cream `--color-bg` made inputs feel like background blocks, not
wells). In dark mode we drop slightly *below* the card surface
so the input still reads as a depressed well rather than merging
into the card panel. */
--color-input-bg: #ffffff;
--color-text: var(--hlc-midnight);
--color-text-muted: #5a6573;
--color-text-subtle: #6b7280; /* third-tier text (placeholders, helper) */
--color-accent: var(--hlc-lime);
--color-accent-light: #d8f78a; /* lighter lime for hover */
--color-accent-dark: var(--hlc-midnight); /* foreground on lime — WCAG AA */
/* Accent text colour. Lime fails WCAG on the cream/white BGs we use
in light mode, so accent emphasis in body copy is rendered in
midnight here. Dark-mode flips this to lime (lime on midnight is
WCAG AA); the .sidebar scope below already keeps lime today since
the sidebar lives on a midnight BG, so it's a no-op there. */
--color-accent-fg: var(--hlc-midnight);
--color-border: #e1dcd6; /* derived from cream, neutral warm */
--color-border-strong: #d4d4d8; /* stronger border for tab/select boundaries */
--color-hero-bg: var(--hlc-midnight);
--color-hero-text: #ffffff;
/* Overlay tints for hover/stripe/divider — opacities tuned so they read
on cream backgrounds. Dark mode swaps to white-channel alphas. */
--color-overlay-faint: rgba(0, 0, 0, 0.04);
--color-overlay-subtle: rgba(0, 0, 0, 0.06);
--color-overlay-strong: rgba(0, 0, 0, 0.10);
--color-overlay-modal: rgba(0, 0, 0, 0.4); /* modal/drawer scrim */
/* Status palette — five buckets (red/amber/green/blue/neutral) shared
across dashboard cards, frist-due-chips, agenda urgency, termin
badges, login forms. Light values match the existing pastel-on-dark
Tailwind-100/700 pattern; dark values invert to a tinted alpha
backdrop with bright foreground for AA contrast on dark surfaces. */
--status-red-bg: #fee2e2;
--status-red-fg: #b91c1c;
--status-red-border: #fecaca;
--status-amber-bg: #fef3c7;
--status-amber-fg: #92400e;
--status-amber-fg-2: #b45309;
--status-amber-border: #fcd34d;
--status-green-bg: #dcfce7;
--status-green-fg: #166534;
--status-green-border: #bbf7d0;
--status-green-soft-bg: #ecfccb;
--status-green-soft-fg: #365314;
--status-blue-bg: #dbeafe;
--status-blue-fg: #1e40af;
--status-blue-fg-2: #2563eb;
--status-blue-soft-bg: #eef2ff;
--status-blue-soft-fg: #4338ca;
--status-neutral-bg: #f3f4f6;
--status-neutral-fg: #6b7280;
--status-neutral-fg-2: #475569;
--status-neutral-fg-3: #374151;
/* Project-tree icon palette — five identity colours by node type.
Light values are saturated-mid; dark values are brightened pastels
so they remain legible on midnight without losing identity. */
--tree-icon-client: #4338ca;
--tree-icon-litigation: #9d174d;
--tree-icon-patent: #075985;
--tree-icon-case: #92400e;
--tree-icon-project: #166534;
/* Sidebar — light mode harmonises with the cream/white body palette
(t-paliad-104). Surface lifts one step from the body cream so the
sidebar reads as part of the same design language, not a separate
midnight panel. The active item's text colour is midnight (full
contrast against the muted-grey inactive items); the brand-lime
accent stripe on .sidebar-item.active::after stays via --color-accent
directly, so the lime brand cue is preserved in both themes.
Dark mode (block below) restores the original midnight + cream + lime
palette since that already reads as one piece. */
--sidebar-bg: var(--color-bg-subtle);
--sidebar-text: var(--color-text);
--sidebar-text-muted: var(--color-text-muted);
--sidebar-text-active: var(--hlc-midnight);
--sidebar-border: var(--color-border);
--sidebar-hover-bg: rgb(var(--hlc-midnight-rgb) / 0.05);
--sidebar-input-bg: rgb(var(--hlc-midnight-rgb) / 0.05);
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--font-mono: "JetBrains Mono", "Fira Code", monospace;
--radius: 8px;
--shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.15);
--shadow-xl: 0 20px 60px rgba(0, 0, 0, 0.15);
/* Sidebar scrollbar — themed thin scrollbar so the auto-overflow
inside the nav reads as part of the sidebar surface. Light mode
uses midnight-channel alpha against the cream sidebar; the dark
block below switches to cream-channel alpha against midnight. */
--sidebar-scrollbar-thumb: rgb(var(--hlc-midnight-rgb) / 0.18);
--sidebar-scrollbar-thumb-hover: rgb(var(--hlc-midnight-rgb) / 0.32);
--sidebar-scrollbar-width: 6px;
--max-width: 1080px;
--sidebar-collapsed: 64px;
--sidebar-expanded: 240px;
/* User-adjustable width for the expanded/pinned desktop sidebar.
Defaults to --sidebar-expanded; sidebar.ts overrides on
document.documentElement when the user drags the resize handle
and persists the value to localStorage. Mobile drawer keeps the
fixed --sidebar-expanded width. */
--sidebar-width: 240px;
--bottom-nav-height: 56px;
}
/* Dark mode (m/paliad#2). Activated by the pre-paint inline script in
PWAHead.tsx setting <html data-theme="dark"> from localStorage[paliad-theme]
("dark" | "auto"+system-prefers-dark). The body palette flips to
midnight-bg + cream-fg, and accent text flips back to lime (passes WCAG
AA on midnight). Status pills, dashboard cards, and tree-icon colours
are tinted-alpha-on-dark for readability.
Sidebar (t-paliad-104, reversing t-paliad-083): the sidebar now flips
with the theme. Light mode keeps the sidebar on a cream-tinted surface
so it reads as part of the page; dark mode restores the original
midnight + cream-text + lime-active palette below — that combo already
reads as one piece on a midnight body. */
:root[data-theme="dark"] {
--color-bg: var(--hlc-midnight);
--color-bg-subtle: #00304a; /* slightly raised for table headers */
--color-bg-lime-tint: rgb(var(--hlc-lime-rgb) / 0.12);
--color-surface: #0a3047; /* card surface — distinct from body */
--color-surface-2: #0d3a55; /* one step further raised */
--color-surface-muted: rgb(var(--hlc-cream-rgb) / 0.05);
/* Input wells render BELOW card surface so the depression reads. */
--color-input-bg: #00192a;
--color-text: var(--hlc-cream);
--color-text-muted: rgb(var(--hlc-cream-rgb) / 0.66);
--color-text-subtle: rgb(var(--hlc-cream-rgb) / 0.50);
--color-accent-light: #9bd926; /* darker lime for hover on dark */
--color-accent-dark: var(--hlc-midnight); /* foreground on lime stays midnight */
--color-accent-fg: var(--hlc-lime); /* lime text on midnight is AA */
--color-border: rgb(var(--hlc-cream-rgb) / 0.12);
--color-border-strong: rgb(var(--hlc-cream-rgb) / 0.22);
--color-hero-bg: #0a3047; /* hero panel one step lighter than bg */
--color-hero-text: var(--hlc-cream);
--color-overlay-faint: rgba(255, 255, 255, 0.04);
--color-overlay-subtle: rgba(255, 255, 255, 0.07);
--color-overlay-strong: rgba(255, 255, 255, 0.12);
--color-overlay-modal: rgba(0, 0, 0, 0.65);
--shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45);
--shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.55);
--shadow-xl: 0 20px 60px rgba(0, 0, 0, 0.6);
/* Status palette — alpha-tinted backdrops so the pill reads as a
coloured swatch rather than a saturated rectangle. Foregrounds are
the Tailwind 300-shades for AA contrast on the alpha bg. */
--status-red-bg: rgb(239 68 68 / 0.18);
--status-red-fg: #fca5a5;
--status-red-border: rgb(239 68 68 / 0.35);
--status-amber-bg: rgb(245 158 11 / 0.18);
--status-amber-fg: #fcd34d;
--status-amber-fg-2: #fbbf24;
--status-amber-border: rgb(245 158 11 / 0.35);
--status-green-bg: rgb(34 197 94 / 0.18);
--status-green-fg: #86efac;
--status-green-border: rgb(34 197 94 / 0.35);
--status-green-soft-bg: rgb(132 204 22 / 0.18);
--status-green-soft-fg: #bef264;
--status-blue-bg: rgb(59 130 246 / 0.18);
--status-blue-fg: #93c5fd;
--status-blue-fg-2: #60a5fa;
--status-blue-soft-bg: rgb(99 102 241 / 0.18);
--status-blue-soft-fg: #a5b4fc;
--status-neutral-bg: rgb(var(--hlc-cream-rgb) / 0.08);
--status-neutral-fg: rgb(var(--hlc-cream-rgb) / 0.66);
--status-neutral-fg-2: rgb(var(--hlc-cream-rgb) / 0.55);
--status-neutral-fg-3: rgb(var(--hlc-cream-rgb) / 0.78);
/* Tree-icon colours — brighter shades so they remain identifiable
on midnight without losing their colour identity. */
--tree-icon-client: #818cf8;
--tree-icon-litigation: #f472b6;
--tree-icon-patent: #38bdf8;
--tree-icon-case: #fbbf24;
--tree-icon-project: #86efac;
/* Sidebar — restore the original midnight + cream + lime palette here
(the light-mode defaults harmonise with the cream body; dark mode
wants the high-contrast midnight column it had before t-paliad-104). */
--sidebar-bg: var(--hlc-midnight);
--sidebar-text: var(--hlc-cream);
--sidebar-text-muted: rgb(var(--hlc-cream-rgb) / 0.66);
--sidebar-text-active: var(--hlc-lime);
--sidebar-border: rgb(var(--hlc-cream-rgb) / 0.12);
--sidebar-hover-bg: rgb(var(--hlc-cream-rgb) / 0.08);
--sidebar-input-bg: rgb(var(--hlc-cream-rgb) / 0.08);
--sidebar-scrollbar-thumb: rgb(var(--hlc-cream-rgb) / 0.20);
--sidebar-scrollbar-thumb-hover: rgb(var(--hlc-cream-rgb) / 0.35);
}
/* Smooth the body-background swap so theme toggles don't snap. Surface
and text colors are read by individual elements and inherit a similar
transition where they apply their own background/color shorthand. */
:root {
color-scheme: light;
}
:root[data-theme="dark"] {
color-scheme: dark;
}
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
font-family: var(--font-sans);
color: var(--color-text);
background: var(--color-bg);
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.container {
max-width: var(--max-width);
margin: 0 auto;
padding: 0 1.5rem;
}
/* --- Header --- */
.header {
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 10;
}
.nav {
display: flex;
align-items: center;
justify-content: space-between;
height: 3.5rem;
}
.logo {
display: flex;
align-items: baseline;
gap: 0.15rem;
text-decoration: none;
font-weight: 600;
font-size: 1.15rem;
letter-spacing: -0.02em;
color: var(--color-text);
}
.logo-mark {
font-family: var(--font-mono);
color: var(--color-accent-fg);
font-weight: 700;
font-size: 1.3rem;
}
.nav-right {
display: flex;
align-items: center;
gap: 1.25rem;
}
.nav-logout {
font-size: 0.8rem;
color: var(--color-text-muted);
text-decoration: none;
}
.nav-logout:hover {
color: var(--color-accent-fg);
}
.nav-lang {
font-size: 0.8rem;
letter-spacing: 0.05em;
color: var(--color-text-muted);
user-select: none;
}
.lang-btn {
background: none;
border: none;
font-family: inherit;
font-size: inherit;
letter-spacing: inherit;
cursor: pointer;
padding: 0;
color: inherit;
}
.lang-btn:hover {
color: var(--color-accent-fg);
}
.lang-active {
color: var(--color-accent-fg);
font-weight: 600;
cursor: default;
}
.lang-sep {
margin: 0 0.25rem;
}
.timeline-trigger-date {
font-weight: 400;
color: var(--color-text-muted);
font-size: 0.85rem;
}
/* --- Hero --- */
.hero {
background: var(--color-hero-bg);
color: var(--color-hero-text);
padding: 5rem 0 4.5rem;
}
.hero h1 {
font-size: 2.75rem;
font-weight: 700;
line-height: 1.15;
letter-spacing: -0.03em;
}
.hero-accent {
font-weight: 400;
opacity: 0.85;
}
.hero-sub {
margin-top: 1.25rem;
font-size: 1.1rem;
line-height: 1.7;
opacity: 0.9;
max-width: 560px;
}
/* --- Card Grid --- */
.sections {
padding: 4rem 0;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 2rem;
transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.card:hover {
box-shadow: var(--shadow-md);
border-color: var(--color-accent-light);
}
.card-icon {
width: 2.25rem;
height: 2.25rem;
color: var(--color-accent-fg);
margin-bottom: 1rem;
}
.card-icon svg {
width: 100%;
height: 100%;
}
.card h2 {
font-size: 1.15rem;
font-weight: 600;
margin-bottom: 0.5rem;
letter-spacing: -0.01em;
}
.card p {
color: var(--color-text-muted);
font-size: 0.92rem;
line-height: 1.6;
}
.section-heading {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin-bottom: 1rem;
}
.grid-2 {
grid-template-columns: repeat(2, 1fr);
}
.card-link {
text-decoration: none;
color: inherit;
display: block;
}
.card-link:hover {
border-color: var(--color-accent);
}
/* --- Offices --- */
.offices {
padding: 0 0 4rem;
}
.offices h3 {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin-bottom: 1rem;
}
.office-list {
display: flex;
gap: 2rem;
flex-wrap: wrap;
}
.office-list span {
font-size: 1rem;
font-weight: 500;
color: var(--color-text);
position: relative;
padding-left: 0.85rem;
}
.office-list span::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--color-accent);
}
/* --- Footer --- */
.footer {
border-top: 1px solid var(--color-border);
padding: 1.5rem 0;
margin-top: auto;
}
.footer p {
font-size: 0.8rem;
color: var(--color-text-muted);
text-align: center;
}
/* --- Login --- */
.login-main {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 3rem 1.5rem;
}
.login-card {
width: 100%;
max-width: 400px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 2.5rem;
box-shadow: var(--shadow-md);
}
.login-tabs {
display: flex;
margin-bottom: 1.75rem;
border-bottom: 1px solid var(--color-border);
}
.login-tab {
flex: 1;
padding: 0.6rem 0;
background: none;
border: none;
border-bottom: 2px solid transparent;
font-family: var(--font-sans);
font-size: 0.9rem;
font-weight: 500;
color: var(--color-text-muted);
cursor: pointer;
transition: color 0.15s ease, border-color 0.15s ease;
}
.login-tab:hover {
color: var(--color-text);
}
.login-tab.active {
/* Canonical active-tab pattern (F-20) — lime underline + midnight text +
600 weight. Matches .entity-tab.active and .gebuehren-tab.active. */
color: var(--color-text);
border-bottom-color: var(--hlc-lime);
font-weight: 600;
}
.login-error {
background: var(--status-red-bg);
color: var(--status-red-fg);
border: 1px solid var(--status-red-border);
border-radius: var(--radius);
padding: 0.75rem 1rem;
font-size: 0.85rem;
margin-bottom: 1.25rem;
line-height: 1.5;
}
.login-success {
background: var(--status-green-bg);
color: var(--status-green-fg);
border: 1px solid var(--status-green-border);
border-radius: var(--radius);
padding: 0.75rem 1rem;
font-size: 0.85rem;
margin-bottom: 1.25rem;
line-height: 1.5;
}
.login-form {
display: flex;
flex-direction: column;
}
.login-label {
font-size: 0.85rem;
font-weight: 500;
color: var(--color-text);
margin-bottom: 0.35rem;
margin-top: 0.75rem;
}
.login-label:first-child {
margin-top: 0;
}
.login-input {
font-family: var(--font-sans);
font-size: 0.92rem;
padding: 0.6rem 0.8rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
outline: none;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
color: var(--color-text);
background: var(--color-input-bg);
}
.login-input:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
.login-input::placeholder {
color: var(--color-text-muted);
opacity: 0.6;
}
.login-button {
font-family: var(--font-sans);
font-size: 0.92rem;
font-weight: 600;
padding: 0.65rem 1rem;
margin-top: 1.25rem;
border: none;
border-radius: var(--radius);
background: var(--color-accent);
color: var(--color-accent-dark);
cursor: pointer;
transition: background 0.15s ease;
}
.login-button:hover {
background: var(--color-accent-light);
}
.login-hint {
font-size: 0.78rem;
color: var(--color-text-muted);
text-align: center;
margin-top: 1.5rem;
}
/* --- Onboarding (first-login profile capture) --- */
.onboarding-card {
max-width: 460px;
}
.onboarding-heading {
font-size: 1.5rem;
font-weight: 600;
margin: 0 0 0.5rem;
color: var(--color-text);
}
.onboarding-lede {
font-size: 0.9rem;
color: var(--color-text-muted);
line-height: 1.5;
margin: 0 0 1.5rem;
}
.login-label-optional {
font-weight: 400;
color: var(--color-text-muted);
margin-left: 0.25rem;
}
/* --- Nav Links --- */
.nav-link {
font-size: 0.8rem;
color: var(--color-text-muted);
text-decoration: none;
transition: color 0.15s ease;
}
.nav-link:hover {
color: var(--color-accent-fg);
}
/* --- Sidebar --- */
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebar-collapsed);
background: var(--sidebar-bg);
color: var(--sidebar-text);
border-right: 1px solid var(--sidebar-border);
z-index: 40;
display: flex;
flex-direction: column;
overflow: hidden;
transition: width 150ms ease;
/* Accent text inside the sidebar tracks --sidebar-text-active so it
stays legible against the sidebar surface in either theme. Light
mode: midnight on cream-tint (no-op vs the root default). Dark
mode: lime on midnight (matches root). */
--color-accent-fg: var(--sidebar-text-active);
}
.sidebar.expanded,
.sidebar.pinned {
width: var(--sidebar-width);
}
.sidebar.resizing,
.sidebar.resizing .sidebar-label,
.has-sidebar.sidebar-resizing {
transition: none !important;
}
.sidebar-header {
display: flex;
align-items: center;
height: 3.5rem;
border-bottom: 1px solid var(--sidebar-border);
flex-shrink: 0;
overflow: hidden;
}
.sidebar-logo {
display: flex;
align-items: center;
text-decoration: none;
color: var(--sidebar-text);
flex: 1;
min-width: 0;
height: 100%;
}
.sidebar-logo .logo-text {
font-weight: 600;
font-size: 1.15rem;
letter-spacing: -0.02em;
}
.sidebar-pin {
background: none;
border: none;
color: var(--sidebar-text-muted);
cursor: pointer;
padding: 0.35rem;
margin-right: 0.75rem;
border-radius: 4px;
flex-shrink: 0;
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease, color 150ms ease, background 150ms ease;
}
.sidebar.expanded .sidebar-pin,
.sidebar.pinned .sidebar-pin {
opacity: 1;
pointer-events: auto;
}
.sidebar-pin:hover {
color: var(--sidebar-text-active);
background: var(--sidebar-hover-bg);
}
.sidebar-pin svg {
width: 16px;
height: 16px;
display: block;
}
.sidebar.pinned .sidebar-pin {
color: var(--sidebar-text-active);
}
/* Vertical drag-strip on the sidebar's right edge. Only meaningful when
the sidebar is wide enough to show labels (expanded or pinned), so
collapsed/icon-rail state hides it. Positioned slightly off-edge for
easier hit; pointer-events stay enabled only when visible. */
.sidebar-resize-handle {
position: absolute;
top: 0;
right: -3px;
width: 6px;
height: 100%;
cursor: col-resize;
z-index: 41;
background: transparent;
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease, background 150ms ease;
user-select: none;
touch-action: none;
}
.sidebar.expanded .sidebar-resize-handle,
.sidebar.pinned .sidebar-resize-handle {
opacity: 1;
pointer-events: auto;
}
.sidebar-resize-handle:hover,
.sidebar.resizing .sidebar-resize-handle {
background: var(--color-accent);
opacity: 0.5;
}
.sidebar-nav {
display: flex;
flex-direction: column;
padding: 0.5rem 0;
flex: 1 1 auto;
overflow-x: hidden;
overflow-y: auto;
min-height: 0;
/* Themed thin scrollbar — cream-channel alpha so it reads as part of
the midnight sidebar surface in both light and dark mode. The
gutter is reserved (`stable`) so the sidebar's icon column doesn't
shift left when the scrollbar appears (admin nav can be tall
enough to overflow on shorter viewports). */
scrollbar-width: thin;
scrollbar-color: var(--sidebar-scrollbar-thumb) transparent;
scrollbar-gutter: stable;
}
/* WebKit fallback (Safari, older Chromium): explicit thumb styling. The
thumb width matches --sidebar-scrollbar-width so the visual gutter is
the same on Firefox (`scrollbar-width: thin`) and Webkit. */
.sidebar-nav::-webkit-scrollbar {
width: var(--sidebar-scrollbar-width);
}
.sidebar-nav::-webkit-scrollbar-track {
background: transparent;
}
.sidebar-nav::-webkit-scrollbar-thumb {
background: var(--sidebar-scrollbar-thumb);
border-radius: 3px;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover {
background: var(--sidebar-scrollbar-thumb-hover);
}
.sidebar-item {
display: flex;
align-items: center;
min-height: 2.5rem;
color: var(--sidebar-text-muted);
text-decoration: none;
font-size: 0.85rem;
font-weight: 500;
position: relative;
transition: color 150ms ease, background 150ms ease;
border: none;
background: none;
cursor: pointer;
font-family: var(--font-sans);
width: 100%;
text-align: left;
padding: 0;
}
.sidebar-item:hover {
color: var(--sidebar-text);
background: var(--sidebar-hover-bg);
}
.sidebar-item.active {
color: var(--sidebar-text-active);
}
.sidebar-item.active::after {
content: "";
position: absolute;
left: 0;
top: 4px;
bottom: 4px;
width: 3px;
/* Brand lime in both themes — keeps the active cue visually anchored
even when the active text colour flips between midnight (light) and
lime (dark). */
background: var(--color-accent);
border-radius: 0 2px 2px 0;
}
.sidebar-icon {
/* Width accounts for the reserved scrollbar gutter on .sidebar-nav so
icons stay visually centered inside the 64px collapsed rail rather
than drifting left when the scrollbar appears (or appearing left of
center even when it doesn't, since `scrollbar-gutter: stable`
always reserves the gutter). The other sidebar items (header,
bottom, hamburger) sit outside .sidebar-nav and are unaffected. */
width: calc(var(--sidebar-collapsed) - var(--sidebar-scrollbar-width));
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.sidebar-icon svg {
width: 20px;
height: 20px;
}
.sidebar-label {
opacity: 0;
white-space: nowrap;
transition: opacity 150ms ease;
overflow: hidden;
padding-right: 1rem;
}
.sidebar.expanded .sidebar-label,
.sidebar.pinned .sidebar-label {
opacity: 1;
}
.sidebar-spacer {
flex: 1;
}
.sidebar-bottom {
display: flex;
flex-direction: column;
padding: 0.5rem 0;
border-top: 1px solid var(--sidebar-border);
flex-shrink: 0;
}
.sidebar-lang-item {
cursor: default;
}
.sidebar-lang-item:hover {
background: transparent;
color: var(--sidebar-text-muted);
}
.sidebar-lang {
display: flex;
align-items: center;
}
.sidebar-hamburger {
display: none;
position: fixed;
bottom: 1.5rem;
left: 1.5rem;
z-index: 50;
width: 48px;
height: 48px;
border-radius: 50%;
border: none;
background: var(--color-accent);
color: var(--color-accent-dark);
cursor: pointer;
align-items: center;
justify-content: center;
box-shadow: var(--shadow-md);
transition: background 150ms ease;
}
.sidebar-hamburger:hover {
background: var(--color-accent-light);
}
.sidebar-hamburger svg {
width: 22px;
height: 22px;
}
.sidebar-overlay {
display: none;
}
/* Layout: pages with sidebar */
.has-sidebar {
padding-left: var(--sidebar-collapsed);
transition: padding-left 150ms ease;
}
/* Two selectors apply the pinned padding because the pre-paint inline
script in PWAHead.tsx sets `<html class="sidebar-pinned">` (body
doesn't exist yet at that point), while the runtime sidebar.ts later
adds `sidebar-pinned` to `<body>` too. Either source is sufficient
and they don't conflict. Keeping both keeps the legacy DOM contract
intact (sidebar.ts continues to manage the body class). */
.has-sidebar.sidebar-pinned,
:root.sidebar-pinned .has-sidebar {
padding-left: var(--sidebar-width);
}
.has-sidebar .tool-results {
top: 1.5rem;
}
.no-scroll {
overflow: hidden;
}
/* --- Tool Pages --- */
.tool-page {
padding: 2rem 0 4rem;
}
.tool-header {
margin-bottom: 2rem;
}
.tool-header h1 {
font-size: 1.75rem;
font-weight: 700;
letter-spacing: -0.02em;
}
.tool-subtitle {
color: var(--color-text-muted);
font-size: 0.92rem;
margin-top: 0.5rem;
line-height: 1.6;
}
.tool-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: start;
}
.tool-input {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.tool-results {
position: sticky;
top: 4.5rem;
}
/* Input sections */
.input-section h3 {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
margin-bottom: 0.75rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--color-border);
}
.input-section select {
font-family: var(--font-sans);
font-size: 0.88rem;
padding: 0.45rem 0.7rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-input-bg);
color: var(--color-text);
outline: none;
cursor: pointer;
}
.input-section select:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
/* Streitwert */
.streitwert-group {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.streitwert-input-row {
display: flex;
align-items: center;
gap: 0.5rem;
}
.streitwert-prefix {
font-size: 0.88rem;
font-weight: 500;
color: var(--color-text-muted);
}
.streitwert-field {
font-family: var(--font-mono);
font-size: 1.25rem;
font-weight: 600;
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
outline: none;
width: 100%;
max-width: 240px;
}
.streitwert-field:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 4px;
border-radius: 2px;
background: var(--color-border);
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--color-accent);
cursor: pointer;
border: 2px solid var(--color-surface);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
input[type="range"]::-moz-range-thumb {
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--color-accent);
cursor: pointer;
border: 2px solid var(--color-surface);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.streitwert-presets {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
}
.streitwert-presets button {
font-family: var(--font-mono);
font-size: 0.75rem;
font-weight: 500;
padding: 0.3rem 0.6rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.15s ease;
}
.streitwert-presets button:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.streitwert-presets button.active {
background: var(--color-accent);
border-color: var(--color-accent);
color: var(--color-accent-dark);
}
/* Instance cards */
.instance-card {
border: 1px solid var(--color-border);
border-radius: var(--radius);
margin-bottom: 0.5rem;
transition: border-color 0.15s ease;
}
.instance-card.enabled {
border-color: var(--color-accent-light);
}
.instance-header {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.65rem 0.85rem;
cursor: pointer;
}
.instance-header input[type="checkbox"] {
accent-color: var(--color-accent);
width: 16px;
height: 16px;
cursor: pointer;
}
.instance-header label {
flex: 1;
font-size: 0.88rem;
cursor: pointer;
display: flex;
align-items: baseline;
gap: 0.5rem;
}
.instance-header label strong {
font-weight: 500;
}
.instance-toggle {
background: none;
border: none;
color: var(--color-text-muted);
font-size: 0.75rem;
cursor: pointer;
padding: 0.2rem;
}
.instance-details {
padding: 0.75rem 0.85rem;
border-top: 1px solid var(--color-border);
background: var(--color-bg);
}
.instance-fields {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.field-row {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.85rem;
}
.field-row label {
display: flex;
align-items: center;
gap: 0.4rem;
color: var(--color-text);
}
.field-row select {
font-size: 0.82rem;
padding: 0.3rem 0.5rem;
}
.field-row input[type="checkbox"] {
accent-color: var(--color-accent);
}
/* Results panel */
.result-card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 1.5rem;
box-shadow: var(--shadow);
}
.result-total-section {
text-align: center;
padding-bottom: 1.25rem;
margin-bottom: 1.25rem;
border-bottom: 2px solid var(--color-accent);
}
.result-total-label {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
margin-bottom: 0.25rem;
}
.result-total {
font-family: var(--font-mono);
font-size: 1.6rem;
font-weight: 700;
color: var(--color-accent-fg);
}
.result-empty {
text-align: center;
color: var(--color-text-muted);
font-size: 0.88rem;
padding: 2rem 0;
}
.result-summary {
padding-bottom: 1rem;
margin-bottom: 1rem;
border-bottom: 1px solid var(--color-border);
}
.result-summary-row {
display: flex;
justify-content: space-between;
font-size: 0.85rem;
padding: 0.2rem 0;
color: var(--color-text-muted);
}
.result-section {
padding: 0.85rem 0;
border-bottom: 1px solid var(--color-border);
}
.result-section:last-child {
border-bottom: none;
}
.result-section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.result-section-label {
font-size: 0.88rem;
font-weight: 600;
}
.result-section-total {
font-family: var(--font-mono);
font-size: 0.92rem;
font-weight: 600;
color: var(--color-accent-fg);
}
.result-detail-row {
display: flex;
justify-content: space-between;
font-size: 0.82rem;
padding: 0.15rem 0;
color: var(--color-text-muted);
}
.result-detail-sum {
font-weight: 600;
color: var(--color-text);
padding-top: 0.25rem;
border-top: 1px dotted var(--color-border);
margin-top: 0.15rem;
}
.result-attorney-detail {
margin: 0.4rem 0;
padding-left: 0.5rem;
border-left: 2px solid var(--color-border);
}
.result-detail-label {
font-size: 0.8rem;
font-weight: 500;
color: var(--color-text);
margin-bottom: 0.15rem;
}
.result-detail-note {
font-size: 0.78rem;
color: var(--color-text-muted);
font-style: italic;
margin-top: 0.25rem;
}
/* Result action buttons */
.result-actions {
display: flex;
gap: 0.5rem;
margin-top: 1rem;
}
.result-action-btn {
font-family: var(--font-sans);
font-size: 0.82rem;
font-weight: 500;
padding: 0.5rem 1rem;
flex: 1;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.15s ease;
text-align: center;
}
.result-action-btn:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.result-action-btn--accent {
background: var(--color-accent);
border-color: var(--color-accent);
color: var(--color-accent-dark);
}
.result-action-btn--accent:hover {
background: var(--color-accent-light);
border-color: var(--color-accent-light);
color: var(--color-accent-dark);
}
.result-action-btn.copied {
background: var(--color-accent);
border-color: var(--color-accent);
color: var(--color-accent-dark);
}
/* Scenario comparison */
.comparison-container {
margin-top: 2rem;
}
.comparison-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.comparison-header h2 {
font-size: 1.25rem;
font-weight: 700;
}
.comparison-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
align-items: start;
}
.comparison-col-title {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
margin-bottom: 0.75rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--color-border);
}
.comparison-diff {
margin-top: 1.5rem;
}
.comparison-diff-card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 1.25rem;
text-align: center;
}
.comparison-diff-card.diff-decrease {
border-color: var(--color-accent);
background: rgb(var(--hlc-lime-rgb) / 0.04);
}
.comparison-diff-card.diff-increase {
border-color: #e53e3e;
background: rgba(229, 62, 62, 0.04);
}
.comparison-diff-label {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
margin-bottom: 0.25rem;
}
.comparison-diff-value {
font-family: var(--font-mono);
font-size: 1.4rem;
font-weight: 700;
}
.diff-decrease .comparison-diff-value {
color: var(--color-accent-fg);
}
.diff-increase .comparison-diff-value {
color: #e53e3e;
}
.diff-neutral .comparison-diff-value {
color: var(--color-text-muted);
}
.comparison-diff-pct {
font-family: var(--font-mono);
font-size: 0.88rem;
color: var(--color-text-muted);
margin-bottom: 0.75rem;
}
.comparison-diff-detail {
padding-top: 0.75rem;
border-top: 1px solid var(--color-border);
text-align: left;
}
/* Print header/footer (hidden on screen) */
.print-header,
.print-footer {
display: none;
}
/* --- Fristenrechner --- */
.fristen-mode-tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid var(--color-border);
}
.mode-tab {
background: transparent;
border: none;
border-bottom: 2px solid transparent;
padding: 0.6rem 1rem;
font-size: 0.95rem;
font-weight: 500;
color: var(--color-text-muted);
cursor: pointer;
margin-bottom: -1px;
}
.mode-tab:hover {
color: var(--color-text);
}
.mode-tab.is-active {
color: var(--color-text);
border-bottom-color: var(--color-accent);
font-weight: 600;
}
.mode-panel[hidden] {
display: none;
}
.fristen-wizard {
max-width: 720px;
}
/* --- Event mode (Was kommt nach…) --- */
.wizard-step-hint {
color: var(--color-text-muted);
font-size: 0.9rem;
margin: -0.4rem 0 1rem;
}
.event-picker-row {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.event-search-input {
width: 100%;
padding: 0.6rem 0.8rem;
font-size: 1rem;
border: 1px solid var(--color-border);
border-radius: 6px;
background: var(--color-surface);
color: var(--color-text);
}
.event-search-input:focus {
outline: 2px solid var(--color-accent);
outline-offset: 1px;
}
.event-list {
list-style: none;
margin: 0;
padding: 0;
max-height: 320px;
overflow-y: auto;
border: 1px solid var(--color-border);
border-radius: 6px;
background: var(--color-surface);
}
.event-list-item {
padding: 0.55rem 0.8rem;
cursor: pointer;
border-bottom: 1px solid var(--color-border);
font-size: 0.92rem;
line-height: 1.35;
}
.event-list-item:last-child { border-bottom: none; }
.event-list-item:hover,
.event-list-item:focus {
background: var(--color-bg-lime-tint);
outline: none;
}
.event-list-empty {
padding: 1rem;
color: var(--color-text-muted);
font-style: italic;
text-align: center;
}
.event-results-header {
background: var(--color-surface-muted);
border-radius: 6px;
padding: 0.8rem 1rem;
margin-bottom: 1rem;
font-size: 0.95rem;
line-height: 1.5;
}
.event-results-empty {
padding: 1rem;
color: var(--color-text-muted);
font-style: italic;
}
.event-result-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.event-result-row {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 0.8rem 1rem;
}
.event-result-header {
display: flex;
justify-content: space-between;
gap: 1rem;
margin-bottom: 0.4rem;
flex-wrap: wrap;
}
.event-result-title {
font-weight: 600;
color: var(--color-text);
}
.event-result-date {
font-variant-numeric: tabular-nums;
color: var(--color-accent-fg);
font-weight: 600;
}
.event-result-meta {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
font-size: 0.85rem;
color: var(--color-text-muted);
}
.event-result-duration {
background: var(--color-surface-muted);
padding: 0.15rem 0.5rem;
border-radius: 4px;
}
.event-rule-code {
background: var(--color-bg-lime-tint);
color: var(--color-accent-fg);
padding: 0.15rem 0.5rem;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
font-size: 0.78rem;
}
.event-result-composite,
.event-result-adjusted {
margin-top: 0.4rem;
font-size: 0.82rem;
color: var(--color-text-muted);
font-style: italic;
}
.event-result-notes {
margin-top: 0.4rem;
font-size: 0.85rem;
color: var(--color-text);
line-height: 1.4;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.wizard-step {
margin-bottom: 2rem;
}
.wizard-step-label {
font-size: 0.92rem;
font-weight: 600;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.6rem;
}
.step-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: var(--color-accent);
color: var(--color-accent-dark);
font-size: 0.75rem;
font-weight: 700;
flex-shrink: 0;
}
.proceeding-group {
margin-bottom: 1.25rem;
}
.proceeding-group h4 {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
margin-bottom: 0.5rem;
}
.proceeding-btns {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.proceeding-btn {
font-family: var(--font-sans);
font-size: 0.85rem;
padding: 0.6rem 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
cursor: pointer;
transition: all 0.15s ease;
text-align: left;
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.proceeding-btn:hover {
border-color: var(--color-accent);
box-shadow: var(--shadow);
}
.proceeding-btn.active {
border-color: var(--color-accent);
background: rgb(var(--hlc-lime-rgb) / 0.06);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
.proceeding-btn strong {
font-weight: 500;
}
/* Date input */
.date-input-group {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-width: 400px;
}
.date-field-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.date-label {
font-size: 0.85rem;
font-weight: 500;
color: var(--color-text);
min-width: 160px;
}
.trigger-event-name {
font-size: 0.88rem;
font-weight: 600;
color: var(--color-accent-fg);
}
.date-input {
font-family: var(--font-sans);
font-size: 0.92rem;
padding: 0.5rem 0.7rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
outline: none;
}
.date-input:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
.calculate-btn {
font-family: var(--font-sans);
font-size: 0.88rem;
font-weight: 600;
padding: 0.6rem 1.25rem;
border: none;
border-radius: var(--radius);
background: var(--color-accent);
color: var(--color-accent-dark);
cursor: pointer;
transition: background 0.15s ease;
align-self: flex-start;
}
.calculate-btn:hover {
background: var(--color-accent-light);
}
.reset-btn {
font-family: var(--font-sans);
font-size: 0.82rem;
font-weight: 500;
padding: 0.5rem 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.15s ease;
}
.reset-btn:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
/* Timeline */
.timeline-header {
margin-bottom: 1.25rem;
padding-bottom: 0.75rem;
border-bottom: 2px solid var(--color-accent);
}
.timeline-header strong {
font-size: 1rem;
}
.timeline {
position: relative;
}
.timeline-item {
display: flex;
gap: 0.75rem;
min-height: 4rem;
}
.timeline-item:last-child .timeline-line {
display: none;
}
.timeline-dot-col {
display: flex;
flex-direction: column;
align-items: center;
width: 14px;
flex-shrink: 0;
}
.timeline-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--color-accent);
border: 2px solid var(--color-surface);
box-shadow: 0 0 0 2px var(--color-accent);
flex-shrink: 0;
margin-top: 0.35rem;
}
.dot-root {
width: 14px;
height: 14px;
margin-top: 0.2rem;
}
.timeline-line {
width: 2px;
flex: 1;
background: var(--color-border);
margin: 0.25rem 0;
}
.timeline-content {
flex: 1;
padding-bottom: 1rem;
}
.timeline-item-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1rem;
}
.timeline-name {
font-size: 0.88rem;
font-weight: 500;
}
.timeline-date {
font-family: var(--font-mono);
font-size: 0.85rem;
font-weight: 600;
color: var(--color-text);
white-space: nowrap;
}
.timeline-court-set {
font-size: 0.82rem;
color: var(--color-text-muted);
font-style: italic;
text-align: right;
}
.timeline-meta {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: 0.25rem;
}
.party-badge {
font-size: 0.7rem;
font-weight: 500;
padding: 0.1rem 0.45rem;
border-radius: 99px;
}
.party-claimant {
background: var(--status-blue-bg);
color: var(--status-blue-fg);
}
.party-defendant {
background: var(--status-amber-bg);
color: var(--status-amber-fg);
}
.party-court {
background: var(--status-blue-soft-bg);
color: var(--status-blue-soft-fg);
}
.party-both {
background: var(--status-neutral-bg);
color: var(--status-neutral-fg-3);
}
.optional-badge {
font-size: 0.68rem;
font-weight: 500;
padding: 0.05rem 0.4rem;
border-radius: 99px;
background: var(--status-amber-bg);
color: var(--status-amber-fg);
}
.timeline-rule {
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--color-text-muted);
}
.timeline-adjusted {
font-size: 0.78rem;
color: var(--status-amber-fg-2);
margin-top: 0.2rem;
}
.timeline-notes {
font-size: 0.78rem;
color: var(--color-text-muted);
font-style: italic;
margin-top: 0.15rem;
}
/* --- Responsive: Sidebar --- */
@media (max-width: 1023px) {
.sidebar {
width: var(--sidebar-expanded);
transform: translateX(-100%);
transition: transform 150ms ease;
}
.sidebar.mobile-open {
transform: translateX(0);
}
.sidebar .sidebar-label {
opacity: 1;
}
.sidebar .sidebar-pin {
display: none;
}
.sidebar-resize-handle {
display: none;
}
.sidebar-hamburger {
display: flex;
}
.sidebar-overlay {
display: block;
position: fixed;
inset: 0;
background: var(--color-overlay-modal);
z-index: 35;
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease;
}
.sidebar-overlay.visible {
opacity: 1;
pointer-events: auto;
}
.has-sidebar,
.has-sidebar.sidebar-pinned,
:root.sidebar-pinned .has-sidebar {
padding-left: 0;
}
}
/* --- Glossar --- */
.glossar-header-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
}
.btn-suggest {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.55rem 1.1rem;
font-size: 0.85rem;
font-weight: 600;
color: var(--color-accent-dark);
background: var(--color-accent);
border: none;
border-radius: var(--radius);
cursor: pointer;
white-space: nowrap;
transition: background 0.15s ease;
flex-shrink: 0;
margin-top: 0.25rem;
}
.btn-suggest:hover {
background: var(--color-accent-light);
}
.btn-suggest-icon {
font-size: 1.1rem;
font-weight: 700;
line-height: 1;
}
.glossar-controls {
margin-bottom: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.glossar-search-wrap {
position: relative;
display: flex;
align-items: center;
}
.glossar-search-icon {
position: absolute;
left: 0.75rem;
width: 1.1rem;
height: 1.1rem;
color: var(--color-text-muted);
pointer-events: none;
}
.glossar-search {
width: 100%;
padding: 0.65rem 4.5rem 0.65rem 2.5rem;
font-size: 0.92rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
font-family: var(--font-sans);
outline: none;
transition: border-color 0.15s ease;
}
.glossar-search:focus {
border-color: var(--color-accent);
}
.glossar-count {
position: absolute;
right: 0.75rem;
font-size: 0.78rem;
color: var(--color-text-muted);
}
.glossar-filters {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.filter-pill {
padding: 0.35rem 0.85rem;
font-size: 0.8rem;
font-weight: 500;
border: 1px solid var(--color-border);
border-radius: 99px;
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.15s ease;
font-family: var(--font-sans);
}
.filter-pill:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.filter-pill.active {
background: var(--color-accent);
border-color: var(--color-accent);
color: var(--color-accent-dark);
}
.glossar-table-wrap {
overflow-x: auto;
}
.glossar-table {
width: 100%;
border-collapse: collapse;
font-size: 0.88rem;
}
.glossar-table thead th {
text-align: left;
padding: 0.7rem 0.75rem;
font-size: 0.78rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--color-text-muted);
border-bottom: 2px solid var(--color-border);
white-space: nowrap;
}
.glossar-table tbody tr {
border-bottom: 1px solid var(--color-border);
transition: background 0.1s ease;
}
.glossar-table tbody tr:hover {
background: rgb(var(--hlc-lime-rgb) / 0.04);
}
.glossar-table td {
padding: 0.65rem 0.75rem;
vertical-align: top;
}
.glossar-de {
font-weight: 600;
color: var(--color-text);
white-space: nowrap;
}
.glossar-en {
color: var(--color-text);
}
.glossar-def {
color: var(--color-text-muted);
font-size: 0.84rem;
line-height: 1.5;
max-width: 380px;
}
.glossar-no-def {
color: var(--color-border);
}
.glossar-col-actions {
width: 2.5rem;
}
.glossar-actions {
text-align: center;
}
.glossar-feedback-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
border: none;
background: none;
color: var(--color-text-muted);
cursor: pointer;
border-radius: 4px;
transition: all 0.15s ease;
opacity: 0.4;
}
.glossar-table tbody tr:hover .glossar-feedback-btn {
opacity: 1;
}
.glossar-feedback-btn:hover {
background: rgb(var(--hlc-lime-rgb) / 0.1);
color: var(--color-accent-fg);
opacity: 1;
}
.glossar-empty {
text-align: center;
padding: 3rem 1rem;
color: var(--color-text-muted);
font-size: 0.95rem;
}
/* --- Modal --- */
.modal-overlay {
position: fixed;
inset: 0;
background: var(--color-overlay-modal);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
padding: 1rem;
}
.modal-card {
background: var(--color-surface);
border-radius: calc(var(--radius) * 1.5);
box-shadow: var(--shadow-lg);
width: 100%;
max-width: 480px;
max-height: 90vh;
overflow-y: auto;
padding: 1.5rem;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 0.75rem;
}
.modal-header h2 {
font-size: 1.15rem;
font-weight: 700;
}
.modal-close {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: var(--color-text-muted);
line-height: 1;
padding: 0.25rem;
}
.modal-close:hover {
color: var(--color-text);
}
#suggest-form {
padding: 1.25rem 1.5rem 1.5rem;
}
.form-field {
margin-bottom: 1rem;
}
.form-field label {
display: block;
font-size: 0.82rem;
font-weight: 600;
margin-bottom: 0.3rem;
color: var(--color-text);
}
.form-field input,
.form-field textarea,
.form-field select {
width: 100%;
padding: 0.55rem 0.75rem;
font-size: 0.88rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
/* Form fields render on --color-input-bg, which is #ffffff in light
mode (m: 2026-04-30 — the cream `--color-bg` made inputs blur into
the body; white reads as a proper input well) and a value below
--color-surface in dark mode so the well is depressed below the
card panel rather than merging into it. */
background: var(--color-input-bg);
color: var(--color-text);
font-family: var(--font-sans);
outline: none;
transition: border-color 0.15s ease;
}
.form-field input:focus,
.form-field textarea:focus,
.form-field select:focus {
border-color: var(--color-accent);
}
/* Checkboxes and radios must not inherit the text-input width:100% / padding
that the rule above sets — without this, the visual checkbox stretches to
fill the form column and the label text wraps below it. */
.form-field input[type="checkbox"],
.form-field input[type="radio"] {
width: auto;
padding: 0;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1.25rem;
}
.btn-cancel {
padding: 0.5rem 1rem;
font-size: 0.85rem;
font-weight: 500;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
font-family: var(--font-sans);
transition: border-color 0.15s ease;
}
.btn-cancel:hover {
border-color: var(--color-text-muted);
}
.btn-submit {
padding: 0.5rem 1.25rem;
font-size: 0.85rem;
font-weight: 600;
border: none;
border-radius: var(--radius);
background: var(--color-accent);
color: var(--color-accent-dark);
cursor: pointer;
font-family: var(--font-sans);
transition: background 0.15s ease;
}
.btn-submit:hover {
background: var(--color-accent-light);
}
.btn-submit:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.form-msg {
margin-top: 0.75rem;
font-size: 0.82rem;
min-height: 1.25rem;
}
.form-msg-error {
color: #dc2626;
}
.form-msg-success {
color: var(--color-accent-fg);
}
/* Inline warning shown above Save in the project edit modal when changing
the project type clears existing type-specific fields (t-paliad-056). */
.form-warn {
margin-top: 0.75rem;
padding: 0.6rem 0.75rem;
border: 1px solid var(--status-amber-border);
background: var(--status-amber-bg);
color: var(--status-amber-fg);
border-radius: 4px;
font-size: 0.85rem;
line-height: 1.4;
}
.form-warn strong {
display: block;
margin-bottom: 0.2rem;
}
/* --- Responsive: General --- */
/* --- Downloads --- */
.downloads-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
gap: 1.25rem;
}
.download-card {
display: flex;
align-items: center;
gap: 1.25rem;
padding: 1.5rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
text-decoration: none;
color: inherit;
transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.download-card:hover {
box-shadow: var(--shadow-md);
border-color: var(--color-accent);
}
.download-card:hover .download-btn {
background: var(--color-accent);
color: var(--color-accent-dark);
}
.download-icon {
flex-shrink: 0;
width: 2.5rem;
height: 2.5rem;
color: var(--color-accent-fg);
}
.download-icon svg {
width: 100%;
height: 100%;
}
.download-info {
flex: 1;
min-width: 0;
}
.download-info h2 {
font-size: 1.05rem;
font-weight: 600;
margin-bottom: 0.25rem;
letter-spacing: -0.01em;
}
.download-info p {
color: var(--color-text-muted);
font-size: 0.85rem;
line-height: 1.5;
}
.download-action {
flex-shrink: 0;
}
.download-btn {
display: inline-block;
padding: 0.5rem 1rem;
font-size: 0.82rem;
font-weight: 600;
color: var(--color-accent-fg);
border: 1.5px solid var(--color-accent);
border-radius: var(--radius);
transition: background 0.15s ease, color 0.15s ease;
white-space: nowrap;
}
@media (max-width: 768px) {
.hero {
padding: 3.5rem 0 3rem;
}
.hero h1 {
font-size: 2rem;
}
.grid, .grid-2 {
grid-template-columns: 1fr;
gap: 1rem;
}
.office-list {
gap: 1.25rem;
}
.tool-grid {
grid-template-columns: 1fr;
}
.tool-results {
position: static;
}
.nav-right {
gap: 0.75rem;
}
.proceeding-btns {
flex-direction: column;
}
.date-field-row {
flex-direction: column;
align-items: flex-start;
gap: 0.3rem;
}
.timeline-item-header {
flex-direction: column;
gap: 0.25rem;
}
.glossar-header-row {
flex-direction: column;
}
.glossar-de {
white-space: normal;
}
.glossar-def {
max-width: none;
}
.glossar-table {
font-size: 0.82rem;
}
.glossar-table td,
.glossar-table thead th {
padding: 0.5rem;
}
.download-card {
flex-direction: column;
text-align: center;
gap: 0.75rem;
}
.downloads-grid {
grid-template-columns: 1fr;
}
.links-header-row {
flex-direction: column;
gap: 1rem;
}
.links-header-actions {
align-self: flex-start;
}
.links-category-grid {
grid-template-columns: 1fr;
}
.comparison-grid {
grid-template-columns: 1fr;
}
.result-actions {
flex-direction: column;
}
}
/* --- Links --- */
.links-header-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1.5rem;
}
.links-header-actions {
display: flex;
align-items: center;
gap: 0.75rem;
flex-shrink: 0;
padding-top: 0.25rem;
}
.links-pending-badge {
font-size: 0.78rem;
color: var(--color-accent-fg);
background: rgb(var(--hlc-lime-rgb) / 0.1);
padding: 0.25rem 0.65rem;
border-radius: 999px;
font-weight: 600;
white-space: nowrap;
}
.links-suggest-btn {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.5rem 1rem;
font-size: 0.85rem;
font-weight: 600;
color: var(--color-accent-dark);
background: var(--color-accent);
border: none;
border-radius: var(--radius);
cursor: pointer;
transition: background 0.15s ease;
white-space: nowrap;
}
.links-suggest-btn:hover {
background: var(--color-accent-light);
}
.links-filters {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 2rem;
}
.links-filter-btn {
padding: 0.4rem 1rem;
font-size: 0.85rem;
font-weight: 500;
color: var(--color-text-muted);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 999px;
cursor: pointer;
transition: all 0.15s ease;
}
.links-filter-btn:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.links-filter-btn.active {
background: var(--color-accent);
color: var(--color-accent-dark);
border-color: var(--color-accent);
}
.links-category-heading {
font-size: 1.15rem;
font-weight: 700;
letter-spacing: -0.01em;
margin: 2rem 0 0.75rem;
color: var(--color-text);
}
.links-category-heading:first-child {
margin-top: 0;
}
.links-category-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1rem;
margin-bottom: 0.5rem;
}
.link-card {
display: flex;
align-items: stretch;
padding: 1.25rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
text-decoration: none;
color: inherit;
transition: box-shadow 0.15s ease, border-color 0.15s ease;
position: relative;
}
.link-card:hover {
box-shadow: var(--shadow-md);
border-color: var(--color-accent);
}
.link-card-placeholder {
opacity: 0.55;
pointer-events: auto;
}
.link-card-body {
flex: 1;
min-width: 0;
}
.link-card-title {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.95rem;
font-weight: 600;
letter-spacing: -0.01em;
margin-bottom: 0.3rem;
}
.link-card-external {
flex-shrink: 0;
color: var(--color-text-muted);
opacity: 0.6;
}
.link-card:hover .link-card-external {
color: var(--color-accent-fg);
opacity: 1;
}
.link-card-desc {
color: var(--color-text-muted);
font-size: 0.82rem;
line-height: 1.5;
}
.link-card-feedback {
flex-shrink: 0;
display: flex;
align-items: flex-start;
padding: 0.25rem;
margin-left: 0.5rem;
background: none;
border: none;
color: var(--color-text-muted);
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease, color 0.15s ease;
}
.link-card:hover .link-card-feedback {
opacity: 0.5;
}
.link-card-feedback:hover {
opacity: 1 !important;
color: var(--color-accent-fg);
}
.links-empty {
color: var(--color-text-muted);
font-size: 0.9rem;
padding: 2rem 0;
}
/* --- Modals --- */
.modal-overlay {
position: fixed;
inset: 0;
background: var(--color-overlay-modal);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
padding: 1rem;
}
.modal-content {
background: var(--color-surface);
border-radius: calc(var(--radius) * 1.5);
padding: 2rem;
width: 100%;
max-width: 480px;
box-shadow: var(--shadow-xl);
}
.modal-content-sm {
max-width: 380px;
}
.modal-content h2 {
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 1.25rem;
}
.form-field {
margin-bottom: 1rem;
}
.form-field label {
display: block;
font-size: 0.82rem;
font-weight: 600;
color: var(--color-text-muted);
margin-bottom: 0.3rem;
}
.form-field input,
.form-field select,
.form-field textarea {
width: 100%;
padding: 0.55rem 0.75rem;
font-size: 0.9rem;
font-family: var(--font-sans);
border: 1px solid var(--color-border);
border-radius: var(--radius);
/* See .entity-form input rule above for the --color-input-bg rationale. */
background: var(--color-input-bg);
color: var(--color-text);
transition: border-color 0.15s ease;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
outline: none;
border-color: var(--color-accent);
}
.form-field textarea {
resize: vertical;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 0.75rem;
margin-top: 1.25rem;
}
.btn-primary {
padding: 0.5rem 1.25rem;
font-size: 0.85rem;
font-weight: 600;
color: var(--color-accent-dark);
background: var(--color-accent);
border: none;
border-radius: var(--radius);
cursor: pointer;
transition: background 0.15s ease;
}
.btn-primary:hover {
background: var(--color-accent-light);
}
.btn-secondary {
padding: 0.5rem 1.25rem;
font-size: 0.85rem;
font-weight: 600;
color: var(--color-text-muted);
background: none;
border: 1px solid var(--color-border);
border-radius: var(--radius);
cursor: pointer;
transition: border-color 0.15s ease;
}
.btn-secondary:hover {
border-color: var(--color-text-muted);
}
.form-message {
font-size: 0.82rem;
margin-top: 0.75rem;
min-height: 1.2em;
}
.form-message-success {
color: var(--color-accent-fg);
}
.form-message-error {
color: #dc2626;
}
/* --- Print --- */
@media print {
.header, .footer, .sidebar, .sidebar-hamburger, .sidebar-overlay,
.tool-input, .result-actions, .reset-btn, #step-1, #step-2,
.calculate-btn, .modal-overlay, .glossar-feedback-btn, .btn-suggest,
.comparison-header button, .comparison-container {
display: none !important;
}
.print-header, .print-footer {
display: block !important;
}
.print-header {
padding: 1.5rem 0 1rem;
border-bottom: 2px solid var(--color-accent);
margin-bottom: 1.5rem;
}
.print-header-brand {
font-size: 1.2rem;
color: var(--hlc-midnight);
}
.print-header-brand strong {
color: var(--color-accent-fg);
font-size: 1.4rem;
}
.print-header-meta {
margin-top: 0.75rem;
font-size: 0.85rem;
color: #64647a;
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
}
.print-footer {
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid #e5e5ed;
font-size: 0.75rem;
color: #64647a;
display: flex;
justify-content: space-between;
}
.has-sidebar {
padding-left: 0 !important;
}
.tool-grid {
grid-template-columns: 1fr;
}
.tool-results {
position: static;
}
.tool-header {
display: none;
}
.result-card {
box-shadow: none;
border: none;
padding: 0;
}
body {
font-size: 11pt;
color: #000;
}
@page {
margin: 2cm;
size: A4;
}
}
/* --- Geb\u00fchrentabellen --- */
.gebuehren-header-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1rem;
flex-wrap: wrap;
}
.gebuehren-lookup {
margin-bottom: 1.5rem;
}
.gebuehren-lookup label {
display: block;
font-weight: 500;
margin-bottom: 0.375rem;
font-size: 0.875rem;
color: var(--color-text-muted);
}
.gebuehren-lookup-row {
display: flex;
align-items: center;
gap: 0.5rem;
max-width: 480px;
}
.gebuehren-currency {
color: var(--color-text-muted);
font-weight: 500;
font-size: 0.875rem;
}
.gebuehren-input {
flex: 1;
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
font-family: var(--font-mono);
font-size: 0.9rem;
background: var(--color-surface);
transition: border-color 0.15s;
}
.gebuehren-input:focus {
outline: none;
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgb(var(--hlc-lime-rgb) / 0.15);
}
.btn-lookup {
padding: 0.5rem 1rem;
background: var(--color-accent);
color: var(--color-accent-dark);
border: none;
border-radius: var(--radius);
font-weight: 500;
font-size: 0.875rem;
cursor: pointer;
white-space: nowrap;
transition: background 0.15s;
}
.btn-lookup:hover {
background: var(--color-accent-light);
}
/* Lookup result cards */
.gebuehren-lookup-result {
margin-bottom: 1.5rem;
}
.gebuehren-lookup-cards {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.gebuehren-lookup-card {
background: var(--color-surface);
border: 1px solid var(--color-accent);
border-radius: var(--radius);
padding: 0.75rem 1.25rem;
display: flex;
flex-direction: column;
gap: 0.25rem;
min-width: 160px;
}
.gebuehren-lookup-label {
font-size: 0.75rem;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.gebuehren-lookup-value {
font-family: var(--font-mono);
font-weight: 600;
font-size: 1.05rem;
color: var(--color-accent-fg);
}
/* Tabs */
.gebuehren-tabs {
display: flex;
gap: 0;
border-bottom: 2px solid var(--color-border);
margin-bottom: 1.5rem;
overflow-x: auto;
}
.gebuehren-tab {
padding: 0.625rem 1.25rem;
background: none;
border: none;
font-family: var(--font-sans);
font-size: 0.9rem;
font-weight: 500;
color: var(--color-text-muted);
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -2px;
transition: color 0.15s, border-color 0.15s;
white-space: nowrap;
}
.gebuehren-tab:hover {
color: var(--color-text);
}
.gebuehren-tab.active {
/* Canonical active-tab pattern (F-20) — see .login-tab.active. */
color: var(--color-text);
border-bottom-color: var(--hlc-lime);
font-weight: 600;
}
/* Panels */
.gebuehren-panel {
min-height: 200px;
}
.gebuehren-versions {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.gebuehren-section-title {
font-size: 0.95rem;
font-weight: 600;
margin: 1.5rem 0 0.75rem;
color: var(--color-text);
}
.gebuehren-section-title:first-child {
margin-top: 0;
}
/* Fee tables */
.gebuehren-table-wrap {
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: auto;
max-height: 520px;
}
.gebuehren-table-wrap-short {
max-height: none;
}
.gebuehren-table {
width: 100%;
border-collapse: collapse;
font-size: 0.85rem;
}
.gebuehren-table th,
.gebuehren-table td {
padding: 0.5rem 0.875rem;
text-align: right;
border-bottom: 1px solid var(--color-border);
white-space: nowrap;
}
.gebuehren-table th {
background: var(--color-bg);
font-weight: 600;
position: sticky;
top: 0;
z-index: 1;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--color-text-muted);
}
.gebuehren-table th:first-child,
.gebuehren-table td:first-child {
text-align: left;
}
.gebuehren-table tbody tr:hover {
background: rgb(var(--hlc-lime-rgb) / 0.04);
}
.gebuehren-table tbody tr.highlight {
background: rgb(var(--hlc-lime-rgb) / 0.12);
font-weight: 600;
}
.gebuehren-table tbody tr.highlight td {
border-bottom-color: var(--color-accent);
}
.gebuehren-table-compact th,
.gebuehren-table-compact td {
padding: 0.375rem 0.625rem;
font-size: 0.8rem;
}
/* UPC summary cards */
.gebuehren-upc-cards {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
}
.gebuehren-upc-card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 0.75rem 1.25rem;
min-width: 160px;
flex: 1;
}
.gebuehren-upc-card-label {
font-size: 0.75rem;
color: var(--color-text-muted);
margin-bottom: 0.25rem;
}
.gebuehren-upc-card-value {
font-family: var(--font-mono);
font-weight: 600;
font-size: 1.1rem;
color: var(--color-text);
}
/* Multipliers section */
.gebuehren-multipliers {
margin-top: 2rem;
padding-top: 1.5rem;
border-top: 1px solid var(--color-border);
}
.gebuehren-multipliers h3 {
font-size: 1rem;
margin-bottom: 0.25rem;
}
.gebuehren-multipliers-desc {
font-size: 0.825rem;
color: var(--color-text-muted);
margin-bottom: 1rem;
}
.text-muted {
color: var(--color-text-muted);
}
/* Responsive */
@media (max-width: 640px) {
.gebuehren-lookup-row {
flex-wrap: wrap;
max-width: 100%;
}
.gebuehren-input {
min-width: 0;
}
.gebuehren-lookup-cards {
flex-direction: column;
}
.gebuehren-upc-cards {
flex-direction: column;
}
.gebuehren-tab {
padding: 0.5rem 0.75rem;
font-size: 0.8rem;
}
.gebuehren-table th,
.gebuehren-table td {
padding: 0.375rem 0.5rem;
font-size: 0.8rem;
}
}
@media print {
.gebuehren-lookup,
.gebuehren-tabs,
.gebuehren-versions,
.btn-suggest,
.gebuehren-lookup-result,
.modal-overlay {
display: none !important;
}
.gebuehren-panel {
display: block !important;
}
.gebuehren-table-wrap {
max-height: none;
overflow: visible;
border: 1px solid #ccc;
}
}
/* --- Checklisten --- */
.checklist-filters {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-bottom: 1.5rem;
}
.checklist-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1rem;
}
.checklist-card {
display: flex;
flex-direction: column;
gap: 0.6rem;
padding: 1.1rem 1.2rem 1.2rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
text-decoration: none;
color: var(--color-text);
transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.checklist-card:hover {
border-color: var(--color-accent);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.checklist-card-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
}
.checklist-card-count {
font-size: 0.78rem;
color: var(--color-text-muted);
}
.checklist-card-title {
font-size: 1.05rem;
font-weight: 600;
line-height: 1.3;
margin: 0;
}
.checklist-card-desc {
color: var(--color-text-muted);
font-size: 0.88rem;
line-height: 1.5;
margin: 0;
}
.checklist-card-court {
font-size: 0.78rem;
color: var(--color-text-muted);
margin: 0;
font-style: italic;
}
.checklist-card-progress {
display: flex;
align-items: center;
gap: 0.6rem;
margin-top: 0.2rem;
}
.checklist-regime {
display: inline-block;
padding: 0.15rem 0.55rem;
border-radius: 99px;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.04em;
background: rgb(var(--hlc-lime-rgb) / 0.12);
color: var(--color-accent-fg);
}
.checklist-regime-UPC {
background: rgb(var(--hlc-lime-rgb) / 0.12);
color: var(--color-accent-fg);
}
.checklist-regime-DE {
background: rgba(26, 54, 93, 0.08);
color: #1b365d;
}
.checklist-regime-EPA {
background: rgba(100, 100, 122, 0.12);
color: var(--color-text-muted);
}
.checklist-empty {
color: var(--color-text-muted);
text-align: center;
padding: 2rem 1rem;
grid-column: 1 / -1;
}
/* --- Checklist detail --- */
.checklist-back {
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-size: 0.85rem;
color: var(--color-text-muted);
text-decoration: none;
margin-bottom: 1rem;
transition: color 0.15s ease;
}
.checklist-back:hover {
color: var(--color-accent-fg);
}
.checklist-back-arrow {
font-size: 1rem;
}
.checklist-detail-header {
margin-bottom: 1.5rem;
}
.checklist-detail-head-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
}
.checklist-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 0.25rem;
}
.btn-ghost {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.55rem 0.9rem;
font-size: 0.82rem;
font-weight: 500;
color: var(--color-text-muted);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
cursor: pointer;
transition: all 0.15s ease;
font-family: var(--font-sans);
}
.btn-ghost:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.checklist-meta {
display: flex;
flex-wrap: wrap;
gap: 0.4rem 1.5rem;
margin-top: 0.85rem;
font-size: 0.82rem;
}
.checklist-meta-item {
display: flex;
flex-direction: column;
gap: 0.15rem;
}
.checklist-meta-item dt {
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
font-weight: 600;
}
.checklist-meta-item dd {
color: var(--color-text);
margin: 0;
}
.checklist-progress {
display: flex;
align-items: center;
gap: 0.75rem;
margin-top: 1.25rem;
}
.checklist-progress-bar {
flex: 1;
height: 0.4rem;
background: var(--color-border);
border-radius: 99px;
overflow: hidden;
}
.checklist-progress-fill {
height: 100%;
background: var(--color-accent);
border-radius: 99px;
transition: width 0.2s ease;
width: 0%;
}
.checklist-progress-label {
font-size: 0.8rem;
color: var(--color-text-muted);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
/* Checklist instance list (on template detail page) */
.checklist-instances-section {
margin-top: 2rem;
}
.checklist-instances-section h2 {
font-size: 1.1rem;
margin-bottom: 0.25rem;
}
.checklist-progress-inline {
display: flex;
align-items: center;
gap: 0.5rem;
min-width: 9rem;
}
.checklist-progress-inline .checklist-progress-bar {
width: 5.5rem;
flex: 0 0 auto;
}
.checklist-instance-name {
color: var(--color-text);
text-decoration: none;
font-weight: 500;
}
.checklist-instance-name:hover {
color: var(--color-accent-fg);
}
.checklist-instance-akte-link {
color: var(--color-accent-fg);
text-decoration: none;
}
.checklist-instance-akte-link:hover {
text-decoration: underline;
}
.checklist-instance-actions {
display: flex;
gap: 0.35rem;
justify-content: flex-end;
white-space: nowrap;
}
.checklist-instance-titles {
display: flex;
flex-direction: column;
gap: 0.25rem;
min-width: 0;
flex: 1;
}
.checklist-instance-name-row {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
}
.entity-muted {
color: var(--color-text-muted);
font-style: italic;
font-size: 0.85rem;
}
.btn-small {
padding: 0.35rem 0.7rem;
font-size: 0.78rem;
}
.checklist-groups {
display: flex;
flex-direction: column;
gap: 1.75rem;
}
.checklist-group-title {
font-size: 0.78rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
padding-bottom: 0.45rem;
border-bottom: 1px solid var(--color-border);
margin-bottom: 0.75rem;
}
.checklist-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.checklist-item {
padding: 0.55rem 0.6rem;
border-radius: var(--radius);
transition: background 0.15s ease;
}
.checklist-item:hover {
background: rgb(var(--hlc-lime-rgb) / 0.04);
}
.checklist-item.checked .checklist-item-text {
color: var(--color-text-muted);
text-decoration: line-through;
}
.checklist-item-label {
display: flex;
align-items: flex-start;
gap: 0.7rem;
cursor: pointer;
}
.checklist-checkbox {
width: 1.05rem;
height: 1.05rem;
margin-top: 0.2rem;
accent-color: var(--color-accent);
flex-shrink: 0;
cursor: pointer;
}
.checklist-item-body {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.checklist-item-row {
display: flex;
align-items: baseline;
gap: 0.6rem;
flex-wrap: wrap;
}
.checklist-item-text {
font-size: 0.92rem;
line-height: 1.5;
color: var(--color-text);
}
.checklist-item-rule {
font-size: 0.72rem;
padding: 0.1rem 0.45rem;
border-radius: 99px;
background: rgba(26, 54, 93, 0.06);
color: #1b365d;
font-family: var(--font-mono);
white-space: nowrap;
}
.checklist-item-note {
font-size: 0.8rem;
color: var(--color-text-muted);
line-height: 1.5;
margin: 0;
}
.checklist-print-footer {
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid var(--color-border);
}
.checklist-disclaimer {
font-size: 0.75rem;
color: var(--color-text-muted);
line-height: 1.6;
margin: 0;
}
@media (max-width: 640px) {
.checklist-detail-head-row {
flex-direction: column;
}
.checklist-actions {
width: 100%;
}
}
@media print {
.checklist-back,
.checklist-actions,
.checklist-filters,
.checklist-card-progress {
display: none !important;
}
.checklist-item {
break-inside: avoid;
border-bottom: 1px dotted #ccc;
padding: 0.3rem 0;
}
.checklist-item:hover {
background: none;
}
.checklist-checkbox {
/* Keep checkbox visible with actual state */
accent-color: #000;
}
.checklist-group {
break-inside: avoid-page;
margin-bottom: 1rem;
}
.checklist-progress {
margin-top: 0.5rem;
}
.checklist-progress-bar {
display: none;
}
}
/* --- Gerichtsverzeichnis --- */
.gerichte-header-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
}
.gerichte-controls {
display: flex;
flex-direction: column;
gap: 0.85rem;
margin-bottom: 1.5rem;
}
.gerichte-filter-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.65rem;
}
.gerichte-filter-label {
font-size: 0.78rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
min-width: 3rem;
}
.gerichte-list {
display: flex;
flex-direction: column;
gap: 0.65rem;
}
.gericht-card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: hidden;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.gericht-card:hover {
border-color: rgb(var(--hlc-lime-rgb) / 0.4);
}
.gericht-card.open {
border-color: var(--color-accent);
box-shadow: var(--shadow-md);
}
.gericht-summary {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.9rem 1.1rem;
cursor: pointer;
user-select: none;
}
.gericht-title {
flex: 1;
min-width: 0;
}
.gericht-name {
font-weight: 600;
font-size: 0.97rem;
color: var(--color-text);
line-height: 1.35;
margin-bottom: 0.25rem;
}
.gericht-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem 0.9rem;
font-size: 0.8rem;
color: var(--color-text-muted);
}
.gericht-meta svg {
vertical-align: -2px;
margin-right: 0.15rem;
}
.gericht-type-badge {
display: inline-flex;
align-items: center;
padding: 0.12rem 0.55rem;
border-radius: 99px;
background: rgb(var(--hlc-lime-rgb) / 0.1);
color: var(--color-accent-fg);
font-weight: 600;
font-size: 0.72rem;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.gericht-city {
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
.gericht-langs {
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--color-text-muted);
border: 1px solid var(--color-border);
border-radius: 4px;
padding: 0.05rem 0.35rem;
}
.gericht-actions {
display: flex;
align-items: center;
gap: 0.35rem;
flex-shrink: 0;
}
.gericht-feedback-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.9rem;
height: 1.9rem;
border: none;
background: none;
color: var(--color-text-muted);
cursor: pointer;
border-radius: 4px;
opacity: 0.45;
transition: all 0.15s ease;
font-size: 0.85rem;
}
.gericht-card:hover .gericht-feedback-btn {
opacity: 1;
}
.gericht-feedback-btn:hover {
background: rgb(var(--hlc-lime-rgb) / 0.1);
color: var(--color-accent-fg);
}
.gericht-toggle {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.9rem;
height: 1.9rem;
border: 1px solid var(--color-border);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
border-radius: 4px;
font-size: 1.05rem;
line-height: 1;
font-weight: 600;
transition: all 0.15s ease;
}
.gericht-card.open .gericht-toggle {
background: var(--color-accent);
color: var(--color-accent-dark);
border-color: var(--color-accent);
}
.gericht-details {
display: none;
padding: 0.25rem 1.1rem 1.1rem;
border-top: 1px solid var(--color-border);
grid-template-columns: 1fr;
gap: 0.85rem;
}
.gericht-card.open .gericht-details {
display: grid;
}
@media (min-width: 720px) {
.gericht-card.open .gericht-details {
grid-template-columns: 160px 1fr;
}
.gericht-card.open .gericht-field {
display: contents;
}
}
.gericht-field {
display: grid;
gap: 0.25rem;
}
.gericht-field-label {
font-size: 0.72rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
padding-top: 0.85rem;
}
.gericht-field-value {
font-size: 0.88rem;
color: var(--color-text);
line-height: 1.55;
padding-top: 0.85rem;
}
.gericht-contacts {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.gericht-contact {
display: inline-flex;
align-items: center;
gap: 0.4rem;
color: var(--color-text);
}
.gericht-contact a {
color: var(--color-accent-fg);
text-decoration: none;
}
.gericht-contact a:hover {
text-decoration: underline;
}
@media print {
.sidebar,
.sidebar-hamburger,
.sidebar-overlay,
.gerichte-controls,
.gericht-feedback-btn,
.gericht-toggle,
.btn-suggest,
.modal-overlay,
body.has-sidebar main {
/* keep main visible — only specific controls hidden */
}
.sidebar,
.sidebar-hamburger,
.sidebar-overlay,
.gerichte-controls,
.gericht-feedback-btn,
.gericht-toggle,
.btn-suggest,
.modal-overlay,
.footer {
display: none !important;
}
body.has-sidebar main {
padding-left: 0 !important;
}
.gericht-card {
break-inside: avoid;
border: 1px solid #ccc !important;
margin-bottom: 0.5rem;
box-shadow: none !important;
}
/* Expand all cards in print */
.gericht-card .gericht-details {
display: grid !important;
grid-template-columns: 150px 1fr !important;
}
.gericht-card .gericht-field {
display: contents !important;
}
}
/* ============================================================================
Phase D — Akten (Mandate) UI
============================================================================ */
/* --- Sidebar groups --- */
.sidebar-group {
margin-top: 0.75rem;
padding-top: 0.75rem;
border-top: 1px solid var(--sidebar-border);
}
.sidebar-group:first-of-type {
border-top: none;
padding-top: 0.25rem;
}
.sidebar-group-label {
padding: 0 0.5rem 0.25rem 1.5rem;
font-size: 0.66rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--sidebar-text-muted);
opacity: 0;
transition: opacity 0.15s ease;
white-space: nowrap;
overflow: hidden;
}
.sidebar.expanded .sidebar-group-label,
.sidebar.pinned .sidebar-group-label,
.sidebar.mobile-open .sidebar-group-label {
opacity: 0.75;
}
.sidebar-item-disabled {
opacity: 0.4;
cursor: not-allowed;
pointer-events: auto;
}
.sidebar-item-disabled:hover {
background: transparent !important;
}
/* --- Entity list/detail patterns ---
Generic UI primitives reused by projects, deadlines, appointments,
checklists, admin pages. Naming convention (post t-paliad-093 rename
sweep, F-7 of t-paliad-074): generic table/tabs/form/empty/controls/
detail/events/status/type/suggestion/chip/col/ref/search-wrap/select/
soon/loading/muted/unavailable/row/header-row/title-input primitives
live under the .entity-* prefix. Truly generic widgets carry no
prefix at all: .multi-* (multi-select panel), .filter-*, .collab-*
(collaborator picker, bare class .collab-picker), .firmwide-*,
.office-*, .back-link. Project-specific patterns keep specific
names: .party-form/-controls/-table (parties on a project),
.checklists-hint, .netdocs-link. Page-scoped IDs in projects.tsx
are projects-search/-count/-body; in projects-new.tsx,
project-new-form/-msg.
*/
.entity-header-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1.5rem;
flex-wrap: wrap;
}
.btn-cta-lime {
display: inline-flex;
align-items: center;
padding: 0.6rem 1.25rem;
font-size: 0.9rem;
font-weight: 600;
color: var(--hlc-midnight);
background: var(--hlc-lime);
border: none;
border-radius: var(--radius);
cursor: pointer;
text-decoration: none;
transition: background 0.15s ease, transform 0.05s ease;
}
.btn-cta-lime:hover {
background: var(--color-accent-light);
}
.btn-cta-lime:active {
transform: translateY(1px);
}
.btn-cta-lime.btn-outline {
background: transparent;
color: var(--color-accent-fg);
border: 1.5px solid var(--color-accent);
}
.btn-cta-lime.btn-outline:hover {
background: rgb(var(--hlc-lime-rgb) / 0.1);
}
.entity-controls {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1.5rem;
}
.entity-search-wrap {
max-width: 460px;
}
.filter-row {
display: flex;
align-items: flex-end;
gap: 0.5rem 1rem;
flex-wrap: wrap;
}
/* Each filter is a label-above-control cell so the caption sits on top of
its select / button. The whole filter-row stays a horizontal flex-wrap
of these column-cells (t-paliad-117). */
.filter-group {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 0.25rem;
}
.filter-label {
font-size: 0.85rem;
color: var(--color-text-muted);
}
@media (max-width: 480px) {
/* Single-column stack on narrow viewports — F-24. */
.filter-row { flex-direction: column; align-items: stretch; }
.filter-group .entity-select { width: 100%; }
}
.entity-select {
padding: 0.4rem 0.75rem;
font-size: 0.85rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
cursor: pointer;
}
.entity-select:focus {
outline: none;
border-color: var(--color-accent);
}
.entity-unavailable {
padding: 1rem 1.25rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--status-amber-bg);
color: var(--status-amber-fg);
margin-bottom: 1rem;
}
.entity-table-wrap {
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
overflow-x: auto;
box-shadow: var(--shadow);
}
.entity-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
}
.entity-table thead th {
padding: 0.75rem 1rem;
text-align: left;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--color-text-muted);
border-bottom: 1px solid var(--color-border);
background: var(--color-bg-subtle);
}
/* .entity-table contract: every row must EITHER carry a row-level click
handler that navigates to a detail page (skipping clicks on inner <a>
and <button> so nested controls still work) OR the table must wear the
`.entity-table--readonly` modifier (defined below) to opt out of the
pointer cursor and hover highlight. The default rule below primes every
row to look clickable; if your rows don't navigate, the cursor lies. */
.entity-table tbody tr {
cursor: pointer;
transition: background 0.08s ease;
border-bottom: 1px solid var(--color-border);
}
.entity-table tbody tr:last-child {
border-bottom: none;
}
.entity-table tbody tr:hover {
background: var(--color-bg-lime-tint);
}
/* t-paliad-099: opt-out for tables whose rows do NOT navigate. The default
.entity-table styling primes every row with cursor: pointer and a hover
highlight, which lies for read-only summary tables (audit log, CalDAV
sync log) and for admin tables where all actions live in inline buttons
(admin-team, admin-event-types, admin-partner-units). Apply this modifier
on the <table> to neutralise the row-level click affordance. */
.entity-table--readonly tbody tr {
cursor: default;
}
.entity-table--readonly tbody tr:hover {
background: transparent;
}
.entity-table td {
padding: 0.75rem 1rem;
vertical-align: middle;
}
.entity-col-title {
font-weight: 600;
}
.entity-col-ref {
font-family: var(--font-mono);
font-size: 0.82rem;
color: var(--color-text-muted);
}
.entity-col-updated {
font-size: 0.82rem;
color: var(--color-text-muted);
white-space: nowrap;
}
.office-chip,
.entity-status-chip,
.firmwide-chip {
display: inline-block;
padding: 0.15rem 0.55rem;
font-size: 0.72rem;
font-weight: 600;
border-radius: 999px;
white-space: nowrap;
}
/* Office chips matched the type-chip per-type palette and fell out of F-16
for the same reason — the colours don't rank or group. Neutralised to the
same midnight-tint as .entity-type-chip; the office name carries the
information. Per-office classes stay on the markup for future signal use. */
.office-chip {
background: rgb(var(--hlc-midnight-rgb) / 0.06);
color: var(--color-text);
}
.entity-status-chip {
background: var(--status-neutral-bg);
color: var(--status-neutral-fg-3);
}
/* F-23: hide STATUS column when every visible row shares the same value.
Toggled at render time by deadlines.ts / projects.ts. The header and cell
stay in the DOM so the column reappears the moment filters re-introduce
variety. */
.entity-table--hide-status .entity-col-status {
display: none;
}
.entity-status-active {
background: var(--status-green-bg);
color: var(--status-green-fg);
}
.entity-status-completed {
background: var(--status-blue-bg);
color: var(--status-blue-fg);
}
.entity-status-archived {
background: var(--status-neutral-bg);
color: var(--status-neutral-fg);
}
.firmwide-chip {
background: var(--hlc-lime);
color: var(--hlc-midnight);
}
.firmwide-dot {
color: var(--color-accent-fg);
font-size: 0.95em;
margin-left: 0.4rem;
}
.entity-empty {
text-align: center;
padding: 3rem 1.5rem;
border: 1px dashed var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text-muted);
}
.entity-empty h2 {
font-size: 1.15rem;
color: var(--color-text);
margin-bottom: 0.5rem;
}
.entity-empty .btn-cta-lime {
margin-top: 1rem;
}
.entity-empty-filtered {
padding: 2rem 1.5rem;
}
/* --- Project tree view (Baumansicht) --- */
.projekt-tree-wrap {
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
box-shadow: var(--shadow);
padding: 0.5rem 0.75rem;
}
.projekt-tree-loading,
.projekt-tree-error,
.projekt-tree-empty,
.projekt-tree-unavailable {
padding: 1.5rem 1rem;
color: var(--color-text-muted);
font-size: 0.9rem;
text-align: center;
}
.projekt-tree-error,
.projekt-tree-unavailable {
color: #92400e;
}
.projekt-tree-root,
.projekt-tree-children {
list-style: none;
margin: 0;
padding: 0;
}
.projekt-tree-children {
padding-left: 1.5rem;
border-left: 1px dashed var(--color-border);
margin-left: 1.1rem;
}
.projekt-tree-row {
display: flex;
align-items: center;
gap: 0.55rem;
padding: 0.4rem 0.5rem;
border-radius: 6px;
cursor: pointer;
transition: background 0.08s ease;
}
.projekt-tree-row:hover {
background: var(--color-bg-lime-tint);
}
.projekt-tree-row:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 1px;
background: var(--color-bg-lime-tint);
}
.projekt-tree-toggle {
width: 1.2rem;
height: 1.2rem;
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
color: var(--color-text-muted);
cursor: pointer;
padding: 0;
border-radius: 3px;
transition: transform 0.15s ease, background 0.1s ease;
}
.projekt-tree-toggle svg {
width: 0.9rem;
height: 0.9rem;
}
.projekt-tree-toggle:hover {
background: rgb(var(--hlc-lime-rgb) / 0.18);
color: var(--color-text);
}
.projekt-tree-toggle.is-open svg {
transform: rotate(90deg);
}
.projekt-tree-toggle.is-leaf {
cursor: default;
pointer-events: none;
}
.projekt-tree-icon {
width: 1.1rem;
height: 1.1rem;
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--color-text-muted);
}
.projekt-tree-icon svg {
width: 100%;
height: 100%;
}
.projekt-tree-icon-client { color: var(--tree-icon-client); }
.projekt-tree-icon-litigation { color: var(--tree-icon-litigation); }
.projekt-tree-icon-patent { color: var(--tree-icon-patent); }
.projekt-tree-icon-case { color: var(--tree-icon-case); }
.projekt-tree-icon-project { color: var(--tree-icon-project); }
.projekt-tree-title {
font-weight: 600;
color: var(--color-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 28rem;
}
.projekt-tree-type-chip {
flex: 0 0 auto;
font-size: 0.7rem;
padding: 0.1rem 0.5rem;
border-radius: 999px;
background: var(--status-neutral-bg);
color: var(--status-neutral-fg-2);
font-weight: 600;
}
/* Project-type chips were per-type saturated random colours — lavender,
pink-red, cyan, salmon, neutral-green — that carried no semantic ranking
and made /projects feel alarming. F-16 collapses them to one calm
midnight-tint chip and lets the type label inside the chip carry the
differentiation. The per-type modifier classes are kept on the markup so
future signal-use (e.g. highlighting Mandant roots) can re-introduce a
colour for one specific type without re-adding the random palette. */
.entity-type-chip {
display: inline-block;
padding: 0.15rem 0.55rem;
font-size: 0.72rem;
font-weight: 600;
border-radius: 999px;
white-space: nowrap;
background: rgb(var(--hlc-midnight-rgb) / 0.06);
color: var(--color-text);
}
.projekt-tree-meta {
font-size: 0.8rem;
color: var(--color-text-muted);
font-family: var(--font-mono);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.projekt-tree-spacer {
flex: 1 1 auto;
}
.projekt-tree-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 1.3rem;
height: 1.3rem;
padding: 0 0.4rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 700;
line-height: 1;
}
.projekt-tree-badge-overdue {
background: var(--status-red-bg);
color: var(--status-red-fg);
}
.projekt-tree-badge-open {
background: var(--status-amber-bg);
color: var(--status-amber-fg);
}
.projekt-tree-status {
flex: 0 0 auto;
}
.projekt-tree-node[aria-current="true"] > .projekt-tree-row {
background: rgb(var(--hlc-lime-rgb) / 0.2);
border-left: 3px solid var(--color-accent);
padding-left: calc(0.5rem - 3px);
}
@media (max-width: 720px) {
.projekt-tree-meta,
.projekt-tree-status {
display: none;
}
.projekt-tree-title {
max-width: 14rem;
}
}
/* --- Akten create form --- */
.container-narrow {
max-width: 680px;
}
.back-link {
display: inline-block;
margin-bottom: 0.75rem;
font-size: 0.85rem;
color: var(--color-text-muted);
text-decoration: none;
}
.back-link:hover {
color: var(--color-accent-fg);
}
.entity-form {
display: flex;
flex-direction: column;
gap: 1.25rem;
margin-top: 1.5rem;
}
.form-field-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
@media (max-width: 640px) {
.form-field-row {
grid-template-columns: 1fr;
}
}
.form-checkbox {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
user-select: none;
}
.form-checkbox input {
width: 1rem;
height: 1rem;
cursor: pointer;
}
.form-hint {
font-size: 0.78rem;
color: var(--color-text-muted);
margin-top: 0.25rem;
}
.collab-picker {
position: relative;
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 0.4rem;
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
align-items: center;
background: var(--color-surface);
}
.collab-picker input {
flex: 1;
min-width: 160px;
border: none !important;
padding: 0.3rem 0.5rem !important;
outline: none !important;
background: transparent !important;
}
.collab-chips {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
}
.entity-chip {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.2rem 0.6rem;
font-size: 0.8rem;
background: var(--status-blue-soft-bg);
color: var(--status-blue-soft-fg);
border-radius: 999px;
}
.entity-chip-x {
background: none;
border: none;
color: inherit;
cursor: pointer;
font-size: 0.9rem;
line-height: 1;
padding: 0;
}
.collab-suggestions {
position: absolute;
top: 100%;
left: 0;
right: 0;
margin-top: 0.25rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
max-height: 240px;
overflow-y: auto;
display: none;
z-index: 10;
}
.entity-suggestion {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0.75rem;
border: none;
background: var(--color-surface);
text-align: left;
font-size: 0.85rem;
cursor: pointer;
}
.entity-suggestion:hover {
background: var(--color-bg-lime-tint);
}
.entity-suggestion-meta {
color: var(--color-text-muted);
font-size: 0.75rem;
margin-left: 0.75rem;
}
/* --- Akten detail --- */
.entity-detail-header {
padding: 1rem 0;
border-bottom: 1px solid var(--color-border);
margin-bottom: 1rem;
}
.entity-detail-title-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1rem;
flex-wrap: wrap;
}
.entity-detail-title-col h1 {
font-size: 1.6rem;
margin-bottom: 0.3rem;
}
.entity-title-input {
font-size: 1.6rem;
font-weight: 700;
padding: 0.25rem 0.4rem;
border: 1px solid var(--color-accent);
border-radius: var(--radius);
width: 100%;
max-width: 520px;
}
.entity-detail-meta {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
margin-top: 0.4rem;
}
.entity-ref {
font-family: var(--font-mono);
font-size: 0.85rem;
color: var(--color-text-muted);
margin-right: 0.25rem;
}
.entity-detail-actions {
display: flex;
gap: 0.5rem;
align-items: center;
}
.btn-icon {
width: 36px;
height: 36px;
border-radius: var(--radius);
border: 1px solid var(--color-border);
background: var(--color-surface);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--color-text-muted);
transition: border-color 0.15s ease, color 0.15s ease;
}
.btn-icon:hover {
border-color: var(--color-accent);
color: var(--color-accent-fg);
}
.entity-tabs {
display: flex;
gap: 0.25rem;
margin-bottom: 1rem;
border-bottom: 1px solid var(--color-border);
overflow-x: auto;
}
.entity-tab {
padding: 0.6rem 1rem;
text-decoration: none;
color: var(--color-text-muted);
font-size: 0.88rem;
font-weight: 500;
border-bottom: 2px solid transparent;
white-space: nowrap;
transition: color 0.12s ease, border-color 0.12s ease;
}
.entity-tab:hover {
color: var(--color-text);
}
.entity-tab.active {
color: var(--color-text);
border-bottom-color: var(--hlc-lime);
font-weight: 600;
}
.entity-tab-panel {
padding: 0.5rem 0 2rem;
}
.entity-events {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.entity-event {
display: grid;
grid-template-columns: 170px 1fr;
gap: 1rem;
padding: 0.75rem 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
box-shadow: var(--shadow);
}
@media (max-width: 640px) {
.entity-event {
grid-template-columns: 1fr;
}
}
/* Card-wide affordance when the event has a deep-link (deadline/appointment/
note/checklist). Cursor + hover-lift telegraph "clickable row"; the actual
navigation is wired by a row-level click handler in projects-detail.ts that
skips inner <a>/<button> so the title link, action buttons, and text
selection all keep working — same pattern as .entity-table (t-098/099).
Replaces the t-102 ::before overlay, which captured pointer events on the
text and broke select-to-copy (t-paliad-103). */
.entity-event:has(.entity-event-link) {
cursor: pointer;
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.entity-event:has(.entity-event-link):hover,
.entity-event:has(.entity-event-link:focus-visible) {
border-color: var(--color-accent-fg);
box-shadow: var(--shadow-hover, var(--shadow));
}
.entity-event-date {
font-size: 0.8rem;
color: var(--color-text-muted);
font-family: var(--font-mono);
}
.entity-event-title {
font-weight: 600;
font-size: 0.9rem;
}
/* When the event title is wrapped in a link (checklist/deadline/appointment/
note_created — see wrapEventTitleLink in projects-detail.ts), the title text
inherits the parent's weight/colour. The link is the canonical, keyboard-
reachable target; the surrounding .entity-event card grows the click surface
via a row-level handler in projects-detail.ts (t-103). */
.entity-event-link {
color: inherit;
text-decoration: none;
}
.entity-event-link:hover {
color: var(--color-accent-fg);
text-decoration: underline;
}
/* Link's own focus ring is suppressed — the card-level rule above
(.entity-event:has(.entity-event-link:focus-visible)) lifts the whole card
instead, which matches the row-click click surface. */
.entity-event-link:focus-visible {
outline: none;
}
.entity-event-desc {
font-size: 0.85rem;
color: var(--color-text-muted);
margin-top: 0.25rem;
}
.entity-events-empty {
text-align: center;
padding: 2rem 1rem;
color: var(--color-text-muted);
font-size: 0.9rem;
}
.entity-empty-card {
text-align: center;
padding: 2rem 1rem;
color: var(--color-text-muted);
font-size: 0.9rem;
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
.entity-empty-card p {
margin: 0;
}
.entity-events-loadmore {
margin-top: 1rem;
text-align: center;
}
.party-controls {
margin-bottom: 1rem;
}
.btn-small {
padding: 0.4rem 0.9rem;
font-size: 0.82rem;
}
.party-form {
margin-bottom: 1.25rem;
padding: 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
gap: 0.75rem;
}
.party-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: hidden;
background: var(--color-surface);
}
.party-table thead th {
text-align: left;
padding: 0.6rem 1rem;
font-size: 0.72rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--color-text-muted);
border-bottom: 1px solid var(--color-border);
background: var(--color-bg-subtle);
}
.party-table td {
padding: 0.6rem 1rem;
border-bottom: 1px solid var(--color-border);
}
.party-table tr:last-child td {
border-bottom: none;
}
.entity-col-actions {
text-align: right;
}
.btn-link-danger {
background: none;
border: none;
color: #b91c1c;
cursor: pointer;
font-size: 0.82rem;
padding: 0.2rem 0.5rem;
}
.btn-link-danger:hover {
text-decoration: underline;
}
.btn-danger {
padding: 0.5rem 1.25rem;
font-size: 0.85rem;
font-weight: 600;
color: #fff;
background: #dc2626;
border: none;
border-radius: var(--radius);
cursor: pointer;
transition: background 0.15s ease;
}
.btn-danger:hover {
background: #b91c1c;
}
.entity-soon {
text-align: center;
padding: 3rem 1.5rem;
border: 1px dashed var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
}
.entity-soon h2 {
font-size: 1.1rem;
color: var(--color-text);
margin-bottom: 0.5rem;
}
.entity-soon p {
color: var(--color-text-muted);
font-size: 0.9rem;
}
.entity-detail-footer {
margin-top: 2.5rem;
padding-top: 1.5rem;
border-top: 1px solid var(--color-border);
display: flex;
justify-content: flex-end;
}
.entity-loading {
text-align: center;
padding: 3rem;
color: var(--color-text-muted);
font-size: 0.9rem;
}
/* ========================================================================
Phase E — Fristen (persistent deadlines)
Traffic-light: red overdue, amber soon, green later. Done = grey.
======================================================================== */
:root {
--frist-red: #ef4444;
--frist-amber: #f59e0b;
--frist-green: #22c55e;
--frist-grey: #9ca3af;
/* 5-bucket deadline-summary palette (t-paliad-108). Drives both the
Dashboard "Fristen auf einen Blick" cards (.dashboard-card-*) and
the /deadlines summary cards (.frist-card-*) so the urgency
hierarchy reads identically on both surfaces:
red → orange → yellow → green → grey
Each bucket is visually distinct from its neighbours. Light values
pass WCAG AA-large (3:1+) on the white surface for the colored
count (1.62.25rem, 600700 weight = large text). The Überfällig
alarm rule (saturated red bg + white text) overrides this when
overdue > 0; see the .dashboard-card-alarm block below. */
--bucket-overdue: #ef4444;
--bucket-today: #c2410c;
--bucket-week: #a16207;
--bucket-next-week: #16a34a;
--bucket-later: #1d4ed8;
--bucket-done: #6b7280;
}
:root[data-theme="dark"] {
--bucket-overdue: #fca5a5;
--bucket-today: #fb923c;
--bucket-week: #fbbf24;
--bucket-next-week: #4ade80;
--bucket-later: #60a5fa;
--bucket-done: #9ca3af;
}
.fristen-header-actions {
display: flex;
gap: 0.5rem;
align-items: center;
}
.frist-summary-cards {
/* auto-fit so the row re-flows when a card is hidden (Überfällig is
hidden when the count is zero — see t-paliad-105). With explicit
`repeat(4, …)` a hidden card leaves an empty 4th column. */
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 0.75rem;
margin: 0 0 1.5rem;
}
.frist-summary-card {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.35rem;
padding: 0.9rem 1rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-left-width: 4px;
border-radius: var(--radius);
cursor: pointer;
text-align: left;
transition: background 0.12s ease, transform 0.12s ease;
font: inherit;
}
.frist-summary-card:hover {
background: var(--color-bg-subtle);
transform: translateY(-1px);
}
.frist-summary-card .frist-summary-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: currentColor;
opacity: 0.65;
}
.frist-summary-count {
font-size: 1.6rem;
font-weight: 600;
line-height: 1;
color: var(--color-text);
}
.frist-summary-label {
font-size: 0.85rem;
color: var(--color-text-muted);
}
.frist-card-overdue { border-left-color: var(--bucket-overdue); color: var(--bucket-overdue); }
.frist-card-today { border-left-color: var(--bucket-today); color: var(--bucket-today); }
.frist-card-week { border-left-color: var(--bucket-week); color: var(--bucket-week); }
.frist-card-next-week { border-left-color: var(--bucket-next-week); color: var(--bucket-next-week); }
.frist-card-upcoming { border-left-color: var(--bucket-next-week); color: var(--bucket-next-week); }
.frist-card-later { border-left-color: var(--bucket-later); color: var(--bucket-later); }
.frist-card-completed { border-left-color: var(--bucket-done); color: var(--bucket-done); }
.fristen-table .frist-col-check {
width: 28px;
padding-right: 0;
}
.fristen-table .frist-col-due {
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
.fristen-table .frist-col-rule {
color: var(--color-text-muted);
font-size: 0.85rem;
}
.frist-due-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 0.4rem;
vertical-align: middle;
background: var(--frist-grey);
}
.frist-urgency-overdue { color: var(--frist-red); }
.frist-urgency-overdue .frist-due-dot { background: var(--frist-red); }
.frist-urgency-soon { color: var(--frist-amber); }
.frist-urgency-soon .frist-due-dot { background: var(--frist-amber); }
.frist-urgency-later { color: var(--frist-green); }
.frist-urgency-later .frist-due-dot { background: var(--frist-green); }
.frist-urgency-done { color: var(--frist-grey); text-decoration: line-through; }
.frist-urgency-done .frist-due-dot { background: var(--frist-grey); }
.frist-title-done {
text-decoration: line-through;
color: var(--color-text-muted);
}
.frist-reopen-btn {
background: transparent;
border: 1px solid transparent;
color: var(--color-text-muted);
font-size: 1rem;
line-height: 1;
width: 24px;
height: 24px;
border-radius: 4px;
cursor: pointer;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.frist-reopen-btn:hover {
color: var(--color-accent-fg);
border-color: var(--color-accent, var(--color-accent));
background: rgb(var(--hlc-lime-rgb) / 0.08);
}
.frist-reopen-btn:disabled {
cursor: default;
opacity: 0.5;
}
.entity-ref-link {
color: var(--color-text);
text-decoration: none;
font-weight: 500;
}
.entity-ref-link:hover {
text-decoration: underline;
}
.frist-project-title {
display: block;
color: var(--color-text-muted);
font-size: 0.8rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 22rem;
}
.frist-due-chip {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.2rem 0.6rem;
border-radius: 999px;
background: var(--status-neutral-bg);
color: var(--color-text);
font-size: 0.85rem;
font-weight: 500;
}
.frist-due-chip.frist-urgency-overdue { background: var(--status-red-bg); color: var(--status-red-fg); }
.frist-due-chip.frist-urgency-soon { background: var(--status-amber-bg); color: var(--status-amber-fg); }
.frist-due-chip.frist-urgency-later { background: var(--status-green-bg); color: var(--status-green-fg); }
.frist-due-chip.frist-urgency-done { background: var(--status-neutral-bg); color: var(--status-neutral-fg); text-decoration: none; }
.entity-status-chip.entity-status-pending { background: var(--status-amber-bg); color: var(--status-amber-fg); }
.entity-status-chip.entity-status-cancelled { background: var(--status-neutral-bg); color: var(--status-neutral-fg); }
.entity-status-chip.entity-status-waived { background: var(--status-neutral-bg); color: var(--status-neutral-fg); }
.frist-detail-panel {
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 1.5rem;
background: var(--color-surface);
}
.frist-detail-list {
display: grid;
grid-template-columns: max-content 1fr;
column-gap: 1.5rem;
row-gap: 0.75rem;
margin: 0;
}
.frist-detail-list dt {
font-weight: 600;
color: var(--color-text-muted);
font-size: 0.85rem;
}
.frist-detail-list dd {
margin: 0;
color: var(--color-text);
}
.frist-detail-list textarea,
.frist-detail-list input[type="date"] {
width: 100%;
max-width: 22rem;
}
/* Calendar view */
.frist-calendar-controls {
display: flex;
align-items: center;
gap: 0.75rem;
margin: 0 0 1rem;
}
.frist-cal-month-label {
font-size: 1.15rem;
margin: 0;
min-width: 11rem;
text-align: center;
}
.frist-calendar {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 1px;
background: var(--color-border);
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: hidden;
}
.frist-cal-weekday {
background: var(--color-surface-2);
color: var(--color-text-muted);
font-size: 0.78rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.4rem 0.6rem;
text-align: center;
}
.frist-cal-grid {
grid-column: 1 / -1;
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 1px;
background: var(--color-border);
}
.frist-cal-cell {
background: var(--color-surface);
min-height: 88px;
padding: 0.4rem 0.5rem;
display: flex;
flex-direction: column;
justify-content: space-between;
cursor: default;
}
.frist-cal-cell-empty {
background: var(--color-bg-subtle);
}
.frist-cal-cell-has {
cursor: pointer;
}
.frist-cal-cell-has:hover {
background: var(--color-bg-lime-tint);
}
.frist-cal-day {
font-size: 0.8rem;
color: var(--color-text-muted);
font-variant-numeric: tabular-nums;
}
.frist-cal-today .frist-cal-day {
background: var(--color-accent);
color: var(--color-accent-dark);
border-radius: 999px;
width: 1.5rem;
height: 1.5rem;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 600;
}
.frist-cal-dots {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 3px;
}
.frist-cal-dot {
display: inline-block;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--frist-grey);
}
.frist-cal-dot.frist-urgency-overdue { background: var(--frist-red); }
.frist-cal-dot.frist-urgency-soon { background: var(--frist-amber); }
.frist-cal-dot.frist-urgency-later { background: var(--frist-green); }
.frist-cal-dot.frist-urgency-done { background: var(--frist-grey); }
.frist-cal-more {
font-size: 0.7rem;
color: var(--color-text-muted);
margin-left: 0.2rem;
}
.frist-cal-popup-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.frist-cal-popup-item {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 0.6rem;
padding: 0.4rem 0;
border-bottom: 1px solid var(--color-border);
}
.frist-cal-popup-item:last-child {
border-bottom: none;
}
.frist-cal-popup-title {
color: var(--color-text);
text-decoration: none;
font-weight: 500;
}
.frist-cal-popup-title:hover {
text-decoration: underline;
}
.frist-cal-popup-akte {
color: var(--color-text-muted);
font-size: 0.8rem;
text-decoration: none;
}
.frist-cal-popup-akte:hover {
color: var(--color-text);
}
/* Fristenrechner save-to-Akte modal */
.fristen-result-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 1rem;
}
.frist-save-list {
list-style: none;
margin: 0;
padding: 0;
max-height: 16rem;
overflow-y: auto;
border: 1px solid var(--color-border);
border-radius: var(--radius);
}
.frist-save-row {
border-bottom: 1px solid var(--color-border);
}
.frist-save-row:last-child {
border-bottom: none;
}
.frist-save-row label {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.5rem 0.75rem;
cursor: pointer;
margin: 0;
}
.frist-save-row input[type="checkbox"]:disabled + .frist-save-title {
color: var(--color-text-muted);
text-decoration: line-through;
}
.frist-save-title {
flex: 1;
color: var(--color-text);
}
.frist-save-meta {
color: var(--color-text-muted);
font-size: 0.8rem;
font-variant-numeric: tabular-nums;
}
.form-msg-ok {
color: #166534;
}
@media (max-width: 700px) {
.frist-summary-cards {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.frist-cal-cell {
min-height: 64px;
}
}
/* ========================================================================
Dashboard (Phase G — logged-in landing)
======================================================================== */
.dashboard-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 1rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
}
.dashboard-greeting {
font-size: 1.6rem;
font-weight: 600;
letter-spacing: -0.02em;
margin: 0;
}
.dashboard-greeting-name {
color: var(--color-accent-fg);
}
.dashboard-subline {
margin-top: 0.4rem;
display: flex;
align-items: center;
gap: 0.75rem;
color: var(--color-text-muted);
font-size: 0.88rem;
}
.dashboard-office-chip {
margin-right: 0.25rem;
}
.dashboard-date {
text-transform: capitalize;
}
.dashboard-section-heading {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin-bottom: 0.75rem;
font-weight: 600;
}
.dashboard-unavailable {
padding: 1rem 1.25rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--status-amber-bg);
color: var(--status-amber-fg);
margin-bottom: 1.5rem;
font-size: 0.92rem;
}
/* --- Traffic-light summary cards --- */
.dashboard-summary {
margin-bottom: 2rem;
}
.dashboard-summary-grid {
/* auto-fit so the row re-flows when a card is hidden (Überfällig is
hidden when the count is zero — see t-paliad-105). */
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1rem;
}
.dashboard-card {
display: block;
padding: 1.25rem 1.4rem;
border-radius: var(--radius);
background: var(--color-surface);
border: 1px solid var(--color-border);
text-decoration: none;
color: var(--color-text);
transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
box-shadow: var(--shadow);
}
.dashboard-card:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.dashboard-card-count {
font-family: var(--font-mono);
font-size: 2.25rem;
font-weight: 700;
line-height: 1.1;
letter-spacing: -0.03em;
}
.dashboard-card-label {
margin-top: 0.4rem;
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 600;
color: var(--color-text-muted);
}
/* 5-bucket urgency cards — palette shared with .frist-card-* via the
--bucket-* tokens (t-paliad-108). The .dashboard-card-amber class name
is historical (was amber-only pre-t-paliad-106); it now drives the
"Diese Woche" yellow bucket. */
.dashboard-card-red .dashboard-card-count { color: var(--bucket-overdue); }
.dashboard-card-red { border-left: 3px solid var(--bucket-overdue); }
.dashboard-card-today .dashboard-card-count { color: var(--bucket-today); }
.dashboard-card-today { border-left: 3px solid var(--bucket-today); }
.dashboard-card-amber .dashboard-card-count { color: var(--bucket-week); }
.dashboard-card-amber { border-left: 3px solid var(--bucket-week); }
.dashboard-card-green .dashboard-card-count { color: var(--bucket-next-week); }
.dashboard-card-green { border-left: 3px solid var(--bucket-next-week); }
.dashboard-card-done .dashboard-card-count { color: var(--bucket-done); }
.dashboard-card-done { border-left: 3px solid var(--bucket-done); }
/* Später bucket on the Fristen rail — muted blue (t-paliad-110). */
.dashboard-card-later .dashboard-card-count { color: var(--bucket-later); }
.dashboard-card-later { border-left: 3px solid var(--bucket-later); }
/* Termine rail uses the same urgency token family — keep the palette
consistent across rails so users read both at the same glance. */
.dashboard-card-appt-today .dashboard-card-count { color: var(--bucket-today); }
.dashboard-card-appt-today { border-left: 3px solid var(--bucket-today); }
.dashboard-card-appt-week .dashboard-card-count { color: var(--bucket-week); }
.dashboard-card-appt-week { border-left: 3px solid var(--bucket-week); }
.dashboard-card-appt-later .dashboard-card-count { color: var(--bucket-later); }
.dashboard-card-appt-later { border-left: 3px solid var(--bucket-later); }
/* Überfällig alarm — see t-paliad-105 / t-paliad-106.
When overdue > 0 the card flips from a calm border-left accent to a
saturated red surface with bold white text and a pulsing ring. The matching
JS toggles `.dashboard-card-alarm` (Dashboard) and `.frist-card-alarm`
(Fristen); when overdue === 0 the card is hidden entirely. Uses the pulse
animation only (no static glow) to stay below the visual-noise threshold
the spec calls for. */
@keyframes paliad-alarm-pulse {
0%, 100% { box-shadow: 0 0 0 0 rgb(220 38 38 / 0.55); }
50% { box-shadow: 0 0 0 12px rgb(220 38 38 / 0); }
}
.dashboard-card-red.dashboard-card-alarm,
.frist-summary-card.frist-card-overdue.frist-card-alarm {
background: #dc2626;
color: #ffffff;
border-color: #991b1b;
border-left-color: #7f1d1d;
animation: paliad-alarm-pulse 1.8s ease-in-out infinite;
}
.dashboard-card-red.dashboard-card-alarm .dashboard-card-count,
.dashboard-card-red.dashboard-card-alarm .dashboard-card-label,
.frist-summary-card.frist-card-overdue.frist-card-alarm .frist-summary-count,
.frist-summary-card.frist-card-overdue.frist-card-alarm .frist-summary-label {
color: #ffffff;
font-weight: 700;
}
.frist-summary-card.frist-card-overdue.frist-card-alarm .frist-summary-dot {
background: #ffffff;
opacity: 1;
}
.dashboard-card-overdue-hidden,
.frist-card-overdue-hidden {
display: none;
}
@media (prefers-reduced-motion: reduce) {
.dashboard-card-red.dashboard-card-alarm,
.frist-summary-card.frist-card-overdue.frist-card-alarm {
animation: none;
}
}
:root[data-theme="dark"] .dashboard-card-red.dashboard-card-alarm,
:root[data-theme="dark"] .frist-summary-card.frist-card-overdue.frist-card-alarm {
background: #ef4444;
border-color: #f87171;
border-left-color: #fca5a5;
}
/* --- Matter summary card --- */
.dashboard-matters {
margin-bottom: 2rem;
}
.dashboard-matter-card {
display: block;
padding: 1.25rem 1.5rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
text-decoration: none;
color: var(--color-text);
box-shadow: var(--shadow);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dashboard-matter-card:hover {
border-color: var(--color-accent-light);
box-shadow: var(--shadow-md);
}
.dashboard-matter-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.9rem;
}
.dashboard-matter-header h3 {
font-size: 0.95rem;
font-weight: 600;
margin: 0;
}
.dashboard-matter-arrow {
color: var(--color-accent-fg);
font-size: 1.1rem;
}
.dashboard-matter-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.dashboard-matter-num {
font-family: var(--font-mono);
font-size: 1.5rem;
font-weight: 700;
line-height: 1.1;
color: var(--color-text);
}
.dashboard-matter-lbl {
margin-top: 0.25rem;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--color-text-muted);
}
/* --- Two-column lists --- */
.dashboard-columns {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin-bottom: 2.5rem;
}
.dashboard-col {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 1.25rem 1.4rem;
box-shadow: var(--shadow);
/* Grid items default to min-width: auto, which sizes to min-content.
Without this, the nowrap title/ref strings inside .dashboard-list-link
force the column wider than its grid track and overflow the page on
narrow viewports. */
min-width: 0;
}
.dashboard-list {
list-style: none;
margin: 0;
padding: 0;
}
.dashboard-list-item {
border-bottom: 1px solid var(--color-border);
}
.dashboard-list-item:last-child {
border-bottom: none;
}
.dashboard-list-link {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.75rem 0;
text-decoration: none;
color: var(--color-text);
transition: color 0.1s ease;
}
.dashboard-list-link:hover {
color: var(--color-accent-fg);
}
.dashboard-list-main {
display: flex;
flex-direction: column;
gap: 0.15rem;
min-width: 0;
}
.dashboard-list-title {
font-weight: 600;
font-size: 0.92rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dashboard-list-ref {
font-size: 0.78rem;
color: var(--color-text-muted);
font-family: var(--font-mono);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dashboard-list-meta {
flex-shrink: 0;
}
.dashboard-urgency-badge {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 600;
white-space: nowrap;
}
.dashboard-urgency-overdue { background: var(--status-red-bg); color: var(--status-red-fg); }
.dashboard-urgency-today { background: var(--status-amber-bg); color: var(--status-amber-fg); }
.dashboard-urgency-urgent { background: var(--status-amber-bg); color: var(--status-amber-fg-2); }
.dashboard-urgency-soon { background: var(--status-green-soft-bg); color: var(--status-green-soft-fg); }
.dashboard-appt-time {
font-family: var(--font-mono);
font-size: 0.82rem;
color: var(--color-text-muted);
white-space: nowrap;
}
.dashboard-termin-dot {
display: inline-block;
width: 0.55rem;
height: 0.55rem;
border-radius: 999px;
background: #94a3b8;
margin-right: 0.5rem;
vertical-align: middle;
}
.dashboard-termin-hearing { background: #b91c1c; }
.dashboard-termin-meeting { background: #2563eb; }
.dashboard-termin-consultation { background: var(--color-accent); }
.dashboard-termin-deadline_hearing { background: #b45309; }
.dashboard-empty {
padding: 1.5rem 0.5rem;
color: var(--color-text-muted);
font-size: 0.88rem;
font-style: italic;
}
/* --- Activity feed --- */
.dashboard-activity {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 1.25rem 1.4rem;
box-shadow: var(--shadow);
margin-bottom: 3rem;
}
.dashboard-activity-list {
list-style: none;
margin: 0;
padding: 0;
}
/* Whole row is the click surface (row-handler in dashboard.ts t-paliad-103);
inner .dashboard-activity-project link still wins for Cmd-click and keyboard
tabbing, and text selection works because there's no overlay. */
.dashboard-activity-item {
display: grid;
grid-template-columns: 8.5rem 1fr;
gap: 0.75rem;
padding: 0.6rem 0;
border-bottom: 1px solid var(--color-border);
font-size: 0.88rem;
cursor: pointer;
transition: background 0.08s ease;
}
.dashboard-activity-item:hover {
background: var(--color-bg-lime-tint);
}
.dashboard-activity-item:last-child {
border-bottom: none;
}
.dashboard-activity-time {
font-family: var(--font-mono);
font-size: 0.78rem;
color: var(--color-text-muted);
white-space: nowrap;
}
.dashboard-activity-body {
display: flex;
flex-direction: column;
gap: 0.15rem;
min-width: 0;
}
.dashboard-activity-summary {
margin: 0;
color: var(--color-text);
line-height: 1.35;
}
.dashboard-activity-summary strong {
font-weight: 600;
margin-right: 0.3rem;
}
.dashboard-activity-detail {
margin: 0;
color: var(--color-text-muted);
font-size: 0.82rem;
line-height: 1.35;
}
.dashboard-activity-project {
font-family: var(--font-mono);
color: var(--color-accent-fg);
text-decoration: none;
margin-right: 0.4rem;
}
.dashboard-activity-project:hover {
text-decoration: underline;
}
/* --- Responsive --- */
@media (max-width: 900px) {
.dashboard-summary-grid {
grid-template-columns: repeat(2, 1fr);
}
.dashboard-columns {
grid-template-columns: 1fr;
}
.dashboard-matter-stats {
grid-template-columns: repeat(3, 1fr);
}
.dashboard-activity-item {
grid-template-columns: 1fr;
gap: 0.2rem;
}
}
/* ============================================================================
* Phase F — Termine + CalDAV
* ============================================================================ */
/* Type colours match the dashboard set so dots/chips/badges stay coherent.
Keyed by termin_type so adding a new type only needs one block. */
.termin-dot {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: #94a3b8;
margin-right: 0.4rem;
vertical-align: middle;
}
.termin-type-hearing { background: #b91c1c; color: #b91c1c; }
.termin-type-meeting { background: #2563eb; color: #2563eb; }
.termin-type-consultation { background: var(--color-accent); color: var(--color-accent-fg); }
.termin-type-deadline_hearing { background: #b45309; color: #b45309; }
.termin-type-default { background: #94a3b8; color: #64748b; }
.termin-type-chip {
display: inline-block;
padding: 0.15rem 0.55rem;
border-radius: 999px;
font-size: 0.78rem;
font-weight: 600;
background: var(--color-overlay-faint);
color: inherit;
}
.termin-type-chip.termin-type-hearing { background: rgba(185, 28, 28, 0.10); }
.termin-type-chip.termin-type-meeting { background: rgba(37, 99, 235, 0.10); }
.termin-type-chip.termin-type-consultation { background: rgb(var(--hlc-lime-rgb) / 0.10); }
.termin-type-chip.termin-type-deadline_hearing { background: rgba(180, 83, 9, 0.12); }
.termin-type-badge {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 6px;
font-size: 0.78rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
background: var(--color-overlay-subtle);
color: var(--color-text-muted);
margin-bottom: 0.5rem;
}
.termin-type-badge.termin-type-hearing { background: rgba(185, 28, 28, 0.12); color: #b91c1c; }
.termin-type-badge.termin-type-meeting { background: rgba(37, 99, 235, 0.12); color: #2563eb; }
.termin-type-badge.termin-type-consultation { background: rgb(var(--hlc-lime-rgb) / 0.12); color: var(--hlc-midnight); }
.termin-type-badge.termin-type-deadline_hearing { background: rgba(180, 83, 9, 0.14); color: #92400e; }
.termin-personal-tag {
display: inline-block;
padding: 0.1rem 0.5rem;
border-radius: 4px;
background: var(--color-overlay-faint);
color: var(--color-text-muted);
font-size: 0.78rem;
}
/* Summary cards reuse .frist-summary-card; just colour them appropriately. */
.termin-card-today { border-left-color: #b45309; color: #b45309; }
.termin-card-week { border-left-color: #2563eb; color: #2563eb; }
.termin-card-later { border-left-color: #475569; color: #475569; }
.termin-card-today .frist-summary-dot { background: #b45309; }
.termin-card-week .frist-summary-dot { background: #2563eb; }
.termin-card-later .frist-summary-dot { background: #475569; }
.termin-cal-legend {
display: flex;
gap: 1.2rem;
flex-wrap: wrap;
margin: 0.5rem 0 1rem;
color: #475569;
font-size: 0.85rem;
}
.termin-cal-legend-item {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
/* Calendar popup: extra time column for termine (vs. the deadline popup). */
.frist-cal-popup-time {
color: #475569;
font-variant-numeric: tabular-nums;
margin-right: 0.5rem;
}
/* CalDAV settings page */
.caldav-status-card {
background: var(--color-surface-muted);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 0.8rem 1rem;
margin-bottom: 1.5rem;
}
.caldav-status-row {
display: flex;
gap: 0.6rem;
align-items: baseline;
}
.caldav-status-label {
color: #64748b;
font-size: 0.85rem;
min-width: 11rem;
}
.caldav-status-value {
font-weight: 500;
}
.caldav-status-error {
color: #b91c1c;
font-family: ui-monospace, "SF Mono", Menlo, monospace;
font-size: 0.85rem;
word-break: break-word;
}
.caldav-toggle-field {
margin-top: 0.5rem;
}
label.caldav-toggle-label {
display: inline-flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
}
.caldav-actions {
display: flex;
gap: 0.6rem;
flex-wrap: wrap;
justify-content: flex-end;
}
.caldav-log-card {
margin-top: 2rem;
}
.caldav-log-card h2 {
font-size: 1.1rem;
margin-bottom: 0.6rem;
}
.caldav-log-table th,
.caldav-log-table td {
font-size: 0.85rem;
padding: 0.4rem 0.6rem;
}
/* ===== Settings page (t-paliad-022) ===== */
.settings-subhead {
font-size: 1rem;
font-weight: 600;
margin: 0 0 0.25rem;
}
.settings-sub-group {
margin-left: 1.5rem;
padding-top: 0.25rem;
border-left: 2px solid var(--color-border);
padding-left: 0.8rem;
transition: opacity 0.15s ease;
}
.settings-sub-group .form-field {
margin-bottom: 0.3rem;
}
/* ===== Notizen (polymorphic notes — Phase I) ===== */
.notiz-container {
display: flex;
flex-direction: column;
gap: 1rem;
}
.notiz-form {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
}
.notiz-form-editing {
border-color: var(--color-accent);
box-shadow: 0 0 0 2px rgb(var(--hlc-lime-rgb) / 0.15);
}
.notiz-textarea {
width: 100%;
box-sizing: border-box;
font: inherit;
padding: 0.5rem 0.6rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm, 4px);
background: var(--color-bg);
resize: vertical;
min-height: 3.5rem;
}
.notiz-textarea:focus {
outline: none;
border-color: var(--color-accent);
box-shadow: 0 0 0 2px rgb(var(--hlc-lime-rgb) / 0.2);
}
.notiz-form-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
}
.notiz-form-hint {
margin: 0.25rem 0 0;
font-size: 0.75rem;
color: var(--color-text-muted);
}
.notiz-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.notiz-card {
padding: 0.75rem 0.9rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
box-shadow: var(--shadow);
position: relative;
}
.notiz-card-header {
display: flex;
align-items: center;
gap: 0.6rem;
margin-bottom: 0.4rem;
font-size: 0.8rem;
color: var(--color-text-muted);
}
.notiz-author {
font-weight: 600;
color: var(--color-text);
}
.notiz-time {
font-family: var(--font-mono);
font-size: 0.75rem;
}
.notiz-actions {
margin-left: auto;
display: flex;
gap: 0.25rem;
}
.notiz-action-btn {
background: transparent;
border: none;
padding: 0.25rem;
cursor: pointer;
color: var(--color-text-muted);
border-radius: 4px;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background-color 0.15s, color 0.15s;
}
.notiz-action-btn:hover {
background: var(--color-bg);
color: var(--color-text);
}
.notiz-action-btn.notiz-action-danger:hover {
color: #dc2626;
}
.notiz-body {
font-size: 0.9rem;
line-height: 1.5;
color: var(--color-text);
white-space: pre-wrap;
word-break: break-word;
}
.notiz-body a {
color: var(--color-accent-fg);
text-decoration: underline;
word-break: break-all;
}
.notiz-edited {
display: inline-block;
margin-top: 0.4rem;
font-size: 0.7rem;
color: var(--color-text-muted);
font-style: italic;
}
.notiz-empty {
text-align: center;
padding: 1.5rem 1rem;
color: var(--color-text-muted);
font-size: 0.9rem;
}
.frist-notes-section,
.termin-notes-section {
margin-top: 2rem;
}
.frist-section-heading {
font-size: 1.1rem;
margin: 0 0 0.75rem 0;
color: var(--color-text);
}
/* --- Invitation modal (sidebar) --- */
.invite-modal-body {
color: var(--color-text-muted);
font-size: 0.9rem;
margin: 0 0 1rem 0;
line-height: 1.5;
}
#invite-modal .modal-card {
max-width: 480px;
}
#invite-modal textarea {
font-family: var(--font-sans);
resize: vertical;
min-height: 5rem;
}
/* --- Global search (t-paliad-026) --------------------------------------- */
.sidebar-search {
position: relative;
display: flex;
align-items: center;
min-height: 2.5rem;
margin-bottom: 0.35rem;
overflow: hidden;
}
.sidebar-search-icon {
color: var(--sidebar-text-muted);
pointer-events: none;
}
.sidebar-search-input {
flex: 1;
min-width: 0;
height: 2rem;
padding: 0 0.5rem;
font-size: 0.85rem;
font-family: var(--font-sans);
color: var(--sidebar-text);
background: var(--sidebar-input-bg);
border: 1px solid var(--sidebar-border);
border-radius: 6px;
outline: none;
opacity: 0;
pointer-events: none;
transition: border-color 150ms ease, opacity 150ms ease;
margin-right: 0.75rem;
}
.sidebar.expanded .sidebar-search-input,
.sidebar.pinned .sidebar-search-input,
.sidebar.mobile-open .sidebar-search-input {
opacity: 1;
pointer-events: auto;
}
.sidebar-search-input:focus {
border-color: var(--sidebar-text-active);
}
.sidebar-search-input::-webkit-search-cancel-button {
cursor: pointer;
}
.sidebar-search-kbd {
position: absolute;
right: 1.25rem;
font-family: var(--font-mono, monospace);
font-size: 0.7rem;
padding: 0.05rem 0.35rem;
border: 1px solid var(--sidebar-border);
border-radius: 3px;
color: var(--sidebar-text-muted);
background: var(--sidebar-input-bg);
opacity: 0;
pointer-events: none;
transition: opacity 150ms ease;
}
.sidebar.expanded .sidebar-search-kbd,
.sidebar.pinned .sidebar-search-kbd,
.sidebar.mobile-open .sidebar-search-kbd {
opacity: 1;
}
.sidebar-search-input:focus + .sidebar-search-kbd {
opacity: 0;
}
/* Results overlay: fixed to viewport, anchored just below the sidebar header
so it covers the nav items while results are visible. Width matches the
expanded sidebar on desktop and spills over slightly to fit long titles. */
.search-overlay {
position: fixed;
top: 6.75rem;
left: 0.5rem;
width: calc(var(--sidebar-width) - 1rem);
max-width: 420px;
max-height: calc(100vh - 8rem);
overflow-y: auto;
z-index: 55;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 8px;
box-shadow: var(--shadow-lg, 0 10px 30px rgba(0, 0, 0, 0.15));
padding: 0.35rem 0;
font-size: 0.88rem;
}
.search-group + .search-group {
border-top: 1px solid var(--color-border);
margin-top: 0.25rem;
padding-top: 0.25rem;
}
.search-group-header {
padding: 0.35rem 0.85rem 0.2rem;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--color-text-muted);
}
.search-result {
display: flex;
align-items: center;
gap: 0.65rem;
padding: 0.45rem 0.85rem;
color: var(--color-text);
text-decoration: none;
cursor: pointer;
transition: background 120ms ease;
border-left: 3px solid transparent;
}
.search-result:hover,
.search-result.active {
background: var(--color-overlay-faint);
border-left-color: var(--color-accent);
}
.search-result-icon {
flex-shrink: 0;
width: 18px;
height: 18px;
color: var(--color-text-muted);
display: flex;
align-items: center;
justify-content: center;
}
.search-result-icon svg {
width: 16px;
height: 16px;
}
.search-result-body {
display: flex;
flex-direction: column;
min-width: 0;
flex: 1;
}
.search-result-title {
font-weight: 500;
color: var(--color-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.search-result-subtitle {
font-size: 0.78rem;
color: var(--color-text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.search-result mark {
background: transparent;
color: inherit;
font-weight: 700;
padding: 0;
}
.search-empty {
padding: 1rem 0.85rem;
color: var(--color-text-muted);
text-align: center;
font-size: 0.85rem;
}
/* Command palette (t-paliad-044) — actions render as buttons styled like
entity results, footer carries kbd hints. */
.palette-action {
width: 100%;
background: transparent;
border: 0;
border-left: 3px solid transparent;
text-align: left;
font: inherit;
}
.palette-action:hover,
.palette-action.active {
background: var(--color-overlay-faint);
border-left-color: var(--color-accent);
}
.search-group-actions .search-result-icon {
color: var(--color-accent-fg);
}
.palette-footer {
display: flex;
gap: 1rem;
padding: 0.5rem 0.85rem;
margin-top: 0.25rem;
border-top: 1px solid var(--color-border);
font-size: 0.72rem;
color: var(--color-text-muted);
}
.palette-footer kbd {
display: inline-block;
padding: 0.05rem 0.35rem;
border: 1px solid var(--color-border);
border-radius: 3px;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.7rem;
line-height: 1;
color: var(--color-text);
background: var(--color-surface);
margin-right: 0.25rem;
}
@media (max-width: 480px) {
.palette-footer {
display: none;
}
}
/* Mobile: full-width overlay below the hamburger-triggered drawer. When the
sidebar is closed on mobile the search input is hidden inside the drawer;
the overlay is still fixed-positioned so a focus-via-shortcut (no "/" on
phones, but theoretically) or tap-in-drawer would render correctly. */
@media (max-width: 1023px) {
.search-overlay {
left: 0.5rem;
right: 0.5rem;
width: auto;
max-width: none;
top: 6.75rem;
}
.sidebar-search-kbd {
display: none;
}
}
/* --- Changelog / What's New (t-paliad-027) --- */
.sidebar-changelog {
position: relative;
}
.sidebar-badge {
position: absolute;
top: 0.4rem;
left: calc(var(--sidebar-collapsed) - 1rem);
min-width: 1rem;
height: 1rem;
padding: 0 0.3rem;
border-radius: 999px;
background: var(--color-accent);
color: var(--color-accent-dark);
font-size: 0.65rem;
font-weight: 700;
line-height: 1rem;
text-align: center;
box-shadow: 0 0 0 2px var(--sidebar-bg);
pointer-events: none;
transition: left 150ms ease;
}
.sidebar.expanded .sidebar-badge,
.sidebar.pinned .sidebar-badge {
left: auto;
right: 1rem;
top: 50%;
transform: translateY(-50%);
}
.changelog-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 1.75rem;
max-width: 44rem;
}
.changelog-entry {
border-bottom: 1px solid var(--color-border, #e5e7eb);
padding-bottom: 1.75rem;
}
.changelog-entry:last-child {
border-bottom: none;
padding-bottom: 0;
}
.changelog-meta {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.4rem;
}
.changelog-date {
color: var(--color-text-muted);
font-size: 0.8rem;
font-variant-numeric: tabular-nums;
}
.changelog-tag {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.15rem 0.55rem;
border-radius: 999px;
}
.changelog-tag-feature {
background: rgb(var(--hlc-lime-rgb) / 0.14);
color: var(--color-accent-fg);
}
.changelog-tag-content {
background: rgba(37, 99, 235, 0.12);
color: #2563eb;
}
.changelog-tag-fix {
background: rgba(180, 83, 9, 0.14);
color: #92400e;
}
.changelog-title {
font-size: 1.05rem;
font-weight: 600;
margin: 0 0 0.35rem;
letter-spacing: -0.01em;
}
.changelog-body {
color: var(--color-text-muted);
line-height: 1.55;
margin: 0;
font-size: 0.92rem;
}
.changelog-empty {
color: var(--color-text-muted);
font-style: italic;
padding: 1.5rem 0;
}
/* ============================================================
* Agenda — unified timeline across projects
* ============================================================ */
.agenda-controls {
display: flex;
flex-wrap: wrap;
gap: 1.5rem 2rem;
align-items: flex-start;
margin: 1.5rem 0 1.25rem 0;
}
.agenda-filter-group {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.agenda-filter-label {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--color-text-muted, #6b7280);
}
.agenda-chip-row {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.agenda-chip {
appearance: none;
background: var(--color-surface-muted);
border: 1px solid transparent;
border-radius: 999px;
padding: 0.35rem 0.85rem;
font-size: 0.85rem;
font-weight: 500;
color: var(--color-text);
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.agenda-chip:hover { background: var(--color-overlay-subtle); }
.agenda-chip-active {
background: var(--color-accent);
border-color: var(--color-border);
color: var(--color-accent-dark);
}
.agenda-loading {
padding: 1rem 0;
color: var(--color-text-muted, #6b7280);
font-style: italic;
}
.agenda-timeline {
display: flex;
flex-direction: column;
gap: 1.75rem;
margin-top: 0.5rem;
}
.agenda-day { }
.agenda-day-heading {
display: flex;
align-items: baseline;
gap: 0.7rem;
font-size: 1.1rem;
font-weight: 600;
margin: 0 0 0.6rem 0;
padding-bottom: 0.35rem;
border-bottom: 1px solid var(--color-border, #e5e7eb);
}
.agenda-day-relative { color: var(--color-text, #111827); }
.agenda-day-full {
color: var(--color-text-muted, #6b7280);
font-weight: 400;
font-size: 0.95rem;
}
.agenda-items {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.agenda-item-link {
display: grid;
grid-template-columns: 2rem 1fr auto;
gap: 0.7rem;
align-items: center;
padding: 0.6rem 0.85rem;
border-radius: 8px;
border: 1px solid var(--color-border);
background: var(--color-surface);
text-decoration: none;
color: inherit;
transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.agenda-item-link:hover {
background: var(--color-bg-lime-tint);
border-color: var(--color-border-strong);
}
.agenda-item-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 50%;
background: var(--color-surface-muted);
color: var(--color-text-muted);
}
.agenda-item-icon svg { width: 1.1rem; height: 1.1rem; }
.agenda-item-main {
display: flex;
flex-direction: column;
gap: 0.2rem;
min-width: 0;
}
.agenda-item-headline {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
align-items: baseline;
font-size: 0.95rem;
}
.agenda-item-type-label {
font-weight: 600;
color: var(--color-text-muted, #6b7280);
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.02em;
}
.agenda-item-title {
font-weight: 600;
color: var(--color-text, #111827);
overflow: hidden;
text-overflow: ellipsis;
}
.agenda-item-sub {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
font-size: 0.82rem;
color: var(--color-text-muted, #6b7280);
}
.agenda-item-project {
color: var(--color-text-muted, #6b7280);
text-decoration: none;
border-bottom: 1px dotted currentColor;
}
.agenda-item-project:hover {
color: var(--color-text, #111827);
}
.agenda-item-time { font-variant-numeric: tabular-nums; }
.agenda-item-location::before { content: "· "; }
.agenda-item-meta {
display: flex;
align-items: center;
}
.agenda-item-urgency {
display: inline-block;
padding: 0.2rem 0.55rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.03em;
white-space: nowrap;
}
/* Urgency colour system — shares the red/amber/green vocabulary with the
* Fristen page (--frist-red / --frist-amber / --frist-green) so a user who
* learned the traffic lights there reads the agenda without relearning.
* Pulls from the shared --status-* tokens so dark mode swap is automatic. */
.agenda-item-overdue .agenda-item-urgency { background: var(--status-red-bg); color: var(--status-red-fg); }
.agenda-item-overdue .agenda-item-icon { background: var(--status-red-bg); color: var(--status-red-fg); }
.agenda-item-overdue .agenda-item-link { border-left: 3px solid var(--frist-red); }
.agenda-item-today .agenda-item-urgency { background: var(--status-red-bg); color: var(--status-red-fg); }
.agenda-item-today .agenda-item-icon { background: var(--status-red-bg); color: var(--status-red-fg); }
.agenda-item-today .agenda-item-link { border-left: 3px solid var(--frist-red); }
.agenda-item-tomorrow .agenda-item-urgency { background: var(--status-amber-bg); color: var(--status-amber-fg); }
.agenda-item-tomorrow .agenda-item-icon { background: var(--status-amber-bg); color: var(--status-amber-fg); }
.agenda-item-tomorrow .agenda-item-link { border-left: 3px solid var(--frist-amber); }
.agenda-item-this_week .agenda-item-urgency { background: var(--status-amber-bg); color: var(--status-amber-fg-2); }
.agenda-item-this_week .agenda-item-icon { background: var(--status-amber-bg); color: var(--status-amber-fg-2); }
.agenda-item-this_week .agenda-item-link { border-left: 3px solid var(--frist-amber); }
.agenda-item-later .agenda-item-urgency { background: var(--status-green-soft-bg); color: var(--status-green-soft-fg); }
.agenda-item-later .agenda-item-icon { background: var(--status-green-soft-bg); color: var(--status-green-soft-fg); }
.agenda-item-later .agenda-item-link { border-left: 3px solid var(--frist-green); }
/* ---------------------------------------------------------------------------
* Team directory (/team) — t-paliad-029
* Browsable list of all Paliad colleagues, grouped by office or department.
* --------------------------------------------------------------------------- */
.team-controls {
display: flex;
flex-wrap: wrap;
gap: 1rem;
align-items: center;
margin-bottom: 1rem;
}
.team-controls .glossar-search-wrap {
flex: 1 1 280px;
min-width: 240px;
}
.team-toggle {
display: inline-flex;
gap: 0.5rem;
}
.team-filter-row {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.team-group {
margin-bottom: 2rem;
}
.team-group-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
padding-bottom: 0.5rem;
margin-bottom: 1rem;
border-bottom: 1px solid var(--color-border, #e5e5ed);
}
.team-group-header h2 {
margin: 0;
font-size: 1.25rem;
color: var(--color-text, var(--hlc-midnight));
}
.team-group-sub {
font-size: 0.85rem;
color: var(--color-text-muted, #64647a);
margin-top: 0.15rem;
}
.team-dept-lead {
margin-top: 0.35rem;
font-size: 0.85rem;
color: var(--color-text-muted, #64647a);
}
.team-dept-lead strong {
color: var(--color-text, var(--hlc-midnight));
}
.team-dept-lead a {
color: var(--color-accent-fg);
text-decoration: none;
}
.team-dept-lead a:hover {
text-decoration: underline;
}
.team-group-count {
flex-shrink: 0;
background: var(--color-surface-muted);
color: var(--color-text-muted, #64647a);
border-radius: 999px;
padding: 0.15rem 0.7rem;
font-size: 0.85rem;
font-weight: 600;
align-self: center;
}
.team-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 0.85rem;
}
.team-card {
display: flex;
gap: 0.85rem;
align-items: flex-start;
padding: 0.9rem 1rem;
background: var(--color-surface);
border: 1px solid var(--color-border, #e5e5ed);
border-radius: 12px;
transition: border-color 0.15s, box-shadow 0.15s;
}
.team-card:hover {
border-color: var(--color-accent, var(--color-accent));
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.team-avatar {
flex-shrink: 0;
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--color-accent-light, var(--color-accent-light));
color: var(--hlc-midnight);
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.85rem;
letter-spacing: 0.02em;
}
.team-card-body {
min-width: 0;
flex: 1;
}
.team-card-name {
font-weight: 600;
color: var(--color-text, var(--hlc-midnight));
line-height: 1.2;
overflow-wrap: anywhere;
}
.team-card-role {
font-size: 0.85rem;
color: var(--color-text-muted, #64647a);
margin-top: 0.15rem;
overflow-wrap: anywhere;
}
.team-card-meta {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-top: 0.5rem;
font-size: 0.78rem;
align-items: center;
}
.team-office-badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.15rem 0.5rem;
background: var(--status-green-soft-bg);
color: var(--status-green-soft-fg);
border-radius: 999px;
font-weight: 500;
}
.team-office-badge svg {
flex-shrink: 0;
}
.team-office-extra {
color: var(--color-text-muted, #64647a);
}
.team-dept-tag {
display: inline-block;
padding: 0.15rem 0.5rem;
background: var(--color-surface-muted);
color: var(--color-text-muted, #64647a);
border-radius: 999px;
}
.team-card-email {
display: inline-flex;
align-items: center;
gap: 0.35rem;
margin-top: 0.6rem;
font-size: 0.82rem;
color: var(--color-accent-fg);
text-decoration: none;
overflow-wrap: anywhere;
word-break: break-all;
}
.team-card-email:hover {
text-decoration: underline;
}
.team-card-email svg {
flex-shrink: 0;
}
@media (max-width: 600px) {
.team-grid {
grid-template-columns: 1fr;
}
.team-controls {
flex-direction: column;
align-items: stretch;
}
.team-toggle {
justify-content: stretch;
}
.team-toggle .filter-pill {
flex: 1 1 0;
text-align: center;
}
}
/* --- BottomNav (mobile, <768px) --- */
.bottom-nav {
display: none;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 30;
background: var(--color-surface);
border-top: 1px solid var(--color-border);
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.04);
padding-bottom: env(safe-area-inset-bottom);
transition: transform 200ms ease-out;
}
.bottom-nav-slot {
flex: 1 1 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.15rem;
height: var(--bottom-nav-height);
color: var(--color-text-muted);
text-decoration: none;
background: none;
border: none;
font-family: var(--font-sans);
font-size: 0.65rem;
font-weight: 500;
cursor: pointer;
padding: 0.25rem 0.1rem 0.35rem;
position: relative;
-webkit-tap-highlight-color: transparent;
}
.bottom-nav-slot.active {
color: var(--color-accent-fg);
}
.bottom-nav-slot.active::before {
content: "";
position: absolute;
top: 0;
left: 25%;
right: 25%;
height: 3px;
background: var(--color-accent);
border-radius: 0 0 2px 2px;
}
.bottom-nav-icon {
display: flex;
align-items: center;
justify-content: center;
}
.bottom-nav-icon svg {
width: 22px;
height: 22px;
}
.bottom-nav-label {
line-height: 1;
letter-spacing: 0.01em;
}
.bottom-nav-badge {
position: absolute;
top: 4px;
right: calc(50% - 18px);
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 8px;
background: var(--color-accent);
color: var(--color-accent-dark);
font-size: 0.65rem;
font-weight: 700;
line-height: 16px;
text-align: center;
box-shadow: 0 0 0 2px var(--color-surface);
}
.bottom-nav-badge-overdue {
background: #dc2626;
animation: bn-pulse 1800ms ease-in-out infinite;
}
@keyframes bn-pulse {
0%, 100% { box-shadow: 0 0 0 2px var(--color-surface); }
50% { box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 5px rgba(220, 38, 38, 0.25); }
}
/* Center [+] slot — visually elevated lime circle */
.bottom-nav-add {
color: var(--color-text-muted);
}
.bottom-nav-add-circle {
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border-radius: 50%;
background: var(--color-accent);
color: var(--color-accent-dark);
margin-top: -10px;
box-shadow: var(--shadow-md);
transition: background 150ms ease, transform 100ms ease;
}
.bottom-nav-add:active .bottom-nav-add-circle {
background: var(--color-accent-light);
transform: scale(0.95);
}
.bottom-nav-add-circle svg {
width: 22px;
height: 22px;
}
/* Hide BottomNav when keyboard is open (visualViewport watcher) */
body.keyboard-open .bottom-nav {
transform: translateY(120%);
}
/* --- Quick-Add slide-up sheet --- */
dialog.quick-add-sheet {
border: none;
padding: 0;
margin: 0;
background: transparent;
color: var(--color-text);
max-width: none;
max-height: none;
width: 100%;
height: 100%;
}
dialog.quick-add-sheet[open] {
position: fixed;
inset: 0;
width: 100%;
height: 100%;
background: transparent;
display: flex;
align-items: flex-end;
justify-content: center;
overflow: hidden;
}
dialog.quick-add-sheet::backdrop {
background: var(--color-overlay-modal);
}
.quick-add-card {
width: 100%;
max-width: 480px;
background: var(--color-surface);
border-radius: 16px 16px 0 0;
box-shadow: var(--shadow-md);
padding: 0.5rem 1rem calc(1rem + env(safe-area-inset-bottom));
display: flex;
flex-direction: column;
gap: 0.25rem;
transform: translateY(100%);
transition: transform 220ms ease-out;
}
.quick-add-sheet.is-open .quick-add-card {
transform: translateY(0);
}
.quick-add-handle {
width: 36px;
height: 4px;
border-radius: 2px;
background: var(--color-border);
margin: 0.5rem auto 0.75rem;
}
.quick-add-title {
font-size: 0.85rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
margin: 0 0.25rem 0.25rem;
}
.quick-add-row {
display: flex;
align-items: center;
gap: 0.85rem;
padding: 0.85rem 0.5rem;
border-radius: var(--radius);
color: var(--color-text);
text-decoration: none;
cursor: pointer;
transition: background 100ms ease;
}
.quick-add-row:hover,
.quick-add-row:active {
background: var(--color-overlay-faint);
}
.quick-add-icon {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
background: rgb(var(--hlc-lime-rgb) / 0.1);
color: var(--color-accent-fg);
flex-shrink: 0;
}
.quick-add-icon svg {
width: 20px;
height: 20px;
}
.quick-add-row-label {
display: flex;
flex-direction: column;
gap: 0.15rem;
min-width: 0;
}
.quick-add-row-title {
font-weight: 600;
font-size: 0.95rem;
}
.quick-add-row-sub {
font-size: 0.78rem;
color: var(--color-text-muted);
}
.quick-add-cancel {
margin-top: 0.5rem;
padding: 0.85rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
font-family: var(--font-sans);
font-size: 0.95rem;
font-weight: 600;
color: var(--color-text);
cursor: pointer;
}
.quick-add-cancel:hover {
background: var(--color-overlay-faint);
}
/* --- Phone breakpoint (<768px): show BottomNav, hide legacy hamburger --- */
@media (max-width: 767px) {
.bottom-nav {
display: flex;
}
.sidebar-hamburger {
display: none !important;
}
body.has-sidebar main {
/* The center FAB pokes ~10px above the bottom-nav (margin-top: -10px on
.bottom-nav-add-circle), so 1rem gap left content overlapping the
circle on /dashboard at 375px. 1.75rem gives the FAB a safe gutter. */
padding-bottom: calc(var(--bottom-nav-height) + 1.75rem + env(safe-area-inset-bottom));
}
}
/* --- PWA install banner ---------------------------------------------------
Slides in from the bottom on mobile, pinned bottom-right on desktop.
Both Chromium beforeinstallprompt and the iOS Safari hint share this UI;
pwa-install.ts toggles content + behaviour. */
.pwa-install-banner {
position: fixed;
left: 1rem;
right: 1rem;
bottom: calc(env(safe-area-inset-bottom) + 1rem);
z-index: 9000;
display: flex;
align-items: center;
gap: 0.85rem;
padding: 0.85rem 1rem;
background: var(--color-surface);
color: var(--color-text);
border: 1px solid var(--color-border);
border-radius: 14px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15), 0 2px 6px rgba(0, 0, 0, 0.08);
animation: pwa-banner-in 220ms ease-out;
}
@media (max-width: 767px) {
/* Sit above the BottomNav so it never covers it. */
.pwa-install-banner {
bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom) + 0.75rem);
}
}
@media (min-width: 768px) {
.pwa-install-banner {
left: auto;
right: 1.5rem;
bottom: 1.5rem;
max-width: 22rem;
}
}
.pwa-install-icon {
flex: 0 0 auto;
width: 38px;
height: 38px;
border-radius: 10px;
background: var(--color-accent);
color: var(--color-accent-dark);
display: grid;
place-items: center;
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
font-weight: 700;
font-size: 1.4rem;
line-height: 1;
}
.pwa-install-text {
flex: 1 1 auto;
min-width: 0;
}
.pwa-install-title {
font-weight: 600;
font-size: 0.95rem;
line-height: 1.2;
}
.pwa-install-sub {
margin-top: 0.15rem;
font-size: 0.8rem;
color: var(--color-text-muted);
line-height: 1.35;
}
.pwa-install-share {
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: -4px;
margin: 0 0.15rem;
color: var(--color-accent-fg);
}
.pwa-install-cta {
flex: 0 0 auto;
padding: 0.55rem 0.95rem;
border: none;
border-radius: 10px;
background: var(--color-accent);
color: var(--color-accent-dark);
font-family: var(--font-sans);
font-weight: 600;
font-size: 0.85rem;
cursor: pointer;
}
.pwa-install-cta:hover {
background: var(--hlc-midnight);
}
.pwa-install-dismiss {
flex: 0 0 auto;
width: 28px;
height: 28px;
padding: 0;
border: none;
border-radius: 50%;
background: transparent;
color: var(--color-text-muted);
font-size: 1.4rem;
line-height: 1;
cursor: pointer;
}
.pwa-install-dismiss:hover {
background: var(--color-overlay-subtle);
color: var(--color-text);
}
@keyframes pwa-banner-in {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
/* =========================================================================
Admin team-management page (t-paliad-050)
========================================================================= */
.admin-team-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.admin-team-controls {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
}
.admin-team-filter-row {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.admin-team-table-wrap {
margin-top: 0.5rem;
}
.admin-team-table {
font-size: 0.85rem;
}
.admin-team-table tbody tr {
cursor: default;
}
.admin-team-table tbody tr:hover {
background: var(--color-bg-lime-tint);
}
.admin-team-loading {
text-align: center;
color: var(--color-text-muted);
padding: 2rem 1rem;
}
.admin-team-muted {
color: var(--color-text-muted);
font-size: 0.85em;
}
.admin-team-actions-cell {
white-space: nowrap;
text-align: right;
}
.admin-team-actions-cell .btn-link {
background: none;
border: none;
color: var(--color-text);
cursor: pointer;
font-size: 0.82rem;
padding: 0.2rem 0.5rem;
}
.admin-team-actions-cell .btn-link:hover {
text-decoration: underline;
}
.admin-team-actions-cell .admin-team-delete {
color: #b91c1c;
}
.admin-team-edit-row {
background: var(--color-bg-lime-tint);
}
.admin-team-input {
width: 100%;
padding: 0.3rem 0.45rem;
font-size: 0.85rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
}
.admin-team-multi {
max-width: 220px;
}
.admin-team-multi-opt {
display: inline-flex;
align-items: center;
gap: 0.25rem;
margin: 0.1rem 0.4rem 0.1rem 0;
font-size: 0.78rem;
}
.admin-team-edit-row .btn-primary,
.admin-team-edit-row .btn-cancel {
padding: 0.3rem 0.7rem;
font-size: 0.78rem;
margin-left: 0.3rem;
}
.sidebar-admin-group .sidebar-group-label {
color: var(--color-accent-fg);
}
/* --- Admin Event-Types moderation panel (t-paliad-089) ----------------- */
.aet-col-check {
width: 2.4rem;
text-align: center;
}
.aet-archived-badge {
display: inline-block;
padding: 0.05rem 0.4rem;
margin-right: 0.4rem;
border-radius: 999px;
background: var(--color-surface-muted, #f0f0f0);
color: var(--color-text-muted);
font-size: 0.7rem;
font-weight: 500;
vertical-align: middle;
}
.aet-row-archived td {
opacity: 0.65;
}
.aet-label-en,
.aet-slug {
font-size: 0.72rem;
margin-top: 0.1rem;
}
.aet-merge-options {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin: 0.5rem 0 1rem;
}
.aet-merge-option {
display: flex;
align-items: flex-start;
gap: 0.6rem;
padding: 0.6rem 0.8rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
cursor: pointer;
transition: border-color 0.15s ease, background 0.15s ease;
}
.aet-merge-option:hover {
border-color: var(--color-accent);
}
.aet-merge-option input[type="radio"] {
margin-top: 0.2rem;
}
.aet-merge-option-body {
flex: 1;
}
.aet-merge-option-label {
font-weight: 500;
color: var(--color-text);
}
.aet-merge-option-meta {
font-size: 0.78rem;
margin-top: 0.15rem;
}
/* --- Project breadcrumb (t-paliad-049) ---------------------------------
Pill-style breadcrumbs with type icons, chevron separators and a hover
lime accent. Horizontal-scroll fallback on narrow screens; the trailing
current crumb stays bolder/non-link. */
.projekt-breadcrumb {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.25rem 0.35rem;
margin: 0.25rem 0 1rem;
font-size: 0.82rem;
line-height: 1.2;
}
.projekt-crumb {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.28rem 0.6rem;
border-radius: 999px;
border: 1px solid var(--color-border);
background: var(--color-surface);
color: var(--color-text-muted);
text-decoration: none;
font-weight: 500;
max-width: 16rem;
transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.projekt-crumb-link:hover,
.projekt-crumb-link:focus-visible {
border-color: var(--color-accent, var(--hlc-lime));
background: rgb(var(--hlc-lime-rgb) / 0.12);
color: var(--color-text, var(--hlc-midnight));
outline: none;
}
.projekt-crumb-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 14px;
height: 14px;
flex-shrink: 0;
color: var(--color-text-muted);
}
.projekt-crumb-link:hover .projekt-crumb-icon,
.projekt-crumb-link:focus-visible .projekt-crumb-icon {
color: var(--color-text, var(--hlc-midnight));
}
.projekt-crumb-icon svg {
width: 100%;
height: 100%;
display: block;
}
.projekt-crumb-title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.projekt-crumb-current {
color: var(--color-text, var(--hlc-midnight));
font-weight: 700;
background: var(--color-bg-subtle);
border-color: #d4d4d8;
}
.projekt-breadcrumb-chevron {
width: 12px;
height: 12px;
flex-shrink: 0;
color: var(--color-text-muted);
opacity: 0.55;
}
@media (max-width: 640px) {
.projekt-breadcrumb {
flex-wrap: nowrap;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding-bottom: 0.25rem;
scrollbar-width: thin;
}
.projekt-crumb {
max-width: 10rem;
flex-shrink: 0;
}
}
/* --- Wide modal variant for the project edit form ------------------- */
.modal-card.modal-card-wide {
max-width: 720px;
padding: 1.5rem 1.75rem;
}
.modal-card-wide .entity-form {
margin-top: 0.5rem;
}
/* --- Standardised tab toolbar action buttons (t-paliad-049) ----------
The .party-controls toolbar above each project sub-tab table
used a mix of <a class="btn-cta-lime btn-small"> and <button>; pin them
to a single shape so heights, paddings and hover states match across
tabs. Mehr laden's btn-secondary gets the same compact size. */
.party-controls {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.party-controls .btn-primary,
.party-controls .btn-secondary,
.party-controls .btn-cta-lime,
.party-controls a.btn-primary,
.party-controls a.btn-cta-lime,
.entity-events-loadmore .btn-secondary {
display: inline-flex;
align-items: center;
height: 2.1rem;
padding: 0 0.95rem;
font-size: 0.82rem;
font-weight: 600;
border-radius: var(--radius);
line-height: 1;
text-decoration: none;
}
/* --- Admin landing page (t-paliad-054) ------------------------------
/admin index reuses the standard .grid + .card pattern from the
public landing page. The "Geplant" section uses .admin-card-soon
to dim placeholder cards and add a "Kommt bald" badge so they
read as a roadmap rather than broken links. */
.admin-section-planned {
margin-top: 2.5rem;
}
.admin-card-soon {
position: relative;
opacity: 0.6;
cursor: default;
}
.admin-card-soon:hover {
border-color: var(--color-border);
box-shadow: var(--shadow-sm);
}
.admin-soon-badge {
position: absolute;
top: 0.85rem;
right: 0.85rem;
font-size: 0.68rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
background: var(--color-surface-muted);
border: 1px solid var(--color-border);
padding: 0.2rem 0.5rem;
border-radius: 999px;
}
/* Admin audit log (t-paliad-071) */
.admin-audit-controls {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.admin-audit-control-row {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
align-items: flex-end;
}
.admin-audit-field {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.admin-audit-field label {
font-size: 0.75rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.admin-audit-input {
padding: 0.4rem 0.55rem;
font-size: 0.9rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
}
.admin-audit-search-field {
flex: 1 1 16rem;
}
.admin-audit-search-field .admin-audit-input {
width: 100%;
}
.admin-audit-counter-field {
margin-left: auto;
align-self: flex-end;
}
.admin-audit-counter {
font-size: 0.85rem;
color: var(--color-text-muted);
}
.admin-audit-custom-range {
flex-direction: row;
align-items: center;
gap: 0.5rem;
}
.admin-audit-custom-range label {
margin-bottom: 0;
}
.admin-audit-table-wrap {
margin-top: 0.5rem;
}
.admin-audit-table {
font-size: 0.85rem;
}
.admin-audit-time {
white-space: nowrap;
font-variant-numeric: tabular-nums;
color: var(--color-text-muted);
}
.admin-audit-event {
font-size: 0.78rem;
background: var(--color-surface-muted);
padding: 0.1rem 0.4rem;
border-radius: var(--radius);
}
.admin-audit-desc {
color: var(--color-text-muted);
}
.admin-audit-loading {
text-align: center;
color: var(--color-text-muted);
padding: 2rem 1rem;
}
.admin-audit-source {
display: inline-block;
font-size: 0.72rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.15rem 0.5rem;
border-radius: 999px;
border: 1px solid var(--color-border);
background: var(--color-surface-muted);
color: var(--color-text-muted);
white-space: nowrap;
}
.admin-audit-source-project {
background: var(--status-blue-soft-bg);
border-color: var(--status-blue-soft-bg);
color: var(--status-blue-soft-fg);
}
.admin-audit-source-caldav {
background: var(--status-blue-bg);
border-color: var(--status-blue-bg);
color: var(--status-blue-fg);
}
.admin-audit-source-reminder {
background: var(--status-amber-bg);
border-color: var(--status-amber-border);
color: var(--status-amber-fg);
}
.admin-audit-pagination {
margin-top: 1rem;
display: flex;
justify-content: center;
}
@media (max-width: 720px) {
.admin-audit-control-row {
flex-direction: column;
align-items: stretch;
}
.admin-audit-counter-field {
margin-left: 0;
}
.admin-audit-custom-range {
flex-wrap: wrap;
}
}
/* /admin/email-templates — list + editor (t-paliad-072) */
.admin-et-loading {
color: var(--color-text-muted);
font-style: italic;
text-align: center;
}
.admin-et-card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.admin-et-card-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 0.75rem;
}
.admin-et-card-header h2 {
margin: 0;
font-size: 1.1rem;
}
.admin-et-card-key {
font-size: 0.75rem;
color: var(--color-text-muted);
background: var(--color-surface-muted);
padding: 2px 6px;
border-radius: 4px;
}
.admin-et-card-langs {
display: flex;
gap: 0.5rem;
margin-top: auto;
}
.admin-et-card-lang-btn {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
padding: 0.625rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-bg);
text-decoration: none;
color: inherit;
transition: border-color 120ms, background 120ms;
}
.admin-et-card-lang-btn:hover {
border-color: var(--hlc-lime, #BFF355);
background: var(--color-surface-muted);
}
.admin-et-card-lang-flag {
font-weight: 700;
font-size: 0.85rem;
letter-spacing: 0.04em;
}
.admin-et-card-lang-status {
font-size: 0.78rem;
color: var(--color-text-muted);
}
/* Editor layout */
.admin-et-edit-container {
max-width: 1400px;
}
.admin-et-back {
display: inline-block;
color: var(--color-text-muted);
text-decoration: none;
font-size: 0.85rem;
margin-bottom: 0.5rem;
}
.admin-et-back:hover {
color: var(--color-text);
text-decoration: underline;
}
.admin-et-lang-toggle {
display: inline-flex;
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: hidden;
}
.admin-et-lang-btn {
padding: 0.4rem 0.9rem;
border: 0;
background: var(--color-bg);
cursor: pointer;
font-weight: 600;
color: var(--color-text-muted);
}
.admin-et-lang-btn[aria-pressed="true"],
.admin-et-lang-btn.active {
background: var(--hlc-lime, #BFF355);
color: #1c1917;
}
.admin-et-editor {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 1.5rem;
margin-top: 1rem;
}
.admin-et-editor-form,
.admin-et-editor-preview {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.admin-et-subject-input,
.admin-et-note-input {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
font-size: 0.95rem;
box-sizing: border-box;
}
.admin-et-body-input {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
font-size: 0.85rem;
line-height: 1.5;
box-sizing: border-box;
resize: vertical;
min-height: 320px;
}
.admin-et-actions {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.admin-et-variables {
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 0.75rem;
}
.admin-et-variables summary {
cursor: pointer;
font-weight: 600;
}
.admin-et-variables-list {
display: flex;
flex-direction: column;
gap: 0.4rem;
margin-top: 0.75rem;
font-size: 0.85rem;
}
.admin-et-variable-row {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 0.5rem;
}
.admin-et-variable-name {
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
color: #1c1917;
}
.admin-et-variable-type {
font-size: 0.75rem;
color: var(--color-text-muted);
background: var(--color-surface-muted);
padding: 1px 6px;
border-radius: 3px;
}
.admin-et-variable-desc {
color: var(--color-text);
}
.admin-et-variable-sample {
color: var(--color-text-muted);
font-style: italic;
margin-left: auto;
text-align: right;
}
.admin-et-preview-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
}
.admin-et-preview-header h2 {
margin: 0;
font-size: 1rem;
}
.admin-et-preview-actions {
display: flex;
gap: 0.5rem;
align-items: center;
}
.admin-et-slot-select {
padding: 0.3rem 0.5rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-bg);
font-size: 0.85rem;
}
.admin-et-preview-subject {
padding: 0.5rem 0.75rem;
background: var(--color-surface-muted);
border-radius: var(--radius);
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
font-size: 0.85rem;
word-break: break-word;
}
.admin-et-preview-frame {
width: 100%;
height: 600px;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface-2);
}
.admin-et-versions {
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 0.75rem;
}
.admin-et-versions summary {
cursor: pointer;
font-weight: 600;
}
.admin-et-versions-list {
list-style: none;
margin: 0.75rem 0 0 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.admin-et-version-row {
display: grid;
grid-template-columns: max-content 1fr max-content;
gap: 0.5rem;
align-items: center;
font-size: 0.85rem;
padding: 0.4rem 0.5rem;
border-radius: 4px;
}
.admin-et-version-row:hover {
background: var(--color-surface-muted);
}
.admin-et-version-date {
color: var(--color-text);
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}
.admin-et-version-note {
color: var(--color-text-muted);
font-style: italic;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.admin-et-version-empty {
color: var(--color-text-muted);
font-style: italic;
}
@media (max-width: 1024px) {
.admin-et-editor {
grid-template-columns: 1fr;
}
.admin-et-preview-frame {
height: 480px;
}
}
/* ===================================================================
Dark mode — class-level overrides for sites that still hold their
own hardcoded colours (status pills, dashboard cards, agenda urgency,
termin types). The bulk of the swap is handled by the token redef
at :root[data-theme="dark"] earlier in this file; this block targets
the long-tail of class-scoped colour pairs that are too local to
warrant a full token. Keeping them in one section makes the dark-
mode palette greppable when tweaking contrast.
=================================================================== */
:root[data-theme="dark"] {
/* Surface elevations — tables/alt-rows/code-blocks read flat against
the body background otherwise. */
}
/* Soft amber surfaces (warning callouts, entity-unavailable, etc) */
:root[data-theme="dark"] .entity-unavailable {
background: var(--status-amber-bg);
color: var(--status-amber-fg);
}
/* Dashboard cards + urgency chips read --status-* tokens directly now
(see .dashboard-card-*, .dashboard-urgency-* rules above). The dark
swap is automatic via the token redef. */
/* Dashboard termin dots */
:root[data-theme="dark"] .dashboard-termin-hearing { background: var(--status-red-fg); }
:root[data-theme="dark"] .dashboard-termin-meeting { background: var(--status-blue-fg-2); }
:root[data-theme="dark"] .dashboard-termin-deadline_hearing { background: var(--status-amber-fg-2); }
/* Termin type colour-codes (card border-left + dot) */
:root[data-theme="dark"] .termin-type-hearing { background: var(--status-red-fg); color: var(--status-red-fg); }
:root[data-theme="dark"] .termin-type-meeting { background: var(--status-blue-fg-2); color: var(--status-blue-fg-2); }
:root[data-theme="dark"] .termin-type-deadline_hearing { background: var(--status-amber-fg-2); color: var(--status-amber-fg-2); }
:root[data-theme="dark"] .termin-type-default { background: var(--status-neutral-fg-2); color: var(--status-neutral-fg-2); }
/* Termin pill badges */
:root[data-theme="dark"] .termin-type-badge.termin-type-hearing { background: var(--status-red-bg); color: var(--status-red-fg); }
:root[data-theme="dark"] .termin-type-badge.termin-type-meeting { background: var(--status-blue-bg); color: var(--status-blue-fg-2); }
:root[data-theme="dark"] .termin-type-badge.termin-type-deadline_hearing { background: var(--status-amber-bg); color: var(--status-amber-fg); }
/* Termin pill chips (Termin-Typ column on /events). Without this block the
chip would inherit the bare .termin-type-XYZ rule above, which paints
text the same colour as the swatch background → invisible. */
:root[data-theme="dark"] .termin-type-chip.termin-type-hearing { background: var(--status-red-bg); color: var(--status-red-fg); }
:root[data-theme="dark"] .termin-type-chip.termin-type-meeting { background: var(--status-blue-bg); color: var(--status-blue-fg-2); }
:root[data-theme="dark"] .termin-type-chip.termin-type-consultation { background: rgb(var(--hlc-lime-rgb) / 0.18); color: var(--hlc-lime); }
:root[data-theme="dark"] .termin-type-chip.termin-type-deadline_hearing { background: var(--status-amber-bg); color: var(--status-amber-fg); }
/* Termin card border-left colour cues */
:root[data-theme="dark"] .termin-card-today { border-left-color: var(--status-amber-fg-2); color: var(--status-amber-fg-2); }
:root[data-theme="dark"] .termin-card-week { border-left-color: var(--status-blue-fg-2); color: var(--status-blue-fg-2); }
:root[data-theme="dark"] .termin-card-later { border-left-color: var(--status-neutral-fg-2); color: var(--status-neutral-fg-2); }
:root[data-theme="dark"] .termin-card-today .frist-summary-dot { background: var(--status-amber-fg-2); }
:root[data-theme="dark"] .termin-card-week .frist-summary-dot { background: var(--status-blue-fg-2); }
:root[data-theme="dark"] .termin-card-later .frist-summary-dot { background: var(--status-neutral-fg-2); }
/* Frist due-date chips, entity-status chips, agenda urgency markers all
read --status-*-{bg,fg} tokens directly now (see .frist-due-chip,
.entity-status-chip, .agenda-item-* rules above). The dark-mode swap
happens automatically via the token redef at :root[data-theme="dark"]
— no per-class override needed here. */
/* Tab-style selection borders (gebuehren-tab, entity-tab, etc.) read on
the lime accent in both themes — no override needed. */
/* Code blocks / soft alt-row backgrounds — these specific Tailwind-grey
shades land too washed-out on midnight; pin them to surface-2 instead. */
:root[data-theme="dark"] .entity-table thead th,
:root[data-theme="dark"] .gebuehren-table th {
background: var(--color-bg-subtle);
}
/* Project breadcrumb pill (was background: #eef2ff; color: #4338ca;) */
:root[data-theme="dark"] .projekt-breadcrumb-pill,
:root[data-theme="dark"] .projekt-tree-pill {
background: var(--status-blue-soft-bg);
color: var(--status-blue-soft-fg);
}
/* Generic .frist-card hover/alt rows — neutralize the rgba(0,0,0,...)
stripes and dividers so the dark surface doesn't get a black wash. */
:root[data-theme="dark"] .frist-card:hover,
:root[data-theme="dark"] .entity-table tbody tr:hover {
background: var(--color-bg-lime-tint);
}
/* t-paliad-099: readonly opt-out also wins in dark mode. The generic
dark-theme hover rule above outranks the .entity-table--readonly base
rule on specificity, so re-state the override here scoped to dark. */
:root[data-theme="dark"] .entity-table--readonly tbody tr:hover {
background: transparent;
}
/* Sidebar scrollbar tinting is handled via --sidebar-scrollbar-thumb /
-hover (see :root + dark block at top), so it tracks the sidebar
surface in either theme. On the body in dark mode the browser-default
scrollbar is dark via color-scheme, so no per-element override is
needed here. */
/* ============================================================================
t-paliad-088 — Event Types: picker, multi-select filter, add modal
============================================================================ */
/* Picker host — chip cluster + search + suggest dropdown */
.event-type-picker {
display: flex;
flex-direction: column;
gap: 0.5rem;
border: 1px solid var(--color-border);
border-radius: 0.5rem;
padding: 0.5rem;
background: var(--color-bg-subtle);
}
.event-type-chips {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
}
.event-type-chip {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.15rem 0.35rem 0.15rem 0.55rem;
background: var(--color-bg-lime-tint);
border: 1px solid var(--color-border);
border-radius: 999px;
font-size: 0.875rem;
line-height: 1.2;
}
.event-type-chip-label { white-space: nowrap; }
.event-type-chip-remove {
background: transparent;
border: 0;
padding: 0 0.25rem;
cursor: pointer;
font-size: 1.05rem;
line-height: 1;
color: var(--color-text-muted);
}
.event-type-chip-remove:hover { color: var(--color-text); }
.event-type-search-row {
display: flex;
gap: 0.5rem;
align-items: center;
flex-wrap: wrap;
}
.event-type-search-row .event-type-search { min-width: 8rem; }
.event-type-search {
flex: 1;
padding: 0.4rem 0.5rem;
border: 1px solid var(--color-border);
border-radius: 0.375rem;
background: var(--color-bg);
font-size: 0.875rem;
}
.event-type-add-btn,
.event-type-browse-btn {
padding: 0.4rem 0.75rem;
border: 1px dashed var(--color-border);
border-radius: 0.375rem;
background: transparent;
cursor: pointer;
font-size: 0.875rem;
color: var(--color-text);
white-space: nowrap;
}
.event-type-add-btn:hover,
.event-type-browse-btn:hover { background: var(--color-bg-subtle); }
.event-type-browse-btn { border-style: solid; }
.event-type-suggest {
display: flex;
flex-direction: column;
border: 1px solid var(--color-border);
border-radius: 0.375rem;
background: var(--color-bg);
max-height: 14rem;
overflow-y: auto;
}
.event-type-suggest-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.4rem 0.6rem;
background: transparent;
border: 0;
border-bottom: 1px solid var(--color-border);
cursor: pointer;
text-align: left;
font-size: 0.875rem;
color: var(--color-text);
}
.event-type-suggest-row:last-child { border-bottom: 0; }
.event-type-suggest-row:hover { background: var(--color-bg-lime-tint); }
.event-type-suggest-cat {
font-size: 0.75rem;
color: var(--color-text-muted);
margin-left: 0.5rem;
}
.event-type-suggest-empty {
padding: 0.5rem 0.6rem;
font-size: 0.875rem;
color: var(--color-text-muted);
}
/* Multi-select filter — trigger button + popover panel.
The .multi-anchor wraps trigger+panel so the absolutely-positioned panel
lands directly under the trigger button (t-paliad-117). */
.multi-anchor {
position: relative;
display: inline-flex;
}
.multi-trigger {
display: inline-flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
cursor: pointer;
text-align: left;
min-width: 12rem;
}
.multi-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.multi-chevron {
color: var(--color-text-muted);
flex-shrink: 0;
}
.multi-panel {
position: absolute;
z-index: 50;
margin-top: 0.25rem;
width: 22rem;
max-width: calc(100vw - 1rem);
background: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: 0.5rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
padding: 0.5rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
max-height: 28rem;
}
/* Scoped anchor: pin the panel under its trigger only when wrapped in
.multi-anchor. Agenda's multi-select renders the panel as a sibling
inside a column flex group and relies on auto-positioning, so leave
that path alone. */
.multi-anchor > .multi-panel {
top: 100%;
left: 0;
}
.multi-panel[hidden] { display: none; }
.multi-search-row { display: flex; }
.multi-search {
flex: 1;
padding: 0.4rem 0.5rem;
border: 1px solid var(--color-border);
border-radius: 0.375rem;
background: var(--color-bg-subtle);
font-size: 0.875rem;
}
.multi-specials {
display: flex;
flex-direction: column;
gap: 0.15rem;
padding-bottom: 0.4rem;
border-bottom: 1px solid var(--color-border);
}
.multi-list {
overflow-y: auto;
overflow-x: hidden;
flex: 1;
min-height: 4rem;
min-width: 0;
}
.multi-group { padding: 0.25rem 0; }
.multi-group-label {
font-size: 0.75rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.25rem 0.4rem;
}
.multi-option {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.3rem 0.5rem;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.875rem;
min-width: 0;
overflow-wrap: anywhere;
}
.multi-option:hover { background: var(--color-bg-lime-tint); }
.multi-option input[type="checkbox"] { margin: 0; }
.multi-special { font-weight: 500; }
.multi-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
border-top: 1px solid var(--color-border);
padding-top: 0.5rem;
}
/* Typ pill in the deadlines table — compact, neutral. */
.entity-event-type-pill {
display: inline-block;
padding: 0.05rem 0.4rem;
margin-right: 0.2rem;
background: var(--color-bg-subtle);
border: 1px solid var(--color-border);
border-radius: 999px;
font-size: 0.75rem;
color: var(--color-text);
white-space: nowrap;
}
/* Hide-on-uniform: when no row has any event_type, hide the column. */
.entity-table--hide-event-type .entity-col-event-type { display: none; }
/* t-paliad-110 — column hiders for the unified EventsPage. The shared
table renders the union of deadline + appointment columns; each
`events-table--hide-*` modifier collapses one column when no visible
row supplies the matching field, mirroring the t-073 pattern. */
.events-table--hide-row-type .events-col-row-type { display: none; }
.events-table--hide-rule .events-col-rule { display: none; }
.events-table--hide-location .events-col-location { display: none; }
.events-table--hide-appointment-type .events-col-appointment-type { display: none; }
/* Type chip rendered in the leftmost data column when the table mixes
deadlines + appointments — at-a-glance type signal that survives
monochrome printing. */
.events-row-type-chip {
display: inline-block;
padding: 0.05rem 0.45rem;
border-radius: 999px;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.02em;
text-transform: uppercase;
border: 1px solid var(--color-border);
background: var(--color-surface-muted);
color: var(--color-text-muted);
white-space: nowrap;
}
.events-row-type-frist { color: var(--bucket-today); border-color: var(--bucket-today); }
.events-row-type-termin { color: var(--bucket-next-week); border-color: var(--bucket-next-week); }
/* Type chip toggle row (Fristen / Termine / Beides) above the bucket
cards — reuses the agenda-chip visuals so users get muscle-memory
parity with /agenda. */
.event-type-chip-row {
margin: 0;
}
/* View ⊥ filter (t-paliad-115). The type-chip row is the FILTER axis;
the view selector is the VIEW axis (cards / list / calendar). The two
live side-by-side in `events-axis-row` so users can scan them as
independent controls. On narrow viewports they stack and the view
selector wraps below the chips. */
.events-axis-row {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1rem;
align-items: center;
justify-content: space-between;
margin: 0.5rem 0 1rem;
}
.events-view-selector {
display: inline-flex;
background: var(--color-surface-muted);
border: 1px solid var(--color-border);
border-radius: 999px;
padding: 2px;
gap: 0;
}
.events-view-btn {
appearance: none;
background: transparent;
border: none;
color: var(--color-text-muted);
font-size: 0.85rem;
font-weight: 500;
padding: 0.3rem 0.85rem;
border-radius: 999px;
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.events-view-btn:hover {
color: var(--color-text);
}
.events-view-btn-active {
background: var(--color-surface);
color: var(--color-text);
box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.08));
}
/* Calendar view (t-paliad-115). Reuses the existing .frist-calendar
styles — only the appointment dot colour is new. The frist-cal-dot
urgency variants already cover the deadline palette; we just need a
distinct hue for appointments so a mixed-type cell reads at a glance. */
.events-calendar-wrap {
margin: 0.25rem 0 1rem;
}
.frist-cal-dot.events-cal-dot-appointment {
background: var(--bucket-next-week, #1d4ed8);
}
/* Add-modal styling — extends the existing .modal-overlay/.modal pattern. */
.event-type-add-modal {
width: 28rem;
max-width: calc(100vw - 2rem);
}
.event-type-add-modal .form-field-row { display: flex; gap: 0.75rem; }
.event-type-add-modal .form-field-row > .form-field { flex: 1; }
.event-type-suggest-warn {
padding: 0.5rem 0.6rem;
background: var(--status-amber-soft-bg);
color: var(--status-amber-soft-fg);
border-radius: 0.375rem;
font-size: 0.875rem;
}
.event-type-suggest-pill {
display: inline-block;
margin: 0 0.2rem;
padding: 0.05rem 0.4rem;
background: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: 999px;
font-size: 0.75rem;
}
/* Generic .modal surface — shared by the event-type add and browse modals.
Both render as `<div class="modal …">` inside a `.modal-overlay`; the
modifier class layers width/layout overrides on top. Mirrors `.modal-card`
so the surface reads consistently with the rest of the app. */
.modal {
background: var(--color-surface);
border-radius: calc(var(--radius) * 1.5);
box-shadow: var(--shadow-lg);
padding: 1.5rem;
width: 100%;
max-width: 480px;
max-height: 90vh;
overflow-y: auto;
}
/* Browse-all modal (t-paliad-107) — companion to the picker's
search-as-you-type. Fixed header (title + sticky search), scrollable
category-grouped list, footer actions. */
.event-type-browse-modal {
width: 36rem;
max-width: calc(100vw - 2rem);
max-height: min(80vh, 40rem);
display: flex;
flex-direction: column;
padding: 0;
overflow: hidden;
}
.event-type-browse-header {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1.25rem 1.5rem 0.75rem;
border-bottom: 1px solid var(--color-border);
background: var(--color-surface);
flex-shrink: 0;
}
.event-type-browse-header h2 {
font-size: 1.15rem;
font-weight: 700;
margin: 0;
color: var(--color-text);
}
.event-type-browse-search {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-input-bg);
color: var(--color-text);
font-family: var(--font-sans);
font-size: 0.9rem;
outline: none;
transition: border-color 0.15s ease;
}
.event-type-browse-search:focus { border-color: var(--color-accent); }
.event-type-browse-list {
flex: 1 1 auto;
overflow-y: auto;
padding: 0.5rem 0;
}
.event-type-browse-group { padding: 0.5rem 0; }
.event-type-browse-group-label {
font-size: 0.75rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.25rem 1.5rem;
margin: 0;
}
.event-type-browse-options {
list-style: none;
margin: 0;
padding: 0;
}
.event-type-browse-options li { margin: 0; }
.event-type-browse-option {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.4rem 1.5rem;
cursor: pointer;
font-size: 0.9rem;
color: var(--color-text);
}
.event-type-browse-option:hover { background: var(--color-bg-lime-tint); }
.event-type-browse-option:focus-within { background: var(--color-bg-lime-tint); }
.event-type-browse-option input[type="checkbox"] {
margin: 0;
flex-shrink: 0;
}
.event-type-browse-option-label {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.event-type-browse-jurisdiction {
flex-shrink: 0;
padding: 0.05rem 0.5rem;
background: var(--color-bg-subtle);
border: 1px solid var(--color-border);
border-radius: 999px;
font-size: 0.7rem;
color: var(--color-text-muted);
white-space: nowrap;
}
.event-type-browse-empty {
padding: 2rem 1.5rem;
text-align: center;
color: var(--color-text-muted);
font-size: 0.9rem;
}
.event-type-browse-actions {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.75rem 1.5rem;
border-top: 1px solid var(--color-border);
background: var(--color-surface);
flex-shrink: 0;
}
.event-type-browse-count {
flex: 1;
font-size: 0.82rem;
color: var(--color-text-muted);
}
/* Mobile: filter row already wraps; the multi-panel becomes a bottom-anchored
sheet on narrow viewports. The browse modal does the same so it
doesn't scroll-clip on small screens. */
@media (max-width: 640px) {
.multi-panel {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: auto;
width: 100%;
max-width: 100%;
max-height: 70vh;
border-radius: 0.75rem 0.75rem 0 0;
margin: 0;
}
.event-type-browse-modal {
width: 100%;
max-width: 100%;
max-height: 90vh;
border-radius: 0.75rem 0.75rem 0 0;
align-self: flex-end;
}
}