Compare commits

..
4 Commits
7 changed files with 204 additions and 30 deletions

No files matched your search

@@ -1,14 +1,29 @@
/* The card grid (.event-list) is shared with the home-page embed and lives in the /* The card grid (.event-list) is shared with the home-page embed and lives in the
global app.css; the card itself is EventCard. Only the page's own parts are here. */ global app.css; the card itself is EventCard. Only the page's own parts are here. */
/* Same centred 42rem reading column as a content page (ContentPage.razor.css), so
every page of the site shares one column under the header. */
h1,
h2,
article,
p,
.event-list,
.past-events {
max-width: 42rem;
margin-inline: auto;
}
/* auto, not 0: this rule outweighs the column rule above and would otherwise pull
the button back to the left edge of the page. */
.events-subscribe { .events-subscribe {
margin: var(--space-4) 0; margin: var(--space-4) auto;
} }
/* Past events: one folded-up card. Opened, a compact list grouped by year, /* Past events: one folded-up card. Opened, a compact list grouped by year,
deliberately quieter than the upcoming cards above. The open/close triangle is deliberately quieter than the upcoming cards above. The open/close triangle is
the shared .disclosure rule in app.css, the same as on the FAQ topics. */ the shared .disclosure rule in app.css, the same as on the FAQ topics. */
.past-events { .past-events {
box-sizing: border-box; /* padding inside the 42rem, flush with the text */
margin-top: var(--space-5); margin-top: var(--space-5);
padding: var(--space-3) var(--space-4); padding: var(--space-3) var(--space-4);
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
@@ -0,0 +1,17 @@
/* Same centred 42rem reading column as a content page (ContentPage.razor.css), so
every page of the site shares one column under the header. The topic cards and
the questions inside them live in the global app.css. */
h1,
article,
p,
.faq-topic {
box-sizing: border-box; /* padding inside the 42rem, flush with the text */
max-width: 42rem;
margin-inline: auto;
}
/* The intro's last paragraph drops its margin (app.css), so the first card would
sit right under the text; this gives it the same air as between sections. */
article {
margin-bottom: var(--space-5);
}
@@ -93,6 +93,26 @@
outline-color: var(--color-focus-inverse); outline-color: var(--color-focus-inverse);
} }
/* On a phone the buttons used to wrap onto a row each: two wide blocks stacked,
far too heavy for the top of the page. Instead they share one row in equal
columns -- the same buttons as on the desktop, just side by side and a little
tighter. Short labels ("Termine", "Kontakt") fit on one line; a longer one
wraps inside its button (centred) rather than pushing the other off the row. */
@media (max-width: 40rem) {
.hero-actions {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
gap: var(--space-2);
}
.hero .btn {
justify-content: center;
padding: var(--space-2) var(--space-3);
text-align: center;
}
}
/* --- Next event --------------------------------------------------------------- /* --- Next event ---------------------------------------------------------------
A card on the gradient: the regular card surface, so its text uses the normal A card on the gradient: the regular card surface, so its text uses the normal
tokens and adapts to dark mode by itself. The whole card is one link to the tokens and adapts to dark mode by itself. The whole card is one link to the
@@ -0,0 +1,11 @@
/* A content page is one reading column: its text, boxes and card grids all stop at
42rem (app.css). Left-aligned in the 72rem layout that column left a wide empty
strip on the right of a desktop screen; centred, the empty space splits evenly and
the page sits balanced under the header. Title and body share the column, so they
keep one left edge. The children inside keep margin 0 and simply fill it. */
h1,
article,
p {
max-width: 42rem;
margin-inline: auto;
}
@@ -1,13 +1,21 @@
/* The article: a reading column of about 68 characters with generous leading, so a /* The article: the site's centred 42rem reading column (as on a content page,
long post reads like a page, not like a form. Everything inside follows this ContentPage.razor.css) with generous leading, so a long post reads like a page,
width -- the global 42rem cap on paragraphs, lists and boxes is lifted here, or not like a form. Everything inside follows this width -- the global 42rem cap on
the text would stop short of the column it sits in. */ paragraphs, lists and boxes is lifted here, so nothing stops short of the column
(the post's own leading makes the text a touch wider than elsewhere). */
.post { .post {
max-width: 68ch; max-width: 42rem;
margin-top: var(--space-4); margin: var(--space-4) auto 0;
line-height: 1.75; line-height: 1.75;
} }
/* The back link is an inline button, which margin: auto cannot centre. A left
margin of half the free space puts it on the column's left edge instead, and
max() keeps it at 0 once the screen is narrower than the column. */
.btn-quiet {
margin-left: max(0px, (100% - 42rem) / 2);
}
.post ::deep :is(p, ul, ol, blockquote, .aufruf, .hinweis) { .post ::deep :is(p, ul, ol, blockquote, .aufruf, .hinweis) {
max-width: none; max-width: none;
} }
@@ -46,8 +54,8 @@
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: var(--space-3); gap: var(--space-3);
max-width: 68ch; max-width: 42rem;
margin-top: var(--space-6); margin: var(--space-6) auto 0;
padding-top: var(--space-4); padding-top: var(--space-4);
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
} }
@@ -10,3 +10,20 @@
grid-column: 1 / -1; grid-column: 1 / -1;
} }
} }
/* Same centred 42rem reading column as a content page (ContentPage.razor.css), so
every page of the site shares one column under the header. Two cards still fit
side by side in it. */
h1,
article,
p,
.post-list {
max-width: 42rem;
margin-inline: auto;
}
/* The intro's last paragraph drops its margin (app.css), so the first card would
sit right under the text; this gives it the same air as between sections. */
article {
margin-bottom: var(--space-5);
}
+107 -21
View File
@@ -170,6 +170,7 @@
light button text ................. 8.1 / 9.7 (hover 7.2 / 8.3) light button text ................. 8.1 / 9.7 (hover 7.2 / 8.3)
white on calendar band ............ 5.2 / 6.4 white on calendar band ............ 5.2 / 6.4
avatar blue / green ............... 7.2 / 8.6 5.9 / 6.7 avatar blue / green ............... 7.2 / 8.6 5.9 / 6.7
key figure / caption on card ...... 5.4 / 7.5 5.0 / 6.9
focus ring on page / card ......... 7.5 / 11.0 8.1 / 9.4 focus ring on page / card ......... 7.5 / 11.0 8.1 / 9.4
white ring on header / footer ..... 4.9 / 5.5 11.4 / 16.6 white ring on header / footer ..... 4.9 / 5.5 11.4 / 16.6
green markers on card (graphic) ... 3.8 / 7.5 green markers on card (graphic) ... 3.8 / 7.5
@@ -346,8 +347,12 @@ h1:focus {
links (and with them every card, which is one big link), buttons, the <summary> links (and with them every card, which is one big link), buttons, the <summary>
of each disclosure, form fields and anything made focusable with tabindex. Dark of each disclosure, form fields and anything made focusable with tabindex. Dark
brand surfaces (header, hero, footer) switch the colour to brand surfaces (header, hero, footer) switch the colour to
--color-focus-inverse. */ --color-focus-inverse.
:is(a, button, summary, input, select, textarea, [tabindex]):focus-visible { tabindex="-1" is left out: such an element is never reached with Tab, only
focused by code -- the h1 by FocusOnNavigate on every page load, <main> by the
skip link. Chromium counts that as :focus-visible, and since this rule outweighs
h1:focus / main:focus below, the page title would otherwise get a ring. */
:is(a, button, summary, input, select, textarea, [tabindex]:not([tabindex="-1"])):focus-visible {
outline: 3px solid var(--color-focus); outline: 3px solid var(--color-focus);
outline-offset: 2px; outline-offset: 2px;
} }
@@ -516,19 +521,18 @@ main:focus {
background: var(--color-accent); background: var(--color-accent);
} }
/* Mobile: the stacked links in the open menu become full-width rows with a /* Mobile: the open menu stacks the links centred, each as wide as its text -- so
rounded highlight instead of pills, and the green stroke shrinks to a short they stay the same pills as on the desktop, with the stroke under the whole word.
mark at the start, so a long row does not get a long line. Same global Only taller, for a comfortable tap target; the stroke moves up with the extra
placement, same NavLink reason as above. */ padding so it still sits right under the text, not at the pill's edge. Same
global placement, same NavLink reason as above. */
@media (max-width: 40rem) { @media (max-width: 40rem) {
.main-nav a { .main-nav a {
padding: 0.6rem var(--space-3); padding: 0.6rem var(--space-3);
border-radius: var(--radius-sm);
} }
.main-nav a.active::after { .main-nav a.active::after {
right: auto; bottom: 0.55rem;
width: 1.5rem;
} }
} }
@@ -902,24 +906,39 @@ main:focus {
mask: var(--icon-info) center / contain no-repeat; mask: var(--icon-info) center / contain no-repeat;
} }
/* ::: kacheln and ::: kennzahlen -- a list laid out as a grid of cards. auto-fill /* ::: kacheln and ::: kennzahlen -- a list laid out as a grid of cards. They keep
with a minimum width gives as many columns as fit (one on a phone) without any the 42rem reading column like the text and the other boxes: one calm left and
breakpoint. */ right edge down the page instead of blocks of three different widths. */
.markdown-body :is(.kacheln, .kennzahlen) > ul { .markdown-body :is(.kacheln, .kennzahlen) > ul {
display: grid; display: grid;
gap: var(--space-3); gap: var(--space-3);
max-width: none; box-sizing: border-box;
max-width: 42rem;
margin: 0 0 var(--space-4); margin: 0 0 var(--space-4);
padding: 0; padding: 0;
list-style: none; list-style: none;
} }
/* Kacheln: auto-fit with a 15rem minimum gives exactly two columns in the 42rem
(three would need 46rem), so four tiles sit as 2 x 2. Below ~31rem it drops to
one column -- two would squeeze a long word like "Chancengerechtigkeit" out of
its card. min() keeps a single card from overflowing a very narrow screen. */
.markdown-body .kacheln > ul { .markdown-body .kacheln > ul {
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}
/* Kennzahlen: one row of equal columns where there is room. auto-fill used to
leave empty tracks on the right on a wide screen and one figure alone in a second
row on a phone. A narrow column switches to stacked rows instead (below). The
block is its own container, so the switch follows the width the figures actually
get, not the screen. */
.markdown-body .kennzahlen {
container-type: inline-size;
} }
.markdown-body .kennzahlen > ul { .markdown-body .kennzahlen > ul {
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); grid-auto-flow: column;
grid-auto-columns: 1fr;
} }
/* The grid gap does the spacing; the list's own item spacing would only push the /* The grid gap does the spacing; the list's own item spacing would only push the
@@ -943,24 +962,87 @@ main:focus {
color: var(--color-heading); color: var(--color-heading);
} }
/* On a phone the tiles keep their card but tighten up, so four of them stacked
do not turn into a long scroll. */
@media (max-width: 40rem) {
.markdown-body .kacheln > ul {
gap: var(--space-2);
}
.markdown-body .kacheln li {
padding: var(--space-2) var(--space-3);
}
.markdown-body .kacheln li > strong:first-child {
margin-bottom: 0;
}
}
/* Kennzahlen: "- **seit 1975** Gründung" -- the bold part becomes a big figure, /* Kennzahlen: "- **seit 1975** Gründung" -- the bold part becomes a big figure,
the rest a small caption beneath. Brand blue for the figure, not the green: the the rest a small caption beneath. A white card with a green stroke on top, not
green does not reach 3:1 on its own tint, the blue does. */ a green wash: a ::: hinweis often follows right below, and two green tints in a
row ran together into one green patch. Brand blue for the figure: 5.4:1 on the
card (5.0 dark), where the green would not reach 3:1. */
.markdown-body .kennzahlen li { .markdown-body .kennzahlen li {
padding: var(--space-4) var(--space-3); padding: var(--space-4) var(--space-2);
border-top: 4px solid var(--color-accent);
border-radius: var(--radius); border-radius: var(--radius);
background: var(--color-accent-tint); background: var(--color-bg);
box-shadow: var(--shadow);
color: var(--color-text-soft); color: var(--color-text-soft);
text-align: center; text-align: center;
} }
/* The figure scales with the block (cqi, not vw): 2rem in the full 42rem, a little
less just above the switch to rows. nowrap: "seit 1975" split over two lines
reads as two figures. */
.markdown-body .kennzahlen li > strong:first-child { .markdown-body .kennzahlen li > strong:first-child {
display: block; display: block;
color: var(--color-brand); color: var(--color-brand);
font-size: 2rem; font-size: clamp(1.5rem, 4.75cqi, 2rem);
font-weight: var(--font-weight-heading); font-weight: var(--font-weight-heading);
letter-spacing: var(--letter-spacing-heading); letter-spacing: var(--letter-spacing-heading);
line-height: 1.15; line-height: 1.15;
white-space: nowrap;
}
/* Below 30rem three columns get under 10rem each: the figure no longer fits on one
line and a caption like "im Einsatz für die IGMH" stacks up word by word. So the
figures become rows of one card -- figure left, caption beside it, a thin line
between rows. Subgrid gives every row the same figure column, so the captions
line up whatever the figure's length. */
@container (max-width: 30rem) {
.markdown-body .kennzahlen > ul {
grid-auto-flow: row;
grid-template-columns: max-content 1fr;
gap: 0;
border-top: 4px solid var(--color-accent);
border-radius: var(--radius);
background: var(--color-bg);
box-shadow: var(--shadow);
}
.markdown-body .kennzahlen li {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
column-gap: var(--space-3);
align-items: baseline;
padding: var(--space-2) var(--space-3);
border-top: none;
border-radius: 0;
background: none;
box-shadow: none;
text-align: left;
}
.markdown-body .kennzahlen li + li {
border-top: 1px solid var(--color-border);
}
.markdown-body .kennzahlen li > strong:first-child {
font-size: 1.35rem;
}
} }
/* ::: team -- one person card per list item (Markdown.cs/TeamMember.cs build the /* ::: team -- one person card per list item (Markdown.cs/TeamMember.cs build the
@@ -968,13 +1050,17 @@ main:focus {
a normal heading; every group is a block of its own. One raster for all of them, a normal heading; every group is a block of its own. One raster for all of them,
so the cards line up across groups: a group of one person gets the same card so the cards line up across groups: a group of one person gets the same card
width as a group of six, not a stretched one. 17rem fits a long double name. width as a group of six, not a stretched one. 17rem fits a long double name.
Like every other block it stays in the 42rem reading column, so the cards share
the edges of the text above and below them; that leaves room for two columns
(three would need 52.5rem), one on a phone.
The cards of a row share one height (the grid's default stretch), so a row reads The cards of a row share one height (the grid's default stretch), so a row reads
as a calm band; the card itself keeps its content at the top (align-content). */ as a calm band; the card itself keeps its content at the top (align-content). */
.markdown-body .team > ul { .markdown-body .team > ul {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
gap: var(--space-3); gap: var(--space-3);
max-width: none; box-sizing: border-box;
max-width: 42rem;
margin: 0 0 var(--space-4); margin: 0 0 var(--space-4);
padding: 0; padding: 0;
list-style: none; list-style: none;