/* Build Pro Co: motion layer.
   One idea runs through it, gold catching light: lines draw themselves, photos are unveiled
   along their slanted gold edge, icons are sketched in, and a glint travels across gold
   surfaces. Anything that moves on its own lives inside prefers-reduced-motion: no-preference;
   scroll- and pointer-linked effects stay because the visitor is driving them. */

/* ---------- Tokens ---------- */
:root {
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --stagger: 90ms;
}

/* ---------- Order inside groups, so markup stays clean ---------- */
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(2) { --n: 1; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(3) { --n: 2; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(4) { --n: 3; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(5) { --n: 4; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(6) { --n: 5; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(7) { --n: 6; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(8) { --n: 7; }
:is(.why__list, .feature-row, .checklist, .pin-list, .locations__list, .contact__list, .socials, .footer-nav, .drawer__links, .carousel__track,
  .process__steps, .faq__list, .quote-form, .quote__direct, .trade-list, .promise__list, .city-links, .filters, .next-steps, .hero__direct,
  .contact-aside, .then-now, .city__copy, .review-wall, .gallery) > :nth-child(9) { --n: 8; }

.map-pin--melbourne { --n: 1; }
.map-pin--adelaide { --n: 2; }

.stars > :nth-child(2) { --s: 1; }
.stars > :nth-child(3) { --s: 2; }
.stars > :nth-child(4) { --s: 3; }
.stars > :nth-child(5) { --s: 4; }

/* ---------- Where each slanted photo starts its unveil ---------- */
.slant {
  --clip-from: polygon(calc(100% + var(--slant)) 0, 100% 0, 100% 100%, 100% 100%);
  --edge-origin: 50% 0%;
  --edge-from: 1 0;
}

.slant--right { --clip-from: polygon(0 0, 0 0, calc(0% - var(--slant)) 100%, 0 100%); }

.slant__edge { transform-origin: var(--edge-origin); }

@media (max-width: 999px) {
  .slant--stack {
    --clip-from: polygon(0 0, 100% 0, 100% 0, 0 0);
    --edge-origin: 0% 50%;
    --edge-from: 0 1;
  }

  .slant--stack-top {
    --clip-from: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
    --edge-origin: 0% 50%;
    --edge-from: 0 1;
  }

  .slant--stack .slant__edge::after,
  .slant--stack-top .slant__edge::after { display: none; }
}

/* Each signature line is only as wide as its words, so the pen finishes with the text */
.script__line { width: fit-content; }
.hero__title .line > span { width: fit-content; }

.rating-summary__sep { transform-origin: 50% 0; }

/* Gold text that a glint of light can cross */
.glint-text {
  background-image:
    linear-gradient(105deg, rgba(255, 255, 255, 0) 42%, rgba(255, 252, 238, .95) 50%, rgba(255, 255, 255, 0) 58%),
    var(--metal-text);
  background-size: 250% 100%, 100% 100%;
  background-position: 115% 0, 0 0;
  background-repeat: no-repeat;
}

/* ---------- Reading progress: the header's gold rule fills with light ---------- */
.site-header .gold-rule::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(255, 241, 184, 0) 0%, rgba(255, 241, 184, .85) 78%, #fff 100%);
  transform-origin: 0 50%;
  scale: var(--progress, 0) 1;
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  .site-header .gold-rule::before {
    animation: read-progress linear both;
    animation-timeline: scroll(root block);
  }
}

/* ---------- Pointer light: a gold glow and a bright border that follow the cursor ---------- */
@property --mx {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

@property --my {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

.service-card,
.service-panel,
.review-card {
  position: relative;
  isolation: isolate;
}

.service-card::before,
.service-panel::before,
.review-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(360px circle at var(--mx) var(--my), rgba(246, 191, 63, .13), rgba(246, 191, 63, 0) 62%);
  opacity: 0;
  pointer-events: none;
}

.service-card::after,
.service-panel::after,
.review-card::after {
  content: "";
  position: absolute;
  inset: -1.5px;
  z-index: 2;
  padding: 1.5px;
  border-radius: inherit;
  background: radial-gradient(220px circle at var(--mx) var(--my), rgba(255, 240, 190, .95), rgba(246, 191, 63, .35) 45%, rgba(246, 191, 63, 0) 72%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  :is(.service-card, .service-panel, .review-card):hover::before,
  :is(.service-card, .service-panel, .review-card):hover::after { opacity: 1; }
}

/* ---------- Interaction feedback ---------- */
@media (prefers-reduced-motion: no-preference) {
  .btn {
    transition: background-color .25s, color .3s, border-color .25s, box-shadow .35s, filter .3s,
      translate .45s var(--ease-expo), scale .25s var(--ease-expo);
  }

  .btn:active { scale: .97; }
  .btn .icon-arrow { transition: translate .45s var(--ease-expo); }

  .btn--line::before,
  .btn--pill::before { transition: scale .55s var(--ease-expo); }

  .btn--gold:hover::after {
    translate: 110% 0;
    transition: translate .95s var(--ease-in-out);
  }

  .btn--pill .icon { transition: color .25s, translate .45s var(--ease-expo), rotate .45s var(--ease-expo); }

  .btn--pill:hover .icon {
    translate: 3px -2px;
    rotate: -10deg;
  }

  .site-nav__indicator { transition: translate .55s var(--ease-expo), scale .55s var(--ease-expo), opacity .3s; }

  .brand:hover::before { animation: logo-sheen 1.3s var(--ease-in-out); }

  .service-card { transition: box-shadow .45s, border-color .45s; }

  .service-panel,
  .review-card { transition: border-color .45s; }

  :is(.service-card, .service-panel, .review-card)::before,
  :is(.service-card, .service-panel, .review-card)::after { transition: opacity .45s var(--ease-out); }

  .service-card__media img { transition: scale 1.1s var(--ease-expo); }
  .badge-icon { transition: translate .5s var(--ease-expo), box-shadow .45s; }

  .carousel__btn { transition: color .2s, background-color .2s, scale .2s var(--ease-expo); }
  .carousel__btn:active { scale: .9; }
  .carousel__btn .icon { transition: translate .4s var(--ease-expo); }
  .carousel__btn--prev:hover .icon { translate: -3px 0; }
  .carousel__btn--next:hover .icon { translate: 3px 0; }
  .carousel__dot::before { transition: background-color .3s, clip-path .55s var(--ease-expo); }

  .footer-nav a { transition: color .2s, background-size .45s var(--ease-expo); }
  .socials .icon { transition: translate .45s var(--ease-expo); }
  .socials a:hover .icon { translate: 0 -3px; }

  .menu-toggle { transition: scale .2s var(--ease-expo); }
  .menu-toggle:active { scale: .92; }

  .work-tile,
  .space-card { transition: border-color .45s; }

  .work-tile img,
  .space-card img { transition: scale 1.1s var(--ease-expo); }

  .space-card__cta .icon { transition: translate .45s var(--ease-expo); }

  .trade__name,
  .trade__note { transition: color .3s, translate .55s var(--ease-expo); }
  .trade__arrow { transition: translate .55s var(--ease-expo); }
  .trade__img { transition: opacity .35s var(--ease-out), scale .6s var(--ease-expo), rotate .6s var(--ease-expo); }
  .trade:is(:hover, :focus-visible) .trade__name { translate: 10px 0; }
  .trade:is(:hover, :focus-visible) .trade__note { translate: 10px 0; }
  .trade:is(:hover, :focus-visible) .trade__arrow { translate: 6px 0; }

  .gallery-tile img { transition: scale 1.1s var(--ease-expo); }
  .gallery-tile__zoom { transition: opacity .3s var(--ease-out), scale .45s var(--ease-expo); }
  .filters__btn::after { transition: scale .55s var(--ease-expo); }
  .city-links .icon { transition: translate .45s var(--ease-expo); }
  .city-links a:hover .icon { translate: 0 -3px; }
  .map-pin__dot { transition: scale .55s var(--ease-expo), box-shadow .55s; }
  .map-pin.is-active::after { animation: pin-ping 1.7s var(--ease-out) 2; }
  .contact-aside__link .icon { transition: translate .45s var(--ease-expo); }
  .contact-aside__link:hover .icon { translate: 4px 0; }

  .lightbox__btn,
  .lightbox__close { transition: background-color .2s, color .2s, scale .2s var(--ease-expo); }
  .lightbox__btn:active,
  .lightbox__close:active { scale: .9; }

  /* The lightbox rises out of the dark and settles; the backdrop deepens behind it */
  .lightbox { transition: opacity .35s var(--ease-out), scale .6s var(--ease-expo), display .6s allow-discrete, overlay .6s allow-discrete; }
  .lightbox::backdrop { transition: background-color .45s ease, display .45s allow-discrete, overlay .45s allow-discrete; }
  .lightbox[open]:not([data-closing]) .gold-rule::after { animation: glint-x 1.6s .35s var(--ease-in-out) backwards; }

  /* Filter changes: tiles glide to their new places (element-scoped view transition) */
  .gallery::view-transition-group(.gallery-item) { animation-duration: .6s; animation-timing-function: var(--ease-expo); }
  .faq-item__icon::after { transition: rotate .5s var(--ease-expo); }

  /* Cards stay put on hover (a lifting card can slip out from under a resting cursor);
     the light, the photo and the badge carry the response instead. */
  @media (hover: hover) and (pointer: fine) {
    .service-card:hover .service-card__media img { scale: 1.06; }

    .service-card:hover .badge-icon {
      translate: 0 -3px;
      box-shadow: 0 0 0 5px rgba(0, 0, 0, .55), 0 0 30px rgba(246, 191, 63, .5);
    }

    /* The icon sketches itself again; it runs on <use> so the reveal never replays */
    .service-card:hover .badge-icon use { animation: icon-draw .9s var(--ease-in-out); }

    .review-card:hover { border-color: var(--gold-400); }

    /* Photo tiles: the frame catches the light and the photo eases in */
    .work-tile:hover,
    .space-card:hover { border-color: var(--gold-400); }

    .work-tile:hover img,
    .space-card:hover img { scale: 1.05; }

    .space-card:hover .space-card__cta .icon { translate: 4px 0; }

    .gallery-tile:hover img { scale: 1.05; }
  }
}

/* ---------- Scroll reveals ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Hidden until the observer marks it in view. The .js class is set in the page head,
     so nothing is ever hidden without JavaScript, and the failsafe shows everything if
     main.js never arrives. */
  .js [data-animate]:not(.is-inview) { opacity: 0; }
  .js:not(.motion-ready) [data-animate] { animation: failsafe-show 0s 3s forwards; }

  [data-animate].is-inview {
    animation: var(--anim, rise) var(--dur, .9s) var(--ease-expo) calc(var(--delay, 0ms) + var(--i, 0) * var(--stagger)) backwards;
  }

  [data-animate="focus"] { --anim: focus-in; }
  [data-animate="fade"] { --anim: fade-in; --dur: 1.2s; }
  [data-animate="rule"] { --anim: rule-draw; --dur: 1.4s; }

  [data-animate="card"] {
    --anim: rise;
    --dur: 1s;
    --stagger: 110ms;
    --t0: calc(var(--i, 0) * 110ms);
  }

  [data-animate="mask"],
  [data-animate="list"],
  [data-animate="group"],
  [data-animate="slant"] { --anim: none; }

  /* Gold rules: drawn out from the centre, then a glint runs along them */
  [data-animate="rule"].is-inview::after { animation: glint-x 1.7s .55s var(--ease-in-out) backwards; }

  /* Headings rise from behind their own baseline */
  [data-animate="mask"].is-inview > span { animation: mask-up 1.1s var(--delay, 0ms) var(--ease-expo) backwards; }
  [data-animate="mask"].is-inview .glint-text { animation: text-glint 1.8s calc(var(--delay, 0ms) + .85s) var(--ease-in-out) backwards; }

  [data-animate="mask"].is-inview > .glint-text {
    animation:
      mask-up 1.1s var(--delay, 0ms) var(--ease-expo) backwards,
      text-glint 1.8s calc(var(--delay, 0ms) + .85s) var(--ease-in-out) backwards;
  }

  /* Service cards: photo lifts its curtain, the badge scales in and its icon is sketched,
     then the words follow. Rows ripple left to right (--i is the column, set by main.js). */
  [data-animate="card"].is-inview :is(.service-card__media, .service-panel__media) { animation: media-reveal 1.15s calc(var(--t0) + 60ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview :is(.service-card__media, .service-panel__media) img { animation: image-settle 1.7s calc(var(--t0) + 60ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview .badge-icon { animation: badge-pop .9s calc(var(--t0) + 360ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview .badge-icon .icon { animation: icon-draw 1.1s calc(var(--t0) + 470ms) var(--ease-in-out) backwards; }
  [data-animate="card"].is-inview .card-title { animation: rise .8s calc(var(--t0) + 430ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview :is(p, .service-panel__desc) { animation: rise .8s calc(var(--t0) + 510ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview .btn { animation: rise .8s calc(var(--t0) + 590ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview .checklist > li { animation: slide-in .7s calc(var(--t0) + 600ms + var(--n, 0) * 75ms) var(--ease-expo) backwards; }
  [data-animate="card"].is-inview .checklist > li::before { animation: tick-pop .7s calc(var(--t0) + 660ms + var(--n, 0) * 75ms) var(--ease-expo) backwards; }

  /* Slanted photos: the gold edge is drawn first, the photo is unveiled behind it,
     a glint runs down the edge, and the signature is written last */
  [data-animate="slant"].is-inview > .slant__frame { animation: frame-wipe 1.2s var(--ease-expo) backwards; }
  [data-animate="slant"].is-inview .slant__frame img { animation: image-settle 1.8s var(--ease-expo) backwards; }
  [data-animate="slant"].is-inview > .slant__glow { animation: fade-in .6s .15s ease-out backwards; }
  [data-animate="slant"].is-inview .slant__edge { animation: edge-draw 1.05s .15s var(--ease-expo) backwards; }
  [data-animate="slant"].is-inview .slant__edge::after { animation: glint-down 1.4s .95s var(--ease-in-out) backwards; }
  [data-animate="slant"].is-inview .script__line:first-child { animation: write-on .75s .85s var(--ease-in-out) backwards; }
  [data-animate="slant"].is-inview .script__line:last-child { animation: write-on .95s 1.3s var(--ease-in-out) backwards; }

  /* Feature lists: items rise in turn, icons are sketched, dividers grow down */
  [data-animate="list"].is-inview > li { animation: rise .85s calc(var(--n, 0) * 100ms + 80ms) var(--ease-expo) backwards; }
  [data-animate="list"].is-inview > li .icon { animation: icon-draw 1.15s calc(var(--n, 0) * 100ms + 170ms) var(--ease-in-out) backwards; }
  [data-animate="list"].is-inview > li + li::before { animation: divider-grow 1s calc(var(--n, 0) * 100ms + 140ms) var(--ease-expo) backwards; }

  /* Rating summary: stars land one by one */
  .rating-summary.is-inview .stars .icon { animation: star-pop .7s calc(var(--s, 0) * 70ms + 100ms) var(--ease-expo) backwards; }
  .rating-summary.is-inview strong { animation: fade-in .9s .45s ease-out backwards; }
  .rating-summary.is-inview .rating-summary__sep { animation: divider-grow .9s .5s var(--ease-expo) backwards; }
  .rating-summary.is-inview > span:last-child { animation: fade-in .9s .6s ease-out backwards; }

  /* Reviews */
  .carousel.is-inview .carousel__slide { animation: rise .95s calc(var(--n, 0) * 110ms) var(--ease-expo) backwards; }
  .carousel.is-inview .avatar { animation: badge-pop .85s calc(var(--n, 0) * 110ms + 240ms) var(--ease-expo) backwards; }
  .carousel.is-inview .review-card .stars .icon { animation: star-pop .65s calc(var(--n, 0) * 110ms + 360ms + var(--s, 0) * 55ms) var(--ease-expo) backwards; }
  .carousel.is-inview .review-card blockquote { animation: fade-in 1.1s calc(var(--n, 0) * 110ms + 420ms) ease-out backwards; }
  .carousel.is-inview :is(.carousel__btn, .carousel__dots) { animation: fade-in .9s .55s ease-out backwards; }

  /* Locations and contact */
  .locations.is-inview .band-title { animation: rise .85s var(--ease-expo) backwards; }
  .locations.is-inview .band-title .icon { animation: pin-drop 1s .12s var(--ease-expo) backwards; }
  .locations.is-inview .locations__intro { animation: fade-in 1s .25s ease-out backwards; }
  .locations.is-inview .locations__list > li { animation: rise .85s calc(var(--n, 0) * 100ms + .3s) var(--ease-expo) backwards; }
  .locations.is-inview .locations__list .icon { animation: pin-drop 1s calc(var(--n, 0) * 100ms + .34s) var(--ease-expo) backwards; }
  .contact.is-inview .band-title { animation: rise .85s .1s var(--ease-expo) backwards; }
  .contact.is-inview .contact__list > li { animation: rise .85s calc(var(--n, 0) * 110ms + .2s) var(--ease-expo) backwards; }
  .contact.is-inview .icon-ring { animation: badge-pop .9s calc(var(--n, 0) * 110ms + .26s) var(--ease-expo) backwards; }
  .contact.is-inview .icon-ring .icon { animation: icon-draw 1.1s calc(var(--n, 0) * 110ms + .4s) var(--ease-in-out) backwards; }
  .contact.is-inview .contact__social { animation: fade-in 1s .5s ease-out backwards; }
  .contact.is-inview .socials > li { animation: badge-pop .75s calc(var(--n, 0) * 80ms + .6s) var(--ease-expo) backwards; }
  [data-animate="fade"].is-inview img { animation: image-settle 2s var(--ease-expo) backwards; }

  [data-animate="tile"],
  [data-animate="steps"],
  [data-animate="ticks"] { --anim: none; }

  /* Photo tiles: the curtain lifts, the photo settles, then the caption follows */
  [data-animate="tile"].is-inview { animation: media-reveal 1.2s var(--delay, 0ms) var(--ease-expo) backwards; }
  [data-animate="tile"].is-inview img { animation: image-settle 1.8s var(--delay, 0ms) var(--ease-expo) backwards; }
  [data-animate="tile"].is-inview .work-tile__title { animation: rise .8s calc(var(--delay, 0ms) + 420ms) var(--ease-expo) backwards; }
  [data-animate="tile"].is-inview .work-tile__note { animation: rise .8s calc(var(--delay, 0ms) + 500ms) var(--ease-expo) backwards; }

  /* Process: each step lands in turn, and the gold line runs on to the next one */
  [data-animate="steps"].is-inview .step { animation: rise .9s calc(var(--n, 0) * 380ms + 60ms) var(--ease-expo) backwards; }
  [data-animate="steps"].is-inview .step__node { animation: badge-pop .9s calc(var(--n, 0) * 380ms) var(--ease-expo) backwards; }
  [data-animate="steps"].is-inview .step__node .icon { animation: icon-draw 1.1s calc(var(--n, 0) * 380ms + 110ms) var(--ease-in-out) backwards; }
  [data-animate="steps"].is-inview .step::after { animation: line-down .55s calc(var(--n, 0) * 380ms + 300ms) var(--ease-in-out) backwards; }

  /* Ticked lists outside the service cards */
  [data-animate="ticks"].is-inview > li { animation: slide-in .7s calc(var(--delay, 0ms) + var(--n, 0) * 90ms) var(--ease-expo) backwards; }
  [data-animate="ticks"].is-inview > li::before { animation: tick-pop .7s calc(var(--delay, 0ms) + 60ms + var(--n, 0) * 90ms) var(--ease-expo) backwards; }

  /* Tiling spotlight: the tall photo is unveiled, the finished shower slides in over it */
  .spotlight__media.is-inview .spotlight__photo--main { animation: media-reveal 1.2s var(--ease-expo) backwards; }
  .spotlight__media.is-inview .spotlight__photo--main img { animation: image-settle 1.8s var(--ease-expo) backwards; }
  .spotlight__media.is-inview .spotlight__photo--inset { animation: inset-in 1.1s .45s var(--ease-expo) backwards; }

  /* Questions, the quote form and its contact links come in one after another */
  .faq__list.is-inview > .faq-item { animation: rise .8s calc(var(--n, 0) * 70ms) var(--ease-expo) backwards; }
  .quote-form.is-inview > * { animation: rise .8s calc(var(--n, 0) * 60ms + 120ms) var(--ease-expo) backwards; }
  .quote__direct.is-inview > li { animation: rise .85s calc(var(--n, 0) * 110ms) var(--ease-expo) backwards; }
  .quote__direct.is-inview .icon-ring { animation: badge-pop .9s calc(var(--n, 0) * 110ms + 60ms) var(--ease-expo) backwards; }
  .quote__direct.is-inview .icon-ring .icon { animation: icon-draw 1.1s calc(var(--n, 0) * 110ms + 200ms) var(--ease-in-out) backwards; }

  [data-animate="map"],
  [data-animate="rows"],
  [data-animate="quote"],
  [data-animate="review"] { --anim: none; }

  /* Gallery tiles ripple in by column; captions follow the curtain */
  .gallery [data-animate="tile"] { --delay: calc(var(--i, 0) * 90ms); }
  .gallery.is-filtered [data-animate="tile"] { --delay: 0ms; }
  [data-animate="tile"].is-inview .gallery-tile__title { animation: rise .8s calc(var(--delay, 0ms) + 420ms) var(--ease-expo) backwards; }
  [data-animate="tile"].is-inview .gallery-tile__note { animation: rise .8s calc(var(--delay, 0ms) + 500ms) var(--ease-expo) backwards; }
  .filters.is-inview > * { animation: rise .8s calc(var(--n, 0) * 60ms) var(--ease-expo) backwards; }

  /* Locations: the coast is traced in gold, the states settle in, then the pins drop */
  [data-animate="map"].is-inview .map__coast { animation: icon-draw 1.7s .1s var(--ease-in-out) backwards, map-fill 1.2s 1.3s ease-out backwards; }
  [data-animate="map"].is-inview .map__borders { animation: fade-in 1.2s 1.1s ease-out backwards; }
  [data-animate="map"].is-inview .map-pin { animation: pin-drop 1s calc(1.2s + var(--n, 0) * 150ms) var(--ease-expo) backwards; }
  [data-animate="map"].is-inview .map-pin__label { animation: fade-in .8s calc(1.45s + var(--n, 0) * 150ms) ease-out backwards; }
  .city-links.is-inview > li { animation: rise .85s calc(var(--n, 0) * 100ms + .25s) var(--ease-expo) backwards; }
  .city-links.is-inview .icon { animation: pin-drop 1s calc(var(--n, 0) * 100ms + .3s) var(--ease-expo) backwards; }
  .city__copy.is-inview > * { animation: rise .85s calc(var(--n, 0) * 90ms + .2s) var(--ease-expo) backwards; }

  /* About */
  .then-now.is-inview > * { animation: rise .85s calc(var(--n, 0) * 120ms + .1s) var(--ease-expo) backwards; }
  .then-now.is-inview .then-now__arrow { animation: slide-in .9s .3s var(--ease-expo) backwards; }
  [data-animate="rows"].is-inview > li { animation: rise .85s calc(var(--n, 0) * 90ms + 60ms) var(--ease-expo) backwards; }
  [data-animate="quote"].is-inview .big-quote__mark { animation: badge-pop .9s var(--ease-expo) backwards; }
  [data-animate="quote"].is-inview .big-quote__mark use { animation: icon-draw 1.3s .15s var(--ease-in-out) backwards; }
  [data-animate="quote"].is-inview .big-quote__text { animation: focus-in 1.2s .3s var(--ease-expo) backwards; }
  [data-animate="quote"].is-inview .big-quote__cite { animation: rise .9s .6s var(--ease-expo) backwards; }
  [data-animate="quote"].is-inview .stars .icon { animation: star-pop .7s calc(var(--s, 0) * 70ms + .7s) var(--ease-expo) backwards; }
  [data-animate="quote"].is-inview .big-quote__link { animation: rise .9s .85s var(--ease-expo) backwards; }

  /* Reviews: each card rises as it arrives, then its avatar and stars land */
  [data-animate="review"].is-inview { animation: rise .95s var(--ease-expo) backwards; }
  [data-animate="review"].is-inview .avatar { animation: badge-pop .85s .2s var(--ease-expo) backwards; }
  [data-animate="review"].is-inview .stars .icon { animation: star-pop .65s calc(.3s + var(--s, 0) * 55ms) var(--ease-expo) backwards; }

  /* Contact */
  .contact-aside.is-inview > * { animation: rise .85s calc(var(--n, 0) * 100ms + .15s) var(--ease-expo) backwards; }
  .contact-aside.is-inview .next-steps li::before { animation: badge-pop .7s calc(var(--n, 0) * 160ms + .4s) var(--ease-expo) backwards; }
  .contact-aside.is-inview .next-steps li::after { animation: divider-grow .7s calc(var(--n, 0) * 160ms + .55s) var(--ease-expo) backwards; }

  /* Footer */
  .site-footer__inner.is-inview > .brand { animation: rise .95s var(--ease-expo) backwards; }
  .site-footer__inner.is-inview > .brand::after { animation: logo-sheen 1.5s .6s var(--ease-in-out) backwards; }
  .site-footer__inner.is-inview .footer-nav > li { animation: rise .75s calc(var(--n, 0) * 45ms + 120ms) var(--ease-expo) backwards; }
  .site-footer__inner.is-inview .site-footer__meta { animation: fade-in 1s .5s ease-out backwards; }
  .site-footer__inner.is-inview .site-footer__right .socials > li { animation: badge-pop .75s calc(var(--n, 0) * 80ms + .35s) var(--ease-expo) backwards; }
  .site-footer__inner.is-inview .footer-rating .stars .icon { animation: star-pop .6s calc(var(--s, 0) * 60ms + .6s) var(--ease-expo) backwards; }

  /* Mobile menu: links follow the sheet in */
  .drawer:popover-open .drawer__links > li { animation: drawer-in .7s calc(var(--n, 0) * 45ms + .16s) var(--ease-expo) backwards; }
  .drawer:popover-open .drawer__cta { animation: rise .8s .5s var(--ease-expo) backwards; }
  .drawer:popover-open .drawer__contact { animation: fade-in .9s .6s ease-out backwards; }
}

/* ---------- Hero: one opening sequence on page load ---------- */
@media (prefers-reduced-motion: no-preference) {
  .hero .slant__frame { animation: frame-wipe 1.25s var(--ease-expo) backwards; }
  .hero .slant__frame img { animation: image-settle 2s var(--ease-expo) backwards; }
  .hero .slant__shade { animation: fade-in 1.2s .45s ease-out backwards; }
  .hero .slant__glow { animation: fade-in .6s .25s ease-out backwards; }
  .hero .slant__edge { animation: edge-draw 1.1s .25s var(--ease-expo) backwards; }
  .hero .slant__edge::after { animation: glint-down 1.5s 1.1s var(--ease-in-out) backwards; }

  .hero :is(.hero__services, .kicker) { animation: focus-in 1s .1s var(--ease-expo) backwards; }
  .hero__title .line > span { animation: mask-up 1.15s .2s var(--ease-expo) backwards; }

  .hero__title .line > .glint-text {
    animation:
      mask-up 1.15s .32s var(--ease-expo) backwards,
      text-glint 1.9s 1.55s var(--ease-in-out) backwards;
  }

  .hero__lede { animation: rise 1s .44s var(--ease-expo) backwards; }
  .hero .rating { animation: rise 1s .54s var(--ease-expo) backwards; }
  .hero .rating .stars .icon { animation: star-pop .75s calc(var(--s, 0) * 70ms + .72s) var(--ease-expo) backwards; }
  .hero__cta,
  .hero__actions,
  .hero__direct > li { animation: rise 1s calc(.66s + var(--n, 0) * 90ms) var(--ease-expo) backwards; }
  .hero__direct .icon-ring { animation: badge-pop .9s calc(.74s + var(--n, 0) * 90ms) var(--ease-expo) backwards; }
  .hero__direct .glint-text { animation: text-glint 1.9s 1.4s var(--ease-in-out) backwards; }
  .hero__cta::after { animation: sheen 1.15s 1.9s var(--ease-in-out) backwards; }
  .hero .pin-list > li { animation: rise .9s calc(var(--n, 0) * 90ms + .8s) var(--ease-expo) backwards; }
  .hero .pin-list .icon { animation: pin-drop 1s calc(var(--n, 0) * 90ms + .84s) var(--ease-expo) backwards; }
  .hero__brush { animation: brush-wipe .95s 1.05s var(--ease-in-out) backwards; }
  .hero .script__line:first-child { animation: write-on .75s 1.35s var(--ease-in-out) backwards; }
  .hero .script__line:last-child { animation: write-on .95s 1.8s var(--ease-in-out) backwards; }

  .site-header .brand::after { animation: logo-sheen 1.5s 1.2s var(--ease-in-out) backwards; }
}

/* ---------- Scroll-linked depth (progressive enhancement, no fallback needed) ---------- */
@supports ((animation-timeline: view()) and (animation-range: entry)) {
  @media (prefers-reduced-motion: no-preference) {
    /* Photos drift slightly slower than the page inside their frames */
    .slant__frame img {
      scale: 1.1;
      animation: drift linear both;
      animation-timeline: view();
      animation-range: cover;
    }

    .hero .slant__frame img {
      animation: image-settle 2s var(--ease-expo) backwards, drift linear both;
      animation-timeline: auto, view();
      animation-range: normal, cover;
    }

    [data-animate="slant"].is-inview .slant__frame img {
      animation: image-settle 1.8s var(--ease-expo) backwards, drift linear both;
      animation-timeline: auto, view();
      animation-range: normal, cover;
    }

    /* Review cards ease back only while they are partly out of view, so every card
       that has settled sits at full strength. The effect runs on the card, not the
       slide: scaling a snap target moves the point the carousel snaps to. */
    .carousel__slide { view-timeline: --slide inline; }

    .carousel__slide .review-card,
    .carousel__slide .space-card {
      animation: slide-presence linear both;
      animation-timeline: --slide;
      animation-range: entry 0% exit 100%;
    }
  }

  @media (prefers-reduced-motion: no-preference) and (min-width: 1000px) {
    /* As the hero leaves, its copy lifts away faster than the photo */
    .hero { view-timeline: --hero block; }

    .hero__inner {
      animation: hero-exit linear both;
      animation-timeline: --hero;
      animation-range: exit 10% exit 90%;
    }
  }
}

/* ---------- Questions: answers unfold instead of snapping open ---------- */
@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    .faq-item { interpolate-size: allow-keywords; }

    .faq-item::details-content {
      block-size: 0;
      overflow-y: clip;
      transition: block-size .55s var(--ease-expo), content-visibility .55s allow-discrete;
    }

    .faq-item[open]::details-content { block-size: auto; }
  }
}

/* ---------- Page to page (the opt-in itself is inline in each page's <head>) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .site-header { view-transition-name: site-header; }

  ::view-transition-group(site-header) {
    animation-duration: .5s;
    animation-timing-function: var(--ease-expo);
  }

  :root::view-transition-old(root) { animation: vt-out .35s cubic-bezier(.55, 0, 1, .45) both; }
  :root::view-transition-new(root) { animation: vt-in .7s .1s var(--ease-expo) both; }
}

@media (prefers-reduced-motion: reduce) {
  .gallery::view-transition-group(*),
  .gallery::view-transition-old(*),
  .gallery::view-transition-new(*) { animation: none !important; }
}

/* ---------- Print: everything visible, nothing mid-animation ---------- */
@media print {
  .js [data-animate],
  .js [data-animate] * {
    opacity: 1 !important;
    animation: none !important;
  }
}

/* ---------- Keyframes ---------- */
@keyframes rise { from { opacity: 0; translate: 0 26px; } }
@keyframes slide-in { from { opacity: 0; translate: -14px 0; } }
@keyframes drawer-in { from { opacity: 0; translate: 28px 0; } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes focus-in { from { opacity: 0; filter: blur(8px); translate: 0 8px; } }
@keyframes mask-up { from { translate: 0 105%; } }
@keyframes rule-draw { from { opacity: 0; scale: 0 1; } }
@keyframes divider-grow { from { scale: 1 0; } }
@keyframes image-settle { from { scale: 1.18; } }
@keyframes edge-draw { from { scale: var(--edge-from); } }
@keyframes badge-pop { from { opacity: 0; scale: .35; rotate: -30deg; } }
@keyframes tick-pop { from { opacity: 0; scale: 0; rotate: -90deg; } }
@keyframes star-pop { from { opacity: 0; scale: .3; rotate: -45deg; } }
@keyframes failsafe-show { to { opacity: 1; } }

@keyframes frame-wipe {
  from { clip-path: var(--clip-from); }
  to { clip-path: var(--clip); }
}

@keyframes media-reveal {
  from { clip-path: inset(0 0 100% 0); }
  to { clip-path: inset(0 0 0 0); }
}

/* Paths in drawn icons use pathLength="1", so one dash covers any shape */
@keyframes icon-draw {
  from { stroke-dasharray: 1 2; stroke-dashoffset: 1; }
  to { stroke-dasharray: 1 2; stroke-dashoffset: 0; }
}

@keyframes pin-drop {
  0% { opacity: 0; translate: 0 -16px; }
  55% { opacity: 1; }
}

@keyframes write-on {
  from { clip-path: inset(-30% 100% -30% -8%); }
  to { clip-path: inset(-30% -8% -30% -8%); }
}

@keyframes brush-wipe {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

@keyframes glint-x {
  0% { opacity: 0; translate: -100% 0; }
  12%, 88% { opacity: 1; }
  100% { opacity: 0; translate: 625% 0; }
}

@keyframes glint-down {
  0% { opacity: 0; translate: 0 -100%; }
  15%, 85% { opacity: 1; }
  100% { opacity: 0; translate: 0 455%; }
}

@keyframes sheen {
  from { translate: -110% 0; }
  to { translate: 110% 0; }
}

@keyframes text-glint {
  from { background-position: 115% 0, 0 0; }
  to { background-position: -15% 0, 0 0; }
}

@keyframes logo-sheen {
  from { background-position: 110% 0; }
  to { background-position: -10% 0; }
}

@keyframes read-progress {
  from { scale: 0 1; }
  to { scale: 1 1; }
}

@keyframes drift {
  from { translate: 0 -4%; }
  to { translate: 0 5%; }
}

@keyframes hero-exit { to { opacity: .2; translate: 0 -56px; } }

@keyframes slide-presence {
  entry 0% { opacity: .35; scale: .95; }
  entry 100%, exit 0% { opacity: 1; scale: 1; }
  exit 100% { opacity: .35; scale: .95; }
}

@keyframes line-down { from { scale: 1 0; } }
@keyframes inset-in { from { opacity: 0; translate: 36px 28px; } }

@keyframes map-fill { from { fill-opacity: 0; } }

@keyframes pin-ping {
  0% { opacity: .9; scale: .4; }
  100% { opacity: 0; scale: 1.9; }
}

@keyframes vt-out { to { opacity: 0; translate: 0 -24px; } }
@keyframes vt-in { from { opacity: 0; translate: 0 28px; } }
