/* Monolen company page: the space version, direction "Graphite material".

   One material, used for every frame and for the floating bar: graphite glass.
   It is dark, a little see-through, and it blurs the sky behind it. A fine light edge runs along
   the top and a soft shadow falls below. Notes on the system are in DESIGN.md, in the project folder.

   The page works in two ways:
   1. Still. No JavaScript is needed. The background is the still sky in .sky-fallback.
   2. Moving. js/main.js adds the class "scene-on" to <html> when the sky can run on the canvas. */

@font-face {
  font-family: "Ysabeau Office";
  src: url("assets/fonts/ysabeau-office.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* Colour: two tones of text, one accent, one material. */
  --space: #000000;
  --ink: #f2f3f5;            /* text */
  --ink-soft: #c6c9d1;       /* quieter text */
  --accent: #ffb69b;         /* the sunlit edge of the planet, taken from the sky. Only on things you can act on. */
  --accent-up: #ffc7b1;      /* the accent under the pointer */
  --accent-down: #f0a58a;    /* the accent while pressed */
  --on-accent: #1b1310;      /* text on the accent */

  /* The material. The fill is solid enough for text to stay readable over the brightest dawn. */
  --glass: rgb(36 38 44 / 0.8);
  --glass-plain: rgb(31 33 38 / 0.96);   /* where the browser cannot blur */
  --glass-raised: rgb(58 60 66 / 0.82);  /* a control resting on the bar: the glass with a little more light in it */
  --frost: blur(28px) saturate(180%) brightness(1.8);
  /* The edge: bright along the top, fading down the sides. */
  --edge: linear-gradient(180deg, rgb(255 255 255 / 0.42) 0, rgb(255 255 255 / 0.16) 1.5rem, rgb(255 255 255 / 0.07) 5rem, rgb(255 255 255 / 0.05) calc(100% - 1.5rem), rgb(255 255 255 / 0.11) 100%);
  --edge-plain: inset 0 0.0625rem 0 rgb(255 255 255 / 0.22), inset 0 0 0 0.0625rem rgb(255 255 255 / 0.07);
  /* Inside: a soft sheen under the top edge, and the foot falls into shade. Neither reaches the words. */
  --shade: inset 0 1.25rem 1.25rem -1rem rgb(255 255 255 / 0.09), inset 0 -3rem 3rem -3rem rgb(0 0 0 / 0.35);
  /* Outside: a dark hairline, then a soft shadow below. */
  --lift: 0 0 0 0.0625rem rgb(0 0 0 / 0.5), 0 0.25rem 0.75rem rgb(0 0 0 / 0.28), 0 1.75rem 3.5rem -1.25rem rgb(0 0 0 / 0.7);
  --line: rgb(255 255 255 / 0.1);        /* hairlines between rows */
  --raise: rgb(255 255 255 / 0.08);      /* a control resting on the material */
  --raise-up: rgb(255 255 255 / 0.13);   /* the same control under the pointer */
  --well: rgb(0 0 0 / 0.26);             /* a shape pressed into the material */

  /* Type: one family, eight sizes. */
  --font: "Ysabeau Office", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --t-display: clamp(2rem, min(1.42rem + 4.6vw, (100vw - 5rem) / 6.7), 5.5rem);   /* the second part keeps "useful software." on one line on the narrowest phones */
  --t-title: clamp(2.125rem, 1.6rem + 2.2vw, 3.5rem);
  --t-claim: clamp(1.625rem, 1.3rem + 1.4vw, 2.5rem);
  --t-h3: clamp(1.25rem, 1.18rem + 0.3vw, 1.4375rem);
  --t-lead: clamp(1.25rem, 1.03rem + 0.95vw, 1.75rem);
  --t-lede: clamp(1.1875rem, 1.1rem + 0.4vw, 1.4375rem);
  --t-body: clamp(1.0625rem, 1.02rem + 0.2vw, 1.1875rem);
  --t-small: 1rem;

  /* Space: everything sits on steps of 0.25rem. */
  --gutter: clamp(1rem, 4vw, 3rem);
  --content: 76rem;          /* the widest the column of frames gets */
  --gap: 0.75rem;            /* between frames of one group */
  --pad: 1.5rem;             /* inside a frame */
  --pad-row: 1.25rem;        /* above and below a row */
  --r: 1.5rem;               /* corner of a frame */
  --r-small: 1.125rem;       /* corner of a small frame */
  --bar-top: 0.75rem;
  --bar-h: 3.5rem;
  --bar-inset: 0.375rem;     /* a pill inside the bar sits this far in, so its curve follows the bar's. On a touch screen that leaves a control 2.75rem tall */
  --chapter: clamp(4.5rem, 13vh, 8.5rem);

  /* Where the dawn rests in the sky. The opening frame is hung just under it. */
  --dawn-x: 38.8%;
  --dawn-y: 40.3vh;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

@supports (height: 1lvh) {
  :root { --dawn-y: 40.3lvh; }
}

@media (min-width: 40rem) {
  :root {
    --pad: 2rem;
    --r: 1.75rem;
    --r-small: 1.25rem;
  }
}

@media (min-width: 60rem) {
  :root {
    --gap: 1rem;
    --pad: 2.5rem;
    --bar-top: 1rem;
    --bar-inset: 0.5rem;
  }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--bar-top) + var(--bar-h) + 1rem);
  scrollbar-color: #4d5059 #000000;
}

body {
  margin: 0;
  background: var(--space);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  font-weight: 430;
  line-height: 1.5;
  font-variant-numeric: lining-nums;
  overflow-x: clip;
}

h1, h2, h3, p, ul, ol, dl, dd {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

img, svg {
  display: block;
}

p {
  text-wrap: pretty;
}

::selection {
  background: rgb(255 182 155 / 0.28);
  color: #ffffff;
}

a {
  border-radius: 0.25rem;   /* rounds the focus ring */
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: 0.0625rem;
  text-decoration-color: rgb(255 182 155 / 0.55);
  text-underline-offset: 0.22em;
}

a:hover {
  color: var(--accent-up);
  text-decoration-color: currentColor;
}

a:focus-visible,
button:focus-visible {
  outline: 0.125rem solid var(--accent);
  outline-offset: 0.1875rem;
}

.wrap {
  max-width: calc(var(--content) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---- The sky ---- */

.sky {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100vw;
  height: 100vh;
  height: 100lvh;
  overflow: hidden;
  background: #000;
}

/* The still sky, for when the canvas cannot run. It follows the moving one: stars and a faint nebula in the
   upper left, the dawn at the same spot on the edge of the planet, and the dark planet in the lower right. */
.sky-fallback {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background-color: #000;
  background-image:
    radial-gradient(circle at var(--dawn-x) 40.3%, #fff4e6 0, rgb(255 236 220 / 0.95) 0.5vh, rgb(255 196 168 / 0.6) 1.2vh, rgb(244 136 118 / 0.3) 2.6vh, rgb(190 70 84 / 0.14) 5vh, rgb(190 70 84 / 0) 9vh),
    radial-gradient(ellipse 30vw 19vh at 51% 16%, rgb(66 18 48 / 0.7), rgb(66 18 48 / 0) 72%),
    radial-gradient(ellipse 24vw 15vh at 64% 7%, rgb(44 22 68 / 0.55), rgb(44 22 68 / 0) 72%),
    radial-gradient(ellipse 28vw 24vh at 27% 31%, rgb(42 14 36 / 0.55), rgb(42 14 36 / 0) 72%),
    radial-gradient(ellipse 30vw 28vh at 3% 54%, rgb(9 28 40 / 0.6), rgb(9 28 40 / 0) 72%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='352' height='352'%3E%3Ccircle cx='137.9' cy='279.7' r='0.61' fill='%23ffd9bf' opacity='0.33'/%3E%3Ccircle cx='99.1' cy='287.1' r='0.54' fill='%23cfe0ff' opacity='0.30'/%3E%3Ccircle cx='108.8' cy='213.4' r='0.70' fill='%23bcd2ff' opacity='0.55'/%3E%3Ccircle cx='243.6' cy='11.6' r='1.10' fill='%23ffffff' opacity='0.98'/%3E%3Ccircle cx='19.3' cy='131.8' r='0.53' fill='%23bcd2ff' opacity='0.50'/%3E%3Ccircle cx='102.9' cy='269.4' r='0.57' fill='%23ffffff' opacity='0.49'/%3E%3Ccircle cx='152.5' cy='232.0' r='0.88' fill='%23ffffff' opacity='0.82'/%3E%3Ccircle cx='302.9' cy='33.0' r='0.36' fill='%23bcd2ff' opacity='0.58'/%3E%3Ccircle cx='326.3' cy='256.1' r='0.44' fill='%23e9d6ff' opacity='0.63'/%3E%3Ccircle cx='86.8' cy='153.7' r='0.46' fill='%23e9d6ff' opacity='0.38'/%3E%3Ccircle cx='212.9' cy='89.0' r='0.37' fill='%23ffffff' opacity='0.50'/%3E%3Ccircle cx='278.6' cy='231.1' r='0.52' fill='%23cfe0ff' opacity='0.43'/%3E%3Ccircle cx='192.8' cy='98.9' r='0.46' fill='%23ffffff' opacity='0.53'/%3E%3Ccircle cx='190.4' cy='348.8' r='0.88' fill='%23ffffff' opacity='0.93'/%3E%3Ccircle cx='231.7' cy='223.5' r='0.56' fill='%23ffffff' opacity='0.40'/%3E%3Ccircle cx='83.2' cy='211.0' r='0.56' fill='%23ffffff' opacity='0.51'/%3E%3Ccircle cx='336.5' cy='63.0' r='0.87' fill='%23bcd2ff' opacity='0.75'/%3E%3Ccircle cx='112.5' cy='272.8' r='0.38' fill='%23ffffff' opacity='0.54'/%3E%3Ccircle cx='254.6' cy='217.0' r='0.54' fill='%23ffffff' opacity='0.56'/%3E%3Ccircle cx='152.9' cy='42.5' r='1.04' fill='%23ffd9bf' opacity='0.98'/%3E%3Ccircle cx='38.7' cy='260.7' r='0.99' fill='%23ffffff' opacity='0.81'/%3E%3Ccircle cx='56.0' cy='81.6' r='0.93' fill='%23ffffff' opacity='0.93'/%3E%3Ccircle cx='18.3' cy='109.7' r='0.66' fill='%23bcd2ff' opacity='0.49'/%3E%3Ccircle cx='336.4' cy='240.6' r='0.51' fill='%23ffffff' opacity='0.51'/%3E%3Ccircle cx='218.6' cy='345.6' r='0.69' fill='%23ffd9bf' opacity='0.40'/%3E%3Ccircle cx='199.9' cy='132.2' r='0.48' fill='%23ffffff' opacity='0.48'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='496' height='496'%3E%3Ccircle cx='77.6' cy='466.6' r='0.51' fill='%23ffffff' opacity='0.50'/%3E%3Ccircle cx='176.2' cy='257.7' r='0.69' fill='%23e9d6ff' opacity='0.38'/%3E%3Ccircle cx='395.1' cy='99.2' r='0.63' fill='%23cfe0ff' opacity='0.56'/%3E%3Ccircle cx='146.5' cy='411.3' r='1.10' fill='%23e9d6ff' opacity='0.87'/%3E%3Ccircle cx='129.4' cy='344.7' r='0.42' fill='%23bcd2ff' opacity='0.35'/%3E%3Ccircle cx='317.0' cy='346.6' r='0.62' fill='%23cfe0ff' opacity='0.34'/%3E%3Ccircle cx='495.8' cy='307.0' r='0.56' fill='%23e9d6ff' opacity='0.51'/%3E%3Ccircle cx='225.8' cy='210.4' r='0.37' fill='%23cfe0ff' opacity='0.36'/%3E%3Ccircle cx='32.2' cy='329.9' r='0.67' fill='%23ffffff' opacity='0.52'/%3E%3Ccircle cx='270.0' cy='377.0' r='0.43' fill='%23e9d6ff' opacity='0.30'/%3E%3Ccircle cx='157.0' cy='49.2' r='0.53' fill='%23ffd9bf' opacity='0.39'/%3E%3Ccircle cx='229.1' cy='179.1' r='0.40' fill='%23ffffff' opacity='0.29'/%3E%3Ccircle cx='406.4' cy='412.1' r='0.57' fill='%23cfe0ff' opacity='0.39'/%3E%3Ccircle cx='312.7' cy='448.4' r='0.37' fill='%23ffd9bf' opacity='0.53'/%3E%3Ccircle cx='268.5' cy='451.0' r='1.04' fill='%23ffffff' opacity='0.90'/%3E%3Ccircle cx='385.7' cy='464.4' r='0.42' fill='%23ffffff' opacity='0.41'/%3E%3Ccircle cx='354.9' cy='56.3' r='0.51' fill='%23e9d6ff' opacity='0.36'/%3E%3Ccircle cx='91.2' cy='372.0' r='0.36' fill='%23e9d6ff' opacity='0.38'/%3E%3Ccircle cx='232.8' cy='277.2' r='0.51' fill='%23ffd9bf' opacity='0.49'/%3E%3Ccircle cx='234.8' cy='410.4' r='0.50' fill='%23ffd9bf' opacity='0.59'/%3E%3Ccircle cx='290.8' cy='244.1' r='0.40' fill='%23ffffff' opacity='0.44'/%3E%3Ccircle cx='463.5' cy='324.0' r='0.64' fill='%23bcd2ff' opacity='0.59'/%3E%3C/svg%3E");
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat;
  background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 7rem 4rem;
}

.sky-fallback[hidden] {
  display: none;
}

/* The glow of the dawn lies along the edge of the planet, so it is drawn on a turned shape. */
.sky-fallback::before {
  content: "";
  position: absolute;
  left: var(--dawn-x);
  top: 40.3%;
  width: 70vh;
  height: 30vh;
  margin: -15vh 0 0 -35vh;
  background: radial-gradient(closest-side, rgb(255 176 150 / 0.5) 0, rgb(236 112 106 / 0.34) 10%, rgb(178 58 80 / 0.22) 26%, rgb(110 30 62 / 0.13) 50%, rgb(60 16 44 / 0.05) 76%, rgb(60 16 44 / 0) 100%);
  transform: rotate(-40deg);
}

.sky-planet {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.limb-tall {
  display: none;
}

@media (max-aspect-ratio: 1/1) {
  .limb-wide { display: none; }
  .limb-tall { display: inline; }
  .sky-fallback::before { transform: rotate(-66deg); }
}

.sky-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* ---- The material: graphite glass. Every frame, the floating bar and the pause button are made of it. ---- */

.frame,
.bar {
  position: relative;
  border-radius: var(--r);
  background-color: var(--glass);
  -webkit-backdrop-filter: var(--frost);
  backdrop-filter: var(--frost);
  box-shadow: var(--edge-plain), var(--shade), var(--lift);
}

/* Where the browser can cut a ring out of a gradient, the edge is drawn as one: bright along the top,
   fading down the sides, as if light fell on it from above. */
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
  .frame,
  .bar {
    box-shadow: var(--shade), var(--lift);
  }

  .frame::before,
  .bar::before {
    content: "";
    position: absolute;
    inset: 0;
    padding: 0.0625rem;
    border-radius: inherit;
    /* The second picture is the dawn on the edge. js/main.js sets --lx and --ly, the place of the dawn measured
       from this frame's own corner. Until it does, that light is parked far away and only the first picture shows. */
    background:
      radial-gradient(circle at var(--lx, -100rem) var(--ly, -100rem), rgb(255 244 230 / 0.95) 0, rgb(255 244 230 / 0.62) 2.5rem, rgb(255 244 230 / 0.24) 7rem, rgb(255 244 230 / 0) 15rem),
      var(--edge);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    pointer-events: none;
  }

  /* A frame near the dawn (js/main.js marks it "lit") also gets a soft glow along that part of its edge.
     It is a ring a few pixels wide, so it never comes near the words. */
  .frame.lit::after,
  .bar.lit::after {
    content: "";
    position: absolute;
    inset: 0;
    padding: 0.25rem;
    border-radius: inherit;
    background: radial-gradient(circle at var(--lx, -100rem) var(--ly, -100rem), rgb(255 242 230 / 1) 0, rgb(255 230 212 / 0.62) 3rem, rgb(255 216 196 / 0.2) 8rem, rgb(255 216 196 / 0) 14rem);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    filter: blur(0.25rem);
    pointer-events: none;
  }
}

/* No blur available: the fill becomes almost solid, so the words stay readable. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .frame,
  .bar {
    background-color: var(--glass-plain);
  }
}

/* ---- The floating bar: the name and the two page links. The pause button sits in its right end. ---- */

.top {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: grid;
  grid-template-columns: minmax(0, var(--content));
  justify-content: center;
  padding: var(--bar-top) var(--gutter) 0;
  pointer-events: none;
}

/* A soft shade at the very top of the window. A frame that scrolls up past the bar goes into the dark here,
   so nothing shows in the narrow gap above the bar. */
.top::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: calc(var(--bar-top) + var(--bar-h) * 0.75);
  background: linear-gradient(180deg, #000 0, rgb(0 0 0 / 0.9) var(--bar-top), rgb(0 0 0 / 0.55) calc(var(--bar-top) + var(--bar-h) * 0.35), rgb(0 0 0 / 0) 100%);
}

.bar {
  grid-area: 1 / 1;
  pointer-events: auto;
  display: flex;
  align-items: center;
  min-height: var(--bar-h);
  padding-inline: var(--pad) var(--bar-inset);
  border-radius: calc(var(--bar-h) / 2);
  box-shadow: var(--edge-plain), var(--lift);
}

@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
  .bar {
    box-shadow: var(--lift);
  }
}

.name {
  margin-right: auto;
  font-size: 1.1875rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.005em;
}

.bar nav {
  display: flex;
  gap: 0.125rem;
}

.bar a,
.pause {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--bar-h) - 2 * var(--bar-inset));
  border-radius: 62.5rem;
  color: var(--ink);
  font-size: 1rem;
  font-weight: 560;
  line-height: 1;
  text-decoration: none;
}

.bar a {
  padding-inline: 0.75rem;
}

.bar a:hover,
.bar a[aria-current] {
  background-color: var(--raise);
  color: var(--ink);
}

.bar a:active {
  background-color: var(--raise-up);
}

.bar a:focus-visible,
.pause:focus-visible {
  outline-offset: 0.125rem;
}

/* The pause button. On a narrow screen it floats on its own in the bottom corner, made of the same glass. */
.pause {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 1;
  justify-content: center;
  gap: 0.4375rem;
  min-width: 9.25rem;
  min-height: 2.75rem;
  margin: 0;
  padding: 0 1.125rem 0 0.9375rem;
  border: 0;
  background-color: var(--glass);
  -webkit-backdrop-filter: var(--frost);
  backdrop-filter: var(--frost);
  box-shadow: var(--edge-plain), var(--lift);
  font-family: inherit;
  cursor: pointer;
  pointer-events: auto;
}

.pause[hidden] {
  display: none;
}

.pause:active {
  transform: scale(0.97);
}

.pause .icon {
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
}

.pause .icon-play,
.pause[data-state="still"] .icon-pause {
  display: none;
}

.pause[data-state="still"] .icon-play {
  display: block;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pause {
    background-color: var(--glass-plain);
  }
}

/* ---- Opening ---- */

/* The first screen, from the top: open sky, the frame, the small note, then room for the pause button.
   The open sky is as tall as it takes to hang the frame just under the dawn, so the light rests on the frame's
   top edge. On a short screen (a phone with its toolbars showing) the open sky gives way, down to a strip under
   the bar, so the frame and the note still fit on the first screen. js/main.js then moves the dawn up with them. */
.hero {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding-bottom: 1.5rem;
}

/* The open sky above the frame. It takes the free room first, up to the place of the dawn. */
.hero::before {
  content: "";
  flex: 1000 0 0px;
  min-height: calc(var(--bar-top) + var(--bar-h) + 4rem);
  max-height: calc(var(--dawn-y) + 1.5rem);
}

/* Whatever room is left goes under the frame. */
.hero::after {
  content: "";
  flex: 1 0 0px;
}

/* On a narrow screen the pause button floats in the bottom corner. The first screen keeps that corner clear. */
.scene-on .hero {
  padding-bottom: calc(max(1rem, env(safe-area-inset-bottom)) + 2.75rem + 0.75rem);
}

.hero-row {
  flex: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: start;
  gap: var(--gap);
}

.hero-words {
  width: fit-content;
  max-width: 100%;
  padding: var(--pad);
}

h1 {
  max-width: 8.9em;
  font-size: var(--t-display);
  font-weight: 340;
  line-height: 1;
  letter-spacing: -0.022em;
  text-wrap: balance;
  margin-left: -0.045em;   /* big letters start a little inside their box. This lines their stems up with the small type below. */
}

.lede {
  max-width: 33rem;
  font-size: var(--t-lede);
  font-weight: 420;
  line-height: 1.4;
}

h1 + .lede {
  margin-top: 1.25rem;
}

.hint {
  display: none;
  max-width: 19rem;
  padding: 0.875rem 1.125rem 0.9375rem;
  border-radius: var(--r-small);
  color: var(--ink-soft);
  font-size: var(--t-small);
  line-height: 1.4;
}

.scene-on .hint {
  display: block;
}

.by-touch {
  display: none;
}

@media (hover: none) {
  .by-mouse { display: none; }
  .by-touch { display: inline; }
}

/* ---- Chapters ---- */

.chapter {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
  padding-block: var(--chapter);
}

.shout {
  font-size: var(--t-title);
  font-weight: 380;
  line-height: 1.04;
  letter-spacing: -0.018em;
  text-wrap: balance;
  margin-left: -0.04em;
}

h3 {
  font-size: var(--t-h3);
  font-weight: 640;
  line-height: 1.25;
  text-wrap: balance;
}

/* The frame that opens a chapter: its title, and sometimes a line under it. */
.head {
  padding: var(--pad);
}

.shout + .lede {
  margin-top: 0.875rem;
}

/* The line under the first chapter's title leads its frame, so it is set a step larger. */
.head .lede {
  font-size: var(--t-lead);
  line-height: 1.3;
  letter-spacing: -0.008em;
}

/* A title alone is a small tab, as wide as its words. */
.tab {
  width: fit-content;
  max-width: 100%;
  padding: 0.875rem var(--pad) 1.125rem;
}

/* A frame of rows with a hairline between them. */
.rows {
  padding: calc(var(--pad) - var(--pad-row)) var(--pad);
}

.rows > * {
  padding-block: var(--pad-row);
}

.rows > * + * {
  border-top: 0.0625rem solid var(--line);
}

.rows p {
  max-width: 36rem;
  color: var(--ink-soft);
}

.rules li,
.facts > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.375rem 1.5rem;
}

.facts dt {
  color: var(--ink-soft);
  font-size: var(--t-small);
  font-weight: 520;
  line-height: 1.4;
}

.facts dd {
  max-width: 24em;
  font-size: var(--t-h3);
  font-weight: 480;
  line-height: 1.3;
}

.answers p {
  margin-top: 0.5rem;
}

/* ---- The release ---- */

.banner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  padding: var(--pad);
}

.fresh {
  display: block;
  color: var(--ink-soft);
  font-weight: 340;
}

.product {
  display: inline-flex;
  align-items: center;
  gap: 0.22em;
  font-weight: 700;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.product img {
  width: 1em;
  height: 1em;
}

.claim {
  max-width: 15em;
  font-size: var(--t-claim);
  font-weight: 460;
  line-height: 1.08;
  letter-spacing: -0.014em;
  text-wrap: balance;
}

.claim + .lede {
  margin-top: 0.75rem;
  color: var(--ink-soft);
}

.how {
  padding: var(--pad) var(--pad) calc(var(--pad) - var(--pad-row));
}

.steps {
  counter-reset: step;
  margin-top: calc(1rem - var(--pad-row) + 0.75rem);
}

.steps li {
  counter-increment: step;
  position: relative;
  min-height: calc(2rem + 2 * var(--pad-row));
  padding: var(--pad-row) 0 var(--pad-row) 3rem;
  color: var(--ink-soft);
}

.steps li + li {
  border-top: 0.0625rem solid var(--line);
}

/* The number sits in a small well pressed into the material, beside the first line of its step. */
.steps strong::before {
  content: counter(step);
  position: absolute;
  left: -3rem;
  top: -0.125rem;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background-color: var(--well);
  box-shadow: inset 0 0 0 0.0625rem rgb(255 255 255 / 0.12), 0 0.0625rem 0 rgb(255 255 255 / 0.08);
  color: var(--ink);
  font-size: 1rem;
  font-weight: 640;
  line-height: 1;
}

.steps strong {
  position: relative;
  display: block;
  color: var(--ink);
  font-size: var(--t-h3);
  font-weight: 640;
  line-height: 1.25;
}

.about {
  display: flex;
  flex-direction: column;
  padding: var(--pad) var(--pad) var(--pad-row);
}

.about-words {
  flex: 1;
}

.about-words p {
  max-width: 35rem;
  font-size: var(--t-lead);
  line-height: 1.3;
  letter-spacing: -0.008em;
}

.about-words p + p {
  margin-top: 1rem;
  color: var(--ink-soft);
  font-size: var(--t-body);
  line-height: 1.5;
  letter-spacing: 0;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-top: var(--pad);
  padding-top: var(--pad-row);
  border-top: 0.0625rem solid var(--line);
}

/* The main button. The arrow sits in a round seat whose curve follows the end of the pill. */
.go {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.125rem;
  min-height: 3.5rem;
  padding: 0.5rem 0.5rem 0.5rem 1.75rem;
  border-radius: 62.5rem;
  background-color: var(--accent);
  box-shadow:
    inset 0 0.0625rem 0 rgb(255 255 255 / 0.55),
    inset 0 -0.0625rem 0 rgb(0 0 0 / 0.16),
    0 0.125rem 0.25rem rgb(0 0 0 / 0.3),
    0 0.875rem 1.75rem -0.625rem rgb(0 0 0 / 0.7);
  color: var(--on-accent);
  font-size: 1.1875rem;
  font-weight: 680;
  line-height: 1.2;
  text-decoration: none;
}

.go:hover {
  background-color: var(--accent-up);
  color: var(--on-accent);
}

.go:active {
  background-color: var(--accent-down);
  transform: scale(0.98);
}

.go-seat {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-color: var(--on-accent);
  color: var(--accent);
}

.go:hover .go-seat svg {
  transform: translateX(0.125rem);
}

.host {
  color: var(--ink-soft);
  font-size: var(--t-small);
}

/* ---- Contact and the foot ---- */

.contact {
  padding-bottom: var(--gap);
}

.address {
  font-size: clamp(1.5rem, 0.9rem + 2.9vw, 3.25rem);
  font-weight: 380;
  line-height: 1.15;
  letter-spacing: -0.018em;
}

.address a {
  display: inline-block;
  padding-block: 0.125rem;
  border-radius: 0.5rem;
  overflow-wrap: anywhere;
  text-decoration-color: rgb(255 182 155 / 0.45);
  text-underline-offset: 0.16em;
}

.address a:hover {
  text-decoration-color: currentColor;
}

.foot {
  padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
}

/* On a narrow screen the pause button floats in the bottom corner. The page ends a little lower, so the last
   words can be scrolled clear of it. */
.scene-on .foot {
  padding-bottom: calc(max(1rem, env(safe-area-inset-bottom)) + 2.75rem + 0.75rem);
}

.foot-lines {
  display: grid;
  gap: 0.25rem 2rem;
  padding: 1rem var(--pad) 1.0625rem;
  color: var(--ink-soft);
  font-size: var(--t-small);
  line-height: 1.4;
}

/* ---- A device that cannot keep up ---- */

/* Blurring the sky behind every frame is the costly part of this page. If the pictures come too slowly,
   js/main.js adds "lean" to <html>. The frames then stop blurring and use the solid fill. */
.lean .frame,
.lean .bar,
.lean .pause {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.lean .frame,
.lean .bar {
  background-color: var(--glass-plain);
}

.lean .frame::after,
.lean .bar::after {
  display: none;
}

@media (max-width: 39.99rem) {
  .lean .pause {
    background-color: var(--glass-plain);
  }
}

/* ---- From 40rem: the pause button joins the bar ---- */

@media (min-width: 40rem) {
  /* The button moves into the right end of the bar. It is not frosted there: it rests on the bar's glass. */
  .pause {
    grid-area: 1 / 1;
    position: relative;
    right: auto;
    bottom: auto;
    justify-self: end;
    align-self: center;
    min-height: calc(var(--bar-h) - 2 * var(--bar-inset));
    margin-right: var(--bar-inset);
    padding: 0 1rem 0 0.8125rem;
    background-color: var(--glass-raised);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: inset 0 0.0625rem 0 rgb(255 255 255 / 0.16), inset 0 0 0 0.0625rem rgb(255 255 255 / 0.07), 0 0.0625rem 0.125rem rgb(0 0 0 / 0.3);
  }

  .pause:hover {
    background-color: rgb(70 72 79 / 0.84);
  }

  .scene-on .bar {
    padding-right: calc(var(--bar-inset) + 9.25rem + 0.375rem);
  }

  .scene-on .foot {
    padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
  }

  .scene-on .hero {
    padding-bottom: 1.5rem;
  }

  /* Rows with a name and a line about it: the name stands in its own column. */
  .rules li,
  .facts > div {
    grid-template-columns: 11rem minmax(0, 1fr);
    align-items: baseline;
  }

  .bar a {
    padding-inline: 1rem;
  }
}

/* ---- Wide screens: twelve columns. Titles take five, what they introduce takes seven. ---- */

@media (min-width: 60rem) {
  .name {
    font-size: 1.25rem;
  }

  .bar a,
  .pause {
    font-size: 1.0625rem;
  }

  .hero-words {
    padding-block: 2.5rem 2.75rem;
  }

  .chapter {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }

  .head {
    grid-column: 1 / span 5;
    position: sticky;
    top: calc(var(--bar-top) + var(--bar-h) + var(--gap));
  }

  .split > .rows {
    grid-column: 6 / span 7;
  }

  /* The first chapter: title and rows stand side by side at one height. */
  #approach .head {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2rem;
  }

  /* A banner runs the full width. Inside, its second part starts on the same line as the seven-column frames. */
  .banner {
    grid-column: 1 / -1;
    grid-template-columns: calc((100% + 2 * var(--pad) + var(--gap)) * 5 / 12) minmax(0, 1fr);
    gap: 0;
    align-items: start;
  }

  .banner > :first-child {
    padding-right: 2rem;
  }

  .release {
    align-items: stretch;
  }

  .how {
    grid-column: 1 / span 5;
  }

  .about {
    grid-column: 6 / span 7;
  }

  .contact .banner {
    align-items: end;
  }

  .foot-lines {
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    min-height: var(--bar-h);
    padding-block: 0.75rem;
    border-radius: calc(var(--bar-h) / 2);
  }
}

/* ---- Motion: small, and only where it is asked for ---- */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  .bar a,
  .pause,
  .go {
    transition: background-color 0.2s ease-out, transform 0.2s var(--ease);
  }

  .go-seat svg {
    transition: transform 0.3s var(--ease);
  }

  a {
    transition: color 0.2s ease-out, text-decoration-color 0.2s ease-out;
  }

  /* The opening: the sky comes up out of the dark, the bar comes down, the frame rises into place under the
     dawn, then the small note follows. With the moving sky, js/main.js also lets the dawn rise (see "sunrise"). */
  .sky {
    animation: sky-in 1.4s ease-out both;
  }

  .bar,
  .pause {
    animation: arrive-down 0.9s var(--ease) both;
  }

  .hero-words {
    animation: arrive-up 1.1s var(--ease) 0.1s both;
  }

  .hint {
    animation: arrive-up 1.1s var(--ease) 0.3s both;
  }

  /* The address switches for checking show the page at rest (js/main.js adds "at-rest"):
     no opening, and no easing between the states of a control. */
  .at-rest .sky,
  .at-rest .bar,
  .at-rest .pause,
  .at-rest .hero-words,
  .at-rest .hint {
    animation: none;
  }

  .at-rest a,
  .at-rest .pause,
  .at-rest .go-seat svg {
    transition: none;
  }
}

@keyframes sky-in {
  from { opacity: 0; }
}

@keyframes arrive-up {
  from { opacity: 0; transform: translateY(1.25rem); }
}

@keyframes arrive-down {
  from { opacity: 0; transform: translateY(-0.75rem); }
}

/* ---- The widest screens: the small note stands beside the opening frame ---- */

@media (min-width: 75rem) {
  .hero-row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: 2rem;
  }
}

/* ---- Forced colours (Windows contrast themes): the glass is replaced by plain surfaces, so frames get a real edge ---- */

@media (forced-colors: active) {
  .frame,
  .bar,
  .pause,
  .go {
    border: 0.0625rem solid CanvasText;
  }

  .frame::before,
  .frame::after,
  .bar::before,
  .bar::after {
    display: none;
  }
}

/* ---- Services and process ---- */

/* Words for screen readers only. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* One kind of work we take on: who it is for, how long it takes, what is in it, and a way to start. */
.service {
  display: flex;
  flex-direction: column;
  padding: var(--pad) var(--pad) var(--pad-row);
}

.service-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.service h3,
.offer-words h3 {
  font-size: clamp(1.5rem, 1.35rem + 0.6vw, 1.875rem);
  font-weight: 560;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.badge {
  flex: none;
  padding: 0.25rem 0.75rem 0.3125rem;
  border-radius: 62.5rem;
  background-color: var(--raise);
  box-shadow: inset 0 0 0 0.0625rem rgb(255 255 255 / 0.09);
  font-size: 0.9375rem;
  font-weight: 560;
  line-height: 1.3;
}

.for {
  margin-top: 0.625rem;
  color: var(--ink-soft);
}

.timeline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  margin-top: var(--pad-row);
  padding-top: var(--pad-row);
  border-top: 0.0625rem solid var(--line);
  color: var(--ink-soft);
  font-size: var(--t-small);
}

.timeline strong {
  color: var(--ink);
  font-size: var(--t-body);
  font-weight: 620;
}

/* A list of what is included. The tick is drawn with two borders, not a glyph. */
.ticks {
  display: grid;
  align-content: start;
  gap: 0.625rem;
  flex: 1;
  margin-top: 1.25rem;
}

.ticks li {
  position: relative;
  padding-left: 1.75rem;
}

.ticks li::before {
  content: "";
  position: absolute;
  left: 0.1875rem;
  top: 0.5em;
  width: 0.6875rem;
  height: 0.375rem;
  border-left: 0.125rem solid var(--ink-soft);
  border-bottom: 0.125rem solid var(--ink-soft);
  transform: rotate(-45deg);
}

.service .go {
  width: 100%;
}

/* A second kind of button: the same shape, resting on the glass without the accent. */
.go.quiet {
  background-color: var(--raise);
  box-shadow: inset 0 0.0625rem 0 rgb(255 255 255 / 0.16), inset 0 0 0 0.0625rem rgb(255 255 255 / 0.09), 0 0.0625rem 0.125rem rgb(0 0 0 / 0.3);
  color: var(--ink);
}

.go.quiet:hover {
  background-color: var(--raise-up);
  color: var(--ink);
}

.go.quiet:active {
  background-color: var(--raise);
}

.go.quiet .go-seat {
  background-color: var(--well);
  box-shadow: inset 0 0 0 0.0625rem rgb(255 255 255 / 0.12);
  color: var(--ink);
}

.aside {
  width: fit-content;
  max-width: 100%;
  padding: 0.875rem var(--pad) 1rem;
  border-radius: var(--r-small);
  color: var(--ink-soft);
}

.offer-words h3 + p {
  margin-top: 0.75rem;
  color: var(--ink-soft);
  font-size: var(--t-lede);
  line-height: 1.4;
  letter-spacing: 0;
}

.offer-words .ticks {
  flex: none;
}

@media (min-width: 60rem) {
  .head.wide {
    grid-column: 1 / -1;
    position: static;
  }

  .head.wide .lede {
    max-width: 44rem;
  }

  .services {
    align-items: stretch;
  }

  .service {
    grid-column: span 4;
  }

  .for {
    min-height: 3lh; /* the three cards keep their timelines on one line across */
  }

  .aside {
    grid-column: 1 / -1;
  }

  .offer-words {
    grid-column: 1 / span 7;
  }

  .offer-steps {
    grid-column: 8 / span 5;
  }

  .split > .how {
    grid-column: 6 / span 7;
  }
}

/* On a narrow phone the bar holds the name and three links, so the links sit closer together. */
@media (max-width: 26rem) {
  .bar a {
    padding-inline: 0.5rem;
    font-size: 0.9375rem;
  }

  .bar nav {
    gap: 0;
  }

  .name {
    padding-right: 0.5rem;
  }
}

/* The "Recommended" tag rides on the top edge of its card, so the three card titles stay on one line. */
.service {
  position: relative;
}

.service .badge {
  position: absolute;
  top: -0.8125rem;
  right: var(--pad);
  background-color: var(--glass-raised);
  box-shadow: inset 0 0.0625rem 0 rgb(255 255 255 / 0.2), inset 0 0 0 0.0625rem rgb(255 255 255 / 0.09), 0 0.125rem 0.375rem rgb(0 0 0 / 0.4);
}

/* ---- CareerHex's six characters ----
   CareerHex's own artwork, with its own colours and shapes (assets/careerhex/, copied from careerhex.monolen.com).
   They appear only here, inside the CareerHex section. Three across on a phone, six across from 40rem. */

.cast {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem 0.75rem;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
}

.cast li {
  --i: 0; /* its place in the row, for the rise below */
  display: grid;
  justify-items: center;
  gap: 0.375rem;
  text-align: center;
}

.cast li:nth-child(2) { --i: 1; }
.cast li:nth-child(3) { --i: 2; }
.cast li:nth-child(4) { --i: 3; }
.cast li:nth-child(5) { --i: 4; }
.cast li:nth-child(6) { --i: 5; }

.cast img {
  width: 100%;
  max-width: 7rem;
  height: auto;
  aspect-ratio: 1;
}

.cast span {
  color: var(--ink-soft);
  font-size: var(--t-small);
  font-weight: 520;
  line-height: 1.2;
}

@media (min-width: 40rem) {
  .cast {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0.75rem;
  }
}

/* As the row scrolls into view, the six rise one after another. It follows the scroll, so it never plays on
   its own. Browsers without scroll timelines, and anyone who asks for less motion, see them at rest. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .cast li {
      animation: cast-rise linear both;
      animation-timeline: view();
      animation-range: entry calc(10% + var(--i) * 8%) entry calc(60% + var(--i) * 8%);
    }

    .at-rest .cast li {
      animation: none;
    }
  }
}

@keyframes cast-rise {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }
}

/* On wide screens the two CareerHex frames stand side by side at one height. The frame with the six characters
   is the taller one, so the three steps beside it share out the extra room: each row grows by the same amount
   and its words stay centred, so the lines between the steps stay evenly spaced. */
@media (min-width: 60rem) {
  #careerhex .how {
    display: flex;
    flex-direction: column;
  }

  #careerhex .how .steps {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
  }

  #careerhex .how .steps li {
    flex: 1 0 auto; /* each row keeps its own height and gains an equal share of any spare room */
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}
