/* ===================================================================
   Bladestack template pack — style tokens.
   All selectors scoped under .tp-bladestack so the pack can coexist
   with other packs and the Nueform operator chrome without leaking.
   =================================================================== */

.tp-bladestack {
  /* These vars are local fallbacks; the operator shell may override them
     with brand-row values via :root.tp-active before the pack mounts. */
  --tp-bg: #0A0A0A;
  --tp-bg-elev: #111111;
  --tp-text: #FFFFFF;
  --tp-text-muted: #838383;
  --tp-text-dim: #4a4a4a;
  --tp-accent: #FF3D00;
  --tp-accent-2: #FF9900;
  --tp-grid-line: rgba(255, 255, 255, 0.04);
  --tp-grid-line-strong: rgba(255, 255, 255, 0.08);
  --tp-display: 'Inter Tight', system-ui, sans-serif;
  --tp-body: 'Manrope', system-ui, sans-serif;
  /* Chart tokens — read by Chart.js configs at render time so the
     pack drives every visual aspect of the chart (colors, fonts, grid). */
  --tp-chart-grid:        rgba(255, 255, 255, 0.06);
  --tp-chart-axis:        #6a6a6a;
  --tp-chart-axis-label:  #b5b5b5;
  --tp-chart-bar-1:       #FF3D00;
  --tp-chart-bar-2:       #FF9900;
  --tp-chart-bar-3:       #f1f1f1;
  --tp-chart-line:        #FF3D00;
  --tp-chart-font-family: 'JetBrains Mono', ui-monospace, monospace;
  --tp-chart-font-size:   18px;
}

/* ============== CAROUSEL SLIDES ============== */
/* Aspect-aware (v2.5): see default pack style-tokens.css for the full
   aspect → CSS-var contract. */
.tp-bladestack .cx-slide {
  width: var(--slide-w, 1080px);
  height: var(--slide-h, 1080px);
  position: relative;
  background: var(--tp-bg);
  overflow: hidden;
  color: var(--tp-text);
  isolation: isolate;
  font-family: var(--tp-body);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 1;
  margin-bottom: 24px;
}
.tp-bladestack .cx-slide::before {
  content: ""; position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, var(--tp-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tp-grid-line) 1px, transparent 1px);
  background-size: 60px 60px;
  pointer-events: none; z-index: 0;
}
.tp-bladestack .cx-slide::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 50%, transparent 60%, rgba(0,0,0,0.4) 100%);
  pointer-events: none; z-index: 1;
}
.tp-bladestack .cx-slide > * { position: relative; z-index: 2; }
.tp-bladestack .cx-wheel {
  position: absolute; z-index: 0; pointer-events: none;
  width: var(--wheel-size, 0px); height: var(--wheel-size, 0px);
  left: var(--wheel-cx, 50%); top: var(--wheel-cy, 50%);
  transform: translate(-50%, -50%) rotate(180deg);
  opacity: 0.45;
  background-size: contain; background-repeat: no-repeat; background-position: center;
}
.tp-bladestack .cx-wheel-mask {
  position: absolute; z-index: 0; pointer-events: none;
  width: calc(var(--wheel-size, 0px) * 1.4); height: calc(var(--wheel-size, 0px) * 1.4);
  left: var(--wheel-cx, 50%); top: var(--wheel-cy, 50%);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, var(--tp-bg) 30%, transparent 70%);
}
.tp-bladestack .cx-glow {
  position: absolute; z-index: 1; pointer-events: none;
  left: var(--glow-x, 30%); top: var(--glow-y, 65%);
  width: var(--glow-w, 75%); height: var(--glow-h, 75%);
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center, rgba(255, 61, 0, 0.18) 0%, transparent 80%);
  filter: blur(40px);
}
.tp-bladestack .cx-glow-2 {
  position: absolute; z-index: 1; pointer-events: none;
  left: var(--glow-x-2, 45%); top: var(--glow-y-2, 50%);
  width: var(--glow-w-2, 65%); height: var(--glow-h-2, 60%);
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center, rgba(255, 61, 0, 0.14) 0%, transparent 65%);
  filter: blur(45px);
}

.tp-bladestack .cx-chrome {
  position: absolute; top: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
}
.tp-bladestack .cx-indicator {
  font-family: var(--tp-display);
  font-size: 14px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--tp-text-muted);
  display: flex; align-items: center; gap: 14px;
}
.tp-bladestack .cx-indicator::before {
  content: ""; width: 24px; height: 2px; background: var(--tp-accent);
}
.tp-bladestack .cx-logo svg { display: block; height: 24px; width: auto; }

.tp-bladestack .cx-footer {
  position: absolute; bottom: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--tp-display);
  font-size: 13px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--tp-text-dim);
}
.tp-bladestack .cx-footer::before {
  content: ""; position: absolute; left: 0; right: 0; top: -16px;
  height: 1px; background: var(--tp-grid-line-strong);
}
.tp-bladestack .cx-footer::after {
  content: ""; position: absolute;
  left: -60px; right: -60px; bottom: -60px;
  height: 160px;
  background: linear-gradient(to bottom, transparent, var(--tp-bg) 80%);
  z-index: -1;
  pointer-events: none;
}
.tp-bladestack .cx-ticker { display: flex; gap: 28px; }
.tp-bladestack .cx-ticker span { color: var(--tp-text-muted); }

.tp-bladestack .cx-section-label {
  font-family: var(--tp-display);
  font-size: 16px; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--tp-accent);
  display: inline-flex; align-items: center; gap: 14px;
  margin-bottom: 36px;
}
.tp-bladestack .cx-section-label:empty { display: none; }
.tp-bladestack .cx-section-label::before {
  content: ""; width: 28px; height: 2px; background: var(--tp-accent);
}
.tp-bladestack .cx-body {
  position: absolute; left: 60px; right: 60px;
  top: 50%; transform: translateY(-50%);
  max-width: 940px;
}
.tp-bladestack .cx-body--top { top: 220px; transform: none; }

.tp-bladestack .cx-h-hook,
.tp-bladestack .cx-h-problem,
.tp-bladestack .cx-h-insight,
.tp-bladestack .cx-h-cta {
  font-family: var(--tp-display);
  font-size: clamp(60px, calc(var(--slide-h, 1080px) * 0.111), 140px);
  line-height: 1.02; font-weight: 700;
  letter-spacing: -0.025em; color: var(--tp-text);
}
.tp-bladestack .cx-h-cta { margin-bottom: 48px; }
.tp-bladestack .cx-subtitle {
  font-family: var(--tp-body);
  font-size: 22px; font-weight: 500;
  color: var(--tp-text-muted); letter-spacing: 0.02em;
  margin-top: 20px; text-transform: uppercase;
}
.tp-bladestack .cx-stat-wrap {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; padding: 0 80px;
}
.tp-bladestack .cx-stat-number {
  font-family: var(--tp-display);
  font-size: 240px; font-weight: 700;
  letter-spacing: -0.04em; line-height: 1;
  color: var(--tp-text);
}
.tp-bladestack .cx-stat-rule {
  width: 80px; height: 3px; background: var(--tp-accent); margin: 36px 0 32px;
}
.tp-bladestack .cx-stat-caption {
  font-family: var(--tp-body);
  font-size: 28px; font-weight: 500;
  color: var(--tp-text-muted); line-height: 1.4; max-width: 720px;
}
.tp-bladestack .cx-cta-button {
  display: inline-flex; align-items: center; gap: 14px;
  padding: 22px 36px;
  border: 1.5px solid var(--tp-accent);
  color: var(--tp-accent);
  font-family: var(--tp-display);
  font-size: 20px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.tp-bladestack .cx-cta-button .cx-arrow { font-size: 24px; line-height: 1; }
.tp-bladestack .cx-cta-url {
  margin-top: 28px;
  font-family: var(--tp-display);
  font-size: 18px; color: var(--tp-text-muted); letter-spacing: 0.04em;
}
.tp-bladestack .cx-data-strip {
  position: absolute; bottom: 160px; left: 60px; right: 60px;
  display: flex; gap: 18px; z-index: 2;
}
.tp-bladestack .cx-data-strip .cx-bar { flex: 1; height: 4px; background: var(--tp-grid-line-strong); }
.tp-bladestack .cx-data-strip .cx-bar.cx-active { background: var(--tp-accent); }

/* ============== SINGLE-CARD (image post) ==============
   Aspect-aware single card. Dimensions come from --card-w / --card-h
   CSS vars set by the renderer per platform/aspect (see default pack
   style-tokens.css for the full aspect → size mapping). Inherits the
   Terminal chrome (grid background + ticker footer) for visual continuity
   with the carousel slides. */
.tp-bladestack .cx-card {
  width: var(--card-w, 1080px);
  height: var(--card-h, 1080px);
  position: relative;
  background: var(--tp-bg);
  overflow: hidden;
  color: var(--tp-text);
  isolation: isolate;
  font-family: var(--tp-body);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 1;
  margin-bottom: 24px;
}
.tp-bladestack .cx-card::before {
  content: ""; position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, var(--tp-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tp-grid-line) 1px, transparent 1px);
  background-size: 60px 60px;
  pointer-events: none; z-index: 0;
}
.tp-bladestack .cx-card::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 50%, transparent 60%, rgba(0,0,0,0.4) 100%);
  pointer-events: none; z-index: 1;
}
.tp-bladestack .cx-card > * { position: relative; z-index: 2; }
.tp-bladestack .cx-card-wheel {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  width: var(--wheel-size, 0px);
  height: var(--wheel-size, 0px);
  left: var(--wheel-cx, 50%);
  top: var(--wheel-cy, 50%);
  transform: translate(-50%, -50%) rotate(180deg);
  opacity: 0.45;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
.tp-bladestack .cx-card-wheel-mask {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  width: calc(var(--wheel-size, 0px) * 1.4);
  height: calc(var(--wheel-size, 0px) * 1.4);
  left: var(--wheel-cx, 50%);
  top: var(--wheel-cy, 50%);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, var(--tp-bg) 30%, transparent 70%);
}
.tp-bladestack .cx-card-glow {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  left: var(--glow-x, 30%);
  top: var(--glow-y, 65%);
  width: var(--glow-w, 75%);
  height: var(--glow-h, 75%);
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center, rgba(255, 61, 0, 0.18) 0%, transparent 80%);
  filter: blur(40px);
}
.tp-bladestack .cx-card-scanlines {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 3px,
    rgba(0, 0, 0, 0.09) 3px,
    rgba(0, 0, 0, 0.09) 4px
  );
}
.tp-bladestack .cx-card-glow-2 {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  left: var(--glow-x-2, 45%);
  top: var(--glow-y-2, 50%);
  width: var(--glow-w-2, 65%);
  height: var(--glow-h-2, 60%);
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center, rgba(255, 61, 0, 0.14) 0%, transparent 65%);
  filter: blur(45px);
}
.tp-bladestack .cx-card-chrome {
  position: absolute; top: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
}
.tp-bladestack .cx-card-indicator {
  font-family: var(--tp-display);
  font-size: 14px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--tp-text-muted);
  display: flex; align-items: center; gap: 14px;
}
.tp-bladestack .cx-card-indicator::before {
  content: ""; width: 24px; height: 2px; background: var(--tp-accent);
}
.tp-bladestack .cx-card-logo svg { display: block; height: 24px; width: auto; }
.tp-bladestack .cx-card-body {
  position: absolute; left: 60px; right: 60px;
  top: 50%; transform: translateY(-50%);
  max-width: 940px;
}
.tp-bladestack .cx-card-body--top {
  top: calc(var(--card-h, 1080px) * 0.21);
  transform: none;
}
.tp-bladestack .cx-card-text {
  font-family: var(--tp-display);
  font-size: clamp(60px, calc(var(--card-h, 1080px) * 0.111), 140px);
  line-height: 1.02; font-weight: 700;
  letter-spacing: -0.025em; color: var(--tp-text);
}
.tp-bladestack .cx-card-subtitle {
  font-family: var(--tp-body);
  font-size: clamp(20px, calc(var(--card-h, 1080px) * 0.035), 50px);
  line-height: 1.35; font-weight: 400;
  color: var(--tp-text-muted);
  margin-top: 28px;
}
.tp-bladestack .cx-card-subtitle:empty { display: none; }
.tp-bladestack .cx-card-footer {
  position: absolute; bottom: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--tp-display);
  font-size: 13px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--tp-text-dim);
}
.tp-bladestack .cx-card-footer::before {
  content: ""; position: absolute; left: 0; right: 0; top: -16px;
  height: 2px; background: var(--tp-grid-line-strong);
}
.tp-bladestack .cx-card-footer::after {
  content: ""; position: absolute;
  left: -60px; right: -60px; bottom: -60px;
  height: 160px;
  background: linear-gradient(to bottom, transparent, var(--tp-bg) 80%);
  z-index: -1;
  pointer-events: none;
}
.tp-bladestack .cx-card-ticker { display: flex; gap: 28px; }
.tp-bladestack .cx-card-ticker span { color: var(--tp-text-muted); }

/* ============== CAROUSEL — EDITORIAL VARIANT ==============
   Same .cx-slide outer (1080x1080, dark bg, scoped under .tp-bladestack)
   but every editorial-only piece is namespaced .cx-ed-* so the Terminal
   variant's selectors don't collide. The editorial layout strips the grid
   background and ticker chrome — read like a printed brief, not a terminal. */
.tp-bladestack .cx-slide.cx-ed::before,
.tp-bladestack .cx-slide.cx-ed::after { display: none; }

.tp-bladestack .cx-ed-chrome {
  position: absolute; top: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
}
.tp-bladestack .cx-ed-eyebrow {
  font-family: var(--tp-display);
  font-size: 14px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--tp-text-muted);
}
.tp-bladestack .cx-ed-logo svg { display: block; height: 24px; width: auto; }

.tp-bladestack .cx-ed-body {
  position: absolute; left: 120px; right: 120px;
  top: 50%; transform: translateY(-50%);
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 56px;
}
.tp-bladestack .cx-ed-body--cta { gap: 40px; }

.tp-bladestack .cx-ed-rule {
  width: 64px; height: 2px; background: var(--tp-accent);
}

.tp-bladestack .cx-ed-h-hook {
  font-family: var(--tp-display);
  font-size: 88px; line-height: 1.06; font-weight: 600;
  letter-spacing: -0.025em; color: var(--tp-text);
  max-width: 820px;
}
.tp-bladestack .cx-ed-h-problem {
  font-family: var(--tp-display);
  font-size: 60px; line-height: 1.12; font-weight: 500;
  letter-spacing: -0.02em; color: var(--tp-text);
  max-width: 820px;
}
.tp-bladestack .cx-ed-h-insight {
  font-family: var(--tp-display);
  font-size: 56px; line-height: 1.16; font-weight: 500;
  letter-spacing: -0.018em; color: var(--tp-text);
  max-width: 820px;
}
.tp-bladestack .cx-ed-h-cta {
  font-family: var(--tp-display);
  font-size: 64px; line-height: 1.08; font-weight: 600;
  letter-spacing: -0.02em; color: var(--tp-text);
  max-width: 820px;
}

.tp-bladestack .cx-ed-stat-wrap {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; padding: 0 100px; gap: 36px;
}
.tp-bladestack .cx-ed-stat-number {
  font-family: var(--tp-display);
  font-size: 280px; font-weight: 600;
  letter-spacing: -0.045em; line-height: 1;
  color: var(--tp-accent);
}
.tp-bladestack .cx-ed-stat-caption {
  font-family: var(--tp-display);
  font-size: 30px; font-weight: 400;
  color: var(--tp-text); line-height: 1.4; max-width: 720px;
  letter-spacing: -0.005em;
}

.tp-bladestack .cx-ed-cta-link {
  display: inline-flex; align-items: center; gap: 14px;
  padding-bottom: 8px;
  border-bottom: 1.5px solid var(--tp-accent);
  font-family: var(--tp-display);
  font-size: 22px; font-weight: 500;
  color: var(--tp-accent);
  letter-spacing: 0.02em;
}
.tp-bladestack .cx-ed-cta-link .cx-ed-arrow { font-size: 24px; line-height: 1; }

.tp-bladestack .cx-ed-footer {
  position: absolute; bottom: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  font-family: var(--tp-display);
  font-size: 13px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--tp-text-dim);
}
.tp-bladestack .cx-ed-footer .cx-ed-dot { color: var(--tp-text-dim); }

/* ============== SINGLE-CARD — EDITORIAL / LIGHT VARIANT ==============
   Off-white background, centered editorial layout. Namespaced .cx-sc-ed-*
   so it never collides with the Dark (.cx-card-*) selectors. */
.tp-bladestack .cx-card.cx-sc-ed {
  background: #F5F4F0;
  color: #0A0A0A;
}
.tp-bladestack .cx-card.cx-sc-ed::before,
.tp-bladestack .cx-card.cx-sc-ed::after { display: none; }

.tp-bladestack .cx-sc-ed-chrome {
  position: absolute; top: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: space-between;
}
.tp-bladestack .cx-sc-ed-eyebrow {
  font-family: var(--tp-display);
  font-size: 14px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(10,10,10,0.4);
}
.tp-bladestack .cx-sc-ed-logo svg {
  display: block; height: 24px; width: auto;
}

.tp-bladestack .cx-sc-ed-body {
  position: absolute; left: 120px; right: 120px;
  top: 50%; transform: translateY(-50%);
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 48px;
}
.tp-bladestack .cx-sc-ed-rule {
  width: 64px; height: 2px; background: var(--tp-accent);
}
.tp-bladestack .cx-sc-ed-text {
  font-family: var(--tp-display);
  font-size: 88px; line-height: 1.06; font-weight: 600;
  letter-spacing: -0.025em; color: #0A0A0A;
  max-width: 820px;
}

.tp-bladestack .cx-sc-ed-footer {
  position: absolute; bottom: 60px; left: 60px; right: 60px;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  font-family: var(--tp-display);
  font-size: 13px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(10,10,10,0.4);
}
.tp-bladestack .cx-sc-ed-footer::before {
  content: ""; position: absolute; left: 0; right: 0; top: -16px;
  height: 1px; background: rgba(10,10,10,0.12);
}
.tp-bladestack .cx-sc-ed-dot { color: rgba(10,10,10,0.25); }

/* ============== CAROUSEL — EDITORIAL LIGHT OVERRIDE ==============
   .cx-ed-light swaps the editorial dark background to off-white and
   flips all text tokens to dark equivalents. */
.tp-bladestack .cx-slide.cx-ed.cx-ed-light {
  background: #F5F4F0;
  color: #0A0A0A;
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-eyebrow {
  color: rgba(10,10,10,0.4);
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-logo svg {
  filter: none;
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-h-hook,
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-h-problem,
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-h-insight,
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-h-cta {
  color: #0A0A0A;
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-stat-caption {
  color: #0A0A0A;
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-footer {
  color: rgba(10,10,10,0.4);
}
.tp-bladestack .cx-slide.cx-ed.cx-ed-light .cx-ed-dot {
  color: rgba(10,10,10,0.25);
}

/* ============== LINKEDIN PREVIEW ============== */
.tp-bladestack .li-frame {
  background: var(--tp-bg-elev);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 4px;
  padding: 18px;
  cursor: pointer;
  transition: border-color 0.18s ease;
  font-family: var(--tp-body);
}
.tp-bladestack .li-frame:hover { border-color: var(--tp-accent); }
.tp-bladestack .li-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.tp-bladestack .li-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: linear-gradient(135deg, var(--tp-accent-2), var(--tp-accent));
  display: flex; align-items: center; justify-content: center;
  font-family: var(--tp-display); font-size: 12px; font-weight: 700; color: #fff;
}
.tp-bladestack .li-name { font-size: 13px; font-weight: 600; color: var(--tp-text); }
.tp-bladestack .li-meta { font-size: 11px; color: var(--tp-text-muted); }
.tp-bladestack .li-body { font-size: 14px; line-height: 1.55; color: var(--tp-text); white-space: pre-wrap; }

/* ============== X / TWITTER PREVIEW ============== */
.tp-bladestack .x-frame {
  background: var(--tp-bg-elev);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 4px;
  padding: 16px;
  cursor: pointer;
  font-family: var(--tp-body);
  font-size: 14px; line-height: 1.5;
  white-space: pre-wrap;
  transition: border-color 0.18s ease;
  color: var(--tp-text);
}
.tp-bladestack .x-frame:hover { border-color: var(--tp-accent); }
.tp-bladestack .x-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.tp-bladestack .x-handle { color: var(--tp-text-muted); font-size: 12px; }
.tp-bladestack .x-name { font-weight: 600; font-size: 13px; }

/* ============== IG PREVIEW ============== */
.tp-bladestack .ig-frame {
  background: var(--tp-bg-elev);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 4px;
  cursor: pointer;
  font-family: var(--tp-body);
  transition: border-color 0.18s ease;
  overflow: hidden;
}
.tp-bladestack .ig-frame:hover { border-color: var(--tp-accent); }
.tp-bladestack .ig-square {
  aspect-ratio: 1 / 1;
  background-color: var(--tp-bg);
  background-image:
    linear-gradient(to right, var(--tp-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tp-grid-line) 1px, transparent 1px);
  background-size: 30px 30px;
  position: relative;
  display: flex; align-items: center; justify-content: center;
}
.tp-bladestack .ig-square::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 50%, transparent 60%, rgba(0,0,0,0.4) 100%);
  pointer-events: none;
}
.tp-bladestack .ig-square-text {
  font-family: var(--tp-display);
  font-size: 28px; font-weight: 600; color: var(--tp-text);
  text-align: center; padding: 0 32px; line-height: 1.15;
  letter-spacing: -0.01em; position: relative; z-index: 2;
}
.tp-bladestack .ig-meta {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-top: 1px solid var(--tp-grid-line-strong);
}
.tp-bladestack .ig-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: linear-gradient(135deg, var(--tp-accent-2), var(--tp-accent));
  background-size: cover;
  background-position: center;
}
.tp-bladestack .ig-handle { font-size: 13px; color: var(--tp-text); font-weight: 600; }
.tp-bladestack .ig-caption {
  padding: 0 14px 14px;
  font-size: 13px; line-height: 1.5; color: var(--tp-text-muted);
  white-space: pre-wrap;
}

/* ============== COMPOSITE SINGLE-CARD ==============
   Used by every visual source (the brand-template Signature engine
   was retired). Same outer chrome (grid bg, indicator, ticker footer)
   so renders feel consistent; the centre is a media slot that hosts a
   chart canvas, library image, or AI background. Title text sits
   above the slot. */
.tp-bladestack .cx-card-composite .cx-card-composite-body {
  position: absolute;
  left: 60px; right: 60px;
  top: 140px; bottom: 140px;
  display: flex; flex-direction: column;
  gap: 32px;
}
.tp-bladestack .cx-composite-title {
  font-family: var(--tp-display);
  font-size: 44px; line-height: 1.08; font-weight: 600;
  letter-spacing: -0.018em; color: var(--tp-text);
  max-width: 940px;
  flex-shrink: 0;
}
.tp-bladestack .cx-composite-title:empty { display: none; }
.tp-bladestack .cx-media-slot {
  flex: 1;
  position: relative;
  min-height: 0; /* allow flex-shrink for tall canvases */
  display: flex; align-items: stretch; justify-content: stretch;
}
.tp-bladestack .cx-media-slot canvas,
.tp-bladestack .cx-media-slot img {
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
}
.tp-bladestack .cx-media-slot canvas { object-fit: contain; }

/* Source eyebrow row — small label above chart titles ("DATA / BAR"). */
.tp-bladestack .cx-card-composite .cx-card-indicator { color: var(--tp-accent); }

/* AI Full modifier — when source = ai_full, the AI image already includes
   the headline text. Drop the title row, shrink the chrome to a corner
   logo lockup so the AI image fills nearly the whole card. The footer
   ticker also gets dropped to keep it pure AI. */
.tp-bladestack .cx-card-composite--ai-full .cx-card-chrome {
  top: 28px; left: 28px; right: 28px;
  font-size: 11px;
}
.tp-bladestack .cx-card-composite--ai-full .cx-card-indicator { display: none; }
.tp-bladestack .cx-card-composite--ai-full .cx-card-logo svg { height: 18px; }
.tp-bladestack .cx-card-composite--ai-full .cx-card-composite-body {
  top: 0; bottom: 0; left: 0; right: 0;
  gap: 0;
}
.tp-bladestack .cx-card-composite--ai-full .cx-composite-title { display: none; }
.tp-bladestack .cx-card-composite--ai-full .cx-media-slot {
  height: 100%;
}
.tp-bladestack .cx-card-composite--ai-full .cx-media-slot img {
  object-fit: cover;
}
.tp-bladestack .cx-card-composite--ai-full .cx-card-footer {
  display: none;
}

/* ============== COMPOSITE CAROUSEL SLIDES ==============
   Used for AI carousel renders (5 slides via single n=5 gpt-image-2 call)
   and for any future library/chart-based carousels. Each slide mirrors the
   single-card composite layout but lives inside the existing .cx-slide
   sizing chain (--slide-w / --slide-h CSS vars set per-aspect by the
   renderer, just like brand carousel slides). */
.tp-bladestack .cx-slide-composite .cx-slide-composite-body {
  position: absolute;
  left: 60px; right: 60px;
  top: 140px; bottom: 140px;
  display: flex; flex-direction: column;
  gap: 32px;
  z-index: 2;
}
.tp-bladestack .cx-slide-composite .cx-composite-title {
  font-family: var(--tp-display);
  font-size: 44px; line-height: 1.08; font-weight: 600;
  letter-spacing: -0.018em; color: var(--tp-text);
  max-width: 940px;
  flex-shrink: 0;
}
.tp-bladestack .cx-slide-composite .cx-composite-title:empty { display: none; }
.tp-bladestack .cx-slide-composite .cx-media-slot {
  flex: 1;
  position: relative;
  min-height: 0;
  display: flex; align-items: stretch; justify-content: stretch;
}
.tp-bladestack .cx-slide-composite .cx-media-slot img,
.tp-bladestack .cx-slide-composite .cx-media-slot canvas {
  width: 100%; height: 100%;
  display: block;
}
.tp-bladestack .cx-slide-composite .cx-media-slot img { object-fit: cover; }
.tp-bladestack .cx-slide-composite .cx-media-slot canvas { object-fit: contain; }
.tp-bladestack .cx-slide-composite .cx-indicator { color: var(--tp-accent); }

/* Slide-level ai_full modifier — same shrink-the-chrome treatment as the
   single-card composite. Each slide's AI image fills edge-to-edge with a
   small corner logo lockup so the 5 slides feel like a coherent series. */
.tp-bladestack .cx-slide-composite--ai-full .cx-chrome {
  top: 28px; left: 28px; right: 28px;
}
.tp-bladestack .cx-slide-composite--ai-full .cx-indicator { display: none; }
.tp-bladestack .cx-slide-composite--ai-full .cx-logo svg { height: 18px; }
.tp-bladestack .cx-slide-composite--ai-full .cx-slide-composite-body {
  top: 0; bottom: 0; left: 0; right: 0;
  gap: 0;
}
.tp-bladestack .cx-slide-composite--ai-full .cx-composite-title { display: none; }
.tp-bladestack .cx-slide-composite--ai-full .cx-media-slot { height: 100%; }
.tp-bladestack .cx-slide-composite--ai-full .cx-footer { display: none; }
