import Elementary import Foundation import Infrastructure import Localization /// The site-wide defaults shared by every page of the website. extension Page { // MARK: Constants /// The fonts preloaded on every page: one per face the stylesheets actually render. /// /// Listed rather than derived from every WOFF2 in ``StaticFile/all``: a subset gated by a `unicode-range` no page reaches would add a /// download that never otherwise happens. Empty until the site ships fonts of its own. static var preloadedFonts: [StaticFile] { [] } // MARK: Computed /// The document language, derived from the page's locale and falling back to the default language. var lang: String { locale.language.languageCode?.identifier ?? LanguageList().default } /// The site-wide head metadata; a page that adds tags of its own composes ``siteMetadata`` rather than replacing it. var metadata: some HTML { siteMetadata } /// The ``preloadedFonts`` links, then the icon, manifest, and theme colour metadata shared by every page of the website. /// /// A preload URL must match the stylesheet's `@font-face` source exactly — unversioned, with `crossorigin` — or the browser fetches the /// font twice. @HTMLBuilder var siteMetadata: some HTML { for file in Self.preloadedFonts { link( .rel("preload"), .href(file.urlPath(for: .woff2)), .as(.font), .custom( name: "type", value: AssetExtension.woff2.contentType ), .crossorigin(.anonymous) ) } link( .rel(.icon), .href(StaticFile.favicon.urlPath( for: .ico, version: assetVersion )), .custom( name: "sizes", value: "any" ) ) link( .rel(.icon), .href(StaticFile.icon.urlPath( for: .svg, version: assetVersion )), .custom( name: "type", value: "image/svg+xml" ) ) link( .rel("apple-touch-icon"), .href(StaticFile.appleTouchIcon.urlPath( for: .png, version: assetVersion )) ) link( .rel("manifest"), .href(StaticFile.site.urlPath( for: .webmanifest, version: assetVersion )) ) meta( .name("theme-color"), .content("#fafafa") ) meta( .name("theme-color"), .content("#0c0710"), .custom( name: "media", value: "(prefers-color-scheme: dark)" ) ) } }