When Alternative Finds You
Freelancing usually means juggling consumer work whereas attempting to put money into your individual progress and future prospects. Selecting to dedicate time to work on your self isn’t a simple choice as a result of it could actually rapidly really feel such as you’re “shedding” cash. However as a French expression goes, “Le hasard fait bien les choses”, which may be translated to “As luck would have it”.
One month, I instantly discovered myself with none tasks or earnings. Fairly than seeing it as a setback, I selected to deal with it as a chance: a uncommon likelihood to be proactive and switch this quiet interval to my benefit by utterly rethinking my portfolio.
Defining Objective
With the fifth iteration of my portfolio, I already had a stable basis, so ranging from scratch wasn’t crucial. The construction was easy and clear, I refined it into three pages:
- Residence: introduces the necessities, previews tasks, and guides guests to discover my profile or dive into the work.
- Work: showcases every mission with fullscreen parallax imagery, important data, and color-driven animations. A number of navigation paths make sure the content material flows naturally and each mission will get observed.
- About: presents my background, method, providers, and phone data.
The actual problem wasn’t the construction although, it was the connection between type and content material which nonetheless didn’t really feel absolutely aligned. That’s why I revisited each phrase and rethought each sentence, ensuring the portfolio didn’t simply showcase my work, but in addition actually mirrored who I’m and what issues most to me as an impartial.
With that basis clarified, it was time to outline the aim behind it. With a background in design, and having grown right into a frontend developer over time, I wished my portfolio to lastly convey the duality that defines my work. That’s how the intention and guiding imaginative and prescient of my new portfolio took form:
Reclaiming my UI eye whereas asserting technical experience.
Structure & Id
Having grown up within the birthplace of the Swiss Model (recognized in graphic design for its modular grids, sans-serif typography, and minimalist graphic parts) and having studied structure for a yr, my method is of course rooted in methods, precision, and symmetry. The purpose was to create a refined identification, fastidiously built-in and delivered to life by way of distinctive animations.
Fonts & Colours
With simplicity in thoughts, I selected a single fashionable and versatile typeface: Neue Montreal from Pangram Pangram Foundry. An intentional nod to the three years I spent in Canada.
The colour palette can also be intentionally restrained: shades of black and white, with a contact of orange on the About web page so as to add a extra private really feel. On the opposite pages, the principle colours of every mission information the visible route, letting the work itself take middle stage.

Strict Grid System
The portfolio additionally depends on a single strict grid, with parts stretched throughout the display screen and positioned to benefit from the house. This disciplined format provides each web page a way of stability, rhythm and consistency

Improvement Overview
For each mission, I attempt to set myself a technical problem or study one thing new. For this one, it was constructing a backend with Sanity. It ensures longevity and effectivity, mixed with my normal tech stack that I all the time try to maintain as fashionable and up-to-date as potential.
Tech & Instruments
- Nuxt 4: versatile frontend framework
- Sanity CMS: headless content material administration
- TypeScript & SCSS: modular and reusable code
- Pinia: to handle world state and knowledge
- Lenis: clean scrolling
- GSAP: scroll and textual content animations
- Swiper: touch-friendly sliders
- WebGL: pixel path impact
- Vite & Nitro: server-side optimization
- Infomaniak: eco-friendly internet hosting
Backend Construction Overview
studio/ # Sanity CMS — Again-office content material administration
├── schemaTypes/ # Content material sort definitions
├── construction.ts # Studio sidebar construction
├── sanity.config.ts # Sanity mission configuration
└── sanity.cli.ts # CLI configuration
Frontend Construction Overview
internet/ # Nuxt 4 Utility — Entrance-end
├── app.vue # Root part, format & transitions
├── nuxt.config.ts # Nuxt configuration
├── pages/ # File-based routing
│ ├── index.vue # Residence web page
│ └── [...uri].vue # Dynamic catch-all (CMS-driven pages)
├── elements/
│ ├── blocks/ # CMS-driven content material sections
│ ├── nav/ # Navigation elements
│ ├── shared/ # Reusable UI elements
│ ├── icons/ # SVG icon
│ ├── system/ # Dev / debug utilities solely
│ └── templates/ # Web page-level templates
│ ├── About.vue
│ ├── Error.vue
│ └── Initiatives.vue
├── composables/ # Reusable Vue logic
├── shops/ # Pinia world state
│ ├── content material.ts # CMS content material retailer
│ └── ui.ts # UI state (navigation, loader…)
├── plugins/ # Nuxt plugins (app initialization)
├── directives/ # Customized Vue directives
│ ├── textAnim.ts # v-text-anim directive
│ └── scrollReveal.ts # v-scroll-reveal directive
├── middleware/ # Route middleware and redirections
├── server/ # Nitro server
│ └── api/sanity/[query].ts # Sanity API proxy endpoint
├── utils/ # Helper capabilities
│ └── sanityQueries.ts # GROQ question definitions
└── property/ # International stylesheets & fonts
Content material is fetched from Sanity as soon as at load by way of a server-side plugin, cached in Pinia shops to keep away from redundant API calls, then a single catch-all route [...uri].vue matches any URL, appears to be like up the corresponding knowledge within the retailer, and dynamically renders the precise web page template with its elements.
Every part is self-contained with its personal scoped SCSS and logic, whereas sharing SCSS utilities (mixins, easings, media queries) and composables (scroll animations, textual content reveals) are imported on demand and globally accessible.
Responsive System
To make sure pixel-perfect implementation of the design and maintain layouts constant throughout all screens, I depend on two custom-built parts that collectively type a simple to implement responsive system.
Grid Overlay
The primary factor, impressed by Figma’s Structure Guides (⇧ + G on Mac), is a part that shows the grid as an overlay and utilized in growth setting. It may be absolutely configured to match the design grid precisely.

Fluid Sizing
Then, a {custom} SCSS perform permits all sizes (font sizes, spacing, padding) to scale fluidly with the viewport as a substitute of leaping at fastened breakpoints. The result’s a smoother expertise and a extra managed format throughout all display screen sizes.
The perform, fluid-px(), generates a clamp() worth based mostly on three reference breakpoints:
- 480px: minimal viewport, the place the worth reaches its smallest measurement
- 1440px: design artboard, matching the precise worth outlined in Figma
- 2560px: most viewport, the place the worth reaches its cap
Instance utilization:
font-size: fluid-px(24); // → 21.6px at 480px, 24px at 1440px, 36px at 2560px
font-size: fluid-px(24, 16, 32); // → 16px at 480px, 24px at 1440px, 32px at 2560px
By default, the minimal and most values are calculated routinely (×0.9 and ×1.5 of the enter worth), however they will also be overridden manually. This produces a single responsive worth with no media queries required.
SCSS configuration
// Breakpoints
$fluid-min-viewport: 480 !default;
$fluid-artboard-size: 1440 !default;
$fluid-max-viewport: 2560 !default;
// PX → REM
@perform fluid-px-to-rem($px, $root: 16) {
@return calc($px / $root * 1rem);
}
@perform fluid-px($worth, $min: null, $max: null) {
$min-vw: $fluid-min-viewport;
$pref-vw: $fluid-artboard-size;
$max-vw: $fluid-max-viewport;
@if $min == null { $min: $worth * 0.9; }
@if $max == null { $max: $worth * 1.5; }
$min-rem: fluid-px-to-rem($min);
$value-rem: fluid-px-to-rem($worth);
$max-rem: fluid-px-to-rem($max);
$slope-1: (#{$worth - $min}) / (#{$pref-vw - $min-vw});
@return clamp(
#{$min-rem},
calc(#{$min-rem} + #{$slope-1} * (100vw - #{$min-vw}px)),
#{$max-rem}
);
}
Instance
p {
width: fluid-px(340);
font-size: fluid-px(24);
margin-top: fluid-px(100, 60, 120);
margin-bottom: fluid-px(100, 60, 120);
}
By scaling each dimension collectively, the container and the textual content shrink on the identical price. The variety of phrases per line stays constant, stopping sudden wrapping or format shifts. The identical paragraph merely adapts easily to any display screen measurement.
Modular and Contextual Navigation
An simply accessible and context-aware navigation bar that breaks the inflexible format to carry some flexibility and motion. Sitting on the backside middle of the display screen, it’s a completely modular part that invitations the consumer to play and work together with.
One part, three completely different behaviors pushed by the web page state:
- Residence: pages hyperlinks and a mission carrousel permitting to rapidly entry a specific content material
- Work: thumbnail of present mission with a number of actions buttons round it, one in all them triggering a full tasks record aiming to once more simplify navigation within the web page
- About: present seen part and arrow to navigate into web page with social hyperlinks showing on hover
To bolster the accessibility intention, the module responds to keyboard enter: arrow keys to navigate and Escape to go residence, permitting the consumer to go to your entire website utilizing just one part.

Tailor-made Animations
All animations are triggered both on scroll or on mouse interplay. They goal to create a sort of geeky feeling, highlighting my dev-side all through the positioning. To maintain them straightforward to make use of and constant, the pixel-based one are reusable elements with parameters whereas the others are centralized into two methods: useScrollProgress, a Lenis-driven composable for scroll-based animations, and v-text-anim, a {custom} Vue directive powered by GSAP SplitText that handles all textual content results with a single attribute.
- Pixel Transition: On arrival, the display screen loader disappears in a grid of stable white pixels, revealing the web page beneath.
- Pixel Path: In the identical vibe, a WebGL canvas renders coloured pixels sampled immediately from the underlying pictures. Every pixel has a randomized lifetime and fades out independently, creating an natural, scattered path that displays the precise content material beneath the cursor.
- Terminal reveal: Textual content varieties out character by character with a blinking block cursor transferring alongside as if it was printed in actual time by a command line. As soon as full, the cursor disappears.
- Glitch reveal: randomizes by way of glitch characters (
@#$%&*, digits, uppercase letters) earlier than resolving to the actual textual content. It feels just like the textual content is being decoded or descrambled. - Parallax: Because the consumer scrolls, the fullscreen pictures and the footer translate with sturdy destructive values to provides the sensation of inertia and depth.


Conclusion & Ideas
This newest model of my portfolio is a crucial milestone. For the primary time, I set a transparent deadline to finish a full identification redesign with a goal. The result’s a website that displays my strengths: rigorous, but artistic, and has given me credibility and visibility I by no means might have imagined. After all, this website will proceed to evolve, however the important thing lesson is obvious: even for private tasks, a structured method and methodology result in the most effective outcomes.
I hope this case research conjures up your individual artistic journey. Thanks for sticking round and don’t hesitate to succeed in out!


