@knitli/docs-components 1.0.4 → 1.1.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.
package/package.json CHANGED
@@ -4,7 +4,10 @@
4
4
  "dependencies": {
5
5
  "astro": "catalog:astro-core",
6
6
  "lightningcss": "catalog:optimization",
7
- "svgo": "catalog:optimization"
7
+ "svgo": "catalog:optimization",
8
+ "@knitli/shared-layouts": "workspace:*",
9
+ "@knitli/shared-file-types": "workspace:*",
10
+ "@knitli/tsconfig": "workspace:*"
8
11
 
9
12
  },
10
13
  "devDependencies": {
@@ -12,20 +15,20 @@
12
15
  "auto-changelog": "^2.4.0",
13
16
  "typescript": "catalog:dev-common",
14
17
  "bun": "catalog:dev-common",
18
+ "vitest": "catalog:dev-common",
15
19
  "@biomejs/biome": "catalog:dev-common",
16
20
  "@types/node": "catalog:types",
17
21
  "@knitli/tsconfig": "*"
18
22
  },
19
23
  "engine": {
20
- "node": ">=24.0.0"
24
+ "node": "catalog:"
21
25
  },
22
26
  "exports": {
23
27
  ".": "./dist/index.js",
24
28
  "./DocsBreadcrumb.astro": "./src/components/DocsBreadcrumb.astro",
25
- "./DocsFooter.astro": "./src/components/DocsFooter.astro",
26
- "./DocsHeader.astro": "./src/components/DocsHeader.astro",
29
+ "./Footer.astro": "./src/components/Footer.astro",
30
+ "./PageFrame.astro": "./src/components/PageFrame.astro",
27
31
  "./logos/*": "./src/assets/logos/*",
28
- "./styles/copper.css": "./src/styles/copper-archive.css",
29
32
  "./styles/theme.css": "./src/styles/docs-theme.css",
30
33
  "./styles/variables.css": "./src/styles/variables.css"
31
34
  },
@@ -47,6 +50,7 @@
47
50
  "main": "./dist/index.js",
48
51
  "name": "@knitli/docs-components",
49
52
  "peerDependencies": {
53
+ "@astrojs/starlight": ">=0.30.0",
50
54
  "astro": "^5.0.0"
51
55
  },
52
56
  "repository": {
@@ -62,5 +66,5 @@
62
66
  },
63
67
  "type": "module",
64
68
  "types": "./dist/index.d.ts",
65
- "version": "1.0.4"
69
+ "version": "1.1.0"
66
70
  }
@@ -3,19 +3,18 @@
3
3
  // SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
4
4
  //
5
5
  // SPDX-License-Identifier: MIT OR Apache-2.0
6
- //
7
- // Optional breadcrumb component for product-specific navigation
8
6
 
9
7
  interface Props {
10
8
  product?: 'ReCoco' | 'CodeWeaver' | 'Thread';
11
9
  productUrl?: string;
12
10
  path?: string;
13
- variant?: 'default' | 'compact';
11
+ /** 'inline' no padding, designed for embedding in a subnav bar */
12
+ variant?: 'default' | 'compact' | 'inline';
14
13
  }
15
14
 
16
15
  const {
17
16
  product,
18
- productUrl = product ? `/${product}` : '',
17
+ productUrl = '/',
19
18
  path = '',
20
19
  variant = 'default',
21
20
  } = Astro.props;
@@ -24,40 +23,39 @@ const {
24
23
  const segments = path
25
24
  .split('/')
26
25
  .filter(Boolean)
27
- .map((segment) => ({
26
+ .map((segment, index, all) => ({
28
27
  name: segment.replace(/-/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()),
29
- path: segment,
28
+ href: `${productUrl}${all.slice(0, index + 1).join('/')}`,
29
+ isLast: index === all.length - 1,
30
30
  }));
31
31
  ---
32
32
 
33
33
  {product && (
34
34
  <nav
35
- class:list={['docs-breadcrumb-nav', { compact: variant === 'compact' }]}
35
+ class:list={['docs-breadcrumb-nav', variant]}
36
36
  aria-label="Breadcrumb"
37
37
  >
38
38
  <ol class="breadcrumb-list">
39
39
  <li class="breadcrumb-item">
40
- <a href="/">Documentation</a>
40
+ <a href="https://docs.knitli.com">Documentation</a>
41
41
  </li>
42
42
 
43
- <li class="breadcrumb-separator" aria-hidden="true">→</li>
43
+ <li class="breadcrumb-separator" aria-hidden="true">›</li>
44
44
 
45
45
  <li class="breadcrumb-item">
46
- {productUrl ? (
46
+ {segments.length > 0 ? (
47
47
  <a href={productUrl}>{product}</a>
48
48
  ) : (
49
- <span class="breadcrumb-current">{product}</span>
49
+ <span class="breadcrumb-current" aria-current="page">{product}</span>
50
50
  )}
51
51
  </li>
52
52
 
53
- {segments.map((segment, index) => (
53
+ {segments.map((segment) => (
54
54
  <>
55
- <li class="breadcrumb-separator" aria-hidden="true">→</li>
55
+ <li class="breadcrumb-separator" aria-hidden="true">›</li>
56
56
  <li class="breadcrumb-item">
57
- {index < segments.length - 1 ? (
58
- <a href={`${productUrl}/${segments.slice(0, index + 1).map((s) => s.path).join('/')}`}>
59
- {segment.name}
60
- </a>
57
+ {!segment.isLast ? (
58
+ <a href={segment.href}>{segment.name}</a>
61
59
  ) : (
62
60
  <span class="breadcrumb-current" aria-current="page">
63
61
  {segment.name}
@@ -71,83 +69,82 @@ const segments = path
71
69
  )}
72
70
 
73
71
  <style>
74
- :root {
75
- --docs-copper: oklch(0.58 0.08 50);
76
- --docs-slate: oklch(0.35 0.02 240);
77
- --docs-parchment: oklch(0.96 0.015 70);
72
+ .docs-breadcrumb-nav {
73
+ font-size: var(--sl-text-xs);
78
74
  }
79
75
 
80
- .docs-breadcrumb-nav {
76
+ .docs-breadcrumb-nav.default {
81
77
  padding: 1rem 0;
82
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
83
78
  }
84
79
 
85
80
  .docs-breadcrumb-nav.compact {
86
81
  padding: 0.5rem 0;
87
82
  }
88
83
 
84
+ /* inline: no padding, fits inside a subnav bar */
85
+ .docs-breadcrumb-nav.inline {
86
+ padding: 0;
87
+ display: flex;
88
+ align-items: center;
89
+ height: 100%;
90
+ min-width: 0;
91
+ overflow: hidden;
92
+ }
93
+
89
94
  .breadcrumb-list {
90
95
  display: flex;
91
- flex-wrap: wrap;
96
+ flex-wrap: nowrap;
92
97
  align-items: center;
93
- gap: 0.5rem;
98
+ gap: 0.35rem;
94
99
  list-style: none;
95
100
  margin: 0;
96
101
  padding: 0;
102
+ min-width: 0;
103
+ overflow: hidden;
97
104
  }
98
105
 
99
106
  .breadcrumb-item {
100
- font-size: 0.875rem;
107
+ font-size: inherit;
108
+ white-space: nowrap;
109
+ overflow: hidden;
110
+ text-overflow: ellipsis;
111
+ }
112
+
113
+ /* Only ellipsis the last item — earlier ones can wrap/hide naturally */
114
+ .breadcrumb-item:last-child {
115
+ min-width: 0;
101
116
  }
102
117
 
103
118
  .breadcrumb-item a {
104
- color: var(--docs-slate);
119
+ color: var(--sl-color-gray-3);
105
120
  text-decoration: none;
106
- opacity: 0.7;
107
- transition: all 0.2s ease;
121
+ transition: color 0.15s ease;
108
122
  }
109
123
 
110
124
  .breadcrumb-item a:hover {
111
- opacity: 1;
112
- text-decoration: underline;
113
- color: var(--docs-copper);
125
+ color: var(--sl-color-gray-1);
126
+ text-decoration: none;
114
127
  }
115
128
 
116
129
  .breadcrumb-current {
117
- color: var(--docs-slate);
130
+ color: var(--sl-color-gray-2);
118
131
  font-weight: 500;
119
132
  }
120
133
 
121
134
  .breadcrumb-separator {
122
- color: var(--docs-slate);
123
- opacity: 0.4;
124
- font-size: 0.875rem;
125
- }
126
-
127
- /* Mobile Responsive */
128
- @media (max-width: 768px) {
129
- .breadcrumb-list {
130
- gap: 0.375rem;
131
- font-size: 0.8125rem;
132
- }
133
-
134
- .breadcrumb-item,
135
- .breadcrumb-separator {
136
- font-size: 0.8125rem;
137
- }
135
+ color: var(--sl-color-gray-5);
136
+ font-size: inherit;
137
+ flex-shrink: 0;
138
138
  }
139
139
 
140
- /* Accessibility */
141
140
  .breadcrumb-item a:focus-visible {
142
- outline: 3px solid var(--docs-copper);
143
- outline-offset: 4px;
144
- border-radius: 4px;
141
+ outline: 2px solid var(--sl-color-accent);
142
+ outline-offset: 2px;
143
+ border-radius: 2px;
145
144
  }
146
145
 
147
- /* Reduced motion */
148
146
  @media (prefers-reduced-motion: reduce) {
149
- * {
150
- animation-duration: 0.01ms !important;
147
+ .breadcrumb-item a {
151
148
  transition-duration: 0.01ms !important;
152
149
  }
153
150
  }
@@ -1,181 +1,8 @@
1
1
  ---
2
- // SPDX-FileCopyrightText: 2025 Knitli Inc.
3
- // SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
4
- //
5
- // SPDX-License-Identifier: MIT OR Apache-2.0
6
- //
7
- // Simple footer for Knitli documentation sites
8
-
9
- interface Props {
10
- variant?: 'default' | 'minimal';
11
- }
12
-
13
- const { variant = 'default' } = Astro.props;
14
-
15
- // Environment-aware URL configuration
16
- const isDev = import.meta.env.DEV;
17
-
18
- const getSiteUrls = () => {
19
- if (isDev) {
20
- return {
21
- marketing: import.meta.env.PUBLIC_MARKETING_URL || 'http://localhost:4321',
22
- blog: import.meta.env.PUBLIC_BLOG_URL || 'http://localhost:4322',
23
- docs: import.meta.env.PUBLIC_DOCS_URL || 'http://localhost:4323',
24
- };
25
- }
26
-
27
- return {
28
- marketing: 'https://knitli.com',
29
- blog: 'https://blog.knitli.com',
30
- docs: 'https://docs.knitli.com',
31
- };
32
- };
33
-
34
- const urls = getSiteUrls();
35
- const currentYear = new Date().getFullYear();
2
+ // DEPRECATED This component has been removed.
3
+ // Use Footer.astro instead:
4
+ // starlight({ components: { Footer: '@knitli/docs-components/Footer.astro' } })
5
+ throw new Error(
6
+ '@knitli/docs-components: DocsFooter has been removed. Use Footer.astro instead.'
7
+ );
36
8
  ---
37
-
38
- <footer class:list={['docs-footer', { minimal: variant === 'minimal' }]}>
39
- <div class="footer-content">
40
- {variant === 'default' && (
41
- <nav class="footer-nav" aria-label="Footer navigation">
42
- <a href={urls.marketing}>Main Site</a>
43
- <a href={urls.blog}>Blog</a>
44
- <a href="https://github.com/knitli" target="_blank" rel="noopener noreferrer">
45
- GitHub
46
- </a>
47
- <a href={`${urls.marketing}/privacy`}>Privacy</a>
48
- </nav>
49
- )}
50
-
51
- <div class="footer-legal">
52
- <p class="copyright">
53
- © {currentYear} <a href={urls.marketing}>Knitli Inc.</a> All rights reserved.
54
- </p>
55
- {variant === 'default' && (
56
- <p class="license">
57
- Documentation licensed under{' '}
58
- <a
59
- href="https://github.com/knitli/knitli-site/blob/main/LICENSE"
60
- target="_blank"
61
- rel="noopener noreferrer"
62
- >
63
- MIT OR Apache-2.0
64
- </a>
65
- </p>
66
- )}
67
- </div>
68
- </div>
69
- </footer>
70
-
71
- <style>
72
- :root {
73
- --docs-copper: oklch(0.58 0.08 50);
74
- --docs-slate: oklch(0.35 0.02 240);
75
- --docs-parchment: oklch(0.96 0.015 70);
76
- }
77
-
78
- .docs-footer {
79
- background: var(--docs-parchment);
80
- border-top: 1px solid oklch(0.85 0.01 50);
81
- margin-top: 4rem;
82
- padding: 2rem 0;
83
- }
84
-
85
- .docs-footer.minimal {
86
- margin-top: 2rem;
87
- padding: 1rem 0;
88
- }
89
-
90
- .footer-content {
91
- max-width: 1400px;
92
- margin: 0 auto;
93
- padding: 0 2rem;
94
- display: flex;
95
- flex-direction: column;
96
- gap: 1.5rem;
97
- align-items: center;
98
- }
99
-
100
- .footer-nav {
101
- display: flex;
102
- gap: 2rem;
103
- align-items: center;
104
- flex-wrap: wrap;
105
- justify-content: center;
106
- }
107
-
108
- .footer-nav a {
109
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
110
- font-size: 0.875rem;
111
- color: var(--docs-slate);
112
- text-decoration: none;
113
- transition: color 0.2s ease;
114
- }
115
-
116
- .footer-nav a:hover {
117
- color: var(--docs-copper);
118
- }
119
-
120
- .footer-legal {
121
- display: flex;
122
- flex-direction: column;
123
- gap: 0.5rem;
124
- text-align: center;
125
- }
126
-
127
- .copyright,
128
- .license {
129
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
130
- font-size: 0.8125rem;
131
- color: var(--docs-slate);
132
- opacity: 0.7;
133
- margin: 0;
134
- }
135
-
136
- .copyright a,
137
- .license a {
138
- color: inherit;
139
- text-decoration: none;
140
- transition: opacity 0.2s ease;
141
- }
142
-
143
- .copyright a:hover,
144
- .license a:hover {
145
- opacity: 1;
146
- text-decoration: underline;
147
- }
148
-
149
- /* Mobile Responsive */
150
- @media (max-width: 768px) {
151
- .footer-content {
152
- padding: 0 1rem;
153
- }
154
-
155
- .footer-nav {
156
- gap: 1rem;
157
- flex-direction: column;
158
- }
159
-
160
- .footer-legal {
161
- font-size: 0.75rem;
162
- }
163
- }
164
-
165
- /* Accessibility */
166
- .footer-nav a:focus-visible,
167
- .copyright a:focus-visible,
168
- .license a:focus-visible {
169
- outline: 3px solid var(--docs-copper);
170
- outline-offset: 4px;
171
- border-radius: 4px;
172
- }
173
-
174
- /* Reduced motion */
175
- @media (prefers-reduced-motion: reduce) {
176
- * {
177
- animation-duration: 0.01ms !important;
178
- transition-duration: 0.01ms !important;
179
- }
180
- }
181
- </style>
@@ -1,231 +1,8 @@
1
1
  ---
2
- // Custom header with actual Knitli logo
3
- const { pathname } = Astro.url;
4
-
5
- // Environment-aware URL configuration
6
- const isDev = import.meta.env.DEV;
7
-
8
- const getSiteUrls = () => {
9
- if (isDev) {
10
- return {
11
- marketing: import.meta.env.PUBLIC_MARKETING_URL || 'http://localhost:4321',
12
- blog: import.meta.env.PUBLIC_BLOG_URL || 'http://localhost:4322',
13
- docs: import.meta.env.PUBLIC_DOCS_URL || 'http://localhost:4323',
14
- };
15
- }
16
-
17
- return {
18
- marketing: 'https://knitli.com',
19
- blog: 'https://blog.knitli.com',
20
- docs: 'https://docs.knitli.com',
21
- };
22
- };
23
-
24
- const urls = getSiteUrls();
25
- const isDocsHome = pathname === '/' || pathname === '';
26
- const shouldShowBreadcrumb = !isDocsHome;
27
-
2
+ // DEPRECATED This component has been removed.
3
+ // Use PageFrame.astro instead:
4
+ // starlight({ components: { PageFrame: '@knitli/docs-components/PageFrame.astro' } })
5
+ throw new Error(
6
+ '@knitli/docs-components: DocsHeader has been removed. Use PageFrame.astro instead.'
7
+ );
28
8
  ---
29
-
30
- <header class="docs-header">
31
- <div class="docs-header-content">
32
- <!-- Knitli Logo + Docs Section -->
33
- <a href={urls.marketing} class="docs-logo" aria-label="Knitli home">
34
- <img src={`${import.meta.env.BASE_URL}/knitli-logo.svg`} alt="Knitli" class="logo-icon" />
35
- <span class="logo-text">
36
- <span class="logo-separator">/</span>
37
- <span class="logo-section">docs</span>
38
- </span>
39
- </a>
40
-
41
- <!-- Breadcrumb -->
42
- {shouldShowBreadcrumb && (
43
- <nav class="docs-breadcrumb" aria-label="Breadcrumb">
44
- <a href="/">Documentation</a>
45
- <span class="breadcrumb-separator" aria-hidden="true">→</span>
46
- <a href="/ReCoco" class="breadcrumb-product">
47
- ReCoco
48
- </a>
49
- </nav>
50
- )}
51
-
52
- <div class="spacer"></div>
53
-
54
- <!-- Cross-site Navigation -->
55
- <nav class="docs-nav" aria-label="Site navigation">
56
- <a
57
- href="/"
58
- class:list={[{ active: isDocsHome }]}
59
- aria-current={isDocsHome ? 'page' : undefined}
60
- >
61
- Docs Home
62
- </a>
63
- <a href={urls.marketing}>
64
- Main Site
65
- </a>
66
- <a href={urls.blog}>
67
- Blog
68
- </a>
69
- <a
70
- href="https://github.com/knitli"
71
- class="external"
72
- target="_blank"
73
- rel="noopener noreferrer"
74
- aria-label="Knitli on GitHub (opens in new tab)"
75
- >
76
- GitHub
77
- <span class="external-icon" aria-hidden="true">↗</span>
78
- </a>
79
- </nav>
80
- </div>
81
- </header>
82
-
83
- <style>
84
- .docs-header {
85
- background: white;
86
- border-bottom: 1px solid #e5e7eb;
87
- border-radius: 0 0 6px 2px; /* Chamfered bottom corners only */
88
- position: sticky;
89
- top: 0;
90
- z-index: 100;
91
- }
92
-
93
- .docs-header-content {
94
- max-width: 1400px;
95
- margin: 0 auto;
96
- padding: 1rem 2rem;
97
- display: flex;
98
- align-items: center;
99
- gap: 2rem;
100
- }
101
-
102
- .docs-logo {
103
- display: flex;
104
- align-items: center;
105
- gap: 0.5rem;
106
- text-decoration: none;
107
- transition: opacity 0.2s ease;
108
- }
109
-
110
- .docs-logo:hover {
111
- opacity: 0.8;
112
- }
113
-
114
- .logo-icon {
115
- height: 32px;
116
- width: auto;
117
- flex-shrink: 0;
118
- }
119
-
120
- .logo-text {
121
- font-family: system-ui, -apple-system, sans-serif;
122
- font-size: 1.125rem;
123
- font-weight: 600;
124
- line-height: 1;
125
- color: #374151;
126
- }
127
-
128
- .logo-separator {
129
- color: #9ca3af;
130
- margin: 0 0.5rem;
131
- }
132
-
133
- .logo-section {
134
- color: #6b7280;
135
- }
136
-
137
- .docs-breadcrumb {
138
- display: flex;
139
- align-items: center;
140
- align-self: flex-end;
141
- gap: 0.5rem;
142
- font-size: 0.875rem;
143
- color: #6b7280;
144
- }
145
-
146
- .docs-breadcrumb a {
147
- color: inherit;
148
- text-decoration: none;
149
- transition: color 0.2s ease;
150
- }
151
-
152
- .docs-breadcrumb a:hover {
153
- color: #111827;
154
- text-decoration: underline;
155
- }
156
-
157
- .breadcrumb-separator {
158
- opacity: 0.5;
159
- }
160
-
161
- .breadcrumb-product {
162
- font-weight: 500;
163
- color: #111827;
164
- }
165
-
166
- .spacer {
167
- flex: 1;
168
- }
169
-
170
- .docs-nav {
171
- display: flex;
172
- gap: 2rem;
173
- align-items: center;
174
- }
175
-
176
- .docs-nav a {
177
- font-size: 0.9375rem;
178
- color: #374151;
179
- text-decoration: none;
180
- position: relative;
181
- padding: 0.25rem 0;
182
- transition: color 0.2s ease;
183
- }
184
-
185
- .docs-nav a:hover {
186
- color: #111827;
187
- }
188
-
189
- .docs-nav a.active {
190
- color: #111827;
191
- font-weight: 500;
192
- }
193
-
194
- .docs-nav a.external {
195
- display: inline-flex;
196
- align-items: center;
197
- gap: 0.25rem;
198
- }
199
-
200
- .external-icon {
201
- font-size: 0.75em;
202
- opacity: 0.6;
203
- }
204
-
205
- /* Mobile Responsive */
206
- @media (max-width: 768px) {
207
- .docs-header-content {
208
- flex-wrap: wrap;
209
- padding: 1rem;
210
- gap: 1rem;
211
- }
212
-
213
- .docs-breadcrumb {
214
- order: 3;
215
- width: 100%;
216
- }
217
-
218
- .spacer {
219
- display: none;
220
- }
221
-
222
- .docs-nav {
223
- gap: 1rem;
224
- font-size: 0.875rem;
225
- }
226
-
227
- .logo-icon {
228
- height: 28px;
229
- }
230
- }
231
- </style>
@@ -0,0 +1,244 @@
1
+ ---
2
+ // SPDX-FileCopyrightText: 2025 Knitli Inc.
3
+ // SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
4
+ //
5
+ // SPDX-License-Identifier: MIT OR Apache-2.0
6
+ //
7
+ // Starlight Footer override for Knitli product documentation sites.
8
+ // Renders Starlight's native page-level footer (edit link, last updated,
9
+ // pagination, optional credits) followed by the Knitli site footer.
10
+ //
11
+ // Usage in astro.config.mjs:
12
+ // starlight({ components: { Footer: '@knitli/docs-components/Footer.astro' } })
13
+
14
+ // @ts-expect-error: virtual modules are typed in virtual-internal.d.ts (not in Starlight's public exports map)
15
+ import EditLink from 'virtual:starlight/components/EditLink';
16
+ // @ts-expect-error
17
+ import LastUpdated from 'virtual:starlight/components/LastUpdated';
18
+ // @ts-expect-error
19
+ import Pagination from 'virtual:starlight/components/Pagination';
20
+ // @ts-expect-error
21
+ import config from 'virtual:starlight/user-config';
22
+ import { Icon } from '@astrojs/starlight/components';
23
+
24
+ const currentYear = new Date().getFullYear();
25
+ ---
26
+
27
+ <footer class="sl-flex knitli-page-footer">
28
+
29
+ <!-- Starlight's native page-level footer: edit link, last updated, pagination, optional credits -->
30
+ <div class="sl-flex page-actions">
31
+ <div class="meta sl-flex">
32
+ <EditLink />
33
+ <LastUpdated />
34
+ </div>
35
+ <Pagination />
36
+ {config.credits && (
37
+ <a class="kudos sl-flex" href="https://starlight.astro.build">
38
+ <Icon name="starlight" /> {Astro.locals.t('builtWithStarlight.label')}
39
+ </a>
40
+ )}
41
+ </div>
42
+
43
+ <!-- Knitli site footer -->
44
+ <div class="site-footer sl-flex">
45
+ <div class="footer-content sl-flex">
46
+
47
+ <div class="footer-brand">
48
+ <p class="copyright">© {currentYear} Knitli, Inc. All rights reserved.</p>
49
+ <div class="social-links sl-flex">
50
+ <a href="https://github.com/knitli" aria-label="GitHub" class="social-link" target="_blank" rel="noopener noreferrer">
51
+ <Icon name="github" size="1.1rem" />
52
+ </a>
53
+ <a href="https://x.com/knitli_inc" aria-label="X" class="social-link" target="_blank" rel="noopener noreferrer">
54
+ <Icon name="x.com" size="1.1rem" />
55
+ </a>
56
+ <a href="https://bsky.app/profile/knitli.com" aria-label="Bluesky" class="social-link" target="_blank" rel="noopener noreferrer">
57
+ <Icon name="blueSky" size="1.1rem" />
58
+ </a>
59
+ <a href="https://linkedin.com/company/knitli" aria-label="LinkedIn" class="social-link" target="_blank" rel="noopener noreferrer">
60
+ <Icon name="linkedin" size="1.1rem" />
61
+ </a>
62
+ </div>
63
+ </div>
64
+
65
+ <nav class="footer-nav" aria-label="Knitli">
66
+ <p class="nav-heading">Knitli</p>
67
+ <ul>
68
+ <li><a href="https://knitli.com">knitli.com</a></li>
69
+ <li><a href="https://blog.knitli.com">Blog</a></li>
70
+ </ul>
71
+ </nav>
72
+
73
+ <nav class="footer-nav" aria-label="Documentation">
74
+ <p class="nav-heading">Docs</p>
75
+ <ul>
76
+ <li><a href="https://docs.knitli.com">Developer Docs</a></li>
77
+ <li><a href="https://docs.knitli.com/ReCoco">ReCoco</a></li>
78
+ <li>
79
+ <span class="link-disabled">
80
+ CodeWeaver
81
+ <span class="soon-badge">soon</span>
82
+ </span>
83
+ </li>
84
+ <li>
85
+ <a href="https://docs.rs/thread" target="_blank" rel="noopener noreferrer">
86
+ Thread ↗
87
+ </a>
88
+ </li>
89
+ </ul>
90
+ </nav>
91
+
92
+ </div>
93
+ </div>
94
+
95
+ </footer>
96
+
97
+ <style>
98
+ @layer starlight.core {
99
+ /* ---- Outer wrapper ---- */
100
+ .knitli-page-footer {
101
+ flex-direction: column;
102
+ gap: 0;
103
+ }
104
+
105
+ /* ---- Starlight native page actions (replicated from Starlight's Footer) ---- */
106
+ .page-actions {
107
+ flex-direction: column;
108
+ gap: 1.5rem;
109
+ }
110
+
111
+ .meta {
112
+ gap: 0.75rem 3rem;
113
+ justify-content: space-between;
114
+ flex-wrap: wrap;
115
+ margin-top: 3rem;
116
+ font-size: var(--sl-text-sm);
117
+ color: var(--sl-color-gray-3);
118
+ }
119
+
120
+ .meta > :global(p:only-child) {
121
+ margin-inline-start: auto;
122
+ }
123
+
124
+ .kudos {
125
+ align-items: center;
126
+ gap: 0.5em;
127
+ margin: 1.5rem auto;
128
+ font-size: var(--sl-text-xs);
129
+ text-decoration: none;
130
+ color: var(--sl-color-gray-3);
131
+ }
132
+
133
+ .kudos:hover {
134
+ color: var(--sl-color-white);
135
+ }
136
+
137
+ /* ---- Knitli site footer ---- */
138
+ .site-footer {
139
+ flex-direction: column;
140
+ border-top: 1px solid var(--sl-color-gray-5);
141
+ padding-top: 2rem;
142
+ margin-top: 2rem;
143
+ gap: 1.5rem;
144
+ }
145
+
146
+ .footer-content {
147
+ flex-wrap: wrap;
148
+ gap: 2rem 4rem;
149
+ align-items: flex-start;
150
+ }
151
+
152
+ .footer-brand {
153
+ flex: 1;
154
+ min-width: 200px;
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 0.75rem;
158
+ }
159
+
160
+ .copyright {
161
+ margin: 0;
162
+ font-size: var(--sl-text-sm);
163
+ color: var(--sl-color-gray-3);
164
+ }
165
+
166
+ .social-links {
167
+ gap: 0.75rem;
168
+ align-items: center;
169
+ }
170
+
171
+ .social-link {
172
+ display: flex;
173
+ align-items: center;
174
+ color: var(--sl-color-gray-3);
175
+ text-decoration: none;
176
+ transition: color 0.2s ease;
177
+ }
178
+
179
+ .social-link:hover {
180
+ color: var(--sl-color-accent-high);
181
+ }
182
+
183
+ .footer-nav {
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: 0.5rem;
187
+ }
188
+
189
+ .nav-heading {
190
+ margin: 0 0 0.5rem;
191
+ font-size: var(--sl-text-xs);
192
+ font-weight: 600;
193
+ text-transform: uppercase;
194
+ letter-spacing: 0.08em;
195
+ color: var(--sl-color-accent);
196
+ }
197
+
198
+ .footer-nav ul {
199
+ list-style: none;
200
+ padding: 0;
201
+ margin: 0;
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 0.4rem;
205
+ }
206
+
207
+ .footer-nav a {
208
+ font-size: var(--sl-text-sm);
209
+ color: var(--sl-color-gray-2);
210
+ text-decoration: none;
211
+ transition: color 0.2s ease;
212
+ }
213
+
214
+ .footer-nav a:hover {
215
+ color: var(--sl-color-accent-high);
216
+ }
217
+
218
+ .link-disabled {
219
+ font-size: var(--sl-text-sm);
220
+ color: var(--sl-color-gray-4);
221
+ display: flex;
222
+ align-items: center;
223
+ gap: 0.4rem;
224
+ }
225
+
226
+ .soon-badge {
227
+ font-size: var(--sl-text-xs);
228
+ padding: 0.1em 0.4em;
229
+ border-radius: 3px;
230
+ background: var(--sl-color-accent-low);
231
+ color: var(--sl-color-accent-high);
232
+ font-weight: 600;
233
+ letter-spacing: 0.05em;
234
+ text-transform: uppercase;
235
+ }
236
+ }
237
+
238
+ @layer starlight.components {
239
+ /* Starlight icon color in the kudos link */
240
+ .kudos :global(svg) {
241
+ color: var(--sl-color-orange);
242
+ }
243
+ }
244
+ </style>
@@ -0,0 +1,189 @@
1
+ ---
2
+ // SPDX-FileCopyrightText: 2025 Knitli Inc.
3
+ // SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
4
+ //
5
+ // SPDX-License-Identifier: MIT OR Apache-2.0
6
+ //
7
+ // Starlight PageFrame override for Knitli product documentation sites.
8
+ // Adds the cross-site subnav bar (with breadcrumb) above the Starlight header.
9
+ //
10
+ // Usage in astro.config.mjs:
11
+ // starlight({ components: { PageFrame: '@knitli/docs-components/PageFrame.astro' } })
12
+ //
13
+ // Required env variable: PUBLIC_DOCS_PRODUCT = 'ReCoco' | 'CodeWeaver' | 'Thread'
14
+ // The --sl-subnav-height CSS variable defaults to 2rem if not set in customCss.
15
+
16
+ // @ts-expect-error: virtual:starlight/components/* are typed in virtual-internal.d.ts,
17
+ // which is not in Starlight's public exports map
18
+ import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle';
19
+ import DocsBreadcrumb from './DocsBreadcrumb.astro';
20
+
21
+ const { hasSidebar } = Astro.locals.starlightRoute;
22
+
23
+ const product = import.meta.env.PUBLIC_DOCS_PRODUCT as
24
+ | 'ReCoco'
25
+ | 'CodeWeaver'
26
+ | 'Thread'
27
+ | undefined;
28
+
29
+ // Strip the configured base URL to get the within-product path for the breadcrumb.
30
+ // e.g. for base='/ReCoco/' and pathname='/ReCoco/guide/start', path = 'guide/start'
31
+ const basePath = (import.meta.env.BASE_URL ?? '/').replace(/\/?$/, '/');
32
+ const currentPath = Astro.url.pathname
33
+ .slice(basePath.length)
34
+ .replace(/^\//, '');
35
+ ---
36
+
37
+ <div class="page sl-flex">
38
+
39
+ <nav class="knitli-subnav sl-flex" aria-label="Knitli">
40
+ {product && (
41
+ <div class="subnav-breadcrumb">
42
+ <DocsBreadcrumb
43
+ product={product}
44
+ productUrl={basePath}
45
+ path={currentPath}
46
+ variant="inline"
47
+ />
48
+ </div>
49
+ )}
50
+ <div class="subnav-links sl-flex">
51
+ <a href="https://knitli.com" class="subnav-link">Knitli Home</a>
52
+ <a href="https://blog.knitli.com" class="subnav-link">Blog</a>
53
+ </div>
54
+ </nav>
55
+
56
+ <header class="header"><slot name="header" /></header>
57
+
58
+ {
59
+ hasSidebar && (
60
+ <nav class="sidebar print:hidden" aria-label={Astro.locals.t('sidebarNav.accessibleLabel')}>
61
+ <MobileMenuToggle />
62
+ <div id="starlight__sidebar" class="sidebar-pane">
63
+ <div class="sidebar-content sl-flex">
64
+ <slot name="sidebar" />
65
+ </div>
66
+ </div>
67
+ </nav>
68
+ )
69
+ }
70
+
71
+ <div class="main-frame"><slot /></div>
72
+ </div>
73
+
74
+ <style>
75
+ @layer starlight.core {
76
+ /* Replicated from Starlight's PageFrame — only positional values modified */
77
+ .page {
78
+ flex-direction: column;
79
+ min-height: 100vh;
80
+ }
81
+
82
+ .header {
83
+ z-index: var(--sl-z-index-navbar);
84
+ position: fixed;
85
+ inset-inline-start: 0;
86
+ inset-block-start: var(--sl-subnav-height, 2rem); /* offset below subnav */
87
+ width: 100%;
88
+ height: var(--sl-nav-height);
89
+ border-bottom: 1px solid var(--sl-color-hairline-shade);
90
+ padding: var(--sl-nav-pad-y) var(--sl-nav-pad-x);
91
+ padding-inline-end: var(--sl-nav-pad-x);
92
+ background-color: var(--sl-color-bg-nav);
93
+ }
94
+
95
+ :global([data-has-sidebar]) .header {
96
+ padding-inline-end: calc(
97
+ var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size)
98
+ );
99
+ }
100
+
101
+ .sidebar-pane {
102
+ visibility: var(--sl-sidebar-visibility, hidden);
103
+ position: fixed;
104
+ z-index: var(--sl-z-index-menu);
105
+ inset-block: calc(var(--sl-nav-height) + var(--sl-subnav-height, 2rem)) 0;
106
+ inset-inline-start: 0;
107
+ width: 100%;
108
+ background-color: var(--sl-color-black);
109
+ overflow-y: auto;
110
+ }
111
+
112
+ :global([aria-expanded='true']) ~ .sidebar-pane {
113
+ --sl-sidebar-visibility: visible;
114
+ }
115
+
116
+ .sidebar-content {
117
+ height: 100%;
118
+ min-height: max-content;
119
+ padding: 1rem var(--sl-sidebar-pad-x) 0;
120
+ flex-direction: column;
121
+ gap: 1rem;
122
+ }
123
+
124
+ @media (min-width: 50rem) {
125
+ .sidebar-content::after {
126
+ content: '';
127
+ padding-bottom: 1px;
128
+ }
129
+ }
130
+
131
+ .main-frame {
132
+ padding-top: calc(
133
+ var(--sl-nav-height) + var(--sl-subnav-height, 2rem) + var(--sl-mobile-toc-height)
134
+ );
135
+ padding-inline-start: var(--sl-content-inline-start);
136
+ }
137
+
138
+ @media (min-width: 50rem) {
139
+ :global([data-has-sidebar]) .header {
140
+ padding-inline-end: var(--sl-nav-pad-x);
141
+ }
142
+ .sidebar-pane {
143
+ --sl-sidebar-visibility: visible;
144
+ width: var(--sl-sidebar-width);
145
+ background-color: var(--sl-color-bg-sidebar);
146
+ border-inline-end: 1px solid var(--sl-color-hairline-shade);
147
+ }
148
+ }
149
+
150
+ /* Knitli cross-site subnav */
151
+ .knitli-subnav {
152
+ position: fixed;
153
+ inset-block-start: 0;
154
+ inset-inline-start: 0;
155
+ width: 100%;
156
+ height: var(--sl-subnav-height, 2rem);
157
+ z-index: var(--sl-z-index-navbar);
158
+ background-color: var(--sl-color-bg-nav);
159
+ padding-inline: var(--sl-nav-pad-x);
160
+ justify-content: space-between;
161
+ align-items: center;
162
+ gap: 1rem;
163
+ }
164
+
165
+ .subnav-breadcrumb {
166
+ flex: 1;
167
+ min-width: 0; /* allows breadcrumb to shrink and truncate */
168
+ overflow: hidden;
169
+ }
170
+
171
+ .subnav-links {
172
+ gap: 1.25rem;
173
+ align-items: center;
174
+ flex-shrink: 0;
175
+ }
176
+
177
+ .subnav-link {
178
+ font-size: var(--sl-text-xs);
179
+ color: var(--sl-color-gray-3);
180
+ text-decoration: none;
181
+ transition: color 0.2s ease;
182
+ white-space: nowrap;
183
+ }
184
+
185
+ .subnav-link:hover {
186
+ color: var(--sl-color-white);
187
+ }
188
+ }
189
+ </style>
@@ -5,7 +5,8 @@
5
5
  */
6
6
 
7
7
  /* Import color palette and variables */
8
- @import "./variables.css";
8
+ @import "@knitli/layouts/styles/variables.css";
9
+ @import "@knitli/layouts/styles/textures.css";
9
10
 
10
11
  /* ========================================
11
12
  GOOGLE FONTS
@@ -24,7 +25,7 @@
24
25
  }
25
26
 
26
27
  html {
27
- font-size: 16px;
28
+ font-size: var(--font-sm);
28
29
  -webkit-font-smoothing: antialiased;
29
30
  -moz-osx-font-smoothing: grayscale;
30
31
  }
@@ -32,8 +33,8 @@ html {
32
33
  body {
33
34
  margin: 0;
34
35
  padding: 0;
35
- font-family: var(--font-docs-body);
36
- font-size: var(--text-base);
36
+ font-family: var(--font-cw-body);
37
+ font-size: var(--font-base);
37
38
  line-height: var(--leading-normal);
38
39
  color: var(--docs-text-primary);
39
40
  background: var(--docs-parchment);
@@ -198,20 +198,3 @@
198
198
  --breakpoint-2xl: 1536px;
199
199
  }
200
200
 
201
- /* ========================================
202
- DARK MODE VARIABLES (Optional)
203
- ======================================== */
204
-
205
- @media (prefers-color-scheme: dark) {
206
- :root {
207
- --docs-parchment: oklch(0.2 0.01 260);
208
- --docs-cream: oklch(0.22 0.01 260);
209
- --docs-white: oklch(0.25 0.01 260);
210
- --docs-ink: oklch(0.9 0.01 180);
211
- --docs-text-primary: oklch(0.85 0.01 180);
212
- --docs-text-secondary: oklch(0.65 0.01 200);
213
- --docs-text-muted: oklch(0.5 0.01 220);
214
- --docs-border-light: oklch(0.3 0.01 240);
215
- --docs-border-medium: oklch(0.4 0.01 240);
216
- }
217
- }
@@ -1,25 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg id="knitli-logo-copper" viewBox="0 0 425.64246 125" width="425.64246" height="125" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="knitli-logo-copper-title">
3
- <title id="knitli-logo-copper-title">Knitli</title>
4
- <defs>
5
- <style>
6
- .text { fill: #b56c30; }
7
- .knot { fill: #b56c30; }
8
- </style>
9
- </defs>
10
- <g class="text" transform="matrix(0.87019392,0,0,0.87019392,-446.87779,5.0497)">
11
- <path d="m 755.7988,56.199038 h 18.2535 l -0.72516,15.734735 h 0.24458 c 1.51469,-5.68544 4.14501,-9.89053 7.85664,-12.61525 3.7245,-2.71614 8.9122,-4.076356 15.55881,-4.076356 7.28166,0 13.02718,1.973815 17.22797,5.942896 4.2008,3.95622 6.30334,9.70173 6.30334,17.22797 v 37.103427 h -18.2535 V 82.497973 c 0,-2.71614 -0.49774,-4.98173 -1.49323,-6.78391 -1.00836,-1.80647 -2.46298,-3.14523 -4.3896,-4.02487 -1.91374,-0.87963 -4.23941,-1.31731 -6.95984,-1.31731 -3.2053,0 -5.97293,0.64364 -8.28573,1.92662 -2.32567,1.27869 -4.08494,3.17527 -5.28639,5.69832 -1.20145,2.52305 -1.79789,5.62966 -1.79789,9.31125 V 115.52075 H 755.7988 V 56.203329 Z"/>
12
- <path d="m 877.6218,111.01102 c -3.91759,-3.6344 -5.88283,-8.94224 -5.88283,-15.910667 v -24.73276 h -8.76631 V 56.199038 h 8.76631 V 37.306197 h 18.2535 v 18.892841 h 18.96579 v 14.168555 h -18.96579 v 23.77589 c 0,2.08109 0.34327,3.70305 1.01694,4.86588 0.68226,1.154257 1.73782,1.973817 3.18385,2.462977 1.43746,0.48058 3.40269,0.71229 5.88283,0.71229 1.36022,0 2.82341,-0.0772 4.38959,-0.236 1.55331,-0.16734 2.85345,-0.36043 3.90043,-0.60502 v 13.80813 c -1.27869,0.32181 -2.98217,0.62647 -5.10188,0.90967 -2.12829,0.27462 -4.26945,0.42051 -6.43206,0.42051 -8.88217,0 -15.29278,-1.82793 -19.21037,-5.4709 z"/>
13
- <path d="M 746.36311,115.51646 725.55653,89.131713 c 9.82616,-7.68501 16.26681,-19.51502 16.26681,-32.932675 H 723.587 c 0,13.078665 -10.64143,23.720105 -23.72868,23.720105 h -2.61745 V 30.0417 h -18.24492 v 85.47476 h 18.24492 V 98.164063 h 2.61745 c 3.23104,0 6.34624,-0.44626 9.36703,-1.14138 l 13.10871,18.493777 h 24.02047 z"/>
14
- <path d="m 922.09271,30.0417 h 18.24491 v 85.47476 h -18.24491 z"/>
15
- <g transform="matrix(0.42909019,0,0,0.42909019,470.15775,-1.6079935)">
16
- <rect x="849.52002" y="134.72" width="42.540001" height="138.24001"/>
17
- <path d="m 881.84,70.51 c -3.48,-1.28 -7.2,-1.93 -11.05,-1.93 -3.85,0 -7.57,0.65 -11.05,1.93 -8.82,3.22 -14.75,11.33 -14.75,20.18 0,8.85 5.93,16.95 14.76,20.18 3.5,1.28 7.21,1.92 11.04,1.92 3.83,0 7.55,-0.65 11.04,-1.92 8.82,-3.23 14.76,-11.34 14.76,-20.18 0,-8.84 -5.93,-16.96 -14.75,-20.18 z"/>
18
- </g>
19
- <g transform="matrix(0.42909019,0,0,0.42909019,470.15775,-1.6079935)">
20
- <rect x="1133.5601" y="134.72" width="42.540001" height="138.24001"/>
21
- <path d="m 1165.88,70.51 c -3.48,-1.28 -7.2,-1.93 -11.05,-1.93 -3.85,0 -7.57,0.65 -11.05,1.93 -8.82,3.22 -14.75,11.33 -14.75,20.18 0,8.85 5.93,16.95 14.76,20.18 3.5,1.28 7.21,1.92 11.04,1.92 3.83,0 7.55,-0.65 11.04,-1.92 8.82,-3.23 14.76,-11.34 14.76,-20.18 0,-8.84 -5.93,-16.96 -14.75,-20.18 z"/>
22
- </g>
23
- </g>
24
- <path class="knot" d="m 112.681,56.603739 c -1.74264,-0.639671 -3.60049,-0.959506 -5.5148,-0.959506 -5.91696,0 -11.1519,2.909088 -14.58307,5.434847 -0.860732,-1.077093 -1.62504,-2.234144 -2.347025,-3.459394 -0.698465,-1.239361 -1.319318,-2.478722 -1.822592,-3.762767 3.903867,-1.709707 9.037687,-4.78812 11.998517,-9.912537 0.95951,-1.657969 1.60859,-3.426469 1.92607,-5.256114 0.80664,-4.618795 -1.21114,-9.199963 -5.04211,-11.415292 -3.82156,-2.20357 -8.804864,-1.665024 -12.403013,1.340486 -1.420446,1.187622 -2.62688,2.633936 -3.586384,4.29896 -2.956122,5.122066 -3.057249,11.102513 -2.586903,15.345031 -1.37106,0.209304 -2.770336,0.310428 -4.193136,0.308076 -1.422793,0 -2.822069,-0.09877 -4.193129,-0.308076 0.470345,-4.242518 0.369219,-10.225317 -2.586903,-15.345031 -0.961859,-1.665024 -2.165939,-3.111338 -3.586384,-4.29896 -3.598148,-3.00551 -8.581461,-3.544056 -12.403024,-1.340486 -3.830966,2.215329 -5.846392,6.798848 -5.042102,11.415292 0.317485,1.829645 0.968915,3.598145 1.926065,5.256114 2.960823,5.124417 8.094649,8.20283 11.998523,9.912537 -0.503271,1.284045 -1.124128,2.523406 -1.822589,3.762767 -0.721985,1.22525 -1.486297,2.382301 -2.34703,3.459394 -3.433523,-2.525759 -8.666121,-5.432495 -14.583067,-5.434847 -1.914312,0 -3.772176,0.319835 -5.514808,0.959506 -4.402437,1.610934 -7.363261,5.648853 -7.365616,10.072455 0,4.411843 2.960831,8.459168 7.363269,10.070101 1.737922,0.637318 3.593439,0.957156 5.517155,0.957156 5.912245,0 11.142487,-2.902034 14.583067,-5.432494 0.867788,1.081795 1.65327,2.243549 2.363489,3.478207 0.714928,1.232304 1.326375,2.495186 1.829646,3.786281 -3.910924,1.714414 -9.040048,4.792825 -11.99617,9.912541 -0.961857,1.665021 -1.613286,3.43117 -1.928418,5.256117 -0.80429,4.618794 1.220547,9.204657 5.039755,11.412937 3.83332,2.21062 8.809577,1.66502 12.407726,-1.34284 1.425146,-1.18997 2.631581,-2.63628 3.588737,-4.29661 2.956122,-5.126766 3.057242,-11.111917 2.584549,-15.347379 1.361649,-0.206954 2.74682,-0.28926 4.169613,-0.303373 1.4228,0.01414 2.80561,0.09642 4.169614,0.303373 -0.470345,4.235462 -0.371573,10.220613 2.584555,15.347379 0.95715,1.65797 2.163585,3.10664 3.588737,4.29661 3.595792,3.00552 8.574396,3.55111 12.407716,1.34284 3.81922,-2.20828 5.84405,-6.794143 5.03975,-11.412937 -0.31748,-1.824947 -0.96656,-3.591096 -1.92841,-5.256117 -2.95612,-5.119716 -8.08524,-8.198127 -11.996173,-9.912541 0.503274,-1.293449 1.117074,-2.553977 1.829651,-3.786281 0.710223,-1.234658 1.49805,-2.39406 2.363482,-3.478207 3.44057,2.53046 8.67083,5.432494 14.58307,5.432494 1.92372,0 3.77688,-0.319838 5.51716,-0.957156 4.40244,-1.613281 7.36092,-5.660609 7.36326,-10.070101 -0.003,-4.425954 -2.96318,-8.461521 -7.36561,-10.074807 z m -70.798794,12.95097 c -0.961852,0 -1.871976,-0.155213 -2.709192,-0.460939 -1.147638,-0.420959 -2.010724,-1.460423 -2.010724,-2.417576 0.005,-0.954802 0.865433,-1.99897 2.008376,-2.417578 0.841917,-0.305725 1.754389,-0.46329 2.71154,-0.46329 2.551629,0.0024 5.507752,1.041815 8.374505,2.878517 -2.87381,1.841402 -5.82523,2.880866 -8.374505,2.878515 z M 55.698618,39.864133 c -0.479755,-0.827808 -0.799588,-1.695596 -0.954803,-2.577495 -0.211656,-1.199382 0.263391,-2.466964 1.088849,-2.949068 0.83016,-0.479753 2.161237,-0.249284 3.099579,0.533841 0.684355,0.573823 1.274634,1.281693 1.754389,2.116557 1.274635,2.205922 1.850808,5.281983 1.693246,8.691991 -3.024323,-1.563901 -5.401924,-3.605202 -6.678913,-5.813474 z m 5.01153,56.544975 c -0.477401,0.830157 -1.070034,1.540379 -1.754389,2.116546 -0.933634,0.783131 -2.267065,1.006547 -3.097225,0.531498 -0.83016,-0.479753 -1.298156,-1.747341 -1.088855,-2.951421 0.155214,-0.879546 0.475054,-1.744986 0.957156,-2.577499 1.272287,-2.20827 3.649882,-4.244871 6.681261,-5.811117 0.157568,3.400594 -0.420958,6.481359 -1.695593,8.691993 z M 83.162103,71.675969 c -1.030052,1.7685 -1.89784,3.607551 -2.596308,5.503043 -1.98486,-0.341 -3.997939,-0.498563 -6.039241,-0.500917 -2.043651,0.0025 -4.056729,0.159917 -6.039235,0.500917 -0.696113,-1.895492 -1.563901,-3.734543 -2.596313,-5.503043 -1.015947,-1.777906 -2.175349,-3.447634 -3.468798,-4.999775 1.288747,-1.547437 2.429336,-3.212462 3.454692,-4.980962 1.020648,-1.770852 1.89079,-3.593442 2.586897,-5.481881 1.989562,0.343353 4.016753,0.512679 6.062757,0.503271 2.048359,0.0071 4.073196,-0.159918 6.062757,-0.503271 0.696113,1.888439 1.566256,3.711029 2.586905,5.481881 1.023001,1.7685 2.165944,3.433525 3.454691,4.980962 -1.293455,1.552141 -2.450503,3.221869 -3.468804,4.999775 z M 93.32863,93.528232 c 0.4821,0.832513 0.80194,1.697953 0.95715,2.577499 0.20931,1.20408 -0.25869,2.471668 -1.08885,2.951421 -0.83016,0.475049 -2.163583,0.251633 -3.097227,-0.531498 -0.686703,-0.576167 -1.279338,-1.286389 -1.754387,-2.116546 -1.272286,-2.210634 -1.85081,-5.291399 -1.695595,-8.691993 3.03138,1.568601 5.406619,3.605194 6.681259,5.811117 z M 86.67559,45.677607 c -0.157568,-3.410008 0.418605,-6.483717 1.693239,-8.691991 0.479753,-0.834864 1.07004,-1.542733 1.754394,-2.116556 0.938342,-0.783126 2.269417,-1.011243 3.099577,-0.533843 0.82546,0.482105 1.29816,1.747336 1.08885,2.949069 -0.15522,0.881898 -0.47505,1.749686 -0.95481,2.577495 -1.27699,2.208273 -3.65693,4.249574 -6.678901,5.813474 z m 23.2045,23.416163 c -0.83957,0.305726 -1.74733,0.460939 -2.70919,0.460939 -2.54927,0 -5.50069,-1.037112 -8.3745,-2.878515 2.86675,-1.8367 5.82523,-2.876166 8.3745,-2.878517 0.95716,0 1.86962,0.155214 2.71155,0.463291 1.14528,0.418608 2.00602,1.460424 2.00838,2.417577 0,0.957154 -0.8631,1.998969 -2.01074,2.417578 z"/>
25
- </svg>
@@ -1,25 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg id="knitli-logo" viewBox="0 0 425.64246 125" width="425.64246" height="125" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="knitli-logo-title">
3
- <title id="knitli-logo-title">Knitli</title>
4
- <defs>
5
- <style>
6
- .text { fill: #1e061b; }
7
- .knot { fill: #ea5932; }
8
- </style>
9
- </defs>
10
- <g class="text" transform="matrix(0.87019392,0,0,0.87019392,-446.87779,5.0497)">
11
- <path d="m 755.7988,56.199038 h 18.2535 l -0.72516,15.734735 h 0.24458 c 1.51469,-5.68544 4.14501,-9.89053 7.85664,-12.61525 3.7245,-2.71614 8.9122,-4.076356 15.55881,-4.076356 7.28166,0 13.02718,1.973815 17.22797,5.942896 4.2008,3.95622 6.30334,9.70173 6.30334,17.22797 v 37.103427 h -18.2535 V 82.497973 c 0,-2.71614 -0.49774,-4.98173 -1.49323,-6.78391 -1.00836,-1.80647 -2.46298,-3.14523 -4.3896,-4.02487 -1.91374,-0.87963 -4.23941,-1.31731 -6.95984,-1.31731 -3.2053,0 -5.97293,0.64364 -8.28573,1.92662 -2.32567,1.27869 -4.08494,3.17527 -5.28639,5.69832 -1.20145,2.52305 -1.79789,5.62966 -1.79789,9.31125 V 115.52075 H 755.7988 V 56.203329 Z"/>
12
- <path d="m 877.6218,111.01102 c -3.91759,-3.6344 -5.88283,-8.94224 -5.88283,-15.910667 v -24.73276 h -8.76631 V 56.199038 h 8.76631 V 37.306197 h 18.2535 v 18.892841 h 18.96579 v 14.168555 h -18.96579 v 23.77589 c 0,2.08109 0.34327,3.70305 1.01694,4.86588 0.68226,1.154257 1.73782,1.973817 3.18385,2.462977 1.43746,0.48058 3.40269,0.71229 5.88283,0.71229 1.36022,0 2.82341,-0.0772 4.38959,-0.236 1.55331,-0.16734 2.85345,-0.36043 3.90043,-0.60502 v 13.80813 c -1.27869,0.32181 -2.98217,0.62647 -5.10188,0.90967 -2.12829,0.27462 -4.26945,0.42051 -6.43206,0.42051 -8.88217,0 -15.29278,-1.82793 -19.21037,-5.4709 z"/>
13
- <path d="M 746.36311,115.51646 725.55653,89.131713 c 9.82616,-7.68501 16.26681,-19.51502 16.26681,-32.932675 H 723.587 c 0,13.078665 -10.64143,23.720105 -23.72868,23.720105 h -2.61745 V 30.0417 h -18.24492 v 85.47476 h 18.24492 V 98.164063 h 2.61745 c 3.23104,0 6.34624,-0.44626 9.36703,-1.14138 l 13.10871,18.493777 h 24.02047 z"/>
14
- <path d="m 922.09271,30.0417 h 18.24491 v 85.47476 h -18.24491 z"/>
15
- <g transform="matrix(0.42909019,0,0,0.42909019,470.15775,-1.6079935)">
16
- <rect x="849.52002" y="134.72" width="42.540001" height="138.24001"/>
17
- <path d="m 881.84,70.51 c -3.48,-1.28 -7.2,-1.93 -11.05,-1.93 -3.85,0 -7.57,0.65 -11.05,1.93 -8.82,3.22 -14.75,11.33 -14.75,20.18 0,8.85 5.93,16.95 14.76,20.18 3.5,1.28 7.21,1.92 11.04,1.92 3.83,0 7.55,-0.65 11.04,-1.92 8.82,-3.23 14.76,-11.34 14.76,-20.18 0,-8.84 -5.93,-16.96 -14.75,-20.18 z"/>
18
- </g>
19
- <g transform="matrix(0.42909019,0,0,0.42909019,470.15775,-1.6079935)">
20
- <rect x="1133.5601" y="134.72" width="42.540001" height="138.24001"/>
21
- <path d="m 1165.88,70.51 c -3.48,-1.28 -7.2,-1.93 -11.05,-1.93 -3.85,0 -7.57,0.65 -11.05,1.93 -8.82,3.22 -14.75,11.33 -14.75,20.18 0,8.85 5.93,16.95 14.76,20.18 3.5,1.28 7.21,1.92 11.04,1.92 3.83,0 7.55,-0.65 11.04,-1.92 8.82,-3.23 14.76,-11.34 14.76,-20.18 0,-8.84 -5.93,-16.96 -14.75,-20.18 z"/>
22
- </g>
23
- </g>
24
- <path class="knot" d="m 112.681,56.603739 c -1.74264,-0.639671 -3.60049,-0.959506 -5.5148,-0.959506 -5.91696,0 -11.1519,2.909088 -14.58307,5.434847 -0.860732,-1.077093 -1.62504,-2.234144 -2.347025,-3.459394 -0.698465,-1.239361 -1.319318,-2.478722 -1.822592,-3.762767 3.903867,-1.709707 9.037687,-4.78812 11.998517,-9.912537 0.95951,-1.657969 1.60859,-3.426469 1.92607,-5.256114 0.80664,-4.618795 -1.21114,-9.199963 -5.04211,-11.415292 -3.82156,-2.20357 -8.804864,-1.665024 -12.403013,1.340486 -1.420446,1.187622 -2.62688,2.633936 -3.586384,4.29896 -2.956122,5.122066 -3.057249,11.102513 -2.586903,15.345031 -1.37106,0.209304 -2.770336,0.310428 -4.193136,0.308076 -1.422793,0 -2.822069,-0.09877 -4.193129,-0.308076 0.470345,-4.242518 0.369219,-10.225317 -2.586903,-15.345031 -0.961859,-1.665024 -2.165939,-3.111338 -3.586384,-4.29896 -3.598148,-3.00551 -8.581461,-3.544056 -12.403024,-1.340486 -3.830966,2.215329 -5.846392,6.798848 -5.042102,11.415292 0.317485,1.829645 0.968915,3.598145 1.926065,5.256114 2.960823,5.124417 8.094649,8.20283 11.998523,9.912537 -0.503271,1.284045 -1.124128,2.523406 -1.822589,3.762767 -0.721985,1.22525 -1.486297,2.382301 -2.34703,3.459394 -3.433523,-2.525759 -8.666121,-5.432495 -14.583067,-5.434847 -1.914312,0 -3.772176,0.319835 -5.514808,0.959506 -4.402437,1.610934 -7.363261,5.648853 -7.365616,10.072455 0,4.411843 2.960831,8.459168 7.363269,10.070101 1.737922,0.637318 3.593439,0.957156 5.517155,0.957156 5.912245,0 11.142487,-2.902034 14.583067,-5.432494 0.867788,1.081795 1.65327,2.243549 2.363489,3.478207 0.714928,1.232304 1.326375,2.495186 1.829646,3.786281 -3.910924,1.714414 -9.040048,4.792825 -11.99617,9.912541 -0.961857,1.665021 -1.613286,3.43117 -1.928418,5.256117 -0.80429,4.618794 1.220547,9.204657 5.039755,11.412937 3.83332,2.21062 8.809577,1.66502 12.407726,-1.34284 1.425146,-1.18997 2.631581,-2.63628 3.588737,-4.29661 2.956122,-5.126766 3.057242,-11.111917 2.584549,-15.347379 1.361649,-0.206954 2.74682,-0.28926 4.169613,-0.303373 1.4228,0.01414 2.80561,0.09642 4.169614,0.303373 -0.470345,4.235462 -0.371573,10.220613 2.584555,15.347379 0.95715,1.65797 2.163585,3.10664 3.588737,4.29661 3.595792,3.00552 8.574396,3.55111 12.407716,1.34284 3.81922,-2.20828 5.84405,-6.794143 5.03975,-11.412937 -0.31748,-1.824947 -0.96656,-3.591096 -1.92841,-5.256117 -2.95612,-5.119716 -8.08524,-8.198127 -11.996173,-9.912541 0.503274,-1.293449 1.117074,-2.553977 1.829651,-3.786281 0.710223,-1.234658 1.49805,-2.39406 2.363482,-3.478207 3.44057,2.53046 8.67083,5.432494 14.58307,5.432494 1.92372,0 3.77688,-0.319838 5.51716,-0.957156 4.40244,-1.613281 7.36092,-5.660609 7.36326,-10.070101 -0.003,-4.425954 -2.96318,-8.461521 -7.36561,-10.074807 z m -70.798794,12.95097 c -0.961852,0 -1.871976,-0.155213 -2.709192,-0.460939 -1.147638,-0.420959 -2.010724,-1.460423 -2.010724,-2.417576 0.005,-0.954802 0.865433,-1.99897 2.008376,-2.417578 0.841917,-0.305725 1.754389,-0.46329 2.71154,-0.46329 2.551629,0.0024 5.507752,1.041815 8.374505,2.878517 -2.87381,1.841402 -5.82523,2.880866 -8.374505,2.878515 z M 55.698618,39.864133 c -0.479755,-0.827808 -0.799588,-1.695596 -0.954803,-2.577495 -0.211656,-1.199382 0.263391,-2.466964 1.088849,-2.949068 0.83016,-0.479753 2.161237,-0.249284 3.099579,0.533841 0.684355,0.573823 1.274634,1.281693 1.754389,2.116557 1.274635,2.205922 1.850808,5.281983 1.693246,8.691991 -3.024323,-1.563901 -5.401924,-3.605202 -6.678913,-5.813474 z m 5.01153,56.544975 c -0.477401,0.830157 -1.070034,1.540379 -1.754389,2.116546 -0.933634,0.783131 -2.267065,1.006547 -3.097225,0.531498 -0.83016,-0.479753 -1.298156,-1.747341 -1.088855,-2.951421 0.155214,-0.879546 0.475054,-1.744986 0.957156,-2.577499 1.272287,-2.20827 3.649882,-4.244871 6.681261,-5.811117 0.157568,3.400594 -0.420958,6.481359 -1.695593,8.691993 z M 83.162103,71.675969 c -1.030052,1.7685 -1.89784,3.607551 -2.596308,5.503043 -1.98486,-0.341 -3.997939,-0.498563 -6.039241,-0.500917 -2.043651,0.0025 -4.056729,0.159917 -6.039235,0.500917 -0.696113,-1.895492 -1.563901,-3.734543 -2.596313,-5.503043 -1.015947,-1.777906 -2.175349,-3.447634 -3.468798,-4.999775 1.288747,-1.547437 2.429336,-3.212462 3.454692,-4.980962 1.020648,-1.770852 1.89079,-3.593442 2.586897,-5.481881 1.989562,0.343353 4.016753,0.512679 6.062757,0.503271 2.048359,0.0071 4.073196,-0.159918 6.062757,-0.503271 0.696113,1.888439 1.566256,3.711029 2.586905,5.481881 1.023001,1.7685 2.165944,3.433525 3.454691,4.980962 -1.293455,1.552141 -2.450503,3.221869 -3.468804,4.999775 z M 93.32863,93.528232 c 0.4821,0.832513 0.80194,1.697953 0.95715,2.577499 0.20931,1.20408 -0.25869,2.471668 -1.08885,2.951421 -0.83016,0.475049 -2.163583,0.251633 -3.097227,-0.531498 -0.686703,-0.576167 -1.279338,-1.286389 -1.754387,-2.116546 -1.272286,-2.210634 -1.85081,-5.291399 -1.695595,-8.691993 3.03138,1.568601 5.406619,3.605194 6.681259,5.811117 z M 86.67559,45.677607 c -0.157568,-3.410008 0.418605,-6.483717 1.693239,-8.691991 0.479753,-0.834864 1.07004,-1.542733 1.754394,-2.116556 0.938342,-0.783126 2.269417,-1.011243 3.099577,-0.533843 0.82546,0.482105 1.29816,1.747336 1.08885,2.949069 -0.15522,0.881898 -0.47505,1.749686 -0.95481,2.577495 -1.27699,2.208273 -3.65693,4.249574 -6.678901,5.813474 z m 23.2045,23.416163 c -0.83957,0.305726 -1.74733,0.460939 -2.70919,0.460939 -2.54927,0 -5.50069,-1.037112 -8.3745,-2.878515 2.86675,-1.8367 5.82523,-2.876166 8.3745,-2.878517 0.95716,0 1.86962,0.155214 2.71155,0.463291 1.14528,0.418608 2.00602,1.460424 2.00838,2.417577 0,0.957154 -0.8631,1.998969 -2.01074,2.417578 z"/>
25
- </svg>