diff --git a/site/assets/site.css b/site/assets/site.css index 9f8dfd9..3287160 100644 --- a/site/assets/site.css +++ b/site/assets/site.css @@ -291,12 +291,15 @@ img.frame{width:100%;height:auto;object-fit:cover;transition:transform .8s var(- /* ---------- footer ---------- */ .footer{background:var(--ink);color:rgba(246,242,234,.78);padding-block:clamp(2.6rem,5vw,4.4rem) 1.6rem;font-size:.92rem} .footer a:hover{color:#fff} -.footer__grid{display:grid;gap:2rem;grid-template-columns:minmax(0,1.5fr) repeat(auto-fit,minmax(9rem,1fr))} +/* The brand column must keep a real minimum: with minmax(0,…) the auto-fit link + columns at their 9rem floor squeezed it to a few pixels between ~390px and + ~960px, so the network/contact headings overlapped the logo and the claim. */ +.footer__grid{display:grid;gap:2rem;grid-template-columns:minmax(15rem,1.5fr) repeat(auto-fit,minmax(9rem,1fr))} .footer__brand .brand{color:var(--paper)} .footer__brand .brand__mark{box-shadow:0 0 0 1px rgba(246,242,234,.34)} .footer__claim{margin-top:1rem;max-width:34ch;color:rgba(246,242,234,.66);font-size:.9rem} .footer h2{font-family:var(--font-sans);font-size:.74rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:rgba(246,242,234,.5);margin-bottom:.9rem} -.footer__links{display:grid;gap:.5rem} +.footer__links{display:grid;gap:.5rem;overflow-wrap:anywhere} .footer__bottom{ margin-top:clamp(2rem,4vw,3.2rem);padding-top:1.2rem;border-top:1px solid rgba(246,242,234,.16); display:flex;flex-wrap:wrap;gap:.6rem 1.4rem;justify-content:space-between;font-size:.82rem;color:rgba(246,242,234,.58); @@ -492,6 +495,10 @@ img.frame{width:100%;height:auto;object-fit:cover;transition:transform .8s var(- .scroll-cue{display:none} } @media (max-width:52rem){ + /* Below this width the brand sits on its own full-width row and the four link + columns pair up 2x2, so nothing can overlap. */ + .footer__grid{grid-template-columns:repeat(2,minmax(0,1fr))} + .footer__brand{grid-column:1/-1} .nav{ position:fixed;inset:4.4rem 0 auto;margin:0; flex-direction:column;align-items:stretch;gap:.15rem; diff --git a/src/theme.py b/src/theme.py index d305479..622592c 100644 --- a/src/theme.py +++ b/src/theme.py @@ -300,12 +300,15 @@ img.frame{width:100%;height:auto;object-fit:cover;transition:transform .8s var(- /* ---------- footer ---------- */ .footer{background:var(--ink);color:rgba(246,242,234,.78);padding-block:clamp(2.6rem,5vw,4.4rem) 1.6rem;font-size:.92rem} .footer a:hover{color:#fff} -.footer__grid{display:grid;gap:2rem;grid-template-columns:minmax(0,1.5fr) repeat(auto-fit,minmax(9rem,1fr))} +/* The brand column must keep a real minimum: with minmax(0,…) the auto-fit link + columns at their 9rem floor squeezed it to a few pixels between ~390px and + ~960px, so the network/contact headings overlapped the logo and the claim. */ +.footer__grid{display:grid;gap:2rem;grid-template-columns:minmax(15rem,1.5fr) repeat(auto-fit,minmax(9rem,1fr))} .footer__brand .brand{color:var(--paper)} .footer__brand .brand__mark{box-shadow:0 0 0 1px rgba(246,242,234,.34)} .footer__claim{margin-top:1rem;max-width:34ch;color:rgba(246,242,234,.66);font-size:.9rem} .footer h2{font-family:var(--font-sans);font-size:.74rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:rgba(246,242,234,.5);margin-bottom:.9rem} -.footer__links{display:grid;gap:.5rem} +.footer__links{display:grid;gap:.5rem;overflow-wrap:anywhere} .footer__bottom{ margin-top:clamp(2rem,4vw,3.2rem);padding-top:1.2rem;border-top:1px solid rgba(246,242,234,.16); display:flex;flex-wrap:wrap;gap:.6rem 1.4rem;justify-content:space-between;font-size:.82rem;color:rgba(246,242,234,.58); @@ -501,6 +504,10 @@ img.frame{width:100%;height:auto;object-fit:cover;transition:transform .8s var(- .scroll-cue{display:none} } @media (max-width:52rem){ + /* Below this width the brand sits on its own full-width row and the four link + columns pair up 2x2, so nothing can overlap. */ + .footer__grid{grid-template-columns:repeat(2,minmax(0,1fr))} + .footer__brand{grid-column:1/-1} .nav{ position:fixed;inset:4.4rem 0 auto;margin:0; flex-direction:column;align-items:stretch;gap:.15rem; diff --git a/tests/test_site.py b/tests/test_site.py index 3b0d4d3..671af0c 100644 --- a/tests/test_site.py +++ b/tests/test_site.py @@ -556,6 +556,25 @@ class Redesign(unittest.TestCase): with self.subTest(needle=needle): self.assertIn(needle, js) + def test_footer_grid_keeps_a_readable_brand_column(self): + """Regression: the brand track was `minmax(0,1.5fr)`, so the 9rem auto-fit + link columns squeezed it to a few pixels between roughly 390px and 960px and + the "Kontakt"/"Netzwerk" headings overlapped the logo and the claim. The + brand column must keep a real minimum and the narrow layout must give the + brand a full-width row.""" + css = read(SITE / "assets" / "site.css") + grid = re.search(r"\.footer__grid\{[^}]*\}", css) + self.assertIsNotNone(grid, "footer grid rule missing") + self.assertIn("minmax(15rem,1.5fr)", grid.group(0)) + self.assertNotIn("minmax(0,1.5fr)", grid.group(0)) + narrow = re.search(r"@media \(max-width:52rem\)\{(?:(?!\n\}).)*?\n\}", css, re.S) + self.assertIsNotNone(narrow, "52rem breakpoint missing") + self.assertIn(".footer__brand{grid-column:1/-1}", narrow.group(0)) + self.assertIn(".footer__grid{grid-template-columns:repeat(2,minmax(0,1fr))}", narrow.group(0)) + # Long unbreakable tokens (the e-mail address) must wrap instead of spilling + # out of a narrow column. + self.assertIn(".footer__links{display:grid;gap:.5rem;overflow-wrap:anywhere}", css) + class Release(unittest.TestCase): def test_deploy_removes_only_targeted_desfoto_labels(self):