vitepress 1.0.0-draft.4 → 1.0.0-draft.7

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 (67) hide show
  1. package/README.md +3 -1
  2. package/bin/vitepress.js +1 -1
  3. package/dist/client/app/index.js +1 -5
  4. package/dist/client/index.d.ts +123 -137
  5. package/dist/client/index.js +1 -2
  6. package/dist/client/theme-default/Layout.vue +7 -0
  7. package/dist/client/theme-default/NotFound.vue +74 -14
  8. package/dist/client/theme-default/components/VPBox.vue +2 -6
  9. package/dist/client/theme-default/components/VPButton.vue +0 -1
  10. package/dist/client/theme-default/components/VPCarbonAds.vue +90 -0
  11. package/dist/client/theme-default/components/VPContent.vue +11 -1
  12. package/dist/client/theme-default/components/VPDoc.vue +29 -35
  13. package/dist/client/theme-default/components/VPDocAside.vue +46 -0
  14. package/dist/client/theme-default/components/VPDocAsideCarbonAds.vue +13 -0
  15. package/dist/client/theme-default/components/{VPDocOutline.vue → VPDocAsideOutline.vue} +39 -34
  16. package/dist/client/theme-default/components/VPDocAsideSponsors.vue +32 -0
  17. package/dist/client/theme-default/components/VPDocFooter.vue +1 -1
  18. package/dist/client/theme-default/components/VPFlyout.vue +2 -3
  19. package/dist/client/theme-default/components/VPFooter.vue +1 -1
  20. package/dist/client/theme-default/components/VPHero.vue +170 -29
  21. package/dist/client/theme-default/components/VPHomeFeatures.vue +1 -0
  22. package/dist/client/theme-default/components/VPHomeHero.vue +1 -0
  23. package/dist/client/theme-default/components/VPHomeSponsors.vue +3 -3
  24. package/dist/client/theme-default/components/VPLink.vue +2 -1
  25. package/dist/client/theme-default/components/VPLocalNav.vue +1 -1
  26. package/dist/client/theme-default/components/VPMenu.vue +9 -14
  27. package/dist/client/theme-default/components/VPMenuLink.vue +10 -4
  28. package/dist/client/theme-default/components/VPNav.vue +18 -1
  29. package/dist/client/theme-default/components/VPNavBar.vue +19 -7
  30. package/dist/client/theme-default/components/VPNavBarExtra.vue +20 -45
  31. package/dist/client/theme-default/components/VPNavBarMenuGroup.vue +2 -8
  32. package/dist/client/theme-default/components/VPNavBarMenuLink.vue +3 -3
  33. package/dist/client/theme-default/components/VPNavBarSearch.vue +6 -6
  34. package/dist/client/theme-default/components/VPNavBarTitle.vue +4 -2
  35. package/dist/client/theme-default/components/VPNavBarTranslations.vue +10 -39
  36. package/dist/client/theme-default/components/VPNavScreenMenuGroup.vue +1 -2
  37. package/dist/client/theme-default/components/VPNavScreenMenuGroupSection.vue +1 -1
  38. package/dist/client/theme-default/components/VPSidebar.vue +10 -4
  39. package/dist/client/theme-default/components/VPSidebarGroup.vue +80 -17
  40. package/dist/client/theme-default/components/VPSidebarLink.vue +2 -9
  41. package/dist/client/theme-default/components/VPSocialLink.vue +2 -2
  42. package/dist/client/theme-default/components/VPSocialLinks.vue +1 -1
  43. package/dist/client/theme-default/components/VPSponsors.vue +15 -40
  44. package/dist/client/theme-default/components/VPSponsorsGrid.vue +2 -2
  45. package/dist/client/theme-default/components/icons/VPIconMinus.vue +5 -0
  46. package/dist/client/theme-default/components/icons/VPIconMinusSquare.vue +6 -0
  47. package/dist/client/theme-default/components/icons/VPIconPlusSquare.vue +6 -0
  48. package/dist/client/theme-default/composables/aside.js +17 -0
  49. package/dist/client/theme-default/composables/copy-code.js +33 -0
  50. package/dist/client/theme-default/composables/outline.js +3 -3
  51. package/dist/client/theme-default/composables/sponsor-grid.js +8 -6
  52. package/dist/client/theme-default/index.js +1 -0
  53. package/dist/client/theme-default/styles/base.css +13 -1
  54. package/dist/client/theme-default/styles/components/custom-block.css +2 -2
  55. package/dist/client/theme-default/styles/components/vp-doc.css +98 -107
  56. package/dist/client/theme-default/styles/components/vp-sponsor.css +51 -7
  57. package/dist/client/theme-default/styles/vars.css +42 -27
  58. package/dist/node/cli.js +32 -31
  59. package/dist/node/index.d.ts +371 -364
  60. package/dist/node/index.js +22 -37
  61. package/dist/node/serve-9c85885c.js +64795 -0
  62. package/dist/node-cjs/cli.cjs +304 -0
  63. package/dist/node-cjs/index.cjs +38 -0
  64. package/dist/{node/serve-b3182d88.js → node-cjs/serve-a73b4871.cjs} +27419 -28634
  65. package/package.json +46 -38
  66. package/theme.d.ts +7 -2
  67. package/types/default-theme.d.ts +15 -2
@@ -2,7 +2,7 @@
2
2
  import { computed } from 'vue'
3
3
  import { useData } from 'vitepress'
4
4
  import { useSidebar } from '../composables/sidebar'
5
- import VPDocOutline from './VPDocOutline.vue'
5
+ import VPDocAside from './VPDocAside.vue'
6
6
  import VPDocFooter from './VPDocFooter.vue'
7
7
 
8
8
  const { page } = useData()
@@ -17,10 +17,17 @@ const pageName = computed(() => {
17
17
  <div class="VPDoc" :class="{ 'has-sidebar': hasSidebar }">
18
18
  <div class="container">
19
19
  <div class="aside">
20
+ <div class="aside-curtain" />
20
21
  <div class="aside-container">
21
- <div class="aside-curtain" />
22
22
  <div class="aside-content">
23
- <VPDocOutline v-if="page.headers" />
23
+ <VPDocAside>
24
+ <template #aside-top><slot name="aside-top" /></template>
25
+ <template #aside-bottom><slot name="aside-bottom" /></template>
26
+ <template #aside-outline-before><slot name="aside-outline-before" /></template>
27
+ <template #aside-outline-after><slot name="aside-outline-after" /></template>
28
+ <template #aside-ads-before><slot name="aside-ads-before" /></template>
29
+ <template #aside-ads-after><slot name="aside-ads-after" /></template>
30
+ </VPDocAside>
24
31
  </div>
25
32
  </div>
26
33
  </div>
@@ -52,7 +59,7 @@ const pageName = computed(() => {
52
59
 
53
60
  @media (min-width: 960px) {
54
61
  .VPDoc {
55
- padding: 32px 32px 128px;
62
+ padding: 32px 32px 0;
56
63
  }
57
64
 
58
65
  .VPDoc:not(.has-sidebar) .container {
@@ -101,58 +108,51 @@ const pageName = computed(() => {
101
108
  display: none;
102
109
  order: 2;
103
110
  flex-grow: 1;
104
- flex-shrink: 0;
105
111
  padding-left: 32px;
106
- min-width: 240px;
107
- }
108
-
109
- @media (min-width: 1440px) {
110
- .aside {
111
- padding-left: 64px;
112
- }
112
+ width: 100%;
113
+ max-width: 256px;
113
114
  }
114
115
 
115
116
  .aside-container {
116
- position: fixed;
117
- top: var(--vp-nav-height-desktop);
118
- bottom: 0;
119
- padding-top: 32px;
120
- width: 208px;
117
+ position: sticky;
118
+ top: 0;
119
+ margin-top: calc(var(--vp-nav-height-desktop) * -1 - 32px);
120
+ padding-top: calc(var(--vp-nav-height-desktop) + 32px);
121
+ height: 100vh;
121
122
  overflow-x: hidden;
122
123
  overflow-y: auto;
124
+ scrollbar-width: none;
123
125
  }
124
126
 
125
127
  .aside-container::-webkit-scrollbar {
126
128
  display: none;
127
129
  }
128
130
 
129
- @media (min-width: 1440px) {
130
- .aside-container {
131
- width: 256px;
132
- }
133
- }
134
-
135
131
  .aside-curtain {
136
132
  position: fixed;
137
- top: var(--vp-nav-height-desktop);
133
+ bottom: 0;
138
134
  z-index: 10;
139
- width: 100%;
140
- height: 40px;
141
- background: linear-gradient(var(--vp-c-bg-content), transparent);
135
+ width: 224px;
136
+ height: 32px;
137
+ background: linear-gradient(transparent, var(--vp-c-bg) 70%);
142
138
  }
143
139
 
144
140
  .aside-content {
145
- padding-bottom: 96px;
141
+ display: flex;
142
+ flex-direction: column;
143
+ min-height: calc(100vh - (var(--vp-nav-height-desktop) + 32px));
144
+ padding-bottom: 32px;
146
145
  }
147
146
 
148
147
  .content {
149
148
  position: relative;
150
149
  margin: 0 auto;
150
+ width: 100%;
151
151
  }
152
152
 
153
153
  @media (min-width: 960px) {
154
154
  .content {
155
- padding: 0 32px;
155
+ padding: 0 32px 128px;
156
156
  }
157
157
  }
158
158
 
@@ -164,12 +164,6 @@ const pageName = computed(() => {
164
164
  }
165
165
  }
166
166
 
167
- @media (min-width: 1440px) {
168
- .content {
169
- padding-left: 64px;
170
- }
171
- }
172
-
173
167
  .content-container {
174
168
  margin: 0 auto;
175
169
  max-width: 688px;
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ import { useData } from 'vitepress'
3
+ import VPDocAsideOutline from './VPDocAsideOutline.vue'
4
+ import VPDocAsideCarbonAds from './VPDocAsideCarbonAds.vue'
5
+
6
+ const { page, theme } = useData()
7
+ </script>
8
+
9
+ <template>
10
+ <div class="VPDocAside">
11
+ <slot name="aside-top" />
12
+
13
+ <slot name="aside-outline-before" />
14
+ <VPDocAsideOutline v-if="page.headers.length" />
15
+ <slot name="aside-outline-after" />
16
+
17
+ <div class="spacer" />
18
+
19
+ <slot name="aside-ads-before" />
20
+ <VPDocAsideCarbonAds v-if="theme.carbonAds" />
21
+ <slot name="aside-ads-after" />
22
+
23
+ <slot name="aside-bottom" />
24
+ </div>
25
+ </template>
26
+
27
+ <style scoped>
28
+ .VPDocAside {
29
+ display: flex;
30
+ flex-direction: column;
31
+ flex-grow: 1;
32
+ }
33
+
34
+ .spacer {
35
+ flex-grow: 1;
36
+ }
37
+
38
+ .VPDocAside :deep(.spacer + .VPDocAsideSponsors),
39
+ .VPDocAside :deep(.spacer + .VPDocAsideCarbonAds) {
40
+ margin-top: 24px;
41
+ }
42
+
43
+ .VPDocAside :deep(.VPDocAsideSponsors + .VPDocAsideCarbonAds) {
44
+ margin-top: 16px;
45
+ }
46
+ </style>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { defineAsyncComponent } from 'vue'
3
+
4
+ const VPCarbonAds = __ALGOLIA__
5
+ ? defineAsyncComponent(() => import('./VPCarbonAds.vue'))
6
+ : () => null
7
+ </script>
8
+
9
+ <template>
10
+ <div class="VPDocAsideCarbonAds">
11
+ <VPCarbonAds />
12
+ </div>
13
+ </template>
@@ -28,51 +28,56 @@ function handleClick({ target: el }: Event) {
28
28
  </script>
29
29
 
30
30
  <template>
31
- <div class="VPDocOutline" :class="{ 'has-outline': hasOutline }" ref="container">
32
- <div class="outline-marker" ref="marker" />
33
-
34
- <div class="outline-title">On this page</div>
35
-
36
- <nav aria-labelledby="doc-outline-aria-label">
37
- <span class="visually-hidden" id="doc-outline-aria-label">
38
- Table of Contents for current page
39
- </span>
40
-
41
- <ul class="root">
42
- <li
43
- v-for="{ text, link, children, hidden } in resolvedHeaders"
44
- v-show="!hidden"
45
- >
46
- <a class="outline-link" :href="link" @click="handleClick">
47
- {{ text }}
48
- </a>
49
- <ul v-if="children && frontmatter.outline === 'deep'">
50
- <li v-for="{ text, link, hidden } in children" v-show="!hidden">
51
- <a class="outline-link nested" :href="link" @click="handleClick">
52
- {{ text }}
53
- </a>
54
- </li>
55
- </ul>
56
- </li>
57
- </ul>
58
- </nav>
31
+ <div class="VPDocAsideOutline" :class="{ 'has-outline': hasOutline }" ref="container">
32
+ <div class="content">
33
+ <div class="outline-marker" ref="marker" />
34
+
35
+ <div class="outline-title">On this page</div>
36
+
37
+ <nav aria-labelledby="doc-outline-aria-label">
38
+ <span class="visually-hidden" id="doc-outline-aria-label">
39
+ Table of Contents for current page
40
+ </span>
41
+
42
+ <ul class="root">
43
+ <li
44
+ v-for="{ text, link, children, hidden } in resolvedHeaders"
45
+ v-show="!hidden"
46
+ >
47
+ <a class="outline-link" :href="link" @click="handleClick">
48
+ {{ text }}
49
+ </a>
50
+ <ul v-if="children && frontmatter.outline === 'deep'">
51
+ <li v-for="{ text, link, hidden } in children" v-show="!hidden">
52
+ <a class="outline-link nested" :href="link" @click="handleClick">
53
+ {{ text }}
54
+ </a>
55
+ </li>
56
+ </ul>
57
+ </li>
58
+ </ul>
59
+ </nav>
60
+ </div>
59
61
  </div>
60
62
  </template>
61
63
 
62
64
  <style scoped>
63
- .VPDocOutline {
64
- position: relative;
65
+ .VPDocAsideOutline {
65
66
  display: none;
67
+ }
68
+
69
+ .VPDocAsideOutline.has-outline {
70
+ display: block;
71
+ }
72
+
73
+ .content {
74
+ position: relative;
66
75
  border-left: 1px solid var(--vp-c-divider-light);
67
76
  padding-left: 16px;
68
77
  font-size: 13px;
69
78
  font-weight: 500;
70
79
  }
71
80
 
72
- .VPDocOutline.has-outline {
73
- display: block;
74
- }
75
-
76
81
  .outline-marker {
77
82
  position: absolute;
78
83
  top: 32px;
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import VPSponsors from './VPSponsors.vue'
3
+
4
+ export interface Sponsors {
5
+ tier?: string
6
+ size?: 'xmini' | 'mini' | 'small'
7
+ items: Sponsor[]
8
+ }
9
+
10
+ export interface Sponsor {
11
+ name: string
12
+ img: string
13
+ url: string
14
+ }
15
+
16
+ defineProps<{
17
+ tier?: string
18
+ size?: 'xmini' | 'mini' | 'small'
19
+ data: Sponsors[] | Sponsor[]
20
+ }>()
21
+ </script>
22
+
23
+ <template>
24
+ <div class="VPDocAsideSponsors">
25
+ <VPSponsors
26
+ mode="aside"
27
+ :tier="tier"
28
+ :size="size"
29
+ :data="data"
30
+ />
31
+ </div>
32
+ </template>
@@ -44,7 +44,7 @@ const control = usePrevNext()
44
44
  }
45
45
 
46
46
  .edit-link {
47
- padding-bottom: 8px;
47
+ padding-bottom: 14px;
48
48
  }
49
49
 
50
50
  .edit-link-button {
@@ -1,12 +1,11 @@
1
1
  <script lang="ts" setup>
2
2
  import { ref } from 'vue'
3
- import { DefaultTheme } from 'vitepress'
4
3
  import { useFlyout } from '../composables/flyout'
5
4
  import VPIconChevronDown from './icons/VPIconChevronDown.vue'
6
5
  import VPIconMoreHorizontal from './icons/VPIconMoreHorizontal.vue'
7
6
  import VPMenu from './VPMenu.vue'
8
7
 
9
- const props = defineProps<{
8
+ defineProps<{
10
9
  icon?: any
11
10
  button?: string
12
11
  label?: string
@@ -141,7 +140,7 @@ function onBlur() {
141
140
  transition: opacity 0.25s, visibility 0.25s, transform 0.25s;
142
141
  }
143
142
 
144
- @media (min-width: 1280px) {
143
+ @media (min-width: 960px) {
145
144
  .menu {
146
145
  top: calc(var(--vp-nav-height-desktop) / 2 + 20px);
147
146
  }
@@ -21,7 +21,7 @@ const { hasSidebar } = useSidebar()
21
21
  z-index: var(--vp-z-index-footer);
22
22
  border-top: 1px solid var(--vp-c-divider-light);
23
23
  padding: 32px 24px;
24
- background-color: var(--vp-c-bg-content);
24
+ background-color: var(--vp-c-bg);
25
25
  }
26
26
 
27
27
  .VPFooter.has-sidebar {
@@ -1,36 +1,51 @@
1
1
  <script setup lang="ts">
2
2
  import VPButton from './VPButton.vue'
3
3
 
4
- interface HeroAction {
4
+ export interface HeroAction {
5
5
  theme?: 'brand' | 'alt'
6
6
  text: string
7
7
  link: string
8
8
  }
9
9
 
10
+ export interface Image {
11
+ light: string
12
+ dark: string
13
+ }
14
+
10
15
  defineProps<{
11
16
  name?: string
12
17
  text: string
13
18
  tagline?: string
19
+ image?: Image
14
20
  actions?: HeroAction[]
15
21
  }>()
16
22
  </script>
17
23
 
18
24
  <template>
19
- <div class="VPHero">
25
+ <div class="VPHero" :class="{ 'has-image': image }">
20
26
  <div class="container">
21
- <p v-if="name" class="name"><span class="clip">{{ name }}</span></p>
22
- <h1 v-if="text" class="text">{{ text }}</h1>
23
- <p v-if="tagline" class="tagline">{{ tagline }}</p>
24
-
25
- <div v-if="actions" class="actions">
26
- <div v-for="action in actions" :key="action.link" class="action">
27
- <VPButton
28
- tag="a"
29
- size="big"
30
- :theme="action.theme"
31
- :text="action.text"
32
- :href="action.link"
33
- />
27
+ <div class="main">
28
+ <p v-if="name" class="name"><span class="clip">{{ name }}</span></p>
29
+ <h1 v-if="text" class="text">{{ text }}</h1>
30
+ <p v-if="tagline" class="tagline">{{ tagline }}</p>
31
+
32
+ <div v-if="actions" class="actions">
33
+ <div v-for="action in actions" :key="action.link" class="action">
34
+ <VPButton
35
+ tag="a"
36
+ size="medium"
37
+ :theme="action.theme"
38
+ :text="action.text"
39
+ :href="action.link"
40
+ />
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <div v-if="image" class="image">
46
+ <div class="image-container">
47
+ <img class="image-src light" :src="image.light">
48
+ <img class="image-src dark" :src="image.dark">
34
49
  </div>
35
50
  </div>
36
51
  </div>
@@ -41,6 +56,7 @@ defineProps<{
41
56
  .VPHero {
42
57
  margin-top: calc(var(--vp-nav-height) * -1);
43
58
  padding: calc(var(--vp-nav-height) + 48px) 24px 48px;
59
+ overflow: hidden;
44
60
  }
45
61
 
46
62
  @media (min-width: 640px) {
@@ -50,66 +66,113 @@ defineProps<{
50
66
  }
51
67
 
52
68
  .container {
69
+ display: flex;
70
+ flex-direction: column;
53
71
  margin: 0 auto;
54
72
  max-width: 960px;
55
73
  }
56
74
 
75
+ @media (min-width: 960px) {
76
+ .container {
77
+ flex-direction: row;
78
+ }
79
+ }
80
+
81
+ .main {
82
+ position: relative;
83
+ z-index: 10;
84
+ order: 2;
85
+ flex-grow: 1;
86
+ flex-shrink: 0;
87
+ }
88
+
89
+ .VPHero.has-image .container {
90
+ text-align: center;
91
+ }
92
+
93
+ @media (min-width: 960px) {
94
+ .VPHero.has-image .container {
95
+ text-align: left;
96
+ }
97
+ }
98
+
99
+ @media (min-width: 960px) {
100
+ .main {
101
+ order: 1;
102
+ }
103
+ }
104
+
105
+ @media (min-width: 960px) {
106
+ .main {
107
+ width: 100%;
108
+ max-width: calc((100% / 3) * 2);
109
+ }
110
+ }
111
+
57
112
  .name,
58
113
  .text {
114
+ max-width: 392px;
115
+ letter-spacing: -0.4px;
59
116
  line-height: 40px;
60
117
  font-size: 32px;
61
118
  font-weight: 700;
62
119
  }
63
120
 
121
+ .VPHero.has-image .name,
122
+ .VPHero.has-image .text {
123
+ margin: 0 auto;
124
+ }
125
+
64
126
  .name {
65
- padding-bottom: 4px;
66
127
  color: var(--vp-home-hero-name-color);
67
128
  }
68
129
 
69
130
  .clip {
70
131
  background: var(--vp-home-hero-name-background);
71
- -webkit-text-fill-color: var(--vp-home-hero-name-color);
72
132
  -webkit-background-clip: text;
133
+ background-clip: text;
134
+ -webkit-text-fill-color: var(--vp-home-hero-name-color);
73
135
  }
74
136
 
75
137
  @media (min-width: 640px) {
76
138
  .name,
77
139
  .text {
78
- max-width: 640px;
140
+ max-width: 576px;
79
141
  line-height: 56px;
80
142
  font-size: 48px;
81
143
  }
82
-
83
- .name {
84
- padding-bottom: 6px;
85
- }
86
144
  }
87
145
 
88
146
  @media (min-width: 960px) {
89
147
  .name,
90
148
  .text {
91
- max-width: 720px;
92
149
  line-height: 64px;
93
150
  font-size: 56px;
94
151
  }
95
152
 
96
- .name {
97
- padding-bottom: 6px;
153
+ .VPHero.has-image .name,
154
+ .VPHero.has-image .text {
155
+ margin: 0;
98
156
  }
99
157
  }
100
158
 
101
159
  .tagline {
102
160
  padding-top: 16px;
161
+ max-width: 392px;
103
162
  line-height: 28px;
104
163
  font-size: 18px;
105
164
  font-weight: 500;
106
165
  color: var(--vp-c-text-2);
107
166
  }
108
167
 
168
+ .VPHero.has-image .tagline {
169
+ margin: 0 auto;
170
+ }
171
+
109
172
  @media (min-width: 640px) {
110
173
  .tagline {
111
174
  padding-top: 24px;
112
- max-width: 540px;
175
+ max-width: 576px;
113
176
  line-height: 32px;
114
177
  font-size: 20px;
115
178
  }
@@ -118,27 +181,105 @@ defineProps<{
118
181
  @media (min-width: 960px) {
119
182
  .tagline {
120
183
  padding-top: 24px;
121
- max-width: 640px;
122
184
  line-height: 36px;
123
185
  font-size: 24px;
124
186
  }
187
+
188
+ .VPHero.has-image .tagline {
189
+ margin: 0;
190
+ }
125
191
  }
126
192
 
127
193
  .actions {
128
194
  display: flex;
129
195
  flex-wrap: wrap;
130
- margin: -8px;
196
+ margin: -6px;
131
197
  padding-top: 24px;
132
198
  }
133
199
 
200
+ .VPHero.has-image .actions {
201
+ justify-content: center;
202
+ }
203
+
134
204
  @media (min-width: 640px) {
135
205
  .actions {
136
206
  padding-top: 32px;
137
207
  }
138
208
  }
139
209
 
210
+ @media (min-width: 960px) {
211
+ .VPHero.has-image .actions {
212
+ justify-content: flex-start;
213
+ }
214
+ }
215
+
140
216
  .action {
141
217
  flex-shrink: 0;
142
- padding: 8px;
218
+ padding: 6px;
219
+ }
220
+
221
+ .image {
222
+ order: 1;
223
+ margin: -76px -24px -48px;
224
+ }
225
+
226
+ @media (min-width: 640px) {
227
+ .image {
228
+ margin: -108px -24px -48px;
229
+ }
230
+ }
231
+
232
+ .image-container {
233
+ position: relative;
234
+ margin: 0 auto;
235
+ width: 320px;
236
+ height: 320px;
237
+ }
238
+
239
+ @media (min-width: 640px) {
240
+ .image-container {
241
+ width: 392px;
242
+ height: 392px;
243
+ }
244
+ }
245
+
246
+ .image-src {
247
+ position: absolute;
248
+ top: 50%;
249
+ left: 50%;
250
+ max-width: 392px;
251
+ transform: translate(-50%, -50%);
252
+ }
253
+
254
+ .image-src.light { opacity: 1; }
255
+ .image-src.dark { opacity: 0; }
256
+
257
+ .dark .image-src.light { opacity: 0; }
258
+ .dark .image-src.dark { opacity: 1; }
259
+
260
+ @media (min-width: 640px) {
261
+ .image-src {
262
+ max-width: 512px;
263
+ transform: translate(-50%, -50%);
264
+ }
265
+ }
266
+
267
+ @media (min-width: 960px) {
268
+ .image {
269
+ order: 2;
270
+ margin: -8px 0;
271
+ width: calc(100% / 3);
272
+ min-height: 100%;
273
+ }
274
+
275
+ .image-container {
276
+ width: 100%;
277
+ height: 100%;
278
+ }
279
+
280
+ .image-src {
281
+ max-width: 640px;
282
+ transform: translate(calc(-50% - 32px), calc(-50% - 32px));
283
+ }
143
284
  }
144
285
  </style>
@@ -42,6 +42,7 @@ const grid = computed(() => {
42
42
 
43
43
  <style scoped>
44
44
  .VPHomeFeatures {
45
+ position: relative;
45
46
  padding: 0 24px;
46
47
  }
47
48
 
@@ -11,6 +11,7 @@ const { frontmatter: fm } = useData()
11
11
  :name="fm.hero.name"
12
12
  :text="fm.hero.text"
13
13
  :tagline="fm.hero.tagline"
14
+ :image="fm.hero.image"
14
15
  :actions="fm.hero.actions"
15
16
  />
16
17
  </div>