bulma-turbo-themes 0.10.8 → 0.11.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.
- checksums.yaml +4 -4
- data/README.md +26 -26
- data/lib/bulma-turbo-themes.rb +3 -4
- metadata +23 -58
- data/_data/i18n.yml +0 -3
- data/_layouts/default.html +0 -377
- data/assets/css/custom.css +0 -62
- data/assets/css/themes/base.css +0 -2
- data/assets/css/themes/bulma-dark.css +0 -1
- data/assets/css/themes/bulma-light.css +0 -1
- data/assets/css/themes/catppuccin-frappe.css +0 -1
- data/assets/css/themes/catppuccin-latte.css +0 -1
- data/assets/css/themes/catppuccin-macchiato.css +0 -1
- data/assets/css/themes/catppuccin-mocha.css +0 -1
- data/assets/css/themes/critical.css +0 -1
- data/assets/css/themes/dracula.css +0 -1
- data/assets/css/themes/github-dark.css +0 -1
- data/assets/css/themes/github-light.css +0 -1
- data/assets/img/bulma-logo-dark.png +0 -0
- data/assets/img/bulma-logo-dark.webp +0 -0
- data/assets/img/bulma-logo.png +0 -0
- data/assets/img/bulma-logo.webp +0 -0
- data/assets/img/catppuccin-logo-latte.png +0 -0
- data/assets/img/catppuccin-logo-latte.webp +0 -0
- data/assets/img/catppuccin-logo-macchiato.png +0 -0
- data/assets/img/catppuccin-logo-macchiato.webp +0 -0
- data/assets/img/dracula-logo.png +0 -0
- data/assets/img/dracula-logo.webp +0 -0
- data/assets/img/github-logo-dark.png +0 -0
- data/assets/img/github-logo-dark.webp +0 -0
- data/assets/img/github-logo-light.png +0 -0
- data/assets/img/github-logo-light.webp +0 -0
- data/assets/js/theme-selector.js +0 -687
- data/assets/js/theme-selector.min.js +0 -1
- data/lib/bulma-turbo-themes/version.rb +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 784f6197542e1d800be530f0faa4cd39038b5f264cd1b86e49919ef15cce8c61
|
|
4
|
+
data.tar.gz: 5a51c92f26a56d8c472b4b919a08b782aefbb18692422c8e5ed771149471c7a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9db3fd7feefb14f6bf8fdb8967c745da351ab02e40de819f279870c0523f0ee7c8fe17754141fc6549e1a1c272ef031e10c709bd3ab15cfaf70a1569aed27f67
|
|
7
|
+
data.tar.gz: 4858b5f3da6e499b6dd8730fb16e70bcac5bfc72b857ff66bc8b57d4fb640ec4955bc5cff364374217158a66fae2e2ee42a4794895cc87394565c1c98da30266
|
data/README.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# turbo-themes
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Universal, accessible theme packs and a drop-in theme selector.
|
|
4
4
|
|
|
5
5
|
[](https://bun.sh/)
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
|
-
[](https://codecov.io/gh/TurboCoder13/turbo-themes)
|
|
8
8
|
[](LICENSE)
|
|
9
|
-
[](https://github.com/TurboCoder13/turbo-themes/actions/workflows/quality-ci-main.yml?query=branch%3Amain)
|
|
10
|
+
[](https://github.com/TurboCoder13/turbo-themes/actions/workflows/quality-ci-main.yml?query=branch%3Amain)
|
|
11
|
+
[](https://github.com/TurboCoder13/turbo-themes/actions/workflows/reporting-lighthouse-ci.yml?query=branch%3Amain)
|
|
12
12
|
|
|
13
|
-
[](https://github.com/TurboCoder13/turbo-themes/actions/workflows/security-codeql.yml?query=branch%3Amain)
|
|
14
14
|
[](https://www.bestpractices.dev/projects/11471)
|
|
15
15
|
[](SECURITY.md)
|
|
16
|
-
[](https://github.com/TurboCoder13/
|
|
16
|
+
[](https://github.com/TurboCoder13/turbo-themes/actions/workflows/security-sbom.yml)
|
|
17
17
|
|
|
18
|
-
[](https://www.npmjs.com/package/@turbocoder13/turbo-themes)
|
|
19
|
+
[](https://rubygems.org/gems/turbo-themes)
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
@@ -36,12 +36,12 @@ Install as a Ruby gem:
|
|
|
36
36
|
|
|
37
37
|
```ruby
|
|
38
38
|
# Gemfile
|
|
39
|
-
gem "
|
|
39
|
+
gem "turbo-themes", "~> 0.10"
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
```yaml
|
|
43
43
|
# _config.yml
|
|
44
|
-
theme:
|
|
44
|
+
theme: turbo-themes
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
Then run:
|
|
@@ -63,10 +63,10 @@ Install via Bun (recommended) or npm:
|
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
# Using Bun (recommended - 5-10x faster)
|
|
66
|
-
bun add @turbocoder13/
|
|
66
|
+
bun add @turbocoder13/turbo-themes
|
|
67
67
|
|
|
68
68
|
# Using npm
|
|
69
|
-
npm install @turbocoder13/
|
|
69
|
+
npm install @turbocoder13/turbo-themes
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
## Quick start
|
|
@@ -115,7 +115,7 @@ npm install @turbocoder13/bulma-turbo-themes
|
|
|
115
115
|
|
|
116
116
|
### Non-Jekyll Projects
|
|
117
117
|
|
|
118
|
-
1. Copy CSS files from `node_modules/@turbocoder13/
|
|
118
|
+
1. Copy CSS files from `node_modules/@turbocoder13/turbo-themes/assets/css/themes/` to your project:
|
|
119
119
|
- `global.css` (required)
|
|
120
120
|
- Flavor CSS files (e.g., `catppuccin-mocha.css`, `dracula.css`, `github-dark.css`) - copy the ones you want to use
|
|
121
121
|
2. Include CSS links (adjust paths to match your project structure):
|
|
@@ -150,7 +150,7 @@ npm install @turbocoder13/bulma-turbo-themes
|
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
```ts
|
|
153
|
-
import { initTheme, wireFlavorSelector } from '@turbocoder13/
|
|
153
|
+
import { initTheme, wireFlavorSelector } from '@turbocoder13/turbo-themes';
|
|
154
154
|
|
|
155
155
|
document.addEventListener('DOMContentLoaded', () => {
|
|
156
156
|
initTheme(document, window);
|
|
@@ -165,15 +165,15 @@ This package provides platform-agnostic design tokens that work in React Native,
|
|
|
165
165
|
#### Installation
|
|
166
166
|
|
|
167
167
|
```bash
|
|
168
|
-
bun add @turbocoder13/
|
|
168
|
+
bun add @turbocoder13/turbo-themes
|
|
169
169
|
# or
|
|
170
|
-
npm install @turbocoder13/
|
|
170
|
+
npm install @turbocoder13/turbo-themes
|
|
171
171
|
```
|
|
172
172
|
|
|
173
173
|
#### Basic Usage (Without Context)
|
|
174
174
|
|
|
175
175
|
```tsx
|
|
176
|
-
import { useTheme, useThemeColors } from '@turbocoder13/
|
|
176
|
+
import { useTheme, useThemeColors } from '@turbocoder13/turbo-themes/tokens/react-native';
|
|
177
177
|
|
|
178
178
|
function MyComponent() {
|
|
179
179
|
const { colors, styles, theme } = useTheme('catppuccin-mocha');
|
|
@@ -192,7 +192,7 @@ function MyComponent() {
|
|
|
192
192
|
#### With ThemeProvider (Recommended)
|
|
193
193
|
|
|
194
194
|
```tsx
|
|
195
|
-
import { ThemeProvider, useThemeContext } from '@turbocoder13/
|
|
195
|
+
import { ThemeProvider, useThemeContext } from '@turbocoder13/turbo-themes/tokens/react-native';
|
|
196
196
|
import { useColorScheme } from 'react-native';
|
|
197
197
|
|
|
198
198
|
// Wrap your app with ThemeProvider
|
|
@@ -229,10 +229,10 @@ function MyApp() {
|
|
|
229
229
|
|
|
230
230
|
| Import Path | Use Case |
|
|
231
231
|
|-------------|----------|
|
|
232
|
-
| `@turbocoder13/
|
|
233
|
-
| `@turbocoder13/
|
|
234
|
-
| `@turbocoder13/
|
|
235
|
-
| `@turbocoder13/
|
|
232
|
+
| `@turbocoder13/turbo-themes/tokens` | Platform-agnostic tokens (pure data) |
|
|
233
|
+
| `@turbocoder13/turbo-themes/tokens/react-native` | React Native utilities, hooks, and context |
|
|
234
|
+
| `@turbocoder13/turbo-themes/tokens.json` | JSON tokens for Flutter, Swift, Kotlin |
|
|
235
|
+
| `@turbocoder13/turbo-themes/css/*` | CSS files for web |
|
|
236
236
|
|
|
237
237
|
#### Pre-built Styles
|
|
238
238
|
|
|
@@ -284,8 +284,8 @@ For detailed E2E testing documentation, see `docs/E2E-TESTING.md`.
|
|
|
284
284
|
|
|
285
285
|
```bash
|
|
286
286
|
# Clone and install
|
|
287
|
-
git clone https://github.com/TurboCoder13/
|
|
288
|
-
cd
|
|
287
|
+
git clone https://github.com/TurboCoder13/turbo-themes.git
|
|
288
|
+
cd turbo-themes
|
|
289
289
|
bun install
|
|
290
290
|
bundle install
|
|
291
291
|
|
data/lib/bulma-turbo-themes.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "bulma-turbo-themes/version"
|
|
4
|
-
|
|
5
|
-
# Jekyll theme for Bulma Turbo Themes
|
|
6
|
-
# Provides accessible theme packs and theme selector for Bulma CSS framework
|
|
7
3
|
module BulmaTurboThemes
|
|
4
|
+
VERSION = "0.11.0"
|
|
8
5
|
end
|
|
9
6
|
|
|
7
|
+
require "turbo-themes"
|
|
8
|
+
|
metadata
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bulma-turbo-themes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Turbo Coder
|
|
8
|
-
|
|
9
|
-
bindir: exe
|
|
8
|
+
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: turbo-themes
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
- - "<"
|
|
21
|
-
- !ruby/object:Gem::Version
|
|
22
|
-
version: '5.0'
|
|
18
|
+
version: '1.0'
|
|
23
19
|
type: :runtime
|
|
24
20
|
prerelease: false
|
|
25
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
22
|
requirements:
|
|
27
|
-
- - "
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
version: '3.5'
|
|
30
|
-
- - "<"
|
|
23
|
+
- - "~>"
|
|
31
24
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
33
|
-
description:
|
|
34
|
-
|
|
25
|
+
version: '1.0'
|
|
26
|
+
description: This gem has been renamed to 'turbo-themes'. Please update your Gemfile
|
|
27
|
+
to `gem "turbo-themes"`.
|
|
35
28
|
email:
|
|
36
29
|
- turbocoder13@users.noreply.github.com
|
|
37
30
|
executables: []
|
|
@@ -41,48 +34,21 @@ files:
|
|
|
41
34
|
- CHANGELOG.md
|
|
42
35
|
- LICENSE
|
|
43
36
|
- README.md
|
|
44
|
-
- _data/i18n.yml
|
|
45
|
-
- _layouts/default.html
|
|
46
|
-
- assets/css/custom.css
|
|
47
|
-
- assets/css/themes/base.css
|
|
48
|
-
- assets/css/themes/bulma-dark.css
|
|
49
|
-
- assets/css/themes/bulma-light.css
|
|
50
|
-
- assets/css/themes/catppuccin-frappe.css
|
|
51
|
-
- assets/css/themes/catppuccin-latte.css
|
|
52
|
-
- assets/css/themes/catppuccin-macchiato.css
|
|
53
|
-
- assets/css/themes/catppuccin-mocha.css
|
|
54
|
-
- assets/css/themes/critical.css
|
|
55
|
-
- assets/css/themes/dracula.css
|
|
56
|
-
- assets/css/themes/github-dark.css
|
|
57
|
-
- assets/css/themes/github-light.css
|
|
58
|
-
- assets/img/bulma-logo-dark.png
|
|
59
|
-
- assets/img/bulma-logo-dark.webp
|
|
60
|
-
- assets/img/bulma-logo.png
|
|
61
|
-
- assets/img/bulma-logo.webp
|
|
62
|
-
- assets/img/catppuccin-logo-latte.png
|
|
63
|
-
- assets/img/catppuccin-logo-latte.webp
|
|
64
|
-
- assets/img/catppuccin-logo-macchiato.png
|
|
65
|
-
- assets/img/catppuccin-logo-macchiato.webp
|
|
66
|
-
- assets/img/dracula-logo.png
|
|
67
|
-
- assets/img/dracula-logo.webp
|
|
68
|
-
- assets/img/github-logo-dark.png
|
|
69
|
-
- assets/img/github-logo-dark.webp
|
|
70
|
-
- assets/img/github-logo-light.png
|
|
71
|
-
- assets/img/github-logo-light.webp
|
|
72
|
-
- assets/js/theme-selector.js
|
|
73
|
-
- assets/js/theme-selector.min.js
|
|
74
37
|
- lib/bulma-turbo-themes.rb
|
|
75
|
-
|
|
76
|
-
homepage: https://github.com/TurboCoder13/bulma-turbo-themes
|
|
38
|
+
homepage: https://github.com/TurboCoder13/turbo-themes
|
|
77
39
|
licenses:
|
|
78
40
|
- MIT
|
|
79
41
|
metadata:
|
|
80
|
-
bug_tracker_uri: https://github.com/TurboCoder13/
|
|
81
|
-
changelog_uri: https://github.com/TurboCoder13/
|
|
82
|
-
documentation_uri: https://turbocoder13.github.io/
|
|
83
|
-
homepage_uri: https://github.com/TurboCoder13/
|
|
84
|
-
source_code_uri: https://github.com/TurboCoder13/
|
|
85
|
-
post_install_message:
|
|
42
|
+
bug_tracker_uri: https://github.com/TurboCoder13/turbo-themes/issues
|
|
43
|
+
changelog_uri: https://github.com/TurboCoder13/turbo-themes/blob/main/CHANGELOG.md
|
|
44
|
+
documentation_uri: https://turbocoder13.github.io/turbo-themes/
|
|
45
|
+
homepage_uri: https://github.com/TurboCoder13/turbo-themes
|
|
46
|
+
source_code_uri: https://github.com/TurboCoder13/turbo-themes
|
|
47
|
+
post_install_message: |
|
|
48
|
+
⚠️ DEPRECATION WARNING ⚠️
|
|
49
|
+
The 'bulma-turbo-themes' gem has been renamed to 'turbo-themes'.
|
|
50
|
+
Please update your Gemfile:
|
|
51
|
+
gem "turbo-themes"
|
|
86
52
|
rdoc_options: []
|
|
87
53
|
require_paths:
|
|
88
54
|
- lib
|
|
@@ -97,8 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
97
63
|
- !ruby/object:Gem::Version
|
|
98
64
|
version: '0'
|
|
99
65
|
requirements: []
|
|
100
|
-
rubygems_version: 3.
|
|
101
|
-
signing_key:
|
|
66
|
+
rubygems_version: 3.6.9
|
|
102
67
|
specification_version: 4
|
|
103
|
-
summary:
|
|
68
|
+
summary: 'DEPRECATED: Use ''turbo-themes'' gem instead.'
|
|
104
69
|
test_files: []
|
data/_data/i18n.yml
DELETED
data/_layouts/default.html
DELETED
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="{{ site.lang | default: 'en' }}" data-theme="auto" data-baseurl="{{ site.baseurl }}">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<meta
|
|
7
|
-
name="app-i18n"
|
|
8
|
-
data-theme-label="{{ site.data.i18n.en.theme_label }}"
|
|
9
|
-
data-current-theme-title-template="{{ site.data.i18n.en.current_theme_title }}"
|
|
10
|
-
/>
|
|
11
|
-
<!--
|
|
12
|
-
CSP Security Trade-off: 'unsafe-inline' for script-src
|
|
13
|
-
========================================================
|
|
14
|
-
Why required: The inline theme-blocking script (lines 19-87 below) must run
|
|
15
|
-
synchronously before first paint to prevent Flash of Unstyled Content (FOUC).
|
|
16
|
-
Without it, users would see the wrong theme briefly before it snaps to their
|
|
17
|
-
saved preference — a jarring experience.
|
|
18
|
-
|
|
19
|
-
Why not use nonces/hashes:
|
|
20
|
-
- Nonces require server-side generation (not possible with static Jekyll/GitHub Pages)
|
|
21
|
-
- Hashes are brittle and break on any script change, causing CI failures
|
|
22
|
-
|
|
23
|
-
Mitigations in place:
|
|
24
|
-
- Inline script validates theme IDs against allowlist (prevents class injection)
|
|
25
|
-
- URL sanitization prevents XSS via manipulated data-baseurl
|
|
26
|
-
- No eval() or dynamic code execution
|
|
27
|
-
- All other scripts are external files
|
|
28
|
-
|
|
29
|
-
Future tightening: Service worker precomputed theme class, or migration to SSR
|
|
30
|
-
with nonce-based CSP.
|
|
31
|
-
|
|
32
|
-
See: docs/adr/0004-csp-unsafe-inline-for-theme-blocking-script.md
|
|
33
|
-
-->
|
|
34
|
-
<!-- Note: frame-ancestors can only be set via HTTP header, not meta tag, so it's omitted here -->
|
|
35
|
-
<meta
|
|
36
|
-
http-equiv="Content-Security-Policy"
|
|
37
|
-
content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' https://fonts.googleapis.com https://fonts.gstatic.com; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests"
|
|
38
|
-
/>
|
|
39
|
-
<title>{{ page.title | default: site.title }}</title>
|
|
40
|
-
{% seo %}
|
|
41
|
-
<!-- Blocking script to apply theme immediately from localStorage -->
|
|
42
|
-
<!-- This prevents FOUC by setting theme class before first paint -->
|
|
43
|
-
<script>
|
|
44
|
-
(function () {
|
|
45
|
-
try {
|
|
46
|
-
var STORAGE_KEY = 'bulma-theme-flavor';
|
|
47
|
-
var DEFAULT_THEME = 'catppuccin-mocha';
|
|
48
|
-
// Valid theme IDs - must match THEMES array in theme-selector.js
|
|
49
|
-
var VALID_THEMES = [
|
|
50
|
-
'bulma-light',
|
|
51
|
-
'bulma-dark',
|
|
52
|
-
'catppuccin-latte',
|
|
53
|
-
'catppuccin-frappe',
|
|
54
|
-
'catppuccin-macchiato',
|
|
55
|
-
'catppuccin-mocha',
|
|
56
|
-
'dracula',
|
|
57
|
-
'github-light',
|
|
58
|
-
'github-dark',
|
|
59
|
-
];
|
|
60
|
-
var savedTheme = localStorage.getItem(STORAGE_KEY) || DEFAULT_THEME;
|
|
61
|
-
// Validate theme ID against allowed list to prevent invalid class/URL injection
|
|
62
|
-
if (VALID_THEMES.indexOf(savedTheme) === -1) {
|
|
63
|
-
savedTheme = DEFAULT_THEME;
|
|
64
|
-
}
|
|
65
|
-
var themeClass = 'theme-' + savedTheme;
|
|
66
|
-
|
|
67
|
-
// Apply theme class using classList to preserve existing classes
|
|
68
|
-
// First remove any existing theme classes
|
|
69
|
-
var classList = document.documentElement.classList;
|
|
70
|
-
var classesToRemove = [];
|
|
71
|
-
for (var i = 0; i < classList.length; i++) {
|
|
72
|
-
if (classList[i].indexOf('theme-') === 0) {
|
|
73
|
-
classesToRemove.push(classList[i]);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
classesToRemove.forEach(function (cls) {
|
|
77
|
-
classList.remove(cls);
|
|
78
|
-
});
|
|
79
|
-
// Add the new theme class
|
|
80
|
-
classList.add(themeClass);
|
|
81
|
-
|
|
82
|
-
// Preload theme CSS for faster loading
|
|
83
|
-
var baseUrl = document.documentElement.getAttribute('data-baseurl') || '';
|
|
84
|
-
// Sanitize baseUrl to prevent XSS attacks
|
|
85
|
-
function sanitizeUrlPath(path) {
|
|
86
|
-
if (!path) return '';
|
|
87
|
-
// Remove or encode dangerous characters that could be interpreted as HTML/JS
|
|
88
|
-
return path.replace(/[<>"'`&]/g, '').replace(/\\/g, '');
|
|
89
|
-
}
|
|
90
|
-
var sanitizedBaseUrl = sanitizeUrlPath(baseUrl);
|
|
91
|
-
// Resolve path relative to site root
|
|
92
|
-
var base = sanitizedBaseUrl
|
|
93
|
-
? window.location.origin + sanitizedBaseUrl + '/'
|
|
94
|
-
: window.location.origin + '/';
|
|
95
|
-
var themePath = new URL('assets/css/themes/' + savedTheme + '.css', base).pathname;
|
|
96
|
-
|
|
97
|
-
// Create preload link
|
|
98
|
-
var preloadLink = document.createElement('link');
|
|
99
|
-
preloadLink.rel = 'preload';
|
|
100
|
-
preloadLink.as = 'style';
|
|
101
|
-
preloadLink.href = themePath;
|
|
102
|
-
document.head.appendChild(preloadLink);
|
|
103
|
-
|
|
104
|
-
// Store theme info for later use
|
|
105
|
-
window.__INITIAL_THEME__ = savedTheme;
|
|
106
|
-
} catch (e) {
|
|
107
|
-
// Silently fail if localStorage is not available
|
|
108
|
-
console.warn('Unable to load saved theme:', e);
|
|
109
|
-
}
|
|
110
|
-
})();
|
|
111
|
-
</script>
|
|
112
|
-
<link rel="icon" href="{{ '/favicon.ico' | relative_url }}" />
|
|
113
|
-
<link
|
|
114
|
-
rel="icon"
|
|
115
|
-
type="image/png"
|
|
116
|
-
href="{{ '/assets/img/bulma-logo.png' | relative_url }}"
|
|
117
|
-
media="(prefers-color-scheme: light)"
|
|
118
|
-
/>
|
|
119
|
-
<link
|
|
120
|
-
rel="icon"
|
|
121
|
-
type="image/png"
|
|
122
|
-
href="{{ '/assets/img/bulma-logo-dark.png' | relative_url }}"
|
|
123
|
-
media="(prefers-color-scheme: dark)"
|
|
124
|
-
/>
|
|
125
|
-
<link
|
|
126
|
-
rel="mask-icon"
|
|
127
|
-
href="{{ '/assets/img/bulma-logo.png' | relative_url }}"
|
|
128
|
-
color="#111827"
|
|
129
|
-
/>
|
|
130
|
-
<!--
|
|
131
|
-
Critical CSS removed - was causing theme override issues.
|
|
132
|
-
Theme CSS uses CSS variables for colors, but hardcoded critical CSS
|
|
133
|
-
was overriding them. The theme CSS is preloaded for fast loading.
|
|
134
|
-
-->
|
|
135
|
-
<!-- Base CSS (shared styles, loaded asynchronously) -->
|
|
136
|
-
<link
|
|
137
|
-
id="theme-base-css"
|
|
138
|
-
rel="preload"
|
|
139
|
-
as="style"
|
|
140
|
-
href="{{ '/assets/css/themes/base.css' | relative_url }}"
|
|
141
|
-
onload="this.rel = 'stylesheet'"
|
|
142
|
-
/>
|
|
143
|
-
<noscript>
|
|
144
|
-
<link rel="stylesheet" href="{{ '/assets/css/themes/base.css' | relative_url }}" />
|
|
145
|
-
</noscript>
|
|
146
|
-
<link rel="stylesheet" href="{{ '/assets/css/custom.css' | relative_url }}" />
|
|
147
|
-
<!-- Use minified JS in production for ~50% smaller payload -->
|
|
148
|
-
{% if jekyll.environment == 'production' %}
|
|
149
|
-
<script type="module" src="{{ '/assets/js/theme-selector.min.js' | relative_url }}"></script>
|
|
150
|
-
{% else %}
|
|
151
|
-
<script type="module" src="{{ '/assets/js/theme-selector.js' | relative_url }}"></script>
|
|
152
|
-
{% endif %}
|
|
153
|
-
<script>
|
|
154
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
155
|
-
// Initialize navbar highlighting
|
|
156
|
-
if (window.initNavbar) {
|
|
157
|
-
window.initNavbar(document);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Initialize burger menu toggle
|
|
161
|
-
const burgers = document.querySelectorAll('.navbar-burger');
|
|
162
|
-
burgers.forEach((burger) => {
|
|
163
|
-
burger.addEventListener('click', () => {
|
|
164
|
-
const targetId = burger.dataset.target;
|
|
165
|
-
const target = document.getElementById(targetId);
|
|
166
|
-
if (target) {
|
|
167
|
-
burger.classList.toggle('is-active');
|
|
168
|
-
target.classList.toggle('is-active');
|
|
169
|
-
// Update aria-expanded
|
|
170
|
-
const isExpanded = burger.classList.contains('is-active');
|
|
171
|
-
burger.setAttribute('aria-expanded', String(isExpanded));
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
</script>
|
|
177
|
-
</head>
|
|
178
|
-
<body>
|
|
179
|
-
<nav class="navbar is-spaced" role="navigation" aria-label="main navigation">
|
|
180
|
-
<div class="container">
|
|
181
|
-
<div class="navbar-brand">
|
|
182
|
-
<a class="navbar-item" href="{{ '/' | relative_url }}" data-testid="navbar-brand">
|
|
183
|
-
{{ site.title }}
|
|
184
|
-
</a>
|
|
185
|
-
<button
|
|
186
|
-
class="navbar-burger"
|
|
187
|
-
aria-label="menu"
|
|
188
|
-
aria-expanded="false"
|
|
189
|
-
data-target="navbarBasicExample"
|
|
190
|
-
type="button"
|
|
191
|
-
data-testid="navbar-burger"
|
|
192
|
-
style="min-width: 24px; min-height: 24px"
|
|
193
|
-
>
|
|
194
|
-
<span aria-hidden="true"></span>
|
|
195
|
-
<span aria-hidden="true"></span>
|
|
196
|
-
<span aria-hidden="true"></span>
|
|
197
|
-
</button>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<div id="navbarBasicExample" class="navbar-menu">
|
|
201
|
-
<div class="navbar-start">
|
|
202
|
-
<a class="navbar-item" href="{{ '/' | relative_url }}" data-testid="nav-home">Home</a>
|
|
203
|
-
<a
|
|
204
|
-
class="navbar-item"
|
|
205
|
-
href="{{ '/components/' | relative_url }}"
|
|
206
|
-
data-testid="nav-components"
|
|
207
|
-
>
|
|
208
|
-
Components
|
|
209
|
-
</a>
|
|
210
|
-
<a class="navbar-item" href="{{ '/forms/' | relative_url }}" data-testid="nav-forms"
|
|
211
|
-
>Forms</a
|
|
212
|
-
>
|
|
213
|
-
<div class="navbar-item has-dropdown is-hoverable">
|
|
214
|
-
<button
|
|
215
|
-
class="navbar-link"
|
|
216
|
-
id="nav-reports-trigger"
|
|
217
|
-
type="button"
|
|
218
|
-
aria-haspopup="true"
|
|
219
|
-
aria-expanded="false"
|
|
220
|
-
aria-controls="nav-reports-menu"
|
|
221
|
-
data-testid="nav-reports"
|
|
222
|
-
>
|
|
223
|
-
Reports
|
|
224
|
-
</button>
|
|
225
|
-
<div
|
|
226
|
-
class="navbar-dropdown"
|
|
227
|
-
id="nav-reports-menu"
|
|
228
|
-
aria-labelledby="nav-reports-trigger"
|
|
229
|
-
>
|
|
230
|
-
<a
|
|
231
|
-
class="navbar-item"
|
|
232
|
-
href="{{ '/coverage/' | relative_url }}"
|
|
233
|
-
target="_blank"
|
|
234
|
-
rel="noopener noreferrer"
|
|
235
|
-
aria-label="Coverage (opens in new tab)"
|
|
236
|
-
data-testid="nav-reports-coverage"
|
|
237
|
-
>
|
|
238
|
-
Coverage
|
|
239
|
-
<span
|
|
240
|
-
class="icon is-small"
|
|
241
|
-
style="margin-left: 0.25rem; display: inline-flex"
|
|
242
|
-
aria-hidden="true"
|
|
243
|
-
>
|
|
244
|
-
<svg
|
|
245
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
246
|
-
width="12"
|
|
247
|
-
height="12"
|
|
248
|
-
viewBox="0 0 24 24"
|
|
249
|
-
fill="none"
|
|
250
|
-
stroke="currentColor"
|
|
251
|
-
stroke-width="2"
|
|
252
|
-
stroke-linecap="round"
|
|
253
|
-
stroke-linejoin="round"
|
|
254
|
-
>
|
|
255
|
-
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
256
|
-
<polyline points="15 3 21 3 21 9"></polyline>
|
|
257
|
-
<line x1="10" y1="14" x2="21" y2="3"></line>
|
|
258
|
-
</svg>
|
|
259
|
-
</span>
|
|
260
|
-
</a>
|
|
261
|
-
<a
|
|
262
|
-
class="navbar-item"
|
|
263
|
-
href="{{ '/playwright/' | relative_url }}"
|
|
264
|
-
target="_blank"
|
|
265
|
-
rel="noopener noreferrer"
|
|
266
|
-
aria-label="Playwright (opens in new tab)"
|
|
267
|
-
data-testid="nav-reports-playwright"
|
|
268
|
-
>
|
|
269
|
-
Playwright
|
|
270
|
-
<span
|
|
271
|
-
class="icon is-small"
|
|
272
|
-
style="margin-left: 0.25rem; display: inline-flex"
|
|
273
|
-
aria-hidden="true"
|
|
274
|
-
>
|
|
275
|
-
<svg
|
|
276
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
277
|
-
width="12"
|
|
278
|
-
height="12"
|
|
279
|
-
viewBox="0 0 24 24"
|
|
280
|
-
fill="none"
|
|
281
|
-
stroke="currentColor"
|
|
282
|
-
stroke-width="2"
|
|
283
|
-
stroke-linecap="round"
|
|
284
|
-
stroke-linejoin="round"
|
|
285
|
-
>
|
|
286
|
-
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
287
|
-
<polyline points="15 3 21 3 21 9"></polyline>
|
|
288
|
-
<line x1="10" y1="14" x2="21" y2="3"></line>
|
|
289
|
-
</svg>
|
|
290
|
-
</span>
|
|
291
|
-
</a>
|
|
292
|
-
<a
|
|
293
|
-
class="navbar-item"
|
|
294
|
-
href="{{ '/lighthouse/' | relative_url }}"
|
|
295
|
-
target="_blank"
|
|
296
|
-
rel="noopener noreferrer"
|
|
297
|
-
aria-label="Lighthouse (opens in new tab)"
|
|
298
|
-
data-testid="nav-reports-lighthouse"
|
|
299
|
-
>
|
|
300
|
-
Lighthouse
|
|
301
|
-
<span
|
|
302
|
-
class="icon is-small"
|
|
303
|
-
style="margin-left: 0.25rem; display: inline-flex"
|
|
304
|
-
aria-hidden="true"
|
|
305
|
-
>
|
|
306
|
-
<svg
|
|
307
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
308
|
-
width="12"
|
|
309
|
-
height="12"
|
|
310
|
-
viewBox="0 0 24 24"
|
|
311
|
-
fill="none"
|
|
312
|
-
stroke="currentColor"
|
|
313
|
-
stroke-width="2"
|
|
314
|
-
stroke-linecap="round"
|
|
315
|
-
stroke-linejoin="round"
|
|
316
|
-
>
|
|
317
|
-
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
318
|
-
<polyline points="15 3 21 3 21 9"></polyline>
|
|
319
|
-
<line x1="10" y1="14" x2="21" y2="3"></line>
|
|
320
|
-
</svg>
|
|
321
|
-
</span>
|
|
322
|
-
</a>
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
</div>
|
|
326
|
-
<div class="navbar-end">
|
|
327
|
-
<div class="navbar-item has-dropdown is-hoverable" data-testid="theme-dropdown">
|
|
328
|
-
<button
|
|
329
|
-
class="theme-trigger-icon"
|
|
330
|
-
id="theme-flavor-trigger"
|
|
331
|
-
type="button"
|
|
332
|
-
aria-haspopup="true"
|
|
333
|
-
aria-expanded="false"
|
|
334
|
-
aria-controls="theme-flavor-menu"
|
|
335
|
-
aria-label="Select theme"
|
|
336
|
-
data-testid="theme-trigger"
|
|
337
|
-
>
|
|
338
|
-
<img
|
|
339
|
-
id="theme-flavor-trigger-icon"
|
|
340
|
-
src="{{ '/assets/img/catppuccin-logo-macchiato.png' | relative_url }}"
|
|
341
|
-
alt="Current theme"
|
|
342
|
-
width="32"
|
|
343
|
-
height="32"
|
|
344
|
-
/>
|
|
345
|
-
</button>
|
|
346
|
-
<div
|
|
347
|
-
class="navbar-dropdown is-right"
|
|
348
|
-
id="theme-flavor-menu"
|
|
349
|
-
aria-labelledby="theme-flavor-trigger"
|
|
350
|
-
data-testid="theme-menu"
|
|
351
|
-
role="menu"
|
|
352
|
-
>
|
|
353
|
-
<!-- Theme items populated by JS -->
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
<div class="select is-rounded is-small is-hidden">
|
|
357
|
-
<select id="theme-flavor-select" aria-label="Theme flavor" disabled></select>
|
|
358
|
-
</div>
|
|
359
|
-
</div>
|
|
360
|
-
</div>
|
|
361
|
-
</div>
|
|
362
|
-
</nav>
|
|
363
|
-
|
|
364
|
-
<section class="section">
|
|
365
|
-
<div class="container content" data-testid="main-content">
|
|
366
|
-
<h1 class="title">{{ page.title | default: site.title }}</h1>
|
|
367
|
-
{{ content }}
|
|
368
|
-
</div>
|
|
369
|
-
</section>
|
|
370
|
-
|
|
371
|
-
<footer class="footer">
|
|
372
|
-
<div class="content has-text-centered">
|
|
373
|
-
<p><strong>{{ site.title }}</strong> — Bulma demo with theme switch.</p>
|
|
374
|
-
</div>
|
|
375
|
-
</footer>
|
|
376
|
-
</body>
|
|
377
|
-
</html>
|