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
14 changes: 14 additions & 0 deletions contributors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"name": "Kiya Rose",
"url": "https://kiya.cat",
"avatar": "https://avatars.githubusercontent.com/u/75678535?v=4",
"label": "Kiya Rose — Portfolio"
},
{
"name": "Krystal Rose",
"url": "https://enby.fun",
"avatar": "https://avatars.githubusercontent.com/u/32627918?v=4",
"label": "Krystal Rose — Website"
}
]
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ <h1 class="name">Silly Little <span class="tech-thin">Tech</span></h1>
</div>

<div class="right-section">
<!-- Contributor profile icons — populated from contributors.json -->
<div class="contributor-icons" id="contributorsContainer"></div>
<div class="links" id="linksContainer">
<!-- Links will be rendered here from links.json -->
</div>
Expand Down
9 changes: 3 additions & 6 deletions links.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
[
{
"title": "Kiya Rose — Portfolio",
"url": "/kiya"
},
{
"title": "Krystal Rose — Website",
"url": "/krystal"
"title": "Projects",
"url": "https://projects.sillylittle.tech",
"subtitle": "Explore our open-source projects"
}
]
45 changes: 45 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ document.addEventListener('DOMContentLoaded', () => {
debugLog('Calling renderLinks')
renderLinks('#linksContainer', 'links.json')

// Render contributor icons from contributors.json
debugLog('Calling renderContributors')
renderContributors('#contributorsContainer', 'contributors.json')

// Render footer from includes/footer.html
debugLog('Calling renderFooter')
renderFooter('#siteFooter', 'includes/footer.html')
Expand Down Expand Up @@ -75,6 +79,47 @@ function renderLinks (containerSelector, jsonPath) {
})
}

/**
* Fetches a JSON file containing contributor data and renders round profile icon links.
* Each contributor object may have: { name, url, avatar, label }
*/
function renderContributors (containerSelector, jsonPath) {
const container = document.querySelector(containerSelector)
if (!container) return
debugLog(`renderContributors: fetching ${jsonPath}`)

fetch(jsonPath)
.then((res) => {
if (!res.ok) throw new Error(`Failed to load ${jsonPath}`)
return res.json()
})
.then((contributors) => {
container.innerHTML = ''
debugLog(`renderContributors: got ${contributors.length} contributors`)

contributors.forEach((contributor) => {
const anchor = document.createElement('a')
anchor.className = 'contributor-icon'
anchor.href = contributor.url || '#'
Comment on lines +101 to +103
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

renderContributors sets anchor.href to '#' when contributor.url is missing but still forces target="_blank". This can open a useless blank tab (and # can also jump to the top if opened in-page). Prefer skipping entries without a valid URL, or only setting target/rel when the URL is present and external.

Suggested change
const anchor = document.createElement('a')
anchor.className = 'contributor-icon'
anchor.href = contributor.url || '#'
// Skip contributors without a valid URL to avoid creating useless "#" links.
if (!contributor.url) {
debugLog('renderContributors: skipping contributor without URL')
return
}
const anchor = document.createElement('a')
anchor.className = 'contributor-icon'
anchor.href = contributor.url

Copilot uses AI. Check for mistakes.
anchor.target = '_blank'
anchor.rel = 'noopener noreferrer'
anchor.setAttribute('aria-label', contributor.label || contributor.name || contributor.url || 'Contributor')

const img = document.createElement('img')
img.src = contributor.avatar || ''
img.alt = contributor.name || ''

Comment on lines +108 to +111
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

img.src is set to an empty string when contributor.avatar is missing. An empty src is treated as a (relative) URL and may trigger an unintended request for the current document and show a broken image. Prefer omitting the <img>/skipping the contributor when avatar is missing, or providing a real placeholder image.

Copilot uses AI. Check for mistakes.
anchor.appendChild(img)
container.appendChild(anchor)
})
})
.catch((err) => {
const msg = err?.message ?? 'unknown error'
console.error('Error rendering contributors:', err)
debugLog(`renderContributors error: ${msg}`)
})
Comment on lines +116 to +120
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

On fetch/render failure, contributor icons fail silently in the UI (only console/debug logs). renderLinks shows a visible error message and renderFooter restores static content; consider adding a similar fallback for contributors (e.g., keep existing markup if present, or render a small non-intrusive error/placeholder) so users aren’t left with an unexplained empty area.

Copilot uses AI. Check for mistakes.
}

/**
* Fetches an HTML file and injects its content into the target element.
* Falls back to the original static footer markup already in the page if the fetch fails.
Expand Down
32 changes: 32 additions & 0 deletions site.css
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,38 @@ footer.site-footer a {
font-size: 14px;
}

/* Contributor profile icons — displayed above the links list in the right section */
.contributor-icons {
display: flex;
flex-direction: row;
gap: 10px;
margin-bottom: 16px;
}
Comment on lines +161 to +167
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The PR title/issue request calls these “floating” profile icons and asks that they be “out of the way”, but the current styles lay them out inline in the normal document flow above the links list (no fixed/absolute positioning). If floating behavior is still required, adjust the CSS to position the panel (and ensure it doesn’t overlap the theme toggle/buttons) or update the PR title/description to match the implemented non-floating layout.

Copilot uses AI. Check for mistakes.
.contributor-icon {
width: 44px;
height: 44px;
border-radius: 50%;
overflow: hidden;
border: 2px solid var(--border-color);
background: var(--card-bg);
display: block;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
transition:
transform 0.18s ease,
box-shadow 0.18s ease;
text-decoration: none;
}
.contributor-icon:hover {
transform: scale(1.12);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
}
.contributor-icon img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}

@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
Expand Down
Loading