@beatzball/create-litro 0.2.1 → 0.4.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 (42) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/recipes/starlight/template/app.ts +14 -0
  3. package/dist/recipes/starlight/template/nitro.config.ts +2 -0
  4. package/dist/recipes/starlight/template/package.json +2 -0
  5. package/dist/recipes/starlight/template/pages/docs/[slug].ts +75 -2
  6. package/dist/recipes/starlight/template/pages/index.ts +6 -6
  7. package/dist/recipes/starlight/template/public/styles/highlight.css +108 -0
  8. package/dist/recipes/starlight/template/public/styles/starlight.css +58 -19
  9. package/dist/recipes/starlight/template/src/components/{sl-aside.ts → litro-aside.ts} +5 -5
  10. package/{recipes/starlight/template/src/components/sl-badge.ts → dist/recipes/starlight/template/src/components/litro-badge.ts} +5 -5
  11. package/{recipes/starlight/template/src/components/sl-card-grid.ts → dist/recipes/starlight/template/src/components/litro-card-grid.ts} +7 -7
  12. package/{recipes/starlight/template/src/components/sl-card.ts → dist/recipes/starlight/template/src/components/litro-card.ts} +36 -12
  13. package/dist/recipes/starlight/template/src/components/{sl-tab-item.ts → litro-tab-item.ts} +6 -6
  14. package/{recipes/starlight/template/src/components/sl-tabs.ts → dist/recipes/starlight/template/src/components/litro-tabs.ts} +12 -12
  15. package/dist/recipes/starlight/template/src/components/starlight-header.ts +128 -32
  16. package/dist/recipes/starlight/template/src/components/starlight-page.ts +53 -5
  17. package/dist/recipes/starlight/template/src/highlight.ts +40 -0
  18. package/dist/recipes/starlight/template/src/route-meta.ts +4 -1
  19. package/dist/recipes/starlight/template/vite.config.ts +1 -1
  20. package/dist/src/scaffold.test.js +6 -6
  21. package/dist/src/scaffold.test.js.map +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +1 -1
  24. package/recipes/starlight/template/app.ts +14 -0
  25. package/recipes/starlight/template/nitro.config.ts +2 -0
  26. package/recipes/starlight/template/package.json +2 -0
  27. package/recipes/starlight/template/pages/docs/[slug].ts +75 -2
  28. package/recipes/starlight/template/pages/index.ts +6 -6
  29. package/recipes/starlight/template/public/styles/highlight.css +108 -0
  30. package/recipes/starlight/template/public/styles/starlight.css +58 -19
  31. package/recipes/starlight/template/src/components/{sl-aside.ts → litro-aside.ts} +5 -5
  32. package/{dist/recipes/starlight/template/src/components/sl-badge.ts → recipes/starlight/template/src/components/litro-badge.ts} +5 -5
  33. package/{dist/recipes/starlight/template/src/components/sl-card-grid.ts → recipes/starlight/template/src/components/litro-card-grid.ts} +7 -7
  34. package/{dist/recipes/starlight/template/src/components/sl-card.ts → recipes/starlight/template/src/components/litro-card.ts} +36 -12
  35. package/recipes/starlight/template/src/components/{sl-tab-item.ts → litro-tab-item.ts} +6 -6
  36. package/{dist/recipes/starlight/template/src/components/sl-tabs.ts → recipes/starlight/template/src/components/litro-tabs.ts} +12 -12
  37. package/recipes/starlight/template/src/components/starlight-header.ts +128 -32
  38. package/recipes/starlight/template/src/components/starlight-page.ts +53 -5
  39. package/recipes/starlight/template/src/highlight.ts +40 -0
  40. package/recipes/starlight/template/src/route-meta.ts +4 -1
  41. package/recipes/starlight/template/vite.config.ts +1 -1
  42. package/src/scaffold.test.ts +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # create-litro
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1cd1e7f: Add syntax highlighting to the starlight recipe. Code blocks in Markdown docs are now automatically highlighted at SSG build time using `highlight.js` with the fire palette theme (dark background, orange keywords, sky-blue strings, amber numbers). The `DocPage` component includes `static override styles` with all `.hljs-*` token rules so highlighting works correctly inside the Lit shadow DOM.
8
+ - 1a84fad: Add responsive hamburger menu to the starlight recipe. A hamburger button appears to the left of the site logo on screens ≤72rem where the sidebar is hidden. Clicking it opens/closes the sidebar as a fixed drawer overlay with a backdrop. The nav auto-closes on route change.
9
+
10
+ ## 0.3.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 2456382: Add official documentation site and starlight recipe improvements
15
+
16
+ **`@beatzball/litro`**
17
+
18
+ - Add `LITRO_BASE_PATH` env var support in `create-page-handler.ts` — prefixes the `/_litro/app.js` script URL for sub-path deployments (e.g. GitHub Pages project sites at `owner.github.io/repo/`)
19
+ - Fix Lit hydration mismatch on SSR'd pages: `LitroPage.connectedCallback()` now peeks at the `__litro_data__` script tag to set `serverData` before Lit's first render, without consuming the tag
20
+ - Fix layout shift on navigation: `LitroOutlet.firstUpdated()` no longer eagerly clears SSR children — the router's atomic swap handles it
21
+
22
+ **`@beatzball/litro-router`**
23
+
24
+ - Atomic DOM swap in `_resolve()`: new element is appended hidden alongside old SSR content, waits for `updateComplete` + `requestAnimationFrame`, then old content is removed and new element revealed — eliminates blank flash and layout shift during navigation
25
+ - `_lastPathname` guard prevents re-render on hash-only `popstate` events (TOC / fragment link clicks)
26
+
27
+ **`@beatzball/create-litro`**
28
+
29
+ - Starlight recipe: rename `sl-card`, `sl-card-grid`, `sl-badge`, `sl-tabs`, `sl-tab-item`, `sl-aside` → `litro-card`, `litro-card-grid`, `litro-badge`, `litro-tabs`, `litro-tab-item`, `litro-aside` to avoid collision with Shoelace's registered custom element names
30
+ - Starlight recipe: integrate Shoelace (`@shoelace-style/shoelace`) — tree-shaken component imports in `app.ts`, icon assets at `/shoelace/assets/`, theme CSS at `/shoelace/themes/`; `sl-button` and `sl-icon-button` now available in all scaffolded starlight sites
31
+ - Starlight recipe: `litro-card` improvements — equal-height cards via flex column, icon + title rendered inline side-by-side, new `iconSrc` prop for image-based icons
32
+ - Starlight recipe: sticky header via `:host { position: sticky }` (works correctly across shadow DOM boundary); sticky TOC matching sidebar behaviour
33
+ - Starlight recipe: theme script falls back to `prefers-color-scheme` when no localStorage preference is set
34
+ - Add `docs/` workspace (`@beatzball/litro-docs`) — official Litro documentation site built on the starlight recipe, deployed to GitHub Pages via `.github/workflows/docs.yml`
35
+
3
36
  ## 0.2.1
4
37
 
5
38
  ### Patch Changes
@@ -5,6 +5,20 @@ import '@lit-labs/ssr-client/lit-element-hydrate-support.js';
5
5
  import '@beatzball/litro/runtime/LitroOutlet.js';
6
6
  import '@beatzball/litro/runtime/LitroLink.js';
7
7
 
8
+ // Shoelace components (tree-shaken — only what the template uses)
9
+ import '@shoelace-style/shoelace/dist/components/button/button.js';
10
+ import '@shoelace-style/shoelace/dist/components/icon/icon.js';
11
+ import '@shoelace-style/shoelace/dist/components/badge/badge.js';
12
+ import '@shoelace-style/shoelace/dist/components/copy-button/copy-button.js';
13
+ import '@shoelace-style/shoelace/dist/components/details/details.js';
14
+ import '@shoelace-style/shoelace/dist/components/tab-group/tab-group.js';
15
+ import '@shoelace-style/shoelace/dist/components/tab/tab.js';
16
+ import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js';
17
+ import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
18
+
19
+ // Point Shoelace's icon loader at the served assets directory
20
+ setBasePath('/shoelace/');
21
+
8
22
  // Routes generated by the page scanner before each vite build.
9
23
  import { routes } from './routes.generated.js';
10
24
 
@@ -15,6 +15,8 @@ export default defineNitroConfig({
15
15
  { dir: '../dist/client', baseURL: '/_litro/', maxAge: 31536000 },
16
16
  { dir: '../public', baseURL: '/', maxAge: 0 },
17
17
  { dir: '../content', baseURL: '/content/', maxAge: 86400 },
18
+ { dir: '../node_modules/@shoelace-style/shoelace/dist/assets', baseURL: '/shoelace/assets/', maxAge: 604800 },
19
+ { dir: '../node_modules/@shoelace-style/shoelace/dist/themes', baseURL: '/shoelace/themes/', maxAge: 604800 },
18
20
  ],
19
21
 
20
22
  externals: { inline: ['@lit-labs/ssr', '@lit-labs/ssr-client'] },
@@ -14,6 +14,8 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@beatzball/litro": "latest",
17
+ "@shoelace-style/shoelace": "^2.19.0",
18
+ "highlight.js": "^11.10.0",
17
19
  "lit": "^3.2.1",
18
20
  "@lit-labs/ssr": "^3.3.0",
19
21
  "@lit-labs/ssr-client": "^1.1.7",
@@ -1,4 +1,4 @@
1
- import { html } from 'lit';
1
+ import { html, css } from 'lit';
2
2
  import { unsafeHTML } from 'lit/directives/unsafe-html.js';
3
3
  import { customElement } from 'lit/decorators.js';
4
4
  import { LitroPage } from '@beatzball/litro/runtime';
@@ -8,6 +8,7 @@ import type { Post } from 'litro:content';
8
8
  import { getPosts } from 'litro:content';
9
9
  import { siteConfig } from '../../server/starlight.config.js';
10
10
  import { extractHeadings, addHeadingIds } from '../../src/extract-headings.js';
11
+ import { applyHighlighting } from '../../src/highlight.js';
11
12
  import { starlightHead } from '../../src/route-meta.js';
12
13
 
13
14
  // Register components used in render()
@@ -55,7 +56,7 @@ export const pageData = definePageData(async (event) => {
55
56
  }
56
57
 
57
58
  const toc = extractHeadings(doc.rawBody);
58
- const body = addHeadingIds(doc.body);
59
+ const body = applyHighlighting(addHeadingIds(doc.body));
59
60
  const { prevDoc, nextDoc } = computePrevNext(siteConfig.sidebar, slug);
60
61
  const editUrl = siteConfig.editUrlBase
61
62
  ? `${siteConfig.editUrlBase}/content/docs/${slug}.md`
@@ -89,6 +90,78 @@ export const routeMeta = {
89
90
 
90
91
  @customElement('page-docs-slug')
91
92
  export class DocPage extends LitroPage {
93
+ /**
94
+ * Styles injected into page-docs-slug's shadow root so they reach the
95
+ * <div slot="content"> subtree. Global stylesheets (starlight.css,
96
+ * highlight.css) cannot pierce shadow DOM boundaries.
97
+ */
98
+ static override styles = css`
99
+ /* ── Typography for slotted doc content ─────────────────────────── */
100
+ h1, h2, h3, h4, h5, h6 {
101
+ margin-top: 1.5em; margin-bottom: 0.5em;
102
+ font-weight: 600; line-height: 1.25;
103
+ color: var(--sl-color-text);
104
+ }
105
+ h1 { font-size: var(--sl-text-4xl, 2.25rem); }
106
+ h2 { font-size: var(--sl-text-2xl, 1.5rem); border-bottom: 1px solid var(--sl-color-border, #e8e8e8); padding-bottom: 0.25em; }
107
+ h3 { font-size: var(--sl-text-xl, 1.25rem); }
108
+ h4 { font-size: var(--sl-text-lg, 1.125rem); }
109
+ p { margin-top: 0; margin-bottom: 1rem; line-height: 1.7; }
110
+ a { color: var(--sl-color-text-accent, var(--sl-color-accent)); text-decoration: none; }
111
+ a:hover { text-decoration: underline; }
112
+ code {
113
+ font-family: var(--sl-font-mono, ui-monospace, monospace);
114
+ font-size: 0.875em;
115
+ background-color: var(--sl-color-bg-inline-code, #e8e8e8);
116
+ border: 1px solid var(--sl-color-border, #e8e8e8);
117
+ border-radius: 0.25rem;
118
+ padding: 0.15em 0.4em;
119
+ }
120
+ pre {
121
+ background-color: #0d0e11;
122
+ color: #e2e4e9;
123
+ border-radius: 0.375rem;
124
+ padding: 1rem 1.25rem;
125
+ overflow-x: auto;
126
+ margin: 1.5rem 0;
127
+ font-size: var(--sl-text-sm, 0.875rem);
128
+ line-height: 1.6;
129
+ }
130
+ pre code { background: none; border: none; padding: 0; font-size: inherit; }
131
+ ul, ol { padding-left: 1.5rem; margin: 0 0 1rem; }
132
+ li { margin-bottom: 0.25rem; line-height: 1.7; }
133
+ blockquote {
134
+ margin: 1.5rem 0; padding: 0.75rem 1rem;
135
+ border-left: 4px solid var(--sl-color-accent, #ea580c);
136
+ background-color: var(--sl-color-accent-low, #fff7ed);
137
+ border-radius: 0 0.375rem 0.375rem 0;
138
+ }
139
+ hr { border: none; border-top: 1px solid var(--sl-color-border, #e8e8e8); margin: 2rem 0; }
140
+ img { max-width: 100%; height: auto; }
141
+ table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; font-size: var(--sl-text-sm, 0.875rem); }
142
+ th, td { border: 1px solid var(--sl-color-border, #e8e8e8); padding: 0.5rem 0.75rem; text-align: left; }
143
+ th { background-color: var(--sl-color-gray-1, #f6f6f6); font-weight: 600; }
144
+
145
+ /* ── highlight.js fire theme ─────────────────────────────────────── */
146
+ pre:has(.hljs) { background-color: #0d0d10; color: #cbd5e1; }
147
+ .hljs { color: #cbd5e1; background: transparent; }
148
+ .hljs-keyword, .hljs-selector-tag, .hljs-tag { color: #f97316; }
149
+ .hljs-string, .hljs-attr, .hljs-attribute { color: #38bdf8; }
150
+ .hljs-number, .hljs-literal { color: #fbbf24; }
151
+ .hljs-title, .hljs-title.class_, .hljs-title.function_, .hljs-built_in { color: #fb923c; }
152
+ .hljs-comment { color: #6b7280; font-style: italic; }
153
+ .hljs-variable, .hljs-params { color: #cbd5e1; }
154
+ .hljs-operator, .hljs-punctuation { color: #94a3b8; }
155
+ .hljs-meta, .hljs-meta .hljs-keyword { color: #38bdf8; }
156
+ .hljs-type { color: #fb923c; }
157
+ .hljs-deletion { color: #f87171; background: rgba(248,113,113,.1); }
158
+ .hljs-addition { color: #4ade80; background: rgba(74,222,128,.1); }
159
+ .hljs-section, .hljs-selector-class, .hljs-selector-id { color: #fb923c; }
160
+ .hljs-symbol, .hljs-bullet, .hljs-link { color: #38bdf8; }
161
+ .hljs-emphasis { font-style: italic; }
162
+ .hljs-strong { font-weight: bold; }
163
+ `;
164
+
92
165
  override render() {
93
166
  const data = this.serverData as DocPageData | null;
94
167
  if (!data?.doc) return html`<p>Loading&hellip;</p>`;
@@ -8,8 +8,8 @@ import { starlightHead } from '../src/route-meta.js';
8
8
 
9
9
  // Register components used in render()
10
10
  import '../src/components/starlight-header.js';
11
- import '../src/components/sl-card.js';
12
- import '../src/components/sl-card-grid.js';
11
+ import '../src/components/litro-card.js';
12
+ import '../src/components/litro-card-grid.js';
13
13
 
14
14
  export interface SplashData {
15
15
  siteTitle: string;
@@ -116,15 +116,15 @@ export class SplashPage extends LitroPage {
116
116
  </section>
117
117
 
118
118
  <section>
119
- <sl-card-grid>
119
+ <litro-card-grid>
120
120
  ${features.map(f => html`
121
- <sl-card
121
+ <litro-card
122
122
  icon="${f.icon ?? ''}"
123
123
  title="${f.title}"
124
124
  description="${f.description}"
125
- ></sl-card>
125
+ ></litro-card>
126
126
  `)}
127
- </sl-card-grid>
127
+ </litro-card-grid>
128
128
  </section>
129
129
  </main>
130
130
  </div>
@@ -0,0 +1,108 @@
1
+ /* highlight.js — fire theme (always dark background) */
2
+
3
+ pre:has(.hljs) {
4
+ background-color: #0d0d10;
5
+ color: #cbd5e1;
6
+ }
7
+
8
+ [data-theme="dark"] pre:has(.hljs) {
9
+ background-color: #0d0d10;
10
+ color: #cbd5e1;
11
+ }
12
+
13
+ .hljs {
14
+ color: #cbd5e1;
15
+ background: transparent;
16
+ }
17
+
18
+ /* Keywords: const, let, if, class, return … */
19
+ .hljs-keyword,
20
+ .hljs-selector-tag,
21
+ .hljs-tag {
22
+ color: #f97316;
23
+ }
24
+
25
+ /* Strings and attribute values */
26
+ .hljs-string,
27
+ .hljs-attr,
28
+ .hljs-attribute {
29
+ color: #38bdf8;
30
+ }
31
+
32
+ /* Numbers and boolean literals */
33
+ .hljs-number,
34
+ .hljs-literal {
35
+ color: #fbbf24;
36
+ }
37
+
38
+ /* Function/class names, built-ins */
39
+ .hljs-title,
40
+ .hljs-title.class_,
41
+ .hljs-title.function_,
42
+ .hljs-built_in {
43
+ color: #fb923c;
44
+ }
45
+
46
+ /* Comments */
47
+ .hljs-comment {
48
+ color: #6b7280;
49
+ font-style: italic;
50
+ }
51
+
52
+ /* Variables and parameters */
53
+ .hljs-variable,
54
+ .hljs-params {
55
+ color: #cbd5e1;
56
+ }
57
+
58
+ /* Operators and punctuation */
59
+ .hljs-operator,
60
+ .hljs-punctuation {
61
+ color: #94a3b8;
62
+ }
63
+
64
+ /* Meta / imports / decorators */
65
+ .hljs-meta,
66
+ .hljs-meta .hljs-keyword {
67
+ color: #38bdf8;
68
+ }
69
+
70
+ /* Type annotations */
71
+ .hljs-type {
72
+ color: #fb923c;
73
+ }
74
+
75
+ /* Diff deletions */
76
+ .hljs-deletion {
77
+ color: #f87171;
78
+ background: rgba(248, 113, 113, 0.1);
79
+ }
80
+
81
+ /* Diff additions */
82
+ .hljs-addition {
83
+ color: #4ade80;
84
+ background: rgba(74, 222, 128, 0.1);
85
+ }
86
+
87
+ /* Section / selector */
88
+ .hljs-section,
89
+ .hljs-selector-class,
90
+ .hljs-selector-id {
91
+ color: #fb923c;
92
+ }
93
+
94
+ /* Symbol / bullet */
95
+ .hljs-symbol,
96
+ .hljs-bullet,
97
+ .hljs-link {
98
+ color: #38bdf8;
99
+ }
100
+
101
+ /* Emphasis */
102
+ .hljs-emphasis {
103
+ font-style: italic;
104
+ }
105
+
106
+ .hljs-strong {
107
+ font-weight: bold;
108
+ }
@@ -1,3 +1,23 @@
1
+ /* FOUCE - https://www.abeautifulsite.net/posts/flash-of-undefined-custom-elements/ */
2
+ :not(:defined) {
3
+ visibility: hidden;
4
+ }
5
+
6
+ /* Shoelace theme bridge — map sl-color-primary-* to Litro's accent palette */
7
+ :root {
8
+ --sl-color-primary-50: #f5f3ff;
9
+ --sl-color-primary-100: #ede9fe;
10
+ --sl-color-primary-200: #ddd6fe;
11
+ --sl-color-primary-300: #c4b5fd;
12
+ --sl-color-primary-400: #a78bfa;
13
+ --sl-color-primary-500: #8b5cf6;
14
+ --sl-color-primary-600: #7c3aed;
15
+ --sl-color-primary-700: #6d28d9;
16
+ --sl-color-primary-800: #5b21b6;
17
+ --sl-color-primary-900: #4c1d95;
18
+ --sl-color-primary-950: #2e1065;
19
+ }
20
+
1
21
  /* Starlight design tokens — light mode defaults */
2
22
  :root {
3
23
  --sl-color-white: #fff;
@@ -30,14 +50,14 @@
30
50
  --sl-font-sans: ui-sans-serif, system-ui, -apple-system, sans-serif;
31
51
  --sl-font-mono: ui-monospace, "Cascadia Code", "Fira Code", monospace;
32
52
 
33
- --sl-text-xs: 0.75rem;
34
- --sl-text-sm: 0.875rem;
53
+ --sl-text-xs: 0.75rem;
54
+ --sl-text-sm: 0.875rem;
35
55
  --sl-text-base: 1rem;
36
- --sl-text-lg: 1.125rem;
37
- --sl-text-xl: 1.25rem;
38
- --sl-text-2xl: 1.5rem;
39
- --sl-text-3xl: 1.875rem;
40
- --sl-text-4xl: 2.25rem;
56
+ --sl-text-lg: 1.125rem;
57
+ --sl-text-xl: 1.25rem;
58
+ --sl-text-2xl: 1.5rem;
59
+ --sl-text-3xl: 1.875rem;
60
+ --sl-text-4xl: 2.25rem;
41
61
 
42
62
  --sl-nav-height: 3.5rem;
43
63
  --sl-sidebar-width: 16rem;
@@ -54,7 +74,7 @@
54
74
  }
55
75
 
56
76
  /* Dark mode overrides */
57
- [data-theme='dark'] {
77
+ [data-theme="dark"] {
58
78
  --sl-color-text: #f0f0f0;
59
79
  --sl-color-bg: #17181c;
60
80
  --sl-color-bg-sidebar: #1e1f24;
@@ -80,7 +100,9 @@
80
100
  }
81
101
 
82
102
  /* Base reset */
83
- *, *::before, *::after {
103
+ *,
104
+ *::before,
105
+ *::after {
84
106
  box-sizing: border-box;
85
107
  }
86
108
 
@@ -99,7 +121,12 @@ body {
99
121
  }
100
122
 
101
123
  /* Typography reset for content areas */
102
- h1, h2, h3, h4, h5, h6 {
124
+ h1,
125
+ h2,
126
+ h3,
127
+ h4,
128
+ h5,
129
+ h6 {
103
130
  margin-top: 1.5em;
104
131
  margin-bottom: 0.5em;
105
132
  font-weight: 600;
@@ -107,10 +134,20 @@ h1, h2, h3, h4, h5, h6 {
107
134
  color: var(--sl-color-text);
108
135
  }
109
136
 
110
- h1 { font-size: var(--sl-text-4xl); }
111
- h2 { font-size: var(--sl-text-2xl); border-bottom: 1px solid var(--sl-color-border); padding-bottom: 0.25em; }
112
- h3 { font-size: var(--sl-text-xl); }
113
- h4 { font-size: var(--sl-text-lg); }
137
+ h1 {
138
+ font-size: var(--sl-text-4xl);
139
+ }
140
+ h2 {
141
+ font-size: var(--sl-text-2xl);
142
+ border-bottom: 1px solid var(--sl-color-border);
143
+ padding-bottom: 0.25em;
144
+ }
145
+ h3 {
146
+ font-size: var(--sl-text-xl);
147
+ }
148
+ h4 {
149
+ font-size: var(--sl-text-lg);
150
+ }
114
151
 
115
152
  p {
116
153
  margin-top: 0;
@@ -147,7 +184,7 @@ pre {
147
184
  line-height: 1.6;
148
185
  }
149
186
 
150
- [data-theme='dark'] pre {
187
+ [data-theme="dark"] pre {
151
188
  background-color: #0d0e11;
152
189
  color: #e2e4e9;
153
190
  }
@@ -166,7 +203,8 @@ table {
166
203
  font-size: var(--sl-text-sm);
167
204
  }
168
205
 
169
- th, td {
206
+ th,
207
+ td {
170
208
  border: 1px solid var(--sl-color-border);
171
209
  padding: 0.5rem 0.75rem;
172
210
  text-align: left;
@@ -177,11 +215,12 @@ th {
177
215
  font-weight: 600;
178
216
  }
179
217
 
180
- [data-theme='dark'] th {
218
+ [data-theme="dark"] th {
181
219
  background-color: var(--sl-color-gray-1);
182
220
  }
183
221
 
184
- ul, ol {
222
+ ul,
223
+ ol {
185
224
  padding-left: 1.5rem;
186
225
  margin: 0 0 1rem;
187
226
  }
@@ -199,7 +238,7 @@ blockquote {
199
238
  border-radius: 0 var(--sl-border-radius) var(--sl-border-radius) 0;
200
239
  }
201
240
 
202
- [data-theme='dark'] blockquote {
241
+ [data-theme="dark"] blockquote {
203
242
  background-color: var(--sl-color-accent-low);
204
243
  }
205
244
 
@@ -18,13 +18,13 @@ const LABELS: Record<AsideType, string> = {
18
18
  };
19
19
 
20
20
  /**
21
- * <sl-aside type="tip" title="Custom Title">
21
+ * <litro-aside type="tip" title="Custom Title">
22
22
  * Callout box with an icon and colored left border.
23
23
  * Slot content is the body.
24
- * </sl-aside>
24
+ * </litro-aside>
25
25
  */
26
- @customElement('sl-aside')
27
- export class SlAside extends LitElement {
26
+ @customElement('litro-aside')
27
+ export class LitroAside extends LitElement {
28
28
  static override properties = {
29
29
  type: { type: String },
30
30
  title: { type: String },
@@ -88,4 +88,4 @@ export class SlAside extends LitElement {
88
88
  }
89
89
  }
90
90
 
91
- export default SlAside;
91
+ export default LitroAside;
@@ -4,12 +4,12 @@ import { customElement } from 'lit/decorators.js';
4
4
  type BadgeVariant = 'note' | 'tip' | 'caution' | 'danger' | 'default';
5
5
 
6
6
  /**
7
- * <sl-badge variant="tip" text="New">
7
+ * <litro-badge variant="tip" text="New">
8
8
  * Inline color-coded chip. Use `text` attribute or slot content.
9
- * </sl-badge>
9
+ * </litro-badge>
10
10
  */
11
- @customElement('sl-badge')
12
- export class SlBadge extends LitElement {
11
+ @customElement('litro-badge')
12
+ export class LitroBadge extends LitElement {
13
13
  static override properties = {
14
14
  variant: { type: String },
15
15
  text: { type: String },
@@ -73,4 +73,4 @@ export class SlBadge extends LitElement {
73
73
  }
74
74
  }
75
75
 
76
- export default SlBadge;
76
+ export default LitroBadge;
@@ -2,13 +2,13 @@ import { LitElement, html, css } from 'lit';
2
2
  import { customElement } from 'lit/decorators.js';
3
3
 
4
4
  /**
5
- * <sl-card-grid>
6
- * Responsive auto-fit grid for <sl-card> elements.
7
- * Single slot — place <sl-card> elements directly inside.
8
- * </sl-card-grid>
5
+ * <litro-card-grid>
6
+ * Responsive auto-fit grid for <litro-card> elements.
7
+ * Single slot — place <litro-card> elements directly inside.
8
+ * </litro-card-grid>
9
9
  */
10
- @customElement('sl-card-grid')
11
- export class SlCardGrid extends LitElement {
10
+ @customElement('litro-card-grid')
11
+ export class LitroCardGrid extends LitElement {
12
12
  static override styles = css`
13
13
  :host {
14
14
  display: block;
@@ -31,4 +31,4 @@ export class SlCardGrid extends LitElement {
31
31
  }
32
32
  }
33
33
 
34
- export default SlCardGrid;
34
+ export default LitroCardGrid;
@@ -2,28 +2,32 @@ import { LitElement, html, css } from 'lit';
2
2
  import { customElement } from 'lit/decorators.js';
3
3
 
4
4
  /**
5
- * <sl-card title="Feature" description="Short desc" href="/docs/feature">
5
+ * <litro-card title="Feature" description="Short desc" href="/docs/feature">
6
6
  * Renders as an <a> when `href` is set, otherwise a <div>.
7
7
  * Rotating accent color per nth-card via CSS counter.
8
- * </sl-card>
8
+ * </litro-card>
9
9
  */
10
- @customElement('sl-card')
11
- export class SlCard extends LitElement {
10
+ @customElement('litro-card')
11
+ export class LitroCard extends LitElement {
12
12
  static override properties = {
13
13
  title: { type: String },
14
14
  description: { type: String },
15
15
  icon: { type: String },
16
+ iconSrc: { type: String },
16
17
  href: { type: String },
17
18
  };
18
19
 
19
20
  static override styles = css`
20
21
  :host {
21
- display: block;
22
+ display: flex;
23
+ flex-direction: column;
22
24
  counter-increment: card;
23
25
  }
24
26
 
25
27
  .card {
26
- display: block;
28
+ display: flex;
29
+ flex-direction: column;
30
+ flex: 1;
27
31
  padding: 1.25rem 1.5rem;
28
32
  border: 1px solid var(--sl-color-border, #e8e8e8);
29
33
  border-radius: var(--sl-border-radius, 0.375rem);
@@ -45,16 +49,31 @@ export class SlCard extends LitElement {
45
49
  transform: translateY(-2px);
46
50
  }
47
51
 
52
+ .card-header {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 0.6rem;
56
+ margin-bottom: 0.4rem;
57
+ }
58
+
48
59
  .card-icon {
49
- font-size: 1.75rem;
50
- margin-bottom: 0.5rem;
60
+ font-size: 1.5rem;
61
+ flex-shrink: 0;
62
+ line-height: 1;
63
+ }
64
+
65
+ .card-icon-img {
66
+ width: 1.5rem;
67
+ height: 1.5rem;
68
+ object-fit: contain;
69
+ flex-shrink: 0;
51
70
  }
52
71
 
53
72
  .card-title {
54
73
  font-size: var(--sl-text-lg, 1.125rem);
55
74
  font-weight: 600;
56
75
  color: var(--sl-color-text, #23262f);
57
- margin: 0 0 0.4rem;
76
+ margin: 0;
58
77
  }
59
78
 
60
79
  .card-desc {
@@ -72,12 +91,17 @@ export class SlCard extends LitElement {
72
91
  title = '';
73
92
  description = '';
74
93
  icon = '';
94
+ iconSrc = '';
75
95
  href = '';
76
96
 
77
97
  override render() {
78
98
  const inner = html`
79
- ${this.icon ? html`<div class="card-icon">${this.icon}</div>` : ''}
80
- <p class="card-title">${this.title}</p>
99
+ <div class="card-header">
100
+ ${this.iconSrc
101
+ ? html`<img class="card-icon-img" src="${this.iconSrc}" alt="" aria-hidden="true" />`
102
+ : this.icon ? html`<span class="card-icon">${this.icon}</span>` : ''}
103
+ <p class="card-title">${this.title}</p>
104
+ </div>
81
105
  ${this.description ? html`<p class="card-desc">${this.description}</p>` : ''}
82
106
  <div class="card-slot"><slot></slot></div>
83
107
  `;
@@ -88,4 +112,4 @@ export class SlCard extends LitElement {
88
112
  }
89
113
  }
90
114
 
91
- export default SlCard;
115
+ export default LitroCard;
@@ -2,13 +2,13 @@ import { LitElement, html, css } from 'lit';
2
2
  import { customElement } from 'lit/decorators.js';
3
3
 
4
4
  /**
5
- * <sl-tab-item label="Tab Label">
6
- * A single tab panel managed by a parent <sl-tabs> element.
5
+ * <litro-tab-item label="Tab Label">
6
+ * A single tab panel managed by a parent <litro-tabs> element.
7
7
  * Hidden automatically when not selected.
8
- * </sl-tab-item>
8
+ * </litro-tab-item>
9
9
  */
10
- @customElement('sl-tab-item')
11
- export class SlTabItem extends LitElement {
10
+ @customElement('litro-tab-item')
11
+ export class LitroTabItem extends LitElement {
12
12
  static override properties = {
13
13
  label: { type: String },
14
14
  selected: { type: Boolean, reflect: true },
@@ -32,4 +32,4 @@ export class SlTabItem extends LitElement {
32
32
  }
33
33
  }
34
34
 
35
- export default SlTabItem;
35
+ export default LitroTabItem;