howdy-jekyll-theme 1.0.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/AGENTS.md +49 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +431 -0
- data/_includes/analytics.html +19 -0
- data/_includes/blog-pagination.html +31 -0
- data/_includes/comments.html +46 -0
- data/_includes/dark-mode-toggle.html +18 -0
- data/_includes/head.html +137 -0
- data/_includes/hero-carousel.html +80 -0
- data/_includes/logo.html +5 -0
- data/_includes/navigation.html +24 -0
- data/_includes/newsletter.html +10 -0
- data/_includes/share-buttons.html +70 -0
- data/_includes/social-links.html +37 -0
- data/_includes/toc.html +29 -0
- data/_layouts/autopage_collection.html +43 -0
- data/_layouts/blog.html +42 -0
- data/_layouts/default.html +86 -0
- data/_layouts/home.html +5 -0
- data/_layouts/page.html +33 -0
- data/_layouts/post.html +76 -0
- data/_layouts/project.html +61 -0
- data/_plugins/sort_projects.rb +6 -0
- data/_plugins/user_colors.rb +68 -0
- data/_posts/2026-01-01-beyond-pixels.md +21 -0
- data/_posts/2026-01-02-collaboration.md +25 -0
- data/_posts/2026-01-03-design-feeling.md +25 -0
- data/_posts/2026-01-04-finding-inspiration.md +25 -0
- data/_posts/2026-01-05-freebies.md +35 -0
- data/_posts/2026-01-06-ux-research-methods.md +25 -0
- data/_posts/2026-01-07-color-theory.md +25 -0
- data/_posts/2026-01-08-responsive-design.md +25 -0
- data/_posts/2026-01-09-web-performance.md +25 -0
- data/_posts/2026-01-10-mobile-first.md +25 -0
- data/_posts/2026-04-15-crafting-visual-hierarchy.md +27 -0
- data/_posts/2026-04-16-building-design-systems.md +27 -0
- data/_posts/2026-04-18-accessibility-matters.md +25 -0
- data/_posts/2026-04-19-motion-design.md +29 -0
- data/_posts/2026-04-20-typography-basics.md +25 -0
- data/_posts/2026-04-22-product-design-best-practices.md +239 -0
- data/_projects/atlas.md +26 -0
- data/_projects/luminous.md +26 -0
- data/_projects/nova.md +31 -0
- data/_projects/osaka.md +26 -0
- data/_sass/_base.scss +181 -0
- data/_sass/_components.scss +767 -0
- data/_sass/_dark-mode.scss +39 -0
- data/_sass/_layout.scss +1033 -0
- data/_sass/_typography.scss +394 -0
- data/_sass/_user-colors.scss +1 -0
- data/_sass/_variables.scss +165 -0
- data/about.md +62 -0
- data/assets/css/main.scss +10 -0
- data/assets/css/swiper-bundle.min.css +13 -0
- data/assets/fonts/ChaumontScript-Regular.otf +0 -0
- data/assets/fonts/DMSans-Italic-Variable.ttf +0 -0
- data/assets/fonts/DMSans-Variable.ttf +0 -0
- data/assets/illustrations/analytics.svg +218 -0
- data/assets/illustrations/business-strategy.svg +161 -0
- data/assets/illustrations/designer.svg +267 -0
- data/assets/illustrations/email.svg +123 -0
- data/assets/illustrations/friends-taking-selfie.svg +189 -0
- data/assets/illustrations/launch.svg +230 -0
- data/assets/illustrations/love-animals.svg +83 -0
- data/assets/illustrations/meeting.svg +292 -0
- data/assets/illustrations/mobile-shopping.svg +113 -0
- data/assets/illustrations/online-shopping.svg +148 -0
- data/assets/illustrations/oops-something-went-wrong.svg +97 -0
- data/assets/illustrations/podcast.svg +199 -0
- data/assets/illustrations/presentation.svg +138 -0
- data/assets/illustrations/programmer.svg +240 -0
- data/assets/illustrations/task-management.svg +174 -0
- data/assets/illustrations/tasks-complete.svg +161 -0
- data/assets/illustrations/travel-booking-hotel.svg +214 -0
- data/assets/illustrations/video-call.svg +178 -0
- data/assets/images/apple-touch-icon.png +0 -0
- data/assets/images/favicon-dark.png +0 -0
- data/assets/images/favicon-light.png +0 -0
- data/assets/images/howdy-theme-dark.png +0 -0
- data/assets/images/howdy-theme-light.png +0 -0
- data/assets/images/og-image.png +0 -0
- data/assets/js/hero-carousel.js +36 -0
- data/assets/js/mobile-nav.js +62 -0
- data/assets/js/swiper-bundle.min.js +13 -0
- data/assets/js/swiper-bundle.min.js.map +1 -0
- data/assets/js/theme-toggle.js +54 -0
- data/assets/resume.pdf +683 -0
- data/contact.md +74 -0
- data/howdy-jekyll-theme.gemspec +25 -0
- data/lib/howdy-jekyll-theme.rb +19 -0
- metadata +245 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3e5fe3f63665dc591e58b9ff6a57b5656b2a538ea7ff26eb2a575514d2a1db1b
|
|
4
|
+
data.tar.gz: 5a2a87e1f35d519013abe2e6c1dc722574c71bec65039a6c953f3db911629434
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 96872e77ddd36759fa876672c4be696bc1763f84cf8ed8da91ddfae4286a2f2ea53c1c74af21fbbe07c17661a216600e8018e634a9765c762ffef4de148ec523
|
|
7
|
+
data.tar.gz: 202609b75773017be7e56f38117732d96cf80e9fd5a44f8e4fcdc70bb6bc23a210abbc48ab334cbe603ec2bb7922f1ee5cecf4cb7fd1b145bb6fe9f40bfe5202
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# AGENTS.md — Howdy Jekyll Theme
|
|
2
|
+
|
|
3
|
+
## What this is
|
|
4
|
+
|
|
5
|
+
A gem-based Jekyll theme (`howdy-jekyll-theme`, v1.0.0) for personal sites and portfolios. Ruby >= 3.0, runs on 3.4.0 locally. No tests, no CI, no linter.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
| Action | Command |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Setup | `bundle config --local path .bundle && bundle install` |
|
|
12
|
+
| Dev server | `bundle exec jekyll serve` → http://localhost:4000 |
|
|
13
|
+
| Build gem | `gem build howdy-jekyll-theme.gemspec` |
|
|
14
|
+
| Install local gem | `gem install ./howdy-jekyll-theme-1.0.0.gem` |
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
- **`lib/howdy-jekyll-theme.rb`** — Entry point. Registers a `Jekyll::Hooks.register :site, :after_init` hook that injects the theme's `_layouts`, `_includes`, and `_sass` paths into Jekyll's lookup.
|
|
19
|
+
- **`howdy-jekyll-theme.gemspec`** — `spec.files` uses `Dir[]` glob patterns. Any new files must match an existing pattern to be included in the built gem.
|
|
20
|
+
- **`_config.yml`** — Uses `theme: howdy-jekyll-theme` so the repo serves as both the gem source and its own demo site.
|
|
21
|
+
|
|
22
|
+
## Key conventions
|
|
23
|
+
|
|
24
|
+
- **Sass**: Uses modern `@use` syntax (not `@import`). All partials live directly under `_sass/`.
|
|
25
|
+
- **Pagination**: Uses `jekyll-paginate-v2` (NOT `jekyll-paginate`). Config in `_config.yml` under `pagination:`.
|
|
26
|
+
- **Excerpts**: `<!--more-->` is the separator, not the default.
|
|
27
|
+
- **Projects collection**: Sorted by `year` front-matter field. Lives in `_projects/`.
|
|
28
|
+
- **Blog**: Entry page is `blog/index.html` (layout: `blog`). Posts in `_posts/` follow `YYYY-MM-DD-slug.md` naming.
|
|
29
|
+
- **Categories** have color accents: Tutorials=blue, Inspiration=orange, Freebies=green, Interviews=purple.
|
|
30
|
+
- **Dark mode**: Toggled via `assets/js/theme-toggle.js`, persisted in `localStorage`, respects `prefers-color-scheme`.
|
|
31
|
+
|
|
32
|
+
## File structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
_layouts/ — 7 layouts: default, home, page, post, project, blog, autopage_collection
|
|
36
|
+
_includes/ — 12 partials (analytics, blog-pagination, comments, dark-mode-toggle, head, hero-carousel, logo, navigation, newsletter, share-buttons, social-links, toc)
|
|
37
|
+
_sass/ — 6 partials: variables, base, typography, layout, components, dark-mode
|
|
38
|
+
assets/ — css/main.scss (entry), js/theme-toggle.js, fonts/, images/
|
|
39
|
+
_projects/ — Demo project content
|
|
40
|
+
_posts/ — Demo blog posts
|
|
41
|
+
blog/ — Blog index page (pagination entry)
|
|
42
|
+
lib/ — Gem entry point (Jekyll hook)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Gotchas
|
|
46
|
+
|
|
47
|
+
- The `_config.yml` excludes `Gemfile`, `Gemfile.lock`, `*.gemspec`, `README.md`, `LICENSE` from the Jekyll build — do not put content there expecting it to render.
|
|
48
|
+
- Font files (Inter, Chaumont Script, Fragment Mono) in `assets/fonts/` are licensed; verify licensing before redistributing.
|
|
49
|
+
- The `.bundle/` directory contains vendored gems — do not edit files inside it.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kyle Greenan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
# Howdy Jekyll Theme
|
|
2
|
+
|
|
3
|
+
> A clean, modern, and minimalist Jekyll theme for personal websites and portfolios.
|
|
4
|
+
|
|
5
|
+
[](https://rubygems.org/gems/howdy-jekyll-theme)
|
|
6
|
+
[](https://github.com/howdyitskyle/howdy-jekyll-theme/actions/workflows/ci.yml)
|
|
7
|
+
[](https://jekyllrb.com/)
|
|
8
|
+
[](https://www.ruby-lang.org/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](lighthouserc.json)
|
|
11
|
+
|
|
12
|
+
[**Live Demo**](https://howdyitskyle.github.io/howdy-jekyll-theme/) · [**Installation**](#installation) · [**Configuration**](#configuration) · [**Contributing**](#contributing)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
| Dependency | Version | Required |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| [Ruby](https://www.ruby-lang.org/) | >= 3.0 | Yes |
|
|
21
|
+
| [Jekyll](https://jekyllrb.com/) | >= 3.9 | Yes |
|
|
22
|
+
| [Bundler](https://bundler.io/) | >= 2.4 | Yes |
|
|
23
|
+
| [Node.js](https://nodejs.org/) | >= 18 | For Lighthouse CI only |
|
|
24
|
+
|
|
25
|
+
## Screenshots
|
|
26
|
+
|
|
27
|
+
| Light Mode | Dark Mode |
|
|
28
|
+
|---|---|
|
|
29
|
+
|  |  |
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
| Feature | Description |
|
|
34
|
+
|---|---|
|
|
35
|
+
| **Gem-based** | Easy installation via RubyGems |
|
|
36
|
+
| **Light & Dark** | Toggle with persistent preference, respects system preference |
|
|
37
|
+
| **Responsive** | Desktop, tablet, and mobile optimized |
|
|
38
|
+
| **Hero Carousel** | Touch/swipe-enabled, Swiper.js powered, fade transitions, autoplay |
|
|
39
|
+
| **Projects** | Portfolio collection sorted by year with dedicated layouts |
|
|
40
|
+
| **Blog** | jekyll-paginate-v2 powered with category color accents |
|
|
41
|
+
| **SEO** | jekyll-seo-tag integration |
|
|
42
|
+
| **RSS** | Automatic feed via jekyll-feed |
|
|
43
|
+
| **TOC** | Auto-generated table of contents with configurable heading levels |
|
|
44
|
+
| **Share** | Twitter, LinkedIn, Facebook, Reddit, Hacker News, WhatsApp, Telegram, Email, and copy-link buttons |
|
|
45
|
+
| **Newsletter** | Mailchimp, Buttondown, or custom form support |
|
|
46
|
+
| **Comments** | Giscus, Disqus, or Utterances |
|
|
47
|
+
| **Analytics** | Google Analytics or Plausible |
|
|
48
|
+
| **Company Logos** | Configurable "Trusted by" marquee section |
|
|
49
|
+
| **Fonts** | Local DM Sans variable font + Chaumont Script logo font. Configurable via `fonts.primary` and `fonts.mono` |
|
|
50
|
+
|
|
51
|
+
## Browser Compatibility
|
|
52
|
+
|
|
53
|
+
| Browser | Version | Supported |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Chrome | 120+ | ✅ |
|
|
56
|
+
| Firefox | 115+ | ✅ |
|
|
57
|
+
| Safari | 16+ | ✅ |
|
|
58
|
+
| Edge | 120+ | ✅ |
|
|
59
|
+
|
|
60
|
+
### Known Quirks
|
|
61
|
+
|
|
62
|
+
- **Firefox scrollbars**: Uses `scrollbar-color` and `scrollbar-width` (native thin scrollbars). `::-webkit-scrollbar` rules are ignored.
|
|
63
|
+
- **Safari `scroll-margin-top`**: Fully supported in Safari 15+. Older versions may require `padding-top` workaround on headings.
|
|
64
|
+
- **Safari SVG `loading="lazy"`**: SVG images do not support lazy loading in Safari; they load eagerly regardless of attribute.
|
|
65
|
+
|
|
66
|
+
## Automated Testing
|
|
67
|
+
|
|
68
|
+
This theme includes Playwright end-to-end tests covering:
|
|
69
|
+
|
|
70
|
+
| Test Suite | Coverage |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `nav.spec.js` | Hamburger toggle, ESC/overlay close, desktop hide |
|
|
73
|
+
| `theme.spec.js` | Light/dark toggle, localStorage persistence, reload restore |
|
|
74
|
+
| `carousel.spec.js` | Dot navigation, swipe gestures, slide dimensions |
|
|
75
|
+
| `toc.spec.js` | Anchor scroll, scroll-margin offset, TOC presence |
|
|
76
|
+
| `transitions.spec.js` | Page fade-out, external/hash link exclusion |
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm test # Run all tests
|
|
80
|
+
npm run test:ui # Interactive UI mode
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
### New Jekyll Site
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
jekyll new my-site --skip-bundle
|
|
89
|
+
cd my-site
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Add the Theme
|
|
93
|
+
|
|
94
|
+
Add to your `Gemfile`:
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
gem "howdy-jekyll-theme"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Add to your `_config.yml`:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
theme: howdy-jekyll-theme
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then install:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
bundle config --local path .bundle
|
|
110
|
+
bundle install
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
> **Troubleshooting:** If you run into permission issues or conflicts with system gems, run `bundle config --local path .bundle` before `bundle install`. This vendors all gems into the project's `.bundle/` directory, keeping your environment isolated.
|
|
114
|
+
|
|
115
|
+
### Existing Site
|
|
116
|
+
|
|
117
|
+
Remove any `theme:` and `remote_theme:` lines from `_config.yml`, delete `_layouts`, `_includes`, and `_sass` directories, then follow the steps above.
|
|
118
|
+
|
|
119
|
+
## Configuration
|
|
120
|
+
|
|
121
|
+
### Minimal Setup
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# _config.yml
|
|
125
|
+
title: "Your Name"
|
|
126
|
+
description: "Your site description"
|
|
127
|
+
author: "Your Name"
|
|
128
|
+
email: "hi@yoursite.com"
|
|
129
|
+
|
|
130
|
+
url: "https://yoursite.com"
|
|
131
|
+
baseurl: ""
|
|
132
|
+
|
|
133
|
+
theme: howdy-jekyll-theme
|
|
134
|
+
|
|
135
|
+
plugins:
|
|
136
|
+
- jekyll-seo-tag
|
|
137
|
+
- jekyll-feed
|
|
138
|
+
- jekyll-sitemap
|
|
139
|
+
- jekyll-paginate-v2
|
|
140
|
+
|
|
141
|
+
collections:
|
|
142
|
+
projects:
|
|
143
|
+
output: true
|
|
144
|
+
permalink: /projects/:slug/
|
|
145
|
+
sort_by: year
|
|
146
|
+
|
|
147
|
+
pagination:
|
|
148
|
+
enabled: true
|
|
149
|
+
per_page: 5
|
|
150
|
+
permalink: "/blog/page:num/"
|
|
151
|
+
sort_reverse: true
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Hero Carousel
|
|
155
|
+
|
|
156
|
+
Single image or multi-image carousel:
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
# Single image
|
|
160
|
+
hero_image: /assets/images/hero.png
|
|
161
|
+
|
|
162
|
+
# Carousel (2+ images enables touch/swipe)
|
|
163
|
+
hero_images:
|
|
164
|
+
- /assets/images/hero-1.jpg
|
|
165
|
+
- /assets/images/hero-2.jpg
|
|
166
|
+
- /assets/images/hero-3.jpg
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Navigation
|
|
170
|
+
|
|
171
|
+
```yaml
|
|
172
|
+
navigation:
|
|
173
|
+
- title: "Home"
|
|
174
|
+
url: "/"
|
|
175
|
+
- title: "Projects"
|
|
176
|
+
url: "/projects/"
|
|
177
|
+
- title: "Blog"
|
|
178
|
+
url: "/blog/"
|
|
179
|
+
- title: "About"
|
|
180
|
+
url: "/about"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Social Links
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
social:
|
|
187
|
+
github: "https://github.com/yourusername"
|
|
188
|
+
twitter: "https://x.com/yourusername"
|
|
189
|
+
linkedin: "https://linkedin.com/in/yourusername"
|
|
190
|
+
instagram: "https://instagram.com/yourusername"
|
|
191
|
+
dribbble: "https://dribbble.com/yourusername"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Homepage Hero
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
hero:
|
|
198
|
+
headline: "I shape product strategy<br>& design experiences<br><span class=\"text-muted\">at scale</span>"
|
|
199
|
+
subtitle: "Your tagline or short description."
|
|
200
|
+
cta_text: "View case studies"
|
|
201
|
+
cta_url: "/projects/"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### About Page
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
about_bio: "Your intro paragraph. <strong>HTML</strong> supported."
|
|
208
|
+
about_headline: "Building products that<br>sit at the intersection<br><span class=\"text-muted\">of design and intelligence</span>"
|
|
209
|
+
about_paragraph_2: "Your second paragraph."
|
|
210
|
+
about_paragraph_3: "Your third paragraph."
|
|
211
|
+
about_hero_image: "/assets/illustrations/designer.svg"
|
|
212
|
+
about_resume:
|
|
213
|
+
enabled: true
|
|
214
|
+
text: "Download Resume"
|
|
215
|
+
url: "/assets/resume.pdf"
|
|
216
|
+
|
|
217
|
+
# Testimonials (shown on about page)
|
|
218
|
+
testimonials:
|
|
219
|
+
- quote: "A great testimonial quote."
|
|
220
|
+
name: "Jane Doe"
|
|
221
|
+
role: "Title, Company"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Pagination
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
pagination:
|
|
228
|
+
enabled: true
|
|
229
|
+
per_page: 5
|
|
230
|
+
permalink: "page:num/"
|
|
231
|
+
sort_reverse: true
|
|
232
|
+
prev_text: "Prev"
|
|
233
|
+
next_text: "Next"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 404 Page
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
page_404:
|
|
240
|
+
title: "Page Not Found"
|
|
241
|
+
message: "The page you're looking for doesn't exist or has been moved."
|
|
242
|
+
button_text: "Go Home"
|
|
243
|
+
button_url: "/"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Fonts
|
|
247
|
+
|
|
248
|
+
```yaml
|
|
249
|
+
fonts:
|
|
250
|
+
primary: "DM Sans" # DM Sans, Inter, Plus Jakarta Sans, Instrument Sans, Space Grotesk, Work Sans, Outfit, Manrope, Sora
|
|
251
|
+
mono: "Fragment Mono" # Fragment Mono, JetBrains Mono, Fira Code
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Company Logos Marquee
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
company_logos:
|
|
258
|
+
enabled: true
|
|
259
|
+
items:
|
|
260
|
+
- name: "Company 1"
|
|
261
|
+
width: 120
|
|
262
|
+
url: "https://company1.com"
|
|
263
|
+
- name: "Company 2"
|
|
264
|
+
width: 100
|
|
265
|
+
url: "https://company2.com"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Newsletter, Comments, Analytics
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
# Newsletter
|
|
272
|
+
newsletter:
|
|
273
|
+
enabled: true
|
|
274
|
+
provider: buttondown # mailchimp, buttondown, custom
|
|
275
|
+
action_url: "https://..." # form action URL
|
|
276
|
+
title: "Stay updated"
|
|
277
|
+
|
|
278
|
+
# Comments
|
|
279
|
+
comments:
|
|
280
|
+
enabled: false
|
|
281
|
+
provider: giscus # giscus, disqus, utterances
|
|
282
|
+
giscus:
|
|
283
|
+
repo: "user/repo"
|
|
284
|
+
repo_id: "R_XXXXXXXX"
|
|
285
|
+
category: "Announcements"
|
|
286
|
+
category_id: "DIC_XXXXXXXX"
|
|
287
|
+
|
|
288
|
+
# Analytics
|
|
289
|
+
analytics:
|
|
290
|
+
provider: plausible # google, plausible
|
|
291
|
+
plausible_domain: "yoursite.com"
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Content Types
|
|
295
|
+
|
|
296
|
+
### Projects
|
|
297
|
+
|
|
298
|
+
Create files in `_projects/`:
|
|
299
|
+
|
|
300
|
+
```yaml
|
|
301
|
+
---
|
|
302
|
+
layout: project
|
|
303
|
+
title: "Project Name"
|
|
304
|
+
subtitle: "Brief description"
|
|
305
|
+
category: "Web Design"
|
|
306
|
+
year: "2025"
|
|
307
|
+
image: /assets/images/project.jpg
|
|
308
|
+
---
|
|
309
|
+
Project content with markdown...
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Blog Posts
|
|
313
|
+
|
|
314
|
+
Create files in `_posts/` with naming format `YYYY-MM-DD-slug.md`:
|
|
315
|
+
|
|
316
|
+
```yaml
|
|
317
|
+
---
|
|
318
|
+
layout: post
|
|
319
|
+
title: "Post Title"
|
|
320
|
+
category: "Tutorials" # Tutorials, Inspiration, Freebies, Interviews
|
|
321
|
+
image: /assets/images/post.jpg
|
|
322
|
+
---
|
|
323
|
+
Post content...
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
> **Tip:** Use `<!--more-->` to define the excerpt shown on the blog index.
|
|
327
|
+
|
|
328
|
+
## Customization
|
|
329
|
+
|
|
330
|
+
### Override Styles
|
|
331
|
+
|
|
332
|
+
Create `assets/css/main.scss` in your site:
|
|
333
|
+
|
|
334
|
+
```scss
|
|
335
|
+
---
|
|
336
|
+
---
|
|
337
|
+
@use "variables";
|
|
338
|
+
@use "base";
|
|
339
|
+
@use "typography";
|
|
340
|
+
@use "layout";
|
|
341
|
+
@use "components";
|
|
342
|
+
@use "dark-mode";
|
|
343
|
+
|
|
344
|
+
// Your styles here
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Override Partials
|
|
348
|
+
|
|
349
|
+
Copy any `_includes/` or `_layouts/` file into your site's directory with the same path. Jekyll will use your version instead of the theme's.
|
|
350
|
+
|
|
351
|
+
### User Color Palette
|
|
352
|
+
|
|
353
|
+
Override the green accent in your `_config.yml`:
|
|
354
|
+
|
|
355
|
+
```yaml
|
|
356
|
+
colors:
|
|
357
|
+
accent_green: "#008a1e"
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Development
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
git clone https://github.com/howdyitskyle/howdy-jekyll-theme.git
|
|
364
|
+
cd howdy-jekyll-theme
|
|
365
|
+
bundle config --local path .bundle
|
|
366
|
+
bundle install
|
|
367
|
+
bundle exec jekyll serve
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Visit `http://localhost:4000`.
|
|
371
|
+
|
|
372
|
+
### Testing
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
bundle exec rake test # HTML validation (links, images, scripts)
|
|
376
|
+
bundle exec rake validate_config # Config field checks
|
|
377
|
+
bundle exec rake lighthouse # Performance & accessibility audits
|
|
378
|
+
bundle exec rake all # All of the above
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Lighthouse CI asserts accessibility >= 0.9 across 5 pages.
|
|
382
|
+
|
|
383
|
+
### Build the Gem
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
gem build howdy-jekyll-theme.gemspec
|
|
387
|
+
gem install ./howdy-jekyll-theme-1.0.0.gem
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## File Structure
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
├── _includes/ # 12 partials (nav, hero-carousel, toc, share, etc.)
|
|
394
|
+
├── _layouts/ # 7 layouts (default, home, page, post, project, blog, collection)
|
|
395
|
+
├── _sass/ # 7 stylesheets (variables, base, typography, layout, components, dark-mode, user-colors)
|
|
396
|
+
├── assets/
|
|
397
|
+
│ ├── css/ # main.scss, swiper-bundle.min.css
|
|
398
|
+
│ ├── js/ # hero-carousel.js, mobile-nav.js, theme-toggle.js, swiper-bundle.min.js
|
|
399
|
+
│ ├── fonts/ # ChaumontScript-Regular.otf, DMSans-Variable.ttf, DMSans-Italic-Variable.ttf
|
|
400
|
+
│ ├── images/
|
|
401
|
+
│ └── illustrations/
|
|
402
|
+
├── _projects/ # Demo portfolio items
|
|
403
|
+
├── _posts/ # Demo blog posts
|
|
404
|
+
├── blog/ # Blog index with pagination
|
|
405
|
+
├── lib/ # Gem entry point
|
|
406
|
+
├── _config.yml # Fully documented configuration
|
|
407
|
+
├── Rakefile # Test runner
|
|
408
|
+
└── lighthouserc.json # Lighthouse CI assertions
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Contributing
|
|
412
|
+
|
|
413
|
+
1. Fork the repo
|
|
414
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
415
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
416
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
417
|
+
5. Open a Pull Request
|
|
418
|
+
|
|
419
|
+
Bug reports and feature requests are welcome at [Issues](https://github.com/howdyitskyle/howdy-jekyll-theme/issues).
|
|
420
|
+
|
|
421
|
+
## License
|
|
422
|
+
|
|
423
|
+
This theme is available under the [MIT License](LICENSE).
|
|
424
|
+
|
|
425
|
+
## Acknowledgments
|
|
426
|
+
|
|
427
|
+
- **[axeltmpl](https://axeltmpl.framer.website/)** — Design inspired by and remixed from this Framer template
|
|
428
|
+
- **[Illustration Kit](https://illustrationkit.com/illustrations/ven)** — Free SVG illustrations by Pencil
|
|
429
|
+
- **[Swiper.js](https://swiperjs.com/)** — Touch-enabled carousel (MIT)
|
|
430
|
+
- **[Chaumont Script](https://fontmeme.com/fonts/chaumont-script-font/)** — by Måns Grebäck
|
|
431
|
+
- **[Jekyll](https://jekyllrb.com/)** — Static site generator
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{% if site.analytics %}
|
|
2
|
+
{% if site.analytics.google_analytics %}
|
|
3
|
+
<!-- Google Analytics -->
|
|
4
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google_analytics }}"></script>
|
|
5
|
+
<script>
|
|
6
|
+
window.dataLayer = window.dataLayer || [];
|
|
7
|
+
function gtag(){dataLayer.push(arguments);}
|
|
8
|
+
gtag('js', new Date());
|
|
9
|
+
gtag('config', '{{ site.analytics.google_analytics }}');
|
|
10
|
+
</script>
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
13
|
+
{% if site.analytics.plausible %}
|
|
14
|
+
<!-- Plausible Analytics -->
|
|
15
|
+
{% assign script_url = site.analytics.plausible.script_url | default: "https://plausible.io/js/script.js" %}
|
|
16
|
+
{% assign domain = site.analytics.plausible.domain %}
|
|
17
|
+
<script defer data-domain="{{ domain }}" src="{{ script_url }}"></script>
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% endif %}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% if paginator.total_pages > 1 %}
|
|
2
|
+
<div class="pagination">
|
|
3
|
+
{% if paginator.previous_page %}
|
|
4
|
+
<a href="{{ paginator.previous_page_path }}" class="btn btn-secondary">
|
|
5
|
+
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true" class="btn-arrow">
|
|
6
|
+
<path d="M9 3L4 8L9 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7
|
+
</svg>
|
|
8
|
+
{{ site.pagination.prev_text | default: "Prev" }}
|
|
9
|
+
</a>
|
|
10
|
+
{% endif %}
|
|
11
|
+
|
|
12
|
+
{% for page_num in (1..paginator.total_pages) %}
|
|
13
|
+
{% if page_num == paginator.page %}
|
|
14
|
+
<span class="pagination-page active">{{ page_num }}</span>
|
|
15
|
+
{% elsif page_num == 1 %}
|
|
16
|
+
<a href="{{ paginator.first_page_path }}" class="pagination-page">{{ page_num }}</a>
|
|
17
|
+
{% else %}
|
|
18
|
+
<a href="{{ paginator.first_page_path | append: 'page' | append: page_num | append: '/' }}" class="pagination-page">{{ page_num }}</a>
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% endfor %}
|
|
21
|
+
|
|
22
|
+
{% if paginator.next_page %}
|
|
23
|
+
<a href="{{ paginator.next_page_path }}" class="btn btn-secondary post-nav-next">
|
|
24
|
+
{{ site.pagination.next_text | default: "Next" }}
|
|
25
|
+
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true" class="btn-arrow">
|
|
26
|
+
<path d="M7 3L12 8L7 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
27
|
+
</svg>
|
|
28
|
+
</a>
|
|
29
|
+
{% endif %}
|
|
30
|
+
</div>
|
|
31
|
+
{% endif %}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{% if site.comments and site.comments.provider %}
|
|
2
|
+
<div class="comments">
|
|
3
|
+
{% if site.comments.provider == "giscus" and site.comments.giscus %}
|
|
4
|
+
<script src="https://giscus.app/client.js"
|
|
5
|
+
data-repo="{{ site.comments.giscus.repo }}"
|
|
6
|
+
data-repo-id="{{ site.comments.giscus.repo_id }}"
|
|
7
|
+
data-category="{{ site.comments.giscus.category }}"
|
|
8
|
+
data-category-id="{{ site.comments.giscus.category_id }}"
|
|
9
|
+
data-mapping="{{ site.comments.giscus.mapping | default: 'pathname' }}"
|
|
10
|
+
data-strict="{{ site.comments.giscus.strict | default: 0 }}"
|
|
11
|
+
data-reactions-enabled="{{ site.comments.giscus.reactions_enabled | default: 1 }}"
|
|
12
|
+
data-emit-metadata="{{ site.comments.giscus.emit_metadata | default: 0 }}"
|
|
13
|
+
data-theme="{{ site.comments.giscus.theme | default: 'light' }}"
|
|
14
|
+
data-lang="{{ site.comments.giscus.lang | default: 'en' }}"
|
|
15
|
+
crossorigin="anonymous"
|
|
16
|
+
async>
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
{% elsif site.comments.provider == "disqus" and site.comments.disqus %}
|
|
20
|
+
<div id="disqus_thread"></div>
|
|
21
|
+
<script>
|
|
22
|
+
var disqus_config = function () {
|
|
23
|
+
this.page.url = '{{ page.url | absolute_url }}';
|
|
24
|
+
this.page.identifier = '{{ page.url }}';
|
|
25
|
+
};
|
|
26
|
+
(function() {
|
|
27
|
+
var d = document, s = d.createElement('script');
|
|
28
|
+
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
|
|
29
|
+
s.setAttribute('data-timestamp', +new Date());
|
|
30
|
+
(d.head || d.body).appendChild(s);
|
|
31
|
+
})();
|
|
32
|
+
</script>
|
|
33
|
+
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
|
34
|
+
|
|
35
|
+
{% elsif site.comments.provider == "utterances" and site.comments.utterances %}
|
|
36
|
+
<script src="https://utteranc.es/client.js"
|
|
37
|
+
repo="{{ site.comments.utterances.repo }}"
|
|
38
|
+
issue-term="{{ site.comments.utterances.issue_term | default: 'pathname' }}"
|
|
39
|
+
theme="{{ site.comments.utterances.theme | default: 'github-light' }}"
|
|
40
|
+
label="{{ site.comments.utterances.label | default: 'comments' }}"
|
|
41
|
+
crossorigin="anonymous"
|
|
42
|
+
async>
|
|
43
|
+
</script>
|
|
44
|
+
{% endif %}
|
|
45
|
+
</div>
|
|
46
|
+
{% endif %}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<button class="theme-toggle" id="theme-toggle" aria-label="Toggle dark mode">
|
|
2
|
+
<!-- Sun icon (shown in dark mode) -->
|
|
3
|
+
<svg class="sun-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
4
|
+
<circle cx="12" cy="12" r="5"/>
|
|
5
|
+
<line x1="12" y1="1" x2="12" y2="3"/>
|
|
6
|
+
<line x1="12" y1="21" x2="12" y2="23"/>
|
|
7
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
|
|
8
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
|
|
9
|
+
<line x1="1" y1="12" x2="3" y2="12"/>
|
|
10
|
+
<line x1="21" y1="12" x2="23" y2="12"/>
|
|
11
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
|
|
12
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
|
|
13
|
+
</svg>
|
|
14
|
+
<!-- Moon icon (shown in light mode) -->
|
|
15
|
+
<svg class="moon-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
16
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
|
17
|
+
</svg>
|
|
18
|
+
</button>
|