This is a submission for Frontend Challenge: Office Edition sponsored by Axero, Holistic Webdev: Office Space
What i built
LazyCats intranet portal: where work feels like play
At my workplace, we use a legacy corporate CRM - honestly, it feels ancient. That got me thinking: what if we could transform boring work routines into an engaging adventure? I've always dreamed of being at the forefront of a company that builds amazing games, and little by little, I’m working towards that vision. Now, I’m excited to share with you the prototype of LazyCats - a game developer’s intranet portal!
Design philosophy: Game Development from the Inside Out
Imagine: you’re a game developer, building intricate, vibrant worlds every day - places where people love the journey, the interactions, and the challenges. Then you log into your company system, and... the fun evaporates. I wanted to break this stereotype.
LazyCats Intranet is crafted as a genuine game ecosystem. Every employee has a level (our protégé John Willson is already at level 42!), gains experience, and earns achievements. Here, achievements aren’t just digital badges - they represent real recognition of one’s contribution to the team and the company’s growth.
The architecture of experience
Dark gradients, smooth transitions, sleek icons - my goal was to make everything feel more like a premium game than another forgettable office app.
Each section has its own vibe:
• The Dashboard greets you with a warm welcome and fresh stats.
• Team showcases your “guild” of developers, their skills and roles.
• Tasks turns planning into a strategy game.
• The Knowledge Base is a spellbook library (read: documentation).
• Cards - yes, LazyCats includes collectible cards with real in-company perks employees can use!
• News page with comments block.
• A profile page where the employee can track completed courses, their activity, achievements, experience history, and skills.
• A page for tracking the company's stock price.
• A company chat with group-based channels.
• A page with a set of tools that simplify corporate life.
Tech magic
Under the hood: Nuxt 3 (Vue 3). Tailwind CSS 4 brings flexibility to the design, while the auto-animate plugin adds those smooth transitions everyone loves.
One standout feature is Presentation Mode. See that ▶️ button? It’s not just for show (though it’s not fully wired up everywhere yet - still a work in progress). Click it, and a component comes to life, revealing new data or showcasing what’s possible.
What I wanted to achieve
My main goal was to create a system employees actually want to use (instead of dreading every new notification). I want checking tasks or reading company news to feel like a micro-reward.
It’s an ecosystem of motivation: every action gives experience, every achievement is celebrated, every employee can see their progress - just like in an RPG, only in real life. Of course, this is just a prototype, but I’ve tried to bring it as close as possible to my true vision. The emotional side - that’s what makes LazyCats special.
The Result
The result is a portal that reflects the culture of our (so far, fictional) company, sending a clear message: we’re not just coding - we’re creating experiences. And that experience starts with your very first click on our little cat logo. 🐱
Demo
Journey
The cats didn’t appear by accident. Lazy Cats is a perfect metaphor for developers, isn’t it? We may seem lazy, but in reality, we’re just conserving energy for what truly matters. Besides, who would say no to a company intranet with cats in the logo?
Technical Solutions I’m Proud Of
Nuxt
In short, I really liked Nuxt 3. It’s built on Vue 3 and comes with everything you’d normally have to set up manually: routing, server-side rendering, TypeScript, and module integration - all out of the box. That saves a lot of time, allowing me to focus more on logic and UI instead of spending hours on infrastructure. It’s also super convenient that changes appear instantly thanks to hot reload, and page generation is fast and predictable. Sure, not everything is perfect - I did run into some truly bizarre bugs in my production projects - but overall, the experience has been positive, and working with Nuxt just feels comfortable.
Gamification without overkill
The core feature of the project is subtle gamification. No loud pop-ups shouting “CONGRATS, YOU GOT +10 XP!” Instead, it’s all about delicate touches: user levels, an achievement system, smooth animations. Everything is integrated so naturally that it feels like a native part of the UI.
Composables as the soul of the app
What I’m most proud of is the composables-based architecture. Every piece of logic has its own home: useTeamData, useAchievements, useStockData. This isn’t just modularity - it’s a philosophy. Want to add a new feature? Create a composable. Need to tweak the logic? Open the relevant file. Clean and beautiful.
Corporate tools system
Restroom monitor, climate control, parking spot tracking - these features came from the idea that an intranet should solve real-world office problems. It may sound absurd, but imagine: no more bathroom queues or thermostat wars!
A Story of how 8GB of RAM per site taught me to listen to my computer
Here comes the most dramatic part of the story. I was working on a modal image optimization component - modal-image-optimizer.client. The goal was simple: when a user opens a card, the image inside should be reloaded in high quality. So I wrote a function called forceImageQuality, added a bunch of event listeners - everything worked flawlessly.
Testing went great. Cards opened, images looked crisp. Beautiful. I committed the code and went to make some tea.
A few days later, I was polishing the card animations. I opened one card, then another, then a third… and suddenly, I heard it - my computer roaring like a Boeing at takeoff. At first I thought, “Eh, must be something in the background.” I hovered my mouse over the app tab and...
The browser tab was using 8 gigabytes of RAM. Eight, Carl! My poor PC was weeping blood, fans blasting at full throttle.
I jumped into debugging. Opened DevTools → Memory tab - and there it was: a sea of orphaned event listeners stuck in memory. I had assumed JavaScript would just clean up everything. Rookie mistake.
Turned out, in the forceImageQuality function I was adding a load event listener to every image - but never removed it after execution. Each time a card opened, another handler got stuck in memory. And since I was opening cards constantly while developing…
// What I had (bad):
image.addEventListener('load', handleLoad);
// What it should’ve been (good):
image.addEventListener('load', handleLoad);
// ... and later:
image.removeEventListener('load', handleLoad);
One simple removeEventListener line - could’ve saved hours of suffering. Lesson learned: what you add, always remove. Memory is not infinite.