/*
 * TrackForge landing site — the ONLY hand-written CSS on it.
 *
 * ---------------------------------------------------------------------------
 * THIS FILE IS ADDITIONS. IT MUST NEVER FIGHT `app.css`.
 * ---------------------------------------------------------------------------
 * It replaced a `styles.css` that did exactly that, and the damage is the
 * reason these rules exist. That file loaded after the app's compiled CSS and:
 *
 *   · reset `border-radius: 0` on `*`, erasing every `rounded-xl` in the
 *     captured markup — the "why are the edges square" difference;
 *   · redefined `--font-sans` in `:root` to a system stack, so body copy lost
 *     Inter and only classes naming `--font-heading` kept Archivo;
 *   · set `body { font-family / font-size / line-height / color / background }`,
 *     overriding the design system at the root of the cascade.
 *
 * So, three standing rules for anything added here:
 *
 *   1. NO `:root` block, NO `body` rule, NO `*` selector. Ever.
 *   2. Every colour, radius, font and weight comes from an app token
 *      (`var(--foreground)`, `var(--radius)`, `var(--font-heading)`, …).
 *      No hex, no system font stacks, no invented scale.
 *   3. Only style class names the app does not use. Everything here is
 *      prefixed `tf-`, except `.waitlist`, which is ours by construction.
 *
 * The homepage loads one same-origin, network-silent reveal helper. The CSP
 * stays `default-src 'none'` and names that one `script-src 'self'`; every
 * other route is script-free.
 */

/* ------------------------------------------------------------------ waitlist */

/*
 * Shaped to match `btnPrimary` from the app's `page-shell.tsx`: same radius
 * token, same primary surface, same weight. It sits where the hero's CTA row
 * was, so it has to read as the button that used to be there.
 */
.waitlist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  max-width: 30rem;
}

.waitlist input[type="email"] {
  flex: 1 1 15rem;
  min-width: 0;
  padding: 0.625rem 0.875rem;
  font: inherit;
  font-size: 15px;
  color: var(--foreground);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.waitlist input[type="email"]::placeholder {
  color: var(--muted-foreground);
}

.waitlist input[type="email"]:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 1px;
}

.waitlist button {
  padding: 0.625rem 1.125rem;
  font: inherit;
  font-size: 15px;
  font-weight: var(--font-weight-semibold);
  color: var(--primary-foreground);
  background: var(--primary);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.waitlist button:hover,
.waitlist button:focus-visible {
  background: color-mix(in oklch, var(--primary) 88%, black);
}

.waitlist button:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 2px;
}

/* On the navy hero the input needs a light surface to stay legible; `--card`
   is white in light mode, which is what the app's own on-navy inputs use. */
.waitlist-on-dark input[type="email"] {
  border-color: color-mix(in oklch, var(--background) 35%, transparent);
}

/* The honeypot. Off-screen rather than `display:none`, because a bot that
   reads computed styles skips hidden fields. */
.tf-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------------------- prose */

/*
 * Legal and policy pages: PLAIN TEXT, no boxes and no cards.
 *
 * Owner instruction, 2026-08-22: "all real sites like volt and teambuildr use
 * just a big full page with the whole text across the whole screen … the actual
 * policy itself is just text." The extraction in `extract-legal.mjs` already
 * strips every wrapper element, so there is nothing here to un-box — these
 * rules only give the bare `h1`/`h2`/`p`/`ul` a readable rhythm in the app's
 * own faces.
 */
.tf-prose {
  max-width: 58rem;
  margin-inline: auto;
  padding: 3.5rem 1.5rem 5rem;
  color: var(--foreground);
  font-size: 16px;
  line-height: 1.7;
}

.tf-prose h1 {
  font-family: var(--font-heading);
  font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin: 0 0 0.5rem;
}

.tf-prose h2 {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.015em;
  margin: 2.75rem 0 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.tf-prose h3 {
  font-size: 1.0625rem;
  font-weight: var(--font-weight-semibold);
  margin: 1.75rem 0 0.5rem;
}

.tf-prose p,
.tf-prose li {
  margin-block: 0 0.75rem;
}

.tf-prose ul,
.tf-prose ol {
  padding-left: 1.25rem;
  margin-block: 0 1rem;
}

.tf-prose li {
  margin-bottom: 0.35rem;
}

.tf-prose a:not(.tf-btn) {
  color: var(--primary);
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 3px;
}

.tf-prose a:not(.tf-btn):hover {
  color: color-mix(in oklch, var(--primary) 82%, black);
}

.tf-prose a:not(.tf-btn):focus-visible {
  border-radius: var(--radius-sm);
  outline: 3px solid var(--ring);
  outline-offset: 2px;
}

.tf-prose code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--secondary);
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
}

.tf-prose hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2.5rem 0;
}

.tf-prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
  margin: 1.25rem 0;
  display: block;
  overflow-x: auto;
}

.tf-prose th,
.tf-prose td {
  border-bottom: 1px solid var(--border);
  padding: 0.6rem 0.85rem 0.6rem 0;
  text-align: left;
  vertical-align: top;
}

.tf-prose th {
  font-weight: var(--font-weight-semibold);
}

.tf-updated {
  color: var(--muted-foreground);
  font-size: 0.9375rem;
  margin: 0 0 2.5rem;
}

/* A caveat, not decoration: a flat tint with one accent edge. */
.tf-callout {
  background: var(--secondary);
  border-left: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  padding: 1rem 1.25rem;
  margin: 2rem 0;
  font-size: 0.9375rem;
  color: var(--muted-foreground);
}

.tf-callout strong {
  color: var(--foreground);
}

/* ------------------------------------------------------------------ pricing */

.tf-price-table {
  width: 100%;
  border-collapse: collapse;
  border-top: 1px solid var(--border);
  margin: 2rem 0;
}

.tf-price-table th,
.tf-price-table td {
  padding: 1.5rem 1.25rem 1.5rem 0;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.tf-price-table thead th {
  padding-block: 0.75rem;
  color: var(--muted-foreground);
  font-size: 0.75rem;
  font-weight: var(--font-weight-semibold);
}

.tf-price-table tbody th {
  font-weight: inherit;
}

.tf-plan-name {
  font-family: var(--font-heading);
  font-size: 1.125rem;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.015em;
  margin: 0 0 0.25rem;
}

.tf-plan-who {
  color: var(--muted-foreground);
  font-size: 0.9375rem;
  margin: 0;
}

.tf-amount {
  font-family: var(--font-heading);
  font-size: 1.875rem;
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.03em;
  line-height: 1;
  white-space: nowrap;
}

.tf-cadence {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: var(--font-weight-normal);
  color: var(--muted-foreground);
}

.tf-annual {
  color: var(--muted-foreground);
  font-size: 0.9375rem;
  margin: 0.4rem 0 0;
}

.tf-quoted {
  font-family: var(--font-heading);
  font-size: 1.125rem;
  font-weight: var(--font-weight-semibold);
}

.tf-includes {
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--muted-foreground);
  font-size: 0.9375rem;
}

.tf-includes li {
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.3rem;
}

.tf-includes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.66em;
  width: 6px;
  height: 1px;
  background: var(--border);
}

/* Numerals are tabular wherever they are data. */
.tf-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 780px) {
  .tf-price-table,
  .tf-price-table tbody,
  .tf-price-table tr,
  .tf-price-table tbody th,
  .tf-price-table td {
    display: block;
    width: 100%;
  }
  .tf-price-table tr {
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
  }
  .tf-price-table tbody th,
  .tf-price-table td {
    border-bottom: 0;
    padding: 0.35rem 0;
  }
  .tf-price-table tr th:first-child {
    padding-top: 1.5rem;
  }

  .tf-price-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* --------------------------------------------------------------------- misc */

.tf-btn {
  display: inline-block;
  padding: 0.625rem 1.125rem;
  font-size: 15px;
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  border-radius: var(--radius);
  background: var(--primary);
  color: var(--primary-foreground);
}

.tf-btn:hover,
.tf-btn:focus-visible {
  background: color-mix(in oklch, var(--primary) 88%, black);
}

.tf-btn:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 2px;
}

.tf-text-link {
  display: inline-flex;
  min-height: 1.75rem;
  align-items: center;
  border-radius: var(--radius-sm);
  color: var(--primary);
  font-weight: var(--font-weight-semibold);
  text-underline-offset: 3px;
}

.tf-text-link:hover {
  text-decoration: underline;
}

.tf-text-link:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 2px;
}

:where(main, section, input)[id] {
  scroll-margin-top: 7rem;
}

/* The ported comparison starts as a wide three-column desktop table. H47
   narrows it to two columns; on a phone the rows stack so the evidence reads
   as three compact facts instead of a sentence broken into six-word columns. */
@media (max-width: 639px) {
  .tf-static-comparison thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  .tf-static-comparison,
  .tf-static-comparison tbody,
  .tf-static-comparison tr,
  .tf-static-comparison th,
  .tf-static-comparison td {
    display: block;
    width: 100%;
  }

  .tf-static-comparison tr {
    padding-block: 1rem;
  }

  .tf-static-comparison th,
  .tf-static-comparison td {
    padding: 0;
  }

  .tf-static-comparison td {
    margin-top: 0.375rem;
  }
}

/*
 * Restore list markers. Tailwind's preflight sets `list-style: none` on every
 * `ul`/`ol`, which the app compensates for per component — but these pages are
 * bare semantic HTML extracted from the app, so nothing puts the markers back.
 * In a policy document the nesting IS the meaning ("you agree not to: …"), so
 * an unmarked list is a legibility problem, not a style preference.
 */
/* `:not(.tf-includes)` because that rule is appended AFTER `.tf-includes`
   and out-specifies it (0,1,1 vs 0,1,0), so without the guard the pricing
   page renders a disc AND the dash marker on every line. */
.tf-prose ul:not(.tf-includes) {
  list-style: disc;
}

.tf-prose ol {
  list-style: decimal;
}

.tf-prose li::marker {
  color: var(--muted-foreground);
}

/*
 * Footer columns whose links were all removed.
 *
 * The shape is `<div><p>Who it's for</p><div class="flex flex-col …"></div></div>`
 * — the links live in a nested DIV, not a list, so the port's structural cleanup
 * did not catch it and two columns rendered as a title over empty space.
 *
 * `:has()` matches that shape exactly: a column containing a title immediately
 * followed by an EMPTY element. The footer tagline has no empty sibling, so it
 * is untouched. This is a presentational patch over a generator gap — the
 * markup still contains the dead columns, so if `port-home.mjs` is ever fixed to
 * drop them structurally, delete this rule rather than keeping both.
 */
footer div:has(> p + div:empty) {
  display: none;
}
