moonwalk 0.1.2 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2967d34ac4d69b0a22ed559b8332cccebe5c2cdd371ce09fa4566bdb384caac1
4
- data.tar.gz: 63d7e752098c997ee32d0c25e6c2eb3103c19a689edade42b524a462d86030fc
3
+ metadata.gz: c5e02cb1df7e558c3ccdda484e3bc9b6c6b29087c8691c7fdcea20b5610fbe62
4
+ data.tar.gz: b2fa5b617e6d9c030274cc51ac6900bbd1e13cc8f298313f915a9e6924e9d2c6
5
5
  SHA512:
6
- metadata.gz: 75da973db880f5071dd744bd4da7490c5ce319428e31bc38b9375f037dcf636e9bc2a326128df29f7ba0bfe1045c42cd31445a5a563548e69360a4b26cf63e40
7
- data.tar.gz: 408605ab11b60c50086241c69c291d7d66e55d08ef524a7cfce49473df0406c468e2ee31ac494d29abbb045edc8840dbbe40c8042783e05f419a19cfbc526113
6
+ metadata.gz: dae6d3047030c1bf2e97dfd78f7daccf626722cc1bfc7c221f2cbfd8f7a67a816957ed1188387e0579a5bafedf690b15e72946efee248bc0d1da3eac32a90445
7
+ data.tar.gz: 8e991204aba28ef6f7734f591b5675b34069c1df209c1e857c9033af46f987a8e6dc96950a4659a9b4ba49a6a268a67fa32db8b4132e04ceed5a2324d8e3d51c
data/README.md CHANGED
@@ -8,13 +8,32 @@
8
8
  </h3>
9
9
 
10
10
  ## Features
11
- * Light & dark mode with theme switcher
11
+ * Light & dark mode with theme switcher (respects `prefers-reduced-motion`)
12
+ * Typeset in [Geist](https://vercel.com/font) (body & headings) and [Geist Mono](https://vercel.com/font) (code)
13
+ * [Agent-friendly out of the box](#agent-friendly-by-default) - per-page `.md` siblings, `/llms.txt`, and `/llms-full.txt`
14
+ * Built-in client-side search over post titles, tags, and excerpts
15
+ * Hover-preview cards on internal post links (opt-in)
16
+ * Footnote tooltips - read footnotes inline without scrolling (opt-in)
17
+ * Smooth page transitions via the View Transitions API in supporting browsers
18
+ * Drop-cap on the first paragraph of a post (opt-in via `dropcap: true`)
19
+ * Tag cloud with frequency-weighted sizing on the tag archive
20
+ * Personality 404 with random-post link
12
21
  * Vertical list, horizontal list, card list
13
22
  * Landing page with navbar, footer, portfolio
14
23
  * Fast (very minimal CSS) - 100/100 on performance, accessibility, best practices and SEO, please see [Lighthouse Report](https://raw.githubusercontent.com/abhinavs/moonwalk/master/_screenshots/lighthouse-report.png) for more details
15
24
  * Responsive and mobile friendly
16
- * SEO optimized (uses [Jekyll Soopr SEO Tag](https://github.com/jekyll/jekyll-soopr-seo-tag))
25
+ * SEO optimized with auto-generated sitemap
17
26
  * RSS feed (uses [Jekyll Feed](https://github.com/jekyll/jekyll-feed))
27
+ * [GitHub Markdown Alerts](#github-markdown-alerts) (NOTE, TIP, IMPORTANT, WARNING, CAUTION)
28
+ * Polished `<details>` collapsibles for asides and "long version" expansions
29
+ * Tag archive page with clickable tags
30
+ * Light and dark mode syntax highlighting with language label on each code block
31
+ * Accessible - ARIA labels, keyboard friendly
32
+ * Reading progress bar (opt-in)
33
+ * Back-to-top button (opt-in)
34
+ * Previous/next post navigation (opt-in)
35
+ * Table of contents via `toc: true` front matter (opt-in)
36
+ * Code block copy button with language label (opt-in)
18
37
  * Easy to extend
19
38
  * Fully compatible with [GitHub Pages](https://pages.github.com/) (see [GitHub Pages installation](#github-pages-installation))
20
39
  * Auto-generated share images for social media (using [Soopr](https://www.soopr.co))
@@ -52,7 +71,7 @@ For further customization (e.g. layout, CSS) see the [official Jekyll's document
52
71
 
53
72
  ### Customize the menu
54
73
 
55
- In order to add/edit/delete entries in the home page, you can copy the `home.yml` file inside `_data` folder. Through that file you can define the structure of the menu and add data for navbar, footer, portfolio or simply remove all of that and use simple blog layout. Take a look at the default configuration to get an idea of how it works and read on for a more comprehensive explaination.
74
+ In order to add/edit/delete entries in the home page, you can copy the `home.yml` file inside `_data` folder. Through that file you can define the structure of the menu and add data for navbar, footer, portfolio or simply remove all of that and use simple blog layout. Take a look at the default configuration to get an idea of how it works and read on for a more comprehensive explanation.
56
75
 
57
76
  The `home.yml` file accepts the following fields:
58
77
 
@@ -85,47 +104,133 @@ The `home.yml` file accepts the following fields:
85
104
  - home - for landing page
86
105
  you can change your `index.md` file to use either home or blog layout.
87
106
 
88
- 2. It is extremely easy to tweak the color scheme.
107
+ 2. It is extremely easy to tweak the color scheme.
89
108
  - for light mode, customize these css variables
90
109
  ```css
91
110
  html {
92
- --bg: #fff;
93
- --bg-secondary: #f8f9fa;
94
- --headings: #000;
95
- --text: #333;
96
- --links: blue;
111
+ --bg: #fcfcfc;
112
+ --bg-secondary: #f1f2f4;
113
+ --bg-subtle: #f6f7f8;
114
+ --headings: #0f172a;
115
+ --text: #2b2f36;
116
+ --text-secondary: #5b6470;
117
+ --links: #4f46e5;
97
118
  --highlight: #ffecb2; // light yellow
119
+ --code-text: #9d174d;
98
120
  }
99
121
  ```
100
122
  - for dark mode customize these css variables
101
123
  ```css
102
124
  @mixin dark-appearance {
103
125
  html, body {
104
- --bg: #1f242A;
105
- --bg-secondary: #323945;
106
- --headings: #3D9970;
107
- --text: #adb5bd;
126
+ --headings: #e6edf3;
108
127
  --links: #91a7ff;
109
- --highlight: #ffd8a8;
110
- --highlight: #ffd43b;
128
+ --highlight: #41c7c7;
129
+ --bg: #15161d;
130
+ --bg-secondary: #23242f;
131
+ --bg-subtle: #1c1d26;
132
+ --text: #c4ccd6;
133
+ --text-secondary: #8b94a3;
134
+ --code-text: #91a7ff;
111
135
  };
112
136
  }
113
137
  ```
114
- 3. Sign up for free on [Soopr](https://www.soopr.co) and add your `publish_token` in `_config.yml` file - with this, each page gets short URL, like button and auto generated share image for social media.
138
+
139
+ 3. Want different fonts? Moonwalk uses Geist / Geist Mono via two CSS variables. Override them in your own SCSS:
140
+ ```css
141
+ :root {
142
+ --font-sans: "Inter", system-ui, sans-serif;
143
+ --font-mono: "JetBrains Mono", monospace;
144
+ }
145
+ ```
146
+ Don't forget to update the `<link>` to Google Fonts in `_includes/head.html` to match.
147
+
148
+ ### Optional features
149
+
150
+ Each of these is wired up in `_config.yml` under `theme_config`:
151
+
152
+ - `show_footnote_tooltips: true` - when readers hover a kramdown footnote ref (`[^1]`), the footnote text appears in a small tooltip instead of forcing a scroll to the bottom.
153
+ - `show_link_previews: true` - hover any internal post link to see a preview card with title, excerpt, and date. Powered by an auto-generated `/search.json` index.
154
+
155
+ To add **client-side search** anywhere on your site, drop `{% raw %}{% include search.html %}{% endraw %}` into a layout or page. It searches over titles, tags, and excerpts using the same `/search.json`.
156
+
157
+ To enable a **drop-cap** on a post's opening paragraph, add `dropcap: true` to the post's front matter.
158
+
159
+ To use the **`<details>` collapsible** style, just write native HTML in your Markdown:
160
+
161
+ ```html
162
+ <details>
163
+ <summary>Long version</summary>
164
+ Hidden by default, expanded on click.
165
+ </details>
166
+ ```
115
167
 
116
168
  <img src="https://raw.githubusercontent.com/abhinavs/moonwalk/master/_screenshots/twitter_card.png" />
117
169
 
170
+ ### Agent-friendly by default
171
+
172
+ LLM crawlers and coding agents read your site too. Moonwalk ships with two small Jekyll plugins so they can fetch clean Markdown instead of parsing HTML:
173
+
174
+ - **[jekyll-markdown-output](https://github.com/abhinavs/jekyll-markdown-output)** - emits a `.md` sibling for every post. A page rendered at `/foo` also exists as `/foo.md` with a small frontmatter block and the source Markdown. No layouts, no nav chrome, no theme toggles - just the content.
175
+ - **[jekyll-llms-output](https://github.com/abhinavs/jekyll-llms-output)** - generates `/llms.txt` (a curated index) and `/llms-full.txt` (full content concatenated) following the [llmstxt.org](https://llmstxt.org) spec, so agents can discover and ingest your site in one fetch.
176
+
177
+ Both are wired up in `_config.yml` with sensible defaults:
178
+
179
+ ```yaml
180
+ plugins:
181
+ - jekyll-markdown-output
182
+ - jekyll-llms-output
183
+
184
+ markdown_output:
185
+ collections: [posts]
186
+
187
+ llms_output:
188
+ index:
189
+ collections: [posts]
190
+ full:
191
+ collections: [posts]
192
+ respect_markdown_output: true
193
+ ```
194
+
195
+ Set `enabled: false` on either block to turn it off. For curated `llms.txt` content, drop a `_data/llms.yml` file with `title`, `description`, and `sections` - the plugin will use it instead of auto-generating. See each plugin's README for full configuration.
196
+
197
+ > [!NOTE]
198
+ > GitHub Pages restricts plugins to a [whitelist](https://pages.github.com/versions/), and these two are not on it. If you host on GH Pages, build the site yourself in CI (Actions, Netlify, Cloudflare Pages, Vercel) or remove the plugins.
199
+
200
+ ### GitHub Markdown Alerts
201
+
202
+ Moonwalk supports [GitHub-style Markdown Alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts). Use them in your posts like this:
203
+
204
+ ```markdown
205
+ > [!NOTE]
206
+ > Useful information that users should know, even when skimming content.
207
+
208
+ > [!TIP]
209
+ > Helpful advice for doing things better or more easily.
210
+
211
+ > [!IMPORTANT]
212
+ > Key information users need to know to achieve their goal.
213
+
214
+ > [!WARNING]
215
+ > Urgent info that needs immediate user attention to avoid problems.
216
+
217
+ > [!CAUTION]
218
+ > Advises about risks or negative outcomes of certain actions.
219
+ ```
220
+
221
+ All five alert types are styled with color-coded left borders and icons, and work in both light and dark mode.
222
+
118
223
  ## Contributing
119
224
 
120
- Bug reports and pull requests are welcome on GitHub at https://github.com/abhinavs/moonwalk.
225
+ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
121
226
 
122
227
  ## Development
123
228
 
124
- To set up your environment to develop this theme, run `bundle install`.
125
-
126
- Your theme is setup just like a normal Jekyll site! To test your theme, run `bundle exec jekyll serve` and open your browser at `http://localhost:4000`. This starts a Jekyll server using your theme. Add pages, documents, data, etc. like normal to test your theme's contents. As you make modifications to your theme and to your content, your site will regenerate and you should see the changes in the browser after a refresh, just like normal.
229
+ 1. Run `bin/bootstrap` (or `make setup`) to install dependencies
230
+ 2. Run `bin/start` (or `make serve`) to start the dev server with live reload at `http://127.0.0.1:4000`
231
+ 3. Run `bin/build` (or `make build`) for a production build
127
232
 
128
- When your theme is released, only the files in `_layouts`, `_includes`, `_sass` and `assets` tracked with Git will be bundled.
233
+ When your theme is released, only the files in `_layouts`, `_includes`, `_sass`, `_data`, and `assets` tracked with Git will be bundled.
129
234
  To add a custom directory to your theme-gem, please edit the regexp in `moonwalk.gemspec` accordingly.
130
235
 
131
236
  ## Acknowledgement
@@ -146,6 +251,6 @@ If you like Moonwalk, do check out my other projects
146
251
  * [blockr](https://www.abhinav.co/blockr) - a CLI tool to help you easily block and unblock websites
147
252
  * [microrequests](https://www.abhinav.co/microrequests) - a Python library to help you consume microservice efficiently
148
253
 
149
- ✨⚡You can read more about me on my [blog](https://www.abhinav.co/about/) or follow me on Twitter - [@abhinav](https://twitter.com/abhinav)
254
+ You can read more about me on my [blog](https://www.abhinav.co/about/) or follow me on Twitter - [@abhinav](https://twitter.com/abhinav)
150
255
 
151
- ✨⚡If you like my work, you can [buy me a coffee](https://buymeacoffee.com/abhinavs)
256
+ If you like my work, you can [buy me a coffee](https://buymeacoffee.com/abhinavs)
data/_config.yml CHANGED
@@ -1,16 +1,15 @@
1
1
  title: Moonwalk
2
2
  author: Abhinav Saxena
3
- url: https://www.abhinavsaxena.com/moonwalk # root address of the site
3
+ url: https://www.abhinavsaxena.com # root address of the site
4
+ baseurl: "/moonwalk/" # set to "/moonwalk" if hosting under a project subpath
4
5
  description: > # description of the site (multiple lines allowed)
5
6
  Moonwalk is a fast and elegant Jekyll theme with a clean dark mode. It comes with horizontal list (for navbar and footer), card list (for portfolio), and a generic vertical list. It is very easy to modify in case you want to build over it - please see _layouts/home.html to do that.
6
7
 
7
8
  permalink: /:slug
8
9
 
9
- favicon: "./logo.png" # relative path to site's favicon
10
-
11
10
  twitter:
12
- username: abhinav # update or delete this
13
- card: summary_large_image
11
+ username: abhinav # update or delete this
12
+ card: summary_large_image
14
13
 
15
14
  #theme: moonwalk # if you are using GitHub Pages, change it to remote_theme: abhinavs/moonwalk
16
15
  remote_theme: abhinavs/moonwalk
@@ -18,7 +17,6 @@ remote_theme: abhinavs/moonwalk
18
17
  theme_config:
19
18
  appearance: "dark" # can be "light", "dark" or "auto"
20
19
  appearance_toggle: true # if appearance can be switched by user
21
- back_home_text: "home.." # customize text for homepage link in post layout
22
20
  date_format: "%Y-%m-%d" # customize how date is formatted
23
21
  show_description: true # show blog description
24
22
  show_navbar: true # show horizontal navbar
@@ -30,6 +28,14 @@ theme_config:
30
28
  show_old_projects: true # show old projects as cards, add in _data/home.yml
31
29
  show_misc_list: false # show generic vertical list for misc details, add _data/home.yml
32
30
  show_reading_time: true # show number of words and reading time in the blog posts
31
+ show_tags: true # show tags in a blog posts
32
+ show_code_copy: true # show copy button on code blocks
33
+ show_progress_bar: true # show reading progress bar on posts
34
+ show_back_to_top: true # show back-to-top button
35
+ show_post_nav: true # show prev/next links on posts
36
+ show_toc: true # allow per-post table of contents via toc: true front matter
37
+ show_footnote_tooltips: true # show footnote text on hover instead of scrolling to bottom
38
+ show_link_previews: true # show preview cards when hovering internal post links
33
39
  # options for "home" page
34
40
  home:
35
41
  title_projects: Portfolio
@@ -47,4 +53,21 @@ sass:
47
53
 
48
54
  plugins:
49
55
  - jekyll-feed
56
+ - jekyll-sitemap
50
57
  - jekyll-soopr-seo-tag
58
+ - jekyll-markdown-output
59
+ - jekyll-llms-output
60
+
61
+ # Emit a clean .md sibling for each post (e.g. /foo -> /foo.md) so AI agents
62
+ # can fetch source Markdown instead of parsing HTML. Set enabled: false to disable.
63
+ markdown_output:
64
+ collections: [posts]
65
+
66
+ # Emit /llms.txt (curated index) and /llms-full.txt (full content) so agents
67
+ # can discover and ingest the site. See https://llmstxt.org for the spec.
68
+ llms_output:
69
+ index:
70
+ collections: [posts]
71
+ full:
72
+ collections: [posts]
73
+ respect_markdown_output: true
data/_data/home.yml ADDED
@@ -0,0 +1,104 @@
1
+ navbar_entries:
2
+ - title: about
3
+ url: about
4
+
5
+ - title: blog
6
+ url: blog
7
+
8
+ - title: website
9
+ url: https://www.abhinav.co
10
+
11
+ project_entries:
12
+ - title: Project 1
13
+ url: overview-post
14
+ desc: This is an example project, configured in _data/home.yml
15
+
16
+ - title: Project 2
17
+ url: overview-post
18
+ desc: Projects are shown in card layout
19
+
20
+ - title: Project 3
21
+ url: overview-post
22
+ desc: You can control visibility from _config.yml file
23
+
24
+ - title: Project 4
25
+ url: overview-post
26
+ desc: This project uses highlight markup, configured in _data/home.yml
27
+ highlight: WIP
28
+
29
+ - title: Project 5
30
+ url: overview-post
31
+ desc: Moonwalk also has horizontal list (used in header and footer)
32
+ highlight: WIP
33
+
34
+ - title: Project 6
35
+ url: overview-post
36
+ desc: It also has a scalable vertical list (in case you need it)
37
+
38
+ old_project_entries:
39
+ - title: Soopr
40
+ url: https://www.soopr.co
41
+ desc: Delight your readers - add beautiful share and like buttons easily to your websites
42
+ highlight: NEW
43
+
44
+ - title: Cookie
45
+ url: https://github.com/abhinavs/cookie
46
+ desc: An open source landing website with supporting pages and integrated blog
47
+
48
+ - title: Moonwalk
49
+ url: https://github.com/abhinavs/moonwalk
50
+ desc: A fast and minimalist Jekyll blog theme with clean dark mode
51
+
52
+ - title: Humangous
53
+ url: https://www.humangous.co
54
+ desc: The better people know you, the better they collaborate
55
+
56
+ footer_entries:
57
+ - title: abhinav's homepage
58
+ url: https://www.abhinav.co
59
+
60
+ - title: twitter
61
+ url: https://twitter.com/abhinav
62
+
63
+ - title: github
64
+ url: https://github.com/abhinavs
65
+
66
+ - title: feed
67
+ url: feed.xml
68
+
69
+ - title: llms.txt
70
+ url: llms.txt
71
+
72
+ misc_entries:
73
+ - title: this is an example vertical list
74
+ url: false
75
+
76
+ - title: you can show or hide using a boolean flag in _config.yml
77
+ url: false
78
+
79
+ - title: and you can add data in _data/home.yml
80
+ url: false
81
+
82
+ - title: Blog posts
83
+ post_list: true
84
+ url: false
85
+
86
+ - title: moonwalk on the Internet
87
+ url: false
88
+ entries:
89
+ - title: on Github
90
+ url: https://github.com/abhinavs/moonwalk
91
+
92
+ - title: originally built for abhinav's homepage
93
+ url: https://www.abhinav.co
94
+
95
+ - title: this list is scalable and can be nested
96
+ url: false
97
+ entries:
98
+ - title: this is nested inside a nested list
99
+ url: false
100
+
101
+ - title: it is easy to use, see _data/home.yml to see how to configure it.
102
+ url: false
103
+
104
+
@@ -0,0 +1,53 @@
1
+ <button class="back-to-top" aria-label="Back to top" onclick="window.scrollTo({top:0,behavior:'smooth'})">
2
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3
+ <polyline points="18 15 12 9 6 15"></polyline>
4
+ </svg>
5
+ </button>
6
+ <style>
7
+ .back-to-top {
8
+ position: fixed;
9
+ bottom: 2em;
10
+ right: 2em;
11
+ width: 40px;
12
+ height: 40px;
13
+ border-radius: 50%;
14
+ border: 1px solid var(--border);
15
+ background: var(--bg-secondary);
16
+ color: var(--text);
17
+ cursor: pointer;
18
+ opacity: 0;
19
+ pointer-events: none;
20
+ transition: opacity 0.3s ease;
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ z-index: 50;
25
+ }
26
+ .back-to-top.visible {
27
+ opacity: 1;
28
+ pointer-events: auto;
29
+ }
30
+ .back-to-top:hover {
31
+ color: var(--links);
32
+ }
33
+ @media screen and (max-width: 600px) {
34
+ .back-to-top {
35
+ bottom: 1em;
36
+ right: 1em;
37
+ width: 36px;
38
+ height: 36px;
39
+ }
40
+ }
41
+ </style>
42
+ <script>
43
+ (function() {
44
+ var btn = document.querySelector('.back-to-top');
45
+ window.addEventListener('scroll', function() {
46
+ if (window.scrollY > 400) {
47
+ btn.classList.add('visible');
48
+ } else {
49
+ btn.classList.remove('visible');
50
+ }
51
+ });
52
+ })();
53
+ </script>
@@ -0,0 +1,31 @@
1
+ <script>
2
+ (function() {
3
+ document.querySelectorAll('div.highlighter-rouge').forEach(function(block) {
4
+ block.style.position = 'relative';
5
+
6
+ // Language label derived from rouge's language-* class
7
+ var langClass = Array.from(block.classList).find(function(c) {
8
+ return c.indexOf('language-') === 0 && c !== 'language-plaintext';
9
+ });
10
+ if (langClass) {
11
+ var label = document.createElement('span');
12
+ label.className = 'code-lang';
13
+ label.textContent = langClass.replace('language-', '');
14
+ block.appendChild(label);
15
+ }
16
+
17
+ var btn = document.createElement('button');
18
+ btn.className = 'code-copy';
19
+ btn.setAttribute('aria-label', 'Copy code to clipboard');
20
+ btn.textContent = 'copy';
21
+ btn.addEventListener('click', function() {
22
+ var code = block.querySelector('code');
23
+ navigator.clipboard.writeText(code.innerText).then(function() {
24
+ btn.textContent = 'copied!';
25
+ setTimeout(function() { btn.textContent = 'copy'; }, 2000);
26
+ });
27
+ });
28
+ block.appendChild(btn);
29
+ });
30
+ })();
31
+ </script>
@@ -1,25 +1,32 @@
1
- <p class="post-date text-bold text-upcase">
2
- {% if page.author %}
3
- <span class="text-bold">{{ page.author }}</span> /
4
- {% endif %}
5
- {% if page.date %}
6
- <span>{{ page.date | date: "%B %Y"}}</span>
1
+ <div class="post-meta">
2
+ <div class="post-meta-line">
3
+ {% if page.author %}
4
+ <span class="post-meta-author">{{ page.author }}</span>
5
+ <span class="post-meta-sep">·</span>
6
+ {% endif %}
7
+ {% if page.date %}
8
+ <time class="post-meta-date" datetime="{{ page.date | date_to_xmlschema }}">
9
+ {{ page.date | date: "%B %-d, %Y" }}
10
+ </time>
11
+ {% endif %}
12
+ {% if site.theme_config.show_reading_time == true %}
13
+ {% capture words %}{{ content | number_of_words | minus: 180 }}{% endcapture %}
14
+ {% unless words contains '-' %}
15
+ <span class="post-meta-sep">·</span>
16
+ <span class="post-meta-reading">{{ words | plus: 180 | divided_by: 180 }} min read</span>
17
+ {% endunless %}
18
+ {% endif %}
19
+ </div>
20
+
21
+ {% if site.theme_config.show_tags == true and page.tags %}
22
+ <div class="post-meta-tags">
23
+ {% for tag in page.tags %}
24
+ <a href="{{ "/tags" | relative_url }}#{{ tag | slugify }}" class="tag">{{ tag }}</a>
25
+ {% endfor %}
26
+ </div>
7
27
  {% endif %}
8
- </p>
9
28
 
10
- <div class="soopr-btn"
11
- data-twitter="SooprCo"
12
- >
29
+ <div class="soopr-btn"
30
+ {% if site.twitter.username %}data-twitter="{{ site.twitter.username }}"{% endif %}
31
+ ></div>
13
32
  </div>
14
-
15
- {% if site.theme_config.show_reading_time == true %}
16
- <p class="post-date text-bold">
17
- {% capture words %}
18
- {{ content | number_of_words | minus: 180 }}
19
- {% endcapture %}
20
- {% unless words contains '-' %}
21
- {{ words | append: ' Words, ' }}
22
- {{ words | plus: 180 | divided_by: 180 | append: ' Minutes' }}
23
- {% endunless %}
24
- </p>
25
- {% endif %}
@@ -0,0 +1,39 @@
1
+ <script>
2
+ (function() {
3
+ // Render a small tooltip preview when hovering/tapping kramdown-generated
4
+ // footnote refs (e.g. <a href="#fn:1">1</a>) so readers don't have to
5
+ // scroll to the bottom of the post.
6
+ var refs = document.querySelectorAll('a.footnote, sup a[href^="#fn"]');
7
+ if (!refs.length) return;
8
+
9
+ var tip = document.createElement('div');
10
+ tip.className = 'fn-tooltip';
11
+ tip.setAttribute('role', 'tooltip');
12
+ document.body.appendChild(tip);
13
+
14
+ function show(ref) {
15
+ var id = ref.getAttribute('href').slice(1);
16
+ var fn = document.getElementById(id);
17
+ if (!fn) return;
18
+ var clone = fn.cloneNode(true);
19
+ var back = clone.querySelector('.reversefootnote, a[href^="#fnref"]');
20
+ if (back) back.remove();
21
+ tip.innerHTML = clone.innerHTML;
22
+
23
+ var rect = ref.getBoundingClientRect();
24
+ var top = window.scrollY + rect.bottom + 8;
25
+ var left = Math.max(12, window.scrollX + rect.left - 12);
26
+ tip.style.top = top + 'px';
27
+ tip.style.left = left + 'px';
28
+ tip.classList.add('visible');
29
+ }
30
+ function hide() { tip.classList.remove('visible'); }
31
+
32
+ refs.forEach(function(ref) {
33
+ ref.addEventListener('mouseenter', function() { show(ref); });
34
+ ref.addEventListener('mouseleave', hide);
35
+ ref.addEventListener('focus', function() { show(ref); });
36
+ ref.addEventListener('blur', hide);
37
+ });
38
+ })();
39
+ </script>
@@ -0,0 +1,41 @@
1
+ <script>
2
+ document.addEventListener("DOMContentLoaded", function () {
3
+ var defined_alerts = {
4
+ NOTE: { icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>', label: 'Note' },
5
+ TIP: { icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"></path></svg>', label: 'Tip' },
6
+ IMPORTANT: { icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>', label: 'Important' },
7
+ WARNING: { icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>', label: 'Warning' },
8
+ CAUTION: { icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>', label: 'Caution' }
9
+ };
10
+
11
+ var blockquotes = document.querySelectorAll("blockquote");
12
+ for (var i = 0; i < blockquotes.length; i++) {
13
+ var bq = blockquotes[i];
14
+ var firstP = bq.querySelector("p:first-child");
15
+ if (!firstP) continue;
16
+
17
+ var text = firstP.innerHTML;
18
+ var match = text.match(/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(<br\s*\/?>)?/);
19
+ if (!match) continue;
20
+
21
+ var type = match[1];
22
+ var alert = defined_alerts[type];
23
+
24
+ // Remove the marker from the paragraph text
25
+ firstP.innerHTML = text.replace(match[0], "").trim();
26
+
27
+ // If the paragraph is now empty, remove it
28
+ if (!firstP.innerHTML) {
29
+ firstP.remove();
30
+ }
31
+
32
+ // Build the alert title
33
+ var title = document.createElement("p");
34
+ title.className = "markdown-alert-title";
35
+ title.innerHTML = alert.icon + " " + alert.label;
36
+ bq.insertBefore(title, bq.firstChild);
37
+
38
+ bq.classList.add("markdown-alert", "markdown-alert-" + type.toLowerCase());
39
+ }
40
+ });
41
+ </script>
data/_includes/head.html CHANGED
@@ -14,7 +14,25 @@
14
14
  {% seo title=false %}
15
15
  {% feed_meta %}
16
16
 
17
- <link rel="shortcut icon" type="image/x-icon" href="/{{ site.favicon | relative_url }}" />
17
+ <!-- Favicon -->
18
+ <link rel="apple-touch-icon" sizes="180x180" href="{{ "/assets/images/favicon/apple-touch-icon.png" | relative_url }}">
19
+ <link rel="icon" type="image/png" sizes="32x32" href="{{ "/assets/images/favicon/favicon-32x32.png" | relative_url }}">
20
+ <link rel="icon" type="image/png" sizes="16x16" href="{{ "/assets/images/favicon/favicon-16x16.png" | relative_url }}">
21
+ <link rel="manifest" href="{{ "/assets/images/favicon/site.webmanifest" | relative_url }}">
22
+ <link rel="mask-icon" href="{{ "/assets/images/favicon/safari-pinned-tab.svg" | relative_url }}" color="#5bbad5">
23
+ <link rel="shortcut icon" href="{{ "/assets/images/favicon/favicon.ico" | relative_url }}">
24
+ <meta name="msapplication-TileColor" content="#00aba9">
25
+ <meta name="msapplication-config" content="{{ "/assets/images/favicon/browserconfig.xml" | relative_url }}">
26
+ <meta name="theme-color" content="#ffffff">
27
+ <!-- Favicon -->
28
+
29
+ <link rel="preconnect" href="https://fonts.googleapis.com">
30
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
31
+ <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
32
+ {%- if site.soopr -%}
33
+ <link rel="dns-prefetch" href="https://sdk.soopr.co">
34
+ {%- endif -%}
35
+
18
36
  <link rel="stylesheet" href="{{ "/assets/css/main.css" | relative_url }}" />
19
37
  {% if site.theme_config.appearance_toggle %}
20
38
  {% include toggle_theme_js.html %}