@openpresentation/cli 0.8.1 → 0.9.0

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.
package/dist/index.js CHANGED
@@ -8149,13 +8149,13 @@ import path2 from "path";
8149
8149
  // ../javascript/dist/index.js
8150
8150
  init_define_OPF_SKILLS();
8151
8151
 
8152
- // ../javascript/dist/chunk-EWJNRHXA.js
8152
+ // ../javascript/dist/chunk-EQHZ3ZO4.js
8153
8153
  init_define_OPF_SKILLS();
8154
8154
 
8155
- // ../javascript/dist/chunk-ZIL7MGZU.js
8155
+ // ../javascript/dist/chunk-CHKJ4QHQ.js
8156
8156
  init_define_OPF_SKILLS();
8157
8157
 
8158
- // ../javascript/dist/chunk-PQJRDNA6.js
8158
+ // ../javascript/dist/chunk-FTWNWFIV.js
8159
8159
  init_define_OPF_SKILLS();
8160
8160
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
8161
8161
  function tableGrid(value, path3 = "table") {
@@ -9540,13 +9540,13 @@ function resolveCanvasDimensions(input) {
9540
9540
  return { width, height };
9541
9541
  }
9542
9542
 
9543
- // ../javascript/dist/chunk-D3GQIREP.js
9543
+ // ../javascript/dist/chunk-GN52EE3P.js
9544
9544
  init_define_OPF_SKILLS();
9545
9545
  var presentation = {
9546
9546
  "$schema": "https://json-schema.org/draft/2020-12/schema",
9547
9547
  "$id": "https://openpresentation.org/schema/opf/v1",
9548
9548
  "title": "Presentation",
9549
- "description": "Open-source JSON format for describing PowerPoint presentations. Agents describe narratives, content, audience, reusable assets, and design \u2014 the engine handles OOXML complexity.\n\nFields that reference catalog records (narrative, language, tone, audience, purpose, design.theme / design.theme.id, design.colorScheme / design.colorScheme.id, design.fontScheme / design.fontScheme.id, Slide.layout, Chart.type, Organization.socials / Speaker.socials) resolve through the catalog system: inline 'catalogs.<kind>.records[]' on the document \u2192 'catalogs.<kind>.source' on the document \u2192 engine defaults \u2192 the default catalog at https://www.pptx.gallery/<kind>. Every reference resolves to the catalog record's 'id' field. When an OPF document omits a reference entirely, the engine falls back to engine defaults (see /spec/reference/engine-defaults.json for a reference example). The defaults file is engine configuration; it is not part of the OPF document contract and has no JSON Schema.\n\nMost catalog references accept the bare 'id' as a string for the common case (e.g. narrative = 'classic-story', design.colorScheme = 'cool-horizon'). Audience, purpose, tone, design, and language object forms use 'id' as a base catalog reference plus inline overrides. Asset references use 'asset:<id>' strings that point into the top-level assets registry.",
9549
+ "description": "Open-source JSON format for describing PowerPoint presentations. Agents describe narratives, content, audience, reusable assets, and design \u2014 the engine handles OOXML complexity.\n\nFields that reference catalog records (narrative, language, tone, audience, purpose, design.theme / design.theme.id, design.colorScheme / design.colorScheme.id, design.fontScheme / design.fontScheme.id, Slide.layout, Chart.type, Organization.socials / Speaker.socials) resolve through the catalog system: inline 'catalogs.<kind>.records[]' on the document \u2192 'catalogs.<kind>.source' on the document \u2192 engine defaults \u2192 the default catalog at https://www.pptx.gallery/<kind>. Every reference resolves to the catalog record's 'id' field. When an OPF document omits a reference entirely, the engine falls back to engine defaults (see /spec/reference/engine-defaults.json for a reference example). The defaults file is engine configuration; it is not part of the OPF document contract and has no JSON Schema.\n\nMost catalog references accept the bare 'id' as a string for the common case (e.g. narrative = 'classic-story', design.colorScheme = 'cool-horizon'). Audience, purpose, tone, design, and language object forms use 'id' as a base catalog reference plus inline overrides. Asset references use 'asset:<id>' strings that point into the top-level assets registry, and content color fields (rich-text runs, styled table cells) accept hex values, color-scheme slot/role names, or 'var:<id>' references into the top-level variables map.",
9550
9550
  "type": "object",
9551
9551
  "required": [
9552
9552
  "slides"
@@ -9827,6 +9827,10 @@ var presentation = {
9827
9827
  "$ref": "#/$defs/Design",
9828
9828
  "description": "Optional design system covering theme, color scheme, font scheme, dimensions, background, logo, watermark, header, and footer applied to the deck. When omitted, engines use their default design configuration."
9829
9829
  },
9830
+ "variables": {
9831
+ "$ref": "#/$defs/Variables",
9832
+ "description": "Optional named color variables for values the deck uses in more than one place or wants to name for intent (e.g. a risk red, a brand highlight). Content color fields reference entries as 'var:<id>' strings. Variables complement the color scheme: scheme slots and roles stay the primary vocabulary; variables cover deck-specific named colors that have no scheme slot."
9833
+ },
9830
9834
  "narrative": {
9831
9835
  "oneOf": [
9832
9836
  {
@@ -11525,6 +11529,109 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
11525
11529
  "#0F172AFF"
11526
11530
  ]
11527
11531
  },
11532
+ "ColorRef": {
11533
+ "anyOf": [
11534
+ {
11535
+ "$ref": "#/$defs/HexColor"
11536
+ },
11537
+ {
11538
+ "type": "string",
11539
+ "enum": [
11540
+ "accent1",
11541
+ "accent2",
11542
+ "accent3",
11543
+ "accent4",
11544
+ "accent5",
11545
+ "accent6",
11546
+ "dark1",
11547
+ "dark2",
11548
+ "light1",
11549
+ "light2",
11550
+ "hyperlink",
11551
+ "followedHyperlink",
11552
+ "primary",
11553
+ "secondary",
11554
+ "accent",
11555
+ "background",
11556
+ "surface",
11557
+ "text",
11558
+ "textSecondary"
11559
+ ]
11560
+ },
11561
+ {
11562
+ "type": "string",
11563
+ "pattern": "^var:[a-z][a-z0-9-]*$"
11564
+ }
11565
+ ],
11566
+ "description": "A color value or reference, enforced on styled table cell fill and text colors and on cell border colors. Three forms:\n- Literal hex: '#RGB', '#RRGGBB', or '#RRGGBBAA'.\n- Color-scheme name, resolved through the effective color scheme after design resolution: an OOXML slot ('accent1'-'accent6', 'dark1', 'dark2', 'light1', 'light2', 'hyperlink', 'followedHyperlink') or an abstract role ('primary', 'secondary', 'accent', 'background', 'surface', 'text', 'textSecondary'). Roles resolve through the same role-to-slot mapping engines already apply to color schemes.\n- Variable reference: 'var:<id>' into the top-level variables map.\n\nNames keep content theme-portable: re-theming the deck updates every named reference, where a literal hex stays frozen. Unknown 'var:' ids produce a validation warning, never an error, and engines fall back to their default text color. TextRun.color documents the same three forms but remains an open string so imported decks with unrecognized run colors stay valid; validators warn there instead of erroring.",
11567
+ "examples": [
11568
+ "#0F4C81",
11569
+ "accent2",
11570
+ "text",
11571
+ "var:risk"
11572
+ ]
11573
+ },
11574
+ "Variables": {
11575
+ "type": "object",
11576
+ "propertyNames": {
11577
+ "pattern": "^[a-z][a-z0-9-]*$"
11578
+ },
11579
+ "additionalProperties": {
11580
+ "$ref": "#/$defs/Variable"
11581
+ },
11582
+ "description": "Named color variables, keyed by stable kebab-case id. Content color fields reference entries as 'var:<id>' strings. Each value is a hex string shorthand or a Variable object.",
11583
+ "examples": [
11584
+ {
11585
+ "risk": "#B42318",
11586
+ "highlight": {
11587
+ "type": "color",
11588
+ "value": "#0F4C81",
11589
+ "description": "Brand highlight for emphasized runs."
11590
+ }
11591
+ }
11592
+ ]
11593
+ },
11594
+ "Variable": {
11595
+ "oneOf": [
11596
+ {
11597
+ "$ref": "#/$defs/HexColor"
11598
+ },
11599
+ {
11600
+ "type": "object",
11601
+ "required": [
11602
+ "type",
11603
+ "value"
11604
+ ],
11605
+ "additionalProperties": false,
11606
+ "properties": {
11607
+ "type": {
11608
+ "type": "string",
11609
+ "enum": [
11610
+ "color"
11611
+ ],
11612
+ "description": "Variable kind. Only 'color' is defined today; other kinds may be added when content surfaces exist to consume them."
11613
+ },
11614
+ "value": {
11615
+ "$ref": "#/$defs/HexColor",
11616
+ "description": "Hex color this variable resolves to."
11617
+ },
11618
+ "description": {
11619
+ "type": "string",
11620
+ "description": "Optional prose describing what the variable is for, surfaced by pickers and agents."
11621
+ }
11622
+ }
11623
+ }
11624
+ ],
11625
+ "description": 'A single named variable. A hex string is shorthand for { "type": "color", "value": value }.',
11626
+ "examples": [
11627
+ "#B42318",
11628
+ {
11629
+ "type": "color",
11630
+ "value": "#B42318",
11631
+ "description": "Risk emphasis."
11632
+ }
11633
+ ]
11634
+ },
11528
11635
  "BackgroundShortcut": {
11529
11636
  "oneOf": [
11530
11637
  {
@@ -12256,6 +12363,10 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
12256
12363
  },
12257
12364
  "composition": {
12258
12365
  "$ref": "#/$defs/Composition"
12366
+ },
12367
+ "extensions": {
12368
+ "type": "object",
12369
+ "description": 'Custom data passthrough for agent workflows at slide scope; ignored by the engine but preserved across read/write round-trips. Use for review state, generation provenance, or authoring conventions such as { "authoring": { "locked": true } }.'
12259
12370
  }
12260
12371
  }
12261
12372
  },
@@ -12264,6 +12375,18 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
12264
12375
  "description": "A content leaf or recursively composed group. A group contains blocks and optional composition; it cannot mix blocks with leaf payload fields. Groups may nest up to 32 levels.",
12265
12376
  "additionalProperties": false,
12266
12377
  "properties": {
12378
+ "id": {
12379
+ "type": "string",
12380
+ "description": "Optional stable identifier for this payload, unique among slide and payload ids in the document. Use when another system needs to address the payload across edits \u2014 patch-style agent edits, comments, review state, or generation provenance. Identity survives reordering where array indexes do not.",
12381
+ "examples": [
12382
+ "kpi-adoption",
12383
+ "churn-quote"
12384
+ ]
12385
+ },
12386
+ "extensions": {
12387
+ "type": "object",
12388
+ "description": "Custom data passthrough for agent workflows at payload scope; ignored by the engine but preserved across read/write round-trips."
12389
+ },
12267
12390
  "type": {
12268
12391
  "type": "string",
12269
12392
  "enum": [
@@ -13130,10 +13253,11 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
13130
13253
  },
13131
13254
  "color": {
13132
13255
  "type": "string",
13133
- "description": "Run text color as a hex string.",
13256
+ "description": "Run text color. Documented forms: a hex string ('#RGB', '#RRGGBB', '#RRGGBBAA'), a color-scheme slot or role name resolved through the effective color scheme ('accent2', 'text'), or a 'var:<id>' reference into the top-level variables map. Prefer names over hex so runs survive re-theming. Any other string stays schema-valid so imported decks keep validating: validators warn and renderers fall back to the theme text color.",
13134
13257
  "examples": [
13135
13258
  "#0F172A",
13136
- "#1E40AF"
13259
+ "accent2",
13260
+ "var:risk"
13137
13261
  ]
13138
13262
  },
13139
13263
  "fontSize": {
@@ -13476,14 +13600,12 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
13476
13600
  "additionalProperties": false,
13477
13601
  "properties": {
13478
13602
  "fill": {
13479
- "type": "string",
13480
- "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
13481
- "description": "Explicit RGB or RGBA color. Eight-digit colors include alpha; #00000000 is transparent."
13603
+ "$ref": "#/$defs/ColorRef",
13604
+ "description": "Cell background: a hex color, a color-scheme slot or role name, or a 'var:<id>' variable reference. Eight-digit hex colors include alpha; #00000000 is transparent."
13482
13605
  },
13483
13606
  "color": {
13484
- "type": "string",
13485
- "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
13486
- "description": "Default text color, overridden by individual rich run colors."
13607
+ "$ref": "#/$defs/ColorRef",
13608
+ "description": "Default text color, overridden by individual rich run colors. Accepts a hex color, a color-scheme slot or role name, or a 'var:<id>' variable reference."
13487
13609
  },
13488
13610
  "align": {
13489
13611
  "type": "string",
@@ -13564,9 +13686,8 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
13564
13686
  ],
13565
13687
  "properties": {
13566
13688
  "color": {
13567
- "type": "string",
13568
- "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
13569
- "description": "Explicit RGB or RGBA color. Eight-digit colors include alpha; #00000000 is transparent."
13689
+ "$ref": "#/$defs/ColorRef",
13690
+ "description": "Border color: a hex color, a color-scheme slot or role name, or a 'var:<id>' variable reference. Eight-digit hex colors include alpha; #00000000 is transparent."
13570
13691
  },
13571
13692
  "width": {
13572
13693
  "type": "number",
@@ -16225,7 +16346,7 @@ var schemaEntries = [
16225
16346
  { name: "fontScheme", file: "schemas/font-scheme.schema.json", schema: fontScheme }
16226
16347
  ];
16227
16348
 
16228
- // ../javascript/dist/chunk-TU7I3KSB.js
16349
+ // ../javascript/dist/chunk-6FU2KICU.js
16229
16350
  init_define_OPF_SKILLS();
16230
16351
  var audiences = [
16231
16352
  {
@@ -25440,7 +25561,7 @@ var narratives = [
25440
25561
  "id": "hook",
25441
25562
  "name": "Hook",
25442
25563
  "description": "Open with a striking question, statistic, customer quote, or moment that earns the audience's attention. The goal is to make them want to hear what comes next, not to convey information.",
25443
- "layoutHint": "title-center"
25564
+ "layoutHint": "title"
25444
25565
  },
25445
25566
  {
25446
25567
  "id": "problem",
@@ -25471,7 +25592,7 @@ var narratives = [
25471
25592
  "id": "ask",
25472
25593
  "name": "The Ask",
25473
25594
  "description": "State a clear, specific call to action. What do you want the audience to do, decide, or commit to next? Make the smallest credible ask that moves things forward, and make it unambiguous.",
25474
- "layoutHint": "title-left"
25595
+ "layoutHint": "title"
25475
25596
  }
25476
25597
  ]
25477
25598
  },
@@ -25516,7 +25637,7 @@ var narratives = [
25516
25637
  "id": "answer",
25517
25638
  "name": "Answer",
25518
25639
  "description": "Deliver the recommendation in a single sentence, up front. No arguments yet, no caveats \u2014 just the conclusion the rest of the deck will defend. This is the apex of the Minto pyramid; everything that follows supports it.",
25519
- "layoutHint": "title-left"
25640
+ "layoutHint": "title"
25520
25641
  },
25521
25642
  {
25522
25643
  "id": "key-arguments",
@@ -25587,7 +25708,7 @@ var narratives = [
25587
25708
  "id": "ask",
25588
25709
  "name": "Call to Action",
25589
25710
  "description": "Close with the single decision you want the audience to make. Frame it as the obvious next move given the shift, the stakes, and the new game. Make it small enough to say yes to today and large enough to start a real engagement.",
25590
- "layoutHint": "title-left"
25711
+ "layoutHint": "title"
25591
25712
  }
25592
25713
  ]
25593
25714
  },
@@ -25637,7 +25758,7 @@ var narratives = [
25637
25758
  "id": "invitation",
25638
25759
  "name": "Invitation",
25639
25760
  "description": "Close by inviting the audience to share the belief \u2014 to buy, build, join, or evangelize. The strongest invitations don't argue; they assume alignment and offer a way in.",
25640
- "layoutHint": "title-left"
25761
+ "layoutHint": "title"
25641
25762
  }
25642
25763
  ]
25643
25764
  },
@@ -25691,7 +25812,7 @@ var narratives = [
25691
25812
  "id": "recap",
25692
25813
  "name": "Recap",
25693
25814
  "description": "Restate the promise, the mechanism, and the call to action in a single short slide. Give the audience the line they'll repeat to a colleague and the one image that will stick with them after the lights come up.",
25694
- "layoutHint": "title-left"
25815
+ "layoutHint": "title"
25695
25816
  }
25696
25817
  ]
25697
25818
  },
@@ -25741,7 +25862,7 @@ var narratives = [
25741
25862
  "id": "ask",
25742
25863
  "name": "Ask",
25743
25864
  "description": "Close with the single low-friction action that starts the audience across the bridge. Make it small enough to act on now and meaningful enough to count as commitment.",
25744
- "layoutHint": "title-left"
25865
+ "layoutHint": "title"
25745
25866
  }
25746
25867
  ]
25747
25868
  },
@@ -25771,7 +25892,7 @@ var narratives = [
25771
25892
  "id": "opening",
25772
25893
  "name": "Opening",
25773
25894
  "description": "Open with the company name, logo, and a one-line tagline that doubles as a positioning statement. Set the visual tone for the deck. Keep it confident and uncluttered \u2014 this is the cover.",
25774
- "layoutHint": "title-left"
25895
+ "layoutHint": "title"
25775
25896
  },
25776
25897
  {
25777
25898
  "id": "purpose",
@@ -25842,13 +25963,13 @@ var narratives = [
25842
25963
  "id": "ask",
25843
25964
  "name": "The Ask",
25844
25965
  "description": "State the round size, intended use of funds, and what milestones the capital takes you to. Be specific \u2014 investors should leave knowing exactly what you want and what they get.",
25845
- "layoutHint": "title-left"
25966
+ "layoutHint": "title"
25846
25967
  },
25847
25968
  {
25848
25969
  "id": "closing",
25849
25970
  "name": "Closing",
25850
25971
  "description": "Close on a strong final image: logo, contact info, and the one line you most want the investor to remember. Leave space for the conversation that follows.",
25851
- "layoutHint": "title-left"
25972
+ "layoutHint": "title"
25852
25973
  }
25853
25974
  ]
25854
25975
  },
@@ -25877,7 +25998,7 @@ var narratives = [
25877
25998
  "id": "logo",
25878
25999
  "name": "Logo",
25879
26000
  "description": "Cover slide with the company name, logo, and one-line positioning. Simple, branded, confident.",
25880
- "layoutHint": "title-left",
26001
+ "layoutHint": "title",
25881
26002
  "instructions": "Establish presence",
25882
26003
  "slideType": "text"
25883
26004
  },
@@ -25887,7 +26008,7 @@ var narratives = [
25887
26008
  "description": "Open by naming a large, undeniable shift in the world. Tech, regulatory, behavioral. The shift is the reason this company exists \u2014 investors should feel its weight before they hear about the product.",
25888
26009
  "instructions": "Highlight market transformation",
25889
26010
  "slideType": "text",
25890
- "layoutHint": "text-1x-left"
26011
+ "layoutHint": "text-1x"
25891
26012
  },
25892
26013
  {
25893
26014
  "id": "past-struggle",
@@ -25895,7 +26016,7 @@ var narratives = [
25895
26016
  "description": "Show what the world tried to do about the problem before the shift, and why those approaches fell short. Honest credit to predecessors makes the new game more credible.",
25896
26017
  "instructions": "Emphasize previous challenges",
25897
26018
  "slideType": "text",
25898
- "layoutHint": "text-1x-left"
26019
+ "layoutHint": "text-1x"
25899
26020
  },
25900
26021
  {
25901
26022
  "id": "innovative-breakthrough",
@@ -25903,7 +26024,7 @@ var narratives = [
25903
26024
  "description": "Present the founding insight or breakthrough that makes a new approach possible. This is the 'secret' the company is built on \u2014 name it plainly.",
25904
26025
  "instructions": "Present innovative solution",
25905
26026
  "slideType": "text",
25906
- "layoutHint": "text-1x-left"
26027
+ "layoutHint": "text-1x"
25907
26028
  },
25908
26029
  {
25909
26030
  "id": "unique-offering",
@@ -25911,7 +26032,7 @@ var narratives = [
25911
26032
  "description": "Detail the product or service. Lead with the customer-visible thing they touch; the architecture can wait. Show why this offering is structurally different from the past struggle.",
25912
26033
  "instructions": "Detail product or service",
25913
26034
  "slideType": "text",
25914
- "layoutHint": "text-1x-left"
26035
+ "layoutHint": "text-1x"
25915
26036
  },
25916
26037
  {
25917
26038
  "id": "costly-issues",
@@ -25919,7 +26040,7 @@ var narratives = [
25919
26040
  "description": "Quantify the pain customers experience without your offering. Time, dollars, opportunity cost. Specific numbers convert sympathy into urgency.",
25920
26041
  "instructions": "Quantify problems faced",
25921
26042
  "slideType": "text",
25922
- "layoutHint": "text-1x-left"
26043
+ "layoutHint": "text-1x"
25923
26044
  },
25924
26045
  {
25925
26046
  "id": "effective-solutions",
@@ -25927,7 +26048,7 @@ var narratives = [
25927
26048
  "description": "Demonstrate the customer outcome your offering produces. Before/after numbers from early users, even small N. Early-stage pitches are won by leading indicators, not by trailing ones.",
25928
26049
  "instructions": "Demonstrate benefits",
25929
26050
  "slideType": "text",
25930
- "layoutHint": "text-1x-left"
26051
+ "layoutHint": "text-1x"
25931
26052
  },
25932
26053
  {
25933
26054
  "id": "unit-economics",
@@ -25935,7 +26056,7 @@ var narratives = [
25935
26056
  "description": "Explain the financial model. Cost to acquire, gross margin, payback. Investors don't expect maturity \u2014 they expect that you've thought about it.",
25936
26057
  "instructions": "Explain financial model",
25937
26058
  "slideType": "text",
25938
- "layoutHint": "text-1x-left"
26059
+ "layoutHint": "text-1x"
25939
26060
  },
25940
26061
  {
25941
26062
  "id": "talented-team",
@@ -25943,7 +26064,7 @@ var narratives = [
25943
26064
  "description": "Introduce the founders and key early hires. Show why this team uniquely sees and can execute on this opportunity. Insight beats r\xE9sum\xE9 at the seed stage.",
25944
26065
  "instructions": "Introduce key players",
25945
26066
  "slideType": "text",
25946
- "layoutHint": "text-1x-left"
26067
+ "layoutHint": "text-1x"
25947
26068
  },
25948
26069
  {
25949
26070
  "id": "traction",
@@ -25951,7 +26072,7 @@ var narratives = [
25951
26072
  "description": "Showcase the early signal: pilots, design partners, waitlist, retention data, anything credible. Frame it honestly \u2014 investors at this stage discount inflation aggressively.",
25952
26073
  "instructions": "Showcase accomplishments",
25953
26074
  "slideType": "text",
25954
- "layoutHint": "text-1x-left"
26075
+ "layoutHint": "text-1x"
25955
26076
  },
25956
26077
  {
25957
26078
  "id": "investment-opportunity",
@@ -25959,13 +26080,13 @@ var narratives = [
25959
26080
  "description": "Detail the round size, structure, and use of funds. Tie the raise to specific milestones it takes the company to. Specificity here signals operational maturity.",
25960
26081
  "instructions": "Detail funding needs",
25961
26082
  "slideType": "text",
25962
- "layoutHint": "text-1x-left"
26083
+ "layoutHint": "text-1x"
25963
26084
  },
25964
26085
  {
25965
26086
  "id": "closing-logo",
25966
26087
  "name": "Closing Logo",
25967
26088
  "description": "Close on the brand and contact info. Leave the room with the line you most want repeated when the partner pitches you to the rest of the firm.",
25968
- "layoutHint": "title-left",
26089
+ "layoutHint": "title",
25969
26090
  "instructions": "Leave a lasting impression",
25970
26091
  "slideType": "text"
25971
26092
  }
@@ -25999,84 +26120,84 @@ var narratives = [
25999
26120
  "name": "Opening",
26000
26121
  "instructions": "Establish identity",
26001
26122
  "slideType": "text",
26002
- "layoutHint": "text-1x-left"
26123
+ "layoutHint": "text-1x"
26003
26124
  },
26004
26125
  {
26005
26126
  "id": "purpose",
26006
26127
  "name": "Purpose",
26007
26128
  "instructions": "State your mission",
26008
26129
  "slideType": "text",
26009
- "layoutHint": "text-1x-left"
26130
+ "layoutHint": "text-1x"
26010
26131
  },
26011
26132
  {
26012
26133
  "id": "problem",
26013
26134
  "name": "Problem",
26014
26135
  "instructions": "Present the challenge",
26015
26136
  "slideType": "text",
26016
- "layoutHint": "text-1x-left"
26137
+ "layoutHint": "text-1x"
26017
26138
  },
26018
26139
  {
26019
26140
  "id": "solution",
26020
26141
  "name": "Solution",
26021
26142
  "instructions": "Propose your idea",
26022
26143
  "slideType": "text",
26023
- "layoutHint": "text-1x-left"
26144
+ "layoutHint": "text-1x"
26024
26145
  },
26025
26146
  {
26026
26147
  "id": "why-now",
26027
26148
  "name": "Why Now",
26028
26149
  "instructions": "Explain timing importance",
26029
26150
  "slideType": "text",
26030
- "layoutHint": "text-1x-left"
26151
+ "layoutHint": "text-1x"
26031
26152
  },
26032
26153
  {
26033
26154
  "id": "market-size",
26034
26155
  "name": "Market Size",
26035
26156
  "instructions": "Demonstrate potential",
26036
26157
  "slideType": "text",
26037
- "layoutHint": "text-1x-left"
26158
+ "layoutHint": "text-1x"
26038
26159
  },
26039
26160
  {
26040
26161
  "id": "competition",
26041
26162
  "name": "Competition",
26042
26163
  "instructions": "Analyze competitive landscape",
26043
26164
  "slideType": "text",
26044
- "layoutHint": "text-1x-left"
26165
+ "layoutHint": "text-1x"
26045
26166
  },
26046
26167
  {
26047
26168
  "id": "product",
26048
26169
  "name": "Product",
26049
26170
  "instructions": "Showcase features/benefits",
26050
26171
  "slideType": "text",
26051
- "layoutHint": "text-1x-left"
26172
+ "layoutHint": "text-1x"
26052
26173
  },
26053
26174
  {
26054
26175
  "id": "business-model",
26055
26176
  "name": "Business Model",
26056
26177
  "instructions": "Detail revenue streams",
26057
26178
  "slideType": "text",
26058
- "layoutHint": "text-1x-left"
26179
+ "layoutHint": "text-1x"
26059
26180
  },
26060
26181
  {
26061
26182
  "id": "team",
26062
26183
  "name": "Team",
26063
26184
  "instructions": "Highlight key members",
26064
26185
  "slideType": "text",
26065
- "layoutHint": "text-1x-left"
26186
+ "layoutHint": "text-1x"
26066
26187
  },
26067
26188
  {
26068
26189
  "id": "financials",
26069
26190
  "name": "Financials",
26070
26191
  "instructions": "Show projections/needs",
26071
26192
  "slideType": "text",
26072
- "layoutHint": "text-1x-left"
26193
+ "layoutHint": "text-1x"
26073
26194
  },
26074
26195
  {
26075
26196
  "id": "closing",
26076
26197
  "name": "Closing",
26077
26198
  "instructions": "Reinforce brand",
26078
26199
  "slideType": "text",
26079
- "layoutHint": "text-1x-left"
26200
+ "layoutHint": "text-1x"
26080
26201
  }
26081
26202
  ]
26082
26203
  },
@@ -26107,7 +26228,7 @@ var narratives = [
26107
26228
  "description": "Open with a brief framing of who you are and why this conversation is worth the prospect's next thirty minutes. Keep credentials short; the audience cares about their problem, not your r\xE9sum\xE9.",
26108
26229
  "instructions": "Name & logo",
26109
26230
  "slideType": "text",
26110
- "layoutHint": "text-1x-left"
26231
+ "layoutHint": "text-1x"
26111
26232
  },
26112
26233
  {
26113
26234
  "id": "big-change",
@@ -26115,7 +26236,7 @@ var narratives = [
26115
26236
  "description": "Name the market shift the prospect's industry is living through. Make it concrete, recent, and undeniable. The change \u2014 not the product \u2014 is the reason they should care.",
26116
26237
  "instructions": "Highlight market shift",
26117
26238
  "slideType": "text",
26118
- "layoutHint": "text-1x-left"
26239
+ "layoutHint": "text-1x"
26119
26240
  },
26120
26241
  {
26121
26242
  "id": "response-to-change",
@@ -26123,7 +26244,7 @@ var narratives = [
26123
26244
  "description": "Show how the change is creating winners and losers in the prospect's space. Use named examples where you can. The goal is for the prospect to wonder which side they'll end up on.",
26124
26245
  "instructions": "Show winners & losers",
26125
26246
  "slideType": "text",
26126
- "layoutHint": "text-1x-left"
26247
+ "layoutHint": "text-1x"
26127
26248
  },
26128
26249
  {
26129
26250
  "id": "benefits",
@@ -26131,7 +26252,7 @@ var narratives = [
26131
26252
  "description": "Paint the outcome a winner experiences: a vivid picture of the prospect's life on the other side of the change. Lead with what changes for them, not with what your product does.",
26132
26253
  "instructions": "Describe benefits, paint a vivid picture",
26133
26254
  "slideType": "text",
26134
- "layoutHint": "text-1x-left"
26255
+ "layoutHint": "text-1x"
26135
26256
  },
26136
26257
  {
26137
26258
  "id": "capabilities",
@@ -26139,7 +26260,7 @@ var narratives = [
26139
26260
  "description": "Reveal the unique capabilities that make those outcomes possible. Frame them as the 'magic gifts' the prospect needs to win the new game. Highlight what's structurally different from the alternatives.",
26140
26261
  "instructions": "Present unique features as 'magic gifts' to the customer",
26141
26262
  "slideType": "text",
26142
- "layoutHint": "text-1x-left"
26263
+ "layoutHint": "text-1x"
26143
26264
  },
26144
26265
  {
26145
26266
  "id": "evidence",
@@ -26147,13 +26268,13 @@ var narratives = [
26147
26268
  "description": "Share customer testimonials, case studies, and measurable outcomes from organizations like the prospect's. Pick evidence that maps to the benefits you promised, not generic logos.",
26148
26269
  "instructions": "Share testimonials",
26149
26270
  "slideType": "text",
26150
- "layoutHint": "text-1x-left"
26271
+ "layoutHint": "text-1x"
26151
26272
  },
26152
26273
  {
26153
26274
  "id": "call-to-action",
26154
26275
  "name": "Call to Action",
26155
26276
  "description": "Ask for the next step in the sales process. Be specific: a pilot, a workshop, a follow-on conversation with a named stakeholder. Make the smallest credible commitment that keeps momentum.",
26156
- "layoutHint": "title-left",
26277
+ "layoutHint": "title",
26157
26278
  "instructions": "Encourage decision-making",
26158
26279
  "slideType": "text"
26159
26280
  },
@@ -26161,7 +26282,7 @@ var narratives = [
26161
26282
  "id": "close",
26162
26283
  "name": "Close",
26163
26284
  "description": "Close with a final image and contact path. Leave the prospect with one line about why they're better off acting now than later, and clear instructions for how to engage.",
26164
- "layoutHint": "title-left",
26285
+ "layoutHint": "title",
26165
26286
  "instructions": "Logo & contact info",
26166
26287
  "slideType": "text"
26167
26288
  }
@@ -26193,7 +26314,7 @@ var narratives = [
26193
26314
  "id": "logo",
26194
26315
  "name": "Logo",
26195
26316
  "description": "Cover slide with the logo, tagline, and a single line of positioning. Set the visual tone \u2014 confident, branded, uncluttered.",
26196
- "layoutHint": "title-left",
26317
+ "layoutHint": "title",
26197
26318
  "instructions": "Establish brand identity",
26198
26319
  "slideType": "text"
26199
26320
  },
@@ -26203,7 +26324,7 @@ var narratives = [
26203
26324
  "description": "Capture the company in three or four lines: what you do, who you do it for, and how long you've been at it. Avoid jargon; an outsider should grok the business in fifteen seconds.",
26204
26325
  "instructions": "Capture attention",
26205
26326
  "slideType": "text",
26206
- "layoutHint": "text-1x-left"
26327
+ "layoutHint": "text-1x"
26207
26328
  },
26208
26329
  {
26209
26330
  "id": "competitive-advantage",
@@ -26211,7 +26332,7 @@ var narratives = [
26211
26332
  "description": "State the one or two things you do that the alternatives can't. Frame it as a structural advantage, not a feature list. The audience should leave able to repeat the differentiator in their own words.",
26212
26333
  "instructions": "Stand out",
26213
26334
  "slideType": "text",
26214
- "layoutHint": "text-1x-left"
26335
+ "layoutHint": "text-1x"
26215
26336
  },
26216
26337
  {
26217
26338
  "id": "company-story",
@@ -26219,7 +26340,7 @@ var narratives = [
26219
26340
  "description": "Share the founding insight or origin moment \u2014 why this company exists, told as a short story. Specific people, specific problems, a specific 'aha.' Story beats biography.",
26220
26341
  "instructions": "Share origin",
26221
26342
  "slideType": "text",
26222
- "layoutHint": "text-1x-left"
26343
+ "layoutHint": "text-1x"
26223
26344
  },
26224
26345
  {
26225
26346
  "id": "offerings",
@@ -26227,7 +26348,7 @@ var narratives = [
26227
26348
  "description": "Map the products and services into a coherent picture. Show how they fit together rather than listing them flat. The shape of the portfolio is itself a message.",
26228
26349
  "instructions": "Highlight products/services",
26229
26350
  "slideType": "text",
26230
- "layoutHint": "text-1x-left"
26351
+ "layoutHint": "text-1x"
26231
26352
  },
26232
26353
  {
26233
26354
  "id": "ideal-customer",
@@ -26235,7 +26356,7 @@ var narratives = [
26235
26356
  "description": "Define who you serve best. Industry, size, role, situation. Specificity here helps the audience self-select and signals you understand the customer well enough to be choosy.",
26236
26357
  "instructions": "Define target market",
26237
26358
  "slideType": "text",
26238
- "layoutHint": "text-1x-left"
26359
+ "layoutHint": "text-1x"
26239
26360
  },
26240
26361
  {
26241
26362
  "id": "key-benefits",
@@ -26243,7 +26364,7 @@ var narratives = [
26243
26364
  "description": "Translate offerings into three to five customer outcomes. Lead with the result, not the mechanism. Each benefit should answer 'what becomes easier or better for me?'",
26244
26365
  "instructions": "Emphasize value",
26245
26366
  "slideType": "text",
26246
- "layoutHint": "text-1x-left"
26367
+ "layoutHint": "text-1x"
26247
26368
  },
26248
26369
  {
26249
26370
  "id": "success-story",
@@ -26251,13 +26372,13 @@ var narratives = [
26251
26372
  "description": "Tell one named customer's story with concrete before/after metrics. A single specific story is more persuasive than a logo grid; pick one that mirrors the audience you're presenting to.",
26252
26373
  "instructions": "Showcase satisfied customer",
26253
26374
  "slideType": "text",
26254
- "layoutHint": "text-1x-left"
26375
+ "layoutHint": "text-1x"
26255
26376
  },
26256
26377
  {
26257
26378
  "id": "closing-cta",
26258
26379
  "name": "Closing & CTA",
26259
26380
  "description": "Close with one line of why now and one specific next step \u2014 a discovery call, a pilot, a partner program. End with contact info that's easy to act on without searching.",
26260
- "layoutHint": "title-left",
26381
+ "layoutHint": "title",
26261
26382
  "instructions": "Encourage action",
26262
26383
  "slideType": "text"
26263
26384
  }
@@ -26290,7 +26411,7 @@ var narratives = [
26290
26411
  "description": "Open by establishing the product or service this strategy is for, and what window of time it covers. One slide that tells the audience exactly which world they're being asked to weigh in on.",
26291
26412
  "instructions": "Establish product/service specifics",
26292
26413
  "slideType": "text",
26293
- "layoutHint": "text-1x-left"
26414
+ "layoutHint": "text-1x"
26294
26415
  },
26295
26416
  {
26296
26417
  "id": "objective",
@@ -26298,7 +26419,7 @@ var narratives = [
26298
26419
  "description": "State the marketing goals in measurable terms: revenue, pipeline, awareness, share. Two or three goals, ranked. Goals without ranking get equal energy and equal mediocrity.",
26299
26420
  "instructions": "Share marketing goals",
26300
26421
  "slideType": "text",
26301
- "layoutHint": "text-1x-left"
26422
+ "layoutHint": "text-1x"
26302
26423
  },
26303
26424
  {
26304
26425
  "id": "customer",
@@ -26306,7 +26427,7 @@ var narratives = [
26306
26427
  "description": "Detail the target audience. Segments, jobs-to-be-done, decision criteria, where they live in the buying cycle. Specificity here is the foundation everything else stands on.",
26307
26428
  "instructions": "Detail target audience",
26308
26429
  "slideType": "text",
26309
- "layoutHint": "text-1x-left"
26430
+ "layoutHint": "text-1x"
26310
26431
  },
26311
26432
  {
26312
26433
  "id": "market",
@@ -26314,7 +26435,7 @@ var narratives = [
26314
26435
  "description": "Describe the market landscape: size, growth, segments, behavioral trends. Use external data for credibility and your own research for nuance. Show how the market is changing, not just how big it is.",
26315
26436
  "instructions": "Discuss market landscape",
26316
26437
  "slideType": "text",
26317
- "layoutHint": "text-1x-left"
26438
+ "layoutHint": "text-1x"
26318
26439
  },
26319
26440
  {
26320
26441
  "id": "competition",
@@ -26322,7 +26443,7 @@ var narratives = [
26322
26443
  "description": "Map the competitive set honestly. Direct, indirect, and substitutes. A 2x2 or feature-comparison framework helps; what matters is that the audience trusts your read of the field.",
26323
26444
  "instructions": "Analyze competitive environment",
26324
26445
  "slideType": "text",
26325
- "layoutHint": "text-1x-left"
26446
+ "layoutHint": "text-1x"
26326
26447
  },
26327
26448
  {
26328
26449
  "id": "strategy",
@@ -26330,7 +26451,7 @@ var narratives = [
26330
26451
  "description": "Articulate the marketing approach in one sentence and a single supporting frame. Positioning, primary motion, where you choose to play and not play. Clarity here is what makes the tactics that follow coherent.",
26331
26452
  "instructions": "Elaborate marketing approach",
26332
26453
  "slideType": "text",
26333
- "layoutHint": "text-1x-left"
26454
+ "layoutHint": "text-1x"
26334
26455
  },
26335
26456
  {
26336
26457
  "id": "product",
@@ -26338,7 +26459,7 @@ var narratives = [
26338
26459
  "description": "Highlight the unique value the product brings to the strategy. Lead with the customer outcome; tie it directly back to the customer beat. Avoid feature soup.",
26339
26460
  "instructions": "Highlight unique value",
26340
26461
  "slideType": "text",
26341
- "layoutHint": "text-1x-left"
26462
+ "layoutHint": "text-1x"
26342
26463
  },
26343
26464
  {
26344
26465
  "id": "price",
@@ -26346,7 +26467,7 @@ var narratives = [
26346
26467
  "description": "Justify pricing and packaging. Show the logic \u2014 cost-plus, value-based, competitor-anchored \u2014 and the levers you'll use over the period. Price decisions are strategy decisions.",
26347
26468
  "instructions": "Justify pricing strategy",
26348
26469
  "slideType": "text",
26349
- "layoutHint": "text-1x-left"
26470
+ "layoutHint": "text-1x"
26350
26471
  },
26351
26472
  {
26352
26473
  "id": "place",
@@ -26354,7 +26475,7 @@ var narratives = [
26354
26475
  "description": "Describe distribution channels and the role each plays. Direct, partner, marketplace, retail. Channel mix is often where strategies quietly succeed or fail.",
26355
26476
  "instructions": "Discuss distribution channels",
26356
26477
  "slideType": "text",
26357
- "layoutHint": "text-1x-left"
26478
+ "layoutHint": "text-1x"
26358
26479
  },
26359
26480
  {
26360
26481
  "id": "promotion",
@@ -26362,13 +26483,13 @@ var narratives = [
26362
26483
  "description": "Reveal the campaign and content tactics that bring the strategy to market. Pair each tactic with the audience and metric it serves. Avoid listing channels for their own sake.",
26363
26484
  "instructions": "Reveal promotional tactics",
26364
26485
  "slideType": "text",
26365
- "layoutHint": "text-1x-left"
26486
+ "layoutHint": "text-1x"
26366
26487
  },
26367
26488
  {
26368
26489
  "id": "summary",
26369
26490
  "name": "Summary",
26370
26491
  "description": "Recap the strategy in a single page: customer, position, motion, expected outcome. End with the decision or commitment you need from the audience.",
26371
- "layoutHint": "title-left",
26492
+ "layoutHint": "title",
26372
26493
  "instructions": "Recap key points",
26373
26494
  "slideType": "text"
26374
26495
  }
@@ -26400,7 +26521,7 @@ var narratives = [
26400
26521
  "id": "opening",
26401
26522
  "name": "Opening",
26402
26523
  "description": "Open with the company brand and a confident visual. Set the tone \u2014 this is a moment, not a meeting. One slide that signals the audience is somewhere worth being.",
26403
- "layoutHint": "title-left",
26524
+ "layoutHint": "title",
26404
26525
  "instructions": "Show company branding",
26405
26526
  "slideType": "text"
26406
26527
  },
@@ -26410,7 +26531,7 @@ var narratives = [
26410
26531
  "description": "Hook the audience with the promise of the talk. Tell them, in one sentence, what they're about to see and why it matters to them. Specific promises buy patient audiences.",
26411
26532
  "instructions": "Hook the audience",
26412
26533
  "slideType": "text",
26413
- "layoutHint": "text-1x-left"
26534
+ "layoutHint": "text-1x"
26414
26535
  },
26415
26536
  {
26416
26537
  "id": "context",
@@ -26418,7 +26539,7 @@ var narratives = [
26418
26539
  "description": "Set the stage with the world the product enters. The customer reality, the market state, the unmet expectation. Context turns the launch from a product release into a moment in a larger story.",
26419
26540
  "instructions": "Set the stage",
26420
26541
  "slideType": "text",
26421
- "layoutHint": "text-1x-left"
26542
+ "layoutHint": "text-1x"
26422
26543
  },
26423
26544
  {
26424
26545
  "id": "conflict",
@@ -26426,7 +26547,7 @@ var narratives = [
26426
26547
  "description": "Introduce the villain \u2014 the problem, friction, or status quo the product opposes. Make the conflict concrete enough that the audience can name a moment they've felt it themselves.",
26427
26548
  "instructions": "Introduce villain/problem",
26428
26549
  "slideType": "text",
26429
- "layoutHint": "text-1x-left"
26550
+ "layoutHint": "text-1x"
26430
26551
  },
26431
26552
  {
26432
26553
  "id": "stakes",
@@ -26434,7 +26555,7 @@ var narratives = [
26434
26555
  "description": "Emphasize what's at risk if the conflict isn't resolved. Quantify, personalize, dramatize. Stakes are what convert a curious audience into an invested one.",
26435
26556
  "instructions": "Emphasize importance",
26436
26557
  "slideType": "text",
26437
- "layoutHint": "text-1x-left"
26558
+ "layoutHint": "text-1x"
26438
26559
  },
26439
26560
  {
26440
26561
  "id": "reveal",
@@ -26442,7 +26563,7 @@ var narratives = [
26442
26563
  "description": "Showcase the product. One striking visual, one defining capability, one sentence that captures what's new. Earn the applause line; don't bury it under a bullet list.",
26443
26564
  "instructions": "Showcase the solution",
26444
26565
  "slideType": "text",
26445
- "layoutHint": "text-1x-left"
26566
+ "layoutHint": "text-1x"
26446
26567
  },
26447
26568
  {
26448
26569
  "id": "raise-stakes",
@@ -26450,7 +26571,7 @@ var narratives = [
26450
26571
  "description": "Highlight where the alternatives fall short and what they cost the customer. Re-energize the room midway by sharpening the contrast with the reveal.",
26451
26572
  "instructions": "Highlight shortcomings of alternatives",
26452
26573
  "slideType": "text",
26453
- "layoutHint": "text-1x-left"
26574
+ "layoutHint": "text-1x"
26454
26575
  },
26455
26576
  {
26456
26577
  "id": "raise-stakes-again",
@@ -26458,7 +26579,7 @@ var narratives = [
26458
26579
  "description": "Reinforce why change is non-negotiable now. A second beat of stakes, framed differently \u2014 perhaps a customer voice or a future cost. Cement the reason to act.",
26459
26580
  "instructions": "Reinforce the need for change",
26460
26581
  "slideType": "text",
26461
- "layoutHint": "text-1x-left"
26582
+ "layoutHint": "text-1x"
26462
26583
  },
26463
26584
  {
26464
26585
  "id": "sell",
@@ -26466,13 +26587,13 @@ var narratives = [
26466
26587
  "description": "Make the audience want the product. Lead with the outcome it produces in their lives. Pricing, packaging, availability go here, but only after the desire is built.",
26467
26588
  "instructions": "Make them want your solution",
26468
26589
  "slideType": "text",
26469
- "layoutHint": "text-1x-left"
26590
+ "layoutHint": "text-1x"
26470
26591
  },
26471
26592
  {
26472
26593
  "id": "cta",
26473
26594
  "name": "Call to Action",
26474
26595
  "description": "Close with the single action you want from the audience. Pre-order, sign up, attend, share. Make it simple, specific, and immediate.",
26475
- "layoutHint": "title-left",
26596
+ "layoutHint": "title",
26476
26597
  "instructions": "Inspire action",
26477
26598
  "slideType": "text"
26478
26599
  }
@@ -26504,7 +26625,7 @@ var narratives = [
26504
26625
  "id": "title",
26505
26626
  "name": "Title",
26506
26627
  "description": "Open with a one-line summary statement that captures the recommendation, not the topic. The title slide is the headline of the entire engagement \u2014 make it specific enough that someone reading only this slide already understands the position.",
26507
- "layoutHint": "title-left",
26628
+ "layoutHint": "title",
26508
26629
  "instructions": "Brief summary sentence",
26509
26630
  "slideType": "text"
26510
26631
  },
@@ -26519,7 +26640,7 @@ var narratives = [
26519
26640
  "description": "Deliver the recommendation in a single sentence. No arguments yet, no caveats. The answer is the apex of the pyramid; the rest of the deck supports it.",
26520
26641
  "instructions": "A solution in one sentence, no arguments yet",
26521
26642
  "slideType": "text",
26522
- "layoutHint": "text-1x-left"
26643
+ "layoutHint": "text-1x"
26523
26644
  },
26524
26645
  {
26525
26646
  "id": "arguments",
@@ -26527,7 +26648,7 @@ var narratives = [
26527
26648
  "description": "Preview the three top-level arguments that defend the answer. One slide naming all three so the audience knows where the deck is going. Each argument should be a complete claim, not a topic.",
26528
26649
  "instructions": "Support the solution",
26529
26650
  "slideType": "text",
26530
- "layoutHint": "text-1x-left"
26651
+ "layoutHint": "text-1x"
26531
26652
  },
26532
26653
  {
26533
26654
  "id": "argument-1",
@@ -26535,7 +26656,7 @@ var narratives = [
26535
26656
  "description": "Develop the first argument with supporting data, examples, and reasoning. Lead with the claim, then the evidence \u2014 Minto-style. The slide should stand alone if pulled out.",
26536
26657
  "instructions": "First key point",
26537
26658
  "slideType": "text",
26538
- "layoutHint": "text-1x-left"
26659
+ "layoutHint": "text-1x"
26539
26660
  },
26540
26661
  {
26541
26662
  "id": "argument-2",
@@ -26543,7 +26664,7 @@ var narratives = [
26543
26664
  "description": "Develop the second argument the same way. Vary the type of evidence \u2014 quantitative, qualitative, comparative \u2014 so the audience hears the case from multiple angles.",
26544
26665
  "instructions": "Second key point",
26545
26666
  "slideType": "text",
26546
- "layoutHint": "text-1x-left"
26667
+ "layoutHint": "text-1x"
26547
26668
  },
26548
26669
  {
26549
26670
  "id": "argument-3",
@@ -26551,13 +26672,13 @@ var narratives = [
26551
26672
  "description": "Develop the third argument and walk through the supporting process or methodology. This is often where the 'how' lives \u2014 the implementation insight that makes the recommendation feel actionable.",
26552
26673
  "instructions": "Third key point with a process",
26553
26674
  "slideType": "text",
26554
- "layoutHint": "text-1x-left"
26675
+ "layoutHint": "text-1x"
26555
26676
  },
26556
26677
  {
26557
26678
  "id": "summary",
26558
26679
  "name": "Summary",
26559
26680
  "description": "Recap the answer and arguments in a single slide and point to additional resources. Close with the explicit next step you want the audience to take.",
26560
- "layoutHint": "title-left",
26681
+ "layoutHint": "title",
26561
26682
  "instructions": "Recap the answer, provide additional resources",
26562
26683
  "slideType": "text"
26563
26684
  }
@@ -26591,7 +26712,7 @@ var narratives = [
26591
26712
  "description": "Open with a specific, visible signal of the challenge \u2014 a metric heading the wrong way, a customer story, a competitive event. The hook should make the audience nod that yes, this matters.",
26592
26713
  "instructions": "Capture audience attention",
26593
26714
  "slideType": "text",
26594
- "layoutHint": "text-1x-left"
26715
+ "layoutHint": "text-1x"
26595
26716
  },
26596
26717
  {
26597
26718
  "id": "dilemma",
@@ -26599,7 +26720,7 @@ var narratives = [
26599
26720
  "description": "State the challenge plainly. What is failing, who is feeling it, and why has it now risen to a level that demands a decision? The dilemma must feel real, not academic.",
26600
26721
  "instructions": "Present the problem",
26601
26722
  "slideType": "text",
26602
- "layoutHint": "text-1x-left"
26723
+ "layoutHint": "text-1x"
26603
26724
  },
26604
26725
  {
26605
26726
  "id": "backdrop",
@@ -26607,7 +26728,7 @@ var narratives = [
26607
26728
  "description": "Provide the context behind the dilemma: how it formed, what's been tried, what constraints exist. Just enough history that the audience trusts your diagnosis without drowning in detail.",
26608
26729
  "instructions": "Provide context",
26609
26730
  "slideType": "text",
26610
- "layoutHint": "text-1x-left"
26731
+ "layoutHint": "text-1x"
26611
26732
  },
26612
26733
  {
26613
26734
  "id": "remedy",
@@ -26615,7 +26736,7 @@ var narratives = [
26615
26736
  "description": "Propose the resolution. Lead with the recommendation, then sketch the approach. Be opinionated \u2014 vague remedies invite vague responses.",
26616
26737
  "instructions": "Propose a solution",
26617
26738
  "slideType": "text",
26618
- "layoutHint": "text-1x-left"
26739
+ "layoutHint": "text-1x"
26619
26740
  },
26620
26741
  {
26621
26742
  "id": "evidence",
@@ -26623,7 +26744,7 @@ var narratives = [
26623
26744
  "description": "Demonstrate why the remedy will work. Comparable cases, supporting data, or pilot results. Choose evidence that addresses the audience's most likely objection, not the one easiest to answer.",
26624
26745
  "instructions": "Demonstrate success",
26625
26746
  "slideType": "text",
26626
- "layoutHint": "text-1x-left"
26747
+ "layoutHint": "text-1x"
26627
26748
  },
26628
26749
  {
26629
26750
  "id": "motivate",
@@ -26631,13 +26752,13 @@ var narratives = [
26631
26752
  "description": "Make the case for acting now. Quantify the cost of delay and the upside of decisive action. Help the audience picture the room a quarter from now if they say yes.",
26632
26753
  "instructions": "Encourage action",
26633
26754
  "slideType": "text",
26634
- "layoutHint": "text-1x-left"
26755
+ "layoutHint": "text-1x"
26635
26756
  },
26636
26757
  {
26637
26758
  "id": "conclusion",
26638
26759
  "name": "Conclusion",
26639
26760
  "description": "Recap the challenge, the remedy, and the specific decision you need from the audience. End with a clear ask, not a summary slide.",
26640
- "layoutHint": "title-left",
26761
+ "layoutHint": "title",
26641
26762
  "instructions": "Recap and end powerfully",
26642
26763
  "slideType": "text"
26643
26764
  }
@@ -26671,7 +26792,7 @@ var narratives = [
26671
26792
  "description": "Open with the proposal in one slide: the project name, the audience, the goal, and the headline benefit. If a sponsor reads only this slide, they should still know what they're being asked to approve.",
26672
26793
  "instructions": "Audience hook & objectives",
26673
26794
  "slideType": "text",
26674
- "layoutHint": "text-1x-left"
26795
+ "layoutHint": "text-1x"
26675
26796
  },
26676
26797
  {
26677
26798
  "id": "problem-statement",
@@ -26679,7 +26800,7 @@ var narratives = [
26679
26800
  "description": "Articulate the problem this project solves and why it deserves resources now. Tie it to a known business goal or pain. Vague problems produce vague approvals.",
26680
26801
  "instructions": "Highlight struggles & project necessity",
26681
26802
  "slideType": "text",
26682
- "layoutHint": "text-1x-left"
26803
+ "layoutHint": "text-1x"
26683
26804
  },
26684
26805
  {
26685
26806
  "id": "core-concept",
@@ -26687,7 +26808,7 @@ var narratives = [
26687
26808
  "description": "Describe the central idea of the project in plain language. The 'what' before the 'how.' A reader should be able to repeat the concept in one sentence after this slide.",
26688
26809
  "instructions": "Share actionable idea",
26689
26810
  "slideType": "text",
26690
- "layoutHint": "text-1x-left"
26811
+ "layoutHint": "text-1x"
26691
26812
  },
26692
26813
  {
26693
26814
  "id": "benefits",
@@ -26695,7 +26816,7 @@ var narratives = [
26695
26816
  "description": "Quantify the impact: revenue, cost, risk, customer, capability. Use numbers where possible and clear comparisons where not. Each benefit should map to a metric the sponsor cares about.",
26696
26817
  "instructions": "Spotlight key metrics",
26697
26818
  "slideType": "text",
26698
- "layoutHint": "text-1x-left"
26819
+ "layoutHint": "text-1x"
26699
26820
  },
26700
26821
  {
26701
26822
  "id": "justification",
@@ -26703,7 +26824,7 @@ var narratives = [
26703
26824
  "description": "Connect the project to broader strategy, OKRs, or constraints the audience already cares about. Show why this project is more important than the alternatives competing for the same resources.",
26704
26825
  "instructions": "Strategic alignment & significance",
26705
26826
  "slideType": "text",
26706
- "layoutHint": "text-1x-left"
26827
+ "layoutHint": "text-1x"
26707
26828
  },
26708
26829
  {
26709
26830
  "id": "approach",
@@ -26711,7 +26832,7 @@ var narratives = [
26711
26832
  "description": "Lay out how the project will be executed: the solution, the team shape, the budget envelope. Enough detail to feel credible, not so much that it pre-commits to choices that will mature in flight.",
26712
26833
  "instructions": "Solution, resources, & budget",
26713
26834
  "slideType": "text",
26714
- "layoutHint": "text-1x-left"
26835
+ "layoutHint": "text-1x"
26715
26836
  },
26716
26837
  {
26717
26838
  "id": "timeline",
@@ -26719,7 +26840,7 @@ var narratives = [
26719
26840
  "description": "Show the project phases on a timeline, with major milestones and decision points marked. Sponsors are buying a sequence of bets, not a single launch \u2014 make those bets visible.",
26720
26841
  "instructions": "Outline project phases",
26721
26842
  "slideType": "text",
26722
- "layoutHint": "text-1x-left"
26843
+ "layoutHint": "text-1x"
26723
26844
  },
26724
26845
  {
26725
26846
  "id": "risks",
@@ -26727,7 +26848,7 @@ var narratives = [
26727
26848
  "description": "Name the top risks honestly and pair each with a mitigation or open question. Listing risks without mitigations signals you haven't thought it through; hiding risks signals worse.",
26728
26849
  "instructions": "Consider potential challenges",
26729
26850
  "slideType": "text",
26730
- "layoutHint": "text-1x-left"
26851
+ "layoutHint": "text-1x"
26731
26852
  },
26732
26853
  {
26733
26854
  "id": "outlook",
@@ -26735,13 +26856,13 @@ var narratives = [
26735
26856
  "description": "Paint the picture of what the organization looks like a quarter or year after the project ships. Stretch beyond the immediate deliverable to the second-order benefits.",
26736
26857
  "instructions": "Envision project impact",
26737
26858
  "slideType": "text",
26738
- "layoutHint": "text-1x-left"
26859
+ "layoutHint": "text-1x"
26739
26860
  },
26740
26861
  {
26741
26862
  "id": "wrap-up",
26742
26863
  "name": "Wrap Up",
26743
26864
  "description": "Recap the proposal and state the specific decision you're asking for: approval, budget, headcount, sponsorship. Make it easy to say yes today.",
26744
- "layoutHint": "title-left",
26865
+ "layoutHint": "title",
26745
26866
  "instructions": "Summarize & persuade",
26746
26867
  "slideType": "text"
26747
26868
  }
@@ -26775,7 +26896,7 @@ var narratives = [
26775
26896
  "description": "Set an empathetic, accountable tone before any analysis. Acknowledge the impact on the people in the room and the customers affected. Authenticity here earns you the credibility you'll need for the rest of the deck.",
26776
26897
  "instructions": "Set an empathetic tone",
26777
26898
  "slideType": "text",
26778
- "layoutHint": "text-1x-left"
26899
+ "layoutHint": "text-1x"
26779
26900
  },
26780
26901
  {
26781
26902
  "id": "incident-breakdown",
@@ -26783,7 +26904,7 @@ var narratives = [
26783
26904
  "description": "Walk through what happened, in time order. Stick to facts: what systems, what users, what timeline. No causal claims yet \u2014 just an accurate, neutral reconstruction the audience can trust.",
26784
26905
  "instructions": "Detail the failure",
26785
26906
  "slideType": "text",
26786
- "layoutHint": "text-1x-left"
26907
+ "layoutHint": "text-1x"
26787
26908
  },
26788
26909
  {
26789
26910
  "id": "impact-analysis",
@@ -26791,7 +26912,7 @@ var narratives = [
26791
26912
  "description": "Quantify the damage. Customer-hours lost, revenue at risk, SLA breaches, downstream knock-ons. Be specific and direct; vague impact statements undermine the rest of the post-mortem.",
26792
26913
  "instructions": "Describe failure's effects",
26793
26914
  "slideType": "text",
26794
- "layoutHint": "text-1x-left"
26915
+ "layoutHint": "text-1x"
26795
26916
  },
26796
26917
  {
26797
26918
  "id": "root-cause",
@@ -26799,7 +26920,7 @@ var narratives = [
26799
26920
  "description": "Trace the failure to its underlying cause, not the most visible symptom. Use a 'five whys' or fishbone framing if useful. Distinguish between the proximate trigger and the systemic conditions that allowed it.",
26800
26921
  "instructions": "Analyze underlying reasons",
26801
26922
  "slideType": "text",
26802
- "layoutHint": "text-1x-left"
26923
+ "layoutHint": "text-1x"
26803
26924
  },
26804
26925
  {
26805
26926
  "id": "proposed-solutions",
@@ -26807,7 +26928,7 @@ var narratives = [
26807
26928
  "description": "Present the corrective actions you're taking. Lead with the highest-leverage fix; sequence the rest. For each action, name an owner and a date \u2014 solutions without owners are aspirations.",
26808
26929
  "instructions": "Suggest corrective measures",
26809
26930
  "slideType": "text",
26810
- "layoutHint": "text-1x-left"
26931
+ "layoutHint": "text-1x"
26811
26932
  },
26812
26933
  {
26813
26934
  "id": "action-plan",
@@ -26815,7 +26936,7 @@ var narratives = [
26815
26936
  "description": "Lay out the rollout: what ships when, how it's verified, who signs off. Show that 'fixed' has a definition and a deadline, not just intent.",
26816
26937
  "instructions": "Map out steps",
26817
26938
  "slideType": "text",
26818
- "layoutHint": "text-1x-left"
26939
+ "layoutHint": "text-1x"
26819
26940
  },
26820
26941
  {
26821
26942
  "id": "evaluate-outcome",
@@ -26823,7 +26944,7 @@ var narratives = [
26823
26944
  "description": "Define the metrics that will tell you the fix worked. Pre/post comparisons, monitoring SLOs, error budgets \u2014 whatever proves the failure mode is closed and not just deferred.",
26824
26945
  "instructions": "Assess corrective actions",
26825
26946
  "slideType": "text",
26826
- "layoutHint": "text-1x-left"
26947
+ "layoutHint": "text-1x"
26827
26948
  },
26828
26949
  {
26829
26950
  "id": "lessons-learned",
@@ -26831,7 +26952,7 @@ var narratives = [
26831
26952
  "description": "Distill the broader lessons that outlive this specific incident. What does the team or organization now know that it didn't before? What patterns will you watch for elsewhere?",
26832
26953
  "instructions": "Reflect on failure lessons",
26833
26954
  "slideType": "text",
26834
- "layoutHint": "text-1x-left"
26955
+ "layoutHint": "text-1x"
26835
26956
  },
26836
26957
  {
26837
26958
  "id": "preventive-measures",
@@ -26839,13 +26960,13 @@ var narratives = [
26839
26960
  "description": "List the systemic safeguards being added \u2014 process changes, automated checks, on-call procedures, review gates. Show how this category of failure becomes harder to recur, not just this specific instance.",
26840
26961
  "instructions": "List safeguards",
26841
26962
  "slideType": "text",
26842
- "layoutHint": "text-1x-left"
26963
+ "layoutHint": "text-1x"
26843
26964
  },
26844
26965
  {
26845
26966
  "id": "closing-thoughts",
26846
26967
  "name": "Closing Thoughts",
26847
26968
  "description": "Close with humility and forward momentum. Re-affirm accountability, thank the audience for their patience, and signal confidence in the path forward without overclaiming.",
26848
- "layoutHint": "title-left",
26969
+ "layoutHint": "title",
26849
26970
  "instructions": "Empathize, trust, and encourage",
26850
26971
  "slideType": "text"
26851
26972
  }
@@ -26877,7 +26998,7 @@ var narratives = [
26877
26998
  "description": "Capture attention with a vivid moment, image, or question that sets the world of the story. The audience should immediately know what kind of room they're in. Avoid agendas \u2014 the opening is the first scene, not a preamble.",
26878
26999
  "instructions": "Capture audience attention",
26879
27000
  "slideType": "text",
26880
- "layoutHint": "text-1x-left"
27001
+ "layoutHint": "text-1x"
26881
27002
  },
26882
27003
  {
26883
27004
  "id": "context",
@@ -26885,7 +27006,7 @@ var narratives = [
26885
27006
  "description": "Establish what's normal in this world before anything goes wrong. Just enough background for the audience to feel the stakes when the villain shows up. Keep it tight; backstory is fuel, not the engine.",
26886
27007
  "instructions": "Give background & importance",
26887
27008
  "slideType": "text",
26888
- "layoutHint": "text-1x-left"
27009
+ "layoutHint": "text-1x"
26889
27010
  },
26890
27011
  {
26891
27012
  "id": "villain",
@@ -26893,7 +27014,7 @@ var narratives = [
26893
27014
  "description": "Introduce the antagonist \u2014 a problem, a competitor, a market force, an inertia. Give it a face and a name where you can. The clearer the villain, the more the audience cares about how the story turns out.",
26894
27015
  "instructions": "Introduce problem",
26895
27016
  "slideType": "text",
26896
- "layoutHint": "text-1x-left"
27017
+ "layoutHint": "text-1x"
26897
27018
  },
26898
27019
  {
26899
27020
  "id": "despair",
@@ -26901,7 +27022,7 @@ var narratives = [
26901
27022
  "description": "Show what's at risk if the villain wins. Emphasize the human or business cost of inaction. Don't rush past this beat \u2014 the discomfort here is what makes the resolution land.",
26902
27023
  "instructions": "Emphasize negative impact",
26903
27024
  "slideType": "text",
26904
- "layoutHint": "text-1x-left"
27025
+ "layoutHint": "text-1x"
26905
27026
  },
26906
27027
  {
26907
27028
  "id": "hero",
@@ -26909,7 +27030,7 @@ var narratives = [
26909
27030
  "description": "Reveal the hero of the story. Often this is the audience themselves, your team, or your product. Frame the hero by what they uniquely bring to the fight, not by their r\xE9sum\xE9.",
26910
27031
  "instructions": "Present solution",
26911
27032
  "slideType": "text",
26912
- "layoutHint": "text-1x-left"
27033
+ "layoutHint": "text-1x"
26913
27034
  },
26914
27035
  {
26915
27036
  "id": "plan",
@@ -26917,13 +27038,13 @@ var narratives = [
26917
27038
  "description": "Walk through how the hero defeats the villain. Concrete, sequential, credible. Generic plans signal weak heroes; specific plans earn belief that the ending you're promising is reachable.",
26918
27039
  "instructions": "Detail implementation",
26919
27040
  "slideType": "text",
26920
- "layoutHint": "text-1x-left"
27041
+ "layoutHint": "text-1x"
26921
27042
  },
26922
27043
  {
26923
27044
  "id": "closing",
26924
27045
  "name": "Closing",
26925
27046
  "description": "End with the resolution and the lesson. Show what the world looks like after the villain loses, and leave the audience with the feeling \u2014 and the line \u2014 they'll repeat afterwards.",
26926
- "layoutHint": "title-left",
27047
+ "layoutHint": "title",
26927
27048
  "instructions": "Inspire & conclude",
26928
27049
  "slideType": "text"
26929
27050
  }
@@ -26956,7 +27077,7 @@ var narratives = [
26956
27077
  "description": "Engage the audience and set expectations for the next twenty minutes. Tell them you're going to tell them a story \u2014 and then start telling it. Avoid a separate agenda slide; the introduction is the first scene.",
26957
27078
  "instructions": "Engage and set expectations",
26958
27079
  "slideType": "text",
26959
- "layoutHint": "text-1x-left"
27080
+ "layoutHint": "text-1x"
26960
27081
  },
26961
27082
  {
26962
27083
  "id": "setting",
@@ -26964,7 +27085,7 @@ var narratives = [
26964
27085
  "description": "Establish the world the story takes place in: the team, the market, the moment. Just enough context that the challenge will feel meaningful when it arrives.",
26965
27086
  "instructions": "Establish the environment",
26966
27087
  "slideType": "text",
26967
- "layoutHint": "text-1x-left"
27088
+ "layoutHint": "text-1x"
26968
27089
  },
26969
27090
  {
26970
27091
  "id": "challenge",
@@ -26972,7 +27093,7 @@ var narratives = [
26972
27093
  "description": "Identify the issue at hand. Concrete, specific, attributable. The challenge is the inciting incident \u2014 the thing that pulled the rest of the story into motion.",
26973
27094
  "instructions": "Identify the issue at hand",
26974
27095
  "slideType": "text",
26975
- "layoutHint": "text-1x-left"
27096
+ "layoutHint": "text-1x"
26976
27097
  },
26977
27098
  {
26978
27099
  "id": "tension",
@@ -26980,7 +27101,7 @@ var narratives = [
26980
27101
  "description": "Raise the stakes. What happens if the challenge isn't met? Quantify the cost, name the people affected, surface the trade-offs that make the choice hard. Tension is what makes the audience lean in.",
26981
27102
  "instructions": "Emphasize the stakes",
26982
27103
  "slideType": "text",
26983
- "layoutHint": "text-1x-left"
27104
+ "layoutHint": "text-1x"
26984
27105
  },
26985
27106
  {
26986
27107
  "id": "solution",
@@ -26988,7 +27109,7 @@ var narratives = [
26988
27109
  "description": "Reveal the strategy or hero of the story. Lead with what changes for the audience or customer when the solution is in place. This is the turn from problem to promise.",
26989
27110
  "instructions": "Present the hero/strategy",
26990
27111
  "slideType": "text",
26991
- "layoutHint": "text-1x-left"
27112
+ "layoutHint": "text-1x"
26992
27113
  },
26993
27114
  {
26994
27115
  "id": "implementation",
@@ -26996,7 +27117,7 @@ var narratives = [
26996
27117
  "description": "Describe the path to success. Phases, owners, milestones, key bets. Show the audience that the solution has weight behind it \u2014 not just intent.",
26997
27118
  "instructions": "Describe the path to success",
26998
27119
  "slideType": "text",
26999
- "layoutHint": "text-1x-left"
27120
+ "layoutHint": "text-1x"
27000
27121
  },
27001
27122
  {
27002
27123
  "id": "recap",
@@ -27004,13 +27125,13 @@ var narratives = [
27004
27125
  "description": "Bring the audience back to the surface with a clear summary of what was said and decided. Echo the language from the opening so the story feels closed.",
27005
27126
  "instructions": "Review key points and insights",
27006
27127
  "slideType": "text",
27007
- "layoutHint": "text-1x-left"
27128
+ "layoutHint": "text-1x"
27008
27129
  },
27009
27130
  {
27010
27131
  "id": "conclusion",
27011
27132
  "name": "Conclusion",
27012
27133
  "description": "Reinforce the key message and the call to action. End on the line you most want repeated in tomorrow's hallway conversations.",
27013
- "layoutHint": "title-left",
27134
+ "layoutHint": "title",
27014
27135
  "instructions": "Reinforce takeaways and call to action",
27015
27136
  "slideType": "text"
27016
27137
  }
@@ -27044,7 +27165,7 @@ var narratives = [
27044
27165
  "description": "Start at the bottom. Describe the humble beginning, the constraint, the moment before anything had been built. Concrete details \u2014 a place, a year, a feeling \u2014 earn the audience's investment in what follows.",
27045
27166
  "instructions": "Humble beginning",
27046
27167
  "slideType": "text",
27047
- "layoutHint": "text-1x-left"
27168
+ "layoutHint": "text-1x"
27048
27169
  },
27049
27170
  {
27050
27171
  "id": "inspiration",
@@ -27052,7 +27173,7 @@ var narratives = [
27052
27173
  "description": "Show the moment the protagonist found their calling. A conversation, a customer, a problem they couldn't unsee. The inspiration is the engine that pushes the rest of the story uphill.",
27053
27174
  "instructions": "Discover true calling",
27054
27175
  "slideType": "text",
27055
- "layoutHint": "text-1x-left"
27176
+ "layoutHint": "text-1x"
27056
27177
  },
27057
27178
  {
27058
27179
  "id": "opportunity",
@@ -27060,7 +27181,7 @@ var narratives = [
27060
27181
  "description": "Reveal the chance the protagonist took. Why this and not something safer? Make the choice visible \u2014 opportunities only count when there was something else they passed up to grab them.",
27061
27182
  "instructions": "Spot golden chance",
27062
27183
  "slideType": "text",
27063
- "layoutHint": "text-1x-left"
27184
+ "layoutHint": "text-1x"
27064
27185
  },
27065
27186
  {
27066
27187
  "id": "adversity",
@@ -27068,7 +27189,7 @@ var narratives = [
27068
27189
  "description": "Walk through the hardest stretch. Concrete failures, near-misses, moments of doubt. Resist the temptation to skip past the pain \u2014 the audience trusts the win more when the loss was real.",
27069
27190
  "instructions": "Face hardest struggles",
27070
27191
  "slideType": "text",
27071
- "layoutHint": "text-1x-left"
27192
+ "layoutHint": "text-1x"
27072
27193
  },
27073
27194
  {
27074
27195
  "id": "overcoming",
@@ -27076,7 +27197,7 @@ var narratives = [
27076
27197
  "description": "Show how the obstacles got beaten. What changed, what was learned, what hard call was made. The transition from 'rags' to 'riches' should feel earned, not granted.",
27077
27198
  "instructions": "Surmount tough obstacles",
27078
27199
  "slideType": "text",
27079
- "layoutHint": "text-1x-left"
27200
+ "layoutHint": "text-1x"
27080
27201
  },
27081
27202
  {
27082
27203
  "id": "impactful-change",
@@ -27084,13 +27205,13 @@ var narratives = [
27084
27205
  "description": "Describe the moment the world tipped. The customer who said yes, the product that broke through, the metric that turned. One concrete transformation lands harder than a montage.",
27085
27206
  "instructions": "Alter the status quo",
27086
27207
  "slideType": "text",
27087
- "layoutHint": "text-1x-left"
27208
+ "layoutHint": "text-1x"
27088
27209
  },
27089
27210
  {
27090
27211
  "id": "lasting-legacy",
27091
27212
  "name": "Lasting Legacy",
27092
27213
  "description": "Close on what the journey means for those who come next. The lesson, the people changed, the work that endures. Leave the audience with a takeaway that outlives the story.",
27093
- "layoutHint": "title-left",
27214
+ "layoutHint": "title",
27094
27215
  "instructions": "Create enduring effect",
27095
27216
  "slideType": "text"
27096
27217
  }
@@ -27123,7 +27244,7 @@ var narratives = [
27123
27244
  "description": "Establish the opening scene: who the underdog is and the world that overlooked them. Specific details make the rest of the journey feel real.",
27124
27245
  "instructions": "Establish opening scene",
27125
27246
  "slideType": "text",
27126
- "layoutHint": "text-1x-left"
27247
+ "layoutHint": "text-1x"
27127
27248
  },
27128
27249
  {
27129
27250
  "id": "struggles",
@@ -27131,7 +27252,7 @@ var narratives = [
27131
27252
  "description": "Highlight the early setbacks. What didn't work, who said no, where the path closed up. The audience needs to feel the doubt before they can feel the win.",
27132
27253
  "instructions": "Highlight initial setbacks",
27133
27254
  "slideType": "text",
27134
- "layoutHint": "text-1x-left"
27255
+ "layoutHint": "text-1x"
27135
27256
  },
27136
27257
  {
27137
27258
  "id": "determination",
@@ -27139,7 +27260,7 @@ var narratives = [
27139
27260
  "description": "Showcase the enduring passion that kept the underdog going. What they refused to give up on, and why. Determination, in this beat, is the only resource the underdog has.",
27140
27261
  "instructions": "Showcase enduring passion",
27141
27262
  "slideType": "text",
27142
- "layoutHint": "text-1x-left"
27263
+ "layoutHint": "text-1x"
27143
27264
  },
27144
27265
  {
27145
27266
  "id": "crisis",
@@ -27147,7 +27268,7 @@ var narratives = [
27147
27268
  "description": "Identify the lowest point of the journey. The moment the dream nearly ended. Don't soften \u2014 the contrast with the triumph ahead depends on the depth of this slide.",
27148
27269
  "instructions": "Identify lowest point",
27149
27270
  "slideType": "text",
27150
- "layoutHint": "text-1x-left"
27271
+ "layoutHint": "text-1x"
27151
27272
  },
27152
27273
  {
27153
27274
  "id": "resolve",
@@ -27155,7 +27276,7 @@ var narratives = [
27155
27276
  "description": "Articulate the choice the underdog made to keep going. The strong will, the small bet, the borrowed faith. Resolve is where the protagonist becomes someone the audience roots for.",
27156
27277
  "instructions": "Articulate strong will",
27157
27278
  "slideType": "text",
27158
- "layoutHint": "text-1x-left"
27279
+ "layoutHint": "text-1x"
27159
27280
  },
27160
27281
  {
27161
27282
  "id": "breakthrough",
@@ -27163,7 +27284,7 @@ var narratives = [
27163
27284
  "description": "Show the reward of perseverance: the customer who said yes, the door that opened, the fortune that turned. The breakthrough should feel earned, not granted.",
27164
27285
  "instructions": "Reward of perseverance",
27165
27286
  "slideType": "text",
27166
- "layoutHint": "text-1x-left"
27287
+ "layoutHint": "text-1x"
27167
27288
  },
27168
27289
  {
27169
27290
  "id": "triumph",
@@ -27171,13 +27292,13 @@ var narratives = [
27171
27292
  "description": "Reveal the ultimate success. Concrete outcomes, named milestones. The triumph is the audience's emotional payoff \u2014 let it land.",
27172
27293
  "instructions": "Reveal ultimate success",
27173
27294
  "slideType": "text",
27174
- "layoutHint": "text-1x-left"
27295
+ "layoutHint": "text-1x"
27175
27296
  },
27176
27297
  {
27177
27298
  "id": "legacy",
27178
27299
  "name": "Legacy",
27179
27300
  "description": "Share the lasting impact. What the underdog's victory makes possible for those who come after. The legacy beat is what turns a story into a lesson.",
27180
- "layoutHint": "title-left",
27301
+ "layoutHint": "title",
27181
27302
  "instructions": "Share long-lasting impact",
27182
27303
  "slideType": "text"
27183
27304
  }
@@ -27210,7 +27331,7 @@ var narratives = [
27210
27331
  "description": "Open in the middle of the disaster. Specific moment, specific stakes, specific damage. Drop the audience into the worst point of the story before walking them back.",
27211
27332
  "instructions": "Present initial disaster",
27212
27333
  "slideType": "text",
27213
- "layoutHint": "text-1x-left"
27334
+ "layoutHint": "text-1x"
27214
27335
  },
27215
27336
  {
27216
27337
  "id": "backstory",
@@ -27218,7 +27339,7 @@ var narratives = [
27218
27339
  "description": "Detail the events that led up to the catastrophe. Just enough for the audience to understand how the disaster could have happened. Avoid moralizing \u2014 the story does the work.",
27219
27340
  "instructions": "Detail past events",
27220
27341
  "slideType": "text",
27221
- "layoutHint": "text-1x-left"
27342
+ "layoutHint": "text-1x"
27222
27343
  },
27223
27344
  {
27224
27345
  "id": "blueprint",
@@ -27226,7 +27347,7 @@ var narratives = [
27226
27347
  "description": "Illustrate the recovery plan. Specific moves, specific bets, specific people. The audience should see the strategy as more than 'try hard.'",
27227
27348
  "instructions": "Illustrate recovery plans",
27228
27349
  "slideType": "text",
27229
- "layoutHint": "text-1x-left"
27350
+ "layoutHint": "text-1x"
27230
27351
  },
27231
27352
  {
27232
27353
  "id": "danger",
@@ -27234,7 +27355,7 @@ var narratives = [
27234
27355
  "description": "Highlight the emerging threats to the recovery plan. New risks, returning ones. Tension here makes the eventual triumph credible.",
27235
27356
  "instructions": "Highlight emerging threats",
27236
27357
  "slideType": "text",
27237
- "layoutHint": "text-1x-left"
27358
+ "layoutHint": "text-1x"
27238
27359
  },
27239
27360
  {
27240
27361
  "id": "endeavor",
@@ -27242,7 +27363,7 @@ var narratives = [
27242
27363
  "description": "Show the determined effort underway. The hours, the trade-offs, the discipline. The audience must feel the work, not just hear about it.",
27243
27364
  "instructions": "Show determination effort",
27244
27365
  "slideType": "text",
27245
- "layoutHint": "text-1x-left"
27366
+ "layoutHint": "text-1x"
27246
27367
  },
27247
27368
  {
27248
27369
  "id": "struggles",
@@ -27250,7 +27371,7 @@ var narratives = [
27250
27371
  "description": "Showcase challenging moments along the way: the setbacks, the false starts, the hard calls. Honest setbacks make eventual success feel earned.",
27251
27372
  "instructions": "Showcase challenging encounters",
27252
27373
  "slideType": "text",
27253
- "layoutHint": "text-1x-left"
27374
+ "layoutHint": "text-1x"
27254
27375
  },
27255
27376
  {
27256
27377
  "id": "pivot",
@@ -27258,7 +27379,7 @@ var narratives = [
27258
27379
  "description": "Highlight the strategic shift that changed the trajectory. What got reconsidered, what got dropped, what got doubled down on. The pivot is the moment the protagonist became something new.",
27259
27380
  "instructions": "Highlight strategy shift",
27260
27381
  "slideType": "text",
27261
- "layoutHint": "text-1x-left"
27382
+ "layoutHint": "text-1x"
27262
27383
  },
27263
27384
  {
27264
27385
  "id": "breakthrough",
@@ -27266,7 +27387,7 @@ var narratives = [
27266
27387
  "description": "Emphasize the moment adversity finally broke. Concrete result, concrete date. Let the slide land \u2014 the audience came for this turn.",
27267
27388
  "instructions": "Emphasize overcoming adversity",
27268
27389
  "slideType": "text",
27269
- "layoutHint": "text-1x-left"
27390
+ "layoutHint": "text-1x"
27270
27391
  },
27271
27392
  {
27272
27393
  "id": "legacy",
@@ -27274,13 +27395,13 @@ var narratives = [
27274
27395
  "description": "Discuss the enduring impact. What survival made possible afterward, who benefited, what was built on top. Survival stories are most powerful when they create more than they restore.",
27275
27396
  "instructions": "Discuss enduring impact",
27276
27397
  "slideType": "text",
27277
- "layoutHint": "text-1x-left"
27398
+ "layoutHint": "text-1x"
27278
27399
  },
27279
27400
  {
27280
27401
  "id": "takeaway",
27281
27402
  "name": "Takeaway",
27282
27403
  "description": "Share the lesson the audience can carry away. One transferable insight, framed for their own challenges \u2014 not a general moral.",
27283
- "layoutHint": "title-left",
27404
+ "layoutHint": "title",
27284
27405
  "instructions": "Share important lessons",
27285
27406
  "slideType": "text"
27286
27407
  }
@@ -27313,7 +27434,7 @@ var narratives = [
27313
27434
  "description": "Introduce the topic in a way that respects the audience's time and curiosity. Frame why this question is worth asking, and signal the shape of the journey ahead without giving away the destination.",
27314
27435
  "instructions": "Introduce the topic",
27315
27436
  "slideType": "text",
27316
- "layoutHint": "text-1x-left"
27437
+ "layoutHint": "text-1x"
27317
27438
  },
27318
27439
  {
27319
27440
  "id": "surprising-fact",
@@ -27321,7 +27442,7 @@ var narratives = [
27321
27442
  "description": "Lead with a single curious fact that recasts how the audience thinks about the topic. The fact should be small, specific, and unforgettable \u2014 the cognitive door the rest of the talk walks through.",
27322
27443
  "instructions": "Share a curious fact",
27323
27444
  "slideType": "text",
27324
- "layoutHint": "text-1x-left"
27445
+ "layoutHint": "text-1x"
27325
27446
  },
27326
27447
  {
27327
27448
  "id": "experiment",
@@ -27329,7 +27450,7 @@ var narratives = [
27329
27450
  "description": "Walk through a method, study, or thought experiment that probes the surprising fact. Show how knowledge here gets made \u2014 the audience should feel like they're shoulder-to-shoulder with the investigator.",
27330
27451
  "instructions": "Explain a tried method",
27331
27452
  "slideType": "text",
27332
- "layoutHint": "text-1x-left"
27453
+ "layoutHint": "text-1x"
27333
27454
  },
27334
27455
  {
27335
27456
  "id": "amusing-anecdote",
@@ -27337,7 +27458,7 @@ var narratives = [
27337
27458
  "description": "Drop in a story or moment from the field that brings the topic to human scale. Personality and humor here keep the audience leaning forward; technical depth without warmth loses the room.",
27338
27459
  "instructions": "Relay an interesting story",
27339
27460
  "slideType": "text",
27340
- "layoutHint": "text-1x-left"
27461
+ "layoutHint": "text-1x"
27341
27462
  },
27342
27463
  {
27343
27464
  "id": "intriguing-information",
@@ -27345,7 +27466,7 @@ var narratives = [
27345
27466
  "description": "Layer in the more complex data or detail. By this point the audience is invested enough to do real work alongside you. Visualize generously \u2014 make the numbers tangible.",
27346
27467
  "instructions": "Share complex data",
27347
27468
  "slideType": "text",
27348
- "layoutHint": "text-1x-left"
27469
+ "layoutHint": "text-1x"
27349
27470
  },
27350
27471
  {
27351
27472
  "id": "skeptical-scrutiny",
@@ -27353,7 +27474,7 @@ var narratives = [
27353
27474
  "description": "Question the easy interpretations. Challenge the audience's defaults and your own. Showing where the evidence is contested is what separates a teacher from a publicist.",
27354
27475
  "instructions": "Encourage questioning of accepted truths",
27355
27476
  "slideType": "text",
27356
- "layoutHint": "text-1x-left"
27477
+ "layoutHint": "text-1x"
27357
27478
  },
27358
27479
  {
27359
27480
  "id": "extraordinary-explanation",
@@ -27361,7 +27482,7 @@ var narratives = [
27361
27482
  "description": "Present the most counterintuitive or beautiful explanation the topic offers. Take your time here \u2014 this is the payoff slide the audience came for.",
27362
27483
  "instructions": "Break down unusual research findings",
27363
27484
  "slideType": "text",
27364
- "layoutHint": "text-1x-left"
27485
+ "layoutHint": "text-1x"
27365
27486
  },
27366
27487
  {
27367
27488
  "id": "unconventional-use",
@@ -27369,13 +27490,13 @@ var narratives = [
27369
27490
  "description": "Show an unexpected application or implication of the idea. Surprise reinforces the lesson and gives the audience a story to retell tomorrow.",
27370
27491
  "instructions": "Expand on unique aspects",
27371
27492
  "slideType": "text",
27372
- "layoutHint": "text-1x-left"
27493
+ "layoutHint": "text-1x"
27373
27494
  },
27374
27495
  {
27375
27496
  "id": "captivating-conclusion",
27376
27497
  "name": "Captivating Conclusion",
27377
27498
  "description": "Close with a thoughtful, slightly poetic wrap-up. Echo the surprising fact, name the lesson, and leave the audience with a new question instead of a tidy answer.",
27378
- "layoutHint": "title-left",
27499
+ "layoutHint": "title",
27379
27500
  "instructions": "Provide a thoughtful wrap-up",
27380
27501
  "slideType": "text"
27381
27502
  }
@@ -27408,7 +27529,7 @@ var narratives = [
27408
27529
  "description": "Open with a moment, image, or claim the audience can't easily look away from. The first sixty seconds buy you the next twenty minutes \u2014 spend them on something specific and emotionally charged, not on housekeeping.",
27409
27530
  "instructions": "Draw in the audience with a compelling opener",
27410
27531
  "slideType": "text",
27411
- "layoutHint": "text-1x-left"
27532
+ "layoutHint": "text-1x"
27412
27533
  },
27413
27534
  {
27414
27535
  "id": "challenge-status-quo",
@@ -27426,7 +27547,7 @@ var narratives = [
27426
27547
  "description": "Anchor the issue in a specific person, place, or moment. Story is what gets the argument past the audience's defenses. Pick a story that personalizes the data without overstating it.",
27427
27548
  "instructions": "Share significant stories to illuminate the issue",
27428
27549
  "slideType": "text",
27429
- "layoutHint": "text-1x-left"
27550
+ "layoutHint": "text-1x"
27430
27551
  },
27431
27552
  {
27432
27553
  "id": "statistic-shock",
@@ -27434,7 +27555,7 @@ var narratives = [
27434
27555
  "description": "Drop in a single statistic that recasts the scale of the problem. One number, presented well, lands harder than a dashboard. Cite the source so the audience can repeat it with confidence.",
27435
27556
  "instructions": "Use impactful stats to highlight the gravity of the issue",
27436
27557
  "slideType": "text",
27437
- "layoutHint": "text-1x-left"
27558
+ "layoutHint": "text-1x"
27438
27559
  },
27439
27560
  {
27440
27561
  "id": "historical-context",
@@ -27442,7 +27563,7 @@ var narratives = [
27442
27563
  "description": "Show how the issue evolved. Why it has the shape it does today, what was tried, what was missed. Historical context turns 'this is broken' into 'this stayed broken for these reasons.'",
27443
27564
  "instructions": "Show the evolution or history of the issue",
27444
27565
  "slideType": "text",
27445
- "layoutHint": "text-1x-left"
27566
+ "layoutHint": "text-1x"
27446
27567
  },
27447
27568
  {
27448
27569
  "id": "weave-narrative",
@@ -27455,7 +27576,7 @@ var narratives = [
27455
27576
  "description": "Deliver the surprising or significant turn. The fact, finding, or reframing the rest of the talk has been earning. The revelation should redirect, not merely confirm.",
27456
27577
  "instructions": "Deliver a surprising or significant discovery",
27457
27578
  "slideType": "text",
27458
- "layoutHint": "text-1x-left"
27579
+ "layoutHint": "text-1x"
27459
27580
  },
27460
27581
  {
27461
27582
  "id": "propose-solution",
@@ -27463,13 +27584,13 @@ var narratives = [
27463
27584
  "description": "Advocate for the change you want. Concrete enough to be acted on, broad enough to inspire. Pair the solution with the smallest credible first step.",
27464
27585
  "instructions": "Advocate for change or propose an actionable solution",
27465
27586
  "slideType": "text",
27466
- "layoutHint": "text-1x-left"
27587
+ "layoutHint": "text-1x"
27467
27588
  },
27468
27589
  {
27469
27590
  "id": "final-question",
27470
27591
  "name": "Final Question",
27471
27592
  "description": "Close on a question rather than a summary. The right closing question follows the audience out of the room and into their conversations afterward.",
27472
- "layoutHint": "title-left",
27593
+ "layoutHint": "title",
27473
27594
  "instructions": "Finish with a thought-provoking question to stimulate audience thinking",
27474
27595
  "slideType": "text"
27475
27596
  }
@@ -27502,7 +27623,7 @@ var narratives = [
27502
27623
  "description": "Open with a personal experience that establishes why the topic matters to you. Specificity earns intimacy; intimacy earns the audience's permission to be moved.",
27503
27624
  "instructions": "Share personal experiences to connect with the audience",
27504
27625
  "slideType": "text",
27505
- "layoutHint": "text-1x-left"
27626
+ "layoutHint": "text-1x"
27506
27627
  },
27507
27628
  {
27508
27629
  "id": "research-exposition",
@@ -27510,7 +27631,7 @@ var narratives = [
27510
27631
  "description": "Lay out the scientific or empirical data that backs the premise. Be rigorous but not academic \u2014 the audience needs to understand the evidence well enough to defend it later.",
27511
27632
  "instructions": "Unravel scientific data backing the premise",
27512
27633
  "slideType": "text",
27513
- "layoutHint": "text-1x-left"
27634
+ "layoutHint": "text-1x"
27514
27635
  },
27515
27636
  {
27516
27637
  "id": "real-life-anecdote",
@@ -27518,7 +27639,7 @@ var narratives = [
27518
27639
  "description": "Illustrate the research with a story from the field. Make the abstract finding feel like something that happens to people the audience could imagine being.",
27519
27640
  "instructions": "Illustrate with stories to make the point relatable",
27520
27641
  "slideType": "text",
27521
- "layoutHint": "text-1x-left"
27642
+ "layoutHint": "text-1x"
27522
27643
  },
27523
27644
  {
27524
27645
  "id": "critical-insights",
@@ -27526,7 +27647,7 @@ var narratives = [
27526
27647
  "description": "Summarize the two or three findings the audience must walk away with. Distill them into language a non-specialist could repeat without distortion.",
27527
27648
  "instructions": "Summarize key points",
27528
27649
  "slideType": "text",
27529
- "layoutHint": "text-1x-left"
27650
+ "layoutHint": "text-1x"
27530
27651
  },
27531
27652
  {
27532
27653
  "id": "break-stereotypes",
@@ -27534,7 +27655,7 @@ var narratives = [
27534
27655
  "description": "Question redundant norms or beliefs the research undermines. Be specific about what's being challenged so the audience knows what to update.",
27535
27656
  "instructions": "Question redundant norms and belief systems",
27536
27657
  "slideType": "text",
27537
- "layoutHint": "text-1x-left"
27658
+ "layoutHint": "text-1x"
27538
27659
  },
27539
27660
  {
27540
27661
  "id": "empowering-advice",
@@ -27542,7 +27663,7 @@ var narratives = [
27542
27663
  "description": "Translate the insights into a small, actionable practice. The advice should be doable today, not only next quarter \u2014 the goal is movement, not aspiration.",
27543
27664
  "instructions": "Motivational message to act upon",
27544
27665
  "slideType": "text",
27545
- "layoutHint": "text-1x-left"
27666
+ "layoutHint": "text-1x"
27546
27667
  },
27547
27668
  {
27548
27669
  "id": "authenticity",
@@ -27550,13 +27671,13 @@ var narratives = [
27550
27671
  "description": "Speak honestly about your own struggle with the topic. Vulnerability, used with restraint, is what turns research into a felt truth.",
27551
27672
  "instructions": "Honest and real communication to demonstrate authenticity",
27552
27673
  "slideType": "text",
27553
- "layoutHint": "text-1x-left"
27674
+ "layoutHint": "text-1x"
27554
27675
  },
27555
27676
  {
27556
27677
  "id": "close-with-impact",
27557
27678
  "name": "Close With Impact",
27558
27679
  "description": "End on a motivational high \u2014 the line, image, or invitation you want to follow the audience out of the room. Close the talk where it began, transformed.",
27559
- "layoutHint": "title-left",
27680
+ "layoutHint": "title",
27560
27681
  "instructions": "End on a motivational high",
27561
27682
  "slideType": "text"
27562
27683
  }
@@ -27590,7 +27711,7 @@ var narratives = [
27590
27711
  "description": "Set the stage with a moment that earns the audience's full attention. Speak in the moral register the rest of the talk will require. Avoid throat-clearing \u2014 open as if the speech were already underway.",
27591
27712
  "instructions": "Set the stage",
27592
27713
  "slideType": "text",
27593
- "layoutHint": "text-1x-left"
27714
+ "layoutHint": "text-1x"
27594
27715
  },
27595
27716
  {
27596
27717
  "id": "give-context",
@@ -27598,7 +27719,7 @@ var narratives = [
27598
27719
  "description": "Place the issue in its historical and current context. What promises were made, what has and hasn't been kept. Context turns the speech from opinion into accountability.",
27599
27720
  "instructions": "Put in historical and current context",
27600
27721
  "slideType": "text",
27601
- "layoutHint": "text-1x-left"
27722
+ "layoutHint": "text-1x"
27602
27723
  },
27603
27724
  {
27604
27725
  "id": "highlight-inequality",
@@ -27606,7 +27727,7 @@ var narratives = [
27606
27727
  "description": "Show specific, undeniable examples of the inequality at issue. Concrete moments and people, not abstractions. The audience should feel the gap between what is and what was promised.",
27607
27728
  "instructions": "Show examples of inequality",
27608
27729
  "slideType": "text",
27609
- "layoutHint": "text-1x-left"
27730
+ "layoutHint": "text-1x"
27610
27731
  },
27611
27732
  {
27612
27733
  "id": "share-dream",
@@ -27614,7 +27735,7 @@ var narratives = [
27614
27735
  "description": "Describe the future you envision in vivid, specific detail. The dream must be both ambitious and recognizable \u2014 a world the audience can picture themselves living in.",
27615
27736
  "instructions": "Describe your vision",
27616
27737
  "slideType": "text",
27617
- "layoutHint": "text-1x-left"
27738
+ "layoutHint": "text-1x"
27618
27739
  },
27619
27740
  {
27620
27741
  "id": "create-urgency",
@@ -27622,7 +27743,7 @@ var narratives = [
27622
27743
  "description": "Explain why the time for change is now. The cost of waiting, the moment that won't return. Urgency converts shared vision into shared movement.",
27623
27744
  "instructions": "Explain the need for immediate change",
27624
27745
  "slideType": "text",
27625
- "layoutHint": "text-1x-left"
27746
+ "layoutHint": "text-1x"
27626
27747
  },
27627
27748
  {
27628
27749
  "id": "another-dream",
@@ -27630,7 +27751,7 @@ var narratives = [
27630
27751
  "description": "Layer additional visions of the future in parallel structure. Repetition and rhythm build momentum the way a single image cannot.",
27631
27752
  "instructions": "Continue to elaborate on your vision",
27632
27753
  "slideType": "text",
27633
- "layoutHint": "text-1x-left"
27754
+ "layoutHint": "text-1x"
27634
27755
  },
27635
27756
  {
27636
27757
  "id": "emphasize-unity",
@@ -27638,7 +27759,7 @@ var narratives = [
27638
27759
  "description": "Speak to the collective power of the audience together. Name common ground that crosses lines the issue normally divides. Unity is the engine that turns dream into march.",
27639
27760
  "instructions": "Talk about collective power",
27640
27761
  "slideType": "text",
27641
- "layoutHint": "text-1x-left"
27762
+ "layoutHint": "text-1x"
27642
27763
  },
27643
27764
  {
27644
27765
  "id": "last-dream",
@@ -27646,7 +27767,7 @@ var narratives = [
27646
27767
  "description": "Deliver one more, fully realized vision of the world you're calling for. Specific enough to be remembered, expansive enough to inspire.",
27647
27768
  "instructions": "Further share dreams of ideal in-depth",
27648
27769
  "slideType": "text",
27649
- "layoutHint": "text-1x-left"
27770
+ "layoutHint": "text-1x"
27650
27771
  },
27651
27772
  {
27652
27773
  "id": "call-to-action",
@@ -27654,7 +27775,7 @@ var narratives = [
27654
27775
  "description": "Ask the audience to participate in the change. Be specific about what 'doing something' looks like \u2014 show, march, give, vote, organize. Vague CTAs produce vague action.",
27655
27776
  "instructions": "Ask audience to participate in change",
27656
27777
  "slideType": "text",
27657
- "layoutHint": "text-1x-left"
27778
+ "layoutHint": "text-1x"
27658
27779
  },
27659
27780
  {
27660
27781
  "id": "show-determination",
@@ -27662,13 +27783,13 @@ var narratives = [
27662
27783
  "description": "Encourage persistence in the face of resistance. Acknowledge what will be hard. Determination, named honestly, is more durable than easy optimism.",
27663
27784
  "instructions": "Encourage persistence",
27664
27785
  "slideType": "text",
27665
- "layoutHint": "text-1x-left"
27786
+ "layoutHint": "text-1x"
27666
27787
  },
27667
27788
  {
27668
27789
  "id": "create-hope",
27669
27790
  "name": "Create Hope",
27670
27791
  "description": "Close on hope grounded in evidence: progress already made, victories already won, ground already moved. Hope as a conclusion lands strongest when it sounds like it has been earned.",
27671
- "layoutHint": "title-left",
27792
+ "layoutHint": "title",
27672
27793
  "instructions": "Inspire hope for future",
27673
27794
  "slideType": "text"
27674
27795
  }
@@ -27700,7 +27821,7 @@ var narratives = [
27700
27821
  "id": "opening",
27701
27822
  "name": "Opening",
27702
27823
  "description": "Set the stage. Tell the audience they're about to see something that matters, without yet showing it. The pause before the reveal is part of the reveal.",
27703
- "layoutHint": "title-left",
27824
+ "layoutHint": "title",
27704
27825
  "instructions": "Set the stage",
27705
27826
  "slideType": "text"
27706
27827
  },
@@ -27710,7 +27831,7 @@ var narratives = [
27710
27831
  "description": "Announce the product. One image, one name, one sentence. Anything more competes with the moment. The slide should feel like the curtain going up.",
27711
27832
  "instructions": "Announce product",
27712
27833
  "slideType": "text",
27713
- "layoutHint": "text-1x-left"
27834
+ "layoutHint": "text-1x"
27714
27835
  },
27715
27836
  {
27716
27837
  "id": "demonstration",
@@ -27718,7 +27839,7 @@ var narratives = [
27718
27839
  "description": "Show the product in real use. Choose a single defining workflow that captures what the product does and how it feels. Live beats canned wherever possible.",
27719
27840
  "instructions": "Showcase the product",
27720
27841
  "slideType": "text",
27721
- "layoutHint": "text-1x-left"
27842
+ "layoutHint": "text-1x"
27722
27843
  },
27723
27844
  {
27724
27845
  "id": "wow-factor",
@@ -27726,7 +27847,7 @@ var narratives = [
27726
27847
  "description": "Highlight the cutting-edge feature that earns the headline. One thing, presented well \u2014 the audience should leave able to repeat it in a sentence.",
27727
27848
  "instructions": "Highlight cutting-edge features",
27728
27849
  "slideType": "text",
27729
- "layoutHint": "text-1x-left"
27850
+ "layoutHint": "text-1x"
27730
27851
  },
27731
27852
  {
27732
27853
  "id": "differentiation",
@@ -27734,7 +27855,7 @@ var narratives = [
27734
27855
  "description": "Make the contrast with existing alternatives unmistakable. Use comparisons that the audience already understands; don't argue against straw versions of the competition.",
27735
27856
  "instructions": "Distinctive factors",
27736
27857
  "slideType": "text",
27737
- "layoutHint": "text-1x-left"
27858
+ "layoutHint": "text-1x"
27738
27859
  },
27739
27860
  {
27740
27861
  "id": "revolution",
@@ -27742,7 +27863,7 @@ var narratives = [
27742
27863
  "description": "Reframe the category. Show how the product changes what the playing field looks like, not just where you sit on it. This is the slide pundits will quote.",
27743
27864
  "instructions": "Change in the playing field",
27744
27865
  "slideType": "text",
27745
- "layoutHint": "text-1x-left"
27866
+ "layoutHint": "text-1x"
27746
27867
  },
27747
27868
  {
27748
27869
  "id": "excitement",
@@ -27750,7 +27871,7 @@ var narratives = [
27750
27871
  "description": "Build anticipation around what's next: availability, partnerships, what the audience can imagine doing with the product. Excitement is how the room exits the keynote into the world.",
27751
27872
  "instructions": "Build anticipation",
27752
27873
  "slideType": "text",
27753
- "layoutHint": "text-1x-left"
27874
+ "layoutHint": "text-1x"
27754
27875
  },
27755
27876
  {
27756
27877
  "id": "call-to-action",
@@ -27758,13 +27879,13 @@ var narratives = [
27758
27879
  "description": "Give the audience the action that channels the excitement. Pre-order, try it, tell others. Be specific so the energy converts into behavior.",
27759
27880
  "instructions": "Urge to explore",
27760
27881
  "slideType": "text",
27761
- "layoutHint": "text-1x-left"
27882
+ "layoutHint": "text-1x"
27762
27883
  },
27763
27884
  {
27764
27885
  "id": "gratitude",
27765
27886
  "name": "Gratitude",
27766
27887
  "description": "Thank the team that built it and the audience that came. Brief, sincere, not perfunctory. The closing thanks is the period at the end of the keynote.",
27767
- "layoutHint": "title-left",
27888
+ "layoutHint": "title",
27768
27889
  "instructions": "Thank the audience",
27769
27890
  "slideType": "text"
27770
27891
  }
@@ -27798,7 +27919,7 @@ var narratives = [
27798
27919
  "description": "Open with a brief framing of what this update is for and what you intend to leave the audience with. Set the tone \u2014 long-term, candid, principle-driven.",
27799
27920
  "instructions": "Overview and objectives",
27800
27921
  "slideType": "text",
27801
- "layoutHint": "text-1x-left"
27922
+ "layoutHint": "text-1x"
27802
27923
  },
27803
27924
  {
27804
27925
  "id": "accomplishments",
@@ -27806,7 +27927,7 @@ var narratives = [
27806
27927
  "description": "Showcase the period's most material wins, briefly. The audience came for what's next; wins earn permission for the harder slides ahead, but they aren't the headline.",
27807
27928
  "instructions": "Showcase recent achievements",
27808
27929
  "slideType": "text",
27809
- "layoutHint": "text-1x-left"
27930
+ "layoutHint": "text-1x"
27810
27931
  },
27811
27932
  {
27812
27933
  "id": "potential",
@@ -27814,7 +27935,7 @@ var narratives = [
27814
27935
  "description": "Detail the market and customer opportunities ahead. Size them honestly and connect them to the work already underway. Potential without specifics reads as wishful.",
27815
27936
  "instructions": "Detail market opportunities",
27816
27937
  "slideType": "text",
27817
- "layoutHint": "text-1x-left"
27938
+ "layoutHint": "text-1x"
27818
27939
  },
27819
27940
  {
27820
27941
  "id": "competitive-edge",
@@ -27822,7 +27943,7 @@ var narratives = [
27822
27943
  "description": "Reveal the strategic positioning that gives the business its advantage. Frame it as a structural moat, not a list of features. The audience should be able to repeat the moat in their own words.",
27823
27944
  "instructions": "Reveal strategic positioning",
27824
27945
  "slideType": "text",
27825
- "layoutHint": "text-1x-left"
27946
+ "layoutHint": "text-1x"
27826
27947
  },
27827
27948
  {
27828
27949
  "id": "long-term-vision",
@@ -27830,7 +27951,7 @@ var narratives = [
27830
27951
  "description": "Emphasize the long-term view that anchors decisions. Quarters serve years; years serve decades. Anchor the audience in the time horizon you actually run the business on.",
27831
27952
  "instructions": "Emphasize focused future orientation",
27832
27953
  "slideType": "text",
27833
- "layoutHint": "text-1x-left"
27954
+ "layoutHint": "text-1x"
27834
27955
  },
27835
27956
  {
27836
27957
  "id": "performance-metrics",
@@ -27838,7 +27959,7 @@ var narratives = [
27838
27959
  "description": "Illuminate the indicators that show the long-term thesis is working. Choose metrics that compound \u2014 retention, NPS, unit economics \u2014 over those that flatter.",
27839
27960
  "instructions": "Illuminate growth indicators",
27840
27961
  "slideType": "text",
27841
- "layoutHint": "text-1x-left"
27962
+ "layoutHint": "text-1x"
27842
27963
  },
27843
27964
  {
27844
27965
  "id": "growth-achievement",
@@ -27846,7 +27967,7 @@ var narratives = [
27846
27967
  "description": "Certify the tangible progress against the long-term plan. Year-over-year, cohort behavior, expanded reach. Growth, in this beat, is evidence that the strategy is real.",
27847
27968
  "instructions": "Certify tangible progress",
27848
27969
  "slideType": "text",
27849
- "layoutHint": "text-1x-left"
27970
+ "layoutHint": "text-1x"
27850
27971
  },
27851
27972
  {
27852
27973
  "id": "strategic-framework",
@@ -27854,7 +27975,7 @@ var narratives = [
27854
27975
  "description": "Explain the principles that guide decisions. Customer obsession, long-term thinking, frugality, ownership \u2014 whatever the actual operating discipline is. Principles are the connective tissue between strategy and behavior.",
27855
27976
  "instructions": "Explain decision principles",
27856
27977
  "slideType": "text",
27857
- "layoutHint": "text-1x-left"
27978
+ "layoutHint": "text-1x"
27858
27979
  },
27859
27980
  {
27860
27981
  "id": "expansion",
@@ -27862,7 +27983,7 @@ var narratives = [
27862
27983
  "description": "Detail the next areas of growth: products, segments, geographies. Tie each to the principles above so the audience sees expansion as continuity rather than scatter.",
27863
27984
  "instructions": "Detail growth potential",
27864
27985
  "slideType": "text",
27865
- "layoutHint": "text-1x-left"
27986
+ "layoutHint": "text-1x"
27866
27987
  },
27867
27988
  {
27868
27989
  "id": "future-objectives",
@@ -27870,7 +27991,7 @@ var narratives = [
27870
27991
  "description": "Forecast the targets and commitments for the period ahead. Be specific enough to be held accountable. Vague objectives are how strategies erode.",
27871
27992
  "instructions": "Forecast upcoming targets",
27872
27993
  "slideType": "text",
27873
- "layoutHint": "text-1x-left"
27994
+ "layoutHint": "text-1x"
27874
27995
  },
27875
27996
  {
27876
27997
  "id": "acknowledgment",
@@ -27878,13 +27999,13 @@ var narratives = [
27878
27999
  "description": "Recognize the contributions of teams, customers, and partners that made the period possible. Specific names land harder than blanket thanks.",
27879
28000
  "instructions": "Recognize contributions and successes",
27880
28001
  "slideType": "text",
27881
- "layoutHint": "text-1x-left"
28002
+ "layoutHint": "text-1x"
27882
28003
  },
27883
28004
  {
27884
28005
  "id": "closing-remarks",
27885
28006
  "name": "Closing Remarks",
27886
28007
  "description": "Recap the focus, thank the audience, and inspire the work ahead. End with the line you most want quoted in tomorrow's newsletter.",
27887
- "layoutHint": "title-left",
28008
+ "layoutHint": "title",
27888
28009
  "instructions": "Recap, thank, inspire",
27889
28010
  "slideType": "text"
27890
28011
  }
@@ -27915,7 +28036,7 @@ var narratives = [
27915
28036
  "id": "objectives",
27916
28037
  "name": "Objectives",
27917
28038
  "description": "Open with what this review is for and what decisions you want out of it. Frame the scope and the hour ahead, so the audience knows what they're being asked to weigh in on.",
27918
- "layoutHint": "title-center",
28039
+ "layoutHint": "title",
27919
28040
  "instructions": "Set the expectations",
27920
28041
  "slideType": "text"
27921
28042
  },
@@ -27945,7 +28066,7 @@ var narratives = [
27945
28066
  "description": "Name the misses and headwinds honestly. What didn't work, what's still hard, what got harder. Pretending things are fine costs more credibility than acknowledging they aren't.",
27946
28067
  "instructions": "Address difficulties",
27947
28068
  "slideType": "text",
27948
- "layoutHint": "text-1x-left"
28069
+ "layoutHint": "text-1x"
27949
28070
  },
27950
28071
  {
27951
28072
  "id": "insights",
@@ -27971,7 +28092,7 @@ var narratives = [
27971
28092
  "id": "asks",
27972
28093
  "name": "Asks",
27973
28094
  "description": "Specific, named requests of the audience. Decisions needed, resources required, escalations to unblock. End with clarity on what happens next and who owns it.",
27974
- "layoutHint": "title-left"
28095
+ "layoutHint": "title"
27975
28096
  }
27976
28097
  ]
27977
28098
  },
@@ -28000,7 +28121,7 @@ var narratives = [
28000
28121
  "id": "logo",
28001
28122
  "name": "Logo",
28002
28123
  "description": "Cover slide with logos and the review period. Establishes brand identity and signals the level of formality the rest of the deck will hold to.",
28003
- "layoutHint": "title-left",
28124
+ "layoutHint": "title",
28004
28125
  "instructions": "Identity & representation",
28005
28126
  "slideType": "text"
28006
28127
  },
@@ -28010,7 +28131,7 @@ var narratives = [
28010
28131
  "description": "Frame the meeting context and the goals for the next hour. What you'll cover, what decisions you want, what you don't intend to relitigate.",
28011
28132
  "instructions": "Meeting context & goals",
28012
28133
  "slideType": "text",
28013
- "layoutHint": "text-1x-left"
28134
+ "layoutHint": "text-1x"
28014
28135
  },
28015
28136
  {
28016
28137
  "id": "review",
@@ -28018,7 +28139,7 @@ var narratives = [
28018
28139
  "description": "Outline the recent activities in scope: launches, projects, programs. Just enough scope-setting that the rest of the deck has shared vocabulary.",
28019
28140
  "instructions": "Outline recent activities",
28020
28141
  "slideType": "text",
28021
- "layoutHint": "text-1x-left"
28142
+ "layoutHint": "text-1x"
28022
28143
  },
28023
28144
  {
28024
28145
  "id": "successes",
@@ -28026,7 +28147,7 @@ var narratives = [
28026
28147
  "description": "Recognize the achievements in the review window. Lead with outcomes the audience cares about, not effort. Specific moves earn more credibility than aggregate progress.",
28027
28148
  "instructions": "Recognize achievements",
28028
28149
  "slideType": "text",
28029
- "layoutHint": "text-1x-left"
28150
+ "layoutHint": "text-1x"
28030
28151
  },
28031
28152
  {
28032
28153
  "id": "challenges",
@@ -28034,7 +28155,7 @@ var narratives = [
28034
28155
  "description": "Address the problems faced honestly. What didn't work, what's still hard. Naming challenges in front of the audience earns more trust than letting them ask.",
28035
28156
  "instructions": "Address problems faced",
28036
28157
  "slideType": "text",
28037
- "layoutHint": "text-1x-left"
28158
+ "layoutHint": "text-1x"
28038
28159
  },
28039
28160
  {
28040
28161
  "id": "solutions",
@@ -28042,7 +28163,7 @@ var narratives = [
28042
28163
  "description": "Discuss the fixes already implemented. Pair each with the result it produced, or, if it's still in flight, with the leading indicator you're watching.",
28043
28164
  "instructions": "Discuss implemented fixes",
28044
28165
  "slideType": "text",
28045
- "layoutHint": "text-1x-left"
28166
+ "layoutHint": "text-1x"
28046
28167
  },
28047
28168
  {
28048
28169
  "id": "outcome",
@@ -28050,7 +28171,7 @@ var narratives = [
28050
28171
  "description": "Display the results achieved across the review window. Let the data carry the slide; supporting commentary should explain context, not inflate the numbers.",
28051
28172
  "instructions": "Display results achieved",
28052
28173
  "slideType": "text",
28053
- "layoutHint": "text-1x-left"
28174
+ "layoutHint": "text-1x"
28054
28175
  },
28055
28176
  {
28056
28177
  "id": "insights",
@@ -28058,7 +28179,7 @@ var narratives = [
28058
28179
  "description": "Highlight the key learnings. What was confirmed, what surprised you, what the audience should take away. Insights are the slides people quote in follow-on meetings.",
28059
28180
  "instructions": "Highlight key learnings",
28060
28181
  "slideType": "text",
28061
- "layoutHint": "text-1x-left"
28182
+ "layoutHint": "text-1x"
28062
28183
  },
28063
28184
  {
28064
28185
  "id": "future-strategy",
@@ -28066,7 +28187,7 @@ var narratives = [
28066
28187
  "description": "Define the next steps and the strategic direction that follows from the review. Specific enough to sequence; flexible enough to adapt.",
28067
28188
  "instructions": "Define next steps",
28068
28189
  "slideType": "text",
28069
- "layoutHint": "text-1x-left"
28190
+ "layoutHint": "text-1x"
28070
28191
  },
28071
28192
  {
28072
28193
  "id": "feedback",
@@ -28074,7 +28195,7 @@ var narratives = [
28074
28195
  "description": "Capture audience thoughts. Two or three explicit prompts where you want input or alignment. The strength of a relationship review is in the conversation it provokes.",
28075
28196
  "instructions": "Capture audience thoughts",
28076
28197
  "slideType": "text",
28077
- "layoutHint": "text-1x-left"
28198
+ "layoutHint": "text-1x"
28078
28199
  },
28079
28200
  {
28080
28201
  "id": "next-review",
@@ -28082,13 +28203,13 @@ var narratives = [
28082
28203
  "description": "Plan for follow-up: when the next review happens, what evidence you'll bring, what decisions are deferred until then. Continuity is the point of the cadence.",
28083
28204
  "instructions": "Plan for follow-up",
28084
28205
  "slideType": "text",
28085
- "layoutHint": "text-1x-left"
28206
+ "layoutHint": "text-1x"
28086
28207
  },
28087
28208
  {
28088
28209
  "id": "closing",
28089
28210
  "name": "Closing",
28090
28211
  "description": "Recap and express optimism about the path forward. Close with the next concrete step and the people responsible for it.",
28091
- "layoutHint": "title-left",
28212
+ "layoutHint": "title",
28092
28213
  "instructions": "Recap and express optimism",
28093
28214
  "slideType": "text"
28094
28215
  }
@@ -28120,7 +28241,7 @@ var narratives = [
28120
28241
  "id": "introduction",
28121
28242
  "name": "Introduction",
28122
28243
  "description": "Set the tone for the meeting and walk through the agenda in one slide. Signal which sections are for discussion versus information so directors know where their time is most valuable.",
28123
- "layoutHint": "title-left",
28244
+ "layoutHint": "title",
28124
28245
  "instructions": "Set the tone",
28125
28246
  "slideType": "text"
28126
28247
  },
@@ -28130,7 +28251,7 @@ var narratives = [
28130
28251
  "description": "Deliver the CEO's view of the period: what changed, what mattered, where the company stands. Two or three sentences in the speaker's voice \u2014 board members read this slide first.",
28131
28252
  "instructions": "Deliver company insights",
28132
28253
  "slideType": "text",
28133
- "layoutHint": "text-1x-left"
28254
+ "layoutHint": "text-1x"
28134
28255
  },
28135
28256
  {
28136
28257
  "id": "highlights",
@@ -28138,7 +28259,7 @@ var narratives = [
28138
28259
  "description": "Share major successes across the business. Customer wins, launches, hires, milestones. Specific and brief; this is the slide that sets the tone, not the slide that proves the case.",
28139
28260
  "instructions": "Share major successes",
28140
28261
  "slideType": "text",
28141
- "layoutHint": "text-1x-left"
28262
+ "layoutHint": "text-1x"
28142
28263
  },
28143
28264
  {
28144
28265
  "id": "challenges",
@@ -28146,7 +28267,7 @@ var narratives = [
28146
28267
  "description": "Address the obstacles facing the business honestly. Boards earn their value when surfaced to real problems; under-disclosure here erodes trust faster than the problems themselves.",
28147
28268
  "instructions": "Address potential obstacles",
28148
28269
  "slideType": "text",
28149
- "layoutHint": "text-1x-left"
28270
+ "layoutHint": "text-1x"
28150
28271
  },
28151
28272
  {
28152
28273
  "id": "company-needs",
@@ -28154,7 +28275,7 @@ var narratives = [
28154
28275
  "description": "Identify where the business needs the board's help: introductions, decisions, advice. Specific asks turn the meeting from a report into a working session.",
28155
28276
  "instructions": "Identify support requirements",
28156
28277
  "slideType": "text",
28157
- "layoutHint": "text-1x-left"
28278
+ "layoutHint": "text-1x"
28158
28279
  },
28159
28280
  {
28160
28281
  "id": "funnel-metrics",
@@ -28162,7 +28283,7 @@ var narratives = [
28162
28283
  "description": "Discuss the sales pipeline: leads, conversion, velocity, win rate. Use the metrics that match the company's current motion; resist the temptation to show the same chart you showed last quarter for continuity's sake.",
28163
28284
  "instructions": "Discuss sales progress",
28164
28285
  "slideType": "text",
28165
- "layoutHint": "text-1x-left"
28286
+ "layoutHint": "text-1x"
28166
28287
  },
28167
28288
  {
28168
28289
  "id": "engagement-metrics",
@@ -28170,7 +28291,7 @@ var narratives = [
28170
28291
  "description": "Analyze customer interaction: usage, retention, NPS, expansion. Show whether the product is being loved or only being bought.",
28171
28292
  "instructions": "Analyze customer interaction",
28172
28293
  "slideType": "text",
28173
- "layoutHint": "text-1x-left"
28294
+ "layoutHint": "text-1x"
28174
28295
  },
28175
28296
  {
28176
28297
  "id": "financial-metrics",
@@ -28178,7 +28299,7 @@ var narratives = [
28178
28299
  "description": "Review fiscal health: revenue, gross margin, burn, runway, cash. One slide directors can scan in twenty seconds and trust the numbers on.",
28179
28300
  "instructions": "Review fiscal health",
28180
28301
  "slideType": "text",
28181
- "layoutHint": "text-1x-left"
28302
+ "layoutHint": "text-1x"
28182
28303
  },
28183
28304
  {
28184
28305
  "id": "performance-vs-plan",
@@ -28186,7 +28307,7 @@ var narratives = [
28186
28307
  "description": "Compare actuals to plan across the metrics that matter most. Variance is the slide directors will probe; show your work, name the drivers, propose adjustments.",
28187
28308
  "instructions": "Compare objectives and actuals",
28188
28309
  "slideType": "text",
28189
- "layoutHint": "text-1x-left"
28310
+ "layoutHint": "text-1x"
28190
28311
  },
28191
28312
  {
28192
28313
  "id": "org-chart",
@@ -28194,7 +28315,7 @@ var narratives = [
28194
28315
  "description": "Present the team structure and any key changes since the last meeting. Directors track org evolution as a leading indicator; help them see hires, departures, and reshapes clearly.",
28195
28316
  "instructions": "Present team structure",
28196
28317
  "slideType": "text",
28197
- "layoutHint": "text-1x-left"
28318
+ "layoutHint": "text-1x"
28198
28319
  },
28199
28320
  {
28200
28321
  "id": "product-roadmap",
@@ -28202,7 +28323,7 @@ var narratives = [
28202
28323
  "description": "Highlight the product plan and what ships when. Pair each major bet with the customer or business outcome it serves.",
28203
28324
  "instructions": "Highlight future plans",
28204
28325
  "slideType": "text",
28205
- "layoutHint": "text-1x-left"
28326
+ "layoutHint": "text-1x"
28206
28327
  },
28207
28328
  {
28208
28329
  "id": "quality",
@@ -28210,7 +28331,7 @@ var narratives = [
28210
28331
  "description": "Showcase the product quality bar: reliability, defect rates, support outcomes. Directors take quality as a proxy for engineering culture; let the data speak.",
28211
28332
  "instructions": "Showcase product's standards",
28212
28333
  "slideType": "text",
28213
- "layoutHint": "text-1x-left"
28334
+ "layoutHint": "text-1x"
28214
28335
  },
28215
28336
  {
28216
28337
  "id": "engineering-update",
@@ -28218,7 +28339,7 @@ var narratives = [
28218
28339
  "description": "Communicate technical progress, key bets, and platform investments. Translate engineering work into business consequences directors can evaluate.",
28219
28340
  "instructions": "Communicate technical progress",
28220
28341
  "slideType": "text",
28221
- "layoutHint": "text-1x-left"
28342
+ "layoutHint": "text-1x"
28222
28343
  },
28223
28344
  {
28224
28345
  "id": "marketing-update",
@@ -28226,7 +28347,7 @@ var narratives = [
28226
28347
  "description": "Update on demand-gen, brand, and category-shaping efforts. Connect spend to pipeline and pipeline to revenue; avoid 'campaigns we ran' lists.",
28227
28348
  "instructions": "Update on promotional efforts",
28228
28349
  "slideType": "text",
28229
- "layoutHint": "text-1x-left"
28350
+ "layoutHint": "text-1x"
28230
28351
  },
28231
28352
  {
28232
28353
  "id": "business-development-update",
@@ -28234,7 +28355,7 @@ var narratives = [
28234
28355
  "description": "Speak to growth initiatives: partnerships, channels, alliances. Each entry should have a stage, an owner, and a credible upside.",
28235
28356
  "instructions": "Speak on growth initiatives",
28236
28357
  "slideType": "text",
28237
- "layoutHint": "text-1x-left"
28358
+ "layoutHint": "text-1x"
28238
28359
  },
28239
28360
  {
28240
28361
  "id": "operations-update",
@@ -28242,7 +28363,7 @@ var narratives = [
28242
28363
  "description": "Discuss day-to-day operations: people ops, finance, legal, IT. Brief but explicit \u2014 directors notice when ops is missing.",
28243
28364
  "instructions": "Discuss day-to-day activities",
28244
28365
  "slideType": "text",
28245
- "layoutHint": "text-1x-left"
28366
+ "layoutHint": "text-1x"
28246
28367
  },
28247
28368
  {
28248
28369
  "id": "special-topic-1",
@@ -28250,7 +28371,7 @@ var narratives = [
28250
28371
  "description": "Discuss the period's first deep-dive topic. This is where the board does its highest-leverage work; pose the question, show the analysis, ask for their view.",
28251
28372
  "instructions": "Discuss selected subject",
28252
28373
  "slideType": "text",
28253
- "layoutHint": "text-1x-left"
28374
+ "layoutHint": "text-1x"
28254
28375
  },
28255
28376
  {
28256
28377
  "id": "special-topic-2",
@@ -28258,7 +28379,7 @@ var narratives = [
28258
28379
  "description": "Cover the second deep-dive topic, framed the same way. Two specials per meeting; more, and the meeting becomes a recital.",
28259
28380
  "instructions": "Touch on additional topic",
28260
28381
  "slideType": "text",
28261
- "layoutHint": "text-1x-left"
28382
+ "layoutHint": "text-1x"
28262
28383
  },
28263
28384
  {
28264
28385
  "id": "feedback",
@@ -28266,7 +28387,7 @@ var narratives = [
28266
28387
  "description": "Elicit the board's perspective with concrete prompts. The strength of board governance is in its candor \u2014 invite it explicitly.",
28267
28388
  "instructions": "Elicit board's thoughts",
28268
28389
  "slideType": "text",
28269
- "layoutHint": "text-1x-left"
28390
+ "layoutHint": "text-1x"
28270
28391
  },
28271
28392
  {
28272
28393
  "id": "formalities",
@@ -28274,13 +28395,13 @@ var narratives = [
28274
28395
  "description": "Conclude with the necessary governance items: votes, approvals, committee reports, document acknowledgments. Run them efficiently and document the outcomes.",
28275
28396
  "instructions": "Conclude with necessary formalities",
28276
28397
  "slideType": "text",
28277
- "layoutHint": "text-1x-left"
28398
+ "layoutHint": "text-1x"
28278
28399
  },
28279
28400
  {
28280
28401
  "id": "closing-remarks",
28281
28402
  "name": "Closing Remarks",
28282
28403
  "description": "Close with concluding observations and the agenda for the next meeting. End on a forward-looking note; directors should leave knowing what to watch.",
28283
- "layoutHint": "title-left",
28404
+ "layoutHint": "title",
28284
28405
  "instructions": "Concluding observations",
28285
28406
  "slideType": "text"
28286
28407
  }
@@ -28311,7 +28432,7 @@ var narratives = [
28311
28432
  "id": "opening",
28312
28433
  "name": "Opening",
28313
28434
  "description": "Open with the initiative name, the date, and the one-line headline for the week. Frame the meeting in fifteen seconds so the rest of the time is content.",
28314
- "layoutHint": "title-left",
28435
+ "layoutHint": "title",
28315
28436
  "instructions": "Initiative name & date",
28316
28437
  "slideType": "text"
28317
28438
  },
@@ -28321,7 +28442,7 @@ var narratives = [
28321
28442
  "description": "State what the team set out to do this week. Specific, measurable. The audience should be able to read this slide alone and know what 'on track' would mean.",
28322
28443
  "instructions": "Set the expectations",
28323
28444
  "slideType": "text",
28324
- "layoutHint": "text-1x-left"
28445
+ "layoutHint": "text-1x"
28325
28446
  },
28326
28447
  {
28327
28448
  "id": "achievements",
@@ -28329,7 +28450,7 @@ var narratives = [
28329
28450
  "description": "Celebrate the week's wins. Concrete, attributable, dated. Brevity here \u2014 the meeting is for what's next, not a victory lap.",
28330
28451
  "instructions": "Celebrate success",
28331
28452
  "slideType": "text",
28332
- "layoutHint": "text-1x-left"
28453
+ "layoutHint": "text-1x"
28333
28454
  },
28334
28455
  {
28335
28456
  "id": "overall-progress",
@@ -28337,7 +28458,7 @@ var narratives = [
28337
28458
  "description": "Evaluate performance against the objectives. Use a simple status indicator (green/yellow/red) plus the leading metric. Help the audience scan the state in seconds.",
28338
28459
  "instructions": "Evaluate performance",
28339
28460
  "slideType": "text",
28340
- "layoutHint": "text-1x-left"
28461
+ "layoutHint": "text-1x"
28341
28462
  },
28342
28463
  {
28343
28464
  "id": "challenges",
@@ -28345,7 +28466,7 @@ var narratives = [
28345
28466
  "description": "Address what's hard right now: blockers, slipping items, surfaced risks. Tie each challenge to either an owner working it or a discussion you want this week.",
28346
28467
  "instructions": "Address difficulties",
28347
28468
  "slideType": "text",
28348
- "layoutHint": "text-1x-left"
28469
+ "layoutHint": "text-1x"
28349
28470
  },
28350
28471
  {
28351
28472
  "id": "opportunities-for-improvement",
@@ -28353,7 +28474,7 @@ var narratives = [
28353
28474
  "description": "Surface where the team can level up. Process tweaks, tooling needs, ways of working. Improvement opportunities should feel like seeds, not corrections.",
28354
28475
  "instructions": "Seek growth",
28355
28476
  "slideType": "text",
28356
- "layoutHint": "text-1x-left"
28477
+ "layoutHint": "text-1x"
28357
28478
  },
28358
28479
  {
28359
28480
  "id": "highlights-recognition",
@@ -28361,7 +28482,7 @@ var narratives = [
28361
28482
  "description": "Recognize specific contributions by name. Recognition belongs in the deck, not just in the meeting \u2014 written acknowledgment travels further than verbal.",
28362
28483
  "instructions": "Appreciate efforts",
28363
28484
  "slideType": "text",
28364
- "layoutHint": "text-1x-left"
28485
+ "layoutHint": "text-1x"
28365
28486
  },
28366
28487
  {
28367
28488
  "id": "goals-next-week",
@@ -28369,7 +28490,7 @@ var narratives = [
28369
28490
  "description": "Plan the week ahead with three to five specific goals. Each should be small enough to finish, large enough to matter, and clearly owned.",
28370
28491
  "instructions": "Plan ahead",
28371
28492
  "slideType": "text",
28372
- "layoutHint": "text-1x-left"
28493
+ "layoutHint": "text-1x"
28373
28494
  },
28374
28495
  {
28375
28496
  "id": "discussion-feedback",
@@ -28377,13 +28498,13 @@ var narratives = [
28377
28498
  "description": "Open the floor with two or three prompts \u2014 decisions you need, opinions you want, blockers you'd like cleared. End the recap actively.",
28378
28499
  "instructions": "Encourage input",
28379
28500
  "slideType": "text",
28380
- "layoutHint": "text-1x-left"
28501
+ "layoutHint": "text-1x"
28381
28502
  },
28382
28503
  {
28383
28504
  "id": "conclusion",
28384
28505
  "name": "Conclusion",
28385
28506
  "description": "Close with one line that motivates the team into the next week. Echo the headline so the meeting feels closed.",
28386
- "layoutHint": "title-left",
28507
+ "layoutHint": "title",
28387
28508
  "instructions": "Recap & motivate",
28388
28509
  "slideType": "text"
28389
28510
  }
@@ -28415,7 +28536,7 @@ var narratives = [
28415
28536
  "id": "headline",
28416
28537
  "name": "Headline",
28417
28538
  "description": "Open with the single most important sentence the audience needs to know \u2014 on track, off track, or shifted. The headline replaces 'how's it going' with a clear answer.",
28418
- "layoutHint": "title-left",
28539
+ "layoutHint": "title",
28419
28540
  "instructions": "Title & date",
28420
28541
  "slideType": "text"
28421
28542
  },
@@ -28425,7 +28546,7 @@ var narratives = [
28425
28546
  "description": "State the objective for the period and what was promised. One slide, three lines. Frames the rest of the update so progress is read against a clear bar.",
28426
28547
  "instructions": "Summary/objectives",
28427
28548
  "slideType": "text",
28428
- "layoutHint": "text-1x-left"
28549
+ "layoutHint": "text-1x"
28429
28550
  },
28430
28551
  {
28431
28552
  "id": "progress",
@@ -28433,7 +28554,7 @@ var narratives = [
28433
28554
  "description": "Walk through the actions taken since the last update. Specific, attributable, dated. Avoid effort theater \u2014 list outcomes and material moves, not activity for its own sake.",
28434
28555
  "instructions": "Explain actions taken",
28435
28556
  "slideType": "text",
28436
- "layoutHint": "text-1x-left"
28557
+ "layoutHint": "text-1x"
28437
28558
  },
28438
28559
  {
28439
28560
  "id": "results",
@@ -28441,7 +28562,7 @@ var narratives = [
28441
28562
  "description": "Show the outcomes those actions produced. Metrics, customer signals, decisions made. Keep the comparison crisp \u2014 versus plan, versus last period, versus benchmark.",
28442
28563
  "instructions": "Show outcomes",
28443
28564
  "slideType": "text",
28444
- "layoutHint": "text-1x-left"
28565
+ "layoutHint": "text-1x"
28445
28566
  },
28446
28567
  {
28447
28568
  "id": "action-plan",
@@ -28449,13 +28570,13 @@ var narratives = [
28449
28570
  "description": "Outline the next steps and who owns them. Be specific about the next decision point and what would have to happen to slip the schedule.",
28450
28571
  "instructions": "Outline next steps",
28451
28572
  "slideType": "text",
28452
- "layoutHint": "text-1x-left"
28573
+ "layoutHint": "text-1x"
28453
28574
  },
28454
28575
  {
28455
28576
  "id": "feedback",
28456
28577
  "name": "Feedback",
28457
28578
  "description": "Invite the audience to weigh in: where you'd like input, where you need a decision, where help would unblock you. End the update with an open hand, not a closed file.",
28458
- "layoutHint": "title-left",
28579
+ "layoutHint": "title",
28459
28580
  "instructions": "Ask for response",
28460
28581
  "slideType": "text"
28461
28582
  }
@@ -28486,7 +28607,7 @@ var narratives = [
28486
28607
  "id": "briefing",
28487
28608
  "name": "Briefing",
28488
28609
  "description": "Frame what this review covers: the period, the unit, the standard you're measuring against. One slide that lets the audience know exactly what they're being asked to evaluate.",
28489
- "layoutHint": "title-center",
28610
+ "layoutHint": "title",
28490
28611
  "instructions": "Outline presentation objective",
28491
28612
  "slideType": "text"
28492
28613
  },
@@ -28496,7 +28617,7 @@ var narratives = [
28496
28617
  "description": "Lead with the headline result. On track, ahead, or behind, and by how much. Resist softening \u2014 clear numbers up front earn credibility for the analysis that follows.",
28497
28618
  "instructions": "Summarize performance findings",
28498
28619
  "slideType": "text",
28499
- "layoutHint": "text-1x-left"
28620
+ "layoutHint": "text-1x"
28500
28621
  },
28501
28622
  {
28502
28623
  "id": "key-metrics",
@@ -28504,7 +28625,7 @@ var narratives = [
28504
28625
  "description": "Walk through the pivotal indicators. One chart per metric, clear comparison period, target or benchmark visible on the same frame. Help the audience see the data the way you do.",
28505
28626
  "instructions": "Review pivotal indicators",
28506
28627
  "slideType": "text",
28507
- "layoutHint": "text-1x-left"
28628
+ "layoutHint": "text-1x"
28508
28629
  },
28509
28630
  {
28510
28631
  "id": "team-performance",
@@ -28512,7 +28633,7 @@ var narratives = [
28512
28633
  "description": "Examine collective achievements and how the team contributed. Avoid generic praise; cite specific moves and the people behind them where the audience would expect it.",
28513
28634
  "instructions": "Examine collective achievements",
28514
28635
  "slideType": "text",
28515
- "layoutHint": "text-1x-left"
28636
+ "layoutHint": "text-1x"
28516
28637
  },
28517
28638
  {
28518
28639
  "id": "highlight",
@@ -28520,7 +28641,7 @@ var narratives = [
28520
28641
  "description": "Spotlight one standout contribution that defined the period. A landmark deal, a launch, a fix, a hire. One vivid example sticks longer than a list of accomplishments.",
28521
28642
  "instructions": "Show key contribution",
28522
28643
  "slideType": "text",
28523
- "layoutHint": "text-1x-left"
28644
+ "layoutHint": "text-1x"
28524
28645
  },
28525
28646
  {
28526
28647
  "id": "analysis",
@@ -28528,7 +28649,7 @@ var narratives = [
28528
28649
  "description": "Dig under the metrics. What drove the numbers, what held them back, what's signal versus noise. Analysis is where the audience learns whether you actually understand the system you're reporting on.",
28529
28650
  "instructions": "Uncover data insights",
28530
28651
  "slideType": "text",
28531
- "layoutHint": "text-1x-left"
28652
+ "layoutHint": "text-1x"
28532
28653
  },
28533
28654
  {
28534
28655
  "id": "success",
@@ -28536,7 +28657,7 @@ var narratives = [
28536
28657
  "description": "Reinforce the past triumphs that show the system works. Briefly \u2014 the audience came for what's next, not a victory lap. Wins earn permission for the harder slides ahead.",
28537
28658
  "instructions": "Reinforce past triumphs",
28538
28659
  "slideType": "text",
28539
- "layoutHint": "text-1x-left"
28660
+ "layoutHint": "text-1x"
28540
28661
  },
28541
28662
  {
28542
28663
  "id": "challenges",
@@ -28544,7 +28665,7 @@ var narratives = [
28544
28665
  "description": "Name the obstacles encountered honestly. What didn't move, what regressed, what the team is still wrestling with. Understated challenges read as missed signal, not modesty.",
28545
28666
  "instructions": "Highlight encountered obstacles",
28546
28667
  "slideType": "text",
28547
- "layoutHint": "text-1x-left"
28668
+ "layoutHint": "text-1x"
28548
28669
  },
28549
28670
  {
28550
28671
  "id": "adjustments",
@@ -28552,7 +28673,7 @@ var narratives = [
28552
28673
  "description": "Identify the changes you're making in response. New tactics, reallocations, sunsets. Each adjustment should map to a challenge above \u2014 adjustments without diagnosis feel arbitrary.",
28553
28674
  "instructions": "Identify necessary changes",
28554
28675
  "slideType": "text",
28555
- "layoutHint": "text-1x-left"
28676
+ "layoutHint": "text-1x"
28556
28677
  },
28557
28678
  {
28558
28679
  "id": "strategy-evolution",
@@ -28560,13 +28681,13 @@ var narratives = [
28560
28681
  "description": "Show how the strategy itself evolves heading into the next period. Refinements, sharpened bets, dropped initiatives. The audience should see continuity as well as change.",
28561
28682
  "instructions": "Plan for improvement",
28562
28683
  "slideType": "text",
28563
- "layoutHint": "text-1x-left"
28684
+ "layoutHint": "text-1x"
28564
28685
  },
28565
28686
  {
28566
28687
  "id": "discussion",
28567
28688
  "name": "Discussion",
28568
28689
  "description": "Open the floor with two or three specific prompts. End the review actively \u2014 questions you want answered, decisions you want made \u2014 so the meeting yields more than the deck.",
28569
- "layoutHint": "title-left",
28690
+ "layoutHint": "title",
28570
28691
  "instructions": "Promote active discourse",
28571
28692
  "slideType": "text"
28572
28693
  }
@@ -28600,7 +28721,7 @@ var narratives = [
28600
28721
  "description": "Open by naming the question the survey was meant to answer. Why this, why now, who commissioned it. Anchor the audience in the decision the survey is designed to inform.",
28601
28722
  "instructions": "Present survey topic",
28602
28723
  "slideType": "text",
28603
- "layoutHint": "text-1x-left"
28724
+ "layoutHint": "text-1x"
28604
28725
  },
28605
28726
  {
28606
28727
  "id": "executive-summary",
@@ -28608,7 +28729,7 @@ var narratives = [
28608
28729
  "description": "State the top three findings in plain language on a single slide. A reader who only sees this slide should still be able to make the right call. Avoid hedging \u2014 synthesis is the point.",
28609
28730
  "instructions": "Summarize key findings",
28610
28731
  "slideType": "text",
28611
- "layoutHint": "text-1x-left"
28732
+ "layoutHint": "text-1x"
28612
28733
  },
28613
28734
  {
28614
28735
  "id": "context",
@@ -28616,7 +28737,7 @@ var narratives = [
28616
28737
  "description": "Detail the situation behind the survey: prior knowledge, related research, the gap this work fills. Just enough to position the findings as new information rather than restated common sense.",
28617
28738
  "instructions": "Detail survey background",
28618
28739
  "slideType": "text",
28619
- "layoutHint": "text-1x-left"
28740
+ "layoutHint": "text-1x"
28620
28741
  },
28621
28742
  {
28622
28743
  "id": "data-methodology",
@@ -28624,7 +28745,7 @@ var narratives = [
28624
28745
  "description": "Describe how the data was collected and from whom. Sample size, recruitment, instrument, timing. Be honest about limitations; methodological transparency is what gives the findings their weight.",
28625
28746
  "instructions": "Discuss sourcing and collection",
28626
28747
  "slideType": "text",
28627
- "layoutHint": "text-1x-left"
28748
+ "layoutHint": "text-1x"
28628
28749
  },
28629
28750
  {
28630
28751
  "id": "data-summary",
@@ -28632,7 +28753,7 @@ var narratives = [
28632
28753
  "description": "Give the audience an overview of the dataset before drilling in. Demographics, response rates, distribution of key variables. Help them calibrate what 'most' and 'few' mean in this study.",
28633
28754
  "instructions": "Provide data overview",
28634
28755
  "slideType": "text",
28635
- "layoutHint": "text-1x-left"
28756
+ "layoutHint": "text-1x"
28636
28757
  },
28637
28758
  {
28638
28759
  "id": "findings",
@@ -28640,7 +28761,7 @@ var narratives = [
28640
28761
  "description": "Present the key insights one at a time. Lead each finding with the claim, then the chart. Avoid burying the point under the visualization \u2014 captions should restate the insight in words.",
28641
28762
  "instructions": "Highlight key insights",
28642
28763
  "slideType": "text",
28643
- "layoutHint": "text-1x-left"
28764
+ "layoutHint": "text-1x"
28644
28765
  },
28645
28766
  {
28646
28767
  "id": "data-analysis",
@@ -28648,7 +28769,7 @@ var narratives = [
28648
28769
  "description": "Break down the data behind each finding: cross-tabs, segment splits, statistical confidence. This is the slide skeptics will scrutinize \u2014 make it scrutinizable.",
28649
28770
  "instructions": "Break down data",
28650
28771
  "slideType": "text",
28651
- "layoutHint": "text-1x-left"
28772
+ "layoutHint": "text-1x"
28652
28773
  },
28653
28774
  {
28654
28775
  "id": "implications",
@@ -28656,7 +28777,7 @@ var narratives = [
28656
28777
  "description": "Translate findings into 'so what.' What changes for product, marketing, ops, the customer? Implications without consequences are interesting trivia, not research.",
28657
28778
  "instructions": "Discuss survey implications",
28658
28779
  "slideType": "text",
28659
- "layoutHint": "text-1x-left"
28780
+ "layoutHint": "text-1x"
28660
28781
  },
28661
28782
  {
28662
28783
  "id": "recommendations",
@@ -28664,13 +28785,13 @@ var narratives = [
28664
28785
  "description": "Provide the actions that follow from the implications. Prioritize, attach owners, mark which require decisions. This is where research becomes useful.",
28665
28786
  "instructions": "Provide action plans",
28666
28787
  "slideType": "text",
28667
- "layoutHint": "text-1x-left"
28788
+ "layoutHint": "text-1x"
28668
28789
  },
28669
28790
  {
28670
28791
  "id": "conclusion",
28671
28792
  "name": "Conclusion",
28672
28793
  "description": "Recap the headline finding and the most important recommendation. End with the next step \u2014 a follow-on study, a workshop, a decision \u2014 so the work doesn't sit on a shelf.",
28673
- "layoutHint": "title-left",
28794
+ "layoutHint": "title",
28674
28795
  "instructions": "Recap and finalize",
28675
28796
  "slideType": "text"
28676
28797
  }
@@ -28703,7 +28824,7 @@ var narratives = [
28703
28824
  "description": "Open by establishing why this trend matters now. Tie it to a decision on the table or a forecast that's about to be made. Trends without consequences are filler.",
28704
28825
  "instructions": "Ignite interest, establish significance",
28705
28826
  "slideType": "text",
28706
- "layoutHint": "text-1x-left"
28827
+ "layoutHint": "text-1x"
28707
28828
  },
28708
28829
  {
28709
28830
  "id": "historical-comparison",
@@ -28711,7 +28832,7 @@ var narratives = [
28711
28832
  "description": "Contrast current data with the relevant past. Pick the comparison window that makes the trend visible without cherry-picking. Be honest about base effects.",
28712
28833
  "instructions": "Contrast current and past data",
28713
28834
  "slideType": "text",
28714
- "layoutHint": "text-1x-left"
28835
+ "layoutHint": "text-1x"
28715
28836
  },
28716
28837
  {
28717
28838
  "id": "pattern-identification",
@@ -28719,7 +28840,7 @@ var narratives = [
28719
28840
  "description": "Name the recurring outcome you've spotted. Use one or two strong charts that show the pattern unambiguously. Avoid overclaiming significance from a small N.",
28720
28841
  "instructions": "Point out recurring outcomes",
28721
28842
  "slideType": "text",
28722
- "layoutHint": "text-1x-left"
28843
+ "layoutHint": "text-1x"
28723
28844
  },
28724
28845
  {
28725
28846
  "id": "future-prediction",
@@ -28727,7 +28848,7 @@ var narratives = [
28727
28848
  "description": "Project where the trend leads if it continues. Show the forecast and the confidence interval. State the assumptions that would have to break for the prediction to fail.",
28728
28849
  "instructions": "Predict using established patterns",
28729
28850
  "slideType": "text",
28730
- "layoutHint": "text-1x-left"
28851
+ "layoutHint": "text-1x"
28731
28852
  },
28732
28853
  {
28733
28854
  "id": "action-plan",
@@ -28735,7 +28856,7 @@ var narratives = [
28735
28856
  "description": "Translate the prediction into the strategy it implies. Specific actions, sequenced. Each action should map to a particular reading of the trend, not a generic best practice.",
28736
28857
  "instructions": "Strategies based on prediction",
28737
28858
  "slideType": "text",
28738
- "layoutHint": "text-1x-left"
28859
+ "layoutHint": "text-1x"
28739
28860
  },
28740
28861
  {
28741
28862
  "id": "implementation",
@@ -28743,13 +28864,13 @@ var narratives = [
28743
28864
  "description": "Walk through how the actions get executed: owners, milestones, monitoring. The audience should leave understanding what to do tomorrow, not just what to think about.",
28744
28865
  "instructions": "Discuss strategy execution",
28745
28866
  "slideType": "text",
28746
- "layoutHint": "text-1x-left"
28867
+ "layoutHint": "text-1x"
28747
28868
  },
28748
28869
  {
28749
28870
  "id": "conclusion",
28750
28871
  "name": "Conclusion",
28751
28872
  "description": "Recap the trend, the forecast, and the recommended action. End with the leading indicator you'll watch to know if the call is right.",
28752
- "layoutHint": "title-left",
28873
+ "layoutHint": "title",
28753
28874
  "instructions": "Summarize key points",
28754
28875
  "slideType": "text"
28755
28876
  }
@@ -28780,7 +28901,7 @@ var narratives = [
28780
28901
  "id": "introduction",
28781
28902
  "name": "Introduction",
28782
28903
  "description": "Open with the period covered and the spirit of the conversation: collaborative, honest, growth-focused. Frame the meeting so both sides know what to expect.",
28783
- "layoutHint": "title-left",
28904
+ "layoutHint": "title",
28784
28905
  "instructions": "Name & date",
28785
28906
  "slideType": "text"
28786
28907
  },
@@ -28790,7 +28911,7 @@ var narratives = [
28790
28911
  "description": "Review job execution against the role's expectations. Specific examples, dated. Avoid characterizing the person; describe the work and its impact.",
28791
28912
  "instructions": "Review job execution",
28792
28913
  "slideType": "text",
28793
- "layoutHint": "text-1x-left"
28914
+ "layoutHint": "text-1x"
28794
28915
  },
28795
28916
  {
28796
28917
  "id": "achievements",
@@ -28798,7 +28919,7 @@ var narratives = [
28798
28919
  "description": "Acknowledge what went well. Name the projects, the moves, the moments where the employee made a difference. Specific recognition lands harder than generic praise.",
28799
28920
  "instructions": "Acknowledge success",
28800
28921
  "slideType": "text",
28801
- "layoutHint": "text-1x-left"
28922
+ "layoutHint": "text-1x"
28802
28923
  },
28803
28924
  {
28804
28925
  "id": "feedback",
@@ -28806,7 +28927,7 @@ var narratives = [
28806
28927
  "description": "Provide constructive feedback grounded in observation. Distinguish patterns from one-offs. Tell the employee something they can act on, not something they can only feel.",
28807
28928
  "instructions": "Provide positive remarks",
28808
28929
  "slideType": "text",
28809
- "layoutHint": "text-1x-left"
28930
+ "layoutHint": "text-1x"
28810
28931
  },
28811
28932
  {
28812
28933
  "id": "constructive-criticism",
@@ -28814,7 +28935,7 @@ var narratives = [
28814
28935
  "description": "Suggest improvements in language that respects the employee's intelligence. Pair each piece of criticism with a concrete example and a specific behavior change you'd like to see.",
28815
28936
  "instructions": "Suggest improvements",
28816
28937
  "slideType": "text",
28817
- "layoutHint": "text-1x-left"
28938
+ "layoutHint": "text-1x"
28818
28939
  },
28819
28940
  {
28820
28941
  "id": "development-opportunities",
@@ -28822,7 +28943,7 @@ var narratives = [
28822
28943
  "description": "Highlight growth areas and the experiences that could stretch the employee. Frame development as an investment, not a fix.",
28823
28944
  "instructions": "Highlight growth areas",
28824
28945
  "slideType": "text",
28825
- "layoutHint": "text-1x-left"
28946
+ "layoutHint": "text-1x"
28826
28947
  },
28827
28948
  {
28828
28949
  "id": "goals",
@@ -28830,13 +28951,13 @@ var narratives = [
28830
28951
  "description": "Outline next-period goals together. Specific, measurable, with explicit support. The strongest goals are co-authored, not handed down.",
28831
28952
  "instructions": "Outline next steps",
28832
28953
  "slideType": "text",
28833
- "layoutHint": "text-1x-left"
28954
+ "layoutHint": "text-1x"
28834
28955
  },
28835
28956
  {
28836
28957
  "id": "mentoring",
28837
28958
  "name": "Mentoring",
28838
28959
  "description": "Encourage continued learning through mentorship, training, peer pairings. Close the review with the message that growth is a shared responsibility, not a one-way evaluation.",
28839
- "layoutHint": "title-left",
28960
+ "layoutHint": "title",
28840
28961
  "instructions": "Encourage continuous learning",
28841
28962
  "slideType": "text"
28842
28963
  }
@@ -28869,7 +28990,7 @@ var narratives = [
28869
28990
  "description": "Begin respectfully and set a constructive tone. Be clear about what this conversation is and isn't. The opening shouldn't catastrophize or sugarcoat \u2014 clarity is kinder than either.",
28870
28991
  "instructions": "Begin respectfully and positively",
28871
28992
  "slideType": "text",
28872
- "layoutHint": "text-1x-left"
28993
+ "layoutHint": "text-1x"
28873
28994
  },
28874
28995
  {
28875
28996
  "id": "set-expectations",
@@ -28877,7 +28998,7 @@ var narratives = [
28877
28998
  "description": "Detail the level of performance expected in the role. Specific behaviors, deliverables, and standards. Expectations the employee can't quote back are expectations they can't meet.",
28878
28999
  "instructions": "Detail desired performance",
28879
29000
  "slideType": "text",
28880
- "layoutHint": "text-1x-left"
29001
+ "layoutHint": "text-1x"
28881
29002
  },
28882
29003
  {
28883
29004
  "id": "identify-problems",
@@ -28885,7 +29006,7 @@ var narratives = [
28885
29006
  "description": "Name the gap between expected and observed performance. Use specific examples and dates rather than impressions. Avoid characterizing the person; focus on the work product and the impact.",
28886
29007
  "instructions": "Highlight struggles and weaknesses",
28887
29008
  "slideType": "text",
28888
- "layoutHint": "text-1x-left"
29009
+ "layoutHint": "text-1x"
28889
29010
  },
28890
29011
  {
28891
29012
  "id": "possible-solutions",
@@ -28893,7 +29014,7 @@ var narratives = [
28893
29014
  "description": "Suggest improvement strategies tailored to the gaps named above. Behavior changes, structural changes, support structures. Frame them as paths the employee can choose, not orders to follow.",
28894
29015
  "instructions": "Suggest improvement strategies",
28895
29016
  "slideType": "text",
28896
- "layoutHint": "text-1x-left"
29017
+ "layoutHint": "text-1x"
28897
29018
  },
28898
29019
  {
28899
29020
  "id": "offer-resources",
@@ -28901,7 +29022,7 @@ var narratives = [
28901
29022
  "description": "Make explicit what tools, coaching, training, or peer support is available. Resources demonstrate that the organization is investing in the outcome, not setting the employee up to fail.",
28902
29023
  "instructions": "Propose help and tools",
28903
29024
  "slideType": "text",
28904
- "layoutHint": "text-1x-left"
29025
+ "layoutHint": "text-1x"
28905
29026
  },
28906
29027
  {
28907
29028
  "id": "motivate-change",
@@ -28909,7 +29030,7 @@ var narratives = [
28909
29030
  "description": "Connect improvement to what the employee values: their growth, their team, their career. Inspire action without minimizing the seriousness of the situation.",
28910
29031
  "instructions": "Inspire improvement action",
28911
29032
  "slideType": "text",
28912
- "layoutHint": "text-1x-left"
29033
+ "layoutHint": "text-1x"
28913
29034
  },
28914
29035
  {
28915
29036
  "id": "follow-up",
@@ -28917,13 +29038,13 @@ var narratives = [
28917
29038
  "description": "Schedule the check-ins. Frequency, format, criteria for progress. Predictable follow-up turns a PIP from a threat into a plan.",
28918
29039
  "instructions": "Schedule progress check-ins",
28919
29040
  "slideType": "text",
28920
- "layoutHint": "text-1x-left"
29041
+ "layoutHint": "text-1x"
28921
29042
  },
28922
29043
  {
28923
29044
  "id": "conclusion",
28924
29045
  "name": "Conclusion",
28925
29046
  "description": "Close with confidence in the path forward and a clear restatement of what success looks like. End the meeting having both raised the bar and reaffirmed the relationship.",
28926
- "layoutHint": "title-left",
29047
+ "layoutHint": "title",
28927
29048
  "instructions": "Encourage and remind success",
28928
29049
  "slideType": "text"
28929
29050
  }
@@ -28955,7 +29076,7 @@ var narratives = [
28955
29076
  "id": "kickoff",
28956
29077
  "name": "Kickoff",
28957
29078
  "description": "Introduce what the planning exercise covers and the decision you need from the audience. Frame the time horizon and the resources in scope so the rest of the deck stays bounded.",
28958
- "layoutHint": "title-center",
29079
+ "layoutHint": "title",
28959
29080
  "instructions": "Introduce the topic",
28960
29081
  "slideType": "text"
28961
29082
  },
@@ -28965,7 +29086,7 @@ var narratives = [
28965
29086
  "description": "Show why this is the right moment to plan capacity. Pipeline shifts, hiring freezes, operational stress signals. Urgency turns capacity from an annual ritual into a decision the audience leans into.",
28966
29087
  "instructions": "Show needs",
28967
29088
  "slideType": "text",
28968
- "layoutHint": "text-1x-left"
29089
+ "layoutHint": "text-1x"
28969
29090
  },
28970
29091
  {
28971
29092
  "id": "situation",
@@ -28973,7 +29094,7 @@ var narratives = [
28973
29094
  "description": "Highlight the current resource picture: people, tools, infrastructure, vendor capacity. Show utilization, not just headcount. The audience should know where slack and stress live today.",
28974
29095
  "instructions": "Highlight current resources",
28975
29096
  "slideType": "text",
28976
- "layoutHint": "text-1x-left"
29097
+ "layoutHint": "text-1x"
28977
29098
  },
28978
29099
  {
28979
29100
  "id": "projection",
@@ -28981,7 +29102,7 @@ var narratives = [
28981
29102
  "description": "Predict future demand under your base case and a sensitivity case. Tie demand to specific drivers \u2014 pipeline, launches, seasonality \u2014 so the audience can challenge the assumptions, not just the totals.",
28982
29103
  "instructions": "Predict future demands",
28983
29104
  "slideType": "text",
28984
- "layoutHint": "text-1x-left"
29105
+ "layoutHint": "text-1x"
28985
29106
  },
28986
29107
  {
28987
29108
  "id": "tactics",
@@ -28989,7 +29110,7 @@ var narratives = [
28989
29110
  "description": "Suggest the strategies for closing any gap: hiring, automation, outsourcing, prioritization. Each tactic should map to a specific demand driver and a defensible cost.",
28990
29111
  "instructions": "Suggest coping strategies",
28991
29112
  "slideType": "text",
28992
- "layoutHint": "text-1x-left"
29113
+ "layoutHint": "text-1x"
28993
29114
  },
28994
29115
  {
28995
29116
  "id": "implementation",
@@ -28997,7 +29118,7 @@ var narratives = [
28997
29118
  "description": "Discuss how the plan gets deployed. Sequencing, owners, dependencies, lead times. Capacity decisions slip the most when the rollout isn't planned with the same rigor as the sizing.",
28998
29119
  "instructions": "Discuss deployment plans",
28999
29120
  "slideType": "text",
29000
- "layoutHint": "text-1x-left"
29121
+ "layoutHint": "text-1x"
29001
29122
  },
29002
29123
  {
29003
29124
  "id": "revision",
@@ -29005,13 +29126,13 @@ var narratives = [
29005
29126
  "description": "Define the leading indicators that would trigger a re-plan, and the cadence of review. Capacity plans age fast; show the audience how the plan stays alive.",
29006
29127
  "instructions": "Evaluate and adjust",
29007
29128
  "slideType": "text",
29008
- "layoutHint": "text-1x-left"
29129
+ "layoutHint": "text-1x"
29009
29130
  },
29010
29131
  {
29011
29132
  "id": "conclusion",
29012
29133
  "name": "Conclusion",
29013
29134
  "description": "Wrap up with the specific recommendations and the decisions you need today. End with the next checkpoint and what evidence will be on the table at it.",
29014
- "layoutHint": "title-left",
29135
+ "layoutHint": "title",
29015
29136
  "instructions": "Wrap-up & recommendations",
29016
29137
  "slideType": "text"
29017
29138
  }
@@ -34839,9 +34960,87 @@ var catalogEntries = [
34839
34960
  ], records: fontSchemes, index: catalogIndexes.fontSchemes }
34840
34961
  ];
34841
34962
 
34842
- // ../javascript/dist/chunk-ZIL7MGZU.js
34963
+ // ../javascript/dist/chunk-CHKJ4QHQ.js
34843
34964
  var import__ = __toESM(require__(), 1);
34844
34965
  var import_ajv_formats = __toESM(require_dist(), 1);
34966
+ function isRecord(value) {
34967
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34968
+ }
34969
+ function pathFor(parentPath, key) {
34970
+ return parentPath === "/" ? `/${key}` : `${parentPath}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
34971
+ }
34972
+ var bareIdPattern = /^[a-z0-9][a-z0-9-]*$/;
34973
+ var promotedRegionKeys = [
34974
+ "left",
34975
+ "center",
34976
+ "right",
34977
+ "left+center",
34978
+ "center+right",
34979
+ "left+center+right",
34980
+ "top",
34981
+ "middle",
34982
+ "bottom",
34983
+ "top+middle",
34984
+ "middle+bottom",
34985
+ "top+middle+bottom",
34986
+ "top:left",
34987
+ "top:center",
34988
+ "top:right",
34989
+ "top:left+center",
34990
+ "top:center+right",
34991
+ "top:left+center+right",
34992
+ "middle:left",
34993
+ "middle:center",
34994
+ "middle:right",
34995
+ "middle:left+center",
34996
+ "middle:center+right",
34997
+ "middle:left+center+right",
34998
+ "bottom:left",
34999
+ "bottom:center",
35000
+ "bottom:right",
35001
+ "bottom:left+center",
35002
+ "bottom:center+right",
35003
+ "bottom:left+center+right",
35004
+ "top+middle:left",
35005
+ "top+middle:center",
35006
+ "top+middle:right",
35007
+ "top+middle:left+center",
35008
+ "top+middle:center+right",
35009
+ "top+middle:left+center+right",
35010
+ "middle+bottom:left",
35011
+ "middle+bottom:center",
35012
+ "middle+bottom:right",
35013
+ "middle+bottom:left+center",
35014
+ "middle+bottom:center+right",
35015
+ "middle+bottom:left+center+right",
35016
+ "top+middle+bottom:left",
35017
+ "top+middle+bottom:center",
35018
+ "top+middle+bottom:right",
35019
+ "top+middle+bottom:left+center",
35020
+ "top+middle+bottom:center+right",
35021
+ "top+middle+bottom:left+center+right"
35022
+ ];
35023
+ function visitContentPayloads(slide, slidePath, visit2) {
35024
+ const walk = (payload, path3, depth, ancestors) => {
35025
+ visit2(payload, path3);
35026
+ if (!Array.isArray(payload.blocks) || depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(payload)) return;
35027
+ const nested = [...ancestors, payload];
35028
+ const blocksPath = pathFor(path3, "blocks");
35029
+ payload.blocks.forEach((block, index2) => {
35030
+ if (isRecord(block)) walk(block, `${blocksPath}/${index2}`, depth + 1, nested);
35031
+ });
35032
+ };
35033
+ if (Array.isArray(slide.blocks)) {
35034
+ const blocksPath = pathFor(slidePath, "blocks");
35035
+ slide.blocks.forEach((block, index2) => {
35036
+ if (isRecord(block)) walk(block, `${blocksPath}/${index2}`, 0, []);
35037
+ });
35038
+ }
35039
+ for (const key of promotedRegionKeys) {
35040
+ const region = slide[key];
35041
+ if (isRecord(region)) walk(region, pathFor(slidePath, key), 0, []);
35042
+ }
35043
+ }
34845
35044
  var catalogIds = {
34846
35045
  audiences: [
34847
35046
  "executives",
@@ -35299,56 +35498,6 @@ var OPFValidationError = class extends Error {
35299
35498
  var schemaNameByCatalogKind = catalogSchemaNames;
35300
35499
  var ajv;
35301
35500
  var dynamicSchemaCache = /* @__PURE__ */ new WeakMap();
35302
- var promotedRegionKeys = [
35303
- "left",
35304
- "center",
35305
- "right",
35306
- "left+center",
35307
- "center+right",
35308
- "left+center+right",
35309
- "top",
35310
- "middle",
35311
- "bottom",
35312
- "top+middle",
35313
- "middle+bottom",
35314
- "top+middle+bottom",
35315
- "top:left",
35316
- "top:center",
35317
- "top:right",
35318
- "top:left+center",
35319
- "top:center+right",
35320
- "top:left+center+right",
35321
- "middle:left",
35322
- "middle:center",
35323
- "middle:right",
35324
- "middle:left+center",
35325
- "middle:center+right",
35326
- "middle:left+center+right",
35327
- "bottom:left",
35328
- "bottom:center",
35329
- "bottom:right",
35330
- "bottom:left+center",
35331
- "bottom:center+right",
35332
- "bottom:left+center+right",
35333
- "top+middle:left",
35334
- "top+middle:center",
35335
- "top+middle:right",
35336
- "top+middle:left+center",
35337
- "top+middle:center+right",
35338
- "top+middle:left+center+right",
35339
- "middle+bottom:left",
35340
- "middle+bottom:center",
35341
- "middle+bottom:right",
35342
- "middle+bottom:left+center",
35343
- "middle+bottom:center+right",
35344
- "middle+bottom:left+center+right",
35345
- "top+middle+bottom:left",
35346
- "top+middle+bottom:center",
35347
- "top+middle+bottom:right",
35348
- "top+middle+bottom:left+center",
35349
- "top+middle+bottom:center+right",
35350
- "top+middle+bottom:left+center+right"
35351
- ];
35352
35501
  var promotedRegionKeySet = new Set(promotedRegionKeys);
35353
35502
  var rootPayloadFields = [
35354
35503
  "type",
@@ -35488,18 +35637,12 @@ function semanticIssue(path3, message, params = {}) {
35488
35637
  params
35489
35638
  };
35490
35639
  }
35491
- function isRecord(value) {
35492
- return typeof value === "object" && value !== null && !Array.isArray(value);
35493
- }
35494
35640
  function hasOwn(value, key) {
35495
35641
  return Object.hasOwn(value, key);
35496
35642
  }
35497
35643
  function isEnUkTag(value) {
35498
35644
  return typeof value === "string" && value.toLowerCase() === "en-uk";
35499
35645
  }
35500
- function pathFor(parentPath, key) {
35501
- return parentPath === "/" ? `/${key}` : `${parentPath}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
35502
- }
35503
35646
  function presentFields(value, fields3) {
35504
35647
  return fields3.filter((field) => hasOwn(value, field));
35505
35648
  }
@@ -35672,27 +35815,32 @@ function validatePresentationSemantics(value) {
35672
35815
  replacement: "en-GB"
35673
35816
  }));
35674
35817
  }
35675
- const slideIds = /* @__PURE__ */ new Set();
35818
+ const documentIds = /* @__PURE__ */ new Map();
35676
35819
  value.slides.forEach((slide, index2) => {
35677
35820
  if (isRecord(slide)) {
35821
+ const slidePath = `/slides/${index2}`;
35678
35822
  if (typeof slide.id === "string") {
35679
- if (slideIds.has(slide.id)) issues.push(semanticIssue(`/slides/${index2}/id`, "slide ids must be unique within a presentation", { id: slide.id }));
35680
- slideIds.add(slide.id);
35681
- }
35682
- issues.push(...validateSlideRegions(slide, `/slides/${index2}`));
35683
- const visitTables = (node, path3) => {
35684
- if (isRecord(node.table)) for (const issue of tableGrid(node.table).issues) issues.push(semanticIssue(pathFor(path3, "table") + issue.path.slice(5).replaceAll(".", "/"), issue.message));
35685
- if (Array.isArray(node.blocks)) node.blocks.forEach((block, i) => {
35686
- if (isRecord(block)) visitTables(block, `${path3}/blocks/${i}`);
35687
- });
35688
- for (const key of promotedRegionKeys) if (isRecord(node[key])) visitTables(node[key], pathFor(path3, key));
35823
+ const seen = documentIds.get(slide.id);
35824
+ if (seen === "slide") issues.push(semanticIssue(`${slidePath}/id`, "slide ids must be unique within a presentation", { id: slide.id }));
35825
+ else if (seen === "payload") issues.push(semanticIssue(`${slidePath}/id`, "slide id duplicates a content payload id; ids must be unique among slide and payload ids within a presentation", { id: slide.id }));
35826
+ else documentIds.set(slide.id, "slide");
35827
+ }
35828
+ visitContentPayloads(slide, slidePath, (payload, path3) => {
35829
+ if (typeof payload.id === "string") {
35830
+ if (documentIds.has(payload.id)) issues.push(semanticIssue(`${path3}/id`, "content payload ids must be unique among slide and payload ids within a presentation", { id: payload.id }));
35831
+ else documentIds.set(payload.id, "payload");
35832
+ }
35833
+ });
35834
+ issues.push(...validateSlideRegions(slide, slidePath));
35835
+ const payloadTableIssues = (payload, path3) => {
35836
+ if (isRecord(payload.table)) for (const issue of tableGrid(payload.table).issues) issues.push(semanticIssue(pathFor(path3, "table") + issue.path.slice(5).replaceAll(".", "/"), issue.message));
35689
35837
  };
35690
- visitTables(slide, `/slides/${index2}`);
35838
+ payloadTableIssues(slide, slidePath);
35839
+ visitContentPayloads(slide, slidePath, payloadTableIssues);
35691
35840
  }
35692
35841
  });
35693
35842
  return issues;
35694
35843
  }
35695
- var bareIdPattern = /^[a-z0-9][a-z0-9-]*$/;
35696
35844
  function inlineCatalogEntry(context, kind2) {
35697
35845
  const catalogsField = context.document.catalogs;
35698
35846
  if (!isRecord(catalogsField)) {
@@ -35711,7 +35859,7 @@ function unknownIdWarning(kind2, value, path3, context) {
35711
35859
  if (Array.isArray(entry.records) && entry.records.some((record3) => isRecord(record3) && record3.id === value)) {
35712
35860
  return void 0;
35713
35861
  }
35714
- if (typeof entry.source === "string") {
35862
+ if (typeof entry.source === "string" || Array.isArray(entry.source) && entry.source.length > 0) {
35715
35863
  return void 0;
35716
35864
  }
35717
35865
  }
@@ -35765,6 +35913,126 @@ function chartTypeWarnings(payload, path3, context) {
35765
35913
  }
35766
35914
  return issues;
35767
35915
  }
35916
+ var cellBorderEdges = ["top", "right", "bottom", "left"];
35917
+ var variableIdPattern = /^[a-z][a-z0-9-]*$/;
35918
+ var hexColorPattern = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
35919
+ var schemeColorNames = /* @__PURE__ */ new Set([
35920
+ "accent1",
35921
+ "accent2",
35922
+ "accent3",
35923
+ "accent4",
35924
+ "accent5",
35925
+ "accent6",
35926
+ "dark1",
35927
+ "dark2",
35928
+ "light1",
35929
+ "light2",
35930
+ "hyperlink",
35931
+ "followedHyperlink",
35932
+ "primary",
35933
+ "secondary",
35934
+ "accent",
35935
+ "background",
35936
+ "surface",
35937
+ "text",
35938
+ "textSecondary"
35939
+ ]);
35940
+ function variableReferenceWarnings(value) {
35941
+ if (!Array.isArray(value.slides)) {
35942
+ return [];
35943
+ }
35944
+ const variables = isRecord(value.variables) ? value.variables : {};
35945
+ const issues = [];
35946
+ const colorRef = (entry, path3) => {
35947
+ if (typeof entry !== "string" || !entry.startsWith("var:")) return;
35948
+ const id = entry.slice("var:".length);
35949
+ if (!variableIdPattern.test(id) || hasOwn(variables, id)) return;
35950
+ issues.push(semanticIssue(path3, `unknown variable '${id}'; declare it in the top-level variables map`, { id }));
35951
+ };
35952
+ const runColor = (entry, path3) => {
35953
+ if (typeof entry !== "string") return;
35954
+ if (hexColorPattern.test(entry) || schemeColorNames.has(entry)) return;
35955
+ if (entry.startsWith("var:") && variableIdPattern.test(entry.slice("var:".length))) {
35956
+ colorRef(entry, path3);
35957
+ return;
35958
+ }
35959
+ issues.push(semanticIssue(
35960
+ path3,
35961
+ `run color '${entry}' is not a hex color, a color-scheme name, or a 'var:' reference; renderers fall back to the theme color`,
35962
+ { color: entry }
35963
+ ));
35964
+ };
35965
+ const richText = (entry, path3) => {
35966
+ if (!Array.isArray(entry)) return;
35967
+ entry.forEach((run, index2) => {
35968
+ if (isRecord(run)) runColor(run.color, `${path3}/${index2}/color`);
35969
+ });
35970
+ };
35971
+ const cellStyle = (style, path3) => {
35972
+ if (!isRecord(style)) return;
35973
+ colorRef(style.fill, pathFor(path3, "fill"));
35974
+ colorRef(style.color, pathFor(path3, "color"));
35975
+ if (!isRecord(style.borders)) return;
35976
+ const bordersPath = pathFor(path3, "borders");
35977
+ for (const edge of cellBorderEdges) {
35978
+ const border = style.borders[edge];
35979
+ if (isRecord(border)) colorRef(border.color, `${pathFor(bordersPath, edge)}/color`);
35980
+ }
35981
+ };
35982
+ const tableCell = (cell2, path3) => {
35983
+ if (Array.isArray(cell2)) {
35984
+ richText(cell2, path3);
35985
+ return;
35986
+ }
35987
+ if (!isRecord(cell2)) return;
35988
+ richText(cell2.value, pathFor(path3, "value"));
35989
+ cellStyle(cell2.style, pathFor(path3, "style"));
35990
+ };
35991
+ const table = (node, path3) => {
35992
+ if (!isRecord(node)) return;
35993
+ if (Array.isArray(node.columns)) {
35994
+ const columnsPath = pathFor(path3, "columns");
35995
+ node.columns.forEach((column, index2) => {
35996
+ tableCell(column, `${columnsPath}/${index2}`);
35997
+ });
35998
+ }
35999
+ if (Array.isArray(node.rows)) {
36000
+ const rowsPath = pathFor(path3, "rows");
36001
+ node.rows.forEach((row, rowIndex) => {
36002
+ if (!Array.isArray(row)) return;
36003
+ row.forEach((cell2, cellIndex) => {
36004
+ tableCell(cell2, `${rowsPath}/${rowIndex}/${cellIndex}`);
36005
+ });
36006
+ });
36007
+ }
36008
+ };
36009
+ const textEntries = (entries, path3) => {
36010
+ if (!Array.isArray(entries)) return;
36011
+ entries.forEach((entry, index2) => {
36012
+ const entryPath = `${path3}/${index2}`;
36013
+ if (Array.isArray(entry)) {
36014
+ richText(entry, entryPath);
36015
+ return;
36016
+ }
36017
+ if (!isRecord(entry)) return;
36018
+ richText(entry.text, pathFor(entryPath, "text"));
36019
+ richText(entry.description, pathFor(entryPath, "description"));
36020
+ });
36021
+ };
36022
+ const payload = (node, path3) => {
36023
+ richText(node.text, pathFor(path3, "text"));
36024
+ textEntries(node.items, pathFor(path3, "items"));
36025
+ textEntries(node.bullets, pathFor(path3, "bullets"));
36026
+ table(node.table, pathFor(path3, "table"));
36027
+ };
36028
+ value.slides.forEach((slide, index2) => {
36029
+ if (!isRecord(slide)) return;
36030
+ const slidePath = `/slides/${index2}`;
36031
+ payload(slide, slidePath);
36032
+ visitContentPayloads(slide, slidePath, payload);
36033
+ });
36034
+ return issues;
36035
+ }
35768
36036
  function presentationReferenceWarnings(value) {
35769
36037
  if (!isRecord(value) || !Array.isArray(value.slides)) {
35770
36038
  return [];
@@ -35775,6 +36043,7 @@ function presentationReferenceWarnings(value) {
35775
36043
  pushIfDefined(issues, unknownIdWarning("narratives", value.narrative, "/narrative", context));
35776
36044
  }
35777
36045
  issues.push(...designReferenceWarnings(value.design, "/design", context));
36046
+ issues.push(...variableReferenceWarnings(value));
35778
36047
  value.slides.forEach((slide, index2) => {
35779
36048
  if (!isRecord(slide)) {
35780
36049
  return;
@@ -36847,7 +37116,7 @@ function printParseErrorCode(code) {
36847
37116
  return "<unknown ParseErrorCode>";
36848
37117
  }
36849
37118
 
36850
- // ../javascript/dist/chunk-EWJNRHXA.js
37119
+ // ../javascript/dist/chunk-EQHZ3ZO4.js
36851
37120
  var own = (value, key) => Object.hasOwn(value, key);
36852
37121
  var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
36853
37122
  var primitive = (value) => value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
@@ -37582,7 +37851,7 @@ function createDataContent(input, options) {
37582
37851
  return { chart: { type: options.chartType ?? "column", data: { columns: names, rows: rows2 } } };
37583
37852
  }
37584
37853
 
37585
- // ../javascript/dist/chunk-FHGJX5QK.js
37854
+ // ../javascript/dist/chunk-FWA5XB45.js
37586
37855
  init_define_OPF_SKILLS();
37587
37856
  var OPFPaginationError = class extends Error {
37588
37857
  constructor(message, diagnostics = []) {
@@ -37597,6 +37866,13 @@ var contentFields = /* @__PURE__ */ new Set(["text", "items", "bullets", "image"
37597
37866
  var headingFields = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
37598
37867
  var isRecord2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
37599
37868
  var clone = (value) => structuredClone(value);
37869
+ var slideIds = (slide) => {
37870
+ const ids = typeof slide.id === "string" ? [slide.id] : [];
37871
+ visitContentPayloads(slide, "", (payload) => {
37872
+ if (typeof payload.id === "string") ids.push(payload.id);
37873
+ });
37874
+ return ids;
37875
+ };
37600
37876
  var textOf = (value) => typeof value === "string" ? value : Array.isArray(value) ? value.map(textOf).join("") : value?.text ?? "";
37601
37877
  var graphemes = new Intl.Segmenter("und", { granularity: "grapheme" });
37602
37878
  function sliceRichText(value, start, end) {
@@ -37686,7 +37962,26 @@ function paginateSlide(input, options = {}) {
37686
37962
  const slides = [], pages = [];
37687
37963
  let selected = /* @__PURE__ */ new Map();
37688
37964
  const reservedIds = new Set(options.reservedIds ?? []);
37689
- if (typeof source.id === "string") reservedIds.add(source.id);
37965
+ for (const id of slideIds(source)) reservedIds.add(id);
37966
+ const emittedIds = /* @__PURE__ */ new Set();
37967
+ const pageId = (base, pageIndex) => {
37968
+ if (!emittedIds.has(base)) {
37969
+ emittedIds.add(base);
37970
+ return base;
37971
+ }
37972
+ let suffix = pageIndex + 1, id = `${base}--${suffix}`;
37973
+ while (reservedIds.has(id)) id = `${base}--${++suffix}`;
37974
+ reservedIds.add(id);
37975
+ emittedIds.add(id);
37976
+ return id;
37977
+ };
37978
+ const assignPageIds = (slide, pageIndex) => {
37979
+ const assign = (node) => {
37980
+ if (typeof node.id === "string") node.id = pageId(node.id, pageIndex);
37981
+ };
37982
+ assign(slide);
37983
+ visitContentPayloads(slide, "", assign);
37984
+ };
37690
37985
  const project = (portions, pageIndex) => {
37691
37986
  const mappings = [];
37692
37987
  const visit2 = (node, path3, out, root = false) => {
@@ -37732,12 +38027,7 @@ function paginateSlide(input, options = {}) {
37732
38027
  const { slide, mappings } = project(selected, slides.length);
37733
38028
  const issues = geometry(slide, slides.length).diagnostics;
37734
38029
  if (issues.length) throw new OPFPaginationError("A continuation page does not fit at its final page number. No partial result was returned.", issues);
37735
- if (slides.length && typeof source.id === "string") {
37736
- let suffix = slides.length + 1, id = `${source.id}--${suffix}`;
37737
- while (reservedIds.has(id)) id = `${source.id}--${++suffix}`;
37738
- slide.id = id;
37739
- reservedIds.add(id);
37740
- }
38030
+ assignPageIds(slide, slides.length);
37741
38031
  assertValidPresentation({ slides: [slide] });
37742
38032
  slides.push(slide);
37743
38033
  pages.push({ slideIndex: sourceIndex + slides.length - 1, mappings, ...initial.furniture ? { repeatedMappings: repeatedMappings(slides.length - 1) } : {} });
@@ -37796,7 +38086,7 @@ function paginatePresentation(input, options = {}) {
37796
38086
  const maxSlides = options.maxSlides ?? 100;
37797
38087
  if (!Number.isInteger(maxSlides) || maxSlides < 1 || maxSlides > 1e4) throw new RangeError("maxSlides must be an integer between 1 and 10000.");
37798
38088
  const output = [], pages = [];
37799
- const reservedIds = presentation2.slides.map((slide) => slide.id).filter(Boolean);
38089
+ const reservedIds = presentation2.slides.flatMap((slide) => slideIds(slide));
37800
38090
  const resolve2 = (kind2, id) => presentation2.catalogs?.[kind2]?.records?.find((record3) => record3.id === id) ?? catalogs[kind2].find((record3) => record3.id === id);
37801
38091
  presentation2.slides.forEach((slide, index2) => {
37802
38092
  const overrides = options.slideOptions?.(slide, index2) ?? {};
@@ -37817,13 +38107,207 @@ function paginatePresentation(input, options = {}) {
37817
38107
  pages.push({ sourceSlideIndex: index2, slideIndex: outputStart + pageIndex, mappings: page.mappings.map(remap), ...page.repeatedMappings ? { repeatedMappings: page.repeatedMappings.map(remap) } : {} });
37818
38108
  });
37819
38109
  output.push(...result.slides);
37820
- reservedIds.push(...result.slides.map((slide2) => slide2.id).filter(Boolean));
38110
+ reservedIds.push(...result.slides.flatMap((slide2) => slideIds(slide2)));
37821
38111
  });
37822
38112
  presentation2.slides = output;
37823
38113
  assertValidPresentation(presentation2);
37824
38114
  return { presentation: presentation2, pages };
37825
38115
  }
37826
38116
 
38117
+ // ../javascript/dist/index.js
38118
+ function reportKey(kind2, id) {
38119
+ return `${kind2}:${id}`;
38120
+ }
38121
+ function referenceId(value) {
38122
+ if (typeof value === "string" && bareIdPattern.test(value)) return value;
38123
+ if (isRecord(value) && typeof value.id === "string" && bareIdPattern.test(value.id)) return value.id;
38124
+ return void 0;
38125
+ }
38126
+ function addReference(collector, kind2, value, reportable) {
38127
+ const id = referenceId(value);
38128
+ if (!id) return;
38129
+ if (reportable) collector.reportable.add(reportKey(kind2, id));
38130
+ let ids = collector.referenced.get(kind2);
38131
+ if (!ids) {
38132
+ ids = /* @__PURE__ */ new Set();
38133
+ collector.referenced.set(kind2, ids);
38134
+ }
38135
+ if (ids.has(id)) return;
38136
+ ids.add(id);
38137
+ collector.queue.push({ kind: kind2, id });
38138
+ }
38139
+ function collectDesignReferences(collector, design) {
38140
+ if (!isRecord(design)) return;
38141
+ addReference(collector, "themes", design.theme, true);
38142
+ addReference(collector, "colorSchemes", design.colorScheme, true);
38143
+ addReference(collector, "fontSchemes", design.fontScheme, true);
38144
+ if (isRecord(design.theme)) {
38145
+ addReference(collector, "colorSchemes", design.theme.colorScheme, true);
38146
+ addReference(collector, "fontSchemes", design.theme.fontScheme, true);
38147
+ }
38148
+ }
38149
+ function collectChartReference(collector, payload) {
38150
+ if (!isRecord(payload.chart)) return;
38151
+ addReference(collector, "chartTypes", payload.chart.type, typeof payload.chart.type === "string");
38152
+ }
38153
+ function collectSocialReferences(collector, holder) {
38154
+ const entries = Array.isArray(holder) ? holder : [holder];
38155
+ for (const entry of entries) {
38156
+ if (!isRecord(entry) || !isRecord(entry.socials)) continue;
38157
+ for (const key of Object.keys(entry.socials)) addReference(collector, "socialPlatforms", key, false);
38158
+ }
38159
+ }
38160
+ function collectBeatReferences(collector, narrative2) {
38161
+ if (!isRecord(narrative2) || !Array.isArray(narrative2.beats)) return;
38162
+ for (const beat of narrative2.beats) {
38163
+ if (isRecord(beat)) addReference(collector, "layouts", beat.layoutHint, false);
38164
+ }
38165
+ }
38166
+ function collectLanguageReferences(collector, language2) {
38167
+ addReference(collector, "languages", language2, false);
38168
+ if (!isRecord(language2)) return;
38169
+ addReference(collector, "fontSchemes", language2.fontScheme, false);
38170
+ addReference(collector, "fontSchemes", language2.googleFontScheme, false);
38171
+ }
38172
+ function collectDocumentReferences(collector, document) {
38173
+ addReference(collector, "narratives", document.narrative, typeof document.narrative === "string");
38174
+ collectBeatReferences(collector, document.narrative);
38175
+ addReference(collector, "tones", document.tone, false);
38176
+ addReference(collector, "purposes", document.purpose, false);
38177
+ collectLanguageReferences(collector, document.language);
38178
+ const audiences2 = Array.isArray(document.audience) ? document.audience : [document.audience];
38179
+ for (const entry of audiences2) addReference(collector, "audiences", entry, false);
38180
+ collectDesignReferences(collector, document.design);
38181
+ collectSocialReferences(collector, document.organization);
38182
+ collectSocialReferences(collector, document.speaker);
38183
+ if (!Array.isArray(document.slides)) return;
38184
+ for (const slide of document.slides) {
38185
+ if (!isRecord(slide)) continue;
38186
+ addReference(collector, "layouts", slide.layout, false);
38187
+ collectDesignReferences(collector, slide.design);
38188
+ collectChartReference(collector, slide);
38189
+ visitContentPayloads(slide, "", (payload) => {
38190
+ collectChartReference(collector, payload);
38191
+ });
38192
+ }
38193
+ }
38194
+ function collectRecordReferences(collector, kind2, record3) {
38195
+ if (kind2 === "themes") {
38196
+ addReference(collector, "colorSchemes", record3.colorScheme, false);
38197
+ addReference(collector, "fontSchemes", record3.fontScheme, false);
38198
+ } else if (kind2 === "narratives") {
38199
+ collectBeatReferences(collector, record3);
38200
+ } else if (kind2 === "languages") {
38201
+ addReference(collector, "fontSchemes", record3.fontScheme, false);
38202
+ addReference(collector, "fontSchemes", record3.googleFontScheme, false);
38203
+ }
38204
+ }
38205
+ var bundledIndex;
38206
+ function bundledCatalogIndex() {
38207
+ if (bundledIndex) return bundledIndex;
38208
+ const index2 = /* @__PURE__ */ new Map();
38209
+ for (const entry of catalogEntries) {
38210
+ const records = /* @__PURE__ */ new Map();
38211
+ for (const record3 of entry.records) {
38212
+ if (isRecord(record3) && typeof record3.id === "string") records.set(record3.id, record3);
38213
+ }
38214
+ index2.set(entry.kind, records);
38215
+ }
38216
+ bundledIndex = index2;
38217
+ return index2;
38218
+ }
38219
+ function bundledRecord(kind2, id) {
38220
+ const record3 = bundledCatalogIndex().get(kind2)?.get(id);
38221
+ if (!record3) return void 0;
38222
+ const clone2 = structuredClone(record3);
38223
+ delete clone2.$schema;
38224
+ return clone2;
38225
+ }
38226
+ function readKindState(catalogsField, kind2) {
38227
+ const entry = catalogsField[kind2];
38228
+ const inline = /* @__PURE__ */ new Map();
38229
+ if (!isRecord(entry)) return { customSource: false, inline };
38230
+ if (Array.isArray(entry.records)) {
38231
+ for (const record3 of entry.records) {
38232
+ if (isRecord(record3) && typeof record3.id === "string") inline.set(record3.id, record3);
38233
+ }
38234
+ }
38235
+ const customSource = typeof entry.source === "string" || Array.isArray(entry.source) && entry.source.length > 0;
38236
+ return { customSource, inline };
38237
+ }
38238
+ function kindState(states, catalogsField, kind2) {
38239
+ const cached = states.get(kind2);
38240
+ if (cached) return cached;
38241
+ const state = readKindState(catalogsField, kind2);
38242
+ states.set(kind2, state);
38243
+ return state;
38244
+ }
38245
+ function pushReportId(map, kind2, id) {
38246
+ const list = map[kind2];
38247
+ if (list) list.push(id);
38248
+ else map[kind2] = [id];
38249
+ }
38250
+ function bundlePresentation(value) {
38251
+ const report2 = { added: {}, alreadyInline: {}, keptSources: [], unresolved: {} };
38252
+ if (!isRecord(value)) {
38253
+ return { presentation: value, report: report2 };
38254
+ }
38255
+ const presentation2 = structuredClone(value);
38256
+ if (presentation2.catalogs !== void 0 && !isRecord(presentation2.catalogs)) {
38257
+ return { presentation: presentation2, report: report2 };
38258
+ }
38259
+ const catalogsField = isRecord(presentation2.catalogs) ? presentation2.catalogs : {};
38260
+ const collector = { queue: [], referenced: /* @__PURE__ */ new Map(), reportable: /* @__PURE__ */ new Set() };
38261
+ collectDocumentReferences(collector, presentation2);
38262
+ const states = /* @__PURE__ */ new Map();
38263
+ const resolved = /* @__PURE__ */ new Map();
38264
+ for (let index2 = 0; index2 < collector.queue.length; index2 += 1) {
38265
+ const pending = collector.queue[index2];
38266
+ if (!pending) continue;
38267
+ const { kind: kind2, id } = pending;
38268
+ const state = kindState(states, catalogsField, kind2);
38269
+ const inlineRecord = state.inline.get(id);
38270
+ if (inlineRecord) {
38271
+ collectRecordReferences(collector, kind2, inlineRecord);
38272
+ continue;
38273
+ }
38274
+ if (state.customSource) continue;
38275
+ const record3 = bundledRecord(kind2, id);
38276
+ if (!record3) continue;
38277
+ let kindRecords = resolved.get(kind2);
38278
+ if (!kindRecords) {
38279
+ kindRecords = /* @__PURE__ */ new Map();
38280
+ resolved.set(kind2, kindRecords);
38281
+ }
38282
+ kindRecords.set(id, record3);
38283
+ collectRecordReferences(collector, kind2, record3);
38284
+ }
38285
+ for (const [kind2, ids] of collector.referenced) {
38286
+ const state = kindState(states, catalogsField, kind2);
38287
+ if (state.customSource) report2.keptSources.push(kind2);
38288
+ const kindResolved = resolved.get(kind2);
38289
+ const addedIds = [];
38290
+ for (const id of [...ids].sort()) {
38291
+ if (state.inline.has(id)) pushReportId(report2.alreadyInline, kind2, id);
38292
+ else if (kindResolved?.has(id)) addedIds.push(id);
38293
+ else if (!state.customSource && collector.reportable.has(reportKey(kind2, id))) {
38294
+ pushReportId(report2.unresolved, kind2, id);
38295
+ }
38296
+ }
38297
+ if (!addedIds.length) continue;
38298
+ if (!isRecord(presentation2.catalogs)) presentation2.catalogs = {};
38299
+ const catalogs2 = presentation2.catalogs;
38300
+ if (!isRecord(catalogs2[kind2])) catalogs2[kind2] = {};
38301
+ const entry = catalogs2[kind2];
38302
+ if (!Array.isArray(entry.records)) entry.records = [];
38303
+ const records = entry.records;
38304
+ for (const id of addedIds) records.push(kindResolved?.get(id));
38305
+ report2.added[kind2] = addedIds;
38306
+ }
38307
+ report2.keptSources.sort();
38308
+ return { presentation: presentation2, report: report2 };
38309
+ }
38310
+
37827
38311
  // src/patch.ts
37828
38312
  init_define_OPF_SKILLS();
37829
38313
  var PatchError = class extends Error {
@@ -38200,6 +38684,7 @@ var usage = `OPF \u2014 local presentation files for agents (Node 24)
38200
38684
  [--chart-type <id>] [--no-header] [--delimiter <character>] [--title <text>]
38201
38685
  [--force] [--strict]
38202
38686
  opf paginate <input|-> <output|-> [--force] [--strict]
38687
+ opf bundle <input|-> <output|-> [--force] [--strict]
38203
38688
  opf schemas
38204
38689
  opf schema [name] [JSON-Pointer]
38205
38690
  opf catalogs
@@ -38214,6 +38699,9 @@ Edits apply JSON Patch (add/remove/replace/move/copy/test), validate the whole
38214
38699
  result, and save atomically. --dry-run emits the result without saving.
38215
38700
  Exit codes: 0 success, 1 invalid document/patch/conflict, 2 usage/JSON/I/O error.
38216
38701
  Validation checks structure and references, not visual fidelity.
38702
+ Bundle inlines the bundled catalog records a document references (kinds with a
38703
+ custom source are left untouched) so the file resolves every catalog reference
38704
+ offline. Remote media and data assets are not inlined.
38217
38705
  Lint adds source locations, contextual suggestions and explicit host contracts.
38218
38706
  Lint syntax/schema/policy errors exit 1; --strict also rejects warnings.
38219
38707
 
@@ -38321,7 +38809,7 @@ async function main(argv) {
38321
38809
  return;
38322
38810
  }
38323
38811
  if (argv.length === 1 && argv[0] === "--version") {
38324
- print({ cli: "0.8.1", opf: "0.10.1" });
38812
+ print({ cli: "0.9.0", opf: "0.11.0" });
38325
38813
  return;
38326
38814
  }
38327
38815
  const [command, ...args] = argv;
@@ -38332,7 +38820,7 @@ async function main(argv) {
38332
38820
  if (command === "skills") {
38333
38821
  const { positional, options } = parse2(args, ["agent", "global", "directory"]);
38334
38822
  arity(positional, 1);
38335
- print(await manageSkills(positional[0], define_OPF_SKILLS_default, "0.8.1", { agent: options.agent, global: !!options.global, directory: options.directory }));
38823
+ print(await manageSkills(positional[0], define_OPF_SKILLS_default, "0.9.0", { agent: options.agent, global: !!options.global, directory: options.directory }));
38336
38824
  return;
38337
38825
  }
38338
38826
  if (command === "create") {
@@ -38367,7 +38855,7 @@ async function main(argv) {
38367
38855
  print({
38368
38856
  ...result,
38369
38857
  sha256: hash(raw),
38370
- opfVersion: "0.10.1",
38858
+ opfVersion: "0.11.0",
38371
38859
  ...config ? { context: { file: path2.resolve(String(options.config)), sha256: hash(config.raw) } } : {}
38372
38860
  });
38373
38861
  if (!result.valid || options.strict && result.counts.warning) process.exitCode = 1;
@@ -38436,6 +38924,15 @@ async function main(argv) {
38436
38924
  await emit(result.presentation, positional[1], options, void 0, { pages: result.pages });
38437
38925
  return;
38438
38926
  }
38927
+ if (command === "bundle") {
38928
+ const { positional, options } = parse2(args, ["force", "strict"]);
38929
+ arity(positional, 2);
38930
+ const source = await readJson(positional[0]);
38931
+ checked(source.value, !!options.strict);
38932
+ const result = bundlePresentation(source.value);
38933
+ await emit(result.presentation, positional[1], options, void 0, { bundle: result.report });
38934
+ return;
38935
+ }
38439
38936
  if (command === "schemas") {
38440
38937
  arity(args, 0);
38441
38938
  print(schemaEntries.map((entry) => ({ name: entry.name, file: entry.file, id: entry.schema.$id })));