@cyber-dash-tech/revela 0.19.4 → 0.19.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -240,7 +240,7 @@ new SlidePresentation();
240
240
  - **Images for photographic references.** Use image treatment rules rather than fake SVG when the reference is photographic, UI, webpage, or product imagery.
241
241
  - **Content pages need a stable title block.** Except cover, TOC, closing, section divider, and full-bleed hero slides, every normal content slide should include a visible title block from the upper-left safe area. It should contain a compact chapter/section label plus a slide title written as the page's claim or takeaway.
242
242
  - **Do not hide the page title inside a card.** Body components may have their own headings, but the slide-level title block should remain separate and easy to scan unless the chosen layout explicitly defines a compact side-title variant.
243
- - **Text panels are not decorative rule panels.** Do not add a default left border, vertical accent bar, yellow/gold line, or inline rule to `text-panel`. Use typography, spacing, boxes, stats, quotes, or layout-level dividers for emphasis.
243
+ - **Text panels are not decorative rule panels.** Do not add a default left border, vertical accent bar, yellow/gold line, or inline rule to `text-panel`. Use typography, spacing, boxes, stats, italic quote text inside `text-panel`, or layout-level dividers for emphasis.
244
244
  - **Preview must be real.** A design preview should show actual layout/component behavior, not empty placeholder boxes only.
245
245
 
246
246
  ### Common Mistakes
@@ -447,18 +447,18 @@ Structural intent:
447
447
 
448
448
  ### Components
449
449
 
450
- Components are reusable primitives. Use this hierarchy: `layout -> box/card -> text-panel + media/chart/table/stat/quote`.
450
+ Components are reusable primitives. Use this hierarchy: `layout -> box/card -> text-panel + media/chart/table/stat`.
451
451
 
452
452
  LLM-facing vocabulary:
453
453
  - `box` — card/group primitive for one idea, case, evidence item, metric, objection, risk, or action.
454
- - `text-panel` — language module for title, body text, bullets, and source notes.
454
+ - `text-panel` — language module for title, body text, bullets, italic quote text, formula text, and source notes.
455
455
  - `media` — normal image/screenshot/diagram/logo/portrait component; use `hero` instead for full-bleed covers.
456
456
  - `echart-panel` — chart frame with caption/source structure.
457
457
  - `data-table` — structured table component for tabular data and source notes.
458
458
  - `steps` — process or phase sequence; compatibility implementation may use `.flow-*` classes.
459
459
  - `roadmap-horizontal` and `roadmap-vertical` — dated phases, milestones, historical evolution, or future plans; compatibility implementation may use `.timeline-journey-*` classes.
460
460
  - `hero` — full-bleed cover, section divider, closing, or strong visual statement with overlaid title/subtitle.
461
- - `stat-card`, `quote`, and `toc` — pattern components for their specific use cases.
461
+ - `stat-card` and `toc` — pattern components for their specific use cases.
462
462
  - `page-number` and `brand-watermark` — utility components.
463
463
 
464
464
  Do not expose `image-title`, `media--cover`, `editorial-*`, `flow-*`, `timeline-journey-*`, or `svg-motif` as new component choices. Old classes may remain in CSS as compatibility implementation details.
@@ -470,7 +470,7 @@ Density guidance: normal content slides usually need 2-4 boxes. Evidence slides
470
470
  <!-- @component:box:start -->
471
471
  #### Box (.box)
472
472
 
473
- Card/group primitive for one idea, case, evidence item, metric, objection, risk, or action. Put `text-panel`, `media`, `echart-panel`, `data-table`, `stat-card`, or `quote` inside a box when they support the same idea.
473
+ Card/group primitive for one idea, case, evidence item, metric, objection, risk, or action. Put `text-panel`, `media`, `echart-panel`, `data-table`, or `stat-card` inside a box when they support the same idea.
474
474
 
475
475
  ```html
476
476
  <div class="box">
@@ -494,15 +494,20 @@ Card/group primitive for one idea, case, evidence item, metric, objection, risk,
494
494
  <!-- @component:text-panel:start -->
495
495
  #### Text Panel (.text-panel)
496
496
 
497
- Language module for headings, body copy, lists, and footer/source metadata. It can sit inside `box` or directly in a layout slot.
497
+ Language module for headings, body copy, lists, italic quote text, formula text, and footer/source metadata. It can sit inside `box` or directly in a layout slot.
498
498
 
499
- `text-panel` is a neutral language container. Do not add a default left border, vertical accent bar, yellow/gold rule, or decorative stripe to it. If a slide needs emphasis, use a `box`, `stat-card`, `quote`, `toc`, or a layout-level divider instead.
499
+ `text-panel` is a neutral language container. Do not add a default left border, vertical accent bar, yellow/gold rule, or decorative stripe to it. If a slide needs emphasis, use a `box`, `stat-card`, `toc`, or a layout-level divider instead. Quotes and formulas are text members inside `.text-panel-body`, not standalone components.
500
500
 
501
501
  ```html
502
502
  <div class="text-panel text-panel--light">
503
503
  <div class="text-panel-body">
504
504
  <p class="eyebrow">Context</p>
505
505
  <h2>Panel heading</h2>
506
+ <blockquote class="text-panel-quote">Italic quote text belongs inside the text panel body.</blockquote>
507
+ <figure class="text-panel-formula" data-latex="\mathrm{ROI}=\frac{\mathrm{Gain}-\mathrm{Cost}}{\mathrm{Cost}}">
508
+ <span class="katex">Rendered formula</span>
509
+ <p class="text-panel-formula-caption">Formula text member</p>
510
+ </figure>
506
511
  <ul class="editorial-list"><li><strong>Signal.</strong> Supporting copy.</li></ul>
507
512
  </div>
508
513
  <div class="text-panel-footer"><span class="source">Source: dataset</span><span class="caption">01</span></div>
@@ -515,6 +520,10 @@ Language module for headings, body copy, lists, and footer/source metadata. It c
515
520
  .text-panel--light { background: var(--bg-page-alt); color: var(--text-primary); }
516
521
  .text-panel--dark { background: #1f242b; color: #f8fafc; --text-primary: #f8fafc; --text-secondary: #cbd5e1; --text-muted: #94a3b8; --line: rgba(248,250,252,0.16); }
517
522
  .text-panel-body { display: flex; flex-direction: column; gap: 14px; }
523
+ .text-panel-quote { margin: 0; font-style: italic; line-height: 1.46; color: var(--text-secondary); }
524
+ .text-panel-formula { margin: 0; display: grid; gap: 8px; color: var(--text-primary); }
525
+ .text-panel-formula-fallback { display: block; white-space: normal; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82em; line-height: 1.35; color: inherit; }
526
+ .text-panel-formula-caption { margin: 0; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
518
527
  .text-panel-footer { display: flex; justify-content: space-between; align-items: flex-end; gap: 18px; }
519
528
  ```
520
529
  <!-- @component:text-panel:end -->
@@ -711,23 +720,6 @@ Table of contents or section index.
711
720
  ```
712
721
  <!-- @component:toc:end -->
713
722
 
714
- <!-- @component:quote:start -->
715
- #### Quote (.quote-block)
716
-
717
- Large quotation or summary statement.
718
-
719
- ```html
720
- <div class="quote-block"><p class="quote-mark">“</p><blockquote>Statement text goes here.</blockquote><p class="quote-source">Source</p></div>
721
- ```
722
-
723
- ```css
724
- .quote-block { height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 24px; max-width: 980px; }
725
- .quote-mark { font-size: 96px; line-height: 0.7; color: var(--accent-primary); }
726
- .quote-block blockquote { font-family: var(--font-display); font-size: 54px; line-height: 1.06; letter-spacing: -0.04em; color: var(--text-primary); }
727
- .quote-source { font-size: 13px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted); }
728
- ```
729
- <!-- @component:quote:end -->
730
-
731
723
  <!-- @component:brand-watermark:start -->
732
724
  #### Brand Watermark (.brand-watermark)
733
725
 
@@ -910,6 +902,7 @@ Starter skins Revela built-in page templates as a neutral authoring system. The
910
902
 
911
903
  - `cover`, `section-divider`, `closing`: use clear title-first structural pages.
912
904
  - `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use plain narrative and card-grid surfaces.
905
+ - Agenda typography follows design tokens: title and numbers use `--font-display`; item labels and footer use `--font-body`.
913
906
  - `metric-highlight`, `chart-takeaways`, `table`, `table-comparison`: use direct data panels with minimal decoration.
914
907
  - Text panels use explicit variants: `template-text-panel--clear` is transparent with no border or background, `template-text-panel--plain` is theme-neutral, and `template-text-panel--color` is the multicolor emphasis treatment used by chart and timeline reading panels.
915
908
  - `milestone`: dots remain milestone anchors inside each horizontal milestone item; do not position detached decorative markers.
@@ -99,24 +99,24 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
99
99
  linear-gradient(135deg, #07111f, #101a2b 62%, #243a73);
100
100
  }
101
101
 
102
- .template-slide[data-design="lucent"][data-template="cover"] .slide-canvas {
102
+ .template-slide[data-design="starter"][data-template="cover"] .slide-canvas {
103
103
  background:
104
104
  linear-gradient(90deg, rgba(7,17,31,0.82), rgba(7,17,31,0.42) 52%, rgba(7,17,31,0.24)),
105
105
  url("./assets/cover-background.jpg") center center / cover no-repeat;
106
106
  }
107
- .template-slide[data-design="lucent"][data-template="agenda"] .slide-canvas {
107
+ .template-slide[data-design="starter"][data-template="agenda"] .slide-canvas {
108
108
  background:
109
109
  linear-gradient(90deg, rgba(7,17,31,0.86), rgba(7,17,31,0.58) 52%, rgba(7,17,31,0.32)),
110
110
  url("./assets/cover-background.jpg") center center / cover no-repeat;
111
111
  }
112
- .template-slide[data-design="lucent"][data-template="section-divider"] .slide-canvas {
112
+ .template-slide[data-design="starter"][data-template="section-divider"] .slide-canvas {
113
113
  background:
114
114
  linear-gradient(90deg, rgba(7,17,31,0.86), rgba(16,26,43,0.62) 58%, rgba(36,58,115,0.36)),
115
115
  url("./assets/cover-background.jpg") center center / cover no-repeat;
116
116
  }
117
117
  .template-slide[data-template="closing"] .slide-canvas { background: linear-gradient(135deg, #07111f, #315eea 58%, #18a8d8); }
118
118
 
119
- .template-slide[data-design="lucent"][data-template="closing"] .slide-canvas {
119
+ .template-slide[data-design="starter"][data-template="closing"] .slide-canvas {
120
120
  background:
121
121
  linear-gradient(90deg, rgba(7,17,31,0.82), rgba(49,94,234,0.42) 58%, rgba(24,168,216,0.24)),
122
122
  url("./assets/closing-background.jpg") center center / cover no-repeat;
@@ -125,12 +125,12 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
125
125
  .template-agenda-inner { width: 100%; display: grid; grid-template-columns: 37% minmax(0, 1fr); align-items: stretch; gap: 76px; }
126
126
  .template-agenda-header { display: flex; flex-direction: column; min-height: 0; padding: 10px 0 0; }
127
127
  .template-agenda-header .template-eyebrow { color: rgba(255,255,255,0.64); }
128
- .template-agenda-header .template-title { max-width: 440px; font-size: 54px; line-height: 1.16; letter-spacing: 0; text-transform: uppercase; color: white; padding-bottom: 8px; overflow: visible; }
129
- .template-agenda-footer { margin: auto 0 0; font-size: 13px; line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 800; color: rgba(255,255,255,0.84); }
128
+ .template-agenda-header .template-title { max-width: 440px; font-family: var(--font-display); font-size: 54px; line-height: 1.16; letter-spacing: 0; text-transform: uppercase; color: white; padding-bottom: 8px; overflow: visible; }
129
+ .template-agenda-footer { margin: auto 0 0; font-family: var(--font-body); font-size: 13px; line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 800; color: rgba(255,255,255,0.84); }
130
130
  .template-agenda-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 40px; height: 100%; }
131
131
  .template-agenda-item { display: grid; grid-template-columns: 86px minmax(0, 1fr); gap: 44px; align-items: center; min-height: 58px; overflow: visible; }
132
132
  .template-agenda-item span { font-family: var(--font-display); font-size: 44px; line-height: 1; letter-spacing: 0.03em; color: var(--accent-cyan, #18a8d8); font-weight: 800; font-variant-numeric: tabular-nums; }
133
- .template-agenda-item strong { font-size: 18px; line-height: 1.45; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: rgba(255,255,255,0.92); }
133
+ .template-agenda-item strong { font-family: var(--font-body); font-size: 18px; line-height: 1.45; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: rgba(255,255,255,0.92); }
134
134
  .template-metric-layout { height: 100%; min-height: 0; display: grid; gap: 26px; }
135
135
  .template-metric-layout--insight-top { grid-template-rows: auto minmax(0, 1fr); }
136
136
  .template-metric-layout--insight-bottom { grid-template-rows: minmax(0, 1fr) auto; }
@@ -146,6 +146,21 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
146
146
  .template-text-panel--color { background: linear-gradient(135deg, #5f82c8 0%, var(--accent-primary) 58%, #18a8d8 115%); color: white; box-shadow: 0 22px 56px rgba(49,94,234,0.24); }
147
147
  .template-text-panel--color .template-text-panel-title { color: white; }
148
148
  .template-text-panel--color .template-text-panel-body { color: rgba(255,255,255,0.78); }
149
+ .template-text-panel-quote { margin: 2px 0 0; font-size: 22px; line-height: 1.44; font-style: italic; color: var(--text-secondary); }
150
+ .template-text-panel--color .template-text-panel-quote { color: rgba(255,255,255,0.82); }
151
+ .template-text-panel-formula { margin: 0; width: 100%; display: grid; gap: 8px; color: var(--text-primary); }
152
+ .template-text-panel--color .template-text-panel-formula { color: white; }
153
+ .template-text-panel-formula .katex-display { margin: 0; overflow: visible; }
154
+ .template-text-panel-formula .katex { font-size: 1.08em; color: inherit; }
155
+ .template-text-panel-formula-fallback { display: block; white-space: normal; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82em; line-height: 1.35; color: inherit; }
156
+ .template-text-panel-formula-caption { margin: 0; font-size: 14px; line-height: 1.35; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
157
+ .template-text-panel--color .template-text-panel-formula-caption { color: rgba(255,255,255,0.72); }
158
+ .text-panel-quote { margin: 0; font-style: italic; line-height: 1.46; color: var(--text-secondary); }
159
+ .text-panel-formula { margin: 0; display: grid; gap: 8px; color: var(--text-primary); }
160
+ .text-panel-formula .katex-display { margin: 0; overflow: visible; }
161
+ .text-panel-formula .katex { color: inherit; }
162
+ .text-panel-formula-fallback { display: block; white-space: normal; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82em; line-height: 1.35; color: inherit; }
163
+ .text-panel-formula-caption { margin: 0; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
149
164
  .template-chart-takeaway-list { display: grid; gap: 22px; width: 100%; }
150
165
  .template-chart-takeaway-item { display: grid; gap: 7px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,0.24); }
151
166
  .template-chart-takeaway-item:first-child { padding-top: 0; border-top: 0; }
@@ -66,7 +66,7 @@ Accent usage guidance:
66
66
  - `--accent-earth` — warm secondary accent, image captions, secondary labels
67
67
  - `--accent-olive` — muted structural accent, chart fills, subtle dividers
68
68
  - `--accent-stone` — lightest accent, disabled states, faint decorative lines
69
- - `--accent-sage` — desaturated cool green; use for environmental, sustainability, or positive-signal content (e.g. quote decorations, positive indicators, nature-themed slides)
69
+ - `--accent-sage` — desaturated cool green; use for environmental, sustainability, or positive-signal content (e.g. positive indicators, nature-themed slides)
70
70
  - `--accent-danger` — negative indicators, alerts, down-trend markers only
71
71
 
72
72
  ### Typography
@@ -470,7 +470,7 @@ These rules are mandatory for Summit.
470
470
  - **Visual hierarchy is strict:** eyebrow -> heading -> body -> caption.
471
471
  - **Content pages need a stable title block.** Except cover, TOC, closing, section divider, and full-bleed hero slides, every normal content slide should include a visible title block from the upper-left safe area. It should contain a compact chapter/section label plus a slide title written as the page's claim or takeaway.
472
472
  - **Do not hide the page title inside a card.** Body components may have their own headings, but the slide-level title block should remain separate and easy to scan unless the chosen layout explicitly defines a compact side-title variant.
473
- - **Text panels are not decorative rule panels.** Do not add a default left border, vertical accent bar, yellow/gold line, or inline rule to `text-panel`. Use typography, spacing, boxes, stats, quotes, or layout-level dividers for emphasis.
473
+ - **Text panels are not decorative rule panels.** Do not add a default left border, vertical accent bar, yellow/gold line, or inline rule to `text-panel`. Use typography, spacing, boxes, stats, italic quote text inside `text-panel`, or layout-level dividers for emphasis.
474
474
  - **Titles are Title Case.** Do not set `text-transform:uppercase` on `h1`, `h2`, `h3`, or `h4` titles. Uppercase is reserved for eyebrows, captions, metadata labels, short codes, and date/code-like markers.
475
475
  - **Components are transparent by default.** Component primitives should not bring their own paper/background fill. Let `.page`, layout containers, or explicit modifier variants provide background color when needed.
476
476
  - **Icon system is Lucide.** For ordinary UI, semantic, status, category, process, and navigation icons, use Lucide (`data-lucide`). Do not hand-write inline SVG for icons. SVG is allowed only for intentional decorative motifs, illustrations, or design-specific artwork. If any `data-lucide` icon is present, load Lucide via CDN and call `lucide.createIcons()` after `SlidePresentation`.
@@ -859,7 +859,7 @@ Structural intent:
859
859
 
860
860
  Use these components when a page needs repeatable editorial modules inside a larger layout. Components define the block itself, not the page grid around it.
861
861
 
862
- Use this hierarchy: `layout -> box/card -> text-panel + media/chart/table/stat/quote`.
862
+ Use this hierarchy: `layout -> box/card -> text-panel + media/chart/table/stat`.
863
863
 
864
864
  Component defaults are transparent. Use explicit variants such as `box--paper`, `box--dark`, `text-panel--light`, or `text-panel--dark` only when a component intentionally needs its own reading field. Do not add default fills to component primitives.
865
865
 
@@ -867,14 +867,14 @@ Source and citation text should use `.source` or `.source-note`, not `.caption`.
867
867
 
868
868
  LLM-facing vocabulary:
869
869
  - `box` — card/group primitive for one idea, case, evidence item, metric, objection, risk, or action.
870
- - `text-panel` — language module for title, body text, bullets, and source notes.
870
+ - `text-panel` — language module for title, body text, bullets, italic quote text, formula text, and source notes.
871
871
  - `media` — normal image/screenshot/diagram/logo/portrait component; use `hero` for full-bleed covers.
872
872
  - `echart-panel` — chart frame with caption/source structure.
873
873
  - `data-table` — structured table component for tabular data and source notes.
874
874
  - `steps` — process or phase sequence; compatibility implementation may use `.flow-*` classes.
875
875
  - `roadmap-horizontal` and `roadmap-vertical` — dated phases, milestones, historical evolution, or future plans; compatibility implementation may use `.tjh` and `.tjv` classes.
876
876
  - `hero` — full-bleed cover, section divider, closing, or strong visual statement with overlaid title/subtitle.
877
- - `stat-card`, `quote`, and `toc` — pattern components for their specific use cases.
877
+ - `stat-card` and `toc` — pattern components for their specific use cases.
878
878
  - `page-number` and `brand-watermark` — utility components.
879
879
 
880
880
  Do not expose `image-title`, `media--cover`, `editorial-*`, `flow-*`, `timeline-journey-*`, or decorative SVG as new component choices. Old classes may remain in CSS as compatibility implementation details.
@@ -884,7 +884,7 @@ Density guidance: normal content slides usually need 2-4 boxes. Evidence slides
884
884
  <!-- @component:box:start -->
885
885
  #### Box
886
886
 
887
- Card/group primitive for one idea, case, evidence item, metric, objection, risk, or action. Put `text-panel`, `media`, `echart-panel`, `data-table`, `stat-card`, or `quote` inside a box when they support the same idea.
887
+ Card/group primitive for one idea, case, evidence item, metric, objection, risk, or action. Put `text-panel`, `media`, `echart-panel`, `data-table`, or `stat-card` inside a box when they support the same idea.
888
888
 
889
889
  ```html
890
890
  <div class="box">
@@ -913,9 +913,9 @@ Card/group primitive for one idea, case, evidence item, metric, objection, risk,
913
913
 
914
914
  <!-- renamed from report-text-panel -->
915
915
 
916
- Unified narrative text container. Use inside any layout slot that needs a self-contained reading surface with heading, body copy, and optional footer metadata. The body zone accepts prose, a bullet list, or both — choose based on content, not convention.
916
+ Unified narrative text container. Use inside any layout slot that needs a self-contained reading surface with heading, body copy, italic quote text, formula text, and optional footer metadata. The body zone accepts prose, a bullet list, quote, formula, or a mix — choose based on content, not convention.
917
917
 
918
- `text-panel` is a neutral language container. Do not add a default left border, vertical accent bar, yellow/gold rule, or decorative stripe to it. Summit may use thin rules at the layout level or in `toc`, but not as a default `text-panel` treatment.
918
+ `text-panel` is a neutral language container. Do not add a default left border, vertical accent bar, yellow/gold rule, or decorative stripe to it. Summit may use thin rules at the layout level or in `toc`, but not as a default `text-panel` treatment. Quotes and formulas are text members inside `.text-panel-body`, not standalone components.
919
919
 
920
920
  ```html
921
921
  <!-- variant A: prose only (--dark) -->
@@ -925,6 +925,11 @@ Unified narrative text container. Use inside any layout slot that needs a self-c
925
925
  <h2 style="margin-top:16px;font-size:56px;line-height:1;letter-spacing:-0.03em;color:#f7f4ee;max-width:390px;">Narrative Heading</h2>
926
926
  <div class="text-panel-body" style="margin-top:20px;">
927
927
  <p style="color:rgba(243,238,230,0.84);max-width:390px;">Use one or two compact paragraphs when continuous prose fits the content better than a list.</p>
928
+ <blockquote class="text-panel-quote">Italic quote text belongs inside the text panel body.</blockquote>
929
+ <figure class="text-panel-formula" data-latex="\mathrm{ROI}=\frac{\mathrm{Gain}-\mathrm{Cost}}{\mathrm{Cost}}">
930
+ <span class="katex">Rendered formula</span>
931
+ <p class="text-panel-formula-caption">Formula text member</p>
932
+ </figure>
928
933
  </div>
929
934
  </div>
930
935
  <div class="text-panel-footer" style="color:rgba(243,238,230,0.68);">
@@ -1004,6 +1009,38 @@ Unified narrative text container. Use inside any layout slot that needs a self-c
1004
1009
  gap: 12px;
1005
1010
  }
1006
1011
 
1012
+ .text-panel-quote {
1013
+ margin: 0;
1014
+ font-style: italic;
1015
+ line-height: 1.46;
1016
+ color: var(--text-secondary);
1017
+ }
1018
+
1019
+ .text-panel-formula {
1020
+ margin: 0;
1021
+ display: grid;
1022
+ gap: 8px;
1023
+ color: var(--text-primary);
1024
+ }
1025
+
1026
+ .text-panel-formula-fallback {
1027
+ display: block;
1028
+ white-space: normal;
1029
+ overflow-wrap: anywhere;
1030
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
1031
+ font-size: 0.82em;
1032
+ line-height: 1.35;
1033
+ color: inherit;
1034
+ }
1035
+
1036
+ .text-panel-formula-caption {
1037
+ margin: 0;
1038
+ font-size: 12px;
1039
+ letter-spacing: 0.08em;
1040
+ text-transform: uppercase;
1041
+ color: var(--text-muted);
1042
+ }
1043
+
1007
1044
  /* renamed from .report-panel-footer */
1008
1045
  .text-panel-footer {
1009
1046
  display: flex;
@@ -1014,7 +1051,7 @@ Unified narrative text container. Use inside any layout slot that needs a self-c
1014
1051
  ```
1015
1052
 
1016
1053
  Rules:
1017
- - `.text-panel-body` is the only required structural child. Place `<p>` elements, an `<ul class="editorial-list">`, or both inside it.
1054
+ - `.text-panel-body` is the only required structural child. Place `<p>` elements, an `<ul class="editorial-list">`, `<blockquote class="text-panel-quote">`, `<figure class="text-panel-formula">`, or a deliberate mix inside it. Use `.text-panel-formula-fallback` only inside formula figures when LaTeX cannot be rendered.
1018
1055
  - Eyebrow, heading, and footer are all optional — include them only when the content calls for them.
1019
1056
  - Default text panels should remain transparent. Choose `--dark` or `--light` only when the component intentionally needs its own reading field; do not mix variants within a single panel.
1020
1057
  - Pair with a visually dominant neighbor (image, chart) when the layout needs strong contrast against the text zone.
@@ -2107,110 +2144,6 @@ Minimal table-of-contents slide with a quiet title block on the left and a spaci
2107
2144
  - **Left footer stays small.** The footer should read like a restrained production note, not a secondary headline.
2108
2145
  <!-- @component:toc:end -->
2109
2146
 
2110
- <!-- @component:quote:start -->
2111
- #### Quote (.quote-block)
2112
-
2113
- Flat editorial quote block. Wide and short (width > height). Transparent background — place it inside any layout slot. The large decorative quotation mark is CSS-rendered (no icon dependency).
2114
-
2115
- ```html
2116
- <div class="quote-block">
2117
- <div class="quote-mark" aria-hidden="true">“</div>
2118
- <p class="quote-text">The mountains teach us that progress is measured not in speed, but in the ground gained against resistance.</p>
2119
- <div class="quote-attribution">
2120
- <div class="quote-avatar">JD</div><!-- or <img src="avatar.jpg" alt="Jane Doe"> -->
2121
- <div class="quote-meta">
2122
- <p class="quote-name">Jane Doe</p>
2123
- <p class="caption">CEO, Acme Corporation</p>
2124
- </div>
2125
- </div>
2126
- </div>
2127
- ```
2128
-
2129
- ```css
2130
- .quote-block {
2131
- position: relative;
2132
- padding: 36px 44px 32px;
2133
- overflow: hidden;
2134
- }
2135
-
2136
- .quote-mark {
2137
- position: absolute;
2138
- top: -18px;
2139
- left: 28px;
2140
- font-family: Baskerville, Georgia, serif;
2141
- font-size: 140px;
2142
- font-weight: 700;
2143
- line-height: 1;
2144
- color: var(--accent-sage);
2145
- opacity: 0.42;
2146
- pointer-events: none;
2147
- user-select: none;
2148
- }
2149
-
2150
- .quote-text {
2151
- position: relative;
2152
- font-size: 20px;
2153
- font-style: italic;
2154
- line-height: 1.5;
2155
- color: var(--text-primary);
2156
- max-width: 860px;
2157
- padding-top: 48px; /* clears the decorative mark */
2158
- }
2159
-
2160
- .quote-attribution {
2161
- display: flex;
2162
- align-items: center;
2163
- gap: 14px;
2164
- margin-top: 24px;
2165
- }
2166
-
2167
- .quote-avatar {
2168
- width: 48px;
2169
- height: 48px;
2170
- border-radius: 50%;
2171
- background: var(--bg-page-alt);
2172
- border: 1px solid var(--line-strong);
2173
- display: flex;
2174
- align-items: center;
2175
- justify-content: center;
2176
- font-family: var(--font-display);
2177
- font-size: var(--font-size-body);
2178
- font-weight: 700;
2179
- color: var(--text-muted);
2180
- flex-shrink: 0;
2181
- overflow: hidden;
2182
- }
2183
-
2184
- .quote-avatar img {
2185
- width: 100%;
2186
- height: 100%;
2187
- object-fit: cover;
2188
- }
2189
-
2190
- .quote-meta {
2191
- display: flex;
2192
- flex-direction: column;
2193
- gap: 2px;
2194
- }
2195
-
2196
- .quote-name {
2197
- font-size: var(--font-size-body);
2198
- font-weight: 600;
2199
- color: var(--text-primary);
2200
- line-height: 1.3;
2201
- }
2202
- ```
2203
-
2204
- **Tips:**
2205
-
2206
- - **Dark background**: override text colors on the parent slot — `color: var(--bg-page)` for `.quote-text` and `.quote-name`; increase `.quote-mark` opacity to `0.15` (the sage hue reads better against dark at lower opacity).
2207
- - **Avatar with photo**: replace `<div class="quote-avatar">JD</div>` with `<div class="quote-avatar"><img src="path/to/photo.jpg" alt="Jane Doe"></div>`. The `overflow: hidden` + `object-fit: cover` handles any image aspect ratio.
2208
- - **Quote text length**: adjust `font-size` between `18px` (longer quotes, 3+ lines) and `24px` (short punchy quotes, 1 line). Keep `line-height: 1.5`.
2209
- - **Opacity guidance**: on `--bg-page` (warm paper), `.quote-mark` opacity `0.25` works well. On dark `--bg-frame` backgrounds, reduce to `0.15`.
2210
- - **Source-only attribution** (no person): omit `.quote-avatar` entirely and use `.quote-name` for the source text (e.g. a report title or publication name).
2211
-
2212
- <!-- @component:quote:end -->
2213
-
2214
2147
  <!-- @component:brand-watermark:start -->
2215
2148
  #### Brand Watermark
2216
2149
 
@@ -2670,6 +2603,7 @@ Summit skins Revela built-in page templates with editorial hierarchy, broad whit
2670
2603
 
2671
2604
  - `cover`, `section-divider`, `closing`: use strong editorial title pages.
2672
2605
  - `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use borderless narrative groupings with clear hierarchy.
2606
+ - Agenda typography follows design tokens: title and numbers use `--font-display`; item labels and footer use `--font-body`.
2673
2607
  - `metric-highlight`, `chart-takeaways`, `table`, `table-comparison`: use evidence-first data regions without outer container borders.
2674
2608
  - Text panels use explicit variants: `template-text-panel--clear` is transparent with no border or background, `template-text-panel--plain` is theme-neutral, and `template-text-panel--color` is the multicolor emphasis treatment used by chart and timeline reading panels.
2675
2609
  - `milestone`: dots remain milestone anchors inside each horizontal milestone item; do not position detached decorative markers.
@@ -99,24 +99,24 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
99
99
  linear-gradient(135deg, #07111f, #101a2b 62%, #243a73);
100
100
  }
101
101
 
102
- .template-slide[data-design="lucent"][data-template="cover"] .slide-canvas {
102
+ .template-slide[data-design="summit"][data-template="cover"] .slide-canvas {
103
103
  background:
104
104
  linear-gradient(90deg, rgba(7,17,31,0.82), rgba(7,17,31,0.42) 52%, rgba(7,17,31,0.24)),
105
105
  url("./assets/cover-background.jpg") center center / cover no-repeat;
106
106
  }
107
- .template-slide[data-design="lucent"][data-template="agenda"] .slide-canvas {
107
+ .template-slide[data-design="summit"][data-template="agenda"] .slide-canvas {
108
108
  background:
109
109
  linear-gradient(90deg, rgba(7,17,31,0.86), rgba(7,17,31,0.58) 52%, rgba(7,17,31,0.32)),
110
110
  url("./assets/cover-background.jpg") center center / cover no-repeat;
111
111
  }
112
- .template-slide[data-design="lucent"][data-template="section-divider"] .slide-canvas {
112
+ .template-slide[data-design="summit"][data-template="section-divider"] .slide-canvas {
113
113
  background:
114
114
  linear-gradient(90deg, rgba(7,17,31,0.86), rgba(16,26,43,0.62) 58%, rgba(36,58,115,0.36)),
115
115
  url("./assets/cover-background.jpg") center center / cover no-repeat;
116
116
  }
117
117
  .template-slide[data-template="closing"] .slide-canvas { background: linear-gradient(135deg, #07111f, #315eea 58%, #18a8d8); }
118
118
 
119
- .template-slide[data-design="lucent"][data-template="closing"] .slide-canvas {
119
+ .template-slide[data-design="summit"][data-template="closing"] .slide-canvas {
120
120
  background:
121
121
  linear-gradient(90deg, rgba(7,17,31,0.82), rgba(49,94,234,0.42) 58%, rgba(24,168,216,0.24)),
122
122
  url("./assets/closing-background.jpg") center center / cover no-repeat;
@@ -125,12 +125,12 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
125
125
  .template-agenda-inner { width: 100%; display: grid; grid-template-columns: 37% minmax(0, 1fr); align-items: stretch; gap: 76px; }
126
126
  .template-agenda-header { display: flex; flex-direction: column; min-height: 0; padding: 10px 0 0; }
127
127
  .template-agenda-header .template-eyebrow { color: rgba(255,255,255,0.64); }
128
- .template-agenda-header .template-title { max-width: 440px; font-size: 54px; line-height: 1.16; letter-spacing: 0; text-transform: uppercase; color: white; padding-bottom: 8px; overflow: visible; }
129
- .template-agenda-footer { margin: auto 0 0; font-size: 13px; line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 800; color: rgba(255,255,255,0.84); }
128
+ .template-agenda-header .template-title { max-width: 440px; font-family: var(--font-display); font-size: 54px; line-height: 1.16; letter-spacing: 0; text-transform: uppercase; color: white; padding-bottom: 8px; overflow: visible; }
129
+ .template-agenda-footer { margin: auto 0 0; font-family: var(--font-body); font-size: 13px; line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 800; color: rgba(255,255,255,0.84); }
130
130
  .template-agenda-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 40px; height: 100%; }
131
131
  .template-agenda-item { display: grid; grid-template-columns: 86px minmax(0, 1fr); gap: 44px; align-items: center; min-height: 58px; overflow: visible; }
132
132
  .template-agenda-item span { font-family: var(--font-display); font-size: 44px; line-height: 1; letter-spacing: 0.03em; color: var(--accent-cyan, #18a8d8); font-weight: 800; font-variant-numeric: tabular-nums; }
133
- .template-agenda-item strong { font-size: 18px; line-height: 1.45; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: rgba(255,255,255,0.92); }
133
+ .template-agenda-item strong { font-family: var(--font-body); font-size: 18px; line-height: 1.45; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: rgba(255,255,255,0.92); }
134
134
  .template-metric-layout { height: 100%; min-height: 0; display: grid; gap: 26px; }
135
135
  .template-metric-layout--insight-top { grid-template-rows: auto minmax(0, 1fr); }
136
136
  .template-metric-layout--insight-bottom { grid-template-rows: minmax(0, 1fr) auto; }
@@ -146,6 +146,21 @@ body { margin: 0; background: var(--bg-frame, #07111f); color: var(--text-primar
146
146
  .template-text-panel--color { background: linear-gradient(135deg, #5f82c8 0%, var(--accent-primary) 58%, #18a8d8 115%); color: white; box-shadow: 0 22px 56px rgba(49,94,234,0.24); }
147
147
  .template-text-panel--color .template-text-panel-title { color: white; }
148
148
  .template-text-panel--color .template-text-panel-body { color: rgba(255,255,255,0.78); }
149
+ .template-text-panel-quote { margin: 2px 0 0; font-size: 22px; line-height: 1.44; font-style: italic; color: var(--text-secondary); }
150
+ .template-text-panel--color .template-text-panel-quote { color: rgba(255,255,255,0.82); }
151
+ .template-text-panel-formula { margin: 0; width: 100%; display: grid; gap: 8px; color: var(--text-primary); }
152
+ .template-text-panel--color .template-text-panel-formula { color: white; }
153
+ .template-text-panel-formula .katex-display { margin: 0; overflow: visible; }
154
+ .template-text-panel-formula .katex { font-size: 1.08em; color: inherit; }
155
+ .template-text-panel-formula-fallback { display: block; white-space: normal; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82em; line-height: 1.35; color: inherit; }
156
+ .template-text-panel-formula-caption { margin: 0; font-size: 14px; line-height: 1.35; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
157
+ .template-text-panel--color .template-text-panel-formula-caption { color: rgba(255,255,255,0.72); }
158
+ .text-panel-quote { margin: 0; font-style: italic; line-height: 1.46; color: var(--text-secondary); }
159
+ .text-panel-formula { margin: 0; display: grid; gap: 8px; color: var(--text-primary); }
160
+ .text-panel-formula .katex-display { margin: 0; overflow: visible; }
161
+ .text-panel-formula .katex { color: inherit; }
162
+ .text-panel-formula-fallback { display: block; white-space: normal; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82em; line-height: 1.35; color: inherit; }
163
+ .text-panel-formula-caption { margin: 0; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
149
164
  .template-chart-takeaway-list { display: grid; gap: 22px; width: 100%; }
150
165
  .template-chart-takeaway-item { display: grid; gap: 7px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,0.24); }
151
166
  .template-chart-takeaway-item:first-child { padding-top: 0; border-top: 0; }
@@ -1321,7 +1321,7 @@ function inferComponentNesting(name: string): DesignInventoryComponent["nesting"
1321
1321
  return {
1322
1322
  role: "container",
1323
1323
  acceptsChildren: true,
1324
- allowedChildren: ["text-panel", "media", "echart-panel", "data-table", "stat-card", "quote", "steps", "roadmap-horizontal", "roadmap-vertical", "toc"],
1324
+ allowedChildren: ["text-panel", "media", "echart-panel", "data-table", "stat-card", "steps", "roadmap-horizontal", "roadmap-vertical", "toc"],
1325
1325
  }
1326
1326
  }
1327
1327
  if (name === "hero") return { role: "fullbleed", acceptsChildren: false }
@@ -0,0 +1,14 @@
1
+ import { dirname, resolve } from "path"
2
+ import { pathToFileURL } from "url"
3
+
4
+ export function withExportBaseHref(html: string, htmlFilePath: string): string {
5
+ if (/<base\b/i.test(html)) return html
6
+
7
+ const baseHref = pathToFileURL(`${dirname(resolve(htmlFilePath))}/`).href
8
+ const baseTag = `<base href="${baseHref}">`
9
+
10
+ if (/<head[^>]*>/i.test(html)) {
11
+ return html.replace(/<head([^>]*)>/i, `<head$1>\n${baseTag}`)
12
+ }
13
+ return `${baseTag}\n${html}`
14
+ }
@@ -141,6 +141,7 @@
141
141
  </header><div class="template-body template-grid template-chart-layout"><div class="template-chart-panel template-visual-slot-panel" data-template-slot="visual"><span class="template-visual-slot-label">image / chart slot (optional)</span></div><div class="template-text-panel template-text-panel--color template-chart-takeaway-panel" data-template-slot="takeaways">
142
142
  <h2 class="template-text-panel-title">What to read</h2>
143
143
  <div class="template-chart-takeaway-list"><section class="template-chart-takeaway-item"><h3>Trend</h3><p>Call out the movement or comparison the chart is meant to prove, including the direction and the comparison baseline.</p></section><section class="template-chart-takeaway-item"><h3>Driver</h3><p>Name the likely reason without overclaiming; separate observed movement from the interpretation or hypothesis.</p></section><section class="template-chart-takeaway-item"><h3>Decision use</h3><p>Explain how the chart changes the recommendation, what threshold matters, and what follow-up evidence would reduce risk.</p></section></div>
144
+ <figure class="template-text-panel-formula" data-latex="\mathrm{CAGR}=\left(\frac{\mathrm{FY26\ Plan}}{\mathrm{FY25}}\right)^{1/n}-1"><span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mi mathvariant="normal">C</mi><mi mathvariant="normal">A</mi><mi mathvariant="normal">G</mi><mi mathvariant="normal">R</mi></mrow><mo>=</mo><msup><mrow><mo fence="true">(</mo><mfrac><mrow><mi mathvariant="normal">F</mi><mi mathvariant="normal">Y</mi><mn>26</mn><mtext> </mtext><mi mathvariant="normal">P</mi><mi mathvariant="normal">l</mi><mi mathvariant="normal">a</mi><mi mathvariant="normal">n</mi></mrow><mrow><mi mathvariant="normal">F</mi><mi mathvariant="normal">Y</mi><mn>25</mn></mrow></mfrac><mo fence="true">)</mo></mrow><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mi>n</mi></mrow></msup><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\mathrm{CAGR}=\left(\frac{\mathrm{FY26\ Plan}}{\mathrm{FY25}}\right)^{1/n}-1</annotation></semantics></math></span><p class="template-text-panel-formula-caption">Formula text member</p></figure>
144
145
  </div></div>
145
146
 
146
147
  </div>
@@ -153,7 +154,7 @@
153
154
  <header>
154
155
  <p class="template-eyebrow">Template 11 / 17</p>
155
156
  <h1 class="template-title">table</h1>
156
- </header><div class="template-body"><div class="template-table-layout"><div class="template-side-panel template-text-panel template-text-panel--clear" data-template-slot="text-card"><h2 class="template-side-panel-title template-text-panel-title">Financial readout</h2><p class="template-side-panel-body template-text-panel-body">Read top-line growth first, then check margin, cash conversion, and retention to see whether the plan is financially durable.</p></div><div class="template-table-region" data-template-slot="table"><div class="template-table-wrap"><table class="template-table"><thead><tr><th>Line item</th><th>FY2025</th><th>FY2026 Plan</th><th>YoY / note</th></tr></thead><tbody><tr><td>Revenue</td><td>$84.2M</td><td>$104.8M</td><td>+24% planned growth</td></tr><tr><td>Gross margin</td><td>68.4%</td><td>71.2%</td><td>+280 bps mix shift</td></tr><tr><td>Operating expense</td><td>$42.7M</td><td>$49.1M</td><td>Scale hiring below revenue growth</td></tr><tr><td>EBITDA</td><td>$14.9M</td><td>$23.6M</td><td>+58% operating leverage</td></tr><tr><td>Free cash flow</td><td>$9.8M</td><td>$16.4M</td><td>Cash conversion improves to 69%</td></tr><tr><td>Net retention</td><td>116%</td><td>121%</td><td>Expansion supports plan quality</td></tr></tbody></table></div></div></div></div>
157
+ </header><div class="template-body"><div class="template-table-layout"><div class="template-side-panel template-text-panel template-text-panel--clear" data-template-slot="text-card"><h2 class="template-side-panel-title template-text-panel-title">Financial readout</h2><p class="template-side-panel-body template-text-panel-body">Read top-line growth first, then check margin, cash conversion, and retention to see whether the plan is financially durable.</p><blockquote class="template-text-panel-quote">Durability shows up when growth, margin, and cash all point in the same direction.</blockquote></div><div class="template-table-region" data-template-slot="table"><div class="template-table-wrap"><table class="template-table"><thead><tr><th>Line item</th><th>FY2025</th><th>FY2026 Plan</th><th>YoY / note</th></tr></thead><tbody><tr><td>Revenue</td><td>$84.2M</td><td>$104.8M</td><td>+24% planned growth</td></tr><tr><td>Gross margin</td><td>68.4%</td><td>71.2%</td><td>+280 bps mix shift</td></tr><tr><td>Operating expense</td><td>$42.7M</td><td>$49.1M</td><td>Scale hiring below revenue growth</td></tr><tr><td>EBITDA</td><td>$14.9M</td><td>$23.6M</td><td>+58% operating leverage</td></tr><tr><td>Free cash flow</td><td>$9.8M</td><td>$16.4M</td><td>Cash conversion improves to 69%</td></tr><tr><td>Net retention</td><td>116%</td><td>121%</td><td>Expansion supports plan quality</td></tr></tbody></table></div></div></div></div>
157
158
 
158
159
  </div>
159
160
  <div class="template-page-number">11</div>
@@ -232,7 +233,7 @@
232
233
  <header>
233
234
  <p class="template-eyebrow">Template 14 / 17</p>
234
235
  <h1 class="template-title">timeline</h1>
235
- </header><div class="template-body"><div class="template-timeline-layout template-timeline-layout--left"><div class="template-side-panel template-text-panel template-text-panel--color" data-template-slot="insight"><h2 class="template-side-panel-title template-text-panel-title">Reading the journey</h2><p class="template-side-panel-body template-text-panel-body">The timeline should show sequence and decision rhythm, while the side panel explains why the milestones matter.</p></div><div class="template-timeline template-timeline--vertical" data-template-slot="timeline" style="--timeline-count:4"><article class="template-timeline-item">
236
+ </header><div class="template-body"><div class="template-timeline-layout template-timeline-layout--left"><div class="template-side-panel template-text-panel template-text-panel--color" data-template-slot="insight"><h2 class="template-side-panel-title template-text-panel-title">Reading the journey</h2><p class="template-side-panel-body template-text-panel-body">The timeline should show sequence and decision rhythm, while the side panel explains why the milestones matter.</p><blockquote class="template-text-panel-quote">Sequence is evidence when each step changes what the audience can believe.</blockquote></div><div class="template-timeline template-timeline--vertical" data-template-slot="timeline" style="--timeline-count:4"><article class="template-timeline-item">
236
237
  <span class="template-timeline-dot" aria-hidden="true"></span>
237
238
  <div class="template-timeline-copy">
238
239
  <p class="template-timeline-date">Mar 2019</p>