/* ============================================================================
   SEQUENCE INTEGRATIVE — Brand Design System (Prompt 46D: Pilot UI Productization)
   ----------------------------------------------------------------------------
   A calm, minimal, premium light theme for the self-serve participant experience.
   Purely presentational — no backend, contract, routing, or copy-token change.

   Palette (brand):
     #e6e6e6  clay   — page canvas
     #D4E8E5  sage   — soft accent surfaces / tints
     #3D6B62  teal   — primary actions & accents
     #1C2B28  ink    — text & the logo mark
   Typography: Plus Jakarta Sans (loaded in the HTML head), robust system fallback.
   ========================================================================== */

:root {
  /* Brand palette */
  --clay: #e6e6e6;
  --sage: #d4e8e5;
  --teal: #3d6b62;
  --ink: #1c2b28;

  /* Derived neutrals (all AA+ against their intended background) */
  --surface: #ffffff;
  --surface-2: #f6f8f7;
  --muted: #52605c;          /* ~6:1 on white */
  --line: rgba(28, 43, 40, 0.12);
  --line-strong: rgba(28, 43, 40, 0.20);

  /* Interaction states */
  --teal-strong: #325a52;
  --teal-tint: #eef4f2;
  --focus-ring: 0 0 0 4px rgba(61, 107, 98, 0.22);

  /* Feedback */
  --ok-bg: #e9f3f0;
  --ok-ink: #26473f;
  --err-bg: #fbecec;
  --err-ink: #8a2e2e;
  --err-line: rgba(138, 46, 46, 0.28);
  --warn-bg: #f3efe4;
  --warn-ink: #6b5a2e;

  /* Shape & motion */
  --radius-lg: 24px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --shadow-card: 0 1px 2px rgba(28, 43, 40, 0.05), 0 28px 60px -32px rgba(28, 43, 40, 0.28);
  --shadow-soft: 0 1px 2px rgba(28, 43, 40, 0.05), 0 10px 24px -18px rgba(28, 43, 40, 0.25);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  --font: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;

  color-scheme: light;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--clay);
  background-image:
    radial-gradient(1100px 620px at 50% -12%, #eef4f2 0%, rgba(238, 244, 242, 0) 60%),
    linear-gradient(180deg, #ecefee 0%, #e6e6e6 46%, #e2e6e5 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ===========================================================================
   CENTERED SHELL + BRANDED CARD
   ======================================================================== */
.seq-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(20px, 5vw, 56px) clamp(16px, 4vw, 32px);
  gap: 20px;
}

.seq-card {
  position: relative;
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: clamp(28px, 5vw, 48px);
  overflow: hidden;
  isolation: isolate;
}

/* Subtle low-opacity mark watermark — texture, never a distraction. */
.seq-watermark {
  position: absolute;
  right: -14%;
  bottom: -20%;
  width: min(62%, 360px);
  aspect-ratio: 963 / 940;
  background: url("./assets/sequence-logo-mark.png") center / contain no-repeat;
  opacity: 0.04;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}

/* Everything real sits above the watermark. */
.seq-card > *:not(.seq-watermark) { position: relative; z-index: 1; }

/* ===========================================================================
   CARD HEADER — hero (with name) on entry, compact lockup in flow
   ======================================================================== */
.seq-cardhead {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-bottom: 24px;
}

.seq-hero { display: none; }
.seq-hero img {
  width: clamp(150px, 44%, 208px);
  height: auto;
  display: block;
}

.seq-lockup {
  display: none;
  align-items: center;
  gap: 10px;
}
.seq-lockup img { width: 30px; height: auto; display: block; }
.seq-lockup span {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}

/* Phase-driven logo swap (JS sets data-phase on .seq-shell). */
.seq-shell[data-phase="entry"] .seq-hero { display: block; }
.seq-shell[data-phase="flow"] .seq-lockup { display: inline-flex; }
/* Default (no phase yet): show the compact lockup so the card is never bare. */
.seq-shell:not([data-phase]) .seq-lockup { display: inline-flex; }

/* ===========================================================================
   PROGRESS INDICATOR
   ======================================================================== */
.seq-progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0 auto 26px;
  padding: 0;
  list-style: none;
  flex-wrap: wrap;
}
.seq-progress__step {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--muted);
}
.seq-progress__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line-strong);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
  flex: none;
}
.seq-progress__label {
  display: none;
  letter-spacing: 0.01em;
}
.seq-progress__step--done .seq-progress__dot { background: var(--teal); }
.seq-progress__step--current .seq-progress__dot {
  background: var(--teal);
  transform: scale(1.35);
  box-shadow: 0 0 0 4px rgba(61, 107, 98, 0.16);
}
.seq-progress__step--current .seq-progress__label {
  color: var(--teal-strong);
  font-weight: 600;
}
.seq-progress__meta {
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  margin: -14px 0 22px;
  letter-spacing: 0.02em;
}

/* ===========================================================================
   TYPOGRAPHY HELPERS (screen headings rendered by JS)
   ======================================================================== */
.seq-eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal);
  margin: 0 0 8px;
}
.seq-title {
  font-size: clamp(22px, 4.4vw, 27px);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
  color: var(--ink);
}
.seq-lede {
  font-size: 15px;
  color: var(--muted);
  margin: 0 0 24px;
  max-width: 46ch;
}
.seq-screen { text-align: center; }
.seq-screen .cap-form,
.seq-screen .seq-lede,
.seq-screen .seq-eyebrow,
.seq-screen .seq-title { text-align: left; }
.seq-screen.seq-screen--center { text-align: center; }
.seq-screen.seq-screen--center .seq-lede { margin-left: auto; margin-right: auto; }

/* Terminal / branch screens have no form → center everything for a calm, focused close. */
.seq-screen[data-terminal] { text-align: center; }
.seq-screen[data-terminal] .seq-eyebrow,
.seq-screen[data-terminal] .seq-title,
.seq-screen[data-terminal] .seq-lede { text-align: center; }
.seq-screen[data-terminal] .seq-lede { margin-left: auto; margin-right: auto; }

.seq-terminal-icon { display: flex; justify-content: center; margin-bottom: 14px; }
.cap-state__icon--lg {
  width: 46px;
  height: 46px;
  font-size: 22px;
  background: var(--teal);
  color: #fff;
  margin: 0;
}

/* ===========================================================================
   FORMS
   ======================================================================== */
.cap-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 0;
  text-align: left;
}
.cap-form fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.cap-form legend { padding: 0; }

.cap-field { display: flex; flex-direction: column; gap: 7px; }
.cap-field > .cap-label,
.cap-form label:not(.cap-check):not(.cap-consent-accept) {
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.cap-hint {
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}
/* Wording that is registry intent rather than approved copy (DEFERRED-C). Quiet and
   italic: it is an honest caveat, not a warning about anything being wrong. */
.cap-hint--provisional {
  font-style: italic;
  opacity: 0.85;
  margin-top: 10px;
}

.cap-form input[type="text"],
.cap-form input[type="email"],
.cap-form input[type="password"],
.cap-form input[type="number"],
.cap-form input:not([type]),
.cap-form select,
.cap-form textarea,
/* The anchoring search box (Prompt 78) is a capture field in every respect except that it
   deliberately is not inside a <form>: there is nothing to submit, so an Enter key can
   neither pick an anchor nor reload the screen. It still has to look like every other field. */
.cap-anchor-search input[type="text"] {
  width: 100%;
  font: inherit;
  font-size: 16px; /* ≥16px avoids iOS zoom-on-focus */
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
  appearance: none;
  -webkit-appearance: none;
}
.cap-form input::placeholder { color: #9aa5a1; }

.cap-form select {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2352605c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 42px;
  cursor: pointer;
}

.cap-form input:focus-visible,
.cap-form select:focus-visible,
.cap-form textarea:focus-visible,
.cap-anchor-search input[type="text"]:focus-visible {
  outline: none;
  border-color: var(--teal);
  box-shadow: var(--focus-ring);
}
/* Validation feedback only after the user has interacted (modern selector). */
.cap-form input:user-invalid,
.cap-form select:user-invalid {
  border-color: var(--err-line);
  box-shadow: 0 0 0 4px rgba(138, 46, 46, 0.12);
}

/* Checkbox rows (started / consent accept) */
.cap-check,
.cap-consent-accept {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  line-height: 1.45;
}
.cap-check input[type="checkbox"],
.cap-consent-accept input[type="checkbox"] {
  appearance: auto;
  -webkit-appearance: auto;
  accent-color: var(--teal);
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  flex: none;
  cursor: pointer;
}
.cap-check input:focus-visible,
.cap-consent-accept input:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Self-serve clarification (46F-2): one choice per row, matching the checkbox treatment. */
.cap-radios { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 6px; }
.cap-radio {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  line-height: 1.45;
  padding: 12px 14px;
  border: 1px solid var(--line, rgba(28, 43, 40, 0.14));
  border-radius: 12px;
  background: #fff;
}
.cap-radio input[type="radio"] {
  appearance: auto;
  -webkit-appearance: auto;
  accent-color: var(--teal);
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  flex: none;
  cursor: pointer;
}
.cap-radio input:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------------------------------------------------------------------------
   CORRECTION OPTIONS (Prompt 54)
   A correction option carries more than a line of text: how far its setup got, and
   the participant's own private name for it. Those are separate facts and must read
   as separate facts — inline spans with no rules ran them straight into the sentence
   ("...for the next two weeks.Part-way set up"), which is how a status becomes part
   of the offer by accident.
   ------------------------------------------------------------------------ */
.cap-option__body { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.cap-option__text { display: block; }
.cap-option__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cap-option__status,
.cap-option__label {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.02em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* How far the setup got: informational, quiet, never competing with the option. */
.cap-option__status {
  color: var(--teal);
  background: var(--sage, #d4e8e5);
}
/* The participant's OWN words (D-BK/D-BO). Visually distinct from the system's status
   so it is never mistaken for something Sequence said about their correction. */
.cap-option__label {
  color: var(--ink);
  background: transparent;
  border: 1px dashed var(--line, rgba(28, 43, 40, 0.22));
  font-weight: 500;
  font-style: italic;
}
/* An option already set up reads as resumable at a glance. */
.cap-option[data-option-status="complete"] { border-color: var(--teal); }

/* ===========================================================================
   BUTTONS
   ======================================================================== */
.cap-form button,
.cap-next,
.cap-work-confirm-yes,
.cap-work-cancel,
/* Prompt 94 — the map-update controls. Listed here rather than given the `cap-next`
   class they would otherwise borrow: `cap-next` is the generic advance BEHAVIOUR
   (wireAllNext reads data-next-step off it), and these four carry their own
   handlers. Styling and behaviour should not share a hook. */
.cap-mapupdate-start,
.cap-mapupdate-begin,
.cap-mapupdate-continue,
.cap-mapupdate-later,
/* Pre-existing gap, found while wiring the map-update copy onto this screen: the cadence
   prompt's two answers have never been in this list, so they rendered as unstyled bars.
   Fixed here because the approved primary CTA now lands on that screen. */
.cap-cadence-answer,
.hub-offer__later,
/* Prompt 89's work-completion confirm has never been in this list either, so it has been
   rendering as an unstyled bar on the plan screen since it shipped. Same fix, same reason. */
.cap-work-confirm-yes,
.seq-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* The hub's exits are real links (an <a href>), so they work with middle-click, the keyboard
     and a lost session. That means they arrive with the browser's underline, which a control
     styled as a button must not keep. */
  text-decoration: none;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #fff;
  background: var(--teal);
  border: 1px solid var(--teal);
  border-radius: var(--radius-md);
  padding: 13px 22px;
  cursor: pointer;
  transition: background 0.18s var(--ease), transform 0.08s var(--ease),
    box-shadow 0.18s var(--ease);
  box-shadow: var(--shadow-soft);
  width: 100%;
  min-height: 48px;
}
.cap-form button:hover,
.cap-next:hover,
.cap-work-confirm-yes:hover,
.seq-btn:hover { background: var(--teal-strong); border-color: var(--teal-strong); }
.cap-form button:active,
.cap-next:active,
.seq-btn:active { transform: translateY(1px); }
.cap-form button:focus-visible,
.cap-next:focus-visible,
.seq-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring), var(--shadow-soft);
}
.cap-form button:disabled,
.seq-btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* Secondary / ghost action */
.seq-btn--ghost,
.cap-work-cancel,
.cap-next.seq-btn--ghost {
  color: var(--teal-strong);
  background: transparent;
  border-color: var(--line-strong);
  box-shadow: none;
}
.seq-btn--ghost:hover { background: var(--teal-tint); border-color: var(--teal); }

.seq-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 22px;
}

/* ===========================================================================
   FEEDBACK STATES (loading / success / error / mediated)
   ======================================================================== */
.cap-state {
  border-radius: var(--radius-md);
  padding: 18px;
  margin-top: 20px;
  font-size: 15px;
}
.cap-state--ok {
  background: var(--ok-bg);
  color: var(--ok-ink);
  border: 1px solid rgba(38, 71, 63, 0.18);
}
.cap-state--error {
  background: var(--err-bg);
  color: var(--err-ink);
  border: 1px solid var(--err-line);
}
.cap-state__icon {
  display: inline-flex;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  margin-bottom: 10px;
}
.cap-state--ok .cap-state__icon { background: var(--teal); color: #fff; }
.cap-state--error .cap-state__icon { background: var(--err-ink); color: #fff; }
.cap-msg { margin: 0 0 4px; font-weight: 600; }
.cap-mediated {
  margin: 12px 0 0;
  padding: 12px 14px;
  background: var(--sage);
  border-radius: var(--radius-sm);
  color: var(--ok-ink);
  font-size: 14px;
}
.cap-state .cap-next { margin-top: 16px; }

/* Post-cycle reveal (safe forecast-vs-reality read, participant's own current-cycle values) */
.cap-reveal {
  margin: 4px auto 20px;
  max-width: 320px;
  padding: 16px 18px;
  background: var(--sage);
  border-radius: var(--radius-sm);
  text-align: left;
}
.cap-reveal__note { margin: 10px 0 0; font-size: 14px; color: var(--ok-ink); }
.cap-reveal--deferred { background: transparent; padding: 8px 0; }
.cap-reveal--deferred .cap-reveal__note { color: var(--muted); text-align: center; }

/* Loading */
.cap-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 28px 0;
  color: var(--muted);
  font-size: 15px;
}
.cap-spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid rgba(61, 107, 98, 0.22);
  border-top-color: var(--teal);
  animation: seq-spin 0.8s linear infinite;
  flex: none;
}
@keyframes seq-spin { to { transform: rotate(360deg); } }

.cap-consent-err,
.cap-signin-err,
.cap-field-err {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--err-ink);
  font-weight: 500;
}

/* ===========================================================================
   CONSENT DOCUMENTS
   ======================================================================== */
.cap-consent-intro,
.cap-signin-intro { font-size: 15px; color: var(--muted); margin: 0 0 18px; }
.cap-consent-doc {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  background: var(--surface-2);
}
.cap-consent-doc legend,
.cap-consent-doc > .cap-consent-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  padding: 0;
  margin-bottom: 8px;
}
.cap-consent-ver { color: var(--muted); font-weight: 500; font-size: 12px; }
.cap-consent-text summary {
  cursor: pointer;
  color: var(--teal-strong);
  font-size: 14px;
  font-weight: 600;
  list-style: none;
}
.cap-consent-text summary::-webkit-details-marker { display: none; }
.cap-consent-text summary::before { content: "▸ "; }
.cap-consent-text[open] summary::before { content: "▾ "; }
.cap-consent-body {
  margin-top: 10px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink);
  max-height: 220px;
  overflow: auto;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.cap-consent-accept { margin-top: 14px; }

/* ===========================================================================
   FOOTER + MODE NOTE
   ======================================================================== */
.seq-foot {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--muted);
  text-align: center;
}
.cap-mode {
  margin: 18px 0 0;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  letter-spacing: 0.02em;
}
.seq-shell-foot {
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  opacity: 0.8;
}

/* ===========================================================================
   RESPONSIVE
   ======================================================================== */
@media (max-width: 560px) {
  .seq-card { border-radius: 20px; padding: 24px 20px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ===========================================================================
   READ-APP SKELETON (index.html) — retuned to the brand palette so the
   preview dashboard stays coherent with the participant experience.
   ======================================================================== */
.app-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px clamp(16px, 4vw, 28px);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.app-bar h1 { font-size: 18px; margin: 0; letter-spacing: 0.02em; color: var(--ink); font-weight: 700; }
.gate-control { font-size: 13px; color: var(--muted); display: flex; gap: 8px; align-items: center; }
.gate-control input { accent-color: var(--teal); }
.skeleton-note { max-width: 900px; margin: 16px auto 0; padding: 0 20px; color: var(--muted); font-size: 13px; }
.dashboard { max-width: 900px; margin: 0 auto; padding: 24px 20px; display: grid; gap: 24px; }
.surface__title { font-size: 13px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); margin: 0 0 12px; font-weight: 700; }
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 18px; margin-bottom: 12px; box-shadow: var(--shadow-soft);
}
.card h3 { margin: 0 0 4px; font-size: 16px; color: var(--ink); }
.tag { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; padding: 3px 10px; border-radius: 999px; background: var(--sage); color: var(--ok-ink); font-weight: 600; }
.tag--corrective { background: var(--warn-bg); color: var(--warn-ink); }
dl { margin: 8px 0 0; }
dt { color: var(--muted); font-size: 12px; }
dd { margin: 0 0 6px; }
.series__anchor, .cycle__anchor, .reveal__anchor { margin: 8px 0; }
.series__anchor-key, .cycle__anchor-key, .reveal__anchor-key { color: var(--muted); font-size: 12px; display: block; }
.series__anchor-val, .cycle__anchor-val, .reveal__anchor-val { color: var(--teal-strong); font-style: italic; }
.series-status__counts { list-style: none; padding: 0; display: flex; gap: 20px; margin: 8px 0; }
.series-status__counts span { font-size: 20px; font-weight: 700; display: block; color: var(--ink); }
.series-status__warn { color: var(--warn-ink); background: var(--warn-bg); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 14px; margin: 8px 0; }
.series-status__end-btn { background: transparent; border: 1px solid var(--line-strong); color: var(--ink); border-radius: var(--radius-sm); padding: 8px 16px; cursor: pointer; font: inherit; font-weight: 600; }
.series-status__end-btn:hover { border-color: var(--teal); color: var(--teal-strong); }
.series-status__ended { color: var(--muted); font-style: italic; margin: 8px 0 0; }
.series-status__note { color: var(--muted); font-size: 13px; margin: 8px 0; }
.series__counts, .calib__counts { list-style: none; padding: 0; display: flex; gap: 20px; margin: 8px 0; }
.series__counts span, .calib__counts span { font-size: 20px; font-weight: 700; display: block; color: var(--ink); }
.cycle__metrics, .calib__trends, .hist__metrics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 20px; }
.hist__metrics { grid-template-columns: repeat(4, 1fr); }
.cycle__group-title, .calib__headline { grid-column: 1 / -1; margin: 6px 0 2px; font-weight: 600; color: var(--ink); }
.calib__headline--deferred, .cycle__pending, .series__current--none { color: var(--muted); font-style: italic; }
.hist__reflection { margin-top: 10px; color: var(--ink); border-left: 3px solid var(--teal); padding-left: 10px; }
.pager { background: transparent; border: 1px solid var(--teal); color: var(--teal-strong); border-radius: var(--radius-sm); padding: 8px 16px; cursor: pointer; font: inherit; font-weight: 600; }
.pager:hover { background: var(--teal-tint); }
.state { border: 1px dashed var(--line-strong); border-radius: var(--radius-md); padding: 18px; text-align: center; background: var(--surface); }
.state--loading, .state--empty { color: var(--muted); }
.state--error { border-color: var(--err-line); color: var(--err-ink); background: var(--err-bg); }
.state--deferred { border-color: rgba(107, 90, 46, 0.4); color: var(--warn-ink); background: var(--warn-bg); }
.state__title { font-weight: 700; margin: 0 0 4px; }
.state__body { margin: 0; font-size: 13px; opacity: 0.85; }

/* ── The hub (2026-07-31) ────────────────────────────────────────────────────
   The dashboard's one actionable surface: the participant's targets, and the two
   things they can do. It sits above the read-only cards because it is the reason
   they were sent here. Styles lean on the existing card/tag/seq-btn vocabulary so
   the hub does not read as a different product from the flow it launches. */
.hub__title { margin: 0 0 6px; font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }
.hub__lede { margin: 0 0 18px; color: var(--ink-soft, #5b6b66); font-size: 15px; }
.hub__targets { display: grid; gap: 12px; }
.hub-target { padding: 16px 18px; }
.hub-target__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.hub-target__label { margin: 0; font-size: 16px; font-weight: 650; }
.hub-target__anchor,
.hub-target__count { margin: 8px 0 0; font-size: 14px; color: var(--ink-soft, #5b6b66); }
.hub-target__key { font-weight: 600; color: var(--ink, #1d2b27); margin-right: 6px; }
.hub__actions { margin-top: 18px; }
.hub__cap { margin: 18px 0 0; font-size: 14px; color: var(--ink-soft, #5b6b66); }

/* ── The cadence offer (Prompt 53) ───────────────────────────────────────────
   Prominent, never blocking (D-AN). It is tinted and rule-edged so it reads as an
   offer rather than as part of the card's own copy, and it sits ABOVE the target's
   "start the next cycle" button — which stays exactly where it was, because the
   offer must never be something a participant has to get past. */
.hub-offer {
  margin: 14px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--teal, #3d6b62);
  border-left-width: 4px;
  border-radius: var(--radius-sm, 8px);
  background: var(--teal-tint, rgba(212, 232, 229, 0.35));
}
.hub-offer__eyebrow {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--teal-strong, #2c534c);
}
.hub-offer__title { margin: 0 0 6px; font-size: 15px; font-weight: 650; color: var(--ink, #1d2b27); }
.hub-offer__lede { margin: 0 0 8px; font-size: 14px; color: var(--ink-soft, #5b6b66); }
/* The offer's action is prominent but NOT the card's dominant control: "start the next
   cycle" stays full-width below it, because the offer must never read as the thing the
   participant is now supposed to do instead (D-AN: never blocking). */
.hub-offer .seq-actions { margin-top: 12px; flex-direction: row; }
/* .seq-btn is width:100% everywhere else, which is right for a screen's single action but
   wrong here — two identical full-width buttons stacked would read as two equal choices. */
.hub-offer__open { width: auto; align-self: flex-start; }
/* Prompt 94: the offer is answered on the card, so "I'll do this later" sits beside the
   primary rather than under it — and is sized like it, because a deferral that is visibly
   harder to press than the acceptance is not a real choice. */
.hub-offer__later { width: auto; align-self: flex-start; }
/* How long the update takes, under the lede. */
.hub-offer__note { margin: 8px 0 0; font-size: 13px; color: var(--muted); }

/* ============================================================================
   PROMPT 63/64 — the continue panel and the calibration graph.
   ========================================================================== */

/* ── THE CONTINUE PANEL (founder, 2026-08-20: "should be loud") ─────────────
   Loud by SIZE, POSITION and CONTRAST — a filled teal card at the very top of
   the dashboard, above the target list. It is deliberately not the quiet
   card-line pattern .hub-offer uses; that was the recommendation the founder
   overrode. It carries no badge, no count and no overdue language: the product
   does not nag anywhere else, and being first and large is enough. */
.hub-continue {
  background: var(--teal);
  border-color: var(--teal-strong);
  color: #fff;
  padding: 22px;
}
.hub-continue__title {
  margin: 0;
  font-size: 22px;
  line-height: 1.25;
  font-weight: 700;
  color: #fff;
}
.hub-continue__target {
  margin: 6px 0 0;
  font-size: 15px;
  color: rgba(255, 255, 255, 0.88);
}
.hub-continue .seq-actions { margin-top: 14px; }
/* Reversed out of the teal: white fill, teal ink — the highest-contrast control
   on the page, which is the point of the panel. */
.hub-continue__go,
.hub-continue .seq-btn {
  background: #fff;
  border-color: #fff;
  color: var(--teal-strong);
}
.hub-continue__go:hover,
.hub-continue .seq-btn:hover { background: var(--teal-tint); border-color: var(--teal-tint); }
.hub-continue__go:focus-visible,
.hub-continue .seq-btn:focus-visible { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.5); }

/* ── THE CALIBRATION GRAPH ──────────────────────────────────────────────────
   Cycle number across, prediction error percent up. The Y axis is pinned 0-100
   in the view, not fitted to the data, so a small change looks small. */
/* Prompt 94: the first map update is ready on this target. A STATE line, not a
   warning — the target is active and its history is right above it, so this is
   deliberately the same quiet weight as the sensation line and carries no alert
   colour, icon or border. */
.tcard__status {
  margin: 2px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--teal);
}

.calib-graph { margin: 10px 0 0; }
.calib-graph__svg { width: 100%; height: auto; display: block; overflow: visible; }
.calib-graph__line {
  stroke: var(--teal);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.calib-graph__dot { fill: var(--teal); }
.calib-graph__grid { stroke: var(--line); stroke-width: 1; }
.calib-graph__tick { fill: var(--muted); font-size: 9px; }
.calib-graph__caption { margin: 6px 0 0; font-size: 13px; color: var(--muted); }
/* Below the gate: the card says how many cycles it needs, in the same muted
   voice the old deferred line used. */
.calib__pending { margin: 6px 0 0; color: var(--muted); font-style: italic; }

/* The graph's numbers repeated for a screen reader. A line nobody can read is a
   line that excludes the participant from their own result. */
.seq-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* Respect a reduced-motion preference: nothing here animates, but the graph must
   not acquire a transition if the button styles above are ever extended. */
@media (prefers-reduced-motion: reduce) {
  .hub-continue__go, .hub-continue .seq-btn { transition: none; }
}

/* ===========================================================================
   SENSATION ANCHORING (Prompt 78)
   The screens that fix a series' canonical felt-state anchor. Every option is a
   real button: retrieval never selects anything, so choosing is always an
   explicit act by the participant (spec §22.1), and nothing is ever preselected.
   ======================================================================== */
/* .seq-screen centres by default and un-centres its form; this surface has no form, so it
   says so itself rather than reading as a centred announcement. */
.cap-anchor-search { display: flex; flex-direction: column; gap: 7px; margin: 4px 0 0; text-align: left; }

/* The result / candidate list. It wraps rather than scrolls at Stage 2 (three words)
   and scrolls at full browse, where the whole active allowlist is offered. */
.cap-anchor-options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
  max-height: 320px;
  overflow-y: auto;
  padding: 2px;
}
.cap-anchor-option {
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line, rgba(28, 43, 40, 0.14));
  border-radius: 999px;
  padding: 9px 16px;
  cursor: pointer;
  line-height: 1.3;
}
.cap-anchor-option:hover { background: var(--teal-tint); border-color: var(--teal); }
.cap-anchor-option:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
/* The three helper candidates are the same control, given room to read as words
   rather than tags — they are possible words, not determinations (spec §31.3). */
.cap-anchor-candidate { padding: 11px 20px; font-size: 16px; }
.cap-anchor-nomatch { margin: 12px 0 0; }
/* "Choose a word instead" and "Search for another word" are quiet exits, never the
   primary action: the participant is never pushed away from the helper or toward it. */
/* `.cap-form button` is the filled primary, and it out-specifies a bare class — so the skip,
   which sits inside the Stage 1 form, has to name that context to read as the quiet exit it is.
   A skip styled identically to Continue would push the participant away from the helper as
   hard as the primary pushes them toward it. */
.cap-form button.cap-anchor-skip,
.cap-anchor-to-search,
.cap-anchor-retry {
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  color: var(--teal-strong);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md, 12px);
  padding: 12px 18px;
  cursor: pointer;
}
.cap-form button.cap-anchor-skip:hover,
.cap-anchor-to-search:hover,
.cap-anchor-retry:hover { background: var(--teal-tint); border-color: var(--teal); }
.cap-form button.cap-anchor-skip:focus-visible,
.cap-anchor-to-search:focus-visible,
.cap-anchor-retry:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* ===========================================================================
   MICRO-TEST GENERATION (Prompt 87) — the suggestion card
   ========================================================================
   The card is a PROPOSAL, and it is styled as one. It sits inside the ordinary
   form, above the duration field, and reads as a quiet quotation rather than a
   result: no icon, no accent bar, no badge, nothing that would present a model
   suggestion as a determination. The sentence carries the emphasis because the
   sentence IS the content — plan v2 §8A puts nothing under it.
   ======================================================================== */
.cap-mt-card {
  background: var(--teal-tint);
  border: 1px solid var(--line, rgba(28, 43, 40, 0.14));
  border-radius: var(--radius-md, 12px);
  padding: 18px 20px;
  text-align: left;
}
.cap-mt-card__label {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}
.cap-mt-card__sentence {
  margin: 0;
  font-size: 18px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink);
}
/* "Adjust it" is the quiet exit and must never out-weigh "Use this" — the participant is
   pushed neither toward the suggestion nor away from it. `.cap-form button` is the filled
   primary and out-specifies a bare class, so this names that context, exactly as the
   anchoring skip does. */
.cap-form button.cap-mt-adjust {
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  color: var(--teal-strong);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md, 12px);
  padding: 12px 18px;
  cursor: pointer;
}
.cap-form button.cap-mt-adjust:hover { background: var(--teal-tint); border-color: var(--teal); }
.cap-form button.cap-mt-adjust:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* §8A pending. The spinner says work is happening; the note says roughly how long, and
   nothing is advertised to fill in — the field appears when the wait ends, one way or
   the other. */
.cap-mt-wait { text-align: center; }
.cap-mt-wait__note { margin: 0; text-align: center; }

/* The one approved line above the manual field. `.cap-state` carries 18px of padding for the
   boxed ✓/error states; this one is not a box — it is the screen's lead sentence — so it drops
   the padding and sits flush with the field labels beneath it, and eases off the bold so it
   does not compete with the title above. */
.cap-mt-notice { text-align: left; padding: 0; margin: 0; }
.cap-mt-notice .cap-msg { margin: 0; font-size: 15px; font-weight: 500; color: var(--ink); }

/* The go-ahead screen's "Your test:" line. Same weight as "Your cycle:" — the bounded action
   and the target are named at the same volume, because on cycles 2+ this is the whole
   readback of the micro-test. */
.seq-lede--test { margin-bottom: 14px; }

/* §8A's worked examples, as a grayed secondary line beneath the hint (the target step's
   REV-001 cue). Quieter than the hint above it: it is an illustration, not an instruction. */
.cap-hint--example { opacity: 0.8; }

/* ── Prompt 89 (A7): the work-completion affordance ────────────────────── */
/* Quiet by design: completing is always available, never suggested. */
.cap-work-done-region { margin-top: 26px; text-align: center; }
.cap-work-done {
  font: inherit; font-size: 14px; font-weight: 500;
  color: var(--muted); background: transparent;
  border: 1px solid var(--line, rgba(28, 43, 40, 0.14));
  border-radius: 999px; padding: 8px 18px; cursor: pointer;
}
.cap-work-done:hover { color: var(--teal-strong); border-color: var(--teal); }
.cap-work-confirm { text-align: left; margin-top: 14px; }
.cap-work-quote {
  margin: 10px 0; padding: 10px 14px;
  border-left: 3px solid var(--teal);
  background: var(--teal-tint); border-radius: 0 10px 10px 0;
  font-size: 15px; color: var(--ink);
}
.cap-work-confirm .seq-actions { margin-top: 12px; }

/* ── PROMPT 91: the once-only cycle reveal and what replaced it ──────────────
   The reveal is the single screen in the product carrying a raw score, and it is
   never shown twice. It is styled to be READ rather than skimmed: generous rows,
   the interpreting sentence directly under the number it interprets, and a closing
   line that says out loud this is the only showing. The dashboard's replacement
   (.errcard) is deliberately quieter — it carries one percentage and one sentence. */

/* Founder copy pass: each part is a SENTENCE carrying its own number, so this is
   prose with an emphasized figure — not a label-and-value table. */
.cap-reveal__line { margin: 0; padding: 16px 0 2px; font-size: 1.05rem; line-height: 1.45; }
.cap-reveal__line:first-child { padding-top: 0; }
.cap-reveal__val {
  font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em;
  color: var(--teal-strong); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cap-reveal__say { margin: 4px 0 0; color: var(--muted); font-size: 0.95rem; line-height: 1.5; }
.cap-reveal__say--next-step {
  margin-top: 16px; padding: 12px 14px; background: var(--teal-tint);
  border-radius: var(--radius-sm); color: var(--teal-strong); font-weight: 600;
}
.cap-reveal__once {
  margin: 18px 0 0; padding-top: 12px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 0.85rem;
}
.cap-reveal--deferred .cap-reveal__note { color: var(--muted); margin: 0; }


/* The dashboard's error card: one number, one sentence, no score. */
.errcard__label { margin: 0; color: var(--muted); font-size: 0.85rem; }
.errcard__value {
  margin: 4px 0 0; font-size: 2rem; font-weight: 700; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.errcard__say { margin: 8px 0 0; color: var(--ink); font-size: 0.95rem; line-height: 1.5; }

/* The current-cycle card no longer prints ratings; "reported" is now a state. */
.cycle__reported { margin: 10px 0 0; color: var(--muted); font-size: 0.9rem; }


/* ── PROMPT 92: one card per target, and nothing else ────────────────────────
   The dashboard used to be six stacked read-only sections that printed the target
   name three times, the anchor five times and the cycle count three times. The card
   says each once. Its sections are EARNED — a direct-correction target has no cycles,
   so it has no list and no graph, and its card is simply shorter rather than padded
   with empty rows. */
.hub__title {
  margin: 0 0 18px; font-size: 20px; font-weight: 700; letter-spacing: -0.01em;
}
.tcard { padding: 20px 22px; }
.tcard__title { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
/* What is being tested, in the participant's terms. "Anchored sensation" was the
   founder's example of copy that reveals the method. */
.tcard__testing { margin: 6px 0 0; color: var(--muted); font-size: 15px; }

/* The cycle list. Plain rows, tabular figures so the percentages line up, and the
   words "prediction error" nowhere near it. */
.tcard__cycles { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 2px; }
.tcard__cycle {
  display: flex; flex-wrap: wrap; gap: 0 4px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid var(--line); font-size: 15px;
}
.tcard__cycle:first-child { border-top: 0; }
.tcard__cycle-n { font-weight: 600; }
.tcard__cycle-sep { color: var(--muted); }
.tcard__cycle-err { font-variant-numeric: tabular-nums; }

.tcard__actions { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
/* .seq-btn is width:100% for a screen's single action, which is wrong inside a card. */
.tcard__cycle-go { width: auto; }

/* ── PROMPT 95: the ending is discoverable, not competitive ──────────────────
   A ghost button sitting beside the primary one still reads as the second of two
   offers. This is a plain text control on its own line below the actions row: it
   is always there, always reachable by keyboard and always legible against the
   card, and it never asks to be pressed. */
.tcard__end-row { margin: 10px 0 0; }
.tcard__end {
  font-size: 14px; color: var(--muted); text-decoration: underline;
  text-underline-offset: 3px; background: none; border: 0; padding: 0;
}
.tcard__end:hover { color: var(--ink); }
.tcard__end:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; border-radius: 3px; }

/* ── PROMPT 97: the active Direct Correction attempt ─────────────────────────
   The attempt block is the card's whole action area while the participant is out
   trying the change. Before the check-in it is deliberately quiet — a statement
   of the attempt with two text links, no button asking for anything — because the
   participant is meant to be away doing it. At the check-in time it carries the
   card's ordinary primary button into the existing return flow. */
.tcard__attempt { margin-top: 18px; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: var(--radius-md); background: var(--surface); }
.tcard__attempt[data-attempt="due"] { border-color: var(--teal); background: var(--teal-tint); }
.tcard__attempt-title { margin: 0; font-weight: 700; font-size: 15px;
  letter-spacing: 0.01em; }
.tcard__attempt-lede, .tcard__attempt-chose { margin: 6px 0 0; font-size: 14px;
  color: var(--muted); }
.tcard__attempt-when { margin: 8px 0 0; font-size: 14px; }
.tcard__attempt-links { margin: 10px 0 0; display: flex; gap: 16px; flex-wrap: wrap; }
.tcard__attempt-link { font-size: 13px; color: var(--muted); text-decoration: underline;
  text-underline-offset: 3px; }
.tcard__attempt-link:hover { color: var(--ink); }
.tcard__attempt .tcard__actions { margin-top: 12px; }

.tcard__graph { margin: 20px 0 0; }
.tcard__graph-cap { margin: 6px 0 0; font-size: 13px; color: var(--muted); }

/* ── PROMPT 95: what happened with this target? ──────────────────────────────
   Four mutually exclusive outcomes, given identical weight. Only the participant
   knows which one is true, and a product that made one of them look like the
   expected answer would be collecting the wrong fact about their life. Nothing
   here is preselected and nothing is styled as a recommendation. */
.cap-end-options { display: grid; gap: 10px; margin: 18px 0 6px; text-align: left; }
.cap-end-option {
  font: inherit; font-size: 16px; font-weight: 600; width: 100%;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--radius-md);
  padding: 14px 18px; cursor: pointer; text-align: left;
}
.cap-end-option:hover { border-color: var(--teal); background: var(--teal-tint); }
.cap-end-option:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.cap-end-option__help {
  display: block; margin-top: 4px; font-size: 14px; font-weight: 400; color: var(--muted);
}
.cap-end-out:empty { display: none; }
