/* Sinc Energy, the Linear + Stripe hybrid mock (website/hybrid-mock/). From Stripe: the gradient hero on a slanted band
   (animated until 12 Oct), a white page with dark text beneath it, accent eyebrows, alternating two-column feature sections with floating UI
   cards, pill buttons with arrows, a dark band of big numbers, the four-link closing. From Linear: tight tracking (in Urbanist, the brand's typeface, not Linear's Inter),
   the tilted framed product shot, hairline tiles and bento, white-tint cards on the dark band, and restraint. */

@font-face { font-family: "Urbanist"; font-style: normal; font-weight: 100 900; font-display: swap;   /* the brand's typeface (the founder, 28 Sep), as the teacher page and the main draft */
  src: url("/testlandingpage/assets/fonts/urbanist-latin-wght-normal.woff2") format("woff2"); }
@font-face { font-family: "Urbanist"; font-style: italic; font-weight: 100 900; font-display: swap;
  src: url("/testlandingpage/assets/fonts/urbanist-latin-wght-italic.woff2") format("woff2"); }

:root {
  --bg: #ffffff; --bg-2: #f7f5fc; --ink: #1a1530; --text-2: #5c5776; --text-3: #8a84a3; --line: #e8e4f3; --line-2: #d6d0ea;
  --accent: #4f12cb; --accent-2: #784af2; --accent-soft: #ece5ff; --lime: #99ff33; --lime-ink: #3f7d00;
  --dark: #150c33; --dark-2: #1d1145; --dark-line: rgba(255, 255, 255, .12);
  --radius: 12px; --radius-lg: 20px; --max: 1200px; --gutter: 24px; --bar: 64px; --ban: 0px; --nav: calc(var(--bar) + var(--ban));
  --shadow-card: 0 1px 2px rgba(26, 21, 48, .05), 0 14px 34px -14px rgba(26, 21, 48, .2);
  --shadow-float: 0 30px 60px -12px rgba(40, 20, 120, .3), 0 18px 36px -18px rgba(0, 0, 0, .3);
  --font: "Urbanist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --ease: cubic-bezier(.2, .7, .2, 1);
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: clip; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 500 17px/1.6 var(--font); letter-spacing: -.005em;
  -webkit-font-smoothing: antialiased; overflow-x: clip; }
img, svg, canvas { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; border-radius: 6px; }
[id] { scroll-margin-top: calc(var(--nav) + 16px); }
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.024em; line-height: 1.1; text-wrap: balance; }
h1 { font-size: clamp(40px, 5.6vw, 64px); letter-spacing: -.03em; line-height: 1.04; }
h2 { font-size: clamp(30px, 4vw, 46px); }
h3 { font-size: 18px; letter-spacing: -.014em; line-height: 1.3; }
p { margin: 0; }
.lead { font-size: clamp(17px, 1.4vw, 19px); line-height: 1.6; color: var(--text-2); max-width: 58ch; text-wrap: pretty; }
.eyebrow { display: block; margin-bottom: 14px; font-size: 15px; font-weight: 590; color: var(--accent); }
.section-head h2 + .eyebrow { margin: 14px 0 0; }   /* a line under its heading rather than over it (the photo versions' "Up to 33% less heating gas.") */
.muted { color: var(--text-2); }
.dim { color: var(--text-3); }
sup.fn { font-size: .6em; vertical-align: super; line-height: 0; color: var(--text-3); }

/* ---------- buttons and links (Stripe: pills with an arrow) ---------- */
.btn { display: inline-flex; align-items: center; gap: 6px; height: 42px; padding: 0 18px; border-radius: 999px; border: 1px solid transparent;
  font-size: 15px; font-weight: 590; letter-spacing: -.01em; white-space: nowrap; cursor: pointer; transition: background .15s, transform .1s, box-shadow .15s; }
.btn::after { content: "›"; font-size: 19px; line-height: 1; margin-top: -2px; }
.btn:active { transform: translateY(1px); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: #3f0ea6; }
.btn-green { background: #44b25b; color: #fff; font-weight: 800; }   /* the tour's green (the founder, 29 Sep) */
.btn-green:hover { background: #3a9c4f; }
.btn-white { background: #fff; color: var(--accent); box-shadow: 0 2px 8px rgba(0, 0, 0, .12); }
.btn-white:hover { background: #f1ecff; }
.btn-lime { background: var(--lime); color: var(--accent); box-shadow: 0 2px 8px rgba(20, 5, 70, .18); }   /* the brand green, the logo's lime, its words purple: the bar's "Book a call" (the founder, 29 Sep) */
.btn-lime:hover { background: #b0ff66; }
.btn-sm { height: 34px; padding: 0 14px; font-size: 14px; }
.link { display: inline-flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 590; color: var(--accent); }
.link::after { content: "›"; font-size: 19px; line-height: 1; transition: transform .15s; }
.link:hover::after { transform: translateX(3px); }
.link.white { color: #fff; }

/* ---------- the impact banner (the founder, 13 Oct: "Add a green banner at the top that shows the live 'Heating Hours Saved'
   and estimated 'CO2e Saved'", then "Just add a placeholder for now"): the brand green, its words the brand purple, as on
   the lime buttons; placeholder figures until the server counts real ones (tagged "Placeholder" until the founder's "get
   rid of the "placeholder" label", 13 Oct). Fixed to the top of the window, the bar under it, since the founder's "make the
   green bar thinner, and make sure it stays fixed to the top of the browser window" (13 Oct; 40 px tall, two lines on a
   phone, scrolling away with the page above the header until then): the top of the fixed header (.nav), so --nav, the
   header's height, is the banner's and the bar's (--bar) together, and all that is placed under the bar sits under both.
   30 px tall, one line, a phone's status bar over its lime ---------- */
:root { --ban: 30px; }
.impact { height: calc(var(--ban) + env(safe-area-inset-top, 0px)); padding-top: env(safe-area-inset-top, 0px); background: var(--lime); color: var(--accent); }
.nav:has(> .impact) { padding-top: 0; }   /* the safe area in the banner, above */
.impact-in { display: flex; align-items: center; justify-content: center; height: var(--ban); max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); font-size: 13px; font-weight: 600; line-height: 1; white-space: nowrap; }
.impact b { font-weight: 800; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.impact sub { font-size: .72em; line-height: 0; vertical-align: -.2em; }
.impact .est { font-weight: 500; opacity: .8; }
.impact p + p::before { content: ""; display: inline-block; width: 1px; height: 12px; margin: 0 14px 0 15px; vertical-align: -1px; background: currentColor; opacity: .3; }   /* a rule between the two figures */
.impact .short { display: none; }
@media (max-width: 459px) { .impact-in { padding: 0 16px; font-size: 12px; } .impact p + p::before { margin: 0 9px 0 10px; } .impact .long { display: none; } .impact .short { display: inline; } }   /* "(est.)" on a phone, so the line fits from 320 px wide */

/* ---------- navigation: a flat bar the window's width, fixed under the green banner (the founder, 2 Nov 2026: "lets just make
   this a flat and fixed nav-bar at the top of the window"; a pill floating under the banner, shaped as ParentPay Group's,
   from 1 Nov until then: "lets change the top nav-bar to look more like (see attached)", in the brand purple gradient, a
   little 3D for an hour). The brand purple gradient, the product's own (the founder, 28 Sep; white before that), the purple
   lightening towards the right, its halfway at 67 % across (the founder, 2 Nov: "can we make the transition mid-point of
   the gradient be 67% from the start of the darker purple?"; 57.5 % until then). Clear over the photo at the top of the
   page (the founder, 13 Oct: "Would it look better if the nav-bar background appeared only when the user begins to scroll
   down?", and again 1 Nov: "lets have the nav-bar look like this when the user is at the top of the page"), "Sign in" bare
   and "Book a call" with its "›" there; once scrolled "Sign in" an outlined pill and "Book a call" plain (.at-top, from the
   page's line after the bar, then hybrid.js; the bar always without a script), and its shadow once the hero's headline or
   picture nears it (.scrolled, hybrid.js) ---------- */
.nav { position: fixed; inset: 0 0 auto 0; z-index: 50; height: calc(var(--nav) + env(safe-area-inset-top, 0px)); padding-top: env(safe-area-inset-top, 0px); color: #fff; transition: box-shadow .2s; }
.nav::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(90deg, #4f12cb 0%, #4f12cb 15%, 67%, #784af2 100%) #784af2; pointer-events: none; transition: opacity .3s var(--ease); }
.nav.scrolled { box-shadow: 0 10px 30px -16px rgba(38, 8, 110, .55); }
.nav.at-top:not(.open)::before { opacity: 0; }   /* clear over the photo at the top of the page; a phone's open menu on the bar always */
.nav-inner { display: flex; align-items: center; gap: 28px; height: var(--bar); max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
.brand img { width: 97px; height: auto; translate: 0 8.9%; }   /* lowered 8.9 % of its height (2.6 px), so its mark, not the whole logo with the "gy" under it, sits in the middle of the bar (the founder, 1 Nov: "can we lower the logo a bit such that the icon is centered horizontally rather than the full logo. (the "gy" is causing it to position slightly higher)"): the mark 0.15 to 124.56 down the logo's 151.7, its middle 13.49 above the logo's */
.brandrow { display: flex; align-items: center; gap: 16px; }
.brandrow .ucl { display: block; flex: none; overflow: visible; height: 34px; width: auto; padding-left: 16px; border-left: 1px solid rgba(255, 255, 255, .3); fill: #fff; font-family: var(--font); }   /* UCL Innovation & Enterprise's badge beside the logo, a hairline between them (the photo versions, 13 Oct) */
.nav-links { display: flex; align-items: center; gap: 22px; margin: 0; padding: 0; list-style: none; font-size: 15px; font-weight: 590; }
.nav-links a { color: rgba(255, 255, 255, .9); transition: color .15s; }
.nav-links a:hover { color: #fff; }
.nav-right { display: flex; align-items: center; gap: 8px; margin-left: auto; font-size: 15px; font-weight: 590; }
.nav .btn { height: 40px; padding: 0 18px; font-size: 15px; }
.nav .btn-ghost::after { content: none; }
.nav .btn-lime::after { display: inline-block; width: 0; margin-left: -6px; overflow: hidden; opacity: 0; transition: width .3s var(--ease), margin .3s var(--ease), opacity .2s; }   /* plain pills on the pill, as ParentPay's; "Book a call"'s "›" at the top of the page */
.btn-ghost { border-color: rgba(255, 255, 255, .55); background: transparent; color: #fff; transition: border-color .3s, background .15s; }   /* an outlined pill on the purple: "Sign in" */
.btn-ghost:hover { border-color: #fff; background: rgba(255, 255, 255, .12); }
.nav.at-top:not(.open) .btn-ghost { border-color: transparent; background: none; }   /* "Sign in" bare */
.nav.at-top:not(.open) .btn-lime::after { width: .45em; margin-left: 0; opacity: 1; }
@media (min-width: 768px) {                            /* the tabs centred in the bar, the logo left, "Sign in" and "Book a call" right (the founder, 29 Sep); a side wider than its share only nudges them */
  .nav-inner { display: grid; grid-template-columns: 1fr auto 1fr; }
  .nav-inner .brand, .nav-inner .brandrow { justify-self: start; }
  .nav-right { justify-self: end; margin-left: 0; }
}
@media (min-width: 768px) and (max-width: 1023px) {   /* narrower than the bar's whole row: closer gaps, smaller words and buttons, so it fits from 768 px ("Impact" goes, below) */
  .nav-inner { gap: 16px; }
  .brandrow { gap: 12px; }
  .brandrow .ucl { height: 30px; padding-left: 12px; }
  .nav-links { gap: 16px; font-size: 14px; }
  .nav .btn { height: 36px; padding: 0 12px; font-size: 14px; }
}
.nav-toggle { display: none; width: 40px; height: 40px; margin-left: auto; border: 0; border-radius: 50%; background: transparent; cursor: pointer; }
.nav-toggle span { display: block; width: 18px; height: 2px; margin: 5px auto; background: currentColor; border-radius: 2px; }
@media (max-width: 767px) {
  .nav-links, .nav-right { display: none; }
  .nav-toggle { display: block; order: 1; }
  .nav.open { height: auto; box-shadow: 0 10px 30px -16px rgba(38, 8, 110, .55); }
  .nav.open::before { transition: none; }   /* at once, even from the clear bar at the top, so the links never show over the photo unbacked */
  .nav.open .nav-links, .nav.open .nav-right { display: flex; }
  .nav.open .nav-inner { flex-wrap: wrap; height: auto; padding-bottom: 16px; }
  .nav.open .nav-inner .brand, .nav.open .nav-inner .brandrow { height: var(--bar); display: flex; align-items: center; }
  .brandrow .ucl { height: 30px; padding-left: 12px; }
  .brandrow { gap: 12px; }
  .nav.open .nav-links { order: 2; flex-basis: 100%; flex-direction: column; align-items: flex-start; gap: 0; border-top: 1px solid rgba(255, 255, 255, .16); }
  .nav.open .nav-links li { width: 100%; padding: 12px 0; border-bottom: 1px solid rgba(255, 255, 255, .16); }
  .nav.open .nav-right { order: 3; flex-basis: 100%; gap: 10px; margin: 14px 0 0; }
  .nav.open .nav-right .btn { flex: 1; justify-content: center; }
}

/* ---------- hero: the bar's purple gradient on Stripe's slanted band, Linear's headline and framed shot over it ---------- */
main { position: relative; }
.hero { position: relative; z-index: 2; padding: calc(var(--nav) + env(safe-area-inset-top, 0px) + clamp(36px, 4.5vw, 64px)) 0 clamp(24px, 4vw, 48px); color: #fff; }   /* the headline 64 px under the bar on a computer, 36 on a phone (the founder, 12 Oct: "we can reduce the distance a bit between the nav-bar and the hero section"; clamp(48px, 7vw, 96px) until then, 96 and 48) */
.band { position: absolute; inset: 0; z-index: 0; background: linear-gradient(90deg, #4f12cb 0%, #4f12cb 15%, #784af2 100%) #784af2; clip-path: polygon(0 0, 100% 0, 100% calc(100% - 9vw), 0 100%); }   /* the bar's own gradient (.nav::before), still (the founder, 12 Oct, of the bar's: "make that the gradient of this section as well (static background this time)", then "The gradients don't match", then "lets just make it a horizontal gradient instead of 135 degrees"): the brand purple at the left, lightening to #784af2 at the right, horizontal as the bar's so the two meet without a seam (corner to corner, 135°, for an hour). Stripe's animated gradient until then: five soft blobs of the brand's purples, a lavender and a little lime drifting on a small canvas, blurred by CSS, under a faint darkening at the top and foot */
.hero:has(+ .section.purple) { background: var(--accent); }   /* under the band's slanted foot, the purple of the section after it (the founder, 12 Oct: "lets get rid of this section", of the white partners strip between them until then: the names of the systems Sinc works with, moving on their own) */
.hero .wrap { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(28px, 5vw, 64px); align-items: center; }
.hero h1 { max-width: 15ch; text-shadow: 0 2px 24px rgba(20, 5, 70, .25); }
.hero h1 .sub { display: block; margin-top: .3em; font-size: .781em; font-weight: 700; letter-spacing: -.015em; line-height: 1.1; color: var(--lime); }   /* "Stop heating empty classrooms." in the page's bold, what it gets, "Cut carbon. Lower bills.", on one row under it in Urbanist Bold, the headline's own weight (the founder, 12 Oct: "can we increase the weight of 'Cut carbon. Lower bills.'?", "lets go heavier", then "heavier"; Regular until then, Medium and SemiBold for a few minutes each), as wide as "empty classrooms." above it (the founder, 12 Oct: "Lets have it in one row without the icons. Just make sure the width matches the width of '...empty classrooms.' (adjust the font size accordingly)"): 78.1 % of the headline's size since "classrooms." is upright (78.2 while it was italic too; 81.5 in Regular, 80.7 in Medium, 79.4 in SemiBold), so the two lines end together, the ratio of their inked widths less the 1.5 px the italic e's foot reaches left, so they match at every size, to a pixel where text is laid out unhinted (a Mac, Windows, a phone; a Linux browser that hints its fonts rounds each letter, up to 6 px out over the line). Before that the same day: "Lets change this to maybe something like: 'Stop heating empty classrooms. Reduce emissions. Save money'", "I like 'Cut carbon. Lower bills'", then a row at 55 % of the size (the founder: "Should we put 'Cut carbon. Lower bills.' in the same row (almost like a sub-heading) or should we add a relevant icon to the left of them?"; icons made it a feature list and the bill's receipt read as a speech bubble), and "Lower gas bills and less carbon, room by room." until then. In the brand green, the logo's lime, as the bar's "Book a call" (the founder, 12 Oct: "And make 'Cut carbon. Lower bills' green"; white until then, as white at 60 % had greyed out where the animated gradient the hero had until later that day drifted its lime behind it) */
/* the photo versions' saving under the headline, in place of "Cut carbon. Lower bills." (the founder, 13 Oct: "What if we
   change the hero-page text to something like this", a sketch: "Up to" over a large "33%", "Less carbon." and "Reduced
   bills." in two lines beside it, "Lower bills." since): the number in the brand green, the words white as the headline's, in Urbanist
   SemiBold, "Up to" small and on its side at the number's left, reading up from its baseline (the founder: "What if we
   make "Up to" orientated vertically and to the left of "33%"?"; above it until then). In em of the headline, so it
   keeps its shape at every size: as wide as "empty classrooms." above it, to a pixel ("Up to" .603 of the headline's size,
   the number 1.916, the gap .24, the words .72, "Less carbon." the longer line since the founder's "change "Reduced
   bills." to "Lower bills"", 13 Oct), the two lines' caps level with the number's top and the second's baseline on its
   own (line-height 1.216; last-baseline alignment). The simulation's basis is in the lead under it, with its note */
.hero h1 .stat { display: flex; align-items: flex-end; align-items: last baseline; gap: 0 .1em; width: max-content; margin-top: .3em; font-weight: 600; letter-spacing: -.015em; color: #fff; }   /* the words .1 em from the number since the founder's "Can we move "lower bills & less carbon." closer to "33%"?" (1 Nov; .24 until then, about 21 px of clear space at 1,065 px wide, 13 now) */
.hero h1 .stat .num { display: flex; align-items: flex-end; }
.hero h1 .stat .upto { writing-mode: vertical-rl; transform: translateX(-.136em) rotate(180deg); margin: 0 .05em .3151em 0; font-size: .5179em; font-weight: 300; letter-spacing: -.005em; line-height: 1; color: rgba(255, 255, 255, .9); }   /* the line above's size and style since the founder's "Make "up to" the same style and size font as the "Synchronise smart radiator valves with school timetables and achieve" text (even if it no longer matches the height of the "33%")" (14 Oct): .5148 em of the headline (.5179 of the stat's), Urbanist Light since 14 Oct (Medium before), white at .9, its margins kept as they were (.6527 em, white at .8, the digits' height, until then); drawn .136 em to the left since the founder's "can we ensure "up to" aligns better with the rest of section (i.e. move it a bit to the left)" (14 Oct), so its letters' left edge meets "Synchronise"'s, measured (4.5 px to the right at 1440 px wide, 3 at 390, until then); a transform, so nothing else moves */   /* turned to read upwards, as long as the digits are tall, from their foot to their top, to a pixel (the founder, 13 Oct: "yes", to running it the number's whole height so the "up to" that keeps the 33% honest reads at a glance; .3 of the headline's size, 13 px at least, along its lower half, until then), 7 px from the 3 on a computer; "up to", lowercase, since the founder's "make both changes" (13 Oct: the hero's claim the end of the sentence above it, "Up to" until then), its size raised from .603 em so it still runs the digits' height */
.hero h1 .stat b { font-size: 1.916em; font-weight: inherit; letter-spacing: -.03em; line-height: .9; color: var(--lime); }
.hero h1 .stat .gains { font-size: .7756em; font-weight: 700; line-height: 1.02; color: var(--lime); }   /* .7756 em and line height 1.02 since the words came closer to the number (1 Nov, above): a little larger, so "less carbon." still ends under "classrooms?", its line closer, so the first line's tallest letters are still level with the number's top (.748 and 1.085 until then). the 33%'s lime since the founder's "Make "Less carbon." and "Lower bills." in green" (13 Oct; white until then). Urbanist Bold since the founder's "can we increase the font weight of "Less carbon." and "Lower bills."?" (13 Oct; SemiBold, .72 and 1.216 until then), a hair smaller so "Less carbon." still ends under "classrooms."; "less carbon, lower bills." since the founder's "make both changes" (13 Oct: the end of the sentence above it, its capitals and full stop gone; "Less carbon. Lower bills." until then), .7379 em (.7126 before) so "less carbon," still ended under "classrooms."; "less carbon & lower bills." since the founder's "change "lower bills.*" to just "& lower bills."" (13 Oct; the asterisk's place taken by the small line under the buttons), .7028 em so "& lower bills.", now the longer line, ends under "classrooms."; .7222 since "up to" took the line above's size (14 Oct), its column narrower; .645 since the founder's "lets change this to say "lower bills & less carbon."" (14 Oct), "& less carbon." the longer line; .748 since "move the "&" next to "lower bills"", "lower bills &" over "less carbon."; line height 1.085 (1.236 until then) since the founder's "ensure the top of "lower bills &" is inline with the top of "33%". keep "33%" the same size." (14 Oct): its last line on the digits' baseline, so the first line's tallest letters meet the digits' top, measured within a pixel */
.hero h1 em { font-style: italic; }   /* "empty" in Urbanist Bold Italic, the face the page loads, not a slanted upright, "classrooms." upright (the founder, 13 Oct: "Make 'classrooms.' non-italic"; "empty classrooms" italic since the founder's "make 'empty classrooms' italic", 12 Oct, its full stop upright); white here, orange on the photo version (below; here too for an hour: the founder, 13 Oct: "optomise the colour of 'empty' for the photo-hero-section version only") */
.hero-photo h1 { font-weight: 600; }   /* "Stop heating" and "classrooms." in Urbanist SemiBold, a step lighter than the page's other headings (the founder, 13 Oct: "make "Stop heating" and "classrooms." use a slightly lighter weight version of the font"; Bold until then), "empty" still Bold Italic (below), so the stat under them is .994 of the headline's size, to stay as wide as the lighter line */
.hero-photo h1 em { font-weight: 800; }   /* Urbanist ExtraBold Italic since the founder's "lets slightly increase the font weight of "empty"" (14 Oct; Bold until then); its width the same, so the line's fit and the push-in's 3.03 em hold */
.hero-photo h1 .stat { font-size: .994em; }
.hero h1 .lead-in { display: block; margin-top: 1.25em; font-size: .5148em; font-weight: 300; letter-spacing: -.005em; line-height: 1.35; white-space: nowrap; color: rgba(255, 255, 255, .9); }   /* the line leading from the headline into the saving (the founder, 13 Oct: "Add text between the "Stop heating empty classrooms." and "Up to 33% Less Carbon. Lower bills." that says "Synchronise Sinc Energy smart radiator valves with your school timetable and achieve""), white, the saving just under it as the sentence's end. Its longer line as wide as "empty classrooms." since the founder's "scale the middle text to fix the space/width" (13 Oct; the lead's size, 18 to 21 px, until then): in em of the headline, 15.39 em of its own ("with school timetables and achieve" in Urbanist Medium, "school timetables" Bold; "Synchronise smart radiator valves" 15.07) to 7.85 of the headline's, so it keeps the shape at every size (Urbanist Light, 300, since the founder's "can we use a thinner font for "Synchronise smart radiator valves with school timetables and achieve up to" (except for the words "smart radiator valves" and "school timetables")", 14 Oct: 15.25 em of its own, .5148 of the headline; Medium, .5101, until then); the break fixed, after "valves"; 1.25 em under the headline since the founder's "should we add a bit more space between "Stop heating empty classrooms." and the rest of the text in the hero-section?", then "add it and deploy" (14 Oct: 12 px more at 1440 px wide, 8 on a phone, so the headline stands apart from the one sentence under it; .89 em before, and .67 until the founder's "make both changes", 13 Oct). "Synchronise smart radiator valves with school timetables and achieve" since the founder's "change this to" that (13 Oct; "... with your school timetable and achieve" for an hour before, and "Synchronise Sinc Energy smart radiator valves ...", broken after "radiator", until then) */
.hero h1 .lead-in + .stat { margin-top: .14em; }
.hero h1 .lead-in b { font-weight: 700; font-style: italic; }   /* "smart radiator valves" and "school timetables" in Urbanist Bold (the founder, 13 Oct: "make "smart radiator valves" and "school timetable" bolder"), Bold Italic since the founder's "make "smart radiator valves" and "school timetables" italic" (13 Oct; as wide as the upright, so the line keeps its fit) */
.hero-photo h1 em { color: #ff8432; }   /* orange, the heat being wasted, against the row's lime, what Sinc saves (the founder, 13 Oct: "lets make 'empty' orange or red or something", then "optomise the colour of 'empty' for the photo-hero-section version only"; #f97316 for an hour): the photo's own copper, its teacher's hair (OKLCH hue 48 to 50), as vivid as the screen allows at a lightness (OKLCH .74, chroma .174) that sits beside the white "classrooms." without going peach. 5.8:1 on the lightest of the shaded room behind it (768 px wide), more at other widths; 16 apart from the lime as a deuteranope sees them (OKLab x 100, the lime a good deal lighter) */
/* "classrooms." first, then sliding right to uncover "empty" (the founder, 14 Oct: "have "empty classrooms." initially show as
   just "classrooms." then it slides out to reveal "empty classrooms.""): once, as the page opens, 0.6 s in, over 1.1 s.
   "classrooms." starts where "empty" does ("empty" and the space after it, 3.03 em of the headline in Urbanist) and "empty" is
   uncovered behind it, its clip's right edge a hair behind "classrooms."; both fill backwards only, so once done the line is
   the page's own layout again. Only with .ec-intro, set by the page's line after the bar when motion is allowed: without a
   script, or with reduced motion, the line stands as it ends */
.hero h1 .stop { display: block; font-size: .942em; line-height: 1.12; white-space: nowrap; }   /* "Stop heating" as wide as "classrooms." alone (the founder, 14 Oct: "Select a font size that make "Stop heating" the same with as "classrooms."", then "i said make it the same length as just "classrooms.""; 1.429 em, as wide as "empty classrooms.", for a few minutes): .902 of the headline, measured, so the two lines match exactly as the line below first reads "classrooms." alone; a line of its own, so the <br> after it went */
.hero h1 .ln2 { display: block; font-size: .942em; white-space: nowrap; }   /* "empty classrooms?" on one line, the same size as "Why heat and cool" over it (the founder, 30 Oct: "change this to "Why heat and cool vacant classrooms?"", then "make this the same font size and style") */
.hero h1 em, .hero h1 .cls { display: inline-block; }   /* boxes for the transform and the clip; the line measures the same */
.ec-intro .hero h1 .cls { animation: ec-slide 1.1s cubic-bezier(.7, 0, .2, 1) .6s backwards; }
.ec-intro .hero h1 em { animation: ec-push 1.1s cubic-bezier(.7, 0, .2, 1) .6s backwards; }
@keyframes ec-slide { from { transform: translateX(-3.0234em); } to { transform: none; } }
@keyframes ec-push { from { visibility: hidden; transform: translateX(-3.0234em); -webkit-clip-path: inset(-.4em 0 -.4em 3.0234em); clip-path: inset(-.4em 0 -.4em 3.0234em); } to { visibility: visible; transform: none; -webkit-clip-path: inset(-.4em -.4em -.4em -.1em); clip-path: inset(-.4em -.4em -.4em -.1em); } }   /* "empty" pushing its way in from the column's left edge, against "classrooms.", moving with it (the founder, 14 Oct: "I want it to look like the word "empty" is pushing its way in"; uncovered in place, "classrooms." sliding off it, until then): it moves as "classrooms." does, the space between them kept, and its clip holds the column's edge, so it shows only once past it; the clip's right edge on the word's box at the start (-.4 em, for the italic's lean, at the end), as the tip of its "y", past the box, showed at the column's edge before it moved (14 Oct); and hidden outright until it moves (visibility, hidden in the first keyframe and so through the delay, the same in every browser), with the clip prefixed for Safari too, as the tip still showed there on the founder's screen */
/* the 33% counting up from 0 at the same time (the founder, 14 Oct: "lets also animate the 33% so it goes from 0% to 33%"; the script after
   the headline): the figure's own "33%" kept for its place and for screen readers, unseen, and the count over it, centred on it, as the
   numbers on the way are up to 0.14 em wider ("20%") and so share the difference with the gaps either side */
.hero h1 .stat b { position: relative; }
.hero h1 .stat .amp { font-size: .6677em; font-weight: 300; letter-spacing: -.005em; color: rgba(255, 255, 255, .9); }   /* as "up to" since the founder's "ensure the "&" is in the same font style and size as "up to"." (14 Oct): .5179 em of the stat over the line's .7756 (.748 until 1 Nov), Light, white at .9 (the line's size, pure white, until then) */   /* the "&" white among the lime (the founder, 14 Oct: "make the "&" white"), in Urbanist Light as the line above ("reduce the weight of the "&""; Bold, as the words beside it, until then) */
.hero h1 .stat b.counting { color: transparent; }
.hero h1 .stat b.counting::after { content: attr(data-n) "%"; position: absolute; top: 0; left: -50%; right: -50%; text-align: center; white-space: nowrap; color: var(--lime); }
.hero .lead { margin-top: 20px; font-size: clamp(18px, 1.6vw, 21px); color: rgba(255, 255, 255, .9); }   /* 21 px from about 1310 px wide, 18 on a phone (the founder, 12 Oct: "Should we make this a bit bigger?"; the page's lead size, 17 to 19, until then): two sentences now, under a headline bold in both its lines */
@media (max-width: 380px) { .hero h1 { font-size: 10.5vw; } }   /* "empty classrooms." on one line down to 320 px: at the headings' least, 40 px, it splits under 375 */
.hero .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px; margin-top: 30px; }
.hero-shot { position: relative; align-self: start; perspective: 1400px; margin-bottom: -18%; }   /* at the top of its column, so the window's top-left corner, the one by the words, is level with the headline's top at every width, its top edge rising a little to the right as the window turns (the founder, 12 Oct: "I feel the images to the right are not correctly in line with the text"): centred on the words until then, which left it 45 to 61 px lower and the phone about 116 px below the buttons */
.shot-frame { position: relative; border-radius: 14px; border: 1px solid rgba(255, 255, 255, .35); background: #fff; overflow: hidden; transform-origin: 50% 0;
  transform: rotateX(var(--tilt, 12deg)) rotateY(-6deg) scale(.98); box-shadow: var(--shadow-float), 0 0 0 1px rgba(20, 5, 70, .12); transition: transform .2s var(--ease); will-change: transform; }
.shot-frame .bar { display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 14px; background: #f3f0fa; border-bottom: 1px solid var(--line); }
.shot-frame .bar i { width: 10px; height: 10px; border-radius: 50%; background: #d6d0ea; }
.shot-frame .bar span { margin-left: 10px; font-size: 12px; color: var(--text-3); }
.shot-frame img { width: 100%; height: auto; }
.float { position: absolute; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 12px; background: #fff; color: var(--ink); box-shadow: var(--shadow-float); font-size: 13px; font-weight: 590; animation: float 6s ease-in-out infinite; }
.float small { display: block; font-weight: 510; color: var(--text-3); font-size: 12px; }
.float .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 0 3px rgba(153, 255, 51, .3); }
.float.f1 { left: -6%; top: 18%; animation-delay: -1s; }
.float.f2 { left: -2%; bottom: -6%; z-index: 3; animation-delay: -3.5s; }   /* under the console, clear of the phone */
/* the teacher app beside the console (the founder, 29 Sep: "show stills of the school console AND the teacher app"): its screen
   alone, with no phone round it ("do not include the phone border and the dynamic island"), a still of the teacher page's
   demo (assets/img/hero-teacher.webp, website/tools/capture-hero-phone.js), in front of the console's window at its lower
   right, turned a little with it and standing out past the band's foot; edged and shadowed as the window. Its corners are in
   its own width (cqw), as an iPhone's screen's: 14 % */
.hero-phone { position: absolute; right: -3%; bottom: -21%; z-index: 2; width: 31%; container-type: inline-size; transform: rotateY(-8deg) rotateZ(1.5deg); transform-origin: 50% 100%; }
.hero-phone .body { overflow: hidden; border-radius: 14cqw; border: 1px solid rgba(255, 255, 255, .35); background: #fff;
  box-shadow: var(--shadow-float), 0 0 0 1px rgba(20, 5, 70, .12), 0 30px 60px -28px rgba(20, 5, 70, .55); }
.hero-phone img { display: block; width: 100%; height: auto; }
@media (max-width: 1200px) { .hero-phone { right: 1%; } }   /* clear of the window's edge */
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@media (max-width: 767px) {
  .hero .wrap { grid-template-columns: 1fr; }
  .hero-shot { margin: 8px 0 -4%; }   /* -10% until the phone stood below the console (29 Sep) */
  .band { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 6vw), 0 100%); }
  .float.f1 { left: 0; top: 24%; } .float.f2 { left: 0; bottom: -4%; }
  .hero-phone { right: 3%; bottom: -10%; width: min(36%, 250px); }   /* less below the console with one column, clear of the line under the hero */
}

/* ---------- the second version, photo-hero.html: the hero on the founder's classroom photo (12 Oct: "Create a second
   version of the website with this as the main hero-section background. Leave the smartphone in the photo blank/white for
   now"), a teacher seen from behind holding a phone in a lesson, from one edge of the screen to the other under a dark
   shade, as the teacher app's classroom is (the founder, 12 Oct: "Can we improve the way this looks? maybe we can make the
   image span the full width like in the 'Teachers get a say' section? don't worry about matching the hero-section with
   the nav-bar"; until then the words kept the bar's purple at the left and the photo filled the band from 64 px before
   their end). It is the founder's taller version of the photo, the room's ceiling and wall added above it
   (assets/img/hero-classroom-phone-tall.webp, 1672 x 1887, the photo itself its foot 941 px; the founder: "lets use this
   picture instead (with the taller aspect ratio) so we can use the same fade effect in the mobile view of the hero-section
   as the desktop view"). In it the phone is left of the middle (34 to 50 % across) and the teacher's head at the right, so
   across a computer's screen the phone would lie under the words: from 768 px wide (the page's two columns; 901 until the
   founder: "The website switches to mobile format waaay too early", 1200 for the hero before "it moves to the bottom when
   the window width is even slightly shortened") the page has it widened at the left by 640 px of the room, mirrored and
   smeared (assets/img/hero-classroom-phone-wide.webp, 2312 x 1887, from website/tools/widen-hero-photo.py), the photo
   itself whole at its right. The words are 46 % of the screen's width, 520 px at most, and the phone's left edge lies 40
   px past their end (--p: 16 px before the screen's middle from 1200 px wide, where the words end 56 px before it). The
   photo is as close on the phone as keeps the look over the teacher's shoulder (the founder, 12 Oct: "Zoom such that the
   mobile phone occupies as much of the photo as possible whilst maintaining the over-the-shoulder aesthetic"; its right
   edge on the screen's and its foot on the band's until then, a third less close): her ear to the phone's foot (1130 to
   1690 px down the photo) in the band between the bar and the partner schools' strip along its foot (below), its middle
   at that space's, and her ear and neck to the screen's right edge (1400 px across the photo itself), whichever is less
   close; its right edge on the screen's at least. On a screen too wide for that (about 2190 px, from the band's own
   height; 1961 px, fixed, until 13 Oct) its right edge is the screen's, the phone further
   right, as close as the band's height allows. Its left 15 % and its foot (the 6 % under her hand) fade into the band's
   dark wherever they fall: behind the strip on a narrow window, beyond the band's straight foot on a wide one. Over it lies the teacher app's shade, the near-black purple, .88 at the
   screen's left edge, .8 from 154 px before the phone's edge, .5 at 54 px before it and clear by it. Up to 767 px the
   words come first, over the taller photo as it is, as close on the phone as keeps her ear and neck to the screen's
   right edge (138.82 % of the screen's width; as wide as the screen from 690 px, 135 % of it on a phone, until the
   founder's "Zoom such that ..."), cropped round the phone, whose middle stays 41.84 % across, where it is in the photo,
   however wide the screen (the founder, 12 Oct: "The focus of the zooming (as the window changes width) should be on the
   mobile phone"; its right 5 % cut until then), 1700 px down it at the strip's top and its foot faded out under it. The top of the teacher's
   hair is 16 px above the buttons' row, 14 px under the lead (670 px down the photo, 61.6 % of its width above the
   band's foot; the founder: "the 'Book a call' row should be below the top of the teacher's head"; the words ended 16 px
   above it until then), and the same shade lies over the ceiling behind the words, from the top: .88, .8 from 60 px
   above her hair, .5 at 40 px below its top and clear 98 px below it, so "See the numbers" keeps 5:1 against the room. A
   phone's narrow photo starts under the words' top, faded in over its top 12 %. The phone's screen stays white, to be
   filled later. The rest of the page is index.html's ---------- */
.hero-photo { container-type: inline-size; --strip: 72px; padding-bottom: 0;   /* sizes in cqw, the band's width with no scroll bar; --strip: the partner schools' strip along its foot, below: 72 px since the founder's "Lets reduce the height of the "customers" bar" (14 Oct; 96 until then), 84 on a phone, where the label is above the row (beside it for an hour on 2 Nov, the strip keeping its height) */
  --tx: -52.21%; --ty: -74.72%; --kv: 3.3696; --kh: 2.2653; --ke: 1.7077; --w: 138.82cqw; --cx: .4184; --cut: .1118; --hair: .616; }   /* the photo's measures, used below, so a version on another photo sets its own (.hero-empty, after this block) */
.hero-photo .wrap { grid-template-columns: minmax(0, 1fr); }
.hero-photo .band { container-type: size; overflow: hidden; background: #1f0758; clip-path: none; }   /* the hero's purple, here and in its shades over the photo, #1f0758, darker since the founder's "make the colour a bit darker", "make it a bit more darker" and "a bit more darker", twice (1 Nov; #340b8f, #2c097a and #250868 for a few minutes each; #3d0da8, a deeper shade of the brand purple, since the founder's "lets make this dark purple closer to the brand purple", 18 Oct; #1f0656 before that); its foot straight (the founder, 12 Oct: "lets straighten this diagonal"; slanted as index.html's until then, 9 % of the width lower at the left, 6 % on a phone) */
.hero-photo .band::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.hero-photo .hero-blur { position: absolute; inset: 0; pointer-events: none; -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }   /* the photo softened behind the words (the founder, 2 Nov 2026: "I want to add a blur behind the text in the hero section"), under the purple fade: at full strength behind them, fading out before the phone, so the phone and the hand stay sharp (its masks, below) */
.hero-photo .band::before { content: ""; position: absolute; inset: 0 0 auto; z-index: 1; height: calc(var(--nav) + env(safe-area-inset-top, 0px) + 86px); pointer-events: none;
  background: linear-gradient(rgba(31, 7, 88, .62), rgba(31, 7, 88, .28) calc(var(--nav) + env(safe-area-inset-top, 0px) + 6px), rgba(31, 7, 88, 0)); }   /* a soft dark fade from the top, so the bar's links read over the photo when it's clear (above) */
.hero-photo .hero-bg { position: absolute; max-width: none; }
/* a zoom as the page opens (the founder, 30 Oct: "Can we add a zoom effect to the hero-image that triggers when the website first
   loads?"): the photo 12 % closer, about the teacher's phone, settling to its place over 2.4 s, eased out, once it has loaded (.zoomed, hybrid.js),
   as the headline slides in; only with .ec-intro (motion allowed), so with reduced motion or no script it stands as it ends. Closer,
   not further: further, the band's purple would show round its edges */
.ec-intro .hero-photo .hero-bg { scale: 1.12; transform-origin: 58% 74%; transition: scale 2.4s cubic-bezier(.33, 1, .68, 1); }
.ec-intro .hero-photo .hero-bg.zoomed { scale: 1; }
@media (max-width: 767px) { .ec-intro .hero-photo .hero-bg { transform-origin: 45% 72%; } }   /* the phone's middle in the tall photo */
/* the hero's carousel (the founder, 2 Nov 2026: "have the hero image be a carousel containing three other images (use
   placeholder images for now)"): the photo and three placeholders of its own sizes, each placed, cropped and masked as the
   photo (.hero-bg), one at a time (.on), crossfading every 6 s and each settling from close as it fades in, as the photo
   does as the page opens (hybrid.js); its round tabs in a column at the right, over the band's foot (.hero-dots, below). The
   placeholders are dark, so the words read over them as over the photo; real pictures take their files, and each will want
   its own measures (--tx, --ty and the rest, below) where its subject is not where the teacher's phone is */
.hero-photo .hero-bg { transition: opacity 1.2s var(--ease); }
.ec-intro .hero-photo .hero-bg { transition: scale 2.4s cubic-bezier(.33, 1, .68, 1), opacity 1.2s var(--ease); }
.hero-photo .hero-bg:not(.on) { opacity: 0; }
.hero-dots { position: absolute; right: calc(max(var(--gutter), (100% - var(--max)) / 2 + var(--gutter)) - 5px); bottom: calc(var(--strip) + 8px); z-index: 3; display: flex; flex-direction: column-reverse; gap: 4px; }   /* the picture showing's tab always at the foot, the next above it, and so on round (the founder, 2 Nov: "Have the active tab always be at the bottom"; hybrid.js sets their order, the first at the foot without it). A column at the right, the circles on the words' right edge, over the picture's foot, on a phone and a computer alike (the founder, 2 Nov: "in mobile, position the tabs to the right", then "Also position the tabs in the desktop version on the right"): on a phone clear of the phone in the teacher's hand that will show the app ("in the mobile view, the tabs cover the image of the phone that will display the app"; a row centred under it, then a column at the left, until then); on a computer a row centred under the picture before ("Position the tabs so they are more central below the image"), at the words' right edge before that */
.hero-dots button { position: relative; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }   /* round tabs a finger can press (the founder, 2 Nov: "lets use circular tabs that alow the the user to press with their finger"; 8 px dots in 24 px until then, the picture showing a dash): 44 px to press, Apple's least, the circle 14 */
.hero-dots button::before { content: ""; grid-area: 1 / 1; box-sizing: border-box; width: 34px; height: 34px; border: 1.5px solid rgba(255, 255, 255, .85); border-radius: 50%; background: rgba(26, 10, 70, .45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 2px 8px rgba(20, 5, 70, .4); transition: background .3s, border-color .3s; }   /* each tab a round button with its icon (the founder, 2 Nov: "lets make the tabs icons: mobile (to represent the app), fire (to represent heating), snowflake (to represent cooling)"; plain circles until then): a 34 px circle of dark glass, so its white icon reads over the phone's bright screen as over the purple, in the 44 px a finger presses */
.hero-dots .ic { position: relative; grid-area: 1 / 1; width: 24px; height: 24px; fill: #fff; transition: fill .3s; }   /* over the circle: the app's phone and heating's fire, Phosphor's Fill, cooling's snowflake its Bold; 24 px, the phone's corners 3 px inside the circle's edge (the founder, 2 Nov: "make the icons bigger"; 20 until then) */
.hero-dots button:hover::before { background: rgba(26, 10, 70, .65); }
.hero-dots button[aria-current="true"]::before { border-color: #fff; background: #fff; }   /* the picture showing: the circle white, its icon the brand purple (the founder, 2 Nov: "make the green, white"; the brand green for a while after "Make the white circle of an active tab green (but not the loading circle)") */
.hero-dots button[aria-current="true"] .ic { fill: var(--accent); }   /* all one size: the picture showing's a tenth larger first (the founder, 2 Nov: "do the active version of the icons appear smaller?", then "Yes, enlarge it": dark on white reads smaller than white on dark), then the others by the same ("enlarge the non-active state by the same amount"; 18 px until then, 20 from then until "make the icons bigger") */
.hero-dots button:focus-visible { outline: none; }
.hero-dots button:focus-visible::before { outline: 2px solid #fff; outline-offset: 3px; }
.hero-dots .tab-title { position: absolute; right: calc(100% + 12px); top: 50%; color: #fff; font-size: 28px; font-weight: 650; line-height: 1; letter-spacing: -.01em; white-space: nowrap; text-shadow: 0 1px 2px rgba(20, 5, 70, .65), 0 2px 12px rgba(20, 5, 70, .55); opacity: 0; translate: 8px -50%; pointer-events: none; transition: opacity .2s, translate .2s var(--ease); }   /* the picture's title to the left of its tab while it shows (the founder, 2 Nov: "Add a title to the left of each active tab"), white with a shadow under it to read over the picture (the founder: "Get rid of the pill around the text and instead just add a drop shadow. Make the text white"; on a white pill in the brand purple until then), sliding out from behind the tab once the tabs have moved round; 28 px (the founder, 2 Nov: "make the tab titles bigger", then "even bigger" twice; 15 until then, 18 and 22 between); 12 px from its tab, 13 clear of the countdown ring and 17 of the circle, on a computer and a phone (the founder, 2 Nov: "increase the relative spacing between the text and icons for both desktop and mobile view"; 6 until then) */
.hero-dots button[aria-current="true"] .tab-title { opacity: 1; translate: 0 -50%; transition: opacity .35s .3s, translate .35s var(--ease) .3s; }
@media (max-width: 767px) { .hero-dots .tab-title { font-size: 28px; } }   /* on a phone the title as large beside its icon as a computer's, 28 px to a 24 px icon, so 28 to the phone's 24 since the founder's "make this smaller (in mobile view)" (31.5 to 27 for a few minutes) (the founder, 2 Nov: "In mobile view, make the relative size of the text (relative to the tab icons) match the desktop view"; until then as large as kept "Teacher app" 4 px clear of the phone in the teacher's hand, (44.8cqw - 61 px) / 5.61, 20 px at 390 px wide): "Teacher app" now reaches over that phone's lower right */
@media (max-width: 767px) {   /* four tabs between the buttons and the strip on a phone (the founder, 2 Nov: "Add a fourth tab between 'cooling' and 'teacher app' called 'Network'", then "the tabs need moving up in mobile view"; the current tab's middle on the strip's top edge for a few minutes): 40 px apart, the circles 32, the column's foot 8 px over the strip and its top clear of the buttons */
  .hero-dots { right: 3px; bottom: calc(var(--strip) + 8px); gap: 4px; }   /* a size smaller again, a computer's: 44 px apart, the circles 34, the icons 24, 14 px between them (the founder, 2 Nov: "make this smaller (in mobile view)"; 48, 38, 27 and 15.6 for a few minutes, the spacing a computer's scaled); 15.6 px between the circles, as a computer's 14 between its 34 px circles, scaled to these 38 (the founder, 2 Nov: "increase vertical spacing between the tabs in mobile view to match the relative spacing in the desktop view"; 10 until then); the circles 8 px from the window's right edge, 48 px apart, the circles 38 and the icons 27 (the founder, 2 Nov: "In mobile view, move this closer to the right side of the window and make it slightly bigger", then "make it even bigger": 12 px from the edge at a computer's size, 44, 34 and 24, for a few minutes; on the words' right edge, 24 px in, 40 px apart, 32 and 22, before), so the title keeps its room beside the phone in the photo */
  .hero-dots button { width: 44px; height: 44px; }
  .hero-dots button::before { width: 34px; height: 34px; }
  .hero-dots .ic { width: 24px; height: 24px; }
}
@media (max-width: 359px) {   /* the narrowest phones: 44 px apart, the circles 34 and the icons 24, 8 px from the edge, so the top tab still clears "See the numbers" (40, 32 and 22 after the founder's "make it slightly bigger", 36, 28 and 20 before) */
  .hero-dots { right: 4px; gap: 5.2px; }   /* a size smaller still: 40 px apart, the circles 32 and the icons 22, 8 px from the edge, 13.2 px between the circles, a computer's spacing scaled */
  .hero-dots button { width: 40px; height: 40px; }
  .hero-dots button::before { width: 32px; height: 32px; }
  .hero-dots .ic { width: 22px; height: 22px; }
  .hero-dots .tab-title { right: calc(100% + 11px); font-size: 25.7px; }   /* a computer's 28 px to its 24 px icon, and its 12 px from the tab, scaled to this 22 */
}
.hero-dots .ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; opacity: 0; filter: drop-shadow(0 1px 2px rgba(20, 5, 70, .45)); transition: opacity .3s; pointer-events: none; }   /* round the picture showing, the time left before the next (the founder, 2 Nov: "can we have a kind of loading indicator around the tab that shows how long is left before it expires and transitions into the next one"): a faint track, and a white line drawn clockwise from the top over the hold (--hold, hybrid.js's, 6 s), standing still while the carousel waits (.paused); none with reduced motion, where the pictures move only when pressed */
.hero-dots button.timing .ring { opacity: 1; }
.hero-dots .ring circle { fill: none; stroke-width: 2.5; }
.hero-dots .ring .track { stroke: rgba(255, 255, 255, .28); }
.hero-dots .ring .run { stroke: #fff; stroke-linecap: round; stroke-dasharray: 125.66; stroke-dashoffset: 125.66; transform: rotate(-90deg); transform-box: fill-box; transform-origin: center; }   /* the circle's length, 2π × 20: round the 34 px tab, 3 px clear of it */
.hero-dots button.timing .run { animation: hero-ring var(--hold, 6s) linear forwards; }
.hero-dots.paused button.timing .run { animation-play-state: paused; }   /* as particular as the rule that starts it, or that rule's shorthand sets it running again */
@keyframes hero-ring { to { stroke-dashoffset: 0; } }
@media (min-width: 768px) {
  .hero-photo { padding-top: calc(var(--nav) + env(safe-area-inset-top, 0px) + clamp(28px, 3vw, 44px)); }   /* the headline 44 px under the bar (64 until the founder's "can we reduce the overall height of the hero section by reducing empty space/padding", 13 Oct) */
  .hero-photo { --p: calc(max(0px, (100cqw - var(--max)) / 2) + var(--gutter) + min(520px, 46cqw) + 40px); }   /* where the phone's left edge goes: 40 px past the words' end */
  .hero-photo .hero-copy { max-width: min(520px, 46cqw); }
  .hero-photo .hero-bg { --b: calc((100cqh - var(--nav) - var(--strip)) * var(--kv)); --h: min(max(min(var(--b), (100cqw - var(--p)) * var(--kh)), (100cqw - var(--p)) * var(--ke)), var(--b));
    left: max(var(--p), 100cqw - var(--h) / var(--ke)); top: calc(50% + var(--nav) / 2 - var(--strip) / 2); translate: var(--tx) var(--ty); width: auto;   /* the phone's left edge at --p (--tx: 1207 of the photo's 2312 px), the middle of the teacher's ear to the phone's foot (--ty: 1130 to 1690 of 1887 px down) at the middle of the band between the bar and the schools' strip */
    height: var(--h);   /* as close on the phone as the band's height above the strip allows with her ear to the phone's foot in it (560 px of the photo), and her ear and neck to the screen's right edge (to 1400 px across the photo itself, 833 px past the phone's edge); its right edge on the screen's at least; and never closer than the band allows: on a screen so wide that the photo, as close as that, no longer reaches the screen's right edge from the words (about 1970 px wide in the third version and 2190 in this one with the hero as it is), its right edge is the screen's and the phone further right. Worked out from the band's height (the band a size container, cqh), so it follows the hero's height wherever its words take it; from 1961 px wide and 1770 by fixed widths until 13 Oct */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 15%), linear-gradient(#000 94%, transparent); -webkit-mask-composite: source-in;   /* its left 15 % and its foot (the 6 % under the hand) faded into the band's dark, wherever they fall */
    mask-image: linear-gradient(90deg, transparent, #000 15%), linear-gradient(#000 94%, transparent); mask-composite: intersect; }
  .hero-photo .band::after { background: linear-gradient(90deg, rgba(31, 7, 88, .66), rgba(31, 7, 88, .6) calc(var(--p) - 154px), rgba(31, 7, 88, .38) calc(var(--p) - 54px), rgba(31, 7, 88, 0) calc(var(--p) + 4px)); }   /* a quarter lighter, more of the room through it (the founder, 1 Nov: "can we increase the transparency of the purple face a bit?", then "make it more transparent"; .88, .8 and .5 until then, a tenth lighter for an hour): over the room's brightest windows, behind the middle of "Why heat and cool" and the line under it, the words about 2.5:1 or a little more at 1,280 px wide with the darker purple (3.1 at first; 3:1 the large-text guideline), averaged over 6 px */
  .hero-photo .hero-blur { -webkit-mask-image: linear-gradient(90deg, #000 calc(var(--p) - 100px), transparent calc(var(--p) + 4px)); mask-image: linear-gradient(90deg, #000 calc(var(--p) - 100px), transparent calc(var(--p) + 4px)); }   /* full behind the words, gone at the phone's edge */
}
@media (max-width: 767px) {
  .hero-photo { padding-top: calc(var(--nav) + env(safe-area-inset-top, 0px) + 20px); }   /* the headline 20 px under the bar on a phone (36 until the founder's "In the mobile view, can we shorten the height of the space between the nav bar and "Stop heating"?", 13 Oct) */
  .hero-photo { --strip: 84px; }   /* (96 until 14 Oct) --w, the tall photo's width: as close on the phone as keeps the teacher's ear and neck to the screen's right edge (to 1400 px across the photo, the phone's middle 41.84 % across the screen, --cx) */
  .hero-photo { --lift: clamp(0px, var(--w) * .3486 - 114px, 140px); }   /* the photo lifted so the phone's screen is 56 px under the words' foot, the buttons (the founder, 13 Oct: "In the mobile view, lets move the photo up so the phone is closer to the "Book a call" button", then "its a bit too high now in the mobile view, find an in-between": 32 px for an hour, under the buttons once the line under them went, 133 before the lift): the screen's top 78.7 % of the photo's width down it (1404 of 1784 px), so 34.86 % of --w under the hair's line plus the 58 px above it; 77 px at 390 px wide, 62 at 360, 43 at 320, 97 at 430, at most 140 */
  .hero-photo { --drop: 20px; }   /* the "Integrates with" strip 20 px lower on a phone (the founder, 2 Nov: "position this (see attached) slightly lower on the web page"): the room under the words 20 px more, and the photo, its tint and blur kept where they were by it, more of the teacher's hand showing above the strip; the tabs and the foot's fade go down with the strip */
  .hero-photo { --rise: 10px; }   /* the buttons' row 10 px higher on a phone, and the room under the words 10 px more, so the tint and blur, the photo, the tabs and the strip keep their places (the founder, 2 Nov: "in mobile view, position this higher but keep the blur/tint where it is") */
  .hero-photo > .wrap { padding-bottom: calc(var(--w) * var(--hair) - 58px - var(--lift) + var(--drop) + var(--rise)); }   /* the top of the teacher's hair 16 px above the buttons' row (42 px tall) before the lift and the line under the buttons, the schools' strip 1030 px of the photo under it */
  .hero-photo .hero-copy { max-width: none; }
  .hero-photo .actions { margin-top: calc(22px - var(--rise)); }   /* 12 px under the saving (--rise, above); the buttons' row 8 px higher on a phone (the founder, 2 Nov: "in mobile view, reduce the size of "book a call" and "see the numbers" and move that row upwards slightly"; 30 px under the saving until then); the photo, the tabs and the tint keep their places from its foot */
  .hero-photo .actions .btn { height: 38px; padding: 0 16px; font-size: 14px; }   /* "Book a call" a size smaller on a phone, 38 px tall, its words 14 px (42 and 15 until then) */
  .hero-photo .actions .link { font-size: 14px; }   /* "See the numbers" too (15 until then) */
  .hero-photo .actions .btn::after, .hero-photo .actions .link::after { font-size: 17px; }   /* their arrows in step (19 until then) */
  .hero-photo h1 { font-size: min(60.8px, (100cqw - 2 * var(--gutter)) / 8.37); max-width: none; }   /* the words' block 95 % of the column's width on a phone (the founder, 2 Nov: "shrink this text to 75% of its current width for mobile only", then "lets do 85% actually", "Maybe 90% is better" and "maybe 95% is better"; the whole width since the founder's "make this occupy the full width of the mobile view", 14 Oct): its widest lines, "empty classrooms.", the line above the saving and the saving, are 7.85 to 7.91 em of the headline, so the headline is the column over 8.37, 7.95 over .95; 40.9 px at 390 px wide, 45.6 at 430, 32.5 at 320, at most 60.8 (the column over 7.95, at most 64, until 2 Nov, over 10.6, 9.35 and 8.83 for a few minutes; 40, the headings' least, before 14 Oct, 10.5vw under 381 px) */
  .hero-photo .hero-bg { left: calc((100cqw - var(--w)) * var(--cx)); bottom: calc(var(--strip) - var(--w) * var(--cut) + var(--drop)); width: var(--w); height: auto;   /* cropped round the phone, its middle where it is in the photo, 41.84 % across; 1700 px down it, 42 px of the photo under the phone's foot (the hand), at the strip's top, the rest under the strip */
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 94%, transparent); mask-image: linear-gradient(180deg, transparent, #000 12%, #000 94%, transparent); }   /* faded in at its top and out at its foot */
  .hero-photo .band::after { background: linear-gradient(180deg, rgba(31, 7, 88, .66), rgba(31, 7, 88, .6) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) - 60px + var(--lift)), rgba(31, 7, 88, .6) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) - 15px + var(--lift)), rgba(31, 7, 88, .55) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 22px + var(--lift)), rgba(31, 7, 88, .4) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 40px + var(--lift)), rgba(31, 7, 88, .25) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 57px + var(--lift)), rgba(31, 7, 88, .1) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 74px + var(--lift)), rgba(31, 7, 88, 0) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 92px + var(--lift))); }   /* the shading where it was against the words, the lift added back, so the photo's top, lifted behind them, stays under it; .7 to .55 behind the buttons (the words' foot: + 58 px) and feathered out over 70 px, 24 px lower since the founder's "lower the the end of the blur/tint in mobile view" (2 Nov): from .55 at 36 px above the buttons' foot to clear 34 px under it, a quarter (.25) at the foot, eased (the founder, 2 Nov: "can we make the feather more gradual/bigger?", "in mobile view only"; centred on the row's middle until then; clear at the row's middle in 12 px after "In the mobile view, lower the end of the blur/tint to the middle of the "see the numbers" row"; at the row's top after "Raise the blur/tint above the "Book a call" row in the mobile view", 12 px under it after "can we reposition the end of the fade/tint upwards slightly in mobile view", 28 before), just above the phone's screen, since the line under the buttons went (13 Oct): with the photo lifted, the whiteboard lay behind "See the numbers" at .5 to .45, 3.8:1, and it was 5.7:1 or more then. Lighter since the founder's "can we increase the transparency of the purple face a bit?" and "make it more transparent" (1 Nov; .88, .8, .7 and .55 until then): .66 and .6 behind the words, a quarter lighter, and .6 to .5 behind the buttons, so "See the numbers" keeps 4.5:1 (5:1 or more from 360 to 430 px wide with the darker purple) and "empty" 3.5:1 or more, averaged over 6 px */
  .hero-photo .hero-blur { -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 22px + var(--lift)), rgba(0, 0, 0, .5) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 57px + var(--lift)), transparent calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 92px + var(--lift))); mask-image: linear-gradient(180deg, #000 calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 22px + var(--lift)), rgba(0, 0, 0, .5) calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 57px + var(--lift)), transparent calc(100% - var(--strip) - var(--drop) - var(--w) * var(--hair) + 92px + var(--lift))); }   /* full behind the words, feathered out as the fade, half at the buttons' foot and gone 34 px under it (half at the row's middle, gone 10 px under it, for a few minutes) (gone at the row's middle, at its top, then 12 and 28 px under the buttons, before) */
}
/* the third version, photo-hero-empty.html, on the founder's photo of the same teacher in an empty classroom (the
   founder, 13 Oct: "Create another version with this photo instead"; assets/img/hero-classroom-empty-tall.webp, 1784 x
   2000, and -wide.webp, 2464 x 2000, 680 px added at its left; shown as its green copy, -green-tall.webp and
   -green-wide.webp, the room tinted for eco mode, the same in every measure), laid out as the first photo, above, from its own
   measures: the phone's left edge 661 px across the photo (1341 of the wide one's 2464) and its foot 1766 px down, her
   ear's top 1175 px down, so her ear to the phone's foot 1165 to 1798 px down (633 px, its middle 74.08 % down); her
   ear and neck to 1500 px across (839 px past the phone's edge), the photo's right edge 1123 px past it, and from about 1970
   px wide its right edge on the screen's, the phone further right. Up to 767 px the phone's middle 44.73 % across, the
   photo 140.45 % of the screen's width (1500 px across it at the screen's right edge), cut 1808 px down (42 px under the
   phone's foot, above her cuff), and the top of her hair, where the screen shows it, 782 px down */
.hero-photo.hero-empty { --tx: -54.42%; --ty: -74.08%; --kv: 3.1596; --kh: 2.3838; --ke: 1.7809; --w: 140.45cqw; --cx: .4473; --cut: .1076; --hair: .5751; }
.hero-photo.hero-empty .band::before { background: linear-gradient(rgba(31, 7, 88, .7), rgba(31, 7, 88, .36) calc(var(--nav) + env(safe-area-inset-top, 0px) + 6px), rgba(31, 7, 88, 0)); }   /* the fade under the clear bar a little darker than the first photo's: this room's walls and whiteboard are lighter behind its links */
.hero-photo .hero-foot { position: absolute; left: 0; right: 0; bottom: calc(var(--strip) - 60px); z-index: 1; height: calc(var(--nav) + env(safe-area-inset-top, 0px) + 86px); pointer-events: none;   /* the fade under the bar mirrored at the picture's foot, rising from the strip's top (the founder, 2 Nov: "can we add it to the bottom of the hero image window as well? here (see attached). Mirror it exactly"): the same height and shades, upside down, under the tabs and over every picture; on a phone too (the founder: "Add on phones too"; a computer's only for a few minutes), where the photo under the buttons is about as tall as the fade. 60 px lower, its darkest part under the strip (the founder: "lower the new bottom fade"; at the strip's top for a few minutes), so above the strip it rises 120 px from about half strength, .5 */
  background: linear-gradient(0deg, rgba(31, 7, 88, .62), rgba(31, 7, 88, .28) calc(var(--nav) + env(safe-area-inset-top, 0px) + 6px), rgba(31, 7, 88, 0)); }
.hero-photo.hero-empty .hero-foot { background: linear-gradient(0deg, rgba(31, 7, 88, .7), rgba(31, 7, 88, .36) calc(var(--nav) + env(safe-area-inset-top, 0px) + 6px), rgba(31, 7, 88, 0)); }
/* the partner schools along the hero's foot, a solid band of a very light purple, the brand's own (--accent-soft), its words
   in the brand purple (the founder, 2 Nov: "turn the background into a very light purple"; the brand purple, its words white,
   since the founder's "make this part a solid section (no fade) and make it the brand purple", 13 Oct; over the photo, its
   ground darkened from 56 px above, until then),
   the photo ending at its top (the founder, 13 Oct: "lets expand the height of the
   hero-section photo and add an auto-scrolling list which shows our partnered schools (use placeholders for now)"): its
   label "Our customers" at the left, beside the row, since the founder's "move "Our customers" to the left, inline with the
   list of customers" (13 Oct; centred above the row since the founder's "Move "Our partner schools" to the centre and
   rename it to "Our customers"", 13 Oct, and "Our partner schools" at the left above it until then), on two lines on a
   phone so the row beside it shows more; the schools in one row moving on their own, right to left, faded at both ends (6 %, 24 px at least, so on a phone they fade before the label), as the systems Sinc works
   with were under the hero until the founder's "lets get rid of this section" (12 Oct). The schools twice, the second copy
   hidden from screen readers; each copy at least the strip's width, the schools spread across it, so the loop is seamless,
   about 30 px a second (22 s round the three logos and "And more…", about 655 px with the room after it, on a phone and on a computer, whose row is narrower than that since its ends' room was tripled; 17 s round the logos alone; 27 and 34 s round a computer's wider row before; 56 s round eight placeholder schools until 2 Nov).
   Still under the pointer; with reduced motion the first copy alone, still, scrolled by hand. The logos of the systems Sinc
   works with, Bromcom, Arbor and SIMS (the founder, 2 Nov: "add these to the "Works with" carosel instead of the 'Parnter
   school' placeholders"; a placeholder crest and name each until then) */
.hero-photo .schools { position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: center; height: var(--strip); background: var(--accent-soft); margin-top: clamp(36px, 3.4vw, 48px); }   /* 96 px tall, 48 under the buttons, 36 on a narrower computer (since the founder's "even more space", 13 Oct; 32 and 24 for an hour before, and 16 until the founder's "lets add a bit more space between the "Book a call" button and the "Our customers" row", 13 Oct; 124 and 48 until the founder's "can we reduce the overall height of the hero section by reducing empty space/padding (like between the "Book a call" row and the "Our customers" row)?", 13 Oct; 112 tall on a phone) */
.hero-photo .schools .wrap { width: 100%; }
.schools .works { display: flex; align-items: center; gap: clamp(20px, 3vw, 40px); }   /* the label at the left, the row beside it; on a phone the label above the row at its left (below; the founder, 2 Nov: "in mobile view, have "works with" above the carousel"; beside it for an hour after "in mobile, have "Works with" in line with the academies", "Works" over "With" after "in mobile, put "Works" over "With"."; above the row at its left for an hour before that, after "move "customers" to the left and change it to "Works with" for both desktop and mobile", and centred above it since the founder's "For the mobile view, move "Customers" to the top of the bar and centre it", 14 Oct) */
@media (max-width: 767px) { .hero-photo .schools { margin-top: 0; } }   /* on a phone the photo under the phone between the words and the strip: after the rule above, so it holds (before it on 13 Oct, so the strip kept that rule's 24 to 31 px and the teacher's hair lay 8 px under the top of the buttons' row instead of 16 px above it) */
.schools-label { flex: none; font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; color: rgba(79, 18, 203, .8); }   /* the brand purple at .8, 5.3:1 on the light purple, quieter than the schools (white at .72 on the brand purple until 2 Nov, 5:1; .62 was 4.3:1, too faint once the strip turned solid) */
.schools-label .ic { display: inline-block; width: 16px; height: 16px; margin-right: 8px; vertical-align: -3px; fill: currentColor; }   /* Phosphor's puzzle-piece, Bold, before "Integrates with" ("Works with" until the founder's "change "Works with" to "Integrates with""), in its purple (the founder, 2 Nov: "add an icon to left of "works with"", then "what about a puzzel peice"; plugs-connected for a few minutes): Sinc fitting in with the systems schools use; hidden from screen readers, so the list's name is the label's words */
@media (max-width: 767px) { .schools .works { flex-direction: column; align-items: stretch; gap: 10px; } .hero-photo .schools .schools-label { text-align: center; } }   /* on a phone the label on one line above the row, centred (the founder, 2 Nov: "centre "works with" in mobile view"; at its left, in line with the words above, for an hour), the row the strip's whole width (above) */
.schools .marquee { flex: 1; min-width: 0; display: flex; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 max(6%, 24px), #000 min(94%, 100% - 24px), transparent); mask-image: linear-gradient(90deg, transparent, #000 max(6%, 24px), #000 min(94%, 100% - 24px), transparent); }
@media (min-width: 768px) { .schools .works { margin-inline: clamp(54px, 18vw, 270px); } }   /* on a computer the label and the row in one invisible container (the founder, 2 Nov: "have these in one container", then "I meant an invisible container"; a white pill for a few minutes), the room at both ends its margins: 18vw, 54 to 270 px, since the founder's "make the container slightly shorter in with" (16vw after "make this container wider", 24vw before) ("And more" after the row for a few minutes, the room less half its width; in the carousel since the founder's "i meant add it to the carrousel"). The row narrower, room at both ends, so the three logos sit closer (the founder, 2 Nov: "make the row narrower (add padding to the ends)", then "triple it", 24vw: 8vw, 24 to 120 px, for a few minutes): the label next to the row (the founder: "have "Works with" next to the MIS provider carosell"; at the strip's left, the room between them, until then), the two together in the middle; 214 px each end at 1190 px wide, at most 270 */
.schools .track { flex: none; display: flex; align-items: center; justify-content: space-around; gap: 56px; min-width: 100%; margin: 0; padding: 0 56px 0 0; list-style: none;
  font-size: 17px; font-weight: 600; letter-spacing: -.01em; color: var(--accent); white-space: nowrap; animation: schools 22s linear infinite; }
.schools .track li { display: flex; align-items: center; gap: 10px; }
.schools .track .more { margin-right: 28px; font-size: 13px; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; color: rgba(79, 18, 203, .8); }   /* "And more…" after the logos, as the label "Integrates with" looks (the founder, 2 Nov: "add "AND MORE"", then "i meant add it to the carrousel" and ""And more" to "And more...""), but lighter, 400 to the label's 600 (the founder: "make "and more..." a thinner font relative to "works with""); 84 px from it to Bromcom as the loop comes round, half as much again as the 56 between the logos (the founder: "add a bit more space between "and more..." and "Bromcom"") */
.schools .track img { display: block; }   /* each logo at its own height, so the three look alike in size (index.html: Bromcom 22 px, Arbor 32 with its circles, SIMS 20) */
.schools .marquee:hover .track { animation-play-state: paused; }
@keyframes schools { to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  .schools .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .schools .track { animation: none; }
  .schools .track[aria-hidden] { display: none; }
}

/* ---------- sections ---------- */
.section { position: relative; padding: clamp(72px, 9vw, 120px) 0; }
.section.tint { background: var(--bg-2); }
.section-head { max-width: 720px; }
.section-head .lead { margin-top: 16px; }
.section-head .link { margin-top: 18px; }
/* three cards (Linear's, in the light) */
.cards3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 44px; }
.card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius-lg); background: #fff; box-shadow: var(--shadow-card); overflow: hidden; transition: transform .2s var(--ease), box-shadow .2s; }
.card:hover { transform: translateY(-3px); box-shadow: 0 2px 4px rgba(26, 21, 48, .05), 0 24px 48px -18px rgba(26, 21, 48, .28); }
.card .art { position: relative; height: 230px; overflow: hidden; background: var(--bg-2); border-bottom: 1px solid var(--line); }
.card .art img { width: 100%; height: 100%; object-fit: cover; object-position: top left; }
.card .art::after { content: ""; position: absolute; inset: 0; background: linear-gradient(transparent 65%, rgba(255, 255, 255, .9)); }
.card .body { padding: 22px 24px 26px; }
.card .body p { margin-top: 8px; font-size: 15px; line-height: 1.55; color: var(--text-2); }
@media (max-width: 767px) { .cards3 { grid-template-columns: 1fr; } }

/* photo cards (.pcards), one design for two sections (the founder, 29 Sep): each card a picture, a green circle over its foot
   with a white Phosphor icon, a title, a purple label and the text. The pictures run to the card's line, no white fade over
   their foot.
   How Sinc saves (three problems first, then "Rather than first highlighting the problems, lets highlight their direct
   solutions"): optimise pre-heating, eco when vacant, off when closed, on the founder's photographs (sunrise over a school, an
   empty classroom with pupils passing outside, a calendar's weekends crossed out; drawn pictures with a key until then).
   Why Sinc Energy? ("Duplicate this section but it the title of 'Why Sinc Energy?'"), in place of "Why Sinc Energy is perfect
   for schools" and its pictures drawn in the console's look: MIS synchronisation, independent network, use existing accounts,
   on placeholders (Wonde, a cellular hub, Sign in with Microsoft or Google) until the founder's pictures came (the
   last, the valve and the gateway, 30 Sep). */
/* the two sections' heads, centred over their cards with no eyebrow (the founder, 30 Sep: "Lets improve these headers.
   Center them at the top of their respective sections. Remove the small text ("How Sinc saves" and "Made for
   schools")"): the headline a step larger than the page's other sections', its lines balanced, and the lead in even lines
   under it, no wider than two */
.section.pcards { padding-top: clamp(44px, 4.5vw, 64px); }   /* the heads nearer their sections' tops (the founder, 30 Sep: "The headers are very far from the top of their respective sections"; the page's 72 to 120 px until then), about as far below the top as the cards are below them */
/* a way on at the foot of each photo-card section (the founder, 30 Sep: "Add an arrow to at the bottom of the sections that
   directs the viewer the section below it. Put the arrow in a circle and add a drop-shaddow"; a white circle under the
   cards with Phosphor's arrow-down until "Have the arrow overlap the section below it. Have the arrow also match the
   colour of the section its on. Change the arrow symbol to a simpler arrow", the same day): Phosphor's caret-circle-down,
   its circle the tab itself, in the section's own colour, a third of it over the section below (half until "Move them up
   slightly so two-thirds of the height is located in the upper section"), as if the section reached into it, shadowed; its caret in the colour that reads on it (white on the purple, the purple on the tint), drawn apart from
   the circle rather than cut out of it, which would show the two sections behind it. Room under the cards for its top
   two-thirds, and over the next photo-card section's head for its foot, so both keep their gaps (the school console, below the
   second, keeps its photo to the top and its title clear, .room-title) */
:root { --tab: clamp(64px, 5.8vw, 84px); }   /* larger since "Make them bigger as well" (30 Sep; 52 to 64 px until then) */
.section.pcards { padding-bottom: calc(var(--tab) * 2 / 3 + clamp(28px, 3vw, 40px)); }
.section.pcards + .section.pcards { padding-top: calc(clamp(44px, 4.5vw, 64px) + var(--tab) / 3); }
.to-next { position: absolute; left: calc(50% - var(--tab) / 2); bottom: calc(var(--tab) / -3); z-index: 6; width: var(--tab); height: var(--tab); border-radius: 50%;
  box-shadow: 0 2px 4px rgba(10, 0, 40, .12), 0 14px 28px -10px rgba(10, 0, 40, .55); }
.to-next:focus-visible { border-radius: 50%; }   /* round, not the page's 6 px focus corners */
.to-next svg { display: block; width: 100%; height: 100%; fill: currentColor; transition: transform .2s var(--ease); }
.to-next:hover svg, .to-next:focus-visible svg { transform: translateY(3px); }   /* nudged the way it points */
.purple .to-next { background: var(--accent); color: #fff; }
.tint .to-next { background: var(--bg-2); color: var(--accent); }
.section.pcards:has(.to-next) + .section.room .room-title { padding-top: max(clamp(18px, 3.2vh, 32px), calc(var(--tab) / 3 + 12px)); }   /* the school console's title clear of the tab over its top, while there is one (Seamless' went with the founder's "remove the arrow", 3 Nov) (12 px under it; a band of the console's dark over the photo's top instead left a seam), a little lower the whole tour through; hybrid.js sets the laptop under it as ever */
/* the schools that use Sinc, after How Sinc saves (the founder, 2 Nov: "Replace the first down arrow with a section like this
   (see attached) that shows a carossel of schools that use Sinc Energy (use placeholder names for now)", after a strip of
   companies' grey logos on white): a small heading centred over the crests and names, larger than it as the brands were, scrolling as the hero's strip does,
   the row's ends fading out, in the page's quieter grey, on the tint as the sections either side of it are (the founder, 2 Nov: "I don't like that the background is different"; white for a few minutes), that tint painted under the section above (::before), so How Sinc saves' cards' shadows reaching over it are drawn on it rather than cut off in a line (the founder: "its still not seamless"). How Sinc saves' arrow went with it: a photo-card section with no
   arrow ends as far under its cards as the arrow's top was (28 to 40 px), and the next one's head is set from its own top
   (hybrid.js). The space over the schools' heading and under their row about 88 px on a computer and 64 on a phone (the
   founder, 2 Nov: "reduce the space above and below this for bot desktop and mobile", then "you reduced the space too
   much": 64 and 48 for a few minutes; 114 and 117 on a computer, 79 and 80 on a phone, until then) */
.section.pcards:not(:has(.to-next)) { padding-bottom: clamp(28px, 3vw, 40px); }
@media (max-width: 767px) { #saving.stacked { padding-top: 0; } }   /* on a phone its heading as near its top as while its arrow set that (hybrid.js made the space over its letters the space over the arrow, which came to none); Seamless', whose arrow went on 3 Nov, where its arrow set it (hybrid.js, from the section's foot) */
.section.used-by { padding: clamp(25px, 2.7vw, 39px) 0 clamp(28px, 3.05vw, 44px); }
.used-by::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bg-2); }
.used-by h2 { font-size: clamp(18px, 1.6vw, 22px); font-weight: 500; letter-spacing: -.01em; text-align: center; }
.used-by .marquee { display: flex; overflow: hidden; width: var(--row); max-width: 100%; margin: clamp(24px, 3vw, 36px) auto 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent); mask-image: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent); }
.used-by .track { flex: none; display: flex; align-items: center; justify-content: space-around; gap: clamp(40px, 5vw, 72px); min-width: 100%; margin: 0; padding: 0 clamp(40px, 5vw, 72px) 0 0; list-style: none;
  font-size: clamp(17px, 1.7vw, 24px); font-weight: 700; letter-spacing: -.01em; color: var(--text-2); white-space: nowrap; animation: schools 80s linear infinite; }
.used-by .track li { display: flex; align-items: center; gap: .5em; }
.used-by .em { flex: none; width: 1.65em; height: 1.65em; fill: currentColor; }   /* the crests as large beside the names as the brands' marks are beside their words */
@media (min-width: 768px) { .used-by .marquee { width: calc(var(--row) * 1.5); } }   /* as wide as the hero strip's "Integrates with" row (--row, hybrid.js; the founder, 2 Nov: "lets shorten it so it matches the width of the 'integrates with' carousel"), half as wide again on a computer ("make it 50% bigger (for desktop)"); the page's width until then */
@media (max-width: 999px) { .used-by .track { animation-duration: 52s; } }   /* about 30 px a second, as on a computer, where the names are smaller */
.used-by .marquee:hover .track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .used-by .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .used-by .track { animation: none; }
  .used-by .track[aria-hidden] { display: none; }
}
.pcards .section-head { max-width: 880px; margin-inline: auto; text-align: center; }
.pcards .section-head h2 { font-size: clamp(32px, 4.6vw, 54px); letter-spacing: -.03em; }
.pcards .cards3 { margin-top: clamp(40px, 5vw, 56px); }
/* the titles and their labels larger (the founder, 29 Sep: "Increase the size of these texts", then "Make them bigger again";
   18 and 13.5 px, then 22 and 15): 28 and 18 px, less only where a card's text is too narrow to keep them on one line
   (its width is (the page's, up to 1,200 px, - 232) / 3 with three cards, the page's - 96 with one) */
.pcards .card .body h3 { font-size: clamp(22px, calc((min(100vw, 1200px) - 232px) / 31), 28px); letter-spacing: -.03em; }
.pcards .when { display: block; margin-top: 0; font-size: clamp(15px, calc((min(100vw, 1200px) - 232px) / 46), 18px); font-weight: 600; line-height: 1.3; color: var(--accent); }   /* under the title (the founder, 29 Sep; above it until then), right under it (the founder, 3 Nov: "reduce the spacing between the heading (black) and sub heading (purple). Keep the heading (black) where it is"; 8 px under it with the text's 1.6 line until then); the brand purple (a light lime while the cinematic cards were navy, 8 Oct) */
@media (max-width: 767px) {
  .pcards .card .body h3 { font-size: clamp(22px, calc((100vw - 96px) / 10.4), 28px); }
  .pcards .when { font-size: clamp(15px, calc((100vw - 96px) / 15.5), 18px); }
}
/* the photo cards cinematic since 8 Oct (the founder: "i love the cinematic version", the second of three new directions
   on the design canvas of card designs, then "Implement the cinematic version"): the picture runs to the card's edges at
   its top and ends in a straight line falling a little from left to right (the founder, the same day: "i dont like the
   fade anymore, just do a simple line that is at a slight angle", drawn from under the icon to a little lower at the
   right), the icon a smaller green ball centred on the line, the words below in ink, the label the brand purple; a faint
   line round the card. The picture's box 300 px tall, less on a narrow card so it keeps 1.15 to 1 (the calendar's five
   days whole), each picture fitted to it (the founder: "ensure the height of the images is dictated by the top of the card
   and the start of the fade", while it ended in a fade: 254 px clear and a 56 then 72 px fade, the icon just above it,
   then in it, "The icons are too high up, they should be within the fade"). On the
   way, the same day: the picture the whole card, the words over its foot on a long fade that began above the icons, first
   navy (the page's deep purple, the words white, the label lime), then white ("switch the card background colour from
   dark navy to white"), frosted as it went. Until then each card was white, its picture set in its white at its top (1 Oct:
   "Lets keep the original, but give the images this kind of boarder"), the picture's foot under a purple shadow (29 Sep:
   "the drop-shaddow should be OVER the images"; a curve from 30 Sep to 8 Oct, "remove the curved bottom-edge of the
   pictures"), the icon a 64 px green circle over it */
.pcards .card { position: relative; container-type: inline-size; border: 0; border-radius: 26px; background: #fff; color: var(--ink);
  box-shadow: 0 2px 4px rgba(16, 0, 48, .1), 0 28px 56px -28px rgba(16, 0, 48, .5); }
.pcards .card:hover { box-shadow: 0 2px 4px rgba(16, 0, 48, .1), 0 36px 64px -28px rgba(16, 0, 48, .55); }
.pcards .card::after { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(16, 0, 48, .08); pointer-events: none; }
.pcards .card .art { flex: none; height: min(300px, 87cqw); border-bottom: 0; background: #fff;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 calc(100% - 11cqw)); }   /* its foot a straight line falling 11 % of the card's width from left to right, about 6°, the same at every width */
.pcards .card .art::after { content: none; }
.pcards .card .art img { transition: transform .6s var(--ease); }
.pcards .card:hover .art:not(.signin) img { transform: scale(1.04); }   /* the picture leans in a little under the pointer */
@media (prefers-reduced-motion: reduce) { .pcards .card:hover .art:not(.signin) img { transform: none; } }
.pcards .card .body { position: relative; margin-top: calc(46px - 11cqw); padding: 0 clamp(22px, 2.2vw, 28px) 30px; }   /* the title 8 px under the icon, however steep the line's fall over the card's width (the founder, 3 Nov: "move the titles and sub titles closer to icon"; 20 px until then, 49 px for the 48 px icon before that) */
.pcards .card .pc-ic { top: -72px; }   /* the icon where it was on the picture's sloping foot, the body under it 12 px higher (.pc-ic's 84 px over it for the rest) */
.card .pc-photo img { object-position: 50% 50%; }
.card .pc-photo.cal img { object-position: 50% 0%; }   /* the calendar from Wednesday to Sunday (the founder, 30 Sep: "crop closer to 'SAT' and 'SUN'", then "Its cropped a bit too much, ensure 'WED' and 'THU' columns are also visible"; the whole month, then Friday to Sunday, until then), cut from the founder's original at its whole height: narrower than any card (1.15 to 1, the narrowest card 1.17), so every card shows all five days, and a wider one trims the foot, held at the top so the day heads stay whole. In the cinematic card (8 Oct) the picture's box stays 1.15 to 1 or wider for it, so the five days stay whole (laid across the top of a card taller than it is wide, and the Wonde badge with it, while the picture filled the card the same day) */
/* a pill over two of the pictures, what Sinc changes there (the founder, 30 Sep): over the empty classroom its heating going
   down to eco in a free period ("Add an appropriate overlay to the image (not the whole card) that shows '21 Degrees C to 16
   Degrees C'"), the lesson's 21°C to eco's 16°C; over the sunrise the morning's start ("Add something similar to this
   card"), a timer's 05:00 to Sinc's 06:15 ("Change 7:45 to 6:15"; 07:45, a mild morning in the drawn two mornings here
   before, until then), the timer's struck through so the two don't read as a span of time. White, at the picture's top right,
   the corner opposite the icon: the before in ink (grey when struck), Phosphor's bold arrow in grey and Sinc's white in a
   capsule of the icon's green, as the teacher page's Eco tag. The green a shade deeper than the icon's (#44b25b, 2.7 to 1
   under white), and the words at least 19 px bold, so they read as large text (3.2 to 1).
   Larger since "Increase the size of these" (30 Sep; 19 px until then): its words 7 % of the picture's width (cqw), 20 to
   26 px, and the rest in em, so it keeps its shape and share of a narrow card's picture. Frosted since the cinematic cards
   (8 Oct): white at 86 % over a blur of the picture, a hairline of light round it, the after's green deeper at its foot with
   a lit top edge (white on it 3.9 to 1 at its top, 4.9 at its foot), its words 6 % of the card's width, 20 to 22 px. The
   before in orange since the founder's "can we put 05:00 and 21 degrees C in red?" and then "maybe orange actually" (8 Oct;
   red, #dc2626, a moment; grey when struck and ink until then): the timer's 05:00 and its strike, and the lesson's 21°C,
   against the after's green, bold so the orange reads as large text (3.6 to 1 on white, 3 needed) */
.card .pc-photo { container-type: inline-size; }
.pc-pill { position: absolute; right: .7em; top: .7em; z-index: 1; display: flex; align-items: center; gap: .41em; box-sizing: border-box; height: 2.1em; padding: 0 .23em 0 .73em;
  border: 1px solid rgba(255, 255, 255, .95); border-radius: 999px; background: rgba(255, 255, 255, .86); -webkit-backdrop-filter: blur(14px) saturate(1.6); backdrop-filter: blur(14px) saturate(1.6);
  color: #15102b; box-shadow: 0 1px 2px rgba(16, 0, 48, .16), 0 14px 28px -12px rgba(16, 0, 48, .55);
  font-size: clamp(20px, 6cqw, 22px); font-weight: 650; line-height: 1; letter-spacing: -.015em; font-variant-numeric: tabular-nums; white-space: nowrap; transform-origin: 100% 50%; }
.pc-pill s { position: relative; color: #ea580c; font-weight: 700; text-decoration: none; }   /* struck by a line of its own, so it can be drawn */
.pc-pill > span { color: #ea580c; font-weight: 700; }
.pc-pill s::after { content: ""; position: absolute; left: -.06em; right: -.06em; top: 50%; height: .1em; margin-top: -.06em; border-radius: .05em; background: currentColor; transform-origin: 0 50%; }
.pc-pill svg { flex: none; width: .77em; height: .77em; fill: #9a94b2; }
.pc-pill b { display: grid; place-items: center; height: 1.64em; padding: 0 .6em; border-radius: 999px; background: linear-gradient(#34924c, #2b8040); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 2px 6px -2px rgba(20, 90, 40, .6); color: #fff; font-weight: 700; }
/* and played after its card comes in (the founder, 30 Sep: "animate them with respect to their card's reveal (maybe have a 1
   second delay or something like that)"): a second after the card starts to rise (--rd, its place in the row, hybrid.js),
   the pill rises into view with the before; the arrow slides in; the timer's 05:00 turns orange as a line strikes it through; and
   Sinc's figure pops up in its green. Animations, not transitions, so a card gone back (scrolled back up past) drops them at
   once and plays them again when it next comes in; with reduced motion, or no script, the pill is simply there. Each animation
   sets only where it starts, held through its delay (backwards) but not once it ends, where the pill's own style is the
   same: held at the end (both, until 1 Oct), the pill stayed on a layer of its own (which, beside the picture's mask while
   the foot was a curve, took the card's text onto one too, drawn less sharply) */
@keyframes pill-in { from { opacity: 0; transform: translateY(.5em) scale(.9); } }
@keyframes pill-arrow { from { opacity: 0; transform: translateX(-.5em); } }
@keyframes pill-old { from { color: var(--ink); } }
@keyframes pill-strike { from { transform: scaleX(0); } }
@keyframes pill-new { from { opacity: 0; transform: scale(.4); } }
.js .card.in .pc-pill { --pd: calc(var(--rd, 0ms) + 1s); animation: pill-in .55s cubic-bezier(.3, 1.35, .6, 1) var(--pd) backwards; }
.js .card.in .pc-pill svg { animation: pill-arrow .4s var(--ease) calc(var(--pd) + .3s) backwards; }
.js .card.in .pc-pill s { animation: pill-old .35s linear calc(var(--pd) + .5s) backwards; }
.js .card.in .pc-pill s::after { animation: pill-strike .35s var(--ease) calc(var(--pd) + .5s) backwards; }
.js .card.in .pc-pill b { animation: pill-new .5s cubic-bezier(.3, 1.6, .6, 1) calc(var(--pd) + .7s) backwards; }
@media (prefers-reduced-motion: reduce) {
  .js .card.in .pc-pill, .js .card.in .pc-pill svg, .js .card.in .pc-pill s, .js .card.in .pc-pill s::after, .js .card.in .pc-pill b { animation: none; }
}
.card .pc-photo.signin { background: radial-gradient(120% 90% at 50% 0%, #6a2ef0, #4f12cb 46%, #2c0a85); }   /* the founder's screenshot of the sign-in page (29 Sep): Welcome back! to the Google button. In the cinematic card (8 Oct) it floats near the top on the brand purple, lit from above: a white card of its own, its corners rounded and a shadow under it, tilted 3° clockwise as since the founder's "zoom in a little bit and also tilt it clockwise a little bit" (30 Sep). Until then whole on white, its own ground, at 110 %, then 97 % for the curved foot, moved up 12 px so Sign in with Google showed whole */
.card .pc-photo.signin img { position: absolute; left: 12%; top: 16px; width: 76%; height: auto; object-fit: fill; transform: rotate(3deg); transform-origin: 50% 0; border-radius: 12px; box-shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 24px 44px -18px rgba(0, 0, 0, .7); }
/* Why Sinc Energy? on the brand purple (the founder, 29 Sep): its heading white, the eyebrow lime as on the dark band, the
   cards white with their own ink */
.section.purple { background: var(--accent); color: #fff; }
.purple .section-head h2 { font-weight: 400; }   /* the heading's own words, "your" and "use", in Urbanist Regular (the founder, 30 Sep: "Use Urbanist-Regular for 'your' and 'use'"; the page's 700 until then) */
.purple h2 .wm { font-weight: 900; font-style: italic; }   /* the brand's words as its wordmark (the founder, 30 Sep: "make 'Sinc Energy' in lowercase, use the brand colours ('sinc' in white, and 'energy' in green). And use Urbanist Black Italic for the font"): Urbanist at 900, italic, as the logo's, sinc white and energy the logo's lime, on the purple; the heading's other words in its own letters. "Why sinc energy?" until "Change this to 'sinc your energy use' or 'sinc your energy consumption' (whichever is more appropriate). Keep the words 'sinc' and 'energy' in the brand font and colours" (30 Sep): use, shorter and plainer, on one line on a phone */
.purple h2 .wm.en { color: var(--lime); }
/* Independent network's picture, two of the founder's photos side by side (30 Sep: "use these two images instead of the
   placeholder image ... Feel free to crop and combine them as necessary"; a placeholder, "Cellular hub", until then): a
   valve on a classroom radiator, its display facing across to the gateway on a corridor wall, each cropped close at 4:5
   and cut again by its half as the card narrows, the valve held to its right so its face stays whole; a thin line between
   them, white (dark while the cinematic cards were navy, 8 Oct). In the cinematic card each fills its half of the
   picture's box, the gateway's disc above the fade (laid whole across the top while the picture filled the card, 8 Oct:
   cut to the card's height, the photos were drawn so large that the disc fell under the words) */
.card .pc-photo.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; background: #fff; }
.card .pc-photo.duo img { min-width: 0; }
.card .pc-photo.duo img:first-child { object-position: 65% 50%; }
.pcards .when + p { margin-top: 17px; }   /* the text further from the label above it (the founder, 29 Sep; 8 px until then, 18 until the cinematic cards, 8 Oct), as far from its words as before their line closed up (14 px until 3 Nov) */
.pcards .card .body p { color: var(--text-2); line-height: 1.6; text-wrap: pretty; }
/* a small diagram under each of How Sinc saves' cards' text (the founder, 3 Nov: "add some sort diagram or illustration at the
   bottom of these cards", then "Can we improve the design to make it look more professional or premium?"): each with its name
   and a legend over it, drawn in the page in its typeface and colours: a cold morning's warm-up from a
   fixed early start and from Sinc's later one, the heat between them hatched; a day's lessons at 21°C and its empty times at
   16°C; a school year's terms on and its half-terms and holidays off. Illustrations of how it works, not a school's data */
.pcards .pc-fig { margin: 20px 0 0; }   /* on the card itself, the width of its text (the founder, 3 Nov: "Can we remove the feint-purple containers"; in a softly tinted panel with a hairline edge until then) */
.pc-fig figcaption { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 10px; margin-bottom: 8px; font-size: 11.5px; font-weight: 600; line-height: 1.3; color: var(--text-3); }
.pc-fig .k { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-2); }
.pc-fig .lg { display: inline-flex; flex-wrap: wrap; align-items: center; }
.pc-fig .sw { display: inline-block; width: 12px; height: 3px; margin: 0 5px 0 10px; border-radius: 2px; }
.pc-fig .sw:first-child { margin-left: 0; }
.pc-fig .sw.green { background: #44b25b; }
.pc-fig .sw.purple { background: var(--accent-2); }
.pc-fig .sw.dash { height: 0; border-top: 2px dashed var(--text-3); border-radius: 0; }
.pc-fig .sw.track { height: 8px; border-radius: 3px; background: var(--line); }
.pc-fig > svg { display: block; width: 100%; height: auto; overflow: visible; }
.pc-fig text { font: 600 13px var(--font); fill: var(--text-3); font-variant-numeric: tabular-nums; }   /* about 12 px as drawn, 11 on a phone (the founder, 3 Nov: "Do both", of larger labels and a draw-in; 10.5, about 10 px drawn, until then) */
.pc-fig .g { fill: #2f8a43; }   /* the icons' green, a shade darker for words */
.pc-fig .p { fill: var(--accent); }
.pc-fig .w { font-size: 12px; fill: #5b35c9; paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round; }   /* over the hatching, haloed in the card's white, a size under the rest to sit between the lines */
.pc-fig .ax { stroke: var(--line-2); stroke-width: 1; }
.pc-fig .tg { stroke: #44b25b; stroke-opacity: .45; stroke-width: 1; stroke-dasharray: 2 3; }
.pc-fig .old { fill: none; stroke: var(--text-3); stroke-width: 1.75; stroke-dasharray: 4 3; stroke-linecap: round; }
.pc-fig :is(.new, .use) { fill: none; stroke: #44b25b; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.pc-fig .eco { fill: none; stroke: var(--accent-2); stroke-width: 3; stroke-linecap: round; }
.pc-fig .join { fill: none; stroke: var(--line-2); stroke-width: 1.5; }
.pc-fig .mk { stroke: var(--accent); stroke-opacity: .55; stroke-width: 1; stroke-dasharray: 2 3; }
.pc-fig .pt { fill: #44b25b; stroke: #fff; stroke-width: 2; }
.pc-fig .trk { fill: var(--line); }
.pc-fig .hk { stroke: var(--line-2); stroke-width: 1; }
/* and under the Seamless cards' text, as How Sinc saves' (the founder, 3 Nov: "Yes, add them"): how the gateway connects, the
   valves by radio and the gateway on its own 4G, the school's network not used; and the one sign-in, staff through their
   school's Microsoft or Google account (the marks as on the teacher page's buttons) straight into Sinc. Each node a white disc
   with a hairline edge, its Phosphor icon in the purple or the green */
.pc-fig .nd { fill: #fff; stroke: var(--line-2); stroke-width: 1; filter: drop-shadow(0 2px 4px rgba(40, 20, 120, .1)); }
.pc-fig .tile { fill: #fff; stroke: var(--line-2); stroke-width: 1; filter: drop-shadow(0 2px 4px rgba(40, 20, 120, .1)); }
.pc-fig .ip { fill: var(--accent); }
.pc-fig .ig { fill: #44b25b; }
.pc-fig .rl { stroke: var(--accent-2); stroke-width: 2; stroke-dasharray: 2 5; stroke-linecap: round; }   /* radio, in dots */
.pc-fig .cl { stroke: #44b25b; stroke-width: 3; stroke-linecap: round; }   /* its own 4G */
.pc-fig .fl { stroke: var(--line-2); stroke-width: 2; stroke-linecap: round; }
.pc-fig .li { display: inline-block; width: 13px; height: 13px; margin-right: 4px; vertical-align: -2px; fill: var(--text-3); }
.pc-fig .li.g { fill: #44b25b; }
/* each drawn in from left to right once its card is open and in view, as its morning, day and year run (hybrid.js: .drawn;
   the founder, 3 Nov): a soft edge sweeping across in about a second; with reduced motion, or without the script, drawn already */
@property --pf { syntax: "<percentage>"; inherits: false; initial-value: 112%; }
.js .pc-fig > svg { --pf: 0%; -webkit-mask-image: linear-gradient(90deg, #000 calc(var(--pf) - 12%), transparent var(--pf)); mask-image: linear-gradient(90deg, #000 calc(var(--pf) - 12%), transparent var(--pf)); transition: --pf 1.1s cubic-bezier(.4, 0, .2, 1) .15s; }
.js .pc-fig.drawn > svg { --pf: 112%; }
@media (prefers-reduced-motion: reduce) { .js .pc-fig > svg { --pf: 112%; -webkit-mask-image: none; mask-image: none; transition: none; } }
/* the MIS the console works with, scrolling under the MIS card's text as under the hero (the founder, 3 Nov: "add the
   "Bromcom, Arbor, Sims" carousel (the one below the hero section) to the bottom of this card"): the hero strip's logos a
   size smaller, about 30 px a second, the row as tall as the other cards' drawings (300 by 76; the Seamless cards' names and
   notes over them, "Works with" and "Via Wonde" here, gone since the founder's "get rid of these texts", 3 Nov), its ends fading; the card's subtitle names them for a screen reader, so the
   panel itself is hidden from one */
.mis-fig .marquee { display: flex; align-items: center; aspect-ratio: 300 / 76; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); }
.mis-fig .track { flex: none; display: flex; align-items: center; gap: 36px; min-width: 100%; margin: 0; padding: 0 36px 0 0; list-style: none; white-space: nowrap; animation: schools 17s linear infinite; }
.mis-fig .track li { display: flex; align-items: center; }
.mis-fig .track img { display: block; }
.mis-fig .and-more { font-size: 12px; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; color: rgba(79, 18, 203, .8); }   /* as the hero strip's "And more…" */
.mis-fig .marquee:hover .track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .mis-fig .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .mis-fig .track { animation: none; }
  .mis-fig .track + .track { display: none; }
}   /* never a word alone on the last line (the founder's shorter texts, 8 Oct: "lets make these texts more digestable") */
.pc-ic { position: absolute; left: clamp(22px, 2.2vw, 28px); top: -84px; display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%;   /* each card's icon: green, as the tours' step icons, its icon white in Phosphor's fill (the founder, 29 Sep); centred on the picture's sloping foot since the cinematic cards (8 Oct; in the middle of a fade, "The icons are too high up, they should be within the fade", and on the picture just above it, the same day), 64 px, the icon 34, since the founder's "now make them bigger" (12 Oct; 48 and 25 from the cinematic cards until then), flat since the founder's "I don't like the 3D look of these icons. Keep the drop shadow tho" (12 Oct; a ball lit from its top left until then, a radial gradient under an inner highlight); over the picture's foot until then, 64 px and the icon 34 after "increase the size of the icons" (52 and 26 before) */
  background: #44b25b; box-shadow: 0 8px 18px -8px rgba(20, 90, 40, .6); }   /* the tours' step green, flat, under the same drop shadow; no white ring (the founder, 29 Sep) */
.pc-ic svg { width: 34px; height: 34px; fill: #fff; }
/* On a phone, How Sinc saves' cards as a stack (the founder, 14 Oct: "lets change how these cards appear in the mobile view.
   I want a design that gives the cards a minimised format such that all the icons and titles appear in a stack. As the
   user scrolls, the minimised cards expand one by one"): each card folded to its icon and title, a white capsule (--row
   tall), the three under one another, pinned under the bar while the page scrolls on beneath them for a run (--run), and
   opened one at a time (.open, hybrid.js): the first with the scroll itself once the whole folded stack is on the screen, the stack's foot held at the window's, each next one further on,
   the one before folding as it opens, the last left open as the stack scrolls away. Opening, the picture slides down out of
   the card's top on its sloping foot to its height (--ph: what the screen leaves under the two folded cards and the
   tallest text, 300 px at most: 297 on a 390 x 844 screen, 166 on the same phone's Safari with its bars showing, 390 x
   664), the pill with it; the icon rides down with the slope, growing from 40 to its 64 px, the title drops away below it
   and slides in under it, growing to its size, and the label and text fade in; folding, the reverse. A folded card opens
   at a tap, and the pill plays as its card opens. No script or a screen too short for a picture of 90 px (hybrid.js)
   keeps the cards one under another as before; on a computer they stay as they were, but for How Sinc saves' (side by
   side, below). The fold, the opening and their timings are shared by both */
.stacked .wrap::after { content: ""; display: block; height: var(--run, 0px); }   /* the run the stack stays pinned for */
/* the heading and the stack pinned together (.stackpin; the founder, 14 Oct: "I want "Heading that matches your timetable" to
   stay at the top of the window while the user scrolls through the cards"), filling the screen under the bar */
.stacked .stackpin { position: sticky; top: calc(var(--nav) + env(safe-area-inset-top, 0px)); display: flex; flex-direction: column;
  height: calc(100svh - var(--nav) - env(safe-area-inset-top, 0px)); overflow-anchor: none; }
.stacked .cards3 { --row: 56px; --sd: .55s; --sw: calc(var(--sd) * .35); --sl: calc(var(--sd) * .65); --se: cubic-bezier(.4, 0, .2, 1);
  flex: 1; min-height: 0; padding-block: 8px; }
.stacked :is(.card, .hw-card) { flex: none; -webkit-tap-highlight-color: transparent; }
.stacked :is(.card, .hw-card) .art { height: var(--ph); transition: height var(--sd) var(--se); }
.pcards.stacked .card .art img { position: absolute; left: 0; bottom: 0; height: var(--ph); }   /* held at the box's foot, so the picture slides down with its sloping edge */
.pcards.stacked .pc-pill { top: calc(100% - var(--ph) + .7em); }   /* and the pill with it, coming in last */
/* Why Sinc Energy?'s two drawn pictures held at the foot the same way (the founder, 14 Oct: "In the mobile view, add the same
   stack effect to these cards"): the valve and the gateway side by side, each its whole height, the pair at the box's foot;
   the sign-in's screenshot riding 16 px under the picture's top as it slides down */
.pcards.stacked .pc-photo.duo { grid-template-rows: var(--ph); align-content: end; }
.pcards.stacked .pc-photo.duo img { position: static; height: var(--ph); }
.pcards.stacked .pc-photo.signin img { top: calc(100% - var(--ph) + 16px); bottom: auto; height: auto; }
.pcards.stacked .pc-pill.stay { top: .7em; }   /* the sunrise's held at the card's top as its picture slides down under it, so it shows first at the picture's foot and rises up it as the card opens (the founder, 14 Oct: "Fix the "05:00 → 06:15" to the top of the card rather than than at the bottom of the image. This way, as the card expands, the pill appear near the bottom of the image and rise up as the card expands."; at the picture's foot everywhere a moment before, "move the "05:00 → 06:15 pill" down to the bottom of the image"); the classroom's too since "move the 21°C pill to the top of the card too", the same day) */
.stacked :is(.card, .hw-card) .body { display: grid; grid-template-rows: auto 1fr;
  transition: margin-top var(--sd) var(--se), padding var(--sd) var(--se), grid-template-rows var(--sd) var(--se), min-height var(--sd) var(--se); }
/* the icon's height in the card with the picture's, the whole way; its size and place across, and the title's, in the last
   35 % opening (--sw, after --sl), once the icon is clear above the title, and in the first 35 % folding, before it comes
   down beside it: so the two never cross, and the icon never leaves the card (all at once, the icon crossed the title's
   first letters halfway; the icon's height eased apart, it rode up out of the card folding) */
.stacked .pc-ic { transform-origin: 0 0; transition: top var(--sd) var(--se), left var(--sw) var(--se) var(--sl), transform var(--sw) var(--se) var(--sl); }
.stacked :is(.card, .hw-card) .body h3 { white-space: nowrap; transition: font-size var(--sw) var(--se) var(--sl), padding var(--sw) var(--se) var(--sl); }
.stacked .more { min-height: 0; overflow: hidden; transition: opacity calc(var(--sd) * .5) var(--se) calc(var(--sd) * .3); }   /* from 30 %, so the opening card is never long blank under its title (45 % until the first card's opening followed the scroll) */
.stacked :is(.card, .hw-card):not(.open) { cursor: pointer; }
.stacked :is(.card, .hw-card):not(.open) .art { height: 0; }
.stacked :is(.card, .hw-card):not(.open) .body { grid-template-rows: auto 0fr; margin-top: 0; padding-block: calc((var(--row) - 40px) / 2); }
.stacked :is(.card, .hw-card):not(.open) .pc-ic { left: calc((var(--row) - 40px) / 2); top: calc((var(--row) - 40px) / 2); transform: scale(.625);   /* 40 px, at the capsule's left end */
  transition: top var(--sd) var(--se), left var(--sw) var(--se), transform var(--sw) var(--se); }
.stacked :is(.card, .hw-card):not(.open) .body h3 { padding: calc(20px - .65em) 0 calc(20px - .65em) 38px; font-size: min(22px, (100cqw - 82px) / 10);
  transition: font-size var(--sw) var(--se), padding var(--sw) var(--se); }   /* beside the icon, 12 px from it (the text's own 22 px and 38), on one line: "Optimised pre-heating", the longest, under 10 em */
.stacked :is(.card, .hw-card):not(.open) .more { opacity: 0; transition: opacity calc(var(--sd) * .4) var(--se); }
.measuring :is(.card, .hw-card) * { transition: none !important; }   /* hybrid.js measuring the cards open */
.js .pcards.stacked .card:not(.open) .pc-pill, .js .pcards.stacked .card:not(.open) .pc-pill svg, .js .pcards.stacked .card:not(.open) .pc-pill s,
.js .pcards.stacked .card:not(.open) .pc-pill s::after, .js .pcards.stacked .card:not(.open) .pc-pill b { animation: none; }
.js .pcards.stacked .card.open .pc-pill { --pd: calc(var(--sd) * .8); }   /* played as its card opens */
.js .pcards.stacked .card.open .pc-pill.stay { --pd: calc(var(--sd) * .1); }   /* a pill held at the card's top from the start, so it is seen at the picture's foot as the picture slides down under it */
@media (max-width: 767px) {
  /* on a phone the heading 10 px under the bar, the cards 12 px under it, one under another, filling the rest of the screen,
     the open card's text 16 px off its foot (24 until then) */
  .stacked .stackpin { padding-top: 10px; }
  .stacked .cards3 { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }   /* 40 px under the heading, as the cards were */
  .stacked.stackfold .wrap { margin-bottom: calc(-1 * var(--spare, 0px)); }   /* the stack's empty foot, once its cards have folded again, taken out of the section, so what follows comes up under the capsules (hybrid.js) */
  .stacked :is(.card, .hw-card) .body { padding-bottom: 16px; }
  /* The hardware's cards (the founder, 14 Oct: "Can we add the card stack feature in the mobile view ... to "The hardware"
     section?"): its heading and paragraph too tall to stay on the screen with the cards, so the stack pins alone, 12 px under
     the bar (.wrap > .cards3, no .stackpin), the heading and paragraph scrolling away above it. Each card with a green icon
     for its device (hidden on a computer: .hw-ic) at the capsule's end folded, and open beside the maker and the name, 48 px;
     the drawing above, its three facts side by side so the open card keeps to the screen */
  .stacked .wrap > .cards3 { position: sticky; top: calc(var(--nav) + env(safe-area-inset-top, 0px)); height: calc(100svh - var(--nav) - env(safe-area-inset-top, 0px));
    margin-top: 28px; padding-block: 12px; overflow-anchor: none; }   /* 40 px under the paragraph, as the cards were */
  .stacked .hw-card { border-radius: 26px; }
  .stacked .hw-card .art { padding: 0; overflow: hidden; transition: height var(--sd) var(--se), border-bottom-width var(--sd) var(--se); }
  .stacked .hw-card .art svg { width: auto; height: min(150px, calc(var(--ph) - 52px)); max-width: 62%; margin-top: 26px; }   /* the drawing under the placeholder's label, as tall as the picture leaves */
  .stacked .hw-card .body { position: relative; grid-template-rows: auto auto 1fr; padding: 16px 22px 18px; }   /* the maker, the name, the rest (the maker folding by its height: a second 1fr row would share the rest's) */
  .stacked .hw-card .hw-ic { display: grid; left: 22px; top: 16px; transform: scale(.75); }
  .stacked .hw-card .maker { max-height: 20px; overflow: hidden; padding-left: 60px; transition: max-height var(--sd) var(--se), opacity calc(var(--sd) * .5) var(--se) calc(var(--sd) * .3); }
  .stacked .hw-card .body h3 { margin-top: 0; }
  .stacked .hw-card.open .body h3 { padding: 2px 0 0 60px; }
  .stacked .hw-card .specs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 14px; margin: 0; padding-top: 14px; }
  .stacked .hw-card .specs div { flex-direction: column; gap: 1px; padding: 8px 0 0; }
  .stacked .hw-card .specs dt { font-size: 12.5px; }
  .stacked .hw-card .specs dd { text-align: left; }
  .stacked .hw-card:not(.open) .art { border-bottom-width: 0; }
  .stacked .hw-card:not(.open) .body { grid-template-rows: auto auto 0fr; padding-block: calc((var(--row) - 42px) / 2); }   /* the card's own border, a pixel each side, inside the row's 56 */
  .stacked .hw-card:not(.open) .maker { max-height: 0; opacity: 0; transition: max-height var(--sd) var(--se), opacity calc(var(--sd) * .4) var(--se); }
}
/* On a computer, How Sinc saves' cards fold and open the same way, side by side (the founder, 15 Oct: "In the desktop view, can
   we have the cards expand as the user scrolls, similar to the mobile view?"; .stackwide, hybrid.js): folded to their capsules
   in a row under the heading, pinned with it, and opened all three together with the scroll itself as the row rises, their
   feet held at the window's foot (the founder, 30 Oct: "don't have them reveal sequentially, have them reveal together"; one
   after another until then). Open, every card as tall as the tallest (--bh,
   hybrid.js), so their feet stay level, and its title on one line; the pictures as tall as the screen leaves under the
   heading and the tallest text (--ph, 300 px at most); where that is under 150 px the cards stay as they were */
@media (min-width: 768px) {
  .stacked .stackpin { padding-top: clamp(20px, 4vh, 44px); }
  .stacked .cards3 { align-items: start; margin-top: clamp(24px, 4vh, 56px); }   /* each card its own height, folded or open */
  .stacked .card .body { min-height: 0; align-content: start; }   /* from 0, so the tallest's height (below) grows with the rest, and any room it adds under the text */
  .stacked .card.open .body { min-height: var(--bh, 0px); }
  .stacked.stackwide .wrap { margin-bottom: calc(-1 * var(--spare, 0px)); }   /* the screen-tall stack's empty foot under the open row, taken out of the section (hybrid.js) */
  .stacked.stackwide .stackpin { pointer-events: none; }   /* so that empty foot never blocks what comes after it */
  .stacked.stackwide .stackpin :is(.section-head, .card) { pointer-events: auto; }
  .stacked .card .body h3 { font-size: min(28px, (100cqw - 2 * clamp(22px, 2.2vw, 28px)) / 10.35); }   /* "Optimised pre-heating", the longest, 10.35 em */
  .stacked .card:not(.open) .body h3 { padding-left: calc(60px - clamp(22px, 2.2vw, 28px)); }   /* 12 px from the icon, as on a phone */
}
@media (prefers-reduced-motion: reduce) { .stacked .cards3 { --sd: 0s; } }
.hero sup.fn { color: rgba(255, 255, 255, .75); }
.hero h1 .gains sup.fn { display: inline-block; width: 0; margin-left: .02em; font-size: .55em; font-weight: 400; letter-spacing: 0; vertical-align: .62em; white-space: nowrap; }   /* "less carbon."'s note mark, 1 (4 for a few minutes, until the founder's "it should start with "1" not "4". recorder other footnotes accordingly."), to the saving's note at the page's foot (the founder, 14 Oct: "Add a numerical footnote marker beside "less carbon.""): hung past the line (no width), so the line still ends under "classrooms."; white and Light as the "&" ; closer and larger since the founder chose "do the second one" of the review's two fixes (14 Oct: .55 em, Regular, .02 em from the full stop, its top at the lowercase letters'; .42 em Light, .08 em off and higher, which read as a stray mark, until then) */
.hero h1 .gains sup.fn a { color: inherit; text-decoration: none; }
.hero h1 .gains sup.fn a:hover { color: #fff; }

/* the teacher app as a guided tour (the founder, 28 Sep: scripted, "so the animations operate as they should"): the steps scroll
   past while the phone stays pinned beside them, and each step drives the real demo in it (hybrid.js). The phone is a photographed
   hand holding an iPhone (assets/img/hand-phone.webp, its screen and background transparent): the demo lies under the photo at
   the screen's place and shows through the cut-out; the photo takes no taps. */
.story { --step: #44b25b; --tour-bg: var(--bg); --tour-bg-0: rgba(255, 255, 255, 0); --slot: clamp(42px, 6vh, 54px); --hw: min(612px, calc((100vh - var(--nav) - 56px) * .88)); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); column-gap: clamp(32px, 6vw, 80px); }   /* --step: the steps' icons, green (the founder, 29 Sep) */
.tint .story { --tour-bg: var(--bg-2); --tour-bg-0: rgba(247, 245, 252, 0); }   /* --tour-bg: the section's own background, behind the icons and, on a phone, the pinned device */
.steps-track { grid-column: 1; grid-row: 2; display: grid; }   /* the list and the marks share one cell: the list stays in view over the marks' length */
.steps-track > * { grid-area: 1 / 1; min-width: 0; }
.marks { padding-bottom: 12vh; }   /* the list stays a little after the last step has played (hybrid.js makes it as much as the pinned list needs to stay until the last step has been read) */
.marks .at { display: block; height: 64vh; }   /* one a step: how far to scroll for it, and where it starts (hybrid.js reads them) */
/* the list pinned with its first icon level with the phone's top (the founder, 29 Sep): the phone's top is the pin's middle less
   .5099 of the photo's width (--hw, on .story for both), and the icon sits mid-slot */
/* all the steps' icons and headings stay in view beside the phone (the founder, 29 Sep: "all the section icons and headings
   always visible, but the detailed description is revealed for each one via scrolling"): the step being read opens to show
   its text as the one before closes */
.steps-pin { position: sticky; top: calc(var(--nav) + (100vh - var(--nav)) / 2 - var(--hw) * .5099 - var(--slot) / 2 + 16px); align-self: start; }   /* "Try it yourself" rides under the list (the founder, 29 Sep: "make sure it remains always visible") */
.steps { box-sizing: content-box; min-height: calc(var(--slot) * var(--n, 8) + var(--sd, 0px)); margin: 0; padding: 0 0 0 52px; list-style: none; }   /* room for every step's row (--n, hybrid.js) and the longest text (--sd), so what's under it never moves */
.step { position: relative; }
.step .sh { cursor: pointer; }   /* a click scrolls the tour to the step (hybrid.js) */
.step .sh:hover h3, .step .sh:focus-visible h3 { color: var(--accent); }
.step .sh:hover .num { border-color: var(--step); color: var(--step); }
.step .sh:focus-visible { outline: none; }
.step .sh:focus-visible .num { box-shadow: 0 0 0 3px rgb(68 178 91 / .35); }
.step .sh { position: relative; display: flex; align-items: center; height: var(--slot); }
.step .sd { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .45s var(--ease), opacity .3s var(--ease); }   /* the text, closed */
.step.on .sd { grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows .45s var(--ease), opacity .4s .1s var(--ease); }   /* open for the step being read */
.step .sd > div { overflow: hidden; min-height: 0; }
.step .num { position: absolute; left: -52px; top: calc(50% - 16px); display: grid; place-items: center; width: 32px; height: 32px; border: 2px solid var(--line-2); border-radius: 50%; background: var(--tour-bg); color: var(--text-3); font-size: 13px; font-weight: 650; transition: background .3s, border-color .3s, color .3s; }
.step.on .num { border-color: var(--step); background: var(--step); color: #fff; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.num .ic { display: block; width: 18px; height: 18px; fill: currentColor; }   /* each step's icon: Phosphor, the teacher app's own for it */
.num .ic.fill, .step.on .num .ic { display: none; }
.step.on .num .ic.fill { display: block; }   /* filled for the step being read, as the app fills what's selected */
.step h3 { overflow: hidden; font-size: clamp(20px, min(2.3vw, var(--slot) * .52), 28px); line-height: 1.2; letter-spacing: -.022em; white-space: nowrap; text-overflow: ellipsis; color: rgb(79 18 203 / .3); transition: color .4s var(--ease); }   /* the brand's purple (the founder, 29 Sep): to come, faint */
.step.past h3 { color: rgb(79 18 203 / .55); }   /* read */
.step.on h3 { color: var(--accent); }   /* being read */
.step.past .num { border-color: var(--step); color: var(--step); }
.step p { max-width: 38ch; padding: 2px 0 16px; font-size: 16.5px; line-height: 1.6; color: var(--text-2); }
.story-foot { width: fit-content; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin: 12px 0 0 52px; padding: 16px 22px 16px 16px; border-radius: 20px; background: var(--accent); box-shadow: 0 18px 40px -20px rgba(40, 20, 120, .6); font-size: 14px; line-height: 1.45; color: rgba(255, 255, 255, .8); }   /* the line beside the button, in a purple box (the founder, 29 Sep) */
.story-foot .btn { flex: none; gap: 8px; padding-left: 16px; }
.story-foot .btn .bi { width: 20px; height: 20px; fill: currentColor; margin-right: 1px; }   /* Phosphor's device-mobile, bold */
.story-foot span { flex: 1 1 120px; min-width: 0; max-width: 23ch; }   /* under the button only where a column is too narrow for it beside */
.story-media { position: relative; grid-column: 2; grid-row: 1 / 4; margin-bottom: calc(-1 * clamp(72px, 9vw, 120px)); }   /* to the section's foot, so the wrist meets the next section */
.story-pin { position: sticky; top: var(--nav); height: calc(100vh - var(--nav)); clip-path: inset(0 -100vw); }   /* the wrist cut at the foot; the fingers and the palm free at the sides */
.story-stage { position: absolute; inset: 0; }
.story-caption { display: none; }
.hand { position: absolute; left: calc(50% - var(--hw) * .3943); top: calc(50% - var(--hw) * .5134); width: var(--hw); }   /* the phone, about as tall as the hand is wide, centred in the pin */
@supports (height: 100svh) {
  .marks { padding-bottom: 12svh; }
  .marks .at { height: 64svh; }
  .story { --hw: min(612px, calc((100svh - var(--nav) - 56px) * .88)); }
  .story-pin { height: calc(100svh - var(--nav)); }
  .steps-pin { top: calc(var(--nav) + (100svh - var(--nav)) / 2 - var(--hw) * .5099 - var(--slot) / 2 + 16px); }
}
@media (max-width: 767px) {                            /* one column: the phone as big as the screen allows, pinned under the bar, the step being read on a card over its foot (the founder, 28 Sep: "an overlay over the phone, so the demo can occupy most of the screen"); the steps' list scrolls beneath (it sets how far to scroll, and a screen reader reads it) */
  .story { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto calc(100vh - var(--nav)) auto auto; }
  .story-media { grid-column: 1; grid-row: 2 / 4; z-index: 2; margin: 0 calc(-1 * var(--gutter)); }
  .story-pin { --hw: min(700px, calc((100vh - var(--nav) - 22px - var(--cap, 150px)) / .9)); height: calc(100vh - var(--nav)); clip-path: inset(0); background: var(--tour-bg); }   /* --cap: the tallest step's card (hybrid.js) */
  .story-stage { overflow: hidden; }
  .story-stage::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: 16%; background: linear-gradient(var(--tour-bg-0), var(--tour-bg)); pointer-events: none; }   /* the hand fades out at its foot */
  .hand { top: calc(10px - var(--hw) * .0097); }   /* the phone's top 10 px under the bar */
  .story-caption { display: block; position: absolute; left: 12px; right: 12px; top: calc(10px + var(--hw) * .9); z-index: 3; max-width: 560px; margin: 0 auto; padding: 13px 16px 15px 60px; border: 1px solid rgba(255, 255, 255, .7); border-radius: 18px; background: rgba(255, 255, 255, .84); -webkit-backdrop-filter: blur(16px) saturate(1.4); backdrop-filter: blur(16px) saturate(1.4); box-shadow: 0 12px 32px -12px rgba(40, 20, 120, .35); }
  .story-caption .num { position: absolute; left: 16px; top: 14px; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--step); color: #fff; font-size: 13px; font-weight: 650; }
  .story-caption .num .ic { display: none; }
  .story-caption .num .ic.fill { display: block; width: 18px; height: 18px; }
  .story-caption .count { position: absolute; right: 16px; top: 16px; font-size: 12px; font-weight: 590; color: var(--text-3); }
  .story-caption h3 { padding: 5px 40px 0 0; font-size: 19px; line-height: 1.25; letter-spacing: -.02em; color: var(--accent); }   /* on the card over Chrome's toolbar, just under the app's own tab bar, which the tour taps */
  .story-caption p { margin-top: 6px; font-size: 15px; line-height: 1.5; color: var(--text-2); }
  .story-caption.swap { animation: capin .4s var(--ease); }
  .steps-track, .steps-pin { display: contents; }   /* the list and the marks in the third row, "Try it yourself" under the phone */
  .steps, .marks { grid-column: 1; grid-row: 3; min-width: 0; }
  .marks { padding-bottom: 40vh; }   /* room after the last step, so the phone stays pinned while it plays and rests */
  .marks .at { height: 60vh; }
  .steps { min-height: 0; }
  .step .sh { height: auto; }
  .step h3 { white-space: normal; }
  .story-foot { grid-column: 1; grid-row: 4; margin: 32px 0 0; }
  @supports (height: 100svh) {
    .story { grid-template-rows: auto calc(100svh - var(--nav)) auto auto; }
    .story-pin { height: calc(100svh - var(--nav)); }
    .story-pin { --hw: min(700px, calc((100svh - var(--nav) - 22px - var(--cap, 150px)) / .9)); }
    .marks { padding-bottom: 40svh; }
    .marks .at { height: 60svh; }
  }
}
@keyframes capin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.hand .photo { position: relative; z-index: 1; width: 100%; height: auto; pointer-events: none; }
.hand .screen { position: absolute; left: 16.631%; top: 1.803%; width: 45.601%; height: 68.295%; overflow: hidden; background: #fff; }   /* the photo's whole screen opening, its soft edge included, and a pixel under the bezel all round: white until the teacher app's demo goes back in it (the founder, 14 Oct: "remove the demo in the mobile phone (leave it white, we will add this again in the future)"; until then a take of the app in iOS Chrome's bars, drawn as the page scrolled) */
.hand .halo { position: absolute; left: 39.43%; top: 35.95%; width: min(520px, 100vw); height: min(520px, 100vw); transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(closest-side, rgba(120, 74, 242, .28), transparent 70%); pointer-events: none; }

/* the school console on a phone (the founder, 14 Oct: "The school admin dashboard will instead be a mobile-friendly
   dashboard/web app (so it can be accessed anywhere and anytime, unlike a desktop version). Use this as the background image"):
   the founder's photograph of a hand holding a phone in a school corridor (assets/img/corridor-phone.webp, 1672 x 941) fills the
   section, the window's whole width, pinned the whole way, its phone's screen white until the mobile console goes in it (.vp,
   over the photo's screen: "Just leave the phone white for now"). The title lies over the photo's top and the list over its
   left, each on a shade so their white words read. hybrid.js places them for the window: the list where the teacher app's is,
   and the photo covering the stage with its phone where the teacher app's phone is, its screen as tall, or bigger where the
   photo must grow to keep the phone clear of the list and still reach the window's sides. Until then the founder's photograph
   of a laptop on a teacher's desk (29 Sep), its display playing a take of the desktop console in perspective, beside eight
   steps */
.section.room { padding: 0; background: #16101f; color: #fff; }   /* the photo fills it; this colour only until it loads, and under "Try it yourself" on a phone */
.story-room { grid-template-columns: minmax(0, 1fr); column-gap: 0; --slot: clamp(34px, 5vh, 50px); }   /* the list's rows the teacher app's: the title, the list and the phone share the screen's height */
.story-room .story-media { grid-area: 1 / 1; margin: 0 calc(50% - 50vw); }   /* the window's whole width */
.story-room .steps-track { grid-area: 1 / 1; position: relative; z-index: 3; }
.story-room .story-pin { overflow: hidden; clip-path: none; background: #16101f; }
.corridor { position: absolute; left: 0; top: 0; width: max(100%, (100vh - var(--nav)) * 1.7768); aspect-ratio: 1672 / 941; }   /* where hybrid.js puts it; this until then */
.corridor .photo { display: block; width: 100%; height: 100%; }
.corridor.shifted .photo { -webkit-mask-image: linear-gradient(90deg, transparent, #000 160px); mask-image: linear-gradient(90deg, transparent, #000 160px); }   /* moved off the window's left to even the list's margin with the phone's (hybrid.js), its edge fading into the section's dark */
.corridor .vp { position: absolute; z-index: 1; left: 42.64%; top: 33.37%; width: 13.82%; height: 51.65%; border-radius: 12.1% / 5.8%; overflow: hidden; background: #fff; }   /* the photo's screen (713 to 944 x 314 to 800 of its 1672 x 941, its corners 28 px round), lit: over the shade, which would grey its top */
.story-room .shade { position: absolute; inset: 0; pointer-events: none;   /* the list's side and the title's top darkened, to the phone's left edge (--gl) and its screen's top (--dt), more than the classroom's were: the corridor is bright */
  background: linear-gradient(rgba(14, 9, 32, .72), rgba(14, 9, 32, .26) calc(var(--dt, 260px) - 30px), rgba(14, 9, 32, 0) calc(var(--dt, 260px) + 40px)); }
.story-room .shade::before { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(14, 9, 32, .86), rgba(14, 9, 32, .72) calc(var(--gl, 420px) - 150px), rgba(14, 9, 32, 0) calc(var(--gl, 420px) + 10px)); transition: opacity .5s var(--ease); }   /* the list's side, coming in with the list (the founder, 3 Nov: "have the left tint (dark purple) appear when the tabs and text appears"; there with the title's from the start until then) */
.story-room.zooming .shade::before { opacity: 0; }
.room-title { position: absolute; left: 0; right: 0; top: 0; z-index: 2; padding: clamp(18px, 3.2vh, 32px) 24px 12px; text-align: center; text-shadow: 0 2px 20px rgba(14, 9, 32, .55); }   /* the title alone (the founder, 29 Sep), at the top the whole way through */
.room-title .eyebrow { margin-bottom: 8px; }
.room-title h2 + .eyebrow { margin: 8px 0 0; }   /* under the heading (the founder, 14 Oct: "bring it back but position it below the main heading") */
.room-title h2 { font-size: clamp(28px, min(4vw, 5vh), 46px); }
.story-room .steps-pin { top: calc(var(--nav) + var(--ly, 150px)); width: var(--lwid, 360px); margin: var(--ly, 150px) 0 0 var(--lx, 0px); padding-bottom: var(--lpad, 0px); }   /* in its place on the photo from the start (the margin), so it pins as the photo does, and leaves with it (the padding) */
.story-room .story-foot span { max-width: none; }
.story-room .steps-pin { transition: opacity .5s var(--ease), translate .5s var(--ease); }
.story-room.zooming .steps-pin { opacity: 0; translate: 0 16px; pointer-events: none; }   /* on a computer, the list and "Try it yourself" only once the corridor has zoomed into place (hybrid.js) */   /* its line in two rows under the button, not three */
@supports (height: 100svh) {
  .corridor { width: max(100%, (100svh - var(--nav)) * 1.7768); }
}
@media (max-width: 767px) {                            /* one column: the phone as big as the room between the title and the step being read on a card under it allows (hybrid.js: --capy), as the teacher app's; the list under the pinned stage, read by a screen reader, and "Try it yourself" after it */
  .story-room .story-media { grid-area: 2 / 1 / 4 / 2; margin: 0 calc(-1 * var(--gutter)); }
  .story-room .story-caption { top: var(--capy, 62%); }
  .corridor .photo { -webkit-mask-image: linear-gradient(#000 87%, transparent); mask-image: linear-gradient(#000 87%, transparent); }   /* the photo's foot, from just under the phone (its row 812 of 941), fading into the section's dark: with the whole phone over the card, the photo stops short of the stage's foot, behind the card */
  .story-room .story-stage::after { content: none; }   /* not the teacher app's fade at the hand's foot */
  .story-room .shade { background: linear-gradient(rgba(14, 9, 32, .74), rgba(14, 9, 32, .26) calc(var(--dt, 200px) - 20px), rgba(14, 9, 32, 0) calc(var(--dt, 200px) + 30px)); }
  .story-room .shade::before { content: none; }   /* no list beside the phone to darken */
  .story-room .story-foot { margin: 28px 0 44px; }
}

/* the list and "Try it yourself" over a photo, in both tours (.scene): white words and a lime eyebrow as on the dark band; every
   icon a filled green circle, its icon white in Phosphor's fill (the founder, 29 Sep); every heading white and opaque (29 Sep);
   the step being read in a white box, its heading in the brand's purple and its text grey (29 Sep); "Try it yourself" in a
   deeper purple box */
.scene .eyebrow { color: var(--lime); }
.scene h2 { color: #fff; }
.scene .step h3, .scene .step .sh:hover h3, .scene .step .sh:focus-visible h3 { color: #fff; }
.scene .step .num, .scene .step .sh:hover .num { border-color: var(--step); background: var(--step); color: #fff; }
.scene .step .num .ic { display: none; }
.scene .step .num .ic.fill { display: block; }
.scene .step p { color: rgba(255, 255, 255, .84); }
.scene .step h3 { font-size: clamp(17px, calc((clamp(300px, 25vw, 420px) - 56px) * .077), 25px); }   /* one size in both tours (the founder, 29 Sep: "Make the fonts of these texts the same size"): the console's, which its list's width sets (a quarter of the window's, 300 to 420 px: hybrid.js), so its headings fit beside the laptop */
.scene .step p { font-size: 15.5px; }
.scene .step::before { content: ""; position: absolute; left: -66px; right: -14px; top: -3px; bottom: 0; z-index: -1; border-radius: 18px; background: #fff;   /* drawn behind the step without moving it, fading in as its text opens */
  box-shadow: 0 20px 44px -22px rgba(10, 0, 40, .7); opacity: 0; transform: scale(.985); transition: opacity .3s var(--ease), transform .3s var(--ease); pointer-events: none; }
.scene .step.on::before { opacity: 1; transform: none; }
.scene .step.on h3, .scene .step.on .sh:hover h3, .scene .step.on .sh:focus-visible h3 { color: var(--accent); }
.scene .step.on p { color: var(--text-2); }
.scene .step h3 { text-shadow: 0 1px 12px rgba(14, 9, 32, .6); }
.scene .step.on h3 { text-shadow: none; }
.scene .story-foot { margin-top: 20px; background: #360c9c; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14), 0 18px 40px -20px rgba(10, 0, 40, .75); }
@media (max-height: 780px) and (min-width: 768px) {   /* a short laptop screen: the step's text and "Try it yourself" a little tighter, so the list keeps to the screen under the title, both tours' lists at one height (hybrid.js: listTop; after the rules above, so it wins) */
  .scene .step p { padding-bottom: 12px; font-size: 14.5px; line-height: 1.5; }
  .scene .story-foot { margin-top: 14px; padding-top: 12px; padding-bottom: 12px; }
}

/* both tours' steps as the hero's tabs, .tabbed (the founder, 2 Nov, of the school console: "lets use this 'tab' component as a
   template for another section", then "lets update this section to match the style and function", and of the teacher app's:
   "Apply these changes to the "Teachers get a say." section as well"; until then the green circles, every title shown and
   the step being read in a white box): each icon in a round tab, its circle frosted dark with a white edge and the icon white,
   the step showing white with its icon in the purple and a ring round it drawing the time left (hybrid.js moves the steps on,
   as the hero's carousel does); only its title shown, beside its tab in white as the hero's are, and its text under it,
   white on the shade, no box. On a phone the step under the phone in white, no card, the tabs in a column at its left,
   12 px from its words as the hero's are from their titles */
.tabbed .steps { padding-left: 56px; }
.tabbed .step .num, .tabbed .step .sh:hover .num { left: -56px; top: calc(50% - 22px); width: 44px; height: 44px; border: 0; background: none; color: #fff; }
.tabbed .step .num::before, .tour-tabs button::before { content: ""; grid-area: 1 / 1; box-sizing: border-box; width: 34px; height: 34px; border: 1.5px solid rgba(255, 255, 255, .85); border-radius: 50%; background: rgba(26, 10, 70, .45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 2px 8px rgba(20, 5, 70, .4); transition: background .3s, border-color .3s; }
.tabbed .step .num .ic.fill, .tour-tabs .ic { position: relative; grid-area: 1 / 1; width: 24px; height: 24px; fill: currentColor; transition: fill .3s; }
.tabbed .step .sh:hover .num::before, .tour-tabs button:hover::before { background: rgba(26, 10, 70, .65); }
.tabbed .step.on .num { color: var(--accent); }
.tabbed .step.on .num::before, .tour-tabs button[aria-current="true"]::before { border-color: #fff; background: #fff; }
.tabbed .step .sh:focus-visible .num { box-shadow: none; }
.tabbed .step .sh:focus-visible .num::before, .tour-tabs button:focus-visible::before { outline: 2px solid #fff; outline-offset: 3px; }
.tabbed .ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; opacity: 0; filter: drop-shadow(0 1px 2px rgba(20, 5, 70, .45)); transition: opacity .3s; pointer-events: none; }
.tabbed .timing .ring { opacity: 1; }
.tabbed .ring circle { fill: none; stroke-width: 2.5; }
.tabbed .ring .track { stroke: rgba(255, 255, 255, .28); }
.tabbed .ring .run { stroke: #fff; stroke-linecap: round; stroke-dasharray: 125.66; stroke-dashoffset: 125.66; transform: rotate(-90deg); transform-box: fill-box; transform-origin: center; }
.tabbed .timing .run { animation: hero-ring var(--hold, 7s) linear forwards; }
.tabbed.paused .timing .run { animation-play-state: paused; }
.tabbed .step h3, .tabbed .step .sh:hover h3, .tabbed .step .sh:focus-visible h3 { font-weight: 650; color: #fff; text-shadow: 0 1px 2px rgba(20, 5, 70, .65), 0 2px 12px rgba(20, 5, 70, .55); opacity: 0; translate: -8px 0; transition: opacity .2s, translate .2s var(--ease); }
.tabbed .step.on h3, .tabbed .step.on .sh:hover h3, .tabbed .step.on .sh:focus-visible h3 { color: #fff; text-shadow: 0 1px 2px rgba(20, 5, 70, .65), 0 2px 12px rgba(20, 5, 70, .55); opacity: 1; translate: 0 0; transition: opacity .35s .1s, translate .35s var(--ease) .1s; }
.tabbed .step.on::before { opacity: 0; }   /* no box: the shade under the list keeps the white words readable */
.tabbed .step.on p { color: rgba(255, 255, 255, .88); text-shadow: 0 1px 2px rgba(20, 5, 70, .6), 0 2px 12px rgba(20, 5, 70, .5); }
@media (min-width: 768px) {   /* on a computer every step in full, one under another (the founder, 3 Nov: "In desktop view, we have enough space to show all three in full"; only the showing step's words, the tabs stacked in a column at their left, its title level with the top tab, from 2 Nov until then): each its round tab at its left with its title beside it and its words under it, the step showing white-tabbed and ringed as the timer runs (hybrid.js), the others a little dimmer; the block centred on the phone (hybrid.js) */
  .tabbed { --tb: clamp(44px, var(--lwid, 420px) * .104, 52px); }   /* the tabs as large as the hero's on a narrow window, a fifth larger on a wide one, with the room beside the phone (--lwid, hybrid.js); the steps' words with them (the founder, 2 Nov: "can we scale and position it better in the desktop version?") */
  .tabbed .steps { position: relative; min-height: 0; padding-left: calc(var(--tb) + 14px); }
  .tabbed .steps::before { content: ""; position: absolute; left: -16px; right: -20px; top: calc(var(--sp-t, 0px) - 14px); height: calc(var(--sp-h, 0px) + 28px); box-sizing: border-box; border: 1px solid rgba(255, 255, 255, .16); border-radius: 22px; background: linear-gradient(180deg, rgba(255, 255, 255, .13), rgba(255, 255, 255, .06)); -webkit-backdrop-filter: blur(12px) saturate(1.3); backdrop-filter: blur(12px) saturate(1.3); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 24px 48px -28px rgba(10, 0, 40, .7); transition: top .55s var(--ease), height .55s var(--ease); pointer-events: none; }   /* the step showing on a frosted panel, as the tabs' circles are frosted, gliding to the next as the timer moves on (the founder, 3 Nov: "Frosted panel", of a white box round the step showing; hybrid.js: --sp-t, --sp-h) */
  .tabbed .steps.still::before { transition: none; }
  .tabbed .step { position: relative; z-index: 1; }
  .tabbed .step + .step { margin-top: clamp(10px, 2.2vh, 22px); }
  .tabbed .step .sh { height: var(--tb); }   /* the title's row as tall as its tab, its middle the tab's */
  .tabbed .step .num, .tabbed .step .sh:hover .num { left: calc(-1 * var(--tb) - 14px); top: 0; width: var(--tb); height: var(--tb); }
  .tabbed .step .num::before { width: calc(var(--tb) * 34 / 44); height: calc(var(--tb) * 34 / 44); }
  .tabbed .step .num .ic.fill { width: calc(var(--tb) * 24 / 44); height: calc(var(--tb) * 24 / 44); }
  .tabbed .step h3 { font-size: clamp(18px, (var(--lwid, 420px) - var(--tb) - 14px) / 15.5, 28px); opacity: .48; translate: none; transition: opacity .35s var(--ease); }   /* the steps not showing a little dimmer (.62 until the frosted panel, 3 Nov) */   /* the hero's titles' 28 px where the room allows, each on one line */
  .tabbed .step.on h3 { opacity: 1; }
  .tabbed .step .sd { grid-template-rows: 1fr; opacity: .48; transition: opacity .35s var(--ease); }
  .tabbed .step:not(.on) .sh:hover h3 { opacity: .75; }   /* a step not showing brighter under the pointer, which shows it */
  .tabbed .step.on .sd { opacity: 1; }
  .tabbed .step p { max-width: 36ch; padding-bottom: 0; font-size: clamp(15.5px, (var(--lwid, 420px) - var(--tb) - 14px) / 24, 18px); color: rgba(255, 255, 255, .88); text-shadow: 0 1px 2px rgba(20, 5, 70, .6), 0 2px 12px rgba(20, 5, 70, .5); }
}
@media (min-width: 768px) and (prefers-reduced-motion: reduce) { .tabbed .steps::before { transition: none; } }   /* the panel moving to the next step at once */
@media (min-width: 768px) and (max-height: 760px) {   /* a short laptop screen: the three steps a little tighter, so they keep to the stage under the title */
  .tabbed { --tb: 44px; }
  .tabbed .step + .step { margin-top: 6px; }
  .tabbed .step p { font-size: 15px; line-height: 1.45; }
}

.tour-tabs { display: none; }
@media (max-width: 767px) {
  .tour-tabs { position: absolute; left: calc(max(8px, (100% - 560px) / 2) + 12px); top: calc(var(--capy, calc(10px + var(--hw) * .9)) + var(--panel, 164px) / 2); translate: 0 -50%; z-index: 4; display: flex; flex-direction: column; gap: 4px; }   /* at the left of the step's words, in the middle of the panel's height (the founder, 3 Nov: "The tabs aren't centered in the container in the mobile view"; at its top until then), the top tab's middle level with the title's, the circles 8 px from the window's edge (the caption's 12, less 4; the founder, 2 Nov: "move the tabs to the left of the text", then of the title "on phones too": level with the top tab, as on a computer; the column's foot level with the words' for a while, and over the photo's right, as the hero's, for a few minutes) */
  .tour-tabs button { position: relative; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: none; color: #fff; cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .tour-tabs button[aria-current="true"] { color: var(--accent); }
  .tour-tabs button:focus-visible { outline: none; }
  .tabbed .story-pin { --panel: var(--cap, calc(var(--n, 3) * 48px + 20px)); }   /* the panel's height, one for every step: the tallest step's (--cap, hybrid.js), at least the column's with 12 px above and below it */
  .tabbed .story-caption { left: 8px; right: 8px; min-height: var(--panel); padding: 21px 14px 12px 70px; border: 1px solid rgba(255, 255, 255, .16); border-radius: 22px; background: linear-gradient(180deg, rgba(255, 255, 255, .13), rgba(255, 255, 255, .06)); -webkit-backdrop-filter: blur(12px) saturate(1.3); backdrop-filter: blur(12px) saturate(1.3); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 24px 48px -28px rgba(10, 0, 40, .7); }   /* the step and its tabs on a frosted panel, as the step showing is on a computer (the founder, 3 Nov: "can we add that frosted effect to mobile view"; no panel, the words on the dark, until then): 8 px in from the window's sides, the tabs 12 px inside it, the words 14 px from them, the title level with the top tab (21 px down; 10 with the tabs at the panel's top), the panel as tall as the column or the words */
  .tabbed .story-caption.swap { animation: none; }
  .tabbed .story-caption.swap > * { animation: capin .4s var(--ease); }   /* the words coming in, the panel staying put */
  .tabbed .story-caption .num, .tabbed .story-caption .count { display: none; }   /* the tabs show which step it is; every step's title where the tallest's is (--capy, the phone sized for the tallest: hybrid.js), the words at least as tall as the column beside them, so it stays over the stage's foot */
  .tabbed .story-caption h3 { padding: 0; font-weight: 650; color: #fff; text-shadow: 0 1px 2px rgba(20, 5, 70, .65), 0 2px 12px rgba(20, 5, 70, .55); }
  .tabbed .story-caption p { color: rgba(255, 255, 255, .86); }
}
@media (prefers-reduced-motion: reduce) { .tabbed .ring { display: none; } }

/* the teacher app's tour in a classroom (the founder, 29 Sep: "Similar to 'The school console' section, add this image to 'The
   teacher app' behind the existing phone demo … Don't change the teacher app demo, just change the white background with this
   image"): the founder's photograph of a classroom's front wall (assets/img/classroom-wall.webp) pinned behind the whole section,
   covering the screen, its pin-up board behind the phone (29 Sep: "The pin up board should be behind the phone and not
   necessarily in view"; the QR poster is to go there). hybrid.js places it; the list's side is darkened so its words read */
.section.wall { padding-top: 0; color: #fff; }   /* the title at its top */
.wall .wrap { position: relative; z-index: 1; }   /* the words and the phone over the photo */
.wall-bg { position: absolute; inset: 0; }   /* the section's whole height, */
.wall-pin { position: sticky; top: var(--nav); height: calc(100vh - var(--nav)); overflow: hidden; }   /* the photo pinned in it the whole way through */
.wall-pin::before { content: ""; position: absolute; inset: 0; background: var(--accent); opacity: var(--q, 1); }   /* the brand purple under the photo, until it loads, and once the classroom has faded in over the console (--q, hybrid.js), should its photo be late (the console's stage faded to it as the section faded in, until the founder's "remove the fade-to-purple at the end", 3 Nov) */
.wall-pin::after { content: ""; position: absolute; inset: 0; -webkit-backdrop-filter: var(--blf, none); backdrop-filter: var(--blf, none); pointer-events: none; }   /* a blur over the change from the console to the classroom, the console blurring out as the classroom comes into focus, most blurred halfway (the founder, 3 Nov: "lets blur our and in"; --blf, hybrid.js): over the photo and the console's pinned stage under it, under the title and the hand */
.wall-photo { position: absolute; left: 0; top: 0; width: max(100%, (100vh - var(--nav)) * 1.5); max-width: none; height: auto; aspect-ratio: 1536 / 1024; pointer-events: none; }   /* where hybrid.js puts it; this until then */
.wall .shade { position: absolute; inset: 0; background: linear-gradient(rgba(14, 9, 32, .62), rgba(14, 9, 32, .22) var(--tt, 130px), rgba(14, 9, 32, 0) calc(var(--tt, 130px) + 60px)); }   /* the title's top darkened, to its foot (--tt), */
.wall .shade::after { content: ""; position: absolute; inset: 0; opacity: var(--r, 1); background: linear-gradient(90deg, rgba(14, 9, 32, .84), rgba(14, 9, 32, .66) calc(var(--pl, 50%) - 150px), rgba(14, 9, 32, 0) calc(var(--pl, 50%) + 10px)); }   /* and the list's side, to the phone's left edge (--pl, hybrid.js), coming in with the list */
.wall .hand .photo { -webkit-mask-image: linear-gradient(#000 86%, transparent); mask-image: linear-gradient(#000 86%, transparent); }   /* the wrist fading into the photo, where a tall screen shows the hand's foot (elsewhere the stage's foot cuts it first) */
/* the title centred at the top the whole way through (the founder, 29 Sep: "Ensure this title is centred and stays at the top of
   its section"), as the console's: pinned over the story from the section's top to its foot, the phone and the list under it
   (--tt: its height, hybrid.js), the phone as big as that leaves room for and the steps' rows the console's; no lead or note
   (the founder, 29 Sep: "Remove this text"). The list is in its place under the title from the start (its margin, hybrid.js), so
   it pins as the photo does, and the first step plays once the section has pinned (the marks' top). The title's box (with its
   margin) and the list's reach the stage's foot, and their tracks the section's, so the title and the list leave with the photo
   and the phone (with one column, with the phone, before "Try it yourself") */
.story-title { grid-column: 1 / -1; grid-row: 1 / 4; align-self: start; position: sticky; top: var(--nav); z-index: 4; margin-bottom: calc(100vh - var(--nav) - var(--tt, 130px) - clamp(72px, 9vw, 120px)); padding: clamp(18px, 3.2vh, 32px) 24px 12px; text-align: center; text-shadow: 0 2px 20px rgba(14, 9, 32, .55); }
.story-title .eyebrow { margin-bottom: 8px; }
.story-title h2 + .eyebrow { margin: 8px 0 0; }   /* under the heading, as the school console's (the founder, 14 Oct: "swap these two as well") */
.story-title h2 { font-size: clamp(28px, min(4vw, 5vh), 46px); }
.wall .story .steps-pin { translate: var(--even, 0px) 0; }   /* moved right with the hand (its rise's translate, below, carries --even too) to even the list's margin with the phone's (hybrid.js) */
.wall .story { --slot: clamp(34px, 5vh, 50px); --hw: min(612px, calc((100vh - var(--nav) - var(--tt, 130px) - 36px) * .94)); }
.wall .hand { top: calc(var(--tt, 130px) + (100% - var(--tt, 130px)) / 2 - var(--hw) * .5134); }   /* the phone centred in the space under the title */
.wall .steps-track { margin-bottom: calc(-1 * clamp(72px, 9vw, 120px)); }
@media (min-width: 768px) and (max-width: 860px) { .wall .story { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }   /* a narrow computer's window (the page's two columns down to 768 px since 12 Oct): the list half the width, so its longest heading, "Sign in with your school account.", fits beside the phone where a scroll bar takes 17 px of 768 */
.wall .steps-pin { top: calc(var(--nav) + var(--tt, 130px) + (100vh - var(--nav) - var(--tt, 130px)) / 2 - var(--hw) * .5099 - var(--slot) / 2 + 16px); }   /* its first icon level with the phone's top, as before (higher on a short screen, where the list wouldn't fit: hybrid.js) */
@supports (height: 100svh) {
  .wall-pin { height: calc(100svh - var(--nav)); }
  .wall-photo { width: max(100%, (100svh - var(--nav)) * 1.5); }
  .wall .story { --hw: min(612px, calc((100svh - var(--nav) - var(--tt, 130px) - 36px) * .94)); }
  .story-title { margin-bottom: calc(100svh - var(--nav) - var(--tt, 130px) - clamp(72px, 9vw, 120px)); }
  .wall .steps-pin { top: calc(var(--nav) + var(--tt, 130px) + (100svh - var(--nav) - var(--tt, 130px)) / 2 - var(--hw) * .5099 - var(--slot) / 2 + 16px); }
}
/* the section fading in over the console's (the founder, 29 Sep: "Rather than a scroll transition between 'The school console' and
   'The teacher app' sections, lets make the 'The teacher app' section fade over it … first have the background … fade over the
   'The school console' section, then have the hand holding the phone rise up"): on a computer it lies over the console's last
   screen and a half, so it pins while the console's stage is still pinned, over it and its list. hybrid.js sets how far in it
   is: over the first half screen of scroll the classroom fades in over the console (--f; the console faded to the brand purple
   first, --q, until 3 Nov), the title with the classroom's second half; over the next, --r
   raises the hand with the phone into its place and fades the list in; then the first step plays. Until the hand is in, the
   section takes no clicks, so the console's list keeps them; with reduced motion the hand fades in instead of rising. On a
   phone too since the founder's "In the mobile view, lets make this transition match the desktop view" (3 Nov; with one
   column it came up the screen after the console's until then, the classroom zooming in as it came) */
.section.wall { z-index: 5; margin-top: calc(-1 * (100vh - var(--nav)) - 50vh); }
.section.wall.fading { pointer-events: none; }
#teachers { scroll-margin-top: calc(var(--nav) - 100vh); }   /* its links land with the section all in */
.wall-photo, .wall .shade { opacity: var(--f, 1); }
.wall .story-title { opacity: clamp(0, calc(var(--f, 1) * 2 - 1), 1); }
@supports (height: 100svh) {
  .section.wall { margin-top: calc(-1 * (100svh - var(--nav)) - 50svh); }
  #teachers { scroll-margin-top: calc(var(--nav) - 100svh); }
}
@media (min-width: 768px) {
  .wall .hand { translate: var(--even, 0px) calc((1 - var(--r, 1)) * 100vh); rotate: calc((1 - var(--r, 1)) * 4deg); }
  .wall .steps-pin { opacity: var(--r, 1); }
  .wall .marks { padding-top: calc(150vh - var(--nav)); }   /* the first step's mark reaching the reading line, mid-screen, as the hand arrives */
  @supports (height: 100svh) {
    .wall .hand { translate: var(--even, 0px) calc((1 - var(--r, 1)) * 100svh); }
    .wall .marks { padding-top: calc(150svh - var(--nav)); }
  }
}
@media (prefers-reduced-motion: reduce) {   /* the hand fading in instead of rising, on a computer and a phone */
  .wall .hand { translate: var(--even, 0px) 0; rotate: none; opacity: var(--r, 1); }
}
@media (max-width: 767px) {                            /* one column: the photo round the phone, darkened, more at the top under the title; the phone's pin clear, so the photo shows round the phone, and the list under it out of sight (a screen reader still reads it); the hand fading out under the phone into the photo, not into white. The title pinned over the phone and leaving with it, before "Try it yourself"; the phone as big as the room between the title and the step's card allows, all of it in view (the founder, 14 Oct: "ensure the phones are scaled to occupy the full height of the space between the white text boxes and the headings (I don't want parts of the mobile phone to be hidden by the text boxes)"): its body (rows 3 to 952 of the photo's 932 x 1331, .0032 to 1.0215 of --hw) 8 px under the title and 12 px over the card, the tallest step's card (--cap) 12 px over the stage's foot; 160 px across at the least (a phone on its side) */
  .wall .shade { background: linear-gradient(rgba(14, 9, 32, .74), rgba(14, 9, 32, .5) 40%, rgba(14, 9, 32, .42)); }
  .wall .shade::after { content: none; }
  .wall .story-pin { background: none; --hw: min(700px, max(160px, calc((100vh - var(--nav) - var(--tt, 90px) - var(--cap, 150px) - 32px) / 1.0183))); }
  .wall .story-stage::after { content: none; }
  .wall .story-stage { -webkit-mask-image: linear-gradient(#000 calc(var(--tt, 90px) + 8px + var(--hw) * 1.0183), transparent); mask-image: linear-gradient(#000 calc(var(--tt, 90px) + 8px + var(--hw) * 1.0183), transparent); }   /* from the phone's foot, under the card */
  .wall .steps { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .story-title { margin-bottom: calc(100vh - var(--nav) - var(--tt, 90px)); }
  .wall .marks { padding-top: 0; }   /* the marks under the phone's row already (half a screen since 14 Oct, for the hand's rise: below) */
  .wall .hand { top: calc(var(--tt, 90px) + 8px - var(--hw) * .0032); }
  .wall .story-caption { top: calc(var(--tt, 90px) + 20px + var(--hw) * 1.0183); }
  @supports (height: 100svh) {
    .wall .story-pin { --hw: min(700px, max(160px, calc((100svh - var(--nav) - var(--tt, 90px) - var(--cap, 150px) - 32px) / 1.0183))); }
    .story-title { margin-bottom: calc(100svh - var(--nav) - var(--tt, 90px)); }
  }
}

/* with one column, the hand rising into its place once the classroom has faded in, as on a computer (the founder, 14 Oct: "In
   the mobile view, have the hand also animate upwards like it does in the desktop view"): the half screen of the fade and the
   half of the rise before the steps play (the marks' top; the rise's half alone until 3 Nov); the step's card fading in with
   it (--r, hybrid.js). The school console's stage held half a screen longer for the fade over it (its 40 % and the fade's
   half). With reduced motion the hand fades in instead (above) */
@media (max-width: 767px) {
  .wall .marks { padding-top: 100vh; }
  .wall .story-caption { opacity: var(--r, 1); }
  .story-room .marks { padding-bottom: 90vh; }
  @supports (height: 100svh) { .wall .marks { padding-top: 100svh; } .story-room .marks { padding-bottom: 90svh; } }
}
@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  .wall .hand { translate: 0 calc((1 - var(--r, 1)) * 100vh); rotate: calc((1 - var(--r, 1)) * 4deg); }
  @supports (height: 100svh) { .wall .hand { translate: 0 calc((1 - var(--r, 1)) * 100svh); } }
}

/* the teacher app's steps, tabbed and timed as the school console's (the founder, 2 Nov: "Apply these changes to the "Teachers
   get a say." section as well"): on a computer "Try it yourself" under the words, in line with them (gone since the founder's
   "remove this", 3 Nov; the rule kept for its return); on a phone the tabs at the left of the step's words under the phone,
   fading in with the hand as the words do, and the classroom darkened under the phone so the white words read on it (on a
   white card until then) */
@media (min-width: 768px) { .tabbed .story-foot { margin-left: calc(var(--tb) + 14px); } }
@media (max-width: 767px) {
  .wall .tour-tabs { top: calc(var(--tt, 90px) + 20px + var(--hw) * 1.0183 + var(--panel, 164px) / 2); opacity: var(--r, 1); }   /* the middle of the panel (the caption, its top here), as the console's (above) */
  .wall:has(.tabbed) .shade { background: linear-gradient(rgba(14, 9, 32, .74), rgba(14, 9, 32, .5) 40%, rgba(14, 9, 32, .42) 66%, rgba(14, 9, 32, .82) 80%, rgba(14, 9, 32, .88)); }
}

/* the UN's Sustainable Development Goals (the founder, 13 Oct): after the numbers, on white, as the UN's guidelines ask of
   the logo in colour; the icons at 96 px, square and as issued (no rounding, shadow or frame of their own), each card the
   goal's target in the brand purple, a title and the figure behind it with its note; the guidelines and the line that the
   UN endorses nothing under them */
/* Security (the founder, 15 Oct: "add a section after "The hardware" section similar to this ... but mention in the description
   that they are pending"): on the hardware's tint, continuing its stretch as the SDGs' do; the heading and its line centred,
   as How Sinc saves'; the three standards side by side (one under another on a phone), each a white badge of the page's own
   (never the schemes' marks while pending: index.html) with the standard's icon in the brand purple, a dashed ring for a seal
   not yet given and an amber Pending tag on its foot, its name and a line saying what is pending */
.section.trust { padding-top: clamp(32px, 4vw, 56px); }
.trust .section-head { max-width: 880px; margin-inline: auto; text-align: center; }
.trust .section-head h2 { font-size: clamp(32px, 4.6vw, 54px); letter-spacing: -.03em; }
.trust .section-head .lead { margin-inline: auto; }
.trust-cards { margin-top: clamp(40px, 5vw, 56px); gap: 32px; }
.trust-card { display: flex; flex-direction: column; align-items: center; text-align: center; }
.trust-badge { position: relative; display: grid; place-items: center; width: 116px; height: 116px; border-radius: 50%; background: #fff; color: var(--accent);
  box-shadow: 0 2px 4px rgba(16, 0, 48, .08), 0 22px 44px -24px rgba(16, 0, 48, .45); }
.trust-badge::before { content: ""; position: absolute; inset: 8px; border: 2px dashed var(--line-2); border-radius: 50%; }
.trust-badge > svg { width: 52px; height: 52px; fill: currentColor; }
.trust-tag { position: absolute; left: 50%; bottom: -12px; display: inline-flex; align-items: center; gap: 5px; width: max-content; padding: 4px 10px 4px 8px; border-radius: 999px;
  background: #fff4db; color: #a14b00; font-size: 12.5px; font-weight: 700; letter-spacing: .02em; white-space: nowrap; transform: translateX(-50%);
  box-shadow: 0 0 0 2px var(--bg-2), 0 6px 14px -8px rgba(120, 60, 0, .5); }   /* amber, 5.5 to 1, ringed in the tint so it sits over the badge's edge */
.trust-tag svg { flex: none; width: 13px; height: 13px; fill: currentColor; }   /* Phosphor's hourglass-medium (fill) */
.trust-card h3 { margin-top: 32px; font-size: clamp(22px, 2.1vw, 28px); letter-spacing: -.03em; }
.trust-card p { max-width: 32ch; margin-top: 10px; font-size: 16px; line-height: 1.6; color: var(--text-2); text-wrap: pretty; }
@media (max-width: 767px) { .trust-cards { gap: 44px; } }
.section.sdgs { padding-top: clamp(32px, 4vw, 56px); }   /* on the hardware's tint, the two one stretch (the founder, 13 Oct: "i want the SDGs section to better match the hardware section"; white until then, where the colour SDG logo belongs: the tint, #f7f5fc, is lighter than the guidelines' light grey, #f1f1f1, but faintly lavender), so less of it between them; the page's own padding below, before the white closing section */
/* "Sinc Energy supports the UN's" and the logo under it, ending the sentence (the founder, 13 Oct: "have this below "Sinc
   Energy supports the UN's""; to its right for an hour, above "Sinc Energy supports the Sustainable Development Goals."
   before that): the heading as wide as its words, the logo's letters as wide as the heading (the picture 1.066 times it,
   moved left by its own clear margin, 3 % of its width, so the letters line up with the words). The guidelines' clear
   space, "approx. 0.35\" square" (34 px), round it but above: the words sit 20 px over its letters since the founder's
   "make the top text the brand purple and move it closer to "Sustainable Development Goals"" (13 Oct; 44 px before), as
   the guidelines' own pairing (page 18) has its words close under the logos; the margin takes back the picture's own
   clear top, 17 % of its height, which is 3.264 % of the heading's width. The cards' 44 px under it and its own 19 % (the
   line under the heading removed, the founder: "And remove this text"). The words in the brand purple,
   "sinc energy" as the brand writes it, lowercase in Urbanist Black Italic, as the purple sections' wordmark */
.sdgs .section-head { max-width: none; }
.sdg-title { color: var(--accent); font-size: clamp(22px, 2.6vw, 32px); text-align: center; }   /* the words and the logo centred in the section (the founder, 13 Oct: "lets also centre them both"; at its left until then), the words smaller ("use a smaller font size": 22 to 32 px, the page's 30 to 46 before) while the logo keeps its size */
.sdg-title .wm { font-weight: 900; font-style: italic; }
.sdg-title .sdg-logo { display: block; width: min(614px, 106.6%); max-width: none; height: auto; margin: calc(20px - .0306 * min(614px, 106.6%)) 0 0 50%; transform: translateX(-50%); }   /* its letters 576 px wide at most, the column's width on a phone (the picture 1.066 times them, centred over its own clear sides); 20 px under the words, the margin taking back its clear top (17 % of its height, 3.06 % of its width) */
/* each card: the goal's icon with its target and title to its right, centred on it, the figure under both (the founder,
   13 Oct: "Can we have the text to the right of the icons?"; all under the icon until then; the figure beside it too
   squeezed it to five to eight lines on a laptop's three cards). A card with under 250 px inside its padding (three to a
   row below about 1,000 px wide, one on a phone under 360) keeps them under the icon, where the target ran to five lines */
.sdg-card { container-type: inline-size; padding: 24px 24px 26px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: #fff; box-shadow: var(--shadow-card); }
.sdg-in { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-content: start; column-gap: 20px; }
.sdg-in img { display: block; grid-row: 1 / span 2; width: 96px; height: 96px; }
.sdg-in .target { grid-column: 2; grid-row: 1; align-self: end; font-size: 13.5px; font-weight: 650; color: var(--accent); }
.sdg-in h3 { grid-column: 2; grid-row: 2; align-self: start; margin-top: 6px; font-size: 22px; letter-spacing: -.02em; }
.sdg-in p { grid-column: 1 / -1; grid-row: 3; margin-top: 18px; font-size: 15px; line-height: 1.6; color: var(--text-2); text-wrap: pretty; }
@container (max-width: 250px) {
  .sdg-in { display: block; }
  .sdg-in img { margin-bottom: 18px; }
  .sdg-in .target { display: block; }
  .sdg-in p { margin-top: 8px; }
}
.sdg-small { margin-top: 28px; max-width: 80ch; font-size: 13px; line-height: 1.55; color: var(--text-2); }
.sdg-small a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
@media (min-width: 768px) and (max-width: 1023px) { .nav-links .wide-only { display: none; } }   /* "Impact" in the bar only where it fits beside the rest ("Sign in" broke in two at 768 px); always in the phone's menu and the footer */
.footer .sdg-foot { margin-top: 12px; max-width: 30ch; font-size: 13px; line-height: 1.5; }
.footer .sdg-foot a { text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(255, 255, 255, .4); }

/* the hardware (the founder, 13 Oct: "Lets make this section all about our hardware (MClimate Vicki, MClimate 16A Dry Switch,
   TTIG Pro Gateway)", then "you can use placeholder images for now"; three screens of the product, Linear's, until then): a
   card for each device in the page's three-card row, its picture a labelled placeholder until the founder's photos come
   (the device drawn in outline on the placeholders' hatching, lit from below in the brand's lilac), then its maker, its name,
   where it goes in the purple of the saving cards' labels, a line on what it does and three facts, the facts' rows held
   at the card's foot so they line up across the row, Power last on each */
.hw-card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius-lg); background: #fff; box-shadow: var(--shadow-card); overflow: hidden; transition: transform .2s var(--ease), box-shadow .2s; }
.hw-card:hover { transform: translateY(-3px); box-shadow: 0 2px 4px rgba(26, 21, 48, .05), 0 24px 48px -18px rgba(26, 21, 48, .28); }
.hw-card .art { position: relative; height: clamp(200px, 19vw, 240px); padding: 30px 0 4px; border-bottom: 1px solid var(--line);   /* the drawing centred below the placeholder's label */
  background: radial-gradient(60% 55% at 50% 100%, rgba(120, 74, 242, .16), transparent 70%), repeating-linear-gradient(-45deg, transparent 0 12px, rgba(79, 18, 203, .04) 12px 24px), var(--bg-2); }
.hw-card .art svg { width: min(62%, 240px); }
.hw-card .art text { font-family: var(--font); }
.hw-card .body { display: flex; flex: 1; flex-direction: column; padding: 22px 24px 24px; }
.hw-card .maker { font-size: 12px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); }
.hw-card h3 { margin-top: 6px; font-size: clamp(22px, calc((min(100vw, 1200px) - 232px) / 31), 28px); letter-spacing: -.03em; }
.hw-card .where { display: block; margin-top: 6px; font-size: clamp(15px, calc((min(100vw, 1200px) - 232px) / 46), 18px); font-weight: 600; color: var(--accent); }
.hw-card p { margin-top: 12px; font-size: 15px; line-height: 1.6; color: var(--text-2); text-wrap: pretty; }
.hw-card .specs { margin: auto 0 0; padding-top: 20px; }
.hw-card .more { display: flex; flex: 1; flex-direction: column; }   /* where, the text and the facts, folding away in the phone's stack (above); the facts still at the card's foot */
.hw-card .hw-ic { display: none; }   /* the device's icon, for the phone's stack only */
.hw-card .specs div { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-top: 1px solid var(--line); font-size: 14px; line-height: 1.4; }
.hw-card .specs div:last-child { padding-bottom: 0; }
.hw-card .specs dt { flex: none; color: var(--text-3); }
.hw-card .specs dd { margin: 0; font-weight: 600; color: var(--ink); text-align: right; }
.hw-card { container-type: inline-size; }
@container (max-width: 300px) {   /* a narrow card (three on a tablet, one on a small phone): each fact's name over it, so none wraps and the rows still line up */
  .hw-card .specs div { flex-direction: column; gap: 1px; padding: 8px 0; }
  .hw-card .specs dt { font-size: 12.5px; }
  .hw-card .specs dd { text-align: left; }
}
@media (max-width: 767px) {
  .hw-card h3 { font-size: clamp(22px, calc((100vw - 96px) / 10.4), 28px); }
  .hw-card .where { font-size: clamp(15px, calc((100vw - 96px) / 15.5), 18px); }
}


/* the closing (Stripe): a question, two buttons, four next steps */
.closing { padding: clamp(40px, 6vw, 80px) 0 clamp(72px, 9vw, 120px); }
.closing .top { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 32px; align-items: end; }
.closing .top .actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 14px 22px; }
.next-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0 32px; margin-top: 48px; border-top: 1px solid var(--line); }
.next { padding: 26px 0 0; }
.next h3 { font-size: 16px; }
.next p { margin-top: 6px; font-size: 14.5px; line-height: 1.55; color: var(--text-2); }
.next .link { margin-top: 10px; font-size: 14.5px; }
@media (max-width: 767px) { .closing .top { grid-template-columns: 1fr; } .closing .top .actions { justify-content: flex-start; } .next-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .next-grid { grid-template-columns: 1fr; } }

/* footer on the brand purple (the founder, 12 Oct: "Make the background of the bottom section of the website the brand
   purple"; the page's pale lavender, under a line, until then): the logo for purple (the bar's), the headings white, the
   words and links white at 80 % (6.2 to 1), lime under the pointer, About (coming) at 65 % and the notes and the legal line
   at 70 % (4.6 and 5.1 to 1), a placeholder lime, the focus ring white (the page's own purple would vanish on it) */
.footer { background: var(--accent); padding: 48px 0 40px; font-size: 13.5px; color: rgba(255, 255, 255, .8); }
.footer-cols { display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 28px; }
.footer h4 { font-size: 13px; font-weight: 590; color: #fff; margin-bottom: 14px; }
.footer ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.footer a:hover { color: var(--lime); }
.footer :focus-visible { outline-color: #fff; }
.footer .dim { color: rgba(255, 255, 255, .65); }
.footer .notes { margin-top: 40px; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, .18); display: grid; gap: 8px; font-size: 12.5px; line-height: 1.5; color: rgba(255, 255, 255, .7); max-width: 90ch; }
.footer .legal { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 20px; margin-top: 22px; font-size: 12.5px; color: rgba(255, 255, 255, .7); }
.footer .legal .ph { color: var(--lime); }
@media (max-width: 767px) { .footer-cols { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .footer-cols { grid-template-columns: 1fr; } }

/* placeholders */
.ph-art { display: grid; place-items: center; height: 100%; color: var(--text-3); background: repeating-linear-gradient(-45deg, transparent 0 12px, rgba(79, 18, 203, .04) 12px 24px), var(--bg-2); }
.ph-art svg { width: 44%; }
.ph-label { position: absolute; left: 14px; top: 12px; z-index: 1; padding: 4px 9px; border-radius: 999px; border: 1px solid var(--line-2); background: #fff; font-size: 11px; font-weight: 590; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }

/* motion */
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }
.js .cards3 > .reveal:not(.in) { transform: translateY(32px); }   /* the photo cards rise further, one after another (hybrid.js; the founder, 30 Sep: "Have the cards reveal sequentially via a fade-in and up") */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .shot-frame { transform: none !important; transition: none; }
  .float { animation: none; }
  .step .sd, .step.on .sd, .step h3, .step .num, .step::before { transition: none; }
  .story-caption.swap { animation: none; }
}

/* review only (the founder, 28 Sep): a switch to see the page as a phone shows it: the page itself, in a frame an iPhone's
   screen wide (390 x 844), so its own phone layout applies. Hidden on a phone, which shows that already. Remove before launch */
.viewtoggle { position: fixed; right: 16px; bottom: 16px; z-index: 70; display: flex; gap: 2px; padding: 4px; border-radius: 999px; background: rgba(21, 12, 51, .86); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); box-shadow: 0 12px 30px -10px rgba(0, 0, 0, .5); }
.viewtoggle button { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px 0 12px; border: 0; border-radius: 999px; background: transparent; color: rgba(255, 255, 255, .78); font: 600 13px var(--font); cursor: pointer; }
.viewtoggle button:hover { color: #fff; }
.viewtoggle button[aria-pressed="true"] { background: #fff; color: var(--accent); }
.viewtoggle svg { width: 16px; height: 16px; }
.mobileview { position: fixed; inset: 0; z-index: 65; display: grid; place-items: center; background: rgba(21, 12, 51, .8); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.mobileview[hidden] { display: none; }
.mv-device { padding: 12px; border-radius: 54px; background: #12101c; box-shadow: 0 40px 90px -24px rgba(0, 0, 0, .7), inset 0 0 0 2px #2a2640; }
.mv-device iframe { display: block; width: 390px; height: 844px; border: 0; border-radius: 42px; background: #fff; }
.mv-note { position: absolute; left: 0; right: 0; bottom: 22px; margin: 0; text-align: center; font-size: 12.5px; color: rgba(255, 255, 255, .62); }
html.mv-open { overflow: hidden; }
html.in-phone { scrollbar-width: none; }                   /* a phone's scrollbars take no room */
html.in-phone::-webkit-scrollbar { display: none; }
@media (max-width: 600px) { .viewtoggle, .mobileview { display: none; } }
