/* First-run onboarding: scroll-driven intro + petal tour.
   The one sanctioned exception to the app's "calm over spectacle" rule —
   motion here is choreographed by GSAP (vendor/gsap/), loaded only when
   onboarding actually runs. Reduced-motion gets the .onb--reduced /
   .onb-tour--reduced variants: same content, same completion, no
   choreography. All colours come from tokens. */

/* ── Intro overlay ─────────────────────────────────────────────── */

.onb {
  position: fixed;
  inset: 0;
  z-index: 260;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: transparent;
}

/* The paper "curtain" the reveal pulls apart. Two leaves so the interface
   underneath appears through a genuine split, not a fade. */
.onb__leaf {
  position: fixed;
  left: 0;
  width: 100%;
  height: 51vh; /* 1vh overlap so no seam shows mid-animation */
  background: var(--paper);
  z-index: 0;
}
.onb__leaf--top { top: 0; }
.onb__leaf--bottom { bottom: 0; }

/* The scroll body; the stage stays sticky inside it. Sticky (not fixed)
   is load-bearing: wheel events over a fixed element scroll-chain to the
   viewport and never reach the .onb scroller, which killed mouse
   scrolling entirely. Only the outline draw is scroll-driven, so the
   body is short; everything after plays on its own clock. */
.onb__body { height: 260vh; }

.onb__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--nv-sp-5);
  z-index: 1;
  padding: var(--edge);
  text-align: center;
}

.onb__hint {
  position: absolute;
  bottom: 7vh;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nv-sp-2);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.onb__hint::after {
  content: '';
  width: 1px;
  height: 56px;
  background: var(--ochre);
}
.onb__hint-chevron {
  width: 10px;
  height: 10px;
  margin-top: -7px;
  border-right: 2px solid var(--ochre-ink);
  border-bottom: 2px solid var(--ochre-ink);
  transform: rotate(45deg);
  animation: nv-hint-nudge 1.6s ease-in-out infinite;
}
@keyframes nv-hint-nudge {
  0%, 100% { transform: rotate(45deg) translate(0, 0); }
  50% { transform: rotate(45deg) translate(5px, 5px); }
}

.onb__mark {
  width: min(228px, 42vw);
  height: auto;
  color: var(--moss);
}

.onb__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  letter-spacing: 0.06em;
  color: var(--ink);
  line-height: 1;
  display: flex;
}
.onb__name span { display: inline-block; }

.onb__line {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.45rem);
  color: var(--ink-soft);
  max-width: 34ch;
}

.onb__nick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nv-sp-3);
}
.onb__nick-label {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--ink-soft);
}
.onb__nick-row {
  display: flex;
  gap: var(--nv-sp-2);
}
.onb__nick-input {
  width: min(280px, 60vw);
  padding: 10px 14px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-md);
  background: var(--nv-white);
  font-family: var(--font-ui);
  font-size: 15px;
  color: var(--ink);
  outline: none;
}
.onb__nick-input:focus-visible {
  border-color: var(--moss);
  box-shadow: 0 0 0 1px var(--moss);
}
.onb__nick-submit {
  padding: 10px 18px;
  border-radius: var(--nv-r-md);
  background: var(--moss);
  color: var(--nv-text-on-accent);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
}
.onb__nick-submit:hover { background: var(--moss-deep); }
.onb__nick-skip,
.onb__skip {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--nv-text-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.onb__nick-skip:hover,
.onb__skip:hover { color: var(--ink-soft); }

.onb__skip {
  position: fixed;
  top: var(--nv-sp-5);
  right: var(--nv-sp-6);
  z-index: 2;
}

.onb__met {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.4rem);
  color: var(--ink-soft);
}
.onb__more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nv-sp-2);
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--nv-text-muted);
}
.onb__more::after {
  content: '';
  width: 1px;
  height: 36px;
  background: var(--rule-strong);
}
/* display:flex above would otherwise defeat the hidden attribute */
.onb__more[hidden],
.onb__met[hidden] { display: none; }

/* Reduced-motion intro: one calm column, button-progressed. */
.onb--reduced {
  overflow-y: auto;
  background: var(--paper);
}
.onb--reduced .onb__leaf { display: none; }
.onb--reduced .onb__body { height: auto; }
.onb--reduced .onb__hint-chevron { display: none; }
.onb--reduced .onb__stage {
  position: static;
  height: auto;
  min-height: 100vh;
}
.onb--reduced .onb__continue {
  padding: 10px 20px;
  border-radius: var(--nv-r-md);
  background: var(--moss);
  color: var(--nv-text-on-accent);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
}
.onb--reduced .onb__continue:hover { background: var(--moss-deep); }

/* ── Petal tour ────────────────────────────────────────────────── */

.onb-tour {
  position: fixed;
  inset: 0;
  z-index: 240;
  pointer-events: none; /* children opt back in */
}

.onb-tour__dim {
  position: absolute;
  inset: 0;
  background: var(--nv-scrim);
  opacity: 0;
  pointer-events: auto; /* blocks the app while the tour runs */
}

/* Spotlight: a transparent window whose enormous shadow is the deep dim,
   so the highlighted element is the only fully clear thing on screen. */
.onb-tour__spot {
  position: absolute;
  border-radius: var(--nv-r-md);
  border: 2px solid var(--ochre);
  box-shadow: 0 0 0 200vmax var(--nv-scrim-deep);
  opacity: 0;
  pointer-events: none;
}

/* JS keeps the card clear of the Almanac panel (right offset recomputed
   on resize/panel toggle); the transition makes that shift a glide. */
.onb-tour__corner {
  position: absolute;
  right: var(--nv-sp-6);
  bottom: var(--nv-sp-6);
  pointer-events: auto;
  z-index: 1;
  transition: right 320ms ease;
}

/* Settings mini-tutorial keeps the intact mark. */
.onb-tour__mark {
  width: 158px;
  height: 158px;
  color: var(--moss);
  overflow: visible;
}

/* Full-viewport stage for the physics fall: the intro flower's petals
   drop onto the real app surface here, then snap into the checklist. */
.onb-tour__fallstage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--moss);
  overflow: visible;
  pointer-events: none;
  z-index: 1;
}

.onb-tour__list {
  pointer-events: auto;
  width: 264px;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-lg);
  padding: var(--nv-sp-4) var(--nv-sp-5);
  box-shadow: 0 12px 32px var(--nv-shadow-ink);
}
.onb-tour__list-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  color: var(--ink);
  margin-bottom: var(--nv-sp-3);
}
.onb-tour__list ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Each row IS a fallen petal: mark, label, completion ring. */
.onb-tour__row {
  display: flex;
  align-items: center;
  gap: var(--nv-sp-3);
  width: 100%;
  padding: 5px 8px;
  border-radius: var(--nv-r-sm);
  font-family: var(--font-ui);
  font-size: 13.5px;
  color: var(--ink-soft);
  text-align: left;
  transition: background 150ms ease, color 150ms ease;
}
.onb-tour__row-label { flex: 1; }
.onb-tour__row-mark {
  flex: none;
  width: 22px;
  height: 32px;
  color: var(--moss);
  overflow: visible;
  transition: transform 160ms ease;
  transform-origin: 50% 85%;
}
.onb-tour__row.is-open { background: var(--nv-tint-accent-low); }
.onb-tour__row.is-open .onb-tour__row-mark { z-index: 1; }

/* "About to interact": one response for mouse hover AND keyboard focus —
   a quick lift of the petal plus an ochre accent. The split-open that
   follows on activation stays the bigger gesture. */
.onb-tour__row:hover,
.onb-tour__row:focus-visible {
  background: var(--nv-tint-accent-low);
  color: var(--ink);
}
.onb-tour__row:hover .onb-tour__row-mark,
.onb-tour__row:focus-visible .onb-tour__row-mark {
  transform: scale(1.16) rotate(-5deg);
}
.onb-tour__row:hover .onb-petal__half,
.onb-tour__row:focus-visible .onb-petal__half {
  stroke: var(--ochre-ink);
}

.onb-tour__check {
  flex: none;
  width: 16px;
  height: 16px;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 10px;
  line-height: 1;
  color: transparent;
}
.onb-tour__row[data-done="true"] { color: var(--nv-text-muted); }
.onb-tour__row[data-done="true"] .onb-petal__half { stroke: var(--moss); }
.onb-tour__row[data-done="true"] .onb-tour__check {
  background: var(--moss);
  border-color: var(--moss);
  color: var(--nv-text-on-accent);
}
.onb-tour__meta {
  margin-top: var(--nv-sp-3);
  padding-top: var(--nv-sp-3);
  border-top: 1px solid var(--rule);
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.5;
  color: var(--nv-text-muted);
}
.onb-tour__explore {
  margin-top: var(--nv-sp-2);
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--nv-text-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.onb-tour__explore:hover { color: var(--ink-soft); }

/* The annotation that opens out of a petal — marginal-note typography:
   ochre rule, small caps label, Newsreader italic body. */
.onb-tour__note {
  position: absolute;
  /* Clear of the checklist card (264px); JS refines this alongside the
     corner's panel-avoiding offset. */
  right: calc(var(--nv-sp-6) + 296px);
  bottom: var(--nv-sp-6);
  transition: right 320ms ease;
  width: min(340px, calc(100vw - 2 * var(--nv-sp-6)));
  z-index: 2;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-lg);
  padding: var(--nv-sp-5);
  box-shadow: 0 16px 40px var(--nv-shadow-ink-strong);
  pointer-events: auto;
  opacity: 0;
  visibility: hidden;
}
.onb-tour__note::before {
  content: '';
  display: block;
  width: 44px;
  height: 2px;
  background: var(--ochre);
  margin-bottom: var(--nv-sp-3);
}
.onb-tour__note-label {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ochre-ink);
  margin-bottom: var(--nv-sp-2);
}
.onb-tour__note-body {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin-bottom: var(--nv-sp-4);
}
.onb-tour__note-ok {
  padding: 8px 16px;
  border-radius: var(--nv-r-md);
  background: var(--moss);
  color: var(--nv-text-on-accent);
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 500;
}
.onb-tour__note-ok:hover { background: var(--moss-deep); }

/* ── Demo panel: the simulated exchanges for Memory / Why / Dispute.
   The tag stays pinned for the demo's entire playback — a simulated
   conversation must never be mistakable for a real one. ── */
.onb-demo {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-lg);
  box-shadow: 0 16px 40px var(--nv-shadow-ink-strong);
  padding: var(--nv-sp-5);
  padding-top: var(--nv-sp-6);
}
.onb-demo__tag {
  position: absolute;
  top: calc(-1 * var(--nv-sp-3));
  left: var(--nv-sp-5);
  padding: 3px 10px;
  border: 1px solid var(--ochre);
  border-radius: 999px;
  /* Opaque paper (not the translucent tint) so the pill never picks up
     the dark scrim where it overhangs the card edge; the soft ochre halo
     gives it its own spotlight against the dimmed surface. */
  background: var(--paper);
  color: var(--ochre-ink);
  box-shadow: 0 0 20px 4px var(--nv-tint-ochre), 0 4px 14px var(--nv-shadow-ink-strong);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.onb-demo__body {
  display: flex;
  flex-direction: column;
  gap: var(--nv-sp-3);
}
.onb-demo__msg {
  max-width: 85%;
  padding: 9px 14px;
  border-radius: var(--nv-r-md);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
}
.onb-demo__msg--user {
  align-self: flex-end;
  background: var(--paper-alt);
  border: 1px solid var(--rule);
  color: var(--ink);
}
.onb-demo__msg--novalis {
  align-self: flex-start;
  color: var(--ink);
  min-height: 1.55em;
}
.onb-demo__why {
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-md);
  padding: var(--nv-sp-3) var(--nv-sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--nv-sp-2);
}
.onb-demo__why-title,
.onb-demo__dispute-title,
.onb-demo__memory-label {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ochre-ink);
}
.onb-demo__why-row {
  display: flex;
  justify-content: space-between;
  gap: var(--nv-sp-3);
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink-soft);
}
.onb-demo__why-row strong { color: var(--ink); font-weight: 500; }
.onb-demo__why-note {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 14.5px;
  color: var(--ink-soft);
}
.onb-demo__memory {
  display: flex;
  flex-direction: column;
  gap: var(--nv-sp-1);
  border: 1px solid var(--rule);
  border-radius: var(--nv-r-md);
  padding: var(--nv-sp-3) var(--nv-sp-4);
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--ink);
}
.onb-demo__memory mark {
  background: transparent;
  color: inherit;
  border-radius: 3px;
  padding: 0 2px;
  transition: background 300ms ease;
}
.onb-demo__memory mark.is-selected { background: var(--nv-tint-ochre); }
.onb-demo__dispute {
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-md);
  padding: var(--nv-sp-3) var(--nv-sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--nv-sp-2);
}
.onb-demo__dispute-input {
  min-height: 34px;
  padding: 7px 12px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--nv-r-sm);
  background: var(--nv-white);
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--ink);
}
.onb-demo__dispute-confirm {
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--moss);
  opacity: 0;
  visibility: hidden;
}
.onb-demo.is-static .onb-demo__dispute-confirm.is-shown,
.onb-demo__dispute-confirm.is-shown {
  opacity: 1;
  visibility: visible;
}
.onb-demo__kept {
  position: fixed;
  z-index: 242;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--moss);
  color: var(--nv-text-on-accent);
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 600;
  pointer-events: none;
}

/* Static state classes: used by the reduced-motion tour AND as the
   no-choreography fallback whenever GSAP isn't loaded (e.g. the Settings
   mini-tutorial in a fresh session). Scoping these to .onb-tour--reduced
   left that fallback note permanently invisible with an unreachable
   "Got it". */
.onb-tour__note.is-open {
  opacity: 1;
  visibility: visible;
}
.onb-tour__dim.is-on { opacity: 1; }
.onb-tour__spot.is-on { opacity: 1; }
.onb-demo.is-static { opacity: 1; visibility: visible; }

@media (prefers-reduced-motion: reduce) {
  .onb__hint-chevron { animation: none; }
  .onb-tour__corner,
  .onb-tour__note,
  .onb-tour__row,
  .onb-tour__row-mark { transition: none; }
  .onb-tour__row:hover .onb-tour__row-mark,
  .onb-tour__row:focus-visible .onb-tour__row-mark { transform: none; }
}

@media (max-width: 900px) {
  .onb-tour__corner {
    flex-direction: column;
    align-items: flex-end;
  }
  /* Bottom sheet instead of a floating marginal note: the desktop offsets
     (right of the checklist card) pushed the note entirely off-screen on
     phones, leaving "Got it" untappable. JS skips its inline right offset
     at this width (see _positionCorner). */
  .onb-tour__note {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: 100%;
    max-width: none;
    border-radius: var(--nv-r-lg) var(--nv-r-lg) 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    z-index: 3;
  }
}
