jekyll-calconnect-theme 0.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.
- checksums.yaml +7 -0
- data/CLAUDE.md +69 -0
- data/README.md +21 -0
- data/_frontend/entrypoints/application.css +80 -0
- data/_frontend/entrypoints/application.js +12 -0
- data/_frontend/js/navigation.js +66 -0
- data/_frontend/js/theme.js +58 -0
- data/_includes/breadcrumbs.html +23 -0
- data/_includes/custom-head.html +2 -0
- data/_includes/feedback.html +3 -0
- data/_includes/footer.html +10 -0
- data/_includes/google-analytics.html +9 -0
- data/_includes/head.html +33 -0
- data/_includes/header.html +9 -0
- data/_layouts/base.html +21 -0
- data/_layouts/default.html +254 -0
- data/_layouts/page.html +4 -0
- data/_sass/calconnect/_code.scss +23 -0
- data/_sass/calconnect/_dark-mode.scss +91 -0
- data/_sass/calconnect/_layout.scss +57 -0
- data/_sass/calconnect/_navigation.scss +113 -0
- data/_sass/calconnect/_tables.scss +20 -0
- data/_sass/calconnect/_typography.scss +112 -0
- data/_sass/calconnect.scss +6 -0
- data/jekyll-calconnect-theme.gemspec +23 -0
- data/lib/jekyll/calconnect/theme/version.rb +7 -0
- data/lib/jekyll/calconnect/theme.rb +8 -0
- metadata +79 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a8101b4b6ebc2ce836878b1bfb0bca4a0cf6a6e74dc1e35882437ae36f81dbd2
|
|
4
|
+
data.tar.gz: 9b23833d258824df5b7b5a2dd33f5491833d35ca2491f071ffff44e660586e98
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 6cad0f652b298dc0467a383c513e7f83384bc5d1f0c828fb7cff3d25cacde3ebba76e5cc97ddb7cea67980d9464815e545160aaa6fb8bf06e2ecd98ba40e6720
|
|
7
|
+
data.tar.gz: a4194106e49d4f06e26d6566529468a34fb7ea9250875e62155c08732ee0a6438d92373583b9d578ec3cc6baff52270cef6f2affa1c5da8f8688e5acd784770a
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
This is a shared Jekyll theme gem (`jekyll-calconnect-theme`) used across multiple CalConnect sites (calconnect.org, DEVGUIDE, standards.calconnect.org). Sites consume it via their Gemfile and override layouts/includes as needed.
|
|
8
|
+
|
|
9
|
+
## Build & Development
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
bundle install
|
|
14
|
+
|
|
15
|
+
# Build the gem
|
|
16
|
+
rake build # outputs to pkg/
|
|
17
|
+
|
|
18
|
+
# Install locally for development
|
|
19
|
+
rake install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This is a theme gem only — there is no standalone site to serve. To preview changes, use the theme in a consumer site's `_config.yml` with a Gemfile pointing at the local path.
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Layout hierarchy
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
base.html → HTML shell: head, header, footer, Vite JS entry
|
|
30
|
+
└─ default.html → Documentation layout: sidebar nav + article area
|
|
31
|
+
└─ page.html → Pass-through wrapper
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Frontend pipeline
|
|
35
|
+
|
|
36
|
+
CSS and JS live under `_frontend/` and are built by [jekyll-vite](https://github.com/elixir-vite/vite_ruby) in the consumer site. The theme provides:
|
|
37
|
+
- `_frontend/entrypoints/application.css` — Tailwind v4 config (`@import "tailwindcss"`), `@tailwindcss/typography` plugin, custom theme tokens (primary/accent colors, fonts)
|
|
38
|
+
- `_frontend/entrypoints/application.js` — imports `theme.js` (dark/light toggle with localStorage) and `navigation.js` (mobile menu, active state highlighting), plus sidebar collapsible toggle init
|
|
39
|
+
- `_sass/calconnect/` — supplementary SCSS for layout, navigation, typography, code blocks, tables, dark mode
|
|
40
|
+
|
|
41
|
+
### Sidebar navigation (default.html layout)
|
|
42
|
+
|
|
43
|
+
The sidebar is fully data-driven from `site.data.navigation_sidebar.sections`. Each section has a `match` string matched against `page.url`. Item types: `link`, `collection` (iterates a Jekyll collection), `collapsible` (expandable with URL filtering), `group` (labeled sub-group), `years` (year list from `site.data.news_years`). The layout has no hardcoded page knowledge — all configuration is in the consumer site's `_data/navigation_sidebar.yml`.
|
|
44
|
+
|
|
45
|
+
### Includes
|
|
46
|
+
|
|
47
|
+
- `head.html` — meta tags, Google Fonts (Inter + JetBrains Mono), critical inline CSS to prevent FOUC, `{% vite_stylesheet_tag %}`
|
|
48
|
+
- `custom-head.html` — Vite client + JS tag (for dev HMR in consumer sites)
|
|
49
|
+
- `header.html` — fixed top nav bar
|
|
50
|
+
- `footer.html` — copyright bar
|
|
51
|
+
- `breadcrumbs.html` — URL-derived breadcrumb trail
|
|
52
|
+
- `feedback.html` — "Was this helpful?" link
|
|
53
|
+
- `google-analytics.html` — conditional GA snippet (production only)
|
|
54
|
+
|
|
55
|
+
### Dark mode
|
|
56
|
+
|
|
57
|
+
Class-based (`html.dark`). `theme.js` runs immediately (before DOM ready) to prevent flash, using localStorage > system preference. Tailwind custom variant: `@custom-variant dark (&:where(.dark, .dark *))`.
|
|
58
|
+
|
|
59
|
+
### Ruby namespace
|
|
60
|
+
|
|
61
|
+
`Jekyll::CalconnectTheme` with version in `lib/jekyll/calconnect/theme/version.rb`. The gemspec requires the version constant from there.
|
|
62
|
+
|
|
63
|
+
### Gem packaging
|
|
64
|
+
|
|
65
|
+
`gemspec` packages: `{_layouts,_includes,_sass,_frontend,lib}/**/*`, `*.md`, `*.gemspec`. Only runtime dependency is `jekyll ~> 4.3`.
|
|
66
|
+
|
|
67
|
+
### Key Tailwind notes
|
|
68
|
+
|
|
69
|
+
Uses Tailwind v4 (CSS-first config with `@theme` blocks, not `tailwind.config.js`). Colors use `gray` not `slate` for class compatibility. Primary color scale is indigo-based; accent is cyan.
|
data/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# jekyll-calconnect-theme
|
|
2
|
+
|
|
3
|
+
Shared Jekyll theme gem for CalConnect sites (calconnect.org, DEVGUIDE, standards.calconnect.org).
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Add to your site's `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem "jekyll-calconnect-theme", git: "git@github.com:calconnect/calconnect-theme.git"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Add to your site's `_config.yml`:
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
theme: jekyll-calconnect-theme
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Site-specific overrides
|
|
20
|
+
|
|
21
|
+
Any layout or include can be overridden by placing a file with the same name in your site's own `_layouts/` or `_includes/` directory.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@plugin "@tailwindcss/typography";
|
|
3
|
+
|
|
4
|
+
/* Enable class-based dark mode */
|
|
5
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
6
|
+
|
|
7
|
+
/* Custom theme configuration */
|
|
8
|
+
@theme {
|
|
9
|
+
/* Font families */
|
|
10
|
+
--font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
11
|
+
--font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
12
|
+
|
|
13
|
+
/* Primary colors */
|
|
14
|
+
--color-primary-50: #eef2ff;
|
|
15
|
+
--color-primary-100: #e0e7ff;
|
|
16
|
+
--color-primary-200: #c7d2fe;
|
|
17
|
+
--color-primary-300: #a5b4fc;
|
|
18
|
+
--color-primary-400: #818cf8;
|
|
19
|
+
--color-primary-500: #6366f1;
|
|
20
|
+
--color-primary-600: #4f46e5;
|
|
21
|
+
--color-primary-700: #4338ca;
|
|
22
|
+
--color-primary-800: #3730a3;
|
|
23
|
+
--color-primary-900: #312e81;
|
|
24
|
+
|
|
25
|
+
/* Accent color */
|
|
26
|
+
--color-accent-400: #22d3ee;
|
|
27
|
+
--color-accent-500: #06b6d4;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Custom base styles */
|
|
31
|
+
@layer base {
|
|
32
|
+
html {
|
|
33
|
+
scroll-behavior: smooth;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
body {
|
|
37
|
+
font-feature-settings: "kern" 1, "liga" 1;
|
|
38
|
+
-webkit-font-smoothing: antialiased;
|
|
39
|
+
-moz-osx-font-smoothing: grayscale;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
main {
|
|
43
|
+
padding-top: 64px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
::selection {
|
|
47
|
+
background-color: rgba(99, 102, 241, 0.2);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:focus-visible {
|
|
51
|
+
outline: 2px solid #6366f1;
|
|
52
|
+
outline-offset: 2px;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Custom component styles */
|
|
57
|
+
@layer components {
|
|
58
|
+
.sr-only {
|
|
59
|
+
position: absolute;
|
|
60
|
+
width: 1px;
|
|
61
|
+
height: 1px;
|
|
62
|
+
padding: 0;
|
|
63
|
+
margin: -1px;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
clip: rect(0, 0, 0, 0);
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
border-width: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.sr-only:focus {
|
|
71
|
+
position: fixed;
|
|
72
|
+
width: auto;
|
|
73
|
+
height: auto;
|
|
74
|
+
padding: 0.5rem 1rem;
|
|
75
|
+
margin: 0;
|
|
76
|
+
overflow: visible;
|
|
77
|
+
clip: auto;
|
|
78
|
+
white-space: normal;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import '../js/theme.js'
|
|
2
|
+
import '../js/navigation.js'
|
|
3
|
+
|
|
4
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
5
|
+
document.querySelectorAll('.nav-toggle').forEach(function(toggle) {
|
|
6
|
+
toggle.addEventListener('click', function() {
|
|
7
|
+
this.classList.toggle('open');
|
|
8
|
+
var subsection = this.nextElementSibling;
|
|
9
|
+
if (subsection) subsection.classList.toggle('collapsed');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation Script
|
|
3
|
+
* Handles mobile menu toggle and active state highlighting
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function() {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Initialize mobile menu toggle
|
|
11
|
+
*/
|
|
12
|
+
function initMobileMenu() {
|
|
13
|
+
var menuButton = document.getElementById('mobile-menu-btn');
|
|
14
|
+
var mobileMenu = document.getElementById('mobile-menu');
|
|
15
|
+
|
|
16
|
+
if (menuButton && mobileMenu) {
|
|
17
|
+
menuButton.addEventListener('click', function() {
|
|
18
|
+
var isExpanded = menuButton.getAttribute('aria-expanded') === 'true';
|
|
19
|
+
menuButton.setAttribute('aria-expanded', !isExpanded);
|
|
20
|
+
mobileMenu.classList.toggle('hidden');
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Highlight active navigation items
|
|
27
|
+
*/
|
|
28
|
+
function initActiveNav() {
|
|
29
|
+
var currentPath = window.location.pathname;
|
|
30
|
+
|
|
31
|
+
// Sidebar navigation
|
|
32
|
+
var sidebarLinks = document.querySelectorAll('.docs-nav .nav-items a');
|
|
33
|
+
sidebarLinks.forEach(function(link) {
|
|
34
|
+
var href = link.getAttribute('href');
|
|
35
|
+
if (href) {
|
|
36
|
+
// Normalize paths for comparison
|
|
37
|
+
var linkPath = href.replace(/\/$/, '');
|
|
38
|
+
var pagePath = currentPath.replace(/\/$/, '');
|
|
39
|
+
if (linkPath === pagePath) {
|
|
40
|
+
link.classList.add('active');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Header navigation
|
|
46
|
+
var headerLinks = document.querySelectorAll('nav a[href]');
|
|
47
|
+
headerLinks.forEach(function(link) {
|
|
48
|
+
var href = link.getAttribute('href');
|
|
49
|
+
if (href && href !== '/') {
|
|
50
|
+
var linkPath = href.replace(/\/$/, '');
|
|
51
|
+
var pagePath = currentPath.replace(/\/$/, '');
|
|
52
|
+
if (pagePath.indexOf(linkPath) === 0) {
|
|
53
|
+
link.classList.add('active');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Initialize on DOM ready
|
|
61
|
+
*/
|
|
62
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
63
|
+
initMobileMenu();
|
|
64
|
+
initActiveNav();
|
|
65
|
+
});
|
|
66
|
+
})();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Toggle Script
|
|
3
|
+
* Handles dark/light mode switching with localStorage persistence
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function() {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the user's theme preference
|
|
11
|
+
* Priority: localStorage > system preference
|
|
12
|
+
*/
|
|
13
|
+
function getThemePreference() {
|
|
14
|
+
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
|
15
|
+
return localStorage.getItem('theme');
|
|
16
|
+
}
|
|
17
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Set the theme on the document
|
|
22
|
+
*/
|
|
23
|
+
function setTheme(theme) {
|
|
24
|
+
if (theme === 'dark') {
|
|
25
|
+
document.documentElement.classList.add('dark');
|
|
26
|
+
} else {
|
|
27
|
+
document.documentElement.classList.remove('dark');
|
|
28
|
+
}
|
|
29
|
+
localStorage.setItem('theme', theme);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Initialize theme immediately to prevent flash
|
|
34
|
+
*/
|
|
35
|
+
setTheme(getThemePreference());
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Handle DOM ready for toggle button
|
|
39
|
+
*/
|
|
40
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
41
|
+
var toggle = document.getElementById('theme-toggle');
|
|
42
|
+
if (toggle) {
|
|
43
|
+
toggle.addEventListener('click', function() {
|
|
44
|
+
var currentTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
|
45
|
+
setTheme(currentTheme === 'dark' ? 'light' : 'dark');
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handle system preference changes
|
|
52
|
+
*/
|
|
53
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
|
54
|
+
if (!localStorage.getItem('theme')) {
|
|
55
|
+
setTheme(e.matches ? 'dark' : 'light');
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
})();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<nav class="hidden lg:flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 mb-4" aria-label="Breadcrumb">
|
|
2
|
+
<ol class="flex items-center flex-wrap gap-2 list-none p-0 m-0">
|
|
3
|
+
<li><a href="{{ '/' | relative_url }}" class="hover:text-gray-700 dark:hover:text-gray-300">Home</a></li>
|
|
4
|
+
{% assign crumbs = page.url | remove:'/index.html' | split: '/' %}
|
|
5
|
+
{% if page.collection == 'posts' %}
|
|
6
|
+
<li>/ <a href="{{ '/news' | relative_url }}" class="hover:text-gray-700 dark:hover:text-gray-300">News</a></li>
|
|
7
|
+
<li>/ {{ page.title }}</li>
|
|
8
|
+
{% else %}
|
|
9
|
+
{% for crumb in crumbs offset: 1 %}
|
|
10
|
+
{% if forloop.last %}
|
|
11
|
+
<li>/ {{ page.title }}</li>
|
|
12
|
+
{% else %}
|
|
13
|
+
{% assign crumb_limit = forloop.index | plus: 1 %}
|
|
14
|
+
{% assign crumb_url = '' %}
|
|
15
|
+
{% for crumb in crumbs limit: crumb_limit %}
|
|
16
|
+
{% assign crumb_url = crumb_url | append: crumb | append: '/' %}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
<li>/ <a href="{{ crumb_url | absolute_url }}" class="hover:text-gray-700 dark:hover:text-gray-300">{{ crumb | replace: '-', ' ' | capitalize }}</a></li>
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% endfor %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
</ol>
|
|
23
|
+
</nav>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<div class="border-t border-gray-200 dark:border-gray-700 mt-8 pt-6">
|
|
2
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">Was this page helpful? Please give us <a href="https://goo.gl/forms/NqKna6d4lsqUtlgD3" class="text-indigo-500 hover:text-indigo-600 underline" target="_blank" rel="noopener">Feedback</a>.</p>
|
|
3
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<footer class="bg-gray-50 dark:bg-gray-950 border-t border-gray-200 dark:border-white/10 py-12 transition-colors">
|
|
2
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
3
|
+
<div class="pt-8 border-t border-gray-200 dark:border-white/10">
|
|
4
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
5
|
+
© {{ site.time | date: '%Y' }} CalConnect<sup>SM</sup>.
|
|
6
|
+
<a href="https://www.calconnect.org/about/policies/copyright-and-licensing" class="hover:text-gray-700 dark:hover:text-gray-300">Copyright</a>
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
</footer>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
3
|
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
4
|
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
5
|
+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
6
|
+
|
|
7
|
+
ga('create', '{{ site.google_analytics }}', 'auto');
|
|
8
|
+
ga('send', 'pageview');
|
|
9
|
+
</script>
|
data/_includes/head.html
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<head>
|
|
2
|
+
<meta charset="UTF-8">
|
|
3
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4
|
+
{% assign page_title = page.title | default: page.name %}
|
|
5
|
+
<title>{% if page_title %}{{ page_title | escape }} | {% endif %}{{ site.title | default: "CalConnect" }}</title>
|
|
6
|
+
<meta name="description"
|
|
7
|
+
content="{{ page.excerpt | default: site.description | strip_html | normalize_whitespace | truncate: 160 | escape }}" />
|
|
8
|
+
|
|
9
|
+
{% if site.favicon %}
|
|
10
|
+
<link rel="icon" type="image/png" href="{{ site.favicon | relative_url }}" sizes="96x96" />
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
13
|
+
<!-- Google Fonts - Inter + JetBrains Mono -->
|
|
14
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
15
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
16
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
17
|
+
|
|
18
|
+
<!-- Critical CSS to prevent flash of unstyled content -->
|
|
19
|
+
<style>
|
|
20
|
+
html{scroll-behavior:smooth!important}
|
|
21
|
+
body{font-feature-settings:"kern" 1,"liga" 1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#fff!important;color:#1e293b!important;font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,sans-serif!important;opacity:1!important}
|
|
22
|
+
html.dark body{background-color:#0f172a!important;color:#f1f5f9!important}
|
|
23
|
+
#nav-header{position:fixed!important;top:0!important;left:0!important;right:0!important;z-index:50!important;height:64px!important}
|
|
24
|
+
main{padding-top:64px!important}
|
|
25
|
+
</style>
|
|
26
|
+
|
|
27
|
+
<!-- Vite Stylesheet (Tailwind CSS) -->
|
|
28
|
+
{% vite_stylesheet_tag application %}
|
|
29
|
+
|
|
30
|
+
{% if jekyll.environment == 'production' and site.google_analytics %}
|
|
31
|
+
{% include google-analytics.html %}
|
|
32
|
+
{% endif %}
|
|
33
|
+
</head>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<header id="nav-header" class="fixed top-0 left-0 right-0 z-50 bg-white dark:bg-gray-950 backdrop-blur-md border-b border-gray-200 dark:border-white/10 transition-colors">
|
|
2
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
3
|
+
<div class="flex items-center justify-between h-16">
|
|
4
|
+
<a href="{{ '/' | relative_url }}" class="flex items-center">
|
|
5
|
+
<span class="text-lg font-semibold text-gray-900 dark:text-white">{{ site.title | default: "CalConnect" }}</span>
|
|
6
|
+
</a>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</header>
|
data/_layouts/base.html
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="">
|
|
3
|
+
|
|
4
|
+
{% include head.html %}
|
|
5
|
+
|
|
6
|
+
<body class="bg-white dark:bg-gray-950 text-gray-900 dark:text-white">
|
|
7
|
+
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-indigo-500 focus:text-white focus:px-4 focus:py-2 focus:rounded-lg">
|
|
8
|
+
Skip to main content
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
{% include header.html %}
|
|
12
|
+
|
|
13
|
+
<main id="main-content">
|
|
14
|
+
{{ content }}
|
|
15
|
+
</main>
|
|
16
|
+
|
|
17
|
+
{% include footer.html %}
|
|
18
|
+
|
|
19
|
+
{% vite_javascript_tag application %}
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: base
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<section class="documentation">
|
|
6
|
+
<!-- Left Sidebar Navigation - Fully Data-Driven -->
|
|
7
|
+
<nav class="docs-nav" aria-label="Section navigation">
|
|
8
|
+
<div class="docs-nav-content">
|
|
9
|
+
|
|
10
|
+
{% comment %}
|
|
11
|
+
Find matching section based on page URL.
|
|
12
|
+
The layout has no knowledge of specific pages - all configuration is in _data/navigation_sidebar.yml
|
|
13
|
+
{% endcomment %}
|
|
14
|
+
{% assign current_section = nil %}
|
|
15
|
+
{% for section in site.data.navigation_sidebar.sections %}
|
|
16
|
+
{% if page.url contains section.match %}
|
|
17
|
+
{% assign current_section = section %}
|
|
18
|
+
{% break %}
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% endfor %}
|
|
21
|
+
|
|
22
|
+
{% if current_section %}
|
|
23
|
+
<div class="nav-section">
|
|
24
|
+
<div class="nav-section-title">{{ current_section.title }}</div>
|
|
25
|
+
<ul class="nav-items">
|
|
26
|
+
{% for item in current_section.items %}
|
|
27
|
+
|
|
28
|
+
{% comment %} --- LINK TYPE --- {% endcomment %}
|
|
29
|
+
{% if item.type == 'link' or item.type == nil %}
|
|
30
|
+
{% assign is_active = false %}
|
|
31
|
+
{% if page.url == item.url %}
|
|
32
|
+
{% assign is_active = true %}
|
|
33
|
+
{% endif %}
|
|
34
|
+
<li>
|
|
35
|
+
<a href="{{ item.url | relative_url }}" {% if is_active %}class="active"{% endif %}>
|
|
36
|
+
{{ item.label }}
|
|
37
|
+
</a>
|
|
38
|
+
</li>
|
|
39
|
+
|
|
40
|
+
{% comment %} --- COLLECTION TYPE --- {% endcomment %}
|
|
41
|
+
{% elsif item.type == 'collection' %}
|
|
42
|
+
{% case item.collection %}
|
|
43
|
+
{% when 'about_pages' %}
|
|
44
|
+
{% assign docs = site.about_pages %}
|
|
45
|
+
{% when 'membership_pages' %}
|
|
46
|
+
{% assign docs = site.membership_pages %}
|
|
47
|
+
{% when 'events' %}
|
|
48
|
+
{% assign docs = site.events %}
|
|
49
|
+
{% when 'resources' %}
|
|
50
|
+
{% assign docs = site.resources %}
|
|
51
|
+
{% else %}
|
|
52
|
+
{% assign docs = site.posts %}
|
|
53
|
+
{% endcase %}
|
|
54
|
+
{% if item.sort_field == 'date' and item.sort_order == 'desc' %}
|
|
55
|
+
{% assign sorted_docs = docs | sort: 'date' | reverse %}
|
|
56
|
+
{% elsif item.sort_field %}
|
|
57
|
+
{% assign sorted_docs = docs | sort: item.sort_field %}
|
|
58
|
+
{% else %}
|
|
59
|
+
{% assign sorted_docs = docs %}
|
|
60
|
+
{% endif %}
|
|
61
|
+
{% for doc in sorted_docs %}
|
|
62
|
+
{% assign is_doc_active = false %}
|
|
63
|
+
{% if page.url == doc.url %}
|
|
64
|
+
{% assign is_doc_active = true %}
|
|
65
|
+
{% endif %}
|
|
66
|
+
<li>
|
|
67
|
+
<a href="{{ doc.url | relative_url }}" {% if is_doc_active %}class="active"{% endif %}>
|
|
68
|
+
{{ doc.title | default: doc.name }}
|
|
69
|
+
</a>
|
|
70
|
+
</li>
|
|
71
|
+
{% endfor %}
|
|
72
|
+
|
|
73
|
+
{% comment %} --- COLLAPSIBLE TYPE --- {% endcomment %}
|
|
74
|
+
{% elsif item.type == 'collapsible' %}
|
|
75
|
+
{% assign is_open = false %}
|
|
76
|
+
{% if page.url contains item.url_filter %}
|
|
77
|
+
{% assign is_open = true %}
|
|
78
|
+
{% endif %}
|
|
79
|
+
{% case item.collection %}
|
|
80
|
+
{% when 'about_pages' %}
|
|
81
|
+
{% assign child_docs = site.about_pages %}
|
|
82
|
+
{% when 'membership_pages' %}
|
|
83
|
+
{% assign child_docs = site.membership_pages %}
|
|
84
|
+
{% when 'events' %}
|
|
85
|
+
{% assign child_docs = site.events %}
|
|
86
|
+
{% when 'resources' %}
|
|
87
|
+
{% assign child_docs = site.resources %}
|
|
88
|
+
{% else %}
|
|
89
|
+
{% assign child_docs = site.posts %}
|
|
90
|
+
{% endcase %}
|
|
91
|
+
<li>
|
|
92
|
+
<span class="nav-toggle {% if is_open %}open{% endif %}">{{ item.label }}</span>
|
|
93
|
+
<ul class="nav-subsection {% unless is_open %}collapsed{% endunless %}">
|
|
94
|
+
{% if item.first_child_label %}
|
|
95
|
+
{% assign first_is_active = false %}
|
|
96
|
+
{% if page.url contains item.url_filter %}
|
|
97
|
+
{% assign first_is_active = true %}
|
|
98
|
+
{% endif %}
|
|
99
|
+
<li><a href="{{ item.url | relative_url }}" {% if first_is_active %}class="active"{% endif %}>{{ item.first_child_label }}</a></li>
|
|
100
|
+
{% endif %}
|
|
101
|
+
{% for doc in child_docs %}
|
|
102
|
+
{% assign url_matches = false %}
|
|
103
|
+
{% if doc.url contains item.url_filter %}
|
|
104
|
+
{% assign url_matches = true %}
|
|
105
|
+
{% endif %}
|
|
106
|
+
{% assign is_excluded = false %}
|
|
107
|
+
{% if doc.url == item.url %}
|
|
108
|
+
{% assign is_excluded = true %}
|
|
109
|
+
{% endif %}
|
|
110
|
+
{% if item.exclude_urls %}
|
|
111
|
+
{% for excl in item.exclude_urls %}
|
|
112
|
+
{% if doc.url == excl %}
|
|
113
|
+
{% assign is_excluded = true %}
|
|
114
|
+
{% endif %}
|
|
115
|
+
{% endfor %}
|
|
116
|
+
{% elsif item.exclude_url %}
|
|
117
|
+
{% if doc.url == item.exclude_url %}
|
|
118
|
+
{% assign is_excluded = true %}
|
|
119
|
+
{% endif %}
|
|
120
|
+
{% endif %}
|
|
121
|
+
{% if url_matches and is_excluded == false %}
|
|
122
|
+
{% assign child_is_active = false %}
|
|
123
|
+
{% if page.url == doc.url %}
|
|
124
|
+
{% assign child_is_active = true %}
|
|
125
|
+
{% endif %}
|
|
126
|
+
<li>
|
|
127
|
+
<a href="{{ doc.url | relative_url }}" {% if child_is_active %}class="active"{% endif %}>
|
|
128
|
+
{{ doc.title }}
|
|
129
|
+
</a>
|
|
130
|
+
</li>
|
|
131
|
+
{% endif %}
|
|
132
|
+
{% endfor %}
|
|
133
|
+
</ul>
|
|
134
|
+
</li>
|
|
135
|
+
|
|
136
|
+
{% comment %} --- YEARS TYPE --- {% endcomment %}
|
|
137
|
+
{% elsif item.type == 'years' %}
|
|
138
|
+
{% assign years = site.data.news_years %}
|
|
139
|
+
{% for year in years %}
|
|
140
|
+
{% assign is_active = false %}
|
|
141
|
+
{% if page.url contains year %}
|
|
142
|
+
{% assign is_active = true %}
|
|
143
|
+
{% endif %}
|
|
144
|
+
<li>
|
|
145
|
+
<a href="/news/{{ year }}/" {% if is_active %}class="active"{% endif %}>
|
|
146
|
+
{{ year }}
|
|
147
|
+
</a>
|
|
148
|
+
</li>
|
|
149
|
+
{% endfor %}
|
|
150
|
+
|
|
151
|
+
{% comment %} --- GROUP TYPE --- {% endcomment %}
|
|
152
|
+
{% elsif item.type == 'group' %}
|
|
153
|
+
</ul>
|
|
154
|
+
<div class="nav-group-title">{{ item.label }}</div>
|
|
155
|
+
<ul class="nav-items">
|
|
156
|
+
{% for child in item.children %}
|
|
157
|
+
{% if child.type == 'link' or child.type == nil %}
|
|
158
|
+
{% assign group_link_active = false %}
|
|
159
|
+
{% if page.url == child.url %}
|
|
160
|
+
{% assign group_link_active = true %}
|
|
161
|
+
{% endif %}
|
|
162
|
+
<li>
|
|
163
|
+
<a href="{{ child.url | relative_url }}" {% if group_link_active %}class="active"{% endif %}>
|
|
164
|
+
{{ child.label }}
|
|
165
|
+
</a>
|
|
166
|
+
</li>
|
|
167
|
+
{% elsif child.type == 'collapsible' %}
|
|
168
|
+
{% assign is_open = false %}
|
|
169
|
+
{% if page.url contains child.url_filter %}
|
|
170
|
+
{% assign is_open = true %}
|
|
171
|
+
{% endif %}
|
|
172
|
+
{% case child.collection %}
|
|
173
|
+
{% when 'about_pages' %}
|
|
174
|
+
{% assign child_docs = site.about_pages %}
|
|
175
|
+
{% when 'membership_pages' %}
|
|
176
|
+
{% assign child_docs = site.membership_pages %}
|
|
177
|
+
{% when 'events' %}
|
|
178
|
+
{% assign child_docs = site.events %}
|
|
179
|
+
{% when 'resources' %}
|
|
180
|
+
{% assign child_docs = site.resources %}
|
|
181
|
+
{% else %}
|
|
182
|
+
{% assign child_docs = site.posts %}
|
|
183
|
+
{% endcase %}
|
|
184
|
+
<li>
|
|
185
|
+
<span class="nav-toggle {% if is_open %}open{% endif %}">{{ child.label }}</span>
|
|
186
|
+
<ul class="nav-subsection {% unless is_open %}collapsed{% endunless %}">
|
|
187
|
+
{% if child.first_child_label %}
|
|
188
|
+
{% assign group_first_active = false %}
|
|
189
|
+
{% if page.url contains child.url_filter %}
|
|
190
|
+
{% assign group_first_active = true %}
|
|
191
|
+
{% endif %}
|
|
192
|
+
<li><a href="{{ child.url | relative_url }}" {% if group_first_active %}class="active"{% endif %}>{{ child.first_child_label }}</a></li>
|
|
193
|
+
{% endif %}
|
|
194
|
+
{% for doc in child_docs %}
|
|
195
|
+
{% assign url_matches = false %}
|
|
196
|
+
{% if doc.url contains child.url_filter %}
|
|
197
|
+
{% assign url_matches = true %}
|
|
198
|
+
{% endif %}
|
|
199
|
+
{% assign is_excluded = false %}
|
|
200
|
+
{% if doc.url == child.url %}
|
|
201
|
+
{% assign is_excluded = true %}
|
|
202
|
+
{% endif %}
|
|
203
|
+
{% if child.exclude_urls %}
|
|
204
|
+
{% for excl in child.exclude_urls %}
|
|
205
|
+
{% if doc.url == excl %}
|
|
206
|
+
{% assign is_excluded = true %}
|
|
207
|
+
{% endif %}
|
|
208
|
+
{% endfor %}
|
|
209
|
+
{% elsif child.exclude_url %}
|
|
210
|
+
{% if doc.url == child.exclude_url %}
|
|
211
|
+
{% assign is_excluded = true %}
|
|
212
|
+
{% endif %}
|
|
213
|
+
{% endif %}
|
|
214
|
+
{% if url_matches and is_excluded == false %}
|
|
215
|
+
{% assign group_doc_active = false %}
|
|
216
|
+
{% if page.url == doc.url %}
|
|
217
|
+
{% assign group_doc_active = true %}
|
|
218
|
+
{% endif %}
|
|
219
|
+
<li>
|
|
220
|
+
<a href="{{ doc.url | relative_url }}" {% if group_doc_active %}class="active"{% endif %}>
|
|
221
|
+
{{ doc.title }}
|
|
222
|
+
</a>
|
|
223
|
+
</li>
|
|
224
|
+
{% endif %}
|
|
225
|
+
{% endfor %}
|
|
226
|
+
</ul>
|
|
227
|
+
</li>
|
|
228
|
+
{% endif %}
|
|
229
|
+
{% endfor %}
|
|
230
|
+
|
|
231
|
+
{% endif %}
|
|
232
|
+
|
|
233
|
+
{% endfor %}
|
|
234
|
+
</ul>
|
|
235
|
+
</div>
|
|
236
|
+
{% endif %}
|
|
237
|
+
|
|
238
|
+
</div>
|
|
239
|
+
</nav>
|
|
240
|
+
|
|
241
|
+
<!-- Main Article -->
|
|
242
|
+
<article>
|
|
243
|
+
{% assign page_title = page.title | default: page.name %}
|
|
244
|
+
{% if page_title %}
|
|
245
|
+
<header>
|
|
246
|
+
<h1>{{ page_title }}</h1>
|
|
247
|
+
</header>
|
|
248
|
+
{% endif %}
|
|
249
|
+
|
|
250
|
+
<div class="body">
|
|
251
|
+
{{ content }}
|
|
252
|
+
</div>
|
|
253
|
+
</article>
|
|
254
|
+
</section>
|
data/_layouts/page.html
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Code blocks and inline code
|
|
2
|
+
|
|
3
|
+
.documentation .body pre {
|
|
4
|
+
background: #1e293b;
|
|
5
|
+
color: #e2e8f0;
|
|
6
|
+
padding: 1rem 1.25rem;
|
|
7
|
+
border-radius: 0.5rem;
|
|
8
|
+
overflow-x: auto;
|
|
9
|
+
margin: 1.5rem 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.documentation .body code {
|
|
13
|
+
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
|
14
|
+
font-size: 0.875rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.documentation .body :not(pre) > code {
|
|
18
|
+
background: #f1f5f9;
|
|
19
|
+
padding: 0.125rem 0.375rem;
|
|
20
|
+
border-radius: 0.25rem;
|
|
21
|
+
color: #1e293b;
|
|
22
|
+
font-size: 0.8125rem;
|
|
23
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Dark mode overrides
|
|
2
|
+
|
|
3
|
+
// Layout
|
|
4
|
+
.dark .documentation > article > header {
|
|
5
|
+
border-bottom-color: #334155;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.dark .documentation > article > header h1 {
|
|
9
|
+
color: #f8fafc;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Navigation
|
|
13
|
+
.dark .docs-nav .nav-group-title {
|
|
14
|
+
color: #64748b;
|
|
15
|
+
border-top-color: #334155;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.dark .docs-nav .nav-items a:hover {
|
|
19
|
+
background: #1e293b;
|
|
20
|
+
color: #f1f5f9;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.dark .docs-nav .nav-items a.active {
|
|
24
|
+
background: #312e81;
|
|
25
|
+
color: #a5b4fc;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.dark .nav-toggle:hover {
|
|
29
|
+
background: #1e293b;
|
|
30
|
+
color: #f1f5f9;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.dark .nav-subsection {
|
|
34
|
+
border-left-color: #334155;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Typography
|
|
38
|
+
.dark .documentation .body h2 {
|
|
39
|
+
color: #f1f5f9;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.dark .documentation .body h3 {
|
|
43
|
+
color: #e2e8f0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.dark .documentation .body p {
|
|
47
|
+
color: #94a3b8;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.dark .documentation .body ul,
|
|
51
|
+
.dark .documentation .body ol,
|
|
52
|
+
.dark .documentation .body dl,
|
|
53
|
+
.dark .documentation .post-content ul,
|
|
54
|
+
.dark .documentation .post-content ol,
|
|
55
|
+
.dark .documentation .post-content dl,
|
|
56
|
+
.dark .documentation .sectionbody ul,
|
|
57
|
+
.dark .documentation .sectionbody ol,
|
|
58
|
+
.dark .documentation .sectionbody dl {
|
|
59
|
+
color: #94a3b8;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.dark .documentation .body li::marker,
|
|
63
|
+
.dark .documentation .post-content li::marker,
|
|
64
|
+
.dark .documentation .sectionbody li::marker {
|
|
65
|
+
color: #818cf8;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.dark .documentation .body dt {
|
|
69
|
+
color: #f1f5f9;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.dark .documentation .body dd {
|
|
73
|
+
color: #94a3b8;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Code
|
|
77
|
+
.dark .documentation .body :not(pre) > code {
|
|
78
|
+
background: #334155;
|
|
79
|
+
color: #e2e8f0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Tables
|
|
83
|
+
.dark .documentation .body th,
|
|
84
|
+
.dark .documentation .body td {
|
|
85
|
+
border-bottom-color: #334155;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.dark .documentation .body th {
|
|
89
|
+
background: #1e293b;
|
|
90
|
+
color: #f1f5f9;
|
|
91
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Documentation layout: two-column flex with sidebar
|
|
2
|
+
.documentation {
|
|
3
|
+
display: flex;
|
|
4
|
+
max-width: 1400px;
|
|
5
|
+
margin: 0 auto;
|
|
6
|
+
margin-top: 64px;
|
|
7
|
+
padding: 2rem 1rem;
|
|
8
|
+
gap: 2rem;
|
|
9
|
+
|
|
10
|
+
@media (min-width: 1024px) {
|
|
11
|
+
padding: 2rem 2rem;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Left sidebar
|
|
16
|
+
.docs-nav {
|
|
17
|
+
width: 220px;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Sticky sidebar content
|
|
22
|
+
@media (min-width: 1024px) {
|
|
23
|
+
.docs-nav-content {
|
|
24
|
+
position: sticky;
|
|
25
|
+
top: 5rem;
|
|
26
|
+
max-height: calc(100vh - 6rem);
|
|
27
|
+
overflow-y: auto;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Main article
|
|
32
|
+
.documentation > article {
|
|
33
|
+
flex: 1;
|
|
34
|
+
min-width: 0;
|
|
35
|
+
max-width: 75ch;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.documentation > article > header {
|
|
39
|
+
margin-bottom: 2rem;
|
|
40
|
+
padding-bottom: 1.5rem;
|
|
41
|
+
border-bottom: 1px solid #e2e8f0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.documentation > article > header h1 {
|
|
45
|
+
font-size: 2.25rem;
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
color: #0f172a;
|
|
48
|
+
line-height: 1.2;
|
|
49
|
+
margin: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Hide sidebar on mobile
|
|
53
|
+
@media (max-width: 1023px) {
|
|
54
|
+
.docs-nav {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Sidebar navigation components
|
|
2
|
+
|
|
3
|
+
.docs-nav .nav-section {
|
|
4
|
+
margin-bottom: 1.5rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.docs-nav .nav-section-title {
|
|
8
|
+
font-size: 0.75rem;
|
|
9
|
+
font-weight: 600;
|
|
10
|
+
text-transform: uppercase;
|
|
11
|
+
letter-spacing: 0.05em;
|
|
12
|
+
color: #94a3b8;
|
|
13
|
+
margin-bottom: 0.5rem;
|
|
14
|
+
padding: 0 0.75rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Group headers within navigation
|
|
18
|
+
.docs-nav .nav-group-title {
|
|
19
|
+
font-size: 0.6875rem;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
text-transform: uppercase;
|
|
22
|
+
letter-spacing: 0.05em;
|
|
23
|
+
color: #94a3b8;
|
|
24
|
+
margin-top: 1rem;
|
|
25
|
+
margin-bottom: 0.25rem;
|
|
26
|
+
padding: 0.25rem 0.75rem;
|
|
27
|
+
border-top: 1px solid #e2e8f0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.docs-nav .nav-group-title:first-child {
|
|
31
|
+
margin-top: 0;
|
|
32
|
+
border-top: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.docs-nav .nav-items {
|
|
36
|
+
list-style: none;
|
|
37
|
+
padding: 0;
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.docs-nav .nav-items li {
|
|
42
|
+
margin-bottom: 0.125rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.docs-nav .nav-items a {
|
|
46
|
+
display: block;
|
|
47
|
+
padding: 0.5rem 0.75rem;
|
|
48
|
+
color: #64748b;
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
border-radius: 0.375rem;
|
|
51
|
+
font-size: 0.875rem;
|
|
52
|
+
transition: all 0.15s ease;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.docs-nav .nav-items a:hover {
|
|
56
|
+
background: #f1f5f9;
|
|
57
|
+
color: #1e293b;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.docs-nav .nav-items a.active {
|
|
61
|
+
background: #eef2ff;
|
|
62
|
+
color: #4f46e5;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Collapsible subsections
|
|
67
|
+
.nav-subsection {
|
|
68
|
+
margin-left: 0.75rem;
|
|
69
|
+
border-left: 2px solid #e2e8f0;
|
|
70
|
+
padding-left: 0.75rem;
|
|
71
|
+
margin-top: 0.25rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Toggle button
|
|
75
|
+
.nav-toggle {
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: space-between;
|
|
79
|
+
padding: 0.5rem 0.75rem;
|
|
80
|
+
color: #64748b;
|
|
81
|
+
font-size: 0.875rem;
|
|
82
|
+
border-radius: 0.375rem;
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
transition: all 0.15s ease;
|
|
85
|
+
user-select: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.nav-toggle:hover {
|
|
89
|
+
background: #f1f5f9;
|
|
90
|
+
color: #1e293b;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Arrow indicator
|
|
94
|
+
.nav-toggle::after {
|
|
95
|
+
content: '';
|
|
96
|
+
display: inline-block;
|
|
97
|
+
width: 5px;
|
|
98
|
+
height: 5px;
|
|
99
|
+
border-right: 2px solid currentColor;
|
|
100
|
+
border-bottom: 2px solid currentColor;
|
|
101
|
+
transform: rotate(-45deg);
|
|
102
|
+
transition: transform 0.2s ease;
|
|
103
|
+
margin-left: auto;
|
|
104
|
+
flex-shrink: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.nav-toggle.open::after {
|
|
108
|
+
transform: rotate(45deg);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.nav-subsection.collapsed {
|
|
112
|
+
display: none;
|
|
113
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Table styling
|
|
2
|
+
|
|
3
|
+
.documentation .body table {
|
|
4
|
+
width: 100%;
|
|
5
|
+
border-collapse: collapse;
|
|
6
|
+
margin: 1.5rem 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.documentation .body th,
|
|
10
|
+
.documentation .body td {
|
|
11
|
+
padding: 0.75rem 1rem;
|
|
12
|
+
text-align: left;
|
|
13
|
+
border-bottom: 1px solid #e2e8f0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.documentation .body th {
|
|
17
|
+
background: #f8fafc;
|
|
18
|
+
font-weight: 600;
|
|
19
|
+
color: #1e293b;
|
|
20
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Documentation body typography
|
|
2
|
+
|
|
3
|
+
.documentation .body {
|
|
4
|
+
font-size: 1rem;
|
|
5
|
+
line-height: 1.75;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.documentation .body h2 {
|
|
9
|
+
font-size: 1.5rem;
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
margin-top: 2.5rem;
|
|
12
|
+
margin-bottom: 1rem;
|
|
13
|
+
color: #1e293b;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.documentation .body h3 {
|
|
17
|
+
font-size: 1.25rem;
|
|
18
|
+
font-weight: 600;
|
|
19
|
+
margin-top: 2rem;
|
|
20
|
+
margin-bottom: 0.75rem;
|
|
21
|
+
color: #334155;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.documentation .body p {
|
|
25
|
+
margin-bottom: 1rem;
|
|
26
|
+
color: #475569;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.documentation .body a {
|
|
30
|
+
color: #6366f1;
|
|
31
|
+
text-decoration: underline;
|
|
32
|
+
text-underline-offset: 2px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.documentation .body a:hover {
|
|
36
|
+
color: #4f46e5;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Lists
|
|
40
|
+
.documentation .body ul,
|
|
41
|
+
.documentation .body ol,
|
|
42
|
+
.documentation .body dl,
|
|
43
|
+
.documentation .post-content ul,
|
|
44
|
+
.documentation .post-content ol,
|
|
45
|
+
.documentation .post-content dl,
|
|
46
|
+
.documentation .sectionbody ul,
|
|
47
|
+
.documentation .sectionbody ol,
|
|
48
|
+
.documentation .sectionbody dl {
|
|
49
|
+
margin-bottom: 1.25rem;
|
|
50
|
+
padding-left: 1.75rem;
|
|
51
|
+
color: #475569;
|
|
52
|
+
list-style-position: outside;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.documentation .body ul,
|
|
56
|
+
.documentation .post-content ul,
|
|
57
|
+
.documentation .sectionbody ul {
|
|
58
|
+
list-style-type: disc !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.documentation .body ul ul,
|
|
62
|
+
.documentation .post-content ul ul,
|
|
63
|
+
.documentation .sectionbody ul ul {
|
|
64
|
+
list-style-type: circle !important;
|
|
65
|
+
margin-top: 0.5rem;
|
|
66
|
+
margin-bottom: 0.5rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.documentation .body ol,
|
|
70
|
+
.documentation .post-content ol,
|
|
71
|
+
.documentation .sectionbody ol {
|
|
72
|
+
list-style-type: decimal !important;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Exception: don't number breadcrumb navigation
|
|
76
|
+
.body nav[aria-label="Breadcrumb"] ol,
|
|
77
|
+
.body nav ol.list-none,
|
|
78
|
+
ol.list-none {
|
|
79
|
+
list-style: none !important;
|
|
80
|
+
padding-left: 0 !important;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.body nav[aria-label="Breadcrumb"] li,
|
|
84
|
+
.body nav ol.list-none li {
|
|
85
|
+
margin-bottom: 0 !important;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.documentation .body li,
|
|
89
|
+
.documentation .post-content li,
|
|
90
|
+
.documentation .sectionbody li {
|
|
91
|
+
margin-bottom: 0.625rem;
|
|
92
|
+
line-height: 1.7;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.documentation .body li::marker,
|
|
96
|
+
.documentation .post-content li::marker,
|
|
97
|
+
.documentation .sectionbody li::marker {
|
|
98
|
+
color: #6366f1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Definition lists
|
|
102
|
+
.documentation .body dt {
|
|
103
|
+
font-weight: 600;
|
|
104
|
+
color: #1e293b;
|
|
105
|
+
margin-bottom: 0.25rem;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.documentation .body dd {
|
|
109
|
+
margin-left: 1.5rem;
|
|
110
|
+
margin-bottom: 0.75rem;
|
|
111
|
+
color: #475569;
|
|
112
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/jekyll/calconnect/theme/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "jekyll-calconnect-theme"
|
|
7
|
+
spec.version = Jekyll::CalconnectTheme::VERSION
|
|
8
|
+
spec.authors = ["CalConnect"]
|
|
9
|
+
spec.email = ["info@calconnect.org"]
|
|
10
|
+
spec.summary = "Shared Jekyll theme for CalConnect sites"
|
|
11
|
+
spec.homepage = "https://github.com/calconnect/calconnect-theme"
|
|
12
|
+
spec.license = "MIT"
|
|
13
|
+
|
|
14
|
+
spec.files = Dir[
|
|
15
|
+
"{_layouts,_includes,_sass,_frontend,lib}/**/*",
|
|
16
|
+
"*.md",
|
|
17
|
+
"*.gemspec"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_runtime_dependency "jekyll", "~> 4.3"
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll-calconnect-theme
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- CalConnect
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: jekyll
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '4.3'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '4.3'
|
|
26
|
+
email:
|
|
27
|
+
- info@calconnect.org
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- CLAUDE.md
|
|
33
|
+
- README.md
|
|
34
|
+
- _frontend/entrypoints/application.css
|
|
35
|
+
- _frontend/entrypoints/application.js
|
|
36
|
+
- _frontend/js/navigation.js
|
|
37
|
+
- _frontend/js/theme.js
|
|
38
|
+
- _includes/breadcrumbs.html
|
|
39
|
+
- _includes/custom-head.html
|
|
40
|
+
- _includes/feedback.html
|
|
41
|
+
- _includes/footer.html
|
|
42
|
+
- _includes/google-analytics.html
|
|
43
|
+
- _includes/head.html
|
|
44
|
+
- _includes/header.html
|
|
45
|
+
- _layouts/base.html
|
|
46
|
+
- _layouts/default.html
|
|
47
|
+
- _layouts/page.html
|
|
48
|
+
- _sass/calconnect.scss
|
|
49
|
+
- _sass/calconnect/_code.scss
|
|
50
|
+
- _sass/calconnect/_dark-mode.scss
|
|
51
|
+
- _sass/calconnect/_layout.scss
|
|
52
|
+
- _sass/calconnect/_navigation.scss
|
|
53
|
+
- _sass/calconnect/_tables.scss
|
|
54
|
+
- _sass/calconnect/_typography.scss
|
|
55
|
+
- jekyll-calconnect-theme.gemspec
|
|
56
|
+
- lib/jekyll/calconnect/theme.rb
|
|
57
|
+
- lib/jekyll/calconnect/theme/version.rb
|
|
58
|
+
homepage: https://github.com/calconnect/calconnect-theme
|
|
59
|
+
licenses:
|
|
60
|
+
- MIT
|
|
61
|
+
metadata: {}
|
|
62
|
+
rdoc_options: []
|
|
63
|
+
require_paths:
|
|
64
|
+
- lib
|
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
requirements: []
|
|
76
|
+
rubygems_version: 3.6.9
|
|
77
|
+
specification_version: 4
|
|
78
|
+
summary: Shared Jekyll theme for CalConnect sites
|
|
79
|
+
test_files: []
|