Files
dating/README.md
T
tiennm99 6d0a21eaf7 refactor: drop the job-description conceit for a plainly romantic register
The page was a mock job posting: applicants, positions, benefits,
responsibilities, a spec table and selection notes. That framing carried real
wit, but it kept the warmest scenes at arm's length behind HR vocabulary.

Every sentence carrying a personal fact is untouched — the dev job, Genshin and
T1 Keria, the light novels, the three-year relationship, 162cm, the playlist,
the whole appendix. Only the framing around them changed:

- Retitled throughout: page title, OG and Twitter tags, wordmark. The site is
  now an open letter rather than a description and a CV.
- "Ứng viên là ai?" becomes "Mình là ai?"; the cold open is a seat that has been
  empty a while rather than a vacancy; the CTA meets a person, not a candidate.
- Scene 4 offers what he can give instead of listing entitlements, and loses the
  job-spec table whose three jokes only worked as a job spec.
- Scene 5 drops "Trách nhiệm" for a smaller, warmer promise.
- Scene 6 keeps its no-tests sentiment without the stress-test phrasing, and the
  climax speaks about the person he hopes to meet rather than a strong applicant.
- The appendix is a few concrete things, not a dossier; the freshness stamp says
  he is still looking rather than that a position remains open.

Also drops the office-parody joke, which pointed at a conceit that no longer
exists, and restyles the numbered package as four unhurried lines so scene 4
keeps a shape of its own without reading as a compensation schedule.
2026-07-25 12:02:10 +07:00

2.8 KiB

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.