/* =========================================================================
   The scenes, under .has-scene (src/js/ui/scene.js). Where the script does
   not build them — narrow or short screens, less motion asked for — none
   of this applies and the sections are laid out as marked up.

   Each is a tall track with a stage pinned inside it: a card (the
   exteriors', the interiors', the floor plan's) and the words before it.
   The stages are stepped: one scroll gesture plays a whole stage, so
   nothing here is ever left half-way.
   ========================================================================= */

.has-scene .scene {
  position: relative;
}

.has-scene .scene__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

/* The stage has to fit the screen, so the galleries' labels keep a
   closer gap over them here than the page's --head-gap. */
.has-scene .scene .section-head {
  margin-bottom: var(--space-5);
}

/* the chooser's invitation to scroll belongs to the page without the
   scenes: in them, the card's edge at the foot of the screen is the cue */
.has-scene .models__more {
  display: none;
}

/* The chooser's intro is the first stage of its scene (scene.js), the
   screen to itself: the choice waits below the screen */
.has-scene .models__intro {
  margin-bottom: 0;
}

/* ---- The words a card rises over (the chooser's, the palettes', the
   floor plan's) ----
   laid out in the stage, over everything but the card (positioned in the
   overlay scene, below) */
.has-scene .scene__story {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.has-scene .scene__story .models__intro,
.has-scene .scene__story .palettes__intro,
.has-scene .scene__story .exteriors__intro,
.has-scene .scene__story .plan__intro,
.has-scene .scene__story .journey__intro,
.has-scene .scene__story .mysolum__words {
  position: absolute;
  left: 50%;
  width: min(48rem, calc(100% - 2 * var(--gutter-safe)));
  margin: 0;
  max-width: none;
}

/* in the stage, the plan's own gap under its head, not the scenes' closer
   one: it fits without it, and the drawing wants the air */
.has-scene .scene--plan .section-head {
  margin-bottom: var(--head-gap);
}

/* =========================================================================
   The palettes and the floor plan: the card rises over the words

   Stage 1 is the words alone, centred, the four palettes (or the two
   sizes) lit between the lines, and the top of the card showing at the
   foot of the screen. One step carries the card up over them to the
   middle of the screen (scene.js writes where it is, --card-y), and the
   words go back as it comes (--veil, 0 to 1):
   dimmed, blurred and drawn in a little.
   ========================================================================= */
.has-scene .scene--overlay {
  height: 170vh;
}

.has-scene .scene--overlay .scene__pin {
  --veil: 0;
}

/* the card: on the page's edges, centred at rest, lowered until it rises
   (scene.js shortens the interiors' pictures where the screen is too
   short for the card); on a very wide screen, no wider than the page's
   content runs (--page-max, tokens.css) */
.has-scene .scene--overlay .scene__pin > :is(section, .models__stage) {
  position: absolute;
  z-index: 2;
  left: var(--gutter-safe);
  right: var(--gutter-safe);
  /* where scene.js puts it, on a device pixel; centred until then */
  top: 0;
  translate: 0 var(--card-y, calc(50vh - 50%));
  margin: 0;
  padding: 0;
}

.has-scene .scene--overlay:not(.is-arrived) .scene__pin > :is(section, .models__stage) {
  pointer-events: none;
}

/* the words, under the card, in the middle of the screen above its edge */
.has-scene .scene--overlay .scene__story {
  z-index: 1;
}

.has-scene .scene--overlay .scene__story .models__intro,
.has-scene .scene--overlay .scene__story .palettes__intro,
.has-scene .scene--overlay .scene__story .exteriors__intro,
.has-scene .scene--overlay .scene__story .plan__intro,
.has-scene .scene--overlay .scene__story .journey__intro,
.has-scene .scene--overlay .scene__story .mysolum__words {
  top: calc((100% - var(--peek, 40px)) / 2);
  translate: -50% -50%;
  opacity: calc(1 - var(--veil) * 0.7);
  scale: calc(1 - var(--veil) * 0.06);
  filter: blur(calc(var(--veil) * 7px));
}

/* The chooser's intro, at its own measure; the choice that rises over it
   is no card, so the intro goes all the way rather than waiting dimmed
   behind it */
.has-scene .scene--chooser .scene__story .models__intro {
  width: min(62rem, calc(100% - 2 * var(--gutter-safe)));
  min-height: 0;
  opacity: calc(1 - var(--veil));
}

/* the claddings, the four palettes or the two sizes, between the lines */
.has-scene .scene--overlay .lead-chips {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin: clamp(var(--space-6), 7vh, 4.5rem) 0;
}

/* As a toggle in the model toggle's family (models.css), of the way
   page's glass (tokens.css, liquid glass), moving through the four
   palettes or the two sizes on its own (ui/lead-toggle.js). The lit pill
   is the milkier glass, the colour of the one it is on a soft wash in its
   foot, and a fainter wash of it travels the bar under it; the name comes
   up in its colour as the pill arrives. The sizes are lit in the floor
   plan's smoke. */
@property --lead-lit {
  syntax: "<color>";
  inherits: true;
  initial-value: #c6cacf;
}

@property --lead-x {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 12.5%;
}

.has-scene .scene--overlay .lead-toggle {
  --count: 4;
  --at: 0;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--count), minmax(0, 1fr));
  gap: 0;
  width: min(100%, calc(var(--count) * 8.75rem));
  margin-inline: auto;
  padding: 5px;
  border-radius: 999px;
  /* the page's glass, and low inside it, under the option lit, a soft
     wash of its colour */
  background:
    radial-gradient(calc(120% / var(--count)) 90% at var(--lead-x) 125%,
      color-mix(in oklab, var(--lead-lit) 22%, transparent),
      transparent 75%),
    var(--glass-frost);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  box-shadow: var(--glass-edge), var(--glass-shadow);
  transition:
    --lead-lit 0.9s var(--ease-out),
    --lead-x 0.75s cubic-bezier(0.65, 0, 0.35, 1);
}

/* the lit pill: the milkier glass, its colour a soft wash in its foot */
.has-scene .scene--overlay .lead-toggle::before {
  content: "";
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 5px;
  width: calc((100% - 10px) / var(--count));
  translate: calc(var(--at) * 100%) 0;
  border-radius: 999px;
  background:
    radial-gradient(90% 85% at 50% 130%,
      color-mix(in oklab, var(--lead-lit) 55%, transparent),
      transparent 78%),
    var(--glass-lit-frost);
  box-shadow: var(--glass-lit-edge), var(--glass-lit-shadow);
  transition: translate 0.75s cubic-bezier(0.65, 0, 0.35, 1);
}

/* The mark over the words, its shape the announcement's (teaser.css), in
   the glass of the toggle under it (below): the colour of the toggle's lit
   option caught low inside it, moving as the toggle does. Only where the
   toggle is. */
.lead-device {
  display: none;
}

/* in the toggles' clear glass (glass-toggle.css), lit from below as light
   would come up through it: a faint body, a little brighter low down; at
   its edges the light coming in, brightest along those facing down and
   falling away inward (hvn-blk-device-rim.svg); and from those, the
   toggle's colour carried up through the glass, fading as it goes
   (hvn-blk-device-glow.svg; both scripts/device.py, kept inside the mark
   by its own mask). A little smaller than the announcement's. */
.has-scene .scene--overlay .lead-device {
  display: block;
  width: clamp(2.35rem, 3.2vw, 3rem);
  margin-inline: auto;
  opacity: 0.9;
  background: linear-gradient(180deg,
    rgb(255 255 255 / 0.07),
    rgb(255 255 255 / 0.05) 50%,
    rgb(255 255 255 / 0.1));
  transition: --lead-lit 0.9s var(--ease-out);
}

/* the light at the edges, white where it enters, a little of the colour
   in it */
.has-scene .scene--overlay .lead-device::before {
  background: color-mix(in oklab, var(--lead-lit) 18%, rgb(255 255 255 / 0.9));
  -webkit-mask: url("/assets/brand/hvn-blk-device-rim.svg") center / 100% 100% no-repeat;
  mask: url("/assets/brand/hvn-blk-device-rim.svg") center / 100% 100% no-repeat;
}

/* and the colour it carries in */
.has-scene .scene--overlay .lead-device::after {
  background: color-mix(in oklab, var(--lead-lit) 85%, #fff);
  opacity: 0.7;
  -webkit-mask: url("/assets/brand/hvn-blk-device-glow.svg") center / 100% 100% no-repeat;
  mask: url("/assets/brand/hvn-blk-device-glow.svg") center / 100% 100% no-repeat;
}

.lead-toggle__option {
  --opt: var(--c-smoke);
  position: relative;      /* over the pill */
  padding: 0.8rem 0.9rem;
  font-family: var(--font-tech);
  font-weight: 400;
  font-size: var(--fs-micro);
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: var(--c-ink-4);
  transition: color 0.6s ease 0.15s, text-shadow 0.6s ease 0.15s;
}

.lead-toggle__option[data-variant="burgundy"] { --opt: var(--c-burgundy); }
.lead-toggle__option[data-variant="sage"]     { --opt: var(--c-sage); }
.lead-toggle__option[data-variant="tide"]     { --opt: var(--c-tide); }
.lead-toggle__option[data-variant="vine"]     { --opt: var(--c-vine); }

.lead-toggle__option.is-lit {
  color: color-mix(in oklab, var(--opt) 45%, #fff);
}

.lead-toggle__option[data-variant="obsidian"] { --opt: var(--c-obsidian); }
.lead-toggle__option[data-variant="ivory"]    { --opt: var(--c-ivory); }
.lead-toggle__option[data-variant="forge"]    { --opt: var(--c-forge); }
.lead-toggle__option[data-variant="char"]     { --opt: var(--c-char); }
.lead-toggle__option[data-variant="amber"]    { --opt: var(--c-amber); }

.has-scene .scene--overlay .lead-chips + .exteriors__line,
.has-scene .scene--overlay .lead-chips + .palettes__line,
.has-scene .scene--overlay .lead-chips + .plan__line {
  margin-top: 0;
}

/* =========================================================================
   Narrower screens, from 56rem to 75rem

   The exteriors' pictures start from a shorter cap here, before the
   scene fits them to the screen (scene.js).
   ========================================================================= */
@media (max-width: 74.99rem) {
  .has-scene .scene--models .exteriors {
    --conveyor-h: clamp(16rem, 40vw, 34rem);
  }
}

/* =========================================================================
   The cue to carry on

   A small upright pill of liquid glass, the tray's glass, set a short
   distance under the end of the screen's words (under the picture, in
   the chooser's stage 2), with an arrow bouncing down inside it. Quiet:
   it is there to be found, not to call out. It rises as
   soon as a stage with words on it comes to rest, and sinks away as
   soon as the page moves (src/js/ui/scene.js). Pressing it plays the next
   step.
   ========================================================================= */
.scene-cue {
  position: fixed;
  z-index: 40;
  left: 50%;
  /* a short distance under the end of the screen's words, set by
     scene.js; at the foot of the screen if it has none */
  top: var(--cue-top, auto);
  bottom: calc(var(--space-6) + var(--safe-bottom));
  display: grid;
  place-items: center;
  width: 1.625rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  color: var(--c-ink-2);
  /* the blurbs' device's glass (above): clear, lit from below as light
     would come up through it. A faint body, brighter low down, and the
     light carried up through it from the foot; at its edge the light
     coming in, brightest along the foot and falling away inward, a
     breath of it along the top. In the page's silver-white: it goes with
     every section, so has no colour of its own */
  background:
    radial-gradient(130% 70% at 50% 112%, rgb(223 231 237 / 0.2), transparent 72%),
    linear-gradient(180deg,
      rgb(255 255 255 / 0.05),
      rgb(255 255 255 / 0.035) 50%,
      rgb(255 255 255 / 0.08));
  -webkit-backdrop-filter: blur(6px) saturate(1.3) brightness(1.06);
  backdrop-filter: blur(6px) saturate(1.3) brightness(1.06);
  box-shadow:
    inset 0 -1px 1.5px rgb(255 255 255 / 0.5),
    inset 0 -5px 7px -3px rgb(223 231 237 / 0.2),
    inset 0 1px 1.5px rgb(255 255 255 / 0.08),
    inset 0 0 2px rgb(255 255 255 / 0.06),
    0 6px 16px -8px rgb(0 0 0 / 0.6);
  cursor: pointer;

  translate: -50% 0.75rem;
  opacity: 0;
  visibility: hidden;
  transition:
    translate 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.35s ease,
    visibility 0s linear 0.5s,
    box-shadow 0.3s ease,
    color 0.3s ease;
}

/* placed under the words: no longer held to the foot */
.scene-cue.is-placed {
  bottom: auto;
}

.scene-cue.is-shown {
  translate: -50% 0;
  opacity: 0.85;
  visibility: visible;
  transition:
    translate 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.25s ease,
    visibility 0s,
    box-shadow 0.3s ease,
    color 0.3s ease;
}

.scene-cue svg {
  width: 0.8rem;
  height: 0.8rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: scene-cue 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* down and back, settling a little on each fall */
@keyframes scene-cue {
  0%, 100% { translate: 0 -4px; opacity: 0.45; }
  45%      { translate: 0 4px;  opacity: 1; }
  60%      { translate: 0 3px;  opacity: 1; }
}

@media (hover: hover) {
  /* under the pointer, more light comes up through it */
  .scene-cue:hover {
    color: var(--c-ink);
    box-shadow:
      inset 0 -1px 1.5px rgb(255 255 255 / 0.7),
      inset 0 -7px 9px -3px rgb(223 231 237 / 0.3),
      inset 0 1px 1.5px rgb(255 255 255 / 0.1),
      inset 0 0 2px rgb(255 255 255 / 0.08),
      0 6px 16px -8px rgb(0 0 0 / 0.6);
  }
}

.scene-cue:focus-visible {
  outline: 1px solid var(--c-led-core);
  outline-offset: 3px;
}

