This commit is contained in:
Felix Klement committed 2026-10-07 21:20:56 +02:00
1 parent a4c2ff3b32
commit 3cb5952e6d
4 files changed
+63 -19

No files matched your search

+48 -10
View File
@@ -2,12 +2,13 @@
import { Picture } from 'astro:assets';
import fiveG from '../../assets/images/sector-5g.jpg';
import substation from '../../assets/images/sector-substation.jpg';
import controlRoom from '../../assets/images/sector-ot.jpg';
import datacentre from '../../assets/images/sector-datacentre.jpg';
import { t, type Lang } from '../../i18n/ui';
interface Props { lang: Lang }
const { lang } = Astro.props;
const ui = t(lang);
const images = [fiveG, substation, datacentre];
const images = [fiveG, substation, controlRoom, datacentre];
const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id: `sector-${i + 1}` }));
---
<section class="section sectors" id="sectors" aria-labelledby="sectors-title">
@@ -36,8 +37,8 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
alt={item.imageAlt}
formats={['avif']}
fallbackFormat="webp"
widths={[480, 768, 1024, 1440]}
sizes="(min-width: 64rem) 50vw, 100vw"
widths={[480, 768, 1024, 1440, 1920]}
sizes="(min-width: 64rem) 60vw, 100vw"
loading="lazy"
decoding="async"
class="sectors__img img-doc"
@@ -56,8 +57,8 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
alt=""
formats={['avif']}
fallbackFormat="webp"
widths={[480, 768, 1024, 1440]}
sizes="(min-width: 64rem) 50vw, 100vw"
widths={[480, 768, 1024, 1440, 1920]}
sizes="(min-width: 64rem) 60vw, 100vw"
loading="lazy"
decoding="async"
class="sectors__img img-doc"
@@ -81,11 +82,34 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
flex-direction: column;
gap: var(--space-8);
}
.sectors__tabs { margin-top: auto; }
.sectors__tab + .sectors__tab { margin-top: var(--space-5); }
/* The tabs are rows between hairlines. The selected row's rule turns ink: that is the marker. */
.sectors__tabs {
margin-top: auto;
border-bottom: var(--hairline) solid var(--line);
}
.sectors__tab {
position: relative;
border-top: var(--hairline) solid var(--line);
}
.sectors__tab::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: calc(-1 * var(--hairline));
height: var(--hairline);
background: var(--ink);
transform: scaleX(0);
transform-origin: left;
transition: transform var(--dur-slow) var(--ease);
}
.sectors__tab:has([aria-selected='true'])::before { transform: none; }
.sectors__heading { font-size: inherit; font-weight: inherit; }
/* The whole row is the button, so the target is as wide as the column. */
.sectors__button {
display: block;
width: 100%;
padding-block: var(--space-5) var(--space-3);
text-align: left;
font-size: var(--step-h3);
line-height: var(--leading-h3);
@@ -96,7 +120,11 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
}
.sectors__button[aria-selected='false'] { color: var(--ink-muted); }
.sectors__button[aria-selected='false']:hover { color: var(--ink); }
.sectors__panel-inner { display: grid; gap: var(--space-5); padding-top: var(--space-3); }
.sectors__panel-inner { display: grid; gap: var(--space-5); }
/* The button keeps a small step below its title, so an open body sits close under it and the
focus ring never crosses the text. The rest of the row padding is the panel's margin: below
the body when open, in place of it when closed, so every row is symmetric. */
.sectors__panel { margin-bottom: var(--space-5); }
.sectors__panel p { max-width: 28em; }
:global(.sectors__picture) { display: block; width: 100%; }
.sectors__img, :global(.sectors__img) { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
@@ -110,17 +138,27 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
display: grid;
grid-template-rows: 0fr;
overflow: hidden;
transition: grid-template-rows var(--dur-slow) var(--ease);
transition:
grid-template-rows var(--dur-slow) var(--ease),
margin var(--dur-slow) var(--ease);
}
:global(html.js) .sectors__panel-inner { min-height: 0; }
:global(html.js) .sectors__panel[data-open] { grid-template-rows: 1fr; }
:global(html.js) .sectors__panel:not([data-open]) { margin-bottom: calc(var(--space-5) - var(--space-3)); }
@media (min-width: 64rem) {
.sectors__text { grid-column: 1 / span 5; }
/* The image runs past the container to the right edge of the window: the page gutter, plus
half of whatever the window is wider than the container. The section clips, so a classic
scrollbar (counted in 100vw) cannot cause a horizontal scroll. */
.sectors { overflow-x: clip; }
.sectors__media {
grid-column: 7 / span 6;
display: grid;
margin-right: calc(-1 * (max(var(--gutter), var(--safe-right)) + max(0px, (100vw - var(--container)) / 2)));
}
/* Near square, but never taller than a screenful on very wide windows. */
.sectors__media :global(.sectors__img) { aspect-ratio: 5 / 4; max-height: 45rem; }
.sectors__media :global(.sectors__picture--stage) {
grid-area: 1 / 1;
opacity: 0;
@@ -132,7 +170,7 @@ const items = ui.sectors.items.map((item, i) => ({ ...item, image: images[i], id
}
@media (prefers-reduced-motion: reduce) {
.sectors__panel, .sectors__media :global(.sectors__picture--stage) { transition: none; }
.sectors__panel, .sectors__tab::before, .sectors__media :global(.sectors__picture--stage) { transition: none; }
}
</style>