This is a personal portfolio website that I designed for my friend, Adrian Ackerman, a media professional with experience in video production, photography, content strategy, and social media. I built this website following Miladicode's YouTube tutorial "How to Create an Animated Portfolio Website with HTML, CSS & JavaScript | Step-by-Step Tutorial", then modified the source code to fit Adrian's preferences. I also created an experience section with animations that were not there in Miladi's version.
Live site: https://patrick948-stack.github.io/adrian-portfolio/ (about to move to Netlify — see "Deploying" below)
- Hero section — Typewriter effect intro animation over a looping space video of a black hole since Adrian loves space
- About cards — A four-card grid covering background, tools, availability, and the motivation behind their work
- Project gallery — Embedded YouTube videos that play on hover using the YouTube IFrame API
- Skills section — Two typewriter descriptions (Media Producer & Content Strategist) that trigger when the section scrolls into view, alongside an auto-scrolling tool logo carousel
- Experience timeline — A vertical timeline of past roles with expandable accordion panels (no JavaScript — pure HTML
<details>) - Contact — Social links + a Formspree-powered contact form
All of the text, photos, videos, and list content above (about cards, project gallery entries, tool logos, experience entries) is now editable without touching code — see Editing content below.
Every piece of editable copy and media lives in content/*.json, and is edited through a visual admin panel at /admin — for example https://your-site.netlify.app/admin. This uses Decap CMS, a free, open-source visual editor. No Git, no Markdown, no config files — just forms, image/video upload buttons, and "Publish" buttons.
What you can do from /admin:
- Site Settings → brand name, logo, and the YouTube/LinkedIn/Instagram links used everywhere on the site
- Hero (Top of Page) → the intro title/paragraph, the big heading, the button text, and the hero/galaxy/black-hole background videos
- About Section → the 4 "Hello, There" cards — title, description, and photo or video for each
- Skills Section → the two skills descriptions and the row of tool logos (add, remove, or reorder logos freely)
- Contact Section → the message, phone number, and email shown in the Contact section
- Project Gallery → add/edit/remove project entries — title, tag, YouTube link, description, and whether it's a vertical Reel
- Experience → add/edit/remove job entries — title, company, dates, location, an optional photo, responsibilities, and tools used
How publishing works: every edit is saved as a draft first (see the "Workflow" tab in the CMS). Nothing changes on the live site until a draft is explicitly moved to "Ready" and then "Publish." Netlify also builds a private preview link for each draft so you can check how it looks before it goes live.
Who can access /admin: only people you've explicitly invited by email (see "Deploying" below) — it's not just hidden, it's actually login-gated. Nobody else can reach it, and it never appears for regular visitors browsing the site.
The site currently lives on GitHub Pages. Moving it to Netlify's free tier is what turns on the /admin panel, since it needs Netlify Identity (login) and Git Gateway (lets the CMS commit content changes on your behalf). Everything in this repo is already configured for that move — nothing else needs to change in the code.
- Push this repo to GitHub (if it isn't already up to date there).
- Create a free Netlify account at netlify.com and choose "Add new site" → "Import an existing project" → connect this GitHub repo.
- Build command: leave blank
- Publish directory:
.(already set innetlify.toml)
- Once the site deploys, go to Site configuration → Identity and click Enable Identity.
- Under Registration, set it to Invite only (so no stranger can self-register an admin account).
- Go to Site configuration → Identity → Services and Enable Git Gateway. This is what lets the CMS save content back to this GitHub repo without giving Adrian a GitHub account or any code access.
- Go to Identity → Invite users, and invite Adrian's email address. They'll get an email, click the link, set a password, and land on
/admin— no GitHub account, no code, ever. - (Optional but recommended) Set up a custom domain or at least note the
*.netlify.appURL Netlify assigns, and send that +/adminto Adrian.
After that, share https://<your-site>.netlify.app/admin with Adrian — that's their whole editing experience.
- HTML / CSS / JavaScript (vanilla) — the site itself is still a static site, no build step
- Decap CMS — the
/adminvisual content editor (config inadmin/config.yml) - Netlify Identity + Git Gateway — free login for the admin panel, no separate backend/database
- AOS — scroll-triggered fade/blur animations
- Boxicons + Font Awesome — icons
- Montserrat via Google Fonts
- YouTube IFrame API — hover-to-play on project embeds
- Formspree — contact form backend (no server needed)
The public site fetches content/*.json at runtime, so it needs to be served over http://, not opened directly as a file:// URL (the same requirement the YouTube hover-play feature already had).
npx serve .
# then visit the printed localhost URLThe real login (Netlify Identity + Git Gateway) only works once the site is actually deployed to Netlify. To test the CMS editing UI locally beforehand — without deploying, and without needing a login — run a second local process alongside the static server:
npx decap-serverThis starts a local proxy on port 8081 that admin/config.yml's local_backend: true setting automatically detects when the site is opened from localhost. Visit http://localhost:<port>/admin/, click the one-click local "Login" button (no password, dev-only), and you'll see the exact same forms Adrian will use — except saves write straight to your local files/git history instead of the live site. Good for double-checking field labels and layout before deploying; don't publish real changes this way if you want to keep your working tree clean — use the real deployed /admin for that instead.
├── index.html # Page structure — text/media containers are populated at runtime
├── styles.css # All styles
├── app.js # Fetches content/*.json, renders sections, then wires up
│ # typewriter/animation/interaction logic
├── content/ # All editable copy & media paths, edited via /admin
│ ├── site.json # brand name, logo, social links
│ ├── hero.json # hero heading/copy/videos
│ ├── about.json # the 4 "Hello, There" cards
│ ├── skills.json # skills copy + tool logo carousel
│ ├── projects.json # project gallery entries
│ ├── experience.json # job/experience timeline entries
│ └── contact.json # contact section copy
├── admin/ # Decap CMS — the /admin visual editor
│ ├── index.html # loads the CMS + Netlify Identity widget
│ └── config.yml # defines every editable field shown above
├── netlify.toml # Deploy config (publish dir, admin no-index header)
├── images/ # Logos, grid card images, skill icons
└── videos/ # Background and hero videos (galaxy, blackhole, globe, hero)
Designed and built by Patrick MM. Source Code: https://github.com/MiladiCode/Animated-Portfolio Portfolio content and career work by Adrian Ackerman.