/* The hero's headline word and its shop (hero.js says when things change; this does the motion).
   Pictures are baked by scene-bake.js into img/scene/ (url()s are relative to this file). The layer
   boxes below are in percent of the scene, from img/scene/manifest.json "scene" (1000 x 1480 units):
   change them together with the bake. */

/* ================================================================ "Bring your [type] shop online." */
/* Three set lines. The painted word is --ws times the other lines, and its line keeps room for the
   widest word in the turn (--longest, in em of the word: "Gear Exchange" is 7.37em of Caprasimo at this
   tracking; hero.js widens it if the turn ever gets a wider one), so nothing ever moves. The whole
   headline is sized from its column's width (container units) so that word always fits on its line,
   with a ceiling for wide screens. */
.hero-head { container-type: inline-size; --longest: 7.37; --ws: 1.14; }
.hero-head > * { --F: min(4.3rem, 8.4vw); }
@media (min-width: 900px) { .hero-head > * { --F: min(5.4rem, 4.2vw); } }
@supports (width: 1cqi) {
  .hero-head > * { --F: min(4.3rem, 100cqi / (var(--ws) * var(--longest) + .12)); }
  @media (min-width: 900px) { .hero-head > * { --F: min(5.4rem, 100cqi / (var(--ws) * var(--longest) + .12)); } }
}
.hero-title { margin: 0; font: 400 1rem/1.04 var(--display); letter-spacing: -.01em; color: var(--ink); }
.ht { display: block; font-size: var(--F); }
.ht-l { display: block; white-space: nowrap; }
.ht-type { position: relative; font-size: calc(var(--ws) * 1em); width: calc(var(--longest) * 1em); height: 1.08em; }

/* each word is an SVG box of its own width (set from the bake), its text 40 units in from the left */
.hw { position: absolute; left: -.04em; top: -.17em; height: 1.28em; overflow: visible; opacity: 0; visibility: hidden; }
.hw text { font-family: var(--display); font-size: 1000px; letter-spacing: -10px; filter: url(#hw-rim); }
.hw.is-on, .hw.is-leaving, .hw.is-fading { opacity: 1; visibility: visible; }
.hw-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* the old word washes off: it pales, blurs and slips a hair as the water lifts it */
.hw.is-leaving { animation: hw-leave var(--hw-out, .46s) cubic-bezier(.55, 0, .8, .25) both; }
@keyframes hw-leave {
  from { opacity: 1; filter: blur(0); transform: none; }
  to { opacity: 0; filter: blur(.07em) saturate(.6); transform: translateY(.04em) scale(1.012); }
}
/* the new word is brushed on left to right, behind a loaded brush's ragged front */
.hw.is-brushing {
  -webkit-mask: url("img/scene/brush.webp") no-repeat 100% 0 / 240% 100%;
          mask: url("img/scene/brush.webp") no-repeat 100% 0 / 240% 100%;
  animation: hw-brush var(--hw-in, .72s) cubic-bezier(.5, .08, .3, 1) var(--hw-in-delay, .2s) both;
}
@keyframes hw-brush {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; }
}
/* reduced motion: a calm crossfade (one word fades out, then the next fades in, so they never jumble) */
.hw.is-fading { animation: hw-calm-out var(--hw-calm, 1.2s) ease both; }
.hw.is-fading-in { animation: hw-calm-in var(--hw-calm, 1.2s) ease both; }
@keyframes hw-calm-out { 0% { opacity: 1; } 48% { opacity: 0; } 100% { opacity: 0; } }
@keyframes hw-calm-in { 0% { opacity: 0; } 42% { opacity: 0; } 100% { opacity: 1; } }
@keyframes hw-fade { from { opacity: 0; } to { opacity: 1; } }

/* the quiet pause / play button, at the end of the last line, under the end of the longest word */
.ht-pause {
  position: absolute; z-index: 4;
  left: calc(var(--F) * var(--ws) * var(--longest) - 42px); top: calc(var(--F) * (1.56 + 1.08 * var(--ws)) - 21px);
  width: 42px; height: 42px; padding: 0;
  border: 0; border-radius: 50%; background: none;
  cursor: pointer; opacity: .5; transition: opacity .3s;
  -webkit-tap-highlight-color: transparent;
}
.ht-pause[hidden] { display: none; }
.ht-pause:hover, .ht-pause:focus-visible { opacity: 1; }
.ht-pause:focus-visible { outline: 2.5px solid var(--ink); outline-offset: 1px; }
.ht-pause-ico { position: absolute; inset: 8px; background: url("img/scene/ctl-pause.webp") center / contain no-repeat; }
.ht-pause.is-paused { opacity: .8; }
.ht-pause.is-paused .ht-pause-ico { background-image: url("img/scene/ctl-play.webp"); }

/* ================================================================ the shop */
.scene { position: relative; width: 100%; aspect-ratio: 1000 / 1480; isolation: isolate; }
.scene img { position: absolute; display: block; max-width: none; }
.sc-sky { left: 0; top: 0; width: 100%; height: 70.2703%; }
.sc-front { left: 0; top: 50%; width: 100%; height: 50%; }
/* the strip of the facade that changes: sign, awning, windows, one opaque picture per look */
.sc-band { position: absolute; left: 13%; top: 68.6937%; width: 74%; height: 25.3941%; }
.sc-look { left: 0; top: 0; width: 100%; height: 100%; opacity: 0; }
.sc-look.was-on { opacity: 1; z-index: 1; }
.sc-look.is-on { opacity: 1; z-index: 2; }
/* "same building, new look": the new look is revealed behind the wet front of a wash sweeping across */
.sc-look.is-sweeping {
  -webkit-mask: url("img/scene/sweep.webp") no-repeat 100% 0 / 220% 100%;
          mask: url("img/scene/sweep.webp") no-repeat 100% 0 / 220% 100%;
  animation: sc-sweep var(--sc-sweep, .9s) cubic-bezier(.42, .05, .36, 1) var(--sc-delay, .1s) both;
}
@keyframes sc-sweep {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; }
}
.sc-look.is-fading-in { animation: hw-fade var(--hw-calm, 1.2s) ease both; }

/* the wash itself: a glaze of the new look's colour, deepest at its wet front, drying as it goes.
   Its box is the building's (pediment to sidewalk), clipped to the building's outline. */
.sc-house {
  position: absolute; z-index: 3; left: 12.4%; top: 52.027%; width: 75.2%; height: 42.027%;
  clip-path: polygon(0 9.97%, 34.31% 9.97%, 34.31% 6.43%, 36.97% 6.43%, 37.41% 4.77%, 38.71% 3.22%, 40.79% 1.88%, 43.48% .86%, 46.63% .22%, 50% 0, 53.37% .22%, 56.52% .86%, 59.21% 1.88%, 61.29% 3.22%, 62.59% 4.77%, 63.03% 6.43%, 65.69% 6.43%, 65.69% 9.97%, 100% 9.97%, 100% 100%, 0 100%);
  mix-blend-mode: multiply; pointer-events: none;
  /* (the clip-path hides the wash once it has run past the building, but only this keeps it from
     widening the page for a moment on phones while it does) */
  overflow: hidden;
}
/* (its picture, in the new look's colour, is set by hero.js for each change) */
.sc-wet { position: absolute; left: 0; top: -3.2154%; width: 78.7234%; height: 104.8232%; background: no-repeat 0 0 / 100% 100%; opacity: 0; }
/* the wet front runs exactly with the band's mask: both go from just left of the building to just past it */
.sc-house.is-wet .sc-wet {
  animation: sc-wet-move var(--sc-sweep, .9s) cubic-bezier(.42, .05, .36, 1) var(--sc-delay, .1s) both,
             sc-wet-dry calc(var(--sc-sweep, .9s) * .6) ease-out calc(var(--sc-delay, .1s) + var(--sc-sweep, .9s) * .85) both;
}
@keyframes sc-wet-move { from { transform: translateX(-96.45%); } to { transform: translateX(53.55%); } }
@keyframes sc-wet-dry { from { opacity: .95; } to { opacity: 0; } }

/* the balloons, their strings and the listings (hero.js draws them); it reaches up above the scene so
   the balloons can rise as you scroll on */
.sc-canvas { position: absolute; z-index: 4; left: 0; top: -22.3%; width: 100%; height: 122.3%; touch-action: pan-y; opacity: 0; transition: opacity .6s ease; }
.sc-canvas.is-ready { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .hw.is-leaving, .hw.is-brushing, .sc-look.is-sweeping { animation: none; -webkit-mask: none; mask: none; }
  .sc-house { display: none; }
  .ht-pause, .sc-canvas { transition: none; }
}
