Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions _data/experiments.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2025 Damien Boisvert (AlphaGameDeveloper)
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT

## Site experiments - to be presented to alejandra :3
experiment_post_userbio: false
experiment_hero_humanreading: false
2 changes: 1 addition & 1 deletion _includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<span class="parish-name">{{ site.data.header.navbar.title }}</span>
<span class="program-name d-none d-md-inline">{{ site.data.header.navbar.subtitle }}</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
<button class="navbar-toggler" type="button" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
Expand Down
9 changes: 9 additions & 0 deletions _layouts/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,18 @@ <h1 class="post-title">{{ page.title }}</h1>
<article class="post-content">
{{ content }}
</article>

{% if site.data.experiments.experiment_post_userbio %}
<section id="author-tag">
{% include author-tag.html %}
</section>
{% endif %}

<div class="post-tags">
{% for tag in page.tags %}
<span class="badge bg-secondary">{{ tag }}</span>
{% endfor %}
</div>
<div class="post-navigation mt-5 pt-4 border-top">
<div class="row">
<div class="col-md-6">
Expand Down
198 changes: 198 additions & 0 deletions _sass/_navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,199 @@
}
}

// Mobile navigation full-screen overlay
@media (max-width: 991.98px) {
.navbar-collapse {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: linear-gradient(145deg,
rgba(26, 26, 26, 0.98) 0%,
rgba(40, 40, 40, 0.95) 50%,
rgba(20, 20, 30, 0.98) 100%);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
z-index: 9999;
display: flex !important;
flex-direction: column;
justify-content: center;
align-items: center;
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);

// Add subtle pattern overlay
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: radial-gradient(circle at 25% 25%, rgba(255, 255, 255, 0.02) 0%, transparent 50%),
radial-gradient(circle at 75% 75%, rgba(255, 255, 255, 0.02) 0%, transparent 50%);
pointer-events: none;
}

&.show {
opacity: 1;
visibility: visible;
transform: scale(1);
}
}

.navbar-nav {
flex-direction: column;
align-items: center;
gap: 0.4rem;
margin: 0;
padding: 0;
position: relative;
z-index: 1;
}

.nav-item {
transform: translateY(50px);
opacity: 0;
width: 100%;
max-width: 220px;

.navbar-collapse.show & {
animation: slideInUp 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;

&:nth-child(1) { animation-delay: 0.1s; }
&:nth-child(2) { animation-delay: 0.15s; }
&:nth-child(3) { animation-delay: 0.2s; }
&:nth-child(4) { animation-delay: 0.25s; }
&:nth-child(5) { animation-delay: 0.3s; }
&:nth-child(6) { animation-delay: 0.35s; }
}
}

.nav-link {
font-size: 1.1rem !important;
font-weight: 400 !important;
letter-spacing: 0.3px;
padding: 0.8rem 1.5rem !important;
margin: 0.2rem 0;
border-radius: 8px;
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
position: relative;
width: 100%;
max-width: 220px;
text-align: center;
color: rgba(255, 255, 255, 0.9) !important;
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.03);

// Subtle glow effect
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 8px;
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.05), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}

&:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
color: white !important;

&::before {
opacity: 1;
}
}

&.active {
background: linear-gradient(135deg, $secondary-color, color.scale($secondary-color, $lightness: 10%));
border-color: $secondary-color;
color: white !important;
transform: translateY(-1px);
box-shadow: 0 5px 15px rgba($secondary-color, 0.3);

&::after {
display: none;
}
}
}

.navbar-toggler {
z-index: 10000;
border: none;
padding: 0.5rem;

&:focus {
box-shadow: none;
}
}

// Hamburger animation
.navbar-toggler-icon {
background-image: none;
width: 24px;
height: 2px;
background-color: white;
position: relative;
transition: all 0.3s ease;

&::before,
&::after {
content: "";
position: absolute;
width: 24px;
height: 2px;
background-color: white;
transition: all 0.3s ease;
}

&::before {
top: -8px;
}

&::after {
top: 8px;
}
}

.navbar-toggler[aria-expanded="true"] .navbar-toggler-icon {
background-color: transparent;

&::before {
transform: rotate(45deg);
top: 0;
}

&::after {
transform: rotate(-45deg);
top: 0;
}
}
}

@keyframes slideInUp {
to {
transform: translateY(0);
opacity: 1;
}
}

.navbar-brand {
display: flex;
flex-direction: column;
line-height: 1.2;
z-index: 10000;
position: relative;
}

.parish-name {
Expand Down Expand Up @@ -58,3 +247,12 @@
background-color: $secondary-color;
}
}

// Desktop-specific styles
@media (min-width: 992px) {
.navbar-nav .nav-link {
&.active::after {
display: block;
}
}
}
65 changes: 33 additions & 32 deletions assets/images/hero-animation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 14 additions & 6 deletions assets/js/healthcheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

(() => {console.log("[healthcheck] Initializing healthcheck script")})();

const updateHealthStatus = () => {
console.log("[updateHealthStatus] Checking backend health status...");
const emojis = {
Expand All @@ -19,7 +21,8 @@ const updateHealthStatus = () => {
const statusDot = healthElement.querySelector('.status-dot');
const statusText = healthElement.querySelector('.status-text');

fetch(`${window.backendBaseURL}/healthcheck?fcnl=1`, {
let startTime = Date.now();
fetch(`${window.backendBaseURL}/healthcheck?fcnl=1&c=1`, { //c - server-side cache
method: 'GET',
cache: 'no-cache',
headers: {
Expand All @@ -30,10 +33,15 @@ const updateHealthStatus = () => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

responseMilliseconds = Date.now() - startTime;

Copilot AI Aug 13, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable responseMilliseconds is declared without let, const, or var, making it an implicit global variable. This should be declared with let or const to avoid polluting the global scope.

Copilot uses AI. Check for mistakes.
console.log("[updateHealthStatus] Backend health status fetched successfully. (Took " + responseMilliseconds + " ms)");
statusDot.title = `Last checked: ${new Date().toLocaleTimeString()}`;
console.log("X-Cache: " + response.headers.get("X-Cache"));
return response.json();
})
.then(data => {
console.log("[updateHealthStatus] Backend health status data:", data);
if (data.status === 'healthy') {
statusDot.textContent = emojis['healthy'];
statusText.textContent = 'All Systems Operational';
Expand All @@ -55,9 +63,9 @@ const updateHealthStatus = () => {
});
}

setInterval(updateHealthStatus, 60000);
setInterval(() => {updateHealthStatus()}, 60000);

document.addEventListener('DOMContentLoaded', () => {
console.log("[healthcheck] Firing updateHealthStatus");
setTimeout(() => {updateHealthStatus()}, 250);
});
// This second `setTimeout` is a workaround for Safari.
// No idea why this works, or why it's needed, but if it ain't broke,
// don't fix it.
setTimeout(() => {updateHealthStatus()}, 100);
Loading
Loading