/* demo-chrome.css — DEMO ONLY. Slim top bar + layout offset.
 * Purely additive: one fixed bar element + an offset on the app shell.
 * Never part of the real product. */

/* Default until demo-chrome.js measures the real banner height (it's taller
   than the old slim bar and wraps on narrow screens — JS keeps this in sync). */
:root { --demo-bar-h: 74px; }

.demo-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2000;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 16px 26px;
  border-bottom: 1px solid rgba(99, 102, 241, 0.15);
  background:
    radial-gradient(520px 200px at 12% 50%, rgba(99, 102, 241, 0.16), transparent 68%),
    linear-gradient(180deg, rgba(99, 102, 241, 0.05), rgba(255, 255, 255, 0)),
    rgba(12, 12, 18, 0.92);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow: 0 8px 30px -18px rgba(0, 0, 0, 0.7);
  font-family: Inter, system-ui, -apple-system, sans-serif;
  color: #eeeef5;
  letter-spacing: -0.01em;
}
/* shimmer sweep */
.demo-bar::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 46%;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.12), transparent);
  transform: translateX(-130%);
}
@media (prefers-reduced-motion: no-preference) {
  .demo-bar::before { animation: demoBarSweep 4.6s linear infinite; }
}
@keyframes demoBarSweep {
  0%   { transform: translateX(-130%); }
  100% { transform: translateX(230%); }
}

.demo-bar-left {
  position: relative;
  display: flex;
  align-items: center;
  gap: 15px;
  min-width: 0;
}
.demo-bar-badge {
  width: 42px; height: 42px;
  border-radius: 11px;
  flex: none;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 50% 32%, #1d1d2c, #0d0d16);
  border: 1px solid rgba(99, 102, 241, 0.15);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4), 0 4px 14px -6px rgba(79, 70, 229, 0.5);
}
.demo-bar-badge img { width: 100%; height: 100%; object-fit: cover; display: block; }
.demo-bar-copy { min-width: 0; }
.demo-bar-head {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
  color: #eeeef5;
}
.demo-bar-sub {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #6f7188;
  margin-top: 3px;
  display: flex;
  align-items: center;
  gap: 9px;
}
.demo-bar-sub .sep {
  width: 3px; height: 3px;
  border-radius: 50%;
  background: #4c4e62;
  flex: none;
}

.demo-bar-right {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  flex: none;
}
.demo-bar-ghost {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 500;
  color: #a3a4b6;
  padding: 9px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: transparent;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.demo-bar-ghost:hover { border-color: rgba(99, 102, 241, 0.15); color: #eeeef5; }
.demo-bar-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 600;
  font-size: 13px;
  color: #fff;
  padding: 10px 17px;
  border-radius: 10px;
  border: none;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  letter-spacing: -0.01em;
  background: linear-gradient(160deg, #818cf8, #4f46e5);
  box-shadow: 0 1px 0 rgba(255,255,255,0.28) inset, 0 6px 18px rgba(79,70,229,0.42);
  transition: filter 0.18s ease, transform 0.18s ease;
}
.demo-bar-cta:hover { filter: brightness(1.06); transform: translateY(-1px); }
.demo-bar-cta svg { width: 13px; height: 13px; }

/* Mobile: drop the sentence and keep a slim single-row bar — just the avatar
   badge and the two CTAs — so it steals as little vertical height as possible. */
@media (max-width: 720px) {
  .demo-bar { flex-wrap: nowrap; gap: 12px; padding: 10px 14px; }
  .demo-bar-copy { display: none; }
  .demo-bar-left { flex: none; }
  .demo-bar-right { width: auto; gap: 8px; }
  .demo-bar-ghost, .demo-bar-cta { flex: none; padding: 8px 12px; font-size: 12px; }
}

/* App pages: lay the shell out as a normal flex column with the banner on top,
   so the banner takes its natural height and .app fills whatever's left. There
   is no pixel offset to get wrong, so the nav can never slide under the banner —
   however the headline wraps, and regardless of when (or whether) the JS height
   measurement runs. The product's .app is { width:100vw; height:100vh; flex }
   with non-fixed children, so flexing it to fill the remaining height is clean. */
body.demo-chrome:has(.app) {
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* Match the visible viewport so the inner .stage scroll can reach its
     bottom on iOS (the toolbar stays shown for inner-scroll pages, and 100vh
     would hide the tail behind it). See the .app note in main.css. */
  height: 100dvh;
  overflow: hidden;
}
/* flex:none so the banner keeps its full natural height — without it the
   flex column lets the banner shrink (it shares the cross-axis squeeze with
   the tall .app), which is what made it look thin. */
body.demo-chrome:has(.app) .demo-bar { position: relative; flex: none; }
body.demo-chrome:has(.app) .app {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}

/* The Eleventy marketing/blog pages don't use .app — there the banner stays
   fixed and we pad the body by its measured height (--demo-bar-h, kept in sync
   by demo-chrome.js). */
body.demo-chrome:not(:has(.app)) { padding-top: var(--demo-bar-h); }

/* Yellow "Sample data" marker, top-right corner of the inner tool pages.
   Scoped to app pages that are NOT the homepage (the homepage is the only page
   with .center-hero, and it already carries the full banner). pointer-events:none
   so it can never intercept clicks on the header's action buttons underneath. */
body.demo-chrome:has(.app):not(:has(.center-hero))::after {
  content: "Sample data";
  position: fixed;
  top: calc(var(--demo-bar-h, 74px) + 8px);
  right: 12px;
  z-index: 2100;
  padding: 4px 9px;
  font: 600 11px/1 Inter, system-ui, sans-serif;
  color: #3a2d00;
  background: #ffd43b;
  border: 1px solid rgba(0, 0, 0, 0.18);
  border-radius: 999px;
  box-shadow: 0 4px 12px -5px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}

/* Mobile: scroll the whole page like a normal document instead of an inner box.
   The desktop shell is a 100dvh frame with .stage scrolling inside it. On iOS
   Safari that fights the browser: while you drag, the toolbar hides and the
   frame grows so you can see the bottom; the moment you lift your finger the
   toolbar returns, the frame shrinks by the toolbar's height, and the last
   ~150px snaps back out of view (behind the toolbar, or behind the fixed
   composer). Letting the document itself scroll — the way get-tokens already
   does (rule below) — lets iOS manage the toolbar correctly, so nothing gets
   trapped. We unwind the flex frame on the body, .app and .stage, keep the
   banner pinned with sticky, and clip horizontal so nothing pans sideways. */
@media (max-width: 768px) {
  body.demo-chrome:has(.app) {
    display: block;
    height: auto;
    min-height: 100dvh;
    overflow-x: clip;      /* lock sideways pan without making body a y-scroller */
    overflow-y: visible;   /* the document (html) scrolls naturally */
  }
  body.demo-chrome:has(.app) .app {
    display: block;
    width: 100%;
    height: auto;
    min-height: 0;
    overflow-x: clip;    /* clip a "hair too wide" content without y-scrolling */
    overflow-y: visible;
  }
  body.demo-chrome:has(.app) .stage,
  body.demo-chrome:has(.app) .center {
    height: auto;
    min-height: 0;
    overflow-x: clip;
    overflow-y: visible;
  }
  /* Keep the banner in view while the page scrolls — the fixed hamburger and the
     "Sample data" badge anchor just beneath it, so it can't scroll away. */
  body.demo-chrome:has(.app) .demo-bar {
    position: sticky;
    top: 0;
  }
  /* Breathing room at the end of the inner tool pages so the last card clears
     the iPhone home indicator / Safari bottom bar. */
  body.demo-chrome:has(.app) .center-scroll {
    padding-bottom: calc(28px + env(safe-area-inset-bottom));
  }

  /* Homepage: composer stays locked to the footer like a native chat app;
     reserve room below the hero so the last feature chip clears it. */
  body.demo-chrome .center.center-hero:not(.chat-active) {
    justify-content: flex-start;
    gap: 24px;
    padding-bottom: calc(190px + env(safe-area-inset-bottom));
  }
  /* The wide radial glow (inset -80px each side) would poke past the viewport on
     a fixed, full-width composer and pan sideways — drop it. */
  body.demo-chrome .center.center-hero:not(.chat-active) .composer::before {
    display: none;
  }
  body.demo-chrome .center.center-hero:not(.chat-active) .composer {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    margin: 0;
    z-index: 50;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
    background: rgba(10, 10, 11, 0.96);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid rgba(255, 255, 255, 0.06);
  }
}

/* get-tokens is an .app page but (unlike the others) scrolls the whole window
   rather than an inner .center-scroll — get-tokens.css sets body{overflow-y:auto}
   and lets the content run past 100vh. The generic .app rule above clamps the
   body to height:100vh + overflow:hidden, which clips that content and kills
   the scroll. Restore normal document flow for this page: banner sits at the
   top, the page scrolls naturally. */
body.demo-chrome[data-page="get-tokens"] {
  display: block;
  height: auto;
  min-height: 100vh;
  overflow-y: auto;
}
body.demo-chrome[data-page="get-tokens"] .demo-bar { position: relative; }

/* Hide signed-in-only controls that don't make sense in a cold demo. */
body.demo-chrome [data-action="logout"],
body.demo-chrome [data-action="dev-new-account"],
body.demo-chrome [data-require="dev-reset"] { display: none !important; }

/* Front-page hero: rounded AI avatar in place of the goat-particle canvas
   (build-demo.sh swaps the <canvas> for <img class="logo-avatar-img">). */
.logo .logo-avatar-img {
  display: block;
  width: 132px;
  height: 132px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow:
    0 0 0 1.5px rgba(99, 102, 241, 0.30),    /* faint full static ring */
    0 0 34px -6px rgba(99, 102, 241, 0.30),   /* green glow */
    0 16px 44px -12px rgba(0, 0, 0, 0.65);
}

/* Sci-fi accent: a bright green arc that slowly orbits the avatar's ring,
   so the static green line looks alive — like an AI "thinking". */
.logo:has(> .logo-avatar-img)::before {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 50%;
  padding: 2px;                  /* ring thickness */
  background: conic-gradient(from 0deg,
    rgba(99, 102, 241, 0) 0deg,
    rgba(99, 102, 241, 0.06) 150deg,
    rgba(99, 102, 241, 0.40) 250deg,
    rgba(150, 255, 190, 0.95) 322deg,
    rgba(99, 102, 241, 0) 360deg);
  /* keep only the ring (border-box minus content-box) */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  animation: avatarRingSpin 8s linear infinite;
  pointer-events: none;
  z-index: 1;
}
@keyframes avatarRingSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .logo:has(> .logo-avatar-img)::before { animation: none; }
}

/* Front-page hero: green-checkmark feature highlights in place of the
   clickable suggestion chips (build-demo.sh swaps .suggested → ul.hero-features). */
.hero-features {
  list-style: none;
  margin: 22px auto 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 9px 10px;
  max-width: 580px;
}
.hero-features li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: rgba(232, 232, 234, 0.85);
  padding: 7px 14px 7px 11px;
  border-radius: 999px;
  background: rgba(99, 102, 241, 0.06);
  border: 1px solid rgba(99, 102, 241, 0.18);
}
.hero-features li::before {
  content: "";
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 12l4 4 10-10' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 12l4 4 10-10' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
}

/* Marketplace sign-up nudge — slim banner prepended to the catalog and the
   per-domain landing page (demo-chrome.js). Explains the masked names and
   funnels to the free sign-up. Demo-only. */
.demo-mk-nudge {
  display: flex;
  align-items: center;
  gap: 12px;
  /* First child of .center.center-scroll — horizontal inset + scrollbar gutter
     come from the container, so it lines up exactly with the cards. The
     container's flex `gap` spaces it from the content below. */
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: linear-gradient(90deg, rgba(99, 102, 241, 0.10), rgba(99, 102, 241, 0.04));
  border: 1px solid rgba(99, 102, 241, 0.26);
}
.demo-mk-nudge-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 8px;
  background: rgba(99, 102, 241, 0.14);
  color: var(--accent, #6366f1);
}
.demo-mk-nudge-ico svg { width: 16px; height: 16px; }
.demo-mk-nudge-text {
  flex: 1 1 auto;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text, #e8e8ea);
}
.demo-mk-nudge-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  padding: 8px 16px;
  border-radius: 999px;
  background: linear-gradient(160deg, #818cf8, #4f46e5);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  letter-spacing: -0.01em;
  box-shadow: 0 1px 0 rgba(255,255,255,0.28) inset, 0 6px 18px rgba(79,70,229,0.42);
  transition: filter 0.18s ease, transform 0.18s ease;
}
.demo-mk-nudge-cta:hover { filter: brightness(1.08); transform: translateY(-1px); }
.demo-mk-nudge-cta svg { width: 14px; height: 14px; }
@media (max-width: 640px) {
  .demo-mk-nudge { flex-wrap: wrap; }
  .demo-mk-nudge-text { flex-basis: 100%; order: 3; }
}

/* Marketplace catalog: the whole listing card is clickable (demo-chrome.js
   navigates to the detail page), and the per-offer marketplace links are
   disabled here so a click anywhere on the card opens the detail. The offers
   stay clickable on the detail page (data-page="marketplace-item"). */
body[data-page="marketplace"] .mk-card { cursor: pointer; }
body[data-page="marketplace"] a.mk-offer-name {
  pointer-events: none;
  text-decoration: none;
}

/* Composer chips: open the Skill and MCP menus upward (above the chip),
   the same way the Model menu already does — they sit at the bottom of the
   page, so a downward menu would spill off-screen. */
.dropdown[data-dropdown="skill"] .menu,
.dropdown[data-dropdown="mcp"] .menu {
  top: auto;
  bottom: calc(100% + 8px);
}

/* Chat: show the Capraseo AI character avatar (the same image as the
   /health/ "Ask Capraseo AI" card) to the left of each AI reply, instead
   of the default green goat silhouette. !important because demo-chrome.css
   is injected before chat-thread.css. */
.chat-avatar {
  -webkit-mask: none !important;
  mask: none !important;
  background-color: transparent !important;
  background-image: url('https://hel1.your-objectstorage.com/capraseo/ai-characters/e5a2ad52f22f4e688ce77c4c22b0075a/image.webp') !important;
  background-size: cover !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  filter: none !important;
}

/* ── Sign-up gate tooltip (demo-signup-gate.js) ──────────────────────
   Hover hint shown over write-actions that need a real account. Self-
   contained so it works on every page (chip-tooltip.css isn't global). */
.demo-gate-tip {
  position: fixed;
  z-index: 2400;
  max-width: 230px;
  padding: 9px 11px 8px;
  border-radius: 9px;
  background: linear-gradient(180deg, rgba(28, 33, 41, 0.98), rgba(18, 22, 28, 0.98));
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #e8e8ea;
  font-size: 11.5px;
  line-height: 1.45;
  pointer-events: none;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.demo-gate-tip.visible { opacity: 1; transform: translateY(0); }
.demo-gate-tip-body { color: rgba(232, 232, 234, 0.92); }
.demo-gate-tip-foot {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  color: #6366f1;
  font-weight: 600;
  font-size: 11px;
}

/* ── Mobile drawer × demo banner ─────────────────────────────────────
   The product's mobile nav (≤768px, css/main.css) is a viewport-fixed
   off-canvas drawer with a floating hamburger pinned at top:12px. On the
   demo, the banner sits in-flow at the very top of every .app page (its
   height tracked live in --demo-bar-h by demo-chrome.js), so a top:12px
   hamburger and a top:0 drawer would slide UNDER the banner and be
   unusable. Push both down by the banner height. Uses body.demo-chrome
   to outweigh main.css (which is injected after this file). */
@media (max-width: 768px) {
  body.demo-chrome .mobile-nav-toggle {
    top: calc(var(--demo-bar-h, 74px) + 8px);
  }
  body.demo-chrome .sidebar {
    top: var(--demo-bar-h, 74px);
    height: calc(100vh - var(--demo-bar-h, 74px));
    height: calc(100dvh - var(--demo-bar-h, 74px));
  }
}
