@rathnasgala2/template 3.2.0 → 4.0.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.
package/README.md CHANGED
@@ -629,7 +629,7 @@ npm run verify
629
629
  hand-maintained) runs, in order: Prettier format check, ESLint,
630
630
  `tsc --checkJs --noEmit`, the dependency-cruiser
631
631
  architecture/module-tree-absence gate, `jscpd` duplication scan, the
632
- `contracts/*.jcs` canonical-form check, the no-local-schema-pin check,
632
+ `contracts/*.jcs` canonical-form check, the no-local-schema-pin check, the
633
633
  `node --test`, the license inventory check, the SBOM currency check
634
634
  (`sbom:check` compares `sbom.cdx.json` against the current lockfile — it is not
635
635
  a presence check), the workflow-pin check, and `npm audit --audit-level=high`.
@@ -645,7 +645,7 @@ npm run architecture # dependency-cruiser: core never imports src/modules, no
645
645
  npm run duplication # jscpd, 3% / 50 tokens
646
646
  npm run contracts:generate # (re)write contracts/*.jcs from their reviewed source modules
647
647
  npm run contracts:check # fail if committed contracts drifted
648
- npm run schema-pin:check # fail on a file: @rathnasgala2/schemas specifier
648
+ npm run schema-pin:check # require the exact registry @rathnasgala2/schemas release
649
649
  npm test # node --test
650
650
  npm run licenses:generate # (re)write THIRD_PARTY_LICENSES.json
651
651
  npm run licenses:check # fail if it drifted from package-lock.json
@@ -656,6 +656,11 @@ npm run workflows:drift # fail if workflow files diverge from their own base
656
656
  npm run audit # npm audit --audit-level=high
657
657
  ```
658
658
 
659
+ Source development does not require a sibling schema checkout. The exact
660
+ `@rathnasgala2/schemas@3.8.0` release is installed from the npm registry, and
661
+ the lockfile carries its registry integrity. The exact peer is the public
662
+ consumer contract.
663
+
659
664
  ## Package layout
660
665
 
661
666
  ```text
@@ -679,17 +684,16 @@ editions: they are a rendered content kind (see Editions).
679
684
 
680
685
  ## Consuming `@rathnasgala2/schemas`
681
686
 
682
- This repository consumes `@rathnasgala2/schemas@3.3.0` from the public npm
683
- registry, declared as `"@rathnasgala2/schemas": "3.3.0"` (exact pin, no range)
684
- so `package-lock.json` records the resolved version and integrity hash. The
685
- LOCAL-1/LOCAL-39 local-tarball convention
686
- (`file:../../local-packages/rathnasgala2-schemas-*.tgz`) is retired for this
687
- package now that it publishes to the registry. The 2.8.0->2.11.0 convergence
688
- changes none of the four roots this renderer validates, for the same reason the
689
- 2.7.0-2.8.0 delta below did not. Only the `"."` export (`validateGalaDocument`,
690
- `GALA_SCHEMA_IDS`) is consumed; the 2.6.0 `./runtime-origins` narrow export and
691
- every other addition through 2.6.1 (new OpenAPI operations, App route/catalog
692
- copy, the `PrincipalSummary`/`AuthenticatorSummary`/keyset field additions) are
687
+ This source targets `@rathnasgala2/schemas@3.8.0` with an exact manifest pin.
688
+ Generation-4 development verifies against the schema sibling/packed candidate.
689
+ The historical `package-lock.json` is not a 3.8.0 registry claim: it must be
690
+ regenerated, together with the SBOM, from the authoritative published 3.8.0
691
+ artifact before release. The 2.8.0->2.11.0 convergence changes none of the four
692
+ roots this renderer validates, for the same reason the 2.7.0-2.8.0 delta below
693
+ did not. Only the `"."` export (`validateGalaDocument`, `GALA_SCHEMA_IDS`) is
694
+ consumed; the 2.6.0 `./runtime-origins` narrow export and every other addition
695
+ through 2.6.1 (new OpenAPI operations, App route/catalog copy, the
696
+ `PrincipalSummary`/`AuthenticatorSummary`/keyset field additions) are
693
697
  App/API-surface changes this renderer does not read. The `"."` export's 2.2.2
694
698
  browser-safety refactor (Node builtins replaced with browser-safe equivalents
695
699
  behind the same public API) is byte-identical in behaviour for a Node consumer
@@ -1 +1 @@
1
- {"attributes":[{"match":"exact-value","name":"data-gala-page-kind","role":"semantic","values":["archive","article","author","error","index","page","profile","series","tag"]},{"match":"exact-value","name":"data-gala-resolved-color-mode","role":"state","values":["dark","light"]},{"match":"exact-value","name":"data-gala-slot","role":"semantic","values":["account-intent","article-end","article-footer-ad","article-preamble","conversation","edition-selector","footer-auxiliary","footer-profile","header-actions","newsletter"]},{"match":"presence","name":"data-gala-publication-root","role":"root","values":[]}],"catalogDigest":"sha256:a10fecf6d43e4392312158f15b66d55a9e2bd3c7816a0747eb2084735d336de5","classSelectors":["g-actions","g-article","g-article-cover","g-article-foot","g-article-grid","g-article-head","g-article-labels","g-article-meta","g-author-bio","g-author-card","g-author-name","g-avatar","g-badge","g-brand","g-brand-name","g-brand-tag","g-brand-text","g-btn","g-byline","g-byline-text","g-card","g-card-body","g-card-excerpt","g-card-foot","g-card-link","g-card-media","g-card-placeholder","g-card-row","g-card-top","g-chip","g-codebar","g-codebar-lang","g-codeblock","g-copy","g-copy-done","g-copy-idle","g-crumbs","g-dek","g-dot","g-eyebrow","g-footer","g-footer-about","g-footer-base","g-footer-brand","g-footer-col","g-footer-grid","g-grid","g-header","g-header-row","g-hero","g-hero-body","g-hero-media","g-icon","g-icon-btn","g-kbd","g-label","g-list","g-main","g-mark","g-menu","g-meta","g-mode-dark","g-mode-icon","g-mode-light","g-mode-system","g-more","g-nav","g-newsletter","g-pager","g-pager-link","g-pager-next","g-pagination","g-panel","g-panel-copy","g-pill","g-pill-count","g-pills","g-progress","g-prose","g-search","g-search-box","g-search-btn","g-search-empty","g-search-hit","g-search-hit-meta","g-search-hit-text","g-search-hit-title","g-search-input","g-search-results","g-section","g-section-head","g-series-box","g-series-card","g-series-here","g-series-list","g-series-n","g-series-tag","g-share","g-skip","g-social","g-sr","g-tag","g-tags","g-toast","g-toc","g-toc-list","g-toc-mobile","g-topic-head","g-topic-hero","g-topic-icon","g-topic-strip","g-wrap","language-bash","language-css","language-diff","language-java","language-javascript","language-json","language-jsx","language-markdown","language-markup","language-python","language-sql","language-tsx","language-typescript","language-yaml","token"],"combinators":[" "," > "," + "," ~ "],"composition":{"compoundOrder":["type","id","class","attribute","pseudo-class","pseudo-element"],"functionalPseudoKeywordArguments":["even","odd"],"functionalSelectorArguments":"compound-only","maximumFunctionalDepth":1,"nthExpressionProfile":"gala-positive-an-plus-b-v2","rootScope":"first-compound-required"},"contractVersion":"3.0.0","functionalPseudos":["is","where","not","nth-child","nth-last-child"],"idSelectors":["gala-appearance-color-mode","main-content"],"orderedLayers":["gala-base","gala-tokens","gala-components","gala-utilities","gala-print"],"profile":"gala-template-styling-contract-v2","pseudoClasses":["active","disabled","focus-visible","hover","visited"],"pseudoElements":["after","before","marker","selection"],"publicThemeSlotHooks":[{"hookId":"code-block","selectorAtom":"pre"},{"hookId":"code-inline","selectorAtom":"code"},{"hookId":"code-language-bash","selectorAtom":".language-bash"},{"hookId":"code-language-css","selectorAtom":".language-css"},{"hookId":"code-language-diff","selectorAtom":".language-diff"},{"hookId":"code-language-java","selectorAtom":".language-java"},{"hookId":"code-language-javascript","selectorAtom":".language-javascript"},{"hookId":"code-language-json","selectorAtom":".language-json"},{"hookId":"code-language-jsx","selectorAtom":".language-jsx"},{"hookId":"code-language-markdown","selectorAtom":".language-markdown"},{"hookId":"code-language-markup","selectorAtom":".language-markup"},{"hookId":"code-language-python","selectorAtom":".language-python"},{"hookId":"code-language-sql","selectorAtom":".language-sql"},{"hookId":"code-language-tsx","selectorAtom":".language-tsx"},{"hookId":"code-language-typescript","selectorAtom":".language-typescript"},{"hookId":"code-language-yaml","selectorAtom":".language-yaml"},{"hookId":"code-token","selectorAtom":".token"},{"hookId":"content-article","selectorAtom":"article"},{"hookId":"control-appearance-toggle","selectorAtom":"#gala-appearance-color-mode"},{"hookId":"control-button","selectorAtom":"button"},{"hookId":"disclosure-details","selectorAtom":"details"},{"hookId":"disclosure-summary","selectorAtom":"summary"},{"hookId":"heading-1","selectorAtom":"h1"},{"hookId":"heading-2","selectorAtom":"h2"},{"hookId":"heading-3","selectorAtom":"h3"},{"hookId":"heading-4","selectorAtom":"h4"},{"hookId":"heading-5","selectorAtom":"h5"},{"hookId":"heading-6","selectorAtom":"h6"},{"hookId":"landmark-footer","selectorAtom":"footer"},{"hookId":"landmark-header","selectorAtom":"header"},{"hookId":"landmark-main","selectorAtom":"main"},{"hookId":"landmark-main-content","selectorAtom":"#main-content"},{"hookId":"landmark-navigation","selectorAtom":"nav"},{"hookId":"landmark-section","selectorAtom":"section"},{"hookId":"media-figure","selectorAtom":"figure"},{"hookId":"media-image","selectorAtom":"img"},{"hookId":"page-archive","selectorAtom":"[data-gala-page-kind=\"archive\"]"},{"hookId":"page-article","selectorAtom":"[data-gala-page-kind=\"article\"]"},{"hookId":"page-author","selectorAtom":"[data-gala-page-kind=\"author\"]"},{"hookId":"page-error","selectorAtom":"[data-gala-page-kind=\"error\"]"},{"hookId":"page-index","selectorAtom":"[data-gala-page-kind=\"index\"]"},{"hookId":"page-page","selectorAtom":"[data-gala-page-kind=\"page\"]"},{"hookId":"page-profile","selectorAtom":"[data-gala-page-kind=\"profile\"]"},{"hookId":"page-series","selectorAtom":"[data-gala-page-kind=\"series\"]"},{"hookId":"page-tag","selectorAtom":"[data-gala-page-kind=\"tag\"]"},{"hookId":"prose-blockquote","selectorAtom":"blockquote"},{"hookId":"prose-divider","selectorAtom":"hr"},{"hookId":"prose-emphasis","selectorAtom":"em"},{"hookId":"prose-link","selectorAtom":"a"},{"hookId":"prose-list-item","selectorAtom":"li"},{"hookId":"prose-list-ordered","selectorAtom":"ol"},{"hookId":"prose-list-unordered","selectorAtom":"ul"},{"hookId":"prose-paragraph","selectorAtom":"p"},{"hookId":"prose-span","selectorAtom":"span"},{"hookId":"prose-strong","selectorAtom":"strong"},{"hookId":"prose-time","selectorAtom":"time"},{"hookId":"slot-account-intent","selectorAtom":"[data-gala-slot=\"account-intent\"]"},{"hookId":"slot-article-end","selectorAtom":"[data-gala-slot=\"article-end\"]"},{"hookId":"slot-article-footer-ad","selectorAtom":"[data-gala-slot=\"article-footer-ad\"]"},{"hookId":"slot-article-preamble","selectorAtom":"[data-gala-slot=\"article-preamble\"]"},{"hookId":"slot-conversation","selectorAtom":"[data-gala-slot=\"conversation\"]"},{"hookId":"slot-edition-selector","selectorAtom":"[data-gala-slot=\"edition-selector\"]"},{"hookId":"slot-footer-auxiliary","selectorAtom":"[data-gala-slot=\"footer-auxiliary\"]"},{"hookId":"slot-footer-profile","selectorAtom":"[data-gala-slot=\"footer-profile\"]"},{"hookId":"slot-header-actions","selectorAtom":"[data-gala-slot=\"header-actions\"]"},{"hookId":"slot-newsletter","selectorAtom":"[data-gala-slot=\"newsletter\"]"},{"hookId":"ui-actions","selectorAtom":".g-actions"},{"hookId":"ui-article","selectorAtom":".g-article"},{"hookId":"ui-article-cover","selectorAtom":".g-article-cover"},{"hookId":"ui-article-foot","selectorAtom":".g-article-foot"},{"hookId":"ui-article-grid","selectorAtom":".g-article-grid"},{"hookId":"ui-article-head","selectorAtom":".g-article-head"},{"hookId":"ui-article-labels","selectorAtom":".g-article-labels"},{"hookId":"ui-article-meta","selectorAtom":".g-article-meta"},{"hookId":"ui-author-bio","selectorAtom":".g-author-bio"},{"hookId":"ui-author-card","selectorAtom":".g-author-card"},{"hookId":"ui-author-name","selectorAtom":".g-author-name"},{"hookId":"ui-avatar","selectorAtom":".g-avatar"},{"hookId":"ui-badge","selectorAtom":".g-badge"},{"hookId":"ui-brand","selectorAtom":".g-brand"},{"hookId":"ui-brand-name","selectorAtom":".g-brand-name"},{"hookId":"ui-brand-tag","selectorAtom":".g-brand-tag"},{"hookId":"ui-brand-text","selectorAtom":".g-brand-text"},{"hookId":"ui-btn","selectorAtom":".g-btn"},{"hookId":"ui-byline","selectorAtom":".g-byline"},{"hookId":"ui-byline-text","selectorAtom":".g-byline-text"},{"hookId":"ui-card","selectorAtom":".g-card"},{"hookId":"ui-card-body","selectorAtom":".g-card-body"},{"hookId":"ui-card-excerpt","selectorAtom":".g-card-excerpt"},{"hookId":"ui-card-foot","selectorAtom":".g-card-foot"},{"hookId":"ui-card-link","selectorAtom":".g-card-link"},{"hookId":"ui-card-media","selectorAtom":".g-card-media"},{"hookId":"ui-card-placeholder","selectorAtom":".g-card-placeholder"},{"hookId":"ui-card-row","selectorAtom":".g-card-row"},{"hookId":"ui-card-top","selectorAtom":".g-card-top"},{"hookId":"ui-chip","selectorAtom":".g-chip"},{"hookId":"ui-codebar","selectorAtom":".g-codebar"},{"hookId":"ui-codebar-lang","selectorAtom":".g-codebar-lang"},{"hookId":"ui-codeblock","selectorAtom":".g-codeblock"},{"hookId":"ui-copy","selectorAtom":".g-copy"},{"hookId":"ui-copy-done","selectorAtom":".g-copy-done"},{"hookId":"ui-copy-idle","selectorAtom":".g-copy-idle"},{"hookId":"ui-crumbs","selectorAtom":".g-crumbs"},{"hookId":"ui-dek","selectorAtom":".g-dek"},{"hookId":"ui-dot","selectorAtom":".g-dot"},{"hookId":"ui-eyebrow","selectorAtom":".g-eyebrow"},{"hookId":"ui-footer","selectorAtom":".g-footer"},{"hookId":"ui-footer-about","selectorAtom":".g-footer-about"},{"hookId":"ui-footer-base","selectorAtom":".g-footer-base"},{"hookId":"ui-footer-brand","selectorAtom":".g-footer-brand"},{"hookId":"ui-footer-col","selectorAtom":".g-footer-col"},{"hookId":"ui-footer-grid","selectorAtom":".g-footer-grid"},{"hookId":"ui-grid","selectorAtom":".g-grid"},{"hookId":"ui-header","selectorAtom":".g-header"},{"hookId":"ui-header-row","selectorAtom":".g-header-row"},{"hookId":"ui-hero","selectorAtom":".g-hero"},{"hookId":"ui-hero-body","selectorAtom":".g-hero-body"},{"hookId":"ui-hero-media","selectorAtom":".g-hero-media"},{"hookId":"ui-icon","selectorAtom":".g-icon"},{"hookId":"ui-icon-btn","selectorAtom":".g-icon-btn"},{"hookId":"ui-kbd","selectorAtom":".g-kbd"},{"hookId":"ui-label","selectorAtom":".g-label"},{"hookId":"ui-list","selectorAtom":".g-list"},{"hookId":"ui-main","selectorAtom":".g-main"},{"hookId":"ui-mark","selectorAtom":".g-mark"},{"hookId":"ui-menu","selectorAtom":".g-menu"},{"hookId":"ui-meta","selectorAtom":".g-meta"},{"hookId":"ui-mode-dark","selectorAtom":".g-mode-dark"},{"hookId":"ui-mode-icon","selectorAtom":".g-mode-icon"},{"hookId":"ui-mode-light","selectorAtom":".g-mode-light"},{"hookId":"ui-mode-system","selectorAtom":".g-mode-system"},{"hookId":"ui-more","selectorAtom":".g-more"},{"hookId":"ui-nav","selectorAtom":".g-nav"},{"hookId":"ui-newsletter","selectorAtom":".g-newsletter"},{"hookId":"ui-pager","selectorAtom":".g-pager"},{"hookId":"ui-pager-link","selectorAtom":".g-pager-link"},{"hookId":"ui-pager-next","selectorAtom":".g-pager-next"},{"hookId":"ui-pagination","selectorAtom":".g-pagination"},{"hookId":"ui-panel","selectorAtom":".g-panel"},{"hookId":"ui-panel-copy","selectorAtom":".g-panel-copy"},{"hookId":"ui-pill","selectorAtom":".g-pill"},{"hookId":"ui-pill-count","selectorAtom":".g-pill-count"},{"hookId":"ui-pills","selectorAtom":".g-pills"},{"hookId":"ui-progress","selectorAtom":".g-progress"},{"hookId":"ui-prose","selectorAtom":".g-prose"},{"hookId":"ui-search","selectorAtom":".g-search"},{"hookId":"ui-search-box","selectorAtom":".g-search-box"},{"hookId":"ui-search-btn","selectorAtom":".g-search-btn"},{"hookId":"ui-search-empty","selectorAtom":".g-search-empty"},{"hookId":"ui-search-hit","selectorAtom":".g-search-hit"},{"hookId":"ui-search-hit-meta","selectorAtom":".g-search-hit-meta"},{"hookId":"ui-search-hit-text","selectorAtom":".g-search-hit-text"},{"hookId":"ui-search-hit-title","selectorAtom":".g-search-hit-title"},{"hookId":"ui-search-input","selectorAtom":".g-search-input"},{"hookId":"ui-search-results","selectorAtom":".g-search-results"},{"hookId":"ui-section","selectorAtom":".g-section"},{"hookId":"ui-section-head","selectorAtom":".g-section-head"},{"hookId":"ui-series-box","selectorAtom":".g-series-box"},{"hookId":"ui-series-card","selectorAtom":".g-series-card"},{"hookId":"ui-series-here","selectorAtom":".g-series-here"},{"hookId":"ui-series-list","selectorAtom":".g-series-list"},{"hookId":"ui-series-n","selectorAtom":".g-series-n"},{"hookId":"ui-series-tag","selectorAtom":".g-series-tag"},{"hookId":"ui-share","selectorAtom":".g-share"},{"hookId":"ui-skip","selectorAtom":".g-skip"},{"hookId":"ui-social","selectorAtom":".g-social"},{"hookId":"ui-sr","selectorAtom":".g-sr"},{"hookId":"ui-tag","selectorAtom":".g-tag"},{"hookId":"ui-tags","selectorAtom":".g-tags"},{"hookId":"ui-toast","selectorAtom":".g-toast"},{"hookId":"ui-toc","selectorAtom":".g-toc"},{"hookId":"ui-toc-list","selectorAtom":".g-toc-list"},{"hookId":"ui-toc-mobile","selectorAtom":".g-toc-mobile"},{"hookId":"ui-topic-head","selectorAtom":".g-topic-head"},{"hookId":"ui-topic-hero","selectorAtom":".g-topic-hero"},{"hookId":"ui-topic-icon","selectorAtom":".g-topic-icon"},{"hookId":"ui-topic-strip","selectorAtom":".g-topic-strip"},{"hookId":"ui-wrap","selectorAtom":".g-wrap"}],"publicationRootSelector":"[data-gala-publication-root]","resolvedPaletteSelectors":{"dark":"[data-gala-publication-root][data-gala-resolved-color-mode=\"dark\"]","light":"[data-gala-publication-root][data-gala-resolved-color-mode=\"light\"]"},"stylesheetLayers":{"components":"gala-components","print":"gala-print","tokens":"gala-tokens","utilities":"gala-utilities"},"templatePackage":"@rathnasgala2/template","templateVersion":"3.0.0","typeSelectors":["a","article","blockquote","button","code","details","em","figure","footer","h1","h2","h3","h4","h5","h6","header","hr","img","li","main","nav","ol","p","pre","section","span","strong","summary","time","ul"]}
1
+ {"attributes":[{"match":"exact-value","name":"data-gala-article-layout","role":"semantic","values":["editorial","full-bleed","issue","prose","technical"]},{"match":"exact-value","name":"data-gala-author-layout","role":"semantic","values":["biography","portfolio","portrait","profile"]},{"match":"exact-value","name":"data-gala-density","role":"semantic","values":["comfortable","compact","spacious"]},{"match":"exact-value","name":"data-gala-footer-layout","role":"semantic","values":["compact","expanded"]},{"match":"exact-value","name":"data-gala-header-layout","role":"semantic","values":["compact","masthead","minimal","publication","utility"]},{"match":"exact-value","name":"data-gala-home-layout","role":"semantic","values":["chronological","gallery","magazine","newspaper","topic-index"]},{"match":"exact-value","name":"data-gala-listing-layout","role":"semantic","values":["dated-rows","image-grid","issues","rows"]},{"match":"exact-value","name":"data-gala-media-ratio","role":"semantic","values":["landscape","mixed"]},{"match":"exact-value","name":"data-gala-page-kind","role":"semantic","values":["archive","article","author","error","index","page","profile","series","tag"]},{"match":"exact-value","name":"data-gala-profile","role":"semantic","values":["developer","editorial","newsletter","personal","visual"]},{"match":"exact-value","name":"data-gala-resolved-color-mode","role":"state","values":["dark","light"]},{"match":"exact-value","name":"data-gala-slot","role":"semantic","values":["account-intent","article-end","article-footer-ad","article-preamble","conversation","edition-selector","footer-auxiliary","footer-profile","header-actions","newsletter"]},{"match":"presence","name":"data-gala-publication-root","role":"root","values":[]}],"catalogDigest":"sha256:63a76754b591a3cda91a4be1f43bdb3fe1d44cf4f9be766154f3944a043399b5","classSelectors":["g-actions","g-article","g-article-cover","g-article-cover-full-bleed","g-article-foot","g-article-grid","g-article-head","g-article-labels","g-article-meta","g-author-bio","g-author-card","g-author-name","g-avatar","g-badge","g-brand","g-brand-name","g-brand-tag","g-brand-text","g-btn","g-byline","g-byline-text","g-card","g-card-body","g-card-excerpt","g-card-foot","g-card-link","g-card-media","g-card-placeholder","g-card-row","g-card-top","g-chip","g-codebar","g-codebar-lang","g-codeblock","g-copy","g-copy-done","g-copy-idle","g-crumbs","g-date-stamp","g-dated-list","g-dated-row","g-dek","g-dot","g-eyebrow","g-footer","g-footer-about","g-footer-base","g-footer-brand","g-footer-col","g-footer-grid","g-grid","g-header","g-header-row","g-hero","g-hero-body","g-hero-media","g-icon","g-icon-btn","g-kbd","g-label","g-list","g-main","g-mark","g-menu","g-meta","g-mode-dark","g-mode-icon","g-mode-light","g-mode-system","g-more","g-nav","g-newsletter","g-pager","g-pager-link","g-pager-next","g-pagination","g-panel","g-panel-copy","g-pill","g-pill-count","g-pills","g-progress","g-prose","g-search","g-search-box","g-search-btn","g-search-empty","g-search-hit","g-search-hit-meta","g-search-hit-text","g-search-hit-title","g-search-input","g-search-results","g-section","g-section-head","g-series-box","g-series-card","g-series-here","g-series-list","g-series-n","g-series-tag","g-share","g-skip","g-social","g-sr","g-tag","g-tags","g-toast","g-toc","g-toc-list","g-toc-mobile","g-topic-head","g-topic-hero","g-topic-icon","g-topic-strip","g-wrap","language-bash","language-css","language-diff","language-java","language-javascript","language-json","language-jsx","language-markdown","language-markup","language-python","language-sql","language-tsx","language-typescript","language-yaml","token"],"combinators":[" "," > "," + "," ~ "],"composition":{"compoundOrder":["type","id","class","attribute","pseudo-class","pseudo-element"],"functionalPseudoKeywordArguments":["even","odd"],"functionalSelectorArguments":"compound-only","maximumFunctionalDepth":1,"nthExpressionProfile":"gala-positive-an-plus-b-v2","rootScope":"first-compound-required"},"contractVersion":"4.0.0","functionalPseudos":["is","where","not","nth-child","nth-last-child"],"idSelectors":["gala-appearance-color-mode","main-content"],"orderedLayers":["gala-base","gala-tokens","gala-components","gala-utilities","gala-print"],"profile":"gala-template-styling-contract-v2","pseudoClasses":["active","disabled","focus-visible","hover","visited"],"pseudoElements":["after","before","marker","selection"],"publicThemeSlotHooks":[{"hookId":"code-block","selectorAtom":"pre"},{"hookId":"code-inline","selectorAtom":"code"},{"hookId":"code-language-bash","selectorAtom":".language-bash"},{"hookId":"code-language-css","selectorAtom":".language-css"},{"hookId":"code-language-diff","selectorAtom":".language-diff"},{"hookId":"code-language-java","selectorAtom":".language-java"},{"hookId":"code-language-javascript","selectorAtom":".language-javascript"},{"hookId":"code-language-json","selectorAtom":".language-json"},{"hookId":"code-language-jsx","selectorAtom":".language-jsx"},{"hookId":"code-language-markdown","selectorAtom":".language-markdown"},{"hookId":"code-language-markup","selectorAtom":".language-markup"},{"hookId":"code-language-python","selectorAtom":".language-python"},{"hookId":"code-language-sql","selectorAtom":".language-sql"},{"hookId":"code-language-tsx","selectorAtom":".language-tsx"},{"hookId":"code-language-typescript","selectorAtom":".language-typescript"},{"hookId":"code-language-yaml","selectorAtom":".language-yaml"},{"hookId":"code-token","selectorAtom":".token"},{"hookId":"composition-article-layout-editorial","selectorAtom":"[data-gala-article-layout=\"editorial\"]"},{"hookId":"composition-article-layout-full-bleed","selectorAtom":"[data-gala-article-layout=\"full-bleed\"]"},{"hookId":"composition-article-layout-issue","selectorAtom":"[data-gala-article-layout=\"issue\"]"},{"hookId":"composition-article-layout-prose","selectorAtom":"[data-gala-article-layout=\"prose\"]"},{"hookId":"composition-article-layout-technical","selectorAtom":"[data-gala-article-layout=\"technical\"]"},{"hookId":"composition-author-layout-biography","selectorAtom":"[data-gala-author-layout=\"biography\"]"},{"hookId":"composition-author-layout-portfolio","selectorAtom":"[data-gala-author-layout=\"portfolio\"]"},{"hookId":"composition-author-layout-portrait","selectorAtom":"[data-gala-author-layout=\"portrait\"]"},{"hookId":"composition-author-layout-profile","selectorAtom":"[data-gala-author-layout=\"profile\"]"},{"hookId":"composition-density-comfortable","selectorAtom":"[data-gala-density=\"comfortable\"]"},{"hookId":"composition-density-compact","selectorAtom":"[data-gala-density=\"compact\"]"},{"hookId":"composition-density-spacious","selectorAtom":"[data-gala-density=\"spacious\"]"},{"hookId":"composition-footer-layout-compact","selectorAtom":"[data-gala-footer-layout=\"compact\"]"},{"hookId":"composition-footer-layout-expanded","selectorAtom":"[data-gala-footer-layout=\"expanded\"]"},{"hookId":"composition-header-layout-compact","selectorAtom":"[data-gala-header-layout=\"compact\"]"},{"hookId":"composition-header-layout-masthead","selectorAtom":"[data-gala-header-layout=\"masthead\"]"},{"hookId":"composition-header-layout-minimal","selectorAtom":"[data-gala-header-layout=\"minimal\"]"},{"hookId":"composition-header-layout-publication","selectorAtom":"[data-gala-header-layout=\"publication\"]"},{"hookId":"composition-header-layout-utility","selectorAtom":"[data-gala-header-layout=\"utility\"]"},{"hookId":"composition-home-layout-chronological","selectorAtom":"[data-gala-home-layout=\"chronological\"]"},{"hookId":"composition-home-layout-gallery","selectorAtom":"[data-gala-home-layout=\"gallery\"]"},{"hookId":"composition-home-layout-magazine","selectorAtom":"[data-gala-home-layout=\"magazine\"]"},{"hookId":"composition-home-layout-newspaper","selectorAtom":"[data-gala-home-layout=\"newspaper\"]"},{"hookId":"composition-home-layout-topic-index","selectorAtom":"[data-gala-home-layout=\"topic-index\"]"},{"hookId":"composition-listing-layout-dated-rows","selectorAtom":"[data-gala-listing-layout=\"dated-rows\"]"},{"hookId":"composition-listing-layout-image-grid","selectorAtom":"[data-gala-listing-layout=\"image-grid\"]"},{"hookId":"composition-listing-layout-issues","selectorAtom":"[data-gala-listing-layout=\"issues\"]"},{"hookId":"composition-listing-layout-rows","selectorAtom":"[data-gala-listing-layout=\"rows\"]"},{"hookId":"composition-media-ratio-landscape","selectorAtom":"[data-gala-media-ratio=\"landscape\"]"},{"hookId":"composition-media-ratio-mixed","selectorAtom":"[data-gala-media-ratio=\"mixed\"]"},{"hookId":"composition-profile-developer","selectorAtom":"[data-gala-profile=\"developer\"]"},{"hookId":"composition-profile-editorial","selectorAtom":"[data-gala-profile=\"editorial\"]"},{"hookId":"composition-profile-newsletter","selectorAtom":"[data-gala-profile=\"newsletter\"]"},{"hookId":"composition-profile-personal","selectorAtom":"[data-gala-profile=\"personal\"]"},{"hookId":"composition-profile-visual","selectorAtom":"[data-gala-profile=\"visual\"]"},{"hookId":"content-article","selectorAtom":"article"},{"hookId":"control-appearance-toggle","selectorAtom":"#gala-appearance-color-mode"},{"hookId":"control-button","selectorAtom":"button"},{"hookId":"disclosure-details","selectorAtom":"details"},{"hookId":"disclosure-summary","selectorAtom":"summary"},{"hookId":"heading-1","selectorAtom":"h1"},{"hookId":"heading-2","selectorAtom":"h2"},{"hookId":"heading-3","selectorAtom":"h3"},{"hookId":"heading-4","selectorAtom":"h4"},{"hookId":"heading-5","selectorAtom":"h5"},{"hookId":"heading-6","selectorAtom":"h6"},{"hookId":"landmark-footer","selectorAtom":"footer"},{"hookId":"landmark-header","selectorAtom":"header"},{"hookId":"landmark-main","selectorAtom":"main"},{"hookId":"landmark-main-content","selectorAtom":"#main-content"},{"hookId":"landmark-navigation","selectorAtom":"nav"},{"hookId":"landmark-section","selectorAtom":"section"},{"hookId":"media-figure","selectorAtom":"figure"},{"hookId":"media-image","selectorAtom":"img"},{"hookId":"page-archive","selectorAtom":"[data-gala-page-kind=\"archive\"]"},{"hookId":"page-article","selectorAtom":"[data-gala-page-kind=\"article\"]"},{"hookId":"page-author","selectorAtom":"[data-gala-page-kind=\"author\"]"},{"hookId":"page-error","selectorAtom":"[data-gala-page-kind=\"error\"]"},{"hookId":"page-index","selectorAtom":"[data-gala-page-kind=\"index\"]"},{"hookId":"page-page","selectorAtom":"[data-gala-page-kind=\"page\"]"},{"hookId":"page-profile","selectorAtom":"[data-gala-page-kind=\"profile\"]"},{"hookId":"page-series","selectorAtom":"[data-gala-page-kind=\"series\"]"},{"hookId":"page-tag","selectorAtom":"[data-gala-page-kind=\"tag\"]"},{"hookId":"prose-blockquote","selectorAtom":"blockquote"},{"hookId":"prose-divider","selectorAtom":"hr"},{"hookId":"prose-emphasis","selectorAtom":"em"},{"hookId":"prose-link","selectorAtom":"a"},{"hookId":"prose-list-item","selectorAtom":"li"},{"hookId":"prose-list-ordered","selectorAtom":"ol"},{"hookId":"prose-list-unordered","selectorAtom":"ul"},{"hookId":"prose-paragraph","selectorAtom":"p"},{"hookId":"prose-span","selectorAtom":"span"},{"hookId":"prose-strong","selectorAtom":"strong"},{"hookId":"prose-time","selectorAtom":"time"},{"hookId":"slot-account-intent","selectorAtom":"[data-gala-slot=\"account-intent\"]"},{"hookId":"slot-article-end","selectorAtom":"[data-gala-slot=\"article-end\"]"},{"hookId":"slot-article-footer-ad","selectorAtom":"[data-gala-slot=\"article-footer-ad\"]"},{"hookId":"slot-article-preamble","selectorAtom":"[data-gala-slot=\"article-preamble\"]"},{"hookId":"slot-conversation","selectorAtom":"[data-gala-slot=\"conversation\"]"},{"hookId":"slot-edition-selector","selectorAtom":"[data-gala-slot=\"edition-selector\"]"},{"hookId":"slot-footer-auxiliary","selectorAtom":"[data-gala-slot=\"footer-auxiliary\"]"},{"hookId":"slot-footer-profile","selectorAtom":"[data-gala-slot=\"footer-profile\"]"},{"hookId":"slot-header-actions","selectorAtom":"[data-gala-slot=\"header-actions\"]"},{"hookId":"slot-newsletter","selectorAtom":"[data-gala-slot=\"newsletter\"]"},{"hookId":"ui-actions","selectorAtom":".g-actions"},{"hookId":"ui-article","selectorAtom":".g-article"},{"hookId":"ui-article-cover","selectorAtom":".g-article-cover"},{"hookId":"ui-article-cover-full-bleed","selectorAtom":".g-article-cover-full-bleed"},{"hookId":"ui-article-foot","selectorAtom":".g-article-foot"},{"hookId":"ui-article-grid","selectorAtom":".g-article-grid"},{"hookId":"ui-article-head","selectorAtom":".g-article-head"},{"hookId":"ui-article-labels","selectorAtom":".g-article-labels"},{"hookId":"ui-article-meta","selectorAtom":".g-article-meta"},{"hookId":"ui-author-bio","selectorAtom":".g-author-bio"},{"hookId":"ui-author-card","selectorAtom":".g-author-card"},{"hookId":"ui-author-name","selectorAtom":".g-author-name"},{"hookId":"ui-avatar","selectorAtom":".g-avatar"},{"hookId":"ui-badge","selectorAtom":".g-badge"},{"hookId":"ui-brand","selectorAtom":".g-brand"},{"hookId":"ui-brand-name","selectorAtom":".g-brand-name"},{"hookId":"ui-brand-tag","selectorAtom":".g-brand-tag"},{"hookId":"ui-brand-text","selectorAtom":".g-brand-text"},{"hookId":"ui-btn","selectorAtom":".g-btn"},{"hookId":"ui-byline","selectorAtom":".g-byline"},{"hookId":"ui-byline-text","selectorAtom":".g-byline-text"},{"hookId":"ui-card","selectorAtom":".g-card"},{"hookId":"ui-card-body","selectorAtom":".g-card-body"},{"hookId":"ui-card-excerpt","selectorAtom":".g-card-excerpt"},{"hookId":"ui-card-foot","selectorAtom":".g-card-foot"},{"hookId":"ui-card-link","selectorAtom":".g-card-link"},{"hookId":"ui-card-media","selectorAtom":".g-card-media"},{"hookId":"ui-card-placeholder","selectorAtom":".g-card-placeholder"},{"hookId":"ui-card-row","selectorAtom":".g-card-row"},{"hookId":"ui-card-top","selectorAtom":".g-card-top"},{"hookId":"ui-chip","selectorAtom":".g-chip"},{"hookId":"ui-codebar","selectorAtom":".g-codebar"},{"hookId":"ui-codebar-lang","selectorAtom":".g-codebar-lang"},{"hookId":"ui-codeblock","selectorAtom":".g-codeblock"},{"hookId":"ui-copy","selectorAtom":".g-copy"},{"hookId":"ui-copy-done","selectorAtom":".g-copy-done"},{"hookId":"ui-copy-idle","selectorAtom":".g-copy-idle"},{"hookId":"ui-crumbs","selectorAtom":".g-crumbs"},{"hookId":"ui-date-stamp","selectorAtom":".g-date-stamp"},{"hookId":"ui-dated-list","selectorAtom":".g-dated-list"},{"hookId":"ui-dated-row","selectorAtom":".g-dated-row"},{"hookId":"ui-dek","selectorAtom":".g-dek"},{"hookId":"ui-dot","selectorAtom":".g-dot"},{"hookId":"ui-eyebrow","selectorAtom":".g-eyebrow"},{"hookId":"ui-footer","selectorAtom":".g-footer"},{"hookId":"ui-footer-about","selectorAtom":".g-footer-about"},{"hookId":"ui-footer-base","selectorAtom":".g-footer-base"},{"hookId":"ui-footer-brand","selectorAtom":".g-footer-brand"},{"hookId":"ui-footer-col","selectorAtom":".g-footer-col"},{"hookId":"ui-footer-grid","selectorAtom":".g-footer-grid"},{"hookId":"ui-grid","selectorAtom":".g-grid"},{"hookId":"ui-header","selectorAtom":".g-header"},{"hookId":"ui-header-row","selectorAtom":".g-header-row"},{"hookId":"ui-hero","selectorAtom":".g-hero"},{"hookId":"ui-hero-body","selectorAtom":".g-hero-body"},{"hookId":"ui-hero-media","selectorAtom":".g-hero-media"},{"hookId":"ui-icon","selectorAtom":".g-icon"},{"hookId":"ui-icon-btn","selectorAtom":".g-icon-btn"},{"hookId":"ui-kbd","selectorAtom":".g-kbd"},{"hookId":"ui-label","selectorAtom":".g-label"},{"hookId":"ui-list","selectorAtom":".g-list"},{"hookId":"ui-main","selectorAtom":".g-main"},{"hookId":"ui-mark","selectorAtom":".g-mark"},{"hookId":"ui-menu","selectorAtom":".g-menu"},{"hookId":"ui-meta","selectorAtom":".g-meta"},{"hookId":"ui-mode-dark","selectorAtom":".g-mode-dark"},{"hookId":"ui-mode-icon","selectorAtom":".g-mode-icon"},{"hookId":"ui-mode-light","selectorAtom":".g-mode-light"},{"hookId":"ui-mode-system","selectorAtom":".g-mode-system"},{"hookId":"ui-more","selectorAtom":".g-more"},{"hookId":"ui-nav","selectorAtom":".g-nav"},{"hookId":"ui-newsletter","selectorAtom":".g-newsletter"},{"hookId":"ui-pager","selectorAtom":".g-pager"},{"hookId":"ui-pager-link","selectorAtom":".g-pager-link"},{"hookId":"ui-pager-next","selectorAtom":".g-pager-next"},{"hookId":"ui-pagination","selectorAtom":".g-pagination"},{"hookId":"ui-panel","selectorAtom":".g-panel"},{"hookId":"ui-panel-copy","selectorAtom":".g-panel-copy"},{"hookId":"ui-pill","selectorAtom":".g-pill"},{"hookId":"ui-pill-count","selectorAtom":".g-pill-count"},{"hookId":"ui-pills","selectorAtom":".g-pills"},{"hookId":"ui-progress","selectorAtom":".g-progress"},{"hookId":"ui-prose","selectorAtom":".g-prose"},{"hookId":"ui-search","selectorAtom":".g-search"},{"hookId":"ui-search-box","selectorAtom":".g-search-box"},{"hookId":"ui-search-btn","selectorAtom":".g-search-btn"},{"hookId":"ui-search-empty","selectorAtom":".g-search-empty"},{"hookId":"ui-search-hit","selectorAtom":".g-search-hit"},{"hookId":"ui-search-hit-meta","selectorAtom":".g-search-hit-meta"},{"hookId":"ui-search-hit-text","selectorAtom":".g-search-hit-text"},{"hookId":"ui-search-hit-title","selectorAtom":".g-search-hit-title"},{"hookId":"ui-search-input","selectorAtom":".g-search-input"},{"hookId":"ui-search-results","selectorAtom":".g-search-results"},{"hookId":"ui-section","selectorAtom":".g-section"},{"hookId":"ui-section-head","selectorAtom":".g-section-head"},{"hookId":"ui-series-box","selectorAtom":".g-series-box"},{"hookId":"ui-series-card","selectorAtom":".g-series-card"},{"hookId":"ui-series-here","selectorAtom":".g-series-here"},{"hookId":"ui-series-list","selectorAtom":".g-series-list"},{"hookId":"ui-series-n","selectorAtom":".g-series-n"},{"hookId":"ui-series-tag","selectorAtom":".g-series-tag"},{"hookId":"ui-share","selectorAtom":".g-share"},{"hookId":"ui-skip","selectorAtom":".g-skip"},{"hookId":"ui-social","selectorAtom":".g-social"},{"hookId":"ui-sr","selectorAtom":".g-sr"},{"hookId":"ui-tag","selectorAtom":".g-tag"},{"hookId":"ui-tags","selectorAtom":".g-tags"},{"hookId":"ui-toast","selectorAtom":".g-toast"},{"hookId":"ui-toc","selectorAtom":".g-toc"},{"hookId":"ui-toc-list","selectorAtom":".g-toc-list"},{"hookId":"ui-toc-mobile","selectorAtom":".g-toc-mobile"},{"hookId":"ui-topic-head","selectorAtom":".g-topic-head"},{"hookId":"ui-topic-hero","selectorAtom":".g-topic-hero"},{"hookId":"ui-topic-icon","selectorAtom":".g-topic-icon"},{"hookId":"ui-topic-strip","selectorAtom":".g-topic-strip"},{"hookId":"ui-wrap","selectorAtom":".g-wrap"}],"publicationRootSelector":"[data-gala-publication-root]","resolvedPaletteSelectors":{"dark":"[data-gala-publication-root][data-gala-resolved-color-mode=\"dark\"]","light":"[data-gala-publication-root][data-gala-resolved-color-mode=\"light\"]"},"stylesheetLayers":{"components":"gala-components","print":"gala-print","tokens":"gala-tokens","utilities":"gala-utilities"},"templatePackage":"@rathnasgala2/template","templateVersion":"4.0.0","typeSelectors":["a","article","blockquote","button","code","details","em","figure","footer","h1","h2","h3","h4","h5","h6","header","hr","img","li","main","nav","ol","p","pre","section","span","strong","summary","time","ul"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rathnasgala2/template",
3
- "version": "3.2.0",
3
+ "version": "4.0.0",
4
4
  "description": "Deterministic Eleventy-backed static publication renderer for Galascribe portable repositories.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -72,11 +72,13 @@
72
72
  "dependencies": {
73
73
  "@11ty/eleventy": "3.1.6",
74
74
  "@11ty/eleventy-plugin-syntaxhighlight": "5.0.2",
75
- "@rathnasgala2/schemas": "3.3.0",
76
75
  "jpeg-js": "0.4.4",
77
76
  "markdown-it": "14.3.1",
78
77
  "sanitize-html": "2.17.7"
79
78
  },
79
+ "peerDependencies": {
80
+ "@rathnasgala2/schemas": "3.8.0"
81
+ },
80
82
  "devDependencies": {
81
83
  "@cyclonedx/cyclonedx-npm": "6.0.1",
82
84
  "@eslint/js": "10.0.1",
package/src/core/index.js CHANGED
@@ -139,6 +139,7 @@ import {
139
139
  defaultThemeStylesheetLinksHtml,
140
140
  loadThemeAssets,
141
141
  } from './internal/theme-assets.js';
142
+ import { EDITORIAL_COMPOSITION } from './internal/template-composition.js';
142
143
  import { resolveTextDirection } from './internal/text-direction.js';
143
144
  import {
144
145
  escapeHtml,
@@ -189,7 +190,7 @@ export const TEMPLATE_PACKAGE_NAME = '@rathnasgala2/template';
189
190
  *
190
191
  * @type {string}
191
192
  */
192
- export const TEMPLATE_PACKAGE_VERSION = '2.1.0';
193
+ export const TEMPLATE_PACKAGE_VERSION = '4.0.0';
193
194
 
194
195
  /**
195
196
  * Validate the caller-supplied render options, independent of build-input
@@ -391,6 +392,22 @@ export async function renderPublication(buildInput, options) {
391
392
  const urlPrefix = derivePublicBasePath(validatedInput.baseUrl, '/');
392
393
  const homeRoute = joinPublicRoute(publicBasePath, '/');
393
394
 
395
+ // Admit the selected generation-4 theme and its complete structural
396
+ // composition before any output directory is created. Theme-less calls
397
+ // use the renderer's Editorial composition and the conventional print
398
+ // stylesheet link; a supplied theme never receives that fallback.
399
+ const themeAssetsResult = options.themeDirectory
400
+ ? await loadThemeAssets({
401
+ themeDirectory: path.resolve(options.themeDirectory),
402
+ basePath: validatedInput.basePath,
403
+ publicBasePath,
404
+ })
405
+ : undefined;
406
+ const themeStylesheetLinksHtml = themeAssetsResult
407
+ ? themeAssetsResult.linkTagsHtml
408
+ : defaultThemeStylesheetLinksHtml(publicBasePath);
409
+ const composition = themeAssetsResult?.composition ?? EDITORIAL_COMPOSITION;
410
+
394
411
  const appearanceControlHtml = renderAppearanceControl({
395
412
  messages: siteMessages,
396
413
  });
@@ -495,6 +512,8 @@ export async function renderPublication(buildInput, options) {
495
512
  showAttribution:
496
513
  validatedInput.appearance.attribution?.showMadeWith !== false,
497
514
  messages: siteMessages,
515
+ profile: composition.profile,
516
+ footerLayout: composition.footerLayout,
498
517
  });
499
518
 
500
519
  /**
@@ -522,6 +541,8 @@ export async function renderPublication(buildInput, options) {
522
541
  searchIndexHref,
523
542
  appearanceControlHtml,
524
543
  messages: siteMessages,
544
+ profile: composition.profile,
545
+ headerLayout: composition.headerLayout,
525
546
  });
526
547
 
527
548
  // The site-wide feeds, resolved once so every page's feed-discovery
@@ -540,22 +561,6 @@ export async function renderPublication(buildInput, options) {
540
561
  `/${GALA_BASE_STYLESHEET_PATH}`,
541
562
  );
542
563
 
543
- // The selected theme package's copied stylesheets/passive assets and the
544
- // ordered `<link>` markup every generated page's `<head>` inserts.
545
- // Run before page assembly (same reasoning as the media pipeline above):
546
- // every page's `data.themeStylesheetLinksHtml` needs the same one
547
- // already-rendered fragment.
548
- const themeAssetsResult = options.themeDirectory
549
- ? await loadThemeAssets({
550
- themeDirectory: path.resolve(options.themeDirectory),
551
- basePath: validatedInput.basePath,
552
- publicBasePath,
553
- })
554
- : undefined;
555
- const themeStylesheetLinksHtml = themeAssetsResult
556
- ? themeAssetsResult.linkTagsHtml
557
- : defaultThemeStylesheetLinksHtml(publicBasePath);
558
-
559
564
  /** @type {{virtualPath: string, content: string, permalink: string, layout?: string, data?: Record<string, unknown>}[]} */
560
565
  const contentPages = [];
561
566
  /** @type {{joinedSource: string, joinedTarget: string, publicTarget: string, filePath: string}[]} */
@@ -567,6 +572,7 @@ export async function renderPublication(buildInput, options) {
567
572
  mediaAssets,
568
573
  mediaDimensions,
569
574
  interactions: interactionsOn ? interactionsModule : undefined,
575
+ composition,
570
576
  });
571
577
  /** @type {Set<string>} output paths of the interaction-bearing routes */
572
578
  const interactionBearingPaths = new Set();
@@ -629,6 +635,7 @@ export async function renderPublication(buildInput, options) {
629
635
  cspMetaTag,
630
636
  baseStylesheetHref: baseStylesheetHrefValue,
631
637
  themeStylesheetLinksHtml,
638
+ composition,
632
639
  },
633
640
  });
634
641
  });
@@ -701,6 +708,7 @@ export async function renderPublication(buildInput, options) {
701
708
  cspMetaTag,
702
709
  baseStylesheetHref: baseStylesheetHrefValue,
703
710
  themeStylesheetLinksHtml,
711
+ composition,
704
712
  },
705
713
  });
706
714
 
@@ -259,7 +259,7 @@ export const GALA_BASE_COMPONENT_CSS = `
259
259
  outline-offset: 3px;
260
260
  }
261
261
  [data-gala-publication-root] img { display: block; max-width: 100%; height: auto; }
262
- [data-gala-publication-root] a { color: inherit; text-decoration: none; }
262
+ [data-gala-publication-root] :where(a) { color: inherit; text-decoration: none; }
263
263
  [data-gala-publication-root] h1, [data-gala-publication-root] h2, [data-gala-publication-root] h3, [data-gala-publication-root] p { margin: 0; }
264
264
  [data-gala-publication-root] button { font: inherit; color: inherit; }
265
265
  [data-gala-publication-root] ul, [data-gala-publication-root] ol { margin: 0; padding: 0; list-style: none; }
@@ -483,6 +483,12 @@ export const GALA_BASE_COMPONENT_CSS = `
483
483
  .g-card-row .g-card-media, .g-card-row .g-card-placeholder { aspect-ratio: 16 / 9; height: 100%; border-bottom: 0; border-right: var(--gala-border-media-divider); }
484
484
  .g-card-row .g-card-body { padding: clamp(1rem, 2.5vw, 1.75rem); }
485
485
  .g-card-row h2, .g-card-row h3 { font-size: clamp(1.3rem, 1rem + 1vw, 1.75rem); }
486
+ .g-dated-list { gap: 0; }
487
+ .g-dated-row { display: grid; grid-template-columns: minmax(8rem, 1fr) minmax(0, 5fr); gap: clamp(1rem, 3vw, 2rem); align-items: start; padding-block: var(--gala-space-4); border-top: var(--gala-border-row-divider); }
488
+ .g-date-stamp { padding-top: var(--gala-space-3); color: var(--gala-color-text-muted); font-family: var(--gala-font-ui); font-size: .8125rem; font-variant-numeric: tabular-nums; }
489
+ .g-dated-row .g-card-row { grid-template-columns: minmax(0, 1fr); padding: 0; border-bottom: 0; box-shadow: none; }
490
+ .g-dated-row .g-card-row .g-card-media, .g-dated-row .g-card-row .g-card-placeholder { display: none; }
491
+ .g-dated-row .g-card-foot .g-meta > time:first-child, .g-dated-row .g-card-foot .g-meta > time:first-child + .g-dot { display: none; }
486
492
 
487
493
  /* ---------- series ---------- */
488
494
  .g-series-card {
@@ -527,6 +533,12 @@ export const GALA_BASE_COMPONENT_CSS = `
527
533
  [data-gala-slot="edition-selector"] { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gala-space-2); min-width: 0; max-width: 100%; }
528
534
  .g-article-cover { margin-block: 0; }
529
535
  .g-article-cover img { width: 100%; height: auto; aspect-ratio: 21 / 9; object-fit: cover; border-radius: var(--gala-radius-large); border: var(--gala-border-card); box-shadow: var(--gala-shadow-card); filter: var(--gala-media-filter); }
536
+ .g-article-cover-full-bleed { width: 100%; max-width: none; margin: 0; padding-inline: 0; }
537
+ .g-article-cover-full-bleed img { aspect-ratio: 16 / 9; border-inline: 0; border-radius: 0; }
538
+ [data-gala-media-ratio="mixed"] .g-hero-media { aspect-ratio: 3 / 2; }
539
+ [data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n + 1) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 4 / 5; }
540
+ [data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n + 2) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 3 / 2; }
541
+ [data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 1; }
530
542
  .g-article-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--gala-content-measure)) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); padding-block: clamp(2rem, 5vw, 3.5rem) var(--gala-space-4); }
531
543
  .g-article-grid > .g-prose { grid-column: 2; }
532
544
  .g-toc { position: sticky; top: 6rem; align-self: start; justify-self: end; width: min(100%, 15rem); display: grid; gap: var(--gala-space-3); }
@@ -671,7 +683,6 @@ export const GALA_BASE_COMPONENT_CSS = `
671
683
  }
672
684
  .g-reaction:hover:not(:disabled) { border-color: var(--gala-color-text); color: var(--gala-color-text); }
673
685
  .g-reaction:active:not(:disabled) { transform: scale(.96); }
674
- .g-reaction:disabled { opacity: .55; cursor: default; }
675
686
  .g-reaction__icon { display: inline-grid; place-items: center; font-size: 1.1rem; line-height: 1; }
676
687
  .g-reaction__icon .g-icon { width: 1.15rem; height: 1.15rem; }
677
688
  .g-reaction__label { overflow-wrap: anywhere; }
@@ -706,12 +717,41 @@ export const GALA_BASE_COMPONENT_CSS = `
706
717
  }
707
718
  .g-composer__submit:hover:not(:disabled), .g-composer__signin:hover, .g-report button[type="submit"]:hover { filter: brightness(1.07) saturate(1.05); }
708
719
  .g-composer__submit:active:not(:disabled), .g-composer__signin:active { transform: scale(.97); }
709
- .g-composer__submit:disabled { opacity: .55; cursor: default; box-shadow: none; }
710
720
  .g-composer__cancel, .g-report button[type="button"] {
711
721
  min-height: 2.75rem; padding: .6rem 1rem; border-radius: var(--gala-radius-pill); border: var(--gala-border-width) solid var(--gala-color-border); background: transparent; color: var(--gala-color-text);
712
722
  font-family: var(--gala-font-ui); font-weight: var(--gala-weight-ui); font-size: .9rem; cursor: pointer;
713
723
  }
714
724
  .g-composer__cancel:hover, .g-report button[type="button"]:hover { border-color: var(--gala-color-text); }
725
+ /* Interaction-button states. Enabled: full-strength tokens and a pointer.
726
+ Disabled (native or aria-disabled): muted surface and border tokens,
727
+ faint text, reduced opacity, a dashed border and not-allowed. Working
728
+ (aria-busy): enabled colours, a progress cursor and a spinner, never the
729
+ muted look. Themes may tint these tokens, never remove the rule. */
730
+ .g-reaction:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
731
+ .g-comments__more:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
732
+ .g-composer__cancel:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
733
+ .g-report button[type="button"]:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
734
+ .g-comment__action:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
735
+ .g-composer__submit:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
736
+ .g-composer__signin:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]),
737
+ .g-report button[type="submit"]:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]) {
738
+ background: var(--gala-color-surface-raised); background-image: none; color: var(--gala-color-text-faint);
739
+ border: var(--gala-border-width) dashed var(--gala-color-border); box-shadow: none; filter: none; transform: none;
740
+ opacity: .6; cursor: not-allowed;
741
+ }
742
+ .g-interactions__signout:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]) { color: var(--gala-color-text-faint); text-decoration-style: dashed; opacity: .6; cursor: not-allowed; }
743
+ .g-reaction[aria-busy="true"], .g-comments__more[aria-busy="true"], .g-composer__cancel[aria-busy="true"], .g-comment__action[aria-busy="true"],
744
+ .g-composer__submit[aria-busy="true"], .g-composer__signin[aria-busy="true"], .g-report button[aria-busy="true"] { cursor: progress; }
745
+ .g-reaction[aria-busy="true"]::after, .g-comments__more[aria-busy="true"]::after, .g-comment__action[aria-busy="true"]::after,
746
+ .g-composer__submit[aria-busy="true"]::after, .g-report button[aria-busy="true"]::after {
747
+ content: ""; display: inline-block; flex: none; width: .9em; height: .9em; margin-left: .5em; border-radius: 50%;
748
+ border: 2px solid currentColor; border-right-color: transparent; vertical-align: -.1em; animation: g-busy-spin .8s linear infinite;
749
+ }
750
+ @keyframes g-busy-spin { to { transform: rotate(360deg); } }
751
+ @media (prefers-reduced-motion: reduce) {
752
+ .g-reaction[aria-busy="true"]::after, .g-comments__more[aria-busy="true"]::after, .g-comment__action[aria-busy="true"]::after,
753
+ .g-composer__submit[aria-busy="true"]::after, .g-report button[aria-busy="true"]::after { animation: none; border-right-color: currentColor; border-style: dotted; }
754
+ }
715
755
  .g-comment-list { display: grid; gap: var(--gala-space-4); min-width: 0; }
716
756
  .g-comment { display: grid; gap: var(--gala-space-2); min-width: 0; }
717
757
  .g-comment__head { display: flex; align-items: center; gap: var(--gala-space-3); min-width: 0; }
@@ -782,6 +822,8 @@ export const GALA_BASE_COMPONENT_CSS = `
782
822
  .g-grid { grid-template-columns: minmax(0, 1fr); }
783
823
  .g-card-row { grid-template-columns: minmax(0, 1fr); }
784
824
  .g-card-row .g-card-media, .g-card-row .g-card-placeholder { border-right: 0; border-bottom: var(--gala-border-media-divider); height: auto; }
825
+ .g-dated-row { grid-template-columns: minmax(0, 1fr); gap: var(--gala-space-2); }
826
+ .g-date-stamp { padding-top: 0; }
785
827
  .g-pager { grid-template-columns: minmax(0, 1fr); }
786
828
  .g-pager-next { grid-column: 1; }
787
829
  .g-article-cover img { aspect-ratio: 16 / 10; }
@@ -804,7 +846,7 @@ export const GALA_BASE_COMPONENT_CSS = `
804
846
  @keyframes g-read { from { transform: scaleX(0); } to { transform: scaleX(1); } }
805
847
  }
806
848
  @supports (animation-timeline: view()) {
807
- .g-grid > .g-card, .g-list > .g-card, .g-panel, .g-series-card, .g-author-card, .g-series-box, .g-prose > pre, .g-codeblock, .g-prose > figure, .g-prose > blockquote {
849
+ .g-grid > .g-card, .g-list > .g-card, .g-dated-row, .g-panel, .g-series-card, .g-author-card, .g-series-box, .g-prose > pre, .g-codeblock, .g-prose > figure, .g-prose > blockquote {
808
850
  animation: g-reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 55%;
809
851
  }
810
852
  @keyframes g-reveal { from { opacity: .15; transform: translateY(28px) scale(.985); } }
@@ -74,15 +74,19 @@ import {
74
74
  APPEARANCE_TOGGLE_ID,
75
75
  } from './contract.js';
76
76
  import { PAGE_KIND_ATTRIBUTE, PAGE_KIND_VALUES } from '../page-kinds.js';
77
+ import {
78
+ COMPOSITION_ATTRIBUTES,
79
+ COMPOSITION_ATTRIBUTE_CATALOG,
80
+ } from '../template-composition.js';
77
81
  import { SLOT_NAMES } from '../skeleton.js';
78
82
  import { canonicalizeJcs, domainDigest } from '../canonical-jcs.js';
79
83
 
80
84
  /** @type {string} */
81
85
  export const TEMPLATE_STYLING_CONTRACT_PACKAGE = '@rathnasgala2/template';
82
86
  /** @type {string} */
83
- export const TEMPLATE_STYLING_CONTRACT_VERSION = '3.0.0';
87
+ export const TEMPLATE_STYLING_CONTRACT_VERSION = '4.0.0';
84
88
  /** @type {string} */
85
- export const TEMPLATE_STYLING_CONTRACT_TEMPLATE_VERSION = '3.0.0';
89
+ export const TEMPLATE_STYLING_CONTRACT_TEMPLATE_VERSION = '4.0.0';
86
90
 
87
91
  /** @type {string} the `main-content` landmark's fixed `id`. */
88
92
  const MAIN_CONTENT_ID = 'main-content';
@@ -278,6 +282,9 @@ export const COMPONENT_CLASS_GROUPS = Object.freeze({
278
282
  'g-section-head',
279
283
  'g-grid',
280
284
  'g-list',
285
+ 'g-dated-list',
286
+ 'g-dated-row',
287
+ 'g-date-stamp',
281
288
  'g-pills',
282
289
  'g-pill',
283
290
  'g-pill-count',
@@ -343,6 +350,7 @@ export const COMPONENT_CLASS_GROUPS = Object.freeze({
343
350
  'g-article-meta',
344
351
  'g-share',
345
352
  'g-article-cover',
353
+ 'g-article-cover-full-bleed',
346
354
  'g-article-grid',
347
355
  'g-toc',
348
356
  'g-toc-list',
@@ -468,6 +476,13 @@ const ATTRIBUTE_VALUE_HOOKS = Object.freeze([
468
476
  kind: /** @type {const} */ ('attribute'),
469
477
  }),
470
478
  ),
479
+ ...COMPOSITION_ATTRIBUTES.map(({ field, name, value }) =>
480
+ Object.freeze({
481
+ hookId: `composition-${field.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-${value}`,
482
+ selectorAtom: `[${name}="${value}"]`,
483
+ kind: /** @type {const} */ ('attribute'),
484
+ }),
485
+ ),
471
486
  ]);
472
487
 
473
488
  /** @type {readonly StyleHookDefinition[]} every public hook, unsorted. */
@@ -524,6 +539,12 @@ export function buildTemplateStylingContract() {
524
539
  values: sortedUniqueBytes(PAGE_KIND_VALUES),
525
540
  role: 'semantic',
526
541
  },
542
+ ...COMPOSITION_ATTRIBUTE_CATALOG.map(({ name, values }) => ({
543
+ name,
544
+ match: 'exact-value',
545
+ values: sortedUniqueBytes(values),
546
+ role: 'semantic',
547
+ })),
527
548
  ].sort((a, b) => {
528
549
  const bufferA = Buffer.from(canonicalizeJcs(a), 'utf8');
529
550
  const bufferB = Buffer.from(canonicalizeJcs(b), 'utf8');
@@ -648,7 +669,7 @@ export function assertTemplateStylingContractShape(contract) {
648
669
  if (contract.profile !== 'gala-template-styling-contract-v2') {
649
670
  fail('profile');
650
671
  }
651
- if (contract.contractVersion !== '3.0.0') fail('contractVersion');
672
+ if (contract.contractVersion !== '4.0.0') fail('contractVersion');
652
673
  if (contract.templatePackage !== '@rathnasgala2/template') {
653
674
  fail('templatePackage');
654
675
  }
@@ -52,6 +52,8 @@ function renderMark(name, mark) {
52
52
  * @param {string} [options.appearanceControlHtml] the already-rendered
53
53
  * appearance control, inserted into the `header-actions` slot
54
54
  * @param {Readonly<Record<string, string | ((...args: string[]) => string)>>} options.messages
55
+ * @param {string} options.profile the admitted composition profile
56
+ * @param {string} options.headerLayout the admitted composition's header layout
55
57
  * @returns {string} the rendered header
56
58
  */
57
59
  export function renderHeader({
@@ -66,6 +68,8 @@ export function renderHeader({
66
68
  searchIndexHref,
67
69
  appearanceControlHtml,
68
70
  messages,
71
+ profile,
72
+ headerLayout,
69
73
  }) {
70
74
  const label = (/** @type {string} */ key) =>
71
75
  escapeHtml(/** @type {string} */ (messages[key]));
@@ -74,19 +78,28 @@ export function renderHeader({
74
78
  ? `<details class="g-menu"><summary>${icon('menu')}<span class="g-sr">${label('menuSummaryLabel')}</span></summary>` +
75
79
  `<ul>${navItems.map((item) => renderNavItem(item, currentRoute, urlPrefix)).join('')}</ul></details>`
76
80
  : '';
77
- return (
78
- `<header class="g-header"><div class="g-wrap g-header-row">` +
81
+ const brand =
79
82
  `<a class="g-brand" href="${escapeHtml(homeRoute)}">${renderMark(publicationName, brandMark)}` +
80
83
  `<span class="g-brand-text"><span class="g-brand-name">${escapeHtml(publicationName)}</span>` +
81
- `<span class="g-brand-tag">${escapeHtml(tagline)}</span></span></a>` +
82
- navHtml +
84
+ `<span class="g-brand-tag">${escapeHtml(tagline)}</span></span></a>`;
85
+ const actions =
83
86
  `<div class="g-actions">` +
84
87
  `<button class="g-search-btn" type="button" hidden data-action="search" data-search-index="${escapeHtml(searchIndexHref)}" aria-label="${label('searchButtonAriaLabel')}">` +
85
88
  `${icon('search')}<span>${label('searchButtonLabel')}</span></button>` +
86
89
  renderSlot('header-actions', { html: appearanceControlHtml }) +
87
90
  menu +
88
- `</div></div></header>`
89
- );
91
+ `</div>`;
92
+ const content =
93
+ profile === 'newsletter'
94
+ ? actions + brand + navHtml
95
+ : profile === 'visual'
96
+ ? brand + actions + navHtml
97
+ : profile === 'personal'
98
+ ? navHtml + brand + actions
99
+ : profile === 'developer'
100
+ ? navHtml + actions + brand
101
+ : brand + navHtml + actions;
102
+ return `<header class="g-header" data-gala-header-layout="${escapeHtml(headerLayout)}"><div class="g-wrap g-header-row">${content}</div></header>`;
90
103
  }
91
104
 
92
105
  /**
@@ -146,6 +159,8 @@ function renderSocialLinks(socialLinks, rssHref, messages) {
146
159
  * attribution line renders: the build input's
147
160
  * `appearance.attribution.showMadeWith`, shown when absent
148
161
  * @param {Readonly<Record<string, string | ((...args: string[]) => string)>>} options.messages
162
+ * @param {string} options.profile the admitted composition profile
163
+ * @param {string} options.footerLayout the admitted composition's footer layout
149
164
  * @returns {string} the rendered footer
150
165
  */
151
166
  export function renderFooter({
@@ -163,6 +178,8 @@ export function renderFooter({
163
178
  copyrightText,
164
179
  showAttribution,
165
180
  messages,
181
+ profile,
182
+ footerLayout,
166
183
  }) {
167
184
  const label = (/** @type {string} */ key) =>
168
185
  escapeHtml(/** @type {string} */ (messages[key]));
@@ -176,20 +193,31 @@ export function renderFooter({
176
193
  ? ''
177
194
  : `<nav class="g-footer-col" aria-label="${label(labelKey)}"><p class="g-label">${label(labelKey)}</p>` +
178
195
  `<ul>${items.map((item) => renderNavItem(item, undefined, urlPrefix)).join('')}</ul></nav>`;
179
- return (
180
- `<footer class="g-footer"><div class="g-wrap g-footer-grid">` +
196
+ const brand =
181
197
  `<div class="g-footer-brand">` +
182
198
  `<a class="g-brand" href="${escapeHtml(homeRoute)}">${renderMark(publicationName, brandMark)}` +
183
199
  `<span class="g-brand-name">${escapeHtml(publicationName)}</span></a>` +
184
200
  `<p class="g-footer-about">${escapeHtml(description)}</p>` +
185
201
  renderSocialLinks(socialLinks, rssHref, messages) +
186
- `</div>` +
187
- column('exploreColumnLabel', primaryItems) +
188
- column('footerNavigationLabel', footerItems) +
202
+ `</div>`;
203
+ const primary = column('exploreColumnLabel', primaryItems);
204
+ const secondary = column('footerNavigationLabel', footerItems);
205
+ const profileCard =
189
206
  `<div class="g-footer-col">` +
190
207
  renderSlot('footer-profile', { html: authorHtml + footerProfileHtml }) +
191
- `</div>` +
192
- `</div>` +
208
+ `</div>`;
209
+ const grid =
210
+ profile === 'newsletter'
211
+ ? brand + profileCard + primary + secondary
212
+ : profile === 'visual'
213
+ ? brand + primary + profileCard + secondary
214
+ : profile === 'personal'
215
+ ? profileCard + brand + primary + secondary
216
+ : profile === 'developer'
217
+ ? primary + secondary + brand + profileCard
218
+ : brand + primary + secondary + profileCard;
219
+ return (
220
+ `<footer class="g-footer" data-gala-footer-layout="${escapeHtml(footerLayout)}"><div class="g-wrap g-footer-grid">${grid}</div>` +
193
221
  renderSlot('footer-auxiliary') +
194
222
  renderSlot('account-intent') +
195
223
  renderSlot('conversation') +
@@ -172,7 +172,7 @@ const SKELETON_LAYOUT_SOURCE = [
172
172
  '<link rel="stylesheet" href="{{ baseStylesheetHref }}">',
173
173
  '{{ themeStylesheetLinksHtml | safe }}',
174
174
  '</head>',
175
- `<body ${PAGE_KIND_ATTRIBUTE}="{{ pageKind }}">`,
175
+ `<body ${PAGE_KIND_ATTRIBUTE}="{{ pageKind }}" data-gala-profile="{{ composition.profile }}" data-gala-home-layout="{{ composition.homeLayout }}" data-gala-article-layout="{{ composition.articleLayout }}" data-gala-author-layout="{{ composition.authorLayout }}" data-gala-listing-layout="{{ composition.listingLayout }}" data-gala-header-layout="{{ composition.headerLayout }}" data-gala-footer-layout="{{ composition.footerLayout }}" data-gala-media-ratio="{{ composition.mediaRatio }}" data-gala-density="{{ composition.density }}">`,
176
176
  '{{ content | safe }}',
177
177
  '</body>',
178
178
  '</html>',