This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Jekyll-based static personal tech blog and tools website. The site features blog posts about .NET, infrastructure, and security topics, plus interactive tools like an embedded YouTube player, DNS toolbox, and password generator.
Using Docker with hot-reload (recommended for development):
.\local-preview.ps1
This checks for an existing Docker image, builds only if needed, and runs Jekyll with hot-reload, incremental builds, and LiveReload. The site will be available at http://localhost:4000 and auto-refreshes on file changes.
Force rebuild when dependencies change:
.\local-preview.ps1 -Rebuild
Using Docker (clean build each time):
.\run.ps1
Rebuilds the Docker image and runs the Jekyll server. Use this when you need a completely fresh build.
Native Jekyll:
bundle install
bundle exec jekyll serve --host 0.0.0.0
_posts/: Blog posts in markdown format with YAML frontmatter. Posts follow the naming convention YYYY-MM-DD-title.md_layouts/: Page templates
default.html: Base layout with navigation, footer, Google Analyticspost.html: Blog post layout with Disqus commentspage.html: Standard page layouttools.html: Layout for interactive tools_includes/: Reusable components
nav.html: Site navigationscss/: Inline SCSS styles (compiled via Liquid)js/: JavaScript libraries (mustache, owl-carousel, slick)sections/: Content sections for code discovery/projectstools/: Interactive web-based tools (YouTube player, DNS toolbox, password generator)reference/: Technical reference materials (protocol header cheatsheets)_config.yml defines:
<!--excerpt-->/:title/Layouts inheritance: Tools and posts extend the default layout, which includes navigation and footer with analytics.
SCSS compilation: Styles are included inline via Liquid templating (`$white: #ffffff; $home-page-boxes: #f8f8f8; $background-color: #F0F2F3; $border-color: #e9e9e9;
$cloud: #BBBBBB; $fossil: #AAAAAA; $shadow: #555555; $shadow-bar: #606060; $charcoal: #363636;
$azure: #4C9CF1;
$font-family-1: “Open Sans”; $font-family-2: “Open Sans Condensed”; $font-family-3: “Roboto”; $font-family-4: Helvetica, Arial, sans-serif;
$paragraph-font-family: $font-family-4; $paragraph-font-size: 14px; $paragraph-color: #626566; $paragraph-line-height: 1.9; $paragraph-letter-spacing: .01em;
$h1-font-size: 30px; $h2-font-size: 26px; $h3-font-size: 22px; $h4-font-size: 18px; $h5-font-size: 14px;
$h1-line-height: 1.8em; $h2-line-height: 1.35em; $h3-line-height: 1.35em; $h4-line-height: 1.32em; $h5-line-height: 1.35em;
$h1-margin: 0px 0 10px 0; $h2-margin: 48px 0 8px; $h3-margin: 48px 0 8px; $h4-margin: 48px 0 8px; $h5-margin: 48px 0 8px;
/**************************/
body { background: $background-color; color: $shadow; }
a { color: $azure; text-decoration: none; }
a:hover { color: $shadow; }
h1, h2, h3, h4, h5 { color: $charcoal; font-family: $font-family-1; text-transform: none; letter-spacing: 0px; font-weight: 300; }
h1 { font-size: $h1-font-size; line-height: $h1-line-height; margin: $h1-margin; }
h2 { font-size: $h2-font-size; line-height: $h2-line-height; margin: $h2-margin; }
h3 { font-size: $h3-font-size; line-height: $h3-line-height; margin: $h3-margin; }
h4 { font-size: $h4-font-size; line-height: $h4-line-height; margin: $h4-margin; font-weight: bold; }
h5 { font-size: $h5-font-size; line-height: $h5-line-height; margin: $h5-margin; font-weight: bold; }
p { font-family: $paragraph-font-family; font-size: $paragraph-font-size; line-height: $paragraph-line-height; letter-spacing: $paragraph-letter-spacing; color: $paragraph-color; margin: 0 0 14px 0; }
p, li, td { word-wrap: break-word; }
section { margin: 80px auto; max-width: 1080px; padding: 20px; position: relative; background-color: $white; border: 1px solid $border-color; }
pre { border: none; border-radius: 0; padding: 0; background-color: #f8f8f8; font-size: 11px; }
code { padding: 2px 4px 1px 4px; font-size: 75%; border-radius: 3px; }
.code pre {
padding: 0 0 0 8px;
}
ol, ul { li { padding: 4px 0; } }
button { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
blockquote { border-left: 5px solid #f1e594; background: #fbfada; }
/**************************/
.navbar { border-radius: 0; min-height: 76px; background: $charcoal; border: none; border-color: transparent;
.navbar-brand {
text-transform: uppercase;
font-weight: 300;
font-style: normal;
color: $fossil;
font-family: $font-family-2;
font-size: 28px;
letter-spacing: 2px;
margin-top: 13px;
}
.navbar-brand:hover {
color: $white;
}
.navbar-collapse {
border: none;
border-color: transparent;
}
.navbar-toggle {
margin-top: 20px;
margin-right: 15px;
border: none;
&:hover,
&:focus {
background-color: $shadow;
}
.icon-bar {
background-color: $white;
height: 3px;
}
} }
#navbar-main {
margin-top: 23px;
.navbar-nav {
.dropdown-menu {
border-radius: 0;
}
li a {
font-family: $font-family-4, $font-family-4;
font-size: 11px;
text-transform: uppercase;
padding: 6px 8px 4px 8px;
margin: 0 6px;
border-bottom: solid 2px transparent;
color: $fossil;
.caret {
margin-left: 6px;
top: 0;
}
}
li.open {
a {
background-color: $shadow;
color: $white;
}
}
li a:hover,
li .active {
color: $white;
border-bottom: solid 2px $cloud;
}
li .dropdown-menu {
right: 6px;
background-color: $shadow;
border: none;
margin-top: -2px;
a {
text-transform: none;
color: $fossil;
font-size: 13px;
font-family: $font-family-3, $font-family-4;
}
a:hover {
border-bottom: solid 2px transparent;
color: $white;
}
}
} }
/**************************/
#index {
h1 {
margin-top: 20px;
text-align: center;
}
p {
text-align: center;
}
.posts {
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
font-family: $font-family-3;
color: #626566;
line-height: 1.6;
letter-spacing: .01em;
border-bottom: 1px solid rgba(0,0,0,0.05);
padding: 18px 0;
position: relative;
list-style-type: none;
font-size: $paragraph-font-size;
}
li:last-child {
border-bottom: none;
}
span {
float: right;
word-break: none;
word-wrap: none;
font-size: 12px;
font-family: $font-family-4;
margin-left: 6px;
}
}
.assets {
background-color: $home-page-boxes;
/*border: 1px solid #e9e9e9;*/
border-radius: 4px;
padding: 20px;
ul {
margin: 0;
list-style: none;
list-style-type: none;
padding: 0;
}
li {
margin: 0 0 28px 0;
h2 {
margin: 0 0 8px 0;
}
h3 {
margin: 0 0 8px 0;
}
p {
text-align: left;
margin: 0;
}
}
li:last-child {
margin: 0;
}
} }
@import url(‘https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css’);
#youtube-embed {
font-family: 'Inter', sans-serif;
font-size: 12px;
text-align: center;
padding: 60px 0;
.container {
text-align: center;
width: 80%;
}
#videoId {
font-size: 14px;
padding: 10px;
margin: 10px 0;
width: 30%;
color: #444;
}
button {
font-size: 14px;
padding: 10px 20px;
cursor: pointer;
color: #444;
}
iframe {
margin-top: 20px;
border: none;
width: 100%;
height: 485px;
border-radius: 4px;
}
.video-link {
color: #007BFF;
font-size: 12px;
display: none;
}
#youTubeLinkContainer {
margin-top: 10px;
font-size: 12px;
display: none;
}
table {
border-collapse: collapse;
border-radius: 6px;
border-style: hidden; /* hide standard table (collapsed) border */
box-shadow: 0 0 0 1px #ddd; /* this draws the table border */
}
td, th {
background-color: #fafafa;
}
table tr:first-child td:first-child {
border-top-left-radius: 10px;
}
table tr:first-child td:last-child {
border-top-right-radius: 10px;
}
table tr:last-child td:first-child {
border-bottom-left-radius: 10px;
}
table tr:last-child td:last-child {
border-bottom-right-radius: 10px;
}
#playedVideos {
margin-top: 20px;
border-spacing: 0;
display: none;
}
#playedVideos th,
#playedVideos td {
padding: 4px 10px;
text-align: left;
}
#playedVideos th {
background-color: #f4f4f4;
}
.video-item a {
color: #007BFF;
text-decoration: none;
}
.video-item a:hover {
text-decoration: underline;
}
.youtube-icon {
font-size: 16px;
color: #ff0000;
margin-left: 5px;
}
.forget-all {
margin-top: 10px;
color: #ff0000;
cursor: pointer;
text-decoration: underline;
}
#recentlyPlayed {
margin-top: 20px;
font-weight: bold;
font-size: 16px;
}
.notes-input,
.group-input {
width: 100%;
box-sizing: border-box;
padding: 6px 8px;
margin: 0;
background-color: transparent;
border: none;
} }
#dns-toolbox {
overflow-x: auto;
padding-bottom: 20px;
margin-bottom: 40px;
button {
height: 27px;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 3px;
color: #555555;
}
button:hover {
background-color: #E9E9E9;
}
button:active {
box-shadow: inset 0 1px 5px rgba(0,0,0,0.125);
}
.formFields input, textarea, select {
display: inline-block;
padding: 4px;
margin-top: 9px;
font-size: 13px;
line-height: 18px;
color: #555555;
border: 1px solid #cccccc;
border-radius: 3px;
}
.formFields input, textarea {
min-width: 260px;
}
.formFields p {
margin: 0;
} }
#dns-toolbox-answers {
padding: 40px;
margin-top: 0;
position: relative;
display: none;
h1 {
margin-top: 0;
}
h2 {
margin: 28px 0 8px 0;
}
h2:first-child {
margin: 0 0 8px 0;
}
table,
td {
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-size: small;
color: #626566;
line-height: 1.6;
letter-spacing: .01em;
}
table {
margin: 0;
padding: 0;
border-spacing: 1px;
border-collapse: separate;
border: 1px solid #ddd;
}
td {
border: 1px solid #ddd;
padding: 2px 2px 2px 5px;
min-width: 70px;
}
.loadingImage {
text-align: center;
position: absolute;
top: 30px;
left: 0;
right: 0;
margin: 0 auto;
}
#dnsResults {
overflow: auto;
}
.header {
background-color: #fafafa;
border: 1px solid #eee;
padding: 8px;
border-radius: 2px;
}
.header p {
font-family: monospace;
font-size: smaller;
margin: 0;
}
.header p:nth-child(3) {
margin-top: 16px;
}
.ui-state-default {
padding: 7px 17px;
border: 1px solid #ddd;
background-color: #fafafa;
}
.ui-state-active {
background: #fff;
border-bottom: 1px solid #fff;
}
.apiErrorMessage {
background-color: #fafafa;
padding: 12px 8px;
border: 1px solid #ddd;
text-align: center;
}
.childTable {
border-spacing: 0;
border: none;
}
.childTable td {
padding-left: 10px;
padding-right: 10px;
border: none; /* important */
border-right: 2px solid #ddd;
min-width: 0;
}
.childTable td:first-child {
padding-left: 2px;
}
.childTable td:last-child {
padding-right: 10px;
border: none;
} }
#code {
h2 {
font-size: 18px;
margin: 0;
}
li:first-child {
margin: 35px 0 15px 0;
}
li {
margin: 15px 0 15px 0;
} }
#disqus_thread { margin: 80px 0 0 0; padding: 16px; background-color: #f9f9f9; border-radius: 3px; }
#generate-passwords { #passwords { margin-bottom: 26px;
ul {
list-style: none;
margin: 15px 0 0 0;
padding: 0;
}
li {
line-height: 1.8em;
}
.password {
font-family: monospace;
border: 1px solid #e0e0e0;
background-color: #fcfcfc;
margin: 0;
padding: 2px 8px;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.length {
font-family: Arial;
font-size: x-small;
color: #aaa;
margin: 0 10px 0 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.copyButton {
border: none;
padding: 0 6px 0 4px;
margin: 1px 0 0 0;
font-size: 8pt;
height: 23px;
font-family: $font-family-1;
line-height: 2.3;
text-transform: uppercase;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
}
#error {
background-color: #fafafa;
padding: 12px 8px;
border: 1px solid #ddd;
text-align: center;
margin-bottom: 16px;
}
}
#about { img { padding: 70px; max-width: 100%; }
h1 {
text-align: center;
max-width: 745px;
margin: 0 auto;
} }
#iis-server-headers { h1 { border-bottom: 1px solid $border-color; } }
#protocol-header-cheetsheets { h1 { border-bottom: 1px solid $border-color; }
hr {
margin: 80px 0;
size: 5px;
}
img {
max-width: 100%;
}
table {
border: 1px solid $border-color;
}
th {
background-color: $background-color;
}
th,
td {
border: 1px solid $border-color;
word-wrap: normal;
padding: 4px;
white-space: nowrap;
vertical-align: top;
}
td:last-child {
word-wrap: break-word;
white-space: normal;
} }
#post { img { max-width: 100%; }
pre {
margin: 0;
} }
#footer { blockquote { font-style: italic; font-size: small; margin: 0 auto; max-width: 1080px; text-align: right; padding-bottom: 25px; border: none; background: none; } }
/**************************/
.viewport-max-height { min-height:80vh; }
table.vcruntime {
margin: 0 0 14px 0;
padding: 0;
border-spacing: 1px;
border-collapse: separate;
border: 1px solid #ddd;
th {
background-color: #fafafa;
border: 1px solid #ddd;
padding: 5px 10px 5px 10px;
min-width: 100px;
}
td {
border: 1px solid #ddd;
padding: 3px 10px 3px 10px;
min-width: 100px;
}
td:nth-child(1) {
font-family: 'Consolas';
font-size: 12px;
} }
/* notice this section is MAX width */ @media only screen and (max-width: 768px) {
#navbar-main {
.navbar-nav {
li,
li:hover {
.active,
a:hover {
border-bottom: solid 2px transparent;
}
.dropdown-menu {
padding: 0;
li {
padding-left: 16px;
border-bottom: 1px solid $shadow-bar;
}
li:last-child {
border-bottom: none;
}
}
}
li.open {
a {
background-color: transparent;
}
}
}
li a:hover {
border-bottom: none;
}
} }
@media only screen and (min-width: 1200px) { .container { max-width: 970px; } }
@media only screen and (max-width: 1100px) { body { background: $white; }
section {
border: 0px transparent;
margin: 0;
}
#footer {
margin-top: 140px;
}
#protocol-header-cheetsheets {
td {
white-space: normal;
}
}
#about {
img {
padding: 20px;
}
} } `) and compiled using the `scssify` filter at build time.
URL redirects: Uses jekyll-redirect-from plugin for legacy URL support (e.g., /yt redirects to YouTube tool).
Interactive tools: Self-contained pages with embedded JavaScript. The YouTube tool uses localStorage to track recently played videos and sanitizes video IDs for security.
Create a markdown file in tools/ directory with:
---
layout: tools
title: Tool Name
redirect_from: "/shorturl"
---
<div class="container">
<!-- Tool HTML and JavaScript here -->
</div>
Knock knock
Race condition
Who's there?