/*
 * Jim AI — public site (D-055, D-059).
 *
 * Built against the design system in `Jim AI/design_handoff_jim_ai_site/`.
 * The token block below is that system's `tokens/*.css` inlined rather than
 * `@import`ed, deliberately: the build copies this one file and fingerprints
 * it by content hash, so an @import would resolve to a URL that is never
 * published and every token would fall back to nothing.
 *
 * Two readers have to be served at once and they want different things:
 * someone deciding whether to sign up, and a carrier reviewer checking that
 * specific required sentences are present. The design leans marketing; the
 * legal pages stay plain and high-contrast, because a reviewer skim-reading
 * for "message and data rates may apply" should not have to fight the layout.
 *
 * Motion is opt-out. `site.js` sets `animation: jimReveal ...` on each section
 * as it scrolls in, so the keyframe lives here and every animated rule is
 * cancelled under `prefers-reduced-motion`. The script also declines to touch
 * anything when that query matches, so the two halves agree.
 */

/* ==========================================================================
   Tokens — from the design system. Do not invent values outside this block.
   ========================================================================== */

:root {
  /* Brand */
  --jim-lime: #b9ff2e;
  --jim-lime-hover: #d4ff7a;
  --jim-lime-16: rgba(185, 255, 46, 0.16);
  --jim-lime-26: rgba(185, 255, 46, 0.26);

  /* Neutrals — near-black gym palette */
  --jim-ink-900: #08090c;
  --jim-ink-850: #0a0c10;
  --jim-ink-800: #0b0d12;
  --jim-ink-750: #0d0f14;
  --jim-ink-700: #0e1015;
  --jim-ink-600: #16181d;
  --jim-ink-500: #1a1d25;
  --jim-line: #1c1f27;
  --jim-line-strong: #23262e;
  --jim-key: #3a3f47;
  --jim-key-alt: #2b3037;

  /* Text */
  --jim-text-1: #f2f3f5;
  --jim-text-2: #d3d7de;
  --jim-text-3: #9ba1ad;
  --jim-text-4: #6e7684;
  --jim-text-5: #565d6a;
  --jim-text-6: #454c58;

  /* Semantic aliases */
  --surface-page: var(--jim-ink-900);
  --surface-card: var(--jim-ink-800);
  --surface-raised: var(--jim-ink-700);
  --surface-footer: var(--jim-ink-850);
  --border-default: var(--jim-line);
  --border-strong: var(--jim-line-strong);
  --accent: var(--jim-lime);
  --accent-hover: var(--jim-lime-hover);
  --on-accent: var(--jim-ink-900);
  --text-body: var(--jim-text-3);
  --text-heading: var(--jim-text-1);
  --text-muted: var(--jim-text-4);
  --text-legal: var(--jim-text-5);

  --grad-card: linear-gradient(180deg, #0d0f14 0%, #0a0c10 100%);
  --grad-card-accent: linear-gradient(180deg, rgba(18, 22, 14, 0.86) 0%, rgba(11, 13, 18, 0.82) 70%);
  --grad-hero-scrim: linear-gradient(
    100deg,
    #08090c 0%,
    rgba(8, 9, 12, 0.93) 34%,
    rgba(8, 9, 12, 0.62) 60%,
    rgba(8, 9, 12, 0.55) 100%
  );
  --grad-page-top: radial-gradient(120% 60% at 50% -10%, #14161c 0%, #08090c 60%);

  /* Type */
  --font-sans: Archivo, Helvetica, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
  --type-hero: 800 68px/0.98 var(--font-sans);
  --type-hero-tracking: -0.035em;
  --type-h2: 800 42px/1.05 var(--font-sans);
  --type-h2-tracking: -0.03em;
  --type-h3: 700 27px/1.2 var(--font-sans);
  --type-h4: 700 22px/1.25 var(--font-sans);
  --type-price: 800 44px/1 var(--font-sans);
  --type-lead: 400 19px/1.55 var(--font-sans);
  --type-body: 400 16px/1.6 var(--font-sans);
  --type-body-sm: 400 15px/1.6 var(--font-sans);
  --type-legal: 400 12px/1.7 var(--font-sans);
  --type-eyebrow: 500 11px/1.2 var(--font-mono);
  --type-eyebrow-tracking: 0.14em;
  --type-data: 500 13px/1.4 var(--font-mono);
  --type-stat: 800 18px/1.15 var(--font-sans);

  /* Space */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-11: 44px;
  --space-14: 56px;
  --space-18: 72px;
  --space-24: 96px;
  --space-28: 110px;
  --page-max: 1200px;
  --prose-max: 860px;
  --page-gutter: var(--space-10);
  --grid-gap: var(--space-5);
  --section-pad-y: var(--space-28);

  /* Effects */
  --radius-sm: 5px;
  --radius-md: 12px;
  --radius-card: 20px;
  --radius-panel: 24px;
  --radius-pill: 999px;
  --radius-phone: 56px;
  --border-1: 1px solid var(--border-default);
  --border-accent: 1px solid var(--accent);
  --shadow-phone: 0 60px 100px -34px rgba(0, 0, 0, 0.95), inset 0 0 0 1px rgba(255, 255, 255, 0.07);
  --shadow-key: 0 1px 0 rgba(0, 0, 0, 0.5);
  --blur-card: blur(8px);
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --dur-fast: 160ms;
  --dur-med: 300ms;
  --dur-slow: 620ms;
}

/* ==========================================================================
   Base
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--surface-page);
  background-image: var(--grad-page-top);
  background-repeat: no-repeat;
  color: var(--text-body);
  font: var(--type-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  color: var(--text-heading);
}

h1 {
  font: var(--type-hero);
  letter-spacing: var(--type-hero-tracking);
}

h2 {
  font: var(--type-h2);
  letter-spacing: var(--type-h2-tracking);
}

h3 {
  font: var(--type-h3);
  letter-spacing: -0.02em;
}

h4 {
  font: var(--type-h4);
}

p {
  margin: 0 0 var(--space-4);
}

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}

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

img,
svg {
  max-width: 100%;
}

/* Visible only to a screen reader. Load-bearing: the comparison table's marks
   are glyphs, so the yes/no meaning exists nowhere else. */
.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;
}

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

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.page,
.page-doc {
  overflow-x: clip;
}

main > section {
  padding: var(--section-pad-y) var(--page-gutter);
}

main > section > * {
  max-width: var(--page-max);
  margin-inline: auto;
}

.section-sub {
  max-width: 62ch;
  margin: var(--space-4) auto var(--space-14);
  font: var(--type-lead);
  color: var(--text-body);
  text-align: center;
}

main > section > h2 {
  text-align: center;
}

.eyebrow {
  display: block;
  margin-bottom: var(--space-3);
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--accent);
}

/* ==========================================================================
   Header and navigation
   ========================================================================== */

/* The header itself is the flex row — brand, nav, CTA are siblings, there is no
   inner wrapper. The padding centres the content on a full-bleed bar without
   one. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-4);
  padding-inline: max(var(--page-gutter), calc((100% - var(--page-max)) / 2));
  background: rgba(8, 9, 12, 0.72);
  backdrop-filter: var(--blur-card);
  -webkit-backdrop-filter: var(--blur-card);
  border-bottom: var(--border-1);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-right: auto;
  color: var(--text-heading);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-size: 18px;
}

.brand:hover {
  color: var(--text-heading);
}

.brand-mark {
  width: 28px;
  height: 28px;
  flex: none;
}

.brand-name {
  display: inline-flex;
  gap: 0.12em;
}

.brand-jim {
  color: var(--text-heading);
}

.brand-ai {
  color: var(--accent);
}

.site-nav a {
  color: var(--text-body);
  font-size: 15px;
}

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

/* The legal pages' header. Same bar, but only a brand and a back link, so it
   does not stick: on a long policy page a fixed bar just eats reading height,
   and there is no in-page nav to keep reachable. */
.doc-header {
  position: static;
}

.header-back {
  margin-left: auto;
  font: var(--type-data);
  color: var(--text-muted);
}

.header-back:hover {
  color: var(--text-heading);
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0 var(--space-6);
  height: var(--space-11);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn:hover {
  background: var(--accent-hover);
  color: var(--on-accent);
}

.btn:active {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-secondary,
.btn-ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text-heading);
}

.btn-secondary:hover,
.btn-ghost:hover {
  background: var(--jim-ink-600);
  border-color: var(--jim-key);
  color: var(--text-heading);
}

.btn-sm {
  height: 34px;
  padding: 0 var(--space-4);
  font-size: 14px;
}

.btn-lg {
  height: 52px;
  padding: 0 var(--space-8);
  font-size: 17px;
}

.btn-block {
  display: flex;
  width: 100%;
}

/* ==========================================================================
   Badges
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-3);
  border: var(--border-1);
  border-radius: var(--radius-pill);
  background: var(--jim-ink-600);
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-body);
}

.badge-accent {
  border-color: var(--jim-lime-26);
  background: var(--jim-lime-16);
  color: var(--accent);
}

.badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* ==========================================================================
   Cards
   ========================================================================== */

.card {
  padding: var(--space-8);
  border: var(--border-1);
  border-radius: var(--radius-card);
  background: var(--grad-card);
}

.card-plain {
  background: var(--surface-card);
}

.card-accent {
  border-color: var(--jim-lime-26);
  background: var(--grad-card-accent);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-18);
  min-height: 84vh;
  padding: var(--space-24) var(--page-gutter) var(--space-28);
  isolation: isolate;
}

.hero > * {
  max-width: none;
}

.hero-backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

/* The photograph. Referenced by name rather than content-hashed, because the
   markup and a favicon-hunting browser both look for it by path. */
.hero-grain {
  position: absolute;
  inset: 0;
  background: url("/assets/gym.png") center right / cover no-repeat;
  opacity: 0.9;
}

/* Three stacked scrims rather than one: the headline sits over the brightest
   part of the photograph, and a single gradient dark enough to carry it made
   the right-hand side flat. */
.hero-scrim-1 {
  position: absolute;
  inset: 0;
  background: var(--grad-hero-scrim);
}

.hero-scrim-2 {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 9, 12, 0.85) 0%, rgba(8, 9, 12, 0) 30%);
}

.hero-scrim-3 {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, var(--surface-page) 0%, rgba(8, 9, 12, 0) 26%);
}

/* Wide enough that the <br> in the headline is the only thing that breaks it.
   Sized in px, not ch: `ch` resolves against this element's 16px body font, not
   the 68px display face the line actually has to fit. */
.hero-copy {
  max-width: 620px;
}

.hero-copy h1 {
  margin: var(--space-5) 0 var(--space-5);
}

.hero-lead {
  font: var(--type-lead);
  color: var(--text-body);
  max-width: 46ch;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: var(--space-8) 0 var(--space-4);
}

.hero-fine {
  font: var(--type-body-sm);
  color: var(--text-muted);
  margin: 0;
}

/* The rotating "225x5 / bench" stat. `is-out` is set by site.js for the swap. */
.lift-log {
  position: absolute;
  left: var(--page-gutter);
  bottom: var(--space-14);
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  transition:
    opacity var(--dur-med) var(--ease-out),
    transform var(--dur-med) var(--ease-out);
}

.lift-log.is-out {
  opacity: 0;
  transform: translateY(6px);
}

.lift-log-value {
  font: var(--type-stat);
  color: var(--text-heading);
}

.lift-log-label {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ==========================================================================
   Phone mockup
   ========================================================================== */

.phone-wrap {
  display: flex;
  justify-content: center;
  perspective: 1400px;
}

.phone {
  position: relative;
  width: 340px;
  height: 700px;
  padding: 12px;
  border-radius: var(--radius-phone);
  background: linear-gradient(160deg, #23262e 0%, #0d0f14 42%, #16181d 100%);
  box-shadow: var(--shadow-phone);
}

.phone-btn {
  position: absolute;
  width: 3px;
  border-radius: 2px;
  background: var(--jim-key-alt);
}

.phone-btn-mute {
  left: -3px;
  top: 116px;
  height: 28px;
}

.phone-btn-up {
  left: -3px;
  top: 162px;
  height: 54px;
}

.phone-btn-down {
  left: -3px;
  top: 228px;
  height: 54px;
}

.phone-btn-power {
  right: -3px;
  top: 186px;
  height: 84px;
}

.phone-screen {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: 44px;
  background: var(--jim-ink-900);
}

/* --- Status bar --- */

.status-bar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-5) var(--space-1);
  font: var(--type-data);
  color: var(--text-heading);
}

.status-time {
  font-weight: 600;
  font-size: 14px;
}

.status-notch {
  position: absolute;
  left: 50%;
  top: 6px;
  transform: translateX(-50%);
  width: 96px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: #000;
}

.status-right {
  display: flex;
  align-items: center;
  gap: 5px;
}

.status-bars,
.status-net {
  font-size: 11px;
  color: var(--text-heading);
}

/* Four <i> elements, drawn as a rising signal staircase. */
.status-bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 11px;
}

.status-bars i {
  width: 3px;
  border-radius: 1px;
  background: var(--text-heading);
}

.status-bars i:nth-child(1) {
  height: 40%;
}

.status-bars i:nth-child(2) {
  height: 60%;
}

.status-bars i:nth-child(3) {
  height: 80%;
}

.status-bars i:nth-child(4) {
  height: 100%;
}

.status-battery {
  display: flex;
  align-items: center;
  gap: 1px;
}

.status-battery-body {
  width: 22px;
  height: 11px;
  padding: 1.5px;
  border: 1px solid rgba(242, 243, 245, 0.45);
  border-radius: 3px;
}

.status-battery-fill {
  width: 72%;
  height: 100%;
  border-radius: 1px;
  background: var(--text-heading);
}

.status-battery-cap {
  width: 1.5px;
  height: 4px;
  border-radius: 0 1px 1px 0;
  background: rgba(242, 243, 245, 0.45);
}

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

.convo-head {
  padding: var(--space-2) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--jim-line);
  background: rgba(22, 24, 29, 0.6);
  backdrop-filter: var(--blur-card);
  -webkit-backdrop-filter: var(--blur-card);
  text-align: center;
}

.convo-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.convo-back {
  color: var(--jim-lime);
  font-size: 20px;
  line-height: 1;
}

.convo-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
  font-size: 15px;
  display: grid;
  place-items: center;
}

.convo-sms {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

.convo-name {
  margin-top: var(--space-1);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2, var(--jim-text-2));
}

/* --- Thread --- */

.thread {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  overflow: hidden;
}

.thread-row {
  display: flex;
}

.thread-row.mine {
  justify-content: flex-end;
}

.thread-row.theirs {
  justify-content: flex-start;
}

.bubble-mine,
.bubble-theirs {
  max-width: 80%;
  padding: 9px 14px;
  border-radius: 20px;
  font-size: 14.5px;
  line-height: 1.4;
}

/* iMessage blue is not used anywhere: this is the brand thread, and a lime
   outgoing bubble is what the design specifies. */
.bubble-mine {
  background: var(--accent);
  color: var(--on-accent);
  border-bottom-right-radius: 6px;
}

.bubble-theirs {
  background: var(--jim-ink-500);
  color: var(--jim-text-2);
  border-bottom-left-radius: 6px;
}

/* --- Composer --- */

.composer {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--jim-line);
}

.composer-plus {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--jim-ink-500);
  color: var(--text-muted);
  display: grid;
  place-items: center;
  font-size: 18px;
}

.composer-field {
  flex: 1;
  display: flex;
  align-items: center;
  min-height: 32px;
  padding: 5px 12px;
  border: 1px solid var(--jim-line-strong);
  border-radius: var(--radius-pill);
  font-size: 14px;
  color: var(--jim-text-2);
}

.composer-placeholder {
  color: var(--text-muted);
}

/* The text site.js "types" into the field, character by character. */
.composer-draft {
  color: var(--text-heading);
  white-space: pre;
}

.composer-caret {
  display: inline-block;
  width: 1.5px;
  height: 16px;
  margin-left: 1px;
  background: var(--accent);
  animation: jimCaret 1s steps(2, start) infinite;
}

.composer-send {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--jim-ink-500);
  color: var(--text-muted);
  display: grid;
  place-items: center;
  font-size: 15px;
  transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

/* site.js toggles this the moment the draft is non-empty. */
.composer-send.is-active {
  background: var(--accent);
  color: var(--on-accent);
}

/* --- Keyboard --- */

.keyboard {
  padding: var(--space-2) 5px var(--space-1);
  background: var(--jim-ink-600);
}

.kb-row {
  display: flex;
  justify-content: center;
  gap: 5px;
  margin-bottom: 6px;
}

.kb-row-2 {
  padding: 0 14px;
}

.kb-row-inner {
  display: contents;
}

.key,
.key-mod {
  flex: 1;
  min-width: 0;
  height: 34px;
  border-radius: var(--radius-sm);
  background: var(--jim-key);
  box-shadow: var(--shadow-key);
  color: var(--text-heading);
  font-size: 15px;
  display: grid;
  place-items: center;
  transition:
    background var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.key-mod {
  background: var(--jim-key-alt);
  font-size: 12px;
  color: var(--jim-text-2);
}

/* site.js flags the key it is "typing". */
.key.is-on,
.key-mod.is-on {
  background: var(--accent);
  color: var(--on-accent);
  transform: translateY(1px);
}

.key-shift,
.key-back {
  flex: 0 0 40px;
}

.key-num {
  flex: 0 0 44px;
}

.key-emoji {
  flex: 0 0 34px;
}

.key-space {
  flex: 1 1 auto;
}

.key-return {
  flex: 0 0 70px;
}

.home-indicator {
  width: 132px;
  height: 5px;
  margin: var(--space-2) auto var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--jim-key);
}

/* ==========================================================================
   Features
   ========================================================================== */

/* The features band sits directly under the hero, so it loses the top padding
   the generic section rule would give it. */
.features {
  padding-top: var(--space-18);
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--grid-gap);
}

.feature-title {
  margin-bottom: var(--space-3);
  font: var(--type-h4);
  color: var(--text-heading);
}

.feature-body {
  margin: 0;
  font: var(--type-body-sm);
  color: var(--text-body);
}

/* ==========================================================================
   How it works
   ========================================================================== */

.how-ghost-list {
  display: none;
}

.step-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-10);
}

/* Each step is a <button role="tab"> whose children are spans, so it needs a
   full control reset and its own block formatting. */
.step {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.step-panel,
.step-title,
.step-body,
.step-detail,
.step-index {
  display: block;
}

.step-index {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  color: var(--accent);
}

.step-panel {
  margin: var(--space-4) 0 var(--space-6);
  padding: var(--space-5);
  border: var(--border-1);
  border-radius: var(--radius-panel);
  background: var(--grad-card);
}

.step-art {
  height: 156px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
}

.step-title {
  margin-bottom: var(--space-2);
  font: var(--type-h4);
  color: var(--text-heading);
}

.step-body {
  margin: 0 0 var(--space-2);
  font: var(--type-body-sm);
  color: var(--text-body);
}

.step-detail {
  margin: 0;
  font: var(--type-legal);
  color: var(--text-legal);
}

/* --- Step 1: the signup form mock --- */

.mock-form {
  justify-content: center;
  gap: var(--space-4);
}

.mock-input {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--jim-ink-900);
  color: var(--text-muted);
  font: var(--type-data);
}

.mock-caret {
  display: inline-block;
  width: 1.5px;
  height: 15px;
  background: var(--accent);
  animation: jimCaret 1s steps(2, start) infinite;
}

.mock-consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

/* Depicts the box after the athlete ticks it — the illustration is of someone
   completing the form, and the real input on this page still ships unchecked
   (D-050, D-057). */
.mock-check {
  flex: none;
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  line-height: 1;
}

/* Two <i> elements standing in for the two lines of disclosure text. */
.mock-bars {
  flex: 1;
  display: grid;
  gap: 6px;
}

.mock-bars i {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--jim-ink-500);
}

.mock-bars i:last-child {
  width: 72%;
}

/* --- Step 2: the chat mock --- */

.mock-chat {
  justify-content: center;
  gap: var(--space-2);
}

.mock-chat-out,
.mock-chat-in {
  max-width: 78%;
  padding: 8px 12px;
  border-radius: 16px;
  font-size: 13.5px;
  line-height: 1.4;
}

.mock-chat-out {
  align-self: flex-end;
  background: var(--accent);
  color: var(--on-accent);
  border-bottom-right-radius: 5px;
}

.mock-chat-in {
  align-self: flex-start;
  background: var(--jim-ink-500);
  color: var(--jim-text-2);
  border-bottom-left-radius: 5px;
}

/* --- Step 3: the trend chart --- */

.mock-chart {
  position: relative;
  justify-content: flex-end;
}

/* `.trend-area`, `.trend-line` and `.trend-dot` are SVG <polygon>, <polyline>
   and <circle>, not boxes — the chart carries its own coordinates, fill and
   stroke as presentation attributes. Nothing is styled here on purpose: a
   `clip-path` or `position` aimed at them would fight geometry that is already
   correct. The only addition is the draw-on animation. */
.mock-chart svg {
  width: 100%;
  height: 100%;
}

.trend-line {
  stroke-dasharray: 260;
  stroke-dashoffset: 260;
  animation: jimTrend 1400ms var(--ease-out) 200ms forwards;
}

/* ==========================================================================
   Pricing
   ========================================================================== */

/* The cards and the radar share one grid area so the radar sits *behind* the
   Pro card, which is what the markup asks for and what its translucent
   background exists to allow. Overlapping them by grid placement rather than by
   absolute offsets means the two stay registered to each other at every width,
   with no magic percentages to drift. */
.pricing {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "head"
    "sub"
    "cards";
  justify-items: center;
  background: linear-gradient(180deg, rgba(14, 16, 21, 0) 0%, rgba(14, 16, 21, 0.55) 50%, rgba(14, 16, 21, 0) 100%);
}

.pricing > h2 {
  grid-area: head;
}

.pricing > .section-sub {
  grid-area: sub;
}

.price-grid {
  grid-area: cards;
  width: 100%;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--grid-gap);
  align-items: start;
}

.price-card {
  position: relative;
  display: flex;
  flex-direction: column;
}

.price-badge {
  position: absolute;
  top: calc(var(--space-5) * -1);
  left: var(--space-8);
}

.price-head {
  margin-bottom: var(--space-6);
}

/* All three are spans in the markup, so they need to be told to stack. */
.price-eyebrow,
.price-amount,
.price-note {
  display: block;
}

.price-eyebrow {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

.price-eyebrow-accent {
  color: var(--accent);
}

.price-amount {
  margin: var(--space-3) 0 var(--space-2);
  font: var(--type-price);
  letter-spacing: -0.03em;
  color: var(--text-heading);
}

.price-period {
  display: inline;
  font: var(--type-body);
  color: var(--text-muted);
}

.price-note {
  margin: 0;
  font: var(--type-body-sm);
  color: var(--text-body);
}

.price-list {
  flex: 1;
  margin: 0 0 var(--space-8);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-3);
}

.price-list li {
  position: relative;
  padding-left: var(--space-6);
  font: var(--type-body-sm);
  color: var(--jim-text-2);
}

.price-list li::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--accent);
}

/* --- Radar --- */

/* Behind the Pro card, as the markup specifies. Placed in the same grid area as
   the cards and pushed onto the right-hand column, so the shape reads through
   the Pro card's translucent background and its six stat labels sit out around
   the card edges where site.js can cycle them in view.
   `aria-hidden` is already on it in the markup; `pointer-events: none` keeps it
   from swallowing clicks meant for the card sitting on top of it. */
.radar {
  grid-area: cards;
  z-index: 0;
  align-self: center;
  justify-self: center;
  width: min(620px, 92%);
  margin: 0;
  aspect-ratio: 1;
  pointer-events: none;
  /* X centres it on the Pro card; Y drops it far enough that the Strength
     label clears the "Coaching" badge pinned to that card's top edge. */
  transform: translate(25%, 11%);
}

.radar-glow {
  position: absolute;
  inset: 12%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--jim-lime-16) 0%, rgba(185, 255, 46, 0) 70%);
}

.radar-stage {
  position: relative;
  width: 100%;
  height: 100%;
}

.radar-shape {
  width: 100%;
  height: 100%;
}

.radar-stat {
  position: absolute;
  display: grid;
  gap: 2px;
  text-align: center;
  transform: translate(-50%, -50%);
}

.radar-stat-word {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

.radar-stat-value {
  font: var(--type-stat);
  color: var(--text-heading);
}

/* The six hexagon vertices, as percentages of the 320x320 viewBox the SVG and
   site.js both use: centre (160,160), outer radius 140. Top vertex is
   (160,20) = 50%/6.25%; the rest follow at 60 degree steps. Each label is
   nudged a little further out than its vertex so it clears the dashed ring. */
.radar-strength {
  left: 50%;
  top: 1%;
}

.radar-volume {
  left: 91%;
  top: 26%;
}

.radar-mobility {
  left: 91%;
  top: 74%;
}

.radar-recovery {
  left: 50%;
  top: 99%;
}

.radar-endurance {
  left: 9%;
  top: 74%;
}

.radar-consistency {
  left: 9%;
  top: 26%;
}

/* ==========================================================================
   Comparison table
   ========================================================================== */

.compare {
  overflow-x: auto;
  border: var(--border-1);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.compare table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}

.compare th,
.compare td {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--jim-line);
  text-align: center;
}

.compare tbody tr:last-child th,
.compare tbody tr:last-child td {
  border-bottom: 0;
}

.compare thead th {
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

.compare thead th.is-us {
  color: var(--accent);
}

.compare tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--jim-text-2);
  white-space: nowrap;
}

.mark-yes {
  color: var(--accent);
  font-size: 17px;
}

.mark-no {
  color: var(--jim-text-6);
  font-size: 17px;
}

.mark-partial {
  color: var(--text-muted);
  font-size: 17px;
}

/* ==========================================================================
   FAQ
   ========================================================================== */

.faq-list {
  max-width: var(--prose-max);
  margin-inline: auto;
  border-top: var(--border-1);
}

.faq-item {
  border-bottom: var(--border-1);
}

.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-5) 0;
  border: 0;
  background: none;
  color: var(--text-heading);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 17px;
  text-align: left;
  cursor: pointer;
}

.faq-q:hover {
  color: var(--accent);
}

.faq-toggle {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--jim-ink-600);
  color: var(--accent);
  font-size: 16px;
  line-height: 1;
}

.faq-a {
  padding: 0 0 var(--space-5);
  margin: 0;
  max-width: 70ch;
  font: var(--type-body-sm);
  color: var(--text-body);
  animation: jimFaqOpen var(--dur-med) var(--ease-out) both;
}

/* site.js sets this, waits 300ms, then sets `hidden` — so the two durations
   have to agree or the answer vanishes mid-animation. */
.faq-a.is-closing {
  animation: jimFaqClose var(--dur-med) var(--ease-in) both;
}

.faq-a[hidden] {
  display: none;
}

/* ==========================================================================
   Signup panel
   ========================================================================== */

.start-panel {
  max-width: 560px;
  margin-inline: auto;
  padding: var(--space-10);
  border: var(--border-1);
  border-radius: var(--radius-panel);
  background: var(--grad-card);
  text-align: center;
}

.start-lead {
  font: var(--type-lead);
  color: var(--text-body);
}

.start-note {
  margin: var(--space-4) 0 0;
  font: var(--type-legal);
  color: var(--text-legal);
}

.signup-form {
  margin-top: var(--space-6);
  text-align: left;
}

.field {
  margin-bottom: var(--space-5);
}

.field-label {
  display: block;
  margin-bottom: var(--space-2);
  font-weight: 600;
  font-size: 14px;
  color: var(--jim-text-2);
}

.field input {
  width: 100%;
  height: var(--space-11);
  padding: 0 var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--jim-ink-900);
  color: var(--text-heading);
  font: var(--type-body);
}

.field input::placeholder {
  color: var(--jim-text-6);
}

.field input:focus {
  border-color: var(--accent);
  outline: none;
}

/* The consent checkbox. Ships unchecked and unstyled-by-default on purpose —
   no `appearance: none` trickery that could visually imply a tick that the
   input does not actually carry (D-050, D-057). */
.consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font: var(--type-body-sm);
  color: var(--text-body);
}

.consent input {
  flex: none;
  margin-top: 4px;
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
}

/* Two bare anchors with no separator in the markup, so the gap is the only
   thing keeping them from reading as one link. */
.legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: var(--space-4) 0 var(--space-6);
  font: var(--type-legal);
  color: var(--text-legal);
}

.result {
  margin-top: var(--space-4);
  font: var(--type-body-sm);
  text-align: center;
}

.result:empty {
  margin: 0;
}

.form-note {
  margin: var(--space-4) 0 0;
  font: var(--type-legal);
  color: var(--text-legal);
  text-align: center;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding: var(--space-18) var(--page-gutter) var(--space-10);
  border-top: var(--border-1);
  background: var(--surface-footer);
}

.footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-10);
  max-width: var(--page-max);
  margin-inline: auto;
  padding-bottom: var(--space-10);
}

.footer-brand .brand {
  margin-bottom: var(--space-4);
}

.footer-tagline {
  max-width: 34ch;
  font: var(--type-body-sm);
  color: var(--text-muted);
}

.footer-col {
  display: grid;
  gap: var(--space-3);
  align-content: start;
  font-size: 15px;
}

.footer-col a {
  color: var(--text-body);
}

.footer-col a:hover {
  color: var(--text-heading);
}

.footer-legal {
  border-top: var(--border-1);
  padding-top: var(--space-8);
}

.footer-legal-inner,
.footer-copy {
  max-width: var(--page-max);
  margin-inline: auto;
  font: var(--type-legal);
  color: var(--text-legal);
}

.footer-copy {
  margin-top: var(--space-4);
}

.footer-doc {
  padding: var(--space-10) var(--page-gutter);
  border-top: var(--border-1);
  background: var(--surface-footer);
}

/* ==========================================================================
   Legal documents (privacy, terms)
   ========================================================================== */

.doc {
  max-width: var(--prose-max);
  margin-inline: auto;
  padding: var(--space-18) var(--page-gutter) var(--space-24);
}

.doc-eyebrow {
  margin: 0 0 var(--space-3);
  font: var(--type-eyebrow);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  color: var(--accent);
}

/* Carries the gap between the title block and the first section — there is no
   wrapper around the header to hang it on. */
.doc-meta {
  margin: var(--space-3) 0 var(--space-10);
  font: var(--type-body-sm);
  color: var(--text-muted);
}

/* Deliberately plainer and higher-contrast than the marketing page. A carrier
   reviewer skim-reads these for specific sentences; body copy here is
   --jim-text-2 rather than --jim-text-3 for that reason. */
.doc-sections {
  color: var(--jim-text-2);
}

.doc-sections section {
  margin-bottom: var(--space-14);
}

.doc-sections h2 {
  font: var(--type-h3);
  letter-spacing: -0.02em;
  margin-bottom: var(--space-4);
  text-align: left;
}

.doc-sections h3 {
  font: var(--type-h4);
  margin: var(--space-8) 0 var(--space-3);
}

.doc-sections ul,
.doc-sections ol {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-6);
}

.doc-sections li {
  margin-bottom: var(--space-2);
}

.callout {
  padding: var(--space-6);
  border: 1px solid var(--jim-lime-26);
  border-radius: var(--radius-card);
  background: var(--jim-lime-16);
}

.callout h2,
.callout h3 {
  margin-top: 0;
}

.address {
  font: var(--type-body-sm);
  font-style: normal;
  color: var(--jim-text-2);
}

.arrow-list {
  list-style: none;
  padding-left: 0 !important;
}

.arrow-list li {
  position: relative;
  padding-left: var(--space-6);
}

.arrow-list li::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--accent);
}

.chip-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-4) 0;
}

.chip {
  padding: 6px var(--space-3);
  border: var(--border-1);
  border-radius: var(--radius-pill);
  background: var(--jim-ink-600);
  font: var(--type-data);
  color: var(--jim-text-2);
}

/* ==========================================================================
   Motion
   ========================================================================== */

@keyframes jimReveal {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes jimFaqOpen {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes jimFaqClose {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@keyframes jimCaret {
  to {
    opacity: 0;
  }
}

@keyframes jimTrend {
  to {
    stroke-dashoffset: 0;
  }
}

/* site.js also bails out entirely when this matches, so nothing here is
   fighting a script that still wants to animate. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1080px) {
  :root {
    --type-hero: 800 54px/1 var(--font-sans);
    --type-h2: 800 34px/1.08 var(--font-sans);
    --section-pad-y: var(--space-18);
    --page-gutter: var(--space-6);
  }

  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-14);
    text-align: left;
  }

  .hero-copy {
    max-width: none;
  }

  .lift-log {
    position: static;
    margin-top: var(--space-6);
  }
}

@media (max-width: 720px) {
  :root {
    --type-hero: 800 40px/1.03 var(--font-sans);
    --type-h2: 800 28px/1.1 var(--font-sans);
  }

  /* The four section links go; the brand and the CTA stay, because texting
     the number is the whole call to action. */
  .site-nav {
    display: none;
  }

  .phone {
    width: 300px;
    height: 620px;
  }

  .start-panel,
  .card,
  .step-panel {
    padding: var(--space-6);
  }

  .footer-top {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }
}
