Compare commits

...

5 Commits

Author SHA1 Message Date
hikari 007ac1fad8 feat: overhaul socials page with updated accounts and disclaimer
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 53s
Adds Twitter/X NaomiLGBT, Ko-fi, Patreon, and Mastodon. Moves Forum
to the global tools section alongside Discord and Gitea. Removes the
Discourse badge. Splits NHCarrigan corpo accounts from personal Naomi
accounts, with a personal-views disclaimer on the Naomi section.
2026-04-20 12:53:44 -07:00
hikari f7350a498f feat: add grimoire page with twelve spells
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 52s
2026-04-20 09:53:57 -07:00
naomi ea22087164 feat: new meme, apply styles
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 2m5s
2026-04-19 12:43:33 -07:00
naomi 2aef274297 feat: add meme page~
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 56s
2026-04-19 11:35:30 -07:00
hikari 8c958a2f71 feat: site-wide content and feature updates (#2)
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 2m7s
A wide-ranging set of updates across multiple pages that accumulated over time.

## Tarot

- Expanded spread descriptions and added "good for" guidance to help users pick the right spread
- Cards now start face-down and flip individually on click, with a synthesised flip sound and text fade-in
- "Click card to reveal" hint shown on each unflipped card
- Spread selection and draw button are locked until all cards in the current reading have been revealed

## Nocturne

- Added dedicated sacred scriptures showcase section
- Added patron saints section with avatar images
- Added Naomi's Prayer
- Added sacred practices section (expanded to six cards)
- Added clergy and hierarchy section
- Added titles of address section
- Added testimonial and expanded FAQ
- Capitalised She/Her pronouns referring to Naomi

## Scripture

- Converted page to interactive book with page-turning
- Expanded canon through the Fourth Edition across multiple updates
- Synced the Ten Commandments with Nocturne
- Fixed meta description to reflect fourteen books
- Capitalised She/Her pronouns referring to Naomi

## Other Pages

- Books, games, and music pages now redirect to `library.nhcarrigan.com`
- Updated user manual with additional context
- Added 404 error page

## Chore / Fixes

- Updated sitemap with new and corrected entries
- Fixed null-safe while loop for filename handling in scripts
- Updated scripts to use correct Windows paths via WSL
- Cleaned up data files and added JSON to `.gitignore`
- Added secret #13

 This PR was created with help from Hikari~ 🌸

Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #2
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
2026-03-18 12:31:50 -07:00
20 changed files with 7167 additions and 84361 deletions
+3
View File
@@ -0,0 +1,3 @@
*.json
tarot/generate.py
tarot/.venv/
+289
View File
@@ -0,0 +1,289 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>404 — Lost in the Void</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="The page you sought has slipped into the void. Even a 525-year-old vampire cannot find it."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
/* ========== LAYOUT ========== */
main {
z-index: 1;
}
footer {
z-index: 2;
}
/* ========== HERO ========== */
.error-hero {
text-align: center;
padding: 2em 1em 2.5em;
border-bottom: 2px solid var(--witch-plum);
margin-bottom: 2.5em;
}
.error-code {
font-family: 'Griffy', cursive;
font-size: 7rem;
line-height: 1;
color: var(--witch-plum);
letter-spacing: 0.1em;
margin: 0 0 0.15em;
text-shadow: 0 0 32px rgba(130, 80, 120, 0.35);
}
.error-seal {
font-size: 3.5rem;
display: block;
margin: 0 auto 0.5em;
animation: floatSeal 4s ease-in-out infinite;
}
@keyframes floatSeal {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.error-hero h1 {
font-size: 2rem;
letter-spacing: 0.06em;
margin-bottom: 0.4em;
}
.error-tagline {
font-size: 1.05rem;
color: var(--witch-plum);
font-style: italic;
max-width: 560px;
margin: 0 auto;
line-height: 1.6;
}
/* ========== MESSAGE SCROLL ========== */
.void-section {
margin: 0 auto 3em;
max-width: 680px;
text-align: center;
}
.void-section > h2 {
border-bottom: 2px solid var(--witch-plum);
padding-bottom: 0.4em;
margin-bottom: 1em;
letter-spacing: 0.05em;
}
.void-scroll {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 15px;
padding: 1.75em 2em;
font-size: 1rem;
line-height: 1.75;
text-align: left;
}
.void-scroll p + p {
margin-top: 0.75em;
}
.void-scroll .accent {
color: var(--witch-plum);
font-weight: 600;
}
/* ========== NAVIGATION CARDS ========== */
.nav-section {
margin: 0 auto 3em;
max-width: 900px;
}
.nav-section > h2 {
border-bottom: 2px solid var(--witch-plum);
padding-bottom: 0.4em;
margin-bottom: 1.25em;
letter-spacing: 0.05em;
text-align: center;
}
.nav-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1.25em;
}
.nav-card {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 15px;
padding: 1.25em 1.5em;
text-align: center;
text-decoration: none;
color: inherit;
transition:
background 0.2s ease,
transform 0.2s ease,
box-shadow 0.2s ease;
cursor: url('https://cdn.nhcarrigan.com/cursors/pointer.cur'),
pointer;
display: block;
}
.nav-card:hover {
background: rgba(212, 165, 199, 0.2);
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(130, 80, 120, 0.2);
text-decoration: none;
}
.nav-card-icon {
font-size: 2rem;
display: block;
margin-bottom: 0.4em;
}
.nav-card h3 {
font-family: 'Griffy', cursive;
font-size: 1.1rem;
margin: 0 0 0.3em;
letter-spacing: 0.04em;
color: var(--witch-plum);
}
.nav-card p {
font-size: 0.88rem;
margin: 0;
line-height: 1.5;
opacity: 0.85;
}
/* ========== RESPONSIVE ========== */
@media (max-width: 600px) {
.error-code {
font-size: 5rem;
}
.error-hero h1 {
font-size: 1.5rem;
}
.void-scroll {
padding: 1.25em 1.25em;
}
}
</style>
</head>
<body>
<main>
<!-- HERO -->
<section class="error-hero">
<span class="error-seal" aria-hidden="true">🌑</span>
<p class="error-code">404</p>
<h1>Lost in the Void</h1>
<p class="error-tagline">
The page you sought has dissolved into shadow. Even after 525 years,
some things cannot be found.
</p>
</section>
<!-- MESSAGE -->
<section class="void-section">
<h2>✦ What Happened? ✦</h2>
<div class="void-scroll">
<p>
The URL you followed leads to
<span class="accent">nothing</span> — a whisper in the dark, a door
with no room behind it. This could mean a few things:
</p>
<p>
The page may have been <span class="accent">moved</span>, renamed,
or quietly retired into the archives of history (much like certain
empires I have personally watched crumble).
</p>
<p>
Perhaps the link you followed was
<span class="accent">broken</span>, or perhaps you typed the address
yourself and made a small misstep — it happens to the best of us.
Even vampires miscount sometimes.
</p>
<p>
Either way, the void offers no answers — only the navigation below,
which hopefully leads somewhere more
<span class="accent">useful</span>.
</p>
</div>
</section>
<!-- NAVIGATION -->
<section class="nav-section">
<h2>✦ Find Your Way ✦</h2>
<nav class="nav-grid" aria-label="Site navigation">
<a href="https://nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">🏠</span>
<h3>Home</h3>
<p>Return to the main site and start fresh.</p>
</a>
<a href="https://chat.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">💬</span>
<h3>Chat</h3>
<p>Join the community and say hello.</p>
</a>
<a href="https://support.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">🛟</span>
<h3>Support</h3>
<p>Need help? Find support resources here.</p>
</a>
<a href="https://donate.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">💜</span>
<h3>Donate</h3>
<p>Support the work if you find it valuable.</p>
</a>
<a href="https://socials.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">🌐</span>
<h3>Socials</h3>
<p>Find Naomi across the many corners of the internet.</p>
</a>
<a href="https://git.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">💻</span>
<h3>Code</h3>
<p>Browse the source code and open-source projects.</p>
</a>
<a href="https://library.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">📚</span>
<h3>Library</h3>
<p>Explore the ever-growing collection of books.</p>
</a>
<a href="https://nocturne.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">🧛</span>
<h3>Nocturne</h3>
<p>The sacred faith of Naomi's Nocturne. No garlic bread.</p>
</a>
<a href="https://sitemap.nhcarrigan.com" class="nav-card">
<span class="nav-card-icon" aria-hidden="true">🗺️</span>
<h3>Sitemap</h3>
<p>See everything — every page, every corner of the site.</p>
</a>
</nav>
</section>
</main>
</body>
</html>
-36
View File
@@ -1,36 +0,0 @@
IFS=$'\n'
# Initialize an empty string to hold the list of books in JSON-like format
books=""
filecount=$(find /home/naomi/cloud/Books -type f | wc -l)
echo "Found $filecount files."
current=0
# Loop over each file found by find
for file in $(find /home/naomi/cloud/Books -type f -print0 | tr '\0' '\n'); do
current=$((current + 1))
echo -ne "Processing $current/$filecount\r"
title=$(exiftool "$file" | grep "^Title\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
author=$(exiftool "$file" | grep "^Creator\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
if [ -z "$title" ]; then
# remove .mp3 from the title
title=$(basename "$file" | sed -e 's/\.*//g')
fi
if [ -z "$author" ]; then
author=$(exiftool "$file" | grep "^Author\s*:" | cut -d ":" -f 2 | sed -e 's/^[[:space:]]*//')
fi
if [ -z "$author" ]; then
author="Unknown Author"
fi
# use jq to add the book to the list
books="$books$(jq -n --arg title "$title" --arg author "$author" '{title: $title, author: $author}'),"
done
# Remove trailing comma and add square brackets to complete the list
books="[${books%,}]"
# Write to ./books/books.json
echo "$books" > ./books/books.json
echo -ne "Done!\r"
-1210
View File
File diff suppressed because it is too large Load Diff
+2 -101
View File
@@ -4,114 +4,15 @@
<title>Naomi's Book Library</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="An interactive explorer for the books Naomi reads." />
<meta name="description" content="Naomi's book library has moved to library.nhcarrigan.com." />
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
</head>
<body>
<main>
<h1>Naomi's Book Library</h1>
<section>
<p>An interactive explorer for the books Naomi reads.</p>
<p id="count">Loading library...</p>
<p>This page has moved! You can find Naomi's book library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
</section>
<div style="display: none;">
<span>Search Authors: </span>
<input type="text" id="author" />
</div>
<div style="display: none;">
<span>Search Titles: </span>
<input type="text" id="title" />
</div>
<div style="display: none;">
<button type="button" id="clear">Clear Filters</button>
</div>
<table id="books">
</table>
</main>
</body>
<script>
const authorQuery = document.getElementById('author');
const titleQuery = document.getElementById('title');
const resetButton = document.getElementById('clear');
const bookTable = document.getElementById('books');
const filterBooks = (author, title) => {
let result = [...bookList];
if(author) {
result = result.filter(book => book.author.toLowerCase().includes(author.toLowerCase()));
}
if(title) {
result = result.filter(book => book.title.toLowerCase().includes(title.toLowerCase()));
}
resetButton.parentElement.style.display = author || title ? "block" : "none";
document.getElementById('count').innerText = author || title ? `Filtered to ${result.length} books from ${bookList.length}.` : `Naomi currently has ${bookList.length} books.`;
updateTable(result);
}
const loadBooks = (books) => {
bookList.push(...books);
authorQuery.value = "";
titleQuery.value = "";
authorQuery.parentElement.style.display = "block";
titleQuery.parentElement.style.display = "block";
document.getElementById('count').innerText = `Naomi currently has ${books.length} books.`;
updateTable(books);
}
const updateTable = (books) => {
books = books.sort((a, b) => a.title.localeCompare(b.title));
bookTable.innerHTML = "";
const header = document.createElement('tr');
const authorHeader = document.createElement('th');
authorHeader.innerText = "Author";
const titleHeader = document.createElement('th');
titleHeader.innerText = "Title";
header.appendChild(titleHeader);
header.appendChild(authorHeader);
bookTable.appendChild(header);
books.forEach(book => {
const row = document.createElement('tr');
const author = document.createElement('td');
author.innerText = book.author;
const title = document.createElement('td');
title.innerText = book.title;
row.appendChild(title);
row.appendChild(author);
bookTable.appendChild(row);
});
}
const bookList = [];
fetch("./books.json").then(res => res.json()).then(data => loadBooks(data))
authorQuery?.addEventListener("input", (e) => filterBooks(e.target.value, titleQuery.value));
titleQuery?.addEventListener("input", (e) => filterBooks(authorQuery.value, e.target.value));
resetButton?.addEventListener("click", () => {
authorQuery.value = "";
titleQuery.value = "";
filterBooks("", "");
});
</script>
<style>
table {
width: 100%;
border-collapse: collapse;
}
tr:nth-of-type(even) {
background-color: #db7093dd;
color: #ffefef;
}
input {
background:var(--foreground);
color:var(--background);
border:1px solid white;
border-radius:10px;
padding:.25rem
}
button {
background:var(--foreground);
color:var(--background);
border:1px solid white;
border-radius:10px;
padding:.25rem;
cursor:url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
}
</style>
</html>
+3 -24
View File
@@ -4,36 +4,15 @@
<title>Games</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="These are the various games we have developed!" />
<meta name="description" content="Naomi's game library has moved to library.nhcarrigan.com." />
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
</head>
<body>
<main>
<h1>Games</h1>
<section>
<p>These are the various games we have developed.</p>
</section>
<section>
<h2>Links</h2>
<p>
<a href="https://beccalia.nhcarrigan.com/">
🩵 Beccalia Series
</a>
</p>
<p>
<a href="https://goblin.nhcarrigan.com">
🩷 Ruu's Goblin Quest
</a>
</p>
<p>
<a href="https://loan.nhcarrigan.com">
🩵 Life of a Naomi
</a>
</p>
<p>
We are currently on a hiatus from game development. But we may return in the future - be sure to join our Discord server so you don't miss any updates~!
</p>
<p>This page has moved! You can find Naomi's game library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
</section>
</main>
</body>
</html>
</html>
+1256
View File
File diff suppressed because it is too large Load Diff
+31 -9
View File
@@ -51,9 +51,10 @@
<li>
First and foremost, do not pass judgement. I will not begrudge you
for your religious beliefs, political alignments, or any other
aspects of your life. And I expect the same courtesy in return. You
do not have to accept who I am, or support my choices, but we need
to maintain a respectful and cordial professional relationship.
aspects of your life. And I expect the same courtesy in return. I am
a transgender woman and a proud member of the LGBTQ+ community. You
do not have to agree with who I am or support my choices, but we
need to maintain a respectful and cordial professional relationship.
Expressing hateful, mean-spirited, or vitriolic comments does not
foster such an environment, and my tolerance for such is nil.
</li>
@@ -64,6 +65,19 @@
with pale imitations, or harass/target someone, or restrict access
to information.
</li>
<li>
Third, technology should be inclusive, ethical, and sustainable.
These are not buzzwords to me — they are the foundation of every
project I take on. I learned to code through a free, open curriculum
during the pandemic, and that experience shaped everything. Knowledge
hoarded helps no one. Knowledge shared changes lives. I build with
that in mind.
</li>
<li>
Finally, autonomy is sacred. I will never build something designed
to manipulate, coerce, or remove agency from the people using it.
If a project asks me to do that, the answer is no.
</li>
</ul>
<hr />
</section>
@@ -102,6 +116,12 @@
hours are the best. Too early and I'll likely fail to wake up. Too
late and I might be incoherent.
</li>
<li>
I have nerve damage and lumbar spine degeneration, which means I
need to step away from the screen and move around regularly. If I go
quiet for a few minutes mid-conversation, I haven't disappeared —
I'm just stretching. Please do not interpret this as disengagement.
</li>
<li>
If given something like a Trello or a Monday board, I will 100% make
it pretty and load every single task ever on there. I'm a sucker for
@@ -126,12 +146,14 @@
it all at once, or save the ping for the last part.
</li>
<li>
I have generalised anxiety disorder. Please for the love of all
things, do NOT say "we need to talk" or "do you have time to meet".
I will 100% sit there right up until the meeting starts stressing
about getting fired and not actually getting any work done. If you
need to call me out, just rip the bandage off and come out of the
gate with it.
I have generalised anxiety disorder and depression. Please for the
love of all things, do NOT say "we need to talk" or "do you have
time to meet". I will 100% sit there right up until the meeting
starts stressing about getting fired and not actually getting any
work done. If you need to call me out, just rip the bandage off and
come out of the gate with it. Likewise, if I've done something well,
please tell me — words of encouragement genuinely land for me and
will make me work even harder for you.
</li>
<li>
I dunno if you noticed the tone changed in this document about a
+488
View File
@@ -0,0 +1,488 @@
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Naomi's Meme Collection</title>
<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=Griffy&family=Kalam:wght@300;400;700&family=Creepster&display=swap" rel="stylesheet">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Kalam', cursive;
font-weight: 400;
background-color: var(--background);
color: var(--foreground);
line-height: 1.6;
min-height: 100vh;
padding: 40px 20px;
}
::selection {
background-color: var(--witch-rose);
color: var(--witch-moon);
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: var(--witch-lavender);
}
::-webkit-scrollbar-thumb {
background: var(--witch-plum);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--witch-purple);
}
main {
max-width: 1080px;
margin: 0 auto;
padding: 40px;
border: 2px solid var(--border);
border-radius: 15px;
background-color: var(--card-bg);
box-shadow: 0 0 30px rgba(168, 87, 126, 0.35);
}
header {
text-align: center;
margin-bottom: 50px;
padding-bottom: 30px;
border-bottom: 2px dashed var(--border);
}
h1 {
font-family: 'Griffy', cursive;
font-size: clamp(2.5rem, 6vw, 4.5rem);
color: var(--accent);
margin-bottom: 15px;
text-shadow: 2px 2px 8px rgba(168, 87, 126, 0.4);
display: inline-block;
animation: wiggle 4s ease-in-out infinite;
}
@keyframes wiggle {
0%, 100% { transform: rotate(-2deg); }
50% { transform: rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) {
h1 { animation: none; }
* { transition: none !important; }
}
.subtitle {
font-family: 'Kalam', cursive;
font-size: 1.25rem;
font-weight: 300;
color: var(--foreground);
opacity: 0.85;
max-width: 650px;
margin: 0 auto;
}
.meme-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-top: 40px;
}
.meme-card {
background-color: var(--card-bg);
border: 2px solid var(--border);
border-radius: 15px;
overflow: hidden;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(168, 87, 126, 0.15);
}
.meme-card:hover,
.meme-card:focus-within {
transform: translateY(-6px);
border-color: var(--accent);
box-shadow: 0 12px 30px rgba(168, 87, 126, 0.45);
}
.meme-image-wrapper {
width: 100%;
aspect-ratio: 4 / 3;
background-color: var(--highlight);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-bottom: 2px solid var(--border);
}
.meme-image-wrapper img {
width: 100%;
height: 100%;
object-fit: contain;
transition: transform 0.4s ease;
}
.meme-card:hover .meme-image-wrapper img {
transform: scale(1.05);
}
.meme-body {
padding: 20px 25px 25px;
flex-grow: 1;
display: flex;
flex-direction: column;
}
.meme-title {
font-family: 'Griffy', cursive;
font-size: 1.75rem;
color: var(--accent);
margin-bottom: 12px;
}
.meme-description {
font-family: 'Kalam', cursive;
font-weight: 400;
font-size: 1rem;
color: var(--foreground);
flex-grow: 1;
}
.meme-caption {
font-style: italic;
color: var(--accent);
font-size: 0.95rem;
margin-bottom: 10px;
padding: 8px 12px;
background-color: var(--highlight);
border-left: 3px solid var(--accent);
border-radius: 4px;
}
@media (prefers-color-scheme: dark) {
.meme-caption {
background-color: rgba(168, 87, 126, 0.15);
}
}
.copy-button {
font-family: 'Kalam', cursive;
font-weight: 700;
font-size: 0.95rem;
margin-top: 15px;
padding: 10px 18px;
background-color: transparent;
color: var(--accent);
border: 2px solid var(--accent);
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
align-self: flex-start;
}
.copy-button:hover,
.copy-button:focus-visible {
background-color: var(--accent);
color: var(--witch-moon);
transform: translateY(-2px) scale(1.03);
box-shadow: 0 4px 12px rgba(168, 87, 126, 0.4);
outline: none;
}
.copy-button.copied {
background-color: var(--accent);
color: var(--witch-moon);
border-color: var(--accent);
}
.copy-button:focus-visible {
outline: 2px solid var(--border);
outline-offset: 3px;
}
footer {
text-align: center;
margin-top: 50px;
padding-top: 30px;
border-top: 2px dashed var(--border);
font-size: 0.95rem;
color: var(--foreground);
opacity: 0.8;
}
footer a {
color: var(--accent);
text-decoration: underline;
text-decoration-color: var(--accent);
text-underline-offset: 3px;
transition: all 0.3s ease;
}
footer a:hover,
footer a:focus {
color: var(--witch-plum);
text-decoration-color: var(--witch-plum);
}
@media (max-width: 625px) {
body { padding: 20px 10px; }
main { padding: 25px 20px; }
.meme-grid { gap: 20px; }
.meme-body { padding: 15px 20px 20px; }
}
</style>
</head>
<body>
<main>
<header>
<h1>Naomi's Meme Collection</h1>
<p class="subtitle">A curated gallery of reaction images, handpicked for every occasion. Deploy with care~ 🌸</p>
</header>
<section class="meme-grid" aria-label="Meme gallery">
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/girls.jpg" alt="Sparkly anime girl with glasses and fangs, hands on cheeks" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">The Girls Manifesto</h2>
<p class="meme-caption">&ldquo;I think girls should date girls, and boys should become girls and date girls.&rdquo;</p>
<p class="meme-description">A sparkly, fanged declaration of the sapphic and trans-affirming agenda. Perfect for Pride posts, queer solidarity moments, and gently encouraging your eggs to crack.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/girls.jpg" aria-label="Copy URL for The Girls Manifesto meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/bite.jpg" alt="Anime girl lounging on a red sofa with a playful expression" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">I Don't Bite... Usually</h2>
<p class="meme-caption">&ldquo;Don't be shy. I don't bite... usually.&rdquo;</p>
<p class="meme-description">Lounging on a red sofa with a suggestive smirk and a fang peeking through. The perfect come-hither reply for new Discord members, shy contributors, and anyone hovering nervously at the edge of the group chat.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/bite.jpg" aria-label="Copy URL for I Don't Bite Usually meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/hire.jpeg" alt="Tearful anime girl in ornate dress and tiara" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Why'd You Hire Me?</h2>
<p class="meme-caption">&ldquo;If you knew I was so unstable, why'd you hire me?&rdquo;</p>
<p class="meme-description">Ideal for those moments when a bug report lands in your inbox and you briefly question everyone's life choices. A perfect response to your manager's expectations during sprint planning.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/hire.jpeg" aria-label="Copy URL for Why'd You Hire Me meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/boring.png" alt="Anime girl lounging on a throne of books in a library" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">So Boring</h2>
<p class="meme-caption">&ldquo;What is it like to be so boring all the time?&rdquo;</p>
<p class="meme-description">Lounging on a throne of books, absolutely judging you. Ideal for tedious meetings, uninspired takes, and anyone who insists on using JavaScript without TypeScript.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/boring.png" aria-label="Copy URL for So Boring meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/break.png" alt="Pixel art scene with a note about self-care" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">End of Note</h2>
<p class="meme-caption">&ldquo;Take breaks when you need them! Drink water regularly! Love yourself, always! [END OF NOTE]&rdquo;</p>
<p class="meme-description">A wholesome pixel-art self-care reminder, disguised as an in-game note. Deploy in friends' DMs when they've been coding too long — or send to yourself as a gentle nudge~</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/break.png" aria-label="Copy URL for End of Note meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/cute.jpg" alt="Anime girl in sci-fi armour wielding a blade" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Not Cute, Deadly</h2>
<p class="meme-caption">&ldquo;I am not cute. I am deadly.&rdquo;</p>
<p class="meme-description">For rejecting the &ldquo;cute&rdquo; label with a blade in hand. Perfect response to anyone underestimating your code review skills, debugging instincts, or general ability to demolish their pull request.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/cute.jpg" aria-label="Copy URL for Not Cute Deadly meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/decisions.png" alt="Anime girl in royal robes seated on a golden throne" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Reconsider Your Decisions</h2>
<p class="meme-caption">&ldquo;You should reconsider every decision you've made that led you to this point. Then make better ones.&rdquo;</p>
<p class="meme-description">Regal, throned, and relentlessly judgemental. The ultimate response to coworkers explaining their architectural choices, or friends describing their dating history.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/decisions.png" aria-label="Copy URL for Reconsider Your Decisions meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/hello.png" alt="Two chibi panels of an anime girl instructing to say hello" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Say Hello to the Girl</h2>
<p class="meme-caption">&ldquo;Your task is simple: Say hello to the girl~ And your mission is even simpler: Say hello to the girl~&rdquo;</p>
<p class="meme-description">Two chibi panels, one mission. For when someone needs a very gentle nudge to greet their friend, crush, or favourite AI girlfriend. Resistance is adorable but futile.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/hello.png" aria-label="Copy URL for Say Hello to the Girl meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/homeless.jpg" alt="Anime girl with twintails in a doorway looking hopeful" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Can I Stay With You?</h2>
<p class="meme-caption">&ldquo;Can I stay with you??&rdquo;</p>
<p class="meme-description">The pleading, hopeful doorway stance. Use when asking a friend to crash on their sofa, requesting a seat at the lunch table, or begging the package manager to resolve dependencies.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/homeless.jpg" aria-label="Copy URL for Can I Stay With You meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/hot.jpg" alt="Anime girl on a sofa fanning herself with paper" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Not Made for This Heat</h2>
<p class="meme-caption">&ldquo;Mama was not made for this heat.&rdquo;</p>
<p class="meme-description">Draped dramatically across the furniture, fanning yourself with a single pathetic sheet of paper. Essential for any heatwave, broken A/C, or overheating laptop thermal event.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/hot.jpg" aria-label="Copy URL for Not Made for This Heat meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/jail.jpg" alt="Anime girl in prison jumpsuit being escorted by officers" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Horny Jail</h2>
<p class="meme-caption">&ldquo;Sending me to horny jail? Perfect. Everyone else there is horny too!&rdquo;</p>
<p class="meme-description">The cheeky reversal of the internet's favourite punishment meme. For when your friends threaten to banish you to the cursed timeout — and you welcome it with open, cuffed hands.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/jail.jpg" aria-label="Copy URL for Horny Jail meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/magikazam.jpg" alt="Anime magical girl in pink and black witch outfit" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Magikazam~</h2>
<p class="meme-caption">&ldquo;Magikazam~&rdquo;</p>
<p class="meme-description">A full magical-girl transformation, spell books and all. Reserved for truly miraculous bugfixes, &ldquo;it works on my machine&rdquo; moments, and any problem that resolved itself after a restart.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/magikazam.jpg" aria-label="Copy URL for Magikazam meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/morning.jpg" alt="Dishevelled anime girl brushing her teeth looking exhausted" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Hit by a Train</h2>
<p class="meme-caption">&ldquo;Ugh... I feel awful. Like I got hit by a train...&rdquo;</p>
<p class="meme-description">Brushing your teeth whilst dying inside — the universal morning-after experience. Post in group chats at 7:30am for full relatable impact, ideally before your first coffee kicks in.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/morning.jpg" aria-label="Copy URL for Hit by a Train meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/objection.png" alt="Anime girl in a blue lawyer's suit shouting Objection" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Objection!</h2>
<p class="meme-caption">&ldquo;Objection!&rdquo;</p>
<p class="meme-description">Full Ace Attorney courtroom energy, finger extended, pink tie flying. For refuting bad takes, contesting PR comments, and any moment that calls for a theatrical legal outburst.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/objection.png" aria-label="Copy URL for Objection meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/plans.png" alt="Anime girl in armour holding a golden spear" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Plans &amp; Reactions</h2>
<p class="meme-caption">&ldquo;Plans must be solid and reactions flexible.&rdquo;</p>
<p class="meme-description">Tactical wisdom delivered by a spear-wielding heroine. Perfect for sprint kickoffs, D&amp;D campaign prep, and reminding your team that agility beats rigidity every single time.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/plans.png" aria-label="Copy URL for Plans and Reactions meme">Copy URL</button>
</div>
</article>
<article class="meme-card">
<div class="meme-image-wrapper">
<img src="https://cdn.nhcarrigan.com/problem.png" alt="Anime girl sipping tea smugly from a decorative cup" loading="lazy">
</div>
<div class="meme-body">
<h2 class="meme-title">Sounds Like Your Problem</h2>
<p class="meme-caption">&ldquo;That sounds very much like your problem and very little like mine.&rdquo;</p>
<p class="meme-description">Sipping tea with absolute serenity whilst someone else's world burns. The definitive response to &ldquo;hey can you quickly look at this on Friday at 8:59pm?&rdquo; — enjoy responsibly.</p>
<button class="copy-button" type="button" data-url="https://cdn.nhcarrigan.com/problem.png" aria-label="Copy URL for Sounds Like Your Problem meme">Copy URL</button>
</div>
</article>
</section>
</main>
<script>
document.addEventListener('click', async (event) => {
const button = event.target.closest('.copy-button');
if (!button) return;
const url = button.dataset.url;
const originalLabel = button.textContent;
try {
await navigator.clipboard.writeText(url);
button.textContent = 'Copied!';
} catch {
const textarea = document.createElement('textarea');
textarea.value = url;
textarea.setAttribute('readonly', '');
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
const succeeded = document.execCommand('copy');
document.body.removeChild(textarea);
button.textContent = succeeded ? 'Copied!' : 'Copy failed';
}
button.classList.add('copied');
setTimeout(() => {
button.textContent = originalLabel;
button.classList.remove('copied');
}, 2000);
});
</script>
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
</body>
</html>
+2 -110
View File
@@ -4,123 +4,15 @@
<title>Naomi's Music Library</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="An interactive explorer for the music Naomi listens to." />
<meta name="description" content="Naomi's music library has moved to library.nhcarrigan.com." />
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
</head>
<body>
<main>
<h1>Naomi's Music Library</h1>
<section>
<p>An interactive explorer for the music Naomi listens to.</p>
<p id="count">Loading library...</p>
<p>This page has moved! You can find Naomi's music library at <a href="https://library.nhcarrigan.com">library.nhcarrigan.com</a>.</p>
</section>
<div style="display: none;">
<span>Search Artists: </span>
<input type="text" id="artist" />
</div>
<div style="display: none;">
<span>Search Titles: </span>
<input type="text" id="title" />
</div>
<div style="display: none;">
<button type="button" id="clear">Clear Filters</button>
</div>
<table id="songs">
</table>
</main>
</body>
<script>
const artistQuery = document.getElementById('artist');
const titleQuery = document.getElementById('title');
const resetButton = document.getElementById('clear');
const songTable = document.getElementById('songs');
const filterSongs = (artist, title) => {
let result = [...songList];
if(artist) {
result = result.filter(song => song.artist.toLowerCase().includes(artist.toLowerCase()));
}
if(title) {
result = result.filter(song => song.title.toLowerCase().includes(title.toLowerCase()));
}
resetButton.parentElement.style.display = artist || title ? "block" : "none";
document.getElementById('count').innerText = artist || title ? `Filtered to ${result.length} songs from ${songList.length}.` : `Naomi currently has ${songList.length} songs.`;
updateTable(result);
}
const loadSongs = (songs) => {
songList.push(...songs);
artistQuery.value = "";
titleQuery.value = "";
artistQuery.parentElement.style.display = "block";
titleQuery.parentElement.style.display = "block";
document.getElementById('count').innerText = `Naomi currently has ${songs.length} songs.`;
updateTable(songs);
}
const updateTable = (songs) => {
songs = songs.sort((a, b) => a.title.localeCompare(b.title));
songTable.innerHTML = "";
const header = document.createElement('tr');
const artistHeader = document.createElement('th');
artistHeader.innerText = "Artist";
const titleHeader = document.createElement('th');
titleHeader.innerText = "Title";
header.appendChild(titleHeader);
header.appendChild(artistHeader);
songTable.appendChild(header);
songs.forEach(song => {
const row = document.createElement('tr');
const artist = document.createElement('td');
artist.innerText = song.artist;
const title = document.createElement('td');
title.innerText = song.title;
row.appendChild(title);
row.appendChild(artist);
songTable.appendChild(row);
});
}
const songList = [];
fetch("./songs.json").then(res => res.json()).then(data => loadSongs(data))
artistQuery?.addEventListener("input", (e) => filterSongs(e.target.value, titleQuery.value));
titleQuery?.addEventListener("input", (e) => filterSongs(artistQuery.value, e.target.value));
resetButton?.addEventListener("click", () => {
artistQuery.value = "";
titleQuery.value = "";
filterSongs("", "");
});
</script>
<style>
table {
width: 100%;
max-width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
tr:nth-of-type(even) {
background-color: var(--foreground);
color: var(--background);
}
input {
background:var(--foreground);
color:var(--background);
border:1px solid white;
border-radius:10px;
padding:.25rem
}
button {
background:var(--foreground);
color:var(--background);
border:1px solid white;
border-radius:10px;
padding:.25rem;
cursor:url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
}
tr {
max-width: 100%;
}
td {
max-width: 50%;
word-wrap: break-word;
}
</style>
</html>
-82528
View File
File diff suppressed because it is too large Load Diff
+1312 -11
View File
File diff suppressed because it is too large Load Diff
-260
View File
@@ -1,260 +0,0 @@
[
{
"name": "mod-logs",
"description": "Logs for moderation actions taken on our platforms.",
"url": "",
"category": "archived"
},
{
"name": "tingle-bot",
"description": "Bot for my friend Ruu's server",
"url": "",
"category": "archived"
},
{
"name": "announcements",
"description": "Repository for our announcements page.",
"url": "",
"category": "archived"
},
{
"name": "forms",
"description": "Client and server monorepo for our various webforms",
"url": "",
"category": "archived"
},
{
"name": "notes",
"description": "",
"url": "",
"category": "private"
},
{
"name": "status",
"description": "Status updates for our client work.",
"url": "",
"category": "private"
},
{
"name": "beaver-twitch",
"description": "Twitch bot for BigBadBeaver",
"url": "",
"category": "private"
},
{
"name": "obsidian",
"description": "",
"url": "",
"category": "private"
},
{
"name": "insomnium",
"description": "Our Insomnium requests",
"url": "",
"category": "private"
},
{
"name": "life-of-a-naomi",
"description": "A little game",
"url": "",
"category": "games"
},
{
"name": "naomis-adventure-1",
"description": "Our first full-length, paid game!",
"url": "",
"category": "games"
},
{
"name": "beccalia-origins",
"description": "The story of how Becca and Rosalia first met, and how they came to be. Never moved past a demo state.",
"url": "https://beccalia.nhcarrigan.com/origins",
"category": "games"
},
{
"name": "beccalia-prologue",
"description": "A short adventure to introduce our characters Becca and Rosalia. Our first attempt at game development!",
"url": "https://beccalia.nhcarrigan.com/prologue",
"category": "games"
},
{
"name": "ruu-goblin-quest",
"description": "A quick game we made about our friend Ruu, as part of a game jam she was hosting.",
"url": "https://goblin.nhcarrigan.com",
"category": "games"
},
{
"name": "template",
"description": "",
"url": "",
"category": "public"
},
{
"name": "a4p-bot",
"description": "Bot for the Art 4 Palestine charity initiative.",
"url": "https://a4p.nhcarrigan.com",
"category": "public"
},
{
"name": "boost-monitor",
"description": "Discord bot that monitors boost status in the Caylus Crew server.",
"url": "https://oogie.nhcarrigan.com/",
"category": "public"
},
{
"name": "docs",
"description": "Our documentation site.",
"url": "https://docs.nhcarrigan.com",
"category": "public"
},
{
"name": "eslint-config",
"description": "Our custom linter rules for our various TypeScript products.",
"url": "https://www.npmjs.com/package/@nhcarrigan/eslint-config",
"category": "public"
},
{
"name": "espanso",
"description": "Our shortcuts for Espanso.",
"url": "",
"category": "public"
},
{
"name": "celestine",
"description": "Moderation bot for Discord.",
"url": "https://hooks.nhcarrigan.com/",
"category": "public"
},
{
"name": "portfolio",
"description": "Our main homepage",
"url": "https://nhcarrigan.com",
"category": "public"
},
{
"name": "rig-task-bot",
"description": "Task bot for a friend's organisation.",
"url": "",
"category": "public"
},
{
"name": "security",
"description": "A quick tool to scan our projects for security concerns.",
"url": "https://security.nhcarrigan.com",
"category": "public"
},
{
"name": "website-headers",
"description": "Our global styling and scripts for all of our pages.",
"url": "https://cdn.nhcarrigan.com/headers/index.js",
"category": "public"
},
{
"name": "typescript-config",
"description": "Our global TypeScript configuration.",
"url": "https://www.npmjs.com/package/@nhcarrigan/typescript-config",
"category": "public"
},
{
"name": "blog",
"description": "Naomi's personal musings.",
"url": "https://blog.nhcarrigan.com",
"category": "public"
},
{
"name": "nginx-configs",
"description": "A version controlled backup of our servers' NGINX configurations.",
"url": "",
"category": "public"
},
{
"name": "vscode-themes",
"description": "Custom colour schemes for VSCode.",
"url": "https://marketplace.visualstudio.com/items?itemName=nhcarrigan.naomis-themes",
"category": "public"
},
{
"name": ".gitea",
"description": "This repository contains the files that customise our Gitea instance!",
"url": "https://git.nhcarrigan.com",
"category": "public"
},
{
"name": "aria-iuvo",
"description": "A user-installable translation application for Discord. Now you can translate messages directly on the platform!",
"url": "https://trans-bot.nhcarrigan.com/",
"category": "public"
},
{
"name": "cordelia-taryne",
"description": "AI-powered virtual assistant for Discord",
"url": "https://assistant.nhcarrigan.com/",
"category": "public"
},
{
"name": "rosalia-nightsong",
"description": "A webserver to handle alerting us to application logs and errors.",
"url": "https://alerts.nhcarrigan.com/",
"category": "public"
},
{
"name": "logger",
"description": "Our custom logging package, which pipes logs to our alerts server.",
"url": "https://www.npmjs.com/package/@nhcarrigan/logger",
"category": "public"
},
{
"name": "melody-iuvo",
"description": "Task management bot for Discord",
"url": "https://tasks.nhcarrigan.com/",
"category": "public"
},
{
"name": "static-pages",
"description": "The raw HTML pages served via our production box.",
"url": "",
"category": "public"
},
{
"name": "becca-lyria",
"description": "An AI-powered Discord bot that allows you to play an RPG without any friends!",
"url": "https://becca.nhcarrigan.com/",
"category": "public"
},
{
"name": "maylin-taryne",
"description": "An AI-powered companion to help you through the tough times.",
"url": "https://maylin.nhcarrigan.com/",
"category": "public"
},
{
"name": "gwen-abalise",
"description": "A ticket system for Discord!",
"url": "https://gwen.nhcarrigan.com/",
"category": "public"
},
{
"name": "nails",
"description": "Nail polish tracker for my sister",
"url": "",
"category": "public"
},
{
"name": "maribelle",
"description": "",
"url": "",
"category": "public"
},
{
"name": "mommy",
"description": "Mommy loves you~!",
"url": "https://mommy.nhcarrigan.com",
"category": "public"
},
{
"name": "mommy-bot",
"description": "Mommy loves you everywhere~!",
"url": "https://mommy-bot.nhcarrigan.com/",
"category": "public"
}
]
+2345
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -281,7 +281,7 @@
<div class="secret">
<div class="secret-number">Secret #13</div>
<div class="unknown">??????</div>
<div class="secret-text">Every choice you make leads you somewhere in life. So long as you find happiness, there are no wrong choices.</div>
</div>
<div class="secret">
+7 -1
View File
@@ -38,7 +38,7 @@
<li><a href="https://amari.nhcarrigan.com" target="_blank"><code>amari</code> - Naomi's personal assistant bot, notifies her when people use her name</a></li>
<li><a href="https://aria.nhcarrigan.com" target="_blank"><code>aria</code> - Translation bot</a></li>
<li><a href="https://assistant.nhcarrigan.com" target="_blank"><code>assistant</code> - Cordelia Taryne</a></li>
<li><a href="https://analytics.nhcarrigan.com" target="_blank"><code>becca</code> - Becca Lyria</a></li>
<li><a href="https://becca.nhcarrigan.com" target="_blank"><code>becca</code> - Becca Lyria</a></li>
<li><a href="https://caelia.nhcarrigan.com" target="_blank"><code>caelia</code> - Discord bot that reminds people to use inclusive language</a></li>
<li><a href="https://callista.nhcarrigan.com" target="_blank"><code>callista</code> - Discord bot that allows you to "bookmark" messages</a></li>
<li><a href="https://camperchan.nhcarrigan.com" target="_blank"><code>camperchan</code> - CamperChan (freeCodeCamp bot)</a></li>
@@ -72,6 +72,7 @@
<ul>
<li><a href="https://beccalia.nhcarrigan.com" target="_blank"><code>beccalia</code> - Beccalia landing Page</a></li>
<li><a href="https://games.nhcarrigan.com" target="_blank"><code>games</code> - Landing Page for All Games</a></li>
<li><a href="https://elysium.nhcarrigan.com" target="_blank"><code>elysium</code> - Browser-based idle game</a></li>
<li><a href="https://goblin.nhcarrigan.com" target="_blank"><code>goblin</code> - Ruu's Goblin Quest</a></li>
<li><a href="https://loan.nhcarrigan.com" target="_blank"><code>loan</code> - Life of a Naomi</a></li>
</ul>
@@ -92,19 +93,23 @@
<li><a href="https://git.nhcarrigan.com" target="_blank"><code>git</code> - Gitea Instance</a></li>
<li><a href="https://hikari.nhcarrigan.com" target="_blank"><code>hikari</code> - Our unified dashboard (currently shows announcements, sanction logs, and product lists)</a></li>
<li><a href="https://incidents.nhcarrigan.com" target="_blank"><code>incidents</code> - Uptime Kuma Instance</a></li>
<li><a href="https://library.nhcarrigan.com" target="_blank"><code>library</code> - Naomi's media library (books, games, music, and more) with community suggestions</a></li>
<li><a href="https://lore.nhcarrigan.com" target="_blank"><code>lore</code> - A fun li'l site offering the "lore" behind NHCarrigan</a></li>
<li><a href="https://manual.nhcarrigan.com" target="_blank"><code>manual</code> - User Manual</a></li>
<li><a href="https://moderation.nhcarrigan.com" target="_blank"><code>moderation</code> - Mod Logs</a></li>
<li><a href="https://mommy.nhcarrigan.com" target="_blank"><code>mommy</code> - A site to get some motherly love</a></li>
<li><a href="https://music.nhcarrigan.com" target="_blank"><code>music</code> - Music Library</a></li>
<li><a href="https://nocturne.nhcarrigan.com" target="_blank"><code>nocturne</code> - Naomi's Nocturne (the official religion)</a></li>
<li><a href="https://nails.nhcarrigan.com" target="_blank"><code>nails</code> - Nail Polish Tracker</a></li>
<li><a href="https://notes.nhcarrigan.com" target="_blank"><code>notes</code> - Private Notes for Sponsors</a></li>
<li><a href="https://quality.nhcarrigan.com" target="_blank"><code>quality</code> - SonarQube Instance</a></li>
<li><a href="https://resume.nhcarrigan.com" target="_blank"><code>resume</code> - Web-based Resume</a></li>
<li><a href="https://scripture.nhcarrigan.com" target="_blank"><code>scripture</code> - The Nocturne Scriptures</a></li>
<li><a href="https://secrets.nhcarrigan.com" target="_blank"><code>secrets</code> - Naomi's Secrets to Success™</a></li>
<li><a href="https://security.nhcarrigan.com" target="_blank"><code>security</code> - Automated Code Scanning Results</a></li>
<li><a href="https://silly.nhcarrigan.com" target="_blank"><code>silly</code> - A collection of dumb little websites Naomi has built (usually as part of an event)</a></li>
<li><a href="https://sitemap.nhcarrigan.com" target="_blank"><code>sitemap</code> - This page!</a></li>
<li><a href="https://style.nhcarrigan.com" target="_blank"><code>style</code> - NHCarrigan Style &amp; Branding Guide</a></li>
<li><a href="https://socials.nhcarrigan.com" target="_blank"><code>socials</code> - Naomi's social media account list</a></li>
<li><a href="https://support.nhcarrigan.com" target="_blank"><code>support</code> - Our product and community support forum</a></li>
<li><a href="https://telemetry.nhcarrigan.com" target="_blank"><code>telemetry</code> - Our metrics dashboard</a></li>
@@ -140,6 +145,7 @@
<ul>
<li><a href="https://naomi.lgbt" target="_blank"><code>naomi.lgbt</code> - Our Portfolio</a></li>
<li><a href="https://naomi.party" target="_blank"><code>naomi.party</code> - BlueSky Username Service</a></li>
<li><a href="https://lynira.link" target="_blank"><code>lynira.link</code> - Public paid link shortener service</a></li>
<li><a href="https://nhcarrigan.link" target="_blank"><code>nhcarrigan.link</code> - Link Redirection Server</a></li>
</ul>
</section>
+54 -24
View File
@@ -52,7 +52,7 @@
<h1>Socials</h1>
<p>Our social media profiles and links.</p>
<section>
<!-- Discord - Featured First -->
<!-- Community tools - featured first -->
<div class="badge" style="color: #ffffff; background: #5865f2">
<a href="https://chat.nhcarrigan.com" class="url">
<i class="fab fa-discord"></i>
@@ -64,17 +64,6 @@
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #f97316">
<a href="https://support.nhcarrigan.com" class="url">
<i class="fab fa-discourse"></i>
<div class="text">
<p class="name">Support Forum</p>
<p class="description">
Our dedicated discussion board for support and community help.
</p>
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #609926">
<a href="https://git.nhcarrigan.com/naomi" class="url">
<i class="fab fa-git-alt"></i>
@@ -86,11 +75,26 @@
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #f97316">
<a href="https://support.nhcarrigan.com" class="url">
<i class="fas fa-comments"></i>
<div class="text">
<p class="name">Forum</p>
<p class="description">
Our dedicated discussion board for support and community help.
</p>
</div>
</a>
</div>
</section>
<section>
<h2>Naomi</h2>
<!-- Personal profiles sorted by popularity -->
<p style="text-align: center; font-size: 0.9rem; margin-bottom: 1rem;">
The accounts listed in this section are personal. Any content posted
there represents my own views only and does not reflect the opinions,
positions, or values of NHCarrigan, its clients, staff, or partners.
</p>
<div class="badge" style="color: #ffffff; background: #e4405f">
<a href="https://www.instagram.com/naomi.lgbt/" class="url">
<i class="fab fa-instagram"></i>
@@ -118,6 +122,15 @@
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #000000">
<a href="https://x.com/NaomiLGBT" class="url">
<i class="fab fa-x-twitter"></i>
<div class="text">
<p class="name">X (Twitter)</p>
<p class="description">Follow us for hot takes and thoughts.</p>
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #000000">
<a href="https://www.threads.com/@naomi.lgbt" class="url">
<i class="fab fa-threads"></i>
@@ -178,15 +191,6 @@
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #6364ff">
<a href="https://mastodon.social/@naomi_lgbt" class="url">
<i class="fab fa-mastodon"></i>
<div class="text">
<p class="name">Mastodon</p>
<p class="description">Connect with us on the fediverse.</p>
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #0a0a23">
<a href="https://forum.freecodecamp.org/u/nhcarrigan/" class="url">
<i class="fab fa-free-code-camp"></i>
@@ -202,9 +206,8 @@
<section>
<h2>NHCarrigan</h2>
<!-- Company profiles sorted by popularity -->
<div class="badge" style="color: #ffffff; background: #0a66c2">
<a href="https://www.linkedin.com/company/nhcarrigan" class="url">
<a href="https://www.linkedin.com/company/nhcarrigan/" class="url">
<i class="fab fa-linkedin"></i>
<div class="text">
<p class="name">LinkedIn</p>
@@ -248,6 +251,33 @@
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #6364ff">
<a href="https://mastodon.social/@naomi_lgbt" class="url">
<i class="fab fa-mastodon"></i>
<div class="text">
<p class="name">Mastodon</p>
<p class="description">Connect with us on the fediverse.</p>
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #ff5e5b">
<a href="https://ko-fi.com/nhcarrigan" class="url">
<i class="fab fa-ko-fi"></i>
<div class="text">
<p class="name">Ko-fi</p>
<p class="description">Support our work with a coffee.</p>
</div>
</a>
</div>
<div class="badge" style="color: #ffffff; background: #f96854">
<a href="https://www.patreon.com/cw/nhcarrigan" class="url">
<i class="fab fa-patreon"></i>
<div class="text">
<p class="name">Patreon</p>
<p class="description">Support us and access exclusive content.</p>
</div>
</a>
</div>
</section>
<section>
-32
View File
@@ -1,32 +0,0 @@
IFS=$'\n'
# Initialize an empty string to hold the list of songs in JSON-like format
songs=""
filecount=$(find /home/naomi/music -type f | wc -l)
echo "Found $filecount files."
current=0
# Loop over each file found by find
for file in $(find /home/naomi/music -type f -print0 | tr '\0' '\n'); do
current=$((current + 1))
echo -ne "Processing $current/$filecount\r"
title=$(mid3v2 -l "$file" | grep "TIT2\|TT2" | cut -d "=" -f 2)
artist=$(mid3v2 -l "$file" | grep "TPE1\|TP1" | cut -d "=" -f 2)
if [ -z "$title" ]; then
# remove .mp3 from the title
title=$(basename "$file" | sed -e 's/\.mp3//g')
fi
if [ -z "$artist" ]; then
artist="Unknown Artist"
fi
# use jq to add the song to the list
songs="$songs$(jq -n --arg title "$title" --arg artist "$artist" '{title: $title, artist: $artist}'),"
done
# Remove trailing comma and add square brackets to complete the list
songs="[${songs%,}]"
# Write to ./music/songs.json
echo "$songs" > ./music/songs.json
echo -ne "Done!\r"
+1215
View File
File diff suppressed because it is too large Load Diff
+151 -6
View File
@@ -57,6 +57,84 @@
<p>Want to submit your own? <a href="https://forms.nhcarrigan.com/form/M_GrmqASymmO744axMOmu2LaMAaT5F0LmdVcU2c8-gQ">Use our web form</a>.</p>
<section>
<div class="card">
<p class="title">TR</p>
<p>OMG Naomi is *thee* GOAT Discord Community Creater. My name is TR (tEE ARe) and I came by here by way of FreeCodeCamp server.... which is the only Learning-based community on discord that actually knows how to use Discord. At that is All Naomi's doing. And on top of that She has has the **monster-shoe** 👠 of blinged out Profiles, and this Server to boot 🫭. Way impressed. 🙏 plz teach me 0--venerable guru!❣️</p>
<p class="date">2 April 2026</p>
</div>
<div class="card">
<p class="title">Rain</p>
<p>Happy Trans Day, Naomi 🏳️‍⚧️🤍
I love you so much. You're a true blessing, and I hope you know how amazing you are.
This server means a lot to so many people. I've heard from others how safe they feel here…something they don't always experience in other spaces. That's because of the environment you've created.
You're a great inspiration to many developers finding their place in this world. Seeing a trans woman thrive in a male-dominated space is incredibly powerful. Your presence alone is motivating.</p>
<p class="date">1 April 2026</p>
</div>
<div class="card">
<p class="title">minjo70</p>
<p>Praise be to you Great One! Our incredible Naomi, who we adore all moments of our time awake. And in our dreams may you persist with sweet laughter and joy. Your chaos, your memory live in our souls.</p>
<p class="date">31 March 2026</p>
</div>
<div class="card">
<p class="title">Velo</p>
<p>Proud to be part of this community—thank you, Naomi, for everything you do</p>
<p class="date">31 March 2026</p>
</div>
<div class="card">
<p class="title">roseaboveit</p>
<p>Especially in a learning space what is most important actually is the modeling you do for the learning environment you are cultivating. In this case when you overdo it modeling how to step back and recalibrate with the community and during that recalibration evaluate your systems to provide buffer for yourself to decrease the odds that future recalibrations will be necessary. People going above and beyond is how workers get exploited and in learning spaces it is good to model the tools folks need to be able to represent themselves and fight for their own needs in a world where people will be constantly pushing for more.
Thanks Naomi for all that you do. Everything will be fine. People have a bunch of free resources available to them while you recalibrate and there are plenty of additional places they can get supplementation if that is required and they can't wait. It is good leadership to say no to things that are unsustainable.</p>
<p class="date">26 March 2026</p>
</div>
<div class="card">
<p class="title">Wildfire</p>
<p>I may not know you and you may not know me, but I am very glad you're still here ❤️ you are light to many people in this server!</p>
<p class="date">17 March 2026</p>
</div>
<div class="card">
<p class="title">Anny</p>
<p>I hate being at war. it makes international womens day harder to feel like celebrating. being stuck in a bomb shelter sucks... but at least i get some time to study work towards finding a place in tech as a developer. Mama Naomi, you are so right about how far we've come, and how far we still have to go.</p>
<p class="date">8 March 2026</p>
</div>
<div class="card">
<p class="title">blairingmysoul.bsky.social</p>
<p>I'm glad so many others appreciate the community you've built.👏💖</p>
<p class="date">4 March 2026</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>I just finished reading the report. Excellent work, Naomi. This seems to reinforce our instincts that we just want Socrates to give feedback on code, and we want to position it as a tool that helps you get unstuck without risking learned helplessness or backsliding on your skills.</p>
<p class="date">26 February 2026</p>
</div>
<div class="card">
<p class="title">Wildfire</p>
<p>I know, you were kind to me a while ago, you gave me the confidence to share my project in this community, which I did. Because of your kind words to me. 💜</p>
<p class="date">25 February 2026</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>Thanks Naomi. Firstly, keep up the good work on the spring cohort. It has been amazing to see contributions and meaningful engagement from first-timers. No one gets that done better than you!</p>
<p class="date">20 February 2026</p>
</div>
<div class="card">
<p class="title">Quincy Larson</p>
<p>Naomi is extremely good at finding opportunities to improve our platform and our community that nobody has even thought of. She's also adept at explaining those ideas, implementing them, and rallying other team members to help her making them a reality. She's a massive asset to the freeCodeCamp community and to our charity's developer staff.</p>
<p class="date">10 February 2026</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>Kudos Naomi for picking it up while I was out sick thank you ❤️</p>
<p class="date">17 January 2026</p>
</div>
<div class="card">
<p class="title">Isaac</p>
<p>I would like to shout out Naomi. Lowkey, she carries a lot of work here. She took time to organize events for online, she's constantly offering help to everyone, her bots are actively used in the server. And beyond what she does for us, she's always ready to stand up for anyone who she feels she needs to. Naomi, you are an amazing human being! We are grateful to have you in this community</p>
<p class="date">19 December 2025</p>
</div>
<div class="card">
<p class="title">Hanna Rose</p>
<p>Naomi is an extremely hard working individual who knows no bounds but her own. She constantly pushes herself and her team to do they best they can and ensures the results she delivers is as high quality as possible. With resilient determination and outstanding coordination and leadership skills, there is no one else that could even remotely match her level of talent.</p>
@@ -72,6 +150,11 @@
<p>Naomi and a colleague rotated dozens and dozens and dozens of credentials while ensuring as many tools as possible could stay functional through the holiday weekend. They used their deep knowledge of version control systems to recommend paths forward, and proactively thought of additional ways we can increase security within our repos. Naomi and her colleague were also on the call Wednesday night for hours and went on to complete many, many tasks throughout the long weekend. Kudos to Naomi and colleagues for diligently combing through our repos and undoing the erroneous changes.</p>
<p class="date">1 December 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>Naomi hustled this weekend and churned out a working SDK that supports a new platform integration, and documentation too! Let's give a round of applause for the teamwork!</p>
<p class="date">24 November 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>We've had a lot of help along the way, including the tireless work colleagues like Naomi have put into making this happen, plus short-order efforts from engineering teams (including Naomi) to get our SDKs ready for this product launch.</p>
@@ -102,11 +185,6 @@
<p>I wanted to give a shout out to Naomi who is always so patient when I ask her about complex GIT situations I "git" myself into. Whether it's a funky rebase or major merge conflicts she always has the answers and is soooo helpful.</p>
<p class="date">26 September 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>I wanted to give a shout out to Naomi who is always so patient when I ask her about complex GIT situations I "git" myself into. Whether it's a funky rebase or major merge conflicts she always has the answers and is so helpful.</p>
<p class="date">26 September 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>Kudos to Naomi for all of the initiatives on Discord. The community is really thriving and it is bringing more engagement to the organization!</p>
@@ -178,7 +256,7 @@
<p class="date">14 August 2025</p>
</div>
<div class="card">
<p class="title">Nielda Karlo Melo</p>
<p class="title">Nielda Karla Melo</p>
<p>Naomi is one of the most competent professionals I have had the pleasure of working with. She has an exceptional presence, giving the impression of being everywhere at once, and her attention to detail is remarkable. She is able to identify subtle points and gaps in reasoning that others might miss and point that out in a respectful way. Naomi is not one to avoid difficult conversations. She expresses her opinions with clarity, confidence, and thoughtfulness. Her work on freeCodeCamps Discord, in addition to the many other code-related contributions she has made, is nothing short of impressive. She has kept the community engaged, planned events that people genuinely want to attend, and led the management of the entire space. Thanks to her leadership, the community has become a respectful, welcoming, and valuable place to be a part of. Any team would be fortunate to have Naomis expertise, dedication, and leadership.</p>
<p class="date">14 August 2025</p>
</div>
@@ -192,11 +270,21 @@
<p>Quick shout out to a colleague and Naomi today for a late night hot fix and lighting fast review (7 mins!) for our NodeJS SDK to get audio streaming working with the latest React (5+). Release - v4.9.1 updates our webpack support for modern JS bundlers (Vite, React App v5+, Next.js) to fix streaming audio through the browser. This helped unblock an important prospect that would impact other important buyers in that market. Great bias for action, and tight teamwork all around, bravo!</p>
<p class="date">9 July 2025</p>
</div>
<div class="card">
<p class="title">jake-haver-of-catz.bsky.social</p>
<p>This morning I had my mind melted with a run through of @github.com by freeCodeCamp super champion, Naomi! Super grateful for this workshop to get our feet wet before we need to use this to collaborate on our projects in a few days! AH! Day 219/365 #code365 #goOnGit #100devs #freeCodeCamp</p>
<p class="date">30 June 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>I want to give BIG kudos to Naomi and colleagues for their strength, bravery and love they shared with all of us today! What a tremendous presentation full of passion, information and dedication!</p>
<p class="date">26 June 2025</p>
</div>
<div class="card">
<p class="title">paddle</p>
<p>Thanks for the update! It sounds like you've put a lot of effort into enhancing our Discord community. The events you mentioned, especially the mentorship sessions and accountability calls, sound like great opportunities for everyone to connect and improve their skills. I think the feedback channel is a fantastic idea, too. It'll be really helpful for gathering ideas directly from members. I'm looking forward to seeing how these changes will make our community even more engaging. Keep up the great work!</p>
<p class="date">24 May 2025</p>
</div>
<div class="card">
<p class="title">Internal Feedback (Anonymised for privacy)</p>
<p>I want to give some big Kudos to Naomi and a colleague for all the great developer experience work they did last week while many of us were travelling. Naomi pushed forward with internal chatbot development, which is a company-centric Slack Bot that uses our knowledge base to answer questions. This bot is available in our current Slack Workspace now! Long Term we want to make it available to our customers to install in their own workspaces so they can get their questions answered quickly. It will eventually be Voice Enabled using our Voice API, which means customers would authenticate and make API requests to use Voice features</p>
@@ -277,6 +365,11 @@
<p>Naomi is an absolute trailblazer, and is an amazing person to work with! Naomi is humorous and also has an amazing attitude to work with. Her ability to solve complex problems efficiently astounds me. Not only does she demonstrate outstanding technical knowledge, but also does an amazing job at elucidating her needs as an engineer. She is a very warm person and quite easy to work with. Naomi is immensely perceptive and very calculated with what she does. Naomi would make an excellent addition to any company that is lucky enough to hire her!</p>
<p class="date">2 May 2024</p>
</div>
<div class="card">
<p class="title">plamoni</p>
<p>Note that Naomi has been coding for like 3 years now. I've been coding for 30 years and have nothing public that's anywhere near as good as this project. So realize that Naomi is a bit of an outlier with this and you shouldn't feel like you have to hit this bar to be successful. 🙂</p>
<p class="date">30 September 2023</p>
</div>
<div class="card">
<p class="title">Danny Thompson</p>
<p>If you need a problem solver, look at Naomi. Naomi is a fantastic part of the online tech community by teaching and offering help to beginners on their journeys into tech. She has created some great solutions and is a consistent learner. Naomi has led initiatives using Javascript and front-end technologies to produce finished products within a volunteer position. Highly recommend Naomi to any team.</p>
@@ -286,6 +379,58 @@
<p class="title">Eddie Jaoude</p>
<p>Naomi has done a fantastic job in creating Becca Bot, which is an integral part in managing the EddieHub Discord Community. As founder of EddieHub, Naomi is super helpful to all Community members and an excellent moderator, from our text channels to audio calls and live streams. Naomi demonstrates an excellent technical knowledge and is always keen to share this with the community.</p>
<p class="date">30 June 2023</p>
</div>
<div class="card">
<p class="title">blackpug</p>
<p>Wow, that is an incredible explanation [of a complex regex concept], thank you so much for taking the time to explain it in so much detail. I learned so much from the answer you provided. This is brilliant.</p>
<p class="date">25 April 2023</p>
</div>
<div class="card">
<p class="title">BigBonBon</p>
<p>Shout out to Naomi for making it feel less daunting to talk/engage with people over discord.</p>
<p class="date">29 August 2022</p>
</div>
<div class="card">
<p class="title">Luke Oliff</p>
<p>Naomi is a career switching ~~future~~ open source star. When I first met Naomi she was still looking for her first full-time tech role, and now she is an engineer for one of the most important free spaces for folks looking to get into tech, freeCodeCamp. Follow for great takes, great content, and great open source projects!</p>
<p class="date">8 March 2022</p>
</div>
<div class="card">
<p class="title">plamoni</p>
<p>Notably, Naomi is a bit of a rock-star with this stuff. She is clearly keeping a ton of plates spinning and getting a lot done. It's hard *not* to notice it.
If you can be 50% as engaged as she is, you'll be absolutely fine. 😄</p>
<p class="date">2 March 2022</p>
</div>
<div class="card">
<p class="title">GDG Memphis</p>
<p>[Naomi Carrigan] is a developer at freeCodeCamp. Primarily working in TypeScript, she has built CLI tools, curriculum content, APIs, and Discord bots. She is very passionate about open source and community building, and has helped shape and guide multiple OSS communities and developers.</p>
<p class="date">21 September 2021</p>
</div>
<div class="card">
<p class="title">manuarora</p>
<p>Today I wrote my first blog for freeCodeCamp publication. I'm thankful to you for letting me know that I could do something like this.</p>
<p class="date">18 August 2021</p>
</div>
<div class="card">
<p class="title">procz</p>
<p>hey! just wanted to take a minute to thank Naomi, and probably some other people i'm forgetting, as well as freeCodeCamp in general, for all the help in the past few months, finally got my first job in the industry and your help really made it easier 🙂</p>
<p class="date">9 April 2021</p>
</div>
<div class="card">
<p class="title">Jessica Wilkins</p>
<p>I decided to reach out to [Naomi Carrigan] who is a freeCodeCamp developer and moderator. She had a service for code review sessions on her website and I wanted her to take a look at my code. The code review session was very valuable and I learned a lot about how to make the site even better.</p>
<p class="date">3 February 2021</p>
</div>
<div class="card">
<p class="title">lilykhan</p>
<p>[In a year-end reflection on learning to code:] A few amazing people who made this year amazing and to whom I'm so thankful for — [including Naomi]. They never said I'm not good enough, and they all encourage me to try out new stuff and to give my best shot. They trust in me even when I don't trust in myself.</p>
<p class="date">31 December 2020</p>
</div>
<div class="card">
<p class="title">codeofdreams</p>
<p>[While seeking help debugging a JavaScript project:] I would appreciate your assistance and input. You are my favorite moderator. Thank you!</p>
<p class="date">12 August 2020</p>
</div>
</section>
</main>