@rathnasgala/theme 0.0.19 → 2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rathnasgala/theme",
3
- "version": "0.0.19",
3
+ "version": "2.0.1",
4
4
  "description": "Managed Gala static-site theme payload",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -2,9 +2,11 @@
2
2
  "schemaVersion": 1,
3
3
  "themePackage": {
4
4
  "name": "@rathnasgala/theme",
5
- "version": "0.0.19",
5
+ "version": "2.0.1",
6
6
  "availableDesignThemes": [
7
- "editorial"
7
+ "editorial",
8
+ "modern",
9
+ "technical"
8
10
  ],
9
11
  "securityAdvisories": []
10
12
  },
@@ -15,7 +17,7 @@
15
17
  "files": {
16
18
  ".gala/publish.yml.template": "73080241d89bd09964b797a8bcc8e18471412e11bc873efad76305b60f497d08",
17
19
  ".gitignore": "b5fa24e10155097a0d372926fd2e59e6072e7cc2cb6399bbfb4beb8b33ea315b",
18
- "eleventy.config.js": "efe587447e3dc374a220c7fa037fdf2fffc02d09ba43a4d2b96d6c6aae0e3325",
20
+ "eleventy.config.js": "0b72076f2f884a3a4a5b2ea4a124e0c1308c735526275bb847a3d6ebd082a186",
19
21
  "lib/build-manifest.js": "88949f0112d683ca809bb67ca969e15634792423559a67bc79a534cd807e5535",
20
22
  "lib/engagement-snapshot.js": "298c11b1ab135a3a98a4e31b6320ab60dfd7fda6a9d9053df37d86282a5a6687",
21
23
  "lib/performance-budget.js": "c279622dfde237cd6e3c64775c91d770a0e1f54f5f94257ccc95d9a44de2c4c9",
@@ -25,35 +27,30 @@
25
27
  "lib/render-markdown.js": "40e6d6743b76de6c16d138475f188a4263967530c370d8b26a363f4df58c2caf",
26
28
  "lib/seo.js": "107de8804931945b8e73894877fc394d6b535a9d0d969a4ba5b68f2e136e0a17",
27
29
  "lib/share-targets.js": "458aff86fab2b62a364442cd8c612565c6e0b53eef2f20cb6237cc562b1e0731",
28
- "lib/site-config.js": "da7d2dffab62c7346c9930494b85fc6ea735d4f50565bbd0454a04393f8cad96",
29
- "package-lock.json": "c97a6a2f794aef083a39a8d2628eccc4a3c484e1c6225899b77ec1fb7c466d9e",
30
- "package.json": "4c60bea06f39aec755ac68caf8d8841c1d59d0f6121fad7f4396231ce14712dc",
30
+ "lib/site-config.js": "450b532049c9bc1b3dc44c4879e74c33b39c7b9a3e5267b15df98991a2255a20",
31
+ "package-lock.json": "dc11470b1ad897c58d91745f23ff25711c593e62972ec9fb83f4e10fd77e1ecd",
32
+ "package.json": "1b3b70f6e94391d309625cb8cef503ee92ecd282bec587643b535ae7a14c24c0",
31
33
  "src/404.njk": "be0d44370ac5402156aaf3d32ea581057bc61ec94c1a5f92bb809733af7a8a20",
32
34
  "src/_data/buildManifest.js": "628163305984e0d3537e27b0d4050f5ba5ead12a834878266d2ce8004ffe1b1e",
33
35
  "src/_data/engagementSnapshot.js": "9217dacebfaf008f7a0ad67ff4e8d1fa8fba609a9dc7e3430c78c5b32024da0e",
34
36
  "src/_data/feedLinks.js": "06c93352ebd888acb431a1c9a8be6ecff757895468e9f2d336761038751c2d5e",
35
37
  "src/_data/languages.js": "1358748f7fa2f74406d3295a030827d6229a53e94da72cf712e719d7a356aeac",
36
- "src/_data/site.js": "d9c001f4cc12a34027dd92303530b11b5402d47613459bb997e22c4bcbea326d",
37
- "src/_includes/components/ui.njk": "23eb647d8658868449ec6bb809e965a85302124a97639f94d5d28af72df56e4c",
38
- "src/_includes/layouts/base.njk": "e73be30738535902599e1c060c11afbd128c86332913114f643dc56dea99fcba",
39
- "src/_includes/layouts/post.njk": "1accd2832064ad19ee7bf18daf5fa1e60569f32c9b7a547934a6361f747d7eb7",
38
+ "src/_data/site.js": "6f9b754876ab7cfa93f02a38be2962edce8245423c354426a1465513caec7911",
39
+ "src/_includes/components/ui.njk": "94042d32664ab4a7a426c0155b43200c87ad1472cba19dcc605e43830967a8b7",
40
+ "src/_includes/layouts/base.njk": "5da6243e6f5242c233808601f299b5ef3aa82fd2a332f89e271c0c886b8d2bcd",
41
+ "src/_includes/layouts/post.njk": "ba46fbf621fb0134137536897408eff0c4caaacace726f6ca18d0f40c101effc",
40
42
  "src/assets/embed-codepen.svg": "e9def697f38c466fb2b6652535c4c814e8cbbbefc6e052a69f335aeb27e8356b",
41
43
  "src/assets/embed-gist.svg": "fcd9bc2bf29a5c118492b853c0a01390b7539c38ddb985da3c2a6e2f246a39f7",
42
44
  "src/assets/embed-x.svg": "0ae74edc6790ec7e933067fe5392bce756e93fa7ad71caacf1c1ca99fa4ec9b6",
43
45
  "src/assets/embed-youtube.svg": "10d192f2b14b67664fea88c8cf246321d20190def51d59fad5762e552219b067",
44
- "src/assets/engagement-comments.js": "b20d9268c9d908b4453a42188eaca25349f25534fb04a9293c9e688a982cd8f8",
45
- "src/assets/engagement-transport.js": "4f9ca0cd669bf8abc25f2909104e3e4b231657ef97d36a17d06e53454d711786",
46
+ "src/assets/engagement-comments.js": "4b12de4d05f479b8f98ccf2da07bb39fe279291842637bdb052cdaa7794761a2",
47
+ "src/assets/engagement-transport.js": "d4108cded823f859e7a8d6e36716162422ceaf5e4b94a57ed9bd7941d5096216",
46
48
  "src/assets/favicon.svg": "8615e3d96fe37ae9ed14afb1886e7c0e690eef5b10be66ca91cccfd085a74bb6",
47
- "src/assets/interactions.js": "dd4e343505e528d89596ca67db679b52c989e022f93399193e4377db01fc8a08",
49
+ "src/assets/interactions.js": "a3290243edd874ff0a20864ea9c3883b5c00a5dae1dd5eabe83ef8dc7d0e0f9f",
48
50
  "src/assets/preferences.js": "789127bee013ed6a1bbf8cefd7b9109291c16220e7a6e09314e3c93c54731d1d",
49
51
  "src/assets/search.js": "df425f0239277792ad39f2138bc89cb66cc4ecda5ed59042d46abc2f05372088",
50
52
  "src/assets/theme-mode.js": "944b29db11a577961a60ddcfa52f07ef2411f3f3631bea85bd79be16428c08be",
51
- "src/assets/theme.css": "cdd41ddb670fb8c823b3490efa2a887d11dd6a1931afa0264deee53283b684d3",
52
- "src/assets/vendor/hooks.js": "ae6ec58592683ca64fa4d65b20d40b103df62a673bcc4712515cf165950b07f3",
53
- "src/assets/vendor/htm.js": "e4dac9bc40a6f2ec590413d787ae30bbcfdfcde4f28971ee65d9578271b7aad4",
54
- "src/assets/vendor/preact.js": "712517dd2a42c3c22b5ab0264ad7e9a2b1e8be6cf97fa00dbedd98203617e616",
55
- "src/assets/vendor/signals-core.js": "1e10560fec5118c9e35eb312c869fe51f4870424766ef2ec0f7cd069bd898c8b",
56
- "src/assets/vendor/signals.js": "717a88151bacf4f8b79b528a96d71be20a133fb3345230c1146929903cecfd19",
53
+ "src/assets/theme.css": "c3e6f8367c824ff129f318113e51f8db3c9cb584c472f9be6ea8710804c8d433",
57
54
  "src/cname.11ty.js": "206fc224df91c569e18312158e7f69803061f2952513f501ada54bd06c4f8006",
58
55
  "src/contact.njk": "f4d74d038781e15af0acef571901c91e7753a2e21b6bef617429585698839a34",
59
56
  "src/feed.11ty.js": "009bd2384e08e02a9405683bab1653bab3aeaec16accb0fd01ba69b24c777da9",
@@ -64,7 +61,13 @@
64
61
  "src/search-index.11ty.js": "700dc2a2be0ef20de3a828a4612fcf7a082691eade29c6e1d75f09c24b6c6024",
65
62
  "src/search.njk": "63f2e8aeebb63c90da2e375eece639ce096cad1eff7f28628cafc46faf7ceee6",
66
63
  "src/sitemap.11ty.js": "4f233e94fb4a913ad5659116518432ed264984a7b622eba3558c77b4ec6435dc",
67
- "static/robots.txt": "16ceb5ee3e0dc13aa9adf31a3ebbe45a1d965b8c2b9f72eaf84e5911e140ed95"
64
+ "static/robots.txt": "16ceb5ee3e0dc13aa9adf31a3ebbe45a1d965b8c2b9f72eaf84e5911e140ed95",
65
+ "scripts/build-reader.js": "743194c8dc9cfb9b6631db1732b5f36a92e3a4f905a2965c71d56e1ef50c2e45",
66
+ "src/client/reader.js": "5a61d629517c5315b3cb14dbae6cee226ba828e95132100f2ad36e614c57470a",
67
+ "src/assets/reader.js": "cb53c4702bae396c708b6763352843868447ca9838bbf2ee451bb81c7c0b5b6c",
68
+ "scripts/lint.js": "c4bb3c961686043fa8c79bed546758ef09d44441421d8209fec9d69f74171025",
69
+ "src/styles/theme.css": "5ba8ccced10ceecd4ead7e60980d6d2f792eb9abff1748484d1a3de0273d2dc8",
70
+ "src/accent.11ty.js": "52e7d3eb731c5f4649c14c4745f65da026c25b58cf462d075b8ef363f0e487dc"
68
71
  },
69
72
  "artifactSources": {
70
73
  ".gitignore": ".gala/artifact-files/gitignore"
@@ -4,6 +4,9 @@ import { loadSiteConfiguration } from './lib/site-config.js';
4
4
  import { enforcePerformanceBudgets } from './lib/performance-budget.js';
5
5
  import { lstat, realpath } from 'node:fs/promises';
6
6
  import path from 'node:path';
7
+ import { createHash } from 'node:crypto';
8
+
9
+ const themeBootstrap = "(function(){try{var m=localStorage.getItem('gala-color-mode');if(m==='light'||m==='dark'||m==='system')document.documentElement.dataset.mode=m}catch(e){}})();";
7
10
 
8
11
  async function verifiedMediaSource(postSource, mediaSource) {
9
12
  const metadata = await lstat(mediaSource);
@@ -25,9 +28,20 @@ export default async function (eleventyConfig) {
25
28
  const [manifest, site] = await Promise.all([readBuildManifest(), loadSiteConfiguration()]);
26
29
  const attributionTier = process.env.GALA_ATTRIBUTION_TIER === 'PAID' ? 'PAID' : 'FREE';
27
30
  eleventyConfig.addGlobalData('attributionTier', attributionTier);
31
+ eleventyConfig.addGlobalData('themeBootstrap', themeBootstrap);
32
+ eleventyConfig.addFilter('sha256Csp', (value) =>
33
+ createHash('sha256').update(String(value)).digest('base64'));
28
34
  eleventyConfig.setLibrary('md', markdownLibrary);
29
35
  eleventyConfig.addPassthroughCopy({ static: '/' });
30
- eleventyConfig.addPassthroughCopy({ 'src/assets': 'assets' });
36
+ eleventyConfig.addPassthroughCopy({
37
+ 'src/assets/theme.css': 'assets/theme.css',
38
+ 'src/assets/reader.js': 'assets/reader.js',
39
+ 'src/assets/favicon.svg': 'assets/favicon.svg',
40
+ 'src/assets/embed-codepen.svg': 'assets/embed-codepen.svg',
41
+ 'src/assets/embed-gist.svg': 'assets/embed-gist.svg',
42
+ 'src/assets/embed-x.svg': 'assets/embed-x.svg',
43
+ 'src/assets/embed-youtube.svg': 'assets/embed-youtube.svg'
44
+ });
31
45
  eleventyConfig.addPassthroughCopy('custom.css');
32
46
  for (const post of manifest.posts) {
33
47
  for (const copy of post.media ?? []) {
@@ -12,14 +12,14 @@ const BUDGET_KEYS = Object.freeze([
12
12
  * a publication looks; anything the CSS does not answer to has no business being offered.
13
13
  */
14
14
  const DESIGN_VALUES = Object.freeze({
15
+ theme: Object.freeze(['editorial', 'modern', 'technical']),
16
+ colorMode: Object.freeze(['system', 'light', 'dark'])
17
+ });
18
+ // Accepted only so repositories created before v2 keep building. New author surfaces never offer
19
+ // these independent knobs; v2's look owns its layout and palette as one reviewed composition.
20
+ const LEGACY_DESIGN_VALUES = Object.freeze({
15
21
  layout: Object.freeze(['article-first', 'portfolio']),
16
- palette: Object.freeze(['default', 'ocean']),
17
- typography: Object.freeze(['system', 'editorial', 'humanist', 'mono']),
18
- density: Object.freeze(['compact', 'comfortable', 'spacious']),
19
- spacing: Object.freeze(['compact', 'comfortable', 'spacious']),
20
- radius: Object.freeze(['sharp', 'soft', 'round']),
21
- motion: Object.freeze(['none', 'subtle', 'expressive']),
22
- componentStyle: Object.freeze(['quiet', 'outlined', 'raised'])
22
+ palette: Object.freeze(['default', 'ocean', 'forest', 'plum'])
23
23
  });
24
24
  const CONTACT_KEYS = Object.freeze([
25
25
  'enabled', 'websiteEnabled', 'phoneEnabled'
@@ -31,17 +31,28 @@ const CONTACT_KEYS = Object.freeze([
31
31
  * back to its own defaults for anything absent. Present-but-unknown is still an error, because
32
32
  * that is a writer expecting something the CSS will not do.
33
33
  */
34
- const REQUIRED_DESIGN = Object.freeze(['layout', 'palette']);
34
+ /** A free colour, not a menu — but still a colour. */
35
+ const ACCENT = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
35
36
 
36
37
  function validateImplementedDesign(config) {
38
+ const accent = config?.design?.accent;
39
+ if (accent !== undefined && !(typeof accent === 'string' && ACCENT.test(accent.trim()))) {
40
+ throw new TypeError(`Unsupported design.accent: ${accent}`);
41
+ }
37
42
  if (config?.design == null) return;
38
43
  for (const [field, allowed] of Object.entries(DESIGN_VALUES)) {
39
44
  const value = config.design[field];
40
- if (value === undefined && !REQUIRED_DESIGN.includes(field)) continue;
45
+ if (value === undefined) continue;
41
46
  if (!allowed.includes(value)) {
42
47
  throw new TypeError(`Unsupported design.${field}: ${value}`);
43
48
  }
44
49
  }
50
+ for (const [field, allowed] of Object.entries(LEGACY_DESIGN_VALUES)) {
51
+ const value = config.design[field];
52
+ if (value !== undefined && !allowed.includes(value)) {
53
+ throw new TypeError(`Unsupported legacy design.${field}: ${value}`);
54
+ }
55
+ }
45
56
  }
46
57
 
47
58
  export function validatePerformanceBudgets(value) {