/* iControls: colour chapters. Each section is one flat field in a colour the app itself uses for
   that state: deep orange while it heats, deep green while it holds, light blue while hot water runs.
   The app's own screens, recorded as they move, carry the page; the words stay short. */

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("fonts/plus-jakarta-sans-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}

:root {
  --paper: #EEF2F7;
  --paper-step: #DCE4EE;
  --ink: #0E1626;
  --orange: #FF6A2B;
  --orange-deep: #7A2608;
  --heat: #C2410C;
  --hold: #13804A;
  --water: #CFE6FF;

  --margin: clamp(20px, 4vw, 56px);
  --gutter: clamp(12px, 2vw, 24px);

  --size-xl: clamp(64px, 9.5vw, 150px);
  --size-l: clamp(30px, 3.6vw, 56px);
  --size-m: clamp(21px, 2vw, 28px);
  --size-body: clamp(17px, 1.2vw, 19px);
  --size-small: 15px;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --t-press: 140ms;
  --t-hover: 180ms;
  --t-reveal: 520ms;

  --bar-height: 72px;
  /* A phone screen is 720 x 1558: its width is this share of its height. */
  --screen: 0.4621;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: var(--bar-height); -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-weight: 500;
  font-size: var(--size-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img, video, svg { display: block; max-width: 100%; }
h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
::selection { background: var(--ink); color: var(--paper); }
:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }

.size-xl { font-size: var(--size-xl); font-weight: 800; letter-spacing: -0.045em; line-height: 0.9; }
.size-l { font-size: var(--size-l); font-weight: 800; letter-spacing: -0.03em; line-height: 1.05; }
.size-m { font-size: var(--size-m); font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; }
.size-s { font-size: var(--size-body); font-weight: 800; line-height: 1.3; }

.skip {
  position: absolute; left: var(--margin); top: -80px; z-index: 30;
  background: var(--ink); color: var(--paper); padding: 12px 18px; text-decoration: none;
}
.skip:focus { top: 12px; }

/* The bar takes the colour and ink of the chapter beneath it (main.js). */
.bar {
  position: fixed; inset: 0 0 auto 0; z-index: 20; height: var(--bar-height);
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: var(--gutter);
  padding: 0 var(--margin);
  background: var(--bar-bg, var(--paper)); color: var(--bar-ink, var(--ink));
  transition: background-color 300ms ease, color 300ms ease;
}
.mark { display: inline-flex; align-items: center; gap: 12px; text-decoration: none; font-weight: 800; font-size: var(--size-body); letter-spacing: -0.02em; }
.mark-tile { width: 32px; height: 32px; }
.mark-tile rect { fill: var(--orange); }
.mark-tile path { fill: none; stroke: #fff; stroke-width: 1.6; stroke-linecap: round; }
.links { display: flex; justify-content: flex-end; gap: clamp(16px, 2.2vw, 32px); }
.links a {
  font-size: var(--size-small); padding: 8px 0;
  text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 2px; text-underline-offset: 6px;
  transition: text-decoration-color var(--t-hover) ease;
}
.links a:hover { text-decoration-color: currentColor; }

/* An app screen, recorded as it moves. A tap on it holds it still; a second tap plays it again. */
.shot { display: grid; gap: 14px; width: var(--shot-w, 320px); max-width: 100%; }
.shot figcaption { font-size: var(--size-small); }
.clip { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; }
.clip video {
  width: 100%; height: auto; aspect-ratio: 720 / 1558; background: var(--paper);
  border-radius: 10% / 4.62%; /* the phone's own screen corners, the same in both directions */
}
.clip:focus-visible { outline: 3px solid currentColor; outline-offset: 6px; border-radius: 10% / 4.62%; }

/* Hero: paper above, the orange rising below, the headline cut by the seam between them, and the
   Home screen whole at the side, as tall as the first screen allows. */
.hero {
  --seam: 50svh;
  position: relative; overflow: hidden; min-height: 100svh; background: var(--orange);
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  padding: calc(var(--bar-height) + 24px) var(--margin) 40px;
}
.hero-field { position: absolute; inset: 0 0 auto 0; height: var(--seam); background: var(--paper); }
.hero-title {
  position: absolute; left: var(--margin); top: calc(var(--seam) - 0.86em * 1.34); z-index: 1;
  font-size: var(--size-xl); font-weight: 800; letter-spacing: -0.05em; line-height: 0.86;
  text-transform: uppercase;
}
.hero-line { display: block; }
.hero-upper { color: var(--heat); clip-path: inset(0 0 33.5% 0); }
.hero-lower { position: absolute; inset: 0; color: var(--orange-deep); clip-path: inset(66.5% 0 0 0); }
.hero-copy {
  position: absolute; left: var(--margin); top: calc(var(--seam) + var(--size-xl) * 0.6 + 40px); z-index: 1;
  width: min(30ch, 44vw); display: grid; justify-items: start; gap: 20px;
}
.hero-text { font-size: var(--size-m); line-height: 1.35; }
.hero-fit { max-width: 34ch; }
.hero-shot {
  --shot-w: calc((100svh - var(--bar-height) - 120px) * var(--screen));
  grid-column: 8 / span 5; justify-self: end; align-self: start; position: relative; z-index: 1;
}

/* Chapters: full-bleed fields on one 12-column grid. */
.chapter {
  position: relative; min-height: 92svh; overflow: hidden;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  padding: calc(var(--bar-height) + clamp(48px, 7vw, 112px)) var(--margin) clamp(56px, 8vw, 120px);
}

/* The dial: the iControls target at poster size. It works, and its state colours the field. */
.dial-chapter { background: var(--field, var(--hold)); color: #fff; transition: background-color 600ms ease; }
.dial-chapter[data-field="hold"] { --field: var(--hold); }
.dial-chapter[data-field="heat"] { --field: var(--heat); }
.dial-chapter { padding-bottom: 0; align-items: start; }
.dial-words { grid-column: 1 / span 5; grid-row: 1; display: grid; gap: 20px; align-content: start; }
.dial-text { max-width: 40ch; }
.dial-status { font-weight: 800; }
/* The ring's open foot runs off the field's lower edge; the knob and the numbers stay whole. */
.dial-stage {
  grid-column: 6 / span 7; grid-row: 1; justify-self: end; align-self: end; position: relative;
  width: min(80vh, 52vw); aspect-ratio: 1; margin-bottom: -11%;
}
.dial { width: 100%; height: 100%; overflow: visible; }
.dial-track { fill: none; stroke: rgba(255, 255, 255, 0.22); stroke-width: 28; stroke-linecap: round; stroke-dasharray: 750 1000; }
.dial-value { fill: none; stroke: #fff; stroke-width: 18; stroke-linecap: round; stroke-dasharray: 495 1000; }
.dial-knob circle { fill: #fff; }
.dial-knob .dial-knob-ring { fill: none; stroke: var(--field, var(--hold)); stroke-width: 5; transition: stroke 600ms ease; }
.dial-radiator rect { fill: rgba(255, 255, 255, 0.92); transition: fill 600ms ease; }
.dial-chapter[data-state="heating"] .dial-radiator rect { fill: #FFC08A; }
.dial-number { fill: #fff; font-family: inherit; font-weight: 500; font-size: 64px; letter-spacing: -2px; }
.dial-room { fill: rgba(255, 255, 255, 0.88); font-family: inherit; font-weight: 500; font-size: 17px; }
.dial-handle { position: absolute; inset: 7%; border-radius: 50%; pointer-events: none; }
.dial-handle:focus-visible { outline: 3px solid #fff; outline-offset: 6px; }
.dial-grab {
  position: absolute; width: 18%; aspect-ratio: 1; border-radius: 50%;
  transform: translate(-50%, -50%); touch-action: none; cursor: grab;
}
.dial-grab:active { cursor: grabbing; }

/* Hot water: the Hot water tab on the left, the four modes on the right, the dial's mirror. */
.tap-chapter { background: var(--water); color: var(--ink); align-items: center; row-gap: 40px; }
.tap-shot { --shot-w: calc(min(76svh, 720px) * var(--screen)); grid-column: 1 / span 5; grid-row: 1; justify-self: center; }
.tap-words { grid-column: 7 / span 6; grid-row: 1; display: grid; gap: 32px; align-content: center; }
.tap-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 28px; max-width: 34em; }
.tap-modes li { display: grid; }
.tap-modes strong { font-size: var(--size-m); font-weight: 800; letter-spacing: -0.02em; }

/* Boost and Away: two sheets side by side under one line. */
.pair-chapter { background: var(--orange); color: var(--ink); row-gap: 48px; align-items: start; }
.pair-title { grid-column: 1 / -1; }
.pair-chapter .shot { --shot-w: calc(min(70svh, 660px) * var(--screen)); justify-self: center; }
.pair-first { grid-column: 1 / span 6; }
.pair-second { grid-column: 7 / span 6; }

/* The boiler: its live readings at size, beside the Boiler tab. */
.boiler-chapter { background: var(--ink); color: var(--paper); align-items: center; }
.boiler-words { grid-column: 1 / span 6; display: grid; gap: 48px; }
/* One reading a line, as in a table: the figures right-aligned in one column, their names beside them. */
.readings { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: baseline; gap: 20px 24px; }
.readings li { display: contents; }
.readings strong { justify-self: end; }
.readings strong { font-size: clamp(32px, 7.6vw, 120px); font-weight: 800; letter-spacing: -0.045em; line-height: 0.9; color: var(--orange); }
.boiler-shot { --shot-w: calc(min(76svh, 720px) * var(--screen)); grid-column: 8 / span 5; justify-self: center; }

/* Energy: three screens in a row, the way the tab is used: the totals, the charts, the advice. */
.trio-chapter { background: var(--hold); color: #fff; row-gap: 48px; align-items: start; }
.trio-title { grid-column: 1 / -1; }
.trio-chapter .shot { --shot-w: calc(min(68svh, 640px) * var(--screen)); justify-self: center; }
.trio-first { grid-column: 1 / span 4; }
.trio-second { grid-column: 5 / span 4; }
.trio-third { grid-column: 9 / span 4; }

/* Set up once: two tiles that grow, each holding the app's own screen at that step. */
.setup {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  padding: clamp(120px, 14vw, 200px) var(--margin) clamp(96px, 10vw, 160px);
  background: var(--paper);
}
.setup-title { grid-column: 1 / span 7; grid-row: 1; align-self: start; padding-top: 4px; }
.stages { grid-column: 1 / -1; grid-row: 1; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: end; }
.stage { display: grid; gap: 12px; }
.stage p { max-width: 34ch; }
.stage-1 { grid-column: 1 / span 5; }
.stage-2 { grid-column: 6 / span 7; }
/* The screen's height is worked out from the tile's: a percentage inside a button is not safe in every browser. */
.tile { position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; height: var(--tile); }
.stage-1 .tile { --tile: 56vh; background: var(--orange); }
.stage-2 .tile { --tile: 76vh; background: var(--hold); }
.tile .clip, .tile .clip video { width: auto; height: calc(var(--tile) * 0.86); }

/* Questions: a band per question, the answers all open. */
.qa {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  padding: 56px var(--margin); background: var(--paper);
}
.qa-alt { background: var(--paper-step); }
.qa h3 { grid-column: 1 / span 5; }
.qa p { grid-column: 7 / span 6; max-width: 52ch; }
.qa-head { min-height: 40svh; align-items: end; background: var(--orange); color: var(--ink); padding-bottom: 40px; }
.qa-head h2 { grid-column: 1 / -1; }

/* The footer: the name at size. */
.foot {
  min-height: 64svh; display: grid; grid-template-rows: auto 1fr auto auto; row-gap: 32px;
  padding: 40px var(--margin) 32px; background: var(--ink); color: var(--paper);
}
.foot-top { display: flex; justify-content: space-between; align-items: start; gap: 24px; font-size: var(--size-small); }
.foot-notes { display: grid; gap: 4px; }
.foot-mail { justify-self: start; padding-block: 4px; text-underline-offset: 3px; }
.foot-up { text-decoration: none; }
.foot-up:hover { text-decoration: underline; text-underline-offset: 4px; }
.foot-name { grid-row: 3; align-self: end; }
.foot-meta { grid-row: 4; display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; font-size: var(--size-small); }
.foot-meta p:last-child { text-align: right; }
.foot-meta a { text-underline-offset: 3px; }

/* Entrances, only once main.js has started: each part rises in reading order. */
.motion [data-rise] {
  opacity: 0; transform: translateY(24px);
  transition: opacity var(--t-reveal) var(--ease-expo), transform var(--t-reveal) var(--ease-expo);
  transition-delay: var(--delay, 0ms);
}
.motion [data-rise].risen { opacity: 1; transform: none; }

@media (max-width: 900px) {
  .links { display: none; }
  .chapter, .setup, .qa { grid-template-columns: minmax(0, 1fr); }
  .dial-words, .tap-words, .boiler-words, .setup-title, .stages, .qa h3, .qa p, .qa-head h2 { grid-column: 1; }
  .chapter .shot, .hero-shot { --shot-w: min(78vw, 360px); grid-column: 1; grid-row: auto; justify-self: center; }

  .hero { --seam: 30svh; grid-template-columns: minmax(0, 1fr); row-gap: 40px; padding-top: calc(var(--seam) + var(--size-xl) * 0.6 + 36px); padding-bottom: 64px; }
  .hero-title { left: 50%; transform: translateX(-50%); width: max-content; max-width: 92vw; text-align: center; }
  .hero-copy { position: static; width: 100%; justify-items: center; text-align: center; }
  .hero-fit { margin-inline: auto; }

  .dial-chapter { min-height: 100svh; row-gap: 32px; }
  .dial-stage { grid-column: 1; grid-row: 2; justify-self: start; width: 108vw; margin-left: -4vw; margin-bottom: -14%; }

  .tap-words { grid-row: 1; }
  .tap-chapter .tap-shot { grid-row: 2; }
  .tap-modes { grid-template-columns: minmax(0, 1fr); }
  .pair-chapter, .trio-chapter, .boiler-chapter { row-gap: 40px; }
  .readings strong { font-size: clamp(44px, 13vw, 64px); }

  .setup { padding-top: 96px; row-gap: 28px; }
  .setup-title { grid-row: auto; }
  .stages { grid-row: auto; grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .stage-1, .stage-2 { grid-column: 1; }
  .stage-1 .tile { --tile: min(150vw, 74svh); }
  .stage-2 .tile { --tile: min(170vw, 84svh); }

  .qa { padding: 32px var(--margin); row-gap: 12px; }
  .qa-head { min-height: 0; padding-top: 72px; }

  .foot { min-height: 0; grid-template-rows: auto auto auto auto; }
  .foot-top { flex-direction: column; }
  .foot-meta { grid-template-columns: minmax(0, 1fr); }
  .foot-meta p:last-child { text-align: left; }
}

/* A tablet has room for the pair and the trio side by side. */
@media (min-width: 601px) and (max-width: 900px) {
  .pair-chapter { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trio-chapter { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pair-title, .trio-title { grid-column: 1 / -1; }
  .pair-chapter .shot, .trio-chapter .shot { --shot-w: 100%; grid-column: auto; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .motion [data-rise] { transition: opacity 300ms ease; transform: none; }
  .dial-chapter { transition: none; }
}
