summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/blogs.json5
-rw-r--r--data/blogs/1.md8
-rw-r--r--data/blogs/altaf-devlog-0.md14
-rw-r--r--data/blogs/urban0.md95
-rw-r--r--data/events.json12
-rw-r--r--data/events/infocomm.md86
-rw-r--r--data/events/noai.md45
-rw-r--r--data/events/noi.md24
-rw-r--r--data/events/nytc.md68
-rw-r--r--data/events/tinkertanker.md66
-rw-r--r--data/projects.json9
-rw-r--r--data/projects/deja.md170
-rw-r--r--data/projects/esp32-blockly.md3
-rw-r--r--data/projects/laundryweb.md66
-rw-r--r--data/projects/simpliCity.md6
-rw-r--r--data/projects/tinkertanker-webdev.md0
-rw-r--r--data/videos/eid2026.md11
-rw-r--r--data/videos/minds.md49
-rw-r--r--data/videos/openhouse.md7
-rw-r--r--data/videos/paperverse.md11
-rw-r--r--data/videos/s3via.md11
-rw-r--r--data/videos/stringsoffreedom.md30
-rw-r--r--main.py3
-rw-r--r--markdown_renderer.py11
-rw-r--r--pages.py14
-rw-r--r--templates/blogpost.html8
-rw-r--r--templates/eventdetails.html1
-rw-r--r--templates/project.html29
-rw-r--r--templates/video.html1
-rw-r--r--www/209.html2
-rw-r--r--www/500.html46
-rw-r--r--www/about/index.html397
-rw-r--r--www/assets/images/education/events/ai_jupyter.pngbin0 -> 1398689 bytes
-rw-r--r--www/assets/images/education/events/av.jpgbin0 -> 2379796 bytes
-rw-r--r--www/assets/images/game-hero/deja_screenshot.pngbin0 -> 2503424 bytes
-rw-r--r--www/assets/images/hero/altaf.pngbin974481 -> 0 bytes
-rw-r--r--www/assets/images/hero/logo.svg331
-rw-r--r--www/assets/images/logo/deja.pngbin0 -> 35086 bytes
-rw-r--r--www/assets/images/screenshots/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--www/assets/images/screenshots/deja/image1.pngbin0 -> 2503424 bytes
-rw-r--r--www/assets/images/screenshots/deja/image2.pngbin0 -> 1674631 bytes
-rw-r--r--www/assets/images/screenshots/deja/image3.pngbin0 -> 424280 bytes
-rw-r--r--www/assets/images/screenshots/deja/image4.pngbin0 -> 299199 bytes
-rw-r--r--www/assets/images/screenshots/deja/image5.pngbin0 -> 375740 bytes
-rw-r--r--www/assets/images/screenshots/deja/image6.pngbin0 -> 660067 bytes
-rw-r--r--www/assets/images/screenshots/deja/image7.pngbin0 -> 641478 bytes
-rw-r--r--www/blog/index.html2
-rw-r--r--www/codehilite-style.css83
-rw-r--r--www/index.html7
-rw-r--r--www/projects/index.html16
-rw-r--r--www/scripts/constants.js4
-rw-r--r--www/scripts/onload.js29
-rw-r--r--www/scripts/scroll.js6
-rw-r--r--www/style.css277
54 files changed, 1767 insertions, 296 deletions
diff --git a/data/blogs.json b/data/blogs.json
index 38e6a60..bd657ec 100644
--- a/data/blogs.json
+++ b/data/blogs.json
@@ -14,11 +14,6 @@
"thumbnail": "/assets/images/blog/33_cover.png",
"banner": "/assets/images/blog/33_banner.png",
"path": "/data/blogs/1.md"
- },
- {
- "thumbnail": "",
- "banner": "",
- "path": "/data/blogs/urban0.md"
}
]
}
diff --git a/data/blogs/1.md b/data/blogs/1.md
index f1168ee..2a0494b 100644
--- a/data/blogs/1.md
+++ b/data/blogs/1.md
@@ -40,11 +40,15 @@ It was a normal day. I was thinking of backing up simpliCity using GitHub. Becau
## The Problem
First, I made a new repo in GitHub, connect the git repo to the GitHub repo using **git remot**e, rename the master branch to main, and push it to GitHub using **git push**-
- fatal: The push operation includes a file which exceeds GitHub's file size restriction of 100MB
+```{: .txt .pre}
+fatal: The push operation includes a file which exceeds GitHub's file size restriction of 100MB
+```
..Alright then. Turns out I included the temporary, automatically-generated Unity project files and folder. To fix this, I added the .gitignore template for Unity to tell Git to simply ignore the files and folder, and upload it again-
- fatal: The push operation includes a file which exceeds GitHub's file size restriction of 100MB
+``` {: .txt .pre}
+fatal: The push operation includes a file which exceeds GitHub's file size restriction of 100MB
+```
Still the same error. Turns out that I have to remove the history of the ignored file, alias I have to make git forget about all of the temp files. **And this is where I messed up.**
diff --git a/data/blogs/altaf-devlog-0.md b/data/blogs/altaf-devlog-0.md
index 7c7fbf0..f709c7f 100644
--- a/data/blogs/altaf-devlog-0.md
+++ b/data/blogs/altaf-devlog-0.md
@@ -1,12 +1,12 @@
---
title: "altaf-devlog[0]: Hello, world! And I'm sorry."
-description: "No description provided."
-date: "May 2026"
-author: "altaf-creator"
-tags:
- - "simpliCity"
- - "Devlog"
- - "Personal"
+description: No description provided.
+date: Jun 2026
+author: altaf-creator
+tags:
+ - simpliCity
+ - Devlog
+ - Personal
---
+=+=+=
diff --git a/data/blogs/urban0.md b/data/blogs/urban0.md
index 469fb15..a55ed47 100644
--- a/data/blogs/urban0.md
+++ b/data/blogs/urban0.md
@@ -1,7 +1,7 @@
---
title: Reimagining Singapore's Streets with Design Thinking
description: A secondary schooler's take on how we should design our streets.
-date: 12 Jun 2026
+date: Tue, 16 Jun 2026
author: altaf-creator
tags:
- Blog
@@ -21,26 +21,28 @@ The roads and streets of Singapore are widely acclaimed to be world-class. This
The traffic engineering in Singapore is definitely world-class. However, I feel like Singapore has been building its streets too much in an engineering lens.
-To be clear, the issue is not that traffic engineering is unimportant. Efficient traffic acts as the veins that keep Singapore alive. Without it, economic productivity and people's daily commute will be severely crippled. However, roads and streets are not only built to accommodate efficient traffic flow.
+To be clear, the issue is not that traffic engineering is unimportant. Efficient traffic acts as the veins that keep Singapore alive. Without it, economic productivity and people's daily commute will be severely crippled. However, roads and streets are not built only to accommodate efficient traffic flow.
Streets inherently are spaces for humans. A street's function is more than connecting places to places. A street can be a place where people connect with each other. It can be a place where people discover new things around their neighbourhood. There is an inextricable social part in streets. When we ignore it, that is, when we design our streets purely in an engineering perspective (despite the name "traffic engineering"), we are reducing a street's functionality from a place for the community to merely a traffic conduit.
<div class="shadow-filter" markdown="1">
![View of Bedok North St 1, a street near Bedok Town Centre and Heartbeat@Bedok. Despite being a silver zone, the carriageway is still fairly wide with 4 lanes of vehicular traffic. Photograph taken by me. CC-BY-SA 4.0](https://files.altafcreator.com/media/good%20DJI_0821_small.JPG)
</div>
-View of Bedok North St 1, a street near Bedok Town Centre and Heartbeat@Bedok. Despite being a silver zone, the carriageway is still fairly wide with 4 lanes of vehicular traffic. Photograph taken by me. <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+View of Bedok North St 1, a street near Bedok Town Centre and Heartbeat@Bedok. Despite being a Silver Zone, the carriageway is still fairly wide with 4 lanes of vehicular traffic. Photograph taken by me. <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
{: .img-caption }
-This is what I feel like I'm seeing in Singapore. There are many instances where wide 4-lane roads are cutting through town centres of heartlands, despite being categorised as a local access road. Town centres are vibrant places bustling of activities and businesses. Regardless of people's background and age, these are places where people want to spend their time in. Having wide roads cutting through it will make it harder for people to explore and find out about new businesses near that place. It may also be harder for residents living across the road to walk there, despite their close proximity, as wide roads for vehicles can act as a physical barrier that reduces permeability. Not only that, vehicles are polluting, and wide roads that facilitate vehicular movement will make the environment around it more uncomfortable to spend time in, which is contradictory of the characteristics of a town centre.
+This is what I feel like I'm seeing in Singapore. There are many instances where wide 4-lane roads are cutting through town centres of heartlands, despite being categorised as a local access road. Town centres are vibrant places bustling with activities and businesses. Regardless of people's background and age, these are places where people want to spend their time. Having wide roads cutting through it will make it harder for people to explore and find out about new businesses near that place. It may also be harder for residents living across the road to walk there, despite their close proximity, as wide roads for vehicles can act as a physical barrier that reduces permeability. Not only that, vehicles are polluting, and wide roads that facilitate vehicular movement will make the environment around it more uncomfortable to spend time in, which is contradictory to the characteristics of a town centre.
-There is also the impacts on road safety. Conventional road design in Singapore often features wide and straight lanes in arterial roads and local streets. Drivers subconsciously associate these characteristics with faster driving, just like how they would drive in expressways, disregarding the speed limit of that street. In an unfortunate circumstance of a traffic accident, higher speeds will result in more fatal consequences. In fact, the risk of a pedestrian fatality increases exponentially with the collision speed[^1]. Places such as town centres should be a place where people can navigate freely with peace of mind, rather than a high-speed thoroughfare that compromises safety.
+There are also the impacts on road safety. Conventional road design in Singapore often features wide and straight lanes in arterial roads and local streets. Drivers subconsciously associate these characteristics with faster driving, just like how they would drive in expressways, disregarding the speed limit of that street. In an unfortunate circumstance of a traffic accident, higher speeds will result in more fatal consequences. In fact, the risk of a pedestrian fatality increases exponentially with the collision speed[^1]. Places such as town centres should be a place where people can navigate freely with peace of mind, rather than a high-speed thoroughfare that compromises safety.
-As of 2024, the road network in Singapore occupies 12% of Singapore's total land area[^2]. This is a significant portion of land-scarce Singapore, even comparable to the total land area allocated for housing (14%)[^3]. Since road infrastructure in Singapore covers such a large area, making sure that we design our roads and streets correctly, that is designing roads that accommodates the needs of everyone, not just the flow of vehicles, is very important. Therefore, designing our roads and streets with empathy is crucial.
+As of 2024, the road network in Singapore occupies 12% of Singapore's total land area[^2][^3]. This is a significant portion of land-scarce Singapore, even comparable to the total land area allocated for housing (14%)[^3]. Since road infrastructure in Singapore covers such a large area, making sure that we design our roads and streets correctly, that is designing roads that accommodates the needs of everyone, not just the flow of vehicles, is very important. Therefore, designing our roads and streets with empathy is crucial.
-+-+-+
+=+=+=
+# Design Thinking
+
This is where **design thinking** can come in.
Design thinking generally refers to a human-centered methodology that designers can use to ensure that they solve problems by prioritising the needs of the users[^4]. There are numerous frameworks of design thinking out there, but they all generally have a common theme of listening and **empathising** to problems that a target audience faces, and focusing on solving them. For this post, I'll use a very common 5-staged design thinking framework. The stages include: empathise, define, ideate, prototype, and test.
@@ -53,8 +55,10 @@ The 5 iterative stages of Design Thinking: empathise, define, ideate, and protot
Let's go through a brief explanation of each of these five stages[^9].
+==shorten this section?==
+
1. **Empathise.** This is a stage where we understand the problems and needs of the people within the context of a problem. Empathy is the main feature of a human centric design process like design thinking. We can do this by listening and engaging with people directly and/or observing people's behaviour.
-2. **Define.** The data we gathered from people may be messy and can be quite overwhelming. This is the stage where we bring clarity to the problem we are tackling. We can do this by crafting a problem statement, kind of like a point-of-view. This way, it will be clearer of what problem we are actually solving for everyone.
+2. **Define.** The data we gathered from people may be messy and can be quite overwhelming. This is the stage where we bring clarity to the problem we are tackling. We can do this by crafting a problem statement, kind of like a point-of-view. This way, it brings clarity to everyone of what problem we are actually solving.
3. **Ideate.** This is the stage where we think of solutions and generate... well... ideas! In this stage, we are focusing on generating as broad of a range of solutions as possible. We won't truly know whether any idea is good or not, but that is where the next stage comes in.
4. **Prototype.** This is where we try out different ideas and create quick and cheap prototypes that can still bring in useful feedback from your team and users. This stage serves many purposes, from being another way to ideate, communicate your idea to users via an example, and to test out different ideas to see whether they work or not.
5. **Test.** This stage is very related to the previous stage. This is the stage where we can see whether our prototypes work well, by giving users the chance to use the prototypes. This is also the stage where we can listen to further feedback and adjust accordingly. In fact, this stage can also be used to refine our problem statement/point-of-view.
@@ -63,16 +67,16 @@ Design thinking can be effective since it eliminates biases of the problem solve
The reason why I am bringing up design thinking is because it is often taught in Singapore schools.
-![something](path/to/image)
+In the Ministry of Education's national curriculum, Design & Technology (D&T) is currently a compulsory subject for lower secondary students. One of the core concepts taught in the D&T syllabus is Design Thinking, where pupils will learn along the way the thought processes of design thinking itself, seeking solutions by considering the needs of users, functionality, and environment[^5]. Academic competitions that encourage students to learn and apply design thinking principles also exist, such as SUTD's STEAMunity, a STEM problem solving competition[^6]. These sort of activities teaches pupils that in the process of creating and designing something, empathy is essential to create solutions that actually help people.
-In the Ministry of Education's national curriculum, Design & Technology (D&T) is currently a compulsory subject for lower secondary students. One of the core concepts taught in the D&T syllabus is Design Thinking, where pupils will learn along the way the thought processes of design thinking itself, seeking solutions by considering the needs of users, functionality, and environment[^5]. Academic competitions that encourage students to learn and apply design thinking principles also exist, such as SUTD's STEAMunity, a STEM problem solving competition[^6]. These sort of activities teaches pupils that in the process of creating and designing something, empathy is essential to ensure (problem is solved)
-
-This shows Singapore already considers empathy as an important aspect in engineering. Having already embraced human-centric design process in education, the same principles can also be applied to how we design our streets.
+This shows Singapore already considers empathy as an important aspect in engineering. Having already embraced the human-centric design process in education, the same principles can also be applied to how we design our streets.
-+-+-+
+=+=+=
+# Let's apply it!
+
Let's see how design thinking can be applied in road design to make it more human-centric.
## Stage 1: Empathise
@@ -80,7 +84,11 @@ Let's see how design thinking can be applied in road design to make it more huma
<div class="shadow-filter" markdown="1">
![Side view of Bedok North Ave 2. Photograph taken by me. CC-BY-SA 4.0](https://files.altafcreator.com/media/good%20DJI_0824_small.jpg)
</div>
-Side view of Bedok North Ave 2. Photograph taken by me. <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+<div class="shadow-filter" markdown="1">
+![Top view of Bedok North Ave 2. Photograph taken by me. CC-BY-SA 4.0](https://files.altafcreator.com/media/good%20DJI_0827_original_small.jpg)
+</div>
+
+Side and top view of Bedok North Ave 2. Photographs taken by me. <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
{: .img-caption }
This is Bedok North Ave 2, a street that serves Kaki Bukit neighbourhood centre at its northern end, numerous HDB precincts, and Heartbeat@Bedok at its southern end. Despite having "Avenue" in its name (which is usually reserved for Major Arterial/Category 2 roads), it is officially classified as a Category 4 road[^7], which means that it is a primary access road/street that provides access to developments[^8]. Despite being a local street though, it has a pretty wide and straight 4-lane carriageway (the portion of road for vehicular traffic), no bus lanes, footpaths on both sides, and a cycling path on only one side.
@@ -88,6 +96,9 @@ This is Bedok North Ave 2, a street that serves Kaki Bukit neighbourhood centre
Being one of the first HDB towns built, Bedok is a mature estate, and in this particular neighbourhood, there is a higher number of elderly living here. I also often see high amounts of foot traffic along the footpaths since I cycle there often. Additionally, this route is a popular route for cyclists and PMD/PMA users to go to Bedok Town Centre, so there are also a lot of cyclists on this street.
Furthermore, from my personal observations, there is often little traffic going through this street. This makes the 4-lane carriageway built here feel overkill, as they take up a vast amount of space on this street. This makes crossing the street inherently more dangerous, which is amplified by the high footfall on this street. For drivers, this street serves as a primary access street, and there are quite a number of HDB car park driveways connected. Due to its 4-lane configuration, some manoeuvres will require drivers to cross 2 lanes of opposing traffic which increases the number of conflict points that makes it more dangerous for them too.
+
+Lastly, this section of Bedok North Ave 2 between Bedok North Rd and its southern end only has one mid-block **signalised** pedestrian crossing. For people living near this ~330 m stretch of this street, they only have three options to cross, the signalised intersection of Bedok North Ave 2 and Bedok North Rd, the mid-block signalised pedestrian crossing I mentioned, and the signalised intersection at the end of Bedok North Ave 2, near Heartbeat@Bedok. Each of these crossings are around 140-190 metres apart. For pedestrians, these distances may be too far which may make walking feel inconvenient, and for the elderly, these distances may make walking physically more demanding. This is especially important to consider for this street due to the high number of elderly residents living nearby. If crossings are perceived as too far, pedestrians may instead "jaywalk" and cross the 4-lane carriageway, which presents significant safety risks, especially given the observed demographics.
+
## Stage 2: Define
Considering these circumstances, carriageway being too wide, high number of cyclists and foot traffic, and high number of elderly residents living nearby, the current design of Bedok North Ave 2 may not be optimal for what it serves. Instead, Bedok North Ave 2 should prioritise safety for everyone, pedestrians, cyclists, and drivers included, and convenience of walking and cycling.
@@ -106,39 +117,64 @@ Let's take some very rough measurements. I'll take my own quick measurements of
* Total carriageway width (median absent): ~14.0 m
* Therefore, ~3.5 m lane width
* East side roadside elements
- * Green verge: 3.60 m
+ * Green verge: 3.5 m
* Cycling path: 2.00 m
* Footpath: 1.56 m
* West side roadside element
- * Green verge: 3.54 m
+ * Green verge: 3.5 m
* Footpath: 1.86 m
-Firstly, let's remove two of the lanes from the carriageway to turn this street into a simpler 2-lane bi-directional street. We can also make the lanes a bit narrower from 3.5 m to 3.2 m. There are two bus services plying this street, 137 and 225W/225G. We can retain the presence of bus bays on this street if we are really so concerned about traffic flow, or even make the bus stop into an in-lane bus stop. That way, while busses stopping will halt the entire traffic flow in that direction, we will have more space for sidewalks, cycling paths, and green verges, and it eliminates delays from buses merging back into traffic. But for now, let's just retain the bus bays.
+**Total width:** 26 m, rounded to the nearest whole number.
+
+Firstly, let's remove two of the lanes from the carriageway to turn this street into a simpler 2-lane bi-directional street. We can also make the lanes a bit narrower from 3.5 m to 3.2 m. There are two bus services plying this street, 137 and 225W/225G. We can retain the presence of bus bays on this street if we are really so concerned about traffic flow, or even make the bus stop into an in-lane bus stop. That way, while busses stopping will halt the entire traffic flow in that direction, we will have more space for sidewalks, cycling paths, and green verges, and it eliminates delays from buses merging back into traffic.
+
+This narrower road also allows us to add more crossings that are safer for pedestrians and cyclists. This also makes a raised zebra crossing pretty safe to use on this street, meaning that we can remove the traffic signals that the existing crossings have. This way, pedestrians and cyclists do not need to wait unnecessarily to cross this street, while still having the traffic calming effect that also forces vehicles to yield to pedestrians, making a raised zebra crossing safe. We can also add another raised zebra crossing on this stretch of this street to further reduce crossing distances of pedestrians and cyclists, and I think we can do so while still having enough distance between them for vehicles to safely drive through. So, let's switch up the existing signalised pedestrian crossing with a raised zebra crossing, and add an additional raised zebra crossing too.
From that alone, we've freed up 7.6 m worth of street space! Currently, the footpaths and cycling path here do meet LTA's minimum standards according to their Walking and Cycling Design Guide[^11]. However, LTA's minimum standards are still quite narrow compared to international standards, especially for a bi-directional cycling path. For instance, the United Kingdom's Cycle Infrastructure Design (LTN 1/20) guide sets out a desirable minimum width of 3.0 m to 4.0 m for a 2 way cycling path depending on bicycle traffic[^13]. So, let's take this opportunity to finally add another cycling path on the west side of the street, and widen these paths. We will also widen the footpaths on both sides of the street to improve walking comfort for everyone. The widened footpaths also ensure that groups of people that want to walk side-by-side have sufficient space and don't need to overflow to the cycling path.
-Last year, LTA started enforcement that prohibits bicycles to use pedestrian-only paths and encourages pedestrians to use their own paths[^14]. Despite that, I still frequently observe cyclists using pedestrian-only paths and pedestrians walking on cycling paths. One of the causes of this may be due to the nature of most cycling paths in Singapore, where they are placed adjacent to pedestrian-only paths without clear physical separation. As a result, cyclists may need to veer onto pedestrian-only paths to avoid people walking on cycling paths, and pedestrians are not guaranteed a peace of mind since they may think that they need to watch out for cyclists using their paths. Therefore, we can try putting a buffer between the footpaths and cycling paths using either a kerb or a green verge. Not only does this increase comfort for cyclists and pedestrians, this also increases safety as the design minimises possible conflicts. If we want to upgrade the physical separation further, we can implement level differences between the cycling path and footpaths, or even use the existing 3.56 m-wide green verge as the buffer between the footpaths and cycling paths.
+Last year, LTA started enforcement that prohibits bicycles to use pedestrian-only paths and encourages pedestrians to use their own paths[^14]. Despite that, I still frequently observe cyclists using pedestrian-only paths and pedestrians walking on cycling paths. One of the causes of this may be due to the nature of most cycling paths in Singapore, where they are placed adjacent to pedestrian-only paths without clear physical separation. As a result, cyclists may need to veer onto pedestrian-only paths to avoid people walking on cycling paths, and pedestrians are not guaranteed a peace of mind since they feel the need to watch out for cyclists using their paths. A possible solution is by putting a physical buffer between the footpaths and cycling paths, like a kerb or a green verge. Not only does this increase comfort for cyclists and pedestrians, this also increases safety as the design minimises possible conflicts. If we want to upgrade the physical separation even further, we can implement level differences between the cycling path and footpaths, or even use the existing 3.56 m-wide green verge as the buffer between the footpaths and cycling paths. But for this concept, let's just use a simple 0.5 m green buffer between the footpath and cycling path.
+
+After reallocating the road space, our concept for our redesigned street would have the following approximate cross-section:
+
+* Carriageway: 2 &times; 3.2 m lanes
+* Roadside elements, for both sides
+ * Green verge: 3.5 m
+ * Cycling path: 3.5 m
+ * Green buffer: 0.5 m
+ * Footpath: 2.5 m
+
+**Total width**: 26 m, rounded to the nearest whole number.
+
+Also, our concept only redistributes street space, without needing to acquire additional land at all!
<div class="shadow-filter" markdown="1">
-![Bedok North Ave 2, drawn on](path/to/image)
+![Bedok North Ave 2 redesign concept illustration. Includes wider footpaths and cycling paths being drawn on previous photography. CC-BY-SA 4.0](https://files.altafcreator.com/media/good%20DJI_0827_edited_small.jpg)
</div>
+
+Tada! A sketch of our Bedok North Ave 2 redesign concept. Illustration by me.<i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+{: .img-caption }
+
+And again, it is important to note that this redesign is intended just as a concept rather than a formal proposal. As a secondary school student, I do not have access to real-world data such as traffic volumes, bus service operations, emergency vehicle requirements, and other important data that should be put into consideration. As such, as you might have already noticed, this redesign idea has been developed primarily from existing road conditions and personal observations that may not fully reflect the whole picture. Nevertheless, I still hope that this idea serves as an example of how we can apply design thinking principles to design streets that are safer, more inclusive, and better suited to everyone's needs.
## Stage 4 & 5: Prototyping and Testing
-Of course, we don't have the authority and resources to make real physical changes to the street. For these two stages,
+Of course, we don't have the authority and resources to make real physical changes to the street. In the context of design thinking, our quick illustration above can actually serve as a low-fidelity digital prototype or a proof of concept.
+
+In the professional world, traffic engineers may come up with different ideas for a road/street redesign. Sometimes, they may want to see more concrete and functional prototypes to really evaluate each idea. A mere drawing that acts more like proof of concept is most likely not enough. Instead of spending huge amounts of money for a full construction of an idea that may very well change, many traffic engineers utilise plastic panels and temporary road barriers to redefine road space. Pop-up planters can also be used to create temporary pedestrians' and cyclists' space as it offers a physical barrier from road traffic and has a nice visual appearance. These methods are great to test and observe how traffic would flow and function, and also allow them to evaluate the efficacy of an idea.
-+-+-+
+=+=+=
-Fortunately, things are already getting better, albeit incrementally. The Land Transport Authority (LTA) has pushed numerous initiatives that shift the focus away from cars to people in designing the streets of Singapore.
+# The Road Ahead
+Fortunately, things are already getting better, albeit incrementally. As you might have known, Singapore has been pushing the car-lite vision quite a lot as of lately. The Land Transport Authority (LTA) has pushed numerous initiatives that shift the focus away from cars to people in designing the streets of Singapore, in alignment with this vision. Here are some of them.
## LTA Road Repurposing
<div class="iframe-manual-container flex-container gap" id="iframe-googlemaps">
<iframe src="about:blank" data-src="https://www.google.com/maps/embed?pb=!4v1781248770546!6m8!1m7!1shv0RJ7fduSSV4znKDkQOvA!2m2!1d1.439052279883805!2d103.8006751428792!3f24.573714104988387!4f-3.9544474037450215!5f0.7820865974627469" height="240" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade" data-iframe-manual id="iframe-google-0" class="flex"></iframe>
<iframe src="about:blank" data-src="https://www.google.com/maps/embed?pb=!4v1781248791238!6m8!1m7!1s1iGF1oI4_Zl6-t5FC9i6SQ!2m2!1d1.439064512003263!2d103.8006792107188!3f24.573714104988387!4f-3.9544474037450215!5f0.7820865974627469" height="240" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade" data-iframe-manual id="iframe-google-1" class="flex"></iframe>
<div class="iframe-manual-warning shadow-filter">
-<div>
+<div class="iframe-manual-notice">
<span>The following contains 3rd party content from Google. Google may be able to track you and use 3rd party cookies.</span>
<button class="button button-inline" onclick="iframeLoad('iframe-googlemaps')">Load External Embed</button>
</div>
@@ -148,16 +184,16 @@ Fortunately, things are already getting better, albeit incrementally. The Land T
Woodlands Ring Rd in 2019 (left/top) vs 2020 (right/bottom), before and after road repurposing works were done. External embed of Google Maps Street View.
{: .img-caption .img-caption-margin }
-For instance, LTA has completed several [road repurposing](https://www.lta.gov.sg/content/ltagov/en/upcoming_projects/road_commuter_facilities/road_repurposing.html) projects. These are projects where LTA is experimenting and reworking several roads and/or streets to better support active mobility and to make the environment more liveable and inclusive.[^12] LTA often does this by either reclaiming vehicle lanes from the carriageway for wider footpaths, cycling paths, and other commuter facilities, like Woodlands Ring Rd as seen above, or even pedestrianising whole stretches of a street, like Eng Hoon St[^12]. This is great, and I'm really looking forward to future road repurposing projects.
-
+For instance, LTA has completed several [road repurposing](https://www.lta.gov.sg/content/ltagov/en/upcoming_projects/road_commuter_facilities/road_repurposing.html) projects. These are projects where LTA is experimenting and reworking several roads and/or streets to better support active mobility and to make the environment more liveable and inclusive.[^12] LTA often does this by either reclaiming vehicle lanes from the carriageway for wider footpaths, cycling paths, and other commuter facilities, like Woodlands Ring Rd as seen above, or even pedestrianising whole stretches of a street, like Eng Hoon St[^12]. This is great, it really shows the paradigm shift within LTA on how Singapore's streets should be designed, and I'm really looking forward to future road repurposing projects. These projects still feel like exceptions that should have been the normal way of building our streets, though. But, things may change significantly in the future.
## LTA Land Transport Masterplan Refresh
-* LTA Road repurposing projects
- * Although feels like exceptions that should have been the norm.
- * But... things may significantly change in the future. OR This may not be the case anymore itf!
-* LTA LTMP 2026 Refresh
+Land Transport Masterplan, or LTMP for short, are long-term plans by LTA that includes the vision, policies, and targets of Singapore's land transport. Very recently, LTA underwent a nation-wide public consultation for the [Land Transport Master Plan Refresh](https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_refresh.html) in late 2025 and early 2026. Those recent consultations were organised for the next edition of LTA's LTMP, the [Land Transport Master Plan 2040](https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_2040.html), or LTMP 2040 for short. For the upcoming masterplan, LTA is "envisioning a more inclusive and gracious" land transport for Singapore, which is quite promising.
+
+LTA has recently published the compiled insights from numerous focus group discussions they held during the recent public consultation phase, in which you can view it for yourselves [here](https://www.lta.gov.sg/content/dam/ltagov/who_we_are/our_work/LTMP/Image/Compiled%20Focus%20Group%20Insight.pdf)! Some of the main talking points from these focus group discussions, as reported by LTA were strong support for people-centric transport infrastructure. This includes better public transport connectivity, reliability, speed, and comfort, more mobility options such as walking and cycling, slowing down vehicle speeds in neighbourhoods, increased safety, and a lot more[^15].
+
+This form of public engagement is also a form of application of design thinking!
-As of recently, LTA is actively undergoing a nation-wide public consultation for the [Land Transport Master Plan Refresh](https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_refresh.html).
+Oh shit I need to end this too.
-+-+-+
@@ -173,6 +209,8 @@ Hello there! Introduce yourself.
///Footnotes Go Here///
+-+-+-+
+
[^1]: [https://road-safety.transport.ec.europa.eu/eu-road-safety-policy/priorities/safe-road-use/safe-speed/archive/speeding/speed-central-issue-road-safety/speed-and-injury-risk-different-speed-levels_en](https://road-safety.transport.ec.europa.eu/eu-road-safety-policy/priorities/safe-road-use/safe-speed/archive/speeding/speed-central-issue-road-safety/speed-and-injury-risk-different-speed-levels_en), accessed 9 Jun 2026
[^2]: [https://www.mot.gov.sg/news-resources/newsroom/written-reply-to-parliamentary-question-on-land-allocation-for-roads-and-car-parks-since-2010-and-future-policy-considerations/](https://www.mot.gov.sg/news-resources/newsroom/written-reply-to-parliamentary-question-on-land-allocation-for-roads-and-car-parks-since-2010-and-future-policy-considerations/#:~:text=Singapore%E2%80%99s%20road%20network%20occupies%20around%2012%25%20of%20our%20total%20land%20area%20today), accessed 9 Jun 2026
[^3]: [https://data.gov.sg/datasets/d_0ad604387b5b2dd99fbf48d89cb4f416/view](https://data.gov.sg/datasets/d_0ad604387b5b2dd99fbf48d89cb4f416/view), accessed 9 Jun 2026
@@ -187,5 +225,4 @@ Hello there! Introduce yourself.
[^12]: [https://www.lta.gov.sg/content/ltagov/en/upcoming_projects/road_commuter_facilities/road_repurposing.html](https://www.lta.gov.sg/content/ltagov/en/upcoming_projects/road_commuter_facilities/road_repurposing.html), accessed 12 Jun 2026. [Archived](https://web.archive.org/web/20260612070039/https://www.lta.gov.sg/content/ltagov/en/upcoming_projects/road_commuter_facilities/road_repurposing.html)
[^13]: [https://assets.publishing.service.gov.uk/media/5ffa1f96d3bf7f65d9e35825/cycle-infrastructure-design-ltn-1-20.pdf](https://assets.publishing.service.gov.uk/media/5ffa1f96d3bf7f65d9e35825/cycle-infrastructure-design-ltn-1-20.pdf), accessed 13 Jun 2026. [Archived](https://web.archive.org/web/20260613021824/https://assets.publishing.service.gov.uk/media/5ffa1f96d3bf7f65d9e35825/cycle-infrastructure-design-ltn-1-20.pdf).
[^14]: [https://www.lta.gov.sg/content/ltagov/en/newsroom/2025/7/news-releases/pedestrian-only_paths_enforcement_starts_1Jul25.html](https://www.lta.gov.sg/content/ltagov/en/newsroom/2025/7/news-releases/pedestrian-only_paths_enforcement_starts_1Jul25.html), accessed 13 Jun 2026. [Archived](https://web.archive.org/web/20260613033237/https://www.lta.gov.sg/content/ltagov/en/newsroom/2025/7/news-releases/pedestrian-only_paths_enforcement_starts_1Jul25.html)
-
--+-+-+ \ No newline at end of file
+[^15]: [https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_refresh.html](https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_refresh.html), accessed 17 Jun 2026. [Archived](https://web.archive.org/web/20260617024642/https://www.lta.gov.sg/content/ltagov/en/who_we_are/our_work/land_transport_master_plan_refresh.html).
diff --git a/data/events.json b/data/events.json
index a3b2a49..27c7d73 100644
--- a/data/events.json
+++ b/data/events.json
@@ -2,7 +2,19 @@
"noi": {
"path": "/data/events/noi.md"
},
+ "noai": {
+ "path": "/data/events/noai.md"
+ },
"nytc": {
"path": "/data/events/nytc.md"
+ },
+ "tinkertanker": {
+ "path": "/data/events/tinkertanker.md"
+ },
+ "infocomm": {
+ "path": "/data/events/infocomm.md"
+ },
+ "temasekeng": {
+ "path": "/data/events/temasekeng.md"
}
}
diff --git a/data/events/infocomm.md b/data/events/infocomm.md
new file mode 100644
index 0000000..5083c39
--- /dev/null
+++ b/data/events/infocomm.md
@@ -0,0 +1,86 @@
+---
+title: Ngee Ann Secondary School Infocomm (Media Creation) Club CCA
+type: CCA
+---
++-+-+-
+
+[&larr; Return to About Me](/about/)
+# Vice President of Infocomm (Media Creation) Club CCA {: .heading }
+
+{{{
+
+![AV duty, Class of 2026 and Class of 2025.](/assets/images/education/events/av.jpg)
+{: .flex-flex }
+
+![AV duty, Class of 2026 and Class of 2025.](/assets/images/education/events/av.jpg)
+{: .flex-flex }
+
+}}}
+
+The Infocomm (Media Creation) Club of Ngee Ann Secondary School is a CCA for students interested in media creation such as video editing, animation, and audio visual systems.
+
+For 2025 (and 2026), I've been chosen as one of the vice presidents for the Infocomm (Media Creation) Club CCA. Here are some things that we've done as a CCA, and some valuable things I've learnt from this journey.
+
+-+-+-+
+
++=+=+=
+
+# 2025–2026 CCA Accomplishments
+
+Here are some of the things that our CCA has accomplished, achieved, or volunteered at.
+## AV Operator for Major School Events
+
+{{{
+![](path/to/file)
+
+![](path/to/file)
+}}}
+
+
+
+## Values-in-Action Project @ Tampines East Community Club
+
+{{{
+![](path/to/file)
+
+![](path/to/file)
+}}}
+
+## MINDS Charity Car Wash Promotional Video Volunteering
+
+Read more [here](/video/minds/).
+
+## Official Video Projects for School
+
+Our CCA has been trusted by Ngee Ann Secondary School to create high-quality videos for various school events, usually for outreach promotional purposes. We often have passionate members that are willing to work on different projects the school has asked us to do. These projects include:
+
+* Value Creators of the Community Symposium Video
+* [2025 NAS Open House Video](/video/openhouse/)
+
+I have also led the production of a few of our video projects before, together with other presidents of the CCA.
+
+## Founder's Day Certificate of Commendation for Outstanding Community Service Recipient
+
+
+
+-+-+-+
+
++=+=+=
+
+This leadership opportunity has undoubtedly been such an invaluable experience for me, and I've learnt so much from it. Here are some of the things that I've learnt throughout the journey.
+# Personal Reflections
+
+## Service-first Leadership
+
+This part is more or less about me finding out what kind of leader I want to be. This leadership opportunity has made me realise this.
+
+Empowerment Empathy Growth Stewardship
+
+Of course, I also believe that this style of leadership may not work for all circumstances. In some situations, a more assertive and autocratic approach may be needed, and as a leader, one should be confident enough to take the actions for the progress of the team.
+
+## Mentoring by Example
+
+Beyond service, ultimately, I also want to be able to uplift my team and be able to contribute to their self-improvement.
+
+
+-+-+-+ \ No newline at end of file
diff --git a/data/events/noai.md b/data/events/noai.md
index e69de29..844814e 100644
--- a/data/events/noai.md
+++ b/data/events/noai.md
@@ -0,0 +1,45 @@
+---
+title: NOAI 2026
+type: Achievement
+---
++-+-+-
+
+[&larr; Return to About Me](/about/)
+# National Olympiad in Artificial Intelligence 2026 { .heading }
+
+{{{
+<div id="flex-300">
+<img alt="Screenshot of my JupyterLab AI notebook thingy" src="/assets/images/education/events/ai_jupyter.png" style="max-width: 100%">
+</div>
+
+NOAI (Singapore) relatively new annual programming competition about AI programming, covering Machine Learning, Deep Learning/Neural Networks, Computer Vision, and Natural Language Processing. A new initiative by AI Singapore and NTU to forge young AI talents in Singapore.
+{ .flex-flex }
+
+}}}
+
+For quite a while, I've been really curious of how AI, more specifically machine learning and neural networks work. I've seen people experimenting that for image recognition and sometimes in games even. I've always wanted to try to code something AI-related and experiment with it too, but never did. As we all know, AI has now become incredibly relevant in today's tech. When my teacher told me about NOAI this year, I took it as an opportunity to finally start experimenting with AI programming like machine learning and beyond!
+
+When I participated in NOAI this year, there were two rounds. The first round was the qualification round which was a 300 questions MCQ test about AI programming including theory questions and debugging. The second round was the final round consisting of a 20 question MCQ test and 5 programming tasks.[^1] This year, I advanced into the final round and attained the bronze medal, which was pretty cool.
+
+Here are some things I've learnt.
+
+[<i class="fa-solid fa-download"></i> Download my certificate](path/to/file)
+{: .info-box }
+
+-+-+-+
+
++=+=+=
+
+# Knowledge: AI programming
+
+
+
+-+-+-+
+
++=+=+=
+
+///Footnotes Go Here///
+
+-+-+-+
+
+[^1]: [https://aisingapore.org/talent/national-olympiad-in-artificial-intelligence/](https://aisingapore.org/talent/national-olympiad-in-artificial-intelligence/) \ No newline at end of file
diff --git a/data/events/noi.md b/data/events/noi.md
index 43fdd75..9cb63c0 100644
--- a/data/events/noi.md
+++ b/data/events/noi.md
@@ -2,10 +2,28 @@
title: "NOI 2026 (and 2025)"
type: "Achievement"
---
-
+-+-+-
-NOI 2026 (and 2025)
-{ .heading }
+[&larr; Return to About Me](/about/)
+# National Olympiad in Informatics 2026 (and 2025) { .heading }
+
+NOI (Singapore) is an annual, and well, prestigious, programming and algorithmic problem-solving contest for secondary school to junior colleges and polytechnic students in Singapore.
+
+I was first exposed to competitive programming last year when I was in Secondary 3 by my Secondary 4 scholar senior. I told myself, “Sure, why not? Sounds quite interesting.”, and it was!
+My senior also invited me to participate in NOI 2025, which I did. I didn’t get into the finals, which was very okay to me back then.
+
+I’m still continuously learning algorithmic problem-solving/competitive programming. This year, I decided to participate again and got into the finals! I even got the bronze medal, which was a nice surprise!
+
+Here are some things I’ve learnt.
+
+[<i class="fa-solid fa-download"></i> Download my certificate](https://files.altafcreator.com/school/certs/noi2026.pdf)
+{: .info-box }
-+-+-+
+
++=+=+=
+# Algorithms, of course.
+
+
+
+-+-+-+ \ No newline at end of file
diff --git a/data/events/nytc.md b/data/events/nytc.md
index aa74308..d8daae1 100644
--- a/data/events/nytc.md
+++ b/data/events/nytc.md
@@ -6,7 +6,7 @@ type: Achievement
+-+-+-
[&larr; Return to About Me](/about/)
-# National Youth Tech Championship 2025 { .heading }
+# National Youth Tech Championship 2025 {: .heading }
<div class="shadow-filter" markdown="1">
![National Youth Tech Championship 2025 banner, Season 3: AI Drone Derby.](https://www.imda.gov.sg/-/media/imda/images/content/news-and-events/upcoming-events/2025/nytc-2025/national-youth-tech-championship-2025-banner-desktop.webp)
@@ -20,11 +20,11 @@ Visit their official site [here](https://www.imda.gov.sg/activities/activities-c
National Youth Tech Championship (NYTC) is the premier tech competition in Singapore organised jointly by IMDA and Google for Infocomm (and Robotics) CCA students.
-<div class="flex-container flex gap-row" markdown="1">
+{{{
<div class="flex-flex" markdown="1">
<div class="shadow-filter" markdown="1">
![July 18 2025 Issue of The Straits Times. Page A18, section Singapore, Headline: "ROBOT WARS: AI drones, land rover robots battle it out in youth tech championship"](https://files.altafcreator.com/media/ROBOT%20WARS_cropped.png)
-</div>
+}}}
Page A18, the headline page of Singapore section of July 19 2025 Issue of The Straits Times. Courtesy of The Straits Times.
{: .img-caption }
@@ -45,7 +45,7 @@ Here are some things I've learnt along the way.
+=+=+=
-# Problem Solving, of course.
+# Adapting and Solving Problems
The night before the final day we were testing and refining our drone’s code. A usual occurrence for these past few weeks. Drones have this very annoying issue of being quite unreliable. Major issues include where they drift around while idle, and that movement commands are not consistent. Despite the documentation saying that the input parameter for movement commands are in centimetres, in practice it doesn’t seem like it. We’ve tried recalibrating it multiple times, but the issue seems to persist. 
@@ -55,7 +55,67 @@ That is where we decided to run some tests and experiments. From that, we found
In fact, it worked very well during the actual finals! We got some pretty good scores for 2 of the obstacles, and somehow a full score for one obstacle about pushing balls around (I’ll elaborate on this more).
+## Lessons Learnt
+
+So, this moment did teach me the lesson of how to adapt properly, which is a form of problem solving.
+
+Generally, the process of problem solving is pretty iterative. First steps usually involve observing the current situation, then looking more into the details, and come up with possible solutions based on the details we know.
+
+So, in the context practical engineering and problem solving, adaptation means finding out how things really work and adjust our actions based on that. We can do this by testing true behaviour multiple times by isolating one variable at a time. Hopefully from that, relationships between other variables can emerge. Then, we can finally adjust our solutions from real-world, empirically tested behaviour that will work better.
+
# Simple solutions are often good enough
+{{{
+
+Drawing here
+
+On the finals, there was this one obstacle where we had to use drone's downwash (that is, the wind currents created by the drone's propellers) to push coloured balls into the correct colour-coded holes. There were three balls—red, yellow, and blue—and these balls were placed on top of a square platform 1.7 m-wide on each side. I think the main challenge of this obstacle is two of the balls need to go diagonally across the whole platform to get into its correct hole, as seen in my beautiful drawing.
+{: .flex-flex }
+
+}}}
+
+Our code was very simple.
+
+```{ .py .long-code }
+# ...
+ uapi.single_fly_takeoff()
+ uapi.single_fly_Qrcode_align(0, 0)
+ uapi.single_fly_up(int(70 / CM))
+ time.sleep(2)
+ uapi.single_fly_left(int(70 / CM))
+ uapi.single_fly_forward(int(75 / CM))
+ uapi.single_fly_down(int(40 / CM))
+ uapi.single_fly_up(int(40 / CM))
+ uapi.single_fly_back(int(75 / CM))
+ time.sleep(3)
+ uapi.single_fly_right(int(70 / CM))
+ uapi.single_fly_right(int(70 / CM))
+ uapi.single_fly_forward(int(85 / CM))
+ uapi.single_fly_down(int(40 / CM))
+ uapi.single_fly_up(int(50 / CM))
+ uapi.single_fly_back(int(85 / CM))
+ time.sleep(2)
+ uapi.single_fly_left(int(60 / CM))
+ uapi.single_fly_Qrcode_align(0, 0)
+ uapi.single_fly_up(15)
+ uapi.single_fly_forward(int(120 / CM))
+ uapi.single_fly_down(int(40 / CM))
+ uapi.single_fly_up(int(40 / CM))
+ uapi.single_fly_back(int(65 / CM))
+
+ uapi.single_fly_touchdown()
+```
+<i class="fa-solid fa-code"></i> Source: [<i class="fa-brands fa-github"></i>/leejiaq/nytc/2.2.py](https://github.com/leejiaq/nytc/blob/bf147375b8c2810f188a451dcfd51aecc599621a/2.2.py#L39-L64)
+{: .img-caption}
+
+In fact, it was just a hard-coded step-by-step movement instructions based on the given obstacle measurements. Fly up, left, forward, down, up, go back, right, forward, down, up, go back, forward, down, up, and you're done. The only slightly more complicated feature we used is aligning to QR code at the start. Yet somehow, we scored full credits on this obstacle, meaning that we successfully moved all three balls into the correct holes.
+
+If I may compare, when I talked to other teams, they described that their code involves much more complicated systems/methods, like aligning the drone to the ball to minimise drifting errors, or using the detected drone speed to calculate distance travelled. To be fair, their code may actually work much better in a wider array of circumstances, unlike our code where it's only written for this specific case. Yet, if my memory doesn't fail me, we were the only ones who got a full score for this obstacle, somehow.
+
+## Lessons Learnt
+
+So, I guess from here, we can learn that we don't always need to come up with the best and most fancy solutions. In some cases, especially when we need to come up with a solution of a one-off problem, a simple solution is good enough. But again, it depends, simple solutions that lack complexity usually can only do well in the circumstance it was developed for. Fancier and more complex solutions can be more comprehensive but may introduce unnecessary overhead for simpler circumstances.
+
+It's really a trade-off between our time and energy and the needed results and the nature of the problem. One would probably be better off spending less time creating quick and straightforward code for a problem they only need to solve once than writing a very sophisticated solutions. Of course, for higher-stakes situations like where a solution needs to be pushed into production, where there will be a wide variety and complexity of situations that our solution will be subjected to, it is best to come up with the most sophisticated solutions that are more adaptive and reliable.
-+-+-+ \ No newline at end of file
diff --git a/data/events/tinkertanker.md b/data/events/tinkertanker.md
new file mode 100644
index 0000000..d49a131
--- /dev/null
+++ b/data/events/tinkertanker.md
@@ -0,0 +1,66 @@
+---
+title: Internship at Tinkertanker
+type: Internship
+---
++-+-+-
+
+[&larr; Return to About Me](/about/)
+# 2025 End of Year Internship at Tinkertanker {: .heading }
+
+{{{
+
+![Image of me and my friends at Tinkertanker](path/to/image.png)
+{: .flex-flex }
+
+![Internship project](path/to/image.png)
+{: .flex-flex }
+
+}}}
+
+In November 2025, a couple of my friends and me was granted the opportunity from the school to attend a 2-week Computing-related Internship (since we all took O-Level Computing as a subject). This internship was with Tinkertanker Pte Ltd, a Singaporean technology and education company that teaches electronics, software, and tech in general, and also builds (and sells) cool tech-related stuff. You can visit their website at [https://tinkertanker.com/](https://tinkertanker.com/).
+
+-+-+-+
+
++-+-+-
+
+# Personal Reflections
+
+
+
+## Taking the Initiative
+
+This internship has shown me that you should take the initiative more, especially if your intention is to improve something or help others.
+
+Initially, we thought that Tinkertanker would give us tasks for us to do throughout the whole internship. Instead, we realised that Tinkertanker actually encourages us to just create things that we want, and they expected us to take the initiative. If we have an idea of something, they encouraged us to discuss about it with them in which they are very happy to do so, which is really cool.
+
+
+
+* See problems or things you want to do or maybe you want to help
+* Ask
+* Then do! Everyone happy. Even did this for LaundryWeb
+# Projects I developed
+
+I've contributed to quite a few projects during my time there. If you want to see more details of the major projects I contributed to/made, click one of the projects below!
+
+<div class="info-box flex-container gap">
+<div class="flex full-img-card gallery-card"
+ style="background-image: url(/assets/images/game-hero/esp32-blockly.png);">
+ <a href="https://github.com/altaf-creator/droid-esp32-blockly" class="fill-div gradient-overlay">
+ </a>
+ <div class="img-card-titlebox">
+ <span class="img-card-subtitle"><i class="fa-solid fa-briefcase"></i> Internship</span>
+ <span class="img-card-title">ESP32 Blockly</span>
+ </div>
+ </div>
+<div class="flex full-img-card gallery-card"
+ style="background-image: url(/assets/images/game-hero/tinkertanker-examples.png);">
+ <a href="https://altaf-creator.github.io/tinkertanker-examples/" class="fill-div gradient-overlay">
+ </a>
+ <div class="img-card-titlebox">
+ <span class="img-card-subtitle"><i class="fa-solid fa-briefcase"></i> Internship</span>
+ <span class="img-card-title">Tinkertanker Web Dev</span>
+ </div>
+ </div>
+</div>
+
+-+-+-+ \ No newline at end of file
diff --git a/data/projects.json b/data/projects.json
index ddb7c28..561249e 100644
--- a/data/projects.json
+++ b/data/projects.json
@@ -7,5 +7,14 @@
},
"laundryweb": {
"path": "/data/projects/laundryweb.md"
+ },
+ "deja": {
+ "path": "/data/projects/deja.md"
+ },
+ "tinkertanker": {
+ "path": "/data/projects/tinkertanker-examples.md"
+ },
+ "droid-blockly": {
+ "path": "/data/projects/droid-blockly.md"
}
}
diff --git a/data/projects/deja.md b/data/projects/deja.md
new file mode 100644
index 0000000..d2806dd
--- /dev/null
+++ b/data/projects/deja.md
@@ -0,0 +1,170 @@
+---
+title: "Deja"
+bannerId: "deja-img"
+logo: "/assets/images/logo/deja.png"
+platforms:
+ - "web"
+actions:
+ - text: "Open Deja"
+ mode: "both"
+ icon: "fa-solid fa-globe"
+ url: "https://deja.earth/"
+ bottomBar: true
+ bannerBar: true
+ - text: "View Source Code"
+ mode: "desktop"
+ icon: "fa-brands fa-github"
+ url: "https://github.com/leejiaq/Deja-NASA-Space-Apps-Challenge-2025/"
+ bottomBar: false
+ bannerBar: true
+ - text: "Source"
+ mode: "mobile"
+ icon: "fa-brands fa-github"
+ url: "https://github.com/leejiaq/Deja-NASA-Space-Apps-Challenge-2025/"
+ bottomBar: false
+ bannerBar: true
+---
+
++-+-+-
+
+The following description is taken from our project write-up, similar to the one we submitted to NASA Space Apps Challenge's portal. NASA Space Apps Challenge 2025 website that contains all participants' project information is no longer accessible.
+{: .info-box }
+
+This project was nominated as a **Global Nominee**, which we thought it was pretty cool!
+{: .info-box }
+# Deja {: .heading }
+
+# Summary
+
+This project aims to simulate the damage an asteroid collision can cause. By selecting one of the few Near Earth Objects (NEOs), users can intuitively visualize the various impacts it can create and be alerted.
+
+This is a web-based interactive tool for simulating the impact of a real meteor. The interface allows the user to easily choose and simulate a past or future real-life meteors collision at wherever they want, and will display the corresponding impacts such as crater size and the population vapourised in an easy-to-understand user interface.
+
+# Purpose and Aims
+
+- Transform complex scientific datasets into an accessible, visual, and interactive experience.
+- Simulate the trajectory and impact of an asteroid using realistic physics approximations.
+- Provide a “what-if” tool that allows users to explore different scenarios: size, speed, impact location.
+- Educate the public about mitigation strategies beyond “do nothing,” highlighting real science and technology.
+
+# Unique Features
+## Interactive Cards Navigation
+Card 1: Welcome / Start → Introduction to Impactor-2025 and the asteroid challenge.
+Card 2: Select Asteroid → Users can choose asteroid size, speed, or type.
+Card 3: Story / Narration → Context about asteroid threats, why they matter, and how humanity prepares.
+Card 4: Select Impact Location → Users pick a region (land/ocean) for the impact scenario.
+Card 5: Simulation → Visualisation of the asteroid colliding with Earth.
+## Impact Simulation
+- 3D Earth + asteroid trajectory with Godot.
+- Explosion, crater, and shockwave animation at the selected location.
+- Data outputs:
+ - Crater size
+ - Energy released (TNT equivalent)
+ - Tsunami or seismic effects (if ocean or land impact)
+ - Population affected
+## Mitigation Strategies Section
+Cards with visuals and explanations of real methods:
+
+- Kinetic Impactor → spacecraft nudges asteroid, small velocity change = huge trajectory shift.
+- Nuclear Detonation → explosion near asteroid, strong deflection but risky.
+- Gravity Tractor
+## Congratulations Page
+
+* Give users a sense of accomplishment
+* Satisfied users will consider sharing it!
+
+# How it Works
+## User Journey
+
+{{{
+
+![Deja / Starting Page](/assets/images/screenshots/deja/image4.png)
+{: .flex-flex }
+
+![Deja / Select Asteroid](/assets/images/screenshots/deja/image7.png)
+{: .flex-flex }
+
+}}}
+
+The project begins from a landing page where we introduce that they can simulate an impact when one of the few Near Earth Objects (NEO) collides with the earth that might very well be a possibility. By fetching the NEO data from NASA’s API, the project shows a list of possible asteroids that are close to earth on the same date as the date the user is visiting the website, so that they can choose with their corresponding properties such as its diameter and relative velocity, and better understand that there are many asteroids are around the earth.
+
+{{{
+
+![Deja / Select Location](/assets/images/screenshots/deja/image3.png)
+{: .flex-500 .nopath }
+
+In the next step, the project lets the user choose a location and angle of impact using a user-friendly 3D interface of the Earth, and visualizes the impact. The location and angle, among many other preset values, are then pushed to our backend API. The backend crunches the numbers using 20+ different equations to create a rough estimate of the impacts of the asteroid. The results are all sent as a response to the frontend.
+{: .flex-flex }
+
+}}}
+
+{{{
+
+Eventually, the project then shows the impacts of the collision based on the backend’s calculations, where it displays the projected crater on the location site chosen on a real-world map, its potential energy, impact energy communicated through tonnes of TNT equivalent scale that is easier to understand, population vapourised due to the asteroid’s impact, and other various effects such as thermal exposure, MMI rating, wind velocity, and blast overpressure. From that, the user will be able to visualise and understand the consequences of an asteroid collision, and will be redirected to the final part of the project where they will learn about possible mitigations to prevent an asteroid impact.
+{: .flex-flex }
+
+![Deja / Impacts](/assets/images/screenshots/deja/image1.png)
+{: .flex-500 }
+
+}}}
+
+## Technical Explanations
+
+{{{
+
+<img alt="Godot" src="/assets/images/screenshots/deja/image6.png" class="img nopath">
+{: .flex-flex }
+
+![Backend Code](/assets/images/screenshots/deja/image2.png)
+{: .flex-flex }
+
+}}}
+
+<div class="flex-flex" markdown="1">
+For visualisation, the frontend uses a two-parted approach, where the first part uses Godot to render a 3D Earth, allow user movement and location selection, complete with explosion effects after the user decides to launch the asteroid. The second part shows the complete repertoire of impacts due to the asteroid chosen and all other parameters, where the crater is drawn on a map using Leaflet, a JavaScript library for interactive maps, and OpenStreetMap for the map tiles. Other impact properties are then displayed on a sidebar where users can digest the consequences and continue on with the next part of the app.
+
+For backend calculations, 5 variables are needed: The impactor diameter, the velocity of the impactor, the impactor’s density, the angle of impact, and the ground density. We assume the impactor’s density to be 2000 kg/m^3, and the ground density to be 2500 kg/m^3. Using 20+ different equations which approximates or solves analytically the physics involved in the impact of the asteroid. The result contains, but not limited to, energy transferred to ground, velocity hitting the ground, peak overpressure and wind velocity for given distance from ground zero, r, as well as seismic effects and ejecta. For more information visit EIEP’s paper.
+
+All of the calculations are fed on-demand by an backend API which requests the 5 variables and responds with 9 constant effects and 8 dynamic effects with respect to r, totalling 160000 quantities. The API is made out of FastAPI and `uvicorn` in Python.
+
+</div>
+
+-+-+-+
+
++-+-+-
+
+The following section is a brief explanation about this competition and notes on my own experience and personal reflections.
+{: .info-box }
+# Personal Notes and Reflections
+## About the Competition
+
+NASA Space Apps Challenge is an annual global 48-hour online hackathon held by NASA where developers and enthusiasts come together and build open-source projects focusing on tackling problems on Earth and space. Participants can (and are encouraged to) utilise free and open data provided by NASA and its partners (like the European Space Agency). 
+
+In the Sec 3 end of year holidays in 2025, a couple of my friends from Ngee Ann Secondary and Dunman Secondary School and me decided to team up and join the universal event (as basically nobody participated in local Singapore events) for this competition.
+
+We formed into a team of five, me, J from Ngee Ann, W from Ngee Ann, D from Dunman, and E from Dunman.
+
+In the team, I was the front-end developer, the other front-end designer, and 3D engine developer.
+
+It was a really fun and memorable experience for me, as it's sort of my first team hackathon if you don't count [NYTC](/event/nytc) and my [solo game jams](/projects/). Anyway, here’s what I’ve learnt from this experience.
+
+## Divide and Conquer
+
+At the start of the hackathon, I asked everyone what skills they currently have and what they think they can contribute. This is so that we can organise our roles efficiently based on our own skills. It's not that efficient if everyone works at the same task at a given time, as some tasks may not require that many people to work on it to begin with, and some people may prefer to work on other tasks. From that, we divided ourselves into specific roles that suit our skills and our project idea.
+
+From this, I think we've made a really great team and as a result a pretty cool project in my opinion. D and E worked on the research and backend side of the
+
+I think this does show the importance of knowing your own team well and make use of each of the different skills each member possesses maximally to be able to work effectively as a team and produce a really great result. At the very least, you'll know your teammates better and may bond well with them :)
+## Working Under Pressure
+
+At 1 am in the morning on the last day of the hackathon, we've finally finished the project with only a few hours left on the clock! But, we’ve just remembered that we needed to craft a write-up page, which is a page that includes information about our whole project documenting what it does, how it works, and how we made it. Uh oh.
+
+So, we immediately got together and focused solely on writing this write-up. I quickly created a Google Docs for us to write it. We wrote the general summary of the project and divided ourselves to write different parts of the write-up depending on what we worked on. We quickly took screenshots, pasted it into the Google Docs, and half an hour later, it was done! It was not perfect, it may not flow that well, but it delivers information, so it was good enough for us. I even created a quick [video]() demonstrating our project.
+
+I guess it was a pretty good opportunity for me to learn how to react and still function under pressure. Stay calm, enjoy the adrenaline rush, and stay try our best to stay focused, and everything should be okay.
+
+&nbsp;
+&nbsp;
+&nbsp;
+
+-+-+-+
diff --git a/data/projects/esp32-blockly.md b/data/projects/esp32-blockly.md
new file mode 100644
index 0000000..6acf3ec
--- /dev/null
+++ b/data/projects/esp32-blockly.md
@@ -0,0 +1,3 @@
+---
+title: ESP32 R32-D32 Blockly Code Editor
+---
diff --git a/data/projects/laundryweb.md b/data/projects/laundryweb.md
index 4747e2c..85c86bb 100644
--- a/data/projects/laundryweb.md
+++ b/data/projects/laundryweb.md
@@ -20,10 +20,72 @@ actions:
---
+-+-+-
-# LaundryWeb
+# LaundryWeb {: .heading }
-This page is under construction.
+A simple laundry timer website/web application for all Victoria Hall boarders.
Do check out the source code [here](https://git.altafcreator.com/victoriahall-laundryweb.git/)!
+## Purpose {: #purpose}
+
+I created this app because I noticed a fairly frequent problem, or frankly an annoyance, in my student hostel. Oftentimes, especially in the male block, residents are found to leave their laundry inside a machine for extended periods of time despite having their laundry fully washed or dried. When another person wants to use that machine, they will need to take out the previous person's laundry and those clothes often end up on top of machines and floors. This creates annoyance and a slight delay for the next person wanting to use that machine, and also makes the place less hygienic and more cluttered.
+
+Perhaps this may be caused due to people forgetting their own laundry. Personally, I'll always bring my phone to start a 25-minute timer whenever I start a new laundry cycle, so that I won't forget about it. It's pretty quick to do, but it may still be an additional friction for some people, so people may choose not to do that at all. Thus, I proposed a new website project for a simple laundry timer that is easily accessible and very quick to use for residents wanting to wash their laundry quickly. When their laundry is finished, they will be notified and can promptly take their laundry. The aim is to make starting a timer to notify yourself about your own laundry **as frictionless as possible**.
+
+## State of Project (Update/remove soon)
+
+Currently, the project is almost finished. All the main features of the app are finished, and I think it's ready for production. Therefore, the next steps of LaundryWeb's development is testing the application with real users, especially iPhone users, and also consulting with Hall Office for deployment and logistics.
+
-+-+-+
+
++-+-+-
+
+The following section is about my personal notes and reflections of what I've learnt from making this project.
+{: .info-box }
+# Developer's Notes and Reflections
+
+Here's what I've learnt from the development process of LaundryWeb.
+
+## Human-Centric Design
+
+During the making of this project, user-friendly design was the main focus. I wanted the app to be as efficient to use as possible as I know there are a lot of users using my hostel's communal laundry rooms, and people don't want to spend extended periods of time just starting their laundry. Ideally, people should be able to scan a LaundryWeb QR code, and immediately know how start a timer and receive notifications of their laundry within 30 seconds without reading a manual. This project really exercised my design skills to create a good and intuitive user experience for the app.
+
+### User Journey
+
+![User Journey using LaundryWeb. Put in laundry into machine → Scan QR code → Enable notification permissions → Start timer → Done.](path/to/file.png)
+
+<div markdown="1" class="flex-flex">
+First, I'd want the simplest, quickest, and most intuitive user journey as possible. This is to make the process of using the app, and hence using communal laundry rooms as frictionless as possible. If the app instead adds additional friction in doing laundry and starting your own timer, then it **defeats** the whole [purpose](#purpose) of this app.
+
+In the end, I created this flow
+
+### UI Design
+
+{{{
+<div class="flex-flex" markdown="1">
+The User Interface (UI) design is also a major part of making the user experience as intuitive as possible, aligned with my aims to make [starting a timer to notify yourself for your own laundry as frictionless as possible](#purpose). In fact, user interface **is** part of the user experience, hence making sure LaundryWeb has "good" UI design is also very critical for my aim.
+
+I settled on these design philosophies for LaundryWeb's UI that I think aligns with my UX goal: **simple** and **humane**.
+
+Every page of LaundryWeb should be **as simple as possible**, both in terms of the tech behind and what is shown to the user. This is so that the user can immediately finish the task that they want to do, whether starting a timer or confirming laundry collection. For instance, each page should have a clear, singular purpose, and each element in the page should align to that purpose. If not, cut it. Navigation should be as simple as possible. In fact, the user should not need to navigate through different pages just to do one task. Make navigation as minimal as possible, and again, if needed, make it simple.
+
+At the same time, the design should still feel **friendly** and **accessible**. Even though I aim to make this app to be used very quickly, I also want the experience to be pleasant, so that users won't feel "forced" to use this app. To achieve this, I decided to create sea green colour palette that in which every element must use. I also decided that elements should have rounded corners, to make the app feel more "welcoming", and it's also a pretty familiar feature that users have already seen all across the internet. Fancy but unnecessary elements should be minimised, so that a wide range of devices can render the app properly, and so that accessibility tools can parse the website well.
+
+An example of my attempt to apply my UI philosophies is at the very first page a new user will see, the start timer page (`/start/`). This was also the very first page I designed to have a feel of what I want the whole app to look like. I think this page has manifested all of my desired design philosophies.
+</div>
+
+![Screenshot of LaundryWeb start timer page](path/to/file.png)
+{: .flex-300 }
+
+}}}
+
+### Thanks, Apple.
+
+Like every project, things may not go according to plan.
+Like everything I do in life, I'll do this section later. ==TODO :)==
+
+&nbsp;
+&nbsp;
+&nbsp;
+
+-+-+-+ \ No newline at end of file
diff --git a/data/projects/simpliCity.md b/data/projects/simpliCity.md
index ad5d1af..87aabfc 100644
--- a/data/projects/simpliCity.md
+++ b/data/projects/simpliCity.md
@@ -66,14 +66,14 @@ Have any feedback? Found some bugs? Or do you want to connect with others about
# Downloads
-{{{
+{&{
[*&nbsp;*{: .fa-brands .fa-steam} Buy Latest Version on Steam (beta0.2)](https://store.steampowered.com/app/2381230/simpliCity/){: .button .button-inline}
[*&nbsp;*{: .fa-brands .fa-microsoft} Download Latest Demo (demo0.1)](https://store.steampowered.com/app/2381230/simpliCity/){: .button .button-inline}
}}}
# Older Versions (coming soon)
-{{{
+{&{
[*&nbsp;*{: .fa-brands .fa-microsoft} alpha2.3.1](){: .button .button-inline .button-disabled}
[*&nbsp;*{: .fa-brands .fa-microsoft} alpha2.3](){: .button .button-inline .button-disabled}
[*&nbsp;*{: .fa-brands .fa-microsoft} alpha2.2](){: .button .button-inline .button-disabled}
@@ -83,7 +83,7 @@ Have any feedback? Found some bugs? Or do you want to connect with others about
# Changelogs (coming soon)
-{{{
+{&{
[*&nbsp;*{: .fa-solid .fa-list} View Changelogs](){: .button .button-inline .button-disabled}
}}}
diff --git a/data/projects/tinkertanker-webdev.md b/data/projects/tinkertanker-webdev.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/data/projects/tinkertanker-webdev.md
diff --git a/data/videos/eid2026.md b/data/videos/eid2026.md
index 39d2bd0..69d0a97 100644
--- a/data/videos/eid2026.md
+++ b/data/videos/eid2026.md
@@ -1,8 +1,9 @@
---
-title: "A message for this Eid"
-description: "A message for this Eid"
-date: "24 March 2026"
+title: A message for this Eid
+description: A message for this Eid
+date: Tue, 24 March 2026
default_copyright: false
-license: "<i class=\"fa-brands fa-creative-commons\"></i><i class=\"fa-brands fa-creative-commons-by\"></i> CC-BY 4.0"
-license_url: "https://creativecommons.org/licenses/by/4.0/"
+license: <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i> CC-BY 4.0
+license_url: https://creativecommons.org/licenses/by/4.0/
+thumbnail: /assets/images/video-hero/eid2026.png
---
diff --git a/data/videos/minds.md b/data/videos/minds.md
index bc161cd..c1089b6 100644
--- a/data/videos/minds.md
+++ b/data/videos/minds.md
@@ -1,6 +1,49 @@
---
-title: "MINDS Charity Car Wash Promotional"
-description: "Volunteer work with MINDS to promote their Charity Car Wash in 2025."
-date: "October 2025"
+title: MINDS Charity Car Wash Promotional
+description: Volunteer work with MINDS to promote their Charity Car Wash in 2025.
+date: October 2025
default_copyright: true
+thumbnail: /assets/images/video-hero/minds.png
---
++=+=+=
+# About the Video
+
+In October 2025, Ngee Ann Secondary School's Infocomm (Media Creation) Club CCA volunteered to create a promotional video for MINDS Charity Car Wash at the Geylang Serai MINDS Community Hub.
+
+-+-+-+
+
++=+=+=
+# About MINDS and MINDS Charity Car Wash
+
+MINDS, formerly stood for Movement for the Intellectually Disabled Singapore, is a social service agency serving persons with intellectual disability, caregivers & their families across life stages[^1].
+
+In October, MINDS organised a charity car wash event at MINDS Community Hub at Geylang Serai. The aim of this event was to raise funds for future projects and initiatives, and to be able to pilot new programmes that addresses the gaps of service that currently exist.
+
+-+-+-+
+
++=+=+=
+
+For this video, I was working with my CCA's other presidents and EXCO members, forming a team of 4 (including me). I was the main videographer and main video editor for this project.
+
+The following section is for **my** own thoughts, reflections, and notes only.
+
+# Personal Notes and Reflections
+
+## Working with Different Parties
+
+
+## Listening to Feedback
+
+
+
+-+-+-+
+
++=+=+=
+
+**References**
+
+///Footnotes Go Here///
+
+-+-+-+
+
+[^1]: [https://www.minds.org.sg/](https://www.minds.org.sg/), accessed 26 Jun 2026. [Archived](https://web.archive.org/web/20260626035314/https://www.minds.org.sg/).
diff --git a/data/videos/openhouse.md b/data/videos/openhouse.md
index 6f9168b..3768ac5 100644
--- a/data/videos/openhouse.md
+++ b/data/videos/openhouse.md
@@ -1,6 +1,7 @@
---
-title: "Ngee Ann Secondary School Open House 2025"
-description: "Made by the Infocomm Club (Media Creation) CCA and Photography Club CCA."
-date: "November 2025"
+title: Ngee Ann Secondary School Open House 2025
+description: Made by the Infocomm Club (Media Creation) CCA and Photography Club CCA.
+date: Sat, 15 November 2025
default_copyright: true
+thumbnail: /assets/images/video-hero/openhouse.png
---
diff --git a/data/videos/paperverse.md b/data/videos/paperverse.md
index 00de361..d48403f 100644
--- a/data/videos/paperverse.md
+++ b/data/videos/paperverse.md
@@ -1,8 +1,9 @@
---
-title: "Paperverse Hub"
-description: "Paperverse Hub, a videography competition entry."
-date: "March 2026"
+title: Paperverse Hub
+description: Paperverse Hub, a videography competition entry.
+date: March 2026
default_copyright: false
-license: "<i class=\"fa-brands fa-creative-commons\"></i><i class=\"fa-brands fa-creative-commons-by\"></i><i class=\"fa-brands fa-creative-commons-sa\"></i> CC-BY-SA 4.0"
-license_url: "https://creativecommons.org/licenses/by-sa/4.0/"
+license: <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+license_url: https://creativecommons.org/licenses/by-sa/4.0/
+thumbnail: /assets/images/video-hero/paperverse.png
---
diff --git a/data/videos/s3via.md b/data/videos/s3via.md
index 5f16bc5..0802e62 100644
--- a/data/videos/s3via.md
+++ b/data/videos/s3via.md
@@ -1,8 +1,9 @@
---
-title: "Secondary 3 VIA Project"
-description: "Secondary 3 Class VIA Project"
-date: "July 2025"
+title: Secondary 3 VIA Project
+description: Secondary 3 Class VIA Project
+date: July 2025
default_copyright: false
-license: "<i class=\"fa-brands fa-creative-commons\"></i><i class=\"fa-brands fa-creative-commons-by\"></i><i class=\"fa-brands fa-creative-commons-sa\"></i> CC-BY-SA 4.0"
-license_url: "https://creativecommons.org/licenses/by-sa/4.0/"
+license: <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+license_url: https://creativecommons.org/licenses/by-sa/4.0/
+thumbnail: /assets/images/video-hero/via3rp.png
---
diff --git a/data/videos/stringsoffreedom.md b/data/videos/stringsoffreedom.md
index 0ce8939..1c03b5b 100644
--- a/data/videos/stringsoffreedom.md
+++ b/data/videos/stringsoffreedom.md
@@ -1,8 +1,28 @@
---
-title: "Strings of Freedom"
-description: "Top Winning Submission for Yellow Ribbon Arts Competition 2025."
-date: "May 2025"
+title: Strings of Freedom
+description: Top Winning Submission for Yellow Ribbon Arts Competition 2025.
+date: May 2025
default_copyright: false
-license: "<i class=\"fa-brands fa-creative-commons\"></i><i class=\"fa-brands fa-creative-commons-by\"></i><i class=\"fa-brands fa-creative-commons-sa\"></i> CC-BY-SA 4.0"
-license_url: "https://creativecommons.org/licenses/by-sa/4.0/"
+license: <i class="fa-brands fa-creative-commons"></i><i class="fa-brands fa-creative-commons-by"></i><i class="fa-brands fa-creative-commons-sa"></i> CC-BY-SA 4.0
+license_url: https://creativecommons.org/licenses/by-sa/4.0/
+thumbnail: /assets/images/video-hero/stringsoffreedom.png
---
++=+=+=
+
+# About the Short Film
+
+-+-+-+
+
++=+=+=
+
+# About the Competition
+
+-+-+-+
+
++=+=+=
+
+# Personal Notes and Reflections
+
+
+
+-+-+-+ \ No newline at end of file
diff --git a/main.py b/main.py
index 459f9a1..0a7eb2b 100644
--- a/main.py
+++ b/main.py
@@ -36,10 +36,13 @@ class TurnstileTokenData(BaseModel):
@app.exception_handler(fastapi.HTTPException)
def exception_handling(request: fastapi.Request, exception: fastapi.HTTPException):
+ print("EXCEPTION:", exception)
if exception.status_code == 404:
return fastapi.responses.FileResponse("./www/404.html", status_code=404)
elif exception.status_code == 209:
return fastapi.responses.FileResponse("./www/209.html", status_code=209)
+ elif exception.status_code == 500:
+ return fastapi.responses.FileResponse("./www/500.html", status_code=500)
@app.post("/api/email/")
diff --git a/markdown_renderer.py b/markdown_renderer.py
index 7c1bd0b..dd70df2 100644
--- a/markdown_renderer.py
+++ b/markdown_renderer.py
@@ -28,7 +28,7 @@ def md_to_html(raw_content: str, text_mode: bool = False) -> str:
html_text = markdown.markdown(
content,
output_format="html",
- extensions=["attr_list", "fenced_code", "tables", DefaultClassExtension(), "md_in_html", "pymdownx.tilde", "footnotes"]
+ extensions=["attr_list", "fenced_code", "tables", DefaultClassExtension(), "md_in_html", "pymdownx.tilde", "footnotes", "codehilite"]
)
section_class = ""
@@ -46,11 +46,14 @@ def md_to_html(raw_content: str, text_mode: bool = False) -> str:
html_text = html_text.replace("<p>+=+=+=</p>", f'<section class="normal-section{section_class_only}"><div class="center-grid"><div class="div-sizing">')
html_text = html_text.replace("<p>+=+=+=", f'<section class="normal-section{section_class_only}"><div class="center-grid"><div class="div-sizing">')
html_text = html_text.replace("+=+=+=</p>", f'<section class="normal-section{section_class_only}"><div class="center-grid"><div class="div-sizing">')
- html_text = html_text.replace("<p>{{{</p>", '<div class="flex-container gap">')
- html_text = html_text.replace("<p>{{{", '<div class="flex-container gap">')
- html_text = html_text.replace("{{{</p>", '<div class="flex-container gap">')
+ html_text = html_text.replace("<p>{{{</p>", '<div class="flex-container flex-container-dynamic gap-row">')
+ html_text = html_text.replace("<p>{{{", '<div class="flex-container flex-container-dynamic gap-row">')
+ html_text = html_text.replace("{{{</p>", '<div class="flex-container flex-container-dynamic gap-row">')
html_text = html_text.replace("<p>}}}</p>", '</div>')
html_text = html_text.replace("}}}</p>", '</div>')
html_text = html_text.replace("<p>}}}", '</div>')
+ html_text = html_text.replace("<p>{&amp;{</p>", '<div class="flex-container flex-container-dynamic gap">')
+ html_text = html_text.replace("<p>{&amp;{", '<div class="flex-container flex-container-dynamic gap">')
+ html_text = html_text.replace("{&amp;{</p>", '<div class="flex-container flex-container-dynamic gap">')
return (metadata, html_text)
diff --git a/pages.py b/pages.py
index cfacd69..80fef67 100644
--- a/pages.py
+++ b/pages.py
@@ -178,7 +178,19 @@ def render_video(video_name: str) -> tuple:
if "youtube" in metadata["path"]:
pass
iframe = BeautifulSoup(f"""
- <iframe src="{metadata["path"]}" id="iframe-yt" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen class="img"></iframe>
+ <div id="iframe-youtube" class="iframe-manual-container">
+ <iframe data-src="{metadata["path"]}" id="iframe-yt" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen class="img"></iframe>
+ <div class="iframe-manual-warning">
+ <img class="img" src="{metadata["thumbnail"]}" alt="">
+ <div class="shadow-filter">
+ <div class="iframe-manual-notice">
+ <span class="desktop">The following is an external embed of YouTube. Google may be able to track you and use 3rd party cookies.</span>
+ <span class="mobile">Contains external resources from YouTube.</span>
+ <button class="button button-inline" onclick="iframeLoad('iframe-youtube')">Load External Video</button>
+ </div>
+ </div>
+ </div>
+ </div>
""", "html.parser")
soup.select_one("#video-parent").append(iframe)
soup.select_one("#video").decompose()
diff --git a/templates/blogpost.html b/templates/blogpost.html
index 3d7e572..7cbafc4 100644
--- a/templates/blogpost.html
+++ b/templates/blogpost.html
@@ -6,6 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
+ <link rel="stylesheet" href="/codehilite-style.css">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<title>{[{title}]} • altaf-creator</title>
<link rel="stylesheet" href="/packages/fontawesome-free-7.2.0-web/css/all.css">
@@ -15,7 +16,6 @@
min-height: 0;
}
</style>
-
</head>
<body onload="blogPost();">
@@ -40,7 +40,7 @@
</div>
<div class="sidebar-progress-container" id="progressContainer">
</div>
- <section class="normal-section">
+ <section class="normal-section" data-excluded>
<div class="banner-shadow" style="margin-top: 100px;">
<img src="" alt="" class="banner img" id="banner">
</div>
@@ -58,11 +58,11 @@
</div>
</section>
{[{content}]}
- <section class="normal-section">
+ <section class="normal-section" data-excluded>
<div class="center-grid">
<div class="div-sizing">
<h1>More Posts</h1>
- <div id="blog-container" class="flex-container flex-container-column flex-center-content">
+ <div id="blog-container" class="flex-container flex-container-column flex-center">
</div>
</div>
diff --git a/templates/eventdetails.html b/templates/eventdetails.html
index 064f27e..28757fe 100644
--- a/templates/eventdetails.html
+++ b/templates/eventdetails.html
@@ -6,6 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
+ <link rel="stylesheet" href="/codehilite-style.css">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<title>{[{title}]} • altaf-creator</title>
diff --git a/templates/project.html b/templates/project.html
index cca74cb..56b581b 100644
--- a/templates/project.html
+++ b/templates/project.html
@@ -6,6 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
+ <link rel="stylesheet" href="/codehilite-style.css">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<title>{[{title}]} • altaf-creator</title>
@@ -32,21 +33,25 @@
</div>
<div class="sidebar-progress-container" id="progressContainer">
</div>
- <div id="bottom-bar" class="bottom-bar flex-container flex-spacebetween flex-aligncenter gap">
- <img class="center-absolute desktop" src="{[{img-src-icon-bottom-bar}]}" alt="">
- <img class="mobile" style="margin-right: 10px;" src="{[{img-src-icon-bottom-bar}]}" alt="">
+ <div class="bottom-bar flex-container flex-center gap">
+ <div class="div-sizing-bare flex-container gap flex-y-center flex-spacebetween" id="bottom-bar">
+ <img class="center-absolute desktop" src="{[{img-src-icon-bottom-bar}]}" alt="">
+ <img class="mobile" style="margin-right: 10px;" src="{[{img-src-icon-bottom-bar}]}" alt="">
+ </div>
</div>
<section style="border-top: none; overflow: hidden;" id="{[{id-banner}]}" class="banner-section">
<video src="{[{video-src-banner}]}" class="banner-video" id="video" onended="stopVideo('video')"></video>
- <div class="banner-bottom-bar flex-container">
- <div class="flex">
- <a class="button button-inline" href="#" onclick="playVideo('video', true)" id="video-play-btn">▶ Trailer</a>
- <i id="compatible-web" class="fa-solid fa-globe" title="Playable on Web"></i>
- <i id="compatible-win" class="fa-brands fa-microsoft" title="Windows 8+ 64-bit"></i>
- <i id="compatible-mac" class="fa-brands fa-apple" title="macOS"></i>
- <i id="compatible-lin" class="fa-brands fa-linux" title="Linux"></i>
- </div>
- <div class="flex-right flex-container gap" id="banner-actions-bar">
+ <div class="banner-bottom-bar flex-container flex-center">
+ <div class="div-sizing-bare flex-container">
+ <div class="flex flex-container flex-y-center gap">
+ <a class="button button-inline" href="#" onclick="playVideo('video', true)" id="video-play-btn">▶ Trailer</a>
+ <i id="compatible-web" class="fa-solid fa-globe" title="Playable on Web"></i>
+ <i id="compatible-win" class="fa-brands fa-microsoft" title="Windows 8+ 64-bit"></i>
+ <i id="compatible-mac" class="fa-brands fa-apple" title="macOS"></i>
+ <i id="compatible-lin" class="fa-brands fa-linux" title="Linux"></i>
+ </div>
+ <div class="flex-right flex-container gap" id="banner-actions-bar">
+ </div>
</div>
</div>
</section>
diff --git a/templates/video.html b/templates/video.html
index 8bba92b..4380e8e 100644
--- a/templates/video.html
+++ b/templates/video.html
@@ -16,6 +16,7 @@
<script defer src="/scripts/onload.js"></script>
<script defer src="/scripts/scroll.js"></script>
<script defer src="/scripts/video.js"></script>
+ <script defer src="/scripts/iframe.js"></script>
<div class="floating-nav-container">
<div class="floating-nav">
<a href="/" class="mobile"><img src="/assets/images/hero/logo.png" alt="" class="sidebar-img mobile" style="margin-top: 0; margin-left: -20px;"></a>
diff --git a/www/209.html b/www/209.html
index 0644f4e..9236e8f 100644
--- a/www/209.html
+++ b/www/209.html
@@ -35,7 +35,7 @@
<section style="border-top: none">
<div class="center-grid">
<div class="div-sizing">
- <span class="big-text">HTTP 209 — Under Construction</span>
+ <span class="big-text">HTTP 209 – Under Construction</span>
<p>Yes. This error is made up. You're not lost; this is going to be a real page, it just doesn't exist yet.</p>
<p>Sorry. Come back soon!</p>
<a href="/" class="link" style="margin-top: 10px; display: inline-block;">Go back to Root →</a>
diff --git a/www/500.html b/www/500.html
new file mode 100644
index 0000000..4b11e86
--- /dev/null
+++ b/www/500.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="/style.css">
+ <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
+ <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
+ <link rel="me" href="https://mastodon.gamedev.place/@altaf">
+ <title>404 • This is altaf-creator</title>
+ <link rel="stylesheet" href="/packages/fontawesome-free-6.5.2-web/css/all.css">
+</head>
+
+<body onload="addNodes()">
+ <script defer src="/scripts/onload.js"></script>
+ <script defer src="/scripts/scroll.js"></script>
+ <div class="floating-nav-container">
+ <div class="floating-nav">
+ <a href="/" class="mobile"><img src="/assets/images/hero/logo.png" alt="" class="sidebar-img mobile" style="margin-top: 0; margin-left: -20px;"></a>
+ <a href="/about/" class="link">About Me</a>
+ <a href="/projects/" class="link">Projects</a>
+ <a href="/blog/" class="link">Library</a>
+ </div>
+ </div>
+ <div class="sidebar" id="sidebar">
+ <a href="/">
+ <img src="/assets/images/hero/logo.png" alt="" class="sidebar-img">
+ </a>
+ <span>altaf-creator</span>
+ </div>
+ <div class="sidebar-progress-container" id="progressContainer">
+ </div>
+ <section style="border-top: none">
+ <div class="center-grid">
+ <div class="div-sizing">
+ <span class="big-text">HTTP 500 – Internal Server Error</span>
+ <p>The webpage is currently unavailable. This is our fault. Sorry! Come back soon.</p>
+ <a href="/" class="link" style="margin-top: 10px; display: inline-block;">Go back to Root →</a>
+ </div>
+ </div>
+ </section>
+</body>
+
+</html>
diff --git a/www/about/index.html b/www/about/index.html
index 039b31b..5eb2362 100644
--- a/www/about/index.html
+++ b/www/about/index.html
@@ -85,164 +85,277 @@
<section>
<div class="center-grid">
<div class="div-sizing">
- <h1>Passion</h1>
- <p>Under construction.</p>
+ <div class="timeline timeline-before">
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <p>Since little, I've always liked making things, from making things with cardboard, to tinkering with computers and electronics. Even making ROBLOX games!</p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <p>Around the age of 10-12, I've started learning programming more seriously. I started off with game devleopment and web development, and also did some desktop programming.</p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <p>At the same time, I also explored other creative media such as videography and others. Programming still remained as my main thing.</p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <div class="flex-container horizontal-scroll carousel-container" style="height: 200px;">
+ <img src="/assets/images/game-hero/space_hero.png" alt="Space Shooter Game. ">
+ <img src="/assets/images/game-hero/ball_screenshot.png" alt="">
+ <img src="/assets/images/game-hero/cargame_screenshot.jpg" alt="">
+ <img src="/assets/images/game-hero/duck_screenshot.png" alt="">
+ </div>
+ <p class="half-opacity-text">During these times, I learnt and experimented with Unity game development and web development mostly.</p>
+ </div>
+ </div>
+ </div>
</div>
</div>
</section>
<section>
<div class="center-grid">
<div class="div-sizing">
- <h1>Community and Events</h1>
- <h2>Infocomm (Media Creation) CCA Vice President</h2>
- <h2>Tinkertanker Internship</h2>
+ <div class="timeline">
+ <div class="timeline-milestone">
+ <h1 class="colored-text">2022</h1>
+ <span class="timeline-milestone-left">Middle School</span>
+ <span class="timeline-milestone-right">Indonesia</span>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-code"></i> Project</span>
+ <h2>Tank Shooter</h2>
+ <p>Created and published my first major game project. A 2D pixel art arcade shooter game.</p>
+ <p><a class="link" href="https://altaf-creator.itch.io/tank-shooter"><i class="fa-brands fa-itch-io"></i> / Tank Shooter &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-code"></i> Project</span>
+ <h2>simpliCity</h2>
+ <p>The original Unity project for simpliCity, "Sandbox Game", was created. This is a major project that I'm still working on!</p>
+ <p><a class="link" href="/projects/simpliCity/">View simpliCity &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-milestone">
+ <h1 class="colored-text">2023</h1>
+ <span class="timeline-milestone-left">Middle School</span>
+ <span class="timeline-milestone-right">Indonesia</span>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Alarm (Al-Azhar Rawamangun) Robotics Competition</h2>
+ <p><b>1st place, Team</b></p>
+ <p>My first major robotics competition. Our team of 3 paritcipated in the creative category. A metropolitan-wide private competition.</p>
+ <p><a class="link" href="/event/alarm_id/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>ASEAN Robotics Day</h2>
+ <p><b>4th place, Team</b></p>
+ <p>Created a new robot with the theme of environmental sustainability. Our team of 5 participated in the creative category. A public nation-wide and theoretically ASEAN region-wide competition.</p>
+ <p><a class="link" href="/event/aseanrd_id/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Trans Studio Bandung Robotics Competition</h2>
+ <p><b>1st place, Team</b></p>
+ <p>Our team of 3 refined our previous robot for the creative category. A pretty major public nation-wide competition.</p>
+ <p><a class="link" href="/event/tsb_id/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-milestone">
+ <h1 class="colored-text">2024</h1>
+ <span class="timeline-milestone-left">Middle School</span>
+ <span class="timeline-milestone-right">Indonesia</span>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-graduation-cap"></i> Opportunity</span>
+ <h2>MOE Singapore ASEAN Scholarship for Indonesia</h2>
+ <p>I've been granted the opportunity to study in Singapore independently for my Upper Secondary to Junior College years from this scholarship.</p>
+ </div>
+ </div>
+ <div class="timeline-milestone">
+ <h1 class="colored-text">2025</h1>
+ <span class="timeline-milestone-left">Secondary 3</span>
+ <span class="timeline-milestone-right">Singapore</span>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Leadership</span>
+ <h2>CCA Vice President for Infocomm (Media Creation) Club</h2>
+ <p>Became one of the presidents for Ngee Ann Secondary School's Infocomm (Media Creation) Club CCA. (Achievements)</p>
+ <p><a class="link" href="/event/infocomm/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Yellow Ribbon Arts Competition</h2>
+ <p><b>Top Winner</b></p>
+ <p>Participated in my first ever videography competition. This competition is part of Yellow Ribbon Arts Festival 2025 hosted by Yellow Ribbon Singapore.</p>
+ <p><a class="link" href="/video/stringsoffreedom/">Watch my short film &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>Class VIA Leader Committe</h2>
+ <p>My form class organised a beach clean-up VIA project, where I helped out organising and creating a video of it.</p>
+ <p><a class="link" href="/video/s3via/">Watch our video &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>National Youth Tech Championship</h2>
+ <p><b>Champion, Team</b></p>
+ <p>Ngee Ann's team of 4 won the 1st place in NYTC in 2025, the premier tech and robotics competition hosted by IMDA. Featured in The Straits Times.</p>
+ <p><a class="link" href="/event/nytc/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>Infocomm CCA VIA at Tampines East CC</h2>
+ <p>Every year, Ngee Ann's Infocomm Club does VIA projects. This year, the CCA collaborated with People's Association in Tampines East to teach elderly residents videography and editing.</p>
+ <p><a class="link" href="/event/infocomm/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <!--
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>Scholar's VIA Project with NTUC Health</h2>
+ <p>Description</p>
+ </div>
+ </div>
+ -->
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-code"></i> Project</span>
+ <h2>NASA Space Apps Challenge</h2>
+ <b>Global Nominee</b>
+ <p>An international hackathon that I participated in with a couple of friends from my school and Dunman Secondary during our end of year holidays.</p>
+ <p><a class="link" href="/projects/deja/">View our project &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>MINDS Charity Carwash Video</h2>
+ <p>Infocomm CCA leaders volunteered to create a promotional video for MINDS Charity Carwash at MINDS Community Hub (Geylang Serai). MINDS is a non-profit social agency serving persons with intellectual disability and their families.</p>
+ <p><a class="link" href="/video/minds/">Watch the video &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>Ngee Ann Open House Video</h2>
+ <p>In partnership with the school, Infocomm CCA in collaboration with Photography CCA created an appreciation video for all student helpers at NAS Open House 2025.</p>
+ <p><a class="link" href="/video/openhouse/">Watch our video &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-briefcase"></i> Internship</span>
+ <h2>Internship at Tinkertanker</h2>
+ <p>Some of my Computing friends and me was granted an internship opportunity from our school with Tinkertanker Pte Ltd during our end of year holidays. This was my first ever internship. We got the opportunity to create some cool projects while we were there too.</p>
+ <p><a class="link" href="/event/tinkertanker/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-milestone">
+ <h1 class="colored-text">2026</h1>
+ <span class="timeline-milestone-right">Singapore</span>
+ <span class="timeline-milestone-left">Secondary 4</span>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-people-group"></i> Service</span>
+ <h2>Secondary 1 Orientation Facilitator</h2>
+ <p>I was offered the opportunity to help out with my school's Secondary 1 orientation as a student facilitator.</p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Ngee Ann Secondary School Founder's Day</h2>
+ <p><b>Recipient of Certificate of Merit for Computing</b></p>
+ <p>The school awards Certificate of Merit to the 2 top-performing students of a subject.</p>
+ <p><a class="link" href="/event/foundersday/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Ngee Ann Secondary School Founder's Day</h2>
+ <p><b>Infocomm CCA as Recipient of Certificate of Commendation for Outstanding Community Service</b></p>
+ <p>The school awards this certificate for students and student groups that has shown commitment in service and has brought real impacts, with the goal of cultivating value creators of the community.</p>
+ <p><a class="link" href="/event/foundersday/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Temasek Engineering Olympiad</h2>
+ <p><b>Silver Medal</b></p>
+ <p>A 3-day engineering and electronics workshop and competition hosted by Temasek Polytechnic School of Engineering.</p>
+ <p><a class="link" href="/event/temasekeng/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <!-- bebras? -->
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>National Olympiad of Informatics 2026 (and 2025)</h2>
+ <p><b>Bronze Medal</b></p>
+ <p>An algorithmic problem-solving contest open to secondary and junior college students in Singapore. I participated in 2025 and 2026, and achieved the bronze medal this year.</p>
+ <p><a class="link" href="/event/noi/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter timeline-highlight">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>National Olympiad of Artificial Intelligence</h2>
+ <p><b>Bronze Medal</b></p>
+ <p>Held by NTU and AI Singapore, NOAI is a relatively new programming contest about AI programming.</p>
+ <p><a class="link" href="/event/noai/">Read more &rarr;</a></p>
+ </div>
+ </div>
+ <div class="timeline-item shadow-filter">
+ <div>
+ <span class="half-opacity-text"><i class="fa-solid fa-trophy"></i> Achievement</span>
+ <h2>Copyright School Challenge '25/26</h2>
+ <p><b>2nd place</b></p>
+ <p>A videography competition held by CLASS Singapore with the theme "The Worlds We Make" in aligment with AFCC 2026.</p>
+ <p><a class="link" href="/video/paperverse/">Watch my submission &rarr;</a></p>
+ </div>
+ </div>
+ </div>
</div>
</div>
</section>
<section>
<div class="center-grid">
<div class="div-sizing">
- <h1>Academics and Achievements</h1>
- <h2>National Youth Tech Championship 2025</h2>
- <h2>NOI 2026 (and 2025)</h2>
- <h2>NOAI 2026</h2>
- <h2>Temasek Engineering Olympiad 2026</h2>
- <h2>Trans Studio Bandung Robotic Competition</h2>
- <h2>Alarm Robotic Competition</h2>
- <h2>ASEAN Robotic Day</h2>
- <h2></h2>
- </div>
- </div>
- </section>
- <!--
- <section style="overflow-x: scroll; padding: 30px;" class="flex-container flex-container-column">
- <div class="shadow-filter flex flex-container flex-container-column">
- <div id="about-skills-container" class="flex">
- <!- -
- <div id="a">
- <div id="aa" class="flex-box center-grid" style="min-height: 100%;"><h1 style="font-size: 2.5rem; line-height: 1rem; margin: 0; font-weight: 400;">Skills</h1></div>
- <div id="ab" class="flex-box"></div>
- <div id="ac" class="flex-box center-grid" style="min-height: 100%;"><a class="button" href="">Hire me!</a></div>
- <div id="ad" class="flex-box"></div>
- </div>
- <div id="b" class="flex-box">
- <h1>Godot 4 Programmer</h1>
- <progress max="10" value="7" class="prog"></progress>
- <span class="half-opacity-text">Intermediate</span>
- <p>GDScript</p>
- <img src="/assets/images/skills/godot.png" alt="" class="bento-img-lr">
- <i class="fa-solid fa-code bento-icon-lr"></i>
- </div>
- <div id="c" class="flex-box"><img src="/assets/images/skills/godot_nvim.png" alt="" class="bento-img-full"></div>
- <div id="d" class="flex-box"><h1>Game Design</h1></div>
- <div id="e" class="flex-box"><h1>2D / 3D Artist</h1></div>
- <div id="f" class="flex-box"></div>
- <div id="g" class="flex-box"></div>
- <div id="h" class="flex-box"><h1>Programmer</h1></div>
- </div>- ->
- <div id="a" class="flex-box center-grid" style="min-height: 100%;"><h1 style="position: absolute; font-size: 2.5rem; line-height: 1rem; margin: 0; font-weight: 400;">Skills</h1></div>
- <div id="b" class="flex-box flex-center-content center">
- <a class="button" href="/freelancing/" style="display: inline;">Hire me!</a>
- <a class="button button-alt" href="/projects/" style="display: inline;">Explore my Projects</a>
- </div>
- <div id="c" class="flex-box"></div>
- <div id="d" class="flex-box"></div>
- <div id="e" class="flex-box">
- </div>
- <div id="f" class="flex-box"></div>
- <div id="g" class="flex-box">
- </div>
- <div id="h" class="flex-box"></div>
- <div id="j" class="flex-box">
- </div>
- <div id="k" class="flex-box">
- </div>
- <div id="l" class="flex-box">
- </div>
- <div id="m" class="flex-box"></div>
- <div id="n" class="flex-box"></div>
- <div id="o" class="flex-box"></div>
- <div id="p" class="flex-box">
- </div>
- <div id="q" class="flex-box">
- </div>
- <div id="r" class="flex-box">
- </div>
- <div id="s" class="flex-box"></div>
- <div id="t" class="flex-box">
- </div>
- </div>
- </div>
- </section>
- -->
- <!--
- <section>
- <div class="flex-boxes-container">
- <div class="shadow-filter">
- <div class="flex-box">
- <h1>Skills</h1>
- </div>
- </div>
- <div class="shadow-filter">
- <div class="flex-box">
- <h2>Game Development</h2>
- <ul>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- Godot 4 Programmer (GDScript)</li>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩⬛⬛<span class="half-opacity-text">]</span>
- Game Designer</li>
- <li><span class="half-opacity-text">[</span>🟩🟩⬛⬛⬛<span class="half-opacity-text">]</span>
- 2D / 3D Artist</li>
- </ul>
- <h2>Front-end Web Developer</h2>
- <ul>
- <li>
- <span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- </li>
- </ul>
- </div>
- </div>
- <div class="shadow-filter">
- <div class="flex-box">
- <h2>Game Development</h2>
- <ul>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- Godot 4 Programmer (GDScript)</li>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩⬛⬛<span class="half-opacity-text">]</span>
- Game Designer</li>
- <li><span class="half-opacity-text">[</span>🟩🟩⬛⬛⬛<span class="half-opacity-text">]</span>
- 2D / 3D Artist</li>
- </ul>
- <h2>Front-end Web Developer</h2>
- <ul>
- <li>
- <span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- </li>
- </ul>
- </div>
- </div>
- <div class="shadow-filter">
- <div class="flex-box">
- <h2>Game Development</h2>
- <ul>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- Godot 4 Programmer (GDScript)</li>
- <li><span class="half-opacity-text">[</span>🟩🟩🟩⬛⬛<span class="half-opacity-text">]</span>
- Game Designer</li>
- <li><span class="half-opacity-text">[</span>🟩🟩⬛⬛⬛<span class="half-opacity-text">]</span>
- 2D / 3D Artist</li>
- </ul>
- <h2>Front-end Web Developer</h2>
- <ul>
- <li>
- <span class="half-opacity-text">[</span>🟩🟩🟩🟩⬛<span class="half-opacity-text">]</span>
- </li>
- </ul>
+ <div class="timeline timeline-future">
+ <div class="timeline-milestone">
+ <h1 class="colored-text">Future?</h1>
+ </div>
</div>
</div>
</div>
</section>
- --->
</body>
</html>
diff --git a/www/assets/images/education/events/ai_jupyter.png b/www/assets/images/education/events/ai_jupyter.png
new file mode 100644
index 0000000..94d9465
--- /dev/null
+++ b/www/assets/images/education/events/ai_jupyter.png
Binary files differ
diff --git a/www/assets/images/education/events/av.jpg b/www/assets/images/education/events/av.jpg
new file mode 100644
index 0000000..18397a3
--- /dev/null
+++ b/www/assets/images/education/events/av.jpg
Binary files differ
diff --git a/www/assets/images/game-hero/deja_screenshot.png b/www/assets/images/game-hero/deja_screenshot.png
new file mode 100644
index 0000000..609643c
--- /dev/null
+++ b/www/assets/images/game-hero/deja_screenshot.png
Binary files differ
diff --git a/www/assets/images/hero/altaf.png b/www/assets/images/hero/altaf.png
deleted file mode 100644
index ff2ce4b..0000000
--- a/www/assets/images/hero/altaf.png
+++ /dev/null
Binary files differ
diff --git a/www/assets/images/hero/logo.svg b/www/assets/images/hero/logo.svg
new file mode 100644
index 0000000..632c0aa
--- /dev/null
+++ b/www/assets/images/hero/logo.svg
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="1080"
+ height="1080"
+ viewBox="0 0 285.74999 285.75"
+ version="1.1"
+ id="svg5"
+ inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+ sodipodi:docname="altaf-creator Logo.svg"
+ inkscape:export-filename="altaf-creator Logo.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview7"
+ pagecolor="#ffffff"
+ bordercolor="#999999"
+ borderopacity="1"
+ inkscape:showpageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:document-units="mm"
+ showgrid="false"
+ inkscape:zoom="0.5"
+ inkscape:cx="163"
+ inkscape:cy="600"
+ inkscape:window-width="1920"
+ inkscape:window-height="1009"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2">
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5846"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5842"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5826"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5818"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5767"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5765"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,0,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4932">
+ <stop
+ style="stop-color:#d6d6d6;stop-opacity:1;"
+ offset="0"
+ id="stop4928" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop4930" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4916">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4912" />
+ <stop
+ style="stop-color:#d6d6d6;stop-opacity:1;"
+ offset="1"
+ id="stop4914" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2362">
+ <stop
+ style="stop-color:#00ba62;stop-opacity:1;"
+ offset="0"
+ id="stop2358" />
+ <stop
+ style="stop-color:#008c94;stop-opacity:1;"
+ offset="1"
+ id="stop2360" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2362"
+ id="linearGradient2364"
+ x1="0"
+ y1="285.75"
+ x2="285.75"
+ y2="0"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4916"
+ id="linearGradient4918"
+ x1="203.14496"
+ y1="219.38403"
+ x2="131.17841"
+ y2="53.705994"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4932"
+ id="linearGradient4934"
+ x1="59.211742"
+ y1="219.38393"
+ x2="131.17841"
+ y2="53.705994"
+ gradientUnits="userSpaceOnUse" />
+ <inkscape:path-effect
+ effect="fillet_chamfer"
+ id="path-effect5767-3"
+ is_visible="true"
+ lpeversion="1"
+ nodesatellites_param="F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1 @ F,0,0,1,0,5.2916667,0,1"
+ unit="px"
+ method="auto"
+ mode="F"
+ radius="20"
+ chamfer_steps="1"
+ flexible="false"
+ use_knot_distance="true"
+ apply_no_radius="true"
+ apply_with_radius="true"
+ only_selected="false"
+ hide_knots="false" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4932"
+ id="linearGradient5820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.48329724,-0.37696096,0,285.05174,202.93252)"
+ x1="131.17839"
+ y1="53.706009"
+ x2="59.211727"
+ y2="219.38393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4932"
+ id="linearGradient5828"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.48329724,-0.37696096,0,285.05174,72.961237)"
+ x1="62.496445"
+ y1="219.38391"
+ x2="134.46309"
+ y2="53.705986" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4932"
+ id="linearGradient5848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.48329724,-0.37696096,0,285.05174,202.93252)"
+ x1="131.17839"
+ y1="53.706009"
+ x2="59.211727"
+ y2="219.38393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4932"
+ id="linearGradient5850"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.48329724,-0.37696096,0,285.05174,72.961237)"
+ x1="62.496445"
+ y1="219.38391"
+ x2="134.46309"
+ y2="53.705986" />
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="fill:url(#linearGradient2364);fill-opacity:1;stroke-width:4.99999;stroke-linecap:round;stroke-linejoin:round"
+ id="rect1516"
+ width="285.75"
+ height="285.75"
+ x="0"
+ y="0"
+ sodipodi:insensitive="true" />
+ <g
+ id="g5771"
+ transform="matrix(0.76687401,0,0,0.76687401,42.290815,38.162268)">
+ <path
+ id="path4903"
+ style="fill:url(#linearGradient4918);stroke-width:4.57214;stroke-linecap:round;stroke-linejoin:round"
+ d="m 117.14103,58.559319 31.26555,71.978351 a 3.4574342,3.4574342 123.36158 0 1 -3.18337,4.83489 l -17.40624,-0.0614 a 8.0367077,8.0367077 146.83965 0 0 -7.39975,4.83495 l -8.71734,20.07029 a 3.4708703,3.4708703 56.73863 0 0 3.18355,4.85361 h 43.23146 a 8.0679283,8.0679283 33.260434 0 1 7.39995,4.85354 l 19.37632,44.60692 a 8.0679283,8.0679283 33.260434 0 0 7.39995,4.85354 h 21.70771 a 3.4707573,3.4707573 123.26051 0 0 3.1834,-4.85355 L 147.32382,53.705766 h -26.99938 a 3.4707626,3.4707626 123.26055 0 0 -3.18341,4.853553 z"
+ inkscape:path-effect="#path-effect5765"
+ inkscape:original-d="m 115.03277,53.705766 35.48207,81.685454 -27.9895,-0.0987 -12.93358,29.77751 h 53.8148 l 23.59288,54.314 h 32.29105 L 147.32382,53.705766 Z" />
+ <path
+ id="rect4789"
+ style="fill:url(#linearGradient4934);stroke-width:4.77094;stroke-linecap:round;stroke-linejoin:round"
+ d="m 120.32446,53.705994 26.99956,0 -69.858398,160.824386 a 8.0679101,8.0679101 146.73951 0 1 -7.399936,4.85355 l -21.707891,0 a 3.4707547,3.4707547 56.739506 0 1 -3.183398,-4.85355 L 112.92452,58.559543 a 8.0679099,8.0679099 146.73951 0 1 7.39994,-4.853549 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:path-effect="#path-effect5767"
+ inkscape:original-d="m 115.03279,53.705994 h 32.29123 L 75.357353,219.38393 H 43.066128 Z" />
+ </g>
+ <g
+ id="g5832"
+ transform="matrix(0.86465773,0,0,0.86465773,33.748785,23.598167)">
+ <path
+ id="path5814"
+ style="fill:url(#linearGradient5820);stroke-width:2.03638;stroke-linecap:round;stroke-linejoin:round"
+ d="m 264.80668,147.33751 v -13.4896 a 3.1099523,3.1099523 30.443074 0 0 -4.62309,-2.71703 l -53.20793,29.63201 a 9.0039117,9.0039117 120.44307 0 0 -4.62309,7.86631 v 8.19792 a 3.1099528,3.1099528 30.443078 0 0 4.62309,2.71703 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:path-effect="#path-effect5818"
+ inkscape:original-d="m 264.80668,147.33751 v -18.78127 l -62.45411,34.78129 v 18.78126 z" />
+ <path
+ id="path5822"
+ style="fill:url(#linearGradient5828);stroke-width:2.03638;stroke-linecap:round;stroke-linejoin:round"
+ d="m 264.80668,133.84791 0,13.4896 -57.83102,-32.20664 a 9.0039105,9.0039105 59.556922 0 1 -4.62309,-7.86631 v -8.197926 a 3.1099531,3.1099531 149.55692 0 1 4.62309,-2.717026 l 53.20793,29.631992 a 9.0039096,9.0039096 59.55692 0 1 4.62309,7.86631 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:path-effect="#path-effect5826"
+ inkscape:original-d="m 264.80668,128.55624 v 18.78127 L 202.35257,112.55623 V 93.774967 Z" />
+ </g>
+ <g
+ id="g5838"
+ transform="matrix(-0.86465773,0,0,0.86465773,252.37536,23.598216)">
+ <path
+ id="path5834"
+ style="fill:url(#linearGradient5848);stroke-width:2.03638;stroke-linecap:round;stroke-linejoin:round"
+ d="m 264.80668,147.33751 v -13.4896 a 3.1099523,3.1099523 30.443074 0 0 -4.62309,-2.71703 l -53.20793,29.63201 a 9.0039117,9.0039117 120.44307 0 0 -4.62309,7.86631 v 8.19792 a 3.1099528,3.1099528 30.443078 0 0 4.62309,2.71703 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:path-effect="#path-effect5842"
+ inkscape:original-d="m 264.80668,147.33751 v -18.78127 l -62.45411,34.78129 v 18.78126 z" />
+ <path
+ id="path5836"
+ style="fill:url(#linearGradient5850);stroke-width:2.03638;stroke-linecap:round;stroke-linejoin:round"
+ d="m 264.80668,133.84791 0,13.4896 -57.83102,-32.20664 a 9.0039105,9.0039105 59.556922 0 1 -4.62309,-7.86631 v -8.197926 a 3.1099531,3.1099531 149.55692 0 1 4.62309,-2.717026 l 53.20793,29.631992 a 9.0039096,9.0039096 59.55692 0 1 4.62309,7.86631 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:path-effect="#path-effect5846"
+ inkscape:original-d="m 264.80668,128.55624 v 18.78127 L 202.35257,112.55623 V 93.774967 Z" />
+ </g>
+ </g>
+</svg>
diff --git a/www/assets/images/logo/deja.png b/www/assets/images/logo/deja.png
new file mode 100644
index 0000000..28e9d31
--- /dev/null
+++ b/www/assets/images/logo/deja.png
Binary files differ
diff --git a/www/assets/images/screenshots/.DS_Store b/www/assets/images/screenshots/.DS_Store
index 8ac5adc..cfdc9d2 100644
--- a/www/assets/images/screenshots/.DS_Store
+++ b/www/assets/images/screenshots/.DS_Store
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image1.png b/www/assets/images/screenshots/deja/image1.png
new file mode 100644
index 0000000..609643c
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image1.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image2.png b/www/assets/images/screenshots/deja/image2.png
new file mode 100644
index 0000000..9f82d2c
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image2.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image3.png b/www/assets/images/screenshots/deja/image3.png
new file mode 100644
index 0000000..c215f0b
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image3.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image4.png b/www/assets/images/screenshots/deja/image4.png
new file mode 100644
index 0000000..d663345
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image4.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image5.png b/www/assets/images/screenshots/deja/image5.png
new file mode 100644
index 0000000..5d9e57a
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image5.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image6.png b/www/assets/images/screenshots/deja/image6.png
new file mode 100644
index 0000000..9cfe87a
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image6.png
Binary files differ
diff --git a/www/assets/images/screenshots/deja/image7.png b/www/assets/images/screenshots/deja/image7.png
new file mode 100644
index 0000000..6c03909
--- /dev/null
+++ b/www/assets/images/screenshots/deja/image7.png
Binary files differ
diff --git a/www/blog/index.html b/www/blog/index.html
index ac05222..e5c9967 100644
--- a/www/blog/index.html
+++ b/www/blog/index.html
@@ -34,7 +34,7 @@
<section style="border-top: none;" class="top-section-margin">
<div class="center-grid">
<div class="div-sizing">
- <div class="flex-container flex-container-column flex-center-content" id="blog-container">
+ <div class="flex-container flex-container-column flex-center" id="blog-container">
<span class="heading">(dev)Blog</span>
</div>
</div>
diff --git a/www/codehilite-style.css b/www/codehilite-style.css
new file mode 100644
index 0000000..c8a2540
--- /dev/null
+++ b/www/codehilite-style.css
@@ -0,0 +1,83 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.codehilite .hll { background-color: #ffffcc }
+.codehilite .c { color: #8F5902; font-style: italic } /* Comment */
+.codehilite .err { color: #A40000; border: 1px solid #EF2929 } /* Error */
+.codehilite .g { color: #000 } /* Generic */
+.codehilite .k { color: #204A87; font-weight: bold } /* Keyword */
+.codehilite .l { color: #000 } /* Literal */
+.codehilite .n { color: #000 } /* Name */
+.codehilite .o { color: #CE5C00; font-weight: bold } /* Operator */
+.codehilite .x { color: #000 } /* Other */
+.codehilite .p { color: #000; font-weight: bold } /* Punctuation */
+.codehilite .ch { color: #8F5902; font-style: italic } /* Comment.Hashbang */
+.codehilite .cm { color: #8F5902; font-style: italic } /* Comment.Multiline */
+.codehilite .cp { color: #8F5902; font-style: italic } /* Comment.Preproc */
+.codehilite .cpf { color: #8F5902; font-style: italic } /* Comment.PreprocFile */
+.codehilite .c1 { color: #8F5902; font-style: italic } /* Comment.Single */
+.codehilite .cs { color: #8F5902; font-style: italic } /* Comment.Special */
+.codehilite .gd { color: #A40000 } /* Generic.Deleted */
+.codehilite .ge { color: #000; font-style: italic } /* Generic.Emph */
+.codehilite .ges { color: #000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+.codehilite .gr { color: #EF2929 } /* Generic.Error */
+.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.codehilite .gi { color: #00A000 } /* Generic.Inserted */
+.codehilite .go { color: #000; font-style: italic } /* Generic.Output */
+.codehilite .gp { color: #8F5902 } /* Generic.Prompt */
+.codehilite .gs { color: #000; font-weight: bold } /* Generic.Strong */
+.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.codehilite .gt { color: #A40000; font-weight: bold } /* Generic.Traceback */
+.codehilite .kc { color: #204A87; font-weight: bold } /* Keyword.Constant */
+.codehilite .kd { color: #204A87; font-weight: bold } /* Keyword.Declaration */
+.codehilite .kn { color: #204A87; font-weight: bold } /* Keyword.Namespace */
+.codehilite .kp { color: #204A87; font-weight: bold } /* Keyword.Pseudo */
+.codehilite .kr { color: #204A87; font-weight: bold } /* Keyword.Reserved */
+.codehilite .kt { color: #204A87; font-weight: bold } /* Keyword.Type */
+.codehilite .ld { color: #000 } /* Literal.Date */
+.codehilite .m { color: #0000CF; font-weight: bold } /* Literal.Number */
+.codehilite .s { color: #4E9A06 } /* Literal.String */
+.codehilite .na { color: #C4A000 } /* Name.Attribute */
+.codehilite .nb { color: #204A87 } /* Name.Builtin */
+.codehilite .nc { color: #000 } /* Name.Class */
+.codehilite .no { color: #000 } /* Name.Constant */
+.codehilite .nd { color: #5C35CC; font-weight: bold } /* Name.Decorator */
+.codehilite .ni { color: #CE5C00 } /* Name.Entity */
+.codehilite .ne { color: #C00; font-weight: bold } /* Name.Exception */
+.codehilite .nf { color: #000 } /* Name.Function */
+.codehilite .nl { color: #F57900 } /* Name.Label */
+.codehilite .nn { color: #000 } /* Name.Namespace */
+.codehilite .nx { color: #000 } /* Name.Other */
+.codehilite .py { color: #000 } /* Name.Property */
+.codehilite .nt { color: #204A87; font-weight: bold } /* Name.Tag */
+.codehilite .nv { color: #000 } /* Name.Variable */
+.codehilite .ow { color: #204A87; font-weight: bold } /* Operator.Word */
+.codehilite .pm { color: #000; font-weight: bold } /* Punctuation.Marker */
+.codehilite .w { color: #F8F8F8 } /* Text.Whitespace */
+.codehilite .mb { color: #0000CF; font-weight: bold } /* Literal.Number.Bin */
+.codehilite .mf { color: #0000CF; font-weight: bold } /* Literal.Number.Float */
+.codehilite .mh { color: #0000CF; font-weight: bold } /* Literal.Number.Hex */
+.codehilite .mi { color: #0000CF; font-weight: bold } /* Literal.Number.Integer */
+.codehilite .mo { color: #0000CF; font-weight: bold } /* Literal.Number.Oct */
+.codehilite .sa { color: #4E9A06 } /* Literal.String.Affix */
+.codehilite .sb { color: #4E9A06 } /* Literal.String.Backtick */
+.codehilite .sc { color: #4E9A06 } /* Literal.String.Char */
+.codehilite .dl { color: #4E9A06 } /* Literal.String.Delimiter */
+.codehilite .sd { color: #8F5902; font-style: italic } /* Literal.String.Doc */
+.codehilite .s2 { color: #4E9A06 } /* Literal.String.Double */
+.codehilite .se { color: #4E9A06 } /* Literal.String.Escape */
+.codehilite .sh { color: #4E9A06 } /* Literal.String.Heredoc */
+.codehilite .si { color: #4E9A06 } /* Literal.String.Interpol */
+.codehilite .sx { color: #4E9A06 } /* Literal.String.Other */
+.codehilite .sr { color: #4E9A06 } /* Literal.String.Regex */
+.codehilite .s1 { color: #4E9A06 } /* Literal.String.Single */
+.codehilite .ss { color: #4E9A06 } /* Literal.String.Symbol */
+.codehilite .bp { color: #3465A4 } /* Name.Builtin.Pseudo */
+.codehilite .fm { color: #000 } /* Name.Function.Magic */
+.codehilite .vc { color: #000 } /* Name.Variable.Class */
+.codehilite .vg { color: #000 } /* Name.Variable.Global */
+.codehilite .vi { color: #000 } /* Name.Variable.Instance */
+.codehilite .vm { color: #000 } /* Name.Variable.Magic */
+.codehilite .il { color: #0000CF; font-weight: bold } /* Literal.Number.Integer.Long */
diff --git a/www/index.html b/www/index.html
index ce89d90..b76faf4 100644
--- a/www/index.html
+++ b/www/index.html
@@ -7,7 +7,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
- <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<link rel="me" href="https://mastodon.gamedev.place/@altaf">
<title>altaf-creator</title>
<link rel="stylesheet" href="/packages/fontawesome-free-7.2.0-web/css/all.css">
@@ -70,7 +69,7 @@
<div class="div-sizing" style="height: 100%;">
<div class="flex-container flex-container-column">
<span class="heading">Highlighted Works</span>
- <div class="flex-container flex gap" style="min-height: 600px;">
+ <div class="flex-container flex-container-dynamic flex gap" style="min-height: 600px;">
<div class="flex full-img-card highlight-card"
style="background-image: url(/assets/images/game-hero/simplicity_screenshot.png); ">
<a href="/projects/simpliCity/" class="fill-div gradient-overlay">
@@ -137,9 +136,9 @@
<span class="heading">Library</span>
<p>my (dev)Blog and other things I'd like to share</p>
<h1>Blog Posts</h1>
- <div class="flex-container flex-center" id="blog-container">
+ <div class="flex-container flex-x-center" id="blog-container">
</div>
- <div class="flex-container flex-center">
+ <div class="flex-container flex-x-center">
<a href="blog/" class="button" style="margin-left: auto; margin-right: auto;">View More</a>
</div>
<h1>Stuff</h1>
diff --git a/www/projects/index.html b/www/projects/index.html
index 27c532e..b3cb586 100644
--- a/www/projects/index.html
+++ b/www/projects/index.html
@@ -62,7 +62,7 @@
<i class="fa-brands fa-git-alt"></i> Source Code for My Projects &UpperRightArrow;
</a>
</p>
- <div class="flex-container flex gap" id="top-project-highlight">
+ <div class="flex-container flex-container-dynamic flex gap" id="top-project-highlight">
<div class="flex full-img-card highlight-card top-gallery-card"
style="background-image: url(/assets/images/game-hero/simplicity_screenshot.png); ">
<a href="/projects/simpliCity/" class="fill-div gradient-overlay">
@@ -109,12 +109,12 @@
</a>
<div class="img-card-titlebox">
<span class="img-card-subtitle"><i class="fa-solid fa-briefcase"></i> Internship</span>
- <span class="img-card-title">Internship Projects</span>
+ <span class="img-card-title">Tinkertanker Web Dev</span>
</div>
</div>
<div class="flex full-img-card gallery-card"
- style="background-image: url(/assets/images/game-hero/.png);">
- <a href="https://deja.earth/" class="fill-div gradient-overlay">
+ style="background-image: url(/assets/images/game-hero/deja_screenshot.png);">
+ <a href="./deja/" class="fill-div gradient-overlay">
</a>
<div class="img-card-titlebox">
<span class="img-card-subtitle"><i class="fa-solid fa-people-group"></i> Team</span>
@@ -375,7 +375,7 @@
<img src="/assets/images/video-hero/paperverse.png" alt="">
<a href="/video/paperverse/" class="video-play-cover">⏵</a>
</div>
- <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center-content">
+ <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center">
<a href="/video/paperverse/" class="link monospaced">Paperverse Hub</a>
<span>2026</span>
</div>
@@ -385,7 +385,7 @@
<img src="/assets/images/video-hero/eid2026.png" alt="">
<a href="/video/eid2026" class="video-play-cover">⏵</a>
</div>
- <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center-content gap">
+ <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center gap">
<a href="/video/eid2026/" class="link monospaced">A message for this Eid</a>
<span>2026</span>
</div>
@@ -395,7 +395,7 @@
<img src="/assets/images/video-hero/openhouse.png" alt="">
<a href="/video/openhouse/" class="video-play-cover">⏵</a>
</div>
- <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center-content gap">
+ <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center gap">
<a href="/video/openhouse/" class="link monspaced">Ngee Ann Open House 2025</a>
<span><i class="fa-solid fa-people-group"></i> 2025</span>
</div>
@@ -405,7 +405,7 @@
<img src="/assets/images/video-hero/via3rp.png" alt="">
<a href="/video/s3via/" class="video-play-cover">⏵</a>
</div>
- <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center-content gap">
+ <div class="video-gallery-card-text flex-container flex-container-normal flex-container-dynamicwrap flex-spacebetween flex-center gap">
<a href="/video/s3via/" class="link monospaced">Secondary 3 VIA Project</a>
<span>2025</span>
</div>
diff --git a/www/scripts/constants.js b/www/scripts/constants.js
index b2b7894..1c2812e 100644
--- a/www/scripts/constants.js
+++ b/www/scripts/constants.js
@@ -1,2 +1,2 @@
-//const API_URL = "https://altafcreator.com/api"
-const API_URL = "http://localhost:9091/api"
+const API_URL = "https://altafcreator.com/api"
+//const API_URL = "http://localhost:9091/api"
diff --git a/www/scripts/onload.js b/www/scripts/onload.js
index 3bc9cf3..539df36 100644
--- a/www/scripts/onload.js
+++ b/www/scripts/onload.js
@@ -1,22 +1,35 @@
function addNodes() {
- const collection = document.getElementsByTagName("section");
- const container = document.getElementById("progressContainer");
+ const collection = document.getElementsByTagName("section");
+ const container = document.getElementById("progressContainer");
- for (var i = 0; i < collection.length; i++) {
+ for (var i = 0; i < collection.length; i++) {
+ if (collection.item(i).getAttribute('data-excluded') != null) {
+ continue;
+ }
var node = document.createElement("a");
node.className = "node";
- container.appendChild(node);
+ container.appendChild(node);
if (collection.item(i).getAttribute('id') == null) {
- collection.item(i).setAttribute('id', `section-${i}`);
+ collection.item(i).setAttribute('id', `section-${i}`);
}
node.setAttribute('id', `node-${i}`)
node.href = `#${collection.item(i).getAttribute('id')}`
- }
+ }
+
+ replaceExternalLinks();
+}
+
+function replaceExternalLinks() {
+ for (var links = document.links, i = 0, a; a = links[i]; i++) {
+ if (a.host !== location.host) {
+ a.target = '_blank';
+ }
+ }
}
function blog(n) {
- // addNodes is called in loadPost(n);
- loadPost(n);
+ // addNodes is called in loadPost(n);
+ loadPost(n);
}
function index() {
diff --git a/www/scripts/scroll.js b/www/scripts/scroll.js
index d7ab5da..6a61015 100644
--- a/www/scripts/scroll.js
+++ b/www/scripts/scroll.js
@@ -11,9 +11,13 @@ nodeBigSize = "25px";
nodeDefaultSize = "16px";
function progress() {
- const sections = document.getElementsByTagName("section");
+ const sections = [...document.getElementsByTagName("section")].filter(e => {
+ return e.getAttribute("data-excluded") == null;
+ });
const nodes = document.getElementsByClassName("node");
+ console.log(sections);
+
if (nodes[0]) {
for (var i = 0; i < sections.length; i++) {
if (isInViewport(sections[i])) {
diff --git a/www/style.css b/www/style.css
index f454dd9..40d8392 100644
--- a/www/style.css
+++ b/www/style.css
@@ -30,6 +30,7 @@
--accent1: #00BA62;
--accent2: #008C94;
--accent: #00A37B;
+ --home-title-offset: 20px;
}
::-moz-selection { /* Code for Firefox */
@@ -46,6 +47,10 @@ html {
overflow-x: none;
}
+p {
+ line-height: 1.5rem;
+}
+
body {
margin: 0;
padding: 0;
@@ -67,6 +72,11 @@ h2 {
font-family: "JetBrains Mono", monospace;
}
+
+h1:target, h2:target, h3:target, h4:target, h5:target, h6:target, p:target {
+ background-color: color-mix(in srgb, var(--accent1) 25%, transparent);
+}
+
section {
padding-inline: 50px;
min-height: 100%;
@@ -82,6 +92,11 @@ section {
section:first-of-type {
border-top: none;
+ min-height: calc(100vh - 20px);
+}
+
+section:first-of-type > .center-grid {
+ min-height: calc(100vh - 20px);
}
hr {
@@ -91,18 +106,25 @@ hr {
margin: 20px;
}
-pre::before {
+.pre > pre::before {
content: "> ";
color: #00A37B;
}
+.long-code {
+ max-height: 16rem;
+ margin-bottom: 1rem;
+}
+
pre {
font-size: large;
background-color: #00000010;
padding: 10px;
border-radius: 5px;
color: #444;
- white-space: pre-wrap;
+ white-space: pre;
+ margin: 0;
+ overflow: auto;
}
li {
@@ -114,10 +136,6 @@ img {
color: #000000AA;
}
-p {
- line-height: 1.5rem;
-}
-
.desktop {
visibility: visible !important;
}
@@ -141,12 +159,12 @@ p {
}
.normal-section {
- min-height: 0;
+ min-height: 0 !important;
height: fit-content;
}
.normal-section > .center-grid {
- min-height: 0;
+ min-height: 0 !important;
}
.video-section {
@@ -166,6 +184,7 @@ p {
margin-top: 1rem;
margin-bottom: 1rem;
font-family: "JetBrains Mono", monospace;
+ line-height: 3.3rem;
}
.colored-text {
@@ -283,7 +302,7 @@ p {
to {
letter-spacing: clamp(10px, -0.875rem + 5vw, 30px);
color: #FFFFFF5A;
- bottom: 46%;
+ bottom: calc(46% + var(--home-title-offset));
}
}
@@ -296,7 +315,7 @@ p {
text-align: center;
width: calc(100% - 70px);
line-height: 65%;
- bottom: 46%;
+ bottom: calc(46% + var(--home-title-offset));
z-index: 0;
letter-spacing: clamp(10px, -0.875rem + 5vw, 30px);
animation-name: title;
@@ -312,11 +331,20 @@ p {
box-sizing: border-box;
}
+.div-sizing-bare {
+ width: 100%;
+ max-width: 1200px;
+}
+
.img {
clip-path: polygon(0 20.00px, 20px 20px, 20.00px 0, calc(100% - 20.00px) 0, calc(100% - 20px) 20px, 100% 20.00px, 100% calc(100% - 20.00px), calc(100% - 20px) calc(100% - 20px), calc(100% - 20.00px) 100%, 20.00px 100%, 20px calc(100% - 20px), 0 calc(100% - 20.00px));
max-width: 100%;
}
+.nopath {
+ clip-path: none !important;
+}
+
.center-grid {
display: grid;
place-items: center;
@@ -408,16 +436,15 @@ p {
clip-path: polygon(0 10.00px, 10px 10px, 10.00px 0, calc(100% - 10.00px) 0, calc(100% - 10px) 10px, 100% 10.00px, 100% calc(100% - 10.00px), calc(100% - 10px) calc(100% - 10px), calc(100% - 10.00px) 100%, 10.00px 100%, 10px calc(100% - 10px), 0 calc(100% - 10.00px));
}
-.flex-center {
- flex-direction: column;
+.flex-x-center {
place-items: center;
}
-.flex-center-content {
+.flex-center {
place-content: center;
}
-.flex-aligncenter {
+.flex-y-center {
align-items: center;
}
@@ -553,12 +580,12 @@ p {
box-sizing: border-box;
}
-.bottom-bar > img {
+.bottom-bar > div > img {
height: 40px;
transition: height .4s;
}
-.bottom-bar > img:hover {
+.bottom-bar > div > img:hover {
height: 45px;
transition: height .4s;
}
@@ -811,6 +838,7 @@ p {
z-index: 4;
background-size: cover;
background-position: center;
+ min-height: 100vh !important;
}
.bento-img-lr {
@@ -1148,6 +1176,136 @@ p {
margin-top: .9rem;
}
+.timeline {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+}
+
+.timeline::after {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 0;
+ bottom: 0;
+ margin-left: -2px;
+ width: 4px;
+ background: linear-gradient(180deg, var(--accent2) 0, var(--accent1) 100%);
+ z-index: -1;
+}
+
+.timeline-before::after {
+ background:
+ repeating-linear-gradient(180deg, white, white 10px, var(--accent2) 10px, var(--accent2) 20px),
+ var(--accent2);
+ background-size: 100% 100px, 100% 100%;
+ background-repeat: no-repeat;
+ mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.5) calc(100% - 200px), black 100%);
+ -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.5) calc(100% - 200px), black 100%);
+}
+
+.timeline-before > .timeline-item::after {
+ background-color: #7ec5c9;
+}
+
+.timeline-before > .timeline-highlight::after {
+ background-color: white;
+ border-color: #7ec5c9;
+}
+
+.timeline-future::after {
+ background: repeating-linear-gradient(180deg, var(--accent1), var(--accent1) 10px, transparent 10px, transparent 20px);
+ -webkit-mask-image: linear-gradient(180deg, black 0, rgba(0, 0, 0, 0.5) 200px, rgba(0, 0, 0, 0.5) calc(100% - 200px), transparent 100%);
+ mask-image: linear-gradient(180deg, black 0, rgba(0, 0, 0, 0.5) 200px, rgba(0, 0, 0, 0.5) calc(100% - 200px), transparent 100%);
+}
+
+.timeline-future > .timeline-milestone {
+ border-color: var(--accent1);
+}
+
+.timeline > * {
+ margin-bottom: 20px;
+}
+
+.timeline-milestone {
+ place-self: center;
+ background-color: white;
+ z-index: 2;
+ border: var(--accent) 4px solid;
+ padding-inline: 8px;
+ position: relative;
+}
+
+.timeline-milestone > h1 {
+ margin: 0;
+ text-align: center;
+}
+
+.timeline-milestone > span {
+ top: 50%;
+ transform: translateY(-50%);
+ font-family: "JetBrains Mono";
+ position: absolute;
+ width: fit-content;
+ width: 200px;
+ opacity: .5;
+}
+
+.timeline-milestone-right {
+ left: calc(100% + 20px);
+ text-align: left;
+ font-weight: bold;
+ opacity: .8 !important;
+}
+
+.timeline-milestone-left {
+ right: calc(100% + 20px);
+ text-align: right;
+}
+
+.timeline-item::after {
+ content: '';
+ position: absolute;
+ height: 4px;
+ width: 20px;
+ background-color: var(--accent);
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.timeline-highlight::after {
+ height: 12px;
+ width: 12px;
+ background-color: white;
+ border: 4px solid var(--accent);
+ transform: rotate(45deg) translate(-50%, -50%);
+ margin-left: -10px;
+}
+
+.timeline-milestone::after {
+ display: none;
+}
+
+.timeline-item > div {
+ padding: 20px;
+ clip-path: polygon(0 10.00px, 10px 10px, 10.00px 0, calc(100% - 10.00px) 0, calc(100% - 10px) 10px, 100% 10.00px, 100% calc(100% - 10.00px), calc(100% - 10px) calc(100% - 10px), calc(100% - 10.00px) 100%, 10.00px 100%, 10px calc(100% - 10px), 0 calc(100% - 10.00px));
+ background-color: white;
+}
+
+.timeline-item > div > h2 {
+ margin-top: .5rem;
+}
+
+.timeline-item:nth-child(odd of .timeline-item) > div {
+ margin-left: calc(50% + 25px);
+}
+
+.timeline-item:nth-child(even of .timeline-item) > div {
+ margin-right: calc(50% + 25px);
+}
+
#video-controls-progress {
width: 100%;
}
@@ -1281,6 +1439,10 @@ p {
background-image: url(/assets/images/game-hero/laundryweb.png);
}
+#deja-img {
+ background-image: url(/assets/images/game-hero/deja_screenshot.png);
+}
+
#simpliCity-link {
position: absolute;
right: 30px;
@@ -1333,6 +1495,14 @@ p {
aspect-ratio: 16/9;
}
+#flex-300 {
+ flex: 0 1 300px;
+}
+
+.flex-500 {
+ flex: 0 1 500px;
+}
+
.footnote {
font-size: .9rem;
opacity: .75;
@@ -1362,12 +1532,20 @@ li:target {
.iframe-manual-warning {
position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+.iframe-manual-warning > * {
+ position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
-.iframe-manual-warning > div {
+.iframe-manual-notice {
display: flex;
gap: 10px;
flex-direction: column;
@@ -1379,6 +1557,10 @@ li:target {
}
@media only screen and (max-width: 600px) {
+ :root {
+ --home-title-offset: 60px;
+ }
+
.desktop {
visibility: collapse !important;
display: none !important;
@@ -1398,10 +1580,6 @@ li:target {
display: inline;
}
- .flex {
- flex-direction: column;
- }
-
.card {
flex-direction: column;
height: auto;
@@ -1453,7 +1631,7 @@ li:target {
width: 100%;
}
- .div-sizing {
+ .div-sizing, .div-sizing-bare {
max-width: calc(100vw - 30px);
}
@@ -1469,10 +1647,10 @@ li:target {
left: 0;
}
- .bottom-bar > img {
+ .bottom-bar > div > img {
height: 30px;
}
- .bottom-bar > img:hover {
+ .bottom-bar > div > img:hover {
height: 35px;
}
@@ -1499,16 +1677,61 @@ li:target {
}
.gap-row {
- gap: 0px;
+ gap: 10px;
+ }
+
+ #flex-300 {
+ flex: 1 1;
+ }
+
+ .flex-500 {
+ flex: 1 1;
+ }
+
+ .timeline::after {
+ left: auto;
+ margin-left: 20px;
+ }
+
+ .timeline-milestone {
+ place-self: start
+ }
+
+ .timeline-item::after {
+ left: 22px;
+ }
+
+ .timeline-item > div {
+ margin-left: 45px !important;
+ margin-right: 0 !important;
+ }
+
+ .timeline-milestone-left {
+ right: auto;
+ left: calc(100% + 20px);
+ text-align: left;
+ top: calc(50% + .65rem) !important;
+ }
+
+ .timeline-milestone-right {
+ top: calc(50% - .65rem) !important;
+ }
+
+ section:first-of-type {
+ min-height: calc(100vh - 80px);
+ }
+
+ section:first-of-type > .center-grid {
+ min-height: calc(100vh - 80px);
}
}
@media only screen and (max-width: 1000px) {
- .flex {
+ .flex-container-dynamic {
flex-direction: column;
}
-
+
#top-project-highlight {
height: 200vh;
}