bump
This commit is contained in:
parent
73c4533926
commit
7a3665abae
|
|
@ -14,5 +14,3 @@ node_modules/
|
|||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Generated PDFs (created at deploy time)
|
||||
docker/resume/pdfs/
|
||||
|
|
|
|||
|
|
@ -31,8 +31,12 @@ RUN cd /srv && \
|
|||
chmod +x update-all.sh && \
|
||||
./update-all.sh
|
||||
|
||||
# Generate PDFs for all pages
|
||||
RUN cd /srv && npm run generate-pdfs
|
||||
# Generate PDFs for all pages (only if they don't already exist)
|
||||
RUN if [ ! -d "/srv/pdfs" ] || [ -z "$(ls -A /srv/pdfs 2>/dev/null)" ]; then \
|
||||
cd /srv && npm run generate-pdfs; \
|
||||
else \
|
||||
echo "PDFs already exist, skipping generation"; \
|
||||
fi
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
# Resume Website
|
||||
|
||||
## Initial Setup
|
||||
|
||||
After cloning the repository, run the setup script from the repository root to install git hooks:
|
||||
|
||||
```bash
|
||||
./setup-git-hooks.sh
|
||||
```
|
||||
|
||||
This installs a pre-push hook that automatically generates PDFs before pushing.
|
||||
|
||||
## Local Development
|
||||
|
||||
To run the local development server:
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="description" content="Colin Knapp - Private Consulting Packs">
|
||||
<title>Consulting Packs (Private) - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<style>
|
||||
.pricing-section {
|
||||
padding: 2rem 0;
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
<meta name="description" content="Colin Knapp - CSV Processing Tool">
|
||||
<title>CSV Viewer - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<link rel="stylesheet" href="csv-tool-fix.css?v=2" integrity="sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<script src="../utils.js" integrity="sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544="></script>
|
||||
<style>
|
||||
/* Additional inline styles to fix layout */
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - DevSecOps consultant, cybersecurity expert, and open-source advocate. Explore resumes, project stories, and free tools.">
|
||||
<title>Colin Knapp - DevSecOps & Cybersecurity Expert</title>
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<style>
|
||||
.hero {
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
<meta name="description" content="Free browser-based CSV viewer tool. Paste CSV data to instantly view as formatted table with sorting, customizable delimiters, and client-side processing for privacy.">
|
||||
<title>CSV Viewer Tool - Free Online CSV Parser</title>
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<link rel="stylesheet" href="tool-styles.css?v=2" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="tool-styles.css?v=2" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<link rel="stylesheet" href="csv-tool-fix.css?v=2" integrity="sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<script src="../utils.js" integrity="sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544="></script>
|
||||
<style>
|
||||
/* Additional inline styles to fix layout */
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - One Pager Tools">
|
||||
<title>Colin Knapp Tools</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<script src="../utils.js" integrity="sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544=" crossorigin="anonymous"></script>
|
||||
<!-- Add tool-specific scripts here -->
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
<meta name="description" content="Colin Knapp - Tool Example">
|
||||
<title>Tool Example - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="tool-styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../utils.js" integrity="sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<script src="tool-example.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - Business Development Resume: Revenue growth, client relations, and entrepreneurship experience.">
|
||||
<title>Business Development - Colin Knapp Resume</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - DevSecOps Resume: Infrastructure, security automation, and compliance expertise.">
|
||||
<title>DevSecOps - Colin Knapp Resume</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="DevSecOps consultant and cybersecurity expert. Led teams of 45+, built open-source tools with 10M+ downloads, and architected resilient infrastructure for government and healthcare clients.">
|
||||
<title>Full Portfolio - Colin Knapp Resume</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - Team Leadership Resume: Management, mentorship, and distributed team coordination experience.">
|
||||
<title>Team Leadership - Colin Knapp Resume</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - Tool Building Resume: Open source development, CI/CD, and custom software solutions.">
|
||||
<title>Tool Building - Colin Knapp Resume</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Architected geographically redundant DNS infrastructure for Flint Bishop International Airport, achieving A+ resilience standards for critical aviation infrastructure.">
|
||||
<title>Airport DNS Infrastructure - Resilient DNS Design</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Developed ad revenue tracking application for content creators with real-time analytics, secure API integrations, and data-driven content optimization tools.">
|
||||
<title>Ad Revenue Tracking App for Influencers</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Revitalized struggling business into profitable operation in two weeks, developing revolutionary open-source tooling that powered major Minecraft projects.">
|
||||
<title>Athion.net Business Turnaround - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Co-created FastAsyncWorldEdit and PlotSquared, scaling Minecraft world editing from 50K server-crashing edits to billions seamlessly, powering a $2B game brand.">
|
||||
<title>FastAsyncWorldEdit & PlotSquared - Minecraft Tools</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Designed secure, scalable infrastructure for Improving MI Practices healthcare education platform with CIS Level 1-2 security standards and high availability.">
|
||||
<title>Healthcare Platform Infrastructure - Secure Design</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Built self-hosted infrastructure cluster with 100+ services for data sovereignty and developed WireGuard mesh networking tool for quantum-resistant networking.">
|
||||
<title>Home Infrastructure & WireGuard Mesh Networking</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Explore detailed case studies and project stories from Colin Knapp's portfolio: cybersecurity, infrastructure, open source development, and team leadership.">
|
||||
<title>Project Stories & Case Studies - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Co-founded sustainable electronics repair company reducing e-waste through circuit board repairs and promoting environmental responsibility in tech industry.">
|
||||
<title>MotherboardRepair.ca - Sustainable Tech Solutions</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Led distributed team of 45 contractors at Nitric Concepts, bootstrapping company to $4M revenue while implementing DevSecOps practices across timezones.">
|
||||
<title>Nitric Concepts Leadership - Team Management</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Architected georedundant, nuclear war-resistant DNS cluster for government clients, ensuring extreme resilience and A+ security standards for critical infrastructure.">
|
||||
<title>Nuclear War-Resistant DNS Infrastructure</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Transformed OhMyForm from abandoned project to thriving community with 32K+ Discord members, 10M+ Docker pulls, and sustainable funding model.">
|
||||
<title>Open Source Community Success - OhMyForm</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Built high-performance ScanSnap scanner service processing ~1 receipt/second with batch capacity up to 50 documents, featuring automatic cleanup and WebDAV access.">
|
||||
<title>ScanSnap Scanner Service - Receipt Digitization</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Revitalized ShowerLoop website with WCAG 2.0 AA compliance, modern responsive design, and improved accessibility for innovative eco-friendly recirculating shower system.">
|
||||
<title>ShowerLoop Project - Web Development & Accessibility</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - Story Example">
|
||||
<title>Story Example - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - [Story Title] Case Study">
|
||||
<title>[Story Title] - Colin Knapp Case Study</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Built AI-powered cybersecurity consultancy ViperWire, delivering enterprise-grade security to SMBs with automated threat detection, reducing incident response time to 15 minutes.">
|
||||
<title>ViperWire - AI-Powered Cybersecurity Consultancy</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Developed web solutions and Java plugins with Jenkins/GitLab CI/CD, WCAG 2.0 AA compliance, and comprehensive documentation for diverse client environments.">
|
||||
<title>Web Design & Java Plugin Development</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Created Docker-based automated WordPress malware removal tool that eliminated persistent attacks, reducing infection frequency from daily to zero for MLPP.">
|
||||
<title>WordPress Security Automation - Malware Removal</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
<script src="../markdown-loader.js" integrity="sha256-qK8mCx0LUZwMtstjbkCOweh/Y+84XwFjcUQSEH4lCws="></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Developed custom Minecraft games for YouTube creators with 15M+ subscriber reach, implementing DDoS defense, anti-phishing protocols, and data privacy measures.">
|
||||
<title>YouTube Game Development & Cybersecurity</title>
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=" crossorigin="anonymous">
|
||||
<script src="../theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA=" crossorigin="anonymous"></script>
|
||||
<script src="../includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="stories.css" integrity="sha256-O+OMb48leSKvekhMTDUK1y6+WG9x33kA0eDw00wUwkY=">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -376,6 +376,11 @@ html[data-theme='dark'] .main-nav a.active {
|
|||
color: #dc3545 !important; /* Red for unwritten stories */
|
||||
}
|
||||
|
||||
/* Bold story links that are written */
|
||||
.main-nav .dropdown-content a:has(.nav-status.written) {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Dark theme support for status indicators */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.main-nav .dropdown-content a .nav-status.written {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Colin Knapp - Template with Includes">
|
||||
<title>Template with Includes - Colin Knapp</title>
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-mjzh8Lh0zDbg3xduiLiH6jR4dfkgwJKGGoF2jAOY/AI=">
|
||||
<link rel="stylesheet" href="styles.css" integrity="sha256-nsutlmVxvyIyABk8i0fzVyO+ram8rkuTntoETIGcou8=">
|
||||
<script src="theme.js" integrity="sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4="></script>
|
||||
<script src="includes.js" integrity="sha256-0VPPSi+jVc1DuyZaSYTq+fnpIfv7ft+ZDenYE6pDPqA="></script>
|
||||
<script src="includes.js" integrity="sha256-CJbyPP0VWE+XrarLtjHMffGrI2GlTXXAXOce+NE+aQg="></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header Include -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
# Pre-push hook to generate PDFs before pushing
|
||||
# This ensures PDFs are always up to date when code is pushed
|
||||
|
||||
set -e
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
DOCKER_DIR="$REPO_ROOT/docker"
|
||||
PDFS_DIR="$REPO_ROOT/docker/resume/pdfs"
|
||||
|
||||
echo "Running pre-push hook: Generating PDFs..."
|
||||
|
||||
# Navigate to docker directory
|
||||
cd "$DOCKER_DIR"
|
||||
|
||||
# Check if node_modules exists, install if not
|
||||
if [ ! -d "node_modules" ]; then
|
||||
echo "Installing npm dependencies..."
|
||||
npm install
|
||||
fi
|
||||
|
||||
# Generate PDFs
|
||||
echo "Generating PDFs..."
|
||||
if npm run generate-pdfs; then
|
||||
echo "✓ PDFs generated successfully"
|
||||
|
||||
# Stage the PDFs directory if it exists and has changes
|
||||
cd "$REPO_ROOT"
|
||||
if [ -d "$PDFS_DIR" ]; then
|
||||
# Check if there are any PDF files
|
||||
if [ -n "$(find "$PDFS_DIR" -name "*.pdf" -type f 2>/dev/null)" ]; then
|
||||
# Add PDFs to staging
|
||||
git add "$PDFS_DIR"/*.pdf 2>/dev/null || true
|
||||
|
||||
# Check if there are unstaged changes
|
||||
if ! git diff --cached --quiet --exit-code "$PDFS_DIR" 2>/dev/null; then
|
||||
echo "PDFs updated and staged"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "✗ PDF generation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
# Setup script to install git hooks
|
||||
# Run this after cloning the repository
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
GIT_HOOKS_DIR="$SCRIPT_DIR/.git/hooks"
|
||||
SOURCE_HOOKS_DIR="$SCRIPT_DIR/git-hooks"
|
||||
|
||||
echo "Setting up git hooks..."
|
||||
|
||||
# Create .git/hooks directory if it doesn't exist
|
||||
mkdir -p "$GIT_HOOKS_DIR"
|
||||
|
||||
# Copy pre-push hook
|
||||
if [ -f "$SOURCE_HOOKS_DIR/pre-push" ]; then
|
||||
cp "$SOURCE_HOOKS_DIR/pre-push" "$GIT_HOOKS_DIR/pre-push"
|
||||
chmod +x "$GIT_HOOKS_DIR/pre-push"
|
||||
echo "✓ Installed pre-push hook"
|
||||
else
|
||||
echo "✗ pre-push hook not found in git-hooks/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Git hooks installed successfully!"
|
||||
echo "PDFs will be automatically generated before each push."
|
||||
|
||||
Loading…
Reference in New Issue