Files
politics-tracking/web/src/styles/layout.css
T
simonandClaude Opus 5.5 456f9816f4 Redesign the web app from a written design concept
Design concept and design system in docs/design/: principles (evidence
first, neutral, fair to the people shown, plain language, time as a
dimension, accessible and private), information architecture, core
patterns and a concept for every page; tokens with checked contrast,
component catalogue, content and accessibility rules.

web:
- neutral ink-indigo accent instead of flag red; party colours only as
  small markers next to the name; light/dark theme with a switcher
- stylesheets split into tokens, base, layout, components, print
- new header (search, filter count, language, theme, mobile menu) and
  footer; breadcrumbs, page headers, tabs with counts, filter bars that
  collapse on phones, pagination, notices and empty states
- claim cards with source meter, legal stage, innocence notice inside
  the card and a permalink; claim pages with citation (/angaben/{id})
- profiles with role timeline and key figures; party and organisation
  dashboards; vote list with position chips; calendar agenda on phones;
  tables that stack into cards; loading and error pages; favicon

backend:
- GET /api/v1/claims/{id} and MCP tool get_claim for permalinks
- parties list: evaluate person_status once instead of per party
  (30 s -> 1 s on the sample database, identical result)
- parliament calendar: HTML-decode titles ("84. Sitzung")

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:21:44 +01:00

465 lines
7.9 KiB
CSS

/* Page frame (header, main, footer) and layout utilities. Breakpoints: 640 / 1024 / 1280 px. */
.skip-link {
position: absolute;
left: var(--space-4);
top: -3rem;
z-index: 100;
padding: var(--space-2) var(--space-4);
border-radius: var(--radius);
background: var(--accent);
color: var(--on-accent);
font-weight: 600;
}
.skip-link:focus {
top: var(--space-2);
color: var(--on-accent);
}
.page {
flex: 1;
width: 100%;
max-width: var(--page-max);
margin: 0 auto;
padding: var(--space-5) var(--gutter) var(--space-8);
}
/* ---------- site header ---------- */
.site-header {
position: sticky;
top: 0;
z-index: 30;
background: color-mix(in srgb, var(--surface) 94%, transparent);
border-bottom: 1px solid var(--line);
backdrop-filter: saturate(1.4) blur(8px);
}
.site-header-inner {
display: flex;
align-items: center;
gap: var(--space-4);
max-width: var(--page-max);
height: var(--header-h);
margin: 0 auto;
padding: 0 var(--gutter);
}
.brand {
display: inline-flex;
align-items: center;
gap: var(--space-2);
color: var(--ink);
font-size: 1.25rem;
font-weight: 800;
letter-spacing: -0.03em;
text-decoration: none;
white-space: nowrap;
}
.brand:hover {
color: var(--ink);
}
.brand-mark {
width: 1.75rem;
height: 1.75rem;
color: var(--accent);
flex-shrink: 0;
}
.main-nav > ul {
display: flex;
align-items: center;
gap: 2px;
margin: 0;
padding: 0;
list-style: none;
}
.nav-link, .nav-more > summary {
display: inline-flex;
align-items: center;
gap: var(--space-1);
padding: var(--space-2) var(--space-3);
border-radius: var(--radius);
color: var(--ink-2);
font-size: 0.95rem;
font-weight: 500;
text-decoration: none;
white-space: nowrap;
list-style: none;
}
.nav-more > summary::-webkit-details-marker, .menu > summary::-webkit-details-marker {
display: none;
}
.nav-link:hover, .nav-more > summary:hover {
background: var(--surface-2);
color: var(--ink);
}
.nav-link[aria-current='page'] {
color: var(--ink);
font-weight: 650;
box-shadow: inset 0 -2px 0 var(--accent);
border-radius: var(--radius) var(--radius) 0 0;
}
.nav-more {
position: relative;
}
.nav-more[open] > summary {
background: var(--surface-2);
}
.nav-more-panel, .menu-panel {
position: absolute;
top: calc(100% + var(--space-2));
z-index: 40;
margin: 0;
padding: var(--space-2);
list-style: none;
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--radius-lg);
box-shadow: var(--shadow);
}
.nav-more-panel {
left: 0;
min-width: 15rem;
}
.nav-more-panel .nav-link {
display: flex;
white-space: normal;
}
.header-tools {
display: flex;
align-items: center;
gap: var(--space-1);
margin-left: auto;
}
.header-search {
position: relative;
width: 13rem;
}
.header-search input {
min-height: 2.25rem;
padding-right: 2.25rem;
border-color: var(--line);
background: var(--paper);
font-size: var(--text-sm);
}
.header-search button {
position: absolute;
right: 0;
top: 0;
}
.icon-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-1);
min-width: 2.25rem;
min-height: 2.25rem;
padding: var(--space-1) var(--space-2);
border: 1px solid transparent;
border-radius: var(--radius);
background: transparent;
color: var(--ink-2);
font-size: var(--text-sm);
font-weight: 600;
text-decoration: none;
white-space: nowrap;
list-style: none;
cursor: pointer;
}
.icon-button:hover {
background: var(--surface-2);
border-color: transparent;
color: var(--ink);
}
.icon-button .icon {
width: 1.25rem;
height: 1.25rem;
}
.count-badge {
display: inline-grid;
place-items: center;
min-width: 1.25rem;
height: 1.25rem;
padding: 0 0.3rem;
border-radius: var(--radius-pill);
background: var(--accent);
color: var(--on-accent);
font-size: var(--text-xs);
font-weight: 700;
line-height: 1;
}
.menu {
position: relative;
display: none;
}
.menu-panel {
right: 0;
width: min(22rem, calc(100vw - 2 * var(--gutter)));
max-height: calc(100vh - var(--header-h) - var(--space-4));
overflow: auto;
padding: var(--space-4);
}
.menu-group + .menu-group {
margin-top: var(--space-4);
padding-top: var(--space-4);
border-top: 1px solid var(--line);
}
.menu-group-title {
margin: 0 0 var(--space-2);
color: var(--ink-3);
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.menu-group ul {
margin: 0;
padding: 0;
list-style: none;
}
.menu-group .nav-link {
display: flex;
padding: var(--space-2);
}
@media (max-width: 1023px) {
.main-nav, .header-search, .tool-label {
display: none;
}
.menu {
display: block;
}
}
@media (min-width: 1024px) {
.header-search-link {
display: none;
}
}
@media (min-width: 1024px) and (max-width: 1359px) {
.tool-label {
display: none;
}
}
@media (min-width: 1024px) and (max-width: 1180px) {
.header-search {
width: 10rem;
}
}
/* ---------- site footer ---------- */
.site-footer {
margin-top: var(--space-8);
border-top: 1px solid var(--line);
background: var(--surface);
color: var(--ink-2);
font-size: var(--text-sm);
}
.site-footer-inner {
display: grid;
gap: var(--space-6);
max-width: var(--page-max);
margin: 0 auto;
padding: var(--space-7) var(--gutter) var(--space-6);
}
@media (min-width: 1024px) {
.site-footer-inner {
grid-template-columns: 1.3fr 3fr;
}
}
.footer-brand p {
max-width: 24rem;
}
.footer-principles {
margin: var(--space-4) 0 0;
padding: 0;
list-style: none;
}
.footer-principles li {
display: flex;
gap: var(--space-2);
align-items: flex-start;
margin-bottom: var(--space-2);
}
.footer-principles .icon {
flex-shrink: 0;
margin-top: 0.15rem;
color: var(--accent);
}
.footer-nav {
display: grid;
gap: var(--space-5);
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
.footer-nav h2 {
margin: 0 0 var(--space-3);
color: var(--ink);
font-size: var(--text-sm);
}
.footer-nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.footer-nav li {
margin-bottom: var(--space-2);
}
.footer-nav a {
color: var(--ink-2);
text-decoration: none;
}
.footer-nav a:hover {
color: var(--accent);
text-decoration: underline;
}
.footer-bottom {
max-width: var(--page-max);
margin: 0 auto;
padding: 0 var(--gutter) var(--space-6);
color: var(--ink-3);
font-size: var(--text-xs);
}
.footer-bottom > span {
display: block;
padding-top: var(--space-4);
border-top: 1px solid var(--line);
}
/* ---------- layout utilities ---------- */
.stack {
display: flex;
flex-direction: column;
gap: var(--space-4);
}
.cluster {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-2);
}
.grid-2 {
display: grid;
gap: var(--space-5) var(--space-6);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
align-items: start;
}
.grid-cards {
display: grid;
gap: var(--space-3);
grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--card-min, 17rem)), 1fr));
margin: 0 0 var(--space-5);
padding: 0;
list-style: none;
}
.layout-aside {
display: grid;
gap: var(--space-6);
align-items: start;
}
@media (min-width: 1024px) {
.layout-aside {
grid-template-columns: minmax(0, 1fr) 20rem;
}
}
.layout-aside > * {
min-width: 0;
}
.section {
margin-top: var(--space-7);
}
.section:first-child {
margin-top: 0;
}
.section-head {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
gap: var(--space-2) var(--space-4);
margin-bottom: var(--space-3);
}
.section-head h2 {
margin: 0;
}
.section-head h2 + .muted {
margin: 0;
}
.more-link {
display: inline-flex;
align-items: center;
gap: var(--space-1);
font-size: var(--text-sm);
font-weight: 600;
text-decoration: none;
}
.more-link:hover {
text-decoration: underline;
}
.prose {
max-width: var(--prose-max);
}
.prose h2 {
margin-top: var(--space-7);
}