/* ─────────────────────────────────────────────────────────────────────────
   D-Allians — couche site.
   Nocturne (nocturne.css) reste la source de vérité : aucune couleur, taille
   de police, espacement, radius ou ombre n'est écrit en dur ici — tout passe
   par les tokens var(--*). Ce fichier ne fait que poser les gabarits de page.
   ───────────────────────────────────────────────────────────────────────── */

/* ── Voix de marque ─────────────────────────────────────────────────────── */
/* Playfair Display porte le nom et les titres de page. Ce n'est pas un choix
   « éditorial » gratuit : c'est le serif que D-Allians utilise déjà sur ses
   propres visuels, et les petites capitales reproduisent le lettrage de la
   plaque de marque. Inter reste la police de travail (corps, interface,
   navigation), donc la hiérarchie est nette : le serif parle au nom de la
   marque, la sans porte l'information. */
:root {
  --font-display: 'Playfair Display', 'Iowan Old Style', Georgia, serif;
}

.wordmark {
  font-family: var(--font-display);
  font-variant-caps: small-caps;
  font-weight: 500;
  letter-spacing: .06em;
  line-height: 1;
}

h1, .display {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -.005em;
  line-height: 1.06;
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Les pages courtes (Services, Témoignages) laissaient le pied de page flotter
   au milieu d'un grand écran ; il est poussé en bas sans devenir fixe. */
body { overflow-x: hidden; min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1 0 auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Le lien d'évitement : invisible jusqu'au premier Tab. */
.skip-link {
  position: absolute; left: var(--space-4); top: -100px; z-index: 200;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-text); text-decoration: none;
}
.skip-link:focus { top: var(--space-4); }

/* ── Conteneurs ─────────────────────────────────────────────────────────── */
/* Une seule gouttière pour tout le site : `.wrap` fixe le bord gauche, et
   toutes les pages s'y alignent — en-tête, pied de page et contenu compris. */
.wrap { max-width: 1240px; margin-inline: auto; padding-inline: var(--space-6); }

/* Les blocs de lecture limitent la longueur de ligne sans se recentrer :
   Nocturne veut le texte contre la gouttière gauche et le blanc à droite.
   Les centrer casserait l'alignement d'une page à l'autre. */
.measure        { max-width: 1100px; }
.measure--prose { max-width: 900px; }
.measure--read  { max-width: 820px; }
.measure--tight { max-width: 760px; }
.measure--cta   { max-width: 640px; }

/* Nocturne construit sa verticalité sur --space-8 (22.4px), à une densité de
   0.7x pensée pour une interface. Un site vitrine n'est pas une interface :
   ce qui donne l'impression d'une maison installée, c'est l'air entre les
   sections. Les multiples sont donc ouverts, et bornés en `clamp` pour que
   le téléphone ne se retrouve pas avec des trous de 200px. */
.section      { padding-block: clamp(56px, 8vw, 124px); }
.section--sm  { padding-block: clamp(44px, 6vw, 88px); }
.page-head    { padding-block: clamp(64px, 9vw, 140px) clamp(36px, 5vw, 72px); }
.pt-0 { padding-top: 0; }

/* Les titres respirent avec les sections, sinon l'air ne fait que déplacer
   le problème : de gros blocs de texte séparés par du vide. */
h2 { font-size: clamp(28px, 3.4vw, 46px); line-height: 1.1; }
h3 { font-size: clamp(19px, 1.6vw, 24px); }
.section-head { margin-bottom: clamp(28px, 4vw, 56px); }

.eyebrow { color: var(--color-accent); }

.section-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-6);
}
.section-head h2 { margin-bottom: 0; }
.section-head a { font-size: 14px; white-space: nowrap; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-6); }

/* ── En-tête ────────────────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 100; width: 100%;
  background: color-mix(in srgb, var(--color-bg) 90%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--color-divider);
}
.site-header .nav { max-width: 1240px; margin-inline: auto; padding: var(--space-4) var(--space-6); }

.nav-brand { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; color: inherit; }
.nav-brand img { height: 32px; width: auto; }

.site-nav { display: flex; align-items: center; gap: var(--space-6); }
.nav-actions { display: flex; align-items: center; gap: var(--space-3); }

.mobile-menu {
  display: none; flex-direction: column; gap: var(--space-4);
  padding: var(--space-2) var(--space-6) var(--space-6);
  border-top: 1px solid var(--color-divider);
}
.mobile-menu[data-open='true'] { display: flex; }
.mobile-menu a { font-size: 16px; }

/* Nocturne met tous les <a> en accent souligné — juste pour un lien isolé dans
   un paragraphe, illisible pour une colonne de huit liens de navigation. Le
   menu mobile et le pied de page reprennent donc le traitement de la nav :
   couleur du texte au repos, accent au survol. */
.mobile-menu a, .footer-links a { color: inherit; text-decoration: none; }
.mobile-menu a:hover, .mobile-menu a[aria-current='page'],
.footer-links a:hover { color: var(--color-accent); }

/* Le prototype basculait à 880px en JS ; ici c'est une media query. */
@media (min-width: 880px) { .nav-burger { display: none; } .mobile-menu { display: none !important; } }
@media (max-width: 879px) { .site-nav, .nav-cta { display: none; } }

/* ── Bandes « présence » ────────────────────────────────────────────────── */
/* Les seuls aplats saturés du système. Le dégradé radial évite l'aplat mort. */
/* La gouttière horizontale vient du `.wrap` intérieur, pas de la bande :
   le fond saturé doit filer d'un bord à l'autre du viewport. */
.band {
  background-color: var(--color-section);
  background-image: radial-gradient(circle at 20% 20%, var(--color-section-glow), transparent 60%);
  padding-block: var(--space-8);
}
.band--cta {
  background-image: radial-gradient(circle at 80% 30%, var(--color-section-glow), transparent 60%);
  padding-block: calc(var(--space-8) * 2);
}
.band--hero { padding-block: calc(var(--space-8) * 2.5); }
.band--pay  { background-image: radial-gradient(circle at 30% 30%, var(--color-section-glow), transparent 60%);
              padding-block: calc(var(--space-8) * 1.5); }
.band h2 { color: var(--color-neutral-100); }
.band p  { color: var(--color-neutral-300); }

.surface { background: var(--color-surface); padding-block: calc(var(--space-8) * 1.5); }

/* ── Chiffres ───────────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
.stat-num   { font-family: var(--font-heading); font-size: 38px; line-height: 1.1; color: var(--color-neutral-100); }
.stat-label { font-size: 13px; margin-top: var(--space-1); }
.stats--pay { max-width: 640px; }
.stats--pay .stat-label { color: var(--color-neutral-300); }

/* ── Citation de marque ─────────────────────────────────────────────────── */
.brand-quote {
  font-family: var(--font-heading); font-style: italic;
  font-size: clamp(22px, 3vw, 30px); line-height: 1.4;
}
.brand-quote--lg { font-size: clamp(24px, 3.6vw, 36px); color: var(--color-neutral-100); }
.brand-quote--sm { font-size: 20px; color: var(--color-neutral-200); }
.quote-sub { margin-top: var(--space-4); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero { padding-block: calc(var(--space-8) * 3) calc(var(--space-8) * 2); }
.hero h1 { max-width: 820px; font-size: clamp(38px, 6vw, 72px); }
.hero > p { max-width: 560px; font-size: 17px; margin-top: var(--space-4); }

/* ── Hero à ouverture (accueil) ─────────────────────────────────────────── */
/* Le récit : on arrive sur Abidjan la nuit, le cadre s'ouvre, et on se
   retrouve à l'intérieur d'un espace livré par D-Allians. De la ville au
   salon. C'est le seul endroit du site où le mouvement raconte quelque chose,
   donc le seul endroit qui en porte.
   Trois règles tenues ici :
   - aucun détournement du scroll. La page défile normalement, l'animation
     est simplement indexée dessus ; on peut la traverser à toute vitesse.
   - aucun écouteur `scroll` en JavaScript. Tout passe par les animations CSS
     pilotées par le défilement, qui tournent hors du fil principal.
   - `clip-path` plutôt que width/height : la photo est posée une fois à sa
     taille finale et n'est jamais redimensionnée, donc jamais déformée, et
     il n'y a pas de recalcul de mise en page à chaque image. */

/* L'amplitude de l'ouverture et de l'écartement est pilotée par ces deux
   variables : sur un téléphone, 32vw d'écartement enverrait la moitié du
   titre hors de l'écran, et une fenêtre à 34% de marge latérale ne ferait
   plus que 120px de large. */
.reveal {
  position: relative; background: var(--color-bg);
  --split: 32vw; --open-x: 34%; --open-y: 31%;
}
@media (max-width: 760px) {
  .reveal { --split: 11vw; --open-x: 16%; --open-y: 27%; }
}

.reveal__viewport {
  position: relative; min-height: 100dvh; overflow: hidden;
  display: grid; place-items: center;
}

.reveal__bg, .reveal__frame { position: absolute; inset: 0; margin: 0; }
.reveal__bg img, .reveal__frame img { width: 100%; height: 100%; object-fit: cover; }

/* La ville reste en retrait : elle plante le décor, elle ne concurrence pas
   le titre. */
.reveal__bg { opacity: .55; }
.reveal__bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--color-bg) 55%, transparent),
    color-mix(in srgb, var(--color-bg) 80%, transparent));
}

/* Sans animation, on montre directement l'état d'arrivée : une belle photo
   cadrée, pas un écran à moitié construit. */
.reveal__frame { clip-path: inset(6% 4% 6% 4% round var(--radius-lg)); }
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .reveal__frame { clip-path: inset(var(--open-y) var(--open-x) var(--open-y) var(--open-x) round var(--radius-lg)); }
  }
}
.reveal__frame::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--color-bg) 30%, transparent) 0%,
    color-mix(in srgb, var(--color-bg) 72%, transparent) 100%);
}

.reveal__type {
  position: relative; z-index: 2; width: 100%;
  max-width: 1240px; padding-inline: var(--space-6); text-align: center;
}
/* Au départ, la fenêtre du salon s'ouvre pile derrière le paragraphe et les
   boutons : sans ce voile, le bouton principal se retrouve sur un mur clair
   et tombe sous le seuil de contraste. Le voile suit le texte, pas la photo,
   donc il protège la lisibilité à tous les stades de l'ouverture. */
.reveal__type::before {
  content: ''; position: absolute; inset: -14% -8%; z-index: -1;
  background: radial-gradient(ellipse at center,
    color-mix(in srgb, var(--color-bg) 82%, transparent) 0%,
    color-mix(in srgb, var(--color-bg) 55%, transparent) 45%,
    transparent 72%);
}
.reveal__type h1 {
  font-size: clamp(40px, 7.5vw, 92px);
  margin: 0; display: flex; flex-direction: column; gap: .06em;
}
.reveal__l, .reveal__r { display: block; will-change: transform; }
.reveal__lede {
  max-width: 46ch; margin: var(--space-6) auto 0; font-size: 17px;
  color: var(--color-neutral-200);
}
.reveal__cta { justify-content: center; }

@media (max-width: 760px) {
  .reveal__type h1 { font-size: clamp(32px, 9vw, 48px); }
  .reveal__lede { font-size: 15px; }
}

/* L'animation ne s'active que si le navigateur sait la piloter au défilement
   ET que l'utilisateur n'a pas demandé moins de mouvement. Partout ailleurs,
   les règles ci-dessus tiennent seules. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    /* La hauteur supplémentaire est la « durée » de l'animation : 210vh au
       total, dont 150vh d'ouverture. */
    .reveal { height: 210vh; }
    .reveal__viewport { position: sticky; top: 0; height: 100dvh; }

    .reveal__bg,
    .reveal__frame,
    .reveal__l,
    .reveal__r,
    .reveal__lede,
    .reveal__cta {
      animation-timeline: scroll(root block);
      animation-range: 0 150vh;
      animation-timing-function: linear;
      animation-fill-mode: both;
    }

    .reveal__bg    { animation-name: revealCityRecede; }
    .reveal__frame { animation-name: revealFrameOpen; }
    .reveal__l     { animation-name: revealSplitLeft; }
    .reveal__r     { animation-name: revealSplitRight; }
    .reveal__lede,
    .reveal__cta   { animation-name: revealLedeOut; animation-range: 0 90vh; }
  }
}

@keyframes revealCityRecede {
  from { opacity: .55; transform: scale(1.06); }
  to   { opacity: .08; transform: scale(1); }
}
@keyframes revealFrameOpen {
  from { clip-path: inset(var(--open-y) var(--open-x) var(--open-y) var(--open-x) round var(--radius-lg)); }
  to   { clip-path: inset(6% 4% 6% 4% round var(--radius-lg)); }
}
/* Les deux moitiés du titre s'écartent pour laisser la photo respirer, puis
   sortent du cadre. En vh pour que l'amplitude suive la taille de l'écran. */
@keyframes revealSplitLeft  { from { transform: translateX(0); } to { transform: translateX(calc(var(--split) * -1)); } }
@keyframes revealSplitRight { from { transform: translateX(0); } to { transform: translateX(var(--split)); } }
@keyframes revealLedeOut    { from { opacity: 1; } to { opacity: 0; } }

/* ── Grilles ────────────────────────────────────────────────────────────── */
.grid { display: grid; gap: var(--space-4); }
.grid--cards     { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--why       { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--steps     { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-6); }
.grid--gallery   { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--portfolio { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--delays    { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

/* Le prototype posait ces numéros en neutral-700, qui ne donne que 2,69:1 sur
   le fond — sous le seuil de 3:1 exigé même pour du gros texte. Un cran plus
   clair sur la même rampe passe à 4,08:1 sans changer l'intention (un chiffre
   d'ordre en retrait, plus discret que le titre qu'il accompagne). */
.step-num { font-family: var(--font-heading); font-size: 36px; color: var(--color-neutral-600); margin-bottom: var(--space-2); }

.tag-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.tag-row .tag { font-size: 13px; padding: var(--space-2) var(--space-4); }

/* ── Images ─────────────────────────────────────────────────────────────── */
/* Le wrapper reste sans fond : `.lighten` (mix-blend-mode) doit se composer
   avec le fond de page, pas avec un fond intermédiaire. */
.media { position: relative; }
.media img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-md);
}
.media .tag { position: absolute; top: var(--space-2); left: var(--space-2); }
figure figcaption.caption { font-size: 14px; line-height: 1.5; color: var(--color-neutral-200); margin-top: var(--space-2); }
figure figcaption.caption--sm { font-size: 13px; color: var(--color-neutral-300); }

/* ── Split texte / image ────────────────────────────────────────────────── */
.split { display: grid; grid-template-columns: 1.1fr 1fr; gap: var(--space-8); align-items: center; }

/* ── Services ───────────────────────────────────────────────────────────── */
.service-list { display: flex; flex-direction: column; gap: var(--space-4); }
.service-row  { display: grid; grid-template-columns: 70px 1fr 1.2fr; gap: var(--space-6); padding: var(--space-6); }
.service-num  { font-family: var(--font-heading); font-size: 36px; color: var(--color-accent); line-height: 1; }
.service-items { display: flex; flex-direction: column; gap: var(--space-2); }
.service-items li { font-size: 14px; color: var(--color-neutral-300); }
.service-items { list-style: none; margin: 0; padding: 0; }
.service-items li::before { content: '— '; }

/* ── Réalisations ───────────────────────────────────────────────────────── */
.filters { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.filters .tag {
  cursor: pointer; padding: var(--space-2) var(--space-4); font-size: 13px;
  font-family: inherit; background-color: transparent; border: 1px solid transparent;
}
.filters .tag-accent { background-color: var(--color-accent-800); }
.portfolio-empty { color: var(--color-neutral-400); font-size: 14px; }

/* ── FAQ ────────────────────────────────────────────────────────────────── */
/* <details name> donne l'accordéon exclusif nativement, sans JS, et reste
   indexable. Les navigateurs sans support ouvrent simplement plusieurs
   entrées à la fois — dégradation acceptable. */
.faq details { border-bottom: 1px solid var(--color-divider); padding: var(--space-4) 0; }
.faq summary {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-4);
  font-family: var(--font-heading); font-size: 16px; cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; color: var(--color-accent); font-size: 18px; line-height: 1; }
.faq details[open] summary::after { content: '−'; }
.faq details > p { margin: var(--space-3) 0 0; }

/* ── Contact ────────────────────────────────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: var(--space-8); }
.contact-info { display: flex; flex-direction: column; gap: var(--space-6); }
.info-row { display: flex; gap: var(--space-3); align-items: flex-start; }
.info-row svg { color: var(--color-accent); flex: none; margin-top: 2px; }
.info-label { font-size: 13px; }
.info-value { font-family: var(--font-heading); font-size: 16px; }
a.info-value { color: inherit; text-decoration: none; }
a.info-value:hover { color: var(--color-accent); }
.form-error { color: var(--color-accent-300); font-size: 13px; margin: 0; }
.form-error[hidden] { display: none; }

/* ── Témoignages ────────────────────────────────────────────────────────── */
.testimonial-slot { border: 1px dashed var(--color-divider); }
.testimonial-slot .mark { font-family: var(--font-heading); font-size: 32px; color: var(--color-accent); line-height: 1; }
.testimonial-slot .placeholder { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.6; color: var(--color-neutral-400); }

/* ── Simulateur de devis ────────────────────────────────────────────────── */
/* Le frein numéro un est « ça coûte combien ». Afficher un prix serait faux,
   puisque tout est sur mesure ; laisser la question sans réponse fait partir
   le visiteur. Ce formulaire remplace le montant par un chemin de trente
   secondes vers un devis, et qualifie la demande au passage : le message qui
   arrive sur WhatsApp contient déjà le projet, l'espace, les dimensions et
   l'échéance, donc le premier échange commence au bon endroit. */
.quote {
  padding: clamp(22px, 3vw, 36px);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.quote__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}
.quote__grid .field--wide { grid-column: 1 / -1; }
.quote__foot {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  margin-top: var(--space-6);
}
.quote__note { font-size: 13px; color: var(--color-neutral-400); margin: 0; flex: 1 1 240px; }
.quote select.input { appearance: none; padding-right: 32px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }

/* ── Accès WhatsApp permanent ───────────────────────────────────────────── */
/* En Côte d'Ivoire, WhatsApp est le canal de vente, pas un canal secondaire.
   L'enfouir dans la page Contact fait perdre des demandes : il reste donc
   accessible partout. Vert de marque WhatsApp assumé (c'est un logo, pas une
   couleur du système) ; le reste du site garde son accent unique. */
.wa-float {
  position: fixed; right: var(--space-6); bottom: var(--space-6); z-index: 90;
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1; text-decoration: none;
  color: #0b1f16; background: #25d366;
  border-radius: 999px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .45);
  transition: transform .18s cubic-bezier(.16, 1, .3, 1);
}
.wa-float:hover  { transform: translateY(-2px); }
.wa-float:active { transform: translateY(0) scale(.98); }
.wa-float svg { flex: none; }

/* Sur téléphone, la pastille seule : un libellé prendrait le tiers de la
   largeur d'écran et masquerait le contenu. */
@media (max-width: 640px) {
  .wa-float { right: var(--space-4); bottom: var(--space-4); padding: var(--space-3); }
  .wa-float span { display: none; }
}
@media (prefers-reduced-motion: reduce) { .wa-float { transition: none; } }

/* ── Pied de page ───────────────────────────────────────────────────────── */
/* Le pied de page passe par `.wrap` comme le reste : sans quoi son bord
   gauche tombe 16,8px avant celui du contenu, ce qui se voit au scroll. */
.site-footer { background: var(--color-surface); padding-block: calc(var(--space-8) * 1.5) var(--space-6); }
.footer-grid {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--space-8);
  padding-bottom: var(--space-6); border-bottom: 1px solid var(--color-divider);
}
.footer-about { font-size: 14px; line-height: 1.7; max-width: 320px; }
.footer-links { display: flex; flex-direction: column; gap: var(--space-3); }
.footer-links a { font-size: 14px; }
.footer-contact { font-size: 14px; line-height: 2; }
.footer-contact a { color: inherit; text-decoration: none; }
.footer-contact a:hover { color: var(--color-accent); }
.footer-legal { padding-top: var(--space-4); font-size: 12px; }
.site-footer h6 { color: var(--color-neutral-500); margin-bottom: var(--space-4); }

/* ── Responsive ─────────────────────────────────────────────────────────── */
/* Le prototype était desktop-first ; ce sont les quatre grilles à ratio fixe
   qui doivent retomber en une colonne, les autres sont déjà en auto-fit. */
@media (max-width: 860px) {
  .split, .contact-grid { grid-template-columns: 1fr; }
  .service-row { grid-template-columns: 1fr; gap: var(--space-4); }
  .service-num { font-size: 28px; }
}
@media (max-width: 760px) {
  .stats, .footer-grid { grid-template-columns: 1fr; }
  .footer-grid { gap: var(--space-6); }
  .section, .band--cta { padding-block: calc(var(--space-8) * 1.5); }
  .hero { padding-block: calc(var(--space-8) * 2) calc(var(--space-8) * 1.5); }
}
