/* Treatment Studio — site styles. Theme values (colours, fonts, sizes) come
   from the <style id="theme"> block that the renderer writes into each page. */

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--c-ink); }
body {
  color: var(--c-paper);
  font-family: var(--body);
  -webkit-font-smoothing: antialiased;
}

/* A slide's height is in screens: its own (--sh) or the one set for all slides
   (--slide-h, default 1 = one screen). Scroll-controlled video slides are
   (--len - 1) screens taller, and their stage stays pinned while the clip plays. */
.slide {
  --screens: var(--sh, var(--slide-h, 1));
  position: relative;
  height: calc(100vh * (var(--screens) + var(--len, 1) - 1));
  height: calc(100svh * (var(--screens) + var(--len, 1) - 1));
  background: var(--slide-bg, var(--c-ink));
  scroll-snap-align: start;
}
.stage {
  position: sticky;
  top: 0;
  height: calc(100vh * var(--screens));
  height: calc(100svh * var(--screens));
  overflow: hidden;
  isolation: isolate;
}

/* Background image or video */
.bg { position: absolute; inset: 0; z-index: -2; }

/* Parallax + zoom-on-scroll. Where supported, the browser drives this itself
   from the scroll position (smooth, off the main thread); elsewhere motion.js does it.
   0% = slide entering from below, 100% = slide leaving at the top. */
.slide[data-bg-motion] .bg { will-change: transform; }
@supports (animation-timeline: view()) {
  .slide { view-timeline: --slide block; }
  .slide[data-bg-motion] .bg { animation: studio-bg linear both; animation-timeline: --slide; }
}
@keyframes studio-bg {
  from { transform: translate3d(0, calc(var(--par, 0) * -50%), 0) scale(calc(1 + var(--par, 0) + var(--zs, 0))); }
  to   { transform: translate3d(0, calc(var(--par, 0) * 50%), 0) scale(calc(1 + var(--par, 0))); }
}
.bg-media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--bx, 50%) var(--by, 50%);
  transform: scale(var(--bz, 1));
  transform-origin: var(--bx, 50%) var(--by, 50%);
}
/* Darkens the image so text reads; tinted with the slide's background colour */
.shade {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--slide-bg) calc(78% * var(--ov, 1)), transparent) 0%,
    color-mix(in srgb, var(--slide-bg) calc(15% * var(--ov, 1)), transparent) 45%,
    color-mix(in srgb, var(--slide-bg) calc(55% * var(--ov, 1)), transparent) 100%);
}

/* Elements are placed in % of the slide. --ax/--ay pick which point of the
   element sits on that spot (0 0 = top-left, 1 1 = bottom-right). */
.el {
  position: absolute;
  left: calc(var(--x) * 1%);
  top: calc(var(--y) * 1%);
  width: calc(var(--w) * 1%);
  translate: calc(var(--ax) * -100%) calc(var(--ay) * -100%);
  color: var(--c, var(--c-paper));
  text-align: var(--al, left);
  /* Box options (all off unless set) */
  border: var(--bw, 0px) var(--bs, solid) var(--bc, currentColor);
  background: var(--fill, transparent);
  border-radius: var(--br, 0px);
  padding: var(--pad, 0px);
}
.el h1, .el h2 {
  font-family: var(--display);
  font-weight: 400;
  font-size: calc(var(--h-size) * var(--s, 1));
  line-height: .95;
  letter-spacing: -.01em;
}
.el .label {
  font-size: var(--l-size);
  font-weight: 600;
  color: var(--c-muted);
  margin-bottom: .6em;
}
/* Text styles (.ts-*) come from the theme. A headline's own label keeps its
   style's colour and size, whatever the headline is set to. */
.el.headline > .label { --c: initial; --s: initial; }
.el.label .label { margin-bottom: 0; }
.el.text { font-size: calc(var(--b-size) * var(--s, 1)); line-height: 1.55; }
.el.text p + p { margin-top: .9em; }
.el a { color: inherit; text-underline-offset: .2em; }
/* Images sit in a frame: --ar sets its shape (none = the picture's own shape),
   --ix/--iy/--iz move and zoom the picture inside it */
.el .crop {
  aspect-ratio: var(--ar, auto);
  overflow: hidden;
  border-radius: max(0px, calc(var(--br, 0px) - var(--bw, 0px)));
}
.el .crop img, .el .crop video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--ix, 50%) var(--iy, 50%);
  transform: scale(var(--iz, 1));
  transform-origin: var(--ix, 50%) var(--iy, 50%);
}
.el .ph { display: none; }

/* Shapes with a fixed frame shape (--ar = width ÷ height). The picture fills the
   frame; text sits on top, placed at the top, middle (default) or bottom. */
.el.framed {
  aspect-ratio: var(--ar);
  display: flex;
  flex-direction: column;
  justify-content: var(--va, center);
}
.el.framed > .crop { position: absolute; inset: 0; aspect-ratio: auto; }
.el > .tx { position: relative; }
/* Text on a picture that keeps its own proportions */
.el.has-media:not(.framed) > .tx {
  position: absolute; inset: var(--pad, 0px);
  display: flex; flex-direction: column; justify-content: center;
}
.el.ellipse, .el.ellipse > .crop { border-radius: 50%; }
/* An empty shape with no frame shape still takes up a little room */
.el.empty:not(.framed) { min-height: 2em; }

.times { list-style: none; }
.times li { display: flex; justify-content: flex-end; gap: 1.2em; padding: .28em 0; }
.times .t { color: var(--c-muted); font-variant-numeric: tabular-nums; }

/* Phones: every element has its own phone position */
@media (max-width: 720px) {
  .el {
    left: calc(var(--px) * 1%);
    top: calc(var(--py) * 1%);
    width: calc(var(--pw) * 1%);
  }
  .bg-media {
    object-position: var(--pbx, 50%) var(--pby, 50%);
    transform-origin: var(--pbx, 50%) var(--pby, 50%);
  }
}

/* Motion. Only applies once motion.js has run (html.js), so the page still
   reads fine without JavaScript. */
.js .el[data-in] {
  transition:
    opacity var(--dur, 1s) ease var(--d, 0s),
    transform var(--dur, 1s) cubic-bezier(.2, .7, .2, 1) var(--d, 0s);
}
.js .el[data-in="fade"]:not(.in) { opacity: 0; }
.js .el[data-in="fade-up"]:not(.in) { opacity: 0; transform: translateY(40px); }
.js .el[data-in="slide-left"]:not(.in) { opacity: 0; transform: translateX(-80px); }
.js .el[data-in="slide-right"]:not(.in) { opacity: 0; transform: translateX(80px); }
.js .el[data-in="words"] .w {
  display: inline-block;
  transition:
    opacity var(--dur, 1s) ease calc(var(--d, 0s) + var(--i) * 80ms),
    transform var(--dur, 1s) cubic-bezier(.2, .7, .2, 1) calc(var(--d, 0s) + var(--i) * 80ms);
}
.js .el[data-in="words"] .label { transition: opacity var(--dur, 1s) ease var(--d, 0s); }
.js .el[data-in="words"]:not(.in) .w { opacity: 0; transform: translateY(.35em); }
.js .el[data-in="words"]:not(.in) .label { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none !important; }
  .slide[data-bg-motion] .bg { animation: none; transform: scale(calc(1 + var(--par, 0) + var(--zs, 0) * .5)); }
  .js .el[data-in], .js .el[data-in] .w, .js .el[data-in] .label {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}
