/* Nocturne, ported for the gt7-datalogger.com landing page.
 *
 * The page is one static file served by anything that can serve a directory,
 * so the design system arrives the same way: tokens and a handful of component
 * classes in plain CSS, with no build step to run and nothing to install. The
 * token names are deliberately identical to the sync portal's
 * (portal/src/styles/tokens.css) — the two surfaces share a domain and a look,
 * and a reader moving between them should find the same variable meaning the
 * same colour. Only the ramp steps this page actually paints are carried over;
 * the rest would be dead weight in a file nobody compiles.
 *
 * The system's signature is restraint with one blurple accent: used as a line,
 * a glow or a tint, never as a flood. Buttons are outlined, not filled. Rules
 * fade out at both ends instead of stopping. Nothing outside this file writes
 * a colour.
 */

/* Inter is requested by `index.html`, not imported here. An @import inside a
   linked stylesheet is only discovered once this file has been fetched and
   parsed, so the font would queue behind it on a second, serial round trip —
   and the page already carries the preconnect hints that a <link> in the head
   makes use of. The stack below still names a system fallback, so the page
   sets in something sensible while the webfont is in flight or blocked. */

:root {
  /* — ground and ink — */
  --color-bg: #161826;
  --color-surface: #232532;
  --color-text: #e9e9ed;
  --color-accent: #9184d9;
  --color-divider: color-mix(in srgb, #e9e9ed 16%, transparent);

  /* — ramps on one shared lightness scale, so the same step of any role
       matches the others in visual value — */
  --color-neutral-100: #f3f5fe;
  --color-neutral-200: #e4e7f5;
  --color-neutral-400: #b2b6ca;
  /* 500 is the darkest muted step this page puts real words in. Nocturne offers
     600 for meta text as well, but at the 12–13px this page sets its footnote,
     footer and code comments in, 600 lands at 4.1:1 on the ground and 3.5:1 on
     a surface — under the 4.5:1 that small text has to clear. 500 clears it on
     both (6.1:1 and 5.3:1) and still reads as an aside. */
  --color-neutral-500: #9397ab;
  /* 300, 600 and 700 are drawn with and never written in: the 404's chequered
     swatch, its gravel and its start-line tick. */
  --color-neutral-300: #cfd3e5;
  --color-neutral-600: #75798c;
  --color-neutral-700: #595d6c;
  --color-neutral-800: #3f424d;

  --color-accent-100: #f5f4ff;
  --color-accent-200: #e7e5fe;
  --color-accent-300: #d2cefd;

  /* Section band ground: a saturated deep indigo used at deck scale only —
     the stat band and the donate band, never an interface surface. */
  --color-section: #262a60;
  --color-section-glow: #353b80;

  --font-heading: "Inter", system-ui, sans-serif;
  --font-heading-weight: 500;
  --font-body: "Inter", system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --radius-md: 8px;
  --radius-lg: 14px;

  /* Elevation on a dark ground: a hairline edge plus ambient darkness. */
  --shadow-sm: 0 0 0 1px #3f424d;
  --shadow-md: 0 0 0 1px #595d6c, 0 6px 18px rgba(0, 0, 0, 0.55);

  /* The one horizontal rhythm the whole page shares. Its floor is 20px, which
     clears the 16px side gutter the narrowest phone needs. */
  --gutter: clamp(20px, 5vw, 64px);
  --measure: 1280px;

  --band: linear-gradient(120deg,
    var(--color-section), var(--color-section-glow) 60%, var(--color-section));

  /* A rule that fades to nothing 48px from each end rather than stopping
     cleanly — a Nocturne signature, reused as a top or bottom edge. */
  --rule: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent);
}

/* ── base ─────────────────────────────────────────────────────────────── */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  /* Nothing on the page may push the viewport sideways. */
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

img { display: block; max-width: 100%; height: auto; }

a { color: var(--color-accent); text-underline-offset: 3px; }
a:hover { color: var(--color-accent-300); }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* Screenshots are dark-on-dark captures; lightening them onto the ground
   dissolves their letterboxing instead of framing it. */
.lighten { mix-blend-mode: lighten; background-color: transparent; }

.kicker {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.shot {
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  min-width: 0;
}

/* ── buttons ──────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 14px;
  line-height: 1.2;
  color: var(--color-text);
  background: transparent;
  border: 1px solid transparent;
  padding: 5.6px 10px;
  border-radius: var(--radius-md);
}
.btn-primary { color: var(--color-accent); border-color: var(--color-accent); }
.btn-primary:hover {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.btn-primary:active { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }

.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:hover {
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-text) 7%, transparent);
}
.btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }

.btn-ghost { color: var(--color-accent); padding-inline: 2.8px; }
.btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }

.btn-lg { font-size: 15px; padding: 11px 18px; }

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* ── tags ─────────────────────────────────────────────────────────────── */

.tags {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tag-neutral {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: 6px;
  background: var(--color-neutral-800);
  color: var(--color-neutral-100);
}

/* ── nav ──────────────────────────────────────────────────────────────── */

.site-nav {
  display: flex;
  align-items: center;
  gap: 11.2px;
  flex-wrap: wrap;
  padding: 10px var(--gutter);
  min-height: 56px;
}
.site-nav a { color: inherit; text-decoration: none; font-size: 14px; }
.site-nav a:hover { color: var(--color-accent); }
.site-nav .btn:hover { color: var(--color-text); }

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  margin-right: auto;
}
/* The GT7 Datalogger mark. A square file with the symbol centred in it, wider
   than it is tall — so it is given the square, and the nav's own min-height
   is what sets the row. */
.brand-mark {
  width: 32px;
  height: 32px;
  flex: none;
}

.rule { height: 1px; background: var(--rule); }

/* ── hero ─────────────────────────────────────────────────────────────── */

.hero {
  padding: clamp(48px, 8vw, 110px) var(--gutter) 40px;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(24px, 5vw, 72px);
  align-items: center;
  position: relative;
  overflow: hidden;
}
/* The accent as a glow rather than a fill: 9 % of it, thrown behind the
   screenshot so the eye lands there before it reads the headline. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 50% at 70% 40%,
    color-mix(in srgb, var(--color-accent) 9%, transparent), transparent 70%);
  pointer-events: none;
}
.hero-copy {
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: relative;
}
.hero h1 {
  font-size: clamp(38px, 5vw, 64px);
  line-height: 1.02;
  letter-spacing: -0.02em;
}
.hero-lede {
  font-size: clamp(16px, 1.4vw, 19px);
  color: var(--color-neutral-400);
  max-width: 520px;
}
.hero .btn-row { margin-top: 4px; }
.hero-footnote {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--color-neutral-500);
  font-variant-numeric: tabular-nums;
}
.hero-figure { position: relative; min-width: 0; }
.hero-figure .shot { box-shadow: var(--shadow-md); }

/* A lit dash chasing a track outline: motion as a hint that the thing on the
   left is a recording, not a still. Decorative, so it is hidden from
   assistive technology and stilled for anyone who asks for less motion. */
.track-outline {
  position: absolute;
  right: -6%;
  bottom: -14%;
  width: 38%;
  overflow: visible;
  pointer-events: none;
}
.track-outline .bed { fill: none; stroke: var(--color-neutral-800); stroke-width: 18; stroke-linejoin: round; }
.track-outline .spark {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1.5;
  stroke-dasharray: 8 392;
  stroke-linecap: round;
  filter: drop-shadow(0 0 6px var(--color-accent));
  animation: dash 5s linear infinite;
}
@keyframes dash { to { stroke-dashoffset: -400; } }

@media (prefers-reduced-motion: reduce) {
  .track-outline .spark { animation: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ── stat band ────────────────────────────────────────────────────────── */

.stat-band {
  background: var(--band);
  padding: 36px var(--gutter);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 24px;
}
.stat-num {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 40px;
  line-height: 1;
  /* Figures in a row of figures should share a width, so the eye compares
     them instead of re-measuring each one. */
  font-variant-numeric: tabular-nums;
}
.stat-caption {
  font-size: 13px;
  color: var(--color-accent-200);
  margin-top: 6px;
}

/* ── what it logs ─────────────────────────────────────────────────────── */

.section {
  padding: clamp(56px, 7vw, 96px) var(--gutter);
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
}
.section-head {
  max-width: 620px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.section-head h2,
.selfhost h2 {
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: -0.015em;
}

.logs { display: flex; flex-direction: column; gap: clamp(40px, 5vw, 72px); }

.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.row-copy { display: flex; flex-direction: column; gap: 14px; }
.row-copy h3 { font-size: 26px; }
.row-copy p { color: var(--color-neutral-400); font-size: 15px; }

/* Copy leads in the markup so a narrow screen and a screen reader both get the
   claim before the picture of it; the alternation is a wide-screen affordance,
   applied there and nowhere else. */
@media (min-width: 900px) {
  .row-reverse .shot { order: -1; }
}

/* ── self-host ────────────────────────────────────────────────────────── */

.selfhost {
  padding: 0 var(--gutter) clamp(56px, 7vw, 96px);
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}
.selfhost-copy { display: flex; flex-direction: column; gap: 14px; }
.selfhost-copy p { color: var(--color-neutral-400); font-size: 15px; }
.selfhost-aside { display: flex; flex-direction: column; gap: 10px; min-width: 0; }

.commands {
  margin: 0;
  padding: 16px 18px;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-neutral-200);
  overflow-x: auto;
}
.commands .comment { color: var(--color-neutral-500); }

/* Three cells divided by the ground showing through a 1px gap, so the grid
   needs no borders of its own. */
.ports {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--color-divider);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: 12.5px;
}
.ports > div { background: var(--color-bg); padding: 10px 12px; }
.ports dt {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-neutral-500);
  font-variant-numeric: tabular-nums;
}
.ports dd { margin: 0; }

/* ── sync ─────────────────────────────────────────────────────────────── */

/* The same two-column shape as self-host, so the two optional halves of the
   product — run it yourself, connect it to the service — read as a pair. */
.sync {
  padding: 0 var(--gutter) clamp(56px, 7vw, 96px);
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}
.sync-copy { display: flex; flex-direction: column; gap: 14px; }
.sync h2 {
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: -0.015em;
}
.sync-copy p { color: var(--color-neutral-400); font-size: 15px; }
.sync-aside { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
/* The portal's comparison, under both columns: a screenshot wants the whole
   measure, not half of it. */
.sync-shot { grid-column: 1 / -1; }

/* Three facts about the shared map, divided by the ground showing through a
   1px gap, like the port grid above — but these are the headline, so the
   figures are set large and tabular. */
.survey-stats {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--color-divider);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.survey-stats > div { background: var(--color-bg); padding: 14px 14px 12px; }
.survey-stats dt {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-neutral-500);
}
.survey-stats dd {
  margin: 4px 0 0;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 20px;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  text-wrap: balance;
}
.sync-note { font-size: 12.5px; color: var(--color-neutral-500); }

/* ── keep it running ──────────────────────────────────────────────────── */

.donate-band { background: var(--band); padding: clamp(48px, 6vw, 80px) var(--gutter); }
.donate-grid {
  max-width: var(--measure);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}
.donate-col { display: flex; flex-direction: column; gap: 14px; }
.donate-col .kicker { color: var(--color-accent-200); }
.donate-col h2 { font-size: clamp(26px, 3vw, 36px); letter-spacing: -0.015em; }
.donate-col p { color: var(--color-accent-100); font-size: 15px; }
/* On the band the ground is already saturated, so the ghost link takes the
   pale accent step rather than the accent itself. */
.donate-col .btn-ghost { color: var(--color-accent-100); }
.donate-col .btn-ghost:hover { color: var(--color-accent-100); }
/* The line under the buttons is an aside, not a fourth paragraph of the ask,
   so it steps down a size and a shade. Its link is set like the ghost button
   beside it, for the same reason that one is. */
.donate-col .donate-note { font-size: 13px; color: var(--color-accent-200); }
.donate-col .donate-note a { color: var(--color-accent-100); }
/* This month so far: one line and a bar, between the heading and the ask. It
   is evidence for the heading, not a second heading, so it is set at the
   body's size in the band's pale steps. The bar is the ground showing through
   a lighter fill — the same two accent steps as the text around it, so it
   needs no colour of its own on the band. */
.donate-month { display: flex; flex-direction: column; gap: 8px; max-width: 460px; }
.donate-month[hidden] { display: none; }
.donate-col .donate-month-line {
  font-size: 14px;
  color: var(--color-accent-200);
  font-variant-numeric: tabular-nums;
}
.donate-col .donate-month-line a { color: inherit; text-decoration-style: dotted; }
.donate-bar {
  height: 6px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--color-accent-100) 18%, transparent);
  overflow: hidden;
}
.donate-bar-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--color-accent-200);
}

/* A column with no neighbour would otherwise run the full measure. */
.donate-col:only-child { max-width: 720px; }

/* ── footer ───────────────────────────────────────────────────────────── */

.site-footer {
  margin-top: auto;
  padding: 22px var(--gutter);
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--color-neutral-500);
  background: var(--rule) no-repeat top / 100% 1px;
}
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--color-accent); }
.site-footer .disclaimer { margin-left: auto; }

/* ── narrow screens ───────────────────────────────────────────────────── */

@media (max-width: 899px) {
  .hero,
  .row,
  .selfhost,
  .sync { grid-template-columns: minmax(0, 1fr); }

  /* The outline is a flourish on a wide hero and a collision on a narrow one:
     at this width it would sit over the copy below it. */
  .track-outline { display: none; }

  .hero { padding-top: clamp(32px, 8vw, 64px); }
  .hero-footnote { gap: 6px 22px; }
  .ports { grid-template-columns: minmax(0, 1fr); }
  .survey-stats { grid-template-columns: minmax(0, 1fr); }
  .site-footer .disclaimer { margin-left: 0; }
}

@media (max-width: 560px) {
  .site-nav { gap: 10px 14px; padding-block: 12px; }
  .brand { margin-right: auto; flex-basis: 100%; }
  .stat-band { grid-template-columns: minmax(0, 1fr); }
}

/* ── costs page ───────────────────────────────────────────────────────── */

/* The second page on the site: the same nav, the same bands, and a table
   where the front page has screenshots. The table's rules fade like the
   portal's, painted on the row so the fade runs the width of the row. */

.page-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 720px;
  padding-bottom: clamp(24px, 3vw, 40px);
}
.page-head h1 {
  font-size: clamp(34px, 4.5vw, 54px);
  line-height: 1.04;
  letter-spacing: -0.02em;
}
.page-head .lede {
  font-size: clamp(16px, 1.3vw, 18px);
  color: var(--color-neutral-400);
}

.cost-section {
  padding-top: 0;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.cost-section .section-head {
  max-width: 720px;
}
.cost-section .section-head p {
  color: var(--color-neutral-400);
  font-size: 15px;
}

.table-wrap {
  overflow-x: auto;
  min-width: 0;
}
.cost-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.cost-table th {
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: var(--font-heading-weight);
  color: var(--color-neutral-500);
  padding: 8px 10px;
  white-space: nowrap;
}
.cost-table td {
  padding: 9px 10px;
  vertical-align: top;
}
.cost-table td:nth-child(2) {
  color: var(--color-neutral-400);
}
.cost-table td:nth-child(3),
.cost-table td:nth-child(4) {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cost-table thead tr {
  background: var(--rule) no-repeat bottom / 100% 1px;
}
.cost-table tbody tr {
  background:
    linear-gradient(
        to right,
        transparent,
        color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
        color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px),
        transparent
      )
      no-repeat bottom / 100% 1px;
}

.fine {
  font-size: 12.5px;
  color: var(--color-neutral-500);
  max-width: 720px;
}

.type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
}
.type-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.type-card h3 {
  font-size: 20px;
}
.type-card p {
  font-size: 14px;
  color: var(--color-neutral-400);
}

/* ── privacy and terms ────────────────────────────────────────────────── */

/* Two pages of prose in the costs page's frame. They are read by somebody
   deciding whether to sign in, so they are set at a reading measure in the
   page's ordinary voice, not in the grey six-point of a document nobody is
   meant to finish. The tables reuse `.cost-table`; `prose` undoes the two
   columns of figures it expects, because these hold sentences. */

.legal {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 720px;
}
.legal p,
.legal li {
  color: var(--color-neutral-400);
  font-size: 15px;
}
.legal ul {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.legal li { text-wrap: pretty; }
.legal strong {
  color: var(--color-text);
  font-weight: 600;
}
.legal h3 {
  font-size: 17px;
  margin-top: 8px;
}
.legal code {
  font-size: 13px;
  color: var(--color-text);
}
.cost-table.prose td:nth-child(3),
.cost-table.prose td:nth-child(4) {
  font-variant-numeric: normal;
  white-space: normal;
}
.cost-table.prose td:first-child {
  white-space: nowrap;
}

/* ── 404: off track ───────────────────────────────────────────────────── */

/* The sync portal's "off track" page, on this site's frame. A car leaves the
   racing line at the corner exit and fades into the gravel. The illustration
   is decoration and goes at the width the hero's columns collapse at. */

/* The page is short, so the body is made a column the height of the window
   and the footer sits at the bottom of it rather than under the last line. */
.flagpage-body { min-height: 100vh; display: flex; flex-direction: column; }

.flagpage {
  flex: 1;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: center;
  gap: 40px;
  padding: clamp(32px, 6vw, 72px) var(--gutter);
  background: radial-gradient(
    ellipse 50% 60% at 70% 50%,
    color-mix(in srgb, var(--color-accent) 8%, transparent),
    transparent 70%
  );
}
.flagpage-copy { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.flagpage-flag { display: flex; align-items: center; gap: 12px; }
.flag-swatch {
  width: 28px;
  height: 20px;
  flex: none;
  border-radius: 2px;
  opacity: 0.8;
  background: repeating-linear-gradient(
    90deg,
    var(--color-neutral-800) 0 5px,
    var(--color-neutral-600) 5px 10px
  );
}
.flagpage-code {
  margin: 0;
  font-size: clamp(84px, 22vw, 120px);
  line-height: 0.9;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-200);
}
.flagpage h1 {
  margin: 0;
  font-size: 32px;
  line-height: 1.1;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.flagpage-lede {
  margin: 0;
  max-width: 420px;
  font-size: 15px;
  color: var(--color-neutral-400);
  text-wrap: pretty;
}
.flagpage-diag {
  margin: 0;
  font: 12px/1.6 var(--font-mono);
  color: var(--color-neutral-500);
  overflow-wrap: anywhere;
}

.flagpage-art { width: 100%; height: auto; overflow: visible; }
.flagpage-art path, .flagpage-art .gravel { fill: none; }
.flagpage-art .bed { stroke: var(--color-neutral-800); stroke-width: 24; stroke-linejoin: round; }
.flagpage-art .ideal {
  stroke: var(--color-accent);
  stroke-width: 1.5;
  stroke-dasharray: 6 6;
  opacity: 0.5;
}
.flagpage-art .wide {
  stroke: var(--color-accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 80 480;
  filter: drop-shadow(0 0 6px var(--color-accent));
  animation: offtrack 3.2s ease-in infinite;
}
.flagpage-art .gravel { stroke: var(--color-neutral-700); stroke-width: 1; }
.flagpage-art .tick { fill: var(--color-neutral-300); }
.flagpage-art text { font: 11px var(--font-mono); fill: var(--color-neutral-500); }

@keyframes offtrack {
  0% { stroke-dashoffset: 0; opacity: 1; }
  70% { opacity: 1; }
  100% { stroke-dashoffset: -560; opacity: 0; }
}

@media (max-width: 899px) {
  .flagpage { grid-template-columns: minmax(0, 1fr); }
  .flagpage-art { display: none; }
  .flagpage h1 { font-size: 28px; }
}
