/* Herald's page. Built from scratch, not mirrored.
 *
 * It inherits the site's system and nothing else: the two type roles
 * (din-condensed-web for display, ibm-plex-mono for text, at the site's
 * -.04em tracking), the heading scale, the 7.2px button at 3.1rem x 1rem,
 * and the 5px and 14px radii. Colour is this page's own decision, as it is
 * for every app page.
 *
 * Always dark, whatever the visitor's system setting: Herald is a tool for
 * people who live in their machine, and the page should read like one.
 * The one accent is taken from Herald's icon, the indigo of the ensign.
 *
 *   ink    #ededf2 on #0b0b10  16.83:1
 *   ink-2  #a3a3ae             7.86:1   body copy
 *   ink-3  #8b8b97             5.83:1   quiet labels
 *   accent #9d8ff0             7.13:1   accent text
 *   white on #6352dc           5.57:1   primary button
 *   white on #7361e4           4.61:1   its hover
 *
 * Everything is scoped under .hd-page (on <body>) or .hd (on the content), so
 * nothing here can leak into the rest of the site.
 */

.hd-page {
  --hd-bg: #0b0b10;
  --hd-raise: #15151c;
  --hd-raise-2: #1d1d26;
  --hd-line: rgba(237, 237, 242, 0.1);
  --hd-ink: #ededf2;
  --hd-ink-2: #a3a3ae;
  --hd-ink-3: #8b8b97;
  --hd-accent: #9d8ff0;
  --hd-fill: #6352dc;
  --hd-fill-hover: #7361e4;
  --hd-display: "din-condensed-web", "Barlow Condensed", "Arial Narrow", sans-serif;
  --hd-mono: "ibm-plex-mono", ui-monospace, "SF Mono", Menlo, monospace;
  --hd-gutter: max(6vw, 16px);
  --hd-section: clamp(4.5rem, 2.5rem + 6vw, 9rem);
  color-scheme: dark;
}

html:has(body.hd-page),
body.hd-page,
.hd-page #siteWrapper,
.hd-page #page {
  background-color: #0b0b10;
}

/* ------------------------------------------------------------------ chrome */

/* Squarespace lays the header over the first section and has its runtime pad
   that section by the header's height; the mirrored pages carry that padding
   frozen inline (193px on the homepage). This page has no such section, so the
   header takes its own place in the flow instead, which also closes up
   properly when the announcement bar is dismissed. */
.hd-page #header {
  position: relative;
}

/* The header runs on the site's own black theme (set in the markup by
   build_herald.py), which turns the wordmark, links and burger white. Its
   background is pinned to the page's ground so it does not sit as a
   pure-black band above a near-black page. */
.hd-page .header .header-background,
.hd-page .header-menu .header-menu-bg {
  background-color: var(--hd-bg) !important;
}

/* ------------------------------------------------------------------ base */

.hd {
  font-family: var(--hd-mono);
  font-size: 1rem;
  line-height: 1.6;
  letter-spacing: -0.04em;
  color: var(--hd-ink-2);
  -webkit-font-smoothing: antialiased;
}

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

.hd-wrap {
  max-width: 1500px;
  margin-inline: auto;
  padding-inline: var(--hd-gutter);
}

.hd-page .hd h1,
.hd-page .hd h2,
.hd-page .hd h3 {
  margin: 0;
  font-family: var(--hd-display);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--hd-ink);
  text-transform: none;
  text-wrap: balance;
}

.hd-page .hd h1 {
  font-size: clamp(3.25rem, 1.6rem + 5.2vw, 6rem);
  line-height: 1;
}

.hd-page .hd h2 {
  font-size: clamp(2.4rem, 1.6rem + 2.6vw, 3.5rem);
  line-height: 1.05;
}

.hd-page .hd h3 {
  font-size: 1.5rem;
  line-height: 1.2;
}

.hd-page .hd p {
  margin: 0;
  max-width: 62ch;
  font-size: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: inherit;
}

.hd-page .hd a:not(.hd-btn) {
  color: var(--hd-ink);
  text-decoration: underline;
  text-decoration-color: var(--hd-accent);
  text-underline-offset: 0.2em;
}

.hd-page .hd a:not(.hd-btn):hover {
  color: var(--hd-accent);
}

.hd-lede {
  font-size: clamp(1rem, 0.9rem + 0.35vw, 1.2rem) !important;
}

.hd-section {
  padding-block: var(--hd-section);
}

.hd-section + .hd-section {
  padding-top: 0;
}

.hd-stack > * + * {
  margin-top: 1.5rem;
}

/* ------------------------------------------------------------------ buttons */

.hd-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.hd-page .hd a.hd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 3.1rem;
  border-radius: 7.2px;
  font-family: var(--hd-display);
  font-size: 1.5rem;
  line-height: 1.12;
  letter-spacing: 0;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color 0.15s ease, transform 0.15s ease;
}

.hd-page .hd a.hd-btn--primary {
  background-color: var(--hd-fill);
  color: #ffffff;
}

.hd-page .hd a.hd-btn--primary:hover {
  background-color: var(--hd-fill-hover);
}

/* The dark counterpart of the site's soft secondary: a raised fill, and a
   hover that lightens it rather than changing hue. */
.hd-page .hd a.hd-btn--secondary {
  background-color: var(--hd-raise-2);
  color: var(--hd-ink);
}

.hd-page .hd a.hd-btn--secondary:hover {
  background-color: #282832;
}

.hd-page .hd a.hd-btn:active {
  transform: translateY(1px);
}

.hd-page .hd a:focus-visible {
  outline: 2px solid var(--hd-accent);
  outline-offset: 3px;
}

/* ------------------------------------------------------------------ hero */

.hd-hero {
  padding-top: clamp(2rem, 0.5rem + 4vw, 4.5rem);
}

.hd-icon {
  display: block;
  width: clamp(72px, 4rem + 2vw, 104px);
  height: auto;
  margin: 0 0 1.25rem -0.4rem;
}

/* two lines at desktop; DIN's condensed ch is narrow, so this is ~880px */
.hd-hero h1 {
  max-width: 22ch;
}

/* the headline sets solid (line-height 1), so its descenders need the room */
.hd-hero .hd-lede {
  margin-top: 2.25rem !important;
  max-width: 46ch;
}

.hd-hero .hd-actions {
  margin-top: 2.25rem;
}

/* "How it installs", a plain link under the two buttons, in the body's
   mono: the buttons are Herald's two ways in, and this is only a pointer
   down the page. */
.hd-page .hd .hd-how {
  margin-top: 1.25rem;
  font-size: 1rem;
}

/* The hero shot is a finished composition, window and wallpaper together, so
   the stage adds nothing to it but the site's corner radius. It is twice the
   stage's widest (1320px) so the 2x window is never drawn past its own size.
   It is cut through the window's lower part, so only the top corners are
   rounded and the last of it dissolves into the page rather than ending on a
   ruled line. */
.hd-stage {
  position: relative;
  margin: clamp(3rem, 2rem + 3vw, 5.5rem) 0 0;
  border-radius: 14px 14px 0 0;
  overflow: hidden;
  line-height: 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 80%, transparent);
  mask-image: linear-gradient(to bottom, #000 80%, transparent);
}

.hd-stage img {
  display: block;
  width: 100%;
  height: auto;
  margin-inline: auto;
}

/* ------------------------------------------------------------------ one list */

.hd-intro h2 {
  max-width: 18ch;
}

.hd-intro p {
  margin-top: 1.5rem !important;
}

/* ------------------------------------------------------------------ install */

.hd-install h2 {
  max-width: 16ch;
}

.hd-install > .hd-wrap > p {
  margin-top: 1.5rem !important;
}

.hd-steps {
  list-style: none;
  margin: clamp(2.5rem, 1.5rem + 3vw, 4.5rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid var(--hd-line);
}

.hd-steps li {
  position: relative;
  padding: 1.75rem 2rem 0 0;
}

/* where each step sits on the line */
.hd-steps li::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 2.5rem;
  height: 2px;
  background: var(--hd-accent);
}

.hd-steps p {
  margin-top: 0.5rem !important;
  font-size: 0.9rem !important;
}

.hd-fallback {
  margin-top: 2.5rem !important;
  color: var(--hd-ink) !important;
}

/* ------------------------------------------------------------------ control */

.hd-split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 3rem clamp(3rem, 7vw, 9rem);
  align-items: start;
}

.hd-split h2 {
  max-width: 14ch;
}

.hd-split .hd-copy p {
  margin-top: 1.5rem !important;
}

.hd-defs {
  margin: 0;
  display: grid;
  gap: 2.25rem;
  padding-top: 0.5rem;
}

.hd-defs > div {
  display: grid;
  gap: 0.5rem;
}

.hd-defs dt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
  font-family: var(--hd-display);
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--hd-ink);
}

.hd-defs dd {
  margin: 0;
  max-width: 52ch;
}

/* The exact words Herald's own row chip uses for each instruction. */
.hd-chip {
  font-family: var(--hd-mono);
  font-size: 0.8rem;
  line-height: 1.5;
  letter-spacing: -0.02em;
  padding: 0.1rem 0.55rem;
  border-radius: 5px;
  background: var(--hd-raise-2);
  color: var(--hd-ink-2);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ more */

/* The rest of what Herald does, as a grid of short entries on the install
   steps' own rule: the line, the accent tick where each sits on it, the
   display face for the name and the body's mono under it. */
.hd-more h2 {
  max-width: 18ch;
}

.hd-features {
  list-style: none;
  margin: clamp(2.5rem, 1.5rem + 3vw, 4.5rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 3rem clamp(2rem, 4vw, 5rem);
}

.hd-features li {
  position: relative;
  margin: 0;
  padding-top: 1.75rem;
  border-top: 1px solid var(--hd-line);
}

.hd-features li::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 2.5rem;
  height: 2px;
  background: var(--hd-accent);
}

.hd-features p {
  margin-top: 0.5rem !important;
  font-size: 0.9rem !important;
}

/* A key as Herald's own menus print it. */
.hd-page .hd kbd {
  font-family: var(--hd-mono);
  font-size: 0.85em;
  padding: 0 0.3em;
  border-radius: 5px;
  background: var(--hd-raise-2);
  color: var(--hd-ink);
}

/* ------------------------------------------------------------------ apps */

/* The apps it keeps up to date, as one tight row in perspective: the two in
   the centre largest and in front, each one out towards the edges smaller,
   further back and partly behind its neighbour nearer the centre, turned a
   little away from the centre, as round a drum (turned towards it, the
   perspective drew them wider than tall). Nothing moves. build_herald.py
   works out every icon's place and writes it on the item (--x and --z in icons, --r, and --s, the size its
   depth draws it at); this sheet only turns those into a transform, under
   one perspective for the whole row, so that the browser's own projection
   puts each icon where it was computed to appear.
   The icons are the apps' own artwork. Each name is the item's text, always
   there for a screen reader and shown under the row on hover and on focus;
   the pictures carry no alt text. */
.hd-apps h2 {
  max-width: 18ch;
}

.hd-apps > .hd-wrap > p {
  margin-top: 1.5rem !important;
}

/* Out to the page's edges, past the gutters, and clipped there, so the row
   never scrolls the page sideways. From about 500px up the whole row fits
   inside the gutters and nothing is faded; below that it runs off the
   edges, and the gutters fade out the icons running off before they are
   cut. */
.hd-row-frame {
  --hd-fade: var(--hd-gutter);
  container-type: inline-size;
  margin: clamp(1.5rem, 0.5rem + 2vw, 2.5rem) calc(-1 * var(--hd-gutter)) 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--hd-fade),
    #000 calc(100% - var(--hd-fade)), transparent);
  mask-image: linear-gradient(to right, transparent, #000 var(--hd-fade),
    #000 calc(100% - var(--hd-fade)), transparent);
}

/* The centre icon's size: as large as fits the text column, up to 124px,
   and never under 56px, below which the row runs off the edges instead.
   The row is the icon tall with the names' line under it. */
.hd-row {
  --hd-icon: clamp(56px, (100cqw - 2 * var(--hd-gutter)) / var(--hd-span), 124px);
  --hd-name-gap: 0.5rem;
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  height: calc(var(--hd-icon) + var(--hd-name-gap) + 2rem);
  perspective: calc(var(--hd-depth) * var(--hd-icon));
  perspective-origin: 50% calc(var(--hd-icon) / 2);
}

.hd-row li {
  position: absolute;
  top: 0;
  left: calc(50% - var(--hd-icon) / 2);
  width: var(--hd-icon);
  height: var(--hd-icon);
  margin: 0;
  transform: translate3d(calc(var(--x) * var(--hd-icon)), 0,
      calc(var(--z) * var(--hd-icon)))
    rotateY(var(--r));
  transform-style: preserve-3d;
  outline: none;
  pointer-events: none;
}

/* Only the icon's face answers the pointer: the picture's margin and shadow
   are transparent, and would otherwise take the hover off the icon behind
   where its face shows. The face is the rounded square of Apple's icon grid,
   824 of 1024, with its corner. An icon under the pointer stays where it is
   (brought to the front, it would cover the part of its inner neighbour the
   pointer moves on to next, and a sweep across the row would skip every
   other icon); one reached with the keyboard comes to the front, whole. */
.hd-row li::before {
  content: "";
  position: absolute;
  inset: 9.766%;
  border-radius: 22.4%;
  pointer-events: auto;
}

.hd-row li:focus-visible {
  z-index: 100 !important;
}

.hd-row img {
  display: block;
  width: 100%;
  height: 100%;
}

/* The name, on one line under the whole row, centred under its icon: turned
   back to face the page and scaled by 1/--s, so that the depth that draws
   the icon at --s draws its name at the page's own size, the same under
   every icon. It is in the Meta role (the body's mono, small) on the raised
   fill of Herald's own chips. */
.hd-app-name {
  position: absolute;
  left: 50%;
  top: calc(50% + (var(--hd-icon) / 2 + var(--hd-name-gap)) / var(--s));
  transform-origin: 50% 0;
  transform: translateX(-50%) rotateY(calc(-1 * var(--r))) scale(calc(1 / var(--s)));
  padding: 0.2rem 0.6rem;
  border-radius: 5px;
  background: var(--hd-raise-2);
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--hd-ink);
  opacity: 0;
  pointer-events: none;
}

.hd-row li:hover .hd-app-name,
.hd-row li:focus .hd-app-name {
  opacity: 1;
}

.hd-row li:focus-visible .hd-app-name {
  outline: 2px solid var(--hd-accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  .hd-app-name {
    transition: opacity 0.12s ease;
  }
}

.hd-page .hd .hd-more-apps {
  margin-top: 0.25rem;
  max-width: none;
  font-family: var(--hd-display);
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--hd-ink);
  text-align: center;
}

/* ------------------------------------------------------------------ pricing */

.hd-offer {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: 3rem clamp(3rem, 7vw, 9rem);
  align-items: end;
  padding-top: clamp(2.5rem, 1.5rem + 3vw, 4.5rem);
  border-top: 1px solid var(--hd-line);
}

.hd-page .hd .hd-price {
  font-family: var(--hd-display);
  font-size: clamp(5.5rem, 3rem + 9vw, 12rem);
  line-height: 0.85;
  letter-spacing: 0;
  color: var(--hd-ink);
}

.hd-price span {
  font-size: 0.28em;
  line-height: 1;
  color: var(--hd-ink-2);
}

.hd-offer .hd-lede {
  margin-top: 1.5rem !important;
}

.hd-needs {
  list-style: none;
  margin: 0 0 2.25rem;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}

.hd-needs li {
  margin: 0;
  padding-left: 1.4rem;
  position: relative;
}

.hd-needs li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.8em;
  width: 0.6rem;
  height: 1px;
  background: var(--hd-ink-3);
}

.hd-needs strong {
  font-weight: 400;
  color: var(--hd-ink);
}

.hd-end {
  margin-top: clamp(3rem, 2rem + 3vw, 5rem) !important;
  font-size: 0.9rem !important;
}

/* ------------------------------------------------------------------ footer */

/* The site's footer, rebuilt: wordmark left, the three social icons right, at
   the homepage's 24px icons and 14px gap. */
.hd-foot {
  border-top: 1px solid var(--hd-line);
  padding-block: 2.5rem;
}

.hd-foot .hd-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.hd-page .hd a.hd-foot-mark {
  font-family: var(--site-title-font-font-family, "Lily Script One"), cursive;
  font-size: 2rem;
  line-height: 1;
  letter-spacing: 0;
  color: var(--hd-ink);
  text-decoration: none;
}

.hd-page .hd a.hd-foot-mark:hover {
  color: var(--hd-ink);
}

.hd-social {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 14px;
}

.hd-social li {
  margin: 0;
}

/* The icons are a quiet grey at rest, #6d6d6d (3.8:1 on the page), and
   the page's white under the pointer and on keyboard focus, as on every
   footer of the site (2026-09-24, Adam). */
.hd-page .hd .hd-social a {
  display: block;
  width: 24px;
  height: 24px;
  color: #6d6d6d;
  text-decoration: none;
  transition: color 0.15s ease;
}

.hd-page .hd .hd-social a:hover,
.hd-page .hd .hd-social a:focus-visible {
  color: var(--hd-ink);
}

@media (prefers-reduced-motion: reduce) {
  .hd-page .hd .hd-social a {
    transition: none;
  }
}

.hd-social svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* ------------------------------------------------------------------ motion */

/* Only the first screen moves, once, in reading order. */
@media (prefers-reduced-motion: no-preference) {
  .hd-hero .hd-wrap > * {
    animation: hd-rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  .hd-hero .hd-wrap > :nth-child(2) { animation-delay: 0.05s; }
  .hd-hero .hd-wrap > :nth-child(3) { animation-delay: 0.1s; }
  .hd-hero .hd-wrap > :nth-child(4) { animation-delay: 0.15s; }
  .hd-hero .hd-wrap > :nth-child(5) { animation-delay: 0.18s; }
  .hd-hero .hd-wrap > .hd-stage { animation-delay: 0.22s; }
}

@keyframes hd-rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* ------------------------------------------------------------------ narrow */

@media (max-width: 1023px) {
  .hd-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 2.5rem;
    border-top: 0;
  }
  .hd-steps li {
    border-top: 1px solid var(--hd-line);
  }
  .hd-features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 767px) {
  .hd-steps,
  .hd-features,
  .hd-split,
  .hd-offer {
    grid-template-columns: minmax(0, 1fr);
  }
  .hd-steps li {
    padding-right: 0;
  }
  .hd-page .hd a.hd-btn {
    padding-inline: 2rem;
  }
  .hd-stage {
    border-radius: 7.2px 7.2px 0 0;
  }
}
