body { font-family: 'Charter', 'Georgia', serif; -webkit-font-smoothing: antialiased; }

/* ============================================================ */
/* Hero Demo — first-screen live simulator                      */
/* Pre-boot: black stage. Post-boot: paper-light reveal.        */
/* ============================================================ */
.hero-demo {
  position: relative;
  min-height: 100svh;
  padding: 32px 24px 28px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* Underlying paper-light surface, revealed once is-booted fades the overlay */
  background: linear-gradient(180deg, #fafaf9 0%, #ffffff 60%);
  color: #1c1917;
}
/* Black hero overlay covers the whole stage pre-boot, fades on boot */
.hero-demo::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 78% 60% at 50% 48%, #15151a 0%, #08080b 58%, #000 100%);
  z-index: 0;
  pointer-events: none;
  transition: opacity 720ms cubic-bezier(0.4, 0, 0.2, 1);
}
.hero-demo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, transparent 60%, rgba(0,0,0,0.55) 100%);
  z-index: 0;
  pointer-events: none;
  transition: opacity 720ms cubic-bezier(0.4, 0, 0.2, 1);
}
.hero-demo.is-booted::before,
.hero-demo.is-booted::after {
  opacity: 0;
}
.hero-demo > * {
  position: relative;
  z-index: 1;
}

/* Phone shell — pre-boot we hide every trace of the device (bezel, side
   buttons, drop shadow, AND the screen + boot-button background) so the
   power glyph floats in a pure black void. After boot the shell fades in
   to give the iframe a real-device feel on the light bg. */
.hero-demo #demo-frame {
  box-shadow: none;
  transition: box-shadow 540ms cubic-bezier(0.4, 0, 0.2, 1) 200ms,
              background-color 540ms cubic-bezier(0.4, 0, 0.2, 1) 200ms;
}
.hero-demo:not(.is-booted) #demo-frame,
.hero-demo:not(.is-booted) #demo-boot-btn {
  background: transparent !important;
}
.hero-demo.is-booted #demo-frame {
  box-shadow:
    0 0 0 2px #16181c,
    0 0 0 3px rgba(255,255,255,0.04),
    0 30px 60px -15px rgba(0,0,0,0.5),
    0 12px 24px -10px rgba(0,0,0,0.3);
}
/* Phone visual scale based on viewport HEIGHT — phone is 800px tall and
   nearly fills 13"/14" laptop viewports, clipping the bottom + crashing
   into the SCROLL hint. Scale down visually so it always fits.
     • Layout box stays 800px (iframe needs that as its design viewport)
     • transform: scale doesn't break iframe coords — browsers remap mouse
       events through the transform automatically
     • Anchored at "center top" so the bottom shifts up, NOT the top — the
       SCROLL hint at the viewport bottom gains room.
     • clamp(0.7, …, 1) — scale never above 1 (no upscaling on tall
       monitors) and never below 0.7 (phone stays readable)
   Reserve is scoped: narrow screens keep the command bar pinned to the
   bottom, so they reserve ~200px so the phone never sits under it; wide
   screens (≥1180px) move the command bar to the LEFT flank, freeing the
   bottom — there the phone gets a bigger 120px reserve override below. */
.hero-demo .demo-phone-wrap {
  --phone-scale: clamp(0.7, calc((100vh - 100px) / 800px), 1);
  transform-origin: center top;
  transform: scale(var(--phone-scale));
  /* Negative margin-bottom compensates for the phantom layout space below
     the phone: scale visually shrinks the phone but the layout box stays
     800px tall, so without this the hero (and any surrounding flex/grid
     centering) reserves 215px of empty space below the visually-smaller
     phone. Pulling the bottom edge up by (1 - scale) * 800px makes the
     layout match what the user sees. */
  margin-bottom: calc((var(--phone-scale) - 1) * 800px);
  transition:
    transform 360ms cubic-bezier(0.4, 0, 0.2, 1),
    margin-bottom 360ms cubic-bezier(0.4, 0, 0.2, 1);
}

.hero-demo .demo-phone-wrap > div > span {
  opacity: 0;
  transition: opacity 540ms cubic-bezier(0.4, 0, 0.2, 1) 200ms;
}
.hero-demo.is-booted .demo-phone-wrap > div > span {
  opacity: 1;
}

/* Boot button label — uppercase spaced caption echoing the SCROLL hint
   typography. Avoids the "loud sentence" feel of the original 16px text. */
.hero-boot-label {
  margin-top: 14px;
  font: 500 10.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  transition: color 240ms ease;
}
.hero-demo #demo-boot-btn:hover .hero-boot-label {
  color: rgba(255, 255, 255, 0.78);
}

/* Boot button — breathing aura + pulsing ring, anchored to the inner circle
   (NOT the button itself: flex centering offsets the button's 50% so a
   button-anchored aura would land above the circle). */
.hero-demo #demo-boot-btn > span:first-child {
  position: relative;
  isolation: isolate;
}
.hero-demo #demo-boot-btn > span:first-child::before {
  content: '';
  position: absolute;
  inset: -22px;
  border-radius: 999px;
  background:
    radial-gradient(circle, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0.03) 45%, transparent 72%);
  filter: blur(2px);
  animation: hero-aura 3.4s ease-in-out infinite;
  pointer-events: none;
  z-index: -1;
}
.hero-demo #demo-boot-btn > span:first-child::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.32);
  opacity: 0;
  animation: hero-ring 2.8s ease-out infinite;
  pointer-events: none;
}
.hero-demo #demo-boot-btn:hover > span:first-child::before {
  animation-duration: 2.4s;
}

@keyframes hero-aura {
  0%, 100% { transform: scale(0.9);  opacity: 0.45; }
  50%      { transform: scale(1.2);  opacity: 0.95; }
}
@keyframes hero-ring {
  0%   { transform: scale(0.94); opacity: 0; }
  20%  { opacity: 0.55; }
  100% { transform: scale(1.6);  opacity: 0; }
}

/* State Builder is no longer a hero card — its pre-boot fade is now
   handled by .state-dock (vertical pill on phone right edge) and
   .state-drawer (fixed right slide-in). See bottom of file. */

/* Hero overlay top bar — brand on the left, resource pills + power-off on
   the right. Both groups stay hidden pre-boot (preserving the pure black
   void) and fade in once the simulator is started. */
.hero-demo-brand,
.hero-demo-actions {
  position: absolute;
  top: 22px;
  z-index: 3;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition:
    opacity 540ms cubic-bezier(0.4, 0, 0.2, 1) 380ms,
    transform 540ms cubic-bezier(0.4, 0, 0.2, 1) 380ms;
}
.hero-demo.is-booted .hero-demo-brand,
.hero-demo.is-booted .hero-demo-actions {
  opacity: 1;
  transform: translateY(0);
}
.hero-demo.is-booted .hero-demo-actions { pointer-events: auto; }

.hero-demo-brand {
  left: 32px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hero-demo-brand-name {
  font: 700 16px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
  color: #1c1917;
}
.hero-demo-brand-meta {
  font: 500 9.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #a8a29e;
}

.hero-demo-actions {
  right: 24px;
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Language switch — a flat globe + current-language label that shares the
   borderless weight of the arXiv / Star / Power-off actions (it reuses
   .hero-demo-action). One click cycles between English and 中文; i18n.js
   swaps the label text. */
.hero-demo-lang {
  gap: 5px;
}
.hero-demo-lang-globe {
  opacity: 0.7;
  transition: opacity 200ms ease;
}
.hero-demo-lang:hover .hero-demo-lang-globe {
  opacity: 1;
}
.hero-demo-lang-current {
  font: 600 12.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
  min-width: 16px;
  text-align: center;
}
/* Top-right utility buttons — arXiv wordmark, GitHub mark, Power off.
   All borderless to match the same low-key visual weight; brand identity
   carries the meaning (arXiv red wordmark, GitHub octocat). Hover reveals
   a subtle background tint, matching .hero-demo-poweroff. */
.hero-demo-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 10px;
  color: #57534e;
  background: transparent;
  border: 0;
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
  transition: color 200ms ease, background 200ms ease;
}
.hero-demo-action:hover {
  color: #1c1917;
  background: rgba(28, 25, 23, 0.04);
}
.hero-demo-arxiv-mark {
  font: 800 14px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.02em;
  color: #B31B1B;
  transition: color 200ms ease;
}
.hero-demo-action-arxiv:hover .hero-demo-arxiv-mark {
  color: #8a1414;
}
.hero-demo-action-arxiv:hover {
  background: rgba(179, 27, 27, 0.06);
}

/* Star button — GitHub octocat + "Star" label + live star count pill.
   Count is populated by scripts/github-stars.js; if the fetch fails the
   pill stays [hidden] and this degrades to a plain octocat + "Star" link. */
.hero-demo-action-star {
  gap: 6px;
}
.hero-demo-star-label {
  font: 600 12.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
}
.hero-demo-star-count {
  font: 700 12px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.01em;
  padding: 2px 6px;
  border-radius: 999px;
  color: #1c1917;
  background: rgba(28, 25, 23, 0.06);
  transition: background 200ms ease;
}
.hero-demo-action-star:hover .hero-demo-star-count {
  background: rgba(28, 25, 23, 0.10);
}
.hero-demo-star-count[hidden] {
  display: none;
}

/* Power off — same row as Paper/Code, but lighter (no pill outline),
   to keep it as a tertiary action. state-builder.js toggles .hidden /
   .inline-flex on click. */
.hero-demo-poweroff {
  display: none;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  font: 500 12px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0;
  color: #78716c;
  background: transparent;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  transition: color 200ms ease, background 200ms ease;
}
.hero-demo-poweroff.inline-flex { display: inline-flex; }
.hero-demo-poweroff:hover {
  color: #1c1917;
  background: rgba(28, 25, 23, 0.04);
}
.hero-demo-poweroff svg { opacity: 0.75; transition: opacity 200ms ease; }
.hero-demo-poweroff:hover svg { opacity: 1; }

@media (max-width: 420px) {
  .hero-demo-poweroff {
    gap: 0;
  }
  .hero-demo-poweroff span {
    display: none;
  }
}

@media (max-width: 380px) {
  .hero-demo-brand {
    left: 20px;
  }
  .hero-demo-actions {
    right: 16px;
    gap: 4px;
  }
  .hero-demo-action,
  .hero-demo-poweroff {
    padding-left: 8px;
    padding-right: 8px;
  }
  .hero-demo-poweroff {
    gap: 0;
  }
}

/* Hero footer — fixed at viewport bottom. Contains the first-load note
   and the SCROLL hint, stacked. Only fades in after power-on. */
.hero-demo-foot {
  position: fixed;
  /* On short viewports the phone (scaled to fit) ends up close to the
     viewport bottom — keeping the hint at a fixed 20px gap from the edge
     would crash it into the phone. So the hint slides down (closer to the
     edge) as the viewport shrinks, maintaining a constant 8px gap above
     the phone. Math: phone visual bottom + 8 + hint_height + bottom = vp,
     so bottom = vp/2 - 442 in the scaled regime, clamped to [8, 20]. */
  bottom: max(env(safe-area-inset-bottom), clamp(8px, calc(50vh - 442px), 20px));
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  z-index: 60;
  opacity: 0;
  transform: translate(-50%, 14px);
  pointer-events: none;
  transition:
    opacity 540ms cubic-bezier(0.4, 0, 0.2, 1) 600ms,
    transform 540ms cubic-bezier(0.4, 0, 0.2, 1) 600ms;
}
.hero-demo.is-booted .hero-demo-foot {
  opacity: 1;
  transform: translate(-50%, 12px);
}


/* Scroll hint is now laid out inside .hero-demo-foot (the footer is
   the fixed-positioned container; hint just stacks below the firstload
   note in flex order). */
.hero-demo-scroll-hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  font: 500 10px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(28, 25, 23, 0.4);
  pointer-events: none;
  margin-top: 2px;
}
.hero-demo-scroll-hint svg {
  /* Arrow shrunk so the whole hint takes less vertical room — gives more
     breathing space above the hint without moving the phone. */
  width: 9px;
  height: 11px;
  animation: hero-arrow 2.4s ease-in-out infinite;
}
@keyframes hero-arrow {
  0%, 100% { transform: translateY(0);   opacity: 0.55; }
  50%      { transform: translateY(5px); opacity: 1;    }
}
/* Once the user starts scrolling, hide the entire footer so it doesn't
   float over the paper content below. */
body.hero-scrolled .hero-demo-foot {
  opacity: 0 !important;
  pointer-events: none !important;
  transform: translate(-50%, 14px) !important;
  transition-delay: 0ms !important;
}

@media (max-width: 1040px) {
  .hero-demo {
    padding: 28px 16px 24px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-demo::before,
  .hero-demo::after,
  .hero-demo #demo-boot-btn > span:first-child::before,
  .hero-demo #demo-boot-btn > span:first-child::after,
  .hero-demo .state-dock,
  .state-dock-tab[data-state-dock-tab="session"]::before,
  .state-drawer,
  .gesture-guide,
  .gesture-guide-icon .gesture-trail,
  .hero-demo-foot,
  .hero-demo-scroll-hint,
  .hero-demo-scroll-hint svg {
    transition: none !important;
    animation: none !important;
  }
  .gesture-guide-icon .gesture-trail {
    stroke-dashoffset: 0 !important;
    opacity: 1 !important;
  }
}

/* Paper header resources row — ghost pill style: subtle stone-100 fill +
   barely-there 1px border + full rounded. Gives the buttons enough visual
   weight to anchor next to the h1 without competing with it. Hover lifts
   1px and snaps to white + darker border for clear feedback. */
.paper-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.paper-action {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  font: 500 14px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0;
  color: #44403c;             /* stone-700 */
  background: rgba(245, 245, 244, 0.6);  /* stone-100 @ 60% */
  border: 1px solid rgba(28, 25, 23, 0.08);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  transition:
    color 200ms ease,
    background 200ms ease,
    border-color 200ms ease,
    transform 200ms ease;
}
.paper-action:hover {
  color: #1c1917;
  background: #ffffff;
  border-color: rgba(28, 25, 23, 0.22);
  transform: translateY(-1px);
}
.paper-action-arxiv-mark {
  font: 800 15px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -0.02em;
  color: #B31B1B;
  transition: color 200ms ease;
}
.paper-action-arxiv:hover .paper-action-arxiv-mark {
  color: #8a1414;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  padding: 0.75rem 1.25rem;
  background: #1c1917;
  color: #fff;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 0.875rem;
  font-weight: 500;
  border-radius: 0 0 0.5rem 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; outline: 2px solid #3b82f6; outline-offset: 2px; }
h1, h2, h3, .ui { font-family: 'Inter', system-ui, sans-serif; }
code, pre, .mono { font-family: 'JetBrains Mono', 'SF Mono', monospace; }
.container-narrow { max-width: 880px; }
.container-demo { max-width: 1120px; }
.gradient-bg {
  background: linear-gradient(180deg, #fafaf9 0%, #ffffff 60%);
}
.stat-num { font-variant-numeric: tabular-nums; }
details > summary { cursor: pointer; list-style: none; }
details > summary::-webkit-details-marker { display: none; }
details[open] summary .marker { transform: rotate(90deg); }
.marker { transition: transform 0.15s ease; display: inline-block; }
/* ------------------------------------------------------------ */
/* Phone is the only visual anchor in hero. State Builder lives  */
/* in a fixed right-side drawer triggered by the dock attached   */
/* to the phone's right edge.                                    */
/* ------------------------------------------------------------ */
.demo-layout {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}
/* The phone wrap's inner relative box is the dock anchor — the
   dock is positioned outside the phone but inside this element
   so transform: scale on .demo-phone-wrap scales them together. */
.phone-rig { overflow: visible; }

/* ============================================================ */
/* State Dock — vertical icon dock attached to phone right edge */
/* Glass-morphism pill, fades in post-boot, hides when drawer    */
/* is open (drawer overlaps it on common laptop widths).         */
/* ============================================================ */
.state-dock {
  position: absolute;
  /* Sit 14px to the right of the phone, vertically centered. */
  left: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.74);
  border: 1px solid rgba(28, 25, 23, 0.08);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.7) inset,
    0 12px 32px -10px rgba(15, 23, 42, 0.18),
    0 4px 12px -6px rgba(15, 23, 42, 0.08);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  z-index: 4;
  /* Pre-boot: hidden alongside the rest of the chrome. */
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 540ms cubic-bezier(0.4, 0, 0.2, 1) 320ms,
    transform 540ms cubic-bezier(0.4, 0, 0.2, 1) 320ms;
}
.hero-demo.is-booted .state-dock {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(-50%);
}
/* When drawer is open, drawer covers the dock's screen real estate
   on common 1280–1600 viewports. Fade dock out so it doesn't poke
   through behind the drawer's left shadow. */
body[data-state-drawer-open="true"] .state-dock {
  opacity: 0;
  pointer-events: none;
  transform: translate(8px, -50%);
  transition-delay: 0ms;
}

.state-dock-eyebrow {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  /* writing-mode: vertical-rl reads top-to-bottom on the right side
     of its container, which is what we want — small caps stacking
     downward like an Apple sidebar caption. */
  font: 700 8.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(28, 25, 23, 0.45);
  padding: 4px 0 2px;
  user-select: none;
}
.state-dock-divider {
  width: 16px;
  height: 1px;
  background: rgba(28, 25, 23, 0.12);
  margin: 2px 0 4px;
}

.state-dock-tab {
  position: relative;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: #57534e;
  cursor: pointer;
  transition:
    background-color 180ms ease,
    color 180ms ease,
    transform 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
.state-dock-tab:hover {
  background: rgba(28, 25, 23, 0.05);
  color: #1c1917;
  transform: scale(1.05);
}
.state-dock-tab[aria-selected="true"] {
  background: #1c1917;
  color: #ffffff;
}
.state-dock-tab[aria-selected="true"] .state-dock-tab-icon-img {
  /* Image-based icons don't respond to currentColor — keep them
     bright on the dark active pill via a touch of contrast lift. */
  filter: brightness(1.05);
}
.state-dock-tab:focus-visible {
  outline: 2px solid rgba(37, 99, 235, 0.55);
  outline-offset: 2px;
}
.state-dock-tab-icon {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.state-dock-tab-icon svg { width: 18px; height: 18px; }
.state-dock-tab-icon-img {
  border-radius: 6px;
  overflow: hidden;
}
.state-dock-tab-icon-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Language tab badge — small pill at the corner of the icon showing
   the current phone locale ("中" / "EN") so visitors can read the
   active language without opening the drawer. */
.state-dock-tab-badge {
  position: absolute;
  bottom: -3px;
  right: -3px;
  min-width: 18px;
  height: 14px;
  padding: 0 4px;
  border-radius: 7px;
  background: #2563eb;
  color: #ffffff;
  font: 700 9px/14px 'Inter', system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-align: center;
  border: 1.5px solid #fafaf9;
  pointer-events: none;
  user-select: none;
}
.state-dock-tab[aria-selected="true"] .state-dock-tab-badge {
  border-color: #1c1917;
}

.studio-language-choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.studio-language-choice {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px;
  border-radius: 10px;
  border: 1px solid rgba(28, 25, 23, 0.12);
  background: #fafaf9;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}
.studio-language-choice:hover {
  border-color: rgba(28, 25, 23, 0.25);
  background: #ffffff;
}
.studio-language-choice[aria-checked="true"] {
  border-color: #2563eb;
  background: rgba(37, 99, 235, 0.06);
  color: #1e40af;
}
.studio-language-choice:focus-visible {
  outline: 2px solid rgba(37, 99, 235, 0.55);
  outline-offset: 2px;
}
.studio-language-choice-name {
  font: 600 13px/1.2 'Inter', system-ui, sans-serif;
}
.studio-language-choice-meta {
  font-size: 11px;
  color: rgba(28, 25, 23, 0.55);
}
.studio-language-choice[aria-checked="true"] .studio-language-choice-meta {
  color: rgba(30, 64, 175, 0.7);
}

/* First-time pulse: the topmost (Session) tab gently pings to draw
   the eye. Fades permanently after first interaction (sessionStorage
   sets body[data-state-dock-touched="true"]). */
.state-dock-tab[data-state-dock-tab="session"]::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 14px;
  border: 1.5px solid rgba(37, 99, 235, 0.7);
  opacity: 0;
  pointer-events: none;
  animation: state-dock-ping 2.4s ease-out 0.6s infinite;
}
.hero-demo:not(.is-booted) .state-dock-tab[data-state-dock-tab="session"]::before,
body[data-state-dock-touched="true"] .state-dock-tab[data-state-dock-tab="session"]::before {
  animation: none;
  opacity: 0;
}
@keyframes state-dock-ping {
  0%   { transform: scale(0.92); opacity: 0; }
  20%  { opacity: 0.85; }
  80%  { transform: scale(1.45); opacity: 0; }
  100% { transform: scale(1.45); opacity: 0; }
}

/* ============================================================ */
/* Gesture Guide — left-side companion to .state-dock. Static    */
/* legend explaining the three full-screen gestures the          */
/* simulator listens for (edge-swipe back / swipe-up home /      */
/* swipe-up-and-hold recents). Same glass-morphism + fade-in     */
/* timing as the dock so they read as a matched pair.            */
/* ============================================================ */
/* ============================================================ */
/* Gesture rail — slim vertical key dock on the phone's LEFT     */
/* edge, mirroring the right-side .state-dock. Collapsed = three  */
/* live hardware keys (Back / Home / Recents) + a "?" help key;   */
/* hovering or focusing the rail reveals the legend popover.      */
/* ============================================================ */
.gesture-guide {
  position: absolute;
  /* Mirror of .state-dock: 14px outside the phone's left edge. */
  right: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  /* Pre-boot: hidden alongside the rest of the chrome. The rail's
     buttons need clicks, so pointer-events is gated by .is-booted. */
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 540ms cubic-bezier(0.4, 0, 0.2, 1) 320ms,
    transform 540ms cubic-bezier(0.4, 0, 0.2, 1) 320ms;
}
.hero-demo.is-booted .gesture-guide {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(-50%);
}

/* Slim glass pill — identical chrome to .state-dock for symmetry. */
.gesture-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.74);
  border: 1px solid rgba(28, 25, 23, 0.08);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.7) inset,
    0 12px 32px -10px rgba(15, 23, 42, 0.18),
    0 4px 12px -6px rgba(15, 23, 42, 0.08);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
}

/* Each key shares the .state-dock-tab footprint. */
.gesture-key {
  position: relative;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: #57534e;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition:
    background-color 180ms ease,
    color 180ms ease,
    transform 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
.gesture-key:hover {
  background: rgba(28, 25, 23, 0.05);
  color: #1c1917;
  transform: scale(1.05);
}
.gesture-key:active {
  background: #1c1917;
  color: #ffffff;
  transform: scale(0.96);
  transition-duration: 60ms;
}
.gesture-key:focus-visible {
  outline: 2px solid rgba(37, 99, 235, 0.55);
  outline-offset: 2px;
}

/* Icon wrapper kept as .gesture-guide-icon so the reduced-motion +
   .gesture-trail animation rules continue to match. */
.gesture-guide-icon {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
}
.gesture-guide-icon svg { width: 24px; height: 24px; display: block; }

.gesture-rail-div {
  width: 18px;
  height: 1px;
  background: rgba(28, 25, 23, 0.12);
  margin: 1px 0;
}

/* "?" help key — reveals the legend. cursor:help signals "hover me". */
.gesture-help {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(28, 25, 23, 0.42);
  cursor: help;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 180ms ease, color 180ms ease;
}
.gesture-help svg { width: 17px; height: 17px; display: block; }
.gesture-guide:hover .gesture-help,
.gesture-guide:focus-within .gesture-help {
  background: rgba(28, 25, 23, 0.06);
  color: #1c1917;
}

/* Legend popover — opens to the LEFT of the rail (into the gutter).
   Read-only: stays pointer-events:none so the hover gap between rail
   and card never matters (you read it, you don't reach into it). */
.gesture-pop {
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  width: 188px;
  transform: translate(8px, -50%);
  padding: 13px 14px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(28, 25, 23, 0.08);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.7) inset,
    0 16px 40px -12px rgba(15, 23, 42, 0.22),
    0 4px 12px -6px rgba(15, 23, 42, 0.08);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 200ms ease,
    transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 5;
}
.gesture-guide:hover .gesture-pop,
.gesture-guide:focus-within .gesture-pop {
  opacity: 1;
  transform: translate(0, -50%);
}
.gesture-pop-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 0 1px 9px;
  border-bottom: 1px solid rgba(28, 25, 23, 0.07);
  margin-bottom: 9px;
}
.gesture-guide-eyebrow {
  font: 700 9.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #1c1917;
}
.gesture-guide-meta {
  font: 600 8.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #2563eb;
}
.gesture-pop-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.gesture-pop-list > li {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.gesture-pop-k {
  font: 600 11.5px/1.2 'Inter', system-ui, sans-serif;
  color: #1c1917;
}
.gesture-pop-d {
  font: 400 10.5px/1.35 'Inter', system-ui, sans-serif;
  color: #78716c;
}

/* Stroke trails inside each gesture icon — "draw" the swipe path so
   the keys read as motion. Staggered so they don't pulse in unison. */
.gesture-guide-icon .gesture-trail {
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
  animation: gesture-trail 2.6s cubic-bezier(0.55, 0, 0.25, 1) infinite;
}
.gesture-key:nth-child(1) .gesture-trail { animation-delay: 0ms; }
.gesture-key:nth-child(2) .gesture-trail { animation-delay: 700ms; }
.gesture-key:nth-child(3) .gesture-trail { animation-delay: 1400ms; }
@keyframes gesture-trail {
  0%   { stroke-dashoffset: 22; opacity: 0; }
  18%  { opacity: 1; }
  55%  { stroke-dashoffset: 0;  opacity: 1; }
  80%  { stroke-dashoffset: 0;  opacity: 0.95; }
  100% { stroke-dashoffset: 0;  opacity: 0; }
}

/* Narrow-viewport responsive rules for .gesture-guide are appended
   AFTER the existing .state-dock @media block further down — see
   the trailing @media block at the bottom of this file. CSS cascade
   only honors the last matching rule, and the dock block re-sets
   .state-dock { top: ... } in narrow mode, so the gesture-guide
   override that pushes the dock down has to live after it. */

/* ============================================================ */
/* State Popover — anchored card to the right of the dock. No   */
/* full-screen drawer, no backdrop scrim. Slides in 10px from   */
/* the dock with a fade. Closes on outside click or ESC.        */
/*                                                              */
/* Position math (relative to .demo-layout, which is centered): */
/*   left = 50% + (phone half 180) + (phone↔dock gap 14)        */
/*               + (dock width ≈50) + (dock↔popover gap 14)     */
/*        = 50% + 258px                                         */
/* ============================================================ */
.state-drawer {
  position: absolute;
  left: calc(50% + 258px);
  top: 0;
  width: 380px;
  height: 800px;            /* matches phone box height for visual alignment */
  max-height: calc(100svh - 80px);
  background: #fbfbfd;
  border: 1px solid rgba(28, 25, 23, 0.06);
  border-radius: 28px;
  box-shadow:
    0 28px 60px -22px rgba(15, 23, 42, 0.22),
    0 10px 18px -8px rgba(15, 23, 42, 0.10);
  opacity: 0;
  transform: translateX(-10px);
  pointer-events: none;
  z-index: 5;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition:
    opacity 280ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.state-drawer[data-open="true"] {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}

/* Below 1280px the side-anchored popover would overflow the right
   edge AND the vertical dock would visually disconnect from where
   the popover lands. Drop the entire group into a column flow:
   phone → horizontal dock (below phone) → popover (below dock).
   This keeps the click target and the panel that opens on a single
   visual axis. */
@media (max-width: 1279px) {
  .hero-demo.is-booted {
    padding-top: 76px;
  }
  .hero-demo .demo-phone-wrap {
    --phone-scale: clamp(0.62, calc((100svh - 160px) / 876px), 1);
    margin-bottom: calc((var(--phone-scale) - 1) * 876px);
  }
  .demo-layout {
    flex-direction: column;
    gap: 24px;
  }
  /* Reserve space below the visual phone for the now-horizontal
     dock (which is still position: absolute on .phone-rig at
     top: 100% + 14px). Without this padding the next column-flow
     item (popover) would render on top of the dock. */
  .demo-phone-wrap {
    padding-bottom: 76px;
  }
  .state-drawer {
    position: relative;
    left: auto;
    top: auto;
    width: min(420px, calc(100vw - 32px));
    height: auto;
    max-height: 70svh;
    transform: translateY(-8px);
  }
  .state-drawer[data-open="true"] {
    transform: translateY(0);
  }
  .state-drawer[data-open="false"] {
    display: none;
  }
}

.state-drawer-head {
  position: relative;
  padding: 20px 22px 14px;
  border-bottom: 1px solid rgba(28, 25, 23, 0.06);
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.state-drawer-head .state-builder-board-kicker {
  margin-bottom: 5px;
}
.state-drawer-head .state-builder-board-title {
  font-size: 17px;
  line-height: 1.3;
  margin-bottom: 4px;
}
.state-drawer-head .state-builder-board-lede {
  font-size: 12.5px;
  line-height: 1.45;
}
.state-drawer-close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: rgba(28, 25, 23, 0.04);
  color: #44403c;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease, transform 180ms ease;
}
.state-drawer-close:hover {
  background: rgba(28, 25, 23, 0.1);
  color: #1c1917;
  transform: rotate(90deg);
}
.state-drawer-close:focus-visible {
  outline: 2px solid rgba(37, 99, 235, 0.55);
  outline-offset: 2px;
}

.state-drawer-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px 22px 22px;
  -webkit-overflow-scrolling: touch;
}
.state-drawer-body .state-builder-board {
  padding-top: 0;
}
.state-drawer-body .state-builder-board > .state-builder-board-head {
  /* Kicker/title/lede already render in the drawer head, hide the
     duplicate inside the embedded board (legacy markup keeps it
     for the standalone fallback). */
  display: none;
}

/* Narrow viewports (matches popover breakpoint): dock collapses to
   a horizontal pill below the phone, so dock and popover always
   travel together along the same vertical axis. */
@media (max-width: 1279px) {
  .state-dock {
    left: 50%;
    top: calc(100% + 14px);
    transform: translate(-50%, 0);
    flex-direction: row;
    padding: 7px 14px;
    gap: 6px;
  }
  .hero-demo.is-booted .state-dock {
    transform: translate(-50%, 0);
  }
  body[data-state-drawer-open="true"] .state-dock {
    /* Keep dock visible under the popover when open — popover
       stacks below it in the column flow, not over it. */
    opacity: 1;
    pointer-events: auto;
    transform: translate(-50%, 0);
  }
  .state-dock-eyebrow {
    writing-mode: horizontal-tb;
    padding: 0 6px 0 2px;
    letter-spacing: 0.28em;
  }
  .state-dock-divider {
    width: 1px;
    height: 18px;
    margin: 0 4px;
  }
  .state-dock-tab {
    width: 34px;
    height: 34px;
  }
  .state-dock-tab-icon { width: 20px; height: 20px; }
  .state-dock-tab-icon svg { width: 16px; height: 16px; }
}

/* ----- Capability board (collapsed state) ----- */
.state-builder-board {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 6px 4px 0;
}

.state-builder-board-head {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.state-builder-board-kicker {
  color: #2563eb;
  font: 800 10px/1 Inter, system-ui, sans-serif;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.state-builder-board-title {
  margin: 0;
  font: 700 18px/1.3 Inter, system-ui, sans-serif;
  color: #1c1917;
}
.state-builder-board-lede {
  margin: 0;
  font: 400 13.5px/1.55 'Charter', 'Georgia', serif;
  color: #57534e;
}

.state-builder-tabs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 2px;
  padding: 4px 0 0;
}
.state-builder-tab {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 4px 2px 6px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: #78716c;
  font: 600 10.5px/1.25 Inter, system-ui, sans-serif;
  text-align: center;
  transition: color 0.14s ease;
}
.state-builder-tab:hover { color: #1c1917; }
.state-builder-tab[aria-selected="true"] {
  color: #1c1917;
  font-weight: 700;
}
.state-builder-tab[aria-selected="true"] .state-builder-tab-icon {
  box-shadow: 0 0 0 1.5px #2563eb;
}
.state-builder-tab:focus-visible {
  outline: 2px solid rgba(37, 99, 235, 0.45);
  outline-offset: 2px;
  border-radius: 4px;
}
.state-builder-tab-icon {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: #f5f5f4;
  color: #57534e;
  overflow: hidden;
}
.state-builder-tab-icon svg { width: 17px; height: 17px; }
.state-builder-tab-icon-img { background: transparent; }
.state-builder-tab-icon-img img { width: 100%; height: 100%; object-fit: cover; }
.state-builder-tab-label { display: block; }

.state-builder-panel-shell {
  padding: 4px 0 0;
}

.state-builder-board-foot {
  margin: 8px 4px 0;
  font: 400 11.5px/1.5 'Charter', 'Georgia', serif;
  color: #a8a29e;
}
.state-builder-board-foot code {
  font: 500 11px/1.5 'JetBrains Mono', 'SF Mono', monospace;
  color: #78716c;
  background: transparent;
  padding: 0;
}

.studio-action-rail {
  display: flex;
  gap: 8px;
  margin: 9px 0 16px;
  overflow-x: auto;
  scrollbar-width: none;
}
.studio-action-rail::-webkit-scrollbar { display: none; }
.studio-action-tab {
  flex: 0 0 auto;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: transparent;
  padding: 4px 0;
  margin-right: 16px;
  color: #78716c;
  font: 600 12px/1 Inter, system-ui, sans-serif;
  cursor: pointer;
  transition: color 0.14s ease, border-color 0.14s ease;
}
.studio-action-tab:hover {
  color: #1c1917;
}
.studio-action-tab[aria-selected="true"] {
  color: #1c1917;
  border-bottom-color: #2563eb;
}
.studio-action-panel { display: none; }
.studio-action-panel[data-active="true"] { display: block; }
#studio-device-location-custom[hidden] { display: none !important; }
.studio-panel { display: none; }
.studio-panel[data-active="true"] {
  display: block;
  animation: studio-panel-in 0.18s ease-out;
}
.state-builder-panel-shell .studio-action-rail {
  margin: 0 0 14px;
}
@keyframes studio-panel-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
.studio-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.studio-field label {
  font-size: 11px;
  line-height: 1.2;
  font-weight: 600;
  color: #78716c;
}
.studio-input {
  width: 100%;
  border: 1px solid rgba(28,25,23,0.06);
  border-radius: 9px;
  background: transparent;
  padding: 10px 12px;
  font: 600 13px/1.35 Inter, system-ui, sans-serif;
  color: #1c1917;
  outline: none;
  box-shadow: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
select.studio-input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M7 10L12 15L17 10' stroke='%2378716c' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: right 11px center;
  background-repeat: no-repeat;
  background-size: 18px 18px;
  padding-right: 34px;
}
input[type="date"].studio-input,
input[type="datetime-local"].studio-input {
  color-scheme: light;
}
textarea.studio-input {
  line-height: 1.5;
}
.studio-input:focus {
  border-color: rgba(37,99,235,0.34);
  background: transparent;
  box-shadow:
    0 0 0 2px rgba(37,99,235,0.05);
}
.studio-input:hover:not(:focus) {
  border-color: rgba(28,25,23,0.12);
  box-shadow: none;
}
.studio-action {
  border-radius: 8px;
  background: #44403c;
  color: #f5f5f4;
  border: 0;
  padding: 9px 14px;
  font: 600 12.5px/1 Inter, system-ui, sans-serif;
  box-shadow: none;
  transition: background 0.14s ease;
}
.studio-action:hover {
  background: #57534e;
  box-shadow: none;
  transform: none;
}
.studio-action:disabled { background: #a8a29e; transform: none; cursor: not-allowed; }
.studio-action.secondary {
  background: rgba(255,255,255,0.72);
  color: #1c1917;
  border: 1px solid rgba(214,211,209,0.88);
  box-shadow: none;
}
.studio-action.secondary:hover {
  background: #fff;
  border-color: #a8a29e;
}
.studio-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font: 600 12px/1.2 Inter, system-ui, sans-serif;
  color: #44403c;
}
.avatar-picker {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
}
.avatar-choice {
  aspect-ratio: 1;
  border-radius: 11px;
  border: 2px solid transparent;
  padding: 2px;
  background: rgba(245,245,244,0.72);
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.avatar-choice:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 18px -14px rgba(28,25,23,0.7);
}
.avatar-choice[aria-pressed="true"] {
  border-color: #2563eb;
  background: #eff6ff;
}
.avatar-choice img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 9px;
  object-fit: cover;
}
.studio-status {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 0 4px;
  margin-top: 4px;
  font: 400 12px/1.5 'Charter', 'Georgia', serif;
}
.studio-status::before {
  content: '';
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: currentColor;
  margin-top: 6px;
}
.studio-status[data-kind="ok"] { color: #047857; }
.studio-status[data-kind="warn"] { color: #a16207; }
.studio-status[data-kind="error"] { color: #b91c1c; }
.studio-snapshot-meta {
  border-radius: 10px;
  background: rgba(245,245,244,0.7);
  padding: 9px 11px;
  color: #78716c;
  font: 700 10px/1.45 Inter, system-ui, sans-serif;
}

/* ============================================================ */
/* Reddit case-study trajectory viewer                          */
/* ============================================================ */
.trace-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; max-width: 640px; margin: 0 auto; }
@media (max-width: 600px) { .trace-grid { grid-template-columns: 1fr; gap: 1rem; } }
.trace-side { display: flex; flex-direction: column; gap: 0.5rem; }
.trace-header {
  display: flex; align-items: center; justify-content: flex-start;
  padding: 0 2px 6px;
}
.trace-badge {
  padding: 3px 8px; border-radius: 4px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 9px; font-weight: 800; letter-spacing: 0.1em;
  text-transform: uppercase;
}
.trace-badge-base    { background: #1c1917; color: #f5f5f4; }
.trace-badge-trained { background: #047857; color: #fff; }
.trace-image-wrap {
  position: relative; border-radius: 10px; overflow: hidden;
  background: #f5f5f4; aspect-ratio: 540 / 1150;
}
.trace-image-wrap img { width: 100%; height: 100%; display: block; object-fit: cover; }
.trace-image-wrap.is-base { border: 1px solid #e7e5e4; }
.trace-image-wrap.is-trained { border: 1px solid #a7f3d0; background: #ecfdf5; }
.trace-controls { display: flex; flex-direction: column; gap: 0.5rem; padding: 0 2px; }
.trace-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 4px; border-radius: 2px;
  background: #e7e5e4; outline: none; cursor: pointer;
  margin: 0;
}
.trace-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; border: 2px solid #44403c;
  cursor: pointer; transition: transform .15s ease;
}
.trace-slider::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; border: 2px solid #44403c;
  cursor: pointer; transition: transform .15s ease;
}
.trace-slider.is-trained::-webkit-slider-thumb { border-color: #047857; }
.trace-slider.is-trained::-moz-range-thumb     { border-color: #047857; }
.trace-slider:hover::-webkit-slider-thumb { transform: scale(1.15); }
.trace-slider:hover::-moz-range-thumb     { transform: scale(1.15); }
.trace-ticks {
  display: flex; justify-content: space-between; align-items: center;
  padding: 0 7px;
  font-family: 'JetBrains Mono', 'SF Mono', monospace;
  font-size: 9px; color: #a8a29e;
  font-variant-numeric: tabular-nums;
}
.trace-tick { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
.trace-tick::before {
  content: ''; width: 1px; height: 5px; background: #d6d3d1; margin-bottom: 2px;
}
.trace-action {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px; line-height: 1.35; color: #44403c;
  min-height: 2.7em; padding: 2px 2px 0;
}
.trace-action .step-label {
  font-family: 'JetBrains Mono', 'SF Mono', monospace;
  font-weight: 700; font-size: 10px;
  margin-right: 6px;
  color: #1c1917;
}
.trace-action.is-trained .step-label { color: #047857; }

.app-tile { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; user-select: none; }
.app-tile .app-icon {
  width: 60px; height: 60px;
  display: flex; align-items: center; justify-content: center;
  transition: transform .18s ease, filter .18s ease;
  position: relative;
}
.app-tile .app-icon img {
  width: 100%; height: 100%;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.08)) drop-shadow(0 2px 4px rgba(0,0,0,.05));
}
.app-tile .app-icon.fallback {
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 2px 6px -2px rgba(0,0,0,.08);
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 600;
  overflow: visible;
}
.app-tile .app-icon.fallback.is-light {
  box-shadow: 0 0 0 1px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.06), 0 2px 6px -2px rgba(0,0,0,.06);
}
.app-tile:hover .app-icon { transform: translateY(-2px) scale(1.06); }
.app-tile:hover .app-icon img {
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.18)) drop-shadow(0 2px 4px rgba(0,0,0,.08));
}
.app-tile .app-name {
  font-size: 11px; line-height: 1.15; text-align: center;
  color: #57534e; transition: color .15s ease;
  font-family: 'Inter', system-ui, sans-serif;
}
.app-tile:hover .app-name { color: #1c1917; }
.app-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: 0.5rem;
  row-gap: 1.5rem;
}
@media (min-width: 640px) { .app-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@media (min-width: 768px) { .app-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); } }
.app-section-label {
  display: flex; align-items: baseline; gap: 0.625rem; margin-bottom: 1.25rem;
  font-family: 'Inter', system-ui, sans-serif;
}
.app-section-label .bar { width: 3px; height: 14px; border-radius: 2px; align-self: center; }
.app-section-label h3 {
  font-size: 11px; font-weight: 700; letter-spacing: 0.22em;
  text-transform: uppercase; color: #44403c;
}
.app-section-label .count { font-size: 11px; color: #a8a29e; font-weight: 500; }

/* ============================================================ */
/* Apps Wall — auto-scrolling marquee                           */
/* ============================================================ */
.apps-marquee-row { margin-bottom: 28px; }
.apps-marquee-row:last-of-type { margin-bottom: 0; }
.apps-marquee-meta {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 14px;
  font-family: 'Inter', system-ui, sans-serif;
}
.apps-marquee-meta .bar {
  width: 3px; height: 14px; border-radius: 2px;
  flex: 0 0 auto;
}
.apps-marquee-meta-label {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: #44403c;
}
.apps-marquee-meta-count {
  font-size: 11px; font-weight: 500; color: #a8a29e;
}

.apps-marquee {
  position: relative;
  overflow: hidden;
  padding: 4px 0 6px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
}
.apps-marquee-track {
  display: flex;
  gap: 28px;
  width: max-content;
  animation: apps-scroll-left 30s linear infinite;
  will-change: transform;
}
.apps-marquee-track.is-reverse {
  animation-name: apps-scroll-right;
  animation-duration: 30s;
}
.apps-marquee:hover .apps-marquee-track,
.apps-marquee:focus-within .apps-marquee-track {
  animation-play-state: paused;
}
@keyframes apps-scroll-left {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
@keyframes apps-scroll-right {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}
.apps-marquee .app-tile {
  flex: 0 0 auto;
  width: 84px;
}
@media (prefers-reduced-motion: reduce) {
  .apps-marquee {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .apps-marquee-track {
    animation: none !important;
    transform: none !important;
  }
}

/* ============================================================ */
/* Gesture Guide — narrow-viewport collapse.                     */
/* Placed at end-of-file so it cascades AFTER the .state-dock    */
/* @media block above (which re-sets dock/hint positions). On    */
/* narrow viewports the left-side legend collapses into an       */
/* icon-only horizontal pill directly under the phone — Android  */
/* soft-key bar — and pushes State Dock + hint further down.    */
/* ============================================================ */
@media (max-width: 1279px) {
  .gesture-guide {
    left: 50%;
    right: auto;
    top: calc(100% + 14px);
    transform: translate(-50%, 0);
  }
  .hero-demo.is-booted .gesture-guide {
    transform: translate(-50%, 0);
  }
  /* Rail lies flat as a horizontal pill under the phone. */
  .gesture-rail {
    flex-direction: row;
    gap: 6px;
    padding: 6px 10px;
  }
  .gesture-rail-div {
    width: 1px;
    height: 18px;
    margin: 0 2px;
  }
  /* Popover opens upward, centered above the pill. */
  .gesture-pop {
    right: auto;
    left: 50%;
    top: auto;
    bottom: calc(100% + 10px);
    transform: translate(-50%, 8px);
  }
  .gesture-guide:hover .gesture-pop,
  .gesture-guide:focus-within .gesture-pop {
    transform: translate(-50%, 0);
  }

  /* Push the State Dock below the new
     gesture-key row so they don't collide. Phone wrap reserves the
     combined height — without it the popover (which renders in
     column flow below) would overlap the dock. */
  .state-dock {
    top: calc(100% + 76px);
  }
  .demo-phone-wrap {
    padding-bottom: 152px;
  }
}

/* ============================================================ */

/* ============================================================ */
/* In-browser demo agent console (scripts/agent/*). Fixed bottom   */
/* command bar; live run state draws on the phone (overlay/HUD) +  */
/* a right-side narration card.                                    */
/* ============================================================ */

.mg-console {
  position: fixed;
  left: 50%;
  bottom: max(env(safe-area-inset-bottom), 16px);
  transform: translateX(-50%);
  width: min(680px, calc(100vw - 32px));
  z-index: 70;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-family: 'Inter', system-ui, sans-serif;
  /* Hidden until the phone is booted; fades/slides in on boot. */
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 16px);
  transition: opacity 480ms cubic-bezier(0.4,0,0.2,1) 420ms,
              transform 480ms cubic-bezier(0.4,0,0.2,1) 420ms;
}
#demo.is-booted ~ .mg-console {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, 0);
}
/* Hide while the visitor scrolls down to read the paper, unless a run is
   active or the panel is open. */
body.hero-scrolled .mg-console {
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 16px);
}
body.hero-scrolled .mg-console[data-run-state="running"],
body.hero-scrolled .mg-console[data-run-state="done"] {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, 0);
}

/* Wide screens: dock the task bar near the phone's right flank instead of the
   viewport corner. On narrower laptops it clamps back to a 16px right gutter
   so the card never overflows. */
@media (min-width: 900px) {
  .mg-console {
    left: min(calc(100vw - 316px), calc(50% + 272px));
    right: auto;
    bottom: clamp(18px, 3vh, 40px);
    width: 300px;
    transform: translateY(14px);
  }
  .mg-console[data-collapsed="true"] { width: auto; }
  #demo.is-booted ~ .mg-console { transform: translateY(0); }
  body.hero-scrolled .mg-console { transform: translateY(14px); }
  body.hero-scrolled .mg-console[data-run-state="running"],
  body.hero-scrolled .mg-console[data-run-state="done"] { transform: translateY(0); }

  /* Two rows in the narrow corner card: the input gets its own full-width
     row, with Run/Stop + gear on the row beneath — no more squeeze. The
     `.mg-console` prefix keeps these winning over the base bar rules that
     come later in the file. */
  .mg-console .mg-console-row { flex-wrap: wrap; }
  .mg-console .mg-console-input { flex: 1 1 100%; }
  .mg-console .mg-agent-btn-run,
  .mg-console .mg-agent-btn-stop { flex: 1 1 auto; }
  .mg-console .mg-console-iconbtn { flex: 0 0 auto; }
}

@media (max-width: 720px) {
  .mg-console {
    bottom: max(env(safe-area-inset-bottom), 14px);
    width: min(560px, calc(100vw - 24px));
  }
  .mg-console[data-collapsed="true"] {
    left: auto;
    right: max(env(safe-area-inset-right), 14px);
    bottom: calc(max(env(safe-area-inset-bottom), 14px) + 78px);
    transform: translate(0, 12px) !important;
  }
  #demo.is-booted ~ .mg-console[data-collapsed="true"],
  body.hero-scrolled .mg-console[data-collapsed="true"][data-run-state="running"],
  body.hero-scrolled .mg-console[data-collapsed="true"][data-run-state="done"] {
    transform: translate(0, 0) !important;
  }
}

/* ---- command bar ---- */
.mg-console-bar {
  background: rgba(255,255,255,0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid #e7e5e4;
  border-radius: 16px;
  box-shadow: 0 12px 30px -12px rgba(0,0,0,0.22), 0 4px 10px -6px rgba(0,0,0,0.12);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.mg-console-meta { display: flex; align-items: center; gap: 8px; }
/* Collapse toggle: folds the input + chips away, leaving the slim status
   header so the bar stops covering the phone. */
.mg-console-collapse {
  flex: 0 0 auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; color: #a8a29e; cursor: pointer; border-radius: 7px;
  transition: background 0.15s, color 0.15s;
}
.mg-console-collapse:hover { background: #f5f5f4; color: #1c1917; }
.mg-console-collapse svg { transition: transform 0.2s ease; }
.mg-console[data-collapsed="true"] .mg-console-collapse svg { transform: rotate(180deg); }
.mg-console[data-collapsed="true"] .mg-console-row,
.mg-console[data-collapsed="true"] .mg-console-chips { display: none; }
.mg-console[data-collapsed="true"] {
  width: 104px;
}
.mg-console[data-collapsed="true"] .mg-console-bar {
  width: 104px;
  height: var(--mg-compact-height, 39px);
  padding: 0 6px 0 11px;
  border-radius: 999px;
  align-items: center;
  justify-content: center;
  gap: 0;
}
.mg-console[data-collapsed="true"] .mg-console-meta {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.mg-console[data-collapsed="true"] .mg-console-status { display: none; }
.mg-console[data-collapsed="true"] .mg-console-eyebrow {
  display: inline-flex;
  min-width: 0;
  overflow: hidden;
  font-size: 0.6rem;
  letter-spacing: 0.09em;
  white-space: nowrap;
}
.mg-console[data-collapsed="true"] .mg-console-eyebrow-text { display: none; }
.mg-console[data-collapsed="true"] .mg-console-compact-text { display: inline; }
.mg-console[data-collapsed="true"] .mg-console-collapse {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  color: #16a34a;
}
.mg-console[data-collapsed="true"] .mg-console-collapse svg {
  width: 15px;
  height: 15px;
}

@media (min-width: 721px) and (max-width: 1279px) {
  .mg-console[data-collapsed="true"] {
    left: var(--mg-compact-left, calc(50% + 140px));
    top: var(--mg-compact-top, calc(100vh - 127px));
    right: auto;
    bottom: auto;
    transform: none !important;
  }
  .mg-console[data-collapsed="true"] .mg-console-collapse {
    width: 22px;
    height: 22px;
  }
  .mg-console[data-collapsed="true"] .mg-console-collapse svg {
    width: 14px;
    height: 14px;
  }
}
.mg-console-eyebrow {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: #16a34a; flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
}
.mg-console-compact-text { display: none; }
.mg-console-eyebrow-dot {
  width: 6px; height: 6px; border-radius: 999px; background: #d6d3d1; flex: 0 0 auto;
}
.mg-console[data-run-state="running"] .mg-console-eyebrow-dot {
  background: #22c55e; animation: mg-eyebrow-pulse 1.5s ease-out infinite;
}
.mg-console[data-run-state="done"] .mg-console-eyebrow-dot { background: #16a34a; }
@keyframes mg-eyebrow-pulse {
  0% { box-shadow: 0 0 0 0 rgba(34,197,94,0.45); }
  70% { box-shadow: 0 0 0 5px rgba(34,197,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}
.mg-console-status {
  font-size: 0.78rem; color: #57534e; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mg-console-status[data-kind="running"] { color: #166534; }
.mg-console-status[data-kind="ok"] { color: #166534; }
.mg-console-status[data-kind="warn"] { color: #b45309; }
.mg-console-status[data-kind="error"] { color: #b91c1c; }

.mg-console-row { display: flex; align-items: center; gap: 8px; }
.mg-console-input {
  flex: 1; min-width: 0; height: 40px; padding: 0 12px;
  border: 1px solid #d6d3d1; border-radius: 10px; background: #fff;
  font-size: 0.9rem; color: #1c1917; font-family: inherit;
}
.mg-console-input:focus { outline: none; border-color: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,0.15); }
.mg-console-input:disabled { background: #f5f5f4; color: #78716c; }

.mg-console-iconbtn {
  flex: 0 0 auto; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid #d6d3d1; border-radius: 10px; background: #fff; color: #57534e; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.mg-console-iconbtn:hover { background: #f5f5f4; color: #1c1917; }

.mg-console-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 64px; opacity: 1; overflow: hidden;
  transition: max-height 260ms cubic-bezier(0.4,0,0.2,1), opacity 180ms ease, margin-top 220ms ease;
}
/* Collapse the example chips once the user has typed something or a run is
   active — discovery affordances, not permanent chrome. */
.mg-console[data-empty="false"] .mg-console-chips,
.mg-console[data-run-state="running"] .mg-console-chips {
  max-height: 0; opacity: 0; margin-top: -8px; pointer-events: none;
}
.mg-agent-chip {
  font-family: inherit; font-size: 0.72rem; color: #44403c;
  background: #f5f5f4; border: 1px solid #e7e5e4; border-radius: 999px;
  padding: 3px 10px; cursor: pointer; transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.mg-agent-chip:hover:not(:disabled) { background: #ecfdf5; border-color: #86efac; color: #166534; }
.mg-agent-chip:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---- shared buttons ---- */
.mg-agent-btn {
  font-family: inherit; font-weight: 600; font-size: 0.88rem; white-space: nowrap;
  border-radius: 10px; padding: 0 18px; height: 40px; border: 1px solid transparent; cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.mg-agent-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.mg-agent-btn-run { background: #16a34a; color: #fff; }
.mg-agent-btn-run:hover:not(:disabled) { background: #15803d; }
.mg-agent-btn-stop { background: #dc2626; color: #fff; }
.mg-agent-btn-stop:hover:not(:disabled) { background: #b91c1c; }
.mg-agent-btn-sm { height: 32px; padding: 0 14px; font-size: 0.8rem; background: #292524; color: #fff; }
.mg-agent-btn-sm:hover:not(:disabled) { background: #1c1917; }
.mg-agent-btn-ghost { background: transparent; color: #57534e; border-color: #d6d3d1; }
.mg-agent-btn-ghost:hover:not(:disabled) { background: #f5f5f4; }

/* ---- close button (shared by the settings sheet head) ---- */
.mg-console-close {
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; color: #a8a29e; cursor: pointer; border-radius: 8px;
}
.mg-console-close:hover { background: #f5f5f4; color: #1c1917; }

/* ============================================================ */
/* Phone-attached live-run chrome. The phone is the star; these  */
/* elements mount on .phone-rig (persistent across power cycles) */
/* and are driven by body[data-agent-run="idle|running|done"].   */
/* ============================================================ */

/* While a run is live or its result is on screen, the side docks retreat so
   the narration card + on-glass marks own the stage (the narration card shares
   the dock's right-edge anchor). Out-specifies `.hero-demo.is-booted
   .state-dock` via :is(). Restored once the narration is dismissed (idle). */
body:is([data-agent-run="running"], [data-agent-run="done"]) .hero-demo.is-booted
  :is(.state-dock, .gesture-guide) {
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease;
}

/* ---- on-glass action overlay (cursor / ripple / swipe trail) ---- */
.mg-ov {
  position: absolute; inset: 0; z-index: 5;
  border-radius: 44px; overflow: hidden; pointer-events: none;
}
.mg-ov-cursor {
  position: absolute; left: 0; top: 0; width: 28px; height: 28px; border-radius: 999px;
  background: radial-gradient(circle at 50% 50%, rgba(34,197,94,0.32), rgba(34,197,94,0.04) 70%);
  border: 1.5px solid rgba(22,163,74,0.9);
  box-shadow: 0 0 0 4px rgba(34,197,94,0.12), 0 4px 12px -2px rgba(0,0,0,0.28);
  transition: transform 380ms cubic-bezier(0.33, 0, 0.2, 1);
  will-change: transform;
}
.mg-ov-cursor.is-gone { opacity: 0; transition: opacity 380ms ease; }
.mg-ov-ripple {
  position: absolute; width: 20px; height: 20px; margin: -10px 0 0 -10px; border-radius: 999px;
  border: 2px solid rgba(22,163,74,0.92); background: rgba(34,197,94,0.18);
  animation: mg-ov-ripple 680ms cubic-bezier(0.2, 0.6, 0.2, 1) forwards;
}
.mg-ov-ripple[data-kind="long"] { animation-duration: 920ms; }
@keyframes mg-ov-ripple {
  0% { transform: scale(0.4); opacity: 0.9; }
  100% { transform: scale(3.6); opacity: 0; }
}
.mg-ov-trail { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.mg-ov-line {
  fill: none; stroke: rgba(22,163,74,0.92); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: 1; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.2));
  animation: mg-ov-draw 460ms ease forwards;
}
@keyframes mg-ov-draw { to { stroke-dashoffset: 0; } }
.mg-ov-trail-head {
  fill: none; stroke: rgba(22,163,74,0.95); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  opacity: 0; animation: mg-ov-head-in 200ms ease 380ms forwards;
}
@keyframes mg-ov-head-in { to { opacity: 1; } }

/* ---- HUD status pill on the phone ---- */
.mg-hud {
  position: absolute; top: 8px; left: 50%; z-index: 7;
  display: flex; align-items: center; gap: 7px; max-width: 280px; white-space: nowrap;
  padding: 5px 12px 5px 10px; border-radius: 999px; pointer-events: none;
  background: rgba(24,24,27,0.82); color: #fff;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 6px 18px -6px rgba(0,0,0,0.42);
  font: 600 11px/1.1 'Inter', system-ui, sans-serif; letter-spacing: 0.01em;
  opacity: 0; transform: translateX(-50%) translateY(-6px);
  transition: opacity 260ms ease, transform 260ms ease;
}
body[data-agent-run="running"] .mg-hud,
body[data-agent-run="done"] .mg-hud {
  opacity: 1; transform: translateX(-50%) translateY(0);
}
.mg-hud-text { overflow: hidden; text-overflow: ellipsis; }
.mg-hud-dot {
  width: 7px; height: 7px; border-radius: 999px; background: #22c55e; flex: 0 0 auto;
  animation: mg-hud-pulse 1.6s ease-out infinite;
}
.mg-hud[data-kind="warn"] .mg-hud-dot { background: #f59e0b; }
.mg-hud[data-kind="error"] .mg-hud-dot { background: #ef4444; animation: none; }
.mg-hud[data-kind="ok"] .mg-hud-dot { background: #22c55e; animation: none; }
.mg-hud[data-kind="idle"] .mg-hud-dot { background: #a1a1aa; animation: none; }
@keyframes mg-hud-pulse {
  0% { box-shadow: 0 0 0 0 rgba(34,197,94,0.5); }
  70% { box-shadow: 0 0 0 6px rgba(34,197,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}

/* ---- live narration card (floats off the phone's right edge) ---- */
.mg-narr {
  position: absolute; left: calc(100% + 18px); top: 0; width: 300px; z-index: 6;
  transform-origin: top left;
  transform: scale(calc(1 / var(--phone-scale, 1))) translateX(10px);
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px 14px 10px;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid rgba(28,25,23,0.10); border-radius: 16px;
  box-shadow: 0 18px 40px -16px rgba(15,23,42,0.22), 0 6px 14px -8px rgba(15,23,42,0.12);
  font-family: 'Inter', system-ui, sans-serif;
  opacity: 0; pointer-events: none;
  transition: opacity 320ms ease, transform 360ms cubic-bezier(0.4, 0, 0.2, 1);
}
body[data-agent-run="running"] .mg-narr,
body[data-agent-run="done"] .mg-narr {
  opacity: 1; pointer-events: auto;
  transform: scale(calc(1 / var(--phone-scale, 1))) translateX(0);
}
.mg-narr-answer {
  font-size: 0.84rem; font-weight: 600; color: #14532d; line-height: 1.45;
  padding: 9px 11px; background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px;
}
.mg-narr-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mg-narr-step {
  flex: 0 0 auto; font: 700 0.72rem/1 'Inter', system-ui, sans-serif; color: #fff;
  background: #1c1917; border-radius: 999px; padding: 4px 9px; letter-spacing: 0.02em;
}
.mg-narr-action {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: 'JetBrains Mono','SF Mono',monospace; font-size: 0.72rem; color: #1c1917;
  background: #f5f5f4; border: 1px solid #e7e5e4; border-radius: 6px; padding: 2px 8px;
}
.mg-narr-action[data-type="COMPLETE"] { color: #166534; background: #f0fdf4; border-color: #86efac; }
.mg-narr-action[data-type="ABORT"],
.mg-narr-action[data-type="NOOP"] { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
.mg-narr-action[data-type="ANSWER"] { color: #1e40af; background: #eff6ff; border-color: #bfdbfe; }
.mg-narr-dismiss {
  flex: 0 0 auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; color: #a8a29e; cursor: pointer; border-radius: 7px;
  transition: background 0.15s, color 0.15s;
}
.mg-narr-dismiss:hover { background: #f5f5f4; color: #1c1917; }
.mg-narr-think {
  margin: 0; font-size: 0.82rem; line-height: 1.55; color: #44403c; white-space: pre-wrap;
  min-height: 1.55em; transition: opacity 140ms ease;
  max-height: 10.85em; overflow-y: auto; padding-right: 4px; scrollbar-width: thin;
}
.mg-narr-think::-webkit-scrollbar { width: 6px; }
.mg-narr-think::-webkit-scrollbar-thumb { background: #d6d3d1; border-radius: 999px; }
.mg-narr-think.is-fading { opacity: 0; }
.mg-narr-retry {
  align-self: flex-start; display: inline-flex; align-items: center; justify-content: center;
  min-height: 30px; padding: 0 11px; border-radius: 999px;
  border: 1px solid #fecaca; background: #fff7f7; color: #b91c1c;
  font: 700 0.72rem/1 'Inter', system-ui, sans-serif; cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.15s;
}
.mg-narr-retry:hover { background: #fee2e2; border-color: #fca5a5; transform: translateY(-1px); }
.mg-narr-retry[hidden] { display: none; }
.mg-narr-tl-toggle {
  display: flex; align-items: center; gap: 8px; width: 100%; cursor: pointer;
  background: none; border: none; border-top: 1px solid #f0efed; margin-top: 2px; padding: 9px 0 3px;
  font: 600 0.7rem/1 'Inter', system-ui, sans-serif; color: #78716c;
}
.mg-narr-count { flex: 0 0 auto; }
.mg-narr-ticks { display: flex; flex-wrap: wrap; gap: 3px; flex: 1 1 auto; min-width: 0; }
.mg-narr-tick { width: 6px; height: 6px; border-radius: 2px; background: #d6d3d1; }
.mg-narr-tick[data-type="COMPLETE"] { background: #22c55e; }
.mg-narr-tick[data-type="ANSWER"] { background: #3b82f6; }
.mg-narr-tick[data-type="ABORT"],
.mg-narr-tick[data-type="NOOP"] { background: #ef4444; }
.mg-narr-tl-chev { flex: 0 0 auto; color: #a8a29e; transition: transform 200ms ease; }
.mg-narr-tl-toggle[aria-expanded="true"] .mg-narr-tl-chev { transform: rotate(180deg); }
.mg-narr-tl { display: flex; gap: 6px; overflow-x: auto; padding: 8px 0 2px; scrollbar-width: thin; }
.mg-narr-frame {
  position: relative; flex: 0 0 auto; width: 46px; height: 102px; padding: 0; cursor: pointer;
  border: 1px solid #e7e5e4; border-radius: 7px; overflow: hidden; background: #000;
}
.mg-narr-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mg-narr-frame.is-active { border-color: #16a34a; box-shadow: 0 0 0 2px rgba(34,197,94,0.3); }
.mg-narr-frame-num {
  position: absolute; left: 3px; top: 3px; font: 700 9px/1 'Inter', system-ui, sans-serif;
  color: #fff; background: rgba(0,0,0,0.55); border-radius: 4px; padding: 2px 4px;
}

/* ---- settings sheet (desktop right drawer / mobile bottom sheet) ----
   Lives at body level so it isn't trapped by #agent-console's transform. */
.mg-sheet { position: fixed; inset: 0; z-index: 95; }
.mg-sheet[hidden] { display: none; }
.mg-sheet-backdrop {
  position: absolute; inset: 0; background: rgba(15,23,42,0.32);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  opacity: 0; transition: opacity 240ms ease;
}
.mg-sheet[data-open="true"] .mg-sheet-backdrop { opacity: 1; }
.mg-sheet-panel {
  position: absolute; top: 0; right: 0; height: 100%; width: min(400px, 92vw);
  display: flex; flex-direction: column; background: #fff;
  box-shadow: -24px 0 60px -24px rgba(15,23,42,0.4);
  transform: translateX(100%);
  transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);
}
.mg-sheet[data-open="true"] .mg-sheet-panel { transform: translateX(0); }
.mg-sheet-grab { display: none; }
.mg-sheet-head {
  flex: 0 0 auto; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 20px 20px 14px; border-bottom: 1px solid #f0efed;
}
.mg-sheet-title { margin: 0; font: 700 1rem/1.2 'Inter', system-ui, sans-serif; color: #1c1917; }
.mg-sheet-sub { margin: 4px 0 0; font: 400 0.74rem/1.4 'Inter', system-ui, sans-serif; color: #a8a29e; }
.mg-sheet-body {
  flex: 1 1 auto; overflow-y: auto; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 18px;
}
.mg-sheet-foot {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 13px 20px; border-top: 1px solid #f0efed; background: #fafaf9;
}
.mg-field-group { display: flex; flex-direction: column; gap: 7px; }
.mg-field-label {
  font: 700 0.64rem/1 'Inter', system-ui, sans-serif; letter-spacing: 0.1em;
  text-transform: uppercase; color: #a8a29e;
}
.mg-field-select {
  width: 100%; padding: 9px 10px; border: 1px solid #d6d3d1; border-radius: 9px;
  font: 0.86rem/1.2 'Inter', system-ui, sans-serif; color: #1c1917; background: #fff;
}
.mg-field-select:focus { outline: none; border-color: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,0.15); }
/* tighten the reused field rows inside the grouped sheet body */
.mg-sheet-body .mg-agent-field { margin-bottom: 0; gap: 5px; }
.mg-sheet-body .mg-agent-blurb { margin: 0; }
.mg-sheet-body .mg-agent-args { margin-bottom: 0; }
.mg-sheet-body .mg-agent-foot { margin: 0; }

/* Narrow viewports: no room for a side card (and .hero-demo clips overflow) —
   dock the narration over the phone's lower screen as a compact translucent
   card, at native (un-counter-scaled) size. */
@media (max-width: 1024px) {
  .mg-narr {
    left: 10px; right: 10px; top: auto; bottom: 70px; width: auto;
    transform: none !important; max-height: 46%; overflow-y: auto;
    background: rgba(255,255,255,0.95);
  }
  .mg-narr-think { max-height: 7.75em; }
}

/* Phones: the settings drawer becomes a bottom sheet with a grab handle. */
@media (max-width: 640px) {
  .mg-sheet-panel {
    top: auto; right: 0; bottom: 0; left: 0; width: auto; height: auto; max-height: 88vh;
    border-radius: 18px 18px 0 0;
    transform: translateY(100%);
    box-shadow: 0 -22px 55px -22px rgba(15,23,42,0.45);
  }
  .mg-sheet[data-open="true"] .mg-sheet-panel { transform: translateY(0); }
  .mg-sheet-grab {
    display: block; flex: 0 0 auto; width: 38px; height: 4px; border-radius: 999px;
    background: #d6d3d1; margin: 9px auto 0;
  }
  .mg-sheet-head { padding-top: 12px; }
  /* keep the narration clear of the on-screen keyboard / short phones */
  .mg-narr { bottom: 64px; max-height: 40%; }
}

@media (prefers-reduced-motion: reduce) {
  .mg-ov-cursor { transition: none; }
  .mg-ov-ripple { animation-duration: 300ms; }
  .mg-ov-line { animation-duration: 1ms; }
  .mg-ov-trail-head { animation-delay: 0ms; }
  .mg-hud-dot { animation: none; }
  .mg-console-eyebrow-dot { animation: none !important; }
}

/* ---- model settings ---- */
.mg-agent-note { font-size: 0.78rem; color: #78716c; line-height: 1.5; margin: 0 0 10px; }
.mg-agent-field { display: flex; flex-direction: column; gap: 4px; font-size: 0.78rem; color: #44403c; margin-bottom: 10px; }
.mg-agent-field input, .mg-agent-field select {
  padding: 7px 9px; border: 1px solid #d6d3d1; border-radius: 8px; font-size: 0.84rem; color: #1c1917;
  font-family: 'JetBrains Mono','SF Mono',monospace; background: #fff;
}
.mg-agent-field select { font-family: 'Inter', system-ui, sans-serif; }
.mg-agent-field input:focus, .mg-agent-field select:focus { outline: none; border-color: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,0.15); }
.mg-agent-blurb,
.mg-agent-fwblurb { font-size: 0.72rem; color: #a8a29e; margin: -4px 0 10px; font-family: 'JetBrains Mono','SF Mono',monospace; }
.mg-agent-args { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px; margin-bottom: 12px; }
.mg-agent-arg { display: flex; flex-direction: column; gap: 4px; font-size: 0.74rem; color: #57534e; }
.mg-agent-arg input {
  padding: 6px 8px; border: 1px solid #d6d3d1; border-radius: 8px; font-size: 0.82rem;
  font-family: 'JetBrains Mono','SF Mono',monospace; color: #1c1917;
}
.mg-agent-arg input:focus { outline: none; border-color: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,0.15); }
.mg-agent-settings-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mg-agent-cfg-status { font-size: 0.76rem; color: #57534e; }
.mg-agent-foot { font-size: 0.72rem; color: #a8a29e; line-height: 1.5; margin: 10px 0 0; }

@media (max-width: 520px) {
  .mg-agent-args { grid-template-columns: 1fr; }
  .mg-console-eyebrow { display: none; }
}
