/* ==========================================================================
   AXIS LAUNCH — style.css
   Direction: "Studio" (redirected 2026-08-24 from "Editorial" — the warm-
   cream/serif magazine system read as flat and static). Two passes to get
   here: pass 1 borrowed Figma's execution style (light ground, bold
   geometric-sans type, hover-pop cards) but ALSO piled on a 5-color
   cycling glow, animated gradient blobs, full-pill buttons, and an
   arrow-slide reveal all at once — the exact effect-stack every AI/Framer
   SaaS template defaults to. Pass 2 (same day) kept the color/type
   direction and stripped the rest back to ONE accent used deliberately and
   ONE consistent hover motion everywhere — restraint, not more effects, is
   what actually reads as considered rather than templated.
   Pure CSS. One self-hosted display font (Fraunces 700, assets/fonts/ —
   downloaded once, never fetched from Google's CDN at runtime, so "no
   external requests" still holds) for headings; body copy stays on system
   fonts. Mobile-first with a single layout breakpoint at 700px.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. DESIGN TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* Surfaces — near-white, not stark #fff (Figma's own ground is a soft
     off-white, not pure white — keeps large flat areas from glaring). */
  --bg: #fbfbfe;
  --surface: #ffffff;
  --surface-alt: #f2f1fb;     /* contrasting band section — cool tint, not tan */
  --surface-sunken: #f4f4fb;  /* note callouts, subtle wells */

  /* Ink (text) — near-black, not pure #000 (softer on a bright ground). */
  --ink: #0e0e16;
  --ink-soft: #46465a;
  --muted: #63637a;           /* 4.9:1 on --bg — meets WCAG AA for normal text */

  /* Structure */
  --border: #e3e2f0;
  --border-strong: #cac8e3;

  /* Accent — ONE hue, used deliberately. The 2026-08-24 pass tried a
     5-color cycling accent family (rainbow per-card glow, multi-hue hero
     mesh, floating blobs) and it read as generic AI-template SaaS, not as a
     considered brand — restraint is what a single ownable color signals
     that a rainbow can't. Oxblood stays the one accent; it is distinctive
     (not a default purple/blue) and now the ONLY color doing decorative
     work anywhere on the site. */
  --accent: #b8321f;
  --accent-dark: #8f2417;
  --accent-tint: #fbe4de;
  --accent-tint-strong: #f4c2b6;

  /* Dark footer surface (same ink family, inverted) */
  --footer-bg: #101018;
  --footer-text: #eceaf6;
  --footer-muted: #a3a2ba;
  --footer-border: #262536;
  --accent-on-dark: #ff8a6b; /* accent hue lightened for AA contrast on dark */

  /* Radii — bigger, rounder: "app tile" not "printed card." */
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  /* Shadow — resting elevation plus a deeper neutral shadow on hover.
     Colored per-card glow (the earlier pass) is gone; a neutral shadow that
     simply deepens is the "considered" version of the same lift. */
  --shadow-card: 0 1px 2px rgba(14, 14, 22, 0.04), 0 10px 24px -14px rgba(14, 14, 22, 0.18);
  --shadow-card-hover: 0 2px 6px rgba(14, 14, 22, 0.07), 0 20px 36px -16px rgba(14, 14, 22, 0.28);

  /* Type — Fraunces (self-hosted, see @font-face below) for display, a
     characterful serif rather than the generic geometric sans every
     AI-template site defaults to; body stays on the neutral system stack. */
  --font-display: "Fraunces", ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, "Noto Serif", serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";

  /* Motion — one shared easing for every hover-pop, so lift/scale/glow feel
     like one system rather than per-component tuning. */
  --pop-ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Layout */
  --max-width: 1120px;
  --gutter: 1.25rem;
}

/* Self-hosted once (2026-08-24) from Google Fonts' own CDN into assets/fonts/ —
   never fetched from fonts.googleapis.com at runtime. One weight only
   (bold/700): a whole variable-weight system wasn't needed for headings,
   same "don't over-build it" call as everywhere else in this pass. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/fraunces-700.woff2") format("woff2");
}

/* --------------------------------------------------------------------------
   2. RESET + BASE
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overflow-x: hidden;   /* RE-INVESTIGATED 2026-08-21 (polish pass) — this comment's
                            earlier "silently clamps below ~500px" claim is FALSIFIED:
                            screenshotted at --window-size=390,900 and confirmed the
                            output PNG is exactly 390x844, so the viewport was honored
                            precisely, not clamped. With overflow-x:hidden removed, a
                            real horizontal scrollbar does appear at 390px width, and
                            body text visibly clips at a fixed right-edge position
                            (not proportional to font-size, present identically on
                            every text element checked). Bisected three concrete
                            suspects with zero effect on the clip in any direction:
                            .hero h1's max-width:20ch, the .nav-cta button (hidden
                            entirely), and .band's width:100vw full-bleed technique.
                            The uniform, fixed-magnitude nature of the clip (unchanged
                            by removing any single candidate element) is consistent
                            with a headless-Chrome viewport-unit discrepancy rather
                            than a per-element CSS bug, but this is NOT confirmed —
                            no second rendering engine was available in this
                            environment to cross-check (Edge headless failed to
                            launch here), and no real device was available either.
                            Left ON as the same harmless-insurance backstop as
                            before; if this is ever chased again, start from a real
                            device or a non-Chromium headless renderer (e.g.
                            Playwright+Firefox) rather than re-deriving the above. */
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd {
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg, video {
  max-width: 100%;
  display: block;
}

a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}

a:hover {
  color: var(--accent-dark);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

::selection {
  background: var(--accent-tint-strong);
  color: var(--accent-dark);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.02em;
}

h1 {
  font-size: clamp(2.25rem, 6vw, 3.75rem);
  line-height: 1.05;
  margin-bottom: 1.1rem;
}

h2 {
  font-size: clamp(1.6rem, 3.4vw, 2.25rem);
  margin: 3rem 0 1.1rem;
}

h3 {
  font-size: 1.2rem;
  margin-bottom: 0.4rem;
}

h4 {
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}

p {
  margin-bottom: 1.1rem;
  max-width: 68ch;
}

small { color: var(--muted); }

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2.5rem 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. LAYOUT — .wrap
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main {
  display: block;
  padding-bottom: 4rem;
}

/* --------------------------------------------------------------------------
   4. HEADER + NAV
   -------------------------------------------------------------------------- */

header {
  background: rgba(251, 251, 254, 0.85);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
}

header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-block: 1rem;
}

.brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.02em;
  order: 1;
  margin-right: auto;
  transition: color 0.15s ease;
}

.brand:hover {
  color: var(--accent);
}

.primary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 1.35rem;
  order: 3;
  flex-basis: 100%;
}

.primary a {
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  padding-block: 0.3rem;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.primary a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.nav-cta {
  order: 2;
}

/* --------------------------------------------------------------------------
   5. BREADCRUMBS
   -------------------------------------------------------------------------- */

.crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  font-size: 0.8125rem;
  color: var(--muted);
  margin: 1.5rem 0 1rem;
}

.crumbs a {
  color: var(--muted);
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   6. BUTTONS
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.9375rem;
  line-height: 1;
  padding: 0.8rem 1.5rem;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease,
    transform 0.22s var(--pop-ease), box-shadow 0.22s var(--pop-ease);
}

.btn:active {
  transform: translateY(1px) scale(0.98);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  box-shadow: 0 1px 2px rgba(14, 14, 22, 0.05);
}

.btn-primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 14px 28px -12px rgba(184, 50, 31, 0.55);
}

.btn-secondary {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--ink);
}

.btn-secondary:hover {
  border-color: var(--ink);
  background: var(--surface-sunken);
  color: var(--ink);
  transform: translateY(-2px);
  box-shadow: 0 14px 28px -16px rgba(14, 14, 22, 0.25);
}

.btn-sm {
  padding: 0.45rem 0.9rem;
  font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   7. TYPOGRAPHY HELPERS
   -------------------------------------------------------------------------- */

.lede {
  font-size: 1.2rem;
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 58ch;
}

.flush {
  margin-top: 0;
}

.legal {
  font-size: 0.8125rem;
  color: var(--muted);
  line-height: 1.6;
  max-width: 72ch;
}

.legal a {
  color: var(--muted);
  text-decoration: underline;
}

.legal a:hover {
  color: var(--accent);
}

.meta {
  font-size: 0.8125rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}

.tagline {
  font-size: 0.95rem;
  color: var(--ink-soft);
  margin-bottom: 0.9rem;
}

/* --------------------------------------------------------------------------
   8. CARDS + GRID
   -------------------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  margin-block: 1.75rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.32s var(--pop-ease), transform 0.32s var(--pop-ease), border-color 0.32s var(--pop-ease);
  position: relative;
  overflow: hidden;
}

/* Accent bar that draws in on hover, two-tone in the single brand accent
   (not a rainbow across five hues — the 2026-08-24 revision: a multi-color
   sweep read as generic template flash, not a signal from THIS brand). */
.card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent), var(--accent-dark));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.32s var(--pop-ease);
}

/* The pop, restrained: a modest lift and a deeper neutral shadow — no
   scale, no rotation, no per-card color cycling. One consistent motion
   applied everywhere reads as a considered system; a different flourish on
   every element is what reads as a template testing "what looks cool." */
.card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-4px);
  border-color: var(--border-strong);
}

.card:hover::before {
  transform: scaleX(1);
}

.card:hover .mark-img {
  border-color: var(--accent);
}

/* Generated app mark — a monogram tile, not a screenshot. The seed listings
   were bootstrapped without maker-submitted thumbnails (Root Design v2 §5.1
   calls for a 240x240 image on every listing; the real submission form will
   collect one). This isn't a placeholder for that — it's an honest abstract
   mark, same family as a wax seal, deliberately not pretending to be product
   art. Three on-brand tones only, no new palette. */
.mark {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  display: block;
}

.mark-lg {
  width: 4.5rem;
  height: 4.5rem;
  border-radius: var(--radius-md);
  margin-bottom: 1rem;
}

/* Real favicon variant of the mark (fetched by scripts/fetch_app_icons.py; the SVG
   monogram remains the fallback for listings whose site serves no usable icon).
   White well + hairline border so transparent and dark favicons both sit cleanly
   on the ground. Border transitions so the hover border-color pickup above
   reads as part of the same card motion, not a separate effect. */
.mark-img {
  object-fit: contain;
  background: var(--surface);
  border: 1.5px solid var(--border);
  padding: 0.3rem;
  transition: border-color 0.32s var(--pop-ease);
}

.card h3 {
  margin-bottom: 0.35rem;
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.card h3 a {
  color: var(--ink);
  text-decoration: none;
}

.card h3 a:hover {
  color: var(--accent);
}

.card .meta:last-child {
  margin-bottom: 0;
}

.cat {
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.cat:hover {
  color: var(--accent);
  text-decoration: underline;
}

.badge-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--accent-tint);
  border: 1px solid var(--accent-tint-strong);
  color: var(--accent-dark);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.28rem 0.65rem;
  border-radius: var(--radius-pill);
  margin: 0 0.35rem 0.35rem 0;
}

.badge-chip .cat {
  color: inherit;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 600;
}

.badge-chip .cat:hover {
  color: var(--accent-dark);
  text-decoration: underline;
}

/* D-01 — dated verification badges (Identity Verified · Aug 9, 2026, etc.). Solid ink
   fill distinguishes an admin-confirmed badge from the lighter accent-tint pricing/
   category chips above — a stamped look, not a decorative one. */
.badge-verified {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

.note {
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 1rem 1.25rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
  margin-block: 1.25rem;
}

.note strong {
  color: var(--ink);
}

.note a {
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   9. SECTIONS — band / hero / cta-row
   -------------------------------------------------------------------------- */

.hero {
  padding-block: 4.5rem 3rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2.5rem;
  /* Redirected 2026-08-24, twice: the ORIGINAL two cream/tan washes read as
     empty space with text in it (too little). A three-hue animated-blob
     mesh (the pass right after) read as a generic AI-template SaaS hero
     (too much, and too generic a "modern SaaS hero" move to boot). This is
     the restrained middle: one soft wash, the single brand accent, no
     motion — a considered choice a template wouldn't make, rather than a
     pile of trendy effects standing in for one. */
  background: radial-gradient(46rem 28rem at 10% -12%, var(--accent-tint) 0%, transparent 60%), var(--bg);
}

/* Hero media — real photography, not decoration standing in for content
   (added 2026-08-24: assets/marketing/, generated once via xAI Grok per
   scripts/generate_marketing_media.py, never fetched at build time). A grid
   splits copy and image on wide screens; the video (muted/looped/inline,
   poster = the still so there's never a blank frame) sits right of the
   headline, not behind it — text stays on the plain hero background above,
   never fighting a busy image for contrast. */
.hero-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  align-items: center;
}

.hero-media {
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card-hover);
  /* Source media is portrait (480x640, 3:4) — matching the box to the real
     asset instead of a generic landscape ratio avoids object-fit:cover
     cropping the composition. */
  aspect-ratio: 3 / 4;
  max-width: 22rem;
  margin-inline: auto;
}

.hero-media video,
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (min-width: 860px) {
  .hero-layout {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.hero h1 {
  max-width: 20ch;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

/* Full-bleed band: breaks out of the ambient .wrap regardless of nesting
   depth, then re-centers its own inner .wrap to the same rhythm. */
.band {
  /* A faint diagonal hairline (ink, not the brand accent — bands are a
     structural pause, not a place to spend the one accent color) gives it
     material without adding weight or any new request. */
  background:
    repeating-linear-gradient(135deg, rgba(14, 14, 22, 0.035) 0, rgba(14, 14, 22, 0.035) 1px, transparent 1px, transparent 14px),
    var(--surface-alt);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding-block: 2.75rem;
  margin-block: 2.25rem;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.band .wrap {
  padding-block: 0;
}

.band p:last-child {
  margin-bottom: 0;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 1.5rem;
}

/* --------------------------------------------------------------------------
   10. NUMBERED STEPS
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.75rem;
  margin-block: 2rem 1rem;
}

.step {
  padding-top: 0.5rem;
  border-top: 2px solid var(--border);
}

.step h3 {
  margin-bottom: 0.35rem;
  position: relative;
  z-index: 1;
}

.step p {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin-bottom: 0;
}

/* Was a small utility label (1.6rem) — indistinguishable from a generic
   4-column template. An oversized, translucent drop-numeral is a standard
   magazine-editorial device and this file's header comment already claims
   that direction; this makes the CSS match it. */
.n {
  display: block;
  font-family: var(--font-display);
  font-size: 3.25rem;
  line-height: 1;
  font-weight: 700;
  color: var(--accent);
  opacity: 0.24;
  margin-bottom: -0.55rem;
}

/* --------------------------------------------------------------------------
   10b. FORMS — A-08 (2026-08-20): the real /launch submission form
   --------------------------------------------------------------------------
   First real form on the site. Same tokens, no new palette; focus ring comes
   from the base :focus-visible rule. .hp is the honeypot wrapper — moved off-
   canvas rather than display:none so naive bots still "see" the field. */

.form-grid {
  display: grid;
  gap: 1.1rem;
  max-width: 44rem;
  margin: 1.25rem 0 2rem;
}

.field {
  display: grid;
  gap: 0.35rem;
  font-weight: 600;
  font-size: 0.95rem;
}

/* Found live 2026-08-21: `.field`'s own `display: grid` has the same specificity as the
   UA stylesheet's `[hidden] { display: none }`, and author rules always win a same-
   specificity tie against the UA sheet — so the App/Microapp toggle script's `el.hidden =
   true` silently did nothing and both Category and Pricing showed at once. Needs an
   explicit override, not just the bare attribute. */
.field[hidden] {
  display: none;
}

.field .hint {
  font-weight: 400;
  font-size: 0.85rem;
  color: var(--muted);
}

.field input,
.field textarea,
.field select {
  font: inherit;
  font-weight: 400;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.75rem;
  width: 100%;
}

.field textarea {
  resize: vertical;
  min-height: 5.5rem;
}

.form-status {
  display: inline-block;
  margin-left: 0.75rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.form-status.err {
  color: var(--accent-dark);
}

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* dev pass 2026-08-21 — the App/Microapp toggle at the top of the submit form. Plain
   fieldset, not styled as a segmented control: this is a fork in what the rest of the
   form asks for, not a settings toggle, so it should read as a question, not a switch. */
.kind-toggle {
  display: grid;
  gap: 0.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin: 0;
}

.kind-toggle legend {
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0 0.3rem;
}

.kind-toggle label {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 400;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.kind-toggle input {
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   11. STATUS
   -------------------------------------------------------------------------- */

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0.3rem 0.75rem 0.3rem 0.6rem;
}

.status::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   11b. FORUM — /community index rows + thread pages
   --------------------------------------------------------------------------
   Design pass 2026-08-20. Forums read as ROWS, not card grids — a grid of
   near-identical cards hides the scan pattern (title -> activity) that makes
   a forum index legible. Thread pages get real post anatomy: author avatar,
   an accent rail on the opening post, and replies visually threaded off it. */

/* C-06: category heading + "Start a thread" action on one line. */
.cat-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.cat-head h2 {
  margin-bottom: 0.5rem;
}

.thread-list {
  margin: 0.75rem 0 2.25rem;
  border-top: 1px solid var(--border);
}

.thread-row {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  padding: 0.8rem 0.25rem;
  border-bottom: 1px solid var(--border);
}

.thread-row h3 {
  font-size: 1.02rem;
  margin: 0;
  flex: 1;
  min-width: 0;
}

.thread-row h3 a {
  color: var(--ink);
  text-decoration: none;
}

.thread-row h3 a:hover {
  color: var(--accent);
}

.thread-row .meta {
  white-space: nowrap;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 500;
}

.reply-count {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0.15rem 0.6rem;
  white-space: nowrap;
}

.avatar {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.85rem;
  color: #f7f2e6;
}

.post {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1rem;
  box-shadow: var(--shadow-card);
}

.post-head {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-bottom: 0.75rem;
}

.post-head .meta {
  margin: 0;
}

.post-op {
  border-left: 3px solid var(--accent);
}

/* Replies indent under the opening post with a connector rail — the thread
   literally hangs off the OP instead of stacking as unrelated boxes. */
.replies {
  position: relative;
  margin-left: 1.1rem;
  padding-left: 1.4rem;
  border-left: 2px solid var(--border-strong);
}

.replies .post:last-child {
  margin-bottom: 0;
}

.post p:last-child {
  margin-bottom: 0;
}

@media (min-width: 700px) {
  .replies {
    margin-left: 1.6rem;
    padding-left: 1.9rem;
  }
}

/* --------------------------------------------------------------------------
   12. FOOTER
   -------------------------------------------------------------------------- */

footer {
  background: var(--footer-bg);
  color: var(--footer-text);
  margin-top: 3rem;
}

footer .wrap {
  padding-block: 2.75rem 2.25rem;
}

footer p {
  color: var(--footer-text);
  margin-bottom: 0.85rem;
}

footer p strong {
  font-family: var(--font-display);
  font-size: 1.05rem;
}

footer .legal {
  color: var(--footer-muted);
}

footer .legal a {
  color: var(--footer-muted);
}

footer .legal a:hover {
  color: var(--accent-on-dark);
}

footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  border-top: 1px solid var(--footer-border);
  border-bottom: 1px solid var(--footer-border);
  padding-block: 1.1rem;
  margin-block: 1.1rem;
}

footer nav a {
  color: var(--footer-text);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}

footer nav a:hover {
  color: var(--accent-on-dark);
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   13. body.person — quiet identity chrome (/about and other personal pages)
   --------------------------------------------------------------------------
   Same design family (tokens, type scale, spacing rhythm) — no product nav,
   no acquisition CTA, no escrow/auction legal line. Just a name, and a
   short, text-only cross-link list.

   Footer note: the shared footer partial renders three top-level <p>
   elements (brand line, escrow legal, credit line) around a middle <nav>.
   :nth-of-type targets by tag position, independent of shared classes, so
   this reliably hides only the escrow paragraph (the 2nd <p> among <p>
   siblings) and leaves the credit line intact.
   -------------------------------------------------------------------------- */

body.person header .wrap {
  justify-content: center;
  padding-block: 1.5rem;
}

.headshot {
  display: block;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: 1.5rem;
  border: 1px solid var(--border-strong);
}

body.person .headshot {
  margin-inline: auto;
}

body.person .primary,
body.person .nav-cta {
  display: none;
}

body.person .brand {
  margin-right: 0;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}

body.person .brand:hover {
  color: var(--accent);
}

body.person .hero {
  border-bottom: 0;
  padding-block: 2.5rem 1.5rem;
  text-align: center;
}

body.person .hero h1 {
  max-width: none;
}

body.person .hero .lede {
  margin-inline: auto;
}

body.person .cta-row {
  justify-content: center;
}

body.person main {
  padding-bottom: 3rem;
}

body.person footer {
  background: var(--bg);
  color: var(--ink);
  border-top: 1px solid var(--border);
}

body.person footer .wrap {
  padding-block: 2rem;
  text-align: center;
}

body.person footer p {
  color: var(--ink-soft);
}

body.person footer p strong {
  color: var(--ink);
}

/* Hide the escrow/auction legal line specifically (2nd <p> among footer's
   <p> siblings); the credit line (3rd <p>, also .legal) remains. */
body.person footer p:nth-of-type(2) {
  display: none;
}

body.person footer nav {
  justify-content: center;
  border-color: var(--border);
  background: transparent;
}

body.person footer nav a {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

body.person footer nav a:hover {
  color: var(--accent);
}

body.person footer .legal a:hover {
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   14. RESPONSIVE — single breakpoint at 700px
   -------------------------------------------------------------------------- */

@media (min-width: 700px) {
  :root {
    --gutter: 2rem;
  }

  header .wrap {
    flex-wrap: nowrap;
  }

  .primary {
    order: 2;
    flex-basis: auto;
    flex-wrap: nowrap;
    gap: 1.75rem;
  }

  .nav-cta {
    order: 3;
  }

  .hero {
    padding-block: 4.5rem 3.5rem;
  }

  .grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 1.5rem;
  }

  .steps {
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem;
  }

  footer .wrap {
    padding-block: 3.5rem 2.5rem;
  }

  body.person .brand {
    font-size: 1.25rem;
  }
}

/* Artifact list on a /microapps/<slug> page — the files a program actually emits.
   Monospace + tight rows because it is a file manifest, not prose; two columns on
   wide screens since some programs emit nineteen of them. */
.outputs {
  list-style: none;
  padding: 0;
  margin: 1rem 0 1.5rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.3rem 1.5rem;
}

.outputs li {
  font-size: 0.875rem;
  color: var(--ink-soft);
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--border);
}

.outputs code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85rem;
  color: var(--ink);
}

@media (min-width: 700px) {
  .outputs { grid-template-columns: 1fr 1fr; }
}

/* Directory-prefix mute on /microapps output-manifest paths — see outputs_html()'s
   comment. Same --muted token already used for meta/legal text elsewhere. */
.outputs li code .path-dir {
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   A-06 (2026-09-12): the daily newsletter — subscribe block, house-ad strip,
   quoted citations, and a real 404.
   -------------------------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.form-status.ok {
  color: var(--ink);
}

.form-status:empty {
  display: none;
}

/* The subscribe block sits at the foot of <main> on every page (axis_build.py shell());
   the newsletter index and the homepage place it themselves. */
.subscribe {
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--border);
}

.subscribe .flush {
  margin-top: 0;
}

.subscribe > p {
  max-width: 62ch;
}

.subscribe-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: stretch;
  max-width: 34rem;
  margin-bottom: 0.5rem;
}

.subscribe-form input[type="email"] {
  flex: 1 1 16rem;
  min-height: 44px;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.9rem;
}

.subscribe-form .btn {
  min-height: 44px;
}

.subscribe .form-status {
  display: block;
  margin-left: 0;
  margin-top: 0.25rem;
}

.subscribe .legal {
  margin-top: 0.75rem;
}

/* House-ad strip on newsletter issue pages. A static, wrapped row rather than the draft
   marquee: every property is readable from its first letter, nothing is clipped mid-word,
   and there is no motion to opt out of. */
.strip {
  border-block: 1px solid var(--border);
  margin-block: 2.5rem;
  padding-block: 0.9rem;
}

.strip-label {
  display: block;
  margin-bottom: 0.55rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.strip-track {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.75rem;
}

.strip-item {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.92rem;
}

.strip-item a {
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.strip-item a:hover,
.strip-item a:focus-visible {
  color: var(--accent);
  border-bottom-color: currentColor;
}

.strip-item span {
  color: var(--ink-soft);
}

/* A maker quoted in their own words, on an issue page. */
.card blockquote {
  margin: 0.5rem 0 0.75rem;
  padding-left: 0.9rem;
  border-left: 3px solid var(--border-strong);
  color: var(--ink-soft);
}

.card blockquote p {
  margin-bottom: 0.5rem;
}

.subscribe-status {
  margin-top: 0.25rem;
  max-width: 34rem;
}

/* Thread rows (community index, newsletter index) below tablet width: the title takes
   the full row and the meta wraps under it. Found 2026-09-12 on the newsletter index at
   phone width, where a flex row with a nowrap meta squeezed the title to one word per line
   and drew the date over it; the community index had the same failure for long titles. */
@media (max-width: 640px) {
  .thread-row {
    flex-wrap: wrap;
    row-gap: 0.25rem;
  }
  .thread-row h3 {
    flex: 1 1 100%;
  }
  .thread-row .meta {
    white-space: normal;
  }
}

/* --------------------------------------------------------------------------
   Magazine feature issues (2026-09-12): one piece about one app, sourced.
   -------------------------------------------------------------------------- */

.feature-kicker {
  font-size: 0.8125rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  margin-bottom: 0.75rem;
}

.feature-headline {
  font-size: clamp(2.4rem, 6vw, 3.6rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  max-width: 24ch;
  margin-bottom: 1rem;
}

.feature-dek {
  font-size: 1.3rem;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 44ch;
  margin-bottom: 1.5rem;
}

.feature-byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-block: 0.9rem;
  border-block: 1px solid var(--border);
  margin-bottom: 2rem;
  font-size: 0.9rem;
  color: var(--muted);
}

.feature-app {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.feature-app .mark {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0.15rem;
}

.feature-app a {
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
}

.feature-app a:hover {
  color: var(--accent);
}

.feature-body {
  max-width: 66ch;
}

.feature-body h2 {
  font-size: 1.5rem;
  margin: 2.4rem 0 0.7rem;
}

.feature-body p {
  font-size: 1.0625rem;
  line-height: 1.72;
  margin-bottom: 1.1rem;
  max-width: none;
}

.feature-body > p:first-of-type::first-letter {
  font-family: var(--font-display);
  font-size: 3.1em;
  line-height: 0.82;
  float: left;
  padding: 0.12em 0.45rem 0 0;
  color: var(--ink);
}

sup.cite {
  font-size: 0.7em;
  line-height: 0;
  margin-left: 0.1em;
}

sup.cite a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 700;
}

.pullquote {
  margin: 2rem 0;
  padding: 1.25rem 1.5rem;
  border-left: 4px solid var(--accent);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
}

.pullquote p {
  font-family: var(--font-display);
  font-size: 1.45rem;
  line-height: 1.35;
  margin: 0 0 0.6rem;
  max-width: none;
}

.pullquote cite {
  font-style: normal;
  font-size: 0.85rem;
  color: var(--muted);
}

.feature-sources {
  font-size: 0.9rem;
  color: var(--ink-soft);
  padding-left: 1.25rem;
  max-width: 70ch;
}

.feature-sources li {
  margin-bottom: 0.5rem;
}

.feature-sources a {
  color: var(--ink);
}

/* The newest feature as the front of /newsletter, above the list of every issue. */
.cover {
  margin-top: 2.25rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

.cover h2 {
  font-size: clamp(1.8rem, 4.5vw, 2.6rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  max-width: 26ch;
  margin-bottom: 0.75rem;
}

.cover h2 a {
  color: var(--ink);
  text-decoration: none;
}

.cover h2 a:hover {
  color: var(--accent);
}

.cover .feature-dek {
  margin-bottom: 1rem;
}

/* --------------------------------------------------------------------------
   Distribution system (2026-09-12)
   -------------------------------------------------------------------------- */

/* Share links under a feature piece: plain links, no scripts, no third-party buttons. */
.share-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  margin: 1.75rem 0 0;
  font-size: 0.95rem;
}

.share-row a {
  font-weight: 600;
}

/* The share link a new subscriber sees right after confirming. */
.subscribe-share {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  word-break: break-all;
}

/* The Featured on AXIS Launch badge and its embed code. */
.badge-embed {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

.badge-variant {
  margin-top: 1.25rem;
}

.badge-preview {
  display: inline-block;
  padding: 1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin: 0.35rem 0 0.6rem;
}

.badge-preview img {
  display: block;
  max-width: 100%;
  height: auto;
}

.badge-variant-light .badge-preview {
  background: #ffffff;
}

.badge-variant-dark .badge-preview {
  background: #101018;
  border-color: #262536;
}

.embed-code {
  max-width: 100%;
  overflow-x: auto;
  padding: 0.85rem 1rem;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
}

/* --------------------------------------------------------------------------
   Media pass (2026-09-12): app screenshots and generated illustrations.
   Every image carries a caption saying what it is: whose site and which day for
   a screenshot, "generated" for an illustration (scripts/site-builders/axis_media.py).
   -------------------------------------------------------------------------- */

.media-figure {
  margin: 1.75rem 0 2.25rem;
  max-width: 760px;
}

.media-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  box-shadow: var(--shadow-card);
}

.media-figure figcaption {
  margin-top: 0.6rem;
  max-width: 62ch;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Illustrations run the full width of their column and sit flat: no frame, no shadow. */
.art-figure {
  max-width: 100%;
}

.art-figure img {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 0;
  box-shadow: none;
}

/* A listing's screenshot at the top of its card, cropped the same way on every card so a
   grid of them lines up. It bleeds to the card's edges, which pad 1.5rem. */
.card-shot,
.card-shot-empty {
  display: block;
  width: calc(100% + 3rem);
  max-width: none;
  aspect-ratio: 1270 / 760;
  margin: -1.5rem -1.5rem 1.1rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
}

.card-shot {
  height: auto;
  object-fit: cover;
  object-position: top center;
}

/* No screenshot (a site that refuses a headless browser and publishes no preview image):
   the app's mark on the same tint, so the grid keeps its rhythm. */
.card-shot-empty {
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-shot-empty .mark-lg {
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Data collection (2026-09-12): the signup box, Privacy choices, the download
   page and its document (scripts/site-builders/axis_engagement.py and
   axis_build_data_pages.py).
   -------------------------------------------------------------------------- */

/* The signup box: a small panel in the corner, never a full-screen interstitial. On a phone
   it runs along the bottom edge and never takes more than 45% of the screen. */
.prompt {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
  width: min(23rem, calc(100vw - 2.5rem));
  max-height: 70vh;
  overflow-y: auto;
  padding: 1.25rem 1.25rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-hover);
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity 0.3s var(--pop-ease), transform 0.3s var(--pop-ease);
}

.prompt.prompt-open {
  opacity: 1;
  transform: none;
}

.prompt [hidden],
.privacy-choices [hidden] {
  display: none !important;
}

.prompt-close {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.prompt-close:hover,
.prompt-close:focus-visible {
  background: var(--surface-sunken);
  color: var(--ink);
}

.prompt-kicker {
  margin: 0 2.5rem 0.35rem 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
}

.prompt-title {
  margin: 0 2rem 0.45rem 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  line-height: 1.2;
  color: var(--ink);
}

.prompt-text {
  margin-bottom: 0.8rem;
  font-size: 0.93rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.prompt-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.prompt-form input[type="email"] {
  flex: 1 1 11rem;
  min-width: 0;
  min-height: 44px;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.75rem;
}

.prompt-form .btn {
  min-height: 44px;
}

.prompt-status {
  margin: 0.55rem 0 0;
  font-size: 0.9rem;
  color: var(--ink);
}

.prompt-status:empty {
  display: none;
}

.prompt-legal {
  margin: 0.65rem 0 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--muted);
}

.prompt-legal a {
  color: inherit;
}

@media (max-width: 640px) {
  .prompt {
    right: 0.75rem;
    left: 0.75rem;
    bottom: 0.75rem;
    width: auto;
    max-height: 45vh;
    padding: 1rem 1rem 0.9rem;
  }
  .prompt-title {
    font-size: 1.15rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .prompt {
    transition: none;
    transform: none;
  }
}

/* Privacy choices: opened from the footer of every page. */
.privacy-choices {
  position: fixed;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 60;
  width: min(26rem, calc(100vw - 2.5rem));
  max-height: 80vh;
  overflow-y: auto;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-hover);
}

.privacy-choices p {
  font-size: 0.93rem;
}

.privacy-choices .btn {
  margin: 0.2rem 0.4rem 0.2rem 0;
}

/* The download page: the offer beside its form, stacked on a phone. */
.magnet-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  margin-top: 1.75rem;
}

.magnet-form {
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

@media (min-width: 900px) {
  .magnet-layout {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    align-items: start;
  }
  .magnet-form {
    position: sticky;
    top: 1.5rem;
  }
}

/* On a phone the form comes first, so nobody scrolls past the whole pitch to find it. */
@media (max-width: 899px) {
  .magnet-form {
    order: -1;
  }
}

.magnet-contents {
  padding-left: 1.25rem;
}

.magnet-contents li {
  margin-bottom: 0.75rem;
}

.optin {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.optin input {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.2rem;
  accent-color: var(--accent);
}

/* The checklist document: one row per item, with a box to tick on paper. */
.checklist-section {
  margin-top: 2.75rem;
}

.checklist {
  list-style: none;
  max-width: 72ch;
  margin: 1rem 0 0;
  padding: 0;
}

.checklist-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0 0.9rem;
  padding-block: 1.1rem;
  border-top: 1px solid var(--border);
}

.checklist-item p {
  margin-bottom: 0.4rem;
}

.checklist-box {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.2rem;
  border: 2px solid var(--border-strong);
  border-radius: 4px;
}

.checklist-action {
  font-weight: 700;
  color: var(--ink);
}

@media print {
  header,
  footer,
  .crumbs,
  .subscribe,
  .prompt,
  .privacy-choices,
  .no-print {
    display: none !important;
  }
  .checklist-item {
    break-inside: avoid;
  }
  .checklist-box {
    border-color: #000;
  }
}
