Skip to content

Latest commit

 

History

183 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Angelo Demetroulakos — Engineering Portfolio

This is the source for my personal engineering portfolio: aloeveraz.github.io.

I use the site to keep my robotics, CAD, controls, manufacturing, and 3D-printing work in one place. The project cards come from one JSON file, so I can add a build without rewriting the page layout each time.

Files

  • index.html contains the page structure and project modal.
  • portfolio.css handles the layout, responsive styles, and visual effects.
  • portfolio.js renders the profile, project collections, carousels, and modal content.
  • portfolio-data.json holds the profile, skills, project write-ups, media, and links.
  • consent.js keeps YouTube embeds from loading until a visitor asks for them.
  • assets/ contains the project photos, GIFs, graphics, and the self-hosted fonts.
  • project-example.json is a project record I can copy when adding something new.

Supporting pages and files: privacy.html, terms.html, 404.html, page.css and page.js (shared styling and the zoom-aware root font size for those three), fonts.css, icons.css, robots.txt, sitemap.xml, and site.webmanifest.

Spacing

Every vertical gap on the site comes from one of six tokens, declared and explained at the top of portfolio.css and copied into page.css:

Token Value Used between
--rhythm-label 12px a label and the heading it names; one list item and the next
--rhythm-heading 16px a heading and the line that supports it; one line of a passage and the next
--rhythm-rule 16px either side of a rule inside a card
--rhythm-block 24px one block and the next inside a section
--rhythm-header 48px a header and the content it heads
--rhythm-section 48–96px one section and the next

Which token a gap takes depends on what the two things are to each other, not on where they sit, so the hero's badge stands above the name at exactly the distance a section's label stands above its title. Nothing sets a spacing value of its own; if a new pair does not fit one of the six, the pair is probably named wrong.

These are the distances you see, not the distances between two boxes. A line box is taller than the letters in it, and by a different amount for every line-height on the page — which is why the hero's name used to sit visibly closer to the badge above it than to the tagline below it, despite having the larger margin of the two. Each text block is therefore leading-trimmed: a pair of zero-height pseudo-elements pulls its box in to cap height at the top and the baseline at the bottom, using the font metrics in the same :root block. The end of portfolio.css carries the arithmetic. To trim a new block, set --lh to its line-height as a plain number, write line-height: var(--lh), and add it to the list for the face it is set in.

tools/measure-faces.js re-reads those font metrics, and is the thing to run if a typeface is ever swapped or resubset.

Nothing loads from a third party

Fonts, icons, and every project image are served from this domain. Opening the page makes no request to Google, a CDN, or an analytics service, and the site sets no cookies. The only outside request is YouTube, and a project video stays a local placeholder until someone clicks it. privacy.html explains this to visitors; keep the two in step if that ever changes.

Run locally

The portfolio is a static site, but it needs a local server so the browser can load the JSON file.

python -m http.server 8000

Then open http://localhost:8000.

Add a project

  1. Add the project images to assets/.
  2. Copy the record in project-example.json into the projects array in portfolio-data.json.
  3. Replace the example values and set category and collectionOrder.
  4. Write an imageAlt describing what is actually in the picture — not the project name, which the heading beside it already says.
  5. Set featured to true and add a featuredOrder when the project belongs in the first row.
  6. Run the media scripts below, then check the card, project modal, links, and mobile layout locally.

Empty links and media fields are skipped by the page, so unfinished material can stay out of the public portfolio until it is ready.

Rebuilding media and assets

The scripts in tools/ regenerate the files that are not written by hand. They need Python with pillow, fonttools, and brotli.

python tools/build-images.py      # source photos/GIFs -> compressed WebP
python tools/build-thumbnails.py  # 900px card variants next to each image
python tools/link-thumbnails.py   # record each card's srcset in the JSON
python tools/build-icons.py       # subset Font Awesome to the icons in use
python tools/build-fonts.py       # download and self-host Inter + Barlow Condensed
python tools/build-brand.py       # favicon set and the social preview card

tools/measure-faces.js is not part of that run: it is pasted into the browser console and prints the --face-* metrics the leading trim needs.

Run build-icons.py again whenever the markup starts using a new fa- icon, otherwise that glyph will not be in the subset and will render as a blank box.

After changing portfolio.css, portfolio.js, or portfolio-data.json, bump the ?v= cache-busting suffix in the HTML files (and the one on the portfolio-data.json fetch inside portfolio.js) so returning visitors do not get a stale copy.

Hosting notes

GitHub Pages serves this from the repository root. HTTPS needs no action: a *.github.io host is on the HSTS preload list and GitHub redirects http:// to https:// on its own — verified against the live site. The upgrade-insecure-requests meta tag in each page covers subresources. If this ever moves to a custom domain, that stops being automatic and Settings → Pages → Enforce HTTPS has to be switched on for the new domain.

About

Engineering portfolio

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages