/* =========================================================================
   mobile.css — the purpose-built MOBILE experience for site3.

   Everything here is scoped to `body.m3` (added by mobile.js on phones) and
   loads AFTER styles.css / sections.css / interact.css, so same-specificity
   rules win the cascade without an !important arms race. The goal is NOT to
   shrink the desktop app-simulation — it's to give the phone its own coherent
   information architecture: a real header on every section, one clean product
   visual at a time, no horizontal overflow, and motion that actually plays.

   Reference viewport: 390–430px wide (iPhone 14/15/Pro family).
   ========================================================================= */

/* ---- fluid scale used throughout (kept local so desktop is untouched) ---- */
body.m3 {
  --m-gutter: 20px;
  /* slightly smaller so the headline never crowds the 20px side gutters */
  --m-h1: clamp(2.1rem, 8.2vw, 2.7rem);
  --m-h2: clamp(1.72rem, 6.6vw, 2.2rem);
  --m-body: 1.0625rem; /* 17px — comfortable mobile reading size */
  --m-kicker: 0.72rem;
  --m-pad-y: clamp(52px, 9vh, 76px);
}

/* ============================ GLOBAL GUARDS ============================ */
/* Belt-and-suspenders against horizontal scroll; in-card scrollers opt back in. */
body.m3,
html:has(body.m3) {
  overflow-x: hidden;
  max-width: 100%;
}
body.m3 *,
body.m3 *::before,
body.m3 *::after {
  box-sizing: border-box;
}
/* media can never force the page wider than the screen */
body.m3 img,
body.m3 svg,
body.m3 canvas,
body.m3 video,
body.m3 table {
  max-width: 100%;
}
/* long words / URLs wrap instead of pushing the layout sideways. Headings wrap
   WHOLE words (balance, no auto-hyphen — "Every sys-tem" looks broken); only
   body prose may hyphenate (html lang=en). */
body.m3 h1,
body.m3 h2,
body.m3 h3,
body.m3 .m-head__title,
body.m3 .landing__h1,
body.m3 .engine__title,
body.m3 .con__h2,
body.m3 .ledger__h2,
body.m3 .linking__title,
body.m3 .model__h2,
body.m3 .sem__h2,
body.m3 .cust__h2 {
  overflow-wrap: break-word;
  hyphens: manual;
  text-wrap: balance;
}
body.m3 p {
  overflow-wrap: break-word;
  hyphens: auto;
  text-wrap: pretty;
}
body.m3 .scroller {
  scroll-snap-type: none; /* free scroll on mobile — snapping fought tall sections */
  padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px));
}
body.m3 .page,
body.m3 .page * {
  min-width: 0;
}

/* The brand + primary CTA must never disappear: pin the top bar across every
   section (the desktop conceit slid it away when you "entered the app"). */
body.m3 .mtopbar,
body.m3.app-booted .mtopbar {
  display: flex !important;
  transform: none !important;
  opacity: 1 !important;
  pointer-events: auto !important;
}
/* Retire the app-style bottom tab bar on the marketing site — it read as
   confusing fake app chrome. Section headers carry orientation instead. */
body.m3 .tabbar {
  display: none !important;
}
/* opaque top bar (translucent blur hurt legibility over light content) */
body.m3 .mtopbar {
  background: #0b0b12;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* tap targets: top-bar controls ≥44px, primary CTAs ≥48px (thumb zone) */
body.m3 .mtopbar__signin,
body.m3 .mtopbar__demo {
  min-height: 44px;
}
body.m3 .btn--lg,
body.m3 .cta__actions .btn,
body.m3 .landing__cta .btn {
  min-height: 48px;
}

/* Retire the yellow "what you're seeing" sticky notes — replaced by m-head. */
body.m3 .s3-meta {
  display: none !important;
}
/* The redundant "keep scrolling…" hints add dead space between sections. */
body.m3 .s3-scrollhint,
body.m3 .chat__foreshadow,
body.m3 .dash__foot,
body.m3 .workflows__foot,
body.m3 .nb__foot,
body.m3 .appframe__foot {
  display: none !important;
}

/* ============================ REVEAL MOTION ============================ */
body.m3 .m-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}
body.m3 .m-reveal.is-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  body.m3 .m-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================ SECTION HEADER (m-head) ============================
   Injected above the five app surfaces. The kicker mirrors the nav label so the
   visitor always knows which capability they're looking at. */
body.m3 .m-head {
  margin: 0 0 22px;
  padding: 0;
}
body.m3 .m-head__kicker {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--m-kicker);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--purple);
  margin-bottom: 12px;
}
body.m3 .m-head__title {
  margin: 0;
  font-size: var(--m-h2);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  text-wrap: balance;
}
body.m3 .m-head__sub {
  margin: 12px 0 0;
  font-size: var(--m-body);
  line-height: 1.55;
  font-weight: 300;
  color: var(--text-secondary);
  max-width: 38ch;
}

/* ============================ HERO (landing) ============================ */
body.m3 .landing {
  /* fill the screen below the 52px top bar — no dead bar at the bottom.
     layered fallback: vh (old) → svh (never overflows) → dvh (tracks toolbar).
     flex-start (not center) keeps clear air under the top bar and lets the
     product card peek past the fold (defeats the false floor). */
  min-height: calc(100vh - 52px);
  min-height: calc(100svh - 52px);
  min-height: calc(100dvh - 52px);
  justify-content: flex-start;
  gap: clamp(22px, 3.5vh, 34px);
  padding: clamp(44px, 7vh, 64px) var(--m-gutter) clamp(28px, 4vh, 40px);
}
/* accent the outcome phrase in the headline (set by mobile.js); period stays white */
body.m3 .landing__h1 .m-accent {
  color: #a9a7ff;
}
/* one primary CTA per viewport: Schedule Demo solid + full width, Sign in a
   quiet text link beneath it (the top bar already carries Sign in for returners) */
body.m3 .landing__cta {
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
body.m3 .landing__cta .btn--solid {
  width: 100%;
}
body.m3 .landing__cta .btn--ghost-dark,
body.m3 .cta__secondary,
body.m3 .footer__cta .btn--ghost-dark {
  flex: 0 0 auto;
  min-height: 0;
  width: auto;
  padding: 8px 6px;
  border: none;
  background: none;
  color: rgba(255, 255, 255, 0.72);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
}
body.m3 .landing__cta .btn--ghost-dark:active,
body.m3 .cta__secondary:active {
  background: none;
  color: #fff;
}
body.m3 .landing__hero {
  gap: clamp(26px, 4.5vh, 40px);
}
body.m3 .landing__h1 {
  font-size: var(--m-h1);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin-bottom: 14px;
}
body.m3 .landing__sub {
  font-size: 1.0625rem;
  line-height: 1.55;
  max-width: 34ch;
}
body.m3 .landing__cta {
  flex-wrap: nowrap;
  gap: 12px;
}
body.m3 .landing__cta .btn {
  flex: 1 1 0;
  min-width: 0;
}

/* One clean product card as the hero visual — not three cropped, floating windows. */
body.m3 .herodecks {
  height: auto;
  overflow: visible;
  margin-top: 0;
  -webkit-mask-image: none;
  mask-image: none;
  display: flex;
  justify-content: center;
}
body.m3 .deck--wf,
body.m3 .deck--dash {
  display: none !important;
}
body.m3 .deck--chat {
  position: static;
  transform: none !important;
  rotate: 0deg !important;
  width: 100%;
  max-width: 360px;
  min-width: 0;
  opacity: 1 !important;
}
body.m3 .deck--chat .deck__card {
  box-shadow: 0 24px 60px -26px rgba(0, 0, 0, 0.85);
}
body.m3 .mini-chat {
  min-height: 0;
}

/* ============================ APP SURFACES (shared spacing) ============================
   chat / dashboards / dataapps / workflows / notebooks already collapse to a
   single column via the existing is-stacked rules; here we add header rhythm
   and consistent section padding. */
body.m3 .chat,
body.m3 .dash,
body.m3 .page--dataapps,
body.m3 .page--workflows,
body.m3 .page--notebooks {
  padding: var(--m-pad-y) var(--m-gutter);
  border-top: 1px solid rgba(0, 0, 0, 0.07); /* separate the run of light sections */
}
/* the chat section is otherwise centered/short — let the header lead it */
body.m3 .chat {
  display: block;
}
body.m3 .chat__center {
  align-items: stretch;
}
/* the "Good morning, Morgan." greeting is redundant with the injected m-head */
body.m3 .chat__greeting {
  display: none;
}
/* frame the conversation as a card so it matches the crisp cards elsewhere
   (it used to sit unframed on the bare canvas and crop mid-sentence) */
body.m3 .chat__thread {
  background: var(--paper);
  border: 1px solid var(--divider);
  border-radius: 14px;
  padding: 16px 14px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  margin-bottom: 14px;
}
body.m3 .chat__thread:empty {
  display: none;
}

/* the "context" dock above each artifact reads as a quoted chat, not app chrome */
body.m3 .dock {
  margin-bottom: 18px;
}

/* DASHBOARDS table: drop the Region column on a phone so Account / Q3 Revenue /
   QoQ fit the card with no in-card horizontal scroll. */
body.m3 .widget--table .dtable th:nth-child(2),
body.m3 .widget--table .dtable td:nth-child(2) {
  display: none;
}
body.m3 .widget--table .dtable {
  min-width: 0;
}
body.m3 .widget--table .widget__body {
  overflow-x: visible;
}

/* ---- DATA APPS: stop the work-queue from forcing a 540px horizontal scroll ----
   The desktop queue is a 6-column grid (account/status/ARR/date/owner/action).
   On a phone we drop to a compact 2-line card per row: name + meta on top,
   status · ARR · date below. The expand/detail panel still works. */
body.m3 .appframe__canvas {
  overflow: visible;
}
body.m3 .da-queue {
  min-width: 0;
}
body.m3 .da-qhead {
  display: none !important; /* the garbled overlapping column header */
}
body.m3 .da-row__main {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  grid-template-areas:
    "caret acct status"
    "caret meta  arr";
  align-items: center;
  gap: 2px 10px;
  padding: 13px 12px;
}
body.m3 .da-row__caret {
  grid-area: caret;
  align-self: start;
  margin-top: 3px;
}
body.m3 .da-row__acct {
  grid-area: acct;
  min-width: 0;
}
body.m3 .da-row__name {
  white-space: normal;
}
body.m3 .da-row__meta {
  grid-area: meta;
}
body.m3 .da-badge {
  grid-area: status;
  justify-self: end;
}
body.m3 .da-row__arr {
  grid-area: arr;
  justify-self: end;
  font-variant-numeric: tabular-nums;
}
/* fold the desktop-only date/owner/inline-action out of the compact card */
body.m3 .da-row__date,
body.m3 .da-row__owner,
body.m3 .da-row__act {
  display: none;
}
body.m3 .da-detail__grid {
  padding-left: 0;
}
body.m3 .da-detail__actions {
  padding-left: 0;
}
body.m3 .appframe__share-row {
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
/* let the published app's name wrap instead of truncating to "Renewals — Ac…" */
body.m3 .appframe__name {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.15;
}
body.m3 .appframe__id {
  align-items: center;
  flex-wrap: wrap;
}

/* ---- WORKFLOWS: the mobile vertical pipeline (.swfm) is the right visual ---- */
body.m3 .workflows__graph {
  display: none;
}

/* ============================ ENGINE INTRO (dark) ============================
   ROOT BUG FIX: .page--engine stays display:flex on mobile, so the injected
   note used to become a flex sibling and squeeze the title to half width.
   Force single-column block flow and let the real eyebrow + title lead. */
body.m3 .page--engine,
body.m3 .page--connectors,
body.m3 .page--ledger,
body.m3 .page--model,
body.m3 .page--linking,
body.m3 .page--semantic {
  display: block;
  min-height: 0;
}
/* the engine story is a long run of dark sections — a hairline marks each
   boundary so they don't blur into one endless dark scroll */
body.m3 .page--connectors,
body.m3 .page--ledger,
body.m3 .page--model,
body.m3 .page--linking,
body.m3 .page--semantic {
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
body.m3 .page--engine {
  padding: clamp(56px, 10vh, 80px) var(--m-gutter);
}
body.m3 .engine__center {
  position: relative;
  width: 100%;
  max-width: 100%;
  padding: 0;
  text-align: left;
}
body.m3 .engine__eyebrow {
  opacity: 1;
  margin-bottom: 16px;
}
body.m3 .engine__title {
  max-width: 100%;
  font-size: var(--m-h2);
  line-height: 1.14;
}
body.m3 .engine__line {
  display: inline; /* let the two sentences wrap as normal prose, not two rigid blocks */
  opacity: 1;
}
body.m3 .engine__line + .engine__line {
  margin-top: 0;
}
body.m3 .engine__subhead {
  opacity: 1;
  font-size: var(--m-body);
  margin: 16px 0 0;
  max-width: 42ch;
}
/* the 5-step engine rail wraps to a tidy two-line chip set */
body.m3 .engrail {
  position: static;
  margin: 28px 0 0;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 8px 4px;
  max-width: 100%;
}

/* ============================ ENGINE SUB-SECTIONS (dark, two-column → one) ============================
   connectors / ledger / model / linking / semantic all ship a real eyebrow + h2
   in markup; we just need them single-column with the copy on top, the visual
   below, copy forced visible (the desktop JS fades it in), and no overflow. */
body.m3 .con__wrap,
body.m3 .ledger__wrap,
body.m3 .model__wrap,
body.m3 .linking__inner,
body.m3 .sem__wrap {
  display: block;
  max-width: 100%;
  padding: clamp(48px, 8vh, 68px) var(--m-gutter);
  height: auto;
}
body.m3 .con__copy,
body.m3 .ledger__copy,
body.m3 .linking__copy,
body.m3 .model__head,
body.m3 .sem__head {
  max-width: 100%;
  text-align: left;
  margin: 0 0 26px;
}
/* force all story copy visible regardless of the desktop JS opacity system */
body.m3 .con__copy > *,
body.m3 .ledger__copy > *,
body.m3 .linking__copy > *,
body.m3 .model__head > *,
body.m3 .sem__head > * {
  opacity: 1;
}
body.m3 .con__h2,
body.m3 .ledger__h2,
body.m3 .linking__title,
body.m3 .model__h2,
body.m3 .sem__h2 {
  font-size: var(--m-h2);
  line-height: 1.14;
  letter-spacing: -0.02em;
}
body.m3 .con__body,
body.m3 .ledger__body,
body.m3 .linking__body,
body.m3 .model__subhead,
body.m3 .model__body,
body.m3 .sem__body {
  font-size: var(--m-body);
  line-height: 1.55;
  max-width: 42ch;
}
body.m3 .model__chips,
body.m3 .sem__chips,
body.m3 .con__caps {
  flex-wrap: wrap;
}

/* CONNECTORS: keep the hub graph, just centre + size it for the column. The
   "12 of 12 connected" counter is absolutely positioned at top:-34px, so the
   stage needs ~56px of headroom or it collides with the "It's all automatic"
   line above it. */
body.m3 .con__stage {
  margin: 56px auto 0;
  max-width: 340px;
}
body.m3 .con__auto {
  margin-bottom: 0;
}

/* MODEL: keep the raw→modeled table inside a card that scrolls internally */
body.m3 .model__caps {
  grid-template-columns: 1fr;
}
/* the "Synopsis applies:" line wraps its instruction to full width instead of a
   cramped column squeezed beside the label */
body.m3 .model__instruction {
  flex-wrap: wrap;
  align-items: baseline;
  row-gap: 6px;
}
body.m3 .model__instr-text {
  flex: 1 1 100%;
  white-space: normal;
}
body.m3 .model__table-card {
  margin-top: 22px;
}
body.m3 .model__table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
body.m3 .model__table {
  min-width: 480px;
}

/* LINKING: the two candidate cards + gauge stack vertically */
body.m3 .slink-stage {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 22px;
}
body.m3 .slink-card {
  transform: none !important;
  width: 100%;
}
body.m3 .slink-center {
  flex-direction: row;
  justify-content: center;
  gap: 16px;
}

/* SEMANTIC: the flippable source-doc PILE collapses to a 0-width, 2200px-tall
   absolute element on mobile (a stray vertical line that bleeds into the next
   section) and adds nothing readable. Drop it; the test-case cards + the
   wrong→right answer trace tell the story on their own. */
body.m3 .sem__stack {
  display: none !important;
}
body.m3 .sem__stage {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 4px;
}
body.m3 .sem__right {
  margin-top: 0;
}

/* ============================ LEDGER / engrail shared ============================ */
body.m3 .ledger__stage {
  margin-top: 22px;
}

/* ============================ CUSTOMERS (light) ============================ */
body.m3 .page--customers {
  padding: var(--m-pad-y) var(--m-gutter);
  border-top: 1px solid rgba(0, 0, 0, 0.07);
}
body.m3 .cust__wrap {
  max-width: 100%;
}
body.m3 .cust__cards {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
body.m3 .cust__intro {
  margin-bottom: 22px;
}

/* ============================ CTA + FOOTER ============================ */
body.m3 .page--cta {
  padding: clamp(64px, 12vh, 88px) var(--m-gutter);
  min-height: 0;
}
body.m3 .cta__actions {
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}
body.m3 .cta__actions .btn {
  width: 100%;
}
body.m3 .footer {
  padding: 48px var(--m-gutter) calc(28px + env(safe-area-inset-bottom, 0px));
}
body.m3 .footer__inner {
  gap: 32px;
}
body.m3 .footer__cols {
  gap: 28px 40px;
}

/* ============================ REV4 — REVIEW FIXES ============================ */

/* (#7) dark-surface body text meets ≥4.5:1 — the desktop greys dip below on dark */
body.m3 .engine__subhead,
body.m3 .ledger__body,
body.m3 .linking__body,
body.m3 .sem__body,
body.m3 .model__subhead,
body.m3 .model__body {
  color: #c5cad3;
}

/* (#8) MODEL header: collapse the competing indigo subhead + grey body into ONE
   sub. Keep the punchy subhead (restyled as a plain sub); drop the redundant body. */
body.m3 .model__subhead {
  font-weight: 400;
  font-size: var(--m-body);
  letter-spacing: 0;
}
body.m3 .model__body {
  display: none;
}

/* (#4) ENGINE intro: kill the dead band under the pipeline and promote the
   Ingest→Understand rail from faint micro-caps to a legible, higher-contrast
   visual that earns its place. */
body.m3 .page--engine {
  padding-bottom: clamp(36px, 6vh, 52px);
}
body.m3 .engrail {
  gap: 6px 10px;
  margin-top: 26px;
}
body.m3 .engrail__step {
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: #cdccf5;
}
body.m3 .engrail__dot {
  background: #8b88ff;
  box-shadow: 0 0 8px rgba(124, 122, 255, 0.6);
}
body.m3 .engrail__line,
body.m3 .engrail__cx {
  background: rgba(124, 122, 255, 0.4);
}

/* (#14) CONNECTORS: the emphatic line read as a hyperlink (purple + underline) */
body.m3 .con__auto {
  text-decoration: none;
  font-weight: 600;
}

/* (#17) LINKING: the "Auto-merged" verdict pill rendered twice (standalone above
   the record + inside its header). Keep the in-card one only. */
body.m3 .slink-verdict {
  display: none;
}

/* (#19) DASHBOARDS: give the artifact's title + "+ Widget" + filter chips room
   and comfortable tap sizes (they were cramped together at the card top). */
body.m3 .board .page-header {
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}
body.m3 .board .page-header__title {
  flex: 1 1 auto;
}
body.m3 .board .hbtn {
  min-height: 40px;
}
body.m3 .board__filterbar {
  gap: 8px;
}
body.m3 .board__filterbar .filter-chip {
  min-height: 34px;
  padding: 7px 13px;
}

/* (#20) the faux chat composer is a static mockup — soften its send glyph so it
   doesn't read as a live button inviting a dead tap */
body.m3 .mini-chat__send,
body.m3 .promptbox__send {
  opacity: 0.5;
}

/* ============================ REV7 — 2nd-review polish ============================ */

/* Customers header was centered while the whole site (and its own cards) are
   left-aligned — bring it onto the same eyebrow→heading→sub rhythm. */
body.m3 .cust__intro {
  text-align: left;
}

/* Standardize every DARK-section eyebrow to one accent (they ranged from muted
   grey-purple to bright blue to purple, reading off-system while scrolling). */
body.m3 .engine__eyebrow,
body.m3 .con__eyebrow,
body.m3 .ledger__eyebrow,
body.m3 .model__eyebrow,
body.m3 .linking__eyebrow,
body.m3 .sem__eyebrow {
  color: #a9a7ff;
}

/* Engine 5-stage rail: fit Ingest→Understand on ONE line (it was orphan-wrapping
   "UNDERSTAND" alone) by tightening the labels and connectors. */
body.m3 .engrail {
  flex-wrap: nowrap;
  gap: 4px 5px;
  justify-content: space-between;
}
body.m3 .engrail__step {
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  gap: 5px;
  white-space: nowrap;
}
body.m3 .engrail__line,
body.m3 .engrail__cx {
  flex: 1 1 auto;
  min-width: 6px;
  width: auto;
}
