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>
42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
import {getTranslations} from 'next-intl/server';
|
|
import {Link} from '@/i18n/navigation';
|
|
import {BrandMark, Icon} from './Icon';
|
|
import {NAV_GROUPS} from './nav';
|
|
|
|
/** Footer: the principles in three lines, the full sitemap, a pointer for developers and agents. */
|
|
export async function SiteFooter() {
|
|
const t = await getTranslations('Nav');
|
|
const tl = await getTranslations('Layout');
|
|
const tf = await getTranslations('Footer');
|
|
|
|
return (
|
|
<footer className="site-footer">
|
|
<div className="site-footer-inner">
|
|
<div className="footer-brand">
|
|
<Link href="/" className="brand"><BrandMark /><span>politrack</span></Link>
|
|
<p>{tf('tagline')}</p>
|
|
<ul className="footer-principles">
|
|
<li><Icon name="document" /> {tf('principleEvidence')}</li>
|
|
<li><Icon name="scale" /> {tf('principleInnocence')}</li>
|
|
<li><Icon name="shield" /> {tf('principlePrivacy')}</li>
|
|
</ul>
|
|
</div>
|
|
<nav className="footer-nav" aria-label={tl('footerNav')}>
|
|
{NAV_GROUPS.map((group) => (
|
|
<div key={group.key}>
|
|
<h2>{tl(`group.${group.key}`)}</h2>
|
|
<ul>
|
|
{group.items.map((item) => (
|
|
<li key={item.href}><Link href={item.href}>{t(item.key)}</Link></li>
|
|
))}
|
|
{group.key === 'about' && <li><Link href="/methodik#daten">{tf('developers')}</Link></li>}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</nav>
|
|
</div>
|
|
<p className="footer-bottom"><span>{tf('bottom')}</span></p>
|
|
</footer>
|
|
);
|
|
}
|