Skip to content

Commit b21bcba

Browse files
committed
Deploy to GitHub pages
0 parents  commit b21bcba

File tree

3,329 files changed

+95459
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,329 files changed

+95459
-0
lines changed

404.html

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Page not found | FullStack Bulletin</title><meta name="description" content="FullStack Bulletin (2017-2026). A farewell to our weekly newsletter for fullstack developers. Browse the full archive of 438 issues."><link rel="canonical" href="https://fullstackbulletin.com/404/"><!-- Google Fonts --><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&family=Space+Mono:wght@400&display=swap" rel="stylesheet"><!-- Favicons --><link rel="icon" type="image/x-icon" href="/favicon.ico"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><meta name="theme-color" content="#f8e81c"><!-- Open Graph --><meta property="og:type" content="website"><meta property="og:url" content="https://fullstackbulletin.com/404/"><meta property="og:title" content="Page not found | FullStack Bulletin"><meta property="og:description" content="FullStack Bulletin (2017-2026). A farewell to our weekly newsletter for fullstack developers. Browse the full archive of 438 issues."><meta property="og:image" content="https://fullstackbulletin.com/images/share-banner-facebook.jpg"><meta property="og:locale" content="en_US"><!-- Twitter --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@fstackbulletin"><meta name="twitter:title" content="Page not found | FullStack Bulletin"><meta name="twitter:description" content="FullStack Bulletin (2017-2026). A farewell to our weekly newsletter for fullstack developers. Browse the full archive of 438 issues."><meta name="twitter:image" content="https://fullstackbulletin.com/images/share-banner-facebook.jpg"><link rel="stylesheet" href="/_astro/Footer.CSlJtjA-.css"></head> <body> <header class="relative z-50" id="site-header" style="background: #000;"> <div class="max-w-6xl mx-auto px-4 py-1 md:py-4 huge:py-6 flex items-center justify-between transition-all duration-400 ease-in-out"> <a href="/" class="flex items-center gap-2 shrink-0"> <img src="/images/logo-minimal-white.svg" alt="FullStack Bulletin" class="w-[45px] md:hidden" id="header-logo-minimal"> <img src="/images/logo-white.svg" alt="FullStack Bulletin" class="hidden md:block w-[165px] huge:w-[210px]" id="header-logo-full"> </a> <nav class="flex items-center gap-4 font-heading text-sm" aria-label="Site navigation"> <div class="relative" id="search-widget"> <input type="text" id="search-input" placeholder="Search articles..." autocomplete="off" class="w-36 md:w-48 px-3 py-1.5 text-sm bg-neutral-900 text-neutral-white placeholder-neutral-medium rounded border border-neutral-700 focus:outline-none focus:ring-1 focus:ring-brand-primary focus:border-brand-primary transition-colors" aria-label="Search articles" aria-expanded="false" aria-controls="search-results" role="combobox"> <div id="search-results" class="hidden absolute top-full left-0 mt-1 w-80 max-h-96 overflow-y-auto bg-white rounded shadow-lg z-50 border border-neutral-200" role="listbox"></div> </div> <script>
2+
(function () {
3+
let pagefind = null;
4+
let debounceTimer;
5+
6+
const input = document.getElementById('search-input');
7+
const resultsContainer = document.getElementById('search-results');
8+
9+
async function loadPagefind() {
10+
if (!pagefind) {
11+
try {
12+
pagefind = await import('/pagefind/pagefind.js');
13+
await pagefind.init();
14+
} catch {
15+
// Pagefind not available (e.g. dev mode)
16+
return null;
17+
}
18+
}
19+
return pagefind;
20+
}
21+
22+
function showResults() {
23+
resultsContainer.classList.remove('hidden');
24+
input.setAttribute('aria-expanded', 'true');
25+
}
26+
27+
function hideResults() {
28+
resultsContainer.classList.add('hidden');
29+
input.setAttribute('aria-expanded', 'false');
30+
}
31+
32+
async function performSearch(query) {
33+
if (!query.trim()) {
34+
hideResults();
35+
resultsContainer.innerHTML = '';
36+
return;
37+
}
38+
39+
const pf = await loadPagefind();
40+
if (!pf) {
41+
resultsContainer.innerHTML =
42+
'<div class="px-4 py-3 text-sm text-neutral-500">Search is not available in dev mode.</div>';
43+
showResults();
44+
return;
45+
}
46+
47+
const search = await pf.search(query);
48+
49+
if (search.results.length === 0) {
50+
resultsContainer.innerHTML =
51+
'<div class="px-4 py-3 text-sm text-neutral-500">No results found.</div>';
52+
showResults();
53+
return;
54+
}
55+
56+
const resultData = await Promise.all(
57+
search.results.slice(0, 10).map(function (r) { return r.data(); })
58+
);
59+
60+
resultsContainer.innerHTML = resultData
61+
.map(function (item) {
62+
return '<a href="' + item.url + '" class="block px-4 py-3 hover:bg-neutral-100 border-b border-neutral-100 last:border-b-0 transition-colors" role="option">' +
63+
'<div class="font-heading text-sm font-semibold text-neutral-900 leading-snug">' + (item.meta && item.meta.title ? item.meta.title : 'Untitled') + '</div>' +
64+
(item.meta && item.meta.date ? '<div class="text-xs text-neutral-500 mt-0.5">' + item.meta.date + '</div>' : '') +
65+
(item.excerpt ? '<div class="text-xs text-neutral-600 mt-1 leading-relaxed">' + item.excerpt + '</div>' : '') +
66+
'</a>';
67+
})
68+
.join('');
69+
70+
showResults();
71+
}
72+
73+
input.addEventListener('focus', function () {
74+
loadPagefind();
75+
});
76+
77+
input.addEventListener('input', function () {
78+
clearTimeout(debounceTimer);
79+
debounceTimer = setTimeout(function () {
80+
performSearch(input.value);
81+
}, 200);
82+
});
83+
84+
document.addEventListener('click', function (e) {
85+
var widget = document.getElementById('search-widget');
86+
if (widget && !widget.contains(e.target)) {
87+
hideResults();
88+
}
89+
});
90+
91+
document.addEventListener('keydown', function (e) {
92+
if (e.key === 'Escape') {
93+
hideResults();
94+
input.blur();
95+
}
96+
});
97+
})();
98+
</script> <a href="/archive" class="hover:text-brand-dark font-semibold text-neutral-white">Archive</a> </nav> </div> </header> <main class="pt-8 pb-16 min-h-[60vh] flex items-center justify-center"> <div class="text-center px-4"> <h1 class="font-heading text-6xl md:text-8xl font-semibold text-neutral-darkest mb-4">404</h1> <p class="font-body text-lg text-neutral-dark mb-8">This page doesn't exist.</p> <a href="/" class="inline-block px-6 py-3 bg-neutral-darkest text-neutral-white no-underline rounded font-heading text-sm font-semibold hover:bg-neutral-dark transition-colors">
99+
Go home
100+
</a> </div> </main> <footer class="bg-black text-neutral-light py-12 px-4 md:px-10 border-t border-neutral-dark/20"> <div class="max-w-4xl mx-auto"> <div class="flex flex-col md:flex-row md:items-start md:justify-between gap-6"> <div> <a href="/" class="inline-block leading-none"> <img src="/images/logo-white.svg" alt="FullStack Bulletin" class="w-[130px] md:w-[150px]"> </a> <nav class="flex flex-wrap items-center gap-x-4 mt-4" aria-label="Footer navigation"> <a href="/archive" class="text-sm text-neutral-light hover:text-brand-primary transition-colors"> Archive </a><a href="https://loige.co" target="_blank" rel="noopener noreferrer" class="text-sm text-neutral-light hover:text-brand-primary transition-colors"> loige.co </a><a href="https://andreamangano.com" target="_blank" rel="noopener noreferrer" class="text-sm text-neutral-light hover:text-brand-primary transition-colors"> andreamangano.com </a> </nav> </div> <div class="md:text-right"> <p class="text-sm leading-relaxed">Made with passion and a bit of <a href="https://github.com/FullStackBulletin" target="_blank" class="underline hover:text-brand-primary transition-colors"><strong>automation</strong></a></p> <p class="mt-4 text-sm text-neutral-light flex items-center gap-1.5 md:justify-end">
101+
Curious how this site is built?
102+
<a href="https://github.com/FullStackBulletin/fullstackbulletin.com" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 text-brand-primary underline underline-offset-2 hover:text-brand-light transition-colors"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class aria-hidden="true"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg>
103+
Check out our public repo
104+
</a> </p> </div> </div> </div> </footer> </body></html>

_astro/Footer.CSlJtjA-.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

android-chrome-192x192.png

1013 Bytes

apple-touch-icon.png

1.83 KB
15.3 KB
27.1 KB
22.4 KB
122 KB
20.6 KB
46.2 KB

0 commit comments

Comments
 (0)