@uniweb/theming 0.1.13 → 0.1.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/theming",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Theming utilities for the Uniweb platform — shade generation, CSS generation, theme processing",
5
5
  "type": "module",
6
6
  "exports": {
@@ -321,6 +321,25 @@ function isGoogleFontsUrl(url) {
321
321
  }
322
322
  }
323
323
 
324
+ /**
325
+ * Marker delimiting the font `<link>` block in a rendered `<head>`.
326
+ *
327
+ * More than one stage can write that block — a build's `transformIndexHtml`, a
328
+ * build's per-page post-processing, and the runtime's shared prerender seam —
329
+ * so each has to tell "already injected" from "never injected" rather than
330
+ * guess, and a page passing through several must still end up with exactly one
331
+ * copy. The theme `<style>` hangs that check on its `id="uniweb-theme"`;
332
+ * `<link>` tags have no natural id, hence a comment.
333
+ *
334
+ * It lives HERE, beside the code producing the block it marks, because its
335
+ * consumers sit in packages that cannot import one another: `@uniweb/build`
336
+ * (both its Vite plugin and its prerenderer) and `@uniweb/runtime`. Both
337
+ * already depend on `@uniweb/theming`, so this is the one home neither has to
338
+ * reach across a dependency boundary to read — and duplicating the literal is
339
+ * exactly how the two halves of a dedupe check drift apart.
340
+ */
341
+ export const FONT_LINKS_MARKER = '<!--uniweb-fonts-->'
342
+
324
343
  /**
325
344
  * Generate font CSS and external link tags.
326
345
  *
@@ -597,10 +616,21 @@ export function generateThemeCSS(config = {}, options = {}) {
597
616
  sections.push(generateDarkSchemeCSS(appearance, contexts.dark, colorVars))
598
617
  }
599
618
 
600
- // 7. Site background (if specified in theme.yml)
601
- if (config.background) {
602
- sections.push(`/* Site Background */\nbody {\n background: ${config.background};\n}`)
603
- }
619
+ // 7. Site background — the page behind the sections.
620
+ //
621
+ // Sections paint themselves (rule 3), and on a page whose sections run the
622
+ // full width that covers the viewport. It does not cover a layout with
623
+ // columns: a sidebar shell paints its rails and its article and leaves the
624
+ // space between them unpainted, which falls through to the browser's white —
625
+ // in both schemes, so dark mode shows a white page around dark panels.
626
+ //
627
+ // Defaulting to var(--section) means the page matches the sections sitting on
628
+ // it and flips with the visitor's choice, because that token already does. A
629
+ // site wanting a different canvas — a wash behind cards, an image — sets
630
+ // `background:` in theme.yml and replaces this.
631
+ sections.push(
632
+ `/* Site Background */\nbody {\n background: ${config.background || 'var(--section)'};\n}`
633
+ )
604
634
 
605
635
  // 8. Inline text styles (if specified in theme.yml)
606
636
  if (config.inline && typeof config.inline === 'object') {
package/src/index.js CHANGED
@@ -26,6 +26,7 @@ export {
26
26
  getDefaultContextTokens,
27
27
  getDefaultColors,
28
28
  extractUsedFamilies,
29
+ FONT_LINKS_MARKER,
29
30
  } from './css-generator.js'
30
31
 
31
32
  // Theme processing