tiennm99 ff6dc3b39e feat: the room gets later as she reads
One continuous transformation across all nine scenes, so the page reads as a
single evening instead of nine separate slides. A fixed backdrop layer travels
from early evening toward past midnight as she scrolls: the corners go to plum,
the lamp keeps its warmth, and dust turns over in the beam.

It starts from the hour on her own device, so opening it at 1am begins deep in
the night and a friend shown it the next afternoon sees a different room.
Nothing leaves the device and there is no backend — it reads her clock.

Deliberate boundaries:
- Atmosphere only. The palette tokens are never interpolated, so an explicit
  light or dark choice always wins; both themes simply travel within themselves.
- The scrubbed value is written to one element, not to :root. On :root it would
  invalidate everything inheriting it on every frame.
- Dust is a masked, tiled dot pattern on one composited layer rather than N
  particle elements — many things moving, one transform.
- Defaults to a lit room in CSS, so the no-JS tier gets a deliberate composition
  rather than an unlit one, and reduced motion freezes the evening at about 22:00
  with the air still.

Verified at 1440x900 and 390x844, both themes, and reduced motion: the value
travels with scroll, the theme choice survives, no horizontal overflow, no hidden
beats, no console output.

This is the light system the remaining objects will be lit by; it is groundwork
as much as it is a scene.
2026-07-25 14:32:47 +07:00
2026-07-24 23:34:09 +07:00

Dating

A warm open letter from Tiến Nguyễn Minh to whoever comes along, told as a scroll-driven short film. Vietnamese only.

The page was originally framed as a mock job description and CV; that conceit was dropped in favour of a plainly romantic register, so avoid reintroducing recruiting language (ứng viên, vị trí, quyền lợi, trách nhiệm, tuyển chọn) when editing copy.

Structure

Single-page site: index.html at the repo root holds the whole story, told as scenes and navigable via anchors:

  • #home — cold open, the vacant position
  • #applicant — who the candidate is
  • #honest — saying it straight
  • #offer — what you get
  • #shared — what you both protect
  • #no-test — bonus points, and the written climax
  • #closing — the connect beat
  • #dossier — appendix, the detail table
  • #end — end card

Features

  • Light theme: warm ivory and terracotta-rose
  • Dark theme: candlelit plum and rose-gold
  • First visit follows the OS colour scheme; an explicit choice is persisted
  • Compact emoji theme switch
  • Vietnamese-only copy

Tech

  • Plain HTML, CSS, and JavaScript — no framework, no build step
  • GitHub Pages (classic, deploy from branch)

Motion tiers

Motion is a three-tier progressive enhancement. Any change must keep all three working, and no [data-reveal] element may ever be left invisible:

  1. Film (html.film-ready) — GSAP + ScrollTrigger + Lenis from a CDN, in assets/story-film.js. Activates only on ≥768px, with motion allowed, and only when the CDN libraries actually arrived in time.
  2. Reveal (html.js-ready:not(.film-ready)) — IntersectionObserver fade-and-rise in assets/story.js. This is what phones and reduced-motion visitors get.
  3. Static — no JS, or a stalled CDN. A watchdog in the index.html head un-hides everything after 1200ms if no engine has claimed the page, so the first paint is never wordless.

Two ordering rules in story-film.js are load-bearing and commented there: pins are created before reveals and carry refreshPriority: 1, and reveals are per-beat and non-reversing.

Files

  • assets/styles.css — tokens, layout, components (both themes)
  • assets/story.css / story.js — tier 2 reveal
  • assets/story-film.css / story-film.js — tier 1 film
  • assets/story-chrome.css / story-chrome.js — progress bar + active nav
  • assets/theme-switch.js — theme toggle (keep in sync with the head bootstrap)
  • assets/freshness-stamp.js — "cập nhật [ngày]" from the GitHub commit date

Developing

No install needed. Open index.html directly, or serve the folder:

python -m http.server 8000

Then visit http://localhost:8000/.

Deploying

Classic GitHub Pages serves the main branch root directly — pushing to main publishes the site. .nojekyll disables Jekyll processing.

S
Description
Warm-witty dating JD and CV site built with SvelteKit
Readme
5.6 MiB
Languages
CSS 40.2%
JavaScript 33.5%
HTML 26.3%