← Portfolio
Meta Project · 2026

Από Portfolio σε Προϊόν

Πώς μια δυσαρέσκεια με την αισθητική του Notion έγινε ένα ολόκληρο σύστημα — και γιατί το επόμενο βήμα είναι να γίνει προϊόν για όλους.

Vanilla HTML / CSS / JS Single Source of Truth EL / EN i18n 5-Phase Refactor

Η Αφορμή

Πριν μπει καν στη συζήτηση vanilla HTML ή React, η πρώτη σκέψη ήταν πολύ πιο απλή: ένα portfolio μέσα σε Notion pages. Γρήγορο, δωρεάν, δοκιμασμένο από χιλιάδες άλλους. Το πρόβλημα δεν ήταν ποτέ λειτουργικό — ήταν αισθητικό.

Καμία από τις έτοιμες πλατφόρμες σελίδων — Notion, Obsidian και ό,τι έμοιαζε μαζί τους — δεν άρεσε ποτέ οπτικά. Το ίδιο block-based look, τα ίδια περιθώρια, η ίδια αίσθηση «template» που θυμίζει χιλιάδες άλλες σελίδες φτιαγμένες με το ίδιο εργαλείο. Αντί να γίνει συμβιβασμός σε αυτό, η απόφαση ήταν να χτιστεί από την αρχή ένα παρόμοιο σύστημα — σελίδες, sidebar, δομή περιεχομένου — αλλά με πλήρη έλεγχο πάνω σε κάθε λεπτομέρεια.

Ταχύτητα υπήρχε ήδη έτοιμη στο Notion. Αυτό που έλειπε ήταν ταυτότητα — και προτιμήθηκε αυτό, ακόμα κι αν κόστιζε παραπάνω χρόνο στην αρχή.

Γιατί Καθόλου Framework

22 υποσελίδες, ένα κύριο index, χωρίς React, χωρίς build step, χωρίς npm install. Δεν είναι έλλειψη εξοικείωσης — τα περισσότερα άλλα projects στο ίδιο portfolio χρησιμοποιούν React, Docker, Python APIs. Ήταν συνειδητή επιλογή, με βάση το τι έπρεπε να κάνει αυτό το συγκεκριμένο site.

DEPLOY Static hosting οπουδήποτε — χωρίς build pipeline, χωρίς dependency να σπάσει σε ένα χρόνο.
PERFORMANCE Καμία framework runtime, καμία hydration — απευθείας HTML/CSS/JS στον browser.
LONGEVITY Δεν θα σπάσει από breaking changes σε major version upgrade — δεν υπάρχει version να ανέβει.

Το ρίσκο ήταν γνωστό εξαρχής: χωρίς framework, η πειθαρχία πρέπει να έρθει από αλλού — αλλιώς 22 σελίδες σημαίνει 22 αντίγραφα του ίδιου sidebar, του ίδιου cursor script, της ίδιας scroll λογικής. Αυτό ακριβώς έλυσε το refactor παρακάτω.

Ένα Config, Όχι 22 Αντίγραφα

Ο κανόνας του project είναι απλός: ποτέ μην αντιγράφεις κώδικα σε πολλαπλά HTML αρχεία. Το sidebar navigation είναι το καθαρότερο παράδειγμα — αντί να υπάρχει hardcoded σε κάθε σελίδα, ζει σε ένα αρχείο δεδομένων.

Απόφαση Σχεδιασμού — nav-config.js ως Single Source of Truth

Κάθε υποσελίδα φορτώνει nav-config.js και subpage-common.js. Το config file δηλώνει ποιες σελίδες υπάρχουν, με ποιο εικονίδιο και σε ποια ενότητα του sidebar· το script διαβάζει αυτά τα δεδομένα και χτίζει το πραγματικό DOM (τη δομή της σελίδας όπως τη «βλέπει» ο browser) κατά το load, ανιχνεύοντας ποιο item είναι ενεργό μέσω του τρέχοντος URL. Θέλεις νέα σελίδα στο nav; Προσθέτεις μία γραμμή στο config — όχι νέο HTML σε 22 αρχεία.

JavaScript · nav-config.js
// One entry = one page. No HTML duplicated anywhere.
const NAV_CONFIG = [
  { type:'sub', href:'moodlight.html',
    icon:'lightbulb', el:'MoodLight', en:'MoodLight' },
  { type:'sub', href:'swaply.html',
    icon:'repeat', el:'Swaply', en:'Swaply' },
  // ...20 more entries, same shape
];

// subpage-common.js reads this once per page load,
// builds the sidebar DOM, and marks the active item
// by comparing NAV_CONFIG[i].href to location.pathname —
// no per-page "which link is active" logic to maintain.

Το ίδιο μοτίβο επαναλαμβάνεται σε άλλα δύο σημεία: όλο το κοινό CSS (cursor, chips, layout, scroll) ζει σε ένα αρχείο, css/style.css· και όλη η κοινή JS συμπεριφορά (custom cursor, scroll progress, back-to-top, mobile menu, fade-up animations) ζει στο subpage-common.js. Κάθε σελίδα κρατάει μόνο ό,τι είναι πραγματικά μοναδικό σε αυτήν.

i18n & Θέματα

Ελληνικά και Αγγλικά, χωρίς μηχανική μετάφραση — κάθε string γράφτηκε στο χέρι και στις δύο γλώσσες. Στο index.html, ένα κεντρικό λεξικό (i18n.js) κρατά όλα τα strings ανά κλειδί και τα εφαρμόζει με CSS selectors· στις υποσελίδες, ένα πιο ελαφρύ και γενικό μοτίβο κάνει την ίδια δουλειά χωρίς λεξικό ανά σελίδα.

HTML · οποιαδήποτε υποσελίδα
<!-- Any element can carry both languages inline -->
<p data-el="Ελληνικό κείμενο" data-en="English text">
  Ελληνικό κείμενο
</p>

<!-- subpage-common.js swaps innerHTML for every
     [data-el][data-en] element based on the saved
     language — no per-page translation file needed -->

Η επιλογή γλώσσας αποθηκεύεται σε localStorage και επιβιώνει μεταξύ σελίδων. Το ίδιο μοτίβο persistence χρησιμοποιείται και για το θέμα (dark gold ή light) — εναλλαγή με το πλήκτρο T ή από τα κουμπιά του sidebar, εφαρμοσμένο πριν καν ζωγραφιστεί η σελίδα ώστε να μην υπάρχει flash λάθος θέματος.

Το Refactor σε 5 Φάσεις

Το site δεν ξεκίνησε έτσι. Πριν το refactor, κάθε νέα υποσελίδα σήμαινε copy-paste ενός ~71-γραμμών sidebar και όλης της σχετικής JS λογικής σε ένα καινούριο αρχείο — 22 φορές. Πέντε φάσεις, μία δομική αλλαγή τη φορά, το μετέτρεψαν σε αυτό που περιγράφεται παραπάνω.

~1.800
Γραμμές inline JS · πριν
~265
Γραμμές inline JS · μετά
−85%
Μείωση κώδικα
01
CSS Consolidation
Όλο το κοινό CSS μετακόμισε σε ένα αρχείο, style.css — τέλος στα ανεξάρτητα, αποκλίνοντα style blocks ανά σελίδα.
02
Sidebar as Data
Το sidebar σταμάτησε να είναι hardcoded HTML και έγινε δεδομένα — nav-config.js + subpage-common.js injection.
03
Template Standardization
Όλες οι υποσελίδες ευθυγραμμίστηκαν στην ίδια λιτή δομή HTML — προβλέψιμη, εύκολη στη συντήρηση.
04
Script Consolidation
Κοινή JS συμπεριφορά (scroll, cursor, mobile menu, fade-up) μετακόμισε στο subpage-common.js — το βήμα που έριξε τις γραμμές κώδικα κατά 85%.
05
Τεκμηρίωση & Tooling
Γράφτηκε το CLAUDE.md ως single source of truth για τη δομή του project, και διορθώθηκε ένα zip-export bug που παρήγαγε τριπλά ένθετους φακέλους.
Το sidebar duplication ήταν απλώς το πιο ορατό σύμπτωμα. Η λύση δεν ήταν να διορθωθεί ένα-ένα τα 22 αρχεία, αλλά να μπει κανόνας που να μην αφήνει τη διπλή δομή να ξαναγυρίσει: κάθε νέα σελίδα ξεκινά πλέον από ένα λιτό template και μία γραμμή config.

Το Επόμενο Βήμα

Αυτό το site χτίστηκε αρχικά για μία ανάγκη — τη δική μου. Αλλά η αρχιτεκτονική που προέκυψε (ένα config αρχείο, κοινό CSS/JS, θέματα) είναι ήδη πολύ κοντά σε κάτι που θα μπορούσε να χρησιμοποιήσει και κάποιος άλλος. Το επόμενο βήμα είναι να γίνει ακριβώς αυτό: ένα portfolio σύστημα σαν το δικό μου, αλλά επεξεργάσιμο χωρίς να χρειάζεται ο χρήστης να ξέρει έστω και μία γραμμή κώδικα.

Θέμα με ένα κλικ
Επιλογή από έτοιμα θέματα (όπως το σημερινό dark gold ή το synthwave) χωρίς να ανοίγει κανείς αρχείο CSS.
Modular ενότητες
Προσθήκη ή αφαίρεση ενοτήτων όπως hero, projects, certifications, experience — σαν κομμάτια lego, όχι σαν επεξεργασία HTML.
Δικό σου περιεχόμενο
Ο καθένας βάζει τα δικά του στοιχεία — κείμενα, projects, links — πάνω στην ίδια δομή που ήδη λειτουργεί σε παραγωγή για τις δικές μου ανάγκες.
Οδηγίες βήμα-βήμα
Σαφείς οδηγίες παραμετροποίησης και deploy, ώστε όποιος θέλει να τρέξει το δικό του site να μπορεί να το κάνει μόνος του.
Managed hosting Μελλοντικό πλάνο
Σε βάθος χρόνου, να μην χρειάζεται καν deploy από τον χρήστη — να αναλαμβάνεται το hosting εξ ολοκλήρου, ώστε το μόνο που μένει είναι να γράψει το περιεχόμενό του.

Το site θα μπορούσε κάλλιστα να έχει μείνει 22 ξεχωριστά αρχεία με το ίδιο sidebar κολλημένο παντού. Το duplication εντοπίστηκε, η αρχιτεκτονική σχεδιάστηκε γύρω από αυτό, και τεκμηριώθηκε ώστε το ίδιο πρόβλημα να μη χρειαστεί να ξαναλυθεί σε κάθε νέα σελίδα.

Spilios Dimakopoulos · Meta Project · 2026
✓ EMAIL COPIED