/* Hestia phone page (860px wide and under). One column you scroll freely: the street, three
   numbered steps, the quiet stairs, the door (step 4, the one moment that plays by itself)
   and the close. The desktop's fixed stage is hidden here and its scripts stay off.
   Colours are the app's tokens (site.css). Sage is for clickable things only, plus the panel.

   Without phone.js (or with reduced motion) the page is a finished, lit story: every drawing
   whole, every light on, the door already open onto the flat. phone.js adds .ph-js to <html>
   and from then on things wait to be reached. */

.ph { display: none; }

@media (max-width: 860px) {
  main[data-sc-mode] { display: none; }
  .ph { display: block; }

  /* The nav: logo and the pill. It slides away as you scroll down and comes back as you
     scroll up (phone.js). No rail here. */
  .bar {
    height: 56px; padding: 0 16px; align-items: center;
    background: var(--sc-canvas);
    transition: transform 280ms cubic-bezier(.2, .7, .2, 1);
  }
  .bar::before, .rail { display: none; }
  .bar.is-hidden { transform: translateY(-100%); }
  .bar .logo { width: 90px; height: 24px; margin: 0; }
  .bar .pill { padding: 0 18px; }
}

/* The column. --spx is where the route runs: 24px at a 390px column, scaled with it, so it
   meets the routes drawn into each drawing. */
.ph {
  position: relative; max-width: 480px; margin: 0 auto; padding-top: 56px;
  overflow-x: clip;
  --spx: calc(min(100vw, 480px) * 0.06154);
}

/* ------------------------------------------------------------------ type -- */
.ph-h1, .ph-h2, .ph-quiet__line, .ph-panel__title {
  margin: 0; font-family: var(--sc-font-display); font-weight: 500;
  letter-spacing: -0.02em; text-wrap: balance; font-variation-settings: "opsz" 96;
}
.ph-h1 { font-size: clamp(34px, 10.8vw, 46px); line-height: 1.02; }
.ph-h2 { font-size: clamp(28px, 8.2vw, 36px); line-height: 1.08; }
.ph-lede, .ph-body { margin: 0; color: var(--sc-ink-soft); text-wrap: pretty; }
.ph-lede { font-size: 17px; line-height: 1.55; }
.ph-body { font-size: 16px; line-height: 1.6; }
/* On the warm ground the grey drops under 4.5:1, so copy goes charcoal there. */
.ph-body--lit { color: var(--sc-ink); }

/* ------------------------------------------------------------------ hero -- */
.ph-hero__copy { padding: 20px 16px 0; display: flex; flex-direction: column; gap: 14px; }
.ph-hero .soon { margin-top: 6px; }

/* ---------------------------------------------------------------- scenes -- */
.ph-scene { position: relative; }
.ph-scene > svg, .ph-scene > img:first-child { display: block; width: 100%; height: auto; }

/* --------------------------------------------------------------- steps 1-3 -- */
.ph-step { position: relative; padding-top: 40px; }
.ph-step .ph-scene { margin-top: 28px; }
.ph-copy { position: relative; padding: 0 16px 0 56px; display: flex; flex-direction: column; gap: 12px; }
/* Real app fragments, cropped, never redrawn. */
.ph-frag {
  display: block; width: 100%; height: auto; border-radius: 14px;
  box-shadow: 0 12px 28px rgb(47 47 43 / 0.12), 0 2px 6px rgb(47 47 43 / 0.08);
}
.ph-copy .ph-frag { margin-top: 8px; }
/* Step numbers sit on the route: terracotta on accent-soft, large enough to pass 3:1. */
.ph-badge {
  position: absolute; z-index: 3; left: calc(var(--spx) - 20px); top: 37px;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--hestia-accent-soft); box-shadow: 0 0 0 4px var(--sc-canvas);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--sc-font-display); font-size: 24px; line-height: 1; color: var(--hestia-accent);
}
/* The Express Interest button stands at the foot of its drawing, where the note leaves from. */
.ph-express {
  position: absolute; left: 8.2%; top: 71.3%; width: 45.1%; height: auto; border-radius: 999px;
  box-shadow: 0 12px 28px rgb(47 47 43 / 0.14), 0 2px 6px rgb(47 47 43 / 0.08);
}
.ph-cards { position: relative; padding: 0 16px 0 56px; margin-top: -16px; display: flex; flex-direction: column; gap: 12px; }
.ph-cards .ph-frag:first-child { border-radius: 20px; }

/* ---------------------------------------------------------------- stairs -- */
.ph-quiet { position: relative; padding-top: 72px; }
.ph-quiet__line { padding: 0 16px 0 56px; font-weight: 400; font-size: clamp(22px, 6.7vw, 28px); line-height: 1.25; letter-spacing: -0.01em; }
.ph-quiet .ph-scene { margin-top: 32px; }

/* ------------------------------------------------------------ the door (4) --
   One screen. The door scene sits in the middle; the warm light, the flat and the line are
   layered over it. phone.js plays it through on a clock while the page holds, by setting
   the variables below. Their defaults are the end of it: you're home. */
.ph-door {
  position: relative; height: 100svh; min-height: 600px; max-height: 1000px; overflow: hidden;
  background: var(--sc-canvas);
  --open: 1; --band: 1; --zoom: 1; --door: 1; --warm: 1; --home: 1; --hearth: 1;
}
.ph-js .ph-door { --open: 0; --band: 0; --warm: 0; --home: 0; --hearth: 0; }
.ph-badge--door { top: 20px; }
.ph-door__band {
  position: absolute; left: 0; right: 0; bottom: 0; top: var(--band-top, 62%);
  background: var(--hestia-accent-soft); transform-origin: top; transform: scaleY(var(--band));
}
.ph-door__stage { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); }
.ph-door__zoom { transform: scale(var(--zoom)); transform-origin: 50% 46%; opacity: var(--door); }
.ph-door .ph-door-open { opacity: var(--open); }
.ph-door .ph-door-shut { opacity: calc(1 - var(--open)); }
/* The lamp over the flatmate lights when the ember reaches it. */
.ph-door .ph-hearth { opacity: var(--hearth); }
.ph-door__warm { position: absolute; inset: 0; background: var(--hestia-accent-soft); opacity: var(--warm); }
.ph-door__home {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  opacity: var(--home); transform: translateY(calc((1 - var(--home)) * 16px));
}
.ph-door__copy { padding: 72px 24px 0; display: flex; flex-direction: column; gap: 12px; }
.ph-door__flat { margin-top: auto; align-self: center; width: min(100%, calc((100svh - 230px) / 1.436)); }

/* ----------------------------------------------------------------- close -- */
.ph-close { position: relative; padding-top: 24px; }
.ph-panel {
  position: relative; margin: 32px 16px 0; padding: 28px 24px 0; border-radius: 28px;
  background: var(--sc-accent); color: var(--sc-accent-ink);
  display: flex; flex-direction: column; gap: 12px; overflow: hidden;
  box-shadow: inset 0 1px 0 rgb(250 250 245 / 0.18), 0 22px 48px rgb(47 47 43 / 0.18), 0 4px 10px rgb(47 47 43 / 0.08);
}
.ph-panel__logo { display: block; width: 120px; height: 32px; color: var(--sc-accent-ink); overflow: visible; }
.ph-panel__title { font-size: clamp(30px, 9vw, 38px); line-height: 1.04; color: var(--sc-accent-ink); }
.ph-panel__body { margin: 0; font-size: 16px; line-height: 1.5; color: var(--sc-accent-ink); }
.ph-panel .soon { margin-top: 4px; }
.ph-panel .soon__tag { background: rgb(47 47 43 / 0.2); color: var(--sc-accent-ink); }
.ph-panel .soon__ember { box-shadow: 0 0 0 2px var(--hestia-accent-soft); }
.ph-panel .soon__ember::after { background: var(--hestia-accent-soft); }
.ph-panel .soon__where { color: var(--sc-accent-ink); }
.ph-panel__door { display: block; align-self: flex-end; width: 150px; height: auto; margin-top: 4px; }
.ph-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 32px 16px calc(40px + env(safe-area-inset-bottom));
  font-size: 13px; color: var(--sc-ink-soft);
}
.ph-foot__logo { display: block; line-height: 0; }
.ph-foot__logo img { display: block; width: 68px; height: 18px; }

/* ------------------------------------------------- the route and the ember --
   One line of dots down the left edge, from the ember on the pavement to the door. It fills
   in as you scroll, with the ember at its tip (phone.js sets its top, height and the fill). */
.ph-route { display: none; position: absolute; z-index: 2; left: calc(var(--spx) - 2px); width: 4px; pointer-events: none; }
.ph-route__ghost, .ph-route__fill {
  position: absolute; left: 0; top: 0; width: 4px;
  background-image: radial-gradient(circle at 2px 2px, var(--hestia-accent) 1.5px, transparent 1.8px);
  background-size: 4px 10px; background-repeat: repeat-y;
}
.ph-route__ghost { height: 100%; opacity: 0.2; filter: grayscale(1); }
.ph-route__fill { height: 0; opacity: 0.85; }
.ph-ember {
  display: none; position: absolute; z-index: 6; left: 0; top: 0;
  width: 37px; height: 37px; margin: -18.5px 0 0 -18.5px; pointer-events: none; will-change: transform;
}
.ph-ember::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--hestia-accent-soft); opacity: var(--glow, 0.9); }
.ph-ember::after { content: ""; position: absolute; left: 13px; top: 13px; width: 11px; height: 11px; border-radius: 50%; background: var(--hestia-accent); }

/* ------------------------------------------------- what waits to be reached --
   Only with phone.js. Drawings draw themselves on once they are on screen, plane by plane;
   fills follow their lines. Dots light one after another, then what they lead to. */
.ph-js .ph-route, .ph-js .ph-ember { display: block; }
/* The drawing's file stands in until phone.js has inlined it. */
.ph-js .ph-scene > img:first-child { visibility: hidden; }
.ph-js .ph-scene svg path[pathLength] {
  stroke-dasharray: 1 1; stroke-dashoffset: 1; fill-opacity: 0;
  transition: stroke-dashoffset 1.3s cubic-bezier(.45, 0, .2, 1) var(--dl, 0s), fill-opacity 600ms ease calc(var(--dl, 0s) + 700ms);
}
.ph-js .ph-scene.is-drawn svg path[pathLength] { stroke-dashoffset: 0; fill-opacity: 1; }
.ph-js .ph-scene svg g :is(circle, rect, path:not([pathLength])):not(.ph-dot) { transition: opacity 600ms ease calc(var(--dl, 0s) + 500ms); }
.ph-js .ph-scene:not(.is-drawn) svg g :is(circle, rect, path:not([pathLength])):not(.ph-dot) { opacity: 0; }
.ph-pl--far { --dl: 0s; }
.ph-pl--mid { --dl: 0.2s; }
.ph-pl--focal { --dl: 0.4s; }
.ph-pl--near { --dl: 0.6s; }

.ph-js .ph-scene .ph-lit { opacity: 0; transition: opacity 600ms ease; }
.ph-js .ph-scene.is-on .ph-lit { opacity: 1; transition-delay: var(--lit-dl, 500ms); }
/* What the dots lead to lights once they have run (30ms a dot). */
.ph-scene[data-scene="browse"] { --lit-dl: 850ms; }
.ph-scene[data-scene="host"] { --lit-dl: 600ms; }
.ph-scene[data-scene="stairs"] { --lit-dl: 0ms; }
.ph-js .ph-scene .ph-dot { opacity: 0; transition: opacity 250ms ease; }
.ph-js .ph-scene.is-on .ph-dot { opacity: 0.85; transition-delay: calc(var(--i) * 30ms); }
.ph-js .ph-scene .ph-win-open { opacity: 0; transition: opacity 700ms ease; }
.ph-js .ph-scene.is-open .ph-win-open { opacity: 1; }
.ph-note { opacity: 0; }

.ph-js .ph-badge { opacity: 0.45; transform: scale(0.8); transition: transform 450ms cubic-bezier(.3, 1.6, .5, 1), opacity 300ms ease; }
.ph-js .ph-badge.is-on { opacity: 1; transform: none; }
.ph-js .ph-rv { opacity: 0; transform: translateY(16px); transition: opacity 700ms cubic-bezier(.2, .7, .2, 1), transform 700ms cubic-bezier(.2, .7, .2, 1); }
.ph-js .ph-rv.is-in { opacity: 1; transform: none; }
.ph-js .ph-hero__copy { animation: ph-rise 800ms cubic-bezier(.2, .7, .2, 1) both; }
@keyframes ph-rise { from { opacity: 0; transform: translateY(12px); } }
