Compare commits

...

38 Commits

Author SHA1 Message Date
54a0dc56ad renaming the css becuse cache is weird 2026-08-14 11:40:48 -05:00
d7ca8b0ce0 update post 2026-08-13 20:29:32 -05:00
afebcae714 Added tag filtering and RSS feed 2026-08-13 19:31:59 -05:00
2b2ab3a115 Added a projects post 2026-08-13 18:54:39 -05:00
e142ef542b fix the link date again, hopefully 2026-08-13 14:37:12 -05:00
cb97df446e Update the way dates render on post list 2026-08-13 14:22:23 -05:00
4586616251 Added new 'my-views' post 2026-08-13 14:11:30 -05:00
4927c33753 Fix date on posts list 2026-08-13 12:38:00 -05:00
40695352ad some style update 2026-08-13 12:35:23 -05:00
3820341b50 fix broken sticky about post link 2026-08-13 12:26:09 -05:00
cf16fa4803 fix id on index page 2026-08-13 12:24:58 -05:00
ae5f36909f Made the red a little redder 2026-08-13 12:24:06 -05:00
d7d60dc0f6 testing dark/light mode 2026-08-13 12:21:37 -05:00
1aad2224e2 Merge branch '2026-redesign' 2026-08-13 11:48:34 -05:00
390a746fec new site 2026-08-13 11:48:06 -05:00
6119e000a5 add KAO banner 2026-08-06 20:46:08 -05:00
bbe1a2d322 re-adding everything since repo moved 2026-08-06 20:41:00 -05:00
cf38e6b07c Update a few things 2026-03-15 20:50:30 -05:00
5335afd88c Update spelling and adding notice at bottom 2026-01-31 22:14:27 -06:00
3e1aec3867 change image 2026-01-31 21:44:45 -06:00
37c4f8d2aa fix bad link on cogwheel 2026-01-31 21:44:05 -06:00
d99dc901ac add more projects and change default colors 2026-01-31 21:40:57 -06:00
bdcc5d0dc8 Merge branch 'main' of https://git.bellsworne.tech/chrisbell/hexstudios-co 2026-01-31 19:28:27 -06:00
0ea57cf4c3 Merge branch 'develop' 2026-01-31 19:25:16 -06:00
a01bc4eb2b Merge pull request 'Pull rewrite into develop' (#5) from rewrite into develop
Reviewed-on: #5
2026-02-01 01:18:04 +00:00
a006bd418c Lots of new stuff for rework 2026-01-31 19:16:51 -06:00
622e62d4b4 More edits to main index 2026-01-31 11:35:24 -05:00
a7e67503e5 Merge pull request 'Adding a description' (#4) from develop into main
Reviewed-on: #4
2026-01-17 01:00:13 +00:00
92d3899de7 Merge pull request 'Update critterfolio apk, again' (#3) from develop into main
Reviewed-on: #3
2026-01-09 05:27:49 +00:00
2ac913a9b9 Merge pull request 'update critterfolio apk' (#2) from develop into main
Reviewed-on: #2
2026-01-08 23:04:34 +00:00
c57f8d82ca Merge pull request 'added critterfolio page' (#1) from develop into main
Reviewed-on: #1
2026-01-08 22:52:45 +00:00
Spudnut2000
1d7144640e testing webhook 2025-06-20 22:56:59 -05:00
Spudnut2000
eb0e0125bc fixed stars description 2025-06-20 22:54:21 -05:00
Spudnut2000
b68bd4cea6 Merge remote-tracking branch 'origin/develop' 2025-06-20 22:37:22 -05:00
Spudnut2000
9624ba2ee3 updates June 2025 2025-06-20 22:34:05 -05:00
Chris Bell
a984a1f5c0 Merge branch 'develop' 2023-08-09 09:09:34 -05:00
Chris Bell
860a8af7c4 Added new project card, removed phone number 2023-08-09 09:04:07 -05:00
Chrisopher Bell
9168c5f807 Merge pull request #1 from HexStudios/develop
Merging dev into main
2022-09-13 22:00:44 -05:00
57 changed files with 1323 additions and 221 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
LICENSE.txt Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

View File

@@ -1,39 +0,0 @@
:root {
--color-background: #010101;
--color-foreground: #aa0000;
}
* {
margin: 0;
padding: 0;
font-family: monospace;
}
html {
background-color: var(--color-background);
color: var(--color-foreground);
}
.tui-box {
width: 100%;
height: auto;
padding: 20px;
border: 2px solid var(--color-foreground);
border-radius: 10px;
margin: 20px;
position: relative;
}
.tui-header {
position: absolute;
top: 0;
left: 25px;
transform: translateY(-50%);
background-color: var(--color-background);
padding: 0 10px;
}
.tui-content p{
font-size: 12pt;
margin: 15px 0 15px 0;
}

0
dev/.htaccess-backup Normal file → Executable file
View File

0
dev/blight/coi-serviceworker.js Normal file → Executable file
View File

0
dev/blight/index.apple-touch-icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

0
dev/blight/index.audio.worklet.js Normal file → Executable file
View File

0
dev/blight/index.html Normal file → Executable file
View File

0
dev/blight/index.icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

0
dev/blight/index.js Normal file → Executable file
View File

0
dev/blight/index.pck Normal file → Executable file
View File

0
dev/blight/index.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

0
dev/blight/index.wasm Normal file → Executable file
View File

0
dev/blight/index.worker.js Normal file → Executable file
View File

0
dev/interactive-angular-map/.htaccess Normal file → Executable file
View File

0
dev/interactive-angular-map/assets/mapimage.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

0
dev/interactive-angular-map/favicon.ico Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

0
dev/interactive-angular-map/index.html Normal file → Executable file
View File

0
dev/interactive-angular-map/main-4Z6S77FU.js Normal file → Executable file
View File

0
dev/interactive-angular-map/polyfills-FFHMD2TL.js Normal file → Executable file
View File

0
dev/interactive-angular-map/styles-U3BIK65T.css Normal file → Executable file
View File

0
dev/stars/index.html Normal file → Executable file
View File

View File

@@ -1,27 +1,132 @@
<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/main.css"> <title>Hex Studios</title>
<title>// Hex Studios //</title> <link rel="alternate" type="application/rss+xml" title="Hex Studios RSS Feed" href="posts/feed.php">
<script>
(function() {
var stored = localStorage.getItem('theme');
if (stored === 'light') document.documentElement.setAttribute('data-theme', 'light');
})();
function toggleTheme() {
var isLight = document.documentElement.getAttribute('data-theme') === 'light';
if (isLight) {
document.documentElement.removeAttribute('data-theme');
localStorage.setItem('theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
}
</script>
<link rel="stylesheet" href="styles/master.css">
</head> </head>
<body> <body>
<button id="theme-toggle" onclick="toggleTheme()">toggle light/dark</button>
<div style="width: 50vh; margin-left: 30px; margin-top: 50px;"> <h1>// Hex Studios</h1>
<i>Developer, biker, musician, engineer, and an unapologetic centrist in the deep red south. The real @hexstudios.</i>
<div class="tui-box"> <div id="links-section">
<h2 class="tui-header">// HEX STUDIOS //</h2> <h2>Links</h2>
<div class="tui-content"> <ul class="custom-list">
<p>Hello! My name is Chris, aka Spudnut2000. Welcome to my personal portfolio site!</p> <li><a href="https://git.bellsworne.tech/">Git repos</a></li>
<h2>About Me</h2> <li><a href="https://youtube.com/c/hexstudios">YouTube</a></li>
<p>I am a husband, programmer, musician, and all around nerd. I like to develop both software and games.</p> <li><a href="https://bellsworne.com">My company - Bellsworne</a></li>
<p>I am primarily a Software Engineer by trade with a Bachelor's in Sotware Engineering and ~5 years of professional experience, where the majority of my knowledge is in C#/.NET, XAML, and HTML/CSS. I am also proficient in many other languages like Odin, C/C++, Java, QML, and JavaScript.</p> <li><a href="https://git.bellsworne.tech/chrisbell/hexstudios-co">Page source code (git)</a></li>
</div> <li><a href="posts/feed.php">RSS feed</a></li>
</div> </ul>
</div> </div>
<div id="sticky-posts-section">
<h2>Pinned posts</h2>
<ul class="custom-list">
<li><a href="post.html?file=about.md">About <i class="post-link-date">August 13, 2026</i></a></li>
<li><a href="post.html?file=projects.md">Projects <i class="post-link-date">August 13, 2026</i></a></li>
</ul>
</div>
<div id="posts-section">
<h2>Posts</h2>
<ul id="tags-list"></ul>
<ul class="custom-list" id="posts-list"></ul>
</div>
<script>
let allPosts = [];
let activeTag = null;
async function loadPosts() {
const list = document.getElementById('posts-list');
try {
const res = await fetch('posts/list.php');
allPosts = await res.json();
renderTags();
renderPosts();
} catch (err) {
list.innerHTML = '<li>Couldn\u2019t load posts.</li>';
}
}
function renderTags() {
const tagsList = document.getElementById('tags-list');
const tags = [...new Set(allPosts.flatMap(p => p.tags || []))].sort();
tagsList.innerHTML = '';
if (!tags.length) return;
const makeTagButton = (label, tagValue) => {
const li = document.createElement('li');
const btn = document.createElement('button');
btn.textContent = label;
btn.className = 'tag-btn' + (activeTag === tagValue ? ' active' : '');
btn.onclick = () => {
activeTag = tagValue;
renderTags();
renderPosts();
};
li.appendChild(btn);
tagsList.appendChild(li);
};
makeTagButton('all', null);
tags.forEach(tag => makeTagButton(tag, tag));
}
function renderPosts() {
const list = document.getElementById('posts-list');
const posts = activeTag
? allPosts.filter(p => (p.tags || []).includes(activeTag))
: allPosts;
list.innerHTML = '';
if (!posts.length) {
list.innerHTML = '<li>No posts' + (activeTag ? ' tagged \u201c' + activeTag + '\u201d' : '') + '.</li>';
return;
}
posts.forEach(post => {
const li = document.createElement('li');
const a = document.createElement('a');
const i = document.createElement('i');
a.textContent = post.title;
i.textContent = post.date;
a.href = post.type === 'html'
? 'posts/' + post.file
: 'post.html?file=' + encodeURIComponent(post.file);
li.appendChild(a);
a.appendChild(i);
i.classList.add("post-link-date");
list.appendChild(li);
});
}
document.addEventListener('DOMContentLoaded', loadPosts);
</script>
</body> </body>
</html>

0
old/css/hex-logo.animate.css Normal file → Executable file
View File

33
old/css/master.css Normal file → Executable file
View File

@@ -154,30 +154,25 @@ body {
width: 100%; width: 100%;
} }
.projects-box { .project-card {
display: flex; margin-bottom: 40px;
flex-wrap: wrap; }
margin: auto;
max-width: 70%;
} .projects-box .card { .project-card img {
margin: auto; width: 10%;
padding-bottom: 30px; height: auto;
} .projects-box img { margin-top: 20px;
width: 100%; border: 2px solid var(--color-pallete-red);
height: 100%; }
border-top-right-radius: 10%;
border-top-left-radius: 1%; .project-card .hexlink {
font-size: 2em;
} }
@media (max-width: 1000px) @media (max-width: 1000px)
{ {
.projects-box { .project-card img {
display: block; width: 40%;
margin: 0 30px 0 30px;
} .projects-box .card {
margin: auto;
padding: 20px 0 20px 0;
} }
} }

0
colorpallete.png → old2/colorpallete.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

0
critterfolio/icon.ico → old2/critterfolio/icon.ico Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

0
critterfolio/icon.svg → old2/critterfolio/icon.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 269 KiB

View File

176
old2/css/main.css Executable file
View File

@@ -0,0 +1,176 @@
:root {
--color-background: #010101;
--color-foreground: #4d6e8d;
--frame-spacing: 15px;
--frame-border-radius: 10px;
--main-view-width: 80vw;
}
* {
margin: 0;
padding: 0;
font-family: monospace;
}
html {
background-color: var(--color-background);
color: var(--color-foreground);
}
#page-heading {
font-size: 30pt;
text-align: center;
font-style: italic;
letter-spacing: 0.10em;
}
@media (max-width: 900px) {
#main {
width: 90vw !important;
}
#page-heading {
font-size: 20pt;
}
}
#main {
margin-top: 20px;
margin-bottom: 100px;
width: var(--main-view-width);
display: flex;
flex-wrap: wrap;
align-items: stretch;
padding: 20px;
gap: var(--frame-spacing);
margin-inline: auto;
}
#main > * {
flex: 1 1 auto;
}
#tui-status-bar {
width: 100vw;
border-top: 2px solid var(--color-foreground);
position: fixed;
left: 0;
bottom: 0;
background-color: var(--color-background);
color: var(--color-foreground);
padding: 20px;
max-height: 30px;
display: flex;
font-size: 10pt;
}
#tui-status-bar p {
margin-left: 10px;
margin-right: 10px;
}
#tui-status-bar p::before {
content: ':';
margin-right: 3px;
}
/* TUI FRAME */
.tui-frame {
width: auto;
height: auto;
padding: 20px;
border: 2px solid var(--color-foreground);
border-radius: var(--frame-border-radius);
position: relative;
display: flex;
}
.tui-frame-header {
position: absolute;
top: 0;
left: 20px;
transform: translateY(-50%);
background-color: var(--color-background);
padding: 0 10px;
text-transform: uppercase;
letter-spacing: 0.15em;
}
.tui-frame-content * {
font-size: 14pt;
/* display: block; */
}
.tui-frame-content p {
margin-bottom: 30px;
}
.tui-frame-content h2 {
font-size: 19pt;
font-style: italic;
letter-spacing: 0.15em;
text-transform: uppercase;
margin-top: 20px;
}
.tui-frame-content h2::before {
content: '//';
}
.tui-frame-content li {
display: flex;
align-items: center;
margin-top: 5px;
align-items: baseline;
}
.tui-frame-content li::before {
content: "*";
display: inline;
margin-right: 5px;
}
.tui-frame-single-image {
display: block;
margin: auto;
width: 80%;
}
.tui-frame-section {
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin-bottom: 10px;
gap: 10px;
}
.tui-frame-section * {
margin-right: 10px;
}
/* CONTROLS */
button {
color: var(--color-foreground);
background-color: transparent;
border: 2px solid var(--color-foreground);
padding: 5px;
text-decoration: underline;
}
button:hover {
transform: scale(1.05, 1.05);
}
a {
text-decoration: underline;
color: var(--color-foreground);
font-style: italic;
display: inline !important;
}
input {
color: var(--color-foreground);
background-color: transparent;
border: 2px solid var(--color-foreground);
padding: 5px;
text-decoration: underline;
}

0
hex-logo-animate.html → old2/hex-logo-animate.html Normal file → Executable file
View File

156
old2/index.html Executable file
View File

@@ -0,0 +1,156 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/main.css">
<script type="module" src="scripts/main.js"></script>
<title>// HEX STUDIOS //</title>
</head>
<body>
<div id="main">
<h1 id="page-heading">// HEX STUDIOS //</h1>
<div class="tui-frame">
<h2 class="tui-frame-header">WELCOME</h2>
<div class="tui-frame-content">
<p>Hello! My name is Chris. Welcome to my personal portfolio site!</p>
<h2>About Me</h2>
<p>I am a husband, programmer, musician, and all around nerd! I like to make games and software, as well as tinker with robots and motorcycles. I am a huge advocate for FOSS (Free and Open Source Software), a Linux user for well over 12 years, and a novice homelabber.</p>
<p>I am primarily a Software Engineer by trade with a Bachelor's in Sotware Engineering and ~5 years of professional experience, where the majority of my knowledge is in C#/.NET, XAML, and HTML/CSS. I am also proficient in many other languages like Odin, C/C++, Java, QML, and JavaScript.</p>
<p>I am also the CEO and Co-Founder of <a href="https://bellsworne.com">Bellsworne LLC.</a> with my wife Alex.</p>
</div>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">IMAGE</h2>
<div class="tui-frame-content">
<img class="tui-frame-single-image" src="res/chris2.jpg" />
</div>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">credentials</h2>
<div class="tui-frame-content">
<h2>Education</h2>
<ul>
<li>Bachelors, Software Engineering - 2026</li>
<li>Associates, Computer Science - 2022</li>
</ul>
<h2>Experience</h2>
<ul>
<li>Software Engineer (C#, .NET, Unity) - 4 years</li>
<li>Computer Technician (Repair, IT) - 2 years</li>
</ul>
<h2>Certs</h2>
<ul>
<li>CompTIA Project+</li>
<li>AWS Certified Cloud Practitioner</li>
</ul>
</div>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">LINKS</h2>
<div class="tui-frame-content">
<ul>
<li><a href="https://git.bellsworne.tech">Git repos</a></li>
<li><a href="https://bellsworne.com">Bellsworne</a></li>
<li><a href="https://youtube.com/@hexstudios">Youtube</a></li>
<li><a href="https://www.linkedin.com/in/christopher-i-bell/">LinkedIn</a></li>
</ul>
</div>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">SITE SETTINGS</h2>
<div class="tui-frame-content">
<p>Change site colors, spacing, and borders</p>
<div class="tui-frame-section" id="settings-form">
<label for="foreground-setting">Foreground Color</label>
<input type="text" name="foreground-setting" id="foreground-setting">
<label for="background-setting">Background Color</label>
<input type="text" name="background-setting" id="background-setting">
<label for="frame-spacing-setting">Frame Spacing</label>
<input type="number" name="frame-spacing-setting" id="frame-spacing-setting" min="5" max="50" value="10">
<label for="frame-border-radius-setting">Frame Rounding</label>
<input type="number" name="frame-border-radius-setting" id="frame-border-radius-setting" min="0" max="50" value="10">
<button type="button" id="save-settings-button">SAVE</button>
<button type="button" id="reset-settings-button">RESET</button>
</div>
</div>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">projects</h2>
<div class="tui-frame-content">
<h2>SessionZero</h2>
<p>SessionZero is a data-driven TTRPG companion application for managing characters, sessions, and game data.</p>
<p>This is my passion project, and is currently a work in progress. Its core is developed using C# with .NET 8.</p>
<p>Visit <a href="https://sessionzero.app">sessionzero.app</a> to learn more, or <a href="https://git.bellsworne.tech/Bellsworne/sessionzero-cs">view the source code.</a></p>
<h2>Critterfolio</h2>
<p>A simple cross-platform full-stack application for managing your critters, for farms or pet owners. Made in C# with Avalonia UI.</p>
<p>This project was developed as my Software Engineering Capstone project, but the idea came from my wife who breeds goats and needed an easy way to track linage and other notes about her goats. It still needs some work, but you can download it for Windows, Linux, or Android <a href="critterfolio/index.html">HERE</a>.</p>
<h2>Let there be blight</h2>
<p>A game made in 72 hours for the MiniJam #150 game jam, made in Godot. <a href="/dev/blight">-- Click here to play in your browser! --</a></p>
<h2>Cogwheel</h2>
<p>A C# .NET 9 library that provides a robust and extendible Command and Developer Console system for Games and Software applications. <a href="https://git.bellsworne.tech/Bellsworne/Cogwheel">-- Click here to view on Gitea --</a></p>
<h2>Interactive Map</h2>
<p>An interactive world map that uses the <a href="https://worldbank.org">World Bank</a> REST API to display country information. Made as a school project in AngularJS. <a href="dev/interactive-angular-map">-- Click here to access-- </a></p>
<h2>Stars</h2>
<p>A really simple plain JS webpage that randomly generates a lot of stars. <a href="dev/stars/index.html">-- Click here to view --</a></p>
<h2>More</h2>
<p>To see more of my personal or professional projects, see my <a href="https://git.bellsworne.tech">Git repos</a> page.</p>
</div>
</div>
<!-- <div class="tui-frame"> -->
<!-- <h2 class="tui-frame-header">notice</h2> -->
<!-- <div class="tui-frame-content" style="width: 100%; display: flex; justify-content: center; text-align: center;"> -->
<!-- <p style="font-size: 20pt; color: darkred;">SAY NO TO GENERATIVE AI</p> -->
<!-- </div> -->
<!-- </div> -->
<!-- <div class="tui-frame">
<h2 class="tui-frame-header">motto</h2>
<p>Say No To AI</p>
</div>
<div class="tui-frame">
<h2 class="tui-frame-header">motto</h2>
<p>Say No To AI</p>
</div> -->
</div>
<div id="tui-status-bar">
<p>COPYRIGHT 2026 <a href="https://bellsworne.com">BELLSWORNE LLC</a></p>
<p><a href="https://git.bellsworne.tech/chrisbell/hexstudios-co">Source Code</a></p>
</div>
<!-- Keep android open banner -->
<script src="https://keepandroidopen.org/banner.js"></script>
</body>

0
projectvii.html → old2/projectvii.html Normal file → Executable file
View File

96
old2/scripts/main.js Executable file
View File

@@ -0,0 +1,96 @@
const r = document.querySelector(':root');
const fgInput = document.getElementById('foreground-setting');
const bgInput = document.getElementById('background-setting');
const spacingInput = document.getElementById('frame-spacing-setting');
const radiusInput = document.getElementById('frame-border-radius-setting');
const saveBtn = document.getElementById('save-settings-button');
const resetBtn = document.getElementById('reset-settings-button');
let lightMode = false;
const defaultSettings = {
foreground: "#4d6e8d",
background: "#010101",
spacing: "15px",
radius: "10px"
};
saveBtn.addEventListener('click', () => {
const currentSettings = {
foreground: fgInput.value,
background: bgInput.value,
spacing: spacingInput.value + 'px',
radius: radiusInput.value + 'px'
};
setForegroundColor(currentSettings.foreground);
setBackgroundColor(currentSettings.background);
setFrameSpacing(currentSettings.spacing);
setFrameBorderRadius(currentSettings.radius);
localStorage.setItem('user-settings', JSON.stringify(currentSettings));
});
resetBtn.addEventListener('click', () => {
localStorage.setItem('user-settings', JSON.stringify(defaultSettings));
loadStoredSettings();
syncSettings();
});
function setForegroundColor(color) {
r.style.setProperty('--color-foreground', color);
}
function setBackgroundColor(color) {
r.style.setProperty('--color-background', color);
}
function setFrameSpacing(amount) {
r.style.setProperty('--frame-spacing', amount);
}
function setFrameBorderRadius(amount) {
r.style.setProperty('--frame-border-radius', amount);
}
function syncSettings() {
const rootStyles = getComputedStyle(document.documentElement);
const varMap = {
'foreground-setting': '--color-foreground',
'background-setting': '--color-background',
'frame-spacing-setting': '--frame-spacing',
'frame-border-radius-setting': '--frame-border-radius'
};
for (const [id, variable] of Object.entries(varMap)) {
const element = document.getElementById(id);
if (element) {
let cssValue = rootStyles.getPropertyValue(variable).trim();
if (element.type === 'number') {
element.value = parseFloat(cssValue) || 0;
} else {
element.value = cssValue;
}
}
}
}
function loadStoredSettings() {
const saved = localStorage.getItem('user-settings');
if (saved) {
const settings = JSON.parse(saved);
setForegroundColor(settings.foreground);
setBackgroundColor(settings.background);
setFrameSpacing(settings.spacing);
setFrameBorderRadius(settings.radius);
}
}
loadStoredSettings();
syncSettings();

0
secret.html → old2/secret.html Normal file → Executable file
View File

144
post.html Normal file
View File

@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Post</title>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js/styles/github.min.css">
<script src="https://cdn.jsdelivr.net/npm/highlight.js/lib/common.min.js"></script>
<script>
(function() {
var stored = localStorage.getItem('theme');
if (stored === 'light') document.documentElement.setAttribute('data-theme', 'light');
})();
function toggleTheme() {
var isLight = document.documentElement.getAttribute('data-theme') === 'light';
if (isLight) {
document.documentElement.removeAttribute('data-theme');
localStorage.setItem('theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
}
</script>
<link rel="stylesheet" href="styles/master.css">
</head>
<body>
<div class="wrap">
<a class="back-link" href="index.html">&larr; Return home</a>
<button id="theme-toggle" onclick="toggleTheme()">toggle light/dark</button>
<p class="meta" id="meta" hidden></p>
<div id="content"><p class="state">Loading post&hellip;</p></div>
</div>
<script>
function parseFrontMatter(raw) {
const match = raw.match(/^---\r?\n([\s\S]+?)\r?\n---\r?\n([\s\S]*)$/);
if (!match) return { meta: {}, body: raw };
const meta = {};
match[1].split(/\r?\n/).forEach(line => {
const idx = line.indexOf(':');
if (idx === -1) return;
const key = line.slice(0, idx).trim();
let value = line.slice(idx + 1).trim();
// strip optional surrounding quotes: title: "My Post"
value = value.replace(/^["'](.*)["']$/, '$1');
meta[key] = value;
});
return { meta, body: match[2] };
}
function formatDate(dateStr) {
if (!dateStr) return '';
const d = new Date(dateStr);
if (isNaN(d)) return dateStr; // fall back to raw string if unparseable
return d.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });
}
function showError(message) {
document.getElementById('content').innerHTML =
`<p class="state error">${message}</p>`;
}
// ---- main ------------------------------------------------------------
marked.setOptions({
highlight: (code, lang) => {
try {
return lang
? hljs.highlight(code, { language: lang }).value
: hljs.highlightAuto(code).value;
} catch (e) {
return code;
}
}
});
async function loadPost() {
const params = new URLSearchParams(window.location.search);
const file = params.get('file');
if (!file) {
showError('No post specified. Link to this page as <code>post.html?file=your-post.md</code>.');
return;
}
// Guard against path traversal — keep the fetch confined to posts/
if (file.includes('..') || file.startsWith('/')) {
showError('Invalid post path.');
return;
}
try {
const res = await fetch('posts/' + file);
if (!res.ok) throw new Error('HTTP ' + res.status);
const raw = await res.text();
const { meta, body } = parseFrontMatter(raw);
const html = marked.parse(body);
document.getElementById('content').innerHTML = html;
// Title: front matter > first H1 in the doc > filename
let title = meta.title;
if (!title) {
const h1 = document.querySelector('#content h1');
title = h1 ? h1.textContent : file.replace(/\.md$/, '');
}
document.title = title;
// Inject an H1 if front matter supplied a title but the body didn't have one
if (meta.title && !document.querySelector('#content h1:first-child')) {
const h1 = document.createElement('h1');
h1.textContent = meta.title;
document.getElementById('content').prepend(h1);
}
// Meta line: date (and tags, if present)
const metaEl = document.getElementById('meta');
const parts = [];
if (meta.date) parts.push(formatDate(meta.date));
if (meta.tags) parts.push(meta.tags.split(',').map(t => t.trim()).join(' &middot; '));
if (parts.length) {
metaEl.innerHTML = parts.join(' &nbsp;/&nbsp; ');
metaEl.hidden = false;
}
} catch (err) {
showError('Could not load this post. It may have been moved or deleted.');
}
}
document.addEventListener('DOMContentLoaded', loadPost);
</script>
</body>
</html>

37
posts/about.md Normal file
View File

@@ -0,0 +1,37 @@
---
title: About
date: 2026-08-13
tags: about-me
---
# About Hex Studios
## // What is this?
Good question. It *was* my personal portfolio site, used for listing on applications to corporate slop jobs, but over time I just grew into wanting this place to be a space where I can be unapologetically ***me***. You can still visit the old site [here](old2/index.html) if you want. It's pretty cool.
So thats what this is. I'll still list my credentials and who I am, but I won't shy away from being me.
## // Well then, who are you?
My name is Chris. I make stuff, sometimes. By day I'm a software engineer working with C# and unity. I love programming and old technology, I spend my time outside of work learning the ins-and-outs of computers and electronics in general, using C and C++ to mess with native applications and embedded firmware, hoping to one day reclaim the magic of technology from the souless corporate sphere it currently lives in.
Some of my hobbies include: Making and enjoying music, motorcycles, game development, light gaming (mostly indie games and older titles), homelabbing, poking at old technology.
Oh yeah I also run a small company with my wife called Bellsworne. You should [check us out](https://bellsworne.com).
## // My Creds:
### Education:
- B.S. Software Engineering
- A.S. Computer Science
- CompTIA Project Managment+ Certification
### Professional:
- 5+ years of software engineering, primarily in C#/.NET
- ~2 years of electronics repair (phones, laptops, etc)
*I was also a barista for two years, who'uld've thunk it lol*
### Personal:
- 13+ years of linux experience (I use NixOS, btw)
- 10+ years of C/C++
- 10+ years of HTML/CSS
- Other languages, experience varies: Odin, Python, JS, Java

41
posts/feed.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
require __DIR__ . '/posts.php';
$siteUrl = 'https://hexstudios.co';
$siteTitle = 'Hex Studios';
$siteDesc = 'Developer, biker, musician, engineer, and an unapologetic centrist in the deep red south.';
$posts = getPosts(__DIR__);
function xmlEscape($str) {
return htmlspecialchars($str, ENT_XML1 | ENT_QUOTES, 'UTF-8');
}
header('Content-Type: application/rss+xml; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
?>
<rss version="2.0">
<channel>
<title><?= xmlEscape($siteTitle) ?></title>
<link><?= xmlEscape($siteUrl) ?></link>
<description><?= xmlEscape($siteDesc) ?></description>
<language>en-us</language>
<lastBuildDate><?= date(DATE_RSS) ?></lastBuildDate>
<?php foreach ($posts as $post):
$postUrl = $post['type'] === 'html'
? $siteUrl . '/posts/' . $post['file']
: $siteUrl . '/post.html?file=' . urlencode($post['file']);
?>
<item>
<title><?= xmlEscape($post['title']) ?></title>
<link><?= xmlEscape($postUrl) ?></link>
<guid isPermaLink="true"><?= xmlEscape($postUrl) ?></guid>
<pubDate><?= date(DATE_RSS, $post['created']) ?></pubDate>
<description><?= xmlEscape($post['excerpt']) ?></description>
<?php foreach ($post['tags'] as $tag): ?>
<category><?= xmlEscape($tag) ?></category>
<?php endforeach; ?>
</item>
<?php endforeach; ?>
</channel>
</rss>

12
posts/list.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
header('Content-Type: application/json');
require __DIR__ . '/posts.php';
$posts = getPosts(__DIR__);
$posts = array_map(function ($p) {
unset($p['excerpt']);
return $p;
}, $posts);
echo json_encode($posts);

54
posts/my-views.md Normal file
View File

@@ -0,0 +1,54 @@
---
title: My Views
date: 2026-08-13
tags: about-me, society, politics
---
# My World Views
This is going to be a hard thing to write about, for obvious reasons. And I won't go in depth on every issue, but I'll give a surface level look on some of the things I find most important.
## // Background
A little background as to who I am and where I come from; I'm not important by any means, so don't take my words as such, I'm just a white guy from the rural southern US. I just think context is important to get the picture though.
### *So, where am I from?*
Alabama. Yes, queue the jokes, I know them all. The incest jokes are old and irrelevant, but the ones about backwoods MAGA loving racists? I can't say the same for those ones. The state hasn't really been doing itself any favours with it's political candidates and weird policies.
As you can imagine growing up in rural Alabama, up until my late teens I flip flopped on whether I considered myself a conservative or a libertarion. Same for my parents. That being said, it was very much a case of: we subscribed to those viewpoints because it's what you did. You were either a christian conservative or you get shunned and socially outcast around here for thinking differently. Actually, for just *thinking* in general sometimes. Thankfully my mom and dad have both moved passed those dangerous views alongside me, we grew together and were able to take off the rose tinted glasses we were forced to see everything through.
We were always poor. Not for a lack of trying though. We always found a place to live when we needed to, but always had to keep moving to the next place we could barely afford before it got ripped out from under us for one reason or another. My mom has always been sick, dealing with consistent health issue after health issue, some chronic, some that the doctors just never put any effort into figuring out. She has always battled insurance completely wrecking her world, be that a change in medication, denying life saving procedures, or just being completely unaffordable. She has two degrees, one even in computer science, yet cannot find a job she can work because of disabilities, age, and work history gap. Hell I can't even find other jobs in my industry and I have 5 something years of experience on top of my degree. The system is just broken, and my parents still suffer from it.
### *So what do I consider myself now?*
Hard to say these days but I just consider it to be a "left leaning centrist" bordering on "democratic socialist". I despise conservatives and liberals alike, but lean more left than anything. I would rather align myself with people who slightly annoy me than associate with the actually dangerous ones.
### *My religion?*
For most of my life I would have said Christian. And while I do still believe in a God, and do identify with a lot of the teachings of Jesus, I don't subscribe to traditional Christian rhetorics of the bible being the single unquestionable source of truth. I align more with universalist views at this time.
## // Common issues and my thoughts on them
Here's where it gets dangerous.
- Fuck Trump
- Fuck ICE
- Fuck the war
- Fuck AI
- Free healthcare and school for all
- Freedom of speech and religion
- Eat the rich
- Climate change is real
- Right to repair
- LGBTQ people aren't indoctrinating your children
- We live in a post-capitalistic society, and it is broken
- The death penalty is sometimes necessary
- Pedos, Chomos, and rapists all get their bits chopped off
I think that covers most of it.
## // Final thoughts
Most important thing that I have learned: People are the cause and the reason for it all. And the people of a nation are not their government. It's hard to do, but we must love and show compassion and empathy for every person.
Give people a chance. It may take a lot of cracking at years of dried mud to get to their center, but they arent always as rotten in there as they have been conditioned to be.
Unless they prove themselves to be a total irredeemable dickhead, in which case they can rot.
*I may update this post from time to time as I remember things to add*

68
posts/posts.php Normal file
View File

@@ -0,0 +1,68 @@
<?php
function parseFrontMatter($raw) {
if (preg_match('/^---\r?\n(.+?)\r?\n---\r?\n(.*)$/s', $raw, $m)) {
$meta = [];
foreach (preg_split('/\r?\n/', $m[1]) as $line) {
if (strpos($line, ':') === false) continue;
[$key, $value] = explode(':', $line, 2);
$meta[trim($key)] = trim($value, " \t\"'");
}
return [$meta, $m[2]];
}
return [[], $raw];
}
function makeExcerpt($body, $length = 220) {
$text = preg_replace('/```.*?```/s', '', $body); // code blocks
$text = preg_replace('/[#>*_`~\[\]]/', '', $text); // markdown symbols
$text = preg_replace('/\(.*?\)/', '', $text); // link targets
$text = preg_replace('/\s+/', ' ', $text); // collapse whitespace
$text = trim($text);
if (mb_strlen($text) > $length) {
$text = mb_substr($text, 0, $length) . '…';
}
return $text;
}
function getPosts($dir) {
$skip = ['.', '..', 'list.php', 'feed.php', 'posts.php'];
$files = array_diff(scandir($dir), $skip);
$posts = [];
foreach ($files as $file) {
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (!in_array($ext, ['html', 'md'])) continue;
$path = $dir . '/' . $file;
$fallbackTitle = ucwords(str_replace(['-', '_'], ' ', pathinfo($file, PATHINFO_FILENAME)));
$created = filectime($path);
$meta = [];
$body = '';
if ($ext === 'md') {
$raw = file_get_contents($path);
[$meta, $body] = parseFrontMatter($raw);
}
$title = $meta['title'] ?? $fallbackTitle;
$date = isset($meta['date']) ? strtotime($meta['date']) : $created;
$tags = isset($meta['tags']) && trim($meta['tags']) !== ''
? array_map('trim', explode(',', $meta['tags']))
: [];
$posts[] = [
'file' => $file,
'title' => $title,
'type' => $ext,
'created' => $date ?: $created,
'date' => date('F j, Y', $date ?: $created),
'tags' => $tags,
'excerpt' => $body ? makeExcerpt($body) : '',
];
}
usort($posts, fn($a, $b) => $b['created'] - $a['created']); // newest first
return $posts;
}

75
posts/projects.md Normal file
View File

@@ -0,0 +1,75 @@
---
title: Projects
date: 2026-08-13
tags: software, games, engineering
---
# Projects (Megathread)
This post serves as a place to list all my projects, previous, ongoing, and future. It will be updated as I do more.
## // Software
### Critterfolio
[View on Gitea](https://git.bellsworne.tech/bellsworne/critterfolio)
A portfolio for your critters! Keep track of critter data from viewing a family tree to storing important notes and documents, all stored locally on your device.
- **STATUS:** In development
- **TECHNOLOGY:** C++ with the RmlUi library using the SDL3 backend
- **PLATFORMS:** Linux, Windows, Android
### SessionZero
[View website](https://sessionzero.app) | [View on Gitea](https://git.bellsworne.tech/bellsworne/sessionzero)
A data-driven, user-generated, open source TTRPG companion application for managing games, game systems, and characters.
- **STATUS:** In development
- **TECHNOLOGY:** C++ with the RmlUi library using the OpenGL backend
- **PLATFORMS:** Linux, Windows, Webassembly
### ADEPT
A secret project, for now. Not in development yet.
## // Games
### Let there be Blight
A game jam game made by a bunch of friends about a wizard saving his town from the 'blight'.
[Play in your browser!](../dev/blight/index.html)
### Shots in the Dark
My magnum opus, and a secret (for now). Not in full development yet.
- **STATUS:** In development
- **TECHNOLOGY:** Godot
- **PLATFORMS:** Linux, Windows
## // Electronics
Nothing planned yet
## // Other
### Adventures in Brandari
A current, heavily customized homebrew Dungeons and Dragons campaign in which I am the writer and the Game Master.
### Morality and Mortality
A book I am writing about our world, and the human condition.
## // Legacy/School projects
### Stars
A simple weird little webpage that procedurally generates "stars". Idk I was bored one day.
[View it here](../dev/stars/index.html)
### "Interactive world map"
A dumb school project that lists information about a continent when you hover over it.
[View in your browser](../dev/interactive-angular-map/index.html)

0
res/blight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

0
res/chris.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

0
res/chris2.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

BIN
res/cogwheel.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 KiB

0
res/hex-logo.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

0
res/map.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

0
res/project7-1080p.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

0
res/project7-card.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

0
res/project7-splash.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 879 KiB

After

Width:  |  Height:  |  Size: 879 KiB

BIN
res/seshzero.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
res/shots.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

0
res/stars.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

182
styles/master.css Normal file
View File

@@ -0,0 +1,182 @@
:root {
--background-color: #1a1a1a;
--foreground-color: #f0f0ea;
--soft-color: #8a8a82;
--accent-color: #197aa7;
--rule-color: #333330;
--code-bg: #242422;
}
[data-theme="light"] {
--background-color: #f2f0ea;
--foreground-color: #1a1a1a;
--soft-color: #6b6a63;
--accent-color: #197aa7;
--rule-color: #d8d5cb;
--code-bg: #e8e5da;
}
* {
font-family: 'Times New Roman', Times, serif;
color: var(--foreground-color);
box-sizing: border-box;
}
body {
background-color: var(--background-color);
width: 80%;
max-width: 700px;
margin: auto;
padding-top: 4%;
padding-bottom: 6%;
font-size: 12pt;
line-height: 1.6;
}
a {
color: var(--accent-color);
}
a:hover {
text-decoration: none;
}
hr {
border: none;
border-top: 1px solid var(--rule-color);
margin: 2em 0;
}
/* theme toggle */
#theme-toggle {
background: none;
border: 1px solid var(--rule-color);
color: var(--soft-color);
font-size: 10pt;
padding: 0.2em 0.6em;
cursor: pointer;
}
#theme-toggle:hover {
color: var(--accent-color);
border-color: var(--accent-color);
}
/* tag filter row */
#tags-list {
list-style: none;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 1em;
margin: 0.5em 0 1.5em;
}
.tag-btn {
background: none;
border: none;
color: var(--soft-color);
font-size: 11pt;
font-family: 'Times New Roman', Times, serif;
cursor: pointer;
padding: 0;
}
.tag-btn:hover {
color: var(--accent-color);
}
.tag-btn.active {
color: var(--accent-color);
text-decoration: underline;
}
/* post lists on the main page */
.custom-list {
list-style: none;
padding: 0;
}
.custom-list li {
margin: 0.5em 0;
}
.custom-list li::before {
content: "> ";
}
i.post-link-date {
font-style: italic;
color: var(--soft-color);
font-size: 11pt;
text-decoration: none;
}
i.post-link-date::before {
content: " // ";
}
/* post.html */
.back-link {
display: inline-block;
font-size: 10pt;
color: var(--soft-color);
text-decoration: none;
margin-bottom: 2em;
}
.back-link:hover {
color: var(--accent-color);
}
.meta {
font-size: 10pt;
color: var(--soft-color);
margin: 0 0 1em;
}
#content h1:first-child {
font-size: 1.8em;
margin: 0 0 0.4em;
}
#content h1,
#content h2,
#content h3 {
margin-top: 1.6em;
margin-bottom: 0.5em;
}
#content h2 {
border-bottom: 1px solid var(--rule-color);
padding-bottom: 0.2em;
}
#content p {
margin: 1em 0;
}
#content blockquote {
margin: 1.2em 0;
padding-left: 1em;
border-left: 2px solid var(--accent-color);
color: var(--soft-color);
font-style: italic;
}
#content code {
font-family: Consolas, Menlo, monospace;
font-size: 0.9em;
background: var(--code-bg);
padding: 0.1em 0.35em;
}
#content pre {
background: var(--code-bg);
padding: 1em;
overflow-x: auto;
line-height: 1.5;
}
#content pre code {
background: none;
padding: 0;
}
.state {
color: var(--soft-color);
font-size: 10pt;
}
.state.error {
color: var(--accent-color);
}