/* Every section after the hero slides up over it, so each one needs a solid background. */
main > section:not(.hero) {
  position: relative;
  z-index: 2;
}

/* About: 90% wide up to 1440px. The sizes match the reference at the 1440px width. */
.about {
  padding-block: clamp(6rem, 11vw, 10rem);
  background: var(--color-light);
  color: var(--color-dark);
}

.about__inner {
  max-width: 1440px;
}

.about__heading {
  margin: 0;
  font-size: clamp(2.5rem, 5.8vw, 5.5rem);
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* Each heading word rises out of its own mask, like the hero. The padding keeps descenders from being clipped. */
.reveal-word {
  display: inline-block;
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
  overflow: hidden;
  vertical-align: top;
}

.reveal-word > span {
  display: block;
}

.about__text {
  max-width: 34em;
  margin: clamp(2.5rem, 6vw, 6rem) 0 0;
  font-size: clamp(1.0625rem, 1rem + 0.5vw, 1.5rem);
  line-height: 1.6;
  text-wrap: pretty;
}

.about__action {
  margin-top: clamp(2rem, 3vw, 2.5rem);
}

.about__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 5vw, 5rem);
  margin-top: clamp(4rem, 9vw, 8rem);
}

.about__line {
  display: block;
  height: 1px;
  background: currentColor;
  transform-origin: left;
}

.about__number {
  margin: clamp(2rem, 4vw, 3.5rem) 0 0;
  font-size: clamp(3.25rem, 10vw, 9.375rem);
  font-weight: var(--weight-body);
  letter-spacing: -0.02em;
  line-height: 1;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

.about__rise {
  display: block;
}

.about__label {
  margin: clamp(0.75rem, 1.5vw, 1.25rem) 0 0;
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.375rem);
  font-weight: var(--weight-action);
  line-height: 1.3;
}

/*
  Showcase: a full-screen image. It's 160% of the section's height, so js/home.js can move it
  more slowly than the page. The section has no background, which keeps the header transparent over it.
*/
.showcase {
  height: 100vh;
  overflow: hidden;
}

/* A Dark layer, stronger behind the header, because the Light text crosses bright parts of the image. */
.showcase::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--color-dark) 50%, transparent) 80px, color-mix(in srgb, var(--color-dark) 35%, transparent) 240px);
  pointer-events: none;
}

/* The text moves faster than the page in js/home.js, while the image moves slower. */
.showcase__content {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  color: var(--color-light);
  text-align: center;
  will-change: transform;
}

.showcase__heading {
  margin: 0;
  font-size: clamp(min(16vw, 3.75rem), 8.466vw, 10rem); /* The same as .hero__heading. */
  font-weight: var(--weight-heading);
  letter-spacing: -0.02em;
  line-height: 1;
}

.showcase__image {
  position: absolute;
  top: -30%;
  left: 0;
  display: block;
  width: 100%;
  height: 160%;
  background: var(--color-dark);
  object-fit: cover;
  will-change: transform;
}

/*
  Services: 90% wide with no max-width. Each row pins under the header and the next one
  slides up over it, while js/home.js darkens the row being covered.
*/
.services {
  --header-height: 80px;

  background: var(--color-light);
  color: var(--color-dark);
}

.services__head {
  display: grid;
  grid-template-columns: 8fr 4fr;
  align-items: end;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(5rem, 10vw, 10rem);
}

.services__heading {
  margin: 0;
  font-size: clamp(2.5rem, 5.8vw, 5.5rem);
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.services__intro {
  margin: 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.service-row {
  position: sticky;
  top: var(--header-height);
  display: block;
  overflow: hidden;
  border-top: 1px solid color-mix(in srgb, var(--color-dark) 20%, transparent);
  background: var(--color-light);
  color: inherit;
  text-decoration: none;
}

.service-row:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: -4px;
}

.service-row__shade {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--color-dark);
  opacity: 0;
  pointer-events: none;
}

.service-row__inner {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 4rem);
  min-height: 62vh;
  padding-block: clamp(3rem, 5vw, 5rem);
}

.service-row__main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.service-row__side {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
}

.service-row__name {
  margin: 0;
  font-size: clamp(1.5rem, 1.1rem + 1.3vw, 2.0625rem);
  font-weight: var(--weight-action);
  line-height: 1.2;
}

.service-row__number {
  display: block;
  color: color-mix(in srgb, var(--color-dark) 14%, transparent);
  font-size: min(17vw, 30vh);
  font-weight: var(--weight-body);
  letter-spacing: -0.02em;
  line-height: 0.8;
}

.service-row__text {
  max-width: 30em;
  margin: 0;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.service-row__action {
  margin-block: clamp(0.75rem, 1.2vw, 1.25rem) clamp(1.25rem, 2vw, 2rem);
}

/* The photos stay inside the container. js/home.js repeats them and moves the track in a loop. */
.service-row__scroller {
  align-self: stretch;
  margin-top: auto;
  overflow: hidden;
}

.service-row__track {
  display: flex;
  width: max-content;
}

/* Limited by screen height too, so a pinned row always fits on screen. */
.service-row__photo {
  display: block;
  flex: none;
  width: min(26vw, 60vh);
  height: auto;
  aspect-ratio: 5 / 3;
  margin-right: clamp(0.5rem, 1vw, 1rem);
  object-fit: cover;
}

/* Our process: 90% wide with no max-width. The middle step sits lower than the other two on desktop. */
.process {
  --process-offset: clamp(3rem, 7.5vw, 7.5rem);

  padding-block: clamp(6rem, 11vw, 10rem);
  background: var(--color-dark);
  color: var(--color-light);
}

.process__intro {
  max-width: 62rem;
  margin-inline: auto;
  margin-bottom: clamp(4rem, 7vw, 7rem);
  text-align: center;
}

.process__heading {
  margin: 0;
  font-size: clamp(2.5rem, 5.8vw, 5.5rem);
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.process__text {
  max-width: 36em;
  margin: clamp(1.5rem, 2.5vw, 2.5rem) auto 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.process__steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: auto auto;
  column-gap: clamp(1.25rem, 2vw, 2rem);
  margin: 0;
  padding: 0 0 var(--process-offset);
  list-style: none;
}

/* Subgrid keeps the three photos level however long each step's text runs. */
.process-step {
  display: grid;
  grid-row: span 2;
  grid-template-rows: subgrid;
  row-gap: clamp(1.5rem, 2.5vw, 2.5rem);
}

.process-step:nth-child(2) {
  position: relative;
  top: var(--process-offset);
}

.process-step__head {
  display: flex;
  align-items: flex-start;
  gap: clamp(1rem, 1.5vw, 1.5rem);
}

.process-step__number {
  flex: none;
  font-size: clamp(5rem, 11vw, 11rem);
  font-weight: var(--weight-body);
  letter-spacing: -0.02em;
  line-height: 1;
}

.process-step__copy {
  padding-top: 0.75em;
}

.process-step__title {
  margin: 0;
  font-size: clamp(1.5rem, 1.1rem + 1.3vw, 2.0625rem);
  font-weight: var(--weight-action);
  line-height: 1.2;
}

.process-step__text {
  margin: 0.75rem 0 0;
  font-size: clamp(1rem, 0.95rem + 0.15vw, 1.125rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.process-step__media {
  overflow: hidden;
  aspect-ratio: 4 / 5;
}

.process-step__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.process__action {
  margin-top: clamp(3rem, 5vw, 5rem);
  text-align: center;
}

/* One step per row on tablets, with the photo beside the text, because three columns would be too narrow. */
@media (max-width: 1023.98px) {
  .process__steps {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    row-gap: clamp(3rem, 7vw, 4rem);
    padding-bottom: 0;
  }

  .process-step {
    grid-row: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: none;
    align-items: start;
    column-gap: clamp(1.25rem, 3vw, 2rem);
  }

  .process-step:nth-child(2) {
    top: 0;
  }
}

/*
  Our Work: a strip of photos with the heading first in the HTML. It's a swipe row by default.
  On desktop, js/home.js adds .work--pinned, which pins the strip and moves it sideways with the scroll.
*/
.work {
  margin-top: -1px; /* Closes the hairline gap to Our process, where the pinned hero could show through. */
  background: var(--color-dark);
  color: var(--color-light);
}

.work__viewport {
  overflow: auto hidden;
  scrollbar-width: none;
}

/* js/home.js lets a mouse drag the row, because the hidden scrollbar leaves it no other way. */
@media (hover: hover) {
  .work:not(.work--pinned) .work__viewport {
    cursor: grab;
  }

  .work:not(.work--pinned) .work__viewport.is-dragging {
    cursor: grabbing;
    user-select: none;
  }
}

.work__viewport::-webkit-scrollbar {
  display: none;
}

.work__track {
  display: grid;
  grid-template-columns: repeat(9, auto);
  column-gap: 4vw;
  align-items: center;
  row-gap: clamp(2.5rem, 6vw, 3.5rem);
  width: max-content;
  padding-block: 0 clamp(5rem, 11vw, 7rem);
  padding-inline: 5vw;
}

/* Stays in place above the row while the photos are swiped. */
.work__intro {
  position: sticky;
  left: 5vw;
  z-index: 1;
  grid-row: 1;
  grid-column: 1 / -1;
  width: 90vw;
  text-align: center;
}

.work__heading {
  margin: 0;
  font-size: clamp(min(16vw, 3.75rem), 8.466vw, 10rem); /* The same as .hero__heading. */
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
}

.work__action {
  margin-top: clamp(1.25rem, 2vw, 2rem);
}

.work__photo {
  grid-row: 2;
  width: var(--work-width);
  margin: 0;
  overflow: hidden;
  aspect-ratio: var(--work-ratio);
}

.work__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  will-change: transform;
}

.work--loop .work__track {
  grid-template-columns: repeat(18, auto); /* js/home.js repeats the nine photos so the row can loop. */
}

.work__photo--1,
.work__photo--3,
.work__photo--5,
.work__photo--7,
.work__photo--9 {
  --work-width: 66vw;
}

.work__photo--2,
.work__photo--4,
.work__photo--6,
.work__photo--8 {
  --work-width: 54vw;
}

.work__photo--1,
.work__photo--4,
.work__photo--7 {
  --work-ratio: 3 / 4;
}

.work__photo--2,
.work__photo--3,
.work__photo--6,
.work__photo--8,
.work__photo--9 {
  --work-ratio: 4 / 5;
}

.work__photo--5 {
  --work-ratio: 1 / 1;
}

/* One staggered line on desktop: the first photo, then the heading, then the other four. */
@media (min-width: 1024px) {
  .work__viewport {
    display: flex;
    align-items: center;
    min-height: 100vh;
    padding-top: 80px; /* The header's height, so the strip centres in the space below it. */
  }

  .work__track {
    display: flex;
    column-gap: 5vw;
    padding: 0 5vw 0 0;
  }

  .work__intro {
    position: relative;
    left: auto;
    order: 1;
    flex: none;
    width: auto;
    margin-right: -7.5vw; /* The heading overlaps the next photo slightly. */
    text-align: left;
    pointer-events: none;
  }

  .work__action a {
    pointer-events: auto;
  }

  .work__photo {
    position: relative;
    flex: none;
    order: 2;
  }

  .work__photo--1 {
    order: 0;
  }

  /* Limited by screen height too, so the pinned strip always fits on screen. */
  .work__photo--1,
  .work__photo--3,
  .work__photo--5,
  .work__photo--7,
  .work__photo--9 {
    --work-width: min(25vw, 50vh);
  }

  .work__photo--2,
  .work__photo--4,
  .work__photo--6,
  .work__photo--8 {
    --work-width: min(20vw, 40vh);
  }

  .work__photo--2,
  .work__photo--6 {
    top: -11vh;
  }

  .work__photo--3,
  .work__photo--9 {
    top: 5.5vh;
  }

  .work__photo--4,
  .work__photo--8 {
    top: -5vh;
  }

  .work__photo--7 {
    top: 3vh;
  }

  .work--pinned .work__viewport {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
  }

  .work--pinned .work__track {
    will-change: transform;
  }
}

/*
  Testimonials: 90% wide with no max-width. The current card is centred, with the previous and next ones
  showing on either side. It's a swipe row by default, and js/home.js adds looping, dragging and the arrows.
*/
.testimonials {
  --testimonial-width: 60vw;

  padding-block: clamp(6rem, 11vw, 10rem);
  background: var(--color-background);
  color: var(--color-dark);
}

.testimonials__head {
  display: grid;
  grid-template-columns: 9fr 4fr; /* Wide enough for the heading to sit on two lines, like the reference. */
  align-items: start;
  gap: clamp(1.5rem, 4vw, 4rem);
  margin-bottom: clamp(4rem, 8vw, 8rem);
}

.testimonials__heading {
  margin: 0;
  font-size: clamp(2.5rem, 5.8vw, 5.5rem);
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
}

.testimonials__intro {
  margin: 0.5em 0 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.testimonials__viewport {
  overflow: auto hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.testimonials__viewport::-webkit-scrollbar {
  display: none;
}

.testimonials__viewport:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 4px;
}

/* Snapping would fight the row while it's being dragged or glides to the next card. */
.testimonials__viewport.is-dragging,
.testimonials__viewport.is-gliding {
  scroll-snap-type: none;
}

@media (hover: hover) {
  .testimonials__viewport {
    cursor: grab;
  }

  .testimonials__viewport.is-dragging {
    cursor: grabbing;
    user-select: none;
  }
}

.testimonials__track {
  display: flex;
  column-gap: clamp(1rem, 1.8vw, 2rem);
  width: max-content;
  margin: 0;
  padding-inline: calc((100vw - var(--testimonial-width)) / 2); /* Lets the first and last cards centre too. */
  list-style: none;
}

/* The corners follow the reference. No other section uses rounded corners so far. */
.testimonial {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 46.7%;
  column-gap: clamp(1.25rem, 2.5vw, 2.5rem);
  flex: none;
  width: var(--testimonial-width);
  padding: clamp(1.25rem, 1.85vw, 2.25rem);
  border-radius: clamp(0.75rem, 1vw, 1.25rem);
  background: var(--color-light);
  color: var(--color-dark); /* Stays readable while the section behind it changes colour. */
  scroll-snap-align: center;
  scroll-snap-stop: always;
}

.testimonial__body {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(1.5rem, 2.5vw, 2.5rem);
}

.testimonial__quote {
  margin: 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.testimonial__person {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.2vw, 1.25rem);
  margin: 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  font-weight: var(--weight-action);
  line-height: 1.2;
}

.testimonial__avatar {
  display: block;
  flex: none;
  width: clamp(3.5rem, 4.6vw, 5.75rem);
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
}

/* Stretches with a long quote, otherwise it keeps the reference's shape. */
.testimonial__media {
  position: relative;
  overflow: hidden;
  border-radius: clamp(0.5rem, 0.7vw, 0.875rem);
}

.testimonial__media::before {
  content: "";
  display: block;
  padding-top: 65.5%;
}

.testimonial__media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.testimonials__nav {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  margin-top: clamp(2rem, 3vw, 3rem);
}

.testimonials__nav[hidden] {
  display: none;
}

.testimonials__arrow {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}

.testimonials__arrow:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 4px;
}

.testimonials__arrow svg {
  display: block;
  width: 0.875rem;
  height: 0.875rem;
}

/* The arrow from assets/icons/arrow.svg points down-right. */
.testimonials__arrow--previous svg {
  transform: rotate(135deg);
}

.testimonials__arrow--next svg {
  transform: rotate(-45deg);
}

/* Hover only where a real pointer exists, so the state doesn't stick after a tap. */
@media (hover: hover) {
  .testimonials__arrow:hover {
    background: var(--color-dark);
    color: var(--color-light);
  }
}

@media (max-width: 1023.98px) {
  .testimonials {
    --testimonial-width: 72vw;
  }
}

@media (max-width: 767.98px) {
  .testimonials {
    --testimonial-width: 76vw;
  }

  .testimonials__head {
    grid-template-columns: minmax(0, 1fr);
  }

  .testimonials__intro {
    margin-top: 0;
  }

  .testimonial {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    row-gap: 1.5rem;
  }

  .testimonial__media {
    order: -1;
  }

  .testimonials__arrow {
    width: 2.5rem;
    height: 2.5rem;
  }

  .testimonials__arrow svg {
    width: 0.75rem;
    height: 0.75rem;
  }
}

@media (max-width: 767.98px) {
  .process-step {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 1.5rem;
  }

  .services__head {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The rows scroll normally on mobile, so nothing covers them and they don't darken. */
  .service-row {
    position: static;
  }

  .service-row__shade {
    display: none;
  }

  .service-row__inner {
    display: block;
    min-height: 0;
  }

  .service-row__side {
    display: block;
  }

  .service-row__number {
    display: none;
  }

  .service-row__text {
    margin-top: 12px;
  }

  .service-row__photo {
    width: min(72vw, 45vh);
  }
}

/*
  Our process and Testimonials arrive in the colours of the section before them, so there's no visible edge,
  then change as they reach the middle of the screen. js/home.js adds .is-arriving, so without it they keep their own colours.
*/
.process,
.testimonials {
  transition: background-color 0.8s ease, color 0.8s ease;
}

.process.is-arriving {
  background: var(--color-light);
  color: var(--color-dark);
}

.testimonials.is-arriving {
  background: var(--color-dark);
  color: var(--color-light);
}

.process .btn--light {
  transition: color 0.8s ease;
}

.process.is-arriving .btn--light {
  color: var(--color-dark);
}

/*
  Grain on the Dark background of the call to action and footer, made of faint specks of Light, so the texture runs
  unbroken from one to the other. It's embedded so it also shows on pages opened as a file.
*/
.cta,
.site-footer {
  background-color: var(--color-dark);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.902 0 0 0 0 0.898 0 0 0 0 0.89 0.256 0 0 0 -0.096'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* Call to action: centred on Dark, 90% wide with no max-width. It runs straight into the footer, which is Dark too. */
.cta {
  padding-block: clamp(6rem, 11vw, 10rem);
  color: var(--color-light);
  text-align: center;
}

.cta__heading {
  margin: 0;
  font-size: clamp(2.5rem, 5.8vw, 5.5rem);
  font-weight: var(--weight-action);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.cta__text {
  max-width: 44em;
  margin: clamp(1.5rem, 2.5vw, 2.5rem) auto 0;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: balance;
}

.cta__action {
  margin-top: clamp(2rem, 3vw, 2.5rem);
}

/*
  Footer: follows https://montarville.ca/, 90% wide with no max-width. A Light panel on the left and a see-through
  one on the right, whose lower part blurs the logo wordmark running across the bottom of the screen.
*/
.site-footer {
  --wordmark-height: 9.72vw; /* The wordmark's shape at full width. */
  --panel-padding: clamp(1.25rem, 1.7vw, 2rem);

  position: relative;
  z-index: 2;
  overflow: hidden;
  margin-top: -1px; /* Closes the hairline gap to the section above. */
  padding-bottom: calc(var(--wordmark-height) * 0.2 + clamp(0.5rem, 1vw, 1rem));
  color: var(--color-light);
}

.site-footer__panels {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 41fr 59fr;
  gap: clamp(1rem, 1.7vw, 1.5rem);
}

.site-footer__nav {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(3rem, 5vw, 5rem);
  margin-bottom: calc(var(--wordmark-height) * 0.8 + clamp(1rem, 1.7vw, 1.5rem));
  padding: var(--panel-padding);
  border-radius: 2px;
  background: var(--color-light);
  color: var(--color-dark);
}

.site-footer__menus {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
}

.site-footer__pages,
.site-footer__legal,
.site-footer__socials {
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__pages {
  font-size: 1.5rem;
  font-weight: var(--weight-action);
  line-height: 1.35;
}

.site-footer__legal {
  flex: none;
  font-size: clamp(0.9375rem, 0.917rem + 0.088vw, 1rem);
  font-weight: var(--weight-action);
  line-height: 1.5;
}

/* The same quick hover underline as the menu's links. */
.site-footer__link {
  position: relative;
  display: inline-block;
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  vertical-align: top;
}

.site-footer__link::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: currentColor;
  transform: translateX(-101%);
  transition: transform 0.35s cubic-bezier(0.65, 0, 0.35, 1);
}

.site-footer__link:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 2px;
}

.site-footer__link:focus-visible::after {
  transform: translateX(0);
}

@media (hover: hover) {
  .site-footer__link:hover::after {
    transform: translateX(0);
  }
}

.site-footer__copyright {
  margin: 0;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  line-height: 1.4;
  text-transform: uppercase;
}

/* A second copy for mobile, where the line goes in the see-through panel instead of the Light one. */
.site-footer__copyright--info {
  display: none;
}

/* The bottom padding keeps the text clear of the wordmark behind the panel. */
.site-footer__info {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto; /* Social Networks sits at the panel's right end. */
  align-items: start;
  gap: var(--panel-padding);
  padding: var(--panel-padding);
  padding-bottom: calc(var(--wordmark-height) * 0.8 + var(--panel-padding));
  border-radius: 2px;
  background: color-mix(in srgb, var(--color-light) 12%, transparent);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

.site-footer__contact {
  display: grid;
  gap: clamp(1.25rem, 1.7vw, 1.5rem);
}

.site-footer__label {
  margin: 0 0 0.25rem;
  font-size: 0.875rem;
  letter-spacing: 0.02em;
  line-height: 1.4;
  text-transform: uppercase;
}

.site-footer__value {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  font-style: normal;
  font-weight: var(--weight-action);
  line-height: 1.4;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

.site-footer__socials {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.site-footer__social {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 2px;
  background: color-mix(in srgb, var(--color-light) 12%, transparent);
  color: inherit;
  transition: background-color 0.2s, color 0.2s;
}

.site-footer__social:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 2px;
}

.site-footer__social svg {
  display: block;
  width: 1.125rem;
  height: 1.125rem;
}

@media (hover: hover) {
  .site-footer__social:hover {
    background: var(--color-light);
    color: var(--color-dark);
  }
}

.site-footer__wordmark {
  position: absolute;
  right: 0;
  bottom: clamp(0.5rem, 1vw, 1rem);
  left: 0;
  display: block;
  width: 100%;
  height: var(--wordmark-height);
}

.site-footer__wordmark path {
  transform-box: fill-box;
}

/* The panels stack below 1024px, because side by side they squeeze the links and the email address. */
@media (max-width: 1023.98px) {
  .site-footer__panels {
    grid-template-columns: minmax(0, 1fr);
  }

  .site-footer__nav {
    margin-bottom: 0;
  }
}

@media (max-width: 767.98px) {
  .site-footer__info {
    grid-template-columns: minmax(0, 1fr);
  }

  .site-footer__nav .site-footer__copyright {
    display: none;
  }

  .site-footer__copyright--info {
    display: block;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-footer__link::after {
    transition: none;
  }
}

/* Starting state for the reveals in js/home.js, which only runs with Motion. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
  }

  .js .reveal-word > span,
  .js .about__rise {
    transform: translateY(110%);
  }

  .js .service-row__scroller,
  .js .process-step__media {
    clip-path: inset(100% 0 0 0);
  }

  .js .service-row__number,
  .js .testimonial {
    opacity: 0;
  }

  .js .about__line {
    transform: scaleX(0);
  }

  .js .site-footer__wordmark path {
    transform: translateY(110%);
  }
}
