/* ============================================================================
   extra-layouts.css — Phase 1.c layouts not yet in framework feishu-deck.css
   Source: examples/_layout-proposal.html · already 4-tier ladder compliant.
   Linked from deck-json/templates/_shell.html.
   ============================================================================ */

/* ============================================================================
   Framework parity (2026-05-21)
   ----------------------------------------------------------------------------
   The 7 Phase 1.c data-layouts (content-before-after / matrix-2x2 / issue-tree
   / flow-swim / waterfall / arch-stack / logo-wall) were authored with per-
   layout `.stage` / container CSS but inherited NONE of the framework's
   per-layout `.slide .header` positioning, `.slide-frame` background image,
   or default centering. Result: titles dropped into flow (top-left of slide,
   overlapping content), present-mode background went black/unbranded.

   Root cause: feishu-deck.css has unified rules (line ~1300 .header, line
   ~179 present-mode bg) that hardcode the original 8 layout names. New
   layouts were added to extra-layouts.css but no one mirrored the hardcoded
   lists. No example deck used these 7 layouts so the breakage went unnoticed.

   This block restores parity. If you add a NEW data-layout in this file,
   append it to BOTH list groups below.
   ============================================================================ */

/* --- Title position: top:61, left:73, right:420 (clears co-brand lockup) --- */
.slide[data-layout="content-before-after"] .header,
.slide[data-layout="matrix-2x2"] .header,
.slide[data-layout="issue-tree"] .header,
.slide[data-layout="flow-swim"] .header,
.slide[data-layout="waterfall"] .header,
.slide[data-layout="arch-stack"] .header,
.slide[data-layout="logo-wall"] .header {
  position: absolute; top: 61px; left: 73px; right: 441px;
  padding-bottom: 0; border-bottom: 0;
  display: block;
}

/* Background ownership lives in assets/feishu-deck.css, beside
   lark-content-bg.jpg. A url() hidden in a cross-file custom property resolves
   relative to this stylesheet in Chromium and would request the wrong path. */

/* ===== content/matrix — data-layout="matrix-2x2" ===== */
.slide[data-layout="matrix-2x2"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 100px;
  display: grid;
  grid-template-columns: 80px 1fr 1fr;
  grid-template-rows: 1fr 1fr 60px;
  gap: 6px;
}
.slide[data-layout="matrix-2x2"] .y-axis {
  grid-row: 1 / 3; grid-column: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between;
  padding: 24px 0;
}
.slide[data-layout="matrix-2x2"] .y-axis .label {
  font: italic 600 var(--fs-body)/1 var(--fs-font-latin);
  color: rgba(255,255,255,0.68);
  letter-spacing: 0.06em;
}
.slide[data-layout="matrix-2x2"] .y-axis .name {
  writing-mode: vertical-rl;
  font: 600 var(--fs-sub)/1 var(--fs-font-cjk);
  color: #fff;
  letter-spacing: 0.3em;
}
.slide[data-layout="matrix-2x2"] .x-axis {
  grid-row: 3; grid-column: 2 / 4;
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 16px;
  padding: 24px 30px 0;
}
.slide[data-layout="matrix-2x2"] .x-axis .label {
  font: italic 600 var(--fs-body)/1 var(--fs-font-latin);
  color: rgba(255,255,255,0.68);
  letter-spacing: 0.06em;
}
.slide[data-layout="matrix-2x2"] .x-axis .name {
  font: 600 var(--fs-sub)/1 var(--fs-font-cjk);
  color: #fff;
  letter-spacing: 0.3em;
  text-align: center;
}
.slide[data-layout="matrix-2x2"] .quad {
  border-radius: 16px;
  padding: 26px 30px;
  display: flex; flex-direction: column; gap: 14px;
  border: 1.5px solid rgba(255,255,255,0.10);
  background: rgba(8,14,40,0.45);
  min-width: 0; min-height: 0;
}
.slide[data-layout="matrix-2x2"] .quad.q-tl {
  border-color: rgba(51,214,192,0.70);
  background: rgba(51,214,192,0.08);
}
.slide[data-layout="matrix-2x2"] .quad.q-tr {
  border-color: rgba(60,127,255,0.70);
  background: rgba(60,127,255,0.08);
}
.slide[data-layout="matrix-2x2"] .quad.q-bl {
  border-color: rgba(255,255,255,0.20);
  background: rgba(255,255,255,0.03);
}
.slide[data-layout="matrix-2x2"] .quad.q-br {
  border-color: rgba(254,127,0,0.50);
  background: rgba(254,127,0,0.05);
}
.slide[data-layout="matrix-2x2"] .quad h3 {
  display: flex; align-items: baseline; gap: 12px;
  font: 700 var(--fs-sub)/1.2 var(--fs-font-cjk);
  color: #fff;
}
.slide[data-layout="matrix-2x2"] .quad h3 .ord {
  font: italic 700 var(--fs-sub)/1 var(--fs-font-latin);
  color: var(--fs-blue);
}
.slide[data-layout="matrix-2x2"] .quad.q-tl h3 .ord { color: var(--fs-teal); }
.slide[data-layout="matrix-2x2"] .quad.q-br h3 .ord { color: var(--fs-orange); }
.slide[data-layout="matrix-2x2"] .quad.q-bl h3 .ord { color: rgba(255,255,255,0.55); }
.slide[data-layout="matrix-2x2"] .quad ul {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 10px;
}
.slide[data-layout="matrix-2x2"] .quad li {
  display: flex; align-items: baseline; gap: 12px;
  font: 500 var(--fs-body)/1.4 var(--fs-font-cjk);
  color: rgba(255,255,255,0.92);
}
.slide[data-layout="matrix-2x2"] .quad li::before {
  content: '';
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--fs-blue);
  align-self: center;
}
.slide[data-layout="matrix-2x2"] .quad.q-tl li::before { background: var(--fs-teal); }
.slide[data-layout="matrix-2x2"] .quad.q-br li::before { background: var(--fs-orange); }
.slide[data-layout="matrix-2x2"] .quad.q-bl li::before { background: rgba(255,255,255,0.55); }


/* ===== stats/waterfall — data-layout="waterfall" ===== */
.slide[data-layout="waterfall"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 130px;
}
.slide[data-layout="waterfall"] .chart {
  position: relative; width: 100%; height: 100%;
  display: grid;
  /* --cols set inline by enricher (3-8 bars). Default 5 for safety. */
  grid-template-columns: repeat(var(--cols, 5), 1fr);
  gap: 32px;
  align-items: stretch;
  /* 2026-05-21 · was padding-bottom: 80px; removed because label area is
     now reserved INSIDE .bar via padding-bottom: 96px. Chart padding +
     bar padding double-counts and pushes X-axis off col bottoms. */
}
/* X-axis aligned to bar .col bottoms. Pairs with the absolute-positioned
   label/sublabel below (see .bar rules), which guarantees col bottoms
   land on a single Y line regardless of whether each bar has a sublabel
   or not (mixed-sublabel bars was the source of "柱子不在一个平面"). */
.slide[data-layout="waterfall"] .chart::after {
  content: ''; position: absolute;
  left: 0; right: 0; bottom: 96px;
  height: 1px;
  background: linear-gradient(90deg, rgba(60,127,255,0.55), rgba(60,127,255,0.10));
}
.slide[data-layout="waterfall"] .connectors {
  position: absolute; inset: 0; pointer-events: none;
}
.slide[data-layout="waterfall"] .connectors line {
  stroke: rgba(255,255,255,0.32);
  stroke-width: 1.5;
  stroke-dasharray: 6 6;
}
.slide[data-layout="waterfall"] .bar {
  display: flex; flex-direction: column;
  align-items: center; gap: 12px;
  justify-content: end;
  position: relative;
  height: 100%;
  /* Reserve 96px at bottom for absolute-positioned label+sublabel. This
     decouples col bottom (in flex flow) from label area size — col bottoms
     line up across bars even when some have sublabel and others don't. */
  padding-bottom: 96px;
}
.slide[data-layout="waterfall"] .bar .label {
  position: absolute;
  left: 0; right: 0;
  bottom: 42px;
  text-align: center;
  margin-top: 0;
  font: 600 var(--fs-body)/1.3 var(--fs-font-cjk); color: rgba(255,255,255,0.92);
}
.slide[data-layout="waterfall"] .bar .sublabel {
  position: absolute;
  left: 0; right: 0;
  bottom: 14px;
  text-align: center;
  margin-top: 0;
  font: 500 var(--fs-foot)/1.3 var(--fs-font-latin);
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.04em;
}
.slide[data-layout="waterfall"] .bar .value {
  font: 700 var(--fs-title)/1 var(--fs-font-latin); color: #fff;
  letter-spacing: -0.01em;
}
.slide[data-layout="waterfall"] .bar .delta {
  font: 700 var(--fs-body)/1.1 var(--fs-font-latin);   /* 16 → 24 body floor (R-VIS-BODY-FLOOR) 2026-05-26 — the Δ% is the waterfall's key number */
  color: var(--fs-teal);
}
.slide[data-layout="waterfall"] .bar.is-neg .delta { color: var(--fs-orange); }
.slide[data-layout="waterfall"] .bar.is-base .delta,
.slide[data-layout="waterfall"] .bar.is-end .delta { color: rgba(255,255,255,0.50); font-weight: 500; }
.slide[data-layout="waterfall"] .bar .col {
  width: 100%; max-width: 180px;
  border-radius: 8px 8px 0 0;
}
.slide[data-layout="waterfall"] .bar.is-base .col {
  background: linear-gradient(180deg, rgba(255,255,255,0.30), rgba(255,255,255,0.10));
}
.slide[data-layout="waterfall"] .bar.is-pos .col {
  background: linear-gradient(180deg, var(--fs-blue), rgba(60,127,255,0.40));
}
.slide[data-layout="waterfall"] .bar.is-neg .col {
  background: linear-gradient(180deg, var(--fs-orange), rgba(254,127,0,0.40));
}
.slide[data-layout="waterfall"] .bar.is-end .col {
  background: linear-gradient(180deg, var(--fs-teal), rgba(51,214,192,0.40));
}
/* (#205) .bar .label / .sublabel typography MERGED into the single positioning
   rule above — these were duplicate selectors silently overriding it. */
/* 2026-05-21 · footnote position. Sits below stage at slide bottom.
   .stage already excludes top:200/bottom:130 so this lives in the 130px
   bottom strip. */
.slide[data-layout="waterfall"] .footnote {
  position: absolute;
  left: 96px; right: 96px;
  bottom: 60px;
  font: 500 var(--fs-foot)/1.4 var(--fs-font-cjk);
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.02em;
}


/* ===== flow/tree — data-layout="issue-tree" ===== */
.slide[data-layout="issue-tree"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 110px;
  display: grid;
  grid-template-columns: 320px 100px 1fr;
  align-items: center;
  gap: 0;
}
.slide[data-layout="issue-tree"] .root {
  padding: 32px 28px;
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(60,127,255,0.30), rgba(92,63,251,0.22));
  border: 2px solid rgba(60,127,255,0.85);
  box-shadow: 0 0 0 4px rgba(60,127,255,0.15);
}
.slide[data-layout="issue-tree"] .root .q {
  font: 700 var(--fs-sub)/1.3 var(--fs-font-cjk); color: #fff;
  text-wrap: balance;   /* 2026-05-26 · avoid orphan last-line (R-VIS-ORPHAN) */
}
.slide[data-layout="issue-tree"] .root .why {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.18);
  font: 600 var(--fs-body)/1.3 var(--fs-font-cjk);
  color: rgba(255,255,255,0.85);
}
.slide[data-layout="issue-tree"] .root .why em {
  font-style: normal; color: var(--fs-teal); font-weight: 700;
}
.slide[data-layout="issue-tree"] .connector {
  height: 100%; position: relative;
}
.slide[data-layout="issue-tree"] .connector svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
/* Vertical trunk in middle of connector column (spans ~50% of height
   between first and last branch midpoints for 2-branch case). */
.slide[data-layout="issue-tree"] .connector::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 25%; bottom: 25%;
  width: 0;
  border-left: 2px dashed rgba(60,127,255,0.55);
  pointer-events: none;
}
/* Root → trunk horizontal stub at middle of connector column. */
.slide[data-layout="issue-tree"] .connector::after {
  content: '';
  position: absolute;
  left: 0;
  width: 50%;
  top: 50%;
  height: 0;
  border-top: 2px dashed rgba(60,127,255,0.55);
  pointer-events: none;
}
.slide[data-layout="issue-tree"] .branches {
  display: flex; flex-direction: column; gap: 16px;
}
.slide[data-layout="issue-tree"] .branch {
  display: grid;
  grid-template-columns: 340px 80px 1fr;
  align-items: center; gap: 0;
  position: relative;
}
/* Branch stub: from trunk (= center of 100px connector column) to b1 left.
   The trunk is drawn by .connector::before; this is the horizontal "branch
   arm" reaching from trunk to each b1. */
.slide[data-layout="issue-tree"] .branch::before {
  content: '';
  position: absolute;
  left: -50px;  /* start at center of connector column */
  width: 50px;
  top: 50%;
  height: 0;
  border-top: 2px dashed rgba(60,127,255,0.55);
  pointer-events: none;
}
.slide[data-layout="issue-tree"] .branch .b1 {
  padding: 16px 22px;
  border-radius: 12px;
  background: rgba(8,14,40,0.55);
  border: 1.5px solid rgba(60,127,255,0.45);
}
.slide[data-layout="issue-tree"] .branch .b1 .ord {
  display: inline-block;
  font: italic 700 var(--fs-body)/1 var(--fs-font-latin);
  color: var(--fs-blue); margin-right: 10px;
}
.slide[data-layout="issue-tree"] .branch .b1 .t {
  font: 600 var(--fs-body)/1.2 var(--fs-font-cjk); color: #fff;
}
.slide[data-layout="issue-tree"] .branch .leaves {
  display: flex; flex-direction: column; gap: 6px;
}
.slide[data-layout="issue-tree"] .branch .leaf {
  padding: 10px 18px;
  border-radius: 8px;
  background: rgba(255,255,255,0.03);
  border-left: 3px solid var(--fs-teal);
  font: 500 var(--fs-body)/1.3 var(--fs-font-cjk);
  color: rgba(255,255,255,0.88);
}
.slide[data-layout="issue-tree"] .branch .b1-conn {
  height: 100%; position: relative;
}
.slide[data-layout="issue-tree"] .branch .b1-conn svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
/* Trunk in middle of b1-conn (vertical line spanning ~50% of leaves
   column height — between first and last leaf midpoints). */
.slide[data-layout="issue-tree"] .branch .b1-conn::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 25%; bottom: 25%;
  width: 0;
  border-left: 2px dashed rgba(51,214,192,0.55);
  pointer-events: none;
}
/* b1 → trunk horizontal stub. */
.slide[data-layout="issue-tree"] .branch .b1-conn::after {
  content: '';
  position: absolute;
  left: 0;
  width: 50%;
  top: 50%;
  height: 0;
  border-top: 2px dashed rgba(51,214,192,0.55);
  pointer-events: none;
}
/* Each leaf gets a stub from trunk to leaf left edge. */
.slide[data-layout="issue-tree"] .branch .leaf {
  position: relative;
}
.slide[data-layout="issue-tree"] .branch .leaf::before {
  content: '';
  position: absolute;
  left: -40px;  /* start at center of 80px b1-conn column */
  width: 40px;
  top: 50%;
  height: 0;
  border-top: 2px dashed rgba(51,214,192,0.55);
  pointer-events: none;
}


/* ===== replica — full-bleed page image ===== */
.slide.page-replica {
  background-color: #000 !important;
  background-position: center center !important;
  background-size: contain !important;
  background-repeat: no-repeat !important;
}
.slide.page-replica::before,
.slide.page-replica::after {
  content: none !important;
  display: none !important;
}
.slide.page-replica .wordmark { display: none; }


/* ===== content/before-after — 痛点 vs 飞书后 双列对比 ===== */
.slide[data-layout="content-before-after"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 110px;
  display: grid;
  grid-template-columns: 1fr 220px 1fr;
  align-items: stretch;
  gap: 0;
}
.slide[data-layout="content-before-after"] .side {
  padding: 32px 36px;
  border-radius: 18px;
  display: flex; flex-direction: column; gap: 18px;
}
.slide[data-layout="content-before-after"] .side.before {
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.15);
}
.slide[data-layout="content-before-after"] .side.after {
  background: rgba(51,214,192,0.06);
  border: 2px solid rgba(51,214,192,0.70);
}
.slide[data-layout="content-before-after"] .side .tag {
  align-self: flex-start;
  padding: 8px 16px;
  border-radius: 999px;
  font: 700 var(--fs-foot)/1 var(--fs-font-cjk);
  letter-spacing: 0.08em;
}
.slide[data-layout="content-before-after"] .side.before .tag {
  background: rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.72);
}
.slide[data-layout="content-before-after"] .side.after .tag {
  background: rgba(51,214,192,0.18);
  color: var(--fs-teal);
}
.slide[data-layout="content-before-after"] .side ul {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 14px;
}
.slide[data-layout="content-before-after"] .side li {
  display: flex; align-items: baseline; gap: 14px;
  padding: 12px 0;
  border-bottom: 1px dashed rgba(255,255,255,0.08);
  font: 500 var(--fs-body)/1.4 var(--fs-font-cjk);
}
.slide[data-layout="content-before-after"] .side.before li {
  color: rgba(255,255,255,0.72);
}
.slide[data-layout="content-before-after"] .side.after li {
  color: #fff;
}
.slide[data-layout="content-before-after"] .side .icon {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font: 700 var(--fs-body)/1 var(--fs-font-cjk);
}
.slide[data-layout="content-before-after"] .side.before .icon {
  background: rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.55);
}
.slide[data-layout="content-before-after"] .side.after .icon {
  background: rgba(51,214,192,0.25);
  color: var(--fs-teal);
}
.slide[data-layout="content-before-after"] .pivot {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 18px;
}
.slide[data-layout="content-before-after"] .pivot .arrow {
  width: 120px; height: 120px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--fs-blue), var(--fs-teal));
  display: flex; align-items: center; justify-content: center;
  font: 700 var(--fs-title)/1 var(--fs-font-latin);
  color: #fff;
}
.slide[data-layout="content-before-after"] .pivot .caption {
  /* 16 → 24 body floor (R-VIS-BODY-FLOOR) 2026-05-26 — standalone pivot
     pill, the audience reads it; 24 fits the centered pill cleanly. */
  font: 700 var(--fs-body)/1.3 var(--fs-font-cjk);
  color: #fff;
  text-align: center;
  padding: 8px 16px;
  background: rgba(60,127,255,0.18);
  border-radius: 999px;
  border: 1px solid rgba(60,127,255,0.45);
}


/* ===== logo-wall — N industries × M client logos ===== */
.slide[data-layout="logo-wall"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 110px;
  display: flex; flex-direction: column; gap: 28px;
}
.slide[data-layout="logo-wall"] .lede {
  font: 600 var(--fs-body)/1.4 var(--fs-font-cjk);
  color: #fff;
  padding: 16px 28px;
  border-left: 4px solid var(--fs-blue);
  background: rgba(60,127,255,0.06);
  border-radius: 0 8px 8px 0;
}
.slide[data-layout="logo-wall"] .industries {
  display: flex; flex-direction: column; gap: 20px;
  flex: 1; min-height: 0;
}
.slide[data-layout="logo-wall"] .industry {
  display: grid; grid-template-columns: 280px 1fr; align-items: center;
  gap: 28px;
}
.slide[data-layout="logo-wall"] .ind-name {
  /* 2026-05-21 · 16 → 24 (Body tier). Industry name is content
     (categorizing the logos), not chrome. */
  font: 600 var(--fs-body)/1.3 var(--fs-font-cjk);
  color: #fff;
  letter-spacing: 0.05em;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(60,127,255,0.10);
  border: 1px solid rgba(60,127,255,0.30);
  text-align: center;
}
.slide[data-layout="logo-wall"] .logos {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 12px;
}
.slide[data-layout="logo-wall"] .logo {
  height: 64px;
  background-color: rgba(255,255,255,0.95);
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  border-radius: 8px;
  padding: 6px;
}


/* ===== Deck-level title_style · 4 PPT-master variants ===== */
/* CSS engages via .deck[data-title-style="X"] from deck.json deck.title_style,
   or via .slide[data-title-style="X"] for per-slide overrides.
   Default (no attr) = left-double (matches existing framework layout). */

/* center-single: 标题在 stage 中部居中, 1 行高字 */
.deck[data-title-style="center-single"] .slide:not([data-layout="cover"]):not([data-layout="end"]) .header,
.slide[data-title-style="center-single"]:not([data-layout="cover"]):not([data-layout="end"]) .header {
  text-align: center;
}
.deck[data-title-style="center-single"] .slide:not([data-layout="cover"]):not([data-layout="end"]) .header .title-zh,
.slide[data-title-style="center-single"]:not([data-layout="cover"]):not([data-layout="end"]) .header .title-zh {
  text-align: center;
  white-space: nowrap;
  font-size: var(--fs-title);
}

/* center-double: 标题在 stage 上部居中, 允许 2 行 */
.deck[data-title-style="center-double"] .slide:not([data-layout="cover"]):not([data-layout="end"]) .header,
.slide[data-title-style="center-double"]:not([data-layout="cover"]):not([data-layout="end"]) .header {
  text-align: center;
}
.deck[data-title-style="center-double"] .slide:not([data-layout="cover"]):not([data-layout="end"]) .header .title-zh,
.slide[data-title-style="center-double"]:not([data-layout="cover"]):not([data-layout="end"]) .header .title-zh {
  text-align: center;
  font-size: var(--fs-title);
}

/* left-double: 标题在 stage 上部居左, 允许 2 行 — DEFAULT, no special override */
/* left: 标题在 stage 中部居左 — vertically center the header band */
.deck[data-title-style="left"] .slide:not([data-layout="cover"]):not([data-layout="end"]) .header,
.slide[data-title-style="left"]:not([data-layout="cover"]):not([data-layout="end"]) .header {
  position: absolute;
  top: 0; bottom: 0; left: 96px;
  display: flex; align-items: center;
}


/* ===== Deck-level logo_position · feishu × customer 联名顺序 ===== */
/* Implementation: framework's official 豆包工作｜飞书 wordmark is always top-right; this
   attr controls where the customer logo lives relative to it. The actual
   customer logo element placement is done by the deck author (via
   data-customer-logo in raw HTML or via image-text slides). This CSS
   adjusts the wordmark's left/right padding to leave room. */

.deck[data-logo-position="front"] .slide .wordmark,
.slide[data-logo-position="front"] .wordmark {
  /* customer logo goes LEFT of the platform lockup; authoring code owns its box */
  right: 96px;
}
.deck[data-logo-position="back"] .slide .wordmark,
.slide[data-logo-position="back"] .wordmark {
  /* customer logo goes RIGHT of the platform lockup; lockup stays put */
  right: 96px;
}
/* Note: the actual customer-logo element rendering is responsibility of
   each layout enricher / template. This attr just signals INTENT to CSS;
   future enrichers can branch on it. */


/* ===== arch-stack — 4-layer architecture diagram ===== */
.slide[data-layout="arch-stack"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 110px;
  display: flex; flex-direction: column; gap: 14px;
}
.slide[data-layout="arch-stack"] .layer {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 280px 1fr;
  align-items: center; gap: 32px;
  padding: 20px 32px;
  border-radius: 14px;
  border: 1.5px solid rgba(255,255,255,0.10);
}
.slide[data-layout="arch-stack"] .layer.is-l1 {
  background: linear-gradient(90deg, rgba(60,127,255,0.18), rgba(60,127,255,0.04));
  border-color: rgba(60,127,255,0.60);
}
.slide[data-layout="arch-stack"] .layer.is-l2 {
  background: linear-gradient(90deg, rgba(51,214,192,0.16), rgba(51,214,192,0.03));
  border-color: rgba(51,214,192,0.55);
}
.slide[data-layout="arch-stack"] .layer.is-l3 {
  background: linear-gradient(90deg, rgba(92,63,251,0.18), rgba(92,63,251,0.04));
  border-color: rgba(92,63,251,0.55);
}
.slide[data-layout="arch-stack"] .layer.is-l4 {
  background: linear-gradient(90deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
  border-color: rgba(255,255,255,0.25);
}
.slide[data-layout="arch-stack"] .layer.is-l5 {
  background: linear-gradient(90deg, rgba(254,127,0,0.16), rgba(254,127,0,0.03));
  border-color: rgba(254,127,0,0.55);
}
.slide[data-layout="arch-stack"] .layer .name {
  display: flex; flex-direction: column; gap: 6px;
}
.slide[data-layout="arch-stack"] .layer .name .title {
  font: 700 var(--fs-sub)/1.2 var(--fs-font-cjk); color: #fff;
}
.slide[data-layout="arch-stack"] .layer .name .sub {
  /* allow:body-floor — layer subtitle is chrome (Latin label), not body. */
  font: 500 var(--fs-foot)/1.3 var(--fs-font-latin);
  color: rgba(255,255,255,0.55); letter-spacing: 0.06em;
}
.slide[data-layout="arch-stack"] .layer .modules {
  display: flex; flex-wrap: wrap; gap: 10px;
  align-items: center;
}
.slide[data-layout="arch-stack"] .layer .m {
  font: 500 var(--fs-body)/1 var(--fs-font-cjk);
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(0,0,0,0.30);
  border: 1px solid rgba(255,255,255,0.20);
}
.slide[data-layout="arch-stack"] .layer.is-l1 .m { border-color: rgba(60,127,255,0.55); }
.slide[data-layout="arch-stack"] .layer.is-l2 .m { border-color: rgba(51,214,192,0.55); }
.slide[data-layout="arch-stack"] .layer.is-l3 .m { border-color: rgba(92,63,251,0.55); }
.slide[data-layout="arch-stack"] .layer.is-l5 .m { border-color: rgba(254,127,0,0.55); }


/* ===== flow/swim — multi-lane roadmap ===== */
.slide[data-layout="flow-swim"] .stage {
  position: absolute; top: 200px; left: 96px; right: 96px; bottom: 110px;
  display: grid;
  /* grid-template-columns/rows set via inline style in template */
  gap: 4px;
}
.slide[data-layout="flow-swim"] .time-cell {
  display: flex; align-items: center; justify-content: center;
  font: 700 var(--fs-body)/1 var(--fs-font-cjk); color: #fff;
  letter-spacing: 0.06em;
  background: rgba(60,127,255,0.10);
  border-bottom: 2px solid rgba(60,127,255,0.55);
}
.slide[data-layout="flow-swim"] .time-cell.empty {
  background: transparent; border-bottom: none;
}
.slide[data-layout="flow-swim"] .lane-name {
  display: flex; flex-direction: column;
  justify-content: center; align-items: center;  /* both axes centered */
  text-align: center;
  padding: 12px 20px;
  font: 700 var(--fs-body)/1.2 var(--fs-font-cjk); color: #fff;
  border-radius: 10px;
}
/* 2026-05-21 · full-color tinted fill, white text on all tones (teal
   slightly darker gradient end for white-text contrast). */
.slide[data-layout="flow-swim"] .lane-name.is-blue   { background: linear-gradient(135deg, var(--fs-blue),   rgba(60,127,255,0.75)); }
.slide[data-layout="flow-swim"] .lane-name.is-teal   { background: linear-gradient(135deg, #1FA593,           rgba(51,214,192,0.55)); }
.slide[data-layout="flow-swim"] .lane-name.is-violet { background: linear-gradient(135deg, var(--fs-violet), rgba(159,111,241,0.75)); }
.slide[data-layout="flow-swim"] .lane-name.is-orange { background: linear-gradient(135deg, var(--fs-orange), rgba(254,127,0,0.75)); }
.slide[data-layout="flow-swim"] .lane-name .sub {
  /* allow:body-floor — lane Latin tagline is chrome */
  display: block; margin-top: 4px;
  font: 500 var(--fs-foot)/1 var(--fs-font-latin);
  color: rgba(255,255,255,0.55); letter-spacing: 0.06em;
}
.slide[data-layout="flow-swim"] .ms {
  margin: 8px 6px;
  padding: 12px 16px;
  border-radius: 10px;
  background: rgba(8,14,40,0.55);
  border: 1.5px solid;
  display: flex; flex-direction: column; gap: 4px;
  align-self: center;
}
.slide[data-layout="flow-swim"] .ms.is-blue   { border-color: rgba(60,127,255,0.70);  background: rgba(60,127,255,0.10); }
.slide[data-layout="flow-swim"] .ms.is-teal   { border-color: rgba(51,214,192,0.70);  background: rgba(51,214,192,0.10); }
.slide[data-layout="flow-swim"] .ms.is-violet { border-color: rgba(92,63,251,0.70);   background: rgba(92,63,251,0.10); }
.slide[data-layout="flow-swim"] .ms.is-orange { border-color: rgba(254,127,0,0.70);   background: rgba(254,127,0,0.10); }
.slide[data-layout="flow-swim"] .ms .t {
  font: 700 var(--fs-body)/1.2 var(--fs-font-cjk); color: #fff;
}
.slide[data-layout="flow-swim"] .ms .d {
  font: 500 var(--fs-body)/1.3 var(--fs-font-cjk);
  color: rgba(255,255,255,0.78);
}


/* ===== block · testimonial-card · 客户证言卡 ===== */
.testimonial-card {
  margin: 0;
  padding: 24px 28px;
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.12);
  border-radius: 16px;
  display: grid;
  grid-template-columns: 96px 1fr 120px;
  gap: 22px;
  align-items: center;
}
.testimonial-card:not(:has(.portrait)) { grid-template-columns: 1fr 120px; }
.testimonial-card:not(:has(.company-logo)) { grid-template-columns: 96px 1fr; }
.testimonial-card:not(:has(.portrait)):not(:has(.company-logo)) { grid-template-columns: 1fr; }
.testimonial-card .portrait {
  width: 96px; height: 96px;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
  background-color: rgba(60,127,255,0.18);
  border: 2px solid rgba(60,127,255,0.45);
}
.testimonial-card .content { min-width: 0; }
.testimonial-card .quote {
  margin: 0 0 12px 0;
  font: 500 var(--fs-body)/1.5 var(--fs-font-cjk);
  color: rgba(255,255,255,0.92);
  /* Leading curly quote via :before for visual marker. */
  position: relative;
  padding-left: 18px;
}
.testimonial-card .quote::before {
  content: "“";
  position: absolute; left: -2px; top: -4px;
  font: 700 32px/1 var(--fs-font-latin);
  color: var(--fs-blue);
}
.testimonial-card .cite {
  display: flex; flex-direction: column; gap: 2px;
  font-style: normal;
}
.testimonial-card .cite .name {
  font: 700 var(--fs-body)/1.2 var(--fs-font-cjk);
  color: #fff;
}
.testimonial-card .cite .title {
  /* allow:body-floor — short job title, chrome label not body */
  font: 500 var(--fs-foot)/1.3 var(--fs-font-cjk);
  color: rgba(255,255,255,0.55);
}
.testimonial-card .company-logo {
  width: 120px; height: 64px;
  background-color: rgba(255,255,255,0.95);
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  border-radius: 8px;
  padding: 6px;
}


/* ===== block · mockup-card · UI mockup 4 kinds ===== */
.mockup-card {
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.12);
  border-radius: 14px;
  padding: 18px 22px;
  display: flex; flex-direction: column; gap: 12px;
  position: relative;
}
.mockup-card.is-past {
  /* 灰底, "过去"态 */
  background: rgba(255,255,255,0.03);
  border-color: rgba(255,255,255,0.15);
  filter: saturate(0.65);
}
.mockup-card.is-past .title { color: rgba(255,255,255,0.65); }
.mockup-card.is-now {
  /* 蓝调突出当前态 */
  background: linear-gradient(135deg, rgba(60,127,255,0.14), rgba(60,127,255,0.04));
  border-color: rgba(60,127,255,0.55);
}
.mockup-card.is-callout {
  /* 带强调箭头/边框 */
  border-color: var(--fs-teal);
  background: linear-gradient(135deg, rgba(51,214,192,0.16), rgba(51,214,192,0.04));
}
.mockup-card.is-callout::before {
  content: "➤";
  position: absolute;
  top: -14px; left: 18px;
  font: 700 var(--fs-sub)/1 var(--fs-font-latin);
  color: var(--fs-teal);
}
.mockup-card.is-compare {
  /* 左右对比布局 */
  display: grid;
  grid-template-areas: "eyebrow eyebrow" "title title" "body body" "image image" "compare compare";
  gap: 12px;
}
.mockup-card .eyebrow {
  font: 700 var(--fs-foot)/1 var(--fs-font-latin);
  letter-spacing: 0.08em;
  color: var(--fs-blue);
}
.mockup-card.is-past    .eyebrow { color: rgba(255,255,255,0.45); }
.mockup-card.is-now     .eyebrow { color: var(--fs-blue); }
.mockup-card.is-callout .eyebrow { color: var(--fs-teal); }
.mockup-card .title {
  margin: 0;
  font: 700 var(--fs-body)/1.2 var(--fs-font-cjk);
  color: #fff;
}
.mockup-card .body {
  margin: 0;
  font: 500 var(--fs-body)/1.4 var(--fs-font-cjk);
  color: rgba(255,255,255,0.78);
}
.mockup-card .ui-shot {
  height: 180px;
  background-color: rgba(0,0,0,0.40);
  background-position: center;
  background-size: cover;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.08);
}
.mockup-card .compare-pair {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center;
  padding: 10px 14px;
  background: rgba(0,0,0,0.30);
  border-radius: 8px;
  font: 600 var(--fs-body)/1.2 var(--fs-font-cjk);
}
.mockup-card .compare-pair .left  { text-align: right; color: rgba(255,255,255,0.65); }
.mockup-card .compare-pair .right { text-align: left;  color: #fff; }
.mockup-card .compare-pair .vs {
  /* allow:body-floor — 2-char latin chrome label */
  padding: 4px 10px;
  background: rgba(60,127,255,0.20);
  border-radius: 999px;
  font: 700 var(--fs-foot)/1 var(--fs-font-latin);
  color: var(--fs-blue);
  letter-spacing: 0.06em;
}


/* ===== block · persona-card · user persona intro ===== */
.persona-card {
  margin: 0;
  padding: 18px 22px;
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.12);
  border-radius: 14px;
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 16px;
  align-items: start;
}
.persona-card:not(:has(.portrait)) { grid-template-columns: 1fr; }
.persona-card .portrait {
  width: 80px; height: 80px;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
  background-color: rgba(60,127,255,0.18);
  border: 2px solid rgba(60,127,255,0.45);
}
.persona-card .who {
  display: flex; flex-direction: column; gap: 4px;
  font-style: normal;
}
.persona-card .who .name {
  font: 700 var(--fs-body)/1.2 var(--fs-font-cjk);
  color: #fff;
}
.persona-card .who .role {
  /* allow:body-floor — role label */
  font: 500 var(--fs-foot)/1.3 var(--fs-font-cjk);
  color: rgba(255,255,255,0.55);
}
.persona-card .who .generation {
  font: 600 14px/1 var(--fs-font-cjk);
  color: var(--fs-teal);
  padding: 3px 9px;
  background: rgba(51,214,192,0.15);
  border-radius: 999px;
  width: max-content;
  margin-top: 2px;
}
.persona-card .summary {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  font: 500 var(--fs-body)/1.4 var(--fs-font-cjk);
  color: rgba(255,255,255,0.85);
}


/* ===== end with-slogan · custom text slogan ===== */
/* When the deck author provides slogan text, hide the graphical default. */
.slide[data-layout="end"]:has(.slogan:not(.slogan-default)) .slogan-default {
  display: none;
}
.slide[data-layout="end"] .slogan:not(.slogan-default) {
  position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  font: 700 88px/1.15 var(--fs-font-cjk);
  color: #fff;
  text-align: center;
  letter-spacing: 0.04em;
  max-width: 80%;
  text-shadow: 0 4px 24px rgba(0,0,0,0.45);
}


/* ===== section subsection · 二级章节页 ===== */
.slide[data-layout="section"] .parent-label {
  /* allow:body-floor — chrome navigation tag */
  position: absolute;
  top: 200px; left: 96px;
  font: 600 var(--fs-foot)/1 var(--fs-font-cjk);
  color: var(--fs-text-40, rgba(255,255,255,0.40));
  letter-spacing: 0.06em;
  padding: 6px 14px;
  background: rgba(60,127,255,0.10);
  border-radius: 999px;
  border: 1px solid rgba(60,127,255,0.30);
}


/* ===== iframe-embed · 嵌入式 demo / 报告 layout =====
   标准 title + 豆包工作｜飞书联名标在顶部 (top: 61 / left: 73 / right: 441),
   .stage 从 top:180 起,iframe 填满下方至底端 (bottom:40),
   可选右下角 hint pill.
   Use for: 嵌入 prototype / live demo / HTML 报告 / 任何外部 HTML 页面
   2026-05-22 · header 从 top:96/left:96 调整到 master spec top:61/left:73,
   跟其他所有 content-style layouts 一致;同步 stage top 220→180 */
.slide[data-layout="iframe-embed"] .header {
  position: absolute; top: 61px; left: 73px; right: 441px;
  padding-bottom: 0; border-bottom: 0;
  display: block;
}
.slide[data-layout="iframe-embed"] .stage {
  position: absolute;
  top: 160px; left: 60px; right: 60px; bottom: 40px;
  padding: 0; display: block;
}
.slide[data-layout="iframe-embed"] .iframe-wrap {
  position: relative;
  width: 100%; height: 100%;
  border-radius: 18px;
  border: 1px solid rgba(60,127,255,0.30);
  background: #fff;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(60,127,255,0.18);
}
.slide[data-layout="iframe-embed"] .iframe-wrap iframe {
  width: 100%; height: 100%;
  border: 0; display: block;
  background: #fff;
}
.slide[data-layout="iframe-embed"] .iframe-hint {
  position: absolute;
  bottom: 18px; right: 18px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(8,12,24,0.82);
  border: 1px solid rgba(60,127,255,0.40);
  color: #fff;
  font: 600 var(--fs-body)/1.2 var(--fs-font-cjk);
  backdrop-filter: blur(8px);
  pointer-events: none;
  z-index: 2;
}
.slide[data-layout="iframe-embed"] .iframe-hint .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--fs-teal);
  box-shadow: 0 0 0 4px rgba(51,214,192,0.20);
}

/* ============================================================
   chart — data-layout="chart" · deterministic data-viz
   variants: bar / line / donut (2026-05-29)
   self-contained: header + bg parity inlined here, not in the
   shared parity lists, so adding a chart layout touches one block.
   ============================================================ */
.slide[data-layout="chart"] .header {
  position: absolute; top: 61px; left: 73px; right: 441px;
  padding-bottom: 0; border-bottom: 0; display: block;
}
.slide[data-layout="chart"] .stage {
  position: absolute; top: 290px; left: 96px; right: 96px; bottom: 124px;
  display: flex; flex-direction: column; gap: 28px; justify-content: center;
}
.slide[data-layout="chart"] .footnote {
  position: absolute; left: 96px; right: 96px; bottom: 60px;
  font: 500 var(--fs-foot)/1.4 var(--fs-font-cjk); color: rgba(255,255,255,0.55);
  letter-spacing: 0.02em;
}
/* shared legend (line / donut) */
.slide[data-layout="chart"] .chart-legend {
  display: flex; flex-wrap: wrap; gap: 28px; justify-content: center; flex: none;
}
.slide[data-layout="chart"] .cl-chip {
  display: inline-flex; align-items: center; gap: 10px;
  font: 600 var(--fs-body)/1.2 var(--fs-font-cjk); color: rgba(255,255,255,0.92);
}
.slide[data-layout="chart"] .cl-chip i {
  width: 18px; height: 18px; border-radius: 5px; flex: none;
}
/* ---- bar ---- */
.slide[data-layout="chart"] .chart-bar {
  flex: 0 0 auto; height: 520px; min-height: 0; display: grid;
  grid-template-columns: repeat(var(--cn,4), 1fr);
  gap: 48px; align-items: end;
}
.slide[data-layout="chart"] .cbar {
  display: flex; flex-direction: column; align-items: center;
  justify-content: end; gap: 12px; min-width: 0;
}
.slide[data-layout="chart"] .cbar .cval {
  font: 700 28px/1 var(--fs-font-latin); color: #fff; letter-spacing: 0;
}
.slide[data-layout="chart"] .cbar .ccol {
  width: 100%; max-width: 150px; border-radius: 10px 10px 0 0; min-height: 8px;
}
.slide[data-layout="chart"] .cbar .clabel {
  font: 600 var(--fs-body)/1.3 var(--fs-font-cjk); color: rgba(255,255,255,0.92); text-align: center;
}
/* ---- line ---- */
.slide[data-layout="chart"] .chart-line {
  flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 14px;
}
.slide[data-layout="chart"] .cline-svg { flex: 1; min-height: 0; width: 100%; display: block; }
.slide[data-layout="chart"] .cline-x { display: flex; justify-content: space-between; flex: none; }
.slide[data-layout="chart"] .cline-x span {
  font: 600 var(--fs-body)/1.2 var(--fs-font-cjk); color: rgba(255,255,255,0.78);
}
/* ---- donut ---- */
.slide[data-layout="chart"] .chart-donut {
  flex: 1; min-height: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
}
.slide[data-layout="chart"] .cdonut-svg { width: 340px; height: 340px; }
.slide[data-layout="chart"] .cdonut-center {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  font: 700 56px/1 var(--fs-font-latin); color: #fff; letter-spacing: -0.02em;
}

/* ============================================================================
   规范 L3 分布修复 sweep(2026-05-30)— extras 版式。配套 feishu-deck.css 末尾
   同名 sweep 块。每条 scoped 到各自渲染结构,经 assets/check-distribution.py 注入
   测 + 真渲染零回归验证。
   ============================================================================ */

/* content/matrix(matrix-2x2):quad 必须继续填满固定 1fr 格子(位置=象限语义),
   不能 un-stretch;只把框内 flex 列垂直居中,消除"贴顶 + 下方空 220px"不均。 */
.slide[data-layout="matrix-2x2"] .quad {
  justify-content: center;
}

/* content/before-after:两栏 un-stretch 共享中线,消除稀疏那栏顶锚 + 大片空带。 */
.slide[data-layout="content-before-after"] .stage {
  align-items: center;
}

/* logo-wall:整墙垂直居中,行块不被拉伸(消除内容偏上、下方大留白)。 */
.slide[data-layout="logo-wall"] .stage {
  justify-content: center;
}
.slide[data-layout="logo-wall"] .industries {
  flex: 0 0 auto;
}
