@publier/shell 2.1.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 (141) hide show
  1. package/README.md +1 -0
  2. package/dist/build-integration.d.mts +7 -0
  3. package/dist/build-integration.mjs +1 -0
  4. package/dist/index-DWtFsw7E.d.mts +1033 -0
  5. package/dist/index.d.mts +33 -0
  6. package/dist/index.mjs +1 -0
  7. package/dist/integration-BIJIcnAT.mjs +99 -0
  8. package/dist/integration-CKjtSkwa.d.mts +183 -0
  9. package/dist/integration.d.mts +2 -0
  10. package/dist/integration.mjs +1 -0
  11. package/dist/loaders/index.d.mts +54 -0
  12. package/dist/loaders/index.mjs +1 -0
  13. package/dist/plugins/remark-asides.d.mts +8 -0
  14. package/dist/plugins/remark-asides.mjs +2 -0
  15. package/dist/plugins/remark-snippets.d.mts +11 -0
  16. package/dist/plugins/remark-snippets.mjs +1 -0
  17. package/dist/plugins/remark-structure.d.mts +13 -0
  18. package/dist/plugins/remark-structure.mjs +1 -0
  19. package/dist/plugins/remark-vars.d.mts +7 -0
  20. package/dist/plugins/remark-vars.mjs +1 -0
  21. package/dist/presets-C7z73xlB.d.mts +16 -0
  22. package/dist/presets-DL0qjtya.mjs +1 -0
  23. package/dist/runtime/code-group-sync.d.mts +30 -0
  24. package/dist/runtime/code-group-sync.mjs +103 -0
  25. package/dist/runtime/lazy-upgrade-registry.d.mts +29 -0
  26. package/dist/runtime/lazy-upgrade-registry.mjs +1 -0
  27. package/dist/runtime/tabs-sync.d.mts +25 -0
  28. package/dist/runtime/tabs-sync.mjs +106 -0
  29. package/dist/search/index.d.mts +92 -0
  30. package/dist/search/index.mjs +1 -0
  31. package/dist/tailwind/css-plugin.d.mts +16 -0
  32. package/dist/tailwind/css-plugin.mjs +1 -0
  33. package/dist/tailwind/index.d.mts +6 -0
  34. package/dist/tailwind/index.mjs +1 -0
  35. package/dist/tailwind/loader.d.mts +94 -0
  36. package/dist/tailwind/loader.mjs +2 -0
  37. package/dist/theme-toggle-element-DzFjxwpS.mjs +1 -0
  38. package/dist/themes/almond.css +115 -0
  39. package/dist/themes/aspen.css +95 -0
  40. package/dist/themes/catppuccin.css +98 -0
  41. package/dist/themes/dark.css +98 -0
  42. package/dist/themes/dusk.css +98 -0
  43. package/dist/themes/emerald.css +95 -0
  44. package/dist/themes/light.css +95 -0
  45. package/dist/themes/maple.css +119 -0
  46. package/dist/themes/neutral.css +73 -0
  47. package/dist/themes/ocean.css +98 -0
  48. package/dist/themes/purple.css +95 -0
  49. package/dist/themes/ruby.css +95 -0
  50. package/dist/themes/solar.css +98 -0
  51. package/dist/themes/vitepress.css +95 -0
  52. package/package.json +189 -0
  53. package/publier-gate +0 -0
  54. package/src/astro-modules.d.ts +20 -0
  55. package/src/components/LastModified.astro +25 -0
  56. package/src/components/announcement-banner.astro +25 -0
  57. package/src/components/aside.astro +17 -0
  58. package/src/components/ask-ai.tsx +146 -0
  59. package/src/components/badge.astro +18 -0
  60. package/src/components/breadcrumbs.astro +23 -0
  61. package/src/components/callouts/caution.astro +13 -0
  62. package/src/components/callouts/check.astro +13 -0
  63. package/src/components/callouts/danger.astro +13 -0
  64. package/src/components/callouts/info.astro +13 -0
  65. package/src/components/callouts/note.astro +13 -0
  66. package/src/components/callouts/tip.astro +13 -0
  67. package/src/components/callouts/warning.astro +13 -0
  68. package/src/components/card-grid.astro +14 -0
  69. package/src/components/card.astro +18 -0
  70. package/src/components/code-group.astro +55 -0
  71. package/src/components/columns.astro +18 -0
  72. package/src/components/docs-layout.astro +25 -0
  73. package/src/components/file-tree-node.astro +13 -0
  74. package/src/components/file-tree.astro +9 -0
  75. package/src/components/icon.astro +18 -0
  76. package/src/components/index.ts +155 -0
  77. package/src/components/link-button.astro +21 -0
  78. package/src/components/link-card.astro +21 -0
  79. package/src/components/open-in-ai.astro +13 -0
  80. package/src/components/package-install.astro +17 -0
  81. package/src/components/panels.astro +16 -0
  82. package/src/components/search-button.astro +21 -0
  83. package/src/components/sidebar.astro +12 -0
  84. package/src/components/skip-link.astro +12 -0
  85. package/src/components/steps.astro +13 -0
  86. package/src/components/table-of-contents.astro +22 -0
  87. package/src/components/tabs.astro +17 -0
  88. package/src/components/theme-storage.ts +5 -0
  89. package/src/components/theme-toggle-element.ts +85 -0
  90. package/src/components/theme-toggle.astro +25 -0
  91. package/src/components/tile-grid.astro +13 -0
  92. package/src/components/tile.astro +17 -0
  93. package/src/components/top-nav-mobile.astro +11 -0
  94. package/src/components/top-nav.astro +20 -0
  95. package/src/components/types.ts +510 -0
  96. package/src/components/ui/blur-image.astro +60 -0
  97. package/src/components/ui/changelog-entry.astro +56 -0
  98. package/src/components/ui/cta-band.astro +30 -0
  99. package/src/components/ui/feature-grid.astro +38 -0
  100. package/src/components/ui/feature-section.astro +85 -0
  101. package/src/components/ui/frame.astro +52 -0
  102. package/src/components/ui/hero.astro +47 -0
  103. package/src/components/ui/jobs-list.astro +53 -0
  104. package/src/components/ui/logo-cloud.astro +68 -0
  105. package/src/components/ui/press-gallery.astro +52 -0
  106. package/src/components/ui/pricing-comparison-table.astro +73 -0
  107. package/src/components/ui/pricing-section.astro +113 -0
  108. package/src/components/ui/pricing-table.astro +54 -0
  109. package/src/components/ui/status-indicator.astro +38 -0
  110. package/src/components/ui/team-grid.astro +63 -0
  111. package/src/components/ui/testimonial-card.astro +42 -0
  112. package/src/components/ui/types.ts +323 -0
  113. package/src/components/update-badge.astro +15 -0
  114. package/src/components/version-switcher.astro +20 -0
  115. package/src/icons/index.tsx +246 -0
  116. package/src/icons/resolve.tsx +45 -0
  117. package/src/layouts/base-layout.astro +63 -0
  118. package/src/qwik.ts +3 -0
  119. package/src/routes/blog-index.astro +20 -0
  120. package/src/routes/blog-rss.xml.ts +40 -0
  121. package/src/routes/blog-slug.astro +32 -0
  122. package/src/routes/changelog-index.astro +25 -0
  123. package/src/routes/changelog-rss.xml.ts +47 -0
  124. package/src/routes/docs-slug.astro +31 -0
  125. package/src/routes/not-found.astro +14 -0
  126. package/src/runtime/banner-init.ts +9 -0
  127. package/src/runtime/lazy-upgrade-init.ts +5 -0
  128. package/src/runtime/sidebar-scroll-init.ts +3 -0
  129. package/src/runtime/theme-init.ts +16 -0
  130. package/src/schemas/blog.ts +37 -0
  131. package/src/schemas/changelog.ts +28 -0
  132. package/src/schemas/common.ts +82 -0
  133. package/src/schemas/docs.ts +101 -0
  134. package/src/schemas/index.ts +14 -0
  135. package/src/schemas/pages.ts +22 -0
  136. package/src/styles/base.css +627 -0
  137. package/src/styles/expressive-code.css +41 -0
  138. package/src/styles/rules.css +66 -0
  139. package/src/styles/tailwind-sources.css +17 -0
  140. package/src/tailwind/preset.css +193 -0
  141. package/src/virtual-modules.d.ts +164 -0
@@ -0,0 +1,627 @@
1
+ /* @publier/shell — base CSS layer (Phase 4 daisyUI rewrite)
2
+ *
3
+ * Foundational styles + residual rules for components that aren't fully
4
+ * expressible in daisyUI / Tailwind utilities. Auto-injected globally by
5
+ * `docsShell()` so landing / blog / docs pages all share the same
6
+ * foundation; customers never import it manually.
7
+ *
8
+ * Imports `@publier/ui/src/css/rules.css` (NOT `…/base.css`) — Tailwind +
9
+ * daisyUI + preset directives are owned by shell's auto-composed entry
10
+ * (`<root>/.astro/publier-tailwind-entry.css`). Importing the directive-
11
+ * carrying `base.css` here would trigger a SECOND Tailwind compilation
12
+ * over a slightly different `@source` set, fragmenting the cascade in
13
+ * dev mode (two `<style>` tags fighting for `.hidden` vs. `.lg:block`
14
+ * ordering, sidebar invisible at desktop). The directive-free
15
+ * `rules.css` adds Publier-specific styles only — no duplicate compile.
16
+ */
17
+ @import "./rules.css";
18
+
19
+ .katex-display {
20
+ margin: 1rem 0;
21
+ padding: 1rem;
22
+ background: var(--color-base-100);
23
+ border-radius: 0.5rem;
24
+ }
25
+
26
+ .katex {
27
+ font-size: 1em;
28
+ }
29
+
30
+ /* What stays here post-Phase 4:
31
+ * - html / body foundation + `.prose` var bridging
32
+ * - SkipLink (a11y primitive)
33
+ * - ThemeToggle button (Qwik island)
34
+ * - AnnouncementBanner (Astro + inline-script; pre-paint hide)
35
+ * - TableOfContents (Astro + inline-script; scroll-spy)
36
+ * - VersionSwitcher (Astro + native <details>)
37
+ * - OpenInAI (Astro + inline-script; dropdown menu)
38
+ *
39
+ * What was removed in Phase 4 Commit 4 (replaced by daisyUI + Tailwind utilities
40
+ * directly in each component): Badge, Aside, Card/CardGrid, LinkCard,
41
+ * LinkButton, Steps, DocsLayout, Sidebar/SidebarEntry, Tabs, CodeGroup,
42
+ * FileTree/Node, Columns, Panels, Tile/TileGrid, UpdateBadge, Breadcrumbs,
43
+ * LastModified, TopNav, TopNavMobile, PackageInstall.
44
+ */
45
+
46
+ /* ─── Global Foundation ───────────────────────────────────── */
47
+ html {
48
+ -webkit-text-size-adjust: 100%;
49
+ text-size-adjust: 100%;
50
+ scroll-behavior: smooth;
51
+ /* 16px root, matching publier.net's reference layout. Customers who
52
+ * want a larger UI surface can set `--publier-font-size-root` at :root
53
+ * in their own CSS and every rem-based utility will scale with it. */
54
+ font-size: var(--publier-font-size-root, 16px);
55
+ }
56
+
57
+ body {
58
+ background-color: var(--color-base-100);
59
+ color: var(--color-base-content);
60
+ font-family: var(--font-body);
61
+ font-weight: var(--publier-font-weight-body, 400);
62
+ line-height: 1.6;
63
+ -webkit-font-smoothing: antialiased;
64
+ -moz-osx-font-smoothing: grayscale;
65
+ }
66
+
67
+ /* ─── daisyUI v5 `<details>` collapse-arrow rotation patch ──
68
+ * v5 only rotates `.collapse-arrow::after` on `.collapse-open` or
69
+ * `:checked~` siblings — it forgot the `<details>[open]` path, so
70
+ * chevrons on our native-disclosure AccordionItem don't flip. Re-
71
+ * applying the same 225deg transform restores the expected motion. */
72
+ @media (prefers-reduced-motion: no-preference) {
73
+ details.collapse.collapse-arrow[open] > summary.collapse-title::after {
74
+ transform: translateY(-50%) rotate(225deg);
75
+ }
76
+ }
77
+
78
+ /* Heading weight follows the theme token so customers can flatten
79
+ * headings (e.g. 600 instead of 700/800) without touching prose. */
80
+ h1,
81
+ h2,
82
+ h3,
83
+ h4,
84
+ h5,
85
+ h6 {
86
+ font-weight: var(--publier-font-weight-heading, 700);
87
+ }
88
+
89
+ /* ─── Prose overrides — wire @tailwindcss/typography to Publier roles ───
90
+ *
91
+ * Readability hierarchy (Fumadocs / shadcn convention):
92
+ * - Body, headings, bold, quotes ─ full `base-content`. Crisp, legible,
93
+ * high-contrast against the page surface. This is the most-read text
94
+ * on the page; it should NEVER be muted.
95
+ * - Lead paragraph ───────────── `pl-muted`. Themed, slightly de-
96
+ * emphasized; signals "this is the intro summary, body starts below".
97
+ * - Captions / counters / table-headers ─ `pl-subtle`. The quietest
98
+ * text on the page.
99
+ * - Links ──────────────────── `primary`. Accents the interactive path.
100
+ * - Bullets / borders / hr ──── `pl-border{,-strong}`.
101
+ *
102
+ * Rationale: body text that carries the theme hue looks nice in isolation
103
+ * but drops contrast vs. the surface and becomes harder to read on long-
104
+ * form docs. Reserving the themed tint for the LEAD + sidebar section
105
+ * titles keeps the "themed feel" without sacrificing body legibility.
106
+ */
107
+ .prose {
108
+ --tw-prose-body: var(--color-base-content);
109
+ --tw-prose-headings: var(--color-base-content);
110
+ --tw-prose-lead: var(--color-pl-muted);
111
+ --tw-prose-links: var(--color-primary);
112
+ --tw-prose-bold: var(--color-base-content);
113
+ --tw-prose-counters: var(--color-pl-subtle);
114
+ --tw-prose-bullets: var(--color-pl-border-strong);
115
+ --tw-prose-hr: var(--color-pl-border);
116
+ --tw-prose-quotes: var(--color-base-content);
117
+ --tw-prose-quote-borders: var(--color-pl-border-strong);
118
+ --tw-prose-captions: var(--color-pl-subtle);
119
+ --tw-prose-code: var(--color-base-content);
120
+ --tw-prose-pre-code: var(--color-base-content);
121
+ --tw-prose-pre-bg: var(--color-pl-card);
122
+ --tw-prose-th-borders: var(--color-pl-border-strong);
123
+ --tw-prose-td-borders: var(--color-pl-border);
124
+ }
125
+
126
+ /* Docs body size matches publier.net's pre-sweep reference: body 1.125rem
127
+ * (18px) / 1.7 line-height for generous long-form reading. H1 leans on the
128
+ * 800-weight heading stack so the article title visually outweighs section
129
+ * H2s without needing a separate display font. */
130
+ .prose {
131
+ font-size: 1.125rem;
132
+ line-height: 1.7;
133
+ }
134
+ .prose > :where(h1):not(:where([class~="not-prose"] *)) {
135
+ font-size: 2.25rem;
136
+ font-weight: var(--publier-font-weight-heading, 800);
137
+ line-height: 1.15;
138
+ }
139
+ .prose > :where(p):not(:where([class~="not-prose"] *)) {
140
+ line-height: 1.7;
141
+ }
142
+
143
+ /* ─── Top-nav active link — brand-tinted highlight ─────────
144
+ *
145
+ * The active tab / link is signalled via `aria-current="page"` (semantic,
146
+ * set both server-side by `render_nav_link` in the native renderer and
147
+ * client-side by `NAV_ACTIVE_UPDATE_SCRIPT` after persisted navigation).
148
+ * The visual tint comes from here — NOT from a JS-stamped color class —
149
+ * and the selector is pinned to `a.btn-ghost` so it can only ever match
150
+ * the ghost-styled nav links. Filled-button variants (`btn-primary` CTA,
151
+ * `btn-secondary`, `btn-accent`, `btn-error`, …) are immune: the CSS
152
+ * rule simply doesn't apply to them, so their daisyUI-derived
153
+ * foreground/background pair stays intact.
154
+ */
155
+ [data-publier-top-nav] a.btn-ghost[aria-current="page"] {
156
+ color: var(--color-primary);
157
+ background-color: color-mix(in oklab, var(--color-primary) 12%, transparent);
158
+ }
159
+
160
+ /* ─── SkipLink ───────────────────────────────────────────── */
161
+ .publier-skip-link {
162
+ position: fixed;
163
+ top: 0.75rem;
164
+ inset-inline-start: 0.75rem;
165
+ clip: rect(0, 0, 0, 0);
166
+ z-index: 50;
167
+ }
168
+ .publier-skip-link:focus {
169
+ clip: unset;
170
+ display: block;
171
+ padding: 0.5rem 1rem;
172
+ text-decoration: none;
173
+ color: var(--color-primary-content);
174
+ background-color: var(--color-primary);
175
+ border-radius: 0.375rem;
176
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
177
+ }
178
+
179
+ /* ─── ThemeToggle ─────────────────────────────────────────
180
+ * `<publier-theme-toggle>` custom element rendered by `theme-toggle.astro`;
181
+ * icon-only button that cycles auto → light → dark. Upgrades lazily via
182
+ * the shell's lazy-upgrade bootstrap on first interaction. Only one of
183
+ * the three inline icons is visible; `data-mode` on the host (set by an
184
+ * inline `<script>` reading localStorage synchronously) picks which one,
185
+ * so there's no FOUC between SSR and upgrade.
186
+ *
187
+ * Uses the active theme's foreground color so the icon is always readable;
188
+ * hover state lifts the background slightly. */
189
+ publier-theme-toggle {
190
+ display: inline-flex;
191
+ }
192
+ .publier-theme-toggle > button {
193
+ display: inline-flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ width: 2.25rem;
197
+ height: 2.25rem;
198
+ padding: 0.375rem;
199
+ border-radius: 0.375rem;
200
+ color: var(--color-base-content);
201
+ background-color: transparent;
202
+ border: none;
203
+ cursor: pointer;
204
+ transition: background-color 150ms ease;
205
+ }
206
+ .publier-theme-toggle > button:hover {
207
+ background-color: var(--color-base-300);
208
+ }
209
+ .publier-theme-toggle > button:focus-visible {
210
+ outline: 2px solid var(--color-primary);
211
+ outline-offset: 2px;
212
+ }
213
+ .publier-theme-toggle__icon {
214
+ display: none;
215
+ }
216
+ .publier-theme-toggle[data-mode="auto"] .publier-theme-toggle__icon--auto,
217
+ .publier-theme-toggle[data-mode="light"] .publier-theme-toggle__icon--light,
218
+ .publier-theme-toggle[data-mode="dark"] .publier-theme-toggle__icon--dark {
219
+ display: inline-block;
220
+ }
221
+
222
+ /* ─── AnnouncementBanner ──────────────────────────────────
223
+ * Pre-paint hide: `BANNER_INIT_SCRIPT` stamps
224
+ * `data-banner-dismissed="true"` on <html> synchronously before first
225
+ * paint; this rule hides the banner with zero flash.
226
+ *
227
+ * `!important` is required because daisyUI's `header.alert[data-publier-banner]`
228
+ * rule has equal specificity (1 element + 1 class + 1 attr = 1 element + 2 attr
229
+ * = (0,2,1)) and source-order makes its `display: flex` win. Without `!important`
230
+ * the click-to-dismiss handler runs but the banner stays visible. */
231
+ html[data-banner-dismissed="true"] [data-publier-banner] {
232
+ display: none !important;
233
+ }
234
+
235
+ /* ─── TableOfContents ─────────────────────────────────────
236
+ * Right-rail per-page navigation. Indented by heading depth;
237
+ * active entry gets primary color via scroll-spy signal. */
238
+ .publier-toc {
239
+ font-size: 0.875rem;
240
+ line-height: 1.4;
241
+ }
242
+
243
+ .publier-toc__label {
244
+ font-size: 0.8125rem;
245
+ font-weight: 600;
246
+ text-transform: uppercase;
247
+ letter-spacing: 0.025em;
248
+ color: var(--color-base-content);
249
+ margin: 0 0 0.75rem 0;
250
+ }
251
+
252
+ .publier-toc__list {
253
+ list-style: none;
254
+ padding: 0;
255
+ margin: 0;
256
+ border-inline-start: 1px solid var(--color-base-300);
257
+ }
258
+
259
+ .publier-toc__item {
260
+ margin: 0;
261
+ }
262
+
263
+ .publier-toc__link {
264
+ display: block;
265
+ padding: 0.3125rem 0.75rem;
266
+ margin-inline-start: -1px;
267
+ border-inline-start: 1px solid transparent;
268
+ color: var(--color-base-content);
269
+ text-decoration: none;
270
+ transition:
271
+ color 100ms ease,
272
+ border-color 100ms ease;
273
+ }
274
+
275
+ .publier-toc__link:hover {
276
+ color: var(--color-primary);
277
+ }
278
+
279
+ .publier-toc__link--active {
280
+ color: var(--color-primary);
281
+ border-inline-start-color: var(--color-primary);
282
+ font-weight: 500;
283
+ }
284
+
285
+ .publier-toc__link--depth-0 {
286
+ padding-inline-start: 0.75rem;
287
+ }
288
+ .publier-toc__link--depth-1 {
289
+ padding-inline-start: 1.5rem;
290
+ }
291
+ .publier-toc__link--depth-2 {
292
+ padding-inline-start: 2.25rem;
293
+ }
294
+ .publier-toc__link--depth-3 {
295
+ padding-inline-start: 3rem;
296
+ }
297
+ .publier-toc__link--depth-4 {
298
+ padding-inline-start: 3.75rem;
299
+ }
300
+
301
+ /* ─── VersionSwitcher ─────────────────────────────────────
302
+ * Compact dropdown for switching between doc versions. Trigger looks like
303
+ * a select; opens a floating listbox anchored to the trigger. Active
304
+ * version gets a check icon. Uses native <details> — no JS. */
305
+ .publier-version-switcher {
306
+ position: relative;
307
+ }
308
+
309
+ .publier-version-switcher > summary {
310
+ list-style: none;
311
+ }
312
+ .publier-version-switcher > summary::-webkit-details-marker {
313
+ display: none;
314
+ }
315
+
316
+ .publier-version-switcher__trigger {
317
+ display: flex;
318
+ align-items: center;
319
+ gap: 0.375rem;
320
+ width: 100%;
321
+ padding: 0.375rem 0.625rem;
322
+ border: 1px solid var(--color-base-300);
323
+ border-radius: 0.375rem;
324
+ background-color: var(--color-base-200);
325
+ color: var(--color-base-content);
326
+ font-size: 0.875rem;
327
+ font-weight: 500;
328
+ font-family: inherit;
329
+ cursor: pointer;
330
+ text-align: start;
331
+ transition:
332
+ background-color 100ms ease,
333
+ border-color 100ms ease;
334
+ }
335
+
336
+ .publier-version-switcher__trigger:hover {
337
+ background-color: var(--color-base-300);
338
+ border-color: var(--color-primary);
339
+ }
340
+
341
+ .publier-version-switcher__trigger:focus-visible {
342
+ outline: 2px solid var(--color-primary);
343
+ outline-offset: 2px;
344
+ }
345
+
346
+ .publier-version-switcher__current {
347
+ flex: 1;
348
+ overflow: hidden;
349
+ text-overflow: ellipsis;
350
+ white-space: nowrap;
351
+ }
352
+
353
+ .publier-version-switcher__chevron {
354
+ flex: none;
355
+ margin-inline-start: auto;
356
+ color: var(--color-base-content);
357
+ transition: transform 150ms ease;
358
+ }
359
+
360
+ .publier-version-switcher[open] .publier-version-switcher__chevron {
361
+ transform: rotate(90deg);
362
+ }
363
+
364
+ .publier-version-switcher__dropdown {
365
+ position: absolute;
366
+ inset-inline-start: 0;
367
+ inset-inline-end: 0;
368
+ top: calc(100% + 0.25rem);
369
+ z-index: 20;
370
+ margin: 0;
371
+ padding: 0.25rem;
372
+ background-color: var(--color-base-200);
373
+ border: 1px solid var(--color-base-300);
374
+ border-radius: 0.5rem;
375
+ box-shadow: 0 4px 12px rgb(0 0 0 / 0.12);
376
+ max-height: 16rem;
377
+ overflow-y: auto;
378
+ }
379
+
380
+ .publier-version-switcher__option {
381
+ display: flex;
382
+ align-items: center;
383
+ gap: 0.5rem;
384
+ padding: 0.375rem 0.625rem;
385
+ border-radius: 0.3125rem;
386
+ font-size: 0.875rem;
387
+ cursor: pointer;
388
+ color: var(--color-base-content);
389
+ text-decoration: none;
390
+ transition: background-color 100ms ease;
391
+ }
392
+
393
+ .publier-version-switcher__option:hover {
394
+ background-color: var(--color-base-300);
395
+ }
396
+
397
+ .publier-version-switcher__option--active {
398
+ color: var(--color-primary);
399
+ font-weight: 600;
400
+ }
401
+
402
+ .publier-version-switcher__option-label {
403
+ flex: 1;
404
+ }
405
+
406
+ .publier-version-switcher__check {
407
+ flex: none;
408
+ color: var(--color-primary);
409
+ }
410
+
411
+ .publier-version-switcher__badge {
412
+ display: inline-flex;
413
+ align-items: center;
414
+ font-size: 0.6875rem;
415
+ font-weight: 500;
416
+ line-height: 1;
417
+ padding: 0.1875rem 0.375rem;
418
+ border-radius: 9999px;
419
+ text-transform: capitalize;
420
+ }
421
+
422
+ .publier-version-switcher__badge--stable {
423
+ background-color: color-mix(in oklab, var(--color-primary) 12%, transparent);
424
+ color: var(--color-primary);
425
+ }
426
+ .publier-version-switcher__badge--beta {
427
+ background-color: color-mix(in oklab, var(--color-accent) 14%, transparent);
428
+ color: var(--color-accent);
429
+ }
430
+ .publier-version-switcher__badge--deprecated {
431
+ background-color: color-mix(in oklab, var(--color-error) 12%, transparent);
432
+ color: var(--color-error);
433
+ }
434
+ .publier-version-switcher__badge--legacy {
435
+ background-color: var(--color-base-300);
436
+ color: var(--color-base-content);
437
+ }
438
+
439
+ /* ─── OpenInAI ────────────────────────────────────────────
440
+ * Per-page action button + dropdown for opening page content in an AI
441
+ * tool. Positioned inline, typically near the page heading. */
442
+ .publier-open-in-ai {
443
+ position: relative;
444
+ display: inline-flex;
445
+ }
446
+
447
+ .publier-open-in-ai__trigger {
448
+ display: inline-flex;
449
+ align-items: center;
450
+ gap: 0.375rem;
451
+ padding: 0.375rem 0.75rem;
452
+ border: 1px solid var(--color-base-300);
453
+ border-radius: 0.375rem;
454
+ background-color: var(--color-base-200);
455
+ color: var(--color-base-content);
456
+ font-size: 0.8125rem;
457
+ font-family: inherit;
458
+ font-weight: 500;
459
+ line-height: 1.4;
460
+ cursor: pointer;
461
+ transition:
462
+ background-color 100ms ease,
463
+ border-color 100ms ease,
464
+ color 100ms ease;
465
+ }
466
+
467
+ .publier-open-in-ai__trigger:hover,
468
+ .publier-open-in-ai__trigger--active {
469
+ background-color: var(--color-base-300);
470
+ border-color: var(--color-primary);
471
+ color: var(--color-base-content);
472
+ }
473
+
474
+ .publier-open-in-ai__trigger:focus-visible {
475
+ outline: 2px solid var(--color-primary);
476
+ outline-offset: 2px;
477
+ }
478
+
479
+ .publier-open-in-ai__trigger-icon {
480
+ flex: none;
481
+ color: var(--color-primary);
482
+ }
483
+
484
+ .publier-open-in-ai__chevron {
485
+ flex: none;
486
+ transition: transform 150ms ease;
487
+ }
488
+
489
+ .publier-open-in-ai__chevron--open {
490
+ transform: rotate(180deg);
491
+ }
492
+
493
+ .publier-open-in-ai__dropdown {
494
+ position: absolute;
495
+ top: calc(100% + 0.375rem);
496
+ inset-inline-end: 0;
497
+ min-width: 13rem;
498
+ padding: 0.375rem;
499
+ background-color: var(--color-base-200);
500
+ border: 1px solid var(--color-base-300);
501
+ border-radius: 0.5rem;
502
+ box-shadow:
503
+ 0 4px 6px -1px rgb(0 0 0 / 0.1),
504
+ 0 2px 4px -2px rgb(0 0 0 / 0.1);
505
+ z-index: 20;
506
+ }
507
+
508
+ .publier-open-in-ai__option {
509
+ display: flex;
510
+ align-items: center;
511
+ gap: 0.5rem;
512
+ width: 100%;
513
+ padding: 0.5rem 0.625rem;
514
+ border: none;
515
+ background: transparent;
516
+ color: var(--color-base-content);
517
+ font-size: 0.8125rem;
518
+ font-family: inherit;
519
+ font-weight: 400;
520
+ line-height: 1.4;
521
+ text-decoration: none;
522
+ border-radius: 0.375rem;
523
+ cursor: pointer;
524
+ transition: background-color 100ms ease;
525
+ }
526
+
527
+ .publier-open-in-ai__option:hover {
528
+ background-color: var(--color-base-300);
529
+ }
530
+
531
+ .publier-open-in-ai__option:focus-visible {
532
+ outline: 2px solid var(--color-primary);
533
+ outline-offset: -2px;
534
+ }
535
+
536
+ .publier-open-in-ai__option--button {
537
+ text-align: start;
538
+ }
539
+
540
+ .publier-open-in-ai__option-icon {
541
+ flex: none;
542
+ color: var(--color-base-content);
543
+ }
544
+
545
+ .publier-open-in-ai__external-icon {
546
+ flex: none;
547
+ margin-inline-start: auto;
548
+ color: var(--color-base-content);
549
+ opacity: 0.5;
550
+ }
551
+
552
+ .publier-open-in-ai__divider {
553
+ border: none;
554
+ border-top: 1px solid var(--color-base-300);
555
+ margin: 0.375rem 0;
556
+ }
557
+
558
+ /* ─── Callouts / Asides ───────────────────────────────────
559
+ * DaisyUI `alert alert-{type} alert-soft` drives background tint.
560
+ * Overrides below shape it into a compact docs callout:
561
+ * - Body text size matches surrounding prose (1rem) instead of DaisyUI's
562
+ * baked-in 0.875rem so callouts sit visually flush with paragraphs.
563
+ * - Body text takes a tinted color (mix of variant accent + base-content)
564
+ * so the callout reads as themed without being hard-to-read.
565
+ * - Padding/gap/radius tightened to match the site's content density.
566
+ * - No left accent border — the soft tint + tinted body text carry the
567
+ * semantic cue.
568
+ * - First child margin reset prevents prose margin-top from misaligning
569
+ * the callout body with the icon top.
570
+ */
571
+ aside.alert {
572
+ align-items: start;
573
+ padding: 0.625rem 0.875rem;
574
+ gap: 0.625rem;
575
+ border-radius: 0.5rem;
576
+ /* Match prose body text size — DaisyUI's default is 0.875rem (text-sm). */
577
+ font-size: 1rem;
578
+ line-height: 1.6;
579
+ /* Tinted body text: 70% base-content, 30% variant accent — readable but themed. */
580
+ color: color-mix(in oklch, var(--alert-color) 30%, var(--color-base-content));
581
+ }
582
+ /* Icon keeps the semantic accent color. */
583
+ aside.alert svg {
584
+ color: var(--alert-color);
585
+ flex-shrink: 0;
586
+ }
587
+ /* Titled callout: heading inherits full accent so it anchors the color cue. */
588
+ aside.alert p.font-semibold {
589
+ color: var(--alert-color);
590
+ }
591
+ /* No left accent border — soft tint alone carries the semantic cue. */
592
+ aside.alert-soft {
593
+ border-inline-start-width: 0;
594
+ }
595
+ aside.alert .pl-callout__body > :first-child {
596
+ margin-top: 0;
597
+ }
598
+
599
+ /* ─── Announcement banner ─────────────────────────────────
600
+ * DaisyUI `.alert` defaults give the banner a 12 px block padding + grid
601
+ * layout that left-aligns content. Override to match the publier.net banner:
602
+ * - Compact 8 px block padding so the banner is ~40 px tall.
603
+ * - Flex layout so `justify-center` actually centers the message.
604
+ * - Body text reverts to base-content (white-ish on dark themes) instead
605
+ * of the variant accent — keeps the soft tinted background but lets the
606
+ * copy read clearly.
607
+ * - Dismiss button absolutely positioned so it doesn't push the centered
608
+ * message off-axis.
609
+ */
610
+ header.alert[data-publier-banner] {
611
+ display: flex;
612
+ align-items: center;
613
+ justify-content: center;
614
+ padding-block: 0.5rem;
615
+ color: var(--color-base-content);
616
+ position: relative;
617
+ }
618
+ header.alert[data-publier-banner] .link,
619
+ header.alert[data-publier-banner] > span {
620
+ color: var(--color-base-content);
621
+ }
622
+ header.alert[data-publier-banner] [data-publier-banner-dismiss] {
623
+ position: absolute;
624
+ inset-inline-end: 0.5rem;
625
+ margin-inline-start: 0;
626
+ color: var(--color-base-content);
627
+ }
@@ -0,0 +1,41 @@
1
+ /* @publier/shell — expressive-code bridge
2
+ *
3
+ * Maps astro-expressive-code's CSS custom properties to daisyUI v5 semantic
4
+ * tokens. Only the frame chrome is overridden here — syntax highlighting
5
+ * colors come from EC's own theme (github-light / github-dark by default).
6
+ *
7
+ * How to import: add this after @publier/shell/styles/base.css in your
8
+ * docs page layout, or let docsShell() handle it automatically via the
9
+ * ./styles/expressive-code.css export.
10
+ *
11
+ * EC variable reference: https://expressive-code.com/reference/configuration/#cssvar
12
+ */
13
+
14
+ .expressive-code {
15
+ /* Frame border — daisyUI base-300 plays the border role */
16
+ --ec-borderColor: var(--color-base-300);
17
+
18
+ /* Tab bar background — subdued surface */
19
+ --ec-frm-tabBarBg: var(--color-base-300);
20
+ --ec-frm-tabBarBorderBottomColor: var(--color-base-300);
21
+
22
+ /* Code area background — left to EC's own per-theme value.
23
+ *
24
+ * History: a previous attempt overrode --ec-codeBg + --ec-frm-edBg to
25
+ * a daisyUI token to fix maple-light's base-200=#fff invisibility
26
+ * against the warm-cream page. That broke darker themes by forcing a
27
+ * dark bg while EC's syntax-highlight tokens (red/blue keywords, dark
28
+ * text) stayed pinned to the github-light palette — dark fg on dark
29
+ * bg = unreadable. EC ships its bg AND its fg as a coordinated pair
30
+ * per theme (github-light, github-dark); the bridge must not split
31
+ * them. If a customer theme makes code blocks invisible against the
32
+ * page, fix it in the theme tokens, not here. */
33
+
34
+ /* Font families — wired through Astro's Fonts API. The body / heading
35
+ * fallbacks chain into `--font-sans` (Astro emits `@font-face` for Inter
36
+ * and binds it to `--font-sans` via the Fonts API). Customers can
37
+ * still override at the theme level via `--publier-font-body` /
38
+ * `--publier-font-mono`. */
39
+ --ec-codeFontFamily: var(--publier-font-mono, var(--font-mono));
40
+ --ec-uiFontFamily: var(--publier-font-body, var(--font-sans));
41
+ }