/* ==========================================================================
   Motion.

   Rules of the house:
   - Everything here is decoration. Nothing depends on JS or on an animation
     completing. With motion off, the site is identical, just static.
   - `prefers-reduced-motion` is honoured by disabling, not by shortening.
   - Nothing animates layout properties. Transform and opacity only, so
     nothing here can cause a reflow or move the LCP element.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The SC mark intro.

   The S and C interlock in the artwork, so they converge into place rather
   than fading in together: S from the left, C from the right a beat later,
   each with a slight overshoot. Runs on load, no JS, about 700ms end to end.

   transform-box: fill-box makes percentage transforms resolve against each
   path's own bounding box instead of the whole SVG viewport.
   -------------------------------------------------------------------------- */

.sc-mark__s,
.sc-mark__c {
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes sc-in-left {
  from {
    opacity: 0;
    transform: translateX(-34%) scale(0.94);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

@keyframes sc-in-right {
  from {
    opacity: 0;
    transform: translateX(38%) scale(0.94);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

.brand .sc-mark__s {
  animation: sc-in-left 620ms cubic-bezier(0.18, 0.89, 0.32, 1.16) both;
}

.brand .sc-mark__c {
  animation: sc-in-right 620ms cubic-bezier(0.18, 0.89, 0.32, 1.16) 90ms both;
}

/* Hover on the header lockup swaps the two letters over: the S takes the brand
   red and the C takes whatever the S was wearing. It makes the mark feel like
   a control rather than a picture, and because the C hands its red to the S
   the amount of brand red on screen never changes.

   currentColor on .brand is #fff, so this is a straight trade in the header.
   Keyboard users get it on :focus-visible, since the mark is the home link. */
.sc-mark__s,
.sc-mark__c {
  transition: fill var(--t);
}

@media (hover: hover) {
  .brand:hover .sc-mark__s {
    fill: var(--red-brand);
  }

  .brand:hover .sc-mark__c {
    fill: currentColor;
  }
}

.brand:focus-visible .sc-mark__s {
  fill: var(--red-brand);
}

.brand:focus-visible .sc-mark__c {
  fill: currentColor;
}

/* --------------------------------------------------------------------------
   2. Section eyebrow rule.

   The short red bar before a section label draws out from the left when the
   heading comes into view. It is the most repeated element on the site, so a
   small amount of life here goes a long way.
   -------------------------------------------------------------------------- */

.eyebrow::before {
  transform-origin: left center;
  transition: transform 520ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

.eyebrow[data-seen='false']::before {
  transform: scaleX(0);
}

.eyebrow[data-seen='true']::before {
  transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   3. Generic reveal. Opt in with data-reveal on any element.
   -------------------------------------------------------------------------- */

[data-reveal][data-seen='false'] {
  opacity: 0;
  transform: translateY(14px);
}

[data-reveal][data-seen='true'] {
  opacity: 1;
  transform: none;
  transition:
    opacity 620ms cubic-bezier(0.2, 0.7, 0.2, 1),
    transform 620ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* Stagger children of a revealed group, so a row of cards arrives in
   sequence instead of as one block.

   The children must be hidden while the group is still waiting, otherwise
   they paint at full opacity and then snap back to 0 when the animation
   starts. Only ever set by JS, so with JS off nothing is hidden. */
[data-reveal-group][data-seen='false'] > * {
  opacity: 0;
}

[data-reveal-group][data-seen='true'] > * {
  animation: reveal-rise 620ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

[data-reveal-group][data-seen='true'] > *:nth-child(2) {
  animation-delay: 90ms;
}

[data-reveal-group][data-seen='true'] > *:nth-child(3) {
  animation-delay: 180ms;
}

[data-reveal-group][data-seen='true'] > *:nth-child(4) {
  animation-delay: 270ms;
}

@keyframes reveal-rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   4. Process timeline rail.

   On /residential/process/ the ten stages get a vertical rule that draws
   downward as you scroll. It reads as a build sequence, which is exactly
   what the page is describing.
   -------------------------------------------------------------------------- */

.steps--timeline {
  position: relative;
}

.steps--timeline::before {
  content: '';
  position: absolute;
  left: 1.1ch;
  top: 0.4em;
  bottom: 0;
  width: 2px;
  background: linear-gradient(to bottom, var(--red) 0%, var(--border-strong) 100%);
  transform-origin: top center;
  transform: scaleY(var(--rail, 0));
  transition: transform 120ms linear;
}

@media (max-width: 600px) {
  .steps--timeline::before {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Off switch. Everything above becomes a no-op.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  /* The hover colour swap is not motion and stays. Its transition disables
     itself: tokens.css collapses --t to 1ms under this same query, so the
     letters trade instantly rather than fading. */
  .brand .sc-mark__s,
  .brand .sc-mark__c,
  [data-reveal-group][data-seen='true'] > * {
    animation: none;
  }

  .eyebrow::before,
  [data-reveal] {
    transition: none;
  }

  .eyebrow[data-seen='false']::before {
    transform: scaleX(1);
  }

  [data-reveal][data-seen='false'],
  [data-reveal-group][data-seen='false'] > * {
    opacity: 1;
    transform: none;
  }

  .steps--timeline::before {
    transform: scaleY(1);
    transition: none;
  }
}
