/* ============================================================
   Altair Power — altair-power.com
   Design: light technical "spec sheet" aesthetic.
   Type: Archivo (variable width) display + body, IBM Plex Mono for
   eyebrows, spec values and labels. Palette from the Altair mark.
   ============================================================ */

:root {
  --ink: #0c2a3a;          /* deep petrol, primary text */
  --ink-soft: #3c5a6b;     /* secondary text */
  --petrol: #16506e;       /* dark brand blue */
  --azure: #1b9fd8;        /* primary accent (logo azure) */
  --azure-deep: #147bb0;   /* hover / borders on accent */
  --aqua: #22d3c0;         /* secondary accent, sparing */
  --paper: #ffffff;
  --mist: #f2f7fa;         /* light section background */
  --line: #d9e5ec;         /* hairlines */
  --ok: #1e9e6a;
  --bad: #c04545;

  --font-body: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", monospace;

  --w-max: 1200px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --radius: 10px;
  --shadow: 0 10px 30px -12px rgba(12, 42, 58, .18);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  font-variation-settings: "wdth" 100;
  overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--azure-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 3px solid var(--azure);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ---------- typography ---------- */

h1, h2, h3, h4 {
  font-family: var(--font-body);
  font-variation-settings: "wdth" 118;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 .6em;
  text-wrap: balance;
  /* Dutch compounds ("waterstoftankstations") overflow narrow screens
     without this; hyphenation uses the lang attribute on <html>. */
  overflow-wrap: break-word;
  hyphens: auto;
}

h1 { font-size: clamp(2.4rem, 6vw, 4.1rem); }

/* For headings carrying long Dutch compounds ("waterstofstroom") that can't be
   reworded — the EFRO project title is fixed by the subsidy rules. A smaller
   scale lets the longest word fit whole, so no mid-word hyphen is needed. */
h1.h1--long {
  font-size: clamp(1.75rem, 4.4vw, 3.3rem);
  hyphens: manual;
}
h2 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.45rem); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

.lead {
  font-size: clamp(1.1rem, 1.9vw, 1.3rem);
  color: var(--ink-soft);
  max-width: 38em;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--azure-deep);
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 0 0 1.1rem;
}

.eyebrow::before {
  content: "";
  width: 2rem;
  height: 2px;
  background: var(--azure);
  flex: none;
}

.mono { font-family: var(--font-mono); }

/* ---------- layout primitives ---------- */

.wrap {
  width: min(var(--w-max), 100% - 2 * var(--gutter));
  margin-inline: auto;
}

.section { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.section--mist { background: var(--mist); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1.25rem;
}

/* ---------- header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 4.75rem;
}

/* Star mark + wordmark, read as one lockup. Both are capped in height: together
   they are ~5x wider than tall, and on the EFRO page the whole lockup has to
   stay narrower than the EU emblem. See the emblem sizing note before growing
   either of these. */
.brand {
  display: flex;
  align-items: center;
  gap: .55rem;
}
.brand:hover { text-decoration: none; }

.brand-mark {
  height: clamp(2.1rem, 3.6vw, 2.6rem);
  width: auto;
  flex: none;
}

.brand-word {
  height: clamp(1.7rem, 2.8vw, 2.1rem);
  width: auto;
  flex: none;
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
}

.site-nav a {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: .97rem;
  padding: .35rem 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.site-nav a:hover { color: var(--ink); text-decoration: none; }
.site-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--azure);
}

/* Selector is .site-nav .lang-switch so it outranks `.site-nav a` without
   !important — otherwise the nav's bottom-border rule reshapes the pill. */
.site-nav .lang-switch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 3rem;
  height: 2.1rem;
  padding: 0 .75rem;
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .06em;
  line-height: 1;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
}

.site-nav .lang-switch:hover {
  border-color: var(--azure);
  color: var(--azure-deep);
  text-decoration: none;
}

.nav-toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .5rem .65rem;
  cursor: pointer;
  color: var(--ink);
}
.nav-toggle svg { display: block; }

/* Switches to the hamburger while the wordmark plus six labels would still be
   too wide for one line — the labels no longer wrap, so they must fit. */
@media (max-width: 960px) {
  .nav-toggle { display: block; }

  /* Smaller lockup below the desktop nav breakpoint. This also lets the EU
     emblem come down proportionally on the funding page while still staying
     larger than every other logo — the two are tuned together. */
  .brand { gap: .45rem; }
  .brand-mark { height: 1.8rem; }
  .brand-word { height: 1.4rem; }
  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    padding: .5rem var(--gutter) 1rem;
    box-shadow: var(--shadow);
  }
  .site-nav.open { display: flex; }
  .site-nav a { padding: .8rem 0; border-bottom: 1px solid var(--mist); font-size: 1.05rem; }
  .site-nav a[aria-current="page"] { border-bottom-color: var(--azure); }
  .site-nav .lang-switch { margin-top: 1rem; align-self: flex-start; }
}

/* ---------- hero ---------- */

.hero { overflow: hidden; }

/* Named areas so the image can sit between the text and the buttons on phones
   while staying in its own column on desktop. */
.hero .wrap {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  grid-template-areas:
    "text  media"
    "ctas  media";
  column-gap: clamp(1.5rem, 4vw, 3rem);
  row-gap: 1.8rem;
  align-items: center;
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

.hero-text { grid-area: text; align-self: end; }
.hero .hero-media { grid-area: media; }
.hero .hero-ctas { grid-area: ctas; align-self: start; margin-top: 0; }

/* Hero headline sets one word per line. Each word is its own block, so the
   line breaks are fixed at every width and `text-wrap: balance` can't decide
   to hyphenate mid-word ("zon-der") to even the lines out. */
.hero h1 {
  hyphens: manual;
  text-wrap: normal;
}

.hero h1 .line { display: block; }

/* No ambient glow here: the product photo carries its own shadow on an opaque
   white background, so a gradient behind it would show as a tinted band along
   the image edges. */
.hero-media { position: relative; }

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  margin-top: 1.8rem;
}

@media (max-width: 900px) {
  .hero .wrap {
    grid-template-columns: 1fr;
    grid-template-areas: "text" "media" "ctas";
  }
  .hero-media { max-width: 34rem; }
}

/* Text / image / call-to-action block. On desktop the image holds its own
   column beside the text; on phones the image slots in between the text and
   the button rather than being pushed below it. */
.feature {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-areas:
    "text media"
    "cta  media";
  column-gap: clamp(1.5rem, 4vw, 4rem);
  row-gap: 1.6rem;
  align-items: center;
}

.feature__text  { grid-area: text; align-self: end; }
.feature__cta   { grid-area: cta;  align-self: start; }
.feature__media { grid-area: media; }

@media (max-width: 900px) {
  .feature {
    grid-template-columns: 1fr;
    grid-template-areas: "text" "media" "cta";
  }
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-weight: 600;
  font-size: 1rem;
  padding: .78rem 1.5rem;
  border-radius: 999px;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn:hover { text-decoration: none; }

.btn--primary { background: var(--petrol); color: #fff; }
.btn--primary:hover { background: var(--azure-deep); }

.btn--ghost { border-color: var(--line); color: var(--ink); background: transparent; }
.btn--ghost:hover { border-color: var(--azure); color: var(--azure-deep); }

/* ---------- spec strip (signature element) ---------- */

.spec-strip {
  border-block: 1px solid var(--line);
  background: var(--paper);
}

.spec-strip .wrap {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0;
}

.spec {
  padding: 1.1rem 1.25rem;
  border-left: 1px solid var(--line);
}
.spec:first-child { border-left: none; }

.spec dt {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 .15rem;
}

.spec dd {
  margin: 0;
  font-variation-settings: "wdth" 118;
  font-weight: 700;
  font-size: clamp(1.05rem, 1.8vw, 1.4rem);
  text-wrap: balance;
}

.spec dd small {
  display: block;
  font-weight: 500;
  font-size: .62em;
  color: var(--ink-soft);
  font-variation-settings: "wdth" 100;
}

@media (max-width: 900px) {
  .spec-strip .wrap { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spec { border-left: none; border-top: 1px solid var(--line); }
  .spec:nth-child(-n+2) { border-top: none; }
  .spec:nth-child(even) { border-left: 1px solid var(--line); }

  /* With an odd number of specs the last one would sit alone in the left
     column with an empty cell beside it, reading as if it had fallen out of
     the grid. Span the full row instead. */
  .spec:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ---------- cards ---------- */

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem 1.5rem;
}

.card h3 { display: flex; align-items: center; gap: .65rem; }

.card .num {
  font-family: var(--font-mono);
  font-size: .75rem;
  font-weight: 500;
  color: var(--azure-deep);
  letter-spacing: .1em;
}

.card-icon {
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 8px;
  background: var(--mist);
  color: var(--petrol);
  display: grid;
  place-items: center;
  margin-bottom: 1rem;
}
.card-icon svg { width: 1.5rem; height: 1.5rem; }

.card p { color: var(--ink-soft); font-size: .98rem; }

/* ---------- comparison ---------- */

.compare-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1.25rem;
  align-items: stretch;
}

.compare-card { display: flex; flex-direction: column; }

.compare-card ul {
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
  display: grid;
  gap: .55rem;
  font-size: .95rem;
  color: var(--ink-soft);
}

.compare-card li {
  display: flex;
  gap: .6rem;
  align-items: baseline;
}

.compare-card li::before {
  font-family: var(--font-mono);
  font-weight: 600;
  flex: none;
}

/* Per-item marks: every card can list both strengths and drawbacks. */
.compare-card li.pro::before { content: "✓"; color: var(--ok); }
.compare-card li.con::before { content: "×"; color: var(--bad); }

/* Small breathing space where the ✓ items give way to the × items. */
.compare-card li.pro + li.con { margin-top: .5rem; }

.compare-card--pro {
  border-color: var(--azure);
  box-shadow: var(--shadow);
  background: linear-gradient(180deg, #fff, var(--mist));
}

/* The solution name is the card heading; the descriptive phrase sits beneath it
   as a quiet subtitle. Sentence case on purpose — the mono uppercase treatment
   used for eyebrows elsewhere would shout a whole phrase. */
.compare-card h3 { margin-bottom: .2rem; }

.compare-card .tag {
  font-family: var(--font-body);
  font-size: .95rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  margin: 0;
}

.compare-card--pro .tag { color: var(--azure-deep); }

/* ---------- mode toggle (power pack page) ---------- */

.mode-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .25rem;
  gap: .25rem;
  background: var(--paper);
  margin-bottom: 1.5rem;
}

.mode-toggle button {
  font: inherit;
  font-weight: 600;
  font-size: .95rem;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  padding: .55rem 1.3rem;
  border-radius: 999px;
  cursor: pointer;
}

.mode-toggle button[aria-pressed="true"] {
  background: var(--petrol);
  color: #fff;
}

.mode-panel[hidden] { display: none; }

/* ---------- spec table ---------- */

.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .98rem;
}

.spec-table th, .spec-table td {
  text-align: left;
  padding: .75rem .5rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.spec-table th {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
  width: 42%;
}

.spec-table td { font-weight: 600; }

/* ---------- steps / operation cycle ---------- */

.steps {
  counter-reset: step;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  gap: 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.steps li {
  counter-increment: step;
  border-top: 2px solid var(--line);
  padding-top: 1rem;
  position: relative;
}

.steps li::before {
  content: "0" counter(step);
  font-family: var(--font-mono);
  color: var(--azure-deep);
  font-size: .8rem;
  letter-spacing: .1em;
}

.steps h3 { font-size: 1.1rem; margin: .3rem 0 .4rem; }
.steps p { color: var(--ink-soft); font-size: .95rem; }

/* ---------- EU project page ---------- */

.eu-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  padding: clamp(.9rem, 3vw, 2rem);
}

/* Emblem and SNN mark sit side by side so the banner stays a compact band
   rather than a full-screen stack on phones. */
.eu-banner__logos {
  display: flex;
  align-items: center;
  gap: clamp(.6rem, 3vw, 2rem);
  /* Must be shrinkable, not `flex: none` — otherwise this box sizes to its own
     content and overflows the banner instead of letting the SNN mark wrap. */
  flex: 0 1 auto;
  min-width: 0;
  flex-wrap: wrap;
}

.eu-banner img { width: auto; }

/* The EU emblem must remain the largest logo on the page — in height AND in
   footprint. Every other logo below is capped on both axes to guarantee that,
   whatever aspect ratio a partner logo has. Do not raise those caps. */
/* Sized so the emblem stays wider AND taller than every other logo on the page
   at every viewport — including the full header lockup (star + wordmark), whose
   combined width is about 5x its height. Changing either this or the
   `.brand-mark` / `.brand-word` heights without re-checking the other can break
   the subsidy requirement. */
.eu-banner .eu-emblem { height: clamp(165px, 20vw, 230px); flex: none; }
/* Scales down on narrow screens so it still fits beside the emblem instead of
   wrapping onto its own row. Always well under the emblem on every axis. */
.eu-banner .snn-logo {
  max-height: 76px;
  max-width: clamp(80px, 22vw, 136px);
  height: auto;
  flex: none;
}

/* Takes the slack between emblem and SNN logo so the SNN mark sits at the
   right edge of the card instead of floating in the middle. */
.eu-banner .funding-statement {
  flex: 1 1 14em;
  font-weight: 600;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  line-height: 1.35;
  margin: 0;
}

.partner-logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2rem;
}

.partner-logos figure {
  margin: 0;
  display: grid;
  gap: .5rem;
  justify-items: center;
}

/* Caps track the EU emblem, which is 165px on phones and grows to 230px on
   desktop. Staying under it on every axis is the subsidy requirement, not a
   style choice — re-check the funding page at several widths if you change
   either value. */
.partner-logos img {
  max-height: 76px;
  max-width: clamp(140px, 16vw, 170px);
  width: auto;
  height: auto;
}

.partner-logos a {
  display: block;
  transition: opacity .15s ease;
}
.partner-logos a:hover { opacity: .7; }

.partner-logos figcaption {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .08em;
  color: var(--ink-soft);
}

/* Mandatory project text beside the impression image. The text column keeps a
   readable measure; the image column is sized to the portrait crop. */
.project-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(200px, 26%, 320px);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

.project-intro > div { max-width: 46em; }

@media (max-width: 820px) {
  .project-intro { grid-template-columns: 1fr; }
  .project-intro .impression { margin-top: 1rem; }
}

/* Artist's impression on the funding page. Captioned as such deliberately: the
   page doubles as subsidy evidence, so a rendering must not read as a photo of
   work already carried out. */
.impression {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: .9rem;
}

.impression img {
  width: 100%;
  max-width: 320px;
  height: auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.impression figcaption {
  font-size: .92rem;
  color: var(--ink-soft);
  max-width: 42em;
  text-align: center;
}

.impression figcaption .tag-impression {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--azure-deep);
  display: block;
  margin-bottom: .25rem;
}

.update-list { display: grid; gap: 1rem; }

.update {
  border-left: 3px solid var(--azure);
  background: var(--paper);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 1rem 1.25rem;
}

.update time {
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--azure-deep);
}

.update h3 { font-size: 1.05rem; margin: .25rem 0 .3rem; }
.update p { color: var(--ink-soft); font-size: .95rem; }

/* ---------- contact ---------- */

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

@media (max-width: 860px) {
  .contact-grid { grid-template-columns: 1fr; }
}

.contact-details { display: grid; gap: 1.4rem; }

.contact-details .label {
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .2rem;
}

.contact-details a { font-weight: 600; }

.form-grid { display: grid; gap: 1rem; }

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }

.field { display: grid; gap: .35rem; }

.field label {
  font-weight: 600;
  font-size: .92rem;
}

.field label .opt {
  font-weight: 400;
  color: var(--ink-soft);
  font-size: .85em;
}

.field input, .field textarea {
  font: inherit;
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .7rem .9rem;
  background: var(--paper);
  width: 100%;
}

.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--azure);
  box-shadow: 0 0 0 3px rgba(27, 159, 216, .15);
}

.form-note { font-size: .88rem; color: var(--ink-soft); }

/* ---------- CTA band ---------- */

.cta-band {
  background: linear-gradient(120deg, var(--petrol), #0d3c56 60%, #0c2a3a);
  color: #fff;
}

.cta-band .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
}

.cta-band h2 { margin: 0 0 .2em; }
.cta-band p { color: rgba(255, 255, 255, .75); margin: 0; }

.cta-band .btn--primary { background: #fff; color: var(--petrol); }
.cta-band .btn--primary:hover { background: var(--aqua); color: var(--ink); }

/* ---------- footer ---------- */

.site-footer {
  background: #0c2a3a;
  color: rgba(255, 255, 255, .82);
  font-size: .95rem;
}

.site-footer .wrap {
  padding-block: clamp(2.5rem, 5vw, 3.5rem) 1.5rem;
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1.4fr;
  gap: 2rem;
  padding-bottom: 2rem;
  border-bottom: 1px solid rgba(255, 255, 255, .14);
}

@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }

/* Footer column headings are <h2> so the document outline has no level gaps;
   they are styled down to a small label. */
.site-footer h2 {
  font-size: .78rem;
  font-family: var(--font-mono);
  font-variation-settings: normal;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  margin: 0 0 .9rem;
}

.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.site-footer a { color: rgba(255, 255, 255, .85); }
.site-footer a:hover { color: #fff; }

.footer-brand img { height: 2.4rem; margin-bottom: .8rem; }
.footer-brand .slogan {
  font-variation-settings: "wdth" 118;
  font-weight: 700;
  color: #fff;
  font-size: 1.1rem;
}

.footer-eu {
  display: flex;
  align-items: center;
  gap: .9rem;
}

.footer-eu img {
  height: 74px;
  width: auto;
  background: #fff;
  padding: 6px;
  border-radius: 6px;
}

.footer-eu p { font-size: .85rem; color: rgba(255, 255, 255, .75); margin: 0; }

.footer-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  padding-top: 1.25rem;
  font-size: .82rem;
  color: rgba(255, 255, 255, .5);
}

/* ---------- reveal animation ---------- */

/* Scoped to .js so that content is never hidden when scripts fail to run —
   the funding page must stay readable under any circumstances. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}

.js .reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal, .js .reveal.in { opacity: 1; transform: none; transition: none; }
}

/* ---------- utilities ---------- */

.center { text-align: center; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }
.max-prose { max-width: 46em; }
.muted { color: var(--ink-soft); }

.section-head { max-width: 46em; margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--petrol);
  color: #fff;
  padding: .6rem 1rem;
  z-index: 100;
  border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }
