01
Case Study · 2024—2025

HOW I BUILT MY PORTFOLIO

A raw breakdown of every decision, every tool, every sleepless iteration that went into building portfolio.vajracognixia.in — from blank file to live production.

Stack
HTML · CSS · JS · Firebase
Hosted
Firebase Hosting
Domain
portfolio.vajracognixia.in
Builder
Devanshu Dhyanu
Scroll to explore
01 · The Origin
THE
IDEA

Most students build portfolios with templates — drag, drop, publish. I wanted something that proves itself by existing. If I claim to build real things, my portfolio should be a real thing.

The constraint: zero templates, zero frameworks, zero shortcuts. Every pixel, every animation, every API call — hand-written. The portfolio is the project.

As a B.Tech CSE student at LPU and national-level handball player, I wanted both identities to come through. Technical precision of a developer, competitive drive of an athlete.

0
Templates used
1
Dev · just me
100%
Custom code
Iterations
02 · The Process
HOW IT
CAME ALIVE
Phase 01 · Design
Vision & Wireframe

Started with rough pencil sketches on paper. Decided on a dark monochrome palette — #060d1a background, orange as the only accent, Bebas Neue for display punch. The rule: if it doesn't feel sharp, cut it. Took three complete redesigns before anything felt right.

SketchingTypographyColor theory
Phase 02 · Build
HTML Foundation

Semantic skeleton first. Proper landmarks, headings, accessibility. CSS custom properties set up before a single component was built.

HTML5CSS vars
Phase 03 · Style
CSS & Motion

No frameworks. Pure CSS — grid, flexbox, keyframe animations, glassmorphism, scroll-snap, noise overlay. Every hover state was a deliberate micro-decision.

CSS3Animations
Phase 04 · JS
Interactivity

IntersectionObserver, GitHub REST API, Web Speech API, EmailJS — all vanilla JS. No React, no Vue. Each feature had to justify its bytes.

Vanilla JSAPIs
Phase 05 · Backend
Firebase

Firestore for contact messages. AI assistant via Claude API. Firebase Hosting for custom domain + free SSL — production-grade at zero cost.

FirestoreHostingClaude API
Phase 06 · Live
Ship & Iterate

Deployed. Shared. Got feedback. Fixed mobile. Added certifications, gallery, testimonials. A portfolio is never finished — it grows with you.

DeployedLive
03 · Tech Stack
TOOLS
USED
🌐
HTML5
Semantic structure, accessibility, landmark elements. 100% hand-written — no generators.
Structure
🎨
CSS3
Custom properties, grid, flexbox, keyframes, scroll-snap, glassmorphism. No framework.
Styling
JavaScript
IntersectionObserver, GitHub API, Web Speech API, EmailJS. Vanilla only.
Logic
🔥
Firebase
Firestore for messages. Hosting for custom domain, free SSL, global CDN.
Backend
✉️
EmailJS
Contact form to email, zero backend. SDK loaded directly from CDN.
Email
🐙
GitHub API
Live repo fetcher pulls latest repos and push timestamps dynamically every visit.
Live data
🔤
Google Fonts
Bebas Neue for display. DM Sans for body. JetBrains Mono for code.
Typography
🤖
Claude API
Powers the on-page AI assistant — answers visitor questions about skills and projects.
AI Feature
04 · The Code
REAL CODE
WRITTEN
GitHub API
Scroll Reveal
Audio Resume
Deploy Config
github-repos.js
// Live GitHub repo fetcher — runs on page load
async function fetchRepos() {
  const base = 'https://api.github.com/users';
  const user = 'Devanshu-Dhyanu';
  const res  = await fetch(`${base}/${user}/repos?sort=pushed`);
  const repos = await res.json();

  repos.slice(0, 6).forEach(repo => {
    const card = createCard(repo.name, repo.pushed_at);
    document.querySelector('#repo-grid').appendChild(card);
  });
}

fetchRepos();
scroll-reveal.js
// IntersectionObserver for scroll-triggered reveals
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible');
        observer.unobserve(entry.target);
      }
    });
  },
  { threshold: 0.15 }
);

document.querySelectorAll('.reveal')
  .forEach(el => observer.observe(el));
audio-resume.js
// Web Speech API — no library, zero cost
function playAudioResume() {
  const synth = window.speechSynthesis;
  const text  = `Hi, I'm Devanshu Dhyanu —
    Full Stack Developer at LPU.
    I build real products, not assignments.`;

  const utt = new SpeechSynthesisUtterance(text);
  utt.rate  = 0.95;
  utt.pitch = 1.0;
  synth.speak(utt);
}
firebase.json
{
  "hosting": {
    "public": ".",
    "ignore": ["firebase.json", ".firebaserc"],
    "headers": [{
      "source": "**/*.@(js|css)",
      "headers": [{
        "key": "Cache-Control",
        "value": "max-age=604800"
      }]
    }]
  }
}
05 · Lessons
WHAT I
LEARNED
01
Design before code

Jumping straight to HTML without a visual plan wastes hours. Even rough paper sketches save massive refactoring later.

02
CSS variables are powerful

Setting up :root variables for everything upfront meant I could retheme the entire site in minutes.

03
Vanilla JS is enough

No React, no Vue. Modern Web APIs — IntersectionObserver, SpeechSynthesis, Fetch — cover nearly every portfolio need natively.

04
Mobile first always

Built desktop first, paid the price with hours of broken breakpoints. Mobile first from day one next time — non-negotiable.

05
Optimise every asset

Uncompressed images tanked load time. Compressing to WebP and adding lazy loading made a measurable, visible difference.

06
Ship, then improve

Waiting for perfect means never launching. Put it live, get real feedback, iterate fast. Done is better than perfect — always.

LIVE

SEE THE
RESULT

The portfolio is live, production-ready, and constantly evolving. Come see what it became.

View Portfolio → VajraCognixia →