valaxy-theme-press 0.0.1 → 0.0.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 (51) hide show
  1. package/README.md +8 -0
  2. package/client/index.ts +1 -0
  3. package/components/DocsBoard.vue +24 -0
  4. package/components/PressArticle.vue +15 -10
  5. package/components/PressArticleCard.vue +6 -2
  6. package/components/PressAside.vue +87 -0
  7. package/components/PressBackdrop.vue +39 -0
  8. package/components/PressButton.vue +31 -0
  9. package/components/PressCategories.vue +71 -0
  10. package/components/PressCategory.vue +58 -0
  11. package/components/PressDocFooter.vue +15 -0
  12. package/components/PressDocFooterLastUpdated.vue +44 -0
  13. package/components/PressFeature.vue +61 -0
  14. package/components/PressFeatures.vue +26 -0
  15. package/components/PressFooter.vue +53 -0
  16. package/components/PressHome.vue +15 -0
  17. package/components/PressHomeFeatures.vue +12 -0
  18. package/components/PressHomeHero.vue +34 -0
  19. package/components/PressLocalNav.vue +109 -0
  20. package/components/PressNav.vue +17 -35
  21. package/components/PressOutline.vue +111 -0
  22. package/components/PressOutlineItem.vue +48 -0
  23. package/components/PressSidebar.vue +88 -0
  24. package/components/PressToggleLocale.vue +1 -1
  25. package/components/ValaxyMain.vue +56 -12
  26. package/components/nav/PressNavBar.vue +111 -0
  27. package/components/nav/PressNavItemGroup.vue +101 -0
  28. package/components/nav/PressNavItemLink.vue +39 -0
  29. package/components/nav/PressSwitchAppearance.vue +71 -0
  30. package/composables/edit-link.ts +14 -0
  31. package/composables/index.ts +1 -0
  32. package/config/index.ts +7 -12
  33. package/layouts/404.vue +13 -12
  34. package/layouts/home.vue +1 -7
  35. package/layouts/layout.vue +52 -39
  36. package/node/index.ts +1 -42
  37. package/package.json +16 -15
  38. package/pages/[..all].vue +15 -0
  39. package/setup/main.ts +89 -0
  40. package/styles/css-vars.scss +46 -0
  41. package/styles/helper.scss +34 -0
  42. package/styles/index.scss +7 -0
  43. package/styles/markdown.scss +49 -0
  44. package/types/home.d.ts +5 -0
  45. package/types/index.d.ts +71 -0
  46. package/valaxy.config.ts +38 -0
  47. package/LICENSE +0 -21
  48. package/components/PressHeader.vue +0 -26
  49. package/pages/index.vue +0 -8
  50. package/tsup.config.ts +0 -16
  51. package/types/index.ts +0 -30
@@ -0,0 +1,101 @@
1
+ <script lang="ts" setup>
2
+ import { ref } from 'vue'
3
+ import type { NavItemGroup } from '../../types'
4
+ defineProps<{
5
+ item: NavItemGroup
6
+ }>()
7
+
8
+ const open = ref(false)
9
+ </script>
10
+
11
+ <template>
12
+ <div
13
+ ref="el"
14
+ class="flex self-stretch relative group"
15
+ :aria-expanded="open"
16
+ aria-haspopup="true"
17
+ @mouseenter="open = true"
18
+ @mouseleave="open = false"
19
+ >
20
+ <button
21
+ type="button"
22
+ class="button flex items-center"
23
+ @click="open = !open"
24
+ >
25
+ <span class="text">
26
+ {{ item.text }}
27
+ </span>
28
+ <div i-ri-arrow-drop-down-line />
29
+ </button>
30
+
31
+ <div class="menu grow" flex="~ col" items="start">
32
+ <AppLink v-for="itemLink in item.items" :key="itemLink.text" class="menu-item" p="x-3" :to="itemLink.link">
33
+ {{ itemLink.text }}
34
+ </AppLink>
35
+ </div>
36
+ </div>
37
+ </template>
38
+
39
+ <style lang="scss" scoped>
40
+ .group .button{
41
+ color: var(--pr-nav-text);
42
+ font-weight: 500;
43
+ font-size: 14px;
44
+ }
45
+
46
+ .group[aria-expanded="true"] .button{
47
+ color: rgba(60, 60, 60, 0.70);
48
+ transition: color 0.25s;
49
+
50
+ .dark &{
51
+ color: rgba(235, 235, 235, 0.6)
52
+ }
53
+ }
54
+
55
+ .menu {
56
+ position: absolute;
57
+ left: 50%;
58
+
59
+ min-width: 128px;
60
+ opacity: 0;
61
+ visibility: hidden;
62
+ transition: opacity 0.25s, visibility 0.25s, transform 0.25s;
63
+ transform: translateX(-50%) translateY(calc(var(--pr-nav-height) / 2));
64
+
65
+ border-radius: 12px;
66
+ padding: 12px;
67
+ border: 1px solid rgba(60, 60, 60, 0.12);
68
+ background-color: #ffffff;
69
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
70
+ .dark &{
71
+ background-color: #242424;
72
+ }
73
+
74
+ &-item{
75
+ display: flex;
76
+ width: 100%;
77
+ border-radius: 6px;
78
+ color: var(--pr-nav-text);
79
+ line-height: 32px;
80
+ font-size: 14px;
81
+ font-weight: 500;
82
+ white-space: nowrap;
83
+ transition: background-color .25s,color .25s;
84
+
85
+ &:hover{
86
+ background-color: #f1f1f1;
87
+ color: var(--va-c-brand);
88
+
89
+ .dark &{
90
+ background-color: #2f2f2f;
91
+ }
92
+ }
93
+
94
+ }
95
+ }
96
+
97
+ .group[aria-expanded="true"] > .menu {
98
+ opacity: 1;
99
+ visibility: visible;
100
+ }
101
+ </style>
@@ -0,0 +1,39 @@
1
+ <script lang="ts" setup>
2
+ import { useRoute } from 'vue-router'
3
+ import type { NavItemLink } from '../../types'
4
+ defineProps<{
5
+ item: NavItemLink
6
+ }>()
7
+
8
+ const route = useRoute()
9
+ </script>
10
+
11
+ <template>
12
+ <AppLink
13
+ class="press-nav-item-link"
14
+ :class="{
15
+ active: route.path === item.link,
16
+ }"
17
+ :to="item.link"
18
+ rel="noopener"
19
+ show-external-icon
20
+ >
21
+ {{ item.text }}
22
+ </AppLink>
23
+ </template>
24
+
25
+ <style lang="scss" scoped>
26
+ .press-nav-item-link{
27
+ font-size: 14px;
28
+ font-weight: 500;
29
+ color: var(--pr-nav-text);
30
+ transition: color 0.25s;
31
+
32
+ &:hover{
33
+ color: var(--va-c-brand);
34
+ }
35
+ }
36
+ .active{
37
+ color: var(--va-c-brand);
38
+ }
39
+ </style>
@@ -0,0 +1,71 @@
1
+ <script lang="ts" setup>
2
+ import { isDark, toggleDark } from 'valaxy'
3
+ </script>
4
+
5
+ <template>
6
+ <button class="switch switch-appearance" type="button" aria-label="Toggle Dark Mode" @click="toggleDark()">
7
+ <span class="check">
8
+ <span class="icon-wrap">
9
+ <div v-if="!isDark" class="icon" i-ri-sun-line />
10
+ <div v-else class="icon" i-ri-moon-line />
11
+ </span>
12
+ </span>
13
+ </button>
14
+ </template>
15
+
16
+ <style lang="scss" scoped>
17
+ .switch {
18
+ position: relative;
19
+ display: block;
20
+ box-sizing: border-box;
21
+ width: 40px;
22
+ height: 22px;
23
+ border-radius: 11px;
24
+ border: 1px solid var(--pr-switch-divider);
25
+ background-color: var(--pr-switch-bg);
26
+ transition: border-color 0.25s, background-color 0.25s;
27
+ }
28
+
29
+ .switch:hover {
30
+ border-color: #8e8e8e;
31
+ }
32
+
33
+ .check {
34
+ position: absolute;
35
+ top: 1px;
36
+ left: 1px;
37
+ width: 18px;
38
+ height: 18px;
39
+ border-radius: 50%;
40
+ background-color: #ffffff;
41
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);
42
+ transition: background-color 0.25s, transform 0.25s;
43
+ }
44
+
45
+ .dark .check {
46
+ background-color: #1a1a1a;
47
+ }
48
+
49
+ .icon-wrap {
50
+ box-sizing: border-box;
51
+ display: block;
52
+ padding: 3px;
53
+ width: 18px;
54
+ height: 18px;
55
+ border-radius: 50%;
56
+ }
57
+
58
+ .icon {
59
+ width: 12px;
60
+ height: 12px;
61
+ background-color: rgba(60, 60, 60, 0.7);
62
+ }
63
+
64
+ .dark .icon {
65
+ background-color: rgba(255, 255, 255, 0.87);
66
+ }
67
+
68
+ .dark .switch-appearance :deep(.check) {
69
+ transform: translateX(18px);
70
+ }
71
+ </style>
@@ -0,0 +1,14 @@
1
+ import { useData } from 'valaxy'
2
+ import { computed } from 'vue'
3
+ import { useThemeConfig } from '.'
4
+
5
+ export function useEditLink() {
6
+ const themeConfig = useThemeConfig()
7
+ return computed(() => {
8
+ const { text = 'Edit this page', pattern } = themeConfig.value.editLink || {}
9
+ const { relativePath } = useData()
10
+ const url = pattern.replace(/:path/g, relativePath)
11
+
12
+ return { url, text }
13
+ })
14
+ }
@@ -1 +1,2 @@
1
1
  export * from './config'
2
+ export * from './edit-link'
package/config/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ThemeConfig, ThemeUserConfig } from '../types'
1
+ import type { ThemeConfig } from '../types'
2
2
 
3
3
  export const anonymousImage = 'https://cdn.yunyoujun.cn/img/avatar/none.jpg'
4
4
 
@@ -12,18 +12,13 @@ export const defaultThemeConfig: ThemeConfig = {
12
12
  primary: '#0078E7',
13
13
  },
14
14
 
15
+ sidebar: [],
15
16
  nav: [],
16
- }
17
17
 
18
- export default defaultThemeConfig
18
+ editLink: {
19
+ pattern: 'https://github.com/YunYouJun/valaxy/edit/main/docs/:path',
20
+ text: 'Edit this page on GitHub',
21
+ },
19
22
 
20
- /**
21
- * generateSafelist by config
22
- * @param themeConfig
23
- * @returns
24
- */
25
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
- export function generateSafelist(themeConfig: ThemeUserConfig) {
27
- const safelist: string[] = []
28
- return safelist
23
+ footer: {},
29
24
  }
package/layouts/404.vue CHANGED
@@ -8,18 +8,19 @@ const { t } = useI18n()
8
8
 
9
9
  <template>
10
10
  <Layout>
11
- <template #content>
12
- <div text="center">
13
- <div text-4xl>
14
- <div i-ri-alarm-warning-line inline-block />
15
- </div>
16
- <router-view />
17
- <div>
18
- <button btn text-sm m="3 t8" @click="router.back()">
19
- {{ t('button.back') }}
20
- </button>
21
- </div>
22
- </div>
11
+ <template #sidebar>
12
+ <div />
23
13
  </template>
14
+ <div text="center" m="t-20">
15
+ <div text-4xl>
16
+ <div i-ri-alarm-warning-line inline-block />
17
+ </div>
18
+ <router-view />
19
+ <div>
20
+ <button btn text-sm m="3 t8" @click="router.back()">
21
+ {{ t('button.back') }}
22
+ </button>
23
+ </div>
24
+ </div>
24
25
  </Layout>
25
26
  </template>
package/layouts/home.vue CHANGED
@@ -1,11 +1,5 @@
1
1
  <template>
2
2
  <Layout>
3
- <div class="divide-y divide-gray-200">
4
- <PressHeader />
5
-
6
- <slot>
7
- <router-view />
8
- </slot>
9
- </div>
3
+ <PressHome />
10
4
  </Layout>
11
5
  </template>
@@ -1,45 +1,58 @@
1
+ <script lang="ts" setup>
2
+ import { useLayout, useSidebar } from 'valaxy'
3
+
4
+ const { isOpen: isSidebarOpen, open: openSidebar, close: closeSidebar } = useSidebar()
5
+ const layout = useLayout()
6
+ </script>
7
+
1
8
  <template>
2
- <div class="antialiased">
3
- <div class="max-w-3xl mx-auto px-4 sm:px-6 xl:max-w-5xl xl:px-0">
4
- <PressNav />
5
- </div>
9
+ <div class="layout antialiased">
10
+ <PressNav />
11
+ <PressLocalNav :open="isSidebarOpen" @open-menu="openSidebar()" />
12
+ <slot name="sidebar">
13
+ <PressSidebar v-if="layout !== 'post'" :open="isSidebarOpen" />
14
+ </slot>
15
+ <PressBackdrop :show="isSidebarOpen" @click="closeSidebar" />
16
+
17
+ <slot>
18
+ <router-view v-slot="{ Component }">
19
+ <component :is="Component">
20
+ <template #main-header>
21
+ <slot name="main-header" />
22
+ </template>
6
23
 
7
- <main class="max-w-3xl mx-auto px-4 sm:px-6 xl:max-w-5xl xl:px-0">
8
- <slot>
9
- <router-view v-slot="{ Component }">
10
- <component :is="Component">
11
- <template #main-header>
12
- <slot name="main-header" />
13
- </template>
24
+ <template #main-header-after>
25
+ <slot name="main-header-after" />
26
+ </template>
27
+ <template #main>
28
+ <slot name="main" />
29
+ </template>
30
+ <template #main-content>
31
+ <slot name="main-content" />
32
+ </template>
33
+ <template #main-content-after>
34
+ <slot name="main-content-after" />
35
+ </template>
36
+ <template #main-nav-before>
37
+ <slot name="main-nav-before" />
38
+ </template>
39
+ <template #main-nav-after>
40
+ <slot name="main-nav-after" />
41
+ </template>
42
+ <template #aside>
43
+ <slot name="aside" />
44
+ </template>
45
+ <template #aside-custom>
46
+ <slot name="aside-custom" />
47
+ </template>
48
+ <template #footer>
49
+ <slot name="footer" />
50
+ </template>
51
+ </component>
52
+ </router-view>
53
+ </slot>
14
54
 
15
- <template #main-header-after>
16
- <slot name="main-header-after" />
17
- </template>
18
- <template #main>
19
- <slot name="main" />
20
- </template>
21
- <template #main-content>
22
- <slot name="main-content" />
23
- </template>
24
- <template #main-content-after>
25
- <slot name="main-content-after" />
26
- </template>
27
- <template #main-nav-before>
28
- <slot name="main-nav-before" />
29
- </template>
30
- <template #main-nav-after>
31
- <slot name="main-nav-after" />
32
- </template>
33
- <template #aside-custom>
34
- <slot name="aside-custom" />
35
- </template>
36
- <template #footer>
37
- <slot name="footer" />
38
- </template>
39
- </component>
40
- </router-view>
41
- </slot>
42
- </main>
55
+ <PressFooter />
43
56
  </div>
44
57
  </template>
45
58
 
package/node/index.ts CHANGED
@@ -1,43 +1,2 @@
1
- import { defineThemePlugin } from 'valaxy'
2
- import type { ResolvedValaxyOptions } from 'valaxy'
3
- import type { Plugin } from 'vite'
4
-
5
1
  export * from '../config'
6
- export * from '../types'
7
-
8
- export interface UserOptions {
9
- colors: {
10
- primary: string
11
- }
12
- }
13
-
14
- function ThemeYunVitePlugin(options: ResolvedValaxyOptions): Plugin {
15
- const themeConfig = options.config.themeConfig
16
- return {
17
- name: 'valaxy-theme-yun',
18
- enforce: 'pre',
19
- config() {
20
- return {
21
- css: {
22
- preprocessorOptions: {
23
- scss: {
24
- additionalData: `$c-primary: ${themeConfig.colors?.primary || '#0078E7'} !default;`,
25
- },
26
- },
27
- },
28
-
29
- optimizeDeps: {
30
- exclude: ['@docsearch/js'],
31
- },
32
- }
33
- },
34
- }
35
- }
36
-
37
- export default defineThemePlugin((options) => {
38
- return {
39
- vite: {
40
- plugins: [ThemeYunVitePlugin(options)],
41
- },
42
- }
43
- })
2
+ export * from '../types/index.d'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valaxy-theme-press",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Docs Theme for Valaxy",
5
5
  "author": {
6
6
  "email": "me@yunyoujun.cn",
@@ -14,24 +14,25 @@
14
14
  "url": "https://github.com/YunYouJun/valaxy/tree/main/packages/valaxy-theme-press"
15
15
  },
16
16
  "exports": {
17
- ".": {
18
- "require": "./dist/index.js",
19
- "import": "./dist/index.mjs"
20
- },
21
17
  "./*": "./*"
22
18
  },
23
- "main": "dist/index.js",
24
- "module": "dist/index.mjs",
25
- "types": "dist/index.d.ts",
19
+ "main": "node/index.ts",
20
+ "types": "types/index.d.ts",
26
21
  "dependencies": {
27
- "@docsearch/css": "^3.1.1",
28
- "@docsearch/js": "^3.1.1"
22
+ "@docsearch/css": "^3.3.0",
23
+ "@docsearch/js": "^3.3.0"
29
24
  },
30
25
  "devDependencies": {
31
- "valaxy": "0.9.0"
26
+ "valaxy": "workspace:*"
32
27
  },
33
- "scripts": {
34
- "build": "rimraf dist && tsup",
35
- "dev": "tsup --watch"
28
+ "pnpm": {
29
+ "peerDependencyRules": {
30
+ "ignoreMissing": [
31
+ "@algolia/client-search",
32
+ "@types/react",
33
+ "react",
34
+ "react-dom"
35
+ ]
36
+ }
36
37
  }
37
- }
38
+ }
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import { useI18n } from 'vue-i18n'
3
+ const { t } = useI18n()
4
+ </script>
5
+
6
+ <template>
7
+ <div>
8
+ {{ t('not-found') }}
9
+ </div>
10
+ </template>
11
+
12
+ <route lang="yaml">
13
+ meta:
14
+ layout: 404
15
+ </route>
package/setup/main.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { defineAppSetup } from 'valaxy'
2
+ import { nextTick } from 'vue'
3
+
4
+ export default defineAppSetup((ctx) => {
5
+ const { router, isClient } = ctx
6
+ if (!isClient)
7
+ return
8
+
9
+ window.addEventListener(
10
+ 'click',
11
+ (e) => {
12
+ const link = (e.target as Element).closest('a')
13
+ if (link) {
14
+ const { protocol, hostname, pathname, hash, target } = link
15
+ const currentUrl = window.location
16
+ const extMatch = pathname.match(/\.\w+$/)
17
+ // only intercept inbound links
18
+ if (
19
+ !e.ctrlKey
20
+ && !e.shiftKey
21
+ && !e.altKey
22
+ && !e.metaKey
23
+ && target !== '_blank'
24
+ && protocol === currentUrl.protocol
25
+ && hostname === currentUrl.hostname
26
+ && !(extMatch && extMatch[0] !== '.html')
27
+ ) {
28
+ if (pathname === currentUrl.pathname) {
29
+ e.preventDefault()
30
+ // scroll between hash anchors in the same page
31
+ if (hash && hash !== currentUrl.hash) {
32
+ history.pushState(null, '', hash)
33
+ // still emit the event so we can listen to it in themes
34
+ window.dispatchEvent(new Event('hashchange'))
35
+ // use smooth scroll when clicking on header anchor links
36
+ scrollTo(link, hash, link.classList.contains('header-anchor'))
37
+ }
38
+ }
39
+ }
40
+ }
41
+ },
42
+ { capture: true },
43
+ )
44
+
45
+ window.addEventListener('hashchange', (e) => {
46
+ e.preventDefault()
47
+ })
48
+
49
+ router.beforeEach((to, from) => {
50
+ if (to.path !== from.path)
51
+ return
52
+
53
+ nextTick(() => {
54
+ scrollTo(document.body, to.hash, true)
55
+ })
56
+ })
57
+ })
58
+
59
+ function scrollTo(el: HTMLElement, hash: string, smooth = false) {
60
+ let target: Element | null = null
61
+ try {
62
+ target = el.classList.contains('header-anchor')
63
+ ? el
64
+ : (decodeURIComponent(hash) && document.querySelector(decodeURIComponent(hash))) || null
65
+ }
66
+ catch (e) {
67
+ console.warn(e)
68
+ }
69
+
70
+ if (target) {
71
+ const targetPadding = -64
72
+ const targetTop
73
+ = window.scrollY
74
+ + (target as HTMLElement).getBoundingClientRect().top
75
+ + targetPadding
76
+
77
+ // only smooth scroll if distance is smaller than screen height.
78
+ if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) {
79
+ window.scrollTo(0, targetTop)
80
+ }
81
+ else {
82
+ window.scrollTo({
83
+ left: 0,
84
+ top: targetTop,
85
+ behavior: 'smooth',
86
+ })
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,46 @@
1
+ :root {
2
+ --pr-c-indigo-lighter: #c9def1;
3
+ }
4
+
5
+ :root {
6
+ --pr-c-text-code: #374562;
7
+ --pr-c-text-1: #213547;
8
+
9
+ // aside
10
+ --pr-aside-text-1: var(--pr-c-text-1);
11
+ --pr-aside-text-2: rgba(60, 60, 60, 0.702);
12
+
13
+ --pr-aside-divider: rgba(60, 60, 60, 0.122);
14
+
15
+ --pr-c-divider-light: rgba(60, 60, 60, 0.12);
16
+
17
+ // nav
18
+ --pr-nav-height: var(--pr-nav-height-mobile);
19
+ --pr-nav-height-mobile: 60px;
20
+ --pr-nav-text: var(--pr-c-text-1);
21
+
22
+ // z-index
23
+ --va-z-overlay: var(--pr-z-index-backdrop);
24
+ --pr-z-index-local-nav: 8;
25
+ --pr-z-index-nav: 9;
26
+ --pr-z-index-backdrop: 10;
27
+ --pr-z-index-aside: 11;
28
+ --pr-z-index-sidebar: 12;
29
+
30
+ // switch
31
+ --pr-switch-divider: rgba(60, 60, 60, 0.29);
32
+ --pr-switch-bg: #f1f1f1;
33
+ }
34
+
35
+ .dark {
36
+ --pr-c-text-code: var(--pr-c-indigo-lighter);
37
+ --pr-c-text-1: #ffffffde;
38
+
39
+ // aside
40
+ --pr-aside-text-2: #ebebeb99;
41
+ --pr-aside-divider: rgba(84, 84, 84, 0.48);
42
+
43
+ // switch
44
+ --pr-switch-divider: rgba(84, 84, 84, 0.65);
45
+ --pr-switch-bg: #3a3a3a;
46
+ }
@@ -0,0 +1,34 @@
1
+ .gradient-text {
2
+ background-clip: text;
3
+ -webkit-background-clip: text;
4
+ -webkit-text-fill-color: transparent;
5
+ }
6
+
7
+ .sese-btn {
8
+ position: relative;
9
+ z-index: 0;
10
+
11
+ @apply transition;
12
+
13
+ &:hover {
14
+ @apply shadow;
15
+ }
16
+ }
17
+
18
+ .press-icon-btn {
19
+ cursor: pointer;
20
+
21
+ display: inline-flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+
25
+ border: none;
26
+ width: 3rem;
27
+ height: 3rem;
28
+
29
+ border-radius: 50%;
30
+
31
+ div {
32
+ font-size: 1.2rem;
33
+ }
34
+ }
@@ -0,0 +1,7 @@
1
+ @use "./helper.scss";
2
+ @use "./markdown.scss";
3
+
4
+ .layout {
5
+ display: flex;
6
+ flex-direction: column;
7
+ }