@cogenta/theme-canonical 0.1.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.
Files changed (126) hide show
  1. package/dist/src/index.d.ts +21 -0
  2. package/dist/src/index.d.ts.map +1 -0
  3. package/dist/src/index.js +21 -0
  4. package/dist/src/index.js.map +1 -0
  5. package/dist/src/render/actions.d.ts +17 -0
  6. package/dist/src/render/actions.d.ts.map +1 -0
  7. package/dist/src/render/actions.js +43 -0
  8. package/dist/src/render/actions.js.map +1 -0
  9. package/dist/src/render/blocks/collection-list.d.ts +16 -0
  10. package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
  11. package/dist/src/render/blocks/collection-list.js +54 -0
  12. package/dist/src/render/blocks/collection-list.js.map +1 -0
  13. package/dist/src/render/blocks/cta.d.ts +5 -0
  14. package/dist/src/render/blocks/cta.d.ts.map +1 -0
  15. package/dist/src/render/blocks/cta.js +10 -0
  16. package/dist/src/render/blocks/cta.js.map +1 -0
  17. package/dist/src/render/blocks/embed.d.ts +5 -0
  18. package/dist/src/render/blocks/embed.d.ts.map +1 -0
  19. package/dist/src/render/blocks/embed.js +88 -0
  20. package/dist/src/render/blocks/embed.js.map +1 -0
  21. package/dist/src/render/blocks/faq.d.ts +5 -0
  22. package/dist/src/render/blocks/faq.d.ts.map +1 -0
  23. package/dist/src/render/blocks/faq.js +21 -0
  24. package/dist/src/render/blocks/faq.js.map +1 -0
  25. package/dist/src/render/blocks/feature-grid.d.ts +5 -0
  26. package/dist/src/render/blocks/feature-grid.d.ts.map +1 -0
  27. package/dist/src/render/blocks/feature-grid.js +27 -0
  28. package/dist/src/render/blocks/feature-grid.js.map +1 -0
  29. package/dist/src/render/blocks/gallery.d.ts +15 -0
  30. package/dist/src/render/blocks/gallery.d.ts.map +1 -0
  31. package/dist/src/render/blocks/gallery.js +28 -0
  32. package/dist/src/render/blocks/gallery.js.map +1 -0
  33. package/dist/src/render/blocks/hero.d.ts +12 -0
  34. package/dist/src/render/blocks/hero.d.ts.map +1 -0
  35. package/dist/src/render/blocks/hero.js +25 -0
  36. package/dist/src/render/blocks/hero.js.map +1 -0
  37. package/dist/src/render/blocks/logos.d.ts +5 -0
  38. package/dist/src/render/blocks/logos.d.ts.map +1 -0
  39. package/dist/src/render/blocks/logos.js +25 -0
  40. package/dist/src/render/blocks/logos.js.map +1 -0
  41. package/dist/src/render/blocks/media-figure.d.ts +15 -0
  42. package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
  43. package/dist/src/render/blocks/media-figure.js +30 -0
  44. package/dist/src/render/blocks/media-figure.js.map +1 -0
  45. package/dist/src/render/blocks/prose.d.ts +10 -0
  46. package/dist/src/render/blocks/prose.d.ts.map +1 -0
  47. package/dist/src/render/blocks/prose.js +11 -0
  48. package/dist/src/render/blocks/prose.js.map +1 -0
  49. package/dist/src/render/blocks/quote.d.ts +14 -0
  50. package/dist/src/render/blocks/quote.d.ts.map +1 -0
  51. package/dist/src/render/blocks/quote.js +25 -0
  52. package/dist/src/render/blocks/quote.js.map +1 -0
  53. package/dist/src/render/blocks/stats.d.ts +5 -0
  54. package/dist/src/render/blocks/stats.d.ts.map +1 -0
  55. package/dist/src/render/blocks/stats.js +23 -0
  56. package/dist/src/render/blocks/stats.js.map +1 -0
  57. package/dist/src/render/entry.d.ts +7 -0
  58. package/dist/src/render/entry.d.ts.map +1 -0
  59. package/dist/src/render/entry.js +35 -0
  60. package/dist/src/render/entry.js.map +1 -0
  61. package/dist/src/render/heading.d.ts +14 -0
  62. package/dist/src/render/heading.d.ts.map +1 -0
  63. package/dist/src/render/heading.js +34 -0
  64. package/dist/src/render/heading.js.map +1 -0
  65. package/dist/src/render/html.d.ts +44 -0
  66. package/dist/src/render/html.d.ts.map +1 -0
  67. package/dist/src/render/html.js +96 -0
  68. package/dist/src/render/html.js.map +1 -0
  69. package/dist/src/render/media.d.ts +32 -0
  70. package/dist/src/render/media.d.ts.map +1 -0
  71. package/dist/src/render/media.js +42 -0
  72. package/dist/src/render/media.js.map +1 -0
  73. package/dist/src/render/render-block.d.ts +26 -0
  74. package/dist/src/render/render-block.d.ts.map +1 -0
  75. package/dist/src/render/render-block.js +66 -0
  76. package/dist/src/render/render-block.js.map +1 -0
  77. package/dist/src/render/rich-text.d.ts +5 -0
  78. package/dist/src/render/rich-text.d.ts.map +1 -0
  79. package/dist/src/render/rich-text.js +105 -0
  80. package/dist/src/render/rich-text.js.map +1 -0
  81. package/dist/src/theme-contract.d.ts +165 -0
  82. package/dist/src/theme-contract.d.ts.map +1 -0
  83. package/dist/src/theme-contract.js +21 -0
  84. package/dist/src/theme-contract.js.map +1 -0
  85. package/dist/theme.config.d.ts +31 -0
  86. package/dist/theme.config.d.ts.map +1 -0
  87. package/dist/theme.config.js +42 -0
  88. package/dist/theme.config.js.map +1 -0
  89. package/package.json +57 -0
  90. package/src/blocks/CollectionList.astro +20 -0
  91. package/src/blocks/Cta.astro +11 -0
  92. package/src/blocks/Embed.astro +18 -0
  93. package/src/blocks/Faq.astro +16 -0
  94. package/src/blocks/FeatureGrid.astro +11 -0
  95. package/src/blocks/Gallery.astro +17 -0
  96. package/src/blocks/Hero.astro +25 -0
  97. package/src/blocks/Logos.astro +11 -0
  98. package/src/blocks/MediaFigure.astro +11 -0
  99. package/src/blocks/Prose.astro +11 -0
  100. package/src/blocks/Quote.astro +11 -0
  101. package/src/blocks/Stats.astro +11 -0
  102. package/src/components/BlockZone.astro +62 -0
  103. package/src/index.ts +20 -0
  104. package/src/layouts/Base.astro +63 -0
  105. package/src/render/actions.ts +57 -0
  106. package/src/render/blocks/collection-list.ts +98 -0
  107. package/src/render/blocks/cta.ts +17 -0
  108. package/src/render/blocks/embed.ts +111 -0
  109. package/src/render/blocks/faq.ts +42 -0
  110. package/src/render/blocks/feature-grid.ts +54 -0
  111. package/src/render/blocks/gallery.ts +49 -0
  112. package/src/render/blocks/hero.ts +42 -0
  113. package/src/render/blocks/logos.ts +45 -0
  114. package/src/render/blocks/media-figure.ts +42 -0
  115. package/src/render/blocks/prose.ts +17 -0
  116. package/src/render/blocks/quote.ts +39 -0
  117. package/src/render/blocks/stats.ts +41 -0
  118. package/src/render/entry.ts +40 -0
  119. package/src/render/heading.ts +44 -0
  120. package/src/render/html.ts +122 -0
  121. package/src/render/media.ts +62 -0
  122. package/src/render/render-block.ts +97 -0
  123. package/src/render/rich-text.ts +150 -0
  124. package/src/styles/theme.css +606 -0
  125. package/src/theme-contract.ts +159 -0
  126. package/tokens.json +36 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Contract D — Thème, frozen at `theme@1.0` on 2026-08-13.
3
+ *
4
+ * TEMPORARY HOME. These types and `defineTheme` belong to `@cogenta/render`,
5
+ * which is being written in parallel (tasks 1–3 of L3). They live here so the
6
+ * canonical theme can be written, typechecked and tested today, and must be
7
+ * replaced by an import from `@cogenta/render` at merge time — not duplicated.
8
+ *
9
+ * Nothing below adds to `ctx`. Two shapes the contract names but does not spell
10
+ * out — `MediaReference` and `ContentEntry` — are given the narrowest reading
11
+ * that matches what is already frozen elsewhere; both are flagged in the code.
12
+ */
13
+
14
+ /**
15
+ * Contract B stores a media field as the media library's identifier, never as
16
+ * an URL and never as a rendition (`f.media` in `@cogenta/blocks`). So a
17
+ * reference the theme can hold is that identifier.
18
+ */
19
+ export type MediaReference = string
20
+
21
+ export interface ImageOptions {
22
+ readonly width?: number
23
+ readonly height?: number
24
+ readonly format?: 'avif' | 'webp' | 'jpeg' | 'png'
25
+ readonly fit?: 'cover' | 'contain'
26
+ }
27
+
28
+ export interface ImageSource {
29
+ readonly src: string
30
+ readonly srcset: string
31
+ readonly width: number
32
+ readonly height: number
33
+ /** Alt text and focal point come from the media entity, never invented here. */
34
+ readonly alt: string
35
+ readonly focal: { readonly x: number; readonly y: number } | null
36
+ }
37
+
38
+ /**
39
+ * Contract A, "Champs système". A theme only ever sees published entries — the
40
+ * read token carries the `public` role — so `status` is narrow in practice but
41
+ * kept whole here rather than guessed at.
42
+ *
43
+ * The schema-defined fields are open: which of them exist depends on the
44
+ * collection, and a theme must not assume one is present. `entryTitle` in
45
+ * `src/render/entry.ts` is the only place that reaches for one.
46
+ */
47
+ export interface ContentEntry {
48
+ readonly id: string
49
+ readonly collection: string
50
+ readonly locale: string
51
+ readonly status: 'draft' | 'scheduled' | 'published' | 'archived'
52
+ readonly [field: string]: unknown
53
+ }
54
+
55
+ export interface QueryRequest {
56
+ readonly collection: string
57
+ readonly filter?: Readonly<Record<string, unknown>>
58
+ readonly sort?: { readonly field: string; readonly direction: 'asc' | 'desc' }
59
+ readonly limit?: number
60
+ readonly cursor?: string
61
+ }
62
+
63
+ export interface Page<T> {
64
+ readonly items: readonly T[]
65
+ readonly nextCursor: string | null
66
+ }
67
+
68
+ export interface ContentClient {
69
+ entry(collection: string, id: string): Promise<ContentEntry | null>
70
+ byPath(path: string): Promise<ContentEntry | null>
71
+ list(request: QueryRequest): Promise<Page<ContentEntry>>
72
+ }
73
+
74
+ export type LinkTargetInput = { collection: string; id: string } | { path: string } | string
75
+
76
+ export interface RenderContext {
77
+ readonly site: {
78
+ readonly name: string
79
+ readonly url: string
80
+ readonly locales: readonly string[]
81
+ readonly defaultLocale: string
82
+ }
83
+ /** The locale being rendered. */
84
+ readonly locale: string
85
+ /** The URL being rendered, already resolved. */
86
+ readonly url: URL
87
+
88
+ /** Translation. An unknown key returns the key, never an empty string. */
89
+ t(key: string, values?: Readonly<Record<string, string | number>>): string
90
+
91
+ /** Image variants. Returns what a responsive `<img>` needs, nothing more. */
92
+ image(media: MediaReference, options?: ImageOptions): ImageSource
93
+
94
+ /** URL of an entry, of a path, or of an external target. Locale-aware. */
95
+ link(target: LinkTargetInput): string
96
+
97
+ /** Read-only content access. The only door to data a theme has. */
98
+ readonly content: ContentClient
99
+ }
100
+
101
+ /** Contract D, "Besoins runtime". */
102
+ export type ThemeRuntime = 'static' | 'server' | 'edge'
103
+
104
+ export interface ThemeManifest {
105
+ readonly name: string
106
+ readonly version: string
107
+ /** Version of the theme contract. */
108
+ readonly engine: string
109
+ /** Version of the block vocabulary supported. */
110
+ readonly blocks: string
111
+ /** Every vocabulary block the theme renders. A gap fails installation. */
112
+ readonly implements: readonly string[]
113
+ /** Content types expected, or `'*'`. */
114
+ readonly collections: readonly string[] | '*'
115
+ readonly runtime: ThemeRuntime
116
+ /** Path to the default skin, relative to the manifest. */
117
+ readonly tokens: string
118
+ readonly a11y: { readonly verified: 'WCAG-2.2-AA' | 'WCAG-2.2-AAA' | 'none' }
119
+ }
120
+
121
+ /**
122
+ * Identity function. It exists for the inference and for the single place a
123
+ * manifest is recognised, not to validate: validation happens at installation,
124
+ * on the theme's sources, where a lie can actually be caught.
125
+ */
126
+ export function defineTheme<const M extends ThemeManifest>(manifest: M): M {
127
+ return manifest
128
+ }
129
+
130
+ /**
131
+ * Contract D, "Tokens de skin". The set is **closed and complete**: a skin that
132
+ * omits a token is refused. Rendered as `--cogenta-<group>-<name>` into a single
133
+ * stylesheet, so changing skin rewrites one file and needs no build.
134
+ */
135
+ export interface SkinTokens {
136
+ readonly color: {
137
+ readonly bg: string
138
+ readonly fg: string
139
+ readonly accent: string
140
+ readonly accentFg: string
141
+ readonly muted: string
142
+ readonly mutedFg: string
143
+ readonly border: string
144
+ }
145
+ readonly font: {
146
+ readonly sans: string
147
+ readonly serif: string
148
+ readonly mono: string
149
+ readonly scale: number
150
+ readonly baseSize: string
151
+ }
152
+ readonly space: {
153
+ readonly unit: string
154
+ readonly density: 'compact' | 'comfortable' | 'spacious'
155
+ }
156
+ readonly radius: { readonly sm: string; readonly md: string; readonly lg: string }
157
+ readonly motion: { readonly duration: string; readonly easing: string; readonly reduced: boolean }
158
+ readonly shadow: { readonly sm: string; readonly md: string }
159
+ }
package/tokens.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "color": {
3
+ "bg": "#ffffff",
4
+ "fg": "#16181d",
5
+ "accent": "#1d4ed8",
6
+ "accentFg": "#ffffff",
7
+ "muted": "#f2f4f7",
8
+ "mutedFg": "#3f4655",
9
+ "border": "#d7dbe2"
10
+ },
11
+ "font": {
12
+ "sans": "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
13
+ "serif": "ui-serif, Georgia, Cambria, 'Times New Roman', serif",
14
+ "mono": "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace",
15
+ "scale": 1.25,
16
+ "baseSize": "1rem"
17
+ },
18
+ "space": {
19
+ "unit": "0.25rem",
20
+ "density": "comfortable"
21
+ },
22
+ "radius": {
23
+ "sm": "0.25rem",
24
+ "md": "0.5rem",
25
+ "lg": "1rem"
26
+ },
27
+ "motion": {
28
+ "duration": "180ms",
29
+ "easing": "cubic-bezier(0.2, 0, 0, 1)",
30
+ "reduced": true
31
+ },
32
+ "shadow": {
33
+ "sm": "0 1px 2px rgba(22, 24, 29, 0.08)",
34
+ "md": "0 6px 24px rgba(22, 24, 29, 0.12)"
35
+ }
36
+ }