feat: Add a recipe book

Created a recipe section in the blog from existing markdown content.
This commit is contained in:
Matthew Binning 2026-01-01 17:48:00 -08:00
parent 5b25211618
commit d2421d41f3
5 changed files with 172 additions and 71 deletions

View file

@ -82,6 +82,44 @@
</article>
</div>
</section>
<!-- Recipes Section -->
<section class="content-section">
<h2>Recipes</h2>
<p class="section-description">Family recipes and culinary experiments.</p>
<div class="blog-grid">
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/st-patricks-day.html">St. Patrick's Day</a></h3>
<p class="blog-meta">Holiday</p>
<p>Traditional Irish recipes - corned beef, lamb stew, soda bread, and more.</p>
</article>
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/christmas.html">Christmas</a></h3>
<p class="blog-meta">Holiday</p>
<p>Holiday favorites including eggnog, gingerbread fruitcake, and meatloaf.</p>
</article>
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/earth-day.html">Earth Day</a></h3>
<p class="blog-meta">Special Event</p>
<p>Lamb stir fry and berry compote from April 2024.</p>
</article>
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/camping.html">Camping & Backpacking</a></h3>
<p class="blog-meta">Outdoor</p>
<p>Trail-ready recipes and energy bars for adventures.</p>
</article>
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/misc.html">Miscellaneous</a></h3>
<p class="blog-meta">Various</p>
<p>Drinks, snacks, sides, and external recipe links.</p>
</article>
<article class="blog-card">
<h3><a href="/blog/public/recipe-book/">Full Recipe Book</a></h3>
<p class="blog-meta">Index</p>
<p>Browse all recipe collections in one place.</p>
</article>
</div>
</section>
</main>
<!--#include virtual="/includes/footer.html" -->

45
common.nginx.nix Normal file
View file

@ -0,0 +1,45 @@
{ config, pkgs, lib, ... }:
{
# Common configuration shared between staging and prod
# This file contains nginx settings that are identical across environments
# Import this in both staging.nginx.nix and prod.nginx.nix
services.nginx = {
# Recommended settings
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
};
# Common location configurations that can be reused
# These are defined as library functions
lib.nginxLocations = {
# Standard root location with SSI support
rootLocation = {
index = "index.html";
tryFiles = "$uri $uri/ =404";
extraConfig = ''
# Enable Server Side Includes for navbar/footer includes
ssi on;
'';
};
# Private blog articles location with HTTP basic authentication
privateLocation = {
extraConfig = ''
auth_basic "Private Articles";
auth_basic_user_file /srv/nginx/.htpasswd;
# Enable Server Side Includes
ssi on;
'';
};
# Common extraConfig for custom 404
custom404 = ''
error_page 404 /404.html;
'';
};
}

View file

@ -2,6 +2,9 @@
set -e
# Common files to deploy (shared between staging and prod)
DEPLOY_FILES="blog includes index.html blog.html resume.html style.css 404.html"
# Usage information
usage() {
printf "Usage: %s [staging|prod]\n\n staging - Deploy to local staging environment (/srv/www/stage.binning.net)\n prod - Deploy to production server via SSH (www.binning.net)\n\nExample:\n %s staging\n %s prod\n" "$0" "$0" "$0"
@ -27,15 +30,7 @@ case $ENV in
# Deploy website files via rsync
printf "Deploying website files...\n"
sudo rsync -av --delete \
blog \
includes \
index.html \
blog.html \
resume.html \
style.css \
404.html \
${STAGING_PATH}/
sudo rsync -av --delete ${DEPLOY_FILES} ${STAGING_PATH}/
# Set proper ownership
sudo chown -R nginx:nginx ${STAGING_PATH}/
@ -50,8 +45,8 @@ case $ENV in
printf "Deploying to PRODUCTION environment...\n"
# SSH details
REMOTE_HOST="binning.net"
REMOTE_USER="matthew.binning"
REMOTE_HOST="crossbox"
REMOTE_USER="m3b"
REMOTE_PATH="/srv/www/binning.net"
REMOTE_NIXOS="/etc/nixos/"
@ -61,24 +56,21 @@ case $ENV in
fi
# Deploy website files via rsync over SSH
# Using just the host from SSH config without user@ prefix
printf "Deploying website files...\n"
rsync -avz --delete \
-e ssh \
blog \
includes \
index.html \
blog.html \
resume.html \
style.css \
404.html \
${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/
ssh ${REMOTE_HOST} "mkdir -p /tmp/${REMOTE_PATH}"
rsync -avz --delete ${DEPLOY_FILES} ${REMOTE_HOST}:/tmp/${REMOTE_PATH}/
# Set proper permissions and move config on remote server
ssh ${REMOTE_HOST} "sudo mv /tmp/${REMOTE_PATH} ${REMOTE_PATH} && \
sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \
printf 'Content deployed.\n'"
# Deploy nginx configuration
printf "Deploying nginx configuration...\n"
scp prod.nginx.nix ${REMOTE_USER}@${REMOTE_HOST}:/tmp/nginx.nix
scp prod.nginx.nix ${REMOTE_HOST}:/tmp/nginx.nix
# Set proper permissions and move config on remote server
ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo mv /tmp/nginx.nix ${REMOTE_NIXOS}nginx.nix && \
ssh ${REMOTE_HOST} "sudo mv /tmp/nginx.nix ${REMOTE_NIXOS}nginx.nix && \
sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \
printf 'Configuration deployed. Run sudo nixos-rebuild switch to activate.\n'"

View file

@ -3,8 +3,8 @@
<a href="/" class="nav-brand">Home</a>
<ul class="nav-menu">
<li><a href="/blog.html">Blog</a></li>
<li><a href="https://forgejo.binning.net" target="_blank">Git</a></li>
<li><a href="/resume.html">Resume</a></li>
<li><a href="https://forgejo.binning.net" target="_blank">Forgejo</a></li>
</ul>
</div>
</nav>

120
style.css
View file

@ -6,19 +6,20 @@
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
line-height: 1.6;
color: #333;
background-color: #f5f5f5;
font-family: 'Courier New', 'Courier', 'Monaco', 'Lucida Console', monospace;
line-height: 1.7;
color: #3e2723;
background-color: #f4ecd8;
}
/* Navbar Styles */
.navbar {
background-color: #2c3e50;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
background-color: #5d4037;
box-shadow: 0 2px 4px rgba(62, 39, 35, 0.3);
position: sticky;
top: 0;
z-index: 1000;
border-bottom: 2px solid #4e342e;
}
.nav-container {
@ -31,14 +32,14 @@ body {
}
.nav-brand {
color: #fff;
color: #f4ecd8;
text-decoration: none;
font-size: 1.5rem;
font-weight: bold;
}
.nav-brand:hover {
color: #3498db;
color: #d7ccc8;
}
.nav-menu {
@ -48,14 +49,14 @@ body {
}
.nav-menu a {
color: #fff;
color: #f4ecd8;
text-decoration: none;
font-size: 1rem;
transition: color 0.3s ease;
}
.nav-menu a:hover {
color: #3498db;
color: #d7ccc8;
}
/* Main Container */
@ -67,39 +68,41 @@ body {
/* Hero Section */
.hero {
background-color: #fff;
background-color: #efebe9;
padding: 3rem 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(62, 39, 35, 0.2);
margin-bottom: 2rem;
text-align: center;
border: 1px solid #d7ccc8;
}
.hero h1 {
font-size: 2.5rem;
color: #2c3e50;
color: #4e342e;
margin-bottom: 1rem;
}
.hero p {
font-size: 1.2rem;
color: #555;
color: #6d4c41;
}
/* Content Section */
.content-section {
background-color: #fff;
background-color: #efebe9;
padding: 2rem;
margin-bottom: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(62, 39, 35, 0.2);
border: 1px solid #d7ccc8;
}
.content-section h2 {
color: #2c3e50;
color: #4e342e;
font-size: 2rem;
margin-bottom: 1.5rem;
border-bottom: 3px solid #3498db;
border-bottom: 3px solid #8d6e63;
padding-bottom: 0.5rem;
}
@ -107,20 +110,21 @@ body {
.genealogy-blurb p {
margin-bottom: 1rem;
line-height: 1.8;
color: #555;
color: #5d4037;
}
.contact-info strong {
color: #2c3e50;
color: #4e342e;
}
/* Footer */
.footer {
background-color: #2c3e50;
color: #fff;
background-color: #5d4037;
color: #f4ecd8;
text-align: center;
padding: 2rem;
margin-top: 3rem;
border-top: 2px solid #4e342e;
}
.footer p {
@ -129,7 +133,7 @@ body {
/* Blog Styles */
.section-description {
color: #666;
color: #6d4c41;
font-style: italic;
margin-bottom: 1.5rem;
}
@ -142,55 +146,55 @@ body {
}
.blog-card {
background-color: #f9f9f9;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #faf8f3;
border: 1px solid #d7ccc8;
border-radius: 4px;
padding: 1.5rem;
transition: transform 0.2s ease, box-shadow 0.2s ease;
position: relative;
}
.blog-card:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(62, 39, 35, 0.25);
}
.blog-card h3 {
color: #2c3e50;
color: #4e342e;
margin-bottom: 0.5rem;
font-size: 1.3rem;
}
.blog-card h3 a {
color: #2c3e50;
color: #4e342e;
text-decoration: none;
transition: color 0.3s ease;
}
.blog-card h3 a:hover {
color: #3498db;
color: #6d4c41;
}
.blog-meta {
color: #999;
color: #8d6e63;
font-size: 0.9rem;
margin-bottom: 0.75rem;
}
.blog-card p {
color: #555;
color: #5d4037;
line-height: 1.6;
}
.blog-card.private {
border-color: #f39c12;
background-color: #fff9f0;
border-color: #a1887f;
background-color: #f5f5f0;
}
.private-badge {
display: inline-block;
background-color: #f39c12;
color: #fff;
background-color: #8d6e63;
color: #f4ecd8;
padding: 0.25rem 0.75rem;
border-radius: 4px;
font-size: 0.85rem;
@ -206,10 +210,10 @@ body {
}
.skill-category h3 {
color: #2c3e50;
color: #4e342e;
margin-bottom: 1rem;
font-size: 1.2rem;
border-bottom: 2px solid #3498db;
border-bottom: 2px solid #8d6e63;
padding-bottom: 0.5rem;
}
@ -220,7 +224,7 @@ body {
.skill-category li {
padding: 0.5rem 0;
color: #555;
color: #5d4037;
position: relative;
padding-left: 1.5rem;
}
@ -229,7 +233,7 @@ body {
content: "▸";
position: absolute;
left: 0;
color: #3498db;
color: #8d6e63;
font-weight: bold;
}
@ -242,13 +246,13 @@ body {
}
.experience-item h3 {
color: #2c3e50;
color: #4e342e;
font-size: 1.4rem;
margin-bottom: 0.5rem;
}
.job-meta {
color: #999;
color: #8d6e63;
font-size: 0.95rem;
margin-bottom: 1rem;
font-style: italic;
@ -260,16 +264,38 @@ body {
}
.experience-item li {
color: #555;
color: #5d4037;
margin-bottom: 0.5rem;
line-height: 1.7;
}
.experience-item p {
color: #555;
color: #5d4037;
line-height: 1.7;
}
/* Recipe Page Styles */
.recipe-card {
background-color: #faf8f3;
border: 1px solid #d7ccc8;
border-radius: 4px;
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.recipe-card h3 {
color: #4e342e;
border-bottom: 2px solid #8d6e63;
padding-bottom: 0.5rem;
margin-bottom: 1rem;
}
.recipe-year {
color: #8d6e63;
font-style: italic;
font-size: 0.9rem;
}
/* Responsive Design */
@media (max-width: 768px) {
.nav-container {