/* Sand Valley Studio
   Built from Figma file 2kyV9aldZfkoaLyxESrcog: desktop frame 5:10101 (1920 wide),
   phone frame 21:4 (402 wide). Every screen is one viewport tall and split into three
   bands by the grey rules. Sizes and horizontal positions use --u (one design pixel,
   scaled to the page width); vertical positions are percentages of the screen, so the
   bands follow the viewport height. */

@font-face {
  font-family: "AR One Sans";
  src: url("../fonts/ar-one-sans-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #f5f5f5;
  --orange: #ff6400;
  --line: #686868;
  --u: calc(100vw / 1920);            /* the fixed header measures the viewport */
  --bar: calc(110 * var(--u));        /* the compact header, always on screen past the hero */
  --screen: calc(100svh - var(--bar));  /* one section: the space below the header */
}

*, *::before, *::after { box-sizing: border-box; }

html { background: #000; }

body {
  margin: 0;
  background: #000;
  color: #fff;
  font-family: "AR One Sans", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* The page measures its own width, so a desktop scrollbar never causes sideways overflow.
   Kept off <body>: older Safari treated such a container as the box for fixed elements. */
main { display: block; container-type: inline-size; --u: calc(100cqw / 1920); }

p, h1, h2 { margin: 0; font-size: inherit; font-weight: inherit; }
a { color: inherit; text-decoration: none; }
img { display: block; }
sup { line-height: 1; }

/* Every section fits the space below the header, as in the storyboard frames (a 965px panel
   under the 110px bar); only the hero is a full screen, with the header over it. */
.screen { position: relative; height: var(--screen); overflow: hidden; }

.rule {
  position: absolute;
  left: calc(50 * var(--u));
  right: calc(50 * var(--u));
  top: var(--at);
  border-top: max(1px, calc(1.327 * var(--u))) solid var(--line);
}

.box { position: absolute; background: #000; }

.sq {
  display: inline-block;
  flex: none;
  width: calc(21.231 * var(--u));
  height: calc(21.231 * var(--u));
  background: var(--orange);
}

/* Shared type */
.hero-box, .regional-title, .inbuild-box {
  font-size: calc(49.097 * var(--u));
  line-height: 1.1;
  letter-spacing: calc(-3.4368 * var(--u));
  color: var(--ink);
}

.pillars-intro, .regional-sub p, .inbuild-text {
  font-size: calc(21.231 * var(--u));
  line-height: 1.35;
  letter-spacing: calc(-0.6369 * var(--u));
  color: var(--ink);
}

.hero-title, .metrics-title {
  font-weight: 500;
  font-size: calc(77.72 * var(--u));
  line-height: 1.04;
  letter-spacing: calc(-1.943 * var(--u));
  text-align: center;
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 10;
  height: calc(162.751 * var(--u));
  pointer-events: none;
}
.site-header > * { pointer-events: auto; }

/* The black bar with its deeper tab under the logo (Figma "Union"). It takes clicks itself, so
   nothing passing underneath can be clicked through it. */
.site-header::before,
.site-header::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  background: #000;
  pointer-events: auto;
  transition: height .45s ease;
}
.site-header::before { right: 0; height: calc(108.643 * var(--u)); }
.site-header::after { width: calc(766.764 * var(--u)); height: calc(162.751 * var(--u)); }

.site-header .logo {
  position: absolute;
  z-index: 1;
  left: calc(162.58 * var(--u));
  top: calc(65.08 * var(--u));
  transform-origin: 0 0;
  transition: transform .45s ease;
}

.logo { display: flex; align-items: flex-start; gap: calc(14.16 * var(--u)); }
/* The mark from Figma "Logos" frame 3 (1058:1011), sized to the word as there: at a 48.366px
   word it is 94.36 x 37.233, 16.06 from it and 3.14 below its top (Victor, 16-10). */
.logo-mark { flex: none; width: calc(83.2 * var(--u)); height: calc(32.83 * var(--u)); margin-top: calc(2.77 * var(--u)); }
.logo-word {
  font-weight: 600;
  font-size: calc(42.642 * var(--u));
  line-height: .9;
  letter-spacing: calc(-2.985 * var(--u));
  white-space: nowrap;
}
.logo-word sup {
  font-weight: 700;
  font-size: calc(8.828 * var(--u));
  letter-spacing: calc(-0.618 * var(--u));
  vertical-align: top;
  margin-left: calc(-1.5 * var(--u));
}

.nav {
  position: absolute;
  z-index: 1;
  left: calc(1472.57 * var(--u));
  top: calc(41.14 * var(--u));
  display: flex;
  gap: calc(43.79 * var(--u));
  font-weight: 500;
  font-size: calc(18.577 * var(--u));
  line-height: 1.5;
  letter-spacing: calc(-0.4273 * var(--u));
  color: #fffafa;
}
.nav .is-accent { color: var(--orange); }

.menu-toggle { display: none; }

/* Once scrolled, the header is the compact 110px bar of the storyboard frames and stays there;
   the sections are laid out below it. */
.site-header.is-compact::before,
.site-header.is-compact::after { height: var(--bar); }
.site-header.is-compact .logo { transform: translateY(calc(-23.5 * var(--u))) scale(.6811); }

/* ---------- 1. Hero ---------- */

.hero { height: 100svh; }

/* The designer's video, with no tint: full-bleed on desktop (Figma layer 97:3, 1920x1080); on
   phones in the band the phone design gives it (126:2), in the phone block below. */
.hero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.hero-title { position: absolute; left: 0; right: 0; top: 45.1%; }

.hero-by {
  position: absolute;
  left: calc(162.63 * var(--u));
  bottom: 3.27%;
  display: flex;
  align-items: center;
  gap: calc(14.87 * var(--u));
  font-weight: 500;
  font-size: calc(26.539 * var(--u));
  line-height: 1.5;
  letter-spacing: calc(-0.6104 * var(--u));
}

.hero-box {
  right: 0;
  bottom: 0;
  width: calc(621.07 * var(--u));
  height: calc(177.81 * var(--u));
  padding: calc(33.84 * var(--u)) 0 0 calc(60.69 * var(--u));
}

/* ---------- 2. Pillars ---------- */

.pillars { --pillars-rule-1: 33.333%; --pillars-rule-2: 66.667%; }

.pillars-intro { position: absolute; left: calc(162.63 * var(--u)); top: 2.6%; }

.pillar {
  position: absolute;
  left: calc(49.63 * var(--u));
  transform: translateY(-50%);
  font-size: calc(170.678 * var(--u));
  line-height: 1.02;
  letter-spacing: calc(-5.1203 * var(--u));
  white-space: pre;
}
.p1 { top: 16.667%; }
.p2 { top: 50%; }
.p3 { top: 83.333%; }

.pillar .no {
  position: absolute;
  top: 0;
  font-weight: 600;
  font-size: calc(45.514 * var(--u));
  line-height: 1.1;
  letter-spacing: calc(-3.186 * var(--u));
  color: var(--orange);
}
.p1 .no { left: calc(1534.34 * var(--u)); }
.p2 .no { left: calc(1352.36 * var(--u)); }
.p3 .no { left: calc(1161.91 * var(--u)); }

/* ---------- 3. Regional advantage ---------- */

.regional-media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.regional .box { width: var(--bw); height: var(--bh); }

.regional-title {
  --bw: calc(618.36 * var(--u));
  --bh: calc(177.81 * var(--u));
  left: 0;
  top: 0;
  padding: calc(30.89 * var(--u)) 0 0 calc(162.63 * var(--u));
}

.regional-sub {
  --bw: calc(626.73 * var(--u));
  --bh: calc(177 * var(--u));
  right: 0;
  bottom: 0;
  padding: calc(59.5 * var(--u)) 0 0 calc(65.92 * var(--u));
}
.regional-sub p { width: calc(353.92 * var(--u)); }

/* ---------- 4. Sectors ---------- */

.sectors {
  --sectors-rule-1: 33.333%;
  --sectors-rule-2: 66.667%;
  --row-travel: 100cqw;                                /* from just past the right edge */
  /* The moving row's shift that puts FinTech, then Blockchain, then Digital Assets where
     PropTech sits here (the words' positions measured in this font; PropTech needs none). */
  --x0: calc(675.94 * var(--u));
  --x2: calc(-798.67 * var(--u));
  --x3: calc(-1735 * var(--u));
  --exit: calc(-1307 * var(--u));                      /* Digital Assets' right edge past the left edge */
  --mid: 50%;                                          /* the metrics' line, where the bottom rule goes */
}

.sectors-lead {
  position: absolute;
  left: calc(1292.83 * var(--u));
  top: 14.76%;
  display: flex;
  align-items: center;
  gap: calc(16.64 * var(--u));
  font-weight: 500;
  font-size: calc(26.539 * var(--u));
  line-height: 1.5;
  letter-spacing: calc(-0.6104 * var(--u));
}
/* Its two halves fade in one after the other; each is one box, so on phones they are its two
   lines. */
.sectors-lead :is(.lead-1, .lead-2) { display: inline-block; }

.sector-row {
  position: absolute;
  white-space: pre;
  color: #414141;
}
.sector-row .is-on { color: #fff; }
.sector-row.d {
  left: calc(-454.61 * var(--u));
  top: 49.44%;
  transform: translateY(-50%);
  font-size: calc(170 * var(--u));
  line-height: 1.02;
  letter-spacing: calc(-5.1 * var(--u));
}
.sector-sq { position: absolute; }
.sector-sq.d { left: calc(153.59 * var(--u)); top: 50%; transform: translateY(-50%); }

/* ---------- 5. Metrics (split image) ---------- */

.metrics { --metrics-rule-1: 33.333%; --metrics-rule-2: 66.667%; --mid: 50%; --half: 16.667%; }

/* The picture and its title sit in one layer, so the opening "slit" reveals both. */
.metrics-slit { position: absolute; inset: 0; }

/* The same picture twice, halves swapped: the left half shows its right side. */
.metrics-media { position: absolute; inset: 0; display: flex; }
.metrics-media .half { width: 50%; height: 100%; object-fit: cover; }
.metrics-media .left { object-position: 100% 50%; }
.metrics-media .right { object-position: 0 50%; }

.metrics-title { position: absolute; left: 0; right: 0; top: 50.19%; transform: translateY(-50%); }

/* The back of the word "Model." (a copy of the table section, made by site.js) is only part of
   the motion, stage 2 below. */
.flip-back { display: none; }

/* ---------- 6. Model (comparison table) ---------- */

.model { --model-rule-1: 33.333%; --model-rule-2: 66.667%; }

.model-title {
  left: calc(288.29 * var(--u));
  top: 5.54%;
  background: none;
  font-size: calc(31.564 * var(--u));
  line-height: 1.1;
  letter-spacing: calc(-2.2095 * var(--u));
  color: var(--ink);
}

.compare {
  position: absolute;
  left: calc(288.29 * var(--u));
  top: calc(33.333% - 71.66 * var(--u));
  border-collapse: collapse;
}
.compare thead, .compare tbody { display: block; }
.compare tr {
  display: grid;
  grid-template-columns: calc(301.63 * var(--u)) calc(305.6 * var(--u)) calc(290.72 * var(--u)) calc(253.88 * var(--u)) calc(175.25 * var(--u));
  align-items: center;
}
.compare th, .compare td { padding: 0; text-align: left; font-weight: 500; }
.compare thead tr {
  height: calc(71.66 * var(--u));
  background: linear-gradient(to right, transparent calc(224.08 * var(--u)), #e9e9e9 0);
  font-size: calc(21.231 * var(--u));
  line-height: 1.35;
  letter-spacing: calc(-0.6369 * var(--u));
  color: #707070;
}
.compare tbody tr {
  height: calc(var(--screen) / 6);
  font-size: calc(21.231 * var(--u));
  line-height: 1.35;
  letter-spacing: calc(-0.6369 * var(--u));
}
.compare tbody th {
  padding-left: calc(50.4 * var(--u));
  font-size: calc(26.539 * var(--u));
  line-height: 1.19;
  letter-spacing: calc(-0.7962 * var(--u));
}
.compare .us { background: linear-gradient(to right, var(--orange) calc(7.96 * var(--u)), #313131 0); color: #fff; }
.compare .them { background: linear-gradient(to right, #313131 calc(7.96 * var(--u)), #1e1e1e 0); color: #919191; }
.compare .them td { font-weight: 400; }

.vs {
  display: grid;
  place-items: center;
  background: #d9d9d9;
  color: #1e1e1e;
  font-weight: 500;
  line-height: 1.19;
}
.model > .vs {
  position: absolute;
  left: calc(338.69 * var(--u));
  top: calc(50% - 18.91 * var(--u));
  width: calc(42.46 * var(--u));
  height: calc(34.5 * var(--u));
  font-size: calc(18.577 * var(--u));
  letter-spacing: calc(-0.5573 * var(--u));
}

.compare-m { display: none; }

.ppp {
  position: absolute;
  left: calc(148.15 * var(--u));
  top: 83.21%;
  transform: translateY(-50%);
  white-space: nowrap;
  font-size: calc(54.207 * var(--u));
  line-height: 1.19;
  letter-spacing: calc(-1.6262 * var(--u));
  color: #9e9e9e;
  --off: #414141;                                      /* the three words before they light up */
}
.ppp b { position: relative; font-weight: 500; color: #fff; }
.ppp-set + .ppp-set { display: none; }                 /* the ticker's second copy (site.js), motion only */
.count-show { display: none; }                         /* the table's counting figures (site.js), motion only */
.ppp .ico {
  position: absolute;
  left: calc(100% - 6 * var(--u));
  top: calc(-15.1 * var(--u));
  width: calc(21.23 * var(--u));
  height: auto;
}

/* ---------- 7. In Build ---------- */

.inbuild { --inbuild-rule: 66.667%; }

/* The picture fills the screen, stretched as Figma shows it (storyboard 18:592); a black panel
   covers it below the top band and carries the "Currently in Build." box on its top edge. */
.inbuild-media { position: absolute; inset: 0; }
.inbuild-media img { width: 100%; height: 100%; object-fit: fill; }
.inbuild-panel { position: absolute; inset: 0; }
.inbuild-panel::before { content: ""; position: absolute; inset: 33.333% 0 0; background: #000; }

.inbuild-box {
  right: 0;
  top: calc(33.333% - 175.2 * var(--u));
  width: calc(625.98 * var(--u));
  height: calc(175.2 * var(--u));
  padding: calc(64.27 * var(--u)) 0 0 calc(95.97 * var(--u));
}

.qantara {
  position: absolute;
  left: calc(777.08 * var(--u));
  top: calc(66.667% - 193.41 * var(--u));
  width: calc(952.06 * var(--u));
  height: calc(220.35 * var(--u));
}

.inbuild-kicker {
  position: absolute;
  left: calc(221.23 * var(--u));
  bottom: 33.333%;
  font-size: calc(33.174 * var(--u));
  line-height: 1.25;
  letter-spacing: calc(-0.9952 * var(--u));
  color: var(--ink);
}

.inbuild-text {
  position: absolute;
  left: calc(221.23 * var(--u));
  top: calc(66.667% + 76.88 * var(--u));
  width: calc(353.92 * var(--u));
}

.next {
  position: absolute;
  left: calc(1373.62 * var(--u));
  top: calc(66.667% + 205.86 * var(--u));
  font-size: calc(26.539 * var(--u));
  white-space: nowrap;
}
.next .n { display: inline-block; width: calc(59.27 * var(--u)); margin-right: calc(-0.28em); font-weight: 600; color: var(--orange); }
.next .a { color: #acacac; }
.next .b { color: #3d3d3d; }

/* ---------- 8. Contact + footer ---------- */

.contact-media { position: absolute; left: 0; top: 0; width: 100%; height: 66.667%; display: block; }
.contact-media img { width: 100%; height: 100%; object-fit: cover; }
.contact-media::before,
.contact-media::after { content: ""; position: absolute; top: 0; bottom: 0; }
.contact-media::before { left: 0; width: calc(397.7 * var(--u)); background: #000; }
.contact-media::after { left: calc(397.42 * var(--u)); width: calc(358.28 * var(--u)); background: linear-gradient(to right, #000, transparent); }

.shower {
  position: absolute;
  left: calc(209.75 * var(--u));
  top: 24.95%;
  font-size: calc(99.522 * var(--u));
  line-height: 1.02;
  letter-spacing: calc(-2.9856 * var(--u));
}

.pitch {
  position: absolute;
  left: calc(1129.61 * var(--u));
  top: 30%;
  font-size: calc(33.174 * var(--u));
  line-height: 1.35;
  letter-spacing: calc(-0.9952 * var(--u));
}
.pitch b { font-weight: 600; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: calc(60.8 * var(--u));
  width: calc(186.81 * var(--u));
  height: calc(53.05 * var(--u));
  background: var(--orange);
  color: #fff;
  font-weight: 700;
  font-size: calc(21.231 * var(--u));
  line-height: 1;
  letter-spacing: calc(-0.6369 * var(--u));
}

.site-footer { position: absolute; left: 0; right: 0; top: 66.667%; bottom: 0; }

.logo-foot {
  position: absolute;
  left: calc(225.04 * var(--u));
  top: calc(125.29 * var(--u));
  align-items: center;
  gap: calc(12.59 * var(--u));
}
.logo-foot .logo-mark { width: calc(147.98 * var(--u)); height: calc(58.39 * var(--u)); margin-top: 0; }
.logo-foot .logo-word { font-size: calc(37.921 * var(--u)); letter-spacing: calc(-2.6545 * var(--u)); }
.logo-foot .logo-word sup { font-size: calc(7.851 * var(--u)); }

.contacts {
  position: absolute;
  left: calc(1129.61 * var(--u));
  top: calc(145.6 * var(--u));
  display: grid;
  grid-template-columns: calc(159.81 * var(--u)) calc(159.37 * var(--u)) auto;
  white-space: nowrap;
  font-size: calc(18.577 * var(--u));
  line-height: 1.55;
  letter-spacing: calc(-0.5573 * var(--u));
  color: var(--ink);
}
.contacts .k { font-weight: 600; color: var(--orange); }

.foot-rule { --at: calc(100% - 1px); }

.owner {
  position: absolute;
  left: calc(225.04 * var(--u));
  bottom: calc(20.26 * var(--u));
  font-weight: 500;
  font-size: calc(21.231 * var(--u));
  line-height: 1.5;
  letter-spacing: calc(-0.4883 * var(--u));
}

.legal {
  position: absolute;
  left: calc(1129.61 * var(--u));
  bottom: calc(22.12 * var(--u));
  display: grid;
  grid-template-columns: calc(334.4 * var(--u)) auto;
  white-space: nowrap;
  font-size: calc(15.923 * var(--u));
  line-height: 1.55;
  letter-spacing: calc(-0.4777 * var(--u));
  color: var(--ink);
}

/* ---------- Brand book (public/brand.html) ---------- */

/* The book is shown as its own pages, one under another at the site's content width, so it reads
   in the page instead of opening a PDF viewer. The pages come from tools/render-brand.sh; the
   book's pages are not all the same shape, so each keeps its own. */
.brand {
  padding: calc(var(--bar) + 72 * var(--u)) calc(162.63 * var(--u)) calc(120 * var(--u));
}

.brand-title {
  font-weight: 500;
  font-size: calc(120 * var(--u));
  line-height: 1;
  letter-spacing: calc(-3.6 * var(--u));
  color: var(--ink);
}

.brand-pages {
  margin-top: calc(60 * var(--u));
  display: flex;
  flex-direction: column;
  gap: calc(40 * var(--u));
}

/* A page edge in the book's own Graphite, so a page that is black to its corners still reads as
   a page on the black ground. */
.brand-pages img {
  width: 100%;
  height: auto;
  border: max(1px, calc(1.327 * var(--u))) solid #282b2b;
}

/* ---------- 404 page (public/404.html) ---------- */

/* One full screen in the site's three bands: the "404" across the middle band (drawn in sand by
   sand.js, which then fades the heading itself out), a line and a way home below. */
.notfound { position: relative; height: 100svh; overflow: hidden; }

.nf-code {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-weight: 500;
  font-size: calc(360 * var(--u));
  line-height: 1;
  letter-spacing: calc(-10.8 * var(--u));
  text-align: center;
  color: #ab5c22;                     /* the colour the sand number averages, measured off a frame */
}

/* Whoever does not get the sand (reduced motion, no WebGL, or the moment before it starts) sees
   the number in the sand's own colours rather than white: the flat colour above, and where the
   browser can paint text from a background, a little of the palette's range across it. */
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .nf-code {
    color: transparent;
    background: linear-gradient(100deg, #c2702c, #ab5c22 45%, #9d501d);
    -webkit-background-clip: text;
    background-clip: text;
  }
}
/* Once sand.js is drawing, the heading itself fades out of the way (it stays in the page for
   screen readers), rather than cutting out the moment the first grains arrive. */
.nf-code { transition: opacity .35s ease; }
.sand .nf-code { opacity: 0; }
.nf-sand { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

.nf-line {
  position: absolute;
  left: calc(162.63 * var(--u));
  top: 83.333%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: calc(14.87 * var(--u));
  font-weight: 500;
  font-size: calc(26.539 * var(--u));
  line-height: 1.5;
  letter-spacing: calc(-0.6104 * var(--u));
}

.nf-home {
  position: absolute;
  right: calc(162.63 * var(--u));
  top: 83.333%;
  margin-top: 0;
  transform: translateY(-50%);
}

/* ================= Motion ================= */

/* Hero intro on load (storyboard 3:52, 3:143, 3:169): black, then the title as a cut-out with
   the orange-tinted skyline showing through its letters, then the black lifts and the title
   turns white. The letters carry the skyline themselves: the video opens on a dark shot, so
   letters cut through to it would barely show. */
.hero-knock { display: none; }
.hero-knock .hero-title {
  padding-bottom: .3em;             /* the fill below the line too, for the tail of the "g" */
  color: transparent;
  background: linear-gradient(89.55deg, rgba(255, 100, 0, .6) 1.43%, rgba(153, 60, 0, .1) 99.68%),
    url("../img/skyline.webp") 50% 30% / 100% auto;
  background-blend-mode: multiply;
  -webkit-background-clip: text;
  background-clip: text;
}

@keyframes appear { from { opacity: 0; } }
@keyframes lift { to { opacity: 0; visibility: hidden; } }

/* Sections that hold in place. A .pin wrapper is taller than one section by --len sections; its
   .pin-stage sticks just below the header while the page scrolls through that extra length,
   and site.js sets --p from 0 to 1 over it. --s is the same distance counted in sections, so
   every step below reads as "starts after N sections of scrolling, lasts M". This applies only
   once site.js has added html.pins (so a script that fails to load leaves the still layouts)
   and when the visitor has not asked for reduced motion.
   The grey rules of a stage draw out from their centre (--d, 0 to 1) while its content comes in.
   Pace (Victor, 18-09: the metrics opening "is super smooth and glides", make it all like that):
   every move eases in and out (smoothstep, as the metrics opening does) and none crosses the
   screen much faster than twice the scroll, so a long move gets a long stretch of scrolling.

   Stage 1: pillars, then the regional picture, then sectors
   0 to 1.8     the three pillar lines slide in from the right, faded until they land, one after
                another, each drawing out the rule below it as it comes (Frames 40-42)
   1.8 to 2     all three in place
   2 to 3.2     the black panel slides off to the left, its text dimming to 30%, and uncovers the
                regional picture (Frames 43-45, image 15)
   3.2 to 3.65  the two text boxes grow out of their corners (image 16)
   4 to 5       they keep growing until the screen is black, their text fading (images 17-19)
   5 to 5.95    the sectors rules draw out while the lead line fades in where it sits, in three
                steps: its square, then "Global infrastructure.", then "Built from the UAE."
                (Victor, 18-09)
   6 to 7.1     only then the sector row comes in from the right, landing with FinTech next to
                the square, white (Frames 36-39 had it from the left, landing on PropTech;
                changed at Victor's request 18-09)
   7.5          past here the row steps on to PropTech: the white passes to it, the square turns
                a quarter and pops. A step runs in time (0.55 s) once the scroll passes its point,
                so the row never rests between two words, and runs back the same way (Victor,
                18-09: "I want it to be snappy")
   8            and on to Blockchain
   8.5          and on to Digital Assets (Victor, 16-10)
   8.9 to 9.45  on into the metrics (Victor, 18-09), all in one move: the whole screen goes up
                while Digital Assets and the square go left, fading as they go; the bottom rule
                goes up with it, more slowly, and settles in the middle just as the last of the
                rest leaves the screen. The metrics stage is already under this one with its line
                in the same place, and this one turns see-through at 9.45.
   Around that point both stages are held in place for a section either side (this one to
   10.45, the metrics one from a section before), so the swap is between two still, identical
   frames even when a phone's scroll update arrives a frame late (Victor, 18-09: "some bars
   flicker around if you do it to fast").
   Stage 2: metrics, then the table. Its pin starts under the end of stage 1 and its sections
   count from the swap (--s is -1 when it is first held).
   0 to 0.9     the line opens into a slit that shows the picture, until the two lines sit on
                the thirds (18:22, 18:29)
   0.9 to 1.6   the slit keeps opening past them to the full picture (18:42, 18:51), and the
                two lines fade out from 1 to 1.5 (Victor, 18-09)
   1.8 to 3     "Model." turns over, right to left, and the view zooms into it: on its back is
                the table section, which grows until it is the screen (Victor, 18-09; the
                storyboard had the table panel rise from the bottom, 18:434 to 18:348)
   3 to 3.7     the real table section has taken over; its rules draw out, its figures count up
                from 0 (1.6 s), and the People / Proof / Power line runs as a ticker, each of
                the three words lighting up at the middle of the screen (Victor, 18-09)
   3.9 to 4.3   the table dims to half (18:713), the ticker still running
   Stage 3: In Build
   0 to 1       the black panel with the "Currently in Build." box rises over the full-screen
                picture, leaving its top band (Frame 31 to Frame 35)
   0.8 to 1.4   the rule draws out (Frame 35)
   1.3 to 2.2   Qantara, the kicker, then the text and "Venture two" (Frames 32-34) */
.pin { position: relative; }
/* The menu's targets: the sections here; with the pin, the moments worth landing on. */
.pin-mark { position: absolute; left: 0; top: 0; scroll-margin-top: var(--bar); }
#sectors { top: var(--screen); }

.pillars { --travel: calc(1886.7 * var(--u)); }        /* from just past the right edge to home */

/* The sector row's steps from word to word (0 or 1 each, see Stage 1) run in time, not with the
   scroll: typed numbers, so a transition can run on them. */
@property --w1 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --w2 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --w3 { syntax: "<number>"; inherits: true; initial-value: 0; }

@media (prefers-reduced-motion: no-preference) {
  /* The black sits over the by-line and the box too (storyboard 3:52 is black); the real
     title sits above it so the two titles cross over as the black lifts. */
  .hero-knock {
    display: block;
    position: absolute;
    z-index: 1;
    inset: 0;
    background: #000;
    animation: lift 1.2s ease 2.2s both;
  }
  .hero-knock .hero-title { animation: appear 1s ease .4s both; }
  .hero > .hero-title { z-index: 2; animation: appear 1.2s ease 2.2s both; }

  .pins .pin { --s: calc(var(--p, 0) * var(--len)); height: calc(var(--screen) * (1 + var(--len))); }
  .pins .pin-stage { position: sticky; top: var(--bar); height: var(--screen); overflow: hidden; }
  .pins .pin-stage > .screen { position: absolute; inset: 0; }
  .pins .pin .rule { scale: var(--d, 1) 1; }

  /* Stage 1 */
  /* The stage sits above the metrics stage and turns see-through at 9.45, where that one shows
     the same line; it stays held, unseen, one more section. */
  .pins .pin-pillars { --len: 10.45; z-index: 1; }
  .pins .pin-pillars .pin-stage { opacity: clamp(0, (9.45 - var(--s)) * 100000, 1); }
  .pins #studio { top: calc(1.9 * var(--screen)); }       /* all three lines in place */
  .pins #sectors { top: calc(3.8 * var(--screen)); }      /* regional picture with its boxes */

  .pins .pillars {
    z-index: 2;
    background: #000;
    --tp: clamp(0, (var(--s) - 2) / 1.2, 1);
    --ep: calc(var(--tp) * var(--tp) * (3 - 2 * var(--tp)));
    --fade: calc(1 - .7 * clamp(0, var(--ep) / .4386, 1));      /* 30% once 842 of 1920 gone */
    translate: calc(-100% * var(--ep)) 0;
    will-change: translate;
  }
  /* Each rule draws with the line above it (Victor, 17-09): the second only starts when the
     second line does. The third is the phones' bottom rule. */
  .pins .pillar, .pins .pillars .rule {
    --t: clamp(0, (var(--s) - var(--in)) / 1.1, 1);
    --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
  }
  .pins .pillar {
    translate: calc((1 - var(--e)) * var(--travel)) 0;
    opacity: calc((.3 + .7 * clamp(0, (var(--e) - .5) / .35, 1)) * var(--fade));
    will-change: translate, opacity;
  }
  .pins .pillars .rule { --d: var(--e); }
  .pins .p1, .pins .pillars .r1 { --in: 0; }
  .pins .p2, .pins .pillars .r2 { --in: .35; }
  .pins .p3, .pins .pillars .r3 { --in: .7; }
  .pins .pillars-intro { opacity: var(--fade); }

  /* The boxes' black is a layer that grows from the box's own corner (the text stays put):
     from nothing to the box (--e1), then on to full width and 55% of the height each (--e2). */
  .pins .regional .box {
    --g1: clamp(0, (var(--s) - 3.2) / .45, 1);
    --g2: clamp(0, (var(--s) - 4) / 1, 1);
    --e1: calc(var(--g1) * var(--g1) * (3 - 2 * var(--g1)));
    --e2: calc(var(--g2) * var(--g2) * (3 - 2 * var(--g2)));
    background: none;
    isolation: isolate;
  }
  .pins .regional .box::before {
    content: "";
    position: absolute;
    z-index: -1;
    width: calc(var(--bw) * var(--e1) + (100cqw - var(--bw)) * var(--e2));
    height: calc(var(--bh) * var(--e1) + (var(--screen) * .55 - var(--bh)) * var(--e2));
    background: #000;
  }
  .pins .regional-title::before { left: 0; top: 0; }
  .pins .regional-sub::before { right: 0; bottom: 0; }
  .pins .regional .box > * { opacity: calc(var(--e1) * (1 - var(--e2))); }   /* 50%, 20% in 17, 18 */

  .pins .pin-pillars .sectors {
    z-index: 1;
    --td: clamp(0, (var(--s) - 5) / .75, 1);
    --d: calc(var(--td) * var(--td) * (3 - 2 * var(--td)));
    /* Each step flips from 0 to 1 at its point and eases there in time. */
    --w1: clamp(0, (var(--s) - 7.5) * 100000, 1);        /* on to PropTech */
    --w2: clamp(0, (var(--s) - 8) * 100000, 1);          /* on to Blockchain */
    --w3: clamp(0, (var(--s) - 8.5) * 100000, 1);        /* on to Digital Assets */
    transition: --w1 .55s cubic-bezier(.6, 0, .2, 1), --w2 .55s cubic-bezier(.6, 0, .2, 1), --w3 .55s cubic-bezier(.6, 0, .2, 1);
    /* On into the metrics, everything starting together: the screen up 40% (the top rule off
       it) and Digital Assets left. The bottom rule only goes up a sixth, to the middle, and
       lands as the last of Digital Assets leaves the screen (9.42); the stage ends there and
       the metrics open straight from it (Victor: "it needs to be tighter"). */
    --tx: clamp(0, (var(--s) - 8.9) / .6, 1);
    --tr: clamp(0, (var(--s) - 8.9) / .52, 1);
    --ex: calc(var(--tx) * var(--tx) * (3 - 2 * var(--tx)));
    --er: calc(var(--tr) * var(--tr) * (3 - 2 * var(--tr)));
    --up: calc(-.4 * var(--screen) * var(--ex));
  }
  .pins .sectors :is(.sectors-lead .sq, .lead-1, .lead-2, .sector-row, .sector-sq) {
    --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
  }
  /* The lead line fades in where it sits, a step at a time (Victor, 18-09). */
  .pins .sectors-lead :is(.sq, .lead-1, .lead-2) { opacity: var(--e); }
  .pins .sectors-lead .sq { --t: clamp(0, (var(--s) - 5.05) / .3, 1); }
  .pins .sectors .lead-1 { --t: clamp(0, (var(--s) - 5.3) / .35, 1); }
  .pins .sectors .lead-2 { --t: clamp(0, (var(--s) - 5.6) / .35, 1); }
  .pins .sectors :is(.sectors-lead, .rule.top) { translate: 0 var(--up); }
  .pins .sectors .rule.bottom { top: calc(var(--sectors-rule-2) + (var(--mid) - var(--sectors-rule-2)) * var(--er)); }
  .pins .sectors :is(.sector-row, .sector-sq) {
    --t: clamp(0, (var(--s) - 6) / 1.1, 1);
    translate: calc(var(--row-travel) * (1 - var(--e)) + var(--exit) * var(--ex)) var(--up);
    opacity: calc(1 - min(1, var(--ex) / .95));          /* fading on its way out, gone by the swap */
    will-change: translate;
  }
  /* --w is where the row stands: -1 still coming in, 0 on FinTech, 1 PropTech, 2 Blockchain,
     3 Digital Assets. A word is white on its own spot and fades to the row's grey a word either
     side. */
  .pins .sector-row.moves {
    --w: calc(var(--e) - 1 + var(--w1) + var(--w2) + var(--w3));
    translate: calc(var(--row-travel) * (1 - var(--e)) + var(--x0) * (1 - var(--w1)) + var(--x2) * var(--w2) + (var(--x3) - var(--x2)) * var(--w3) + var(--exit) * var(--ex)) var(--up);
  }
  .pins .sector-row.moves > span {
    --k: 0;
    --h: max(0, min(1 + var(--w) - var(--k), 1 - var(--w) + var(--k)));
    color: color-mix(in srgb, #fff calc(var(--h) * 100%), currentColor);
  }
  .pins .sector-row.moves > :nth-child(2) { --k: 1; }
  .pins .sector-row.moves > :nth-child(3) { --k: 2; }
  .pins .sector-row.moves > :nth-child(4) { --k: 3; }
  .pins .sector-sq {
    rotate: calc(90deg * (var(--w1) + var(--w2) + var(--w3)));
    scale: calc(1 + 2 * (var(--w1) * (1 - var(--w1)) + var(--w2) * (1 - var(--w2)) + var(--w3) * (1 - var(--w3))));   /* 1.5 midway */
  }
  .pins .sector-sq.d { transform-origin: 50% 0; }   /* it is lifted by half its height: turn it about itself */

  /* Stage 2 */
  /* Held from a section before the swap (its pin starts three sections before stage 1's ends),
     its sections counted from the swap. */
  .pins .pin-model {
    --len: 5.3;
    --lead: 1;                                           /* the section held before the swap */
    --land: 3;                                           /* the table section has landed */
    --s: calc(var(--p, 0) * var(--len) - var(--lead));   /* site.js reads these three too */
    margin-top: calc(-3 * var(--screen));
  }
  .pins #model { top: calc(2.7 * var(--screen)); }        /* the full picture, 1.7 after the swap */

  .pins .pin-model .metrics {
    --t1: clamp(0, var(--s) / .9, 1);
    --t2: clamp(0, (var(--s) - .9) / .7, 1);
    --e1: calc(var(--t1) * var(--t1) * (3 - 2 * var(--t1)));
    --e2: calc(var(--t2) * var(--t2) * (3 - 2 * var(--t2)));
    --h: calc(var(--half) * var(--e1) + (var(--mid) - var(--half)) * var(--e2));   /* half the slit */
    --metrics-rule-1: calc(var(--mid) - var(--half) * var(--e1));
    --metrics-rule-2: calc(var(--mid) + var(--half) * var(--e1));
    /* Into the table (Victor, 18-09): "Model." turns over, right to left, with the table section
       on its back, while the view zooms into it until that section fills the screen. site.js
       measures the word in the still picture: --ox/--oy its centre and --w0 its width, --Z the
       zoom at which it is as wide as the screen, --px/--py the point to zoom about so that it
       also ends centred, --clip how much of the back to hide at first so it starts as tall as
       the word. */
    --tf: clamp(0, (var(--s) - 1.8) / (var(--land) - 1.8), 1);
    --ef: calc(var(--tf) * var(--tf) * (3 - 2 * var(--tf)));
    --ov: clamp(0, var(--ef) * 2 - 1, 1);                /* the back grows to full height once round */
    opacity: clamp(0, (var(--land) - var(--s)) * 100000, 1);   /* gone when the table section takes over */
  }
  /* The two lines fade once the black has opened past them (Victor, 18-09). */
  .pins .pin-model .metrics > .rule { opacity: calc(1 - clamp(0, (var(--s) - 1) / .5, 1)); }
  .pins .pin-model .metrics-slit {
    clip-path: inset(max(0%, calc(var(--mid) - var(--h))) 0 max(0%, calc(100% - var(--mid) - var(--h))) 0);
    transform-origin: var(--px, 50%) var(--py, 50%);
    scale: pow(var(--Z, 1), var(--ef));                  /* the zoom, even in its rate */
  }
  .pins .pin-model .flip {
    display: inline-block;
    transform: perspective(calc(2 * var(--w0, 200px))) rotateY(calc(-180deg * var(--ef)));
    /* Each side shows only while it faces the front, switched at edge-on rather than left to
       backface-visibility, which not every engine honours inside a flattened picture. */
    opacity: clamp(0, (.5 - var(--ef)) * 100000, 1);
  }
  /* The back: the whole table section at screen size, shrunk to the word and placed on it, so
     that at full zoom it is exactly the screen. */
  .pins .pin-model .flip-back {
    display: block;
    position: absolute;
    inset: 0;
    background: #000;
    --d: 0;                                              /* its rules draw once it is the real one */
    transform: translate(calc(var(--ox, 50%) - 50%), calc(var(--oy, 50%) - 50%)) scale(calc(1 / var(--Z, 1)))
      perspective(calc(2 * var(--w0, 200px) * var(--Z, 1))) rotateY(calc(180deg * (1 - var(--ef))));
    opacity: clamp(0, (var(--ef) - .5) * 100000, 1);
    clip-path: inset(calc(var(--clip, 0px) * (1 - var(--ov))) 0);
  }
  /* Measured with the zoom and the turn taken off (site.js, on load and resize). */
  .pins.measuring .pin-model :is(.metrics-slit, .flip) { scale: none; transform: none; }
  /* The real table section, which the back has become at 3: it takes over there, on the same
     pixels, and goes on as before. */
  .pins .pin-model .pin-stage > .model {
    --td: clamp(0, (var(--s) - var(--land)) / .7, 1);
    --d: calc(var(--td) * var(--td) * (3 - 2 * var(--td)));
    z-index: 1;
    background: #000;
    opacity: clamp(0, (var(--s) - var(--land)) * 100000, 1);
  }
  /* The line dims by its two moving copies, not as a whole: Safari clips the icons above it
     when the whole line is drawn as one see-through group (seen 18-09, Victor: "get cut off at
     some point when scrolling"). */
  .pins .pin-model .pin-stage > .model > :not(.ppp),
  .pins .pin-model .pin-stage > .model .ppp-set {
    opacity: calc(1 - .5 * clamp(0, (var(--s) - 3.9) / .4, 1));
  }

  /* Its figures count up from 0 once it has landed (Victor, 18-09; site.js counts). The count
     is drawn over the figure itself, which keeps its place in the layout and is what screen
     readers read. */
  .pins .count { position: relative; -webkit-text-fill-color: transparent; }
  .pins .count-show { display: inline; position: absolute; right: 0; top: 0; -webkit-text-fill-color: currentColor; }

  /* The People / Proof / Power line (Victor, 18-09): an endless ticker once the table has
     landed, coming in from off the right edge (site.js moves it and marks the words lit; the
     back of "Model." has no line). All of it starts grey; each of the three
     words turns white, its icon popping in, as it reaches the middle of the screen, and stays
     so. The phrases keep their colours. */
  .pins .ppp:not(.is-running) { visibility: hidden; }   /* until it comes in from the right */
  .pins .ppp-set { display: inline-block; white-space: pre; }
  .pins .ppp b { color: var(--off); transition: color .4s ease; }
  .pins .ppp b.is-lit { color: #fff; }
  .pins .ppp .ico {
    scale: 0;
    opacity: 0;
    transform-origin: 50% 100%;
    transition: scale .5s cubic-bezier(.3, 1.9, .6, 1), opacity .12s;
  }
  .pins .ppp .is-lit .ico { scale: 1; opacity: 1; }

  /* Stage 3 */
  .pins .pin-inbuild { --len: 2.4; }
  .pins #in-build { top: calc(2.4 * var(--screen)); }     /* everything in */

  .pins .pin-inbuild .inbuild {
    --td: clamp(0, (var(--s) - .8) / .6, 1);
    --d: calc(var(--td) * var(--td) * (3 - 2 * var(--td)));
  }
  .pins .inbuild-panel {
    --t: clamp(0, var(--s) / 1, 1);
    --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
    translate: 0 calc(66.667% * (1 - var(--e)));         /* its top edge from the bottom to the band */
  }
  .pins .pin-inbuild .qantara { opacity: clamp(0, (var(--s) - 1.3) / .3, 1); }
  .pins .pin-inbuild .inbuild-kicker { opacity: clamp(0, (var(--s) - 1.6) / .3, 1); }
  .pins .pin-inbuild :is(.inbuild-text, .next) { opacity: clamp(0, (var(--s) - 1.85) / .35, 1); }
}

/* Desktop-only (.d) and phone-only (.m) pieces. Kept after the components so they win. */
.m { display: none; }

/* ================= Phone (Figma frame 21:4, 402 wide, 874 per screen) ================= */

@media (max-width: 767px) {
  :root { --u: calc(100vw / 402); --bar: calc(72 * var(--u)); }
  main { --u: calc(100cqw / 402); }

  .d { display: none; }
  .m { display: revert; }

  .rule { left: calc(30 * var(--u)); right: calc(30 * var(--u)); }
  .sq { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }

  .hero-box, .regional-title, .inbuild-box, .model-title {
    font-size: calc(36 * var(--u));
    letter-spacing: calc(-2.52 * var(--u));
  }
  .pillars-intro, .regional-sub p, .inbuild-text {
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.48 * var(--u));
  }
  .hero-title, .metrics-title {
    font-size: calc(59 * var(--u));
    letter-spacing: calc(-1.475 * var(--u));
  }

  /* Header: the design's 120px bar over the hero, then a compact 72px bar with the logo and
     menu button centred (mine: the phone design has no compact state); the links open as a
     full-screen list below it. */
  .site-header { height: calc(120 * var(--u)); }
  .site-header::before { height: calc(120 * var(--u)); }
  .site-header.is-compact::before { height: var(--bar); }
  .site-header::after { display: none; }
  .site-header .logo { left: calc(32 * var(--u)); top: calc(49.7 * var(--u)); transform: none; }
  .site-header.is-compact .logo { transform: translateY(calc(-25.7 * var(--u))); }
  .logo { gap: calc(8.48 * var(--u)); }
  .logo-mark { width: calc(49.81 * var(--u)); height: calc(19.65 * var(--u)); margin-top: calc(1.66 * var(--u)); }
  .logo-word { font-size: calc(25.53 * var(--u)); letter-spacing: calc(-1.787 * var(--u)); }
  .logo-word sup { font-size: calc(5.3 * var(--u)); }

  .menu-toggle {
    display: block;
    position: absolute;
    z-index: 1;
    left: calc(344.4 * var(--u));
    top: calc(50.7 * var(--u));
    width: calc(26 * var(--u));
    height: calc(20 * var(--u));
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transition: transform .45s ease;
  }
  .is-compact .menu-toggle { transform: translateY(calc(-24.7 * var(--u))); }
  .menu-toggle span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    background: #fff;
    transition: transform .3s ease, opacity .3s ease;
  }
  .menu-toggle span:nth-child(1) { top: 0; }
  .menu-toggle span:nth-child(2) { top: calc(50% - 1px); }
  .menu-toggle span:nth-child(3) { bottom: 0; }
  .is-open .menu-toggle span:nth-child(1) { transform: translateY(calc(10 * var(--u) - 1px)) rotate(45deg); }
  .is-open .menu-toggle span:nth-child(2) { opacity: 0; }
  .is-open .menu-toggle span:nth-child(3) { transform: translateY(calc(-10 * var(--u) + 1px)) rotate(-45deg); }

  .nav {
    position: fixed;
    left: 0;
    right: 0;
    top: calc(120 * var(--u));
    height: calc(100svh - 120 * var(--u));
    display: none;
    flex-direction: column;
    gap: 0;
    padding: 0 calc(30 * var(--u));
    background: #000;
    font-weight: 400;
    font-size: calc(36 * var(--u));
    line-height: 1.1;
    letter-spacing: calc(-2.52 * var(--u));
  }
  .is-compact .nav { top: var(--bar); height: var(--screen); }
  .nav a { padding: calc(28 * var(--u)) 0; border-top: 1px solid var(--line); }
  .is-open .nav { display: flex; }

  /* 1. Hero: the video's whole height in the band from just under the bar to the black strip
     at the bottom, centred, its sides cropped (Figma 126:2: 1269 x 714 at 107 in the 874-tall
     frame; Victor 18-09: "the cropping looks fine, so respect that croping"). On a shorter
     screen the band is shorter and a little more of the width shows. */
  .hero-video {
    top: calc(107.06 * var(--u));
    height: calc(100% - 160.14 * var(--u));              /* down to the 53px strip */
  }
  .hero-title { top: 39.52%; }
  .hero-by {
    left: calc(30 * var(--u));
    bottom: calc(59.13 * var(--u));
    align-items: flex-start;
    gap: calc(10 * var(--u));
    width: calc(159.52 * var(--u));
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.368 * var(--u));
  }
  .hero-by .sq { margin-top: calc(3 * var(--u)); }
  .hero::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: calc(229.87 * var(--u));
    height: calc(53.08 * var(--u));
    background: #000;
  }
  .hero-box {
    width: calc(190 * var(--u));
    height: calc(122 * var(--u));
    padding: calc(12.25 * var(--u)) 0 0 calc(26.87 * var(--u));
  }

  /* 2. Pillars: the three lines are stacked up from the section's bottom edge, each the same
     distance above the rule under it (Victor 18-09: "spacing is off between the 1st row and the
     next 2 when it comes to the line under them"; the design has 48, 90 and 80 of its 874).
     The height left over once the intro and the lines are placed (354 of the design's 874) is
     shared as the design shares it on average: 7.6% under the intro, 20.53% under each line,
     15.42% from each rule to the line below it. On a screen too short to leave 45% of that, the
     lines' size comes down instead (a phone in Safari has about 600 of the design's units, not
     874). --pl-size is their size, --pl-rows their two rows' height. */
  .pillars {
    --pl-size: min(calc(69.579 * var(--u)), calc((.9428 * var(--screen) - 203.3 * var(--u)) / 6.12));
    --pl-rows: calc(2.04 * var(--pl-size));
    --pl-free: calc(.9428 * var(--screen) - 44 * var(--u) - 3 * var(--pl-rows));   /* below the intro */
    --pl-under: calc(.2053 * var(--pl-free));            /* a line's text to the rule under it */
    --pl-over: calc(.1542 * var(--pl-free));             /* a rule to the line below it */
    --pillars-rule-2: calc(100% - var(--pl-under) - var(--pl-rows) - var(--pl-over));
    --pillars-rule-1: calc(100% - 2 * (var(--pl-under) + var(--pl-rows) + var(--pl-over)));
    --travel: calc(376 * var(--u));
  }
  .pillars-intro { left: calc(29.32 * var(--u)); top: 5.72%; width: calc(217.68 * var(--u)); }
  .pillar {
    left: calc(30 * var(--u));
    transform: none;
    font-size: var(--pl-size);
    letter-spacing: -.03em;
  }
  .p1 { top: calc(var(--pillars-rule-1) - var(--pl-under) - var(--pl-rows)); }
  .p2 { top: calc(var(--pillars-rule-2) - var(--pl-under) - var(--pl-rows)); }
  .p3 { top: calc(100% - var(--pl-under) - var(--pl-rows)); }
  .pillar .no {
    top: calc(1.3165 * var(--pl-size));                  /* the design's 91.6 at 69.579 */
    font-size: calc(18.554 * var(--u));
    letter-spacing: calc(-1.2988 * var(--u));
  }
  .p1 .no, .p2 .no { left: calc(4.6089 * var(--pl-size)); }   /* 320.68 */
  .p3 .no { left: calc(3.3487 * var(--pl-size)); }         /* 233 */

  /* 3. Regional advantage */
  .regional-media { inset: 0 auto auto 50%; width: auto; height: 112.4%; max-width: none; transform: translateX(-50%); }
  .regional-title {
    --bw: calc(320 * var(--u));
    --bh: calc(168 * var(--u));
    padding: calc(60 * var(--u)) 0 0 calc(26.87 * var(--u));
  }
  .regional-sub {
    --bw: calc(300 * var(--u));
    --bh: calc(122 * var(--u));
    padding: calc(39 * var(--u)) 0 0 calc(15 * var(--u));
  }
  .regional-sub p { width: calc(270 * var(--u)); }

  /* 4. Sectors */
  .sectors {
    --sectors-rule-1: 35.6%;
    --sectors-rule-2: 68.93%;
    --x0: calc(252.5 * var(--u));
    --x2: calc(-295.81 * var(--u));
    --x3: calc(-639.5 * var(--u));
    --exit: calc(-481 * var(--u));
    --mid: 52.31%;
  }
  .sectors-lead {
    left: calc(30 * var(--u));
    top: 6.86%;
    align-items: flex-start;
    gap: calc(10 * var(--u));
    width: calc(197 * var(--u));
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.368 * var(--u));
  }
  .sectors-lead .sq { margin-top: calc(3 * var(--u)); }
  .sector-row.m {
    font-size: calc(60 * var(--u));
    line-height: 1.02;
    letter-spacing: calc(-1.8 * var(--u));
    color: #343434;
    left: calc(-184.5 * var(--u));                     /* PropTech at 68, as in the design */
    top: 46.91%;
  }
  .sector-sq.m { left: calc(30 * var(--u)); top: 49.58%; }

  /* 5. Metrics */
  .metrics { --metrics-rule-1: 35.64%; --metrics-rule-2: 68.98%; --mid: 52.31%; --half: 16.67%; }
  .metrics-media .left { width: 100%; object-position: 0 50%; }
  .metrics-media .right { display: none; }
  /* Centred on the line the picture opens from, as the design has it at its own height, and
     never taller than the band between the two lines (a phone in Safari shows about 590px of
     section, not the design's 802). */
  .metrics-title {
    top: var(--mid);
    font-size: min(calc(59 * var(--u)), calc(var(--screen) * .09));
    letter-spacing: -.025em;
  }

  /* 6. Model: the table turns into two columns */
  .model .rule, .compare, .model > .vs { display: none; }
  .model-title {
    left: 0;
    top: 0;
    width: calc(320 * var(--u));
    height: calc(168 * var(--u));
    padding: calc(60 * var(--u)) 0 0 calc(26.87 * var(--u));
    background: #000;
  }
  .model-title h2 { width: calc(273.13 * var(--u)); }
  .compare-m {
    position: absolute;
    left: calc(30 * var(--u));
    top: 22.45%;
    display: grid;
    grid-template-columns: repeat(3, calc(114 * var(--u)));
    /* Row heights follow the section height (the design's 6, 115.75 and 104.5 of 874), so the
       table still clears the line below it with the header on screen. */
    grid-template-rows: calc(var(--screen) * .00686) calc(var(--screen) * .1324) repeat(4, calc(var(--screen) * .1196));
    font-weight: 500;
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.48 * var(--u));
    text-align: center;
  }
  .compare-m .us { grid-column: 2; background: #313131; color: #fff; }
  .compare-m .them { grid-column: 3; background: #1e1e1e; color: #919191; }
  .compare-m .c-bar { grid-row: 1; }
  .compare-m .c-bar.us { background: var(--orange); }
  .compare-m .c-bar.them { background: #292929; }
  .compare-m .c-head { grid-row: 2; padding-top: calc(24.22 * var(--u)); line-height: 1.19; }
  .compare-m .c-label,
  .compare-m .c-val { grid-row: var(--row); display: grid; place-items: center; }
  .compare-m .c-label { grid-column: 1; background: #e9e9e9; color: #707070; line-height: 1.2; }
  .compare-m .c-val.them { font-weight: 400; }
  .compare-m .vs {
    position: absolute;
    left: calc(208.46 * var(--u));
    top: calc(var(--screen) * .1078);
    width: calc(40 * var(--u));
    height: calc(28 * var(--u));
    font-size: calc(14 * var(--u));
    letter-spacing: calc(-0.42 * var(--u));
  }

  .ppp {
    left: calc(30 * var(--u));
    top: 89.91%;
    transform: none;
    font-size: calc(28 * var(--u));
    letter-spacing: calc(-0.84 * var(--u));
    color: #4f4f4f;
    --off: #4f4f4f;
  }
  .ppp b ~ b { color: #4f4f4f; }
  .ppp .ico { left: calc(100% - 5 * var(--u)); top: calc(-6 * var(--u)); width: calc(12 * var(--u)); }

  /* 7. In Build */
  .inbuild { --inbuild-rule: 51.56%; }
  .inbuild-media img { object-fit: cover; }            /* stretching to a tall screen would distort it */
  .inbuild-box {
    top: calc(33.333% - 101.82 * var(--u));
    width: calc(190 * var(--u));
    height: calc(101.82 * var(--u));
    padding: calc(12.25 * var(--u)) 0 0 calc(26.87 * var(--u));
  }
  .qantara {
    left: calc(31.76 * var(--u));
    top: calc(51.56% - 69.17 * var(--u));
    width: calc(340.24 * var(--u));
    height: calc(78.75 * var(--u));
  }
  .inbuild-kicker {
    left: calc(30 * var(--u));
    top: calc(51.56% + 56.04 * var(--u));
    bottom: auto;
    font-size: calc(28 * var(--u));
    letter-spacing: calc(-0.84 * var(--u));
  }
  .inbuild-text { left: calc(30 * var(--u)); top: calc(51.56% + 163.27 * var(--u)); width: calc(270 * var(--u)); }
  .next { left: calc(30 * var(--u)); top: calc(51.56% + 362.4 * var(--u)); font-size: calc(16 * var(--u)); }
  .next .n { width: auto; margin-right: 0; }

  /* 8. Contact + footer */
  .contact-media { height: 57.87%; }
  .contact-media::before { display: none; }
  .contact-media::after { left: 0; width: 100%; background: linear-gradient(319.35deg, transparent 27.27%, rgba(0, 0, 0, .7) 80.09%); }
  .shower {
    left: calc(30 * var(--u));
    top: 14.91%;
    font-weight: 500;
    font-size: calc(36 * var(--u));
    line-height: 1.1;
    letter-spacing: calc(-1.8 * var(--u));
    color: var(--ink);
  }
  .pitch {
    left: calc(174 * var(--u));
    top: 28.76%;
    width: calc(198 * var(--u));
    font-size: calc(18 * var(--u));
    letter-spacing: calc(-0.54 * var(--u));
  }
  .btn {
    margin-top: calc(19.1 * var(--u));
    width: calc(125 * var(--u));
    height: calc(46 * var(--u));
    font-size: calc(14 * var(--u));
    letter-spacing: calc(-0.42 * var(--u));
  }

  .site-footer { top: 0; }
  .pitch { z-index: 1; }                               /* above the footer's box, so "Let's talk" takes taps */

  /* 404 */
  .brand {
    padding: calc(var(--bar) + 40 * var(--u)) calc(30 * var(--u)) calc(60 * var(--u));
  }
  .brand-title { font-size: calc(48 * var(--u)); letter-spacing: calc(-1.44 * var(--u)); }
  .brand-pages { margin-top: calc(28 * var(--u)); gap: calc(20 * var(--u)); }

  .nf-code { font-size: calc(150 * var(--u)); letter-spacing: calc(-4.5 * var(--u)); }
  .nf-line {
    left: calc(30 * var(--u));
    top: 76%;
    gap: calc(10 * var(--u));
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.368 * var(--u));
  }
  .nf-home { left: calc(30 * var(--u)); right: auto; top: 86%; margin-top: 0; }
  .logo-foot { left: calc(29.96 * var(--u)); top: 64.99%; gap: calc(9.18 * var(--u)); }
  .logo-foot .logo-mark { width: calc(107.9 * var(--u)); height: calc(42.58 * var(--u)); }
  .logo-foot .logo-word { font-size: calc(27.656 * var(--u)); letter-spacing: calc(-1.9359 * var(--u)); }
  .logo-foot .logo-word sup { font-size: calc(5.725 * var(--u)); }
  .contacts {
    left: calc(26.26 * var(--u));
    top: 76.89%;
    display: flex;
    flex-direction: column;
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.48 * var(--u));
    color: #fff;
  }
  .foot-rule { --at: 88.57%; }
  .owner {
    left: 0;
    right: 0;
    top: 91.24%;
    bottom: auto;
    text-align: center;
    font-size: calc(16 * var(--u));
    letter-spacing: calc(-0.368 * var(--u));
  }
  .legal {
    left: 0;
    right: 0;
    top: 94.14%;
    bottom: auto;
    display: block;
    text-align: center;
    font-size: calc(12 * var(--u));
    line-height: 1.5;
    letter-spacing: calc(-0.36 * var(--u));
  }
  .legal span { display: block; }
}
