/* Auto-generated by scripts/extract-broadside-runtime.py gradient-bloom — DO NOT hand-edit.
 * Source: html_gen_prompt.py _GRADIENT_BLOOM_EXTRA_TOKENS + _GRADIENT_BLOOM_STAT_CARD_CSS
 * Loaded by editor.html so editor + viewer render gradient-bloom decks
 * even when the saved markup lost the prompt-injected <style> block.
 * (Rainy 2026-05-29 — AI gen for these 4 templates dropped prompt CSS.)
 */

[data-template="gradient-bloom"] {

  /* ══════════════════════════════════════════════════════════════
     gradient-bloom (Fluid Bright) v2 design system
     1:1 from design-specs/gradient-bloom.html
     ══════════════════════════════════════════════════════════════ */

  /* ── FONT FAMILIES ── */
  --font-serif: "Hepta Slab", "Roboto Slab", "Noto Serif SC", Georgia, serif !important;
  --font-sans: "DM Sans", "Inter", "PingFang SC", system-ui, sans-serif !important;
  --font-mono: "JetBrains Mono", "DM Mono", "IBM Plex Mono", ui-monospace, monospace !important;
  --font-heading: var(--font-serif) !important;
  --font-body: var(--font-serif) !important;

  /* ── COLOR · SURFACE ── */
  --slide-bg: #ffffff !important;

  /* ── COLOR · BLOBS (cover only) ── */
  --blob-mint: rgba(161, 244, 225, 0.30) !important;
  --blob-cyan: rgba(126, 225, 255, 0.50) !important;
  --blob-sky: rgba(162, 245, 255, 0.45) !important;
  --blob-blue: rgba(68, 182, 233, 0.50) !important;
  --blob-deep: rgba(49, 121, 255, 0.28) !important;
  --blob-soft: rgba(138, 191, 252, 0.25) !important;
  --blob-white: rgba(241, 255, 254, 1.00) !important;

  /* ── COLOR · INK (TEXT) ── */
  --ink-cover-h1: #0A1E4A !important;
  --ink-cover-sub: #2A5A8A !important;
  --ink-headline: #262626 !important;
  --ink-body: #262626 !important;
  --ink-meta: rgba(38,38,38,0.70) !important;
  --ink-rule: rgba(38,38,38,0.20) !important;
  --ink-on-pill: #ffffff !important;
  --ink-pill: #262626 !important;

  /* ── COLOR · ACCENTS / CARDS ── */
  --accent-teal: #A1F4E1 !important;
  --accent-azure: #8ABFFC !important;
  --card-blue: rgba(138,191,252,0.15) !important;
  --card-amber: rgba(245,200,130,0.30) !important;
  --card-gray-lt: rgba(38,38,38,0.10) !important;
  --card-gray: rgba(38,38,38,0.55) !important;
  --card-navy: #1E3A5F !important;

  /* ── COLOR · DOTTED FRAME ── */
  --dot-color: rgba(38,38,38,0.55) !important;

  /* ── TYPOGRAPHY · COVER (serif) ── */
  --fs-cover-h1: 128px !important; --fw-cover-h1: 400 !important; --lh-cover-h1: 1.0 !important; --ls-cover-h1: -2px !important;
  --fs-cover-sub: 28px !important; --fw-cover-sub: 400 !important; --lh-cover-sub: 1.4 !important;

  /* ── TYPOGRAPHY · INNER HEADLINES (serif) ── */
  --fs-h1-xl: 104px !important; --fw-h1-xl: 400 !important; --lh-h1-xl: 1.05 !important; --ls-h1-xl: -1.5px !important;
  --fs-h1-lg: 96px !important; --fw-h1-lg: 400 !important; --lh-h1-lg: 1.05 !important; --ls-h1-lg: -1.5px !important;
  --fs-h1-md: 88px !important; --fw-h1-md: 400 !important; --lh-h1-md: 1.10 !important; --ls-h1-md: -1px !important;
  --fs-h1-sm: 72px !important; --fw-h1-sm: 400 !important; --lh-h1-sm: 1.10 !important; --ls-h1-sm: -1px !important;

  /* ── TYPOGRAPHY · BODY / META (serif body, mono eyebrow) ── */
  --fs-subhead: 24px !important; --fw-subhead: 400 !important; --lh-subhead: 1.4 !important;
  --fs-pill: 18px !important; --fw-pill: 500 !important; --lh-pill: 1 !important; --ls-pill: 0.06em !important;
  --fs-body: 26px !important; --fw-body: 400 !important; --lh-body: 1.5 !important;
  --fs-eyebrow: 16px !important; --fw-eyebrow: 500 !important; --lh-eyebrow: 1 !important; --ls-eyebrow: 0.12em !important;

  /* ── SPACING ── */
  --sp-4: 4px !important; --sp-8: 8px !important; --sp-12: 12px !important; --sp-16: 16px !important;
  --sp-20: 20px !important; --sp-24: 24px !important; --sp-32: 32px !important; --sp-40: 40px !important;
  --sp-48: 48px !important; --sp-60: 60px !important; --sp-80: 80px !important;

  /* ── BORDER RADIUS ── */
  --radius-sm: 8px !important; --radius-md: 12px !important; --radius-lg: 16px !important; --radius-pill: 9999px !important;

  /* ── SLIDE FRAME ── */
  --frame-pad-x: 80px !important;
  --frame-rule-y-t: 40px !important;
  --frame-rule-y-b: 1040px !important;
  --frame-meta-y: 60px !important;
  --frame-content-top: 130px !important;
  --frame-content-bottom: 1010px !important;
}



/* ─── 1) SECTION FRAME (1920×1080 white slide) ─── */
section.slide[data-template="gradient-bloom"] {
  position: relative !important;
  width: 1920px !important;
  height: 1080px !important;
  background: var(--slide-bg) !important;
  color: var(--ink-body) !important;
  font-family: var(--font-serif) !important;
  overflow: hidden !important;
  padding: 0 !important;
}

/* ─── 2) COVER — full-bleed with animated blobs ─── */
[data-template="gradient-bloom"] .cover-bg {
  position: absolute !important; inset: 0 !important;
  z-index: 0 !important; overflow: hidden !important;
  background: var(--slide-bg) !important;
}
[data-template="gradient-bloom"] .cover-bg .cover-svg {
  position: absolute !important; inset: 0 !important;
  width: 100% !important; height: 100% !important;
  display: block !important;
}
[data-template="gradient-bloom"] .cover-blob {
  position: absolute !important;
  border-radius: 50% !important;
  mix-blend-mode: multiply !important;
  pointer-events: none !important;
  will-change: transform !important;
}
/* Turned out the real culprit for the "cover too dark" complaint
   was the injected fluid SVG itself (window.__GB_FB_COVER_SVG in
   generate-modal.js) — its own #7EE1FF / #A5E2EC circles and paths
   carry the sky-blue saturation Rainy sees, NOT the .cover-blob
   overlays we'd been trimming. The templet-library preview she
   designed against uses a lighter PNG (samples/gradient-figma/
   assets/bg-cover.png), so this rule pulls the SVG down to ~40%
   opacity to visually match. The .cover-blob softening below still
   contributes a subtle diffuse wash. (Rainy 2026-07-06 iteration 3.) */
[data-template="gradient-bloom"] .cover-bg svg.cover-svg {
  /* Calibrated against samples/gradient-figma/assets/bg-cover.png —
     that PNG's most-saturated point (top-center) is #A0E1F3
     (rgb 160,225,243). Our injected fallback SVG's darkest circle
     is #7EE1FF (rgb 126,225,255) full-opacity. To blend #7EE1FF on
     white down to #A0E1F3 needs alpha ≈ 0.70 — solved from
     R: 126×α + 255×(1-α) = 160 → α = 0.68 ≈ 0.70. This gives the
     PNG's exact perceived depth without going washed-out (0.4) or
     saturated (1.0). (Rainy 2026-07-06 iteration 4.) */
  opacity: 0.7 !important;
}
/* Cover blob alpha lowered progressively from spec (0.55/0.35 and
   0.50/0.30) → to 0.28/0.16 (first pass) → to 0.15/0.08 (current)
   to match the Use-this-style figma sample cover pastel wash. Even
   without the SVG-opacity fix above the cumulative color intensity
   was still saturated at 0.28 because the 2 blobs overlap (933×773
   + 827×693 with 80/73px blur). Kept blob geometry / blur /
   animation identical so only the color intensity shifts. */
[data-template="gradient-bloom"] .cover-blob--b1 {
  width: 933px !important; height: 773px !important;
  background: radial-gradient(ellipse, rgba(68,182,233,0.15) 0%, rgba(49,121,255,0.08) 50%, transparent 80%) !important;
  top: -133px !important; left: 267px !important;
  filter: blur(80px) !important;
  animation: gbCoverB1 8s linear infinite !important;
}
[data-template="gradient-bloom"] .cover-blob--b2 {
  width: 827px !important; height: 693px !important;
  background: radial-gradient(ellipse, rgba(162,245,255,0.14) 0%, rgba(138,191,252,0.07) 55%, transparent 80%) !important;
  top: -107px !important; right: 133px !important;
  filter: blur(73px) !important;
  animation: gbCoverB2 11s linear infinite !important;
}
[data-template="gradient-bloom"] .cover-content {
  position: absolute !important;
  left: 133px !important;
  top: 55% !important;
  transform: translateY(-50%) !important;
  z-index: 10 !important;
  max-width: 1400px !important;
}
[data-template="gradient-bloom"] .cover-content h1 {
  font-family: var(--font-serif) !important;
  font-size: var(--fs-cover-h1) !important;
  font-weight: var(--fw-cover-h1) !important;
  line-height: var(--lh-cover-h1) !important;
  letter-spacing: var(--ls-cover-h1) !important;
  color: var(--ink-cover-h1) !important;
  margin: 0 0 32px !important;
}
[data-template="gradient-bloom"] .cover-content .sub {
  font-family: var(--font-serif) !important;
  font-size: var(--fs-cover-sub) !important;
  font-weight: var(--fw-cover-sub) !important;
  line-height: var(--lh-cover-sub) !important;
  color: var(--ink-cover-sub) !important;
  max-width: 900px !important;
}

/* ─── 2.5) PURE INNER-PAGE BACKGROUND (.bg-pure + 3 blobs) ───
   Every interior slide (E1-E8) and section-divider (E7) MUST wrap
   content with `<div class="bg-pure"><div class="blob blob--tl"/>
   <div class="blob blob--tr"/><div class="blob blob--bl"/></div>`.
   Without these rules the blobs render as invisible 0-size divs and
   the slide ends up as a plain white canvas — which was exactly the
   "AI-gen 生成完全没按 gradient 样式" bug Rainy hit (2026-07-06).
   Source of truth: design-specs/gradient-bloom.html — copied 1:1
   into this runtime CSS so both prompt-injected + editor-loaded
   decks pick up the blobs. */
[data-template="gradient-bloom"] .bg-pure {
  position: absolute !important;
  inset: 0 !important;
  /* Interior slides use the same background image the Use-this-style
     figma sample decks use for their content pages — a single 1920×1080
     PNG that bakes the cyan/mint gradient wash TOGETHER with the
     signature white botanical silhouettes (leaves/petals/vines) at
     precise Figma-designed positions. Without this PNG we tried
     replicating the visual with CSS blobs alone, which gave the
     gradient but no silhouettes → Rainy 2026-07-06 called that out as
     the missing "印花". Using the PNG directly is dramatically simpler
     than reproducing the vector shapes in CSS, and it stays 1:1 with
     the sample decks by construction. `.bg-pure .blob` divs below
     still render on top as extra depth, but the PNG carries the
     dominant look. Sample PNG source: samples/gradient-figma/assets/
     bg-content.png (~800 KB, loaded once, cached). Path is relative to
     THIS CSS file's location. */
  /* Absolute path from web root so iframe/srcdoc/editor/viewer all
     resolve identically; a `../../` relative would 404 inside
     dashboard's srcdoc thumbnails. (Rainy 2026-07-06.)

     Default background = `bg-content.png` — pure cyan wash, ZERO
     white silhouettes (measured: 0.0% pure-white pixels). This is
     the clean, content-focused option that lets dense text/chart
     layouts breathe. Sample deck (samples/gradient-figma/deck.json)
     uses this same default on 5 of its 8 interior slides.

     Silhouette-carrying variants (bg-3 / bg-4 / bg-8, 11–17% pure-
     white coverage) are opt-in per layout below — only the visual-
     accent layouts (E7 chapter dividers, E2 stamp hero) get them, so
     silhouettes act as a paced accent, NOT a blanket background.
     Rainy 2026-07-06: "不是每个 slide 都需要印花". */
  /* PNG 素材四周自带 ~20px 深灰边框（原设计要求 image 越界 20px 让 slide
     overflow:hidden 裁掉，sample deck.json 里 image position 是
     x:-20 y:-20 w:1960 h:1120）。用 background-size:1960×1120 +
     position:-20px -20px mirror sample 的越界裁边行为——PNG 边框超出
     `.bg-pure` painting area 被裁掉，slide 里只见 PNG 内部干净区域。
     (Rainy 2026-07-07: "为什么还有这个黑色边框.") */
  background-image: url("/samples/gradient-figma/assets/bg-content.png"),
                    linear-gradient(var(--slide-bg), var(--slide-bg)) !important;
  background-size: 1960px 1120px, cover !important;
  background-position: -20px -20px, 0 0 !important;
  background-repeat: no-repeat, no-repeat !important;
}
/* Silhouette accent for chapter-divider layouts — E7 is the visual
   break between Parts, printing a botanical silhouette here reads
   as an intentional beat. */
[data-template="gradient-bloom"][data-layout="E7"] .bg-pure {
  background-image: url("/samples/gradient-figma/assets/bg-4.png"),
                    linear-gradient(var(--slide-bg), var(--slide-bg)) !important;
  background-size: 1960px 1120px, cover !important;
  background-position: -20px -20px, 0 0 !important;
  background-repeat: no-repeat, no-repeat !important;
}
/* Silhouette accent for stamp-hero layout — E2 is a visual-heavy
   slide with a large stamp graphic + 2 caption blocks; the botanical
   silhouette layers well behind the stamp without fighting it. */
[data-template="gradient-bloom"][data-layout="E2"] .bg-pure {
  background-image: url("/samples/gradient-figma/assets/bg-3.png"),
                    linear-gradient(var(--slide-bg), var(--slide-bg)) !important;
  background-size: 1960px 1120px, cover !important;
  background-position: -20px -20px, 0 0 !important;
  background-repeat: no-repeat, no-repeat !important;
}
/* Closing slide: visual bookend mirror of the Cover — same fluid
   cyan/mint wash, same absence of the dotted `.slide-frame` chrome,
   same treatment of the interior white blob shapes. Applied here at
   the CSS layer (not just via the prompt example) so any deck
   generated BEFORE the closing-example rewrite still visually matches
   Cover as soon as this CSS reaches the browser — no sidecar restart
   or regeneration required. Handles both possible markup shapes:
     • Old markup (`.bg-pure` inside closing) → PNG override below
     • New markup (`.cover-bg` inside closing) → PNG override below,
       plus the existing .cover-bg rules elsewhere for animated blobs
   Also hides the dotted-rule chrome on closing since the Cover
   doesn't carry it either. (Rainy 2026-07-06: "close 应该和 cover
   一样".) */
[data-template="gradient-bloom"][data-layout="closing"] .bg-pure,
[data-template="gradient-bloom"][data-layout="closing"] .cover-bg {
  background: url("/samples/gradient-figma/assets/bg-cover.png") center/cover no-repeat, var(--slide-bg) !important;
}
[data-template="gradient-bloom"][data-layout="closing"] .slide-frame {
  display: none !important;
}
/* Redundant closer so the stray `}` doesn't break the file — the
   real `.bg-pure` block below starts fresh on its own line. */
[data-template="gradient-bloom"] .bg-pure {
  overflow: hidden !important;
  z-index: 0 !important;
  pointer-events: none !important;
}
[data-template="gradient-bloom"] .bg-pure::before {
  content: "" !important;
  position: absolute !important;
  inset: 0 !important;
  background: linear-gradient(135deg,
    rgba(161, 244, 225, 0.20) 0%,
    transparent 45%,
    rgba(126, 225, 255, 0.10) 100%) !important;
}
[data-template="gradient-bloom"] .bg-pure .blob {
  position: absolute !important;
  border-radius: 50% !important;
  mix-blend-mode: multiply !important;
  pointer-events: none !important;
}
[data-template="gradient-bloom"] .bg-pure .blob--tl {
  width: 1200px !important;
  height: 960px !important;
  top: -260px !important;
  left: 80px !important;
  background: radial-gradient(ellipse,
    rgba(68, 182, 233, 0.28) 0%,
    rgba(49, 121, 255, 0.16) 45%,
    transparent 100%) !important;
  filter: blur(120px) !important;
}
[data-template="gradient-bloom"] .bg-pure .blob--tr {
  width: 1000px !important;
  height: 820px !important;
  top: -180px !important;
  right: 0 !important;
  background: radial-gradient(ellipse,
    rgba(162, 245, 255, 0.30) 0%,
    rgba(138, 191, 252, 0.14) 50%,
    transparent 100%) !important;
  filter: blur(110px) !important;
}
[data-template="gradient-bloom"] .bg-pure .blob--bl {
  width: 900px !important;
  height: 720px !important;
  bottom: -200px !important;
  left: 40px !important;
  background: radial-gradient(ellipse,
    rgba(161, 244, 225, 0.28) 0%,
    rgba(161, 244, 225, 0.10) 50%,
    transparent 100%) !important;
  filter: blur(100px) !important;
}

/* ─── 3) DOTTED FRAME (every interior slide) ─── */
[data-template="gradient-bloom"] .slide-frame {
  position: absolute !important; inset: 0 !important;
  z-index: 5 !important;
  pointer-events: none !important;
}
[data-template="gradient-bloom"] .slide-frame__rule {
  position: absolute !important;
  left: 0 !important; right: 0 !important;
  height: 1px !important;
  background-image: url("data:image/svg+xml !important; utf8,<svg xmlns='http: //www.w3.org/2000/svg' width='14' height='1'><line x1='0' y1='0.5' x2='2' y2='0.5' stroke='%23262626' stroke-opacity='0.55' stroke-width='1'/></svg>") !important;
  background-repeat: repeat-x !important;
  background-size: 14px 1px !important;
}
[data-template="gradient-bloom"] .slide-frame__rule--top    { top: var(--frame-rule-y-t); }
[data-template="gradient-bloom"] .slide-frame__rule--bottom { top: var(--frame-rule-y-b); }
[data-template="gradient-bloom"] .slide-frame__meta {
  position: absolute !important;
  top: var(--frame-meta-y) !important;
  font-family: var(--font-mono) !important;
  font-size: var(--fs-eyebrow) !important;
  font-weight: var(--fw-eyebrow) !important;
  letter-spacing: var(--ls-eyebrow) !important;
  text-transform: uppercase !important;
  color: var(--ink-meta) !important;
}
[data-template="gradient-bloom"] .slide-frame__meta--date  { left: var(--frame-pad-x); }
[data-template="gradient-bloom"] .slide-frame__meta--topic { right: var(--frame-pad-x); text-align: right; }

/* ─── 4) HEADLINE / BODY / EYEBROW UTILITY CLASSES ─── */
[data-template="gradient-bloom"] .headline {
  font-family: var(--font-serif) !important;
  font-weight: 400 !important;
  color: var(--ink-headline) !important;
  letter-spacing: -0.01em !important;
  line-height: 1.05 !important;
  margin: 0 !important;
}
[data-template="gradient-bloom"] .headline--xl { font-size: var(--fs-h1-xl); letter-spacing: var(--ls-h1-xl); }
[data-template="gradient-bloom"] .headline--lg { font-size: var(--fs-h1-lg); letter-spacing: var(--ls-h1-lg); }
[data-template="gradient-bloom"] .headline--md { font-size: var(--fs-h1-md); letter-spacing: var(--ls-h1-md); }
[data-template="gradient-bloom"] .headline--sm { font-size: var(--fs-h1-sm); letter-spacing: var(--ls-h1-sm); }
[data-template="gradient-bloom"] .subhead {
  font-family: var(--font-mono) !important;
  font-size: var(--fs-subhead) !important;
  font-weight: var(--fw-subhead) !important;
  color: var(--ink-meta) !important;
  letter-spacing: 0.04em !important;
  margin: 0 0 16px !important;
}
[data-template="gradient-bloom"] .body-text {
  font-family: var(--font-serif) !important;
  font-size: var(--fs-body) !important;
  font-weight: var(--fw-body) !important;
  line-height: var(--lh-body) !important;
  color: var(--ink-body) !important;
  margin: 0 !important;
}
[data-template="gradient-bloom"] .eyebrow-text {
  font-family: var(--font-mono) !important;
  font-size: var(--fs-eyebrow) !important;
  font-weight: var(--fw-eyebrow) !important;
  letter-spacing: var(--ls-eyebrow) !important;
  text-transform: uppercase !important;
  color: var(--ink-meta) !important;
  margin: 0 0 12px !important;
}

/* ─── 5) COLUMN RULE (E1, E3 vertical dividers) ─── */
[data-template="gradient-bloom"] .col-rule {
  position: absolute !important;
  top: 660px !important;
  width: 1px !important; height: 280px !important;
  background: var(--ink-rule) !important;
}

/* ─── 6) PILL BADGE (E7 section divider) ─── */
[data-template="gradient-bloom"] .pill {
  display: inline-block !important;
  background: var(--ink-pill) !important;
  color: var(--ink-on-pill) !important;
  font-family: var(--font-mono) !important;
  font-size: var(--fs-pill) !important;
  font-weight: var(--fw-pill) !important;
  letter-spacing: var(--ls-pill) !important;
  text-transform: uppercase !important;
  padding: 10px 24px !important;
  border-radius: var(--radius-pill) !important;
}

/* ─── 7) DATA CARD (E6 dashboard card) ─── */
[data-template="gradient-bloom"] .data-card {
  background: #ffffff !important;
  border: 1px solid var(--card-gray-lt) !important;
  border-radius: var(--radius-md) !important;
  padding: 28px 24px !important;
  display: flex !important; flex-direction: column !important;
  /* Center content vertically — model often emits stat cards
     (number + label only, no chart canvas), and top-aligned content
     left cards with huge white space below the stat. Centering keeps
     the visual weight balanced regardless of whether the card has
     1 stat or full chart + footer. (Rainy 2026-06-19: 6 stat cards
     都 only show top sliver, 下方 white space.) */
  justify-content: center !important;
  align-items: flex-start !important;
  box-shadow: 0 8px 32px rgba(38,38,38,0.08) !important;
  overflow: hidden !important;
}
[data-template="gradient-bloom"] .data-card__title {
  font-family: var(--font-serif) !important;
  font-size: 28px !important;
  font-weight: 400 !important;
  letter-spacing: -0.5px !important;
  color: var(--card-navy) !important;
  margin: 0 0 6px !important;
}
[data-template="gradient-bloom"] .data-card__sub {
  font-family: var(--font-mono) !important;
  font-size: 22px !important;
  font-weight: 400 !important;
  letter-spacing: 0.02em !important;
  text-transform: uppercase !important;
  color: var(--card-gray) !important;
  margin: 0 0 18px !important;
}
[data-template="gradient-bloom"] .data-card__chart {
  flex: 1 !important; position: relative !important; min-height: 0 !important;
}

/* ─── 8) AI IMG PLACEHOLDER ─── */
[data-template="gradient-bloom"] .tmpl-img {
  position: absolute !important;
  border-radius: var(--radius-md) !important;
  overflow: hidden !important;
}
[data-template="gradient-bloom"] .tmpl-img > img,
[data-template="gradient-bloom"] .tmpl-img > canvas {
  width: 100% !important; height: 100% !important;
  object-fit: cover !important;
  display: block !important;
}

/* ─── 9) STAMP (E2 hero stamp circle) ─── */
[data-template="gradient-bloom"] .stamp-svg {
  position: absolute !important;
  width: 520px !important; height: 520px !important;
}

/* ─── 10) ANIMATIONS ─── */
@keyframes gbCoverB1 {
  0%   { transform: translate(0,0)         scale(1.00); }
  25%  { transform: translate(-107px,80px)  scale(1.06); }
  50%  { transform: translate(-67px,147px)  scale(1.03); }
  75%  { transform: translate(93px,93px)    scale(0.97); }
  100% { transform: translate(0,0)         scale(1.00); }
}
@keyframes gbCoverB2 {
  0%   { transform: translate(0,0)         scale(1.00); }
  25%  { transform: translate(93px,-67px)   scale(1.07); }
  50%  { transform: translate(113px,87px)   scale(1.05); }
  75%  { transform: translate(-13px,107px)  scale(1.02); }
  100% { transform: translate(0,0)         scale(1.00); }
}

/* ─────────────────────────────────────────────────────────────────
   E8 Chart slide — force spec layout per design-specs/gradient-bloom.html
   Same pattern as midnight-purple E8 fix: model often emits subtitle/
   caption + small inline chart wrap that pushes chart into a corner.
   Spec: heading slab 88px @ top:130 left:80, canvas 1708×780 @ (106,240),
   no caption slot. (Rainy 2026-06-19: gradient chart slide layout off.)
   ───────────────────────────────────────────────────────────────── */
[data-template="gradient-bloom"][data-layout="E8"] .tmpl-img,
[data-template="gradient-bloom"][data-layout="E8"] .tmpl-img.chart-host,
[data-template="gradient-bloom"][data-layout="E8"] .chart-host,
[data-template="gradient-bloom"][data-layout="E8"] .tmpl-chart {
  position: absolute !important;
  left: 106px !important; top: 240px !important;
  width: 1708px !important; height: 780px !important;
  max-width: none !important; max-height: none !important;
  min-width: 1708px !important; min-height: 780px !important;
  margin: 0 !important;
  background: transparent !important;
  border: none !important;
  z-index: 6 !important;
  overflow: hidden !important;
}
[data-template="gradient-bloom"][data-layout="E8"] .tmpl-img canvas,
[data-template="gradient-bloom"][data-layout="E8"] .chart-host canvas,
[data-template="gradient-bloom"][data-layout="E8"] .tmpl-chart canvas {
  width: 100% !important; height: 100% !important;
  display: block !important;
}

/* Heading per spec: slab 88 @ top:130 left:80 max-width:1500 (left-aligned,
   NOT centered — this differs from midnight-purple). Match h1/h2/h3 and
   the spec .headline class so model's bare <h1>/<h2> picks this up.
   Force font-family/size/weight too so heading typography matches across
   slides (model uses different tags → different default sizes/fonts).
   (Rainy 2026-06-19: 两个 chart heading 字体不一致.) */
[data-template="gradient-bloom"][data-layout="E8"] h1,
[data-template="gradient-bloom"][data-layout="E8"] h2,
[data-template="gradient-bloom"][data-layout="E8"] h3,
[data-template="gradient-bloom"][data-layout="E8"] .headline {
  position: absolute !important;
  top: 130px !important;
  left: 80px !important;
  max-width: 1500px !important;
  margin: 0 !important;
  z-index: 7 !important;
  font-family: var(--font-serif) !important;
  font-size: var(--fs-h1-md) !important;
  font-weight: var(--fw-h1-md) !important;
  line-height: var(--lh-h1-md) !important;
  letter-spacing: var(--ls-h1-md) !important;
  color: var(--ink, #1c2433) !important;
}

/* Hide caption / subtitle / description text — E8 spec only has heading
   + chart, model's stray <p>/<span>/extra <div> at top pushes layout. */
[data-template="gradient-bloom"][data-layout="E8"] .obj-html-inner > p,
[data-template="gradient-bloom"][data-layout="E8"] .obj-html-inner > span,
[data-template="gradient-bloom"][data-layout="E8"] .obj-html-inner > div:not(.tmpl-chart):not(.tmpl-img):not(.chart-host):not(.bg-pure):not(.slide-frame):not(.slide-content):not([class*="blob"]),
[data-template="gradient-bloom"][data-layout="E8"] > p,
[data-template="gradient-bloom"][data-layout="E8"] > span {
  display: none !important;
}
