diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml new file mode 100644 index 0000000..47c150a --- /dev/null +++ b/.forgejo/workflows/deploy.yaml @@ -0,0 +1,22 @@ +name: Build and Deploy + +on: + push: + branches: + - master + - develop + schedule: + - cron: '0 2 * * *' + +jobs: + deploy: + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build + run: nix shell nixpkgs#mdbook --command ./deploy.sh build + + - name: Deploy + run: nix shell nixpkgs#rsync --command ./deploy.sh local diff --git a/.gitignore b/.gitignore index 2858192..f66e219 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -blog/* +blog/ +src +content/* +example/* diff --git a/404.html b/404.html deleted file mode 100644 index 33c62f8..0000000 --- a/404.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - 404 - Page Not Found - - - - - -
-
-

404 - Page Not Found

-

The page you're looking for doesn't exist.

-
- -
-

What happened?

-

The page you requested could not be found. It may have been moved, deleted, or never existed.

-

← Go back to homepage

-
-
- - - - diff --git a/blog.html b/blog.html deleted file mode 100644 index 2c99c60..0000000 --- a/blog.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - Blog - WWW - - - - - -
-
-

Blog

-

Stories, adventures, and reflections from life's journey

-
- - -
-

The Copper Chronicle

-

Adventures and travels with Copper, exploring the beautiful outdoors.

-
-
-

Big Sur Adventure

-

April 2024

-

Exploring the stunning coastline and trails of Big Sur with Copper.

-
-
-

Dove Hunting

-

September 2024

-

A day in the field with friends, shotguns, and good company.

-
-
-

Shasta & Dunsmuir

-

September 2024

-

Mountain adventures in Northern California.

-
-
-
- - -
-

Life & Reflections

-

Personal thoughts and journeys on health, faith, and life.

-
-
-

Health Journey

-

Private Article

-

Reflections on physical and mental wellness.

- 🔒 Private -
-
-

Faith Journey

-

Private Article

-

Personal spiritual reflections and growth.

- 🔒 Private -
-
-
- - -
-

Events & Experiences

-

Special moments and memorable experiences.

-
-
-

DefCon

-

Private Article

-

Notes and reflections from DefCon.

- 🔒 Private -
-
-

Oktoberfest

-

Private Article

-

Celebrating traditions and community.

- 🔒 Private -
- -
-
- - -
-

Recipes

-

Family recipes and culinary experiments.

-
-
-

St. Patrick's Day

-

Holiday

-

Traditional Irish recipes - corned beef, lamb stew, soda bread, and more.

-
-
-

Christmas

-

Holiday

-

Holiday favorites including eggnog, gingerbread fruitcake, and meatloaf.

-
-
-

Earth Day

-

Special Event

-

Lamb stir fry and berry compote from April 2024.

-
- -
-

Miscellaneous

-

Various

-

Drinks, snacks, sides, and external recipe links.

-
- -
-
-
- - - - diff --git a/book.toml b/book.toml new file mode 100644 index 0000000..f5e7abf --- /dev/null +++ b/book.toml @@ -0,0 +1,19 @@ +[book] +title = "The Bin" +authors = ["Matthew Binning"] +language = "en" + +[build] +build-dir = "blog" + +[output.html] +default-theme = "rust" +smart-punctuation = true +git-repository-url = "https://forgejo.binning.net/matthew.binning/www" +edit-url-template = "https://forgejo.binning.net/matthew.binning/www/src/branch/main/{path}" +no-section-label = true +fold.enable = true +fold.level = 0 + +[output.html.search] +enable = true diff --git a/common.nginx.nix b/common.nginx.nix deleted file mode 100644 index 02a5c24..0000000 --- a/common.nginx.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ 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; - ''; - }; -} diff --git a/deploy.sh b/deploy.sh index 94fd863..f329ca7 100755 --- a/deploy.sh +++ b/deploy.sh @@ -2,83 +2,75 @@ 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" + printf "Usage: %s [build|staging|prod|local]\n\n build - Build the blog with mdbook\n staging - Deploy to local staging environment (/srv/www/stage.binning.net)\n prod - Deploy to production server via SSH (www.binning.net)\n local - Deploy directly to /srv/www/binning.net (used by Forgejo CI runner)\n\nExample:\n %s build\n %s staging\n %s prod\n %s local\n" "$0" "$0" "$0" "$0" "$0" exit 1 } -# Check if argument provided if [ $# -eq 0 ]; then - printf "Error: No environment specified\n" + printf "Error: No command specified\n" usage fi -ENV=$1 +CMD=$1 + +case $CMD in + build) + printf "Building blog with mdbook...\n" + [ -s src ] || ln -s /var/lib/www src + mdbook build + printf "✓ Build complete!\n" + ;; -case $ENV in staging) printf "Deploying to STAGING environment...\n" - + STAGING_PATH="/srv/www/stage.binning.net" - - # Create staging directory if it doesn't exist + sudo mkdir -p ${STAGING_PATH} - - # Deploy website files via rsync + printf "Deploying website files...\n" - sudo rsync -av --delete ${DEPLOY_FILES} ${STAGING_PATH}/ - - # Set proper ownership + sudo rsync -av --delete blog/ ${STAGING_PATH}/ + sudo chown -R nginx:nginx ${STAGING_PATH}/ - - # Copy nginx config - sudo cp -t /etc/nixos/ staging.nginx.nix - - printf "✓ Staging deployment complete!\n Files deployed to: %s\n Nginx config: /etc/nixos/staging.nginx.nix\n\nTo activate, update your NixOS configuration to import staging.nginx.nix\nand run: sudo nixos-rebuild switch\n" "${STAGING_PATH}" + + printf "✓ Staging deployment complete!\n Files deployed to: %s\n\nTo activate nginx, import staging.nginx.nix into your local NixOS config\nand run: sudo nixos-rebuild switch\n" "${STAGING_PATH}" ;; - + prod) printf "Deploying to PRODUCTION environment...\n" - - # SSH details + REMOTE_HOST="crossbox" - REMOTE_USER="m3b" + REMOTE_USER="brimlock" REMOTE_PATH="/srv/www/binning.net" - REMOTE_NIXOS="/etc/nixos/" - - # Check if SSH key is set up + if ! ssh -o BatchMode=yes -o ConnectTimeout=5 ${REMOTE_USER}@${REMOTE_HOST} exit 2>/dev/null; then printf "Warning: SSH connection test failed. Ensure SSH keys are configured.\nYou may be prompted for a password.\n" fi - - # Deploy website files via rsync over SSH - # Using just the host from SSH config without user@ prefix + printf "Deploying website files...\n" - 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} && \ + ssh ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p /tmp/blog-deploy" + rsync -avz --delete blog/ ${REMOTE_USER}@${REMOTE_HOST}:/tmp/blog-deploy/ + ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo rsync -avz --delete /tmp/blog-deploy/ ${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_HOST}:/tmp/nginx.nix - - # Set proper permissions and move config on remote server - 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'" - - printf "✓ Production deployment complete!\n\nSSH into %s and run: sudo nixos-rebuild switch\n" "${REMOTE_HOST}" + + printf "✓ Production deployment complete!\n\nNginx configuration is managed by the nixos-config flake (hosts/crossbox/nginx.nix).\n" ;; - + + local) + printf "Deploying locally to production path...\n" + + LOCAL_PATH="/srv/www/binning.net" + + printf "Deploying website files...\n" + rsync -av --delete blog/ ${LOCAL_PATH}/ + + printf "✓ Local deployment complete!\n Files deployed to: %s\n" "${LOCAL_PATH}" + ;; + *) - printf "Error: Invalid environment '%s'\n" "$ENV" + printf "Error: Invalid command '%s'\n" "$CMD" usage ;; esac diff --git a/includes/footer.html b/includes/footer.html deleted file mode 100644 index d78ea74..0000000 --- a/includes/footer.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/includes/navbar.html b/includes/navbar.html deleted file mode 100644 index 7286aa7..0000000 --- a/includes/navbar.html +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/index.html b/index.html deleted file mode 100644 index ae2384c..0000000 --- a/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - WWW - Personal Website - - - - - -
-
-

Welcome

-

This is my personal website and blog.

-
- -
-

About & Contact

-
-

Email: example@example.com

-

Feel free to reach out via email for any inquiries.

-
-
- -
-

Genealogy

-
-

I am interested in family history and genealogy. This website serves as a personal space to share stories, chronicles, and musings about life's journey, adventures, and family heritage.

-

The Copper Chronicle contains stories and memories from various trips and experiences. More to come as this site develops.

-
-
-
- - - - diff --git a/prod.nginx.nix b/prod.nginx.nix deleted file mode 100644 index d3f84ff..0000000 --- a/prod.nginx.nix +++ /dev/null @@ -1,151 +0,0 @@ -{ config, pkgs, lib, ... }: - -let - # Read multiple API keys from the secrets file at build time - # Note: This embeds the secrets in the Nix store, which is a trade-off - # Alternative: Keep secrets file and read via njs module or external auth service - secretsFile = "/srv/nginx/secrets"; - - # Read API keys from file (one key per line, will be evaluated at build time) - # If the file doesn't exist yet, this will fail - create it first - apiKeysRaw = builtins.readFile secretsFile; - apiKeys = lib.filter (k: k != "") (lib.splitString "\n" apiKeysRaw); - - # Generate map entries for each key - mapEntries = lib.concatMapStringsSep "\n " - (key: ''"Bearer ${key}" "authorized";'') - apiKeys; - -in -{ - services.nginx = { - enable = true; - - # Recommended settings - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - - # Increase bucket size for long Bearer tokens - mapHashBucketSize = 128; - - # Map directive to check Authorization header against multiple keys - appendHttpConfig = '' - # Check if the Authorization header matches any expected value - map $http_authorization $auth_status { - default "unauthorized"; - "" "no_auth"; - ${mapEntries} - } - ''; - - # Virtual hosts configuration - virtualHosts = { - - # Main website - Static HTML/CSS - "www.binning.net" = { - enableACME = true; - forceSSL = true; - - root = "/srv/www/binning.net"; - - locations."/" = { - index = "index.html"; - tryFiles = "$uri $uri/ =404"; - extraConfig = '' - # Enable Server Side Includes for navbar/footer includes - ssi on; - ''; - }; - - # Private blog articles with HTTP basic authentication - locations."/blog/private/" = { - extraConfig = '' - auth_basic "Private Articles"; - auth_basic_user_file /srv/nginx/.htpasswd; - - # Enable Server Side Includes - ssi on; - ''; - }; - - # Optional: Custom 404 page - extraConfig = '' - error_page 404 /404.html; - ''; - }; - - # Ollama with Bearer token authentication - "ollama.binning.net" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - extraConfig = '' - # Check auth status - if ($auth_status = "no_auth") { - return 401 "Unauthorized: Bearer token required\n"; - } - if ($auth_status = "unauthorized") { - return 403 "Forbidden: Invalid API key\n"; - } - - # Proxy to Ollama (only if authorized) - proxy_pass http://localhost:11434; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # Timeouts for long-running requests - proxy_read_timeout 300s; - proxy_connect_timeout 300s; - proxy_send_timeout 300s; - - # Allow large request bodies - client_max_body_size 100M; - - # Logging - access_log /var/log/nginx/ollama_access.log; - error_log /var/log/nginx/ollama_error.log; - ''; - }; - }; - - # Forgejo - "forgejo.binning.net" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://127.0.0.1:3000"; - # No extraConfig needed - recommendedProxySettings handles headers - }; - }; - - # Radicale - "radicale.binning.net" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://127.0.0.1:5232"; - # recommendedProxySettings handles most headers - extraConfig = '' - proxy_set_header X-Script-Name ""; - ''; - }; - }; - }; - }; - - # Firewall - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - # ACME/Let's Encrypt - security.acme = { - acceptTerms = true; - defaults.email = "hvanb@pm.me"; - }; -} diff --git a/resume.html b/resume.html deleted file mode 100644 index cc726f1..0000000 --- a/resume.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - Resume - WWW - - - - - -
-
-

Resume

-

Professional Experience & Skills

-
- -
-

Summary

-

Experienced software engineer with expertise in systems engineering, cloud infrastructure, and full-stack development. Passionate about building reliable, scalable solutions using modern technologies.

-
- -
-

Technical Skills

-
-
-

Languages

-
    -
  • Rust
  • -
  • Python
  • -
  • Go
  • -
  • JavaScript/TypeScript
  • -
  • HTML/CSS
  • -
-
-
-

Systems & Infrastructure

-
    -
  • Linux/NixOS
  • -
  • Docker
  • -
  • Nginx
  • -
  • Git
  • -
  • CI/CD
  • -
-
-
-

Frameworks & Tools

-
    -
  • Rocket (Rust)
  • -
  • React
  • -
  • Node.js
  • -
  • PostgreSQL
  • -
  • RESTful APIs
  • -
-
-
-
- -
-

Professional Experience

- -
-

Software Engineer

-

Example Company • 2020 - Present

-
    -
  • Designed and implemented scalable backend services using Rust and Python
  • -
  • Managed infrastructure using NixOS and containerization technologies
  • -
  • Built and maintained CI/CD pipelines for automated testing and deployment
  • -
  • Collaborated with cross-functional teams to deliver high-quality software solutions
  • -
-
- -
-

Systems Administrator

-

Previous Company • 2018 - 2020

-
    -
  • Maintained Linux-based server infrastructure and monitoring systems
  • -
  • Automated routine tasks using shell scripting and Python
  • -
  • Implemented security best practices and access control policies
  • -
  • Provided technical support and documentation for development teams
  • -
-
-
- -
-

Education

-
-

Bachelor of Science in Computer Science

-

University Name • 2014 - 2018

-

Focus on software engineering, algorithms, and systems programming.

-
-
- -
-

Projects

-
-

Self-Hosted Infrastructure

-

Designed and deployed a complete self-hosted solution including:

-
    -
  • Git hosting with Forgejo
  • -
  • Web server with Nginx and SSL/TLS
  • -
  • Calendar and contacts sync with Radicale
  • -
  • Declarative configuration management with NixOS
  • -
-
- -
-

Personal Website & Blog

-

Built a simple, reliable website using primitive technologies (HTML/CSS) focused on performance and maintainability.

-
-
- -
-

Contact

-

Email: example@example.com

-

GitHub: forgejo.binning.net

-
-
- - - - diff --git a/staging.nginx.nix b/staging.nginx.nix deleted file mode 100644 index 174a7f4..0000000 --- a/staging.nginx.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - services.nginx = { - enable = true; - - # Recommended settings - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - - # Virtual hosts configuration for local staging - virtualHosts = { - - # Main website - Static HTML/CSS - # Access via http://localhost or http://localhost:80 - "localhost" = { - # No SSL for local development - listen = [ - { addr = "127.0.0.1"; port = 80; } - { addr = "0.0.0.0"; port = 80; } - ]; - - root = "/srv/www/stage.binning.net"; - - locations."/" = { - index = "index.html"; - tryFiles = "$uri $uri/ =404"; - extraConfig = '' - # Enable Server Side Includes for navbar/footer includes - ssi on; - ''; - }; - - # Private blog articles with HTTP basic authentication - locations."/blog/private/" = { - extraConfig = '' - auth_basic "Private Articles"; - auth_basic_user_file /srv/nginx/.htpasswd; - - # Enable Server Side Includes - ssi on; - ''; - }; - - # Custom 404 page - extraConfig = '' - error_page 404 /404.html; - ''; - }; - }; - }; - - # Firewall - allow local HTTP access - networking.firewall.allowedTCPPorts = [ 80 ]; -} diff --git a/style.css b/style.css deleted file mode 100644 index 1189e54..0000000 --- a/style.css +++ /dev/null @@ -1,331 +0,0 @@ -/* CSS Reset and Base Styles */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Courier New', 'Courier', 'Monaco', 'Lucida Console', monospace; - line-height: 1.7; - color: #3e2723; - background-color: #f4ecd8; -} - -/* Navbar Styles */ -.navbar { - 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 { - max-width: 1200px; - margin: 0 auto; - padding: 1rem 2rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.nav-brand { - color: #f4ecd8; - text-decoration: none; - font-size: 1.5rem; - font-weight: bold; -} - -.nav-brand:hover { - color: #d7ccc8; -} - -.nav-menu { - list-style: none; - display: flex; - gap: 2rem; -} - -.nav-menu a { - color: #f4ecd8; - text-decoration: none; - font-size: 1rem; - transition: color 0.3s ease; -} - -.nav-menu a:hover { - color: #d7ccc8; -} - -/* Main Container */ -.container { - max-width: 1200px; - margin: 0 auto; - padding: 2rem; -} - -/* Hero Section */ -.hero { - background-color: #efebe9; - padding: 3rem 2rem; - 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: #4e342e; - margin-bottom: 1rem; -} - -.hero p { - font-size: 1.2rem; - color: #6d4c41; -} - -/* Content Section */ -.content-section { - background-color: #efebe9; - padding: 2rem; - margin-bottom: 2rem; - border-radius: 4px; - box-shadow: 0 2px 8px rgba(62, 39, 35, 0.2); - border: 1px solid #d7ccc8; -} - -.content-section h2 { - color: #4e342e; - font-size: 2rem; - margin-bottom: 1.5rem; - border-bottom: 3px solid #8d6e63; - padding-bottom: 0.5rem; -} - -.contact-info p, -.genealogy-blurb p { - margin-bottom: 1rem; - line-height: 1.8; - color: #5d4037; -} - -.contact-info strong { - color: #4e342e; -} - -/* Footer */ -.footer { - background-color: #5d4037; - color: #f4ecd8; - text-align: center; - padding: 2rem; - margin-top: 3rem; - border-top: 2px solid #4e342e; -} - -.footer p { - font-size: 0.9rem; -} - -/* Blog Styles */ -.section-description { - color: #6d4c41; - font-style: italic; - margin-bottom: 1.5rem; -} - -.blog-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 1.5rem; - margin-top: 1.5rem; -} - -.blog-card { - 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(-2px); - box-shadow: 0 4px 12px rgba(62, 39, 35, 0.25); -} - -.blog-card h3 { - color: #4e342e; - margin-bottom: 0.5rem; - font-size: 1.3rem; -} - -.blog-card h3 a { - color: #4e342e; - text-decoration: none; - transition: color 0.3s ease; -} - -.blog-card h3 a:hover { - color: #6d4c41; -} - -.blog-meta { - color: #8d6e63; - font-size: 0.9rem; - margin-bottom: 0.75rem; -} - -.blog-card p { - color: #5d4037; - line-height: 1.6; -} - -.blog-card.private { - border-color: #a1887f; - background-color: #f5f5f0; -} - -.private-badge { - display: inline-block; - background-color: #8d6e63; - color: #f4ecd8; - padding: 0.25rem 0.75rem; - border-radius: 4px; - font-size: 0.85rem; - margin-top: 0.5rem; -} - -/* Resume Styles */ -.skills-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 2rem; - margin-top: 1.5rem; -} - -.skill-category h3 { - color: #4e342e; - margin-bottom: 1rem; - font-size: 1.2rem; - border-bottom: 2px solid #8d6e63; - padding-bottom: 0.5rem; -} - -.skill-category ul { - list-style: none; - padding-left: 0; -} - -.skill-category li { - padding: 0.5rem 0; - color: #5d4037; - position: relative; - padding-left: 1.5rem; -} - -.skill-category li:before { - content: "▸"; - position: absolute; - left: 0; - color: #8d6e63; - font-weight: bold; -} - -.experience-item { - margin-bottom: 2rem; -} - -.experience-item:last-child { - margin-bottom: 0; -} - -.experience-item h3 { - color: #4e342e; - font-size: 1.4rem; - margin-bottom: 0.5rem; -} - -.job-meta { - color: #8d6e63; - font-size: 0.95rem; - margin-bottom: 1rem; - font-style: italic; -} - -.experience-item ul { - margin-top: 1rem; - padding-left: 1.5rem; -} - -.experience-item li { - color: #5d4037; - margin-bottom: 0.5rem; - line-height: 1.7; -} - -.experience-item p { - 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 { - flex-direction: column; - gap: 1rem; - } - - .nav-menu { - flex-direction: column; - gap: 1rem; - text-align: center; - } - - .container { - padding: 1rem; - } - - .hero h1 { - font-size: 2rem; - } - - .content-section h2 { - font-size: 1.5rem; - } - - .blog-grid { - grid-template-columns: 1fr; - } - - .skills-grid { - grid-template-columns: 1fr; - } -} diff --git a/todo.txt b/todo.txt index fdf3b8e..6d6dc6c 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,14 @@ -(A) Populate the blog sections dynamically with blog folders using some include or frame mechanism -(B) Add a sidebar to navigate across the Blog sections, subsections, and pages -(C) Integrate photos for recipes -DefCon article -Oktoberfest article -health journey -faith journey -Add images and captions to those headings. +Personalize the index page. +Personalize the introduction page of the blog. + +Determine which articles should be incorporated into the website +Integrate photos for recipes +Build out the Copper Chronicle +Fill out the DefCon article +Fill out the Oktoberfest article with old physical notes in big binder + +x Add a build step to fetch/symlink "content" to this repo before mdbook build. +x Add a folder to hold the main html files and deploy it properly. x Create a simple webpage with HTML and CSS x Serve it from nginx x Add a navbar at the top with the index page as link in the top-left. @@ -23,3 +26,17 @@ x Re-use code or code blocks where possible between staging.nginx.nix and prod.n x Re-use code or code blocks where possible between deploy.sh staging and deploy.sh prod x Re-theme the blog with sepia tone and monospace fonts/typefaces. x Create a recipe section in the blog based on the markdown content in blog/public/recipes +x Populate the blog sections dynamically with blog folders using some include or frame mechanism +x Add a sidebar to navigate across the Blog sections, subsections, and pages +x Move copper chronicle to the private section of the blog. +x Add a lock symbol to the mdbook sidebar to indicate private/restricted sections. +x Create a "minimal" content set to test building and deployment without the entire blog/content. +x Import Abby's Binning Family Menu @Cline +x Fix anchors (relative links) showing in mdbook's sidebar. +x Create a minimal "Menu" (food menu) page on the main website, which has a selection of line items from the recipe book. @Cline +x 2026-03-22 Add a folder to hold the nginx/nix files and deploy it properly. +x 2026-03-22 Add a Forgejo pipeline to supersede deploy.sh. +x 2026-03-22 Remove the one line descriptions from the menu. +x 2026-03-22 Move the resume to the private section and add the lock symbol. +x 2026-03-23 Reduce the CSS where possible. Match my website's theme to align with mdbook's theme. +x Set up nightly builds