/* A Generous Company — helloagc.com
   Primary palette is black and white, per the brand review deck.
   The gradient is secondary and appears in exactly three places:
   the asterisk mark in the nav, the hero rule, and the large asterisk
   beside the verse on the home page. Keep it to those three. */

@font-face {
  font-family: "Space Mono";
  src: url("../fonts/space-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Mono";
  src: url("../fonts/space-mono-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #000000;
  --fg: #ffffff;
  --fg-dim: #a3a3a3;
  --rule: #2a2a2a;
  --band: #a8aee6;
  --g1: #9d70f4;
  --g2: #fa4b83;
  --g3: #f3bd81;
  --g4: #eac88a;
  --grad: linear-gradient(135deg, var(--g1) 0%, var(--g2) 38%, var(--g3) 72%, var(--g4) 100%);

  --mono: "Space Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* The reading column, as a length rather than in ch. Two reasons.
     One: `ch` is the advance of "0", and in Inter that glyph is 10.72px at
     17px where the average glyph in this copy measures 8.10px. The old
     62ch therefore rendered 80–83 real characters per full line, measured
     across /, /about, /privacy and /terms — above, not below, the 65–75
     the craft floor asks for. 37rem lands the median at 72.
     Two: `ch` resolves against the element using it, so the same token gave
     .prose (17px), .closing (20px) and .lede (21px) three different column
     widths and three different right edges. One length, one edge. */
  --measure: 37rem;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  /* --step closes a section; --step-in opens the next one. The pair is
     deliberately asymmetric: a section rule belongs to the heading beneath
     it, so it sits nearer that heading than the copy it just left. */
  --step: clamp(3.5rem, 9vw, 7rem);
  --step-in: clamp(2.25rem, 5.5vw, 4.25rem);
  /* One tracking value for the uppercase mono micro-labels: the nav, the
     verse citation, the details terms, and both message-log labels. They
     had drifted to 0.04em, 0.06em, 0.08em and 0.1em. */
  --track-label: 0.08em;

  color-scheme: dark;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--fg); text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { color: var(--band); }
/* Press. Hover shifts the colour; active keeps that colour and draws a
   thicker, tighter underline, so the two read as separate moments without
   introducing a fourth colour. Written as text-decoration-line so it also
   reaches the two link families that carry no underline at rest, the nav
   items and the mark. */
a:active {
  color: var(--band);
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.15em;
}

:focus-visible { outline: 2px solid var(--band); outline-offset: 3px; }

/* Paragraph rhythm. The user-agent's 1em margins were the only vertical
   spacing on this site not set here, and they were doing three things by
   accident: leaving 17px of dead space under the last paragraph of every
   section, pushing the first paragraph of a heading-less section down by the
   same amount, and setting .prose's paragraph gap (17px) a notch tighter
   than .section's (20px). Reset at zero specificity so the sibling rules
   below own the rhythm outright. */
:where(.section, .prose) :where(p, ul, ol) { margin-block: 0; }
/* Body copy gets pretty rag: it keeps a single word off the last line of a
   paragraph. Headings ask for balance instead, and set it themselves. */
p { text-wrap: pretty; }

/* ---------- browser chrome (Typeset T5) ----------
   Selection, scrollbar, caret, and list markers were all left at browser
   defaults. Themed from the existing palette: --band as background reads at
   9.86:1 against black text, well past the 4.5:1 floor, so selection uses
   --band as the fill rather than an inverted (dark-on-light-text) treatment. */
::selection { background: var(--band); color: var(--bg); }

html {
  caret-color: var(--band);
  scrollbar-color: var(--rule) var(--bg);
  scrollbar-width: thin;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--rule); border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--fg-dim); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
/* The "Skip to content" link is the only .sr-only element on the site, and
   the only thing a keyboard user tabs to before the nav. Undo the clip on
   focus so it becomes a visible, on-brand target instead of a focus that
   goes nowhere. */
.sr-only:focus,
.sr-only:focus-visible {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 10;
  width: auto;
  height: auto;
  padding: 0.5em 1em;
  margin: 0;
  overflow: visible;
  clip-path: none;
  white-space: normal;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 0.875rem;
}

.wrap {
  width: min(72rem, 100%);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- nav ---------- */

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.75rem;
  flex-wrap: wrap;
}
.nav__links {
  display: flex;
  gap: clamp(1rem, 3vw, 2rem);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
/* 44px on both axes is the WCAG 2.5.5 (AAA) target. min-width rather than
   padding, so short labels grow their hit area without changing the gap. */
.nav__links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  text-decoration: none;
}
.nav__links a:hover { text-decoration: underline; }
.nav__links a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}
/* .nav__links a sets text-decoration: none, which outranks the site-wide
   a:active and left the press state with no underline at all — a step
   backwards from hover. Restated at this specificity so press reads as
   press here too. */
.nav__links a:active {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.15em;
}

/* ---------- the mark ---------- */

.mark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 0.1em;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 1.375rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  line-height: 1;
}
.mark svg { width: 0.62em; height: 0.62em; align-self: flex-start; }
.mark svg stop:nth-of-type(1) { stop-color: var(--g1); }
.mark svg stop:nth-of-type(2) { stop-color: var(--g2); }
.mark svg stop:nth-of-type(3) { stop-color: var(--g3); }
.mark svg stop:nth-of-type(4) { stop-color: var(--g4); }

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

.hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 6vw, 4rem);
  align-items: center;
  padding-block: clamp(3rem, 8vw, 6rem) var(--step);
}
@media (min-width: 56rem) {
  .hero { grid-template-columns: 1.15fr 0.85fr; }
}
/* Only the home page's hero has anything in the second column. Everywhere
   else the hero holds one block, and the two-column track above left a
   four-line H1 crammed into 57% of the viewport with 43% of nothing beside
   it. A lone child takes the whole grid and caps itself, so the heading gets
   room without running to a 1056px display measure. :only-child rather than
   :has(), so this needs nothing newer than the rest of the stylesheet. */
.hero > :only-child {
  grid-column: 1 / -1;
  max-width: 52rem;
}
.hero__title {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(2.25rem, 6.5vw, 4rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  /* Optical, not mathematical: Space Mono centres each glyph in a fixed
     advance, so the H1's ink sat 2.8–4.6px right of the gradient rule under
     it, the mark above it and the lede below it — the loudest element on the
     page was the one off the spine. -0.05em is the median left side bearing
     of the six first letters actually used (C G P P T P). The rule below is
     geometry, not type, so it takes the shift back and stays true. */
  margin: 0 0 1.5rem -0.05em;
  text-wrap: balance;
}
.hero__title::after {
  content: "";
  display: block;
  width: 5.5rem;
  height: 3px;
  margin-top: 1.5rem;
  margin-left: 0.05em;
  background: var(--grad);
}
.hero__media img { width: 100%; }

.lede {
  font-size: clamp(1.0625rem, 1rem + 0.45vw, 1.3125rem);
  line-height: 1.55;
  color: var(--fg-dim);
  max-width: var(--measure);
  margin: 0;
}
/* A hero that ends on a control (404's "Return home") needs the gap that
   .section's sibling rule gives everywhere else. */
.hero .lede + p { margin: 2rem 0 0; }

/* ---------- sections ---------- */

/* The section rule is drawn by a pseudo-element rather than `border-top` so
   its width can follow the content. A single-column section's prose stops at
   --measure (665px inside a 1056px wrap), and a border-top spanning the full
   wrap drew a line across ~390px of nothing, which read as unfinished rather
   than as an editorial column. Sections that genuinely use the full width
   opt back in with .section--wide. */
.section {
  position: relative;
  padding-block: var(--step-in) var(--step);
}
.section::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: min(100%, var(--measure));
  height: 1px;
  background: var(--rule);
}
.section--wide::before { width: 100%; }
.section > * + * { margin-top: 1.25rem; }
.section p { max-width: var(--measure); }
.section__title {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem);
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0 0 1.75rem;
  text-wrap: balance;
}
/* Underline removed (Typeset T3): five non-link section openers were
   underlined the same way real links are, so they read as clickable.
   A short rule above, in --band, re-establishes them as section starts
   without borrowing the underline convention that means "link" everywhere
   else on the site. */
.section__title::before {
  content: "";
  display: block;
  width: 2.25rem;
  height: 2px;
  margin-bottom: 0.9rem;
  background: var(--band);
}

/* ---------- steps ---------- */

.steps {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
  margin-top: 2rem; /* same "section opener to major block" gap as .works */
  padding: 0;
  list-style: none;
  counter-reset: step;
}
/* The only grid .steps draws holds four items (/about's "The belief"; the
   home page's five run stacked instead). repeat(auto-fit, minmax(15rem, 1fr))
   settled on three columns everywhere between roughly 830px and 1130px, which
   left step 04 alone with three empty columns beside it. Stepping 4 → 2 → 1
   keeps the grid a complete rectangle at every width. */
@media (min-width: 34rem) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 70rem) {
  .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.step {
  border-top: 1px solid var(--rule);
  padding-top: 1.25rem;
}
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--band);
  margin-bottom: 0.75rem;
  letter-spacing: var(--track-label);
}
.step h3 {
  font-family: var(--mono);
  font-size: 1rem;
  font-weight: 700;
  margin: 0 0 0.5rem;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.step p { margin: 0; color: var(--fg-dim); font-size: 0.9375rem; }

/* ---------- how it works: steps beside a message log ----------
   The home page runs the five steps as a vertical list rather than the
   auto-fit grid, which put four cards in row one and left step 05 alone
   with three empty columns. /about keeps the grid: four items fill a row.
   The right column is where the page finally shows the product, which is
   a text-message thread. */

.works {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  margin-top: 2rem;
}
@media (min-width: 56rem) {
  .works {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: start;
  }
}

.steps--stack {
  display: block;
  margin-top: 0;
}
.steps--stack .step {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  column-gap: 1rem;
  border-top: 1px solid var(--rule);
  padding-block: 1.15rem;
}
.steps--stack .step:first-child { border-top: 0; padding-top: 0; }
.steps--stack .step:last-child { padding-bottom: 0; }
.steps--stack .step::before {
  grid-column: 1;
  grid-row: 1 / span 2;
  margin-bottom: 0;
  line-height: 1.55;
}
.steps--stack .step h3 { grid-column: 2; grid-row: 1; }
.steps--stack .step p { grid-column: 2; grid-row: 2; }

/* ---------- message log ----------
   A log, not phone chrome: no bezel, no notch, no fake status bar. Monospace
   is earned here because this is a transcript, and the sender gutter is the
   thing that makes it read as one. The copy is limited to message types
   /privacy already commits to; nothing here invents an amount, a name, a
   place, or a time, and .thread__label says so. */

.thread {
  margin: 0;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--rule);
  font-family: var(--mono);
}
.thread__label {
  font-size: 0.6875rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 1.25rem;
}
.thread__log {
  list-style: none;
  margin: 0;
  padding: 0;
}
.thread__msg {
  display: grid;
  grid-template-columns: 3rem 1fr;
  column-gap: 0.9rem;
  padding-block: 1.05rem;
  border-top: 1px solid var(--rule);
}
.thread__msg:first-child { border-top: 0; padding-top: 0; }
.thread__msg:last-child { padding-bottom: 0; }
.thread__from {
  grid-column: 1;
  grid-row: 1;
  font-size: 0.6875rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 2.05;
  color: var(--fg-dim);
}
.thread__msg--out .thread__from { color: var(--band); }
.thread__body {
  grid-column: 2;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
}
.thread__meta {
  grid-column: 2;
  margin: 0.6rem 0 0;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--fg-dim);
}
/* The gutter is sized to the longest sender label, which is "MEMBER" at
   45.7px. The narrow layout used to run 2.4rem (38.4px), which let MEMBER
   spill 7.3px into the column gap and knock the log's left edge out of
   alignment. 2.9rem holds it; the gap gives back most of the width. */
@media (max-width: 22.5rem) {
  .thread__msg { grid-template-columns: 2.9rem 1fr; column-gap: 0.5rem; }
}



/* ---------- verse ---------- */

.verse {
  position: relative;
  padding-block: var(--step-in) var(--step);
  display: grid;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}
/* Full-width rule, earned: this section really does span the wrap. */
.verse::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: 1px;
  background: var(--rule);
}
/* Stacked on narrow screens, the mark leads the verse. It stays large: at
   52vw it is unmistakably the brand asterisk rather than a bullet. */
.verse__mark { line-height: 0; }
.verse__mark svg {
  display: block;
  width: min(52vw, 13rem);
  height: auto;
}
.verse__mark stop:nth-of-type(1) { stop-color: var(--g1); }
.verse__mark stop:nth-of-type(2) { stop-color: var(--g2); }
.verse__mark stop:nth-of-type(3) { stop-color: var(--g3); }
.verse__mark stop:nth-of-type(4) { stop-color: var(--g4); }

.verse__quote { margin: 0; }
.verse__quote p {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(1.25rem, 0.9rem + 1.7vw, 2.125rem);
  line-height: 1.32;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}
.verse__quote cite {
  display: block;
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  font-style: normal;
  font-size: 0.8125rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--band);
  font-family: var(--mono);
}

/* Verse left, mark right. Three arrangements were built and compared at 1440
   and 390 (see the composition report): mark-left/verse-right, this one, and
   a stacked mark-over-indented-verse. This one keeps the verse on the same
   left edge as every other section, so the page's spine holds; it fills the
   right column that the critique flagged as dead; and it rhymes with the
   hero, where the physical band sits on the right. The verse is what is
   printed on that band. */
@media (min-width: 56rem) {
  .verse { grid-template-columns: minmax(0, 1fr) auto; }
  .verse__quote { grid-column: 1; grid-row: 1; }
  .verse__mark { grid-column: 2; grid-row: 1; }
  .verse__mark svg { width: clamp(11rem, 21vw, 19rem); }
}

/* ---------- closing invitation ----------
   The page used to end on a mailing address. The details stay, because a
   carrier reviewer needs them, but they are no longer the last thing a
   pastor reads. */

/* Size and leading only. The max-width used to be an override at 54ch, which
   resolved against this paragraph's own larger font and pushed its right edge
   16px past the section rule above it. It now inherits .section p's column and
   shares that edge. */
.closing {
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  line-height: 1.5;
}

/* ---------- details block ---------- */

.details {
  font-family: var(--mono);
  font-size: 0.9375rem;
  line-height: 1.9;
  color: var(--fg-dim);
  margin: 2rem 0 0;
}
.details dt {
  color: var(--fg);
  font-size: 0.75rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  margin-top: 1.25rem;
}
.details dd { margin: 0; }

/* ---------- button ---------- */

.btn {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  padding: 0.85em 1.6em;
  border: 1px solid var(--fg);
  text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease;
}
.btn:hover { background: var(--fg); color: var(--bg); }
/* Press: the periwinkle fill, so hover (white) and active read apart at a
   glance. #a8aee6 behind #000 is 9.86:1. */
.btn:active {
  background: var(--band);
  border-color: var(--band);
  color: var(--bg);
  text-decoration-line: none;
}

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

.footer {
  border-top: 1px solid var(--rule);
  padding-block: 3rem 4rem;
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--fg-dim);
  display: grid;
  gap: 2rem;
}
@media (min-width: 46rem) {
  .footer { grid-template-columns: 1fr auto; align-items: start; }
}
.footer a { color: var(--fg-dim); }
.footer a:hover { color: var(--fg); }
.footer a:active { color: var(--fg); }
.footer__links { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.footer__links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
}

/* ---------- long-form legal pages ---------- */

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.25rem; }
/* 40px is the user-agent's number, not a chosen one. 1.5rem keeps the list
   legibly indented without breaking the column's left edge so far. */
.prose ul, .prose ol { padding-left: 1.5rem; }
/* Space above each heading is roughly 2.75x the space below it, the same
   ratio .section__title runs (68px above the rule, 28px below): the heading
   binds to the copy it introduces rather than floating between two blocks.
   The rule after these zeroes the sibling gap so the heading's own
   margin-bottom is the only thing setting that distance. */
.prose h2 {
  font-family: var(--mono);
  color: var(--fg);
  font-size: 1.5rem;
  margin: 2.75rem 0 1rem;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.prose h3 {
  font-family: var(--mono);
  color: var(--fg);
  font-size: 1.125rem;
  margin: 1.75rem 0 0.625rem;
  text-wrap: balance;
}
.prose :is(h2, h3) + * { margin-top: 0; }
.prose p, .prose li { color: var(--fg); }
.prose li { margin-bottom: 0.5rem; }
.prose li::marker { color: var(--band); }

@media (forced-colors: active) {
  .step,
  .thread,
  .thread__msg,
  .footer { border-color: CanvasText; }
  .btn { border-color: ButtonText; }
  /* Rules drawn as pseudo-element backgrounds rather than borders. */
  .section::before,
  .verse::before,
  .section__title::before,
  .hero__title::after { background: CanvasText; }
}

/* ---------- the one authored moment ----------
   Scroll-driven, CSS-only (the CSP blocks scripts entirely), and confined to
   the verse — no entrances anywhere else on the page.

   The default state is the finished state. Everything below lives inside
   @supports (animation-timeline: view()), so a browser without scroll-driven
   animation support renders the verse plainly rather than blank. The keyframes
   never reach opacity 0 either, so even mid-animation the text is legible. */

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .verse__mark,
    .verse__quote {
      animation: verse-settle both cubic-bezier(0.16, 1, 0.3, 1);
      animation-timeline: view();
    }
    .verse__mark { animation-range: entry 10% cover 34%; }
    .verse__quote { animation-range: entry 18% cover 42%; }
  }
}

@keyframes verse-settle {
  from {
    opacity: 0.18;
    filter: blur(7px);
    transform: translate3d(0, 1.5rem, 0);
  }
  to {
    opacity: 1;
    filter: blur(0);
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Suppress movement, not state feedback. The only transition here is a
     colour change on .btn, which is not a vestibular trigger and stays. */
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

