Making of toko.re
How I made it, animations, process, brainstorming, try and errors.
- 1 Sept 2025
- ⌘
- 4 min read
Table Contents
- Preparation
- Set up
- Domain name
- Visuals
- Font
- Animate an SVG
- color
- The Logo
- Global Elements
- Navbar
- Background Effect
- Page Transitions
- Dynamic Header
- Easter Eggs
- Metadata and SEO
- Page-progress-Bar
- 2.7 Shortcuts
- Footer
- Sound
- Pages
- Home page
- About me section
- Name Pronunciation
- A character
- Section Highlighs
- Project Index page
- Blog Index Page
- some will have subblogs
- Blog and Project pages
- Media
- Photography and Design
- Images
- Images Metadata
- 404
- Structure of the directories
- ref
Preparation
Set up
Domain name
Why toko.re? Previously, my domain was my full name, but I discovered that many people didn’t really use their full name as a personal site, but either a acronym or some shortened nickname, like rsms.me or cheff.dev. I shortened my name, while still being easy to pronounce for people from different mother tongues and intended it to be remembered easily. At the same time, I want to move out of the .es domain and use another one.
Visuals
- Implement a new logo.
- More visuals on documentation.
Font
-
Change font of the previous website.
-
How to choose
- have a good looking
f, that doesn’t will crumped - robust
e - bottom hooked
y - wider fonts
- more than 2 styles
- have a good looking
-
Posible fonts
- monospace
- Chivo Mono - 2 axes var
- Cascadia Code - 2 axes, the one used by Josh Comeau
- Spline Sans Mono - 2 axis
- sans-serif
- others
- Yarndingssew
- monospace
Animate an SVG
My aim was to let the hamburger button change its color depending on if the page is in dark or light mode. Sounds quite simple and straightforward; the hamburger SVG should be as easy as applying colors to text, but I was wrong. Soon I found it was a quite complicated task to achieve. I tried a lot of ways until I was “lucky”, but mostly patient.
-
First, I tried the most logical way: applying the color directly on the
hamburger.svgfile, finding where the color is located, and it was calledfill. I applied it, and it worked. -
Then I wanted it to have a variable color
var(--text-menu)which is orange in dark mode and black in white mode. Here start the issues: you couldn’t write this variable into the SVGfill.
<svg>
<g fill="var(--text-menu)">
<path d="m520...>
...
- Second way should be adding a class element to the svg group and styled it with CSS, unfortunetely that also doesn’t work.
<svg clip-rule="evenodd"...>
<g class="hamburger-g" fill="var(--text-menu)">
<path d="m520...>
...
- CSS
.hamburger {
fill: var(--text-menu);
}
- The last way I tried was putting the whole SVG in my HTML, and then it was working.
color
- Only use a limited palette of colors, maybe use the yellow-orange-purple palette.
- Light/Dark mode across all the site.
- Have it even in my head picture in the CV, so it will change the lighting of the face pic doing a fade out between the light and dark pic.
The Logo
Global Elements
Navbar
I want to keep it always on top to be something consistent and easy for the user to navigate on the website the fastest way possible.
Navbar blur effect learnt on (https://www.joshwcomeau.com/css/backdrop-filter/)
Background Effect
I was thinking if I want a sticky navbar, the personal blogs many people haven’t a sticky, some have, or even some have a sticky footer, which feels quite refreshing. After I choose to have a sticky navbar, then I ask myself, what should the background of that navbar be:
- Straight putting the default background color I have, a very minimal but not good-looking approach.
- Put a thin shadow on the bottom of the navbar so it doesn’t feel it is “cutting” or devouring the page.
- Have a more modern transparent + blur effect, like a “matte” glass.
At the end I didn’t choose either of them, but I mixed the last two, ending up with a small bottom line which has a transparent blurred effect, which I also took some tricks learned from Josh Comeau’s Backdrop blog. On dark mode it has a Halation Effect around the light sources commonly seen on cine film.
Page Transitions
Im using Astro …
function initYearHeaderHover() {
...
}
// Initialize on first page load
initYearHeaderHover();
// Re-initialize after every Astro client-side page swap
document.addEventListener("astro:after-swap", () => {
initYearHeaderHover();
});
Dynamic Header
On the Header on the sections is dynamically the width of the <main> …
Easter Eggs
Add some fun, hidden, easter eggs elements. More info on Easter Eggs.
Metadata and SEO
- :og preview for social sharing
Optimize meta tags and descriptions using tools like Yoast SEO.
Page-progress-Bar
Represents the user’s scroll position relative to the document length. Options:
- horizontal bar at the top
- A right-bottom mini-notification-style label that instead represents the number of read minutes left [2 minutes left].
- A cake countdown
- A clock countdown
2.7 Shortcuts
-
Search bar Press
/orcmd+Kwill pop up a cmd/search bar -
Navigate
tabgo by projects or blogs on the indextchange theme
Footer
Go to top, logo(go to home), github link, copyright, cv. is a ligther color, which will became black when hover. like github.
Sound
-
sound fx like joshwcomeau
- record your own sound with my voice
-
Sounds will appear when
- scroll though blogs
- toogle sound
- toogle theme
Pages
Home page
About me section
Have the CV link right there in English, Chinese and also make a terminal version, that renders your (JSON) resume/CV for online & pretty terminal display
Name Pronunciation
Being a non-English name I have put a speaker logo which wehn you preass there will be a voice speaking. Because I saw some personal pages have that like Una Kravets and Josh Comeau. For the voice peaking my name I choose the Efrayn voice from Elevan Labs Voices, it will randomly play one of the three voices I have selected, I found it quite funny having many voices saying your name each its own entonation and vibe.
A character
Dimension: 1D, 2D, 3D, 4D (time), 5D, and more.
Form: 3D, pixel, line avatar, sketch, my candy-eyed char
Interactive level: follow cursor, touchable, draggable, null, multiple.
- It can be grabbed
- animated in 10fps like stop motion
- follow in limited array of pigs
- a more natural way of implementing it
- it behaves like a cat, it wants to grab the pointer when it is closer.
- if you move the cursor really fast it will pay more attention
- the eyes following the pointer are implemented in a more organic way,
- it will have a delay like a 0.3~3s(which will randomly change, and not like a robot)
Section Highlighs
After the About me section I will have some highlight of my projects and a bento box with my designs, photogrpahy blogs and my contects and cv.
Project Index page
[…]
Blog Index Page
Big ref is mschf
(#travel) (#eficient) (#foodie) (#dev) (#geopolitics)
2025/03/23 TARO do we need an input for taiwanese(hokkien)?
2004/04/14 GROUND what on green earth is homebrew?
1999/12/31 FIN end of an era or the civilization #3u5bn
09/20 NOTABLE thoughts about the new windows 2000
03/23 CERN certain about
1973/12/29 TOOTH bluetooth its enemies
10/11 > BONE < what remains in the ground
05/14 BANANA wtf.js
01/13 WAVES radio, wifi, microwave, colors, sounds
The blog index was heavily inspired by the 90s websites when JS was wearing diapers and CSS barely could talk. The hover effects were based on the start screens of 80s games where you have arrows to see where you are selecting.
I took some inspiration from the MSCHF website to be minimal, unidirectional, in addition to the 90s websites’ indexes without colors and fancy CSS styling.
From that minimal design, I went on to think about adding more sort options like sort by alphabetical or by date, and having ascending or descending order. Also, to have two types to display the index, in a line or the normal boxes you usually may find on other blogs, but I stuck with one choice at the end.
- Guestbook: maybe in post-it, code(HTML/CSS component) or text/ascii art based.
- Types: learnings, documentation, experiences, zettens.
- Topics: #geopolitics, #code, #design, #travel, #science, #philosophy.
Each blog in the index will be represented with
- Date of birth, it will be in a 0.3 lighter font color
- Title, is in uppercase and has a maximum of 8 letters
- Subtitle, in lower case
hotkeys
- tab jump over the years of the blogs
- ⬆️/⬇️j/k move over blogs
some will have subblogs
will have a open folder like in the sidebar of finders when you open a folder:
⬇️ SWEDEN the good, the bad and the weird of the nation of Spotify, Pipi, Zipper, Tetrapak and IKEA and Fika UNI ergonomics, chairs, students, architecture, HOME SOCIAL FOOD kebab jalapeño pizza > meatballs NATURE one of its delicatessens CITY AUTO not the cars, but the automation
On the university, on the apartment
Blog and Project pages
For the blog pages, I will have an ASCII code art on top, whereas for the project, I will illustrate a header image.
Projects are focused on long-run projects that heavily affected my knowledge, and I share my learning, my struggles, and my successful paths. Blogs may be short, more friendly, and may mix small projects, thoughts, experiences, and random stuff.
____ _ _ _ _ _ _ _
| __ ) / \ | \ | | / \ | \ | | / \
| _ \ / _ \ | \| | / _ \| \ | | / _ \
| |_) / ___ \| |\ |/ ___ \ |\ | |/ ___ \
|____/_/ \_\_| \_/_/ \_\_| \_|_/_/ \_\
**How it become a reason to be yellow**
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
( 👍 ) ( + )
← SNAKE | BLOG INDEX | SAUCE →
Media
For the images, I have some styling. One styling for individual images and another for a group of images.
For the embedded videos, mostly from YouTube, I will make some changes like adding a change to width="100%" so it will not overflow the page when the viewport width of the user is smaller.
Photography and Design
Both sections are basically using the same backbone, only the content changed. Both share the same styling and tsx files.
I want to have all dynamically in one page. Why should you have to go back to the index and then go to another album? Why shouldn’t I show you any visuals right when you enter the picture section?
The sections are based on the type of the picture and location. I will have 37 featured pics. Then, when you scroll to the bottom of the 37th pic, it will point you to the […]
Images
As any good mainly image driven page, you can sort the images, can zoom in […]
Images Metadata
Organize Image Metadata with Tags
To have images placed in src/assets/design with independent tags and enable tag sorting on the design and photography pages in Astro, I follow this step.
But then the first issue happened. The pictures were showing locally, but when deployed, there weren’t showing anything. Then I tried adding this code to my astro.config.mjs:
output: "server",
adapter: vercel({
imageService: true,
}),
- Still dint work so I put the pictues in the public folder and use the vercel image optimazation
const getOptimizedImageUrl = (src: string, width = 600) => {
// If src is absolute URL, encode directly. If relative (like /assets/...), prepend site origin:
const origin = typeof window !== "undefined" ? window.location.origin : "https://toko.re";
const absoluteUrl = src.startsWith("http") ? src : origin + src;
return `/_vercel/image?url=${encodeURIComponent(absoluteUrl)}&w=${width}&auto=format`;
};
Now I face the porblem that the images arent shown localle, How to handle image URLs to work both locally and in production
if (import.meta.env.MODE === "production") {
// Vercel production URL for optimization
return `/_vercel/image?url=${encodeURIComponent(absoluteUrl)}&w=${width}&q=${quality}&auto=format`;
} else {
// Local development - return absolute/public URL without optimization
return src;
}
- Create a js file where each image is an object including its file path, alt text, description, and an array of tags:
export const designProjects = [
{
src: "/design/image.jpg",
alt: "cutie pie",
description: "I cooked it for two hours but end up fluffly and not tasty",
tags: ["mock", "cooking"]
},
Static asset placement and referencing
Static asset placement and referencing
Previously, I had the images located on src/assets. Although in development, it seems to work properly, on production, it fails to appear and will fall back to the alt text.
404
I like how the whole 404 page of ABCdinamo has a messy doodle of a sick dog in a human bed. I find it logical to have an email to report a broken link right in the 404 page; the only time I saw that implemented was in Rafal’s untested site, which coincidentally also has a dog on a bed, although it looks healthier.
Structure of the directories
project/
├── notes/
├── src/
│ ├── components/
│ │ ├── Nav.astro
│ │ ├── Footer.astro
│ │ └── ...
│ ├── pages/
│ │ ├── blog/
│ │ │ ├── blog1.md
│ │ │ ├── blog2.md
│ │ │ └── ...
│ │ ├── project/
│ │ │ ├── prj1.md
│ │ │ ├── prj2.md
│ │ │ └── ...
│ │ ├── 404.astro
│ │ ├── blog.astro
│ │ ├── design.astro
│ │ └── index.astro
│ │ ├── photography.astro
│ │ ├── project.astro
│ ├── styles/
│ │ └── global.css
│ └── scripts/
│ └── global.ts
├── public/
│ ├── project/images
│ ├── blog/images
│ ├── cv.pdf
│ ├── hamburguer.svg
│ └── favicon.svg
├── .env
├── .gitattributes
├── .gitignore
├── .prettierignore
├── .prettierrc.mjs
├── astro.config.mjs
├── eslint.config.mjs
├── LICENSE
├── package.json
├── README.md
├── docu.md
├── robots.txt
└── tsconfig.json
ref
- mauro balades
8creator of zen, tea milf color, animated intro, but really simple one - matthewrayfield
990s style meme, crazy experimenting guy - boutique design com
- anthonycossins
9uk swisstype design, triple theme, - gregives
92010s bento design with the creator follow at your cursor