From a8ac8c238c8747716b816c637df05f5021d9d67f Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 5 May 2026 16:29:07 -0700 Subject: [PATCH] fix visual bugs + enhance sections + revise project orders --- about.html | 14 +++--- index.html | 2 +- projects.html | 5 +++ public/content/index.json | 34 ++++++++++++--- public/css/about.css | 63 +++++++++++++++++++++++++-- public/css/projects.css | 28 ++++++++++++ public/css/style.css | 18 +------- public/scripts/content.js | 79 ++++++++++++++++++++++++++++++++-- public/scripts/hero-effects.js | 22 +--------- 9 files changed, 206 insertions(+), 59 deletions(-) diff --git a/about.html b/about.html index 21ea3f5..1c83065 100755 --- a/about.html +++ b/about.html @@ -93,7 +93,7 @@
  • Python3+
  • Git, Github, GitLab
  • Docker
  • -
  • MongoDB & SQL
  • +
  • MongoDB & PostgreSQL
  • Windows/Debian based OS
  • Data Structures & Algorithms
  • System Administration
  • @@ -129,15 +129,15 @@

    Highlights

    -
    Red Team Hackathon — 3rd Place
    +
    Red Team Hackathon - 3rd Place
    Team Cerberus Gate earned a third-place finish at the inaugural Red Team Hackathon for building a working prototype around signal classification and emitter tracking. -
    - -
    Best Dressed Award
    -
    - Team Cerberus Gate also received the Best Dressed Award during the same hackathon event. + Read the full write-up +
    + Additional recognition +

    Best Dressed Award at the inaugural Red Team Hackathon.

    +
    Capstone Project Recognition
    diff --git a/index.html b/index.html index ad37800..513dd6e 100755 --- a/index.html +++ b/index.html @@ -91,7 +91,7 @@
    BCIT CST Diploma - Backend Systems + C4A President Hackathon Podium Finiher
    diff --git a/projects.html b/projects.html index 9230565..73fe3eb 100755 --- a/projects.html +++ b/projects.html @@ -91,6 +91,11 @@

    Loading projects...

    +
    diff --git a/public/content/index.json b/public/content/index.json index c223c89..dcef4f4 100644 --- a/public/content/index.json +++ b/public/content/index.json @@ -31,7 +31,7 @@ "github": "https://github.com/SowinskiBraeden/school-management-api", "demo": null, "featured": true, - "order": 2, + "order": 6, "tags": [ "Go", "API", @@ -51,7 +51,7 @@ "github": "https://github.com/LinesMerrill/police-cad", "demo": "https://www.linespolice-cad.com/", "featured": false, - "order": 3, + "order": 4, "tags": [ "Node.js", "Express", @@ -71,7 +71,7 @@ "github": "https://github.com/SowinskiBraeden/boker", "demo": null, "featured": true, - "order": 4, + "order": 2, "tags": [ "Python", "Flask", @@ -93,7 +93,7 @@ "github": "https://github.com/SowinskiBraeden/dayz-reforger", "demo": null, "featured": true, - "order": 4, + "order": 3, "tags": [ "Node.js", "Discord.js", @@ -114,7 +114,7 @@ "github": "https://github.com/SowinskiBraeden/XP-System", "demo": null, "featured": false, - "order": 5, + "order": 7, "tags": [ "Web App", "Education Tech", @@ -133,7 +133,7 @@ "github": "https://github.com/SowinskiBraeden/SowinskiBraeden", "demo": null, "featured": false, - "order": 6, + "order": 5, "tags": [ "HTML", "CSS", @@ -183,6 +183,26 @@ "BICT" ], "path": "./public/content/updates/joined-bcit-computing-club.md" + }, + { + "title": "Appointed President of Coding 4 All (C4A)", + "slug": "appointed-president-c4a", + "type": "updates", + "summary": "Appointed to lead Coding 4 All at BCIT, helping guide student events, technical community-building, and collaboration across computing initiatives.", + "label": "Update", + "date": "2026-05-04", + "status": "Leadership", + "github": null, + "demo": null, + "featured": true, + "order": 20, + "tags": [ + "Leadership", + "BCIT", + "Community", + "C4A" + ], + "path": "./public/content/updates/appointed-president-c4a.md" } ] -} \ No newline at end of file +} diff --git a/public/css/about.css b/public/css/about.css index 9701806..4ca031e 100755 --- a/public/css/about.css +++ b/public/css/about.css @@ -41,9 +41,30 @@ section { transition: 0.8s; padding: 24px; - background-color: var(--menu-text-bg); - border-radius: 18px; - border: 1px solid var(--border); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.025)), + linear-gradient(135deg, rgba(235, 82, 52, 0.05), transparent 48%), + rgba(20, 21, 24, 0.36); + border-radius: 22px; + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: + 0 18px 44px rgba(0, 0, 0, 0.16), + inset 0 1px 0 rgba(255, 255, 255, 0.12), + inset 0 -1px 0 rgba(255, 255, 255, 0.03); + backdrop-filter: blur(14px) saturate(120%); + -webkit-backdrop-filter: blur(14px) saturate(120%); +} + +body.light section { + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.68), rgba(255, 255, 255, 0.42)), + linear-gradient(135deg, rgba(235, 82, 52, 0.04), transparent 48%), + rgba(255, 255, 255, 0.34); + border-color: rgba(255, 255, 255, 0.52); + box-shadow: + 0 16px 36px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.72), + inset 0 -1px 0 rgba(255, 255, 255, 0.22); } section h3 { @@ -74,10 +95,20 @@ section h3 { } .profile-sub { - background-color: rgba(0, 0, 0, 0.62); + background: + linear-gradient(180deg, rgba(0, 0, 0, 0.56), rgba(0, 0, 0, 0.42)), + rgba(0, 0, 0, 0.36); padding: 16px; border-radius: 14px; margin-top: 16px; + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); +} + +.profile-sub .profile-name, +.profile-sub .profile-role, +.profile-sub .profile-focus { + color: #f4f1ed; } .skills-list { @@ -103,6 +134,30 @@ dd { color: var(--muted); } +.honor-inline-link { + display: inline-block; + margin-top: 8px; +} + +.honor-subitem { + margin-top: 10px; + padding-left: 14px; +} + +.honor-subitem__label { + display: inline-block; + font-size: 0.74rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--muted); +} + +.honor-subitem__text { + margin: 4px 0 0; + color: var(--muted); +} + .honors dl, .skills-list { margin-bottom: 0; diff --git a/public/css/projects.css b/public/css/projects.css index b2de32f..460cea2 100755 --- a/public/css/projects.css +++ b/public/css/projects.css @@ -84,6 +84,10 @@ gap: 18px; } +.content-card.is-hidden { + display: none; +} + .updates-grid { grid-template-columns: 1fr; } @@ -96,6 +100,7 @@ display: flex; flex-direction: column; min-height: 100%; + scroll-margin-top: 96px; } .content-card.featured { @@ -180,6 +185,29 @@ filter: brightness(1.04); } +.projects-toggle-shell { + display: flex; + justify-content: center; + margin-top: 20px; +} + +.projects-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 999px; + border: 1px solid var(--border); + padding: 12px 18px; + font-weight: 600; + background: rgba(255, 255, 255, 0.03); + color: var(--primary); +} + +.projects-toggle:hover { + border-color: rgba(235, 82, 52, 0.32); + color: var(--secondary); +} + .updates-grid .content-card { background: linear-gradient( 180deg, diff --git a/public/css/style.css b/public/css/style.css index 024378f..c2d9b5c 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -203,10 +203,8 @@ ul { } .logo a img { - display: inline; - vertical-align: middle; + display: block; pointer-events: none; - transform: translate(0, -10%); border-radius: 6pt; margin-inline-end: 8pt; } @@ -315,16 +313,6 @@ ul { box-shadow: var(--shadow); } -.hero-main .profile, -.hero-main .svg-wrapper, -.hero-main .hero-description, -.hero-main .hero-badges, -.hero-main .hero-actions, -.hero-main .social-icons { - will-change: transform; - transition: transform 0.18s ease-out; -} - .hero-badges { display: flex; justify-content: center; @@ -660,8 +648,6 @@ body.menu-open .overlay * { :root { --hero-shell-spot-x: 50%; --hero-shell-spot-y: 28%; - --hero-shell-tilt-x: 0deg; - --hero-shell-tilt-y: 0deg; } body { @@ -725,7 +711,7 @@ button#theme-toggle { backdrop-filter: blur(22px) saturate(135%); -webkit-backdrop-filter: blur(22px) saturate(135%); isolation: isolate; - transform: perspective(1200px) rotateX(var(--hero-shell-tilt-x)) rotateY(var(--hero-shell-tilt-y)); + transform: none; transition: transform 0.18s ease-out, border-color 0.25s ease-out, box-shadow 0.25s ease-out; } diff --git a/public/scripts/content.js b/public/scripts/content.js index 1073e88..88fb445 100644 --- a/public/scripts/content.js +++ b/public/scripts/content.js @@ -78,9 +78,10 @@ const createCard = (entry) => { const formattedDate = formatDate(entry.date); const featuredClass = entry.featured ? " featured" : ""; + const anchorId = entry.slug ? ` id="${escapeHtml(entry.slug)}"` : ""; return ` -
    +
    ${escapeHtml(entry.label || entry.type)} ${formattedDate ? `${escapeHtml(formattedDate)}` : ""} @@ -107,11 +108,83 @@ container.innerHTML = entries.map(createCard).join(""); }; + const initProjectsToggle = (entries) => { + const projectsGrid = document.getElementById("projects-grid"); + const toggleShell = document.getElementById("projects-toggle-shell"); + const toggleButton = document.getElementById("projects-toggle"); + const defaultVisibleCount = 6; + + if (!projectsGrid || !toggleShell || !toggleButton) { + return; + } + + const cards = Array.from(projectsGrid.querySelectorAll(".content-card")); + if (entries.length <= defaultVisibleCount || cards.length <= defaultVisibleCount) { + toggleShell.hidden = true; + return; + } + + const setExpandedState = (expanded) => { + cards.forEach((card, index) => { + card.classList.toggle("is-hidden", !expanded && index >= defaultVisibleCount); + }); + + toggleButton.textContent = expanded ? "Show Fewer Projects" : "Show More Projects"; + toggleButton.setAttribute("aria-expanded", String(expanded)); + }; + + toggleShell.hidden = false; + setExpandedState(false); + + toggleButton.addEventListener("click", () => { + const expanded = toggleButton.getAttribute("aria-expanded") === "true"; + setExpandedState(!expanded); + }); + }; + + const compareByNewestDate = (left, right) => { + const leftTime = left.date ? Date.parse(`${left.date}T00:00:00`) : Number.NEGATIVE_INFINITY; + const rightTime = right.date ? Date.parse(`${right.date}T00:00:00`) : Number.NEGATIVE_INFINITY; + + if (leftTime !== rightTime) { + return rightTime - leftTime; + } + + const leftOrder = Number.isFinite(left.order) ? left.order : Number.MAX_SAFE_INTEGER; + const rightOrder = Number.isFinite(right.order) ? right.order : Number.MAX_SAFE_INTEGER; + + if (leftOrder !== rightOrder) { + return leftOrder - rightOrder; + } + + return String(left.title || "").localeCompare(String(right.title || "")); + }; + + const compareByPriorityOrder = (left, right) => { + const leftOrder = Number.isFinite(left.order) ? left.order : Number.MAX_SAFE_INTEGER; + const rightOrder = Number.isFinite(right.order) ? right.order : Number.MAX_SAFE_INTEGER; + + if (leftOrder !== rightOrder) { + return leftOrder - rightOrder; + } + + const leftTime = left.date ? Date.parse(`${left.date}T00:00:00`) : Number.NEGATIVE_INFINITY; + const rightTime = right.date ? Date.parse(`${right.date}T00:00:00`) : Number.NEGATIVE_INFINITY; + + if (leftTime !== rightTime) { + return rightTime - leftTime; + } + + return String(left.title || "").localeCompare(String(right.title || "")); + }; + const initListPage = async () => { try { const index = await getIndex(); - renderSection("projects-grid", index.projects || [], "No projects added yet."); - renderSection("updates-grid", index.updates || [], "No updates added yet."); + const sortedProjects = [...(index.projects || [])].sort(compareByPriorityOrder); + renderSection("projects-grid", sortedProjects, "No projects added yet."); + initProjectsToggle(sortedProjects); + renderSection("updates-grid", [...(index.updates || [])].sort(compareByNewestDate), "No updates added yet."); } catch (error) { renderSection("projects-grid", [], error.message); renderSection("updates-grid", [], error.message); diff --git a/public/scripts/hero-effects.js b/public/scripts/hero-effects.js index 1ef2258..ced719a 100644 --- a/public/scripts/hero-effects.js +++ b/public/scripts/hero-effects.js @@ -1,13 +1,7 @@ (function() { - const hero = document.querySelector(".hero-main"); const heroShell = document.querySelector(".hero-main .hero-shell"); - const profile = document.querySelector(".hero-main .profile"); - const title = document.querySelector(".hero-main .svg-wrapper"); - const descriptions = document.querySelectorAll( - ".hero-main .hero-description, .hero-main .hero-badges, .hero-main .hero-actions, .hero-main .social-icons" - ); - if (!hero || !heroShell || !profile || !title) { + if (!heroShell) { return; } @@ -25,10 +19,6 @@ const clamp = (value, min, max) => Math.min(Math.max(value, min), max); - const setTransform = (element, x, y) => { - element.style.transform = `translate3d(${x}px, ${y}px, 0)`; - }; - const animate = () => { currentX += (targetX - currentX) * 0.065; currentY += (targetY - currentY) * 0.065; @@ -51,16 +41,6 @@ heroShell.style.setProperty("--hero-shell-spot-x", `${50 + currentX * 14}%`); heroShell.style.setProperty("--hero-shell-spot-y", `${28 + currentY * 10}%`); - heroShell.style.setProperty("--hero-shell-tilt-x", `${currentY * -2.2}deg`); - heroShell.style.setProperty("--hero-shell-tilt-y", `${currentX * 2.6}deg`); - - setTransform(profile, currentX * -4.5, currentY * -4.5); - setTransform(title, currentX * 2.2, currentY * 2.2); - - descriptions.forEach((element, index) => { - const strength = 1.3 + index * 0.35; - setTransform(element, currentX * strength, currentY * strength); - }); requestAnimationFrame(animate); };