diff --git a/Elternbeirat.Web/Components/Layout/MainLayout.razor.css b/Elternbeirat.Web/Components/Layout/MainLayout.razor.css
index be871ed..4096c06 100644
--- a/Elternbeirat.Web/Components/Layout/MainLayout.razor.css
+++ b/Elternbeirat.Web/Components/Layout/MainLayout.razor.css
@@ -25,27 +25,30 @@
z-index keeps it above the content; the opaque background stops content showing
through as it scrolls underneath. */
.site-header {
- border-bottom: 1px solid #e0e0e0;
- background: #fff;
+ /* Brand-blue bar with a warm accent underline -- the strongest, most visible
+ cue that carries the friendly tone across every page. */
+ background: var(--color-brand);
+ border-bottom: 3px solid var(--color-accent);
+ box-shadow: var(--shadow);
position: sticky;
top: 0;
z-index: 20;
}
.header-inner {
- max-width: 60rem;
+ max-width: var(--content-width);
margin: 0 auto;
- padding: 1rem 1.25rem;
+ padding: var(--space-3) 1.25rem;
display: flex;
flex-wrap: wrap;
align-items: baseline;
- gap: 0.5rem 1.5rem;
+ gap: var(--space-2) var(--space-4);
}
.brand {
font-size: 1.35rem;
font-weight: 700;
- color: #1f3a5f;
+ color: #fff;
text-decoration: none;
white-space: nowrap;
}
@@ -65,22 +68,9 @@
display: none;
}
-.main-nav a {
- color: #333;
- text-decoration: none;
- padding: 0.2rem 0;
- border-bottom: 2px solid transparent;
-}
-
-.main-nav a:hover {
- color: #1f3a5f;
-}
-
-/* NavLink adds .active to the link of the current route. */
-.main-nav a.active {
- color: #1f3a5f;
- border-bottom-color: #1f3a5f;
-}
+/* The link colours/states for .main-nav a live in the GLOBAL app.css, not here.
+ Reason: NavLink renders plain elements that carry no scoped-CSS attribute
+ (b-xxxxx), so a scoped rule ".main-nav a" would not match them. See app.css. */
/* Content: at least tall enough that the footer sits at the bottom of the viewport
on short pages. 100dvh - 4rem leaves room for the header (which sits above in
@@ -90,41 +80,41 @@
min-height: calc(100dvh - 4rem);
box-sizing: border-box;
width: 100%;
- max-width: 60rem;
+ max-width: var(--content-width);
margin: 0 auto;
- padding: 1.5rem 1.25rem 3rem;
+ padding: var(--space-4) 1.25rem var(--space-6);
}
/* Footer */
.site-footer {
- border-top: 1px solid #e0e0e0;
- background: #fafafa;
- color: #555;
+ border-top: 1px solid var(--color-border);
+ background: var(--color-surface);
+ color: var(--color-text-soft);
font-size: 0.9rem;
}
.footer-inner {
- max-width: 60rem;
+ max-width: var(--content-width);
margin: 0 auto;
- padding: 1rem 1.25rem;
+ padding: var(--space-3) 1.25rem;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
- gap: 0.5rem 1.5rem;
+ gap: var(--space-2) var(--space-4);
}
.footer-nav {
display: flex;
- gap: 1.25rem;
+ gap: var(--space-4);
}
.footer-nav a {
- color: #555;
+ color: var(--color-text-soft);
text-decoration: none;
}
.footer-nav a:hover {
- color: #1f3a5f;
+ color: var(--color-brand);
text-decoration: underline;
}
@@ -155,7 +145,7 @@
display: block;
width: 1.5rem;
height: 2px;
- background: #1f3a5f;
+ background: #fff; /* on the blue header bar */
content: "";
}
@@ -191,14 +181,6 @@
display: block;
}
- .main-nav a {
- padding: 0.6rem 0;
- border-bottom: 1px solid #eee;
- }
-
- /* The active link keeps its colour but not the desktop underline, which would
- clash with the row separators. */
- .main-nav a.active {
- border-bottom-color: #eee;
- }
+ /* Mobile per-link spacing/separators for .main-nav a are in the global app.css
+ too, for the same scoped-attribute reason as above. */
}
diff --git a/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor b/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor
index cae3aa3..080ed5e 100644
--- a/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor
+++ b/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor
@@ -20,6 +20,6 @@
}
- Alle Termine →
+ Alle Termine →
}
diff --git a/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor.css b/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor.css
index 9c51138..afcd19b 100644
--- a/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor.css
+++ b/Elternbeirat.Web/Features/Embeds/EventsEmbed.razor.css
@@ -1,33 +1,5 @@
+/* Card styles for .event-list are shared with the full events page and live in the
+ global app.css. Only the embed's spacing on the home page is specific here. */
.embed-events {
- margin-top: 2rem;
-}
-
-.event-list {
- list-style: none;
- padding: 0;
-}
-
-.event-list li {
- padding: 0.75rem 0;
- border-bottom: 1px solid #eee;
-}
-
-.event-list time {
- display: block;
- color: #777;
- font-size: 0.85rem;
-}
-
-.event-title {
- font-size: 1.1rem;
- font-weight: 600;
-}
-
-.event-location::before {
- content: " · ";
- color: #777;
-}
-
-.event-location {
- color: #555;
+ margin-top: var(--space-5);
}
diff --git a/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor b/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor
index 9460bdb..278e395 100644
--- a/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor
+++ b/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor
@@ -16,6 +16,6 @@
}
- Alle Fragen →
+ Alle Fragen →
}
diff --git a/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor.css b/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor.css
index 1022fd7..4a084e8 100644
--- a/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor.css
+++ b/Elternbeirat.Web/Features/Embeds/FaqsEmbed.razor.css
@@ -1,18 +1,5 @@
+/* Card styles for .faq-item are shared with the full FAQ page and live in the
+ global app.css. Only the embed's spacing on the home page is specific here. */
.embed-faqs {
- margin-top: 2rem;
-}
-
-.faq-item {
- border-bottom: 1px solid #eee;
- padding: 0.5rem 0;
-}
-
-.faq-item summary {
- cursor: pointer;
- font-weight: 600;
-}
-
-.faq-answer {
- padding: 0.5rem 0 0.25rem;
- color: #333;
+ margin-top: var(--space-5);
}
diff --git a/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor b/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor
index c4de3dc..a70df14 100644
--- a/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor
+++ b/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor
@@ -18,6 +18,6 @@
}
- Alle Beiträge →
+ Alle Beiträge →
}
diff --git a/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor.css b/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor.css
index 9f4fa3b..357ec35 100644
--- a/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor.css
+++ b/Elternbeirat.Web/Features/Embeds/PostsEmbed.razor.css
@@ -1,24 +1,5 @@
+/* Card styles for .post-list are shared with the full posts page and live in the
+ global app.css. Only the embed's spacing on the home page is specific here. */
.embed-posts {
- margin-top: 2rem;
-}
-
-.post-list {
- list-style: none;
- padding: 0;
-}
-
-.post-list li {
- padding: 0.75rem 0;
- border-bottom: 1px solid #eee;
-}
-
-.post-list a {
- font-size: 1.1rem;
- text-decoration: none;
-}
-
-.post-list time {
- display: block;
- color: #777;
- font-size: 0.85rem;
+ margin-top: var(--space-5);
}
diff --git a/Elternbeirat.Web/Features/Events/EventList.razor.css b/Elternbeirat.Web/Features/Events/EventList.razor.css
index 1b33ecc..f95fa43 100644
--- a/Elternbeirat.Web/Features/Events/EventList.razor.css
+++ b/Elternbeirat.Web/Features/Events/EventList.razor.css
@@ -1,42 +1,2 @@
-.event-list {
- list-style: none;
- padding: 0;
-}
-
-.event-list li {
- padding: 0.75rem 0;
- border-bottom: 1px solid #eee;
-}
-
-.event-list time {
- display: block;
- color: #777;
- font-size: 0.85rem;
-}
-
-.event-title {
- font-size: 1.1rem;
- font-weight: 600;
-}
-
-.event-location::before {
- content: " · ";
- color: #777;
-}
-
-.event-location {
- color: #555;
-}
-
-.event-note {
- margin: 0.25rem 0 0;
- color: #444;
-}
-
-.event-list-past {
- color: #777;
-}
-
-.event-list-past .event-title {
- font-weight: 400;
-}
+/* The .event-list card styles (including past-event styling) are shared with the
+ home-page embed and live in the global app.css. Nothing page-specific here. */
diff --git a/Elternbeirat.Web/Features/Faqs/FaqList.razor.css b/Elternbeirat.Web/Features/Faqs/FaqList.razor.css
index d8d3670..6bb2570 100644
--- a/Elternbeirat.Web/Features/Faqs/FaqList.razor.css
+++ b/Elternbeirat.Web/Features/Faqs/FaqList.razor.css
@@ -1,22 +1,10 @@
+/* The .faq-item card styles are shared with the home-page embed and live in the
+ global app.css. Only the topic grouping is specific to this full page (the
+ embed shows a flat list without topic headings). */
.faq-topic {
- margin-bottom: 2rem;
+ margin-bottom: var(--space-5);
}
.faq-topic h2 {
- margin-bottom: 0.5rem;
-}
-
-.faq-item {
- border-bottom: 1px solid #eee;
- padding: 0.5rem 0;
-}
-
-.faq-item summary {
- cursor: pointer;
- font-weight: 600;
-}
-
-.faq-answer {
- padding: 0.5rem 0 0.25rem;
- color: #333;
+ margin-bottom: var(--space-3);
}
diff --git a/Elternbeirat.Web/Features/Posts/PostList.razor.css b/Elternbeirat.Web/Features/Posts/PostList.razor.css
index ac756fa..88fbef8 100644
--- a/Elternbeirat.Web/Features/Posts/PostList.razor.css
+++ b/Elternbeirat.Web/Features/Posts/PostList.razor.css
@@ -1,20 +1,2 @@
-.post-list {
- list-style: none;
- padding: 0;
-}
-
-.post-list li {
- padding: 0.75rem 0;
- border-bottom: 1px solid #eee;
-}
-
-.post-list a {
- font-size: 1.1rem;
- text-decoration: none;
-}
-
-.post-list time {
- display: block;
- color: #777;
- font-size: 0.85rem;
-}
+/* The .post-list card styles are shared with the home-page embed and live in the
+ global app.css. This page needs no extra styling of its own. */
diff --git a/Elternbeirat.Web/wwwroot/app.css b/Elternbeirat.Web/wwwroot/app.css
index e49babf..ac95a71 100644
--- a/Elternbeirat.Web/wwwroot/app.css
+++ b/Elternbeirat.Web/wwwroot/app.css
@@ -1,27 +1,313 @@
+/* Design tokens: one place for colours, spacing, radius, shadow and type. Every
+ component pulls from these variables (var(--...)), so the whole site shares one
+ look and a change here ripples everywhere. Warm-friendly palette: the brand blue
+ plus a warm accent. No external anything -- just CSS custom properties. */
+:root {
+ /* Brand blue and two derived shades (darker for hover, lighter for tints). */
+ --color-brand: #1f3a5f;
+ --color-brand-dark: #16293f;
+ --color-brand-tint: #eef2f7;
+
+ /* Warm accent for highlights (active nav, event dates, call-outs). */
+ --color-accent: #e8a13a;
+ --color-accent-dark: #c9821c;
+
+ /* Text and surfaces. */
+ --color-text: #222;
+ --color-text-soft: #555;
+ --color-bg: #fff; /* cards / content surface */
+ --color-page: #f4f1ea; /* soft warm page background behind the content */
+ --color-surface: #fafafa;
+ --color-border: #e0e0e0;
+
+ /* Spacing scale -- use these instead of ad-hoc rem values so gaps stay even. */
+ --space-1: 0.25rem;
+ --space-2: 0.5rem;
+ --space-3: 1rem;
+ --space-4: 1.5rem;
+ --space-5: 2rem;
+ --space-6: 3rem;
+
+ /* Rounded corners and a soft shadow for cards, matching the friendly tone. */
+ --radius: 12px;
+ --radius-sm: 6px;
+ --shadow: 0 1px 3px rgba(31, 58, 95, 0.08), 0 4px 12px rgba(31, 58, 95, 0.06);
+ --shadow-hover: 0 2px 6px rgba(31, 58, 95, 0.12), 0 8px 20px rgba(31, 58, 95, 0.1);
+
+ /* One transition speed for hovers/focus across the site. */
+ --transition: 0.15s ease;
+
+ /* Reading width, so long text lines never get uncomfortably wide. */
+ --content-width: 60rem;
+}
+
/* Base styles. Self-hosted system font stack — no external fonts, for privacy. */
html {
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
- line-height: 1.6;
- color: #222;
+ line-height: 1.65;
+ color: var(--color-text);
+ /* Smooth-scroll for in-page anchors, with room so headings clear the sticky
+ header instead of hiding under it. */
+ scroll-padding-top: 5rem;
}
body {
margin: 0;
+ /* A soft tinted page background so white cards/content lift off it. */
+ background: var(--color-page);
+ color: var(--color-text);
}
a {
- color: #1f3a5f;
+ color: var(--color-brand);
+ text-underline-offset: 2px;
+ transition: color var(--transition);
}
-h1, h2, h3 {
+a:hover {
+ color: var(--color-brand-dark);
+}
+
+/* Headings: clear hierarchy and a touch more air above them than below, so
+ sections read as groups. */
+h1, h2, h3, h4 {
line-height: 1.25;
- color: #1f3a5f;
+ color: var(--color-brand);
+ margin: var(--space-5) 0 var(--space-3);
+}
+
+h1 {
+ font-size: 2rem;
+ margin-top: 0; /* the first heading on a page needs no gap above */
+}
+
+h2 {
+ font-size: 1.5rem;
+}
+
+h3 {
+ font-size: 1.2rem;
+}
+
+/* Comfortable paragraph rhythm and a capped line length for readability. */
+p {
+ margin: 0 0 var(--space-3);
+ max-width: 42rem;
}
h1:focus {
outline: none;
}
+/* Header navigation links. These live here (global), not in MainLayout.razor.css:
+ NavLink renders plain elements without a scoped-CSS attribute, so a scoped
+ ".main-nav a" rule would not match them -- the links would fall back to the
+ global link colour (dark blue) and become unreadable on the blue header bar. */
+.main-nav a {
+ color: rgba(255, 255, 255, 0.85);
+ text-decoration: none;
+ padding: var(--space-1) 0;
+ border-bottom: 2px solid transparent;
+ transition: color var(--transition), border-color var(--transition);
+}
+
+.main-nav a:hover {
+ color: #fff;
+}
+
+/* NavLink adds .active to the current route's link; a warm accent underline marks
+ where the visitor is on the blue bar. */
+.main-nav a.active {
+ color: #fff;
+ border-bottom-color: var(--color-accent);
+}
+
+/* Mobile: stacked links inside the collapsed menu get row separators. Same global
+ placement, same NavLink reason as above. Scoped to the narrow layout via the
+ media query so it does not affect the desktop row. */
+@media (max-width: 40rem) {
+ .main-nav a {
+ padding: 0.6rem 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.15);
+ }
+
+ .main-nav a.active {
+ border-bottom-color: rgba(255, 255, 255, 0.15);
+ }
+}
+
+/* --- Shared card styles for content lists --------------------------------------
+ Posts, events and FAQs appear both on their own page (PostList/EventList/
+ FaqList) AND embedded on the home page (the *Embed components), with the same
+ class names. These rules live here (global) so both places share one look
+ instead of duplicating the CSS per component. The card look: a white surface
+ lifted off the tinted page background with a soft shadow and a gentle hover. */
+
+.post-list,
+.event-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: grid;
+ gap: var(--space-3);
+}
+
+.post-list li,
+.event-list li {
+ background: var(--color-bg);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+ padding: var(--space-3) var(--space-4);
+ transition: box-shadow var(--transition), transform var(--transition);
+}
+
+.post-list li:hover,
+.event-list li:hover {
+ box-shadow: var(--shadow-hover);
+ transform: translateY(-2px);
+}
+
+/* Posts */
+.post-list a {
+ font-size: 1.15rem;
+ font-weight: 600;
+ text-decoration: none;
+}
+
+.post-list time {
+ display: block;
+ margin-top: var(--space-1);
+ color: var(--color-text-soft);
+ font-size: 0.85rem;
+}
+
+/* Events: the date leads in the warm accent colour. */
+.event-list time {
+ display: block;
+ color: var(--color-accent-dark);
+ font-weight: 600;
+ font-size: 0.9rem;
+}
+
+.event-title {
+ display: block;
+ margin-top: var(--space-1);
+ font-size: 1.15rem;
+ font-weight: 600;
+ color: var(--color-brand);
+}
+
+.event-location::before {
+ content: " · ";
+ color: var(--color-text-soft);
+}
+
+.event-location {
+ color: var(--color-text-soft);
+}
+
+.event-note {
+ margin: var(--space-2) 0 0;
+ color: var(--color-text);
+}
+
+/* Past events (only on the full events page): same cards, quieter and flat. */
+.event-list-past li {
+ box-shadow: none;
+ border: 1px solid var(--color-border);
+ background: var(--color-surface);
+}
+
+.event-list-past li:hover {
+ transform: none;
+ box-shadow: none;
+}
+
+.event-list-past time {
+ color: var(--color-text-soft);
+ font-weight: 400;
+}
+
+.event-list-past .event-title {
+ font-weight: 400;
+ color: var(--color-text-soft);
+}
+
+/* FAQ: each question is an expandable card with an accent +/– marker. */
+.faq-item {
+ background: var(--color-bg);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+ padding: var(--space-3) var(--space-4);
+ margin-bottom: var(--space-3);
+ transition: box-shadow var(--transition);
+}
+
+.faq-item:hover {
+ box-shadow: var(--shadow-hover);
+}
+
+.faq-item summary {
+ cursor: pointer;
+ font-weight: 600;
+ color: var(--color-brand);
+ list-style: none;
+ display: flex;
+ align-items: baseline;
+ gap: var(--space-2);
+}
+
+.faq-item summary::-webkit-details-marker {
+ display: none;
+}
+
+.faq-item summary::before {
+ content: "+";
+ color: var(--color-accent-dark);
+ font-weight: 700;
+ font-size: 1.2rem;
+ line-height: 1;
+}
+
+.faq-item[open] summary::before {
+ content: "–";
+}
+
+.faq-answer {
+ padding-top: var(--space-2);
+ color: var(--color-text);
+}
+
+/* "Alle Beiträge/Termine/Fragen →" links below an embedded list on the home page.
+ Set apart from the cards with extra space above, and styled as a distinct call
+ to action in the accent colour rather than looking like body text. The arrow
+ nudges right on hover for a subtle bit of life. */
+.embed-more {
+ margin-top: var(--space-4);
+ max-width: none; /* override the global paragraph reading cap */
+}
+
+.embed-more a {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-2);
+ font-weight: 600;
+ color: var(--color-accent-dark);
+ text-decoration: none;
+}
+
+.embed-more a:hover {
+ color: var(--color-brand);
+}
+
+.embed-more a span {
+ transition: transform var(--transition);
+}
+
+.embed-more a:hover span {
+ transform: translateX(3px);
+}
+
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}