JARVIS HUD Portfolio with GitHub Pages
Build a live Iron Man-style portfolio that fetches your GitHub data.
Introduction
30 Second Summary
Everyone tells you to make a portfolio site, but most end up looking the same. Imagine if yours looked like Tony Stark's JARVIS interface instead.
In this project, you will build a personal portfolio website styled like Iron Man's JARVIS system that pulls your real GitHub data into animated HUD panels and deploys it live for anyone to visit.
What You'll Build
When someone visits your site, they see a cinematic boot-up sequence with text typing out letter by letter. Then your GitHub profile appears inside glowing neon panels with concentric rings rotating around your avatar.
By the end of this project, you'll have:
- A live portfolio website at your username.github.io URL that you can share with anyone, displaying your real GitHub data in a futuristic interface.
- Working JavaScript that fetches your repositories, follower count, and bio from the GitHub REST API and injects them into the page dynamically using DOM manipulation.
- CSS animations including a rotating Arc Reactor built with SVG graphics, glowing neon panels, and a cinematic boot-up sequence that plays when the page loads.
- Secret Mission: Add voice-activated navigation so you can say "show projects" and watch the interface respond by highlighting the matching panel.
Are there any prerequisites?
None. This project includes setup for all required tools. You will use vanilla HTML, CSS, and JavaScript with no frameworks or build tools to install.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters.
Set Up Your Project and Repository
Your JARVIS HUD needs a home on the internet and a workspace on your computer. GitHub Pages turns any repository into a live website for free, and it uses a special naming convention to give you a personal URL.
In this step, you will create a GitHub Pages repository, clone it to your machine, and set up the project files that will hold your JARVIS interface.
In this step, get ready to:
- Create a GitHub Pages repository with the correct naming convention.
- Clone the repository locally and create the project files.
- Push a basic HTML page to confirm the connection works.
Create the GitHub repository
GitHub Pages requires your repository to follow a specific name pattern to publish it as a personal site. The repository must be named exactly your-username.github.io, replacing your-username with your actual GitHub username.
- In your browser, go to github.com.
- Click the + icon in the upper-right corner of the page.
- Click New repository.
- In the Repository name field, type your-username.github.io (replacing your-username with your actual GitHub username).
- Select Public for the visibility.
- Check the box labeled Add a README file.
- Click Create repository.
You should now see your new repository page with a single README.md file listed.
Why does the name matter?
GitHub Pages looks for a repository named exactly username.github.io to publish it as your personal site at https://username.github.io. Any other name would require extra configuration and give you a longer URL.
Clone the repository and create project files
Now you need a local copy of this repository on your machine so you can build the JARVIS interface.
- On your repository page, click the green Code button.
- Copy the HTTPS URL shown in the dropdown.
- In VS Code, open the integrated terminal by pressing Ctrl+` (backtick key, usually above Tab).
- Move to your Desktop by running this command:
cd ~/Desktop
- Clone your repository by running this command (paste the URL you copied from GitHub):
git clone [[REPO_URL="https://github.com/your-username/your-username.github.io.git"]]
You should see output that says Cloning into 'your-username.github.io'... followed by download progress.
- Move into the cloned folder by running:
cd [[REPO_FOLDER="your-username.github.io"]]
- Create the project files by running:
touch index.html style.css script.js .nojekyll
- Confirm the files exist by running:
ls -a
You should see index.html, style.css, script.js, and .nojekyll in the output (alongside .git and README.md).
What is the .nojekyll file for?
GitHub Pages normally processes files through Jekyll, a static site generator. Since you are building a plain HTML/CSS/JS site, the empty .nojekyll file tells GitHub to skip that processing and serve your files directly.
Don't see the files?
Make sure you ran ls -a (with the -a flag) to show hidden files like .nojekyll. If the files are missing entirely, confirm you are inside the cloned folder (your terminal prompt should show the folder name).
help me find my project files after cloning
- Open this folder in VS Code by clicking File in the top menu bar.
- Click Open Folder.
- Navigate to Desktop, select your your-username.github.io folder, and click Open.
You should now see all four files listed in the Explorer sidebar on the left.
Add the HTML structure and push to GitHub
Your files are empty placeholders right now. You need a basic HTML page that links the CSS and JavaScript files together so future changes work immediately.
- Click on index.html in the Explorer sidebar to open it.
- Add the following HTML to the file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JARVIS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>JARVIS ONLINE</h1>
<script src="script.js"></script>
</body>
</html>
What does this code do?
- The <link rel="stylesheet" href="style.css"> connects your stylesheet so any CSS you write later applies automatically.
- The <script src="script.js"></script> at the bottom of the body loads your JavaScript after the page content is ready.
- The <h1>JARVIS ONLINE</h1> gives you a visible confirmation that the page loaded correctly.
- Save index.html by pressing Ctrl+S.
- Open index.html in your browser by right-clicking the file in the Explorer sidebar and selecting Reveal in File Manager, then double-clicking the file.
You should see a plain white page with the text "JARVIS ONLINE" as a large heading.
Seeing a blank page?
Check that you saved the file (the dot next to the filename in VS Code's tab disappears after saving). Make sure you opened index.html directly in the browser, not the project folder.
help me fix my blank HTML page
Now push this initial code to GitHub to confirm the full connection works.
- In your VS Code terminal, stage all files by running:
git add .
- Commit your changes by running:
git commit -m "Add initial project files"
- Push to GitHub by running:
git push
Before you run the next command, what do you expect to see as the remote URL?
- Verify the connection by running:
git remote -v
You should see your username.github.io repository listed as origin for both fetch and push. This confirms your local project is wired to GitHub.
Push failed or permission denied?
If you see a permission error, Git may need you to authenticate. GitHub no longer accepts passwords for git operations. You need to either set up a personal access token or use SSH keys.
help me fix git push permission denied on GitHub
✔️ Awesome, I've got everything!
Great. Double check you have saved index.html and that your push succeeded with no errors.
ⓧ I'd like to double check the full code
Here is the complete index.html you should have at this point. The other three files (style.css, script.js, .nojekyll) should be empty.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JARVIS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>JARVIS ONLINE</h1>
<script src="script.js"></script>
</body>
</html>
Your project is wired up and live on GitHub. Next up, you will write JavaScript to fetch your real GitHub profile data and display it on the page.
Fetch Your GitHub Data and Display It
In Step 1 you wired your local project to a GitHub Pages repository and confirmed everything connects. Now it is time to make the page do something real.
Before styling anything, you need real data flowing into your page. In this step, you will write JavaScript that pulls your live GitHub profile from the GitHub REST API and puts it on screen.
In this step, get ready to:
- Write a fetch function that calls the GitHub REST API for your profile and repositories.
- Build HTML elements that give JavaScript a place to display each piece of data.
- Display your real GitHub information on the page as plain text.
Write the data-fetching function
The GitHub REST API is public. Anyone can request a user's profile and repository list without needing an API key or authentication.
- In VS Code, open script.js and add the following code that defines your username and a function to fetch your GitHub data:
const GITHUB_USERNAME = "[[GITHUB_USER=\"your GitHub username\"]]";\n\nasync function fetchGitHubData() {\n // Fetch profile data from the GitHub API\n const userResponse = await fetch(`https://api.github.com/users/${GITHUB_USERNAME}`);\n const userData = await userResponse.json();\n\n // Fetch the 6 most recently updated repositories\n const reposResponse = await fetch(`https://api.github.com/users/${GITHUB_USERNAME}/repos?sort=updated&per_page=6`);\n const reposData = await reposResponse.json();\n\n return { user: userData, repos: reposData };\n}
What does this code do?
The GITHUB_USERNAME constant stores your username so both API calls can reference it.
The fetchGitHubData() function uses async/await to pause until each network request finishes. It calls two endpoints: one for your profile (avatar, bio, follower count) and one for your repositories. It returns both responses bundled into a single object.
- Save script.js.
- Open index.html in your browser by double-clicking the file in your file manager, or right-clicking the file in VS Code and selecting Open with Live Server if you have that extension.
- Open DevTools by pressing Cmd+Option+J (macOS) or Ctrl+Shift+J (Windows/Linux) to open the Console tab.
- Type the following into the console and press Enter:
fetchGitHubData().then(data => console.log(data))
You should see an object logged containing your GitHub profile information and an array of your repositories.
Seeing 'undefined' or a 404 error?
- Double-check that the username string in GITHUB_USERNAME matches your actual GitHub username exactly, including capitalisation.
- Make sure you saved script.js before refreshing the browser.
- If you see a CORS or network error, check your internet connection.
help me debug why my fetchGitHubData function is returning a 404 or undefined
Build the HTML structure for your data
JavaScript needs HTML elements to inject data into. Each piece of information (avatar, name, bio, stats, repos) gets its own element with a unique id so your code can find it.
- In VS Code, open index.html and replace the entire file contents with the following HTML:
<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>J.A.R.V.I.S. Interface</title>\n <link rel=\"stylesheet\" href=\"style.css\">\n</head>\n<body>\n <img id=\"avatar\" src=\"\" alt=\"GitHub Avatar\">\n <h2 id=\"user-name\"></h2>\n <p id=\"user-bio\"></p>\n <a id=\"user-link\" href=\"\" target=\"_blank\">View on GitHub</a>\n <div>\n <span id=\"stat-repos\">0</span> Repositories\n <span id=\"stat-followers\">0</span> Followers\n <span id=\"stat-following\">0</span> Following\n </div>\n <ul id=\"repo-list\"></ul>\n <script src=\"script.js\"></script>\n</body>\n</html>
What does this HTML do?
Each element has a unique id attribute that acts as an address. Your JavaScript will use document.getElementById() to find each one and fill it with real data.
The elements are empty right now because the data has not been injected yet. The script.js tag at the bottom ensures the HTML loads before JavaScript runs.
- Save index.html and refresh your browser.
- You should see a broken image icon, the text "View on GitHub", three zeros for your stats, and an empty bullet list. This confirms your HTML structure is in place.
Don't see anything on the page?
- Make sure you replaced the entire file, including the <!DOCTYPE html> line at the top.
- Check that <script src="script.js"></script> appears just before </body>.
help me debug why my index.html shows a blank page after I replaced the contents
✔️ Awesome, I've got everything!
Great. Make sure you have saved index.html before moving on.
ⓧ I'd like to double check the full code
Here is the complete index.html file at this point:
<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>J.A.R.V.I.S. Interface</title>\n <link rel=\"stylesheet\" href=\"style.css\">\n</head>\n<body>\n <img id=\"avatar\" src=\"\" alt=\"GitHub Avatar\">\n <h2 id=\"user-name\"></h2>\n <p id=\"user-bio\"></p>\n <a id=\"user-link\" href=\"\" target=\"_blank\">View on GitHub</a>\n <div>\n <span id=\"stat-repos\">0</span> Repositories\n <span id=\"stat-followers\">0</span> Followers\n <span id=\"stat-following\">0</span> Following\n </div>\n <ul id=\"repo-list\"></ul>\n <script src=\"script.js\"></script>\n</body>\n</html>
Display the fetched data in your HTML elements
Now you will connect the data from the API to the HTML elements you just created. This is DOM manipulation: finding elements on the page and changing their content with JavaScript.
- Return to script.js in VS Code. Below your fetchGitHubData function, add these two display functions:
function displayProfile(user) {\n // Set the avatar image source\n document.getElementById(\"avatar\").src = user.avatar_url;\n // Set the name, falling back to login if name is null\n document.getElementById(\"user-name\").textContent = user.name || user.login;\n document.getElementById(\"user-bio\").textContent = user.bio || \"No bio available.\";\n document.getElementById(\"user-link\").href = user.html_url;\n // Fill in the stats counters\n document.getElementById(\"stat-repos\").textContent = user.public_repos;\n document.getElementById(\"stat-followers\").textContent = user.followers;\n document.getElementById(\"stat-following\").textContent = user.following;\n}\n\nfunction displayRepos(repos) {\n const repoList = document.getElementById(\"repo-list\");\n repoList.innerHTML = \"\";\n\n // Create a list item for each repository\n repos.forEach(function(repo) {\n const li = document.createElement(\"li\");\n li.innerHTML = `\n <a href=\"${repo.html_url}\" target=\"_blank\" rel=\"noopener noreferrer\">${repo.name}</a>\n <span>${repo.language || \"N/A\"} | ${repo.stargazers_count} stars</span>\n `;\n repoList.appendChild(li);\n });\n}
What do these functions do?
The displayProfile function uses textContent to safely set text and src to load your avatar image. The || operator provides fallback values when a field is null (for example, if you have not set a bio on GitHub).
The displayRepos function loops through your repositories, creates a list item for each one, and appends it to the repo-list element. Each item shows the repo name as a link plus its primary language and star count.
- Below the displayRepos function, add the init function that ties everything together:
async function init() {\n try {\n // Fetch data then display it\n const data = await fetchGitHubData();\n displayProfile(data.user);\n displayRepos(data.repos);\n } catch (error) {\n console.error(\"Failed to fetch GitHub data:\", error);\n }\n}\n\n// Start the application\ninit();
What does init do?
The init function is the entry point. It calls fetchGitHubData(), waits for the response, then passes the data to both display functions. The try/catch block prevents the page from silently breaking if the API request fails.
The final init(); line at the bottom runs the function as soon as the script loads.
Before you save and refresh, what do you expect to see on the page? Plain text, styled text, or nothing at all?
- Save script.js and refresh your browser.
You should see your real GitHub avatar, your name (or username), your bio, three stat numbers, and a list of your most recent repositories. Everything is unstyled plain text on a white background. It looks ugly right now, and that is intentional.
Still seeing zeros and empty elements?
- Open the Console tab in DevTools and look for error messages. A 404 means your username string is wrong.
- Make sure init(); appears at the very bottom of script.js, outside any function.
- Check that your index.html has id="avatar", id="user-name", and the other IDs matching what your JavaScript references.
help me debug why my GitHub data is not appearing on the page even though the HTML and script are linked
✔️ Awesome, I've got everything!
Great. Double check you have saved both index.html and script.js.
ⓧ I'd like to double check the full code
Your script.js should contain these sections in order. Scroll up and confirm each one is present:
- The GITHUB_USERNAME constant with your actual username.
- The fetchGitHubData() function that calls both API endpoints.
- The displayProfile(user) function that fills in the avatar, name, bio, link, and stats.
- The displayRepos(repos) function that builds the repository list.
- The init() function followed by the init(); call at the very end.
Why does this work without an API key?
The GitHub REST API allows unauthenticated requests for public data. The trade-off is a rate limit of 60 requests per hour per IP address. For a portfolio site that makes 2 requests per visitor, this is more than enough.
Your data is live on the page. Next up, you will transform this plain white page into a glowing JARVIS heads-up display with dark backgrounds, neon borders, and scanline effects.
Transform Into a JARVIS HUD
In the last step, you proved that your JavaScript can pull real data from GitHub and display it on screen. The problem is your page looks like a plain text document from 1995.
This step transforms that raw data into the signature JARVIS aesthetic. You will apply a near-black background, glowing cyan panels, a grid layout, and scanline effects that make the page look like a sci-fi heads-up display.
In this step, get ready to:
- Set up the dark theme with CSS variables and Google Fonts.
- Restructure the HTML into a HUD panel layout.
- Style panels with glowing borders, add a scanline overlay, and see your data inside a JARVIS interface.
Set up the base dark theme
Every JARVIS interface starts with darkness. A near-black background makes neon colors pop and creates the illusion of looking at a transparent display.
You will also load two Google Fonts that sell the sci-fi look: Orbitron (angular, techy) for headings and Share Tech Mono (monospaced) for body text.
- In index.html, find these lines at the top of the <head> section:
<link rel="stylesheet" href="style.css">
</head>
- Add three new <link> tags between the stylesheet link and the closing </head> tag, so the section now looks like this:
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&display=swap" rel="stylesheet">
</head>
What do these links do?
The two preconnect links tell the browser to start connecting to Google's font servers early, before it even encounters the font request. This shaves time off the first paint.
The third link loads the actual font files for Orbitron and Share Tech Mono so you can reference them in your CSS.
- Now open style.css and add the following CSS variables, reset, and body styles:
:root {
--bg-dark: #0a0a0f;
--cyan: #00d4ff;
--cyan-dim: rgba(0, 212, 255, 0.3);
--cyan-glow: rgba(0, 212, 255, 0.6);
--panel-bg: rgba(0, 212, 255, 0.05);
--panel-border: rgba(0, 212, 255, 0.4);
--text-primary: #e0f7fa;
--text-secondary: #80deea;
--font-heading: 'Orbitron', sans-serif;
--font-mono: 'Share Tech Mono', monospace;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: var(--bg-dark);
color: var(--text-primary);
font-family: var(--font-mono);
min-height: 100vh;
overflow-x: hidden;
}
What does this code do?
The :root block defines CSS custom properties (variables) you will reuse throughout the stylesheet. The cyan colors at different opacities create the layered glow effect JARVIS is known for.
The universal selector (*) resets all default margins and padding. The body gets the near-black background (#0a0a0f) and the monospace font.
- Save both index.html and style.css.
- Refresh the page in your browser.
The page background is now near-black. Your GitHub data still shows as light-colored text, but it looks raw and unstructured. That is about to change.
Still seeing a white background?
- Make sure you saved style.css. Unsaved changes will not appear in the browser.
- Confirm your <link rel="stylesheet" href="style.css"> tag is still in the <head> of your HTML file.
Why is my dark background not showing up?
Restructure the HTML into HUD panels
The current HTML is flat: a bare image, heading, paragraph, and list with no containers. To create the HUD layout, you need to wrap each group of data inside panel containers with class names that the CSS can target.
- In index.html, select everything between the opening <body> tag and the closing </body> tag (all the old content including the script tag).
- Delete that selection and replace it with the following structure. Start by pasting this first block:
<div class="scanlines"></div>
<div id="boot-overlay" class="boot-overlay">
<div class="boot-text" id="boot-text"></div>
</div>
<main id="hud-container" class="hud-container hidden">
<header class="hud-header">
<h1 class="glitch-text">J.A.R.V.I.S.</h1>
<p class="subtitle">Just A Rather Very Intelligent System</p>
</header>
<section class="reactor-section">
<div class="arc-reactor">
<svg class="reactor-ring ring-outer" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="90" fill="none" stroke="#00d4ff" stroke-width="2" stroke-dasharray="15 10" />
</svg>
<svg class="reactor-ring ring-middle" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="70" fill="none" stroke="#00d4ff" stroke-width="1.5" stroke-dasharray="8 6" />
</svg>
<svg class="reactor-ring ring-inner" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="50" fill="none" stroke="#00d4ff" stroke-width="1" stroke-dasharray="4 4" />
</svg>
<div class="avatar-container">
<img id="avatar" class="avatar" src="" alt="GitHub Avatar">
</div>
</div>
</section>
What does this code do?
- The .scanlines div will hold a transparent repeating gradient that simulates CRT scan lines across the entire screen.
- The #boot-overlay is a full-screen cover for the typing animation you will build in a later step.
- The .arc-reactor section contains three SVG rings with dashed strokes that CSS will spin in opposite directions around your avatar.
- Directly below the code you just pasted (still inside the <main> element), paste the panels section:
<section class="panels-grid">
<div class="hud-panel panel-profile" id="panel-profile">
<div class="panel-header">PROFILE</div>
<div class="panel-content">
<h2 id="user-name"></h2>
<p id="user-bio"></p>
<a id="user-link" href="" target="_blank" rel="noopener noreferrer">View on GitHub</a>
</div>
</div>
<div class="hud-panel panel-stats" id="panel-stats">
<div class="panel-header">SYSTEM STATS</div>
<div class="panel-content stats-grid">
<div class="stat-item">
<span class="stat-value" id="stat-repos">0</span>
<span class="stat-label">Repositories</span>
</div>
<div class="stat-item">
<span class="stat-value" id="stat-followers">0</span>
<span class="stat-label">Followers</span>
</div>
<div class="stat-item">
<span class="stat-value" id="stat-following">0</span>
<span class="stat-label">Following</span>
</div>
</div>
</div>
<div class="hud-panel panel-repos" id="panel-repos">
<div class="panel-header">RECENT PROJECTS</div>
<div class="panel-content">
<ul id="repo-list" class="repo-list"></ul>
</div>
</div>
</section>
</main>
<script src="script.js"></script>
What does this code do?
The .panels-grid section uses CSS Grid to arrange three data panels: profile, stats, and recent projects. Each panel has a .panel-header for the label and a .panel-content wrapper for the data.
Notice the element IDs (user-name, stat-repos, repo-list) are the same ones your JavaScript already targets. The data will flow into the new structure automatically.
- Save index.html and refresh your browser.
You should see your GitHub data rendered as light text on the dark background. The layout is still raw because the panel styles are not written yet. The element IDs match, so the JavaScript keeps working.
Page is blank or data is missing?
- Open DevTools (F12 or Cmd+Option+I) and check the Console tab for errors. A typo in an element ID will cause JavaScript to fail silently.
- Confirm the <script src="script.js"></script> tag is at the bottom, just before </body>.
Help me debug why my GitHub data is not showing after restructuring my HTML.
Now you need one small update to script.js so that the repo items get styled properly.
- In script.js, find the displayRepos function. Locate these two lines inside the li.innerHTML template:
<a href="${repo.html_url}" target="_blank" rel="noopener noreferrer">${repo.name}</a>
<span>${repo.language || "N/A"} | ${repo.stargazers_count} stars</span>
- Add class="repo-name" to the <a> tag and class="repo-meta" to the <span> tag, so the lines now look like this:
<a href="${repo.html_url}" target="_blank" rel="noopener noreferrer" class="repo-name">${repo.name}</a>
<span class="repo-meta">${repo.language || "N/A"} | ${repo.stargazers_count} stars</span>
Style the panels with glowing borders
With the structure in place, CSS will turn those plain divs into glowing neon panels. Layered box-shadow values at increasing blur radii create the illusion of light bleeding outward from each border.
- In style.css, add the following below your existing body styles. These handle the scanline overlay, boot overlay, and main container:
/* Scanline Overlay */
.scanlines {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.1) 2px,
rgba(0, 0, 0, 0.1) 4px
);
}
What does this code do?
The scanline overlay creates thin semi-transparent horizontal lines that repeat every 4 pixels across the entire viewport. The pointer-events: none rule makes it completely invisible to clicks, so the learner can still interact with buttons and links underneath.
- Continue adding styles below the scanlines block. These handle the boot overlay and main HUD container:
/* Boot Overlay */
.boot-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--bg-dark);
display: flex;
align-items: center;
justify-content: center;
z-index: 900;
transition: opacity 1s ease;
}
.boot-overlay.fade-out {
opacity: 0;
pointer-events: none;
}
.boot-text {
font-family: var(--font-mono);
font-size: 1.2rem;
color: var(--cyan);
text-align: center;
white-space: pre-line;
text-shadow: 0 0 10px var(--cyan-glow);
}
- Save style.css and refresh your browser.
You should see the scanline overlay as a subtle striped pattern across the screen. The boot overlay currently covers the page with a dark layer. That is expected. The content hides behind it until the boot-up JavaScript is added in a later step.
Temporarily hide the boot overlay
To see your panel work as you build it, right-click the page, select Inspect, find the #boot-overlay element, and add display: none in the element styles. Also find #hud-container and add opacity: 1 to override the hidden class. These DevTools overrides disappear on refresh.
- Add the HUD container and header styles below the boot-text block:
/* HUD Container */
.hud-container {
max-width: 1100px;
margin: 0 auto;
padding: 2rem;
position: relative;
z-index: 1;
}
.hud-container.hidden {
opacity: 0;
pointer-events: none;
}
.hud-container.visible {
opacity: 1;
pointer-events: auto;
transition: opacity 1s ease;
}
/* Header */
.hud-header {
text-align: center;
margin-bottom: 2rem;
opacity: 0;
transform: translateY(-20px);
transition: opacity 0.8s ease, transform 0.8s ease;
}
.hud-header.show {
opacity: 1;
transform: translateY(0);
}
- Add the title and subtitle styles next:
.glitch-text {
font-family: var(--font-heading);
font-size: 2.5rem;
font-weight: 900;
color: var(--cyan);
text-shadow: 0 0 10px var(--cyan-glow), 0 0 20px var(--cyan-dim);
letter-spacing: 0.3em;
}
.subtitle {
font-size: 0.8rem;
color: var(--text-secondary);
margin-top: 0.5rem;
letter-spacing: 0.2em;
}
- Save style.css and use the DevTools trick from earlier to temporarily hide the boot overlay.
You should see the "J.A.R.V.I.S." title rendered in the Orbitron font with a cyan glow radiating outward. The subtitle appears beneath it in a muted secondary color.
- Now add the reactor section and ring animation styles:
/* Arc Reactor */
.reactor-section {
display: flex;
justify-content: center;
margin-bottom: 2rem;
opacity: 0;
transform: scale(0.8);
transition: opacity 0.8s ease, transform 0.8s ease;
}
.reactor-section.show {
opacity: 1;
transform: scale(1);
}
.arc-reactor {
position: relative;
width: 220px;
height: 220px;
display: flex;
align-items: center;
justify-content: center;
}
.reactor-ring {
position: absolute;
width: 100%;
height: 100%;
}
- Add the rotation animations and avatar styles directly below:
.ring-outer {
animation: rotate-clockwise 20s linear infinite;
}
.ring-middle {
animation: rotate-counter 15s linear infinite;
}
.ring-inner {
animation: rotate-clockwise 10s linear infinite;
}
@keyframes rotate-clockwise {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes rotate-counter {
from { transform: rotate(360deg); }
to { transform: rotate(0deg); }
}
.avatar-container {
width: 80px;
height: 80px;
border-radius: 50%;
overflow: hidden;
border: 2px solid var(--cyan);
box-shadow: 0 0 10px var(--cyan-glow), 0 0 20px var(--cyan-dim);
animation: pulse-glow 3s ease-in-out infinite;
}
- Add the pulse animation and avatar image sizing:
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 10px var(--cyan-glow), 0 0 20px var(--cyan-dim); }
50% { box-shadow: 0 0 15px var(--cyan), 0 0 30px var(--cyan-glow), 0 0 45px var(--cyan-dim); }
}
.avatar {
width: 100%;
height: 100%;
object-fit: cover;
}
- Save style.css and check your browser (with the boot overlay still hidden in DevTools).
You should see your GitHub avatar in a circular frame with concentric dashed rings spinning around it. The outer ring rotates clockwise. The middle ring rotates counter-clockwise. The avatar frame pulses with a subtle glow.
- Add the panel grid layout and panel styles:
/* Panels Grid */
.panels-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
}
/* HUD Panels */
.hud-panel {
background: var(--panel-bg);
border: 1px solid var(--panel-border);
border-radius: 4px;
padding: 1.5rem;
position: relative;
box-shadow: 0 0 5px var(--cyan-dim), 0 0 10px rgba(0, 212, 255, 0.1);
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.hud-panel.show {
opacity: 1;
transform: translateY(0);
}
.hud-panel.highlight {
box-shadow: 0 0 10px var(--cyan), 0 0 20px var(--cyan-glow), 0 0 40px var(--cyan-dim);
border-color: var(--cyan);
}
What creates the glow effect?
The box-shadow property accepts multiple shadows separated by commas. Each one uses a larger blur radius (5px, 10px) and different opacity, which creates the illusion of light radiating outward from the panel border. The more layers, the softer and more realistic the glow looks.
- Add the panel content and header styles:
.panel-header {
font-family: var(--font-heading);
font-size: 0.75rem;
color: var(--cyan);
letter-spacing: 0.2em;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--panel-border);
}
.panel-content h2 {
font-family: var(--font-heading);
font-size: 1.1rem;
margin-bottom: 0.5rem;
color: var(--text-primary);
}
.panel-content p {
color: var(--text-secondary);
font-size: 0.9rem;
line-height: 1.5;
}
.panel-content a {
color: var(--cyan);
text-decoration: none;
font-size: 0.8rem;
display: inline-block;
margin-top: 0.5rem;
border-bottom: 1px solid transparent;
transition: border-color 0.3s;
}
.panel-content a:hover {
border-bottom-color: var(--cyan);
}
- Add the stats grid, repo list, and responsive styles to complete the stylesheet:
/* Stats Grid */
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
text-align: center;
}
.stat-value {
display: block;
font-family: var(--font-heading);
font-size: 1.5rem;
color: var(--cyan);
text-shadow: 0 0 5px var(--cyan-glow);
}
.stat-label {
font-size: 0.7rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.1em;
}
- Add the final block of styles for the repo list and responsive layout:
/* Repo List */
.repo-list {
list-style: none;
}
.repo-list li {
padding: 0.6rem 0;
border-bottom: 1px solid rgba(0, 212, 255, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.repo-list li:last-child {
border-bottom: none;
}
.repo-name {
color: var(--text-primary);
text-decoration: none;
font-size: 0.85rem;
transition: color 0.3s;
}
.repo-name:hover {
color: var(--cyan);
}
.repo-meta {
font-size: 0.7rem;
color: var(--text-secondary);
}
- Add the panel spanning rule and responsive media query as the last block:
/* Panel spanning */
.panel-repos {
grid-column: 1 / -1;
}
/* Responsive */
@media (max-width: 768px) {
.panels-grid {
grid-template-columns: 1fr;
}
.glitch-text {
font-size: 1.5rem;
}
.arc-reactor {
width: 160px;
height: 160px;
}
.avatar-container {
width: 60px;
height: 60px;
}
}
What does this code do?
The grid-column: 1 / -1 rule makes the repos panel span the full width of the two-column grid instead of sitting in just one column.
The media query at 768px collapses the grid to a single column on mobile and shrinks the reactor and heading so everything fits on smaller screens.
Verify the full JARVIS transformation
Before you check the result, think about what you expect to see. The panels have opacity: 0 by default and only become visible when the .show class is added. What do you think will be visible when you refresh?
- Save all three files: index.html, style.css, and script.js.
- Refresh your browser.
You will see the boot overlay covering the page (a dark screen). Use DevTools to hide it: right-click the page, select Inspect, find #boot-overlay, and set display: none in the element styles. Then find #hud-container and set opacity: 1. Add the show class to .hud-header, .reactor-section, and each .hud-panel element.
You should see your GitHub data displayed inside glowing cyan-bordered panels on a near-black background. The scanline overlay adds subtle horizontal lines across the entire screen. The three SVG rings spin around your avatar.
Panels not glowing or layout looks wrong?
- Check that the class names in your HTML exactly match what the CSS targets. For example, panel-profile in HTML must match .panel-profile in CSS.
- Confirm your :root variables are at the very top of style.css. If they appear after rules that reference them, the values will be undefined.
- If the rings are not spinning, verify you added both @keyframes rotate-clockwise and @keyframes rotate-counter blocks.
Help me debug why my JARVIS HUD panels are not displaying with the correct glow and layout.
✔️ Awesome, I've got everything!
Great. Double check you have saved all three files before moving on.
ⓧ I'd like to double check the full code
Here is the full index.html at this point. Scroll up and confirm each section is present in order: the Google Fonts links in the head, the scanlines div, the boot-overlay div, the hud-container main element with header, reactor-section, and panels-grid sections.
For style.css, confirm these sections appear in order from top to bottom:
- CSS custom properties in :root.
- Universal reset and body styles.
- Scanline overlay (.scanlines).
- Boot overlay and boot text styles.
- HUD container, hidden, and visible classes.
- Header, glitch-text, and subtitle.
- Reactor section, arc-reactor, reactor-ring, ring classes.
- Keyframe animations (rotate-clockwise, rotate-counter, pulse-glow).
- Avatar container and avatar.
- Panels grid and hud-panel (including show and highlight states).
- Panel header and panel content styles.
- Stats grid, stat-value, stat-label.
- Repo list styles.
- Panel-repos spanning and responsive media query.
For script.js, confirm that the displayRepos function template includes class="repo-name" on the link and class="repo-meta" on the span.
Your plain-text data page has transformed into a sci-fi heads-up display. Next, you will add the Arc Reactor animation logic and a cinematic boot-up sequence that makes the interface feel like it is powering on.
Add the Arc Reactor Animation
Your JARVIS interface has glowing panels and live data, but everything feels static. The real JARVIS has a signature visual: concentric rings spinning around a central core.
In this step, you will add CSS animations that make the SVG rings you placed earlier rotate in alternating directions. You will also add a pulsing glow to the avatar container so the reactor feels alive and mechanical.
In this step, get ready to:
- Understand how the SVG rings use stroke-dasharray to create segmented arcs.
- Add CSS keyframe animations that rotate rings clockwise and counter-clockwise.
- Add a pulsing glow animation to the avatar container.
Examine the SVG ring structure
Your index.html already contains three SVG elements inside the .arc-reactor container. Each SVG draws a circle at a different radius to create concentric rings.
- In VS Code, open index.html and scroll to the <section class="reactor-section"> block.
- Find the three <svg> elements with classes ring-outer, ring-middle, and ring-inner.
<svg class="reactor-ring ring-outer" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="90" fill="none" stroke="#00d4ff" stroke-width="2" stroke-dasharray="15 10" />
</svg>
<svg class="reactor-ring ring-middle" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="70" fill="none" stroke="#00d4ff" stroke-width="1.5" stroke-dasharray="8 6" />
</svg>
<svg class="reactor-ring ring-inner" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="50" fill="none" stroke="#00d4ff" stroke-width="1" stroke-dasharray="4 4" />
</svg>
What does stroke-dasharray do?
The stroke-dasharray attribute on each circle creates a dashed pattern instead of a solid line. The two numbers control the length of each dash and the gap between them.
For example, stroke-dasharray="15 10" draws 15-pixel dashes with 10-pixel gaps. Each ring uses different values so they look distinct when spinning.
Add rotation animations to the rings
The SVG rings need to be positioned on top of each other and spun. CSS @keyframes define the rotation, and the animation property applies it to each ring at a different speed and direction.
- In style.css, find the .arc-reactor rule (the one with position: relative and width: 220px).
- Confirm the following CSS rules exist directly below it. If they are missing, add them:
.reactor-ring {
position: absolute;
width: 100%;
height: 100%;
}
.ring-outer {
animation: rotate-clockwise 20s linear infinite;
}
.ring-middle {
animation: rotate-counter 15s linear infinite;
}
.ring-inner {
animation: rotate-clockwise 10s linear infinite;
}
What does this code do?
- position: absolute stacks all three SVGs on top of each other inside the .arc-reactor container (which has position: relative).
- width: 100% and height: 100% make each ring fill the full 220px container.
- The outer and inner rings rotate clockwise at 20s and 10s. The middle ring rotates counter-clockwise at 15s. Different speeds and directions create the mechanical feel.
- Now confirm the keyframe definitions exist below those rules. If they are missing, add them:
@keyframes rotate-clockwise {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes rotate-counter {
from { transform: rotate(360deg); }
to { transform: rotate(0deg); }
}
What are keyframes?
A @keyframes rule defines the start and end states of an animation. The browser smoothly transitions between them. rotate-clockwise goes from 0 to 360 degrees. rotate-counter goes from 360 down to 0, creating the opposite direction.
- Save style.css.
- Refresh your browser. You should see three dashed cyan rings spinning around the center of the page. The outer and inner rings spin clockwise while the middle ring spins in the opposite direction.
Rings not spinning?
- Make sure the @keyframes names match exactly: rotate-clockwise and rotate-counter. A typo in either the animation property or the keyframe name breaks the link.
- Confirm .reactor-ring has position: absolute. Without it, the rings stack vertically instead of overlapping.
- Check that the boot overlay is not covering the content. If you see a blank dark screen, you may need to temporarily remove the hidden class from the <main> tag and add style="display:none" to the #boot-overlay div for testing.
Why aren't my Arc Reactor rings animating in the browser?
Add the pulsing glow to the avatar
The rings spin, but the avatar in the center sits flat. A pulsing box-shadow animation makes it look like the reactor core is breathing with energy.
- In style.css, find the .avatar-container rule. Confirm it includes the animation property and the @keyframes pulse-glow rule below it. If they are missing, add them:
.avatar-container {
width: 80px;
height: 80px;
border-radius: 50%;
overflow: hidden;
border: 2px solid var(--cyan);
box-shadow: 0 0 10px var(--cyan-glow), 0 0 20px var(--cyan-dim);
animation: pulse-glow 3s ease-in-out infinite;
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 10px var(--cyan-glow), 0 0 20px var(--cyan-dim); }
50% { box-shadow: 0 0 15px var(--cyan), 0 0 30px var(--cyan-glow), 0 0 45px var(--cyan-dim); }
}
What does this code do?
- The border: 2px solid var(--cyan) gives the avatar a crisp cyan ring matching the reactor aesthetic.
- The box-shadow creates a layered glow effect: one close glow (10px) and one wider glow (20px).
- The pulse-glow keyframe cycles from the base glow to a more intense three-layer glow at the halfway point, then back. This creates a smooth breathing pulse over 3 seconds.
- Save style.css.
- Refresh your browser. The avatar in the center of the rings now pulses with an intensifying and fading cyan glow.
Avatar not glowing?
- Check that animation: pulse-glow 3s ease-in-out infinite is inside the .avatar-container rule, not outside it.
- Make sure the keyframe name pulse-glow matches exactly between the animation property and the @keyframes declaration.
Help me fix my pulse-glow CSS animation.
Verify the full Arc Reactor animation
Before you think about what the final result looks like, take a moment to predict.
- How many rings do you expect to see spinning? Which direction should the middle ring go compared to the outer ring?
- Refresh your browser to check your prediction.
You should see three concentric dashed rings rotating in alternating directions around your GitHub avatar. The avatar pulses with a glowing cyan shadow that intensifies and fades every 3 seconds.
Testing past the boot overlay
If you see a blank dark screen instead of the reactor, the boot overlay is covering your content. To test temporarily, right-click the page and select Inspect. Find the #boot-overlay element and add display: none to its styles. Then find #hud-container and remove the hidden class.
This only changes the live page in your browser. Your files stay untouched. The next step will add the proper boot-up sequence that handles this automatically.
✔️ Awesome, I've got everything!
Great. Double check that you have saved style.css and your rings are spinning.
ⓧ I'd like to double check the full code
Scroll up and confirm each of these sections is present in your style.css, in order:
- The .reactor-ring rule with position: absolute.
- The .ring-outer, .ring-middle, and .ring-inner rules with their animation properties.
- The @keyframes rotate-clockwise and @keyframes rotate-counter definitions.
- The .avatar-container rule with animation: pulse-glow 3s ease-in-out infinite.
- The @keyframes pulse-glow definition cycling box-shadow intensity.
Your Arc Reactor is alive. The spinning rings and pulsing glow make the interface feel like a real system humming with energy. Next up, you will add a cinematic boot-up sequence so visitors see the HUD power on one panel at a time, then deploy it live for the world to see.
Add the Boot-Up Sequence and Deploy
Your JARVIS HUD has rotating rings, glowing panels, and live GitHub data. But when someone visits your site, everything appears all at once.
A cinematic boot-up sequence where text types out letter by letter and panels fade in sequentially creates the feeling of a system powering on. In this step, you will write that typing animation, wire it to the panel reveal, and then deploy your site live to GitHub Pages so anyone can visit it.
In this step, get ready to:
- Write a typing animation that displays initialization messages one character at a time.
- Fade out the boot overlay and reveal HUD panels sequentially.
- Deploy your site live at your username.github.io URL.
Write the typing animation function
The boot overlay HTML and CSS are already in place from earlier steps. Now you need JavaScript to type messages into it, one character at a time, like a computer terminal booting up.
- In VS Code, open script.js.
- Find the line that says const GITHUB_USERNAME = "your-github-username-here"; and add the following code directly below it:
const BOOT_MESSAGES = [
"INITIALIZING JARVIS PROTOCOL...",
"CONNECTING TO GITHUB NETWORK...",
"DECRYPTING USER DATA...",
"SYSTEMS ONLINE.",
"",
"WELCOME BACK, SIR."
];
function typeText(element, messages, messageIndex, charIndex) {
// When all messages are typed, trigger the HUD reveal
if (messageIndex >= messages.length) {
setTimeout(endBootSequence, 800);
return;
}
const currentMessage = messages[messageIndex];
if (charIndex < currentMessage.length) {
// Type the next character
element.textContent += currentMessage[charIndex];
setTimeout(function() {
typeText(element, messages, messageIndex, charIndex + 1);
}, 40);
} else {
// Move to the next message
element.textContent += "\n";
setTimeout(function() {
typeText(element, messages, messageIndex + 1, 0);
}, 400);
}
}
What does this code do?
BOOT_MESSAGES is an array of strings that simulate a system initialization sequence. Each message will appear typed out one character at a time.
typeText is a recursive function. It adds one character every 40 milliseconds, creating the typewriter effect. When a message finishes, it waits 400ms then starts the next one. After all messages are done, it calls endBootSequence to reveal the main interface.
Add the panel reveal sequence
After the typing finishes, the boot overlay should fade away and the HUD panels should appear one by one. Each panel slides in with a staggered delay, creating the feeling of systems coming online.
- Still in script.js, add the following function directly below the typeText function you just wrote:
function endBootSequence() {
const bootOverlay = document.getElementById("boot-overlay");
const hudContainer = document.getElementById("hud-container");
// Fade out the boot screen
bootOverlay.classList.add("fade-out");
hudContainer.classList.remove("hidden");
hudContainer.classList.add("visible");
// Reveal each section with staggered timing
setTimeout(function() {
document.querySelector(".hud-header").classList.add("show");
}, 300);
setTimeout(function() {
document.querySelector(".reactor-section").classList.add("show");
}, 600);
setTimeout(function() {
document.getElementById("panel-profile").classList.add("show");
}, 900);
setTimeout(function() {
document.getElementById("panel-stats").classList.add("show");
}, 1200);
setTimeout(function() {
document.getElementById("panel-repos").classList.add("show");
}, 1500);
}
What does this code do?
endBootSequence handles the transition from boot screen to main HUD. It adds the fade-out class to make the overlay disappear, then switches the HUD container from hidden to visible.
Each setTimeout adds the show class to a different element at a different delay (300ms apart). The CSS transitions you already wrote handle the actual animation when show is applied.
Now you need to connect everything by updating the init function to start the boot sequence when the page loads.
- Scroll down to the init function at the bottom of script.js. Find this code:
async function init() {
try {
- Add two new lines at the very top of the function body, before the try block, so the function now starts like this:
async function init() {
const bootText = document.getElementById("boot-text");
typeText(bootText, BOOT_MESSAGES, 0, 0);
try {
- Save script.js.
- Refresh your browser. You should see cyan text typing out messages one by one on a black screen. After the last message, the boot overlay fades and your HUD panels appear sequentially with the Arc Reactor and all your GitHub data.
Boot screen stays forever?
- Check that endBootSequence is defined above the init() call at the bottom of the file. If the function does not exist when typeText tries to call it, you will see a ReferenceError in the browser console.
- Open DevTools (F12) and check the Console tab for errors. A typo in a function name or missing bracket is the most common cause.
- help me debug my boot sequence
Deploy to GitHub Pages
Your JARVIS interface is complete locally. Time to push it live so anyone with the URL can see it.
- Commit all your files and push to GitHub by running these commands in your terminal:
git add .
git commit -m "Add boot sequence and final JARVIS HUD"
git push origin main
- Open your repository on GitHub in your browser.
- Click the Settings tab at the top of the repository.
- In the left sidebar under Code and automation, click Pages.
- Under Build and deployment, confirm the Source is set to Deploy from a branch.
- In the Branch dropdown, select main and leave the folder as / (root).
- Click Save.
How long does deployment take?
GitHub Pages can take up to 10 minutes to publish your site after you push. In practice it usually takes 1-2 minutes. You can check the deployment status under the Actions tab of your repository.
Before you visit your live site, what do you think you will see when it loads?
- Wait about 2 minutes, then visit https://your GitHub username.github.io in your browser.
You should see the full boot-up sequence play: cyan text types out the initialization messages, then your JARVIS HUD fades in with the header, Arc Reactor, and all three panels appearing one after another.
Seeing a 404 page?
- Double-check that your repository is named exactly username.github.io (replacing username with your actual GitHub username). The name must match exactly.
- Confirm you pushed to the main branch and that index.html is in the root of the repository (not inside a subfolder).
- Check the Actions tab on your repository for a green checkmark on the pages deployment workflow. If you see an orange dot, the deploy is still in progress.
- help me debug my GitHub Pages deployment
✔️ Awesome, I've got everything!
Great. Double check you have saved script.js and that your live site is loading correctly.
ⓧ I'd like to double check the full code
Your script.js file should now contain these sections in order. Scroll through your file and confirm each one is present:
- GITHUB_USERNAME constant at the top.
- BOOT_MESSAGES array with 6 strings.
- fetchGitHubData() function.
- displayProfile() function.
- displayRepos() function.
- typeText() recursive function.
- endBootSequence() function with staggered setTimeout calls.
- init() function that calls typeText before the try block.
- init(); call at the very bottom.
index.html and style.css are unchanged from the previous step.
Your JARVIS HUD is live. Anyone with your URL can now see the boot sequence play and explore your GitHub data in a sci-fi interface you built from scratch.
Secret mission
Add Voice-Activated Navigation
JARVIS responds to Tony Stark's voice. Can you add the Web Speech API so visitors can say "show projects" and watch a panel light up? This stretch challenge uses browser feature detection and a command-parsing system you build from scratch.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally and on GitHub Pages (free for public repositories), so there are no ongoing costs.
Resources you used:
- Local project folder (username.github.io on your Desktop).
- GitHub repository (username.github.io) and the live GitHub Pages site.
Keep everything running
No action needed. Choose this if you want to keep your JARVIS portfolio live and accessible to anyone.
- Your site stays live at https://username.github.io with zero cost.
- The GitHub API has a rate limit of 60 requests per hour for unauthenticated calls, which is more than enough for normal visitor traffic.
- Your local project folder remains on your Desktop for future edits.
Pause - I'll come back to this later
Take the site offline while keeping all your code and repository intact. There are no local processes to stop since this is a static site.
- Go to your username.github.io repository on GitHub.
- Click Settings in the top navigation bar of the repository.
- Select Pages in the left sidebar.
- Under Build and deployment, change the Source dropdown to None and click Save.
- Your site goes offline, but your code stays in the repository. To re-enable it later, set the source back to Deploy from a branch (main, root).
Delete - I don't want to use this again
Remove all project resources completely. This takes down the live site and deletes your code from GitHub.
- Delete your local project folder by running this command in your terminal:
rm -rf ~/Desktop/username.github.io
- Go to your username.github.io repository on GitHub.
- Click Settings in the top navigation bar of the repository.
- Scroll all the way down to the Danger Zone section.
- Click Delete this repository.
- GitHub will ask you to type the full repository name to confirm. Type it and click the confirmation button.
- This permanently deletes the repository and takes down your live GitHub Pages site.
Nice Work!
Nice Work!
You just built a full JARVIS-themed portfolio website from scratch and deployed it live for the world to see. Anyone with your URL can watch the boot-up sequence play and explore your real GitHub data inside glowing HUD panels.
You've learned how to:
- Fetch live data from the GitHub REST API without authentication using fetch() and async/await, then inject it into the page with DOM manipulation.
- Create CSS animations including glowing neon borders, a scanline overlay, and a rotating SVG Arc Reactor using @keyframes and layered box-shadow.
- Build a cinematic boot-up sequence with typing animations and sequential panel reveals, then deploy the whole site to GitHub Pages at your own username.github.io URL.
- Secret Mission: Added voice-activated navigation using the Web Speech API with cross-browser feature detection so visitors can speak commands to highlight panels.
Ready to quiz yourself?