@albionlabs/brochure-templates 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +42 -0
  2. package/dist/assets/favicon.svg +1 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +4 -0
  5. package/dist/registry.d.ts +4 -0
  6. package/dist/registry.js +16 -0
  7. package/dist/shared/styles/print-base.css +12 -0
  8. package/dist/templates/investor-pitch/InvestorPitchRenderer.svelte +101 -0
  9. package/dist/templates/investor-pitch/InvestorPitchRenderer.svelte.d.ts +7 -0
  10. package/dist/templates/investor-pitch/components/AssetLocation.svelte +143 -0
  11. package/dist/templates/investor-pitch/components/AssetLocation.svelte.d.ts +9 -0
  12. package/dist/templates/investor-pitch/components/DevelopmentTimeline.svelte +88 -0
  13. package/dist/templates/investor-pitch/components/DevelopmentTimeline.svelte.d.ts +8 -0
  14. package/dist/templates/investor-pitch/components/Footer.svelte +46 -0
  15. package/dist/templates/investor-pitch/components/Footer.svelte.d.ts +8 -0
  16. package/dist/templates/investor-pitch/components/Header.svelte +86 -0
  17. package/dist/templates/investor-pitch/components/Header.svelte.d.ts +9 -0
  18. package/dist/templates/investor-pitch/components/InvestmentThesis.svelte +43 -0
  19. package/dist/templates/investor-pitch/components/InvestmentThesis.svelte.d.ts +7 -0
  20. package/dist/templates/investor-pitch/components/KeyPartners.svelte +69 -0
  21. package/dist/templates/investor-pitch/components/KeyPartners.svelte.d.ts +8 -0
  22. package/dist/templates/investor-pitch/components/KeyRisks.svelte +48 -0
  23. package/dist/templates/investor-pitch/components/KeyRisks.svelte.d.ts +7 -0
  24. package/dist/templates/investor-pitch/components/PortfolioValueChart.svelte +150 -0
  25. package/dist/templates/investor-pitch/components/PortfolioValueChart.svelte.d.ts +11 -0
  26. package/dist/templates/investor-pitch/components/SensitivitySection.svelte +214 -0
  27. package/dist/templates/investor-pitch/components/SensitivitySection.svelte.d.ts +7 -0
  28. package/dist/templates/investor-pitch/components/ValuePropositions.svelte +71 -0
  29. package/dist/templates/investor-pitch/components/ValuePropositions.svelte.d.ts +8 -0
  30. package/dist/templates/investor-pitch/index.d.ts +5 -0
  31. package/dist/templates/investor-pitch/index.js +4 -0
  32. package/dist/templates/investor-pitch/meta.d.ts +2 -0
  33. package/dist/templates/investor-pitch/meta.js +7 -0
  34. package/dist/templates/investor-pitch/print.css +12 -0
  35. package/dist/templates/investor-pitch/sample.json +159 -0
  36. package/dist/templates/investor-pitch/schema.json +360 -0
  37. package/dist/templates/investor-pitch/types.d.ts +118 -0
  38. package/dist/templates/investor-pitch/types.js +1 -0
  39. package/dist/types.d.ts +16 -0
  40. package/dist/types.js +1 -0
  41. package/package.json +50 -0
@@ -0,0 +1,69 @@
1
+ <script lang="ts">
2
+ import type { Partner } from '../types.js';
3
+
4
+ interface Props {
5
+ title: string;
6
+ partners: Partner[];
7
+ }
8
+
9
+ let { title, partners }: Props = $props();
10
+ </script>
11
+
12
+ <section class="card">
13
+ <h2 class="section-title">{title}</h2>
14
+ <div class="partners-grid">
15
+ {#each partners as partner}
16
+ <div class="partner-cell">
17
+ <span class="partner-name">{partner.name}</span>
18
+ <span class="partner-desc">{partner.description}</span>
19
+ </div>
20
+ {/each}
21
+ </div>
22
+ </section>
23
+
24
+ <style>
25
+ .card {
26
+ background: #fff;
27
+ border: 1px solid #e2e8f0;
28
+ border-radius: 8px;
29
+ padding: 20px 24px;
30
+ }
31
+
32
+ .section-title {
33
+ font-size: 14px;
34
+ font-weight: 700;
35
+ color: #0f172a;
36
+ letter-spacing: 0.5px;
37
+ text-transform: uppercase;
38
+ margin: 0 0 14px;
39
+ }
40
+
41
+ .partners-grid {
42
+ display: grid;
43
+ grid-template-columns: 1fr 1fr;
44
+ gap: 1px;
45
+ background: #e2e8f0;
46
+ border: 1px solid #e2e8f0;
47
+ border-radius: 6px;
48
+ overflow: hidden;
49
+ }
50
+
51
+ .partner-cell {
52
+ background: #fff;
53
+ padding: 12px 14px;
54
+ display: flex;
55
+ flex-direction: column;
56
+ gap: 2px;
57
+ }
58
+
59
+ .partner-name {
60
+ font-size: 13px;
61
+ font-weight: 600;
62
+ color: #0f172a;
63
+ }
64
+
65
+ .partner-desc {
66
+ font-size: 11.5px;
67
+ color: #64748b;
68
+ }
69
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { Partner } from '../types.js';
2
+ interface Props {
3
+ title: string;
4
+ partners: Partner[];
5
+ }
6
+ declare const KeyPartners: import("svelte").Component<Props, {}, "">;
7
+ type KeyPartners = ReturnType<typeof KeyPartners>;
8
+ export default KeyPartners;
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ title: string;
4
+ risks: string[];
5
+ }
6
+
7
+ let { title, risks }: Props = $props();
8
+ </script>
9
+
10
+ <section class="card">
11
+ <h2 class="section-title">{title}</h2>
12
+ <p class="risks-text">
13
+ {#each risks as risk, i}
14
+ {#if i > 0}
15
+ <span class="bullet"> &middot; </span>
16
+ {/if}{risk}{/each}
17
+ </p>
18
+ </section>
19
+
20
+ <style>
21
+ .card {
22
+ background: #fff;
23
+ border: 1px solid #e2e8f0;
24
+ border-radius: 8px;
25
+ padding: 20px 24px;
26
+ }
27
+
28
+ .section-title {
29
+ font-size: 14px;
30
+ font-weight: 700;
31
+ color: #0f172a;
32
+ letter-spacing: 0.5px;
33
+ text-transform: uppercase;
34
+ margin: 0 0 12px;
35
+ }
36
+
37
+ .risks-text {
38
+ font-size: 13px;
39
+ line-height: 1.6;
40
+ color: #374151;
41
+ margin: 0;
42
+ }
43
+
44
+ .bullet {
45
+ color: #94a3b8;
46
+ margin: 0 2px;
47
+ }
48
+ </style>
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ title: string;
3
+ risks: string[];
4
+ }
5
+ declare const KeyRisks: import("svelte").Component<Props, {}, "">;
6
+ type KeyRisks = ReturnType<typeof KeyRisks>;
7
+ export default KeyRisks;
@@ -0,0 +1,150 @@
1
+ <script lang="ts">
2
+ import type { PortfolioAsset, DevProbability } from '../types.js';
3
+
4
+ interface Props {
5
+ title: string;
6
+ assets: PortfolioAsset[];
7
+ maxValue: number;
8
+ gridLines: number[];
9
+ developmentProbabilities: DevProbability[];
10
+ }
11
+
12
+ let { title, assets, maxValue, gridLines, developmentProbabilities }: Props = $props();
13
+
14
+ const chartLeft = 110;
15
+ const chartRight = 480;
16
+ const chartTop = 10;
17
+ const barHeight = 18;
18
+ const barGap = 4;
19
+ const groupGap = 16;
20
+ const chartWidth = chartRight - chartLeft;
21
+
22
+ function xPos(val: number): number {
23
+ return chartLeft + (val / maxValue) * chartWidth;
24
+ }
25
+
26
+ function getBarGroups() {
27
+ let y = chartTop;
28
+ const groups: Array<{
29
+ name: string;
30
+ labelY: number;
31
+ bars: Array<{ x: number; width: number; y: number; height: number; color: string }>;
32
+ }> = [];
33
+
34
+ for (const asset of assets) {
35
+ const groupStart = y;
36
+ const bars = asset.bars.map((bar) => {
37
+ const barY = y;
38
+ y += barHeight + barGap;
39
+ return {
40
+ x: chartLeft,
41
+ width: (bar.value / maxValue) * chartWidth,
42
+ y: barY,
43
+ height: barHeight,
44
+ color: bar.color
45
+ };
46
+ });
47
+ const labelY = groupStart + ((y - barGap - groupStart) / 2);
48
+ groups.push({ name: asset.name, labelY, bars });
49
+ y += groupGap;
50
+ }
51
+
52
+ return { groups, totalHeight: y };
53
+ }
54
+
55
+ const { groups, totalHeight } = getBarGroups();
56
+ const svgHeight = totalHeight + 30;
57
+ </script>
58
+
59
+ <section class="card">
60
+ <h2 class="section-title">{title}</h2>
61
+ <svg viewBox="0 0 500 {svgHeight}" class="chart-svg" xmlns="http://www.w3.org/2000/svg">
62
+ <!-- Grid lines -->
63
+ {#each gridLines as val}
64
+ <line
65
+ x1={xPos(val)}
66
+ y1={chartTop - 4}
67
+ x2={xPos(val)}
68
+ y2={totalHeight}
69
+ stroke="#e2e8f0"
70
+ stroke-width="0.5"
71
+ />
72
+ <text
73
+ x={xPos(val)}
74
+ y={totalHeight + 14}
75
+ text-anchor="middle"
76
+ font-size="9"
77
+ fill="#94a3b8">${val}m</text
78
+ >
79
+ {/each}
80
+
81
+ <!-- Bars -->
82
+ {#each groups as group}
83
+ <text
84
+ x={chartLeft - 8}
85
+ y={group.labelY + 5}
86
+ text-anchor="end"
87
+ font-size="10"
88
+ fill="#374151">{group.name}</text
89
+ >
90
+ {#each group.bars as bar}
91
+ <rect
92
+ x={bar.x}
93
+ y={bar.y}
94
+ width={bar.width}
95
+ height={bar.height}
96
+ fill={bar.color}
97
+ rx="2"
98
+ />
99
+ {/each}
100
+ {/each}
101
+ </svg>
102
+ <div class="probabilities">
103
+ <span class="prob-label">Development Probabilities:</span>
104
+ {#each developmentProbabilities as prob}
105
+ <span class="prob-item" style="color: {prob.color}"
106
+ >{prob.name}: {prob.percentage}%</span
107
+ >
108
+ {/each}
109
+ </div>
110
+ </section>
111
+
112
+ <style>
113
+ .card {
114
+ background: #fff;
115
+ border: 1px solid #e2e8f0;
116
+ border-radius: 8px;
117
+ padding: 20px 24px;
118
+ }
119
+
120
+ .section-title {
121
+ font-size: 14px;
122
+ font-weight: 700;
123
+ color: #0f172a;
124
+ letter-spacing: 0.5px;
125
+ text-transform: uppercase;
126
+ margin: 0 0 10px;
127
+ }
128
+
129
+ .chart-svg {
130
+ width: 100%;
131
+ height: auto;
132
+ }
133
+
134
+ .probabilities {
135
+ margin-top: 8px;
136
+ font-size: 11px;
137
+ display: flex;
138
+ flex-wrap: wrap;
139
+ gap: 4px 12px;
140
+ }
141
+
142
+ .prob-label {
143
+ font-weight: 600;
144
+ color: #0f172a;
145
+ }
146
+
147
+ .prob-item {
148
+ font-weight: 600;
149
+ }
150
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { PortfolioAsset, DevProbability } from '../types.js';
2
+ interface Props {
3
+ title: string;
4
+ assets: PortfolioAsset[];
5
+ maxValue: number;
6
+ gridLines: number[];
7
+ developmentProbabilities: DevProbability[];
8
+ }
9
+ declare const PortfolioValueChart: import("svelte").Component<Props, {}, "">;
10
+ type PortfolioValueChart = ReturnType<typeof PortfolioValueChart>;
11
+ export default PortfolioValueChart;
@@ -0,0 +1,214 @@
1
+ <script lang="ts">
2
+ import type { InvestorPitch } from '../types.js';
3
+
4
+ interface Props {
5
+ data: InvestorPitch['priceSensitivity'];
6
+ }
7
+
8
+ let { data }: Props = $props();
9
+
10
+ const { chart, table, footnote } = $derived(data);
11
+
12
+ // Chart dimensions
13
+ const svgW = 460;
14
+ const svgH = 220;
15
+ const padLeft = 52;
16
+ const padRight = 10;
17
+ const padTop = 12;
18
+ const padBottom = 30;
19
+ const plotW = svgW - padLeft - padRight;
20
+ const plotH = svgH - padTop - padBottom;
21
+
22
+ function scaleX(val: number): number {
23
+ return padLeft + ((val - chart.xRange[0]) / (chart.xRange[1] - chart.xRange[0])) * plotW;
24
+ }
25
+
26
+ function scaleY(val: number): number {
27
+ return padTop + plotH - ((val - chart.yRange[0]) / (chart.yRange[1] - chart.yRange[0])) * plotH;
28
+ }
29
+
30
+ const linePath = $derived(
31
+ chart.dataPoints
32
+ .map((p, i) => `${i === 0 ? 'M' : 'L'} ${scaleX(p.x)} ${scaleY(p.y)}`)
33
+ .join(' ')
34
+ );
35
+
36
+ const xTicks = $derived(() => {
37
+ const ticks: number[] = [];
38
+ for (let v = chart.xRange[0]; v <= chart.xRange[1]; v += chart.xStep) {
39
+ ticks.push(v);
40
+ }
41
+ return ticks;
42
+ });
43
+
44
+ const yTicks = $derived(() => {
45
+ const ticks: number[] = [];
46
+ for (let v = chart.yRange[0]; v <= chart.yRange[1]; v += chart.yStep) {
47
+ ticks.push(v);
48
+ }
49
+ return ticks;
50
+ });
51
+ </script>
52
+
53
+ <section class="card">
54
+ <h2 class="section-title">{data.title}</h2>
55
+
56
+ <!-- Line Chart -->
57
+ <svg viewBox="0 0 {svgW} {svgH}" class="line-chart" xmlns="http://www.w3.org/2000/svg">
58
+ <!-- Y grid lines and labels -->
59
+ {#each yTicks() as val}
60
+ <line
61
+ x1={padLeft}
62
+ y1={scaleY(val)}
63
+ x2={svgW - padRight}
64
+ y2={scaleY(val)}
65
+ stroke="#e2e8f0"
66
+ stroke-width="0.5"
67
+ />
68
+ <text
69
+ x={padLeft - 6}
70
+ y={scaleY(val) + 3}
71
+ text-anchor="end"
72
+ font-size="9"
73
+ fill="#94a3b8">${val}m</text
74
+ >
75
+ {/each}
76
+
77
+ <!-- X labels -->
78
+ {#each xTicks() as val}
79
+ <text
80
+ x={scaleX(val)}
81
+ y={svgH - 6}
82
+ text-anchor="middle"
83
+ font-size="9"
84
+ fill="#94a3b8">${val}</text
85
+ >
86
+ {/each}
87
+
88
+ <!-- Base case dashed line -->
89
+ <line
90
+ x1={scaleX(chart.baseCaseX)}
91
+ y1={padTop}
92
+ x2={scaleX(chart.baseCaseX)}
93
+ y2={padTop + plotH}
94
+ stroke="#94a3b8"
95
+ stroke-width="0.8"
96
+ stroke-dasharray="4,3"
97
+ />
98
+ <text
99
+ x={scaleX(chart.baseCaseX)}
100
+ y={scaleY(chart.dataPoints.find((p) => p.x === chart.baseCaseX)?.y ?? 44) + 14}
101
+ text-anchor="middle"
102
+ font-size="8.5"
103
+ fill="#64748b"
104
+ font-weight="500">{chart.baseCaseLabel}</text
105
+ >
106
+
107
+ <!-- Area fill under line -->
108
+ <path
109
+ d="{linePath} L {scaleX(chart.dataPoints[chart.dataPoints.length - 1].x)} {padTop + plotH} L {scaleX(chart.dataPoints[0].x)} {padTop + plotH} Z"
110
+ fill="#0d9488"
111
+ fill-opacity="0.06"
112
+ />
113
+
114
+ <!-- Line -->
115
+ <path d={linePath} fill="none" stroke="#0d9488" stroke-width="2" />
116
+
117
+ <!-- Data points -->
118
+ {#each chart.dataPoints as point}
119
+ <circle
120
+ cx={scaleX(point.x)}
121
+ cy={scaleY(point.y)}
122
+ r="3"
123
+ fill="#fff"
124
+ stroke="#0d9488"
125
+ stroke-width="1.5"
126
+ />
127
+ {/each}
128
+ </svg>
129
+
130
+ <!-- Data Table -->
131
+ <table class="data-table">
132
+ <thead>
133
+ <tr>
134
+ {#each table.columns as col}
135
+ <th>{col.label}</th>
136
+ {/each}
137
+ </tr>
138
+ </thead>
139
+ <tbody>
140
+ {#each table.rows as row, rowIdx}
141
+ <tr class:highlight-row={rowIdx === table.highlightRowIndex}>
142
+ {#each table.columns as col}
143
+ <td
144
+ style={col.highlightColor ? `color: ${col.highlightColor}; font-weight: 600` : ''}
145
+ >
146
+ {row[col.key]}
147
+ </td>
148
+ {/each}
149
+ </tr>
150
+ {/each}
151
+ </tbody>
152
+ </table>
153
+
154
+ {#if footnote}
155
+ <p class="footnote">{footnote}</p>
156
+ {/if}
157
+ </section>
158
+
159
+ <style>
160
+ .card {
161
+ background: #fff;
162
+ border: 1px solid #e2e8f0;
163
+ border-radius: 8px;
164
+ padding: 20px 24px;
165
+ }
166
+
167
+ .section-title {
168
+ font-size: 14px;
169
+ font-weight: 700;
170
+ color: #0f172a;
171
+ letter-spacing: 0.5px;
172
+ text-transform: uppercase;
173
+ margin: 0 0 10px;
174
+ }
175
+
176
+ .line-chart {
177
+ width: 100%;
178
+ height: auto;
179
+ }
180
+
181
+ .data-table {
182
+ width: 100%;
183
+ border-collapse: collapse;
184
+ font-size: 12px;
185
+ margin-top: 12px;
186
+ }
187
+
188
+ .data-table th {
189
+ text-align: left;
190
+ font-weight: 600;
191
+ color: #374151;
192
+ padding: 6px 8px;
193
+ border-bottom: 1.5px solid #cbd5e1;
194
+ font-size: 11px;
195
+ }
196
+
197
+ .data-table td {
198
+ padding: 5px 8px;
199
+ color: #374151;
200
+ border-bottom: 1px solid #f1f5f9;
201
+ }
202
+
203
+ .highlight-row td {
204
+ font-weight: 700;
205
+ color: #0f172a;
206
+ }
207
+
208
+ .footnote {
209
+ font-size: 10.5px;
210
+ color: #94a3b8;
211
+ margin: 8px 0 0;
212
+ font-style: italic;
213
+ }
214
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { InvestorPitch } from '../types.js';
2
+ interface Props {
3
+ data: InvestorPitch['priceSensitivity'];
4
+ }
5
+ declare const SensitivitySection: import("svelte").Component<Props, {}, "">;
6
+ type SensitivitySection = ReturnType<typeof SensitivitySection>;
7
+ export default SensitivitySection;
@@ -0,0 +1,71 @@
1
+ <script lang="ts">
2
+ import type { ValueProposition } from '../types.js';
3
+
4
+ interface Props {
5
+ title: string;
6
+ items: ValueProposition[];
7
+ }
8
+
9
+ let { title, items }: Props = $props();
10
+ </script>
11
+
12
+ <section class="card">
13
+ <h2 class="section-title">{title}</h2>
14
+ <ul class="prop-list">
15
+ {#each items as item}
16
+ <li class="prop-item">
17
+ <span class="check">&#10003;</span>
18
+ <span class="prop-text">{@html item.text}</span>
19
+ </li>
20
+ {/each}
21
+ </ul>
22
+ </section>
23
+
24
+ <style>
25
+ .card {
26
+ background: #fff;
27
+ border: 1px solid #e2e8f0;
28
+ border-radius: 8px;
29
+ padding: 20px 24px;
30
+ }
31
+
32
+ .section-title {
33
+ font-size: 14px;
34
+ font-weight: 700;
35
+ color: #0f172a;
36
+ letter-spacing: 0.5px;
37
+ text-transform: uppercase;
38
+ margin: 0 0 14px;
39
+ }
40
+
41
+ .prop-list {
42
+ list-style: none;
43
+ margin: 0;
44
+ padding: 0;
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: 10px;
48
+ }
49
+
50
+ .prop-item {
51
+ display: flex;
52
+ align-items: flex-start;
53
+ gap: 10px;
54
+ font-size: 13.5px;
55
+ line-height: 1.5;
56
+ color: #374151;
57
+ }
58
+
59
+ .check {
60
+ color: #10b981;
61
+ font-weight: 700;
62
+ font-size: 15px;
63
+ flex-shrink: 0;
64
+ margin-top: 1px;
65
+ }
66
+
67
+ .prop-text :global(strong) {
68
+ color: #0f172a;
69
+ font-weight: 600;
70
+ }
71
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { ValueProposition } from '../types.js';
2
+ interface Props {
3
+ title: string;
4
+ items: ValueProposition[];
5
+ }
6
+ declare const ValuePropositions: import("svelte").Component<Props, {}, "">;
7
+ type ValuePropositions = ReturnType<typeof ValuePropositions>;
8
+ export default ValuePropositions;
@@ -0,0 +1,5 @@
1
+ export { default as InvestorPitchRenderer } from './InvestorPitchRenderer.svelte';
2
+ export { investorPitchMeta } from './meta.js';
3
+ export { default as investorPitchSchema } from './schema.json';
4
+ export { default as investorPitchSampleData } from './sample.json';
5
+ export type * from './types.js';
@@ -0,0 +1,4 @@
1
+ export { default as InvestorPitchRenderer } from './InvestorPitchRenderer.svelte';
2
+ export { investorPitchMeta } from './meta.js';
3
+ export { default as investorPitchSchema } from './schema.json';
4
+ export { default as investorPitchSampleData } from './sample.json';
@@ -0,0 +1,2 @@
1
+ import type { TemplateMeta } from '../../types.js';
2
+ export declare const investorPitchMeta: TemplateMeta;
@@ -0,0 +1,7 @@
1
+ export const investorPitchMeta = {
2
+ id: 'investor-pitch',
3
+ name: 'Investor Pitch',
4
+ description: 'Single-page investor summary with key metrics, charts, and risk analysis',
5
+ version: '1.0.0',
6
+ category: 'investor-relations'
7
+ };
@@ -0,0 +1,12 @@
1
+ @media print {
2
+ .pitch-page {
3
+ max-width: none;
4
+ border-radius: 0;
5
+ box-shadow: none;
6
+ }
7
+
8
+ @page {
9
+ size: A4 landscape;
10
+ margin: 10mm;
11
+ }
12
+ }