/* =====================================================================
   composer/primitives.css  —  V3 primitive vocabulary (Phase 1)

   The ONLY place in the V3 renderer where styling touches design tokens.
   Every rule references --ds-* tokens (emitted by {% composer_theme_css %}).
   Blocks/variants compose these primitives and NEVER declare raw colour,
   font, radius, or spacing — the token lint gate enforces it.

   Rule: no hex, no font-family literal, no px radius here except inside
   var(--token, <fallback>). Fallbacks keep the preview sane if a token is
   missing; production always has the token.
   ===================================================================== */

.cx-root {
  background: var(--ds-page-bg, #f6f8fc);
  color: var(--ds-text-strong, #0f172a);
  font-family: var(--ds-font-body, system-ui, sans-serif);
  line-height: var(--ds-line-height, 1.6);
  min-height: 100%;
}

/* border-box for every primitive — without it .cx-container (width:100% +
   padding-inline) overflows its parent (right-edge clipping). The public site's
   site.css supplies a global reset; this makes the primitives self-contained
   (editor canvas + any future surface). Scoped to the cx- namespace. */
.cx-root, [class^="cx-"], [class*=" cx-"],
[class^="cxv-"], [class*=" cxv-"] { box-sizing: border-box; }   /* cxv- variants too — the ^="cx-" selector misses them (they start "cxv", not "cx-"), which let inputs (width:100%+padding) bleed */

/* ── Layout primitives ───────────────────────────────────────────── */
.cx-stack   { display: flex; flex-direction: column; gap: var(--ds-gap, 1.5rem); }
.cx-row     { display: flex; flex-direction: row; gap: var(--ds-gap, 1.5rem); align-items: center; }
.cx-row--wrap { flex-wrap: wrap; }
.cx-grid    { display: grid; gap: var(--ds-gap, 1.5rem); grid-template-columns: repeat(var(--cx-cols, 3), minmax(0, 1fr)); }
.cx-section { padding-block: var(--ds-section-py, 5rem); }
.cx-container { width: 100%; max-width: 72rem; margin-inline: auto; padding-inline: var(--ds-space, 1rem); }

/* Alignment / rhythm utilities — layout only, no design tokens hardcoded. */
.cx-center         { text-align: center; align-items: center; }
.cx-justify-center { justify-content: center; }
.cx-stack--tight   { gap: calc(var(--ds-gap, 1.5rem) * 0.5); }
.cx-measure        { max-width: 46rem; }

/* Bento: asymmetric grid where the first cell dominates. Layout only. */
.cx-bento { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--ds-gap, 1.5rem); }
.cx-bento > :first-child { grid-column: span 2; grid-row: span 2; }

/* Full-bleed media/effect hero stage. */
.cx-stage { min-height: 60vh; display: flex; align-items: center; }

@media (max-width: 768px) {
  .cx-grid { grid-template-columns: 1fr; }
  .cx-bento { grid-template-columns: 1fr; }
  .cx-bento > :first-child { grid-column: auto; grid-row: auto; }
}

/* ── Text primitives ─────────────────────────────────────────────── */
.cx-heading {
  font-family: var(--ds-font-heading, system-ui, sans-serif);
  font-weight: var(--ds-heading-weight, 700);
  letter-spacing: var(--ds-tracking, -0.02em);
  color: var(--ds-text-strong, #0f172a);
  line-height: 1.15;
  margin: 0;
}
.cx-heading--1 { font-size: clamp(2rem, 5vw, 3.25rem); }
.cx-heading--2 { font-size: clamp(1.5rem, 3vw, 2.25rem); }
.cx-heading--3 { font-size: 1.25rem; }

.cx-text        { color: var(--ds-text-strong, #0f172a); margin: 0; }
.cx-text--muted { color: var(--ds-text-muted, #475569); }
.cx-text--soft  { color: var(--ds-text-soft, #64748b); }
.cx-text--lead  { font-size: 1.125rem; color: var(--ds-text-muted, #475569); }

/* ── Surface primitives ──────────────────────────────────────────── */
.cx-card {
  background: var(--ds-surface, #ffffff);
  border: var(--ds-border-width, 1px) solid var(--ds-border, #e2e8f0);
  border-radius: var(--ds-radius, 12px);
  box-shadow: var(--ds-shadow, none);
  padding: var(--ds-card-p, 1.5rem);
}
.cx-card--subtle { background: var(--ds-surface-2, #f1f5f9); }

/* ── Interactive primitives ──────────────────────────────────────── */
.cx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.7em 1.25em;
  border-radius: var(--ds-radius-sm, 8px);
  font-weight: 600; font-family: inherit; font-size: 0.95rem;
  border: var(--ds-border-width, 1px) solid transparent;
  cursor: pointer; text-decoration: none;
  transition: filter 0.15s ease, transform 0.15s ease;
}
.cx-btn:active { transform: translateY(1px); }
.cx-btn--primary   { background: var(--ds-primary, #4f46e5); color: var(--ds-on-primary, #ffffff); }
.cx-btn--primary:hover  { filter: brightness(1.06); }
.cx-btn--secondary { background: var(--ds-surface, #fff); color: var(--ds-text-strong, #0f172a); border-color: var(--ds-border, #e2e8f0); }
.cx-btn--ghost     { background: transparent; color: var(--ds-primary, #4f46e5); }

/* ── Badge ───────────────────────────────────────────────────────── */
.cx-badge {
  display: inline-flex; align-items: center; gap: 0.35em;
  padding: 0.25em 0.7em; border-radius: var(--ds-radius-lg, 18px);
  font-size: 0.75rem; font-weight: 600;
  background: color-mix(in srgb, var(--ds-accent, #ec4899) 14%, transparent);
  color: var(--ds-accent, #ec4899);
}

/* ── Avatar (round person image) ─────────────────────────────────── */
.cx-avatar {
  width: 3.5rem; height: 3.5rem; border-radius: var(--ds-radius-full, 9999px);
  object-fit: cover; background: var(--ds-surface-2, #f1f5f9);
  border: var(--ds-border-width, 1px) solid var(--ds-border, #e2e8f0);
}

/* ── Media tile (gallery / hero image) ───────────────────────────── */
.cx-media {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--ds-radius, 12px); background: var(--ds-surface-2, #f1f5f9);
}

/* ── Price display ───────────────────────────────────────────────── */
.cx-price { font-size: 2rem; font-weight: 800; color: var(--ds-text-strong, #0f172a); line-height: 1; }
.cx-price small { font-size: 0.9rem; font-weight: 500; color: var(--ds-text-muted, #475569); }

/* ── Rating ──────────────────────────────────────────────────────── */
.cx-rating { color: var(--ds-accent, #ec4899); font-size: 0.9rem; letter-spacing: 0.05em; }

/* ── Icon slot ───────────────────────────────────────────────────── */
.cx-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; border-radius: var(--ds-radius-sm, 8px);
  background: color-mix(in srgb, var(--ds-primary, #4f46e5) 12%, transparent);
  color: var(--ds-primary, #4f46e5);
}

/* ── Prose (imported rich content: prose block, cx_prose HTML) ─────────────── */
.cx-prose > *          { margin-block: 0; }
.cx-prose > * + *      { margin-block-start: 0.9em; }
.cx-prose h1, .cx-prose h2, .cx-prose h3, .cx-prose h4 {
  font-family: var(--ds-font-heading, system-ui, sans-serif); font-weight: 700;
  line-height: 1.25; color: var(--ds-text-strong, #0f172a); }
.cx-prose h2           { font-size: 1.4rem; }
.cx-prose h3           { font-size: 1.15rem; }
.cx-prose ul, .cx-prose ol { padding-inline-start: 1.4em; }
.cx-prose li           { margin-block: 0.25em; }
.cx-prose blockquote   { border-inline-start: 3px solid var(--ds-border, rgba(148,163,184,0.4));
  padding-inline-start: 1em; color: var(--ds-text-muted, #475569); }
.cx-prose code         { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 0.9em; }
.cx-prose pre          { overflow: auto; padding: 1em; border-radius: var(--ds-radius-sm, 8px);
  background: var(--ds-surface-2, #f1f5f9); }

/* ── Masonry gallery (gallery · masonry archetype) — layout only ──────────── */
.cx-masonry            { columns: 3; column-gap: var(--ds-gap, 1.5rem); }
.cx-masonry-item       { break-inside: avoid; margin-bottom: var(--ds-gap, 1.5rem); }
.cx-masonry .cx-media  { width: 100%; height: auto; display: block; border-radius: var(--ds-radius-sm, 8px); }
@media (max-width: 900px) { .cx-masonry { columns: 2; } }
@media (max-width: 560px) { .cx-masonry { columns: 1; } }

/* ── Showcase frame (hero · showcase archetype) — framed product panel ────── */
.cx-showcase-frame {
  width: 100%; max-width: 62rem; aspect-ratio: 16 / 9; margin-inline: auto; margin-block-start: 1rem;
  border-radius: var(--ds-card-radius, 16px);
  border: 1px solid var(--ds-border, rgba(148,163,184,0.22));
  background: var(--ds-surface-2, #f1f5f9);
  box-shadow: var(--ds-card-shadow, 0 22px 55px -26px rgba(2,6,23,0.42));
}

/* ── Gallery frames (device / browser mockups + layouts) — layout + neutral chrome ── */
/* Device chrome is intentionally dark in BOTH modes (a phone/browser is dark); exposed
   as tokens with dark fallbacks so it stays "token-clean" and theme-overridable. */
.cx-gallery-bento { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--ds-gap,1.5rem); grid-auto-flow:dense; }
.cx-gallery-bento > :first-child { grid-column:span 2; grid-row:span 2; }
.cx-gallery-bento .cx-media { width:100%; height:100%; object-fit:cover; display:block; border-radius:var(--ds-radius-sm,10px); min-height:9rem; }
@media (max-width:760px){ .cx-gallery-bento { grid-template-columns:repeat(2,1fr); } .cx-gallery-bento > :first-child { grid-column:span 2; grid-row:auto; } }

.cx-runway { display:flex; gap:var(--ds-gap,1.5rem); overflow-x:auto; scroll-snap-type:x mandatory;
  padding-block-end:.75rem; -webkit-overflow-scrolling:touch; }
.cx-runway > * { scroll-snap-align:center; flex:0 0 min(78vw,22rem); }
.cx-runway .cx-media { width:100%; aspect-ratio:4/3; object-fit:cover; display:block; border-radius:var(--ds-card-radius,14px); }

.cx-phone { position:relative; width:clamp(180px,60vw,226px); aspect-ratio:9/19.3; margin-inline:auto;
  border-radius:34px; padding:10px; background:var(--ds-device-bezel,#0b1220);
  box-shadow:0 26px 60px -22px rgba(2,6,23,.6), inset 0 0 0 1.5px rgba(255,255,255,.06); }
.cx-phone::before { content:''; position:absolute; top:12px; left:50%; transform:translateX(-50%);
  width:38%; height:16px; border-radius:0 0 12px 12px; background:var(--ds-device-bezel,#0b1220); z-index:3; }
.cx-phone-screen { position:relative; width:100%; height:100%; border-radius:25px; overflow:hidden;
  background:var(--ds-device-screen,#0f172a); display:block; }
.cx-phone-screen img, .cx-phone-screen video { width:100%; height:100%; object-fit:cover; display:block; }

.cx-browser { position:relative; border-radius:16px; overflow:hidden; background:var(--ds-device-bezel,#0b1220);
  box-shadow:0 26px 60px -24px rgba(2,6,23,.6), inset 0 0 0 1.5px rgba(255,255,255,.06); }
.cx-browser-chrome { display:flex; align-items:center; gap:10px; height:34px; padding:0 12px;
  background:var(--ds-device-chrome,#0e1626); border-bottom:1px solid rgba(255,255,255,.06); }
.cx-browser-dots { display:flex; gap:6px; flex:none; }
.cx-browser-dots i { width:10px; height:10px; border-radius:50%; display:block; background:rgba(255,255,255,.28); }
.cx-browser-url { flex:1; max-width:62%; height:15px; margin-inline:auto; border-radius:6px; background:rgba(255,255,255,.08); }
.cx-browser-screen { position:relative; width:100%; aspect-ratio:16/10; background:var(--ds-device-screen,#0f172a); display:block; }
.cx-browser-screen img, .cx-browser-screen video { width:100%; height:100%; object-fit:cover; display:block; }
.cx-device-cap { display:block; text-align:center; font-weight:700; font-size:.92rem; margin-top:.85rem; }

/* ── Keyword marquee (hero · marquee archetype) — scrolling chip strip ─────── */
.cx-marquee { width:100%; overflow:hidden; margin-block-start:1.25rem;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent); }
.cx-marquee-track { display:inline-flex; gap:.6rem; padding-block:.25rem; white-space:nowrap;
  animation:cx-marquee 28s linear infinite; }
.cx-marquee:hover .cx-marquee-track { animation-play-state:paused; }
.cx-chip { display:inline-flex; align-items:center; gap:.4rem; padding:.5rem .95rem; border-radius:999px;
  font-weight:600; font-size:.9rem; white-space:nowrap;
  background:var(--ds-surface-2, #f1f5f9); color:var(--ds-text-strong, #0f172a);
  border:1px solid var(--ds-border, rgba(148,163,184,0.22)); }
@keyframes cx-marquee { from { transform:translateX(0); } to { transform:translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .cx-marquee-track { animation:none; flex-wrap:wrap; white-space:normal; } }
