/* ── First Ring landing V3 — "night dispatch" ──────────────────────────────
   Three measures, and the width is the argument. 1560px is a machine surface —
   the night log and the dashboard — and runs to the edge of the window. 1040px
   is the record and the brand. 620px is where the page stops being a system and
   talks to you.

   The night half is a document, because those two sections really are records:
   hairline rules, monospace timestamps, a call list off the office phone and a
   transcript off the dashboard. The day half is not.
   It is paper out of a truck — a service tag with a punched hole. Nothing on
   this page is ruled unless the thing it holds is data.

   Type: Big Shoulders Display (poster) / Libre Franklin (body) / Sometype Mono
   (data). Three faces, three jobs, three different eras of American gothic —
   not one superfamily wearing three hats. Self-hosted below: three variable
   woff2, latin only, no third-party font request on this page.
   Safety-orange stays reserved: the ring, ANSWERED/BOOKED, the CTA. */

/* ── faces ────────────────────────────────────────────────────────────────
   Self-hosted, latin subset, one variable woff2 per family, only the weight
   range this page actually sets. The FAMILIES are deliberately unchanged: the
   live portal loads Spline Sans / Big Shoulders through next/font, and a site
   that disagrees with the product a client logs into is worse than a site with
   a common body face. The research was explicit that the typeface is not why
   this page read as machine-made. `swap` means the copy is readable on the
   first paint — a contractor reading this from a truck cab never waits on a
   font. Nothing here is fetched from a third party. */
@font-face {
  font-family: "Big Shoulders Display";
  font-style: normal;
  font-weight: 800 900;              /* the wordmark/H2s at 800, the two big heads at 900 */
  font-display: swap;
  src: url("fonts/big-shoulders-display-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Spline Sans";
  font-style: normal;
  font-weight: 400 700;              /* body 400, ledes/labels 500-700 */
  font-display: swap;
  src: url("fonts/spline-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Spline Sans Mono";
  font-style: normal;
  font-weight: 400 700;              /* timestamps 500-600, stamps 700 */
  font-display: swap;
  src: url("fonts/spline-sans-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

:root {
  --paper: #f7f8fa;
  --card: #ffffff;
  --ink: #16233b;
  --ink-soft: #45536b;
  --ink-mute: #5c6a80;
  --line: #e3e7ee;
  --ring: #e8642c;
  --ring-soft: #fdeee5;
  --ring-text: #b54712; /* darkened orange for small text on light surfaces (AA) */
  --data-blue: #2e6bd6;
  --good: #1d7a4f;
  --good-soft: #e3f3ea;
  --night: #0b1120;
  --night-2: #101b2e;
  --night-ink: #eef2f8;
  --night-soft: #bcc7d9;
  --night-mute: #8b97ad;
  --night-line: rgba(188, 199, 217, 0.16);
  --miss: #d4694f;

  --display: "Big Shoulders Display", "Arial Narrow", sans-serif;
  --body: "Spline Sans", system-ui, sans-serif;
  --mono: "Spline Sans Mono", ui-monospace, monospace;

  --tint: #eef1f5;
  --form-line: rgba(22, 35, 59, 0.22); /* printed-form rule: --ink at low alpha */

  --sheet: 1040px;      /* the record, the brand, the finale, the footer */
  --sheet-wide: 1560px; /* the dashboard, the one surface still built wide */
  --sheet-tag: 700px;   /* the tag */
  --measure: 620px;     /* the narrow column */
  --pad: clamp(20px, 5vw, 48px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 68px; color-scheme: dark; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--night);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--data-blue); text-decoration: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(232, 100, 44, 0.15);
}
a:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; border-radius: 2px; }

.mono { font-family: var(--mono); }
.sheet { max-width: var(--sheet); margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }
/* On any laptop 1560px is the whole window, so these two sections genuinely
   bleed. The rules bleed with them; the text inside keeps its own measure. */
.sheet-tag { max-width: var(--sheet-tag); }
/* the narrow column holds the same left edge as the 1040 sheet and ends early,
   so the measure changes without the page's left rail moving */
.sheet-narrow .datestamp,
.sheet-narrow .h2,
.sheet-narrow .band-lede { max-width: var(--measure); }
.sheet-narrow .band-lede { margin-bottom: 0; }

/* film grain on night sections */
.night { position: relative; background: var(--night); color: var(--night-ink); }
.night::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}
.night > * { position: relative; z-index: 2; }

/* ── ring mark ── */
.ring-mark {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border: 2.5px solid var(--ring); border-radius: 50%; flex: none;
}
.ring-core { width: 5px; height: 5px; border-radius: 50%; background: var(--ring); }
.ring-mark-sm { width: 14px; height: 14px; border-width: 2px; }
.ring-mark-sm .ring-core { width: 4px; height: 4px; }
/* pulse rides a ::after halo — transform/opacity only, compositor-friendly */
@keyframes ring-pulse {
  0% { transform: scale(1); opacity: 0.5; }
  70%, 100% { transform: scale(2.2); opacity: 0; }
}
@keyframes ring-pulse-soft {
  0% { transform: scale(1); opacity: 0.5; }
  70%, 100% { transform: scale(1.3); opacity: 0; }
}
.topbar .ring-mark::after {
  content: ""; position: absolute; inset: -2.5px; border-radius: 50%;
  border: 2px solid var(--ring); opacity: 0; pointer-events: none;
  animation: ring-pulse 2.4s ease-out 8;
}

/* ── skip link: off-screen until keyboard focus, sits above the sticky bar ── */
.skip-link {
  position: absolute; top: 0; left: -9999px; z-index: 40;
  font-weight: 700; font-size: 13px; letter-spacing: 0.08em;
  background: var(--ring); color: var(--night);
  padding: 12px 18px; border-radius: 0 0 6px 0;
}
.skip-link:focus, .skip-link:focus-visible { left: 0; }

/* ── top bar ── */
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px var(--pad);
  background: color-mix(in srgb, var(--night) 82%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--night-line);
}
.wordmark { display: inline-flex; align-items: center; gap: 10px; color: var(--night-ink); }
.wordmark:hover .wordmark-text { color: #fff; }
.wordmark:hover .ring-mark { border-color: #ff8a55; }
.wordmark-text {
  font-family: var(--display); font-weight: 800; font-size: 23px;
  letter-spacing: 0.05em; text-transform: uppercase;
}
.topnav { display: flex; align-items: center; gap: 22px; }
.topnav-signin {
  font-weight: 600; font-size: 15px;
  border: 1.5px solid var(--night-line); border-radius: 8px; padding: 8px 14px;
  color: var(--night-soft); background: rgba(255, 255, 255, 0.03);
}
.topnav-signin:hover { border-color: var(--night-soft); color: var(--night-ink); }
/* GET STARTED — the self-serve entry, on the sign-in chassis. It borrows the
   orange language but is never filled: the demo-line plate stays the loudest
   action on the page, and no text ever sits white on orange. Peach on night
   reads 10.7:1; the orange hairline reads 5.6:1. */
.topnav-start {
  font-weight: 700; font-size: 12.5px; letter-spacing: 0.1em;
  padding: 10px 14px;
  border-color: var(--ring);
  background: rgba(232, 100, 44, 0.14);
  color: #ffb18f;
  transition: transform 160ms ease;
}
.topnav-start:hover {
  border-color: #ff8a55; background: rgba(232, 100, 44, 0.24);
  color: #ffd0b8; transform: translateY(-1px);
}
/* white outline, so focus never lands orange-on-orange (same rule as .cta-number) */
.topnav-start:focus-visible { outline-color: #fff; }

/* ── hero: the locked cord-ring photograph (decision 0012) ── */
.hero-photo {
  position: relative;
  min-height: max(88vh, 560px);
  min-height: max(88svh, 560px);
  display: flex; flex-direction: column;
  background-color: #0b1120;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  /* The copy and the demo-line CTA sit at the bottom, and on a wide viewport
     that is exactly where the lit phone lands. The lower stop has to be dark
     enough to read against the brightest part of the photograph, not just
     against the concrete.
     Two declarations, deliberately: a renderer that cannot parse image-set()'s
     type() syntax drops the ENTIRE declaration, which would leave the hero with
     no photograph. The plain JPEG below is the floor; the modern formats win
     wherever they parse. 202 KB -> 25 KB. */
  background-image: linear-gradient(180deg, rgba(11, 17, 32, 0.62) 0%, rgba(11, 17, 32, 0.3) 20%, rgba(11, 17, 32, 0.82) 42%, rgba(11, 17, 32, 0.88) 70%, rgba(11, 17, 32, 0.93) 100%), url("hero.jpg");
  background-image: linear-gradient(180deg, rgba(11, 17, 32, 0.62) 0%, rgba(11, 17, 32, 0.3) 20%, rgba(11, 17, 32, 0.7) 44%, rgba(11, 17, 32, 0.8) 70%, rgba(11, 17, 32, 0.9) 100%), image-set(url("hero.avif") type("image/avif"), url("hero.webp") type("image/webp"), url("hero.jpg") type("image/jpeg"));
}
.hero-content {
  width: 100%;
  flex: 1;
  /* Centred as one stack rather than pinned top-and-bottom: the photograph is
     a centred composition, and splitting the type to the two extremes fought
     it. Everything now sits on the same vertical axis as the ring. */
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center;
  gap: clamp(22px, 4vh, 40px);
  padding-top: clamp(28px, 6vh, 72px);
  padding-bottom: clamp(28px, 6vh, 64px);
}
.hero-bottom {
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(20px, 3.2vh, 34px);
}
.hero-photo .hero-sub { text-shadow: 0 1px 14px rgba(11, 17, 32, 0.8); }
.hero-photo .hero-h1 { text-shadow: 0 2px 28px rgba(11, 17, 32, 0.7); }
.hero-h1 {
  font-family: var(--display); font-weight: 900;
  font-size: clamp(54px, 9.5vw, 140px);
  line-height: 0.86;
  text-transform: uppercase; letter-spacing: 0.005em;
  color: #fff;
  margin-bottom: 0;
}
.hero-h1 .line { display: block; overflow: hidden; padding-bottom: 0.1em; margin-bottom: -0.1em; }
.reveal-line { display: inline-block; transform: translateY(110%); animation: rise 760ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards; }
.hero-h1 .line:nth-child(2) .reveal-line { animation-delay: 110ms; }
@keyframes rise { to { transform: none; } }

.ring-glyph {
  /* The mark is punctuation on the end of RING, not an object beside it. Two
     things were wrong once the hero became a centred stack: it sat a whole
     word-space clear of the G, and — because it only adds width on the RIGHT —
     it looked like a badge parked beside the G rather than punctuation. Fix is
     size and proximity, NOT a negative margin — .line has overflow:hidden for
     the reveal mask, so pulling the advance back just clips the mark to an arc. */
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 0.5em; height: 0.5em;
  border: 0.055em solid var(--ring); border-radius: 50%;
  margin-left: 0.06em;
  vertical-align: baseline;
  transform: translateY(-0.05em);
}
.ring-glyph::after {
  content: ""; position: absolute; inset: -0.05em; border-radius: 50%;
  border: 0.045em solid var(--ring); opacity: 0; pointer-events: none;
  animation: ring-pulse-soft 2.4s ease-out 8;
}
.ring-glyph span { width: 0.13em; height: 0.13em; border-radius: 50%; background: var(--ring); }

.hero-sub {
  font-size: clamp(17.5px, 1.5vw, 20px); font-weight: 500;
  color: var(--night-soft); max-width: 34ch; margin-inline: auto;
}
.hero-cta { display: flex; flex-direction: column; align-items: center; }
/* The single highest-intent string on the page, and it was the lowest-contrast
   one: --night-mute over the lit part of the photograph. --night-soft is the
   same colour the body copy uses and clears AA on the raised scrim. */
.cta-label { font-size: 12.5px; font-weight: 600; letter-spacing: 0.08em; color: var(--night-soft); margin-bottom: 10px; }
.cta-number {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--ring); color: var(--night);
  border: 2px solid #ff8a55;
  border-radius: 10px; padding: 14px 26px 16px;
  position: relative;
  transition: transform 160ms ease;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 20px rgba(0, 0, 0, 0.45);
}
/* lift on hover rides ::after opacity — transform/opacity-only animation */
.cta-number::after {
  content: ""; position: absolute; inset: -2px; border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5), 0 14px 30px rgba(0, 0, 0, 0.55);
  opacity: 0; transition: opacity 160ms ease; pointer-events: none;
}
.cta-number:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.cta-number:hover { transform: translateY(-2px); }
.cta-number:hover::after { opacity: 1; }
.cta-tag { font-size: 11.5px; font-weight: 700; letter-spacing: 0.14em; color: var(--night); }
.cta-digits {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(34px, 4.4vw, 52px); letter-spacing: 0.02em; line-height: 1;
}
.cta-hint { margin-top: 12px; font-size: 16px; font-weight: 500; color: var(--night-mute); }

/* described background photos (a11y) */
.photo-desc { position: absolute; inset: 0; pointer-events: none; }

/* ── bands & rules ── */
.band { padding-top: clamp(48px, 8vh, 92px); padding-bottom: clamp(48px, 8vh, 92px); }
/* Identical padding on every band was half the lockstep. These are asymmetric
   on purpose: the log crowds the hero above it and opens up underneath, the
   call record gets the most air on the page, the tag gets the least. */
.band-log { padding-top: clamp(34px, 5vh, 58px); padding-bottom: clamp(56px, 10vh, 116px); }
.band-record { padding-top: clamp(56px, 10vh, 124px); padding-bottom: clamp(60px, 11vh, 132px); }
.band-portal { padding-top: clamp(40px, 6vh, 72px); padding-bottom: clamp(58px, 10vh, 120px); }
.band-tag { padding-top: clamp(32px, 5vh, 54px); padding-bottom: clamp(56px, 9vh, 104px); }

/* ── how it works, then what it costs ──────────────────────────────────────
   The steps are numbered because they ARE a sequence — you cannot read the
   transcript before she answers the call. The plans are not numbered, because
   they are a menu; numbering a menu implies a path through it. */
.band-price { padding-top: clamp(44px, 7vh, 84px); padding-bottom: clamp(48px, 8vh, 96px); }
.band-price .h2 { margin-top: 16px; }

.steps {
  list-style: none;
  display: grid;
  gap: clamp(22px, 3vw, 34px);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: clamp(30px, 4.5vh, 46px) 0 clamp(38px, 6vh, 60px);
}
.steps li { border-top: 2px solid var(--ink); padding-top: 14px; }
.step-n {
  display: block;
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--ring-text); margin-bottom: 10px;
}
.steps h3 {
  font-size: clamp(17px, 1.7vw, 19.5px); font-weight: 650;
  letter-spacing: -0.01em; line-height: 1.25; margin-bottom: 7px;
}
.steps p { font-size: 15px; font-weight: 500; color: var(--ink-soft); line-height: 1.5; }

.price-head {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-size: 11px; font-weight: 600; letter-spacing: 0.12em;
  color: var(--ink-mute);
  border-top: 2px solid var(--ink); padding-top: 9px; margin-bottom: 4px;
}

/* One row per plan. A five-column table cannot survive 390px, and a stack of
   five tall cards is a screen and a half of scrolling — so each plan is one
   row that folds its figures underneath the name instead. */
.tiers { list-style: none; }
.tier {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 2fr) repeat(3, minmax(0, 0.9fr));
  gap: 4px 18px;
  align-items: baseline;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.tier-name {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: 21px; letter-spacing: 0.03em; color: var(--ink);
}
.tier-for { font-size: 14.5px; font-weight: 500; color: var(--ink-soft); }
.tier-fig {
  font-size: 17px; font-weight: 650; color: var(--ink);
  font-variant-numeric: tabular-nums; text-align: right;
}
.tier-fig i {
  display: block; font-style: normal;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-mute); margin-bottom: 2px;
}
/* The tier a one-truck operator lands on, and the one the ads point at. Marked
   with the accent RULE rather than an orange fill — a filled row would be the
   third orange plate on the page and they stop meaning anything. */
.tier.is-featured {
  border-left: 3px solid var(--ring);
  padding-left: 16px;
  background: var(--ring-soft);
}
.tier.is-featured .tier-name { color: var(--ring-text); }

/* The offer sits between the plans and the terms, which is where a reader is
   deciding. Orange RULE, not an orange fill — the demo-line plate and the
   GET STARTED button already own the accent, and a third plate would flatten
   all three. */
.offer {
  margin-top: 26px;
  border-left: 3px solid var(--ring);
  background: var(--ring-soft);
  border-radius: 0 10px 10px 0;
  padding: 18px 22px;
}
.offer-tag {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--ring-text); margin-bottom: 7px;
}
.offer-line {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(22px, 3.2vw, 30px); line-height: 1;
  letter-spacing: 0.01em; color: var(--ink); margin-bottom: 9px;
}
.offer-sub {
  font-size: 15px; font-weight: 500; color: var(--ink-soft);
  line-height: 1.55; max-width: 52ch;
}
.offer-sub b { color: var(--ink); font-weight: 650; }

.price-note {
  margin-top: 22px; max-width: var(--measure);
  font-size: 15px; font-weight: 500; color: var(--ink-soft); line-height: 1.55;
}
.price-note b { color: var(--ink); font-weight: 650; }

@media (max-width: 880px) {
  .steps { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .tier {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2px 14px;
    padding: 18px 0;
  }
  .tier-name { grid-column: 1 / -1; }
  .tier-for  { grid-column: 1 / -1; margin-bottom: 10px; }
  .tier-fig  { text-align: left; }
  .tier.is-featured { padding-left: 14px; }
}

/* ── the last ask, on the finale photograph ───────────────────────────────
   The number plate above it is the only orange on this screen and it stays
   that way: a second filled plate would split the eye between two asks. This
   is an outlined button on night, which reads as the quieter of the two —
   correct, because anyone who still needs convincing should be dialling. */
.final-start-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin-top: clamp(24px, 4vh, 34px);
  padding-top: clamp(20px, 3vh, 28px);
  border-top: 1px solid var(--night-line);
}
.final-start {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 20px;
  letter-spacing: 0.05em;
  color: var(--night-ink);
  text-decoration: none;
  /* 2px because a control boundary needs 3:1 against its own background
     (WCAG 1.4.11); --night-line is a decorative hairline and would fail. */
  border: 2px solid rgba(238, 242, 248, 0.55);
  border-radius: 11px;
  padding: 12px 26px;
  transition: background-color 160ms ease, border-color 160ms ease, transform 160ms ease;
}
.final-start:hover {
  background: var(--ring);
  border-color: var(--ring);
  color: var(--night);          /* night on orange, 5.64:1 — never white, 3.34:1 */
  transform: translateY(-2px);
}
.final-start-arrow { font-size: 0.9em; }
.final-start-note {
  font-size: 15px;
  font-weight: 500;
  color: var(--night-soft);
}
@media (max-width: 480px) {
  .final-start-wrap { flex-direction: column; align-items: stretch; }
  .final-start { justify-content: center; }
  .final-start-note { text-align: center; }
}

.rulehead {
  display: flex; justify-content: space-between; gap: 16px;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.12em;
  color: var(--night-mute);
  border-top: 2px solid var(--night-ink);
  padding-top: 10px; margin-bottom: 26px;
}
/* the portal section opens on a clock stamp instead: one line, no rule, no
   second column — deliberately not the rulehead. */
.datestamp {
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.12em;
  color: var(--ink-mute); margin-bottom: 12px;
}

.h2 {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(40px, 5.5vw, 68px);
  line-height: 0.92; text-transform: uppercase; margin-bottom: 18px;
  text-wrap: balance;
}
.h2-light { color: #fff; }
/* and the straight-talk section opens on a plain heading, at reading size */
.h2-plain {
  font-size: clamp(21px, 2.4vw, 26px); font-weight: 700;
  line-height: 1.3; color: var(--ink); margin-bottom: 4px;
  text-wrap: balance;
}
.band-lede { color: var(--ink-soft); max-width: 40em; margin-bottom: 34px; }
.lede-dark { color: var(--night-soft); font-weight: 500; }

/* ── tonight's log: the office phone ─────────────────────────────────────
   The same night rendered as the call list it actually was, on the 10-inch
   phone that sits on the office desk next to the scheduling software. It is
   landscape because the width is the point: one row carries the number, where
   it rang from, when, and what was left behind, on one line each instead of a
   stack. Missed calls put the danger colour on the NUMBER, the way a real call
   log does — never on a stamp in a label column. The editorial column beside
   it is what keeps this a story and not a stock screenshot. */
.logband {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(30px, 4.5vw, 72px);
  align-items: center;
}
.log-h {
  font-weight: 700;
  font-size: clamp(25px, 2.6vw, 34px);
  line-height: 1.16; letter-spacing: -0.015em;
  color: var(--night-ink); text-wrap: balance;
  margin-bottom: 16px;
}
.log-intro .band-lede { margin-bottom: 0; max-width: 34em; }
/* Last thing in its column, so the 34px is dead on desktop and double-counts the
   grid gap once the band stacks on a phone. Same rule as .log-intro above. */
.ticket-intro .band-lede { margin-bottom: 0; }
/* the line that points down into the call record below */
.log-note {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--night-line);
  font-size: 15px; font-weight: 500; color: var(--night-mute); max-width: 34em;
}
.log-note b { color: var(--night-ink); font-weight: 600; }

/* ── the number the missed rows add up to ──────────────────────────────────
   The log's payoff, and the one figure a contractor actually wants: what those
   missed rows cost in a month. It wears the SAME red as the missed calls
   themselves (--miss), not the reserved safety-orange — this is loss, not the
   accent. One conditional example, honest about the 1-in-3 bookable share and
   labelled as an example, so it informs without pretending to be his invoice. */
.log-cost {
  margin-top: 22px;
  padding: 16px 20px 18px;
  border: 1px solid var(--night-line);
  border-left: 3px solid var(--miss);
  border-radius: 0 8px 8px 0;
  background: rgba(212, 105, 79, 0.06);
}
.log-cost-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--night-mute); margin-bottom: 9px;
}
.log-cost-lead {
  font-size: 15px; font-weight: 500; color: var(--night-soft);
  line-height: 1.5; max-width: 42ch; margin-bottom: 8px;
}
.log-cost-lead b { color: var(--night-ink); font-weight: 650; }
.log-cost-fig { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; }
.log-cost-num {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(44px, 6vw, 62px); line-height: 0.9;
  letter-spacing: 0.01em; color: var(--miss);
  font-variant-numeric: tabular-nums;
}
.log-cost-per { font-size: 15.5px; font-weight: 600; color: var(--night-soft); }
.log-cost-foot {
  margin-top: 10px; font-size: 13px; font-weight: 500;
  color: var(--night-mute); max-width: 44ch;
}

/* ── the object: one phone, drawn once, shown small ──────────────────────
   Everything inside the screen is laid out at a fixed logical width (--canvas)
   and then scaled by --k. That is the whole trick, and it is the difference
   between a phone and a narrow column: scaling shrinks the type along with the
   frame, where simply making the box narrower leaves 18px numerals sitting in
   a 300px slab, which is what makes a mock read as a broken layout.

   The screen's HEIGHT comes from the same pair, so the object keeps phone
   proportions no matter how many rows the list holds — the list overruns the
   bottom and the fade cuts it off, which is also just true. The evening
   carried on. */
.phone {
  --canvas: 360px;    /* the width it is DRAWN at */
  --canvas-h: 730px;  /* … and the height, same units */
  --k: 0.86;          /* the scale it is SHOWN at */
  --bezel: 10px;
  position: relative;
  width: calc(var(--canvas) * var(--k) + var(--bezel) * 2 + 2px); /* +2px = the border, which box-sizing eats out of the padding box */
  padding: var(--bezel);
  border-radius: 42px;
  background: var(--night-2);
  border: 1px solid var(--night-line);
  box-shadow:
    24px 38px 78px -38px rgba(0, 0, 0, 0.92),
    inset 0 1px 0 rgba(255, 255, 255, 0.055),
    inset -1px 0 0 rgba(255, 255, 255, 0.028);
}
.phone-screen {
  position: relative;
  height: calc(var(--canvas-h) * var(--k));
  border-radius: 32px;
  background: var(--night);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}
/* The island and the fade are drawn in SCREEN px, not canvas px, so both are
   written ×--k by hand to stay in step with the scaled contents. */
.phone-screen::before {
  content: ""; position: absolute; z-index: 3;
  top: calc(9px * var(--k)); left: 50%;
  width: calc(92px * var(--k)); height: calc(26px * var(--k));
  margin-left: calc(-46px * var(--k));
  border-radius: 999px;
  background: #04070d;
}
.phone-screen::after {
  content: ""; position: absolute; z-index: 2; inset: auto 0 0 0;
  height: calc(90px * var(--k));
  background: linear-gradient(to bottom, rgba(11, 17, 32, 0), var(--night) 72%);
  pointer-events: none;
}
.phone-canvas {
  position: absolute; top: 0; left: 0; z-index: 1;
  width: var(--canvas);
  transform: scale(var(--k));
  transform-origin: top left;
}

/* status strip — 11:02 PM, one bar out, nearly dead */
.phone-status {
  display: flex; justify-content: space-between; align-items: center;
  padding: 11px 22px 9px;
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.06em; color: var(--night-mute);
}
.phone-status-r { display: inline-flex; align-items: center; gap: 8px; }
.phone-sig { display: inline-flex; align-items: flex-end; gap: 1.5px; height: 9px; }
.phone-sig span { width: 2px; background: var(--night-mute); border-radius: 1px; }
.phone-sig span:nth-child(1) { height: 3px; }
.phone-sig span:nth-child(2) { height: 6px; }
.phone-sig span:nth-child(3) { height: 9px; opacity: 0.3; }
.phone-batt {
  position: relative; display: inline-block; width: 18px; height: 9px;
  border: 1px solid var(--night-mute); border-radius: 2.5px; padding: 1px;
}
.phone-batt::after {
  content: ""; position: absolute; top: 2.5px; right: -3px;
  width: 2px; height: 3px; border-radius: 0 1px 1px 0; background: var(--night-mute);
}
.phone-batt span { display: block; width: 12%; min-width: 2px; height: 100%; border-radius: 1px; background: var(--miss); }

/* list header */
.phone-bar {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 5px 22px 11px;
}
.phone-title { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; color: var(--night-ink); }
.phone-count {
  font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  white-space: nowrap;
  color: var(--miss); border: 1px solid rgba(212, 105, 79, 0.42);
  background: rgba(212, 105, 79, 0.1); border-radius: 999px; padding: 3px 10px;
}
.phone-day {
  padding: 4px 22px 5px; background: rgba(255, 255, 255, 0.035);
  font-size: 12px; font-weight: 600; color: var(--night-mute);
}

/* ── one call ───────────────────────────────────────────────────────────── */
.calls { list-style: none; }
/* One layout only. The canvas is 360px at every viewport, so the four-column
   desktop row this used to switch to could never fire again — the note drops
   under the number, the way it does on the handset being imitated. */
.call {
  position: relative;
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  grid-template-areas: "arrow who when" ". note note";
  column-gap: 12px;
  align-items: start;
  padding: 12px 22px 13px;
}
.call-arrow { margin-top: 4px; }
.call-when { padding-top: 2px; }
.call-note { margin-top: 7px; }
.call + .call::before {
  content: ""; position: absolute; top: 0; left: 52px; right: 22px; height: 1px;
  background: rgba(188, 199, 217, 0.085);
}
/* the same incoming-call glyph on every row — the colour carries the state */
.call-arrow {
  grid-area: arrow; display: block; align-self: start;
  width: 14px; height: 14px; color: var(--night-mute); overflow: visible;
}
.call-who { grid-area: who; min-width: 0; }
.call-num {
  font-size: 18px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
  font-variant-numeric: tabular-nums; color: var(--night-ink);
}
.call-rpt { font-family: var(--mono); font-size: 13px; font-weight: 600; opacity: 0.75; margin-left: 3px; }
.call-meta { margin-top: 3px; font-size: 12px; font-weight: 500; color: var(--night-mute); }
.call-when {
  grid-area: when; text-align: right; white-space: nowrap;
  font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--night-mute);
}
.call-dur { display: block; margin-top: 3px; font-family: var(--mono); font-size: 11.5px; font-weight: 600; color: var(--ring); }
.call-note {
  grid-area: note; min-width: 0; text-wrap: pretty;
  font-size: 14.5px; font-weight: 500; line-height: 1.45; color: var(--night-soft);
}
.call-sting { color: var(--miss); font-weight: 600; }
/* voicemail tag — the device's own label, in the device's own type */
.call-vm {
  display: inline-block; margin-right: 10px; vertical-align: 1px;
  font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.11em;
  color: var(--night-mute); border: 1px solid var(--night-line);
  border-radius: 3px; padding: 2px 7px;
}
/* night-navy on orange, never the other way round */
.call-ans {
  display: inline-block; margin-right: 10px; vertical-align: 1px;
  font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.11em;
  background: var(--ring); color: var(--night);
  border-radius: 3px; padding: 3px 9px;
}
.call-miss .call-num, .call-miss .call-arrow { color: var(--miss); }
/* the one that got answered: lit row, orange rail, a duration nothing else has */
.call-hit {
  background: rgba(232, 100, 44, 0.1);
  border-left: 3px solid var(--ring);
  padding-left: 19px; padding-top: 14px; padding-bottom: 15px;
}
.call-hit::before { display: none; }
.call-hit .call-arrow { color: var(--ring); }
.call-hit .call-meta { color: var(--night-soft); }
.call-hit .call-note { color: var(--night-ink); }
/* the evening carries on underneath, dimming, because it did. No scrim here:
   the screen's own bottom fade is what cuts the list off. */
.calls-more { border-top: 1px solid rgba(188, 199, 217, 0.085); }
.calls-more .call:nth-child(1) { opacity: 0.5; }
.calls-more .call:nth-child(2) { opacity: 0.34; }
.calls-more .call:nth-child(3) { opacity: 0.22; }

/* ── ticket band ── */
.ticket-band {
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 5vw, 64px); align-items: center;
}
.ticket {
  background: var(--card); color: var(--ink);
  border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 24px 64px rgba(0, 0, 0, 0.5);
  padding: 18px 20px;
}
.ticket-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 12px; border-bottom: 2px solid var(--ink);
  font-size: 13px; font-weight: 700; letter-spacing: 0.08em;
}
.ticket-status { display: inline-flex; align-items: center; gap: 9px; }
.ticket-status-dot { position: relative; width: 9px; height: 9px; border-radius: 50%; background: var(--ring); flex: none; }
.ticket-status-dot::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%;
  border: 2px solid var(--ring); opacity: 0; pointer-events: none;
  animation: ring-pulse 2.4s ease-out 8;
}
.ticket-status[data-state="live"] .ticket-status-dot { background: var(--good); }
.ticket-status[data-state="done"] .ticket-status-dot { background: var(--ink-mute); }
.ticket-status[data-state="live"] .ticket-status-dot::after,
.ticket-status[data-state="done"] .ticket-status-dot::after { animation: none; }
.ticket-timer { color: var(--ink-mute); }

.ticket-lines { padding: 14px 0 4px; display: flex; flex-direction: column; gap: 10px; }
.tl { font-size: 15.5px; font-weight: 500; display: flex; gap: 8px; align-items: baseline; }
.js .tl { opacity: 0; transform: translateY(4px); transition: opacity 320ms ease, transform 320ms ease; }
.tl.shown { opacity: 1; transform: none; }
.tl .who {
  display: inline-block; width: 62px; flex: none;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  color: var(--ink-mute);
}
.tl-agent { color: var(--ink); }
.tl-caller { color: var(--ink-soft); }
.tl-meta { font-size: 12.5px; font-weight: 600; letter-spacing: 0.06em; color: var(--data-blue); padding-left: 70px; }

.ticket-booked {
  margin-top: 10px;
  border: 1.5px dashed var(--ring);
  background: var(--ring-soft); border-radius: 6px; padding: 12px 14px;
}
.js .ticket-booked { opacity: 0; transform: translateY(4px); transition: opacity 380ms ease, transform 380ms ease; }
.ticket-booked.shown { opacity: 1; transform: none; }
.booked-row { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; }
.booked-chip {
  font-family: var(--mono); font-weight: 700; font-size: 12px;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--ring); color: var(--night); border-radius: 3px; padding: 2px 10px;
}
.booked-when { font-weight: 600; }
.booked-detail { display: flex; justify-content: space-between; gap: 10px; font-size: 13.5px; font-weight: 500; color: var(--ink-soft); flex-wrap: wrap; }
.booked-remind { color: var(--ink); font-weight: 500; font-size: 15px; }
.ticket-foot { margin-top: 13px; font-size: 15px; font-weight: 500; color: var(--ink-soft); }
.js .ticket-foot { opacity: 0; transition: opacity 380ms ease; }
.ticket-foot.shown { opacity: 1; }

/* ── dawn ── */
/* The last stop must be the ground colour of whatever band follows, or the
   sunrise ends on a hairline seam. That is now the tinted dashboard band. */
.dawn {
  height: clamp(110px, 16vh, 180px);
  background: linear-gradient(180deg, var(--night) 0%, #2a2c44 34%, #7c5a54 62%, #d8a06e 82%, var(--tint) 100%);
}

/* ── day ── */
.day { background: var(--paper); color: var(--ink); }
.band-tint { background: var(--tint); }

/* portal mock — the caption is 620px, the screen behind it is 1560px */
.portal-wide {
  max-width: var(--sheet-wide);
  margin: clamp(30px, 5vh, 56px) auto 0;
  padding-left: var(--pad); padding-right: var(--pad);
}
.portal-mock {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(16, 27, 46, 0.05), 0 16px 40px rgba(16, 27, 46, 0.08);
  font-size: 15px;
}
.pm-chrome { display: flex; align-items: center; gap: 7px; padding: 11px 16px; background: var(--night-2); }
.pm-chrome span { width: 10px; height: 10px; border-radius: 50%; background: rgba(215, 222, 234, 0.3); }
.pm-chrome em { font-style: normal; color: var(--night-mute); font-size: 12px; font-weight: 600; letter-spacing: 0.12em; margin-left: 8px; }
.pm-row {
  display: grid; grid-template-columns: 1.1fr 0.9fr 1.6fr 1fr 1fr;
  gap: 12px; padding: 13px 18px; border-top: 1px solid var(--line); align-items: center;
}
.pm-head { border-top: none; font-size: 11.5px; font-weight: 700; letter-spacing: 0.1em; color: var(--ink-mute); }
.pm-row .mono { font-size: 13.5px; font-weight: 500; color: var(--ink-soft); }
.pm-dash { color: var(--ink-mute); }
.chip {
  font-style: normal; display: inline-block; border-radius: 99px; padding: 2px 11px;
  font-size: 13.5px; font-weight: 600; background: var(--line); color: var(--ink-soft);
}
.chip-good { background: var(--good-soft); color: var(--good); }
.chip-booked { background: var(--ring-soft); color: var(--ring-text); }

/* ── the tag ──────────────────────────────────────────────────────────────
   The narrowest measure on the page and the only object that is neither a
   record nor a form: the service tag you wire to a unit. None of this is
   machine output, so none of it is ruled, columned or monospaced — the three
   limits are just sentences, and the width is what makes you slow down. */
.tagout {
  position: relative;
  background: var(--card);
  border: 1.5px solid var(--form-line);
  border-radius: 12px;
  padding: 46px 26px 20px;
  box-shadow: 0 1px 2px rgba(16, 27, 46, 0.05), 0 14px 34px rgba(16, 27, 46, 0.08);
}
/* the punched hole: page colour showing through the card */
.tagout::before {
  content: ""; position: absolute; top: 17px; left: 50%; margin-left: -9px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--paper); border: 1.5px solid var(--form-line);
}
.nevers { list-style: none; margin-top: 16px; display: flex; flex-direction: column; gap: 15px; }
.nevers li { color: var(--ink-soft); font-size: 16px; }
.nevers strong { color: var(--ink); }
.tag-foot {
  margin-top: 22px; padding-top: 12px;
  border-top: 1px dashed var(--form-line);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.14em; color: var(--ink-mute);
}

/* finale */
/* finale photo lazy-loads: script.js adds .bg-loaded near the viewport
   (IntersectionObserver, 600px rootMargin); the gradient is always on. */
.final-photo {
  background-color: #0b1120;
  background-image: linear-gradient(100deg, rgba(11, 17, 32, 0.92) 0%, rgba(11, 17, 32, 0.72) 45%, rgba(11, 17, 32, 0.35) 100%);
}
.final-photo.bg-loaded {
  background-image: linear-gradient(100deg, rgba(11, 17, 32, 0.92) 0%, rgba(11, 17, 32, 0.72) 45%, rgba(11, 17, 32, 0.35) 100%), url("finale.jpg");
  background-image: linear-gradient(100deg, rgba(11, 17, 32, 0.92) 0%, rgba(11, 17, 32, 0.72) 45%, rgba(11, 17, 32, 0.35) 100%), image-set(url("finale.avif") type("image/avif"), url("finale.webp") type("image/webp"), url("finale.jpg") type("image/jpeg"));
  background-position: center, right center;
  background-size: auto, cover;
  background-repeat: no-repeat, no-repeat;
}
.final-photo::after { display: none; }
.band-final { text-align: left; }
.final-inner { display: flex; flex-direction: column; align-items: flex-start; }
.final-h2 {
  font-family: var(--display); font-weight: 900;
  font-size: clamp(52px, 9vw, 128px); line-height: 0.88;
  text-transform: uppercase; color: #fff; margin-bottom: 18px;
  text-wrap: balance;
}
.final-sub { color: var(--night-soft); font-weight: 500; max-width: 38em; margin-bottom: 30px; }

/* footer */
.footer { background: var(--night); border-top: 1px solid var(--night-line); padding: 30px 0 42px; }
.footer-inner { color: var(--night-mute); font-size: 15px; font-weight: 500; display: flex; flex-direction: column; gap: 8px; }
.footer-brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--display); font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--night-soft); font-size: 17px;
}
.footer-legal { font-size: 13px; letter-spacing: 0.08em; }
.footer a { color: var(--night-soft); text-decoration: underline; text-underline-offset: 3px; }
.footer a:hover { color: var(--night-ink); }
/* stretch the tiny mono legal links to a ~44px hit area without moving pixels */
.footer-legal a { display: inline-block; padding: 12px 4px; margin: -12px -4px; }

/* ── reveals ── */
/* hidden initial states only exist when JS is running (html gets .js in <head>);
   with JS off or blocked the page renders in its finished state */
.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity 560ms ease, transform 700ms linear(0, 0.0047, 0.0966 3.6%, 0.5895 12.4%, 0.8709 19%, 0.9721 24.2%, 1.0158 30%, 1.0313 38.2%, 1.0132 60.6%, 1.0006 83.4%, 1); }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .js .reveal { opacity: 1; transform: none; transition: none; }
  .reveal-line { transform: none; animation: none; }
  .topbar .ring-mark::after, .ring-glyph::after, .ticket-status-dot::after { animation: none; }
}

/* ── responsive ── */
@media (max-width: 880px) {
  .hero-h1 { font-size: clamp(50px, 14vw, 120px); }
  /* Breathing room under the sticky bar — the headline was jammed against it. */
  .hero-content { padding-top: clamp(20px, 4vh, 72px); }
  .hero-sub { font-size: 16.5px; }
  .hero-photo {
    /* A 2.3:1 photo pushed through `cover` into a tall phone container zooms by
       however tall that container happens to be — which put the composition at
       the mercy of whatever svh resolved to, and blew it up. Phones get a
       PORTRAIT master (3:4, cropped from the same locked shot) and a height
       capped at that same aspect, so the work light, the ring and the phone are
       always all in frame. 132vw ≈ 4/3 × 100vw = the tallest this crop can go
       before it starts losing its sides. */
    min-height: min(86svh, 132vw);
    background-image: linear-gradient(180deg, rgba(11, 17, 32, 0.62) 0%, rgba(11, 17, 32, 0.32) 20%, rgba(11, 17, 32, 0.84) 42%, rgba(11, 17, 32, 0.9) 70%, rgba(11, 17, 32, 0.94) 100%), url("hero-portrait.jpg");
    background-image: linear-gradient(180deg, rgba(11, 17, 32, 0.62) 0%, rgba(11, 17, 32, 0.32) 20%, rgba(11, 17, 32, 0.72) 44%, rgba(11, 17, 32, 0.82) 70%, rgba(11, 17, 32, 0.92) 100%), image-set(url("hero-portrait.avif") type("image/avif"), url("hero-portrait.webp") type("image/webp"), url("hero-portrait.jpg") type("image/jpeg"));
    background-position: center;
  }
  .final-photo.bg-loaded {
    background-image:
      linear-gradient(100deg, rgba(11, 17, 32, 0.92) 0%, rgba(11, 17, 32, 0.72) 45%, rgba(11, 17, 32, 0.35) 100%),
      url("finale-800.jpg");
      background-image: linear-gradient(100deg, rgba(11, 17, 32, 0.92) 0%, rgba(11, 17, 32, 0.72) 45%, rgba(11, 17, 32, 0.35) 100%), image-set(url("finale-800.avif") type("image/avif"), url("finale-800.webp") type("image/webp"), url("finale-800.jpg") type("image/jpeg"));
  }
  /* two actions instead of one — tighten both so the bar stays a single row */
  .topnav { gap: 12px; }
  .topnav-signin { font-size: 14px; padding: 8px 12px; }
  .topnav-start { font-size: 11.5px; letter-spacing: 0.08em; padding: 10px 12px; }
  .ticket-band { grid-template-columns: 1fr; }
  .pm-row { grid-template-columns: 1.4fr 1fr 1fr; }
  .pm-row span:nth-child(1), .pm-head span:nth-child(1) { display: none; }
  .pm-row span:nth-child(4), .pm-head span:nth-child(4) { display: none; }
  /* Stacked on a phone, the editorial column landed on top: 89 words before the
     artifact. Lead with the log — it makes the argument in one glance — and let
     the prose follow it. */
  .logband { display: flex; flex-direction: column; }
  .logband .phone { order: -1; align-self: center; }
  .log-intro .band-lede { font-size: 16.5px; }
  /* Once the phone leads, this kicker is no longer opening anything — it is the
     caption under the exhibit. The page's heaviest rule (2px --night-ink) goes
     back to being unique to the CALL RECORD below it, so the two night documents
     stop announcing themselves with the identical device half a screen apart. */
  .logband .rulehead {
    border-top: 1px solid var(--night-mute);
    margin-bottom: 22px;
  }

/* ── phone rhythm: the air says whether the ground changed ─────────────────
   Every band pad on this page is a vh clamp, so a 390×844 phone was handed
   84–85px top AND bottom — the same air a 1440 desktop gets, on a measure a
   third as wide. Measured at 390 before this block: 169px of flat night
   between the log's closing line and the CALL RECORD rule, 127px of flat
   paper between the dashboard and the tag, 102px between the demo plate and
   the call list. Nothing changes ground across any of those, so they read as
   holes in the page rather than as joins.

   Below 880 the air is set in px, and it is set by the JOIN: ~80px where the
   ground does not change, and the ground change itself (the dawn, and the cut
   from paper to the finale photograph) left to carry the ones where it does.
   The hero is not touched — its stack already fills it to within 9px top and
   bottom at 390 and to within 1px at 360; the void was never inside it. */
  .band-log    { padding-top: 30px; padding-bottom: 40px; }  /* 40 + 44 = 84 to the record */
  .band-record { padding-top: 44px; padding-bottom: 58px; }  /* then the dawn does the rest */
  .band-portal { padding-top: 34px; padding-bottom: 48px; }  /* the dawn lands ON the tint */
  .band-tag    { padding-top: 34px; padding-bottom: 58px; }  /* 48 + 34 = 82 off the dashboard */
}

@media (max-width: 560px) {
  /* Wordmark + two actions on a phone-width row: the name stays (a bare ring
     mark reads as a broken logo), and the row tightens around it instead. */
  .topbar { padding-left: 16px; padding-right: 16px; }
  .wordmark { gap: 7px; }
  .wordmark-text { font-size: 17px; letter-spacing: 0.03em; }
  .topnav { gap: 8px; }
  .topnav-start { font-size: 10.5px; letter-spacing: 0.06em; padding: 9px 10px; }
  .topnav-signin { font-size: 13px; padding: 7px 10px; }
}

/* The frame has one fixed width, so a narrow handset shrinks the whole object
   rather than reflowing anything inside it. The measure to fit inside is
   (viewport - 2×--pad), and --pad is itself 5vw between 400 and 960, so the
   two shrink together — these tiers are set from the tightest viewport each
   one has to survive, not from the widest:
     ≤430  → 301px inside a 321px measure at 361  (20px spare)
     ≤360  → 265px inside a 280px measure at 320  (15px spare)
   max-width is the backstop: if a viewport ever undercuts the last tier, the
   frame narrows and the canvas crops a few px on the right, which is a far
   better failure than scrolling the whole page sideways. */
.phone { max-width: 100%; }
@media (max-width: 430px) { .phone { --k: 0.78; } }
@media (max-width: 360px) { .phone { --k: 0.68; } }

@media (max-width: 380px) {
  /* Last resort on the very narrowest phones — the name goes before either
     action does; the ring mark still links home and announces itself. */
  .wordmark-text { display: none; }
}

@media (max-width: 360px) {
  /* The 50px floor in the 880 rule is above 14vw down here, so the headline
     stopped scaling and broke to four lines, taking the ring mark onto a line
     of its own. The mark is punctuation on the end of RING (see .ring-glyph);
     a line of its own is the one thing it must never get. */
  .hero-h1 { font-size: 12.5vw; }
}
