xs-dev 0.25.4 → 0.25.6

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 (55) hide show
  1. package/README.md +27 -1
  2. package/docs/astro.config.mjs +39 -8
  3. package/docs/public/favicon.ico +0 -0
  4. package/docs/public/favicon.svg +25 -0
  5. package/docs/src/assets/Chip.svg +25 -0
  6. package/docs/src/assets/Chip.webp +0 -0
  7. package/docs/src/assets/Logo.svg +113 -0
  8. package/docs/src/assets/Logo.webp +0 -0
  9. package/docs/src/assets/houston.webp +0 -0
  10. package/docs/src/components/YoutubeEmbed.astro +13 -0
  11. package/docs/src/content/config.ts +7 -0
  12. package/docs/src/{pages/en → content/docs}/features/doctor.md +0 -1
  13. package/docs/src/{pages/en → content/docs}/features/include.md +0 -1
  14. package/docs/src/{pages/en → content/docs}/features/init.md +0 -1
  15. package/docs/src/{pages/en → content/docs}/features/run.md +0 -1
  16. package/docs/src/{pages/en → content/docs}/features/scan.md +0 -1
  17. package/docs/src/{pages/en → content/docs}/features/setup.md +1 -2
  18. package/docs/src/{pages/en → content/docs}/features/teardown.md +0 -1
  19. package/docs/src/{pages/en → content/docs}/features/update.md +0 -1
  20. package/docs/src/{pages/en → content/docs}/guide/00-prepare.md +1 -2
  21. package/docs/src/{pages/en → content/docs}/guide/01-hello-console.md +0 -1
  22. package/docs/src/{pages/en → content/docs}/guide/02-blinky.md +2 -1
  23. package/docs/src/content/docs/index.mdx +66 -0
  24. package/docs/src/env.d.ts +2 -1
  25. package/docs/tsconfig.json +1 -16
  26. package/package.json +7 -10
  27. package/docs/public/make-scrollable-code-focusable.js +0 -3
  28. package/docs/public/run-hello-world.png +0 -0
  29. package/docs/src/components/Footer/AvatarList.astro +0 -149
  30. package/docs/src/components/Footer/Footer.astro +0 -16
  31. package/docs/src/components/HeadCommon.astro +0 -38
  32. package/docs/src/components/HeadSEO.astro +0 -28
  33. package/docs/src/components/Header/Header.astro +0 -133
  34. package/docs/src/components/Header/LanguageSelect.css +0 -47
  35. package/docs/src/components/Header/LanguageSelect.tsx +0 -47
  36. package/docs/src/components/Header/Search.css +0 -39
  37. package/docs/src/components/Header/Search.tsx +0 -61
  38. package/docs/src/components/Header/SidebarToggle.tsx +0 -43
  39. package/docs/src/components/Header/SkipToContent.astro +0 -22
  40. package/docs/src/components/LeftSidebar/LeftSidebar.astro +0 -118
  41. package/docs/src/components/PageContent/PageContent.astro +0 -40
  42. package/docs/src/components/RightSidebar/MoreMenu.astro +0 -78
  43. package/docs/src/components/RightSidebar/RightSidebar.astro +0 -26
  44. package/docs/src/components/RightSidebar/TableOfContents.tsx +0 -52
  45. package/docs/src/components/RightSidebar/ThemeToggleButton.css +0 -37
  46. package/docs/src/components/RightSidebar/ThemeToggleButton.tsx +0 -75
  47. package/docs/src/config.ts +0 -48
  48. package/docs/src/languages.ts +0 -10
  49. package/docs/src/layouts/MainLayout.astro +0 -122
  50. package/docs/src/pages/en/introduction.md +0 -82
  51. package/docs/src/pages/index.astro +0 -5
  52. package/docs/src/pages/search-index.json.ts +0 -18
  53. package/docs/src/styles/index.css +0 -382
  54. package/docs/src/styles/theme.css +0 -125
  55. package/docs/tailwind.config.cjs +0 -7
@@ -1,3 +0,0 @@
1
- Array.from(document.getElementsByTagName('pre')).forEach((element) => {
2
- element.setAttribute('tabindex', '0')
3
- })
Binary file
@@ -1,149 +0,0 @@
1
- ---
2
- // fetch all commits for just this page's path
3
- const path = 'docs/' + Astro.props.path;
4
- const url = `https://api.github.com/repos/hipsterbrown/xs-dev/commits?path=${path}`;
5
- const commitsURL = `https://github.com/hipsterbrown/xs-dev/commits/main/${path}`;
6
-
7
- async function getCommits(url) {
8
- try {
9
- const token = import.meta.env.PUBLIC_GITHUB_TOKEN;
10
- if (!token) {
11
- throw new Error('Cannot find "PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.');
12
- }
13
-
14
- const auth = `Basic ${Buffer.from(token, 'binary').toString('base64')}`;
15
-
16
- const res = await fetch(url, {
17
- method: 'GET',
18
- headers: {
19
- Authorization: auth,
20
- 'User-Agent': 'astro-docs/1.0',
21
- },
22
- });
23
-
24
- const data = await res.json();
25
-
26
- if (!res.ok) {
27
- throw new Error(
28
- `Request to fetch commits failed. Reason: ${res.statusText}
29
- Message: ${data.message}`
30
- );
31
- }
32
-
33
- return data;
34
- } catch (e) {
35
- console.warn(`[error] /src/components/AvatarList.astro
36
- ${e?.message ?? e}`);
37
- return new Array();
38
- }
39
- }
40
-
41
- function removeDups(arr) {
42
- if (!arr) {
43
- return new Array();
44
- }
45
- let map = new Map();
46
-
47
- for (let item of arr) {
48
- let author = item.author;
49
- // Deduplicate based on author.id
50
- map.set(author.id, { login: author.login, id: author.id });
51
- }
52
-
53
- return Array.from(map.values());
54
- }
55
-
56
- const data = await getCommits(url);
57
- const unique = removeDups(data);
58
- const recentContributors = unique.slice(0, 3); // only show avatars for the 3 most recent contributors
59
- const additionalContributors = unique.length - recentContributors.length; // list the rest of them as # of extra contributors
60
- ---
61
-
62
- <!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
63
- <div class="contributors">
64
- <ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}>
65
- {recentContributors.map((item) => (
66
- <li>
67
- <a href={`https://github.com/${item.login}`}>
68
- <img alt={`Contributor ${item.login}`} title={`Contributor ${item.login}`} width="64" height="64" src={`https://avatars.githubusercontent.com/u/${item.id}`} />
69
- </a>
70
- </li>
71
- ))}
72
- </ul>
73
- {additionalContributors > 0 && (
74
- <span>
75
- <a href={commitsURL}>{`and ${additionalContributors} additional contributor${additionalContributors > 1 ? 's' : ''}.`}</a>
76
- </span>
77
- )}
78
- {unique.length === 0 && <a href={commitsURL}>Contributors</a>}
79
- </div>
80
-
81
- <style>
82
- .avatar-list {
83
- --avatar-size: 2.5rem;
84
- --avatar-count: 3;
85
-
86
- display: grid;
87
- list-style: none;
88
- /* Default to displaying most of the avatar to
89
- enable easier access on touch devices, ensuring
90
- the WCAG touch target size is met or exceeded */
91
- grid-template-columns: repeat(var(--avatar-count), max(44px, calc(var(--avatar-size) / 1.15)));
92
- /* `padding` matches added visual dimensions of
93
- the `box-shadow` to help create a more accurate
94
- computed component size */
95
- padding: 0.08em;
96
- font-size: var(--avatar-size);
97
- }
98
-
99
- @media (any-hover: hover) and (any-pointer: fine) {
100
- .avatar-list {
101
- /* We create 1 extra cell to enable the computed
102
- width to match the final visual width */
103
- grid-template-columns: repeat(calc(var(--avatar-count) + 1), calc(var(--avatar-size) / 1.75));
104
- }
105
- }
106
-
107
- .avatar-list li {
108
- width: var(--avatar-size);
109
- height: var(--avatar-size);
110
- }
111
-
112
- .avatar-list li:hover ~ li a,
113
- .avatar-list li:focus-within ~ li a {
114
- transform: translateX(33%);
115
- }
116
-
117
- .avatar-list img,
118
- .avatar-list a {
119
- display: block;
120
- border-radius: 50%;
121
- }
122
-
123
- .avatar-list a {
124
- transition: transform 180ms ease-in-out;
125
- }
126
-
127
- .avatar-list img {
128
- width: 100%;
129
- height: 100%;
130
- object-fit: cover;
131
- background-color: #fff;
132
- box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
133
- }
134
-
135
- .avatar-list a:focus {
136
- outline: 2px solid transparent;
137
- /* Double-layer trick to work for dark and light backgrounds */
138
- box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
139
- }
140
-
141
- .contributors {
142
- display: flex;
143
- align-items: center;
144
- }
145
-
146
- .contributors > * + * {
147
- margin-left: 0.75rem;
148
- }
149
- </style>
@@ -1,16 +0,0 @@
1
- ---
2
- import AvatarList from './AvatarList.astro';
3
- const { path } = Astro.props;
4
- ---
5
-
6
- <footer>
7
- <AvatarList {path} />
8
- </footer>
9
-
10
- <style>
11
- footer {
12
- margin-top: auto;
13
- padding: 2rem 0;
14
- border-top: 3px solid var(--theme-divider);
15
- }
16
- </style>
@@ -1,38 +0,0 @@
1
- ---
2
- import '../styles/theme.css'
3
- import '../styles/index.css'
4
- ---
5
-
6
- <!-- Global Metadata -->
7
- <meta charset="utf-8" />
8
- <meta name="viewport" content="width=device-width" />
9
-
10
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
11
- <link rel="alternate icon" type="image/x-icon" href="/favicon.ico" />
12
-
13
- <link rel="sitemap" href="/sitemap.xml" />
14
-
15
- <!-- Preload Fonts -->
16
- <link rel="preconnect" href="https://fonts.googleapis.com" />
17
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
18
- <link
19
- href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap"
20
- rel="stylesheet"
21
- />
22
-
23
- <!-- Scrollable a11y code helper -->
24
- <script src="/make-scrollable-code-focusable.js" is:inline></script>
25
-
26
- <!-- This is intentionally inlined to avoid FOUC -->
27
- <script is:inline>
28
- const root = document.documentElement
29
- const theme = localStorage.getItem('theme')
30
- if (
31
- theme === 'dark' ||
32
- (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)
33
- ) {
34
- root.classList.add('theme-dark')
35
- } else {
36
- root.classList.remove('theme-dark')
37
- }
38
- </script>
@@ -1,28 +0,0 @@
1
- ---
2
- import { SITE, OPEN_GRAPH } from '../config.ts';
3
- export interface Props {
4
- content: any;
5
- site: any;
6
- canonicalURL: URL | string;
7
- }
8
- const canonicalURL = new URL(Astro.url.pathname, Astro.site);
9
- const { content = {} } = Astro.props;
10
- const formattedContentTitle = content.title ? `${content.title} 🚀 ${SITE.title}` : SITE.title;
11
- ---
12
-
13
- <!-- Page Metadata -->
14
- <link rel="canonical" href={canonicalURL} />
15
-
16
- <!-- OpenGraph Tags -->
17
- <meta property="og:title" content={formattedContentTitle} />
18
- <meta property="og:type" content="article" />
19
- <meta property="og:url" content={canonicalURL} />
20
- <meta property="og:locale" content={content.ogLocale ?? SITE.defaultLanguage} />
21
- <meta name="description" property="og:description" content={content.description ? content.description : SITE.description} />
22
- <meta property="og:site_name" content={SITE.title} />
23
-
24
- <!-- Twitter Tags -->
25
- <meta name="twitter:card" content="summary_large_image" />
26
- <meta name="twitter:site" content={OPEN_GRAPH.twitter} />
27
- <meta name="twitter:title" content={formattedContentTitle} />
28
- <meta name="twitter:description" content={content.description ? content.description : SITE.description} />
@@ -1,133 +0,0 @@
1
- ---
2
- import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from '../../languages.ts';
3
- import * as CONFIG from '../../config.ts';
4
- import SkipToContent from './SkipToContent.astro';
5
- import SidebarToggle from './SidebarToggle.tsx';
6
- import LanguageSelect from './LanguageSelect.tsx';
7
- import Search from './Search.tsx';
8
-
9
- const { currentPage } = Astro.props;
10
- const lang = currentPage && getLanguageFromURL(currentPage);
11
- ---
12
-
13
- <header>
14
- <SkipToContent />
15
- <nav class="nav-wrapper" title="Top Navigation">
16
- <div class="menu-toggle">
17
- <SidebarToggle client:idle />
18
- </div>
19
- <div class="logo flex">
20
- <a href={import.meta.env.BASE_URL}>
21
- <h1>{CONFIG.SITE.title ?? "Documentation"}</h1>
22
- </a>
23
- </div>
24
- <div style="flex-grow: 1;"></div>
25
- {KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
26
- </nav>
27
- <Search client:idle />
28
- </header>
29
-
30
- <style>
31
- header {
32
- z-index: 11;
33
- height: var(--theme-navbar-height);
34
- width: 100%;
35
- background-color: var(--theme-navbar-bg);
36
- display: flex;
37
- align-items: center;
38
- justify-content: center;
39
- position: sticky;
40
- top: 0;
41
- }
42
-
43
- .logo {
44
- flex: 1;
45
- display: flex;
46
- overflow: hidden;
47
- width: 30px;
48
- font-size: 2rem;
49
- flex-shrink: 0;
50
- font-weight: 600;
51
- line-height: 1;
52
- color: hsla(var(--color-base-white), 100%, 1);
53
- gap: 0.25em;
54
- z-index: -1;
55
- }
56
-
57
- .logo a {
58
- display: flex;
59
- padding: 0.5em 0.25em;
60
- margin: -0.5em -0.25em;
61
- text-decoration: none;
62
- font-weight: bold;
63
- }
64
-
65
- .logo a {
66
- transition: color 100ms ease-out;
67
- color: var(--theme-text);
68
- }
69
-
70
- .logo a:hover,
71
- .logo a:focus {
72
- color: var(--theme-text-accent);
73
- }
74
-
75
- .logo h1 {
76
- display: none;
77
- font: inherit;
78
- color: inherit;
79
- margin: 0;
80
- }
81
-
82
- .nav-wrapper {
83
- display: flex;
84
- align-items: center;
85
- justify-content: flex-end;
86
- gap: 1em;
87
- width: 100%;
88
- max-width: 82em;
89
- padding: 0 1rem;
90
- }
91
-
92
- @media (min-width: 50em) {
93
- header {
94
- position: static;
95
- padding: 2rem 0rem;
96
- }
97
- .logo {
98
- width: auto;
99
- margin: 0;
100
- z-index: 0;
101
- }
102
- .logo h1 {
103
- display: initial;
104
- }
105
- .menu-toggle {
106
- display: none;
107
- }
108
- }
109
-
110
- /** Style Algolia */
111
- :root {
112
- --docsearch-primary-color: var(--theme-accent);
113
- --docsearch-logo-color: var(--theme-text);
114
- }
115
-
116
- .search-item {
117
- display: none;
118
- position: relative;
119
- z-index: 10;
120
- flex-grow: 1;
121
- padding-right: 0.7rem;
122
- display: flex;
123
- max-width: 200px;
124
- }
125
- :global(.search-item > *) {
126
- flex-grow: 1;
127
- }
128
- @media (min-width: 50em) {
129
- .search-item {
130
- max-width: 400px;
131
- }
132
- }
133
- </style>
@@ -1,47 +0,0 @@
1
- .language-select {
2
- flex-grow: 1;
3
- width: 48px;
4
- box-sizing: border-box;
5
- margin: 0;
6
- padding: 0.33em 0.5em;
7
- overflow: visible;
8
- font-weight: 500;
9
- font-size: 1rem;
10
- font-family: inherit;
11
- line-height: inherit;
12
- background-color: var(--theme-bg);
13
- border-color: var(--theme-text-lighter);
14
- color: var(--theme-text-light);
15
- border-style: solid;
16
- border-width: 1px;
17
- border-radius: 0.25rem;
18
- outline: 0;
19
- cursor: pointer;
20
- transition-timing-function: ease-out;
21
- transition-duration: 0.2s;
22
- transition-property: border-color, color;
23
- -webkit-font-smoothing: antialiased;
24
- padding-left: 30px;
25
- padding-right: 1rem;
26
- }
27
- .language-select-wrapper .language-select:hover,
28
- .language-select-wrapper .language-select:focus {
29
- color: var(--theme-text);
30
- border-color: var(--theme-text-light);
31
- }
32
- .language-select-wrapper {
33
- color: var(--theme-text-light);
34
- position: relative;
35
- }
36
- .language-select-wrapper > svg {
37
- position: absolute;
38
- top: 7px;
39
- left: 10px;
40
- pointer-events: none;
41
- }
42
-
43
- @media (min-width: 50em) {
44
- .language-select {
45
- width: 100%;
46
- }
47
- }
@@ -1,47 +0,0 @@
1
- import type { Component } from 'solid-js';
2
- import './LanguageSelect.css';
3
- import { KNOWN_LANGUAGES, langPathRegex } from '../../languages';
4
-
5
- const LanguageSelect: Component<{ lang: string }> = ({ lang }) => {
6
- return (
7
- <div class="language-select-wrapper">
8
- <svg
9
- aria-hidden="true"
10
- role="img"
11
- xmlns="http://www.w3.org/2000/svg"
12
- viewBox="0 0 88.6 77.3"
13
- height="1.2em"
14
- width="1.2em"
15
- >
16
- <path
17
- fill="currentColor"
18
- d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z"
19
- />
20
- <path
21
- fill="currentColor"
22
- d="M53.6,60.6c-10-4-16-9-22-14c0,0,1.3,1.3,0,0c-6,5-20,13-20,13l-4-6c8-5,10-6,19-13c-2.1-1.9-12-13-13-19h8 c4,9,10,14,10,14c10-8,10-19,10-19h8c0,0-1,13-12,24l0,0c5,5,10,9,19,13L53.6,60.6z M1.6,16.6h56v-8h-23v-7h-9v7h-24V16.6z"
23
- />
24
- </svg>
25
- <select
26
- class="language-select"
27
- value={lang}
28
- onChange={(e) => {
29
- const newLang = e.currentTarget.value;
30
- let actualDest = window.location.pathname.replace(langPathRegex, '/');
31
- if (actualDest == '/') actualDest = `/introduction`;
32
- window.location.pathname = '/' + newLang + actualDest;
33
- }}
34
- >
35
- {Object.keys(KNOWN_LANGUAGES).map((key) => {
36
- return (
37
- <option value={KNOWN_LANGUAGES[key]}>
38
- {key}
39
- </option>
40
- );
41
- })}
42
- </select>
43
- </div>
44
- );
45
- };
46
-
47
- export default LanguageSelect;
@@ -1,39 +0,0 @@
1
- .flex-column {
2
- flex-direction: column;
3
- }
4
-
5
- .SearchContainer {
6
- position: relative;
7
- }
8
-
9
- .SearchContainer-input {
10
- border: 1px solid #333333;
11
- padding: 0.5rem 1rem;
12
- }
13
-
14
- .SearchContainer-button {
15
- border-radius: 0px;
16
- padding: 0.5rem;
17
- }
18
-
19
- .SearchContainer-list {
20
- background: white;
21
- top: 2.6rem;
22
- display: flex;
23
- flex-direction: column;
24
- left: 0;
25
- position: absolute;
26
- width: 100%;
27
- }
28
-
29
- .SearchContainer-list.has-results {
30
- border: 1px solid #333333;
31
- }
32
-
33
- .SearchContainer-list_item {
34
- padding: 0.5rem 1rem;
35
- }
36
-
37
- .SearchContainer-link {
38
- color: blue;
39
- }
@@ -1,61 +0,0 @@
1
- import { type Component, createSignal, For, onMount } from 'solid-js';
2
- import Fuse from 'fuse.js'
3
- import './Search.css'
4
-
5
- const SearchForm: Component = () => {
6
- let fuse: null | Fuse<{ url: string, title: string }> = null;
7
- const [results, setResults] = createSignal([]);
8
-
9
- const searchContent = (event: SubmitEvent) => {
10
- event.preventDefault()
11
- const { search } = Object.fromEntries(
12
- new FormData(event.currentTarget as HTMLFormElement)
13
- )
14
- const result = fuse.search(search as string)
15
- setResults(result.map(({ item }) => item))
16
- }
17
-
18
- onMount(async () => {
19
- const content = await fetch('/search-index.json')
20
- .then((res) => res.json())
21
- const options = { keys: ['title', 'description', 'content'] }
22
- fuse = new Fuse(content, options)
23
- })
24
-
25
- return (
26
- <div class="flex flex-column SearchContainer">
27
- <form method="get" id="search-form" onSubmit={searchContent}>
28
- <div role="search" class="flex flex-row">
29
- <input
30
- type="search"
31
- id="search"
32
- name="search"
33
- aria-label="search documentation content"
34
- placeholder="search documentation content"
35
- class="SearchContainer-input"
36
- />
37
- <button type="submit" class="SearchContainer-button">
38
- Search
39
- </button>
40
- </div>
41
- </form>
42
- <ul
43
- classList={{ 'SearchContainer-list': true, 'has-results': results().length > 0 }}
44
- aria-live="assertive"
45
- aria-atomic="true"
46
- >
47
- <For each={results()}>
48
- {(result) => (
49
- <li class="SearchContainer-list_item">
50
- <a href={result.url} class="SearchContainer-link">
51
- {result.title}
52
- </a>
53
- </li>
54
- )}
55
- </For>
56
- </ul>
57
- </div>
58
- )
59
- }
60
-
61
- export default SearchForm
@@ -1,43 +0,0 @@
1
- import { type Component, createSignal, createEffect } from 'solid-js';
2
-
3
- const MenuToggle: Component = () => {
4
- const [sidebarShown, setSidebarShown] = createSignal(false);
5
-
6
- createEffect(() => {
7
- const [body] = document.getElementsByTagName('body');
8
- const showSidebar = sidebarShown();
9
- if (showSidebar) {
10
- body.classList.add('mobile-sidebar-toggle');
11
- } else {
12
- body.classList.remove('mobile-sidebar-toggle');
13
- }
14
- });
15
-
16
- return (
17
- <button
18
- type="button"
19
- aria-pressed={sidebarShown() ? 'true' : 'false'}
20
- id="menu-toggle"
21
- onClick={() => setSidebarShown(current => !current)}
22
- >
23
- <svg
24
- xmlns="http://www.w3.org/2000/svg"
25
- width="1em"
26
- height="1em"
27
- fill="none"
28
- viewBox="0 0 24 24"
29
- stroke="currentColor"
30
- >
31
- <path
32
- stroke-linecap="round"
33
- stroke-linejoin="round"
34
- stroke-width="2"
35
- d="M4 6h16M4 12h16M4 18h16"
36
- />
37
- </svg>
38
- <span class="sr-only">Toggle sidebar</span>
39
- </button>
40
- );
41
- };
42
-
43
- export default MenuToggle;
@@ -1,22 +0,0 @@
1
- <a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
2
-
3
- <style>
4
- .skiplink,
5
- .skiplink:focus,
6
- .skiplink:focus-visible {
7
- position: absolute;
8
- padding: 0.25em;
9
- font-size: larger;
10
- top: 0;
11
- left: 0;
12
- right: 0;
13
- z-index: 9;
14
- display: block;
15
- text-align: center;
16
- background-color: var(--theme-text-accent);
17
- color: var(--theme-bg);
18
- border-radius: 0.25em;
19
- outline: var(--theme-bg) solid 1px;
20
- outline-offset: 0;
21
- }
22
- </style>