@schneiderelli/cms-runtime 0.0.3 → 0.0.5

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/dist/components/BlockRenderer.svelte +106 -71
  2. package/dist/components/BlockRenderer.svelte.d.ts +15 -4
  3. package/dist/components/blocks/AdBlock.svelte +58 -0
  4. package/dist/components/blocks/AdBlock.svelte.d.ts +9 -0
  5. package/dist/components/blocks/AffiliateBlock.svelte +50 -0
  6. package/dist/components/blocks/AffiliateBlock.svelte.d.ts +9 -0
  7. package/dist/components/blocks/BreadcrumbBlock.svelte +30 -0
  8. package/dist/components/blocks/BreadcrumbBlock.svelte.d.ts +9 -0
  9. package/dist/components/blocks/ChildrenBlock.svelte +46 -0
  10. package/dist/components/blocks/ChildrenBlock.svelte.d.ts +9 -0
  11. package/dist/components/blocks/DividerBlock.svelte +9 -0
  12. package/dist/components/blocks/DividerBlock.svelte.d.ts +26 -0
  13. package/dist/components/blocks/FaqBlock.svelte +77 -0
  14. package/dist/components/blocks/FaqBlock.svelte.d.ts +7 -0
  15. package/dist/components/blocks/HeadingBlock.svelte +35 -5
  16. package/dist/components/blocks/HeadingBlock.svelte.d.ts +3 -3
  17. package/dist/components/blocks/HeroBlock.svelte +43 -0
  18. package/dist/components/blocks/HeroBlock.svelte.d.ts +7 -0
  19. package/dist/components/blocks/HowToBlock.svelte +100 -0
  20. package/dist/components/blocks/HowToBlock.svelte.d.ts +7 -0
  21. package/dist/components/blocks/ImageBlock.svelte +42 -3
  22. package/dist/components/blocks/ImageBlock.svelte.d.ts +3 -3
  23. package/dist/components/blocks/LinksBlock.svelte +66 -0
  24. package/dist/components/blocks/LinksBlock.svelte.d.ts +7 -0
  25. package/dist/components/blocks/MarkdownBlock.svelte +118 -0
  26. package/dist/components/blocks/MarkdownBlock.svelte.d.ts +7 -0
  27. package/dist/components/blocks/NoteBlock.svelte +59 -0
  28. package/dist/components/blocks/NoteBlock.svelte.d.ts +7 -0
  29. package/dist/components/blocks/QuoteBlock.svelte +44 -0
  30. package/dist/components/blocks/QuoteBlock.svelte.d.ts +7 -0
  31. package/dist/index.d.ts +16 -1
  32. package/dist/index.js +26 -1
  33. package/dist/registry.d.ts +43 -0
  34. package/dist/registry.js +374 -0
  35. package/dist/types.d.ts +253 -23
  36. package/dist/types.js +179 -1
  37. package/package.json +2 -1
  38. package/dist/components/blocks/TextBlock.svelte +0 -8
  39. package/dist/components/blocks/TextBlock.svelte.d.ts +0 -7
  40. package/dist/resolve.d.ts +0 -15
  41. package/dist/resolve.js +0 -15
@@ -1,78 +1,113 @@
1
1
  <script lang="ts">
2
- import type {
3
- Block,
4
- TextBlock,
5
- HeadingBlock,
6
- ImageBlock,
7
- MarkdownBlock,
8
- QuoteBlock,
9
- DividerBlock,
10
- FaqBlock,
11
- HowToBlock
12
- } from "../types.js";
13
- import { marked } from "marked";
14
- let { blocks } = $props<{ blocks: Block[] }>();
2
+ import type { Block } from '../types.js';
3
+ // Block Components
4
+ import MarkdownBlock from './blocks/MarkdownBlock.svelte';
5
+ import HeadingBlock from './blocks/HeadingBlock.svelte';
6
+ import ImageBlock from './blocks/ImageBlock.svelte';
7
+ import QuoteBlock from './blocks/QuoteBlock.svelte';
8
+ import DividerBlock from './blocks/DividerBlock.svelte';
9
+ import NoteBlock from './blocks/NoteBlock.svelte';
10
+ import FaqBlock from './blocks/FaqBlock.svelte';
11
+ import HowToBlock from './blocks/HowToBlock.svelte';
12
+ import HeroBlock from './blocks/HeroBlock.svelte';
13
+ import ChildrenBlock from './blocks/ChildrenBlock.svelte';
14
+ import LinksBlock from './blocks/LinksBlock.svelte';
15
+ import BreadcrumbBlock from './blocks/BreadcrumbBlock.svelte';
16
+ import AffiliateBlock from './blocks/AffiliateBlock.svelte';
17
+ import AdBlock from './blocks/AdBlock.svelte';
18
+
19
+ interface Props {
20
+ /** Die zu rendernden Blocks */
21
+ blocks: Block[];
22
+
23
+ /**
24
+ * Custom Renderer für bestimmte Block-Typen
25
+ * Das Framework kann hier eigene Implementierungen übergeben
26
+ */
27
+ customRenderers?: Partial<Record<Block['type'], import('svelte').Component>>;
28
+
29
+ /**
30
+ * Context-Daten die an Blocks weitergegeben werden
31
+ * z.B. currentSlug für Breadcrumbs
32
+ */
33
+ context?: Record<string, unknown>;
34
+ }
35
+
36
+ let { blocks, customRenderers = {}, context = {} }: Props = $props();
15
37
  </script>
16
38
 
17
- <div class="block-container">
18
- {#each blocks as block}
19
- {#if block.type === "heading"}
20
- <h1 style:margin-bottom="1rem">
21
- {(block as HeadingBlock).text}
22
- </h1>
23
-
24
- {:else if block.type === "text"}
25
- <p>
26
- {(block as TextBlock).content}
27
- </p>
28
-
29
- {:else if block.type === "image"}
30
- <img
31
- src={(block as ImageBlock).src}
32
- alt={(block as ImageBlock).alt ?? ""}
33
- style="max-width: 100%; height: auto; margin: 1rem 0;"
34
- />
35
-
36
- {:else if block.type === "markdown"}
37
- <div class="markdown">
38
- {@html marked((block as MarkdownBlock).content)}
39
- </div>
39
+ <div class="csm-blocks">
40
+ {#each blocks as block (block.id)}
41
+ <div class="csm-block csm-block-{block.type}">
42
+ {#if block.type === 'markdown'}
43
+ <MarkdownBlock {block} />
44
+
45
+ {:else if block.type === 'heading'}
46
+ <HeadingBlock {block} />
47
+
48
+ {:else if block.type === 'image'}
49
+ <ImageBlock {block} />
50
+
51
+ {:else if block.type === 'quote'}
52
+ <QuoteBlock {block} />
53
+
54
+ {:else if block.type === 'divider'}
55
+ <DividerBlock />
56
+
57
+ {:else if block.type === 'note'}
58
+ <NoteBlock {block} />
59
+
60
+ {:else if block.type === 'faq'}
61
+ <FaqBlock {block} />
40
62
 
41
- {:else if block.type === "quote"}
42
- <blockquote style="margin: 1rem 0; font-style: italic;">
43
- <p>{(block as QuoteBlock).text}</p>
44
- {#if (block as QuoteBlock).author}
45
- <footer>– {(block as QuoteBlock).author}</footer>
63
+ {:else if block.type === 'howto'}
64
+ <HowToBlock {block} />
65
+
66
+ {:else if block.type === 'hero'}
67
+ <HeroBlock {block} />
68
+
69
+ {:else if block.type === 'children'}
70
+ <ChildrenBlock {block} />
71
+
72
+ {:else if block.type === 'links'}
73
+ <LinksBlock {block} />
74
+
75
+ {:else if block.type === 'breadcrumb'}
76
+ <BreadcrumbBlock {block} />
77
+
78
+ {:else if block.type === 'affiliate'}
79
+ <AffiliateBlock {block} />
80
+
81
+ {:else if block.type === 'ad'}
82
+ <AdBlock {block} />
83
+
84
+ {:else}
85
+ <div class="csm-block-unknown">
86
+ ⚠️ Unbekannter Block: {(block as { type: string }).type}
87
+ </div>
46
88
  {/if}
47
- </blockquote>
48
-
49
- {:else if block.type === "divider"}
50
- <hr style="margin: 2rem 0;" />
51
-
52
- {:else if block.type === "faq"}
53
- <div class="faq-block">
54
- {#each (block as FaqBlock).items as item}
55
- <details>
56
- <summary>{item.question}</summary>
57
- <div class="markdown">
58
- {@html marked(item.answer)}
59
- </div>
60
- </details>
61
- {/each}
62
89
  </div>
63
-
64
- {:else if block.type === "howto"}
65
- <ol class="howto-block">
66
- {#each (block as HowToBlock).steps as step}
67
- <li>
68
- <strong>{step.title}</strong>
69
- <div class="markdown">
70
- {@html marked(step.description)}
71
- </div>
72
- </li>
73
- {/each}
74
- </ol>
75
-
76
- {/if}
77
- {/each}
90
+ {/each}
78
91
  </div>
92
+
93
+ <style>
94
+ .csm-blocks {
95
+ display: flex;
96
+ flex-direction: column;
97
+ gap: 1.5rem;
98
+ }
99
+
100
+ .csm-block {
101
+ /* Blocks können diese Variable nutzen für Animation/Highlight im Editor */
102
+ --csm-block-highlight: transparent;
103
+ }
104
+
105
+ .csm-block-unknown {
106
+ padding: 1rem;
107
+ background: #fef3c7;
108
+ border: 1px solid #f59e0b;
109
+ border-radius: 0.5rem;
110
+ color: #92400e;
111
+ font-size: 0.875rem;
112
+ }
113
+ </style>
@@ -1,7 +1,18 @@
1
- import type { Block } from "../types.ts";
2
- type $$ComponentProps = {
1
+ import type { Block } from '../types.ts';
2
+ interface Props {
3
+ /** Die zu rendernden Blocks */
3
4
  blocks: Block[];
4
- };
5
- declare const BlockRenderer: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ /**
6
+ * Custom Renderer für bestimmte Block-Typen
7
+ * Das Framework kann hier eigene Implementierungen übergeben
8
+ */
9
+ customRenderers?: Partial<Record<Block['type'], import('svelte').Component>>;
10
+ /**
11
+ * Context-Daten die an Blocks weitergegeben werden
12
+ * z.B. currentSlug für Breadcrumbs
13
+ */
14
+ context?: Record<string, unknown>;
15
+ }
16
+ declare const BlockRenderer: import("svelte").Component<Props, {}, "">;
6
17
  type BlockRenderer = ReturnType<typeof BlockRenderer>;
7
18
  export default BlockRenderer;
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import type { AdBlock } from '../../types.js';
3
+
4
+ interface Props {
5
+ block: AdBlock;
6
+ /** Slot für Framework-spezifische Implementierung */
7
+ children?: import('svelte').Snippet;
8
+ }
9
+
10
+ let { block, children }: Props = $props();
11
+ </script>
12
+
13
+ {#if children}
14
+ {@render children()}
15
+ {:else}
16
+ <aside class="csm-ad csm-ad-{block.variant ?? 'inline'}">
17
+ <span class="csm-ad-label">Anzeige</span>
18
+ <div class="csm-ad-placeholder">
19
+ <!-- Ad Slot: {block.slot ?? 'auto'} -->
20
+ </div>
21
+ </aside>
22
+ {/if}
23
+
24
+ <style>
25
+ .csm-ad {
26
+ background: var(--csm-muted-bg, #f8fafc);
27
+ border: 1px dashed var(--csm-border-color, #e2e8f0);
28
+ border-radius: 0.5rem;
29
+ overflow: hidden;
30
+ }
31
+
32
+ .csm-ad-label {
33
+ display: block;
34
+ padding: 0.25rem 0.75rem;
35
+ font-size: 0.625rem;
36
+ text-transform: uppercase;
37
+ letter-spacing: 0.05em;
38
+ color: var(--csm-muted-color, #94a3b8);
39
+ background: var(--csm-card-bg, #ffffff);
40
+ border-bottom: 1px dashed var(--csm-border-color, #e2e8f0);
41
+ }
42
+
43
+ .csm-ad-placeholder {
44
+ min-height: 100px;
45
+ }
46
+
47
+ .csm-ad-inline .csm-ad-placeholder {
48
+ min-height: 120px;
49
+ }
50
+
51
+ .csm-ad-banner .csm-ad-placeholder {
52
+ min-height: 90px;
53
+ }
54
+
55
+ .csm-ad-sidebar .csm-ad-placeholder {
56
+ min-height: 250px;
57
+ }
58
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { AdBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: AdBlock;
4
+ /** Slot für Framework-spezifische Implementierung */
5
+ children?: import('svelte').Snippet;
6
+ }
7
+ declare const AdBlock: import("svelte").Component<Props, {}, "">;
8
+ type AdBlock = ReturnType<typeof AdBlock>;
9
+ export default AdBlock;
@@ -0,0 +1,50 @@
1
+ <script lang="ts">
2
+ import type { AffiliateBlock } from '../../types.js';
3
+
4
+ interface Props {
5
+ block: AffiliateBlock;
6
+ /** Slot für Framework-spezifische Implementierung */
7
+ children?: import('svelte').Snippet;
8
+ }
9
+
10
+ let { block, children }: Props = $props();
11
+ </script>
12
+
13
+ {#if children}
14
+ {@render children()}
15
+ {:else}
16
+ <aside class="csm-affiliate csm-affiliate-{block.variant ?? 'box'}">
17
+ <span class="csm-affiliate-label">Affiliate</span>
18
+ <div class="csm-affiliate-placeholder">
19
+ <p>Affiliate: {block.ref ?? 'nicht konfiguriert'}</p>
20
+ </div>
21
+ </aside>
22
+ {/if}
23
+
24
+ <style>
25
+ .csm-affiliate {
26
+ padding: 1rem;
27
+ background: var(--csm-muted-bg, #f8fafc);
28
+ border: 1px dashed var(--csm-border-color, #e2e8f0);
29
+ border-radius: 0.5rem;
30
+ }
31
+
32
+ .csm-affiliate-label {
33
+ display: block;
34
+ font-size: 0.625rem;
35
+ text-transform: uppercase;
36
+ letter-spacing: 0.05em;
37
+ color: var(--csm-muted-color, #94a3b8);
38
+ margin-bottom: 0.5rem;
39
+ }
40
+
41
+ .csm-affiliate-placeholder {
42
+ text-align: center;
43
+ color: var(--csm-muted-color, #94a3b8);
44
+ font-size: 0.875rem;
45
+ }
46
+
47
+ .csm-affiliate-placeholder p {
48
+ margin: 0;
49
+ }
50
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { AffiliateBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: AffiliateBlock;
4
+ /** Slot für Framework-spezifische Implementierung */
5
+ children?: import('svelte').Snippet;
6
+ }
7
+ declare const AffiliateBlock: import("svelte").Component<Props, {}, "">;
8
+ type AffiliateBlock = ReturnType<typeof AffiliateBlock>;
9
+ export default AffiliateBlock;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import type { BreadcrumbBlock } from '../../types.js';
3
+
4
+ interface Props {
5
+ block: BreadcrumbBlock;
6
+ /** Slot für Framework-spezifische Implementierung */
7
+ children?: import('svelte').Snippet;
8
+ }
9
+
10
+ let { block, children }: Props = $props();
11
+ </script>
12
+
13
+ <nav class="csm-breadcrumb" aria-label="Breadcrumb">
14
+ {#if children}
15
+ {@render children()}
16
+ {:else}
17
+ <span class="csm-breadcrumb-placeholder">Startseite › ...</span>
18
+ {/if}
19
+ </nav>
20
+
21
+ <style>
22
+ .csm-breadcrumb {
23
+ font-size: 0.875rem;
24
+ color: var(--csm-muted-color, #64748b);
25
+ }
26
+
27
+ .csm-breadcrumb-placeholder {
28
+ opacity: 0.5;
29
+ }
30
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { BreadcrumbBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: BreadcrumbBlock;
4
+ /** Slot für Framework-spezifische Implementierung */
5
+ children?: import('svelte').Snippet;
6
+ }
7
+ declare const BreadcrumbBlock: import("svelte").Component<Props, {}, "">;
8
+ type BreadcrumbBlock = ReturnType<typeof BreadcrumbBlock>;
9
+ export default BreadcrumbBlock;
@@ -0,0 +1,46 @@
1
+ <script lang="ts">
2
+ import type { ChildrenBlock } from '../../types.js';
3
+
4
+ interface Props {
5
+ block: ChildrenBlock;
6
+ /** Slot für Framework-spezifische Implementierung */
7
+ children?: import('svelte').Snippet;
8
+ }
9
+
10
+ let { block, children }: Props = $props();
11
+ </script>
12
+
13
+ <section class="csm-children">
14
+ {#if block.title}
15
+ <h2 class="csm-children-title">{block.title}</h2>
16
+ {/if}
17
+
18
+ {#if children}
19
+ {@render children()}
20
+ {:else}
21
+ <div class="csm-children-placeholder">
22
+ <p>Unterseiten werden hier angezeigt</p>
23
+ </div>
24
+ {/if}
25
+ </section>
26
+
27
+ <style>
28
+ .csm-children {
29
+ margin: 0;
30
+ }
31
+
32
+ .csm-children-title {
33
+ font-size: 1.5rem;
34
+ font-weight: 600;
35
+ margin: 0 0 1rem;
36
+ }
37
+
38
+ .csm-children-placeholder {
39
+ padding: 2rem;
40
+ background: var(--csm-muted-bg, #f8fafc);
41
+ border: 2px dashed var(--csm-border-color, #e2e8f0);
42
+ border-radius: 0.75rem;
43
+ text-align: center;
44
+ color: var(--csm-muted-color, #94a3b8);
45
+ }
46
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { ChildrenBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: ChildrenBlock;
4
+ /** Slot für Framework-spezifische Implementierung */
5
+ children?: import('svelte').Snippet;
6
+ }
7
+ declare const ChildrenBlock: import("svelte").Component<Props, {}, "">;
8
+ type ChildrenBlock = ReturnType<typeof ChildrenBlock>;
9
+ export default ChildrenBlock;
@@ -0,0 +1,9 @@
1
+ <hr class="csm-divider" />
2
+
3
+ <style>
4
+ .csm-divider {
5
+ border: none;
6
+ border-top: 1px solid var(--csm-border-color, #e2e8f0);
7
+ margin: 0.5rem 0;
8
+ }
9
+ </style>
@@ -0,0 +1,26 @@
1
+ export default DividerBlock;
2
+ type DividerBlock = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const DividerBlock: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -0,0 +1,77 @@
1
+ <script lang="ts">
2
+ import { marked } from 'marked';
3
+ import type { FaqBlock } from '../../types.js';
4
+
5
+ interface Props {
6
+ block: FaqBlock;
7
+ }
8
+
9
+ let { block }: Props = $props();
10
+ </script>
11
+
12
+ <section class="csm-faq">
13
+ {#if block.title}
14
+ <h2 class="csm-faq-title">{block.title}</h2>
15
+ {/if}
16
+
17
+ <div class="csm-faq-list">
18
+ {#each block.items as item}
19
+ <div class="csm-faq-item">
20
+ <h3 class="csm-faq-question">{item.q}</h3>
21
+ <div class="csm-faq-answer">
22
+ {@html marked.parse(item.a)}
23
+ </div>
24
+ </div>
25
+ {/each}
26
+ </div>
27
+ </section>
28
+
29
+ <style>
30
+ .csm-faq {
31
+ margin: 0;
32
+ }
33
+
34
+ .csm-faq-title {
35
+ font-size: 1.5rem;
36
+ font-weight: 600;
37
+ margin: 0 0 1rem;
38
+ }
39
+
40
+ .csm-faq-list {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 1rem;
44
+ }
45
+
46
+ .csm-faq-item {
47
+ padding: 1rem 1.25rem;
48
+ background: var(--csm-card-bg, #ffffff);
49
+ border: 1px solid var(--csm-border-color, #e2e8f0);
50
+ border-radius: 0.75rem;
51
+ }
52
+
53
+ .csm-faq-question {
54
+ font-size: 1rem;
55
+ font-weight: 600;
56
+ margin: 0 0 0.5rem;
57
+ }
58
+
59
+ .csm-faq-answer {
60
+ font-size: 0.9375rem;
61
+ color: var(--csm-muted-color, #64748b);
62
+ line-height: 1.6;
63
+ }
64
+
65
+ .csm-faq-answer :global(p) {
66
+ margin: 0 0 0.75rem;
67
+ }
68
+
69
+ .csm-faq-answer :global(p:last-child) {
70
+ margin-bottom: 0;
71
+ }
72
+
73
+ .csm-faq-answer :global(strong) {
74
+ font-weight: 600;
75
+ color: var(--csm-text-color, #1e293b);
76
+ }
77
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { FaqBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: FaqBlock;
4
+ }
5
+ declare const FaqBlock: import("svelte").Component<Props, {}, "">;
6
+ type FaqBlock = ReturnType<typeof FaqBlock>;
7
+ export default FaqBlock;
@@ -1,8 +1,38 @@
1
1
  <script lang="ts">
2
- import type { HeadingBlock } from '../../types.js';
3
- let { block } = $props<{ block: HeadingBlock }>();
2
+ import type { HeadingBlock } from '../../types.js';
3
+
4
+ interface Props {
5
+ block: HeadingBlock;
6
+ }
7
+
8
+ let { block }: Props = $props();
4
9
  </script>
5
10
 
6
- <svelte:element this={`h${block.level ?? 2}`} class="my-4 text-2xl font-bold">
7
- {block.text}
8
- </svelte:element>
11
+ {#if block.level === 1}
12
+ <h1 class="csm-heading csm-h1">{block.text}</h1>
13
+ {:else if block.level === 2}
14
+ <h2 class="csm-heading csm-h2">{block.text}</h2>
15
+ {:else if block.level === 3}
16
+ <h3 class="csm-heading csm-h3">{block.text}</h3>
17
+ {:else if block.level === 4}
18
+ <h4 class="csm-heading csm-h4">{block.text}</h4>
19
+ {:else if block.level === 5}
20
+ <h5 class="csm-heading csm-h5">{block.text}</h5>
21
+ {:else}
22
+ <h6 class="csm-heading csm-h6">{block.text}</h6>
23
+ {/if}
24
+
25
+ <style>
26
+ .csm-heading {
27
+ margin: 0;
28
+ line-height: 1.3;
29
+ color: var(--csm-heading-color, inherit);
30
+ }
31
+
32
+ .csm-h1 { font-size: 2rem; font-weight: 700; }
33
+ .csm-h2 { font-size: 1.5rem; font-weight: 600; }
34
+ .csm-h3 { font-size: 1.25rem; font-weight: 600; }
35
+ .csm-h4 { font-size: 1.125rem; font-weight: 600; }
36
+ .csm-h5 { font-size: 1rem; font-weight: 600; }
37
+ .csm-h6 { font-size: 0.875rem; font-weight: 600; }
38
+ </style>
@@ -1,7 +1,7 @@
1
1
  import type { HeadingBlock } from '../../types.ts';
2
- type $$ComponentProps = {
2
+ interface Props {
3
3
  block: HeadingBlock;
4
- };
5
- declare const HeadingBlock: import("svelte").Component<$$ComponentProps, {}, "">;
4
+ }
5
+ declare const HeadingBlock: import("svelte").Component<Props, {}, "">;
6
6
  type HeadingBlock = ReturnType<typeof HeadingBlock>;
7
7
  export default HeadingBlock;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import type { HeroBlock } from '../../types.js';
3
+ interface Props {
4
+ block: HeroBlock;
5
+ }
6
+
7
+ let { block }: Props = $props();
8
+ </script>
9
+
10
+ <header class="csm-hero">
11
+ <h1 class="csm-hero-title">{block.title}</h1>
12
+ {#if block.subtitle}
13
+ <p class="csm-hero-subtitle">{block.subtitle}</p>
14
+ {/if}
15
+ </header>
16
+
17
+ <style>
18
+ .csm-hero {
19
+ text-align: left;
20
+ }
21
+
22
+ .csm-hero-title {
23
+ font-size: 2rem;
24
+ font-weight: 700;
25
+ margin: 0 0 0.75rem;
26
+ line-height: 1.2;
27
+ letter-spacing: -0.025em;
28
+ }
29
+
30
+ @media (min-width: 640px) {
31
+ .csm-hero-title {
32
+ font-size: 2.5rem;
33
+ }
34
+ }
35
+
36
+ .csm-hero-subtitle {
37
+ font-size: 1.125rem;
38
+ color: var(--csm-muted-color, #64748b);
39
+ margin: 0;
40
+ line-height: 1.6;
41
+ max-width: 42rem;
42
+ }
43
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { HeroBlock } from '../../types.ts';
2
+ interface Props {
3
+ block: HeroBlock;
4
+ }
5
+ declare const HeroBlock: import("svelte").Component<Props, {}, "">;
6
+ type HeroBlock = ReturnType<typeof HeroBlock>;
7
+ export default HeroBlock;