/* ───────────────────────────────────────────────────────────────
   Noos Notes — public landing/marketing styles.

   V4 Task 2 (RT-02, PC-05, PC-06). PORTED from the reference
   implementation at `/Users/abc/Desktop/nsr/projects/noos-letters/landing/
   landing.css` (read-only reference; never modified) — same tokens,
   fonts, and green ("Kitchen Garden": `--green`/`--bg` below are the
   SAME literal hex values `vite.config.ts`'s own `THEME_COLOR`/
   `BACKGROUND_COLOR` constants use for the PWA manifest, verified by
   direct comparison).

   V4 Task 3 (RT-07) added the `.insert`/`.caret` proofreader markup, the
   `gapOpen`/`caretIn`/`wordWrite`/`writeIn`/`rise` keyframes, `.turn`/
   `.turn-late`, and the `.editor-host`/`.surface-stub` pre-mount compose
   stand-in — ported VERBATIM from the reference's own landing.css:105-213
   (GC-1: "port verbatim, do not retune") — see each section's own
   comment below for the exact source lines and any documented
   adaptation. Task 4 still owns: the real editor mount that swaps
   `.surface-stub` out, the title field, the Save/Mail/Schedule actions,
   and the schedule drawer. Nothing below is a control that does nothing
   (PC-06: "no dormant controls") — the stub caret is a static visual,
   not an interactive element.

   Shared by every public page (index/privacy/terms/blog/*) — each
   page links this one stylesheet directly (`../landing.css` for pages
   one directory down, e.g. blog/*).
   ─────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;
  --bg: #f2f5ec;
  --surface: #ffffff;
  --ink: #23281f;
  --subtle: #6f7a66;
  --line: rgb(35 40 31 / 0.12);
  --green: #3f8a4f;
  --green-deep: #2f6b3c;
  --green-tint: #e4f0e2;
  --radius: 0.5rem;
  --radius-lg: 0.9rem;
  --shadow-card: 0 1px 2px rgb(28 27 23 / 0.04), 0 12px 32px -16px rgb(28 27 23 / 0.16);
  --shadow-lift: 0 2px 6px rgb(28 27 23 / 0.05), 0 28px 60px -28px rgb(28 27 23 / 0.22);
  --font-display: "Gabarito", "Avenir Next", sans-serif;
  --font-body: "Figtree", system-ui, sans-serif;
  --font-hand: "Shantell Sans", cursive;
  --maxw: 40rem;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* V4 Task 3 (RT-07) — writing geometry, ported verbatim from the
     reference's own landing.css:34-37 ("mirrors the app's src/theme/
     writing.ts"). Used by .editor-host/.surface-stub below so the static
     stand-in's metrics match the real CodeMirror editor Task 4 mounts. */
  --measure: 68ch;
  --write-size: 18px;
  --write-leading: 1.7;
  --editor-h: 13rem;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* PC-05: phone screens must keep text legible, wrapped, vertically
   scrollable, and free of clipping or page-level horizontal scrolling.
   Every layout width below already uses clamp()/ch/%/max-width (never a
   bare fixed px that could exceed a narrow viewport) — this is a belt-
   and-suspenders backstop, not a mask for an actual overflowing element
   (test/tier3/publicPages.test.ts asserts the real, unclipped measurement
   too: documentElement.scrollWidth <= window.innerWidth). */
body {
  margin: 0;
  min-height: 100dvh;
  max-width: 100%;
  overflow-x: hidden;
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

@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;
  }
}

/* ── Header (shared by every public page) ───────────────────── */
.nav {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 0.5rem;
  padding: 0.9rem clamp(1.25rem, 4vw, 2.5rem);
  background: var(--bg);
}
.brand {
  font-family: var(--font-display);
  font-weight: 600; font-size: 1.125rem;
  letter-spacing: -0.01em; color: var(--green);
  text-decoration: none;
}
.nav-links { display: flex; align-items: center; gap: clamp(0.75rem, 3vw, 1.75rem); flex-wrap: wrap; }
.nav-link {
  font-family: var(--font-display);
  font-size: 0.9rem; color: var(--subtle); text-decoration: none;
  transition: color 0.2s var(--ease);
}
.nav-link:hover { color: var(--ink); }

/* ── Layout + type ──────────────────────────────────────────── */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: clamp(1.25rem, 5vw, 2rem); }
.stage { width: 100%; max-width: 46rem; margin-inline: auto; padding-inline: clamp(1.25rem, 5vw, 2rem); }

.hero { text-align: center; padding: clamp(2.75rem, 9vh, 4.75rem) 0 clamp(1.5rem, 4vh, 2.5rem); }
h1.hero-title {
  font-family: var(--font-display);
  font-weight: 600; letter-spacing: -0.022em; line-height: 1.12;
  font-size: clamp(2.1rem, 6vw, 3.4rem);
  text-wrap: balance;
  margin: 0;
}
.lede {
  color: var(--subtle); font-size: clamp(1rem, 2vw, 1.12rem); line-height: 1.6;
  max-width: 34ch; margin: 0.9rem auto 0; text-wrap: pretty;
}

/* ── The insertion mark (V4 Task 3, RT-07) ──────────────────────
   PORTED VERBATIM from the reference's landing.css:104-125. A
   proofreader's insertion: the caret sits in the gap BETWEEN two words
   and holds its own horizontal space; the inserted word is written
   above the line. Both children are absolute so the caret can centre
   under the word while .insert itself only holds the gap open. */
.insert {
  display: inline-block; position: relative;
  width: 0.78em; margin-inline: 0.06em;
  vertical-align: baseline;
}
.insert .ins-word {
  position: absolute; bottom: 1.02em; left: 58%;
  transform: translateX(-50%) rotate(-4deg);
  font-family: var(--font-hand); font-weight: 600; color: var(--green);
  font-size: 0.36em; white-space: nowrap; line-height: 1;
}
.insert .caret {
  position: absolute; left: 50%; bottom: 0.04em;
  transform: translateX(-50%);
  font-family: var(--font-hand); font-weight: 700; color: var(--green);
  font-size: 0.54em; line-height: 1;
}

/* The reveal (V4 Task 3, RT-07): the caret arrives first and opens the
   gap, then the word is written in left to right. Same stroke the
   margin notes use, so the page has one hand throughout. Keyframes and
   the APPROVED timings below are ported byte-for-byte from the
   reference's landing.css:127-150 — do not retune (GC-1). */
@keyframes gapOpen { to { width: 0.78em; margin-inline: 0.06em; } }
@keyframes caretIn {
  from { opacity: 0; transform: translateX(-50%) translateY(0.22em) scale(0.7); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes wordWrite { to { opacity: 1; } }
@keyframes writeIn {
  from { clip-path: inset(0 100% -25% 0); }
  to   { clip-path: inset(0 -12% -25% 0); }
}
@keyframes rise { to { opacity: 1; transform: none; } }

/* This whole block only applies under prefers-reduced-motion:
   no-preference (verbatim from the reference) — under reduce, NONE of
   these rules match, so .insert/.lede/.turn-late never receive their
   own `opacity: 0`, and everything renders at its normal, final
   opacity from first paint. That IS the ported "reduced motion shows
   everything immediately" behavior (landing.css:139 in the reference)
   — no separate reduced-motion override is needed or written; the
   absence of a match is the mechanism. */
@media (prefers-reduced-motion: no-preference) {
  .turn .insert { width: 0; margin-inline: 0; animation: gapOpen .34s var(--ease) .95s forwards; }
  .turn .insert .caret { opacity: 0; animation: caretIn .3s var(--ease) 1.15s forwards; }
  .turn .insert .ins-word {
    opacity: 0;
    animation: wordWrite .01s linear 1.42s forwards, writeIn .52s var(--ease) 1.42s forwards;
  }
  .turn .lede { opacity: 0; animation: rise .55s var(--ease) 2s forwards; }
  .turn-late { opacity: 0; animation: rise .55s var(--ease) 2.25s forwards; }
}

/* ── The writing-surface slot (V4 Task 3 ships the metric-matched
   pre-mount stand-in — .editor-host/.surface-stub below — Task 4 mounts
   the real title field, CodeMirror editor, and Save/Mail/Schedule
   actions inside this SAME card; kept the `.compose-slot` class name
   test/tier1/productCopyScan.test.ts's own PC-06 case already pins, so
   this is the same slot carrying real (if static) content now, not a
   renamed second element). Card geometry ported verbatim from the
   reference's own `.compose` rule, landing.css:154-163. ──────────── */
/* V4 Task 4: the two renditions' own kicker/hint copy, toggled by
   `landing-composer.js` setting `hidden` per `.rendition-writing`/
   `.rendition-letter` (the exact-match `?intent=letter` allowlist,
   RT-02) — real copy shipped in index.html either way, never invented
   at runtime; `[hidden]` is the platform default (display: none), so no
   extra selector is needed to hide the inactive rendition's text. */
.compose-kicker {
  font-family: var(--font-hand); color: var(--green); font-size: 1rem;
  margin: 0 0 0.6rem; text-align: left; max-width: var(--maxw); margin-inline: auto;
}
.compose-hint {
  font-size: 0.9rem; color: var(--subtle); margin: 0.9rem 0 0; text-align: left;
  max-width: var(--maxw); margin-inline: auto;
}
.schedule-letter-link {
  font-family: var(--font-display); font-weight: 600; color: var(--green);
  text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
.schedule-letter-link:hover { border-bottom-color: var(--green); }

.compose-slot {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 1.5rem clamp(1.25rem, 3vw, 1.9rem);
  text-align: left;
  transition: box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.compose-slot:focus-within { box-shadow: var(--shadow-lift); border-color: rgb(63 138 79 / 0.4); }

/* Host for the real CodeMirror editor Task 4 mounts here, built from
   the journalling app. Ported verbatim from the reference's
   landing.css:174-191 (the comment below is the reference's own): the
   editor hangs block markers (#, >, -) into the left margin by a
   negative text-indent; without room to the left of the text the card
   clips them and the page misrepresents the editor's own typography. */
.editor-host { position: relative; min-height: var(--editor-h); margin-inline: -1.2rem; }
.editor-host .cm-editor { outline: none; }
.editor-host .cm-editor.cm-focused { outline: none; }
.editor-host .cm-scroller {
  font-family: var(--font-body);
  font-size: var(--write-size);
  line-height: var(--write-leading);
}
.editor-host .cm-content { padding: 0 1.2rem; max-width: var(--measure); caret-color: var(--green); }
.editor-host .cm-line { padding: 0; }
.editor-host .cm-cursor { border-left-color: var(--green); border-left-width: 2px; }
.editor-host .cm-selectionBackground,
.editor-host .cm-focused .cm-selectionBackground { background: var(--green-tint) !important; }
.editor-host .cm-placeholder { color: var(--subtle); opacity: 0.5; }

/* Static stand-in shown until the editor mounts on intent (Task 4). Its
   metrics match the editor's exactly, so the swap is invisible. Ported
   verbatim from the reference's landing.css:193-213. */
.surface-stub {
  position: absolute; inset: 0 1.2rem;
  font-family: var(--font-body);
  font-size: var(--write-size);
  line-height: var(--write-leading);
  color: var(--subtle);
  cursor: text;
}
.surface-stub .stub-text { opacity: 0.5; }
.surface-stub .stub-caret {
  display: inline-block; width: 2px; height: calc(var(--write-size) * 1.1);
  background: var(--green); vertical-align: text-bottom; margin-right: 1px;
  animation: blink 1.06s steps(1) infinite;
}
@keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.surface-stub.gone { display: none; }
/* One caret at a time: the drawn stand-in caret stands down the moment
   anything real in the surface takes focus. Dead-until-Task-4 today (no
   focusable element exists inside .compose-slot yet — see index.html's
   own comment), ready for Task 4 to activate by construction rather
   than needing a second selector written later. */
.compose-slot:focus-within .stub-caret { opacity: 0; animation: none; }

/* ── Margin notes (V4 Task 3: landing.js's initReveal() targets a
   `.reveal` class here — verified against the reference's own real
   markup that NO element there carries `class="reveal"` either
   (landing.js:154's querySelectorAll(".reveal") is genuine, working,
   ported code that is currently a no-op on this exact page, same
   measured state the reference itself ships — see landing.js's own
   doc comment). This static margin-notes row stays exactly that:
   static, no reveal class applied, matching the reference verbatim). */
.scribble-row {
  display: flex; flex-wrap: wrap; gap: 0.3rem 1.5rem; justify-content: center;
  margin-top: 1.75rem;
  font-family: var(--font-hand); color: var(--green); font-size: 0.88rem; line-height: 1.4;
}

/* ── Footer ─────────────────────────────────────────────────── */
.footer { border-top: 1px solid var(--line); margin-top: clamp(2.5rem, 7vh, 4rem); }
.footer-inner {
  max-width: var(--maxw); margin-inline: auto;
  padding: clamp(2.25rem, 6vh, 3.25rem) clamp(1.25rem, 5vw, 2rem) clamp(2rem, 5vh, 3rem);
  text-align: center;
}
.aphorism {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.15rem, 2.8vw, 1.5rem); letter-spacing: -0.015em;
  margin: 0 0 1.1rem; color: var(--ink);
}
.foot-end {
  display: flex; align-items: center; justify-content: center;
  gap: 0.9rem; flex-wrap: wrap; margin: 0 0 1.75rem;
}
.foot-end p { margin: 0; color: var(--subtle); font-size: 0.92rem; }
.foot-link {
  font-family: var(--font-display); font-size: 0.95rem; font-weight: 600; color: var(--green);
  text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
.foot-link:hover { border-bottom-color: var(--green); }
.social { display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap; margin-bottom: 1rem; }
.social a { color: var(--subtle); text-decoration: none; font-size: 0.9rem; transition: color 0.2s var(--ease); }
.social a:hover { color: var(--green); }
.footnote { font-size: 0.84rem; color: var(--subtle); margin: 0; opacity: 0.85; }
.footnote a { color: var(--green); text-decoration: none; border-bottom: 1px solid transparent; }
.footnote a:hover { border-bottom-color: var(--green); }
.foot-heart { font-size: 1.1rem; margin: 1rem 0 0; line-height: 1; }

/* ── Prose article pages (privacy / terms / blog posts) ────────
   Own max-width so a long line never wraps at an uncomfortable
   measure, but stays inside `--maxw`-scale sizing so it agrees with
   the rest of the page at every viewport — including a 390px phone
   width (PC-05), where clamp() collapses padding/margins toward the
   small end rather than clipping. */
.article { max-width: 40rem; margin-inline: auto; padding: clamp(2.5rem, 8vh, 5rem) clamp(1.25rem, 5vw, 2rem) 3rem; }
.article h1 {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -0.02em; line-height: 1.15;
  font-size: clamp(1.8rem, 5vw, 2.6rem); margin: 0 0 0.5rem;
}
.article h2 {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -0.01em; line-height: 1.2;
  font-size: clamp(1.2rem, 3vw, 1.5rem); margin: 2rem 0 0.6rem;
}
.byline { font-family: var(--font-hand); color: var(--green); font-size: 1rem; margin: 0 0 2.25rem; }
.byline a { color: var(--green); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--green) 45%, transparent); }
.byline a:hover { border-bottom-color: var(--green); }
.updated { color: var(--subtle); font-size: 0.9rem; margin: 0 0 2.25rem; }
.prose p { font-size: 1.05rem; line-height: 1.75; color: var(--ink); margin: 0 0 1.2rem; overflow-wrap: break-word; }
.prose p.dim { color: var(--subtle); }
.prose a { color: var(--green); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--green) 45%, transparent); overflow-wrap: break-word; }
.prose a:hover { border-bottom-color: var(--green); }
.prose ul, .prose ol { margin: 0 0 1.2rem; padding-left: 1.3rem; }
.prose ul li, .prose ol li { font-size: 1.05rem; line-height: 1.75; color: var(--ink); margin-bottom: 0.5rem; }
.prose ul li::marker, .prose ol li::marker { color: var(--green); }
.tldr {
  background: color-mix(in srgb, var(--green-tint) 45%, var(--surface));
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.1rem 1.3rem; margin: 0 0 1.75rem;
}
.tldr p { margin: 0; }
.signoff-hand { font-family: var(--font-hand); color: var(--green); font-size: 1.3rem; margin: 2rem 0 0; }
.signoff-hand a { color: var(--green); border-bottom: 1px solid color-mix(in srgb, var(--green) 45%, transparent); text-decoration: none; }
.back { display: inline-block; margin-top: 2rem; font-family: var(--font-display); color: var(--subtle); text-decoration: none; }
.back:hover { color: var(--green); }

/* Blog index list */
.postlist { list-style: none; margin: 0; padding: 0; }
.postlist li { margin: 0 0 1.5rem; }
.postlist a {
  font-family: var(--font-display); font-weight: 600; font-size: 1.1rem;
  color: var(--ink); text-decoration: none;
}
.postlist a:hover { color: var(--green); }

/* V4 Task 5 (RT-08/RT-09), Fix Round 1 (review Important 1): the landing
   editor's own status/reclaim affordance — a small, non-blocking corner
   badge (NOT a full-box overlay — see Fix Round 1's own reasoning: this
   now shows on EVERY landing engagement, for the ~150ms acquisition
   window alone, mirroring App.tsx's own SHELL-16 "Opening…" cue that
   shows unconditionally on every /app boot/switch too, so it must read as
   routine chrome, not an interruption). Three states, one element,
   toggled entirely by `landing-bundle/composer.ts`'s `wireAuthority`:
   "opening" (neutral, no button — the pre-resolution acquisition window),
   "opening-danger" (a keystroke was genuinely attempted and dropped
   during that window — SHELL-16's own escalation, replicated), "locked"
   (RT-08's "Continue here", genuinely readonly because another tab
   holds the entry). Absolutely positioned over `.editor-host` (already
   `position: relative`) so it never shifts or resizes the editor's own
   box — the CM view stays mounted and visible underneath, nothing modal. */
.jr-landing-readonly {
  position: absolute; top: 0.5rem; right: 0.5rem; z-index: 2;
  display: flex; align-items: center; gap: 0.5rem;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--font-body); font-size: 0.82rem; color: var(--subtle);
  padding: 0.3rem 0.7rem;
  box-shadow: var(--shadow-card);
}
.jr-landing-readonly[hidden] { display: none; }
/* SHELL-16's own "neutral routine state -> danger the instant a keystroke
   is actually attempted and dropped" escalation, reusing this same slot
   rather than inventing new UI — mirrors StatusLine's own
   --jr-danger-toned notice variant in spirit (this file's own token set,
   not that one: landing.css has no --jr-* tokens to reuse). */
.jr-landing-readonly--danger { color: var(--ink); border-color: color-mix(in srgb, #a4453a 55%, var(--line)); }
.jr-landing-continue {
  font-family: var(--font-display); font-weight: 600; color: var(--green);
  background: none; border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
  border-radius: 999px; padding: 0.2rem 0.6rem; cursor: pointer; font-size: 0.8rem;
}
.jr-landing-continue:hover { border-color: var(--green); }

/* FAILURE state (V4 Task 6, GC-4/GC-5): the editor bundle failed to load
   or mount — there is no store to write into, so the (now permanently
   inert) .surface-stub is replaced by this plain-language notice inside
   the SAME .editor-host box (that element's own min-height keeps the
   page from jumping). If anything was typed before the failure, it is
   shown back verbatim as plain, selectable/wrappable text — never
   claimed saved (it wasn't), never silently dropped either. */
.jr-landing-load-failed {
  padding: 1rem 1.2rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.6;
}
.jr-landing-load-failed p { margin: 0 0 0.6rem; }
.jr-landing-load-failed-text {
  white-space: pre-wrap;
  overflow-wrap: break-word;
  background: var(--green-tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.6rem 0.8rem;
  font-family: inherit;
  font-size: inherit;
  color: var(--ink);
  max-width: 100%;
}

.postlist p { margin: 0.3rem 0 0; color: var(--subtle); font-size: 0.95rem; }
