/* The neetree.app apex site — the promo one-pager and the privacy policy. Its
   own stylesheet, deliberately hand-written: this site never builds, so it
   carries no Tailwind, no bundler, no dependency on the app's dist/. The
   palette is copied from src/index.css (dark :root, .light swap) so the two
   surfaces look like the same product; it is a copy, not an import, and
   drifting a shade is fine. Dark is the default and prefers-color-scheme flips
   it, matching the app's own default. The hero panel is the one exception: it
   stays night in both themes — it is the app's own opening frame, and the
   Night Bloom mark is drawn for the dark. Base rules below are shared with
   privacy.html; the promo-only classes are appended at the end. */

/* --ink-4 drifts a shade lighter than the app's (#737373 / #8f887d): at this
   site's small sizes those failed WCAG AA on both surfaces (4.18:1 dark,
   3.31:1 light). These pass on the page and the cards in both schemes. */
:root {
  --surface: #0a0a0a;
  --surface-2: #171717;
  --line: #36363a;
  /* The one interactive field on the page (the guide form's inputs) earns a
     stronger boundary than the decorative hairline: ≥3:1 against the input
     fill in both schemes (3.40:1 here, 3.51:1 light — computed, WCAG 1.4.11).
     Everything non-interactive keeps --line. */
  --input-line: #6b6b74;
  --ink: #f5f5f5;
  --ink-2: #d4d4d4;
  --ink-3: #a3a3a3;
  --ink-4: #868686;
  --accent: #bcb0e8;
}

@media (prefers-color-scheme: light) {
  :root {
    --surface: #faf8f4;
    --surface-2: #ffffff;
    --line: #d6cec1;
    --input-line: #8f887c;
    --ink: #1c1a17;
    --ink-2: #3f3b35;
    --ink-3: #6b655c;
    --ink-4: #787265;
    --accent: #5b4f8a;
  }
}

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

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

body {
  margin: 0;
  padding: 0 1.5rem 6rem;
  background: var(--surface);
  color: var(--ink-2);
  font-family:
    ui-sans-serif,
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    Roboto,
    'Helvetica Neue',
    Arial,
    sans-serif;
  font-size: 1rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 38rem;
  margin: 0 auto;
}

/* The mark, small and quiet — the same crown crop the app icon uses. */
.mark {
  display: block;
  width: 3.25rem;
  height: 3.25rem;
  margin: 4rem auto 0;
  border-radius: 0.9rem;
}

h1,
h2 {
  font-family: ui-serif, 'New York', Georgia, 'Times New Roman', serif;
  color: var(--ink);
  font-weight: 400;
  letter-spacing: -0.01em;
}

h1 {
  margin: 2rem 0 0.25rem;
  font-size: 1.9rem;
  line-height: 1.25;
  text-align: center;
  /* No orphaned last word on the page's most important line ("…quest a / day."). */
  text-wrap: balance;
}

h2 {
  margin: 2.75rem 0 0.75rem;
  font-size: 1.2rem;
  line-height: 1.4;
}

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

ul {
  margin: 0 0 1rem;
  padding-left: 1.15rem;
}

li {
  margin-bottom: 0.5rem;
}

a {
  color: var(--accent);
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-color: currentColor;
}

.lede {
  margin-top: 1.75rem;
  color: var(--ink-3);
  text-align: center;
}

.updated {
  margin: 0 0 2.5rem;
  color: var(--ink-4);
  font-size: 0.85rem;
  text-align: center;
}

.note {
  margin: 2.5rem 0 0;
  padding: 1.15rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: 1rem;
  background: var(--surface-2);
  color: var(--ink-3);
  font-size: 0.95rem;
}

.note p:last-child {
  margin-bottom: 0;
}

footer {
  margin-top: 4rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  color: var(--ink-4);
  font-size: 0.85rem;
  text-align: center;
}

footer a {
  color: var(--ink-3);
}

/* ---- Promo one-pager (index.html only) ------------------------------- */

/* The launch flips work by deleting `hidden` attributes; make sure no
   display rule below can accidentally override one that's still there. */
[hidden] {
  display: none !important;
}

/* The hero: a night panel in both themes — fixed dark hexes, not tokens,
   because the Night Bloom mark and its cream blossoms are drawn for the dark.
   In dark mode it melts into the page; on cream it reads as a window into
   the app. */
.hero {
  margin-top: 2.5rem;
  padding: 2.75rem 1.5rem 2.25rem;
  background: #0a0a0a;
  border: 1px solid #26262a;
  border-radius: 1.25rem;
  text-align: center;
}

.tree {
  display: block;
  margin: 0 auto;
}

/* The mark breathes the way the app's splash does, slowed to ambience. */
.t-glow,
.t-bloom {
  transform-box: fill-box;
  transform-origin: center;
}

.t-glow {
  animation: tree-glow 6s ease-in-out infinite alternate;
}

.t-bloom {
  animation: tree-bloom 6s ease-in-out infinite alternate;
}

@keyframes tree-glow {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.14);
  }
}

@keyframes tree-bloom {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.04);
  }
}

.brand {
  margin: 1rem 0 0;
  font-family: ui-serif, 'New York', Georgia, 'Times New Roman', serif;
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  color: #d4d4d4;
}

.hero h1 {
  margin: 1.1rem 0 0;
  font-size: clamp(2rem, 7vw, 2.5rem);
  color: #f5f5f5;
}

.hero .lede {
  margin: 0.9rem auto 0;
  max-width: 26rem;
  color: #a3a3a3;
}

.cta {
  margin-top: 1.9rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.9rem;
}

.btn {
  display: inline-block;
  padding: 0.7rem 1.5rem;
  background: #bcb0e8;
  color: #0a0a0a;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0.75rem;
}

.btn:hover {
  background: #cdc3f0;
}

/* The ring follows the surface, not the button. The cream hex below was picked
   for the hero panel, which is fixed night in both themes — but the closing CTA
   reuses .btn on the page background, where cream-on-cream is 1.09:1 in light
   mode and a keyboard user tabbing to the page's last call to action sees
   nothing at all. Ink is legible on both grounds; the hero rule wins on
   specificity and keeps its cream, as does the LAUNCH badge inside it. */
.btn:focus-visible,
.store:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* The badge left the hero on 2026-08-10 (it follows the subscribe CTA on the
   cream page now, on both pages), so like .btn it defaults to the ink ring
   above and earns the cream one only back on the night panel. */
.hero .btn:focus-visible,
.hero .store:focus-visible {
  outline: 2px solid #f7eed6;
  outline-offset: 3px;
}

.store {
  display: inline-block;
  line-height: 0;
}

/* The one sentence answering "is this free / do I have to install anything" —
   it earns the lede's ink, not the faintest on the panel. */
.cta-note {
  margin: 0.9rem 0 0;
  font-size: 0.9rem;
  color: #a3a3a3;
}

/* Sections: hairline-divided, generous air, h2 pulled to the divider. */
.section {
  margin-top: 3rem;
  padding-top: 2.25rem;
  border-top: 1px solid var(--line);
}

.section h2 {
  margin: 0 0 0.85rem;
  font-size: 1.35rem;
}

/* The real app, dark theme: two night windows on the cream page — the same
   move as the hero panel, so the page keeps one visual idea. Fixed dark
   border hexes for the same reason the hero's are fixed. */
.shots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  max-width: 26rem;
  margin: 1.75rem auto 0.5rem;
}

.shots img {
  width: 100%;
  height: auto;
  background: #0a0a0a;
  border: 1px solid #26262a;
  border-radius: 1.1rem;
}

/* The four areas, each wearing its own color — the app's palette. (A list,
   not a paragraph of spans — screen readers announce four items. The class
   overrides the shared ul base rules privacy.html depends on.) */
.areas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.65rem 1.35rem;
  margin: 1.35rem 0 0;
  padding-left: 0;
  list-style: none;
  color: var(--ink-3);
  font-size: 0.95rem;
}

.area {
  margin-bottom: 0;
}

.area .dot {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-right: 0.45rem;
  border-radius: 50%;
  background: var(--c);
  vertical-align: 0.02em;
}

.sig {
  margin-top: 1.15rem;
  color: var(--ink-3);
}

/* The two demos: the .shots grid again — two more night windows — but each
   frame is a <button> holding a poster-first <video>. The clips are silent
   and control-bar-free (see the script at the end of index.html); the glyph
   is the whole affordance, so it earns real contrast on the dark poster. */
.demos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  max-width: 26rem;
  margin: 1.75rem auto 0.5rem;
}

.demo-shell {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  background: #0a0a0a;
  border: 1px solid #26262a;
  border-radius: 1.1rem;
  overflow: hidden;
  cursor: pointer;
}

.demo-shell video {
  display: block;
  width: 100%;
  height: auto;
}

/* On the page ground like the closing .btn, so the ring is ink, not cream. */
.demo-shell:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.demo-glyph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #f5f5f5;
  opacity: 1;
  transition: opacity 200ms ease;
}

.demo-glyph svg {
  box-sizing: content-box;
  padding: 0.8rem;
  background: rgba(10, 10, 10, 0.55);
  border: 1px solid rgba(245, 245, 245, 0.35);
  border-radius: 50%;
}

.demo.playing .demo-glyph {
  opacity: 0;
}

.demo-cap,
.meals-cap {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-4);
  text-align: center;
}

.meals-cap {
  margin-bottom: 1rem;
}

/* Three meal cards in a row; they stay a row on narrow screens — three small
   squares read better than three full-width photos mid-essay. */
.meals {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}

.meals img {
  width: 100%;
  height: auto;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

/* Pricing: two quiet cards; annual carries the accent hairline (it is the
   highlighted plan in the app's own Premium section too). */
.plans {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}

.plan {
  padding: 1rem 1.15rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.plan-hl {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line));
}

.plan strong {
  display: block;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
}

.plan span {
  font-size: 0.85rem;
  color: var(--ink-4);
}

.plans-note {
  margin: 0.85rem 0 1.35rem;
  font-size: 0.9rem;
  color: var(--ink-3);
}

/* The free guide: cover beside the pitch; stacks on narrow screens. */
.guide-row {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 1.5rem;
  align-items: start;
}

.guide-cover {
  width: 100%;
  height: auto;
  aspect-ratio: 495 / 640;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.6rem;
}

/* min-height ≈ the rendered Flodesk form, so the async injection doesn't
   shove the footer down when it lands (CLS). Two values because the form's
   height genuinely differs: fields sit side by side at desktop with the
   button wrapped to its own row (~6.9rem rendered, reserve 7.5rem) and
   stack on narrow screens (~10.4rem rendered, reserve 11.5rem — set in the
   media query below). Re-measure if the form's fields change. */
.guide-form {
  margin-top: 1.25rem;
  min-height: 7.5rem;
}

/* The Flodesk inline form, dressed as this page. Its own theme is a cream
   card with its own fonts — fine in an email popup, wrong inside the essay
   column and badly wrong on the dark scheme. The classes are stable (they
   carry the form id). !important outbids the styles its script injects.
   The title + subtitle repeat the section's own pitch, so Tristan's
   paragraph stays the only voice (his call, 2026-08-01). */
#guide .ff-6a6d1fb155f6faeb198b38c4__title,
#guide .ff-6a6d1fb155f6faeb198b38c4__subtitle {
  display: none !important;
}

#guide .ff-6a6d1fb155f6faeb198b38c4,
#guide .ff-6a6d1fb155f6faeb198b38c4__container {
  background: transparent !important;
}

#guide .ff-6a6d1fb155f6faeb198b38c4__form,
#guide .ff-6a6d1fb155f6faeb198b38c4__footer {
  padding: 0 !important;
  text-align: left !important;
  font-family: inherit !important;
  color: var(--ink-2) !important;
}

/* Its content row is a centered flex-wrap, so the button wraps to its own
   centered line; start-aligned it hugs the essay column like everything else. */
#guide .ff-6a6d1fb155f6faeb198b38c4__content {
  justify-content: flex-start !important;
}

#guide .fd-form-control {
  background: var(--surface-2) !important;
  border: 1px solid var(--input-line) !important;
  border-radius: 0.6rem !important;
  color: var(--ink) !important;
  font-family: inherit !important;
}

#guide .fd-form-label {
  color: var(--ink-3) !important;
  font-family: inherit !important;
}

/* One button look everywhere: the hero's fixed hexes work on both schemes. */
#guide .fd-btn {
  background: #bcb0e8 !important;
  color: #0a0a0a !important;
  border: 0 !important;
  border-radius: 0.75rem !important;
  padding: 0.7rem 1.5rem !important;
  font-family: inherit !important;
  font-weight: 600 !important;
}

#guide .fd-btn:hover {
  background: #cdc3f0 !important;
}

#guide .fd-btn:focus-visible {
  outline: 2px solid var(--ink) !important;
  outline-offset: 3px !important;
}

/* One quiet way back into the app at the end of the page. */
.closing {
  margin: 3.5rem 0 0;
  text-align: center;
}

@media (max-width: 34rem) {
  .guide-row {
    grid-template-columns: 1fr;
  }

  .guide-cover {
    max-width: 8.5rem;
  }

  /* The form's fields stack at this width — reserve their real height. */
  .guide-form {
    min-height: 11.5rem;
  }
}

/* Below phablet width the annual card's sub-line wraps to three loose lines
   while the grid stretches the monthly card to match — stacked, each card
   fits its own text. */
@media (max-width: 24rem) {
  .plans {
    grid-template-columns: 1fr;
  }
}

/* The workout-split strip: the free program's week, the app's own answer to
   "what split do you recommend?". Day letters over dots; filled days wear
   Body's green (#7F9C82), the area color the app's strip echoes. Pinned to
   the catalog by src/app/__tests__/siteWeekStrip.test.ts. */
.week {
  margin: 1.5rem 0 0.25rem;
  padding: 1rem 1.15rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.week h3 {
  margin: 0 0 0.75rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
}

.week-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.25rem;
  max-width: 17rem;
}

.wd {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--ink-4);
}

.wd::after {
  content: '';
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  border: 1px solid var(--line);
}

.wd.on::after {
  background: #7f9c82;
  border-color: #7f9c82;
}

.week-note {
  margin: 0.85rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-3);
}

/* Two strips share the card; a hairline keeps them one thought, not two cards. */
.week-strip + .week-strip {
  margin-top: 1.15rem;
  padding-top: 1.15rem;
  border-top: 1px solid var(--line);
}

/* ---- Start page (start.html — the link-in-bio hub) -------------------- */

/* No night panel here: the hero is the app's opening frame, and this page is
   Tristan's, not the app's — a plain centered header on the page ground keeps
   the two surfaces distinct while the tokens keep them family. */
.me {
  margin-top: 3.5rem;
  text-align: center;
}

/* The same crop the Instagram profile wears — profile → page, same person. */
.avatar {
  width: 5.5rem;
  height: 5.5rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  object-fit: cover;
}

.me h1 {
  margin: 1rem 0 0;
  font-size: 1.6rem;
}

.me .lede {
  margin: 0.75rem auto 0;
  max-width: 28rem;
}

/* The links: whole-card anchors — an IG in-app-browser visitor gets a tap
   target the size of the thought, not a text link. The anchor overrides the
   page's accent/underline link dressing; the hover borrows .plan-hl's accent
   hairline so the affordance is the site's own. */
.cards {
  display: grid;
  gap: 0.75rem;
  margin-top: 2.25rem;
}

.card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.95rem;
  align-items: center;
  padding: 0.85rem 1.15rem 0.85rem 0.85rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  color: var(--ink-2);
  text-decoration: none;
}

.card:hover {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line));
}

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

/* The squares are decorative (alt="") — the text is the card. width/height
   attributes + fixed size here mean zero layout shift while they lazy-load;
   the surface ground shows until they land. */
.card-thumb {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 0.5rem;
  object-fit: cover;
  background: var(--surface);
}

.card strong {
  display: block;
  font-weight: 600;
  color: var(--ink);
}

.card-body > span {
  display: block;
  font-size: 0.9rem;
  color: var(--ink-3);
}
