jekyll-theme-merida 0.0.1

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.
@@ -0,0 +1,213 @@
1
+ /* Overrides of Tailwind Theme */
2
+ @import url('https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap');
3
+ @import url('https://fonts.googleapis.com/css2?family=Gilda+Display&display=swap');
4
+
5
+ @import "tailwindcss";
6
+
7
+ @plugin "@tailwindcss/typography";
8
+
9
+ @theme {
10
+ --font-sans: "Source Sans", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
11
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
12
+ --font-gilda: "Gilda Display";
13
+ --font-main: var(--font-sans);
14
+ --color-border-main: var(--color-gray-400);
15
+ --color-primary: var(--color-blue-600);
16
+ }
17
+
18
+ .max-w-theme {
19
+ @apply max-w-6xl;
20
+ }
21
+
22
+ /* ************************************************************** */
23
+
24
+ /* Styles of basic HTML elements */
25
+ html {
26
+ @apply overflow-y-scroll;
27
+ }
28
+
29
+ em:not(li *) {
30
+ @apply block text-center
31
+ }
32
+
33
+ img:has(+ em) {
34
+ @apply mb-0;
35
+ }
36
+
37
+
38
+ .manual-h1 {
39
+ @apply text-2xl sm:text-4xl md:text-5xl lg:text-6xl;
40
+ }
41
+
42
+ /* Task List Styling — checkboxes visible, bullets removed, checked items green */
43
+ ul.task-list {
44
+ @apply list-none p-0 m-0 space-y-2;
45
+ /* remove bullets, vertical spacing */
46
+ }
47
+
48
+ ul.task-list li {
49
+ @apply flex items-center;
50
+ /* align checkbox and text */
51
+ }
52
+
53
+ ul.task-list li input[type="checkbox"] {
54
+ @apply mr-2;
55
+ /* spacing between checkbox and text */
56
+ }
57
+
58
+ /* Make checked tasks green */
59
+ ul.task-list li input[type="checkbox"]:checked + * {
60
+ @apply text-green-600 font-medium;
61
+ }
62
+
63
+ .main a {
64
+ @apply text-primary;
65
+ @apply no-underline;
66
+ }
67
+
68
+ /* All tables except ones inside .highlight */
69
+
70
+ .main table:not(.highlight table) {
71
+ @apply border-collapse border border-gray-200 text-left mb-4 min-w-full;
72
+
73
+ caption {
74
+ @apply text-sm font-semibold mb-2;
75
+ }
76
+
77
+ thead {
78
+ @apply bg-gray-100;
79
+ }
80
+
81
+ th {
82
+ @apply px-4 py-2 border-b border-gray-300 font-medium text-gray-700;
83
+ }
84
+
85
+ td {
86
+ @apply px-4 py-2 border-b border-gray-200 text-gray-600;
87
+ }
88
+
89
+ tbody tr:hover {
90
+ @apply bg-gray-50;
91
+ }
92
+
93
+ /* Optional: for color swatches or inner divs */
94
+
95
+ td div[data-theme] {
96
+ @apply w-12 aspect-square border border-gray-300;
97
+ }
98
+ }
99
+
100
+ .table-wrapper {
101
+ @apply overflow-x-auto mb-4;
102
+ }
103
+
104
+ /* ************************************************************** */
105
+
106
+ /* Code Highlighting styles */
107
+ :not(pre) > code {
108
+ @apply text-gray-600;
109
+ @apply bg-blue-50;
110
+ @apply px-1.5;
111
+ @apply py-0.5;
112
+ @apply rounded;
113
+ @apply font-light;
114
+ @apply font-main;
115
+ }
116
+
117
+ /* ************************************************************** */
118
+
119
+ /* Code Highlighting styles */
120
+ :not(pre) > code {
121
+ @apply text-gray-600;
122
+ @apply bg-blue-50;
123
+ @apply px-1.5;
124
+ @apply py-0.5;
125
+ @apply rounded;
126
+ @apply font-light;
127
+ @apply font-main;
128
+ }
129
+
130
+ /*
131
+ adds rounded corners, padding syntax and horizontal scroll bar to the code block
132
+ author: epigone707
133
+ */
134
+ pre.highlight {
135
+ padding: 7px;
136
+ /* cause a scrolling mechanism to be provided for overflowing boxes */
137
+ overflow-x: auto;
138
+ }
139
+
140
+ figure.highlight > pre {
141
+ padding: 7px;
142
+ overflow-x: auto;
143
+ }
144
+
145
+ /* Default highlight spacing */
146
+ .highlight {
147
+ border-radius: 5px;
148
+ @apply mb-2;
149
+ margin-top: 1rem; /* default */
150
+ }
151
+
152
+ /* Remove top margin if the highlight's parent is inside highlighter-rouge
153
+ AND the highlighter-rouge div is immediately after a paragraph */
154
+ p + .highlighter-rouge .highlight {
155
+ @apply mt-0;
156
+ }
157
+
158
+ .rouge-gutter {
159
+ @apply border-r border-gray-300 pr-2;
160
+ }
161
+
162
+ .rouge-code pre {
163
+ @apply pl-2;
164
+ /* optional: spacing so code doesn’t touch line */
165
+ }
166
+
167
+ .language-plaintext.highlighter-rouge {
168
+ position: relative; /* make outer div relative */
169
+ }
170
+
171
+ .language-plaintext.highlighter-rouge pre.highlight {
172
+ position: static; /* remove relative from inner pre */
173
+ }
174
+
175
+ /* for making copy button accessible in mobile and tablet */
176
+ .copy-button {
177
+ touch-action: manipulation; /* ensures the tap is recognized */
178
+ z-index: 10; /* above everything */
179
+ }
180
+
181
+ /* ************************************************************** */
182
+
183
+ /* Styles for Bibliography */
184
+ .bibliography {
185
+ @apply pl-0!;
186
+ }
187
+
188
+ .bibliography li {
189
+ @apply list-none!;
190
+ }
191
+
192
+ /* ************************************************************** */
193
+
194
+ /* Search utility styles */
195
+
196
+ @keyframes modal-overshoot {
197
+ 0% {
198
+ transform: scale(0.9);
199
+ opacity: 0;
200
+ }
201
+ 70% {
202
+ transform: scale(1.03);
203
+ opacity: 1;
204
+ }
205
+ 100% {
206
+ transform: scale(1);
207
+ }
208
+ }
209
+
210
+ .modal-animate {
211
+ animation: modal-overshoot 150ms ease-out;
212
+ }
213
+
@@ -0,0 +1,116 @@
1
+ .highlight table td { padding: 5px; }
2
+ .highlight table pre { margin: 0; }
3
+ .highlight, .highlight .w {
4
+ color: #c9d1d9;
5
+ background-color: #161b22;
6
+ }
7
+ .highlight .k, .highlight .kd, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kt, .highlight .kv {
8
+ color: #ff7b72;
9
+ }
10
+ .highlight .gr {
11
+ color: #f0f6fc;
12
+ }
13
+ .highlight .gd {
14
+ color: #ffdcd7;
15
+ background-color: #67060c;
16
+ }
17
+ .highlight .nb {
18
+ color: #ffa657;
19
+ }
20
+ .highlight .nc {
21
+ color: #ffa657;
22
+ }
23
+ .highlight .no {
24
+ color: #ffa657;
25
+ }
26
+ .highlight .nn {
27
+ color: #ffa657;
28
+ }
29
+ .highlight .sr {
30
+ color: #7ee787;
31
+ }
32
+ .highlight .na {
33
+ color: #7ee787;
34
+ }
35
+ .highlight .nt {
36
+ color: #7ee787;
37
+ }
38
+ .highlight .gi {
39
+ color: #aff5b4;
40
+ background-color: #033a16;
41
+ }
42
+ .highlight .ges {
43
+ font-weight: bold;
44
+ font-style: italic;
45
+ }
46
+ .highlight .kc {
47
+ color: #79c0ff;
48
+ }
49
+ .highlight .l, .highlight .ld, .highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx {
50
+ color: #79c0ff;
51
+ }
52
+ .highlight .sb {
53
+ color: #79c0ff;
54
+ }
55
+ .highlight .bp {
56
+ color: #79c0ff;
57
+ }
58
+ .highlight .ne {
59
+ color: #79c0ff;
60
+ }
61
+ .highlight .nl {
62
+ color: #79c0ff;
63
+ }
64
+ .highlight .py {
65
+ color: #79c0ff;
66
+ }
67
+ .highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm {
68
+ color: #79c0ff;
69
+ }
70
+ .highlight .o, .highlight .ow {
71
+ color: #79c0ff;
72
+ }
73
+ .highlight .gh {
74
+ color: #1f6feb;
75
+ font-weight: bold;
76
+ }
77
+ .highlight .gu {
78
+ color: #1f6feb;
79
+ font-weight: bold;
80
+ }
81
+ .highlight .s, .highlight .sa, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .se, .highlight .sh, .highlight .sx, .highlight .s1, .highlight .ss {
82
+ color: #a5d6ff;
83
+ }
84
+ .highlight .nd {
85
+ color: #d2a8ff;
86
+ }
87
+ .highlight .nf, .highlight .fm {
88
+ color: #d2a8ff;
89
+ }
90
+ .highlight .err {
91
+ color: #f0f6fc;
92
+ background-color: #8e1519;
93
+ }
94
+ .highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cp, .highlight .cpf, .highlight .c1, .highlight .cs {
95
+ color: #8b949e;
96
+ }
97
+ .highlight .gl {
98
+ color: #8b949e;
99
+ }
100
+ .highlight .gt {
101
+ color: #8b949e;
102
+ }
103
+ .highlight .ni {
104
+ color: #c9d1d9;
105
+ }
106
+ .highlight .si {
107
+ color: #c9d1d9;
108
+ }
109
+ .highlight .ge {
110
+ color: #c9d1d9;
111
+ font-style: italic;
112
+ }
113
+ .highlight .gs {
114
+ color: #c9d1d9;
115
+ font-weight: bold;
116
+ }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
Binary file
Binary file
@@ -0,0 +1,104 @@
1
+ // Adds a copy button to code blocks.
2
+ // It finds the code blocks and adds a button with capibility to copy the code into clipboard.
3
+
4
+ window.addEventListener("DOMContentLoaded", () => {
5
+
6
+ // Select all relevant code blocks
7
+ document.querySelectorAll(
8
+ "pre:has(table.rouge-table), figure.highlight > pre"
9
+ ).forEach(pre => {
10
+ // prevent duplicates
11
+ if (pre.querySelector(":scope > .copy-button")) return;
12
+
13
+ pre.classList.add("relative");
14
+
15
+ const button = document.createElement("button");
16
+ button.type = "button";
17
+ button.textContent = "Copy";
18
+ button.className =
19
+ "copy-button absolute top-2 right-2 px-2 py-1 text-xs " +
20
+ "bg-gray-600 text-white border-white border-1 rounded hover:bg-gray-700 cursor-pointer";
21
+
22
+ pre.appendChild(button);
23
+
24
+ button.addEventListener("click", async () => {
25
+ let text = "";
26
+
27
+ // Case 1 & 2: table inside pre/code
28
+ const table = pre.querySelector("table.rouge-table");
29
+ if (table) {
30
+ const codeCell = table.querySelector("td.code > pre, td.rouge-code > pre");
31
+ if (codeCell) text = codeCell.textContent;
32
+ }
33
+
34
+ // Case 3: plain code inside pre > code
35
+ if (!text) {
36
+ const code = pre.querySelector("code");
37
+ if (code) text = code.textContent;
38
+ }
39
+
40
+ if (!text) return;
41
+
42
+ try {
43
+ await navigator.clipboard.writeText(text);
44
+ button.textContent = "Copied!";
45
+ setTimeout(() => (button.textContent = "Copy"), 2000);
46
+ } catch (err) {
47
+ console.error("Failed to copy:", err);
48
+ }
49
+ });
50
+ });
51
+ });
52
+
53
+
54
+ window.addEventListener("DOMContentLoaded", () => {
55
+ document.querySelectorAll(".bibtex-toggle").forEach(button => {
56
+ button.addEventListener("click", () => {
57
+ const container = button.closest(".bib-entry");
58
+ if (!container) return;
59
+
60
+ const details = container.querySelector(".bibtex-details");
61
+ if (!details) return;
62
+
63
+ details.open = !details.open;
64
+ });
65
+ });
66
+ });
67
+
68
+ // Adds a copy button to BibTeX pre blocks inside details
69
+ window.addEventListener("DOMContentLoaded", () => {
70
+
71
+ // Select all pre blocks inside details (BibTeX)
72
+ document.querySelectorAll("details > pre").forEach(pre => {
73
+
74
+ // Prevent duplicates
75
+ if (pre.querySelector(":scope > .copy-button")) return;
76
+
77
+ pre.classList.add("relative");
78
+
79
+ // Create button
80
+ const button = document.createElement("button");
81
+ button.type = "button";
82
+ button.textContent = "Copy";
83
+ button.className =
84
+ "copy-button absolute top-2 right-2 px-2 py-1 text-xs " +
85
+ "bg-gray-600 text-white border-white border-1 rounded hover:bg-gray-700 cursor-pointer";
86
+
87
+ pre.appendChild(button);
88
+
89
+ // Copy event
90
+ button.addEventListener("click", async () => {
91
+ const text = pre.textContent; // grab all text inside pre
92
+ if (!text) return;
93
+
94
+ try {
95
+ await navigator.clipboard.writeText(text);
96
+ button.textContent = "Copied!";
97
+ setTimeout(() => (button.textContent = "Copy"), 2000);
98
+ } catch (err) {
99
+ console.error("Failed to copy:", err);
100
+ }
101
+ });
102
+ });
103
+
104
+ });
@@ -0,0 +1,12 @@
1
+ /* configures MathJax */
2
+
3
+ window.MathJax = {
4
+ tex: {
5
+ inlineMath: [['$', '$'], ['\\(', '\\)']],
6
+ displayMath: [['$$', '$$'], ['\\[', '\\]']],
7
+ processEscapes: true
8
+ },
9
+ svg: {
10
+ fontCache: 'global'
11
+ }
12
+ };
@@ -0,0 +1,9 @@
1
+ // Opening and closing the sandwich menu
2
+ document.addEventListener("DOMContentLoaded", function () {
3
+ const btn = document.getElementById("menu-btn");
4
+ const menu = document.getElementById("mobile-menu");
5
+
6
+ btn.addEventListener("click", function () {
7
+ menu.classList.toggle("hidden");
8
+ });
9
+ });
@@ -0,0 +1,99 @@
1
+ let pagefind;
2
+
3
+ // Helper: Load Pagefind
4
+ async function initPagefind() {
5
+ const mod = await import("/pagefind/pagefind.js");
6
+ await mod.init();
7
+ return mod;
8
+ }
9
+
10
+ // Helper: Show Centered Message (Placeholder or No Results)
11
+ function showPlaceholder(container, message = "Start typing to search...") {
12
+ container.classList.remove("space-y-4", "block");
13
+ container.classList.add("flex", "items-center", "justify-center", "h-full");
14
+ container.innerHTML = `<p class="text-sm text-gray-500 text-center">${message}</p>`;
15
+ }
16
+
17
+ // Helper: Render the Search Results
18
+ function renderResults(results, container) {
19
+ container.innerHTML = "";
20
+
21
+ if (results.length === 0) {
22
+ showPlaceholder(container, "No results found.");
23
+ return;
24
+ }
25
+
26
+ // Restore normal top-aligned layout
27
+ container.classList.remove("flex", "items-center", "justify-center", "h-full");
28
+ container.classList.add("space-y-4", "block");
29
+
30
+ results.forEach(result => {
31
+ const el = document.createElement("a");
32
+ el.href = result.url;
33
+ el.className = "block p-2 -mx-2 rounded hover:bg-gray-100 transition-colors";
34
+ el.innerHTML = `
35
+ <h3 class="text-blue-600 font-semibold hover:underline">${result.meta.title || "Untitled"}</h3>
36
+ <p class="text-sm text-gray-600">${result.excerpt}</p>
37
+ `;
38
+ container.appendChild(el);
39
+ });
40
+ }
41
+
42
+ // MAIN INITIALIZATION
43
+ document.addEventListener("DOMContentLoaded", async () => {
44
+ // 1. Grab all elements
45
+ const modal = document.getElementById("search-modal");
46
+ const openButtons = document.querySelectorAll(".search-open");
47
+ const input = document.getElementById("search-input");
48
+ const clearBtn = document.getElementById("search-clear");
49
+ const resultsContainer = document.getElementById("search-results");
50
+
51
+ // 2. Initialize Pagefind
52
+ pagefind = await initPagefind();
53
+
54
+ // 3. Modal Toggle Logic
55
+ openButtons.forEach(btn => {
56
+ btn.addEventListener("click", () => {
57
+ modal.classList.remove("hidden");
58
+ input.focus();
59
+ });
60
+ });
61
+
62
+ const closeModal = () => modal.classList.add("hidden");
63
+
64
+ modal.addEventListener("click", (e) => {
65
+ if (e.target === modal) closeModal();
66
+ });
67
+ document.addEventListener("keydown", (e) => {
68
+ if (e.key === "Escape") closeModal();
69
+ });
70
+
71
+ // 4. Search & Clear Button Logic
72
+ input.addEventListener("input", async (e) => {
73
+ const query = e.target.value.trim();
74
+
75
+ // Toggle "X" button visibility
76
+ clearBtn.classList.toggle("hidden", query === "");
77
+
78
+ if (!query) {
79
+ showPlaceholder(resultsContainer);
80
+ return;
81
+ }
82
+
83
+ // Perform Search
84
+ const search = await pagefind.search(query);
85
+ const results = await Promise.all(
86
+ search.results.slice(0, 10).map(r => r.data())
87
+ );
88
+
89
+ renderResults(results, resultsContainer);
90
+ });
91
+
92
+ // 5. Clear Button Click
93
+ clearBtn.addEventListener("click", () => {
94
+ input.value = "";
95
+ input.focus();
96
+ clearBtn.classList.add("hidden");
97
+ showPlaceholder(resultsContainer);
98
+ });
99
+ });
@@ -0,0 +1,15 @@
1
+ // Wrap tables in a scrollable container to fix right-side gap
2
+ window.addEventListener("DOMContentLoaded", () => {
3
+ document.querySelectorAll(".main table:not(.highlight table)").forEach(table => {
4
+ // skip if already wrapped
5
+ if (table.parentElement.classList.contains("table-wrapper")) return;
6
+
7
+ // create wrapper div
8
+ const wrapper = document.createElement("div");
9
+ wrapper.className = "table-wrapper overflow-x-auto mb-4";
10
+
11
+ // insert wrapper before the table and move table inside
12
+ table.parentNode.insertBefore(wrapper, table);
13
+ wrapper.appendChild(table);
14
+ });
15
+ });
@@ -0,0 +1,9 @@
1
+ // queries all elements that should not get prose attributes and adds a not-prose class to them.
2
+ // this is for elements who we don't have direct access to them
3
+ document.addEventListener("DOMContentLoaded", function () {
4
+ const preElements = document.querySelectorAll("pre");
5
+
6
+ preElements.forEach(function (pre) {
7
+ pre.classList.add("not-prose");
8
+ });
9
+ });