/* The public site at ironwoodfit.com. Hand-authored static CSS, no build step:
   this runs on the Express app in front of the SPA, and a marketing page that
   needs a bundler is a marketing page nobody edits.

   The palette is the app's own dark tokens, deliberately. Someone who lands
   here and then signs in should not feel handed off to a different product.
   The page commits to dark rather than following the system, because the
   photography and the app it is showing are both dark. */

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/oswald-500.woff2') format('woff2');
}

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/oswald-600.woff2') format('woff2');
}

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/oswald-700.woff2') format('woff2');
}

:root {
  color-scheme: dark;

  --bg: #0b0a08;
  --bg-raise: #1b1a16;
  --bg-card: #141210;
  --line: #282521;
  --line-soft: rgba(242, 241, 237, 0.08);
  --text: #f2f1ed;
  --text-dim: #99978f;
  --accent: #8fae7d;
  --accent-deep: #4a6540;
  --iron: #a9aeb6;
  --amber: #d9a441;

  --display:
    'Oswald', 'Arial Narrow', 'Helvetica Neue Condensed', 'Roboto Condensed', sans-serif-condensed, sans-serif;
  --body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  --gutter: clamp(1.25rem, 5vw, 4rem);
  --measure: 78rem;
  --radius: 18px;
  --radius-sm: 10px;
}

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

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

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A single grain plate over the whole page. Flat near-black reads as a dead
   screen on an OLED phone; this is the one texture the design uses. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* `height: auto` is doing real work, not tidying. Every screenshot carries
   width and height attributes so the browser can reserve its space before the
   file arrives; without this the attribute height wins while the width shrinks
   to the column, and a 390x844 phone renders as a 240x844 one. */
img,
svg {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Every `display` below beats the browser's own rule for [hidden], so the
   attribute has to be made to win once, here. Without this the beta form's
   submit button stays on screen reading "Sending..." underneath the success
   message that replaced it. */
[hidden] {
  display: none !important;
}

a {
  color: inherit;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 0.96;
  letter-spacing: 0.01em;
  margin: 0;
  text-wrap: balance;
}

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

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1rem;
  background: var(--accent);
  color: #10130d;
  font-weight: 700;
}

.skip:focus {
  left: 0;
}

/* --- shared atoms --------------------------------------------------------- */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 1.15rem;
  color: var(--accent);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.lede {
  max-width: 44ch;
  color: var(--text-dim);
  font-size: clamp(1.02rem, 1.55vw, 1.2rem);
  line-height: 1.62;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.9rem 1.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform 140ms ease,
    background-color 140ms ease,
    border-color 140ms ease,
    color 140ms ease;
}

.btn-primary {
  background: var(--accent);
  color: #10130d;
}

.btn-primary:hover {
  background: #a2c08f;
  transform: translateY(-2px);
}

.btn-ghost {
  border-color: var(--line);
  color: var(--text);
  background: transparent;
}

.btn-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-2px);
}

.btn-sm {
  padding: 0.6rem 1.05rem;
  font-size: 0.82rem;
}

/* --- header --------------------------------------------------------------- */

.site-head {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid transparent;
  background: transparent;
  transition:
    background-color 220ms ease,
    border-color 220ms ease,
    backdrop-filter 220ms ease;
}

.site-head.stuck {
  border-bottom-color: var(--line);
  background: rgba(11, 10, 8, 0.86);
  backdrop-filter: blur(14px);
}

.site-head .wrap {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  min-height: 4.75rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  margin-right: auto;
  text-decoration: none;
}

/* THE REAL LOCKUP, not a mark beside typed-out letters.
   It is authored dark-on-transparent for light paper, so the wordmark is
   whitened here the same way the app's own header does it: a second copy of
   the same file, clipped to the wordmark and pushed to pure white, painted
   over the first. The leaf and the tagline show through untouched, which is
   why this beats a blanket filter - that would flatten the leaf's moss and
   steel into one colour.
   `cover` on a 3:1 box crops the file's own top and bottom margin, so the
   lockup sits on the header's baseline rather than floating in its padding. */
.lockup {
  position: relative;
  isolation: isolate;
  display: block;
  width: 9.6rem;
  height: 3.2rem;
}

.lockup img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lockup-wordmark {
  clip-path: inset(15% 0 30% 23%);
  filter: brightness(0) invert(1);
}

/* The tagline is set in the brand's own green, which is a shade chosen for
   white paper and goes muddy on near-black. Re-tinted to the site's accent
   through the lockup's own alpha, so only the letters take the colour. */
.lockup-tagline {
  position: absolute;
  inset: 0;
  background: var(--accent);
  clip-path: inset(73% 0 6% 23%);
  -webkit-mask: url('/img/lockup.png') center / cover no-repeat;
  mask: url('/img/lockup.png') center / cover no-repeat;
  pointer-events: none;
}

/* The leaf on its own, for widths where the full lockup and both buttons
   cannot share a row. Shrinking the lockup instead pushed the call to action
   off the right edge, where `overflow-x: hidden` quietly swallowed it. */
.brand-mark {
  display: none;
  width: auto;
  height: 2.4rem;
}

@media (max-width: 560px) {
  .lockup {
    display: none;
  }

  .brand-mark {
    display: block;
  }

  .site-head .wrap {
    gap: 0.6rem;
  }

  .head-actions {
    gap: 0.4rem;
  }

  /* Narrower, but never shorter than a thumb: the padding that made these fit
     the row had taken them under the 44px touch target. */
  .head-actions .btn-sm {
    min-height: 2.75rem;
    padding: 0.55rem 0.8rem;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
  }
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.9rem;
}

.site-nav a {
  color: var(--text-dim);
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 140ms ease;
}

.site-nav a:hover {
  color: var(--text);
}

.head-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

@media (max-width: 860px) {
  .site-nav {
    display: none;
  }
}

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

/* Paced off the viewport's HEIGHT, not its width. Sized on width, a 1280x860
   laptop got the same generous padding as a tall desktop and pushed the
   primary button 39px under the fold - the one element on the page that must
   never need a scroll to find. */
.hero {
  position: relative;
  padding: clamp(2.5rem, 7vh, 6.5rem) 0 clamp(2rem, 5vh, 5rem);
  overflow: hidden;
}

/* Two quiet lights behind the type: moss from the upper left, steel from the
   right, so the headline sits in a room rather than on a flat field. */
.hero::before {
  content: '';
  position: absolute;
  inset: -30% -10% auto -25%;
  height: 130%;
  z-index: -1;
  background:
    radial-gradient(closest-side at 22% 28%, rgba(143, 174, 125, 0.16), transparent),
    radial-gradient(closest-side at 82% 12%, rgba(169, 174, 182, 0.09), transparent);
  pointer-events: none;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.hero h1 {
  /* The cap is held a little under what the width alone would allow, so the
     three lines plus the lede plus the buttons still clear a 860px laptop. */
  font-size: clamp(3.1rem, 8vw, 6rem);
  letter-spacing: 0.004em;
}

.hero h1 em {
  display: block;
  font-style: normal;
  color: var(--accent);
}

.hero .lede {
  margin-top: 1.3rem;
  max-width: 40ch;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.8rem;
}

.hero-note {
  margin-top: 1.1rem;
  color: var(--text-dim);
  font-size: 0.85rem;
}

.hero-note strong {
  color: var(--text);
  font-weight: 600;
}

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

/* --- device frames -------------------------------------------------------- */

.device {
  position: relative;
  padding: 0.55rem;
  border: 1px solid var(--line);
  border-radius: 2.35rem;
  background: linear-gradient(160deg, #23211c, #0e0d0b 62%);
  box-shadow:
    0 2.5rem 5rem rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(255, 255, 255, 0.03) inset;
}

.device img {
  width: 100%;
  border-radius: 1.85rem;
  background: var(--bg);
}

/* A pair of phones, the back one tipped away so the front one has somewhere
   to be. Both carry the same shadow so they share a light source. */
.hero-devices {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 2vw, 1.4rem);
  align-items: center;
  padding-block: 1rem;
}

.hero-devices .device:first-child {
  transform: rotate(-3.25deg) translateY(1.15rem) scale(0.93);
  transform-origin: bottom right;
  opacity: 0.92;
}

.hero-devices .device:last-child {
  transform: rotate(2.25deg);
  z-index: 2;
}

@media (max-width: 900px) {
  .hero-devices {
    max-width: 30rem;
    margin-inline: auto;
  }
}

/* On a phone the second device has nowhere to go, and one screenshot blown up
   to the full column turned the hero into a screen and a half of mostly empty
   black before the first real section. Keep the pair - the overlap is the
   composition - but at a size that leaves the hero one screen tall. */
@media (max-width: 560px) {
  .hero-devices {
    max-width: 20rem;
    gap: 0.5rem;
  }

  .hero-devices .device {
    padding: 0.35rem;
    border-radius: 1.5rem;
  }

  .hero-devices .device img {
    border-radius: 1.2rem;
  }

  .hero-devices .device:first-child {
    transform: rotate(-3.5deg) translateY(0.75rem) scale(0.92);
  }

  .hero-devices .device:last-child {
    transform: rotate(2.5deg);
  }
}

/* --- specs strip ---------------------------------------------------------- */

.strip {
  border-block: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(27, 26, 22, 0.55), transparent);
}

.strip .wrap {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.5rem;
  padding-block: clamp(1.75rem, 3.5vw, 2.5rem);
}

/* The figures are read across, so they have to sit on one line. Each cell is a
   centred column with the label pinned to the top, which keeps "100% rule-based"
   level with "1,400+" even where "Programming logic" is the label that wraps. */
.spec {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  text-align: center;
}

.spec dt {
  color: var(--text-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.spec dd {
  margin: 0.5rem 0 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.3rem, 2.6vw, 1.85rem);
  line-height: 1.05;
  text-transform: uppercase;
}

@media (max-width: 760px) {
  .strip .wrap {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.75rem 1.25rem;
  }
}

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

.section {
  padding-block: clamp(4rem, 9vw, 7.5rem);
}

.section-head {
  max-width: 52rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.section-head h2 {
  font-size: clamp(2.2rem, 5.4vw, 3.9rem);
}

.section-head .lede {
  margin-top: 1.25rem;
  max-width: 54ch;
}

/* The argument section: one claim, set large, with the reasoning beside it. */
.claim {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.claim h2 {
  font-size: clamp(2.1rem, 5vw, 3.5rem);
}

.claim h2 em {
  font-style: normal;
  color: var(--accent);
}

/* A claim that stands alone rather than arguing with reasoning beside it: one
   centred column. The philosophy reads as a statement, and the two-column grid
   left its heading marooned against an empty half. */
.claim.claim-solo {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  max-width: 48rem;
  margin-inline: auto;
  text-align: center;
}

.claim-body > p + p {
  margin-top: 1.15rem;
}

.claim-body p {
  color: var(--text-dim);
  font-size: 1.03rem;
  line-height: 1.68;
}

.claim-body strong {
  color: var(--text);
  font-weight: 600;
}

@media (max-width: 900px) {
  .claim {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- feature cards -------------------------------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.card {
  position: relative;
  isolation: isolate;
  padding: 1.6rem 1.5rem 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(150deg, rgba(35, 33, 28, 0.75), var(--bg-card) 62%);
  overflow: hidden;
  transition:
    border-color 180ms ease,
    transform 180ms ease;
}

.card::before {
  content: '';
  position: absolute;
  top: -40%;
  right: -30%;
  z-index: -1;
  width: 16rem;
  height: 16rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(143, 174, 125, 0.16), transparent);
  opacity: 0;
  transition: opacity 220ms ease;
}

.card:hover {
  border-color: rgba(143, 174, 125, 0.42);
  transform: translateY(-3px);
}

.card:hover::before {
  opacity: 1;
}

.card-icon {
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: 1.15rem;
  color: var(--accent);
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.card h3 {
  font-size: 1.22rem;
  letter-spacing: 0.045em;
}

.card p {
  margin-top: 0.65rem;
  color: var(--text-dim);
  font-size: 0.93rem;
  line-height: 1.6;
}

@media (max-width: 940px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- screenshot showcase -------------------------------------------------- */

.shots {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
}

.shot figcaption {
  margin-top: 1.35rem;
}

.shot h3 {
  font-size: 1.1rem;
  letter-spacing: 0.05em;
}

.shot p {
  margin-top: 0.5rem;
  color: var(--text-dim);
  font-size: 0.9rem;
  line-height: 1.55;
}

.shot .device {
  border-radius: 1.9rem;
  padding: 0.45rem;
}

.shot .device img {
  border-radius: 1.5rem;
}

/* Narrow screens get a swipeable rail rather than three stacked phones.
   Stacking them was over two thousand pixels of scrolling to see three
   pictures, and the third was never found. The next card deliberately peeks in
   at the right edge: that peek is the only thing that tells a thumb there is
   more, so the card width stays under 80%.

   It bleeds to the screen edges by cancelling the wrap's gutter, because a rail
   that stops short of the edge reads as a cut-off grid instead of something to
   swipe. */
@media (max-width: 820px) {
  .shots {
    display: flex;
    grid-template-columns: none;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    gap: 1rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .shots::-webkit-scrollbar {
    display: none;
  }

  .shot {
    flex: 0 0 min(76%, 19rem);
    scroll-snap-align: start;
  }

  .shot figcaption {
    margin-top: 1rem;
  }
}

/* --- split (coaches) ------------------------------------------------------ */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding: clamp(2rem, 4vw, 3.25rem);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 8px);
  background:
    radial-gradient(closest-side at 88% 10%, rgba(143, 174, 125, 0.13), transparent),
    linear-gradient(150deg, rgba(35, 33, 28, 0.7), var(--bg-card) 64%);
}

.ticks {
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.85rem;
}

.ticks li {
  position: relative;
  padding-left: 1.9rem;
  color: var(--text-dim);
  font-size: 0.97rem;
  line-height: 1.55;
}

.ticks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 0.7rem;
  height: 0.38rem;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

@media (max-width: 900px) {
  .split {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- the letter ----------------------------------------------------------- */

/* The one place on the page where somebody is talking rather than the product
   describing itself. It gets its own band and its own rhythm - wider measure,
   larger type, an opening line that carries - because a voice set in the same
   boxes as the feature cards reads as another feature. */
.letter {
  position: relative;
  border-block: 1px solid var(--line);
  background:
    radial-gradient(closest-side at 14% 0%, rgba(143, 174, 125, 0.09), transparent),
    linear-gradient(180deg, rgba(27, 26, 22, 0.62), transparent 72%);
}

.letter-inner {
  max-width: 52rem;
  padding-block: clamp(3.5rem, 7vw, 6rem);
}

.letter h2 {
  font-size: clamp(2rem, 4.6vw, 3.2rem);
}

/* The opening sentence is the hook, so it is set as one - larger than the
   body, lighter than a heading, and never bolded into a third headline. */
.letter-open {
  margin-top: 1.6rem;
  color: var(--text);
  font-size: clamp(1.2rem, 2.3vw, 1.6rem);
  line-height: 1.45;
  letter-spacing: 0.002em;
}

.letter-body {
  margin-top: 1.5rem;
  max-width: 44rem;
}

.letter-body p {
  color: var(--text-dim);
  font-size: clamp(1rem, 1.5vw, 1.08rem);
  line-height: 1.72;
}

.letter-body p + p {
  margin-top: 1.15rem;
}

.letter-body strong {
  color: var(--text);
  font-weight: 600;
}

.signature {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-top: 2.25rem;
  color: var(--accent);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.signature::before {
  content: '';
  width: 2.75rem;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}

/* --- beta form ------------------------------------------------------------ */

.beta {
  position: relative;
  overflow: hidden;
}

.beta-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.beta h2 {
  font-size: clamp(2.2rem, 5.4vw, 3.6rem);
}

.form {
  padding: clamp(1.5rem, 3vw, 2.1rem);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 6px);
  background: linear-gradient(160deg, rgba(35, 33, 28, 0.78), var(--bg-card) 66%);
}

.field {
  display: block;
}

.field + .field {
  margin-top: 1.05rem;
}

.field > span {
  display: block;
  margin-bottom: 0.45rem;
  color: var(--text-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.field input,
.field textarea {
  width: 100%;
  padding: 0.85rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  background: rgba(11, 10, 8, 0.72);
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.45;
  transition:
    border-color 140ms ease,
    background-color 140ms ease;
}

.phone-choice {
  margin: 1.05rem 0 0;
  padding: 0;
  border: 0;
}

.phone-choice legend {
  display: block;
  margin-bottom: 0.45rem;
  padding: 0;
  color: var(--text-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.phone-choice-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

.phone-choice-options label {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.85rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: rgba(11, 10, 8, 0.72);
  cursor: pointer;
}

.phone-choice-options label:has(input:checked) {
  border-color: var(--accent);
}

.phone-choice-options input {
  width: auto;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
}

.field textarea {
  resize: vertical;
  min-height: 6rem;
}

.field input::placeholder,
.field textarea::placeholder {
  color: #6c6a63;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(11, 10, 8, 0.95);
}

.form .btn {
  width: 100%;
  margin-top: 1.4rem;
}

.form-note {
  margin-top: 1rem;
  color: var(--text-dim);
  font-size: 0.8rem;
  line-height: 1.5;
}

.form-msg {
  margin-top: 1rem;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  line-height: 1.5;
}

.form-msg[data-tone='ok'] {
  border: 1px solid rgba(143, 174, 125, 0.45);
  color: var(--accent);
  background: rgba(143, 174, 125, 0.1);
}

.form-msg[data-tone='error'] {
  border: 1px solid rgba(217, 93, 78, 0.45);
  color: #e88b7e;
  background: rgba(217, 93, 78, 0.1);
}

.form-msg[hidden] {
  display: none;
}

.form-thanks {
  margin-top: 1rem;
  padding: 1rem 1.1rem;
  border: 1px solid rgba(143, 174, 125, 0.45);
  border-radius: var(--radius-sm);
  background: rgba(143, 174, 125, 0.1);
  line-height: 1.55;
}

.form-thanks h3 {
  margin: 0 0 0.6rem;
  color: var(--accent);
}

.form-thanks p + p {
  margin-top: 0.6rem;
}

.form-thanks[hidden] {
  display: none;
}

@media (max-width: 900px) {
  .beta-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

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

.site-foot {
  border-top: 1px solid var(--line);
  padding-block: clamp(3rem, 6vw, 4.5rem) 2.5rem;
  background: linear-gradient(180deg, transparent, rgba(27, 26, 22, 0.5));
}

.foot-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: 2.5rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line);
}

.foot-brand p {
  margin-top: 1.1rem;
  max-width: 34ch;
  color: var(--text-dim);
  font-size: 0.9rem;
}

.foot-col h3 {
  margin-bottom: 1rem;
  color: var(--text-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
}

.foot-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.65rem;
}

.foot-col a {
  display: inline-flex;
  align-items: center;
  color: var(--text);
  font-size: 0.92rem;
  text-decoration: none;
  transition: color 140ms ease;
}

/* A footer list is where a thumb goes wrong most often: seventeen-pixel rows
   separated by ten. On a touch layout each link gets a full target and the
   list carries the extra height, which a footer has to spare. */
@media (max-width: 760px) {
  .foot-col ul {
    gap: 0.1rem;
  }

  .foot-col a {
    min-height: 2.75rem;
  }
}

.foot-col a:hover {
  color: var(--accent);
}

.legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.65rem 1.75rem;
  padding-top: 2rem;
  text-align: center;
  color: var(--text-dim);
  font-size: 0.82rem;
  line-height: 1.6;
}

.legal address {
  font-style: normal;
}

.legal a {
  color: var(--text-dim);
}

.legal a:hover {
  color: var(--accent);
}

@media (max-width: 760px) {
  .foot-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }
}

/* --- long-form pages (privacy, terms, support) ---------------------------- */

.page-head {
  padding-block: clamp(3rem, 7vw, 5rem) clamp(1.5rem, 3vw, 2.5rem);
  border-bottom: 1px solid var(--line);
}

.page-head h1 {
  font-size: clamp(2.4rem, 6vw, 4.2rem);
}

.page-head .updated {
  margin-top: 1rem;
  color: var(--text-dim);
  font-size: 0.85rem;
}

.prose {
  max-width: 46rem;
  padding-block: clamp(2.5rem, 5vw, 4rem) clamp(3.5rem, 7vw, 6rem);
}

.prose h2 {
  margin-top: 3rem;
  font-size: clamp(1.45rem, 3vw, 1.95rem);
}

.prose h2:first-child {
  margin-top: 0;
}

.prose h3 {
  margin-top: 2rem;
  font-size: 1.08rem;
  letter-spacing: 0.05em;
}

.prose p,
.prose li {
  color: #c9c7c0;
  font-size: 1rem;
  line-height: 1.7;
}

.prose p {
  margin-top: 1.05rem;
}

.prose ul {
  margin: 1.05rem 0 0;
  padding-left: 1.2rem;
  display: grid;
  gap: 0.6rem;
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

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

.callout {
  margin-top: 1.75rem;
  padding: 1.25rem 1.4rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: rgba(27, 26, 22, 0.6);
}

.callout p {
  margin-top: 0;
}

.callout p + p {
  margin-top: 0.85rem;
}

.contact-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 2rem;
}

.contact-cards .card p {
  margin-top: 0.5rem;
}

.contact-cards a {
  color: var(--accent);
  font-size: 1.02rem;
  text-decoration: none;
}

.contact-cards a:hover {
  text-decoration: underline;
}

@media (max-width: 620px) {
  .contact-cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- scroll reveal -------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 620ms cubic-bezier(0.22, 0.75, 0.28, 1),
    transform 620ms cubic-bezier(0.22, 0.75, 0.28, 1);
}

[data-reveal].shown {
  opacity: 1;
  transform: none;
}

/* No JavaScript, no reveal script, no reduced-motion preference: in all three
   cases the content must simply be there. */
.no-js [data-reveal],
[data-reveal].shown {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .btn,
  .card {
    transition: none;
  }

  .btn:hover,
  .card:hover {
    transform: none;
  }
}
