/* ---------------- homepage service gallery (2026-09-09) ----------------
   #act-boiler used to pair one phone capture with a four-item bulleted
   capability list. It now steps through six supplied Customer Hub captures,
   each with its own short heading and one sentence about what that screen
   actually does. Scoped entirely to [data-hsg] inside the boiler act: the
   pinned stage, the act typography, the phone render (iphone-air.css) and
   every other card are untouched.

   The markup works with home-service-gallery.js absent: the first shot and
   the first description are shown, everything after them is hidden, and the
   phone stays a link to /service/. Only .is-enhanced - set by the script
   after it has bound successfully - reveals the controls and hands the
   selection to the script.

   Nothing here changes layout when the selection changes: shots and
   descriptions are stacked in one grid cell each, so the act's height is the
   height of its tallest description from first paint and a step can never
   move the page. */

[data-hsg]{align-items:center}

/* ---- the phone: six captures in one grid cell ---- */
[data-hsg] .hsg__shots{display:grid; grid-template-columns:minmax(0,1fr); grid-template-rows:minmax(0,1fr)}
/* Deferred images can expose a taller alt-text fallback inside this grid.
   Anchor the screen/hover aperture to the actual composite, not that text. */
[data-hsg] .frame-phone.frame-phone--air .hsg__shots{aspect-ratio:1380 / 2880}
[data-hsg] .frame-phone.frame-phone--air .hsg__shots > .hsg__shot{height:100%; object-fit:contain}
[data-hsg] .hsg__shot{
  grid-area:1 / 1;
  width:100%; height:auto;
}
/* iphone-air.css sets display:block on .frame-phone--air .fp-screen img
   (0-3-1), so the base state's [hidden] has to outweigh that or the five
   waiting captures would stack up on a scriptless page */
[data-hsg] .fp-screen .hsg__shot[hidden]{display:none}

.hsg.is-enhanced .hsg__shots > .hsg__shot{
  display:block;
  opacity:0;
  visibility:hidden;
  transform:translateX(8px);
  transition:opacity .5s var(--ease-out), transform .5s var(--ease-out), visibility 0s linear .5s;
}
.hsg.is-enhanced .hsg__shot.is-current{
  opacity:1; visibility:visible; transform:none;
  transition:opacity .5s var(--ease-out), transform .5s var(--ease-out), visibility 0s;
}

/* ---- the copy beside it ---- */
[data-hsg] .hsg__copy{flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:12px}
[data-hsg] .hsg__deck{display:grid}
[data-hsg] .hsg__item{grid-area:1 / 1}
[data-hsg] .hsg__deck .hsg__item[hidden]{display:none}

.hsg.is-enhanced .hsg__deck > .hsg__item{
  display:block;
  opacity:0;
  visibility:hidden;
  transform:translateY(6px);
  transition:opacity .42s var(--ease-out), transform .42s var(--ease-out), visibility 0s linear .42s;
}
.hsg.is-enhanced .hsg__item.is-current{
  opacity:1; visibility:visible; transform:none;
  transition:opacity .42s var(--ease-out), transform .42s var(--ease-out), visibility 0s;
}

[data-hsg] .hsg__head{
  margin:0 0 6px; font-family:var(--font-d);
  font-size:15px; font-weight:600; line-height:1.3; letter-spacing:-.01em;
  color:var(--text);
}
[data-hsg] .hsg__head::before{
  content:''; display:block; width:14px; height:1px;
  background:var(--teal); margin:0 0 8px;
}
[data-hsg] .hsg__line{
  margin:0; font-size:13px; line-height:1.5; color:var(--text-2); max-width:34ch;
}

[data-hsg] .hsg__foot{display:flex; align-items:center; gap:12px; min-height:30px}
[data-hsg] .hsg__choice{
  appearance:none; font:inherit; letter-spacing:inherit; line-height:inherit;
  color:inherit; background:none; border:0; padding:0; text-align:left; cursor:pointer;
}
[data-hsg] .hsg__choice:focus-visible{outline:2px solid var(--teal); outline-offset:3px; border-radius:2px}
[data-hsg] .hsg__status{position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap}

/* A useful feature index fills the phone's vertical measure on larger screens.
   One description expands; fixed detail space keeps the phone from jumping.
   No extra panel, pill or generic card chrome: just type and a teal rule. */
@media(min-width:761px){
  .hsg.is-enhanced .hsg__deck{display:flex; flex-direction:column}
  .hsg.is-enhanced .hsg__deck > .hsg__item{
    opacity:1; visibility:visible; transform:none; transition:none;
    border-left:2px solid var(--line); padding:0 0 0 14px;
  }
  .hsg.is-enhanced .hsg__deck > .hsg__item.is-current{border-left-color:var(--teal)}
  .hsg.is-enhanced .hsg__head{margin:0; font-size:14px}
  .hsg.is-enhanced .hsg__head::before{display:none}
  .hsg.is-enhanced .hsg__choice{width:100%; min-height:34px; padding:7px 0; color:var(--text-2)}
  .hsg.is-enhanced .hsg__choice:hover{color:var(--teal)}
  .hsg.is-enhanced .is-current .hsg__choice{color:var(--text); font-weight:650}
  .hsg.is-enhanced .hsg__line{display:none}
  .hsg.is-enhanced .is-current .hsg__line{display:block; min-height:90px; padding:0 0 10px; font-size:13px; line-height:1.5}
  body.day .hsg.is-enhanced .hsg__choice{color:var(--mid-on-paper)}
  body.day .hsg.is-enhanced .is-current .hsg__choice{color:var(--dark-on-paper)}
}

/* ---- dwell indicator: the only progress feedback, and only while the
   tour is actually running. A rule, not a row of dots. ---- */
[data-hsg] .hsg__timer{
  display:none; height:1px; width:60px;
  background:var(--line); overflow:hidden;
}
.hsg.is-enhanced .hsg__timer{display:block}
[data-hsg] .hsg__timer i{
  display:block; height:100%; width:100%;
  background:var(--teal); transform:scaleX(0); transform-origin:left center;
}
.hsg.is-running .hsg__timer i{transform:scaleX(1); transition:transform 5s linear}

/* ---- controls, revealed only when the script is driving ---- */
[data-hsg] .hsg__nav{display:none; gap:8px; align-items:center}
.hsg.is-enhanced .hsg__nav{display:flex}
[data-hsg] .hsg__btn{
  appearance:none; -webkit-appearance:none;
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; padding:0; cursor:pointer;
  background:transparent; color:var(--text-2);
  border:1px solid var(--line); border-radius:50%;
  transition:color .2s ease, border-color .2s ease;
}
/* the class sets display, so the UA's [hidden] rule needs saying again:
   under reduced motion the play control is removed, not just unlabelled */
[data-hsg] .hsg__btn[hidden]{display:none}
[data-hsg] .hsg__btn:hover{color:var(--teal); border-color:rgba(47,214,195,.45)}
[data-hsg] .hsg__btn:focus-visible{outline:2px solid var(--teal); outline-offset:3px}
[data-hsg] .hsg__btn svg{width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:1.6}
[data-hsg] .hsg__btn--play svg{fill:currentColor; stroke:none}

/* the day theme keeps the same restraint on paper */
body.day [data-hsg] .hsg__head{color:var(--dark-on-paper)}
body.day [data-hsg] .hsg__line{color:var(--mid-on-paper)}
body.day [data-hsg] .hsg__btn{color:var(--mid-on-paper); border-color:var(--paper-line)}
body.day [data-hsg] .hsg__btn:hover{color:var(--teal-ink); border-color:var(--teal-ink)}

/* ---- the compact card: the phone keeps its aspect and its bottom tabs,
   the description keeps its measure, and neither the deck nor the controls
   add height the pinned act cannot pay for ---- */
@media (max-width:760px){
  #act-boiler .frame-phone.frame-phone--air{min-width:0}
  [data-hsg] .hsg__shot{min-width:0; min-height:0}
  [data-hsg] .hsg__copy{gap:8px}
  [data-hsg] .hsg__head{font-size:13px; margin-bottom:4px}
  [data-hsg] .hsg__head::before{margin-bottom:5px; width:12px}
  [data-hsg] .hsg__line{font-size:11.5px; line-height:1.45; max-width:none}
  /* the controls stay thumb-sized on the compact card - they take the room
     the description already has, and never widen it */
  [data-hsg] .hsg__btn{width:28px; height:28px}
  [data-hsg] .hsg__btn svg{width:12px; height:12px}
  [data-hsg] .hsg__foot{gap:10px; min-height:28px}
  [data-hsg] .hsg__timer{width:40px}
}
/* the shortest phones: the sentence goes, the heading and the real screen
   stay - the same trade the act's own paragraph makes at this size */
@media (max-width:360px),(max-width:760px) and (max-height:640px){
  [data-hsg] .hsg__line{display:none}
  /* narrowest column: the dwell rule gives its width back to the controls */
  [data-hsg] .hsg__timer{width:26px}
}

/* ---- reduced motion: manual only. The script stops autoplaying; here the
   crossfade becomes a cut and the dwell rule stops animating. ---- */
@media (prefers-reduced-motion:reduce){
  .hsg.is-enhanced .hsg__shots > .hsg__shot,
  .hsg.is-enhanced .hsg__deck > .hsg__item{transition:none}
  .hsg.is-running .hsg__timer i{transition:none}
  [data-hsg] .hsg__timer{display:none}
}
