@master/internal-site 0.1.1 → 0.1.3

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 (187) hide show
  1. package/README.md +17 -0
  2. package/dist/astro.mjs +145 -10
  3. package/package.json +1 -1
  4. package/src/astro/index.ts +2 -0
  5. package/src/astro/routes.template.ts +1 -0
  6. package/src/astro/style-assets.ts +107 -0
  7. package/src/benchmarks/BenchmarkBarRows.astro +3 -2
  8. package/src/benchmarks/BenchmarkBars.astro +1 -1
  9. package/src/benchmarks/BenchmarkChart.astro +1 -0
  10. package/src/benchmarks/BenchmarkChartGroup.astro +1 -1
  11. package/src/benchmarks/BenchmarkDataTable.astro +1 -1
  12. package/src/benchmarks/BenchmarkFigure.astro +2 -1
  13. package/src/benchmarks/BenchmarkMetricTable.astro +1 -1
  14. package/src/benchmarks/BenchmarkMetrics.astro +1 -1
  15. package/src/benchmarks/BenchmarkSampleSummary.astro +1 -1
  16. package/src/benchmarks/BenchmarkScrollRegion.svelte +2 -1
  17. package/src/benchmarks/BenchmarkSource.astro +1 -1
  18. package/src/benchmarks/BenchmarkStackedBars.astro +2 -1
  19. package/src/benchmarks/types.ts +2 -0
  20. package/src/blog/article/BlogArticleContents.svelte +1 -1
  21. package/src/blog/article/BlogArticleMasthead.astro +12 -1
  22. package/src/css/NamespaceUtilityTable.astro +1 -1
  23. package/src/css/ThemeNumberVariableTable.astro +1 -1
  24. package/src/css/markdown.ts +14 -5
  25. package/src/demo/Demo.svelte +4 -0
  26. package/src/demo/DemoAsset.astro +1 -0
  27. package/src/demo/DemoCatalog.astro +1 -0
  28. package/src/demo/DemoComparison.svelte +3 -0
  29. package/src/demo/DemoContainer.svelte +3 -0
  30. package/src/demo/DemoControls.svelte +2 -0
  31. package/src/demo/DemoCopyButton.svelte +3 -0
  32. package/src/demo/DemoCopyGroup.svelte +2 -0
  33. package/src/demo/DemoFeatureSupport.svelte +2 -0
  34. package/src/demo/DemoGeneratedCSS.svelte +2 -0
  35. package/src/demo/DemoIndex.astro +1 -0
  36. package/src/demo/DemoMotion.svelte +1 -0
  37. package/src/demo/DemoScrollArea.svelte +2 -0
  38. package/src/demo/DemoStyleComparison.astro +1 -0
  39. package/src/demo/DemoSurface.svelte +2 -0
  40. package/src/demo/DemoThemeComparison.astro +1 -0
  41. package/src/demo/DemoTokenTable.astro +1 -1
  42. package/src/demo/DemoViewport.svelte +5 -0
  43. package/src/demo/DemoWaterfall.astro +1 -1
  44. package/src/demo/foundations/FoundationDialog.astro +1 -0
  45. package/src/demo/foundations/FoundationMedia.astro +1 -0
  46. package/src/demo/foundations/FoundationShrink.astro +1 -0
  47. package/src/demo/foundations/Palette.svelte +2 -0
  48. package/src/demo/illustration-materials.ts +1 -1
  49. package/src/demo/illustration.css +218 -0
  50. package/src/docs-shell/components/ArticleHeader.astro +2 -0
  51. package/src/docs-shell/components/Callout.astro +1 -0
  52. package/src/docs-shell/components/CodeCopyButton.astro +2 -0
  53. package/src/docs-shell/components/CodeTabBar.astro +2 -0
  54. package/src/docs-shell/components/CodeTabs.astro +2 -1
  55. package/src/docs-shell/components/CodeView.astro +1 -1
  56. package/src/docs-shell/components/DocHeader.svelte +10 -13
  57. package/src/docs-shell/components/DocMenuButton.svelte +126 -60
  58. package/src/docs-shell/components/DocSidebar.svelte +2 -0
  59. package/src/docs-shell/components/DocVersionSelect.svelte +2 -0
  60. package/src/docs-shell/components/DocumentAPIIndex.astro +1 -1
  61. package/src/docs-shell/components/DocumentChoices.astro +1 -1
  62. package/src/docs-shell/components/DocumentCodeExampleView.astro +3 -1
  63. package/src/docs-shell/components/DocumentCodeTable.astro +1 -1
  64. package/src/docs-shell/components/DocumentCopyButton.svelte +3 -0
  65. package/src/docs-shell/components/DocumentDisclosure.astro +2 -0
  66. package/src/docs-shell/components/DocumentFileTree.astro +3 -0
  67. package/src/docs-shell/components/DocumentFlow.astro +4 -1
  68. package/src/docs-shell/components/DocumentIllustration.astro +5 -11
  69. package/src/docs-shell/components/DocumentKeyList.astro +1 -1
  70. package/src/docs-shell/components/DocumentNamespaceTable.astro +1 -1
  71. package/src/docs-shell/components/DocumentOptionEntry.astro +0 -1
  72. package/src/docs-shell/components/DocumentOptionList.astro +1 -1
  73. package/src/docs-shell/components/DocumentOptions.astro +0 -1
  74. package/src/docs-shell/components/DocumentParameters.astro +1 -1
  75. package/src/docs-shell/components/DocumentPrompt.astro +2 -0
  76. package/src/docs-shell/components/DocumentValueList.astro +1 -1
  77. package/src/docs-shell/components/DocumentationIndex.svelte +2 -0
  78. package/src/docs-shell/components/ExpandContent.svelte +3 -0
  79. package/src/docs-shell/components/ExplorerView.astro +1 -0
  80. package/src/docs-shell/components/Footer.svelte +2 -2
  81. package/src/docs-shell/components/FooterLink.svelte +17 -0
  82. package/src/docs-shell/components/GeneratedCSS.astro +1 -0
  83. package/src/docs-shell/components/Header.svelte +1 -1
  84. package/src/docs-shell/components/InlineCode.astro +1 -0
  85. package/src/docs-shell/components/InteractingIndicator.astro +1 -0
  86. package/src/docs-shell/components/LanguageButton.svelte +1 -0
  87. package/src/docs-shell/components/LanguageSelect.svelte +2 -0
  88. package/src/docs-shell/components/NotFound.astro +3 -0
  89. package/src/docs-shell/components/PMAction.astro +1 -0
  90. package/src/docs-shell/components/PageContent.svelte +1 -1
  91. package/src/docs-shell/components/PageContentDisclosure.astro +2 -1
  92. package/src/docs-shell/components/PageContentList.svelte +2 -0
  93. package/src/docs-shell/components/PageNavs.astro +1 -0
  94. package/src/docs-shell/components/SearchButton.svelte +3 -0
  95. package/src/docs-shell/components/SearchDialog.svelte +6 -1
  96. package/src/docs-shell/components/Segments.svelte +2 -0
  97. package/src/docs-shell/components/StepSection.astro +1 -2
  98. package/src/docs-shell/components/Tabs.astro +1 -0
  99. package/src/docs-shell/components/ThemeSelect.svelte +2 -0
  100. package/src/docs-shell/components/markdown/Table.astro +1 -0
  101. package/src/docs-shell/components/markdown-components.ts +0 -1
  102. package/src/docs-shell/remark/markdown-components.js +28 -7
  103. package/src/docs-shell/scripts/document.ts +1 -1
  104. package/src/docs-shell/types/Metadata.ts +11 -0
  105. package/src/docs-shell/utils/generate-metadata.ts +3 -1
  106. package/src/docs-shell/utils/head.ts +5 -2
  107. package/src/examples/components/ArticleTransitionScene.svelte +4 -0
  108. package/src/examples/layout-system/page.astro +0 -1
  109. package/src/home/HomeBentoFrame.astro +1 -0
  110. package/src/home/HomeBentoGrid.astro +1 -0
  111. package/src/home/HomeFooter.svelte +2 -2
  112. package/src/home/bento.css +167 -0
  113. package/src/home/design.css +1 -1
  114. package/src/home/home.css +4 -576
  115. package/src/home/segmented-control.css +94 -0
  116. package/src/layouts/Document.astro +3 -1
  117. package/src/public/icons/json.svg +1 -0
  118. package/src/scripts/atomic-class-authoring.ts +98 -0
  119. package/src/scripts/style-delivery.mjs +110 -0
  120. package/src/sections/blog.astro +1 -1
  121. package/src/sections/guide.astro +1 -2
  122. package/src/styles/blog-article.css +10 -7
  123. package/src/styles/blog-materials.css +13 -0
  124. package/src/styles/demo.css +0 -1
  125. package/src/styles/docs-shell/code.css +5 -61
  126. package/src/styles/docs-shell/documentation-search.css +1 -0
  127. package/src/styles/docs-shell/footer-link.css +5 -0
  128. package/src/styles/docs-shell/header.css +2 -73
  129. package/src/styles/docs-shell/menu.css +37 -17
  130. package/src/styles/docs-shell/page-content.css +2 -37
  131. package/src/styles/docs-shell/prose.css +18 -9
  132. package/src/styles/docs-shell/steps.css +2 -39
  133. package/src/styles/document-comparison.css +5 -2
  134. package/src/styles/documentation-illustration.css +1 -9
  135. package/src/styles/documentation-index.css +2 -1
  136. package/src/styles/documents.css +2 -4
  137. package/src/styles/interface.css +5 -3
  138. package/src/styles/system/DESIGN.md +34 -14
  139. package/src/styles/system/browser.css +21 -0
  140. package/src/styles/system/button-feedback.css +13 -0
  141. package/src/styles/system/callout.css +14 -0
  142. package/src/styles/system/chart.css +18 -0
  143. package/src/styles/system/checks.css +18 -0
  144. package/src/styles/system/code-panel.css +82 -0
  145. package/src/styles/system/code-tabs.css +40 -0
  146. package/src/styles/system/code.css +8 -85
  147. package/src/styles/system/compare.css +7 -0
  148. package/src/styles/system/controls.css +10 -109
  149. package/src/styles/system/copy.css +32 -0
  150. package/src/styles/system/data.css +10 -134
  151. package/src/styles/system/dialog.css +16 -0
  152. package/src/styles/system/disclosure.css +19 -0
  153. package/src/styles/system/expand.css +11 -0
  154. package/src/styles/system/fields.css +25 -0
  155. package/src/styles/system/header-core.css +101 -0
  156. package/src/styles/system/hint.css +5 -0
  157. package/src/styles/system/index.css +13 -0
  158. package/src/styles/system/inline-code.css +4 -0
  159. package/src/styles/system/kbd.css +4 -0
  160. package/src/styles/system/logos.css +10 -0
  161. package/src/styles/system/menu.css +14 -0
  162. package/src/styles/system/metrics.css +22 -0
  163. package/src/styles/system/pagehead.css +13 -0
  164. package/src/styles/system/pager.css +13 -0
  165. package/src/styles/system/parameters.css +17 -0
  166. package/src/styles/system/prompt.css +7 -0
  167. package/src/styles/system/prose.css +4 -75
  168. package/src/styles/system/range.css +12 -0
  169. package/src/styles/system/reading.css +44 -0
  170. package/src/styles/system/scroll.css +6 -0
  171. package/src/styles/system/search-trigger.css +10 -0
  172. package/src/styles/system/segmented.css +22 -0
  173. package/src/styles/system/sheet.css +8 -0
  174. package/src/styles/system/shell.css +8 -102
  175. package/src/styles/system/sidebar.css +14 -0
  176. package/src/styles/system/source.css +5 -0
  177. package/src/styles/system/specimens.css +3 -0
  178. package/src/styles/system/stage.css +18 -0
  179. package/src/styles/system/steps.css +51 -0
  180. package/src/styles/system/surfaces.css +8 -104
  181. package/src/styles/system/table.css +23 -0
  182. package/src/styles/system/toc.css +59 -0
  183. package/src/styles/system/tooltip.css +6 -0
  184. package/src/styles/system/tray-code.css +6 -0
  185. package/src/styles/system/tray.css +20 -0
  186. package/src/styles/system/tree.css +15 -0
  187. package/src/styles/system/waterfall.css +14 -0
@@ -20,6 +20,9 @@
20
20
  </script>
21
21
 
22
22
  <script lang="ts">
23
+ import '@master/internal-site/styles/interface.css'
24
+ import '@master/internal-site/styles/system/dialog.css'
25
+
23
26
  import '../../styles/docs-shell/documentation-search.css'
24
27
  import { untrack } from 'svelte'
25
28
  import Link from './Link.svelte'
@@ -38,6 +41,7 @@
38
41
  const tw = locale === 'tw'
39
42
  let opened = $state(false)
40
43
  let query = $state('')
44
+ let shortcutModifier = $state('⌘')
41
45
  let pages = $state.raw<DocumentationSearchPage[]>([])
42
46
  let error = $state('')
43
47
  let loading = $state(false)
@@ -67,6 +71,7 @@
67
71
  }
68
72
 
69
73
  function open(event?: Event) {
74
+ shortcutModifier = /Mac|iPhone|iPad|iPod/.test(navigator.platform) ? '⌘' : 'Ctrl'
70
75
  const trigger = (event as CustomEvent<{ trigger?: HTMLElement }> | undefined)?.detail?.trigger
71
76
  returnFocus = trigger instanceof HTMLElement ? trigger : document.activeElement as HTMLElement
72
77
  opened = true
@@ -169,6 +174,6 @@
169
174
  </li>{/each}{/if}
170
175
  </ol>
171
176
  </div>
172
- <div class="ui-dialog-foot" aria-hidden="true"><span><span class="ui-kbd"><IconArrowUp size={12} /></span><span class="ui-kbd"><IconArrowDown size={12} /></span>{tw ? '選擇' : 'Navigate'}</span><span><span class="ui-kbd"><IconCornerDownLeft size={12} /></span>{tw ? '開啟' : 'Open'}</span><span>{tw ? '文件搜尋' : 'Documentation'}</span></div>
177
+ <div class="ui-dialog-foot" aria-hidden="true"><span><span class="ui-kbd"><IconArrowUp size={12} /></span><span class="ui-kbd"><IconArrowDown size={12} /></span>{tw ? '選擇' : 'Navigate'}</span><span><span class="ui-kbd"><IconCornerDownLeft size={12} /></span>{tw ? '開啟' : 'Open'}</span><span class="ui-search-shortcut">{tw ? '隨時搜尋' : 'Search anytime'}<kbd class="ui-kbd">{shortcutModifier}</kbd><kbd class="ui-kbd">K</kbd></span></div>
173
178
  </dialog>
174
179
  {/if}
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import '@master/internal-site/styles/system/segmented.css'
3
+
2
4
  import '../../styles/docs-shell/segments.css'
3
5
  import type { Snippet } from 'svelte'
4
6
 
@@ -1,6 +1,5 @@
1
1
  ---
2
- import '../../styles/system/data.css'
3
- import '../../styles/docs-shell/steps.css'
2
+ import '../../styles/system/steps.css'
4
3
  import type { HTMLAttributes } from 'astro/types'
5
4
 
6
5
  type Props = HTMLAttributes<'ol'>
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import '@master/internal-site/styles/system/segmented.css'
2
3
  import type { HTMLAttributes } from 'astro/types'
3
4
 
4
5
  type Props = HTMLAttributes<'nav'>
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import '@master/internal-site/styles/system/fields.css'
3
+
2
4
  import type { HTMLSelectAttributes } from 'svelte/elements'
3
5
  import clsx from 'clsx'
4
6
  import { useThemeMode } from '../contexts/theme-mode.svelte'
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import '@master/internal-site/styles/system/table.css'
2
3
  ---
3
4
 
4
5
  <div class="ui-table">
@@ -1,4 +1,3 @@
1
- import '../../styles/system/data.css'
2
1
  import Image from './Image.svelte'
3
2
  import Do from './Do.astro'
4
3
  import DoNot from './DoNot.astro'
@@ -53,8 +53,29 @@ function fenceProps(node) {
53
53
  return props
54
54
  }
55
55
 
56
- const componentsExport = `import { markdownComponents as __markdownComponents } from '@master/internal-site/components/markdown-components'
57
- export const components = __markdownComponents`
56
+ // A document imports only the components it renders. Importing a shared object
57
+ // of every component also propagates every component's styles to every MDX page.
58
+ const componentPaths = {
59
+ a: 'markdown/Anchor.astro', h2: 'markdown/Heading2.astro', h3: 'markdown/Heading3.astro',
60
+ img: 'Image.svelte', Image: 'Image.svelte', table: 'markdown/Table.astro',
61
+ Code: 'Code.astro', InlineCode: 'InlineCode.astro', PMAction: 'PMAction.astro',
62
+ Do: 'Do.astro', DoNot: 'DoNot.astro', Info: 'Info.astro', Warn: 'Warn.astro',
63
+ InteractingIndicator: 'InteractingIndicator.astro'
64
+ }
65
+
66
+ function documentComponents(tree) {
67
+ const used = new Set()
68
+ visit(tree, node => {
69
+ if (node.type === 'link' || node.type === 'linkReference') used.add('a')
70
+ if (node.type === 'image' || node.type === 'imageReference') used.add('img')
71
+ if (node.type === 'table') used.add('table')
72
+ if (node.type === 'heading' && [2, 3].includes(node.depth)) used.add(`h${node.depth}`)
73
+ if (['mdxJsxFlowElement', 'mdxJsxTextElement'].includes(node.type) && node.name in componentPaths) used.add(node.name)
74
+ })
75
+ const entries = [...used].sort().map((name, index) => ({ name, local: `__masterComponent${index}`, path: componentPaths[name] }))
76
+ return entries.map(({ local, path }) => `import ${local} from '@master/internal-site/components/${path}'`).join('\n')
77
+ + `\nexport const components = {${entries.map(({ name, local }) => `${name}: ${local}`).join(', ')}}`
78
+ }
58
79
 
59
80
  /**
60
81
  * Markdown constructs that render through site components: fences become `Code` (or a
@@ -63,11 +84,6 @@ export const components = __markdownComponents`
63
84
  */
64
85
  export default function remarkMarkdownComponents() {
65
86
  return (tree) => {
66
- tree.children.unshift({
67
- type: 'mdxjsEsm',
68
- value: componentsExport,
69
- data: { estree: parse(componentsExport, { ecmaVersion: 'latest', sourceType: 'module' }) }
70
- })
71
87
  visit(tree, (node, index, parent) => {
72
88
  if (!parent || index === undefined) return
73
89
  if (node.type === 'code') {
@@ -97,5 +113,10 @@ export default function remarkMarkdownComponents() {
97
113
  return index
98
114
  }
99
115
  })
116
+ const source = documentComponents(tree)
117
+ tree.children.unshift({
118
+ type: 'mdxjsEsm', value: source,
119
+ data: { estree: parse(source, { ecmaVersion: 'latest', sourceType: 'module' }) }
120
+ })
100
121
  }
101
122
  }
@@ -44,4 +44,4 @@ const tableSizes = new ResizeObserver(entries => {
44
44
  else table.removeAttribute('tabindex')
45
45
  }
46
46
  })
47
- document.querySelectorAll<HTMLElement>('.ui-table:not([tabindex])').forEach(table => { if (!table.closest('site-island')) tableSizes.observe(table) })
47
+ document.querySelectorAll<HTMLElement>('.ui-table:not([tabindex])').forEach(table => { if (!table.closest('astro-island')) tableSizes.observe(table) })
@@ -1,10 +1,21 @@
1
1
  export declare type MetadataTitle = string | { absolute: string } | { default: string, template?: string }
2
2
 
3
+ /** An article's visible cover also supplies its social cards. */
4
+ export interface ArticleCover {
5
+ src: string
6
+ alt: string
7
+ width: number
8
+ height: number
9
+ /** Optional PNG/JPEG version of the same artwork for social clients. */
10
+ socialImage?: string
11
+ }
12
+
3
13
  /** Page metadata in the shape `docs-shell/utils/head` renders. */
4
14
  export declare type Metadata = {
5
15
  title?: MetadataTitle
6
16
  description?: string
7
17
  category?: string
18
+ cover?: ArticleCover
8
19
  robots?: string | { index?: boolean, follow?: boolean }
9
20
  alternates?: { canonical?: string }
10
21
  openGraph?: { title?: string, description?: string, siteName?: string, images?: string | string[] }
@@ -38,7 +38,9 @@ export default async function generate(
38
38
  card: 'summary_large_image'
39
39
  }
40
40
  }
41
- if (metadata.openGraph?.images) {
41
+ if (metadata.cover) {
42
+ baseMetadata.openGraph.images = baseMetadata.twitter.images = metadata.cover.socialImage ?? metadata.cover.src
43
+ } else if (metadata.openGraph?.images) {
42
44
  baseMetadata.twitter.images = metadata.openGraph.images
43
45
  } else {
44
46
  // postbuild-static renders each placeholder into a static /og image.
@@ -57,16 +57,19 @@ export function resolveHead(metadata: Partial<Metadata>, { project, siteURL, pat
57
57
  }
58
58
  }
59
59
  const { openGraph, twitter } = metadata
60
+ const coverImage = metadata.cover?.socialImage ?? metadata.cover?.src
60
61
  meta('property', 'og:title', openGraph?.title)
61
62
  meta('property', 'og:description', openGraph?.description)
62
63
  meta('property', 'og:site_name', openGraph?.siteName)
63
64
  // Open Graph and Twitter cards require absolute image URLs.
64
- for (const image of list(openGraph?.images)) meta('property', 'og:image', absolute(image))
65
+ for (const image of list(coverImage ?? openGraph?.images)) meta('property', 'og:image', absolute(image))
66
+ if (metadata.cover) meta('property', 'og:image:alt', metadata.cover.alt)
65
67
  meta('name', 'twitter:card', twitter?.card)
66
68
  meta('name', 'twitter:site', twitter?.site)
67
69
  meta('name', 'twitter:creator', twitter?.creator)
68
70
  meta('name', 'twitter:title', twitter?.title)
69
71
  meta('name', 'twitter:description', twitter?.description)
70
- for (const image of list(twitter?.images)) meta('name', 'twitter:image', absolute(image))
72
+ for (const image of list(coverImage ?? twitter?.images)) meta('name', 'twitter:image', absolute(image))
73
+ if (metadata.cover) meta('name', 'twitter:image:alt', metadata.cover.alt)
71
74
  return { title: resolveTitle(metadata.title, project), tags }
72
75
  }
@@ -1,4 +1,8 @@
1
1
  <script lang="ts">
2
+ import '@master/internal-site/styles/system/button-feedback.css'
3
+ import '@master/internal-site/styles/system/buttons.css'
4
+ import '@master/internal-site/styles/system/sheet.css'
5
+
2
6
  import Image from '@master/internal-site/components/Image.svelte'
3
7
  import IconArrowLeft from '@tabler/icons-svelte-runes/icons/arrow-left'
4
8
  import IconArrowUpRight from '@tabler/icons-svelte-runes/icons/arrow-up-right'
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  // Bare examples import the system parts they render: sheets and specimens.
3
- import '@master/internal-site/styles/system/surfaces.css'
4
3
  import '@master/internal-site/styles/system/specimens.css'
5
4
  import DemoItem from '@master/internal-site/demo/DemoItem.svelte'
6
5
  import DemoLabel from '@master/internal-site/demo/DemoLabel.svelte'
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import './bento.css'
2
3
  import type { HTMLAttributes } from 'astro/types'
3
4
 
4
5
  type Props = HTMLAttributes<'div'>
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import './bento.css'
2
3
  import type { HTMLAttributes } from 'astro/types'
3
4
 
4
5
  type Props = HTMLAttributes<'div'>
@@ -6,7 +6,7 @@
6
6
  import IconMoon from '@tabler/icons-svelte-runes/icons/moon'
7
7
  import IconSun from '@tabler/icons-svelte-runes/icons/sun'
8
8
  import LanguageSelect from '@master/internal-site/components/LanguageSelect.svelte'
9
- import Link from '@master/internal-site/components/Link.svelte'
9
+ import FooterNavLink from '../docs-shell/components/FooterLink.svelte'
10
10
  import ThemeSelect from '@master/internal-site/components/ThemeSelect.svelte'
11
11
  import { useThemeMode } from '@master/internal-site/contexts/theme-mode.svelte'
12
12
  import { getSite } from '@master/internal-site/site'
@@ -32,7 +32,7 @@
32
32
  <ul class="home-footer-links">
33
33
  {#each group.links as link (link.href)}
34
34
  <li>
35
- <Link class="home-footer-link" href={link.href}>{t(link.name)}</Link>
35
+ <FooterNavLink class="home-footer-link" href={link.href} disabled={link.disabled}>{t(link.name)}</FooterNavLink>
36
36
  </li>
37
37
  {/each}
38
38
  </ul>
@@ -0,0 +1,167 @@
1
+ /* * Cards stand directly on the page ground: no shell around them, so every edge is the card's own 1px
2
+ * contour. A card may hold its figure in a well, 12px in, and nothing deeper. */
3
+ /* The title and description stay together, with a separate illustration to their right. */
4
+ /* * A narrow card cannot spare a 7rem column beside its copy: the title shares a row with a smaller
5
+ * illustration and the description takes the full measure below, so neither wraps a word or two per line. */
6
+ /* * The well's contour is drawn above the figure, so a pane that fills the well never hides it and
7
+ * a pane's own edge never doubles it: every well reads as one 1px line. */
8
+ @layer components {
9
+ .home-bento-frame {
10
+ position: relative;
11
+ }
12
+
13
+ .home-bento-grid {
14
+ display: grid;
15
+ gap: var(--home-gap);
16
+
17
+ @media (--md) {
18
+ gap: 1rem;
19
+ }
20
+ }
21
+
22
+ .home-bento-card {
23
+ position: relative;
24
+ display: flex;
25
+ flex-direction: column;
26
+ min-width: 0;
27
+ border-radius: var(--home-radius-sheet);
28
+ background-color: var(--home-sheet);
29
+ box-shadow: 0 0 0 1px var(--home-hairline), var(--home-elevation-1);
30
+ transition: box-shadow var(--home-base) var(--home-ease);
31
+
32
+ &:hover {
33
+ box-shadow: 0 0 0 1px var(--home-rule), var(--home-elevation-1);
34
+ }
35
+ }
36
+ .home-bento-card-header {
37
+ /* Contain the header only: size containment on the subgrid card collapses auto-height code panes. */
38
+ container: home-card / inline-size;
39
+ padding: 1.75rem 1.5rem 2rem;
40
+
41
+ @media (--sm) {
42
+ padding: 2.25rem 2.25rem 2.5rem;
43
+ }
44
+
45
+ @media (--lg) {
46
+ padding: 2.5rem 2.75rem 2.75rem;
47
+ }
48
+ }
49
+
50
+ .home-bento-card-caption {
51
+ display: grid;
52
+ grid-template-columns: minmax(0, 44ch) 7rem;
53
+ /* In a wide card the copy keeps its measure and the illustration rides the card's right edge. */
54
+ justify-content: space-between;
55
+ align-items: start;
56
+ align-content: start;
57
+ column-gap: 1.5rem;
58
+ }
59
+
60
+ .home-bento-card-copy { min-width: 0; }
61
+
62
+ .home-bento-card-caption > .home-illustration {
63
+ --home-illustration-size: 7rem;
64
+ }
65
+ @container home-card (width < 28rem) {
66
+ .home-bento-card-caption {
67
+ grid-template-columns: minmax(0, 1fr) 4rem;
68
+ align-items: center;
69
+ gap: 0.75rem 1rem;
70
+ }
71
+ .home-bento-card-copy { display: contents; }
72
+ .home-bento-card-title { grid-column: 1; grid-row: 1; }
73
+ .home-bento-card-body { grid-column: 1 / -1; grid-row: 2; max-width: none; margin-top: 0; }
74
+ .home-bento-card-hint { grid-column: 1 / -1; grid-row: 3; margin-top: 0; }
75
+ .home-bento-card-caption > .home-illustration {
76
+ --home-illustration-size: 4rem;
77
+ grid-column: 2;
78
+ grid-row: 1;
79
+ margin-block: 0;
80
+ }
81
+ }
82
+
83
+ @container home-card (width < 16rem) {
84
+ .home-bento-card-caption { grid-template-columns: minmax(0, 1fr) 3rem; column-gap: 0.75rem; }
85
+ .home-bento-card-caption > .home-illustration { --home-illustration-size: 3rem; }
86
+ }
87
+
88
+ @container home-card (width < 12rem) {
89
+ .home-bento-card-caption { grid-template-columns: minmax(0, 1fr); }
90
+ .home-bento-card-caption > .home-illustration { display: none; }
91
+ }
92
+
93
+ @container home-card (width >= 28rem) {
94
+ .home-bento-card-caption { column-gap: 3rem; }
95
+ }
96
+
97
+ .home-bento-card-title {
98
+ min-width: 0;
99
+ margin: 0;
100
+ font-size: var(--home-card-title);
101
+ font-weight: var(--font-weight-regular);
102
+ line-height: 1.25;
103
+ letter-spacing: -0.025em;
104
+ color: var(--home-text);
105
+ text-wrap: balance;
106
+ }
107
+
108
+ .home-bento-card-body {
109
+ min-width: 0;
110
+ max-width: 44ch;
111
+ margin: 0.75rem 0 0;
112
+ font-size: var(--home-body);
113
+ line-height: 1.6;
114
+ color: var(--home-text-quiet);
115
+ text-wrap: pretty;
116
+ }
117
+
118
+ .home-bento-card-hint {
119
+ margin: 0.75rem 0 0;
120
+ font-size: var(--home-caption);
121
+ line-height: 1.5;
122
+ color: var(--home-text-faint);
123
+ }
124
+
125
+ .home-heading-link {
126
+ color: inherit;
127
+ text-decoration: none;
128
+ text-decoration-thickness: 1px;
129
+ text-underline-offset: 0.2em;
130
+
131
+ &:hover { text-decoration-line: underline; }
132
+
133
+ &:focus-visible {
134
+ border-radius: var(--radius-sm);
135
+ outline: 2px solid var(--home-ink);
136
+ outline-offset: 4px;
137
+ }
138
+ }
139
+ .home-bento-visual {
140
+ position: relative;
141
+ isolation: isolate;
142
+ overflow: hidden;
143
+ margin: auto var(--home-gap) var(--home-gap);
144
+ border-radius: var(--home-radius-well);
145
+ background-color: var(--home-well);
146
+
147
+ &::after {
148
+ position: absolute;
149
+ inset: 0;
150
+ z-index: 20;
151
+ border-radius: inherit;
152
+ box-shadow: var(--home-groove);
153
+ pointer-events: none;
154
+ content: '';
155
+ }
156
+ }
157
+
158
+ .home-bento-visual-top {
159
+ margin-top: 0;
160
+ }
161
+ }
162
+
163
+ @layer components { @media (forced-colors: active) { .home-bento-card { outline: 1px solid CanvasText; } } }
164
+
165
+ @layer components {
166
+ .home-page:lang(zh) .home-bento-card-body { text-wrap: balance; }
167
+ }
@@ -420,7 +420,7 @@
420
420
  * Han prose breaks between any two characters, so pretty wrapping still leaves a last line of two characters.
421
421
  * Short leads and card descriptions balance their lines instead.
422
422
  */
423
- .home-page:lang(zh) :is(.home-section-body, .home-bento-card-body) {
423
+ .home-page:lang(zh) .home-section-body {
424
424
  text-wrap: balance;
425
425
  }
426
426