@chassis-ui/docs 0.2.0 → 0.3.0

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 (74) hide show
  1. package/README.md +16 -16
  2. package/index.ts +6 -1
  3. package/package.json +20 -8
  4. package/src/components/DocsSidebar.astro +63 -23
  5. package/src/components/FeatureCard.astro +3 -3
  6. package/src/components/TableOfContents.astro +8 -7
  7. package/src/components/ThemeToggler.astro +15 -36
  8. package/src/components/shortcodes/Blockquote.astro +1 -1
  9. package/src/components/shortcodes/CSSOnly.astro +6 -2
  10. package/src/components/shortcodes/Callout.astro +6 -2
  11. package/src/components/shortcodes/Code.astro +289 -0
  12. package/src/components/shortcodes/DeprecatedIn.astro +5 -2
  13. package/src/components/shortcodes/Example.astro +132 -0
  14. package/src/components/shortcodes/Icon.astro +57 -0
  15. package/src/components/shortcodes/InFigma.astro +7 -2
  16. package/src/components/shortcodes/JsDocs.astro +64 -0
  17. package/src/components/shortcodes/Placeholder.astro +28 -0
  18. package/src/components/shortcodes/ResizableExample.astro +126 -0
  19. package/src/components/shortcodes/ScssDocs.astro +108 -0
  20. package/src/components/shortcodes/ScssDocsSimple.astro +66 -0
  21. package/src/js/color-modes.js +3 -3
  22. package/src/js/example-mode.js +75 -0
  23. package/src/js/search.js +501 -39
  24. package/src/js/theme-color.js +1 -1
  25. package/src/layouts/DocsLayout.astro +11 -14
  26. package/src/layouts/RedirectLayout.astro +1 -0
  27. package/src/layouts/footer/Scripts.astro +14 -9
  28. package/src/layouts/head/Analytics.astro +12 -6
  29. package/src/layouts/head/Favicons.astro +0 -2
  30. package/src/layouts/head/Head.astro +2 -7
  31. package/src/layouts/head/Stylesheet.astro +18 -11
  32. package/src/layouts/header/Header.astro +2 -5
  33. package/src/layouts/header/Navigation.astro +31 -33
  34. package/src/layouts/header/SearchDialog.astro +74 -0
  35. package/src/layouts/header/SearchTrigger.astro +41 -0
  36. package/src/libs/highlight.ts +91 -0
  37. package/src/libs/icon.ts +75 -0
  38. package/src/libs/image.ts +12 -1
  39. package/src/libs/layout.ts +18 -0
  40. package/src/libs/markdown.ts +128 -0
  41. package/src/libs/placeholder.ts +250 -0
  42. package/src/libs/rehype.ts +0 -17
  43. package/src/libs/shortcodes.ts +129 -0
  44. package/src/libs/site.ts +95 -0
  45. package/src/libs/toc.ts +40 -6
  46. package/src/libs/utils.ts +34 -82
  47. package/src/libs/vite.ts +45 -0
  48. package/src/scss/_anchor.scss +20 -16
  49. package/src/scss/_callouts.scss +29 -28
  50. package/src/scss/_content.scss +72 -103
  51. package/src/scss/_footer.scss +18 -19
  52. package/src/scss/_layout.scss +56 -63
  53. package/src/scss/_navbar.scss +19 -123
  54. package/src/scss/_placeholder-img.scss +11 -7
  55. package/src/scss/_scrolling.scss +14 -12
  56. package/src/scss/_search.scss +418 -0
  57. package/src/scss/_shiki.scss +120 -0
  58. package/src/scss/_sidebar.scss +137 -132
  59. package/src/scss/_skippy.scss +6 -4
  60. package/src/scss/_snippets.scss +181 -0
  61. package/src/scss/_toc.scss +97 -93
  62. package/src/scss/_vars.scss +89 -0
  63. package/src/scss/main.scss +75 -80
  64. package/src/js/icon-loader.js +0 -229
  65. package/src/libs/chassis.ts +0 -38
  66. package/src/scss/_brand.scss +0 -59
  67. package/src/scss/_buttons.scss +0 -33
  68. package/src/scss/_clipboard-js.scss +0 -63
  69. package/src/scss/_code.scss +0 -116
  70. package/src/scss/_colors.scss +0 -140
  71. package/src/scss/_docsearch.scss +0 -212
  72. package/src/scss/_settings.scss +0 -29
  73. package/src/scss/_syntax.scss +0 -160
  74. package/src/scss/_variables.scss +0 -73
package/src/libs/utils.ts CHANGED
@@ -1,14 +1,20 @@
1
- import os from 'os'
2
1
  import { slug } from 'github-slugger'
3
2
  import { fromMarkdown } from 'mdast-util-from-markdown'
4
3
  import { toString } from 'mdast-util-to-string'
5
4
  import { remark } from 'remark'
6
5
  import remarkHtml from 'remark-html'
7
6
 
7
+ /** Returns `str` with its first character uppercased. */
8
8
  export function capitalizeFirstLetter(str: string) {
9
9
  return str.charAt(0).toUpperCase() + str.slice(1)
10
10
  }
11
11
 
12
+ /**
13
+ * Generates an inclusive numeric sequence from `start` to `end` with the given `step`.
14
+ *
15
+ * @example getSequence(1, 5) // [1, 2, 3, 4, 5]
16
+ * @example getSequence(0, 10, 2) // [0, 2, 4, 6, 8, 10]
17
+ */
12
18
  export function getSequence(start: number, end: number, step = 1) {
13
19
  const sequence = []
14
20
 
@@ -19,107 +25,53 @@ export function getSequence(start: number, end: number, step = 1) {
19
25
  return sequence
20
26
  }
21
27
 
22
- // This function is used in the docs sidebar to generate partial slugs and properly order the sidebar entries and also
23
- // to generate docs frontmatter sections slugs.
24
- // Note: this should be refactored and removed, the sidebar ordering defined in `site/data/sidebar.yml` should not rely
25
- // on slugified custom titles that are expected to generate a string matching the actual file names on disk, this is
26
- // error prone. Instead, custom sidebar titles should be defined in the frontmatter of the MDX files when needed and
27
- // `site/data/sidebar.yml` should only reference the actual file names and slug extracted from the docs content
28
- // collection. Same goes for the docs frontmatter sections.
28
+ /**
29
+ * Converts a string to a URL-safe slug, collapsing consecutive hyphens.
30
+ *
31
+ * Used by the docs sidebar to derive page slugs from sidebar entry titles and
32
+ * by `DocsLayout` to resolve frontmatter section slugs.
33
+ *
34
+ * @remarks
35
+ * **Known limitation:** the sidebar relies on slugified custom titles matching
36
+ * the actual filenames on disk, which is fragile. The long-term fix is to move
37
+ * slug generation into MDX frontmatter and have `sidebar.yml` reference file
38
+ * names directly. See the `DocsSidebar` component for related context.
39
+ */
29
40
  export function getSlug(str: string) {
30
41
  return slug(str).replace(/--+/g, '-')
31
42
  }
32
43
 
44
+ /** Removes leading and trailing slashes from a URL path segment. */
33
45
  export function trimLeadingAndTrailingSlashes(str: string) {
34
46
  return str.replace(/^\/+|\/+$/g, '')
35
47
  }
36
48
 
49
+ /**
50
+ * Strips Markdown formatting from a string, returning plain text.
51
+ * Useful for generating clean meta descriptions from Markdown content.
52
+ */
37
53
  export function stripMarkdown(str: string) {
38
54
  return toString(fromMarkdown(str))
39
55
  }
40
56
 
57
+ /**
58
+ * Converts a Markdown string to an HTML string synchronously.
59
+ * Intended for short inline content such as page descriptions.
60
+ */
41
61
  export function processMarkdownToHtml(markdown: string): string {
42
- // Use remark to process markdown to HTML
43
62
  const result = remark().use(remarkHtml).processSync(markdown)
44
63
  return result.toString()
45
64
  }
46
65
 
66
+ /**
67
+ * Converts a string to title case (first letter of each word uppercased,
68
+ * remaining letters lowercased).
69
+ *
70
+ * @example titleCase('hello world') // 'Hello World'
71
+ */
47
72
  export function titleCase(str: string) {
48
73
  return str.replace(
49
74
  /\w\S*/g,
50
75
  (text) => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase()
51
76
  )
52
77
  }
53
-
54
- /**
55
- * Gets the appropriate host and port for development server
56
- * @returns {object} Object with host and port properties
57
- */
58
- function getDevHost() {
59
- const hasHostFlag = process.argv.includes('--host')
60
- let host = 'localhost'
61
- let port = 4321
62
-
63
- // Check for --port command line argument (e.g., astro dev --port 4322)
64
- const portFlagIndex = process.argv.findIndex((arg) => arg === '--port')
65
- if (portFlagIndex !== -1 && process.argv[portFlagIndex + 1]) {
66
- const cliPort = parseInt(process.argv[portFlagIndex + 1], 10)
67
- if (!isNaN(cliPort) && cliPort > 0 && cliPort < 65536) {
68
- port = cliPort
69
- }
70
- }
71
-
72
- // Check for PORT environment variable (most common way to override port)
73
- if (process.env.PORT) {
74
- const envPort = parseInt(process.env.PORT, 10)
75
- if (!isNaN(envPort) && envPort > 0 && envPort < 65536) {
76
- port = envPort
77
- }
78
- }
79
-
80
- // Determine host based on --host flag
81
- if (hasHostFlag) {
82
- const interfaces = os.networkInterfaces()
83
- for (const iface of Object.values(interfaces).flat()) {
84
- if (iface?.family === 'IPv4' && !iface.internal) {
85
- host = iface.address
86
- break
87
- }
88
- }
89
- }
90
-
91
- return { host, port }
92
- }
93
-
94
- /**
95
- * Determines the site URL based on environment and deployment context
96
- * @returns {string} The appropriate site URL for the current environment
97
- */
98
- export function getSiteUrl(config: any) {
99
- // Check for explicit SITE_URL override first
100
- if (process.env.SITE_URL) {
101
- return process.env.SITE_URL
102
- }
103
-
104
- // Development: Local server with optional network access
105
- if (process.env.NODE_ENV === 'development') {
106
- const { host, port } = getDevHost()
107
- return `http://${host}:${port}`
108
- }
109
-
110
- // Vercel Production: Prefer config.baseURL because it already has the correct
111
- // path-prefixed chassis-ui.com URL (e.g. https://chassis-ui.com/tokens/).
112
- // VERCEL_PROJECT_PRODUCTION_URL is the sub-project's own custom domain
113
- // (e.g. tokens.chassis-ui.com) which is NOT the canonical URL we want in sitemaps.
114
- if (process.env.VERCEL_ENV === 'production') {
115
- return config.baseURL || `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
116
- }
117
-
118
- // Vercel Preview: Branch deployments and previews
119
- if (process.env.VERCEL_URL) {
120
- return `https://${process.env.VERCEL_URL}`
121
- }
122
-
123
- // Fallback: Use baseURL from config.yml
124
- return config.baseURL
125
- }
@@ -0,0 +1,45 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import type { Plugin } from 'vite'
4
+
5
+ // Virtual module URL served by Vite's module graph at /@id/__x00__chassis-bundle.
6
+ // Used to give the browser a single shared ESM instance of the chassis bundle in dev.
7
+ const CHASSIS_BUNDLE_VIRTUAL_URL = '/@id/__x00__chassis-bundle'
8
+
9
+ /**
10
+ * Vite plugin that resolves `@chassis-ui/css` to a virtual module in dev so
11
+ * both the `<script>` tag and any `import()` share one ESM instance.
12
+ *
13
+ * In build, `rollupOptions.external` + `paths` in the consuming `astro.config.ts`
14
+ * handles deduplication instead.
15
+ *
16
+ * @param getChassisCSSFsPath - Returns the absolute path to the compiled Chassis CSS dist folder.
17
+ */
18
+ export function chassisBundlePlugin(getChassisCSSFsPath: () => string) {
19
+ return {
20
+ plugin: {
21
+ name: 'chassis-ui-css',
22
+ enforce: 'pre',
23
+ apply: 'serve',
24
+ resolveId(id: string) {
25
+ if (id === '@chassis-ui/css') return '\0@chassis-ui/css'
26
+ if (id === '/@chassis-bundle') return '\0chassis-bundle'
27
+ },
28
+ load(id: string) {
29
+ if (id === '\0@chassis-ui/css') return `export * from "/@chassis-bundle"`
30
+ if (id === '\0chassis-bundle') {
31
+ const bundlePath = path.join(getChassisCSSFsPath(), 'js/chassis.bundle.js')
32
+ const content = fs.readFileSync(bundlePath, 'utf-8')
33
+ // Strip sourceMappingURL — the map isn't resolvable from a virtual module URL.
34
+ return content.replace(/^\/\/# sourceMappingURL=.+$/m, '')
35
+ }
36
+ }
37
+ } satisfies Plugin,
38
+ // __CHASSIS_JS_SRC__ is a @chassis-ui/docs extension point: sets the URL for the
39
+ // chassis JS <script> tag in dev mode. Points at the virtual module so the browser
40
+ // gets one shared ESM instance instead of a second copy from public/.
41
+ define: {
42
+ 'globalThis.__CHASSIS_JS_SRC__': JSON.stringify(CHASSIS_BUNDLE_VIRTUAL_URL)
43
+ }
44
+ }
45
+ }
@@ -1,21 +1,25 @@
1
- .anchor-link {
2
- padding: 0 .175rem;
3
- font-weight: 400;
4
- color: rgba($link-main, .5);
5
- text-decoration: none;
6
- opacity: 0;
7
- @include transition(color .15s ease-in-out, opacity .15s ease-in-out);
1
+ @use "@chassis-ui/css/scss/config" as *;
2
+ @use "@chassis-ui/css/scss/mixins" as *;
3
+ @use "@chassis-ui/css/scss/functions" as *;
8
4
 
9
- &::after {
10
- content: "#";
11
- }
12
-
13
- &:focus,
14
- &:hover,
15
- :hover > &,
16
- :target > & {
5
+ @layer custom {
6
+ .anchor-link {
7
+ padding: 0 .175rem;
8
+ font-weight: 400;
17
9
  color: $link-main;
18
10
  text-decoration: none;
19
- opacity: 1;
11
+ opacity: 0;
12
+ @include transition(color .15s ease-in-out, opacity .15s ease-in-out);
13
+
14
+ &::after {
15
+ content: "#";
16
+ }
17
+
18
+ &:focus,
19
+ &:hover,
20
+ :hover > &,
21
+ :target > & {
22
+ opacity: 1;
23
+ }
20
24
  }
21
25
  }
@@ -1,40 +1,41 @@
1
+ @use "./vars" as *;
2
+
1
3
  //
2
4
  // Callouts
3
5
  //
4
6
 
5
- .cxd-callout {
6
- --#{$prefix}link-main-color: var(--cxd-callout-link);
7
- --#{$prefix}code-color: var(--cxd-callout-code-color);
8
-
9
- padding: 1.25rem;
10
- margin-top: 1.25rem;
11
- margin-bottom: 1.25rem;
12
- color: var(--cxd-callout-color, inherit);
13
- background-color: var(--cxd-callout-bg, var(--cx-gray-100));
14
- border-left: .25rem solid var(--cxd-callout-border, var(--cx-gray-300));
7
+ @layer custom {
8
+ .cxd-callout {
9
+ padding: 1.25rem;
10
+ margin-block-start: 1.25rem;
11
+ margin-block-end: 1.25rem;
12
+ color: var(--cxd-callout-color, inherit);
13
+ background-color: var(--cxd-callout-bg, var(--cx-neutral-bg-even));
14
+ border-inline-start: .25rem solid var(--cxd-callout-border, var(--cx-neutral-border-main));
15
15
 
16
- h4 {
17
- margin-bottom: .25rem;
18
- }
16
+ h4 {
17
+ margin-block-end: .25rem;
18
+ }
19
19
 
20
- > :last-child {
21
- margin-bottom: 0;
22
- }
20
+ > :last-child {
21
+ margin-block-end: 0;
22
+ }
23
23
 
24
- + .cxd-callout {
25
- margin-top: -.25rem;
26
- }
24
+ + .cxd-callout {
25
+ margin-block-start: -.25rem;
26
+ }
27
27
 
28
- .highlight {
29
- background-color: rgba($black, .05);
28
+ .cxd-code {
29
+ background-color: rgba($black, .05);
30
+ }
30
31
  }
31
- }
32
32
 
33
- // Variations
34
- @each $variant in $cxd-callout-variants {
35
- .cxd-callout-#{$variant} {
36
- --cxd-callout-color: var(--cx-#{$variant}-fg-main);
37
- --cxd-callout-bg: var(--cx-#{$variant}-bg-even);
38
- --cxd-callout-border: var(--cx-#{$variant}-border-subtle);
33
+ // Variations
34
+ @each $variant in $cxd-callout-variants {
35
+ .cxd-callout-#{$variant} {
36
+ --cxd-callout-color: var(--cx-#{$variant}-fg-main);
37
+ --cxd-callout-bg: var(--cx-#{$variant}-bg-even);
38
+ --cxd-callout-border: var(--cx-#{$variant}-border-subtle);
39
+ }
39
40
  }
40
41
  }
@@ -1,141 +1,110 @@
1
+ @use "@chassis-ui/css/scss/config" as *;
2
+ @use "@chassis-ui/css/scss/mixins" as *;
3
+
1
4
  //
2
5
  // Chassis - CSS docs content theming
3
6
  //
4
7
 
5
- .cxd-content {
6
- padding-bottom: 2rem;
7
- > h2,
8
- > h3,
9
- > h4 {
10
- --cx-heading-color: var(--cx-fg-main);
11
- }
12
-
13
- // Offset content from fixed navbar when jumping to headings
14
- > h2:not(:first-child) {
15
- margin-top: 3rem;
16
- }
17
-
18
- > h3 {
19
- margin-top: 2rem;
20
- }
21
-
22
- > ul li,
23
- > ol li {
24
- margin-bottom: .25rem;
8
+ @layer custom {
9
+ .cxd-content {
10
+ padding-block-end: 2rem;
11
+ > h2,
12
+ > h3,
13
+ > h4 {
14
+ --cx-heading-color: var(--cx-fg-main);
15
+ }
25
16
 
26
- // stylelint-disable selector-max-type, selector-max-compound-selectors
27
- > p ~ ul {
28
- margin-top: -.5rem;
29
- margin-bottom: 1rem;
17
+ // Offset content from fixed navbar when jumping to headings
18
+ > h2:not(:first-child) {
19
+ margin-block-start: 3rem;
30
20
  }
31
- // stylelint-enable selector-max-type, selector-max-compound-selectors
32
- }
33
21
 
34
- // Override Chassis - CSS defaults
35
- > .table,
36
- > .table-responsive .table {
37
- // --cx-table-border-color: var(--cx-border-color);
22
+ > h3 {
23
+ margin-block-start: 2rem;
24
+ }
38
25
 
39
- max-width: 100%;
40
- margin-bottom: 1.5rem;
41
- @include font-size(.875rem);
26
+ > ul li,
27
+ > ol li {
28
+ margin-block-end: .25rem;
42
29
 
43
- @include media-breakpoint-down(large) {
44
- &.table-bordered {
45
- border: 0;
30
+ // stylelint-disable-next-line selector-max-type, selector-max-compound-selectors
31
+ > p ~ ul {
32
+ margin-block-start: -.5rem;
33
+ margin-block-end: 1rem;
46
34
  }
47
35
  }
48
36
 
49
- thead {
50
- border-bottom: 2px solid currentcolor;
37
+ > ol > li {
38
+ &:has(:where(h3, h4):first-child)::marker {
39
+ @include font-size(var(--cx-font-size-xlarge));
40
+ font-weight: var(--cx-font-weight-strong);
41
+ }
51
42
  }
52
43
 
53
- tbody:not(:first-child) {
54
- border-top: 2px solid currentcolor;
44
+ // Override Chassis - CSS defaults
45
+ > .table,
46
+ > .table-responsive .table {
47
+ max-width: 100%;
48
+ margin-block-end: 1.5rem;
49
+ th,
50
+ td:first-child > code { // stylelint-disable-line selector-max-compound-selectors
51
+ white-space: nowrap;
52
+ }
55
53
  }
56
54
 
57
- th,
58
- td {
59
- &:first-child {
60
- padding-left: 0;
61
- }
55
+ }
62
56
 
63
- &:not(:last-child) {
64
- padding-right: 1.5rem;
65
- }
57
+ a:has(code) {
58
+ text-decoration: none;
59
+ > code {
60
+ color: var(--cx-link-color);
66
61
  }
62
+ }
67
63
 
68
- th {
69
- color: var(--cx-fg-main);
64
+ .table-options {
65
+ td:nth-child(2) {
66
+ min-width: 160px;
70
67
  }
68
+ }
71
69
 
72
- strong {
70
+ .table-options td:last-child,
71
+ .table-utilities td:last-child {
72
+ min-width: 280px;
73
+ }
74
+
75
+ .table-swatches {
76
+ th {
73
77
  color: var(--cx-fg-main);
74
78
  }
75
79
 
76
- // Prevent breaking of code
77
- th,
78
- td:first-child > code { // stylelint-disable-line selector-max-compound-selectors
80
+ td code {
79
81
  white-space: nowrap;
80
82
  }
81
83
  }
82
- }
83
84
 
84
- .table-options {
85
- td:nth-child(2) {
86
- min-width: 160px;
85
+ .cxd-title {
86
+ --cx-heading-color: var(--cx-fg-main);
87
+ --cx-font-size: 3rem;
87
88
  }
88
- }
89
-
90
- .table-options td:last-child,
91
- .table-utilities td:last-child {
92
- min-width: 280px;
93
- }
94
89
 
95
- .table-swatches {
96
- th {
97
- color: var(--cx-fg-main);
90
+ .cxd-subtitle {
91
+ @include map-font($font-context-lead, "blockquote");
92
+ @include font();
98
93
  }
99
94
 
100
- td code {
101
- white-space: nowrap;
95
+ .border-large-start {
96
+ @include media-breakpoint-up(large) {
97
+ border-inline-start: var(--cx-border-width) solid var(--cx-border-color);
98
+ }
102
99
  }
103
- }
104
100
 
105
- .cxd-title {
106
- --cx-heading-color: var(--cx-fg-main);
107
- --cx-font-size: 3rem;
108
- }
109
-
110
- .cxd-subtitle {
111
- @include map-font($font-context-lead, "blockquote");
112
- @include font();
113
- // font-size: 1.2rem;
114
- // line-height: 1.5em;
115
- // font-family: var(--cx-font-family-display) !important;
116
- }
117
-
118
- .bi {
119
- width: 1em;
120
- height: 1em;
121
- vertical-align: -.125em;
122
- fill: currentcolor;
123
- }
101
+ .cxd-summary-link {
102
+ color: var(--cx-link-color);
124
103
 
125
- .border-large-start {
126
- @include media-breakpoint-up(large) {
127
- border-left: var(--cx-border-width) solid var(--cx-border-color);
104
+ &:hover,
105
+ details[open] > & { // stylelint-disable-line selector-no-qualifying-type
106
+ color: var(--cx-hover-color);
107
+ }
128
108
  }
129
- }
130
-
131
- // stylelint-disable selector-no-qualifying-type
132
- .cxd-summary-link {
133
- color: var(--cx-link-color);
134
109
 
135
- &:hover,
136
- details[open] > & {
137
- color: var(--cx-hover-color);
138
- }
139
110
  }
140
- // stylelint-enable selector-no-qualifying-type
141
-
@@ -2,28 +2,27 @@
2
2
  // Footer
3
3
  //
4
4
 
5
- .cxd-footer {
6
- // margin-top: 0 !important;
7
- // margin-top: 4rem;
8
- --cx-fg-color: var(--cx-fg-subtle);
9
- background-color: var(--cx-bg-evident);
10
- // border-top: var(--cx-border-width) var(--cx-border-style) var(--cx-border-subtle);
11
- .nav {
12
- display: block;
13
- > li {
14
- display: list-item;
15
- margin-bottom: var(--cx-space-xsmall);
5
+ @layer custom {
6
+ .cxd-footer {
7
+ --cx-fg-color: var(--cx-fg-subtle);
8
+ background-color: var(--cx-bg-evident);
9
+ .nav {
10
+ display: block;
11
+ > li {
12
+ display: list-item;
13
+ margin-block-end: var(--cx-space-xsmall);
14
+ }
16
15
  }
17
- }
18
16
 
19
- a {
20
- color: var(--cx-fg-color);
21
- text-decoration: none;
17
+ a {
18
+ color: var(--cx-fg-color);
19
+ text-decoration: none;
22
20
 
23
- &:hover,
24
- &:focus {
25
- color: var(--cx-hover-color);
26
- text-decoration: underline;
21
+ &:hover,
22
+ &:focus {
23
+ color: var(--cx-hover-color);
24
+ text-decoration: underline;
25
+ }
27
26
  }
28
27
  }
29
28
  }