@cyber-dash-tech/revela 0.15.0 → 0.15.1

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.
@@ -57,7 +57,7 @@ Accent usage guidance:
57
57
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
58
58
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Condensed:wght@500;600;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
59
59
  ```
60
- - cover h1: `108px` to `124px`, weight `600` to `700`, line-height `0.88` to `0.94`, uppercase
60
+ - cover h1: `108px` to `124px`, weight `600` to `700`, line-height `0.88` to `0.94`, Title Case
61
61
  - inner-layout h2: `30px` to `36px`, weight `600` to `700`, line-height `1.06` to `1.12`
62
62
  - inner-layout h3: `20px` to `24px`, weight `600`, line-height `1.12` to `1.18`
63
63
  - Body: `17px`, line-height `1.6`
@@ -66,6 +66,7 @@ Accent usage guidance:
66
66
  - Never use text shadows or glow.
67
67
  - Never switch to a serif typeface; Summit is strictly sans-serif.
68
68
  - Foundation owns the default text scale. In components, let `p`, `li`, `.caption`, `.eyebrow`, and `h3` inherit the foundation sizes unless a component has a clear structural reason to differ.
69
+ - Titles use Title Case, not all caps. Use uppercase only for eyebrows, captions, metadata labels, short codes, and date/code-like roadmap markers.
69
70
 
70
71
  All sizes are fixed `px` for the 1920x1080 canvas. JS `transform: scale()` handles viewport adaptation. Never use `clamp()` or viewport-relative units.
71
72
 
@@ -207,6 +208,16 @@ body {
207
208
  color: var(--text-muted);
208
209
  }
209
210
 
211
+ .source,
212
+ .source-note {
213
+ font-family: "Times New Roman", Times, serif;
214
+ font-size: 11px;
215
+ line-height: 1.35;
216
+ letter-spacing: 0;
217
+ text-transform: none;
218
+ color: var(--text-muted);
219
+ }
220
+
210
221
  h1, h2, h3, h4 {
211
222
  font-family: var(--font-display);
212
223
  font-weight: 600;
@@ -273,6 +284,15 @@ p, li {
273
284
  color: var(--text-muted);
274
285
  }
275
286
 
287
+ .media-caption.source,
288
+ .media-caption.source-note {
289
+ font-family: "Times New Roman", Times, serif;
290
+ font-size: 11px;
291
+ line-height: 1.35;
292
+ letter-spacing: 0;
293
+ text-transform: none;
294
+ }
295
+
276
296
  /* editorial-list: square bullet + optional <strong> lead phrase per item.
277
297
  Usage: <li><strong>Lead phrase.</strong> Supporting copy.</li>
278
298
  Dark bg override: set --accent-earth to rgba(247,244,238,0.72) on the list wrapper. */
@@ -418,6 +438,11 @@ These rules are mandatory for Summit.
418
438
  - **Sparse slides depend on image weight.** If content is light, the photo or page framing must hold the composition.
419
439
  - **No glass cards, neon KPI styling, or startup-product chrome.** Summit is editorial and print-adjacent.
420
440
  - **Visual hierarchy is strict:** eyebrow -> heading -> body -> caption.
441
+ - **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.
442
+ - **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.
443
+ - **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.
444
+ - **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.
445
+ - **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.
421
446
 
422
447
  ### Common Mistakes
423
448
 
@@ -447,21 +472,23 @@ These rules are mandatory for Summit.
447
472
 
448
473
  Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. It must also set `data-slide-index="N"`, where `N` is the 1-based `DECKS.json` `slides[].index` value. Use the QA column to decide which value to write. Fetch any layout with the `revela-designs` tool (`action: "read"`, `layout: "<name>"`).
449
474
 
475
+ Normal `qa=true` content layouts should start with a slide-level title block unless the layout marker explicitly says otherwise. Use an eyebrow for chapter/section context, then an `h2` that states the slide's claim or takeaway. Body boxes, charts, media, tables, and text panels should sit below or beside that title region rather than replacing it.
476
+
450
477
  <!-- @layout:fullbleed:start qa=false -->
451
478
  #### Fullbleed
452
479
 
453
480
  Full-canvas layout for slides where a single image dominates the entire canvas with text composited over it. Use for opening (cover) and closing slides, or atmospheric section dividers.
454
481
 
455
482
  Structural intent:
456
- - Single slot: place one `image-title` component directly inside `.page`. The component is self-contained — it manages its own image, blur, overlay, and text layers internally.
483
+ - Single slot: place one `hero` component directly inside `.page`. The component is self-contained — it manages its own image, blur, overlay, and text layers internally.
457
484
 
458
485
  ```html
459
486
  <section class="slide" slide-qa="false" data-slide-index="N">
460
487
  <div class="slide-canvas">
461
488
  <div class="page" style="padding:0;">
462
489
 
463
- <!-- [slot: content] — use image-title component; set --left for cover, --right for closing -->
464
- <!-- image-title handles all internal z-index layering (image → blur → overlay → text) -->
490
+ <!-- [slot: content] — use hero component; set --left for cover, --right for closing -->
491
+ <!-- hero handles all internal z-index layering (image → blur → overlay → text) -->
465
492
 
466
493
  </div>
467
494
  </div>
@@ -469,10 +496,10 @@ Structural intent:
469
496
  ```
470
497
 
471
498
  ##### Tips
472
- - **Use `image-title` as the sole child.** The component is self-contained and fills `width:100%; height:100%` automatically. Do not add extra wrapper divs around it.
473
- - **Cover vs closing.** Cover: `image-title--left` with a diagonal overlay (`105deg`, left-dark to right-transparent) and left-biased blur mask. Closing: `image-title--right` with a bottom-heavy overlay (`180deg`) and right-biased blur mask.
474
- - **Page number.** Use `.page-number--light` — position it inside `.page` at `z-index:10` so it sits above the `image-title` stacking context.
475
- - **Text opacity.** For atmospheric section dividers where content is minimal, add `style="opacity:0.85"` on the `.image-title` container to soften the foreground text layer against the image.
499
+ - **Use `hero` as the sole child.** The component is self-contained and fills `width:100%; height:100%` automatically. Do not add extra wrapper divs around it.
500
+ - **Cover vs closing.** Cover: `hero--left` with a diagonal overlay (`105deg`, left-dark to right-transparent) and left-biased blur mask. Closing: `hero--right` with a bottom-heavy overlay (`180deg`) and right-biased blur mask.
501
+ - **Page number.** Use `.page-number--light` — position it inside `.page` at `z-index:10` so it sits above the `hero` stacking context.
502
+ - **Text opacity.** For atmospheric section dividers where content is minimal, add `style="opacity:0.85"` on the `.hero` container to soften the foreground text layer against the image.
476
503
  <!-- @layout:fullbleed:end -->
477
504
 
478
505
  <!-- @layout:narrative:start qa=true -->
@@ -491,13 +518,17 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
491
518
  <section class="slide" slide-qa="true" data-slide-index="N">
492
519
  <div class="slide-canvas">
493
520
  <div class="page" style="padding:0;overflow:hidden;">
494
- <div class="narrative-grid">
521
+ <div style="display:flex;flex-direction:column;gap:10px;margin:56px 64px 28px;max-width:760px;position:relative;z-index:2;">
522
+ <p class="eyebrow">Chapter / Section</p>
523
+ <h2>Slide Claim or Takeaway</h2>
524
+ </div>
525
+ <div class="narrative-grid" style="height:calc(100% - 150px);">
495
526
 
496
- <!-- [slot: left] — 1+ components; suggested: image-title, echart-panel, text-panel -->
527
+ <!-- [slot: left] — 1+ components; suggested: hero, media, echart-panel, text-panel, box -->
497
528
  <div>
498
529
  </div>
499
530
 
500
- <!-- [slot: right] — 1+ components; suggested: text-panel, toc, flow-vertical, data-table -->
531
+ <!-- [slot: right] — 1+ components; suggested: text-panel, toc, steps, data-table, box -->
501
532
  <div>
502
533
  </div>
503
534
 
@@ -551,13 +582,17 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
551
582
  <section class="slide" slide-qa="true" data-slide-index="N">
552
583
  <div class="slide-canvas">
553
584
  <div class="page" style="padding:0;overflow:hidden;">
554
- <div class="narrative-grid narrative-grid--reverse">
585
+ <div style="display:flex;flex-direction:column;gap:10px;margin:56px 64px 28px;max-width:760px;position:relative;z-index:2;">
586
+ <p class="eyebrow">Chapter / Section</p>
587
+ <h2>Slide Claim or Takeaway</h2>
588
+ </div>
589
+ <div class="narrative-grid narrative-grid--reverse" style="height:calc(100% - 150px);">
555
590
 
556
- <!-- [slot: left] — 1+ components; suggested: text-panel, toc, flow-vertical, echart-panel -->
591
+ <!-- [slot: left] — 1+ components; suggested: text-panel, toc, steps, echart-panel, box -->
557
592
  <div>
558
593
  </div>
559
594
 
560
- <!-- [slot: right] — 1+ components; suggested: image-title, echart-panel, data-table -->
595
+ <!-- [slot: right] — 1+ components; suggested: hero, media, echart-panel, data-table -->
561
596
  <div>
562
597
  </div>
563
598
 
@@ -578,7 +613,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
578
613
 
579
614
  Equal N-column layout. Use when 3 or more parallel items of roughly equal visual weight should appear side by side — proof blocks, highlights, feature comparisons, stat groups, or any multi-column editorial spread.
580
615
 
581
- A short section header is optional but recommended. In Summit, that header should stay lean: eyebrow plus title only, with no intro paragraph competing with the columns below.
616
+ A short section header is the default for normal content uses. In Summit, that header should stay lean: eyebrow plus title only, with no intro paragraph competing with the columns below. Omit it only for deliberate focus/structural exceptions.
582
617
 
583
618
  Structural intent:
584
619
  - each slot: 1fr column — any component(s)
@@ -592,20 +627,20 @@ Every slot accepts 1 or more components. Add or remove child divs to control col
592
627
  <div class="page">
593
628
  <div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:520px;">
594
629
  <p class="eyebrow">Section Label</p>
595
- <h2 style="font-size:52px;line-height:0.94;text-transform:uppercase;">Short framing title for the parallel columns</h2>
630
+ <h2 style="font-size:48px;line-height:1.02;">Short Framing Title for the Parallel Columns</h2>
596
631
  </div>
597
632
 
598
633
  <div class="highlight-cols-grid" style="flex:1;min-height:0;">
599
634
 
600
- <!-- [slot: 1] — 1+ components; suggested: editorial-image-top, editorial-text-top, echart-panel -->
635
+ <!-- [slot: 1] — 1+ components; suggested: box, media, text-panel, echart-panel -->
601
636
  <div>
602
637
  </div>
603
638
 
604
- <!-- [slot: 2] — 1+ components; suggested: editorial-text-top, echart-panel, flow-vertical -->
639
+ <!-- [slot: 2] — 1+ components; suggested: box, text-panel, echart-panel, steps -->
605
640
  <div>
606
641
  </div>
607
642
 
608
- <!-- [slot: 3] — 1+ components; suggested: editorial-image-top, editorial-text-top, echart-panel -->
643
+ <!-- [slot: 3] — 1+ components; suggested: box, media, text-panel, echart-panel -->
609
644
  <div>
610
645
  </div>
611
646
 
@@ -636,7 +671,7 @@ Every slot accepts 1 or more components. Add or remove child divs to control col
636
671
  - **Column count = number of direct child divs.** `repeat(auto-fit, minmax(0, 1fr))` distributes available width equally across however many children exist. Add a 4th or 5th div to get 4 or 5 columns — no CSS change needed.
637
672
  - **Equal columns — no hierarchy.** All slots carry the same visual weight. Adjust content density to suit the slide purpose; do not artificially inflate one column to create false hierarchy.
638
673
  - **When using 4-5 columns, compress the header.** Keep the title to one or two short lines so the grid retains most of the slide height.
639
- - **Do not set fixed heights on editorial components.** Let components fill height via flexbox stretch.
674
+ - **Use boxes for semantic groups.** Normal content slides should usually contain 2-4 `box` components unless using a deliberate focus layout.
640
675
  <!-- @layout:highlight-cols:end -->
641
676
 
642
677
  <!-- @layout:halves:start qa=true -->
@@ -655,9 +690,13 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
655
690
  <section class="slide" slide-qa="true" data-slide-index="N">
656
691
  <div class="slide-canvas">
657
692
  <div class="page" style="overflow:hidden;">
693
+ <div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:760px;">
694
+ <p class="eyebrow">Chapter / Section</p>
695
+ <h2 style="font-size:48px;line-height:1.02;">Slide Claim or Takeaway</h2>
696
+ </div>
658
697
  <div class="halves-grid" style="flex:1;min-height:0;">
659
698
 
660
- <!-- [slot: left] — 1+ components; suggested: echart-panel, data-table, editorial-image-top -->
699
+ <!-- [slot: left] — 1+ components; suggested: echart-panel, data-table, box, media -->
661
700
  <div>
662
701
  </div>
663
702
 
@@ -708,17 +747,23 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
708
747
  ```html
709
748
  <section class="slide" slide-qa="true" data-slide-index="N">
710
749
  <div class="slide-canvas">
711
- <div class="page" style="padding:0;">
712
- <div class="stacked-grid">
750
+ <div class="page">
751
+ <div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:760px;">
752
+ <p class="eyebrow">Chapter / Section</p>
753
+ <h2 style="font-size:48px;line-height:1.02;">Slide Claim or Takeaway</h2>
754
+ </div>
755
+ <div style="flex:1;min-height:0;">
756
+ <div class="stacked-grid">
713
757
 
714
- <!-- [slot: top] — 1+ components; suggested: flow-horizontal, stat-row -->
715
- <div class="stacked-top">
716
- </div>
758
+ <!-- [slot: top] — 1+ components; suggested: steps, stat-card, box -->
759
+ <div class="stacked-top">
760
+ </div>
717
761
 
718
- <!-- [slot: bottom] — 1+ components; suggested: echart-panel, data-table -->
719
- <div class="stacked-bottom">
720
- </div>
762
+ <!-- [slot: bottom] — 1+ components; suggested: echart-panel, data-table -->
763
+ <div class="stacked-bottom">
764
+ </div>
721
765
 
766
+ </div>
722
767
  </div>
723
768
  </div>
724
769
  </div>
@@ -761,6 +806,53 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
761
806
 
762
807
  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.
763
808
 
809
+ Use this hierarchy: `layout -> box/card -> text-panel + media/chart/table/stat/quote`.
810
+
811
+ 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.
812
+
813
+ Source and citation text should use `.source` or `.source-note`, not `.caption`. Source text uses Times New Roman at 11px and never uses uppercase letter-spacing treatment.
814
+
815
+ LLM-facing vocabulary:
816
+ - `box` — card/group primitive for one idea, case, evidence item, metric, objection, risk, or action.
817
+ - `text-panel` — language module for title, body text, bullets, and source notes.
818
+ - `media` — normal image/screenshot/diagram/logo/portrait component; use `hero` for full-bleed covers.
819
+ - `echart-panel` — chart frame with caption/source structure.
820
+ - `data-table` — structured table component for tabular data and source notes.
821
+ - `steps` — process or phase sequence; compatibility implementation may use `.flow-*` classes.
822
+ - `roadmap-horizontal` and `roadmap-vertical` — dated phases, milestones, historical evolution, or future plans; compatibility implementation may use `.tjh` and `.tjv` classes.
823
+ - `hero` — full-bleed cover, section divider, closing, or strong visual statement with overlaid title/subtitle.
824
+ - `stat-card`, `quote`, and `toc` — pattern components for their specific use cases.
825
+ - `page-number` and `brand-watermark` — utility components.
826
+
827
+ 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.
828
+
829
+ Density guidance: normal content slides usually need 2-4 boxes. Evidence slides should use 2-3 evidence boxes or one main chart/table with 2 supporting boxes. Process slides should use 3-5 steps. Use one dominant element only for covers, section dividers, closing asks, full-screen charts/visuals, or deliberate emphasis.
830
+
831
+ <!-- @component:box:start -->
832
+ #### Box
833
+
834
+ 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.
835
+
836
+ ```html
837
+ <div class="box">
838
+ <div class="text-panel text-panel--plain">
839
+ <div class="text-panel-body">
840
+ <p class="eyebrow">Evidence</p>
841
+ <h3>One clear idea</h3>
842
+ <p>Short supporting copy or source-bound explanation.</p>
843
+ </div>
844
+ </div>
845
+ </div>
846
+ ```
847
+
848
+ ```css
849
+ .box { height: 100%; min-height: 0; padding: 28px; border: 1px solid var(--line); background: transparent; display: flex; flex-direction: column; gap: 18px; overflow: hidden; }
850
+ .box--quiet { background: transparent; }
851
+ .box--paper { background: rgba(247,244,238,0.72); }
852
+ .box--dark { background: #2c2828; --text-primary:#f7f4ee; --text-secondary:rgba(247,244,238,0.72); --text-muted:rgba(247,244,238,0.55); --line:rgba(247,244,238,0.16); }
853
+ ```
854
+ <!-- @component:box:end -->
855
+
764
856
 
765
857
 
766
858
  <!-- @component:text-panel:start -->
@@ -770,12 +862,14 @@ Use these components when a page needs repeatable editorial modules inside a lar
770
862
 
771
863
  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.
772
864
 
865
+ `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.
866
+
773
867
  ```html
774
868
  <!-- variant A: prose only (--dark) -->
775
869
  <div class="text-panel text-panel--dark">
776
870
  <div style="max-width:420px;">
777
871
  <p class="eyebrow" style="color:rgba(243,238,230,0.72);">Section label / annual review</p>
778
- <h2 style="margin-top:16px;font-size:60px;line-height:0.92;letter-spacing:-0.03em;text-transform:uppercase;color:#f7f4ee;max-width:360px;">Narrative heading</h2>
872
+ <h2 style="margin-top:16px;font-size:56px;line-height:1;letter-spacing:-0.03em;color:#f7f4ee;max-width:390px;">Narrative Heading</h2>
779
873
  <div class="text-panel-body" style="margin-top:20px;">
780
874
  <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>
781
875
  </div>
@@ -835,6 +929,11 @@ Unified narrative text container. Use inside any layout slot that needs a self-c
835
929
  justify-content: space-between;
836
930
  }
837
931
 
932
+ .text-panel--plain {
933
+ padding: 0;
934
+ background: transparent;
935
+ }
936
+
838
937
  .text-panel--dark {
839
938
  background: #2c2828;
840
939
  color: #f3eee6;
@@ -864,7 +963,7 @@ Unified narrative text container. Use inside any layout slot that needs a self-c
864
963
  Rules:
865
964
  - `.text-panel-body` is the only required structural child. Place `<p>` elements, an `<ul class="editorial-list">`, or both inside it.
866
965
  - Eyebrow, heading, and footer are all optional — include them only when the content calls for them.
867
- - Choose `--dark` or `--light` to match the slide's tone. Do not mix variants within a single panel.
966
+ - 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.
868
967
  - Pair with a visually dominant neighbor (image, chart) when the layout needs strong contrast against the text zone.
869
968
 
870
969
  ##### Tips
@@ -875,6 +974,35 @@ Rules:
875
974
  - **`editorial-list` inside `--dark`.** Add `style="--accent-earth:rgba(247,244,238,0.72)"` on the `<ul>` wrapper so the bullet squares read against the dark background.
876
975
  <!-- @component:text-panel:end -->
877
976
 
977
+ <!-- @component:media:start -->
978
+ #### Media
979
+
980
+ Normal image, screenshot, diagram, logo, or portrait component. Keep important visual information understandable. Do not use `media` for full-bleed covers/dividers/closings; use `hero` for those.
981
+
982
+ ```html
983
+ <figure class="media">
984
+ <div class="media-frame">
985
+ <img src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1200&auto=format&fit=crop" alt="Alpine ridge at dawn">
986
+ </div>
987
+ <figcaption class="media-caption source-note">Optional source or field note</figcaption>
988
+ </figure>
989
+ ```
990
+
991
+ ```css
992
+ .media { height: 100%; min-height: 0; display: flex; flex-direction: column; gap: 12px; }
993
+ .media-frame { position: relative; overflow: hidden; background: transparent; width: 100%; flex: 1; min-height: 0; }
994
+ .media-frame img { width: 100%; height: 100%; display: block; object-fit: cover; }
995
+ .media--contain .media-frame img { object-fit: contain; }
996
+ .media-caption { margin-top: 0; font-size: var(--font-size-meta); line-height: 1.5; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
997
+ .media-caption.source, .media-caption.source-note { font-family: "Times New Roman", Times, serif; font-size: 11px; line-height: 1.35; letter-spacing: 0; text-transform: none; }
998
+ ```
999
+
1000
+ Rules:
1001
+ - Use `media` for screenshots, charts exported as images, diagrams, logos, portraits, and evidence visuals that must stay readable.
1002
+ - Use `object-fit: contain` through `media--contain` for screenshots, diagrams, and logos when cropping would remove information.
1003
+ - Put `media` inside a `box` when the visual and text support one semantic idea.
1004
+ <!-- @component:media:end -->
1005
+
878
1006
  <!-- @component:stat-card:start -->
879
1007
  #### Stat Card
880
1008
 
@@ -888,7 +1016,7 @@ This is **not** a dashboard card. It has no border, no background fill, no shado
888
1016
  <p class="caption" style="color:var(--text-muted);">Performance signal</p>
889
1017
  <div class="stat-card-value" style="color: var(--accent-gold);">27%</div>
890
1018
  <div class="text-panel-body" style="gap:10px;max-width:330px;">
891
- <h3 style="line-height:1.04;text-transform:uppercase;">EBIT Margin</h3>
1019
+ <h3 style="line-height:1.08;">EBIT Margin</h3>
892
1020
  <p>Expanded for the third consecutive quarter as premium mix offset freight pressure and held pricing discipline through softer volume.</p>
893
1021
  </div>
894
1022
  </div>
@@ -900,7 +1028,7 @@ This is **not** a dashboard card. It has no border, no background fill, no shado
900
1028
  <div class="stat-card-value" style="color: var(--accent-olive);">4.8x</div>
901
1029
  </div>
902
1030
  <div class="text-panel-body" style="gap:10px;max-width:330px;">
903
- <h3 style="line-height:1.04;text-transform:uppercase;">Inventory Turnover</h3>
1031
+ <h3 style="line-height:1.08;">Inventory Turnover</h3>
904
1032
  <p>Higher cycle efficiency reduced working-capital drag without adding new capacity, leaving more headroom for seasonal demand swings.</p>
905
1033
  </div>
906
1034
  </div>
@@ -948,7 +1076,7 @@ Rules:
948
1076
  - **Do not over-explain.** If the description starts to become paragraph-length, switch to `text-panel` or pair the stat card with a narrative component in the neighboring slot.
949
1077
  <!-- @component:stat-card:end -->
950
1078
 
951
- <!-- @component:editorial-image-top:start -->
1079
+ <!-- @compat:editorial-image-top:start -->
952
1080
  #### Editorial Image Top
953
1081
 
954
1082
  Image-first editorial module: image on top, text below. Best for highlight grids, product/material stories, and any module where the picture should lead before the reader enters the copy.
@@ -1032,9 +1160,9 @@ Rules:
1032
1160
  - **Image aspect ratio.** Aim for 16:9 or 3:2 crops for the image block. Portrait crops create tall image zones that push text down and unbalance the composition.
1033
1161
  - **Kicker icon size.** Keep Lucide SVG icons at 16–20px. Larger icons shift visual weight from the image to the label zone.
1034
1162
  - **`editorial-list` sizing.** Reuse the foundation list size. If a narrow column needs more room, shorten the copy before introducing a component-specific font override.
1035
- <!-- @component:editorial-image-top:end -->
1163
+ <!-- @compat:editorial-image-top:end -->
1036
1164
 
1037
- <!-- @component:editorial-text-top:start -->
1165
+ <!-- @compat:editorial-text-top:start -->
1038
1166
  #### Editorial Text Top
1039
1167
 
1040
1168
  Text-first editorial module: text on top, image below. Best for narrative snippets, report-style explanations, or blocks where the image serves as evidence rather than the primary hook.
@@ -1098,9 +1226,9 @@ Rules:
1098
1226
  - **Same height/stretch rule as `editorial-image-top`.** Do not set fixed heights; let parent grid stretch control the column.
1099
1227
  - **When used as a center spine in `highlight-cols`,** this is the one component that may legitimately be taller than its neighbors. That density imbalance is intentional — do not try to equalize it with padding or extra content in the outer columns.
1100
1228
  - **`editorial-list` sizing.** Reuse the foundation list size. If a narrow column needs more room, shorten the copy before introducing a component-specific font override.
1101
- <!-- @component:editorial-text-top:end -->
1229
+ <!-- @compat:editorial-text-top:end -->
1102
1230
 
1103
- <!-- @component:editorial-text-left:start -->
1231
+ <!-- @compat:editorial-text-left:start -->
1104
1232
  #### Editorial Text Left
1105
1233
 
1106
1234
  Horizontal editorial module: a full-width title band on top, with text on the left and a visual slot on the right below. Best for compact feature rows or any slot where a wide-but-short frame suits a side-by-side composition with a clear heading above.
@@ -1108,14 +1236,14 @@ Horizontal editorial module: a full-width title band on top, with text on the le
1108
1236
  Structure:
1109
1237
  - **header zone** (full width): holds the `h3` module title — independent of the copy below
1110
1238
  - **left: `.editorial-text-left-copy`** — kicker, then `text-panel-body` (prose, bullets, or both)
1111
- - **right: `.editorial-text-left-visual`** — accepts any of: `media-frame img`, `echart-container`, or `image-title`
1239
+ - **right: `.editorial-text-left-visual`** — accepts any of: `media-frame img`, `echart-container`, or the legacy `image-title` implementation used by `hero`
1112
1240
 
1113
1241
  ```html
1114
1242
  <div class="editorial-text-left">
1115
1243
 
1116
1244
  <!-- header: module title spans full width -->
1117
1245
  <div class="editorial-text-left-header">
1118
- <h3 style="line-height:1.08;">Module title — a single standalone heading above both columns</h3>
1246
+ <h3 style="line-height:1.08;">Module Title — a Single Standalone Heading Above Both Columns</h3>
1119
1247
  </div>
1120
1248
 
1121
1249
  <div class="editorial-text-left-content">
@@ -1150,7 +1278,7 @@ Structure:
1150
1278
  <!-- option B: echart -->
1151
1279
  <!-- <div class="echart-container" id="chart-unique-id" style="width:100%;height:100%;"></div> -->
1152
1280
 
1153
- <!-- option C: image-title (self-contained, handles its own overlay and text layers) -->
1281
+ <!-- option C: hero/image-title compatibility implementation -->
1154
1282
  <!-- <div class="image-title image-title--right"> ... </div> -->
1155
1283
 
1156
1284
  </div>
@@ -1201,7 +1329,7 @@ Structure:
1201
1329
  Rules:
1202
1330
  - The `h3` in `.editorial-text-left-header` is the module's top-level title; it must not be repeated inside the copy zone.
1203
1331
  - The left copy zone holds a kicker row followed by a `text-panel-body`. The body accepts prose `<p>`, an `<ul class="editorial-list">`, or both — choose based on content.
1204
- - The right visual slot is open: use a plain `media-frame img`, an `echart-container`, or a full `image-title` component. Choose based on content — there is no default.
1332
+ - The right visual slot is open: use a plain `media-frame img`, an `echart-container`, or a full `hero` implementation. Choose based on content — there is no default.
1205
1333
  - When using `editorial-list` inside `text-panel-body`, add `<strong>` around the first 2–5 words of each `<li>` to create a bold lead phrase for scannable hierarchy.
1206
1334
  - When the card carries a large statistic or callout number, place it between the header and the copy zone using an inline style (`font-size: 48px; font-family: var(--font-display); font-weight: 700; color: var(--accent-gold); line-height: 1;`).
1207
1335
 
@@ -1210,9 +1338,9 @@ Rules:
1210
1338
  - **Text-to-visual flex ratio.** Default is `1.1 : 1` (copy slightly wider). For more copy, try `1.3 : 1`. For a visually dominant right panel, try `1 : 1.2`. Do not go below `0.8` on the copy side.
1211
1339
  - **`editorial-list` inside copy zone.** Keep the foundation size. If the column feels cramped, reduce the amount of copy or widen the text side instead of introducing a smaller local text scale.
1212
1340
  - **`echart-container` in visual slot.** Set `width:100%;height:100%` on the container and call `echarts.init()` after `SlidePresentation` is instantiated. The `position:relative;overflow:hidden` on `.editorial-text-left-visual` contains the canvas correctly.
1213
- - **`image-title` in visual slot.** The component is self-contained and fills `width:100%;height:100%` automatically. Use `image-title--right` modifier with a bottom-heavy overlay and right-biased blur mask for the most common editorial orientation.
1341
+ - **Hero implementation in visual slot.** The component is self-contained and fills `width:100%;height:100%` automatically. Use right alignment with a bottom-heavy overlay and right-biased blur mask for the most common editorial orientation.
1214
1342
  - **Dark background.** Override CSS variables on `.editorial-text-left` to cascade into both the copy and visual zones: `--text-primary`, `--text-secondary`, `--text-muted`, `--line`, `--line-strong` — all set to white-family values.
1215
- <!-- @component:editorial-text-left:end -->
1343
+ <!-- @compat:editorial-text-left:end -->
1216
1344
 
1217
1345
  <!-- @component:echart-panel:start -->
1218
1346
  #### EChart Panel
@@ -1227,7 +1355,7 @@ Chart layout frame for data visualisation. Defines the structural container and
1227
1355
  <p class="chart-subtitle">Optional context or unit note</p>
1228
1356
  </div>
1229
1357
  <div class="echart-container" id="chart-01"></div>
1230
- <p class="chart-caption">Source: Organisation / Year</p>
1358
+ <p class="chart-caption source-note">Source: Organisation / Year</p>
1231
1359
  </div>
1232
1360
 
1233
1361
  <script>
@@ -1273,10 +1401,6 @@ chart.setOption({ /* LLM selects type and config */ });
1273
1401
  .chart-caption {
1274
1402
  flex-shrink: 0;
1275
1403
  margin-top: 12px;
1276
- font-size: var(--font-size-meta);
1277
- letter-spacing: 0.12em;
1278
- text-transform: uppercase;
1279
- color: var(--text-muted);
1280
1404
  }
1281
1405
  ```
1282
1406
 
@@ -1295,30 +1419,30 @@ Rules:
1295
1419
  - **Chart sizing for `narrative-hero-left-dark`.** The left 7.8fr column is wide. A donut or candlestick chart works best centered with some breathing room. Add `padding: 24px 32px` to `.echart-container` to prevent the chart from touching the column edges.
1296
1420
  <!-- @component:echart-panel:end -->
1297
1421
 
1298
- <!-- @component:flow-horizontal:start -->
1299
- #### Flow Horizontal
1422
+ <!-- @component:steps:start -->
1423
+ #### Steps
1300
1424
 
1301
- Horizontal step or phase sequence. Use for process stages, numbered definitions, or parallel concepts that should be read left to right. Suitable for 2–5 items.
1425
+ Process or phase sequence. Use 3-5 steps. Use the horizontal variant for wide slots and the vertical variant for side panels or narrow slots. Legacy `.flow-horizontal` and `.flow-vertical` classes may remain only as compatibility implementation details.
1302
1426
 
1303
1427
  ```html
1304
- <div class="flow-horizontal">
1305
- <div class="flow-item">
1306
- <div class="flow-number">01</div>
1307
- <div class="flow-body">
1428
+ <div class="steps steps--horizontal">
1429
+ <div class="step-item">
1430
+ <div class="step-number">01</div>
1431
+ <div class="step-body">
1308
1432
  <h4>Step Title</h4>
1309
1433
  <p>Brief description of this step or phase.</p>
1310
1434
  </div>
1311
1435
  </div>
1312
- <div class="flow-item">
1313
- <div class="flow-number">02</div>
1314
- <div class="flow-body">
1436
+ <div class="step-item">
1437
+ <div class="step-number">02</div>
1438
+ <div class="step-body">
1315
1439
  <h4>Step Title</h4>
1316
1440
  <p>Brief description of this step or phase.</p>
1317
1441
  </div>
1318
1442
  </div>
1319
- <div class="flow-item">
1320
- <div class="flow-number">03</div>
1321
- <div class="flow-body">
1443
+ <div class="step-item">
1444
+ <div class="step-number">03</div>
1445
+ <div class="step-body">
1322
1446
  <h4>Step Title</h4>
1323
1447
  <p>Brief description of this step or phase.</p>
1324
1448
  </div>
@@ -1327,8 +1451,13 @@ Horizontal step or phase sequence. Use for process stages, numbered definitions,
1327
1451
  ```
1328
1452
 
1329
1453
  ```css
1330
- /* Shared by flow-horizontal and flow-vertical */
1331
- .flow-number {
1454
+ .steps--horizontal { position: relative; display: flex; align-items: flex-start; width: 100%; }
1455
+ .steps--horizontal::before { content: ''; position: absolute; top: 17px; left: 0; right: 0; height: 1px; background: var(--line-strong); z-index: 0; }
1456
+ .steps--horizontal .step-item { flex: 1; display: flex; flex-direction: column; gap: 18px; padding-right: 40px; }
1457
+ .steps--horizontal .step-item:last-child { padding-right: 0; }
1458
+ .steps--horizontal .step-number { position: relative; z-index: 1; background: var(--bg-page); }
1459
+
1460
+ .step-number {
1332
1461
  font-family: var(--font-display);
1333
1462
  font-size: var(--font-size-meta);
1334
1463
  font-weight: 700;
@@ -1343,17 +1472,18 @@ Horizontal step or phase sequence. Use for process stages, numbered definitions,
1343
1472
  flex-shrink: 0;
1344
1473
  }
1345
1474
 
1346
- .flow-body h4 {
1475
+ .step-body h4 {
1347
1476
  font-size: 20px;
1348
1477
  font-weight: 600;
1349
1478
  line-height: 1.14;
1350
1479
  }
1351
1480
 
1352
- .flow-body p {
1481
+ .step-body p {
1353
1482
  line-height: 1.6;
1354
1483
  color: var(--text-secondary);
1355
1484
  }
1356
1485
 
1486
+ /* Compatibility aliases for older generated decks */
1357
1487
  .flow-horizontal {
1358
1488
  position: relative;
1359
1489
  display: flex;
@@ -1389,6 +1519,10 @@ Horizontal step or phase sequence. Use for process stages, numbered definitions,
1389
1519
  z-index: 1;
1390
1520
  background: var(--bg-page);
1391
1521
  }
1522
+
1523
+ .flow-number { font-family: var(--font-display); font-size: var(--font-size-meta); font-weight: 700; letter-spacing: 0.12em; color: var(--text-muted); border: 1px solid var(--line-strong); width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
1524
+ .flow-body h4 { font-size: 20px; font-weight: 600; line-height: 1.14; }
1525
+ .flow-body p { line-height: 1.6; color: var(--text-secondary); }
1392
1526
  ```
1393
1527
 
1394
1528
  Rules:
@@ -1398,44 +1532,41 @@ Rules:
1398
1532
  - Keep each item's body copy short — this is a reference summary, not a detailed explanation.
1399
1533
 
1400
1534
  ##### Tips
1401
- - **Dark background color overrides.** Flow-number: `border-color:rgba(247,244,238,0.3); color:rgba(247,244,238,0.6); background:<dark-bg-color>`. Heading h4: `color:#f7f4ee`. Body p: `color:rgba(247,244,238,0.7)`. Apply inline on each element — CSS cascade does not automatically inherit from the slide background.
1535
+ - **Dark background color overrides.** Step number: `border-color:rgba(247,244,238,0.3); color:rgba(247,244,238,0.6); background:<dark-bg-color>`. Heading h4: `color:#f7f4ee`. Body p: `color:rgba(247,244,238,0.7)`. Apply inline on each element — CSS cascade does not automatically inherit from the slide background.
1402
1536
  - **Step copy length directly affects column balance.** One step with a long paragraph will push its column taller than the others and break the horizontal rhythm. Trim all steps to roughly equal length (2–4 lines each).
1403
- - **Horizontal rule connector.** The `::before` pseudo-element on `.flow-horizontal` draws a full-width line at `top: 17px` (vertical centre of the 34px number box). `.flow-number` sits above it via `z-index: 1` and `background: var(--bg-page)`, creating the effect of the line threading through the numbers. On dark backgrounds, override `background` on `.flow-number` to match the slide background color, and set `.flow-horizontal::before { background: rgba(247,244,238,0.15); }`.
1404
- <!-- @component:flow-horizontal:end -->
1405
-
1406
- <!-- @component:flow-vertical:start -->
1407
- #### Flow Vertical
1537
+ - **Horizontal rule connector.** The `::before` pseudo-element on `.steps--horizontal` draws a full-width line at `top: 17px`. `.step-number` sits above it via `z-index: 1` and `background: var(--bg-page)`, creating the effect of the line threading through the numbers. On dark backgrounds, override `background` on `.step-number` to match the slide background color, and set `.steps--horizontal::before { background: rgba(247,244,238,0.15); }`.
1538
+ #### Vertical Variant
1408
1539
 
1409
1540
  Vertical step or timeline sequence. Use for chronological phases, execution stages, or progress narratives that should be read top to bottom. Suitable for 2–6 items.
1410
1541
 
1411
1542
  ```html
1412
- <div class="flow-vertical">
1413
- <div class="flow-item">
1414
- <div class="flow-marker">
1415
- <div class="flow-number">01</div>
1416
- <div class="flow-line"></div>
1543
+ <div class="steps steps--vertical">
1544
+ <div class="step-item">
1545
+ <div class="step-marker">
1546
+ <div class="step-number">01</div>
1547
+ <div class="step-line"></div>
1417
1548
  </div>
1418
- <div class="flow-body">
1549
+ <div class="step-body">
1419
1550
  <h4>Phase Title</h4>
1420
1551
  <p>Description of this stage or milestone.</p>
1421
1552
  </div>
1422
1553
  </div>
1423
- <div class="flow-item">
1424
- <div class="flow-marker">
1425
- <div class="flow-number">02</div>
1426
- <div class="flow-line"></div>
1554
+ <div class="step-item">
1555
+ <div class="step-marker">
1556
+ <div class="step-number">02</div>
1557
+ <div class="step-line"></div>
1427
1558
  </div>
1428
- <div class="flow-body">
1559
+ <div class="step-body">
1429
1560
  <h4>Phase Title</h4>
1430
1561
  <p>Description of this stage or milestone.</p>
1431
1562
  </div>
1432
1563
  </div>
1433
- <div class="flow-item last">
1434
- <div class="flow-marker">
1435
- <div class="flow-number">03</div>
1436
- <!-- no flow-line on last item -->
1564
+ <div class="step-item last">
1565
+ <div class="step-marker">
1566
+ <div class="step-number">03</div>
1567
+ <!-- no step-line on last item -->
1437
1568
  </div>
1438
- <div class="flow-body">
1569
+ <div class="step-body">
1439
1570
  <h4>Phase Title</h4>
1440
1571
  <p>Description of this stage or milestone.</p>
1441
1572
  </div>
@@ -1450,6 +1581,15 @@ Vertical step or timeline sequence. Use for chronological phases, execution stag
1450
1581
  width: 100%;
1451
1582
  }
1452
1583
 
1584
+ .steps--vertical { display: flex; flex-direction: column; width: 100%; }
1585
+ .steps--vertical .step-item { display: flex; gap: 28px; align-items: flex-start; }
1586
+ .step-marker { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
1587
+ .step-line { width: 1px; flex: 1; min-height: 28px; background: var(--line-strong); margin: 6px 0; }
1588
+ .steps--vertical .step-body { padding-bottom: 32px; }
1589
+ .steps--vertical .step-item.last .step-body { padding-bottom: 0; }
1590
+ .steps--vertical .step-body h4 { margin-top: 4px; }
1591
+ .steps--vertical .step-body p { margin-top: 8px; }
1592
+
1453
1593
  .flow-vertical .flow-item {
1454
1594
  display: flex;
1455
1595
  gap: 28px;
@@ -1489,18 +1629,18 @@ Vertical step or timeline sequence. Use for chronological phases, execution stag
1489
1629
  ```
1490
1630
 
1491
1631
  Rules:
1492
- - Add class `last` to the final `.flow-item` and omit the `.flow-line` div inside it.
1632
+ - Add class `last` to the final `.step-item` and omit the `.step-line` div inside it.
1493
1633
  - The connecting line grows to fill the vertical space between items via `flex: 1`.
1494
- - Number boxes share the same border-only square style as `flow-horizontal` for visual consistency.
1634
+ - Number boxes share the same border-only square style as the horizontal variant for visual consistency.
1495
1635
  - Copy per item can be slightly longer than horizontal flow since vertical reading allows more density.
1496
1636
  - Combine with `text-panel` or `echart-panel` on the opposing side of a layout when needed.
1497
1637
 
1498
1638
  ##### Tips
1499
- - **`.last` class on final item is mandatory.** Without it, the connecting line extends past the last item and exits the component boundary. Always add `.last` to the final `div.flow-item`.
1500
- - **Dark background with background image.** When the column containing `flow-vertical` has a background image, use the same three-layer z-index pattern: background `z-index:0`, dark scrim `z-index:1`, component content `z-index:2`. Set the parent column to `position:relative;overflow:hidden`.
1501
- - **Dark text overrides (same as flow-horizontal).** Flow-number border `rgba(247,244,238,0.3)`, color `rgba(247,244,238,0.6)`; h4 `#f7f4ee`; p `rgba(247,244,238,0.7)`. Also override the connecting line color: `background:rgba(247,244,238,0.2)`.
1502
- - **Column height constraint.** `flow-vertical` expands naturally with content. In a two-column layout, ensure the opposing column (`text-panel` or `echart-panel`) has enough content to avoid a large height mismatch.
1503
- <!-- @component:flow-vertical:end -->
1639
+ - **`.last` class on final item is mandatory.** Without it, the connecting line extends past the last item and exits the component boundary. Always add `.last` to the final `div.step-item`.
1640
+ - **Dark background with background image.** When the column containing `steps` has a background image, use the same three-layer z-index pattern: background `z-index:0`, dark scrim `z-index:1`, component content `z-index:2`. Set the parent column to `position:relative;overflow:hidden`.
1641
+ - **Dark text overrides.** Step-number border `rgba(247,244,238,0.3)`, color `rgba(247,244,238,0.6)`; h4 `#f7f4ee`; p `rgba(247,244,238,0.7)`. Also override the connecting line color: `background:rgba(247,244,238,0.2)`.
1642
+ - **Column height constraint.** Vertical steps expand naturally with content. In a two-column layout, ensure the opposing column (`text-panel` or `echart-panel`) has enough content to avoid a large height mismatch.
1643
+ <!-- @component:steps:end -->
1504
1644
 
1505
1645
  <!-- @component:data-table:start -->
1506
1646
  #### Data Table
@@ -1551,7 +1691,7 @@ Annual-report format data table. Use for year-on-year comparisons, emissions dat
1551
1691
  </tr>
1552
1692
  </tbody>
1553
1693
  </table>
1554
- <p class="table-caption">Thousands of tonnes CO₂e · Source: Company Disclosures 2024</p>
1694
+ <p class="table-caption source-note">Thousands of tonnes CO₂e · Source: Company Disclosures 2024</p>
1555
1695
  </div>
1556
1696
  ```
1557
1697
 
@@ -1661,10 +1801,6 @@ Annual-report format data table. Use for year-on-year comparisons, emissions dat
1661
1801
 
1662
1802
  .table-caption {
1663
1803
  margin-top: 12px;
1664
- font-size: var(--font-size-meta);
1665
- letter-spacing: 0.1em;
1666
- text-transform: uppercase;
1667
- color: var(--text-muted);
1668
1804
  }
1669
1805
  ```
1670
1806
 
@@ -1677,7 +1813,7 @@ Rules:
1677
1813
  - Use `.col-highlight` on both `th` and `td` in a column to spotlight the current or most important period.
1678
1814
  - `.delta.positive` and `.delta.negative` use Summit accent colours, not generic green/red. `.delta.neutral` for flat movement.
1679
1815
  - Use `data-table-label` as a heading above the table when multiple tables are stacked.
1680
- - Include `.table-caption` below with the data source and unit.
1816
+ - Include `.table-caption.source-note` below with the data source and unit.
1681
1817
 
1682
1818
  ##### Tips
1683
1819
  - **Dense tables.** Keep the table on the foundation text scale when possible. If the dataset is too large, simplify the table, split it into multiple tables, or reduce the number of columns before introducing a smaller local text size.
@@ -1694,18 +1830,18 @@ Rules:
1694
1830
 
1695
1831
 
1696
1832
 
1697
- <!-- @component:image-title:start -->
1698
- #### Image Title
1833
+ <!-- @component:hero:start -->
1834
+ #### Hero
1699
1835
 
1700
- Self-contained full-canvas component: a dominant photograph with a directional blur layer, a gradient overlay, and a foreground text stack — all composited inside one element. Use for cover slides, closing slides, atmospheric section dividers, or any full-bleed spread where a single image should dominate the entire canvas.
1836
+ Self-contained full-canvas component: a dominant photograph with a directional blur layer, a gradient overlay, and a foreground text stack — all composited inside one element. Use for cover slides, closing slides, atmospheric section dividers, or any full-bleed spread where a single image should dominate the entire canvas. Never use `hero` inside a `box`. Never use it for screenshots, charts, tables, diagrams, or source evidence that must stay fully readable.
1701
1837
 
1702
1838
  The LLM controls three key variables via inline style or modifier class:
1703
- - **Alignment**: `image-title--left` (cover default), `image-title--right` (closing default), `image-title--center`
1839
+ - **Alignment**: `hero--left`/`image-title--left` (cover default), `hero--right`/`image-title--right` (closing default), `hero--center`/`image-title--center`
1704
1840
  - **Overlay opacity / direction**: set the `background` gradient on `.image-title-overlay` inline
1705
- - **Text opacity**: set `opacity` on `.image-title` itself (range `0.7`–`1.0`; default `1.0`)
1841
+ - **Text opacity**: set `opacity` on `.hero` itself (range `0.7`–`1.0`; default `1.0`)
1706
1842
 
1707
1843
  ```html
1708
- <div class="image-title image-title--left">
1844
+ <div class="hero hero--left image-title image-title--left">
1709
1845
 
1710
1846
  <!-- Layer 0: background image -->
1711
1847
  <img class="image-title-media" src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1920&auto=format&fit=crop" alt="Alpine ridge at dawn">
@@ -1749,6 +1885,14 @@ The LLM controls three key variables via inline style or modifier class:
1749
1885
  color: #f7f4ee;
1750
1886
  }
1751
1887
 
1888
+ .hero {
1889
+ position: relative;
1890
+ width: 100%;
1891
+ height: 100%;
1892
+ overflow: hidden;
1893
+ color: #f7f4ee;
1894
+ }
1895
+
1752
1896
  /* Layer 0: background image */
1753
1897
  .image-title-media {
1754
1898
  position: absolute;
@@ -1792,21 +1936,27 @@ The LLM controls three key variables via inline style or modifier class:
1792
1936
  max-width: 680px;
1793
1937
  }
1794
1938
 
1939
+ .hero--left .image-title-body { max-width: 680px; }
1940
+
1795
1941
  .image-title--right .image-title-fg {
1796
1942
  text-align: right;
1797
1943
  }
1944
+ .hero--right .image-title-fg { text-align: right; }
1798
1945
  .image-title--right .image-title-body {
1799
1946
  max-width: 860px;
1800
1947
  margin-left: auto;
1801
1948
  }
1949
+ .hero--right .image-title-body { max-width: 860px; margin-left: auto; }
1802
1950
 
1803
1951
  .image-title--center .image-title-fg {
1804
1952
  text-align: center;
1805
1953
  align-items: center;
1806
1954
  }
1955
+ .hero--center .image-title-fg { text-align: center; align-items: center; }
1807
1956
  .image-title--center .image-title-body {
1808
1957
  max-width: 900px;
1809
1958
  }
1959
+ .hero--center .image-title-body { max-width: 900px; }
1810
1960
 
1811
1961
  /* Text elements */
1812
1962
  .image-title-eyebrow {
@@ -1823,7 +1973,6 @@ The LLM controls three key variables via inline style or modifier class:
1823
1973
  font-size: 96px;
1824
1974
  line-height: 0.92;
1825
1975
  letter-spacing: -0.03em;
1826
- text-transform: uppercase;
1827
1976
  }
1828
1977
 
1829
1978
  .image-title-subtitle {
@@ -1843,7 +1992,7 @@ The LLM controls three key variables via inline style or modifier class:
1843
1992
  ```
1844
1993
 
1845
1994
  Rules:
1846
- - Always use one of the three modifier classes: `image-title--left`, `image-title--right`, or `image-title--center`. Never omit the modifier.
1995
+ - Always use one of the three hero modifier classes: `hero--left`, `hero--right`, or `hero--center`. Keep legacy `image-title--*` classes only for compatibility when reusing the built-in CSS.
1847
1996
  - Set the `background` gradient on `.image-title-overlay` inline — never use a static class value. The direction and opacity must match the text position: dense dark on the text side, fading toward the open image side.
1848
1997
  - The blur mask direction must mirror the text alignment: `--left` uses `to left`, `--right` uses `to right`. Both `-webkit-mask-image` and `mask-image` are required for cross-browser support.
1849
1998
  - All text inside `.image-title-fg` must be white-family: headings `#f7f4ee`, body `rgba(247,244,238,0.72)`, captions and eyebrows `rgba(247,244,238,0.50–0.55)`.
@@ -1858,7 +2007,7 @@ Rules:
1858
2007
  - **`--right` closing variant.** Mirror the blur mask: use `mask-image:linear-gradient(to right, transparent 0%, transparent 20%, black 100%)`. The right side stays blurred (text zone); the left side of the image stays sharp.
1859
2008
  - **`--center` variant.** Use a radial or symmetric overlay: `radial-gradient(ellipse at center, rgba(5,5,5,0.72) 0%, rgba(5,5,5,0.20) 100%)` or a flat `rgba(5,5,5,0.55)`. Center blur mask: `mask-image:radial-gradient(ellipse at center, black 0%, transparent 80%)`.
1860
2009
  - **Subtitle width on `--right`.** `.image-title-subtitle` inherits `max-width:480px` which is set for left-aligned text. On `--right`, override to match the `.image-title-body` width: `style="max-width:520px;margin-left:auto;"`.
1861
- <!-- @component:image-title:end -->
2010
+ <!-- @component:hero:end -->
1862
2011
 
1863
2012
  <!-- @component:toc:start -->
1864
2013
  #### TOC Panel
@@ -1870,15 +2019,15 @@ Narrow editorial panel for table-of-contents slides. A 3px accent-gold vertical
1870
2019
  <div style="width:3px;background:var(--accent-gold);flex:0 0 3px;"></div>
1871
2020
  <div style="padding-left:22px;display:flex;flex-direction:column;justify-content:space-between;flex:1;">
1872
2021
  <div>
1873
- <h2 style="font-size:34px;line-height:0.94;letter-spacing:-0.03em;text-transform:uppercase;max-width:220px;">Table of Contents</h2>
1874
- <p style="margin-top:18px;letter-spacing:0.04em;color:var(--text-secondary);max-width:255px;">Short introductory note describing the scope of the sections that follow.</p>
1875
- <ol style="list-style:none;display:flex;flex-direction:column;gap:10px;margin-top:26px;">
1876
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">01</span><span>Chapter title or section theme</span></li>
1877
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">02</span><span>Chapter title or section theme</span></li>
1878
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">03</span><span>Chapter title or section theme</span></li>
1879
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">04</span><span>Chapter title or section theme</span></li>
1880
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid var(--line);padding-bottom:8px;"><span style="font-weight:700;">05</span><span>Chapter title or section theme</span></li>
1881
- <li style="display:grid;grid-template-columns:26px 1fr;gap:12px;align-items:center;line-height:1.45;text-transform:uppercase;letter-spacing:0.06em;"><span style="font-weight:700;">06</span><span>Chapter title or section theme</span></li>
2022
+ <h2 style="font-size:28px;line-height:1.04;letter-spacing:-0.02em;max-width:220px;">Table of Contents</h2>
2023
+ <p style="margin-top:14px;font-size:15px;line-height:1.45;color:var(--text-secondary);max-width:255px;">Short introductory note describing the scope of the sections that follow.</p>
2024
+ <ol style="list-style:none;display:flex;flex-direction:column;gap:7px;margin-top:20px;">
2025
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">01</span><span>Chapter Title or Section Theme</span></li>
2026
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">02</span><span>Chapter Title or Section Theme</span></li>
2027
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">03</span><span>Chapter Title or Section Theme</span></li>
2028
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">04</span><span>Chapter Title or Section Theme</span></li>
2029
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;border-bottom:1px solid var(--line);padding-bottom:6px;"><span style="font-weight:700;">05</span><span>Chapter Title or Section Theme</span></li>
2030
+ <li style="display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center;font-size:14px;line-height:1.35;letter-spacing:0.01em;"><span style="font-weight:700;">06</span><span>Chapter Title or Section Theme</span></li>
1882
2031
  </ol>
1883
2032
  </div>
1884
2033
  <div style="display:flex;flex-direction:column;gap:14px;">
@@ -1897,15 +2046,16 @@ Narrow editorial panel for table-of-contents slides. A 3px accent-gold vertical
1897
2046
 
1898
2047
  ```css
1899
2048
  .toc-panel {
1900
- background: var(--bg-page);
2049
+ background: transparent;
1901
2050
  height: 100%;
1902
- padding: 42px 38px 30px;
2051
+ padding: 38px 34px 28px;
1903
2052
  display: flex;
1904
2053
  }
1905
2054
  ```
1906
2055
 
1907
2056
  ##### Tips
1908
2057
  - **Chapter numbers must be `font-weight:700`.** Without bold, the numbers dissolve visually into the lighter chapter title text.
2058
+ - **Keep TOC compact.** Use a smaller title and 14px chapter items so the agenda reads as a navigation panel, not a main content slide.
1909
2059
  - **Last `li` has no `border-bottom`.** Every item except the last carries `border-bottom:1px solid var(--line)`. Remove it from the final entry to avoid a floating rule at the bottom of the list.
1910
2060
  - **accent-gold vertical rule.** The 3px left rule uses `var(--accent-gold)`. Do not substitute another color — it is the primary editorial accent in Summit.
1911
2061
  - **`justify-content:space-between` requires a defined height on the parent.** The panel must sit inside a container with a known height (grid cell, absolute position, or `height:100%` chain) or the footer will not pin to the bottom.
@@ -2100,13 +2250,13 @@ Omit `--light` only on slides with a white/light background.
2100
2250
 
2101
2251
  <!-- @component:page-number:end -->
2102
2252
 
2103
- <!-- @component:timeline-journey-horizontal:start -->
2104
- #### Timeline Journey Horizontal
2253
+ <!-- @component:roadmap-horizontal:start -->
2254
+ #### Roadmap Horizontal
2105
2255
 
2106
2256
  A horizontal milestone timeline with a central axis line. Nodes sit on the axis; a dashed vertical stem leads to a tip node, with date, title, and description text alongside. Alternate nodes above and below the axis for rhythm. Suitable for 4–8 milestones across a chronological arc, transformation story, or multi-year programme recap.
2107
2257
 
2108
2258
  ```html
2109
- <div class="tjh">
2259
+ <div class="roadmap-horizontal tjh" data-preview-component="roadmap-horizontal">
2110
2260
  <div class="tjh-axis"></div>
2111
2261
 
2112
2262
  <!-- UP node: item bottom edge sits on axis, content grows upward.
@@ -2150,6 +2300,8 @@ A horizontal milestone timeline with a central axis line. Nodes sit on the axis;
2150
2300
  height: 360px;
2151
2301
  }
2152
2302
 
2303
+ .roadmap-horizontal { position: relative; width: 100%; height: 360px; }
2304
+
2153
2305
  /* Axis line */
2154
2306
  .tjh-axis {
2155
2307
  position: absolute;
@@ -2260,17 +2412,17 @@ Rules:
2260
2412
  - **Adjust stem length**: Change `--tjh-stem-h` to lengthen or shorten the dashed connector.
2261
2413
  - **Dark background overrides**: Set `--line-strong: rgba(247,244,238,0.25)` on `.tjh`, override `.tjh-axis { background }`, set `.tjh-title { color: #f7f4ee }`, `.tjh-text { color: rgba(247,244,238,0.7) }`. The `--tjh-item-color` accent colours work on dark backgrounds without change.
2262
2414
  - **Fewer nodes**: For 4–5 nodes, widen `--tjh-col` by using a smaller denominator (e.g. `calc(100% / 5)`), and space `left` values accordingly.
2263
- <!-- @component:timeline-journey-horizontal:end -->
2415
+ <!-- @component:roadmap-horizontal:end -->
2264
2416
 
2265
- <!-- @component:timeline-journey-vertical:start -->
2266
- #### Timeline Journey Vertical
2417
+ <!-- @component:roadmap-vertical:start -->
2418
+ #### Roadmap Vertical
2267
2419
 
2268
2420
  A vertical milestone timeline with a central axis line. Nodes sit on the axis; a horizontal dashed stem leads to a tip dot, with date, title, and description text alongside. Alternate nodes left and right of the axis for rhythm. Suitable for 3–8 milestones across a chronological arc, transformation story, or multi-year programme recap.
2269
2421
 
2270
2422
  Can be placed inside any layout slot that provides a defined height (`narrative`, `halves`, `highlight-cols`, `stacked`, or a full-page content zone). The component fills `width: 100%; height: 100%` of its parent.
2271
2423
 
2272
2424
  ```html
2273
- <div class="tjv">
2425
+ <div class="roadmap-vertical tjv" data-preview-component="roadmap-vertical">
2274
2426
  <div class="tjv-axis"></div>
2275
2427
 
2276
2428
  <!-- LEFT node: DOM order axis-dot → stem → tip-dot → label.
@@ -2315,6 +2467,8 @@ Can be placed inside any layout slot that provides a defined height (`narrative`
2315
2467
  height: 100%;
2316
2468
  }
2317
2469
 
2470
+ .roadmap-vertical { position: relative; width: 100%; height: 100%; }
2471
+
2318
2472
  /* Vertical axis — horizontally centered, full height */
2319
2473
  .tjv-axis {
2320
2474
  position: absolute;
@@ -2457,6 +2611,6 @@ Rules:
2457
2611
  - **Dark background overrides**: set on the `.tjv` wrapper — `--line-strong: rgba(247,244,238,0.25)` (axis + stem), `.tjv-title { color: #f7f4ee }`, `.tjv-text { color: rgba(247,244,238,0.7) }`. The `--tjv-item-color` accent colours work on dark backgrounds without change.
2458
2612
  - **Fewer nodes (3–4)**: increase spacing — use `top` values like `15%, 35%, 55%, 75%` to prevent the timeline from clustering at the top.
2459
2613
  - **More nodes (6–8)**: keep `.tjv-text` to 1–2 lines and increase vertical spacing before shrinking the text scale.
2460
- <!-- @component:timeline-journey-vertical:end -->
2614
+ <!-- @component:roadmap-vertical:end -->
2461
2615
 
2462
2616
  <!-- @design:components:end -->