/*
 * marketing/site.css — RectifyHQ marketing site, foundation stylesheet.
 *
 * Hand-authored, no build step, no framework. Shared by every page under
 * marketing/ (spec #585 slice #587). Design contract:
 * docs/design/marketing/README.md + Export Notes.md (DESIGN.md EX-L1.marketing).
 *
 * Token provenance: the base zinc swatches below are pinned 1:1 to
 * apps/rectify-hq/src/integrations/email/theme.ts's `EMAIL` export — the
 * SAME shared zinc source EX-L1.email already established for a
 * non-build-pipeline surface (transactional email). theme.ts documents the
 * app's LIGHT theme role assignment (card/frame/fg/muted/border/primary/
 * primaryFg); marketing's dark canvas reuses the identical hex literals at
 * DIFFERENT semantic roles (same zinc scale, inverted mapping — the same
 * relationship shadcn's own light/dark zinc themes have to each other).
 * A parity test (apps/rectify-hq/src/integrations/email/__tests__/
 * marketing-tokens.test.ts, AC-587.7) asserts the `--email-*` custom
 * properties below stay byte-identical to theme.ts. Do not hand-edit them
 * independently of that module.
 */

:root {
  /* ---- Layer 1: base swatches pinned to theme.ts's EMAIL export. Keep
     these SEVEN exactly as theme.ts defines them — the nudges below live
     in Layer 3, never here. */
  --email-card: #ffffff;       /* theme.ts EMAIL.card */
  --email-frame: #f4f4f5;      /* theme.ts EMAIL.frame (unused on the dark
                                   canvas; kept only for 1:1 parity) */
  --email-fg: #09090b;         /* theme.ts EMAIL.fg */
  --email-muted: #71717a;      /* theme.ts EMAIL.muted — the EXPORT'S
                                   original muted value, pre-nudge */
  --email-border: #e4e4e7;     /* theme.ts EMAIL.border */
  --email-primary: #18181b;    /* theme.ts EMAIL.primary */
  --email-primary-fg: #fafafa; /* theme.ts EMAIL.primaryFg */

  /* ---- Layer 2: the rest of the zinc scale the dark canvas needs that
     isn't one of theme.ts's 7 email roles (docs/design/marketing/README.md
     "Design tokens"). */
  --zinc-400: #a1a1aa;
  --zinc-800: #27272a;
  --zinc-700: #3f3f46;

  /* ---- Layer 3: marketing role tokens — what markup actually uses.
     TWO operator-approved contrast nudges off the design export (re-review
     finding 1, decided 2026-07-20; spec #587 AC-587.6/587.9). Everything
     else in this sheet is the export verbatim.
       muted #71717a -> #82828c  (~5.5:1 on #000; the original is ~4.35:1,
                                   under the 4.5:1 AA floor for body text)
       faint #52525c -> #6a6a75  (~3.9:1 on #000; the original is ~2.72:1,
                                   under the 3:1 AA floor for large/
                                   decorative text)
     `marketing-tokens.test.ts`'s contrast check pins both nudged values in
     and both originals out of these two role tokens. */
  --bg-canvas: #000000;
  --surface-card: var(--email-fg);          /* #09090b — raised surfaces */
  --surface-hover: var(--email-primary);    /* #18181b — hover fills */
  --border-subtle: var(--email-primary);    /* #18181b */
  --border-standard: var(--zinc-800);       /* #27272a */
  --border-emphasis: var(--zinc-700);       /* #3f3f46 */
  --text-heading: var(--email-primary-fg);  /* #fafafa */
  --text-body: var(--zinc-400);             /* #a1a1aa */
  --text-muted: #82828c;                    /* NUDGED, was var(--email-muted) */
  --text-faint: #6a6a75;                    /* NUDGED, was #52525c */
  --btn-primary-bg: var(--email-primary-fg);
  --btn-primary-fg: var(--email-fg);
  --btn-primary-hover: var(--email-border); /* #e4e4e7 */
  --link-color: var(--email-primary-fg);
  --link-hover: var(--email-card);          /* #ffffff */
  --selection-bg: var(--zinc-800);
  --selection-fg: var(--email-primary-fg);
  --focus-ring: var(--email-primary-fg);
  --header-pill-bg: rgba(9, 9, 11, 0.85);
  --panel-bg: rgba(9, 9, 11, 0.97);
  --font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --ease-settle: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ===== Reset & base typography ===== */

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

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

body {
  margin: 0;
  background: var(--bg-canvas);
  color: var(--text-body);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
}

h1, h2, h3, p, ul, figure { margin: 0; }

img, svg { display: block; max-width: 100%; }

a {
  color: var(--link-color);
  text-decoration: none;
}
a:hover { color: var(--link-hover); }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

::selection {
  background: var(--selection-bg);
  color: var(--selection-fg);
}

h1 {
  font-size: clamp(38px, 6.5vw, 68px);
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 600;
  color: var(--text-heading);
  text-wrap: balance;
}
h1.h1-narrow { font-size: clamp(34px, 5.5vw, 56px); }
h1.h1-usecase { font-size: clamp(36px, 6vw, 60px); }

h2 {
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 600;
  color: var(--text-heading);
  text-wrap: balance;
}

h3 {
  font-size: 19px;
  font-weight: 600;
  color: var(--text-heading);
}

.eyebrow {
  margin: 0 0 20px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.lede {
  font-size: clamp(17px, 2vw, 20px);
  line-height: 1.65;
  color: var(--text-body);
  text-wrap: pretty;
}

.body-copy {
  font-size: 17px;
  line-height: 1.7;
  text-wrap: pretty;
}

/* ===== Layout ===== */

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

main { background: var(--bg-canvas); position: relative; overflow: hidden; }

.section {
  border-top: 1px solid var(--border-subtle);
}
.section-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: clamp(72px, 10vw, 120px) 24px;
}

/* ===== Buttons & links ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  padding: 0 24px;
  border-radius: 10px;
  font-size: 16px;
  text-decoration: none;
  white-space: nowrap;
}
.btn-primary {
  background: var(--btn-primary-bg);
  color: var(--btn-primary-fg);
  font-weight: 600;
}
.btn-primary:hover { background: var(--btn-primary-hover); color: var(--btn-primary-fg); }
.btn-ghost {
  background: transparent;
  color: var(--text-heading);
  border: 1px solid var(--border-standard);
}
.btn-ghost:hover { background: var(--surface-hover); color: var(--text-heading); }

.btn-cta svg { transition: transform 0.18s var(--ease-settle); }
.btn-cta:hover svg { transform: translateX(3px); }

.pill-link {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 14px;
  padding: 8px 12px;
  border-radius: 999px;
}
.pill-link:hover { color: var(--text-heading); background: var(--surface-hover); }

.pill-btn-primary {
  color: var(--btn-primary-fg);
  background: var(--btn-primary-bg);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 999px;
  margin-left: 4px;
}
.pill-btn-primary:hover { background: var(--btn-primary-hover); color: var(--btn-primary-fg); }

/* ===== Header — floating pill ===== */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  padding: 12px 16px 0;
}

.header-pill {
  max-width: 920px;
  margin: 0 auto;
  border: 1px solid var(--border-standard);
  border-radius: 999px;
  background: var(--header-pill-bg);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  padding: 0 8px 0 18px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.brand-link {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text-heading);
}
.brand-link img { display: block; }
.brand-wordmark { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }

.desk-nav { display: none; }
.mobile-nav { display: block; }
@media (min-width: 760px) {
  .desk-nav { display: flex; align-items: center; gap: 2px; }
  .mobile-nav { display: none; }
}

.nav-dd { position: relative; }
.nav-dd-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  color: var(--text-muted);
  font-size: 14px;
  padding: 8px 12px;
  border-radius: 999px;
}
.nav-dd-trigger:hover { color: var(--text-heading); background: var(--surface-hover); }
.nav-dd-caret { transition: transform 0.18s var(--ease-settle); }
.nav-dd:hover .nav-dd-caret,
.nav-dd:focus-within .nav-dd-caret { transform: rotate(180deg); }

.nav-dd-panel {
  position: absolute;
  left: -8px;
  top: calc(100% + 14px);
  width: 340px;
  background: var(--panel-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--border-standard);
  border-radius: 16px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* visibility:hidden is load-bearing (README) — opacity-only would leave
     the backdrop blur smearing the hero even while invisible. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px) scale(0.98);
  transform-origin: top left;
  pointer-events: none;
  transition: opacity 0.18s var(--ease-settle), transform 0.18s var(--ease-settle), visibility 0.18s;
}
/* Invisible 16px hover bridge above the panel — prevents flicker crossing
   the gap between the trigger and the panel. */
.nav-dd-panel::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -16px;
  height: 16px;
}
.nav-dd:hover .nav-dd-panel,
.nav-dd:focus-within .nav-dd-panel {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}
@media (prefers-reduced-motion: reduce) {
  .nav-dd-panel, .nav-dd-caret { transition: none; }
}

.nav-dd-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 10px 12px;
  border-radius: 10px;
  text-decoration: none;
}
.nav-dd-item:hover { background: var(--surface-hover); }
.nav-dd-icon {
  width: 32px; height: 32px; flex: none;
  border: 1px solid var(--border-standard);
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-body);
  background: var(--surface-card);
}
.nav-dd-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nav-dd-title { font-size: 14.5px; font-weight: 600; color: var(--text-heading); }
.nav-dd-sub { font-size: 12.5px; line-height: 1.45; color: var(--text-muted); }

.menu-summary {
  cursor: pointer;
  display: flex;
  align-items: center;
  color: var(--text-heading);
  font-size: 14px;
  padding: 8px 14px;
  /* #814 operator refinement: borderless — the bare icon is the whole
     affordance; radius kept so the focus ring stays pill-shaped. */
  border-radius: 999px;
  list-style: none;
}
.menu-summary::-webkit-details-marker { display: none; }
/* #814: icon-only burger→X trigger (replaces #615's "Menu" + rotating caret;
   the reference still ships the static "Menu" pill). The outer lines sit
   3.5px off the svg's centre row, so translateY(±3.5px) lands them exactly
   on it before the ±45° rotate; transform-box: fill-box keeps each line's
   own centre as the rotation origin. */
.burger-line {
  transition: transform 0.18s var(--ease-settle), opacity 0.18s var(--ease-settle);
  transform-box: fill-box;
  transform-origin: center;
}
details.mobile-details[open] .burger-top { transform: translateY(3.5px) rotate(45deg); }
details.mobile-details[open] .burger-mid { opacity: 0; }
details.mobile-details[open] .burger-bot { transform: translateY(-3.5px) rotate(-45deg); }
details.mobile-details { position: relative; }
.mobile-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  /* #615: widened from the reference's 250px — the "How it helps" items now
     carry the desktop dropdown's 32px icon-tile anatomy (below), which needs
     more room than plain text links; max-width keeps it clear of a narrow
     phone's left edge. */
  min-width: 288px;
  max-width: calc(100vw - 32px);
  background: var(--panel-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--border-standard);
  border-radius: 16px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.mobile-link {
  color: var(--text-heading);
  text-decoration: none;
  font-size: 16px;
  padding: 12px 14px;
  border-radius: 10px;
}
.mobile-link:hover { background: var(--surface-hover); }
.mobile-cta {
  color: var(--btn-primary-fg);
  background: var(--btn-primary-bg);
  font-weight: 600;
  text-decoration: none;
  font-size: 16px;
  padding: 12px 14px;
  border-radius: 999px;
  text-align: center;
  margin-top: 6px;
}

/* ===== Footer ===== */

.site-footer { border-top: 1px solid var(--border-subtle); }
.footer-inner { max-width: 1120px; margin: 0 auto; padding: 56px 24px 28px; }
.footer-cols { display: flex; flex-wrap: wrap; gap: 40px 64px; }
.footer-brand { flex: 1 1 260px; min-width: 240px; display: flex; flex-direction: column; gap: 14px; }
.footer-brand-link { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text-heading); width: fit-content; }
.footer-brand-name { font-size: 21px; font-weight: 600; letter-spacing: -0.015em; }
.footer-tagline { margin: 0; font-size: 15px; line-height: 1.6; color: var(--text-body); max-width: 30ch; }
.footer-email { font-size: 14px; color: var(--text-muted); text-decoration: none; width: fit-content; }
.footer-email:hover { color: var(--text-heading); }
.footer-col { display: flex; flex-direction: column; gap: 10px; min-width: 150px; }
/* #689: was --text-faint (3.93:1) — below the 4.5:1 AA floor for text this
   size (12px, well under the 18.66px/700-weight large-text carve-out).
   --text-muted clears 4.5:1. --text-faint is left declared with no usage
   site — retiring it is a separate follow-up, not this fix. */
.footer-col-title {
  margin: 0 0 2px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.footer-link { font-size: 14px; color: var(--text-muted); text-decoration: none; width: fit-content; }
.footer-link:hover { color: var(--text-heading); }
.footer-bottom {
  margin-top: 44px;
  padding-top: 20px;
  border-top: 1px solid var(--border-subtle);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
}
/* #689: was --text-faint (3.93:1), below the 4.5:1 AA floor at 13px. */
.footer-bottom p { margin: 0; font-size: 13px; color: var(--text-muted); }
/* Legal entity identification (business name -> Pty Ltd). Last in the DOM and
   flex-basis:100%, so it wraps onto its own full-width row BELOW the
   copyright/made-in pair; no other footer change. */
.footer-legal { flex-basis: 100%; }

/* ===== Related links (use-case pages, #689) =====
   Contextual in-body cross-links between the three use-case pages
   (defects/handover/managers) — distinct from the mega-menu and footer,
   which already link every page to every other via unrelated selectors. */
.related-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px 28px;
  padding-top: 32px;
  border-top: 1px solid var(--border-subtle);
}
.related-links a { font-size: 15px; color: var(--text-body); }
.related-links a:hover { color: var(--text-heading); }

/* DESIGN.md L11 — mobile touch targets are >=44px, and L11 binds here because
   DESIGN.md's Scope line covers `marketing/`. These anchors are 17.5px on their
   own line box (15px text, no padding), so below the 760px desktop breakpoint
   they take the floor as a min-height with the label centred inside it. Scoped to
   mobile deliberately: at desktop widths they are pointer targets in a text flow
   and L11's floor does not apply, so the desktop rendering is unchanged.
   Measured live at 386px before the fix: 17.5px (rectify-hq#699). */
@media (max-width: 759px) {
  .related-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ===== Article template (Privacy / Terms) =====
   docs/design/marketing/README.md: "Shared quiet article template: 680px
   measure, h1 clamp(32px,5vw,44px), h2 22px sections, 17px/1.75 body." Scoped
   to the `article` element rather than named classes — Privacy and Terms
   both wrap their content in a bare <article>, so this composes with the
   base h1/h2 rules above (color/weight/text-wrap stay inherited from
   those). */
.article-date { margin: 0; font-size: 14px; color: var(--text-muted); }
article h1 { font-size: clamp(32px, 5vw, 44px); line-height: 1.12; letter-spacing: -0.025em; }
article h2 { margin-top: 44px; font-size: 22px; letter-spacing: -0.01em; }
article p { margin: 14px 0 0; font-size: 17px; line-height: 1.75; text-wrap: pretty; }
article h1 + p { margin-top: 24px; }

/* Lists inside the article template (spec #713 slice #714). None existed
   before: Privacy and Terms were pure h1/h2/p until the sub-processor
   disclosure needed something scannable. Sized to the same 17px/1.75 rhythm as
   `article p`, so a list reads as body copy rather than as a UI control. */
article ul { margin: 14px 0 0; padding-left: 22px; }
article li { margin-top: 8px; font-size: 17px; line-height: 1.75; color: var(--text-body); text-wrap: pretty; }
article li::marker { color: var(--text-faint); }

/* The sub-processor disclosure (Privacy → "Who else handles your data").
   Discrete stacked rows, not inline citations: each row is one processor, so a
   reader scanning for "who else sees my data" can count them without reading
   prose. Hairline dividers only — DESIGN.md's depth rule admits no shadows. */
.subprocessors { list-style: none; margin-top: 20px; padding-left: 0; border-top: 1px solid var(--border-subtle); }
.subprocessors > li { margin-top: 0; padding: 14px 0; border-bottom: 1px solid var(--border-subtle); }
.subprocessors .sp-name { color: var(--text-heading); font-weight: 600; }
.subprocessors a { color: var(--link-color); text-decoration: underline; text-underline-offset: 3px; }

/* DESIGN.md L11 — same shape as the `.related-links a` floor above, and for the
   same reason: these anchors sit alone at the end of their row, so below the
   760px desktop breakpoint they are discrete touch targets and take the 44px
   floor. Scoped to mobile deliberately; at desktop they are pointer targets in
   a text flow, which L11's own text puts out of scope. */
@media (max-width: 759px) {
  .subprocessors a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* DESIGN.md L11 — #702's remainder: `.menu-summary` (a real tap control,
   measured 34.5px live) and the footer's `.footer-link`/`.footer-email` list
   (16.5px) both missed the floor #699 already gave `.related-links a`. Widened
   here to the two brand marks (`.brand-link`, `.footer-brand-link`) for the same
   reason, and `.footer-col`'s gap collapses to 0 so the column stays as short as
   the floor allows — contiguous 44px tap rows, not floored rows with the old
   10px gaps stacked on top. Scoped to mobile deliberately, same as the two
   floors above: at desktop widths these are pointer targets in a compact layout
   and L11's floor does not apply. */
/* Below the desktop breakpoint the footer-bottom row has no width to hold a
   space-between pair: at 320px the copyright and made-in lines closed to 14px
   of each other, reading as a collision rather than as two ends. Stack all
   three left-aligned instead, matching every other column in the mobile
   footer. */
@media (max-width: 759px) {
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 759px) {
  .menu-summary, .brand-link, .footer-brand-link {
    min-height: 44px;
  }
  .footer-link, .footer-email {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .footer-col {
    gap: 0;
  }
}

/* ===== FAQ (pricing) ===== */
.faq-list {
  margin-top: 28px;
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border-standard);
}
.faq-item { border-bottom: 1px solid var(--border-standard); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 4px;
  font-size: 17px;
  font-weight: 600;
  color: var(--text-heading);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-caret { flex: none; transition: transform 0.15s; }
.faq-item[open] .faq-caret { transform: rotate(180deg); }
.faq-answer { margin: 0; padding: 0 4px 20px; font-size: 16px; line-height: 1.7; text-wrap: pretty; }

/* ===== Mock frame pattern ===== */
/* Every "app screenshot" is hand-built markup, aria-hidden, never an image. */

.mock-figure { margin: 0; }
.mock-frame {
  border: 1px solid var(--border-standard);
  border-radius: 14px;
  background: var(--surface-card);
  padding: 8px;
}
.mock-viewport {
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-canvas);
  text-align: left;
}
.mock-caption {
  margin-top: 12px;
  text-align: center;
  font-size: 14px;
  color: var(--text-muted);
}

/* ===== Mock animation system =====
   docs/design/marketing/README.md "Mock animation system": CSS-only
   staggered loops, opacity/translateY only (no layout shift). mkA…mkF beat
   at ~3/19/39/57/73/84% of a 14s loop, all fade at 98%. */

@keyframes mkA { 0% { opacity: 0; transform: translateY(6px); } 3%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkB { 0%, 15% { opacity: 0; transform: translateY(6px); } 19%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkC { 0%, 35% { opacity: 0; transform: translateY(6px); } 39%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkD { 0%, 53% { opacity: 0; transform: translateY(6px); } 57%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkE { 0%, 69% { opacity: 0; transform: translateY(6px); } 73%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkF { 0%, 80% { opacity: 0; transform: translateY(6px); } 84%, 94% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }

/* The landing search + email mocks run a 12s loop. */
@keyframes mkSceneA { 0%, 44% { opacity: 1; } 50%, 94% { opacity: 0; } 99%, 100% { opacity: 1; } }
@keyframes mkSceneB { 0%, 46% { opacity: 0; } 52%, 94% { opacity: 1; } 99%, 100% { opacity: 0; } }
@keyframes mkPress { 0%, 38% { transform: none; } 41% { transform: scale(0.95); } 44%, 100% { transform: none; } }
@keyframes mkTypeA { 0%, 2% { max-width: 0; border-color: var(--zinc-400); } 16% { max-width: 200px; border-color: var(--zinc-400); } 44% { max-width: 200px; border-color: var(--zinc-400); } 48% { max-width: 0; border-color: var(--zinc-400); } 49%, 100% { max-width: 0; border-color: transparent; } }
@keyframes mkTypeB { 0%, 50% { max-width: 0; border-color: transparent; } 52% { max-width: 0; border-color: var(--zinc-400); } 66% { max-width: 220px; border-color: var(--zinc-400); } 96% { max-width: 220px; border-color: var(--zinc-400); } 99%, 100% { max-width: 0; border-color: transparent; } }
@keyframes mkShowB { 0%, 49% { opacity: 0; } 50%, 97% { opacity: 1; } 99%, 100% { opacity: 0; } }
@keyframes mkRowA1 { 0%, 7% { opacity: 0; transform: translateY(4px); } 10%, 44% { opacity: 1; transform: none; } 47%, 100% { opacity: 0; } }
@keyframes mkRowA2 { 0%, 10% { opacity: 0; transform: translateY(4px); } 13%, 44% { opacity: 1; transform: none; } 47%, 100% { opacity: 0; } }
@keyframes mkRowA3 { 0%, 13% { opacity: 0; transform: translateY(4px); } 16%, 44% { opacity: 1; transform: none; } 47%, 100% { opacity: 0; } }
@keyframes mkRowB1 { 0%, 58% { opacity: 0; transform: translateY(4px); } 61%, 95% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkRowB2 { 0%, 61% { opacity: 0; transform: translateY(4px); } 64%, 95% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkRowB3 { 0%, 64% { opacity: 0; transform: translateY(4px); } 67%, 95% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes mkCaret { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

.mk-hl {
  color: var(--text-heading);
  background: var(--border-standard);
  border-radius: 3px;
  padding: 0 3px;
  font-weight: 500;
}

.mk-a { animation: mkA 14s linear infinite; }
.mk-b { animation: mkB 14s linear infinite; }
.mk-c { animation: mkC 14s linear infinite; }
.mk-d { animation: mkD 14s linear infinite; }
.mk-e { animation: mkE 14s linear infinite; }
.mk-f { animation: mkF 14s linear infinite; }

/* Reveal-beat elements start in DOM order with layout already reserved
   (opacity/translateY only) so removing the animation never shifts
   heights — the reduced-motion complete-static-state guarantee below. */

.mk-cta svg { transition: transform 0.18s var(--ease-settle); }
.mk-cta:hover svg { transform: translateX(3px); }

/* prefers-reduced-motion: every mock collapses to ONE complete, static
   scene — no partial reveal, no content that stays hidden forever except
   the deliberately-inline-opacity:0 alternate scenes the markup itself
   marks as the "not shown by default" half of a scene swap (README: mkA…F
   items have no inline opacity — with animation:none they simply render
   at their base CSS opacity, i.e. fully visible/complete). */
@media (prefers-reduced-motion: reduce) {
  main * { animation: none !important; }
  .nav-dd-panel, .nav-dd-caret, .btn-cta svg, .mk-cta svg, .faq-caret, .burger-line { transition: none; }
}

/* ===== Responsive mock adaptations (README "Responsive rules") ===== */
/* 720px: fixed mock heights become auto; the landing hero mock's chat
   sidebar hides; the landing Issues two-pane mock stacks vertically
   (chat 340px, detail below, its border flips from left to top). */
@media (max-width: 719px) {
  .mk-mock { height: auto !important; }
  .mk-side { display: none !important; }
  .mk-issues { flex-direction: column !important; height: auto !important; }
  .mk-ichat { height: 340px !important; flex: none !important; }
  .mk-idetail { width: auto !important; border-left: 0 !important; border-top: 1px solid var(--border-subtle) !important; }
}
/* 520px: the managers Issues-table mock drops its assignee column. */
@media (max-width: 519px) {
  .mk-tbl { grid-template-columns: 1fr 58px 78px !important; }
  .mk-tbl > *:nth-child(3) { display: none !important; }
}

/* ===== Auth-cluster visibility (spec #614 — pre-paint auth hint) =====
   The inline <head> script in every page (before this stylesheet link)
   sets html[data-auth] from a sessionStorage hint before first paint;
   site.js's background fetch to /api/auth/get-session corrects it once it
   resolves. CSS owns cluster visibility now — site.js no longer toggles the
   `hidden` attribute directly (author styles override the UA `[hidden]`
   rule regardless of specificity, so this cleanly wins over the markup's
   static `hidden` attribute on the signed-in cluster).
   No-JS fallback: with JS disabled the inline script never runs, so <html>
   carries NO data-auth attribute at all. The attribute-less default below
   (html:not([data-auth="in"])) renders identically to today's JS-disabled
   state: signed-out cluster visible, signed-in cluster hidden. */
html:not([data-auth="in"]) [data-auth="signed-out"] { display: inline; }
html:not([data-auth="in"]) [data-auth="signed-in"] { display: none; }
html[data-auth="in"] [data-auth="signed-out"] { display: none; }
html[data-auth="in"] [data-auth="signed-in"] { display: inline; }

/* ===== Cross-document view transitions (Export Notes.md) ===== */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vtOut 0.2s ease both; }
::view-transition-new(root) { animation: vtIn 0.3s ease both; }
@keyframes vtIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes vtOut { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
.site-header { view-transition-name: site-header; }
