Files
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

611 lines
26 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="vi">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Tiến Nguyễn Minh | Thư ngỏ tìm người đi đường dài</title>
<meta
name="description"
content="Một lá thư ngỏ của Tiến Nguyễn Minh, gửi người sẽ cùng đi đường dài — kể như một thước phim ngắn."
/>
<link rel="icon" href="assets/favicon.svg" />
<!-- The hero photo is the film's opening frame but is only discoverable after
styles.css parses; preloading it pulls the first paint forward. -->
<link
rel="preload"
as="image"
href="assets/dating-application-hero-background.webp"
fetchpriority="high"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<!-- Fraunces is requested as a continuous weight RANGE (400..750), not as three
fixed instances. With only 500/650/750 available, CSS weight matching
snapped both h2 (550) and h3 (600) to 650 — h1, h2 and h3 all rendered at
the same weight and the type hierarchy the stylesheet describes did not
exist. Be Vietnam Pro 500 was requested but never used; dropped. -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@400;600;700&amp;family=Fraunces:opsz,wght@9..144,400..750&amp;display=swap"
/>
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Thư ngỏ hẹn hò" />
<meta property="og:locale" content="vi_VN" />
<meta property="og:title" content="Tiến Nguyễn Minh | Thư ngỏ tìm người đi đường dài" />
<meta
property="og:description"
content="Một lá thư ngỏ của Tiến Nguyễn Minh, gửi người sẽ cùng đi đường dài — kể như một thước phim ngắn."
/>
<meta
property="og:image"
content="https://tiennm99.github.io/dating/assets/social/dating-jd-cv-social-preview.png"
/>
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Minh họa một lá thư ngỏ ấm áp" />
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:image"
content="https://tiennm99.github.io/dating/assets/social/dating-jd-cv-social-preview.png"
/>
<meta name="twitter:image:alt" content="Minh họa một lá thư ngỏ ấm áp" />
<script>
// Pre-paint theme bootstrap. Keep the storage key, accepted values, and default
// in sync with assets/theme-switch.js.
(() => {
try {
const root = document.documentElement;
// First visit (no stored choice) follows the OS light/dark setting; a
// stored choice always wins. Persisting happens only on an explicit
// toggle (see theme-switch.js), so the OS default stays "unset" and keeps
// tracking the system until the visitor actually picks a theme.
const storedTheme = localStorage.getItem('dating-theme');
const theme =
storedTheme === 'dark' || storedTheme === 'light'
? storedTheme
: window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
root.dataset.theme = theme;
root.style.colorScheme = theme;
// Gate scroll-reveal motion behind JS + IntersectionObserver support,
// set pre-paint so revealable content never flashes visible then hides.
// Consumed by assets/story.css and assets/story-chrome.css.
if ('IntersectionObserver' in window) {
root.classList.add('js-ready');
// Watchdog. `js-ready` hides all 31 beats, and the engine that
// reveals them again sits behind ~40KB of deferred CDN script.
// A hard CDN failure is handled (the scripts never run, and
// story.js is local), but a SLOW-but-successful CDN is not:
// until it resolves, the first paint contains no words at all.
// If no engine has claimed the page in time, un-hide everything
// and let the reader read. Engines set `storyEngine` when they
// take over; story.js also checks `storyWatchdog` so it never
// re-hides content this already revealed.
window.setTimeout(() => {
if (root.dataset.storyEngine) return;
root.dataset.storyWatchdog = 'fired';
root.classList.remove('js-ready');
}, 1200);
}
} catch {
document.documentElement.dataset.theme = 'light';
document.documentElement.style.colorScheme = 'light';
}
})();
</script>
<link rel="stylesheet" href="assets/styles.css" />
<link rel="stylesheet" href="assets/story.css" />
<link rel="stylesheet" href="assets/story-chrome.css" />
<link rel="stylesheet" href="assets/story-film.css" />
<script src="assets/theme-switch.js" defer></script>
<!-- Film engine libraries (CDN, versioned). Load before story-film.js.
If any fails, story-film.js bails and the static reveal (story.js) runs.
All three come from one host so the film costs a single connection
rather than two DNS+TLS handshakes. -->
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.3.25/dist/lenis.min.js" defer></script>
<!-- story-film.js decides whether the film activates; must run before story.js
so story.js can defer to it. story.js is the reduced-motion / mobile / no-CDN fallback. -->
<script src="assets/story-film.js" defer></script>
<script src="assets/story.js" defer></script>
<script src="assets/story-chrome.js" defer></script>
<!-- Fills the closing "cập nhật [ngày]" stamp from the GitHub commit date;
independent of the motion engines, degrades silently on any failure. -->
<script src="assets/freshness-stamp.js" defer></script>
</head>
<body>
<!-- The room gets later as she reads. One fixed backdrop layer whose --night
value travels from her own local hour toward midnight across the whole
page, so the nine scenes read as one evening rather than nine slides.
Purely atmospheric and aria-hidden: it never touches the theme tokens
(her explicit light/dark choice always wins) and never gates content.
Defaults to a lit room in CSS, so the no-JS and reduced-motion tiers get
a deliberate composition rather than an unlit one. -->
<div class="nightfall" aria-hidden="true"><span class="nightfall__dust"></span></div>
<div class="scroll-progress" aria-hidden="true"><span class="scroll-progress__fill"></span></div>
<a class="skip-link" href="#content">Bỏ qua đến nội dung</a>
<!-- Full-bleed bar with an inner shell: .site-shell used to be on the header
itself, so the background, border and blur were clipped to 1120px and the
bar floated over the hero with the photo showing on both sides. -->
<header class="site-header">
<div class="site-shell site-header__inner">
<a
class="brand-mark"
href="#home"
aria-label="Về đầu trang thư ngỏ của Tiến Nguyễn Minh"
>
<span class="brand-seal">TN</span>
<span class="brand-name">Thư ngỏ</span>
</a>
<div class="header-actions">
<!-- "Kết nối" (#closing) is the page's only apply door; it previously
had no link in the persistent chrome. -->
<nav aria-label="Điều hướng chính">
<a href="#home">Mở đầu</a>
<a href="#applicant">Con người</a>
<a href="#offer">Lời mời</a>
<a href="#closing">Kết nối</a>
<a href="#dossier">Chi tiết</a>
</nav>
<div class="preference-controls">
<div class="segmented-control icon-segmented" role="group" aria-label="Giao diện">
<button
type="button"
data-theme-option="light"
aria-label="Chuyển sang giao diện sáng"
aria-pressed="false"
title="Chuyển sang giao diện sáng"
>
<span class="emoji-icon" aria-hidden="true">☀️</span>
</button>
<button
type="button"
data-theme-option="dark"
aria-label="Chuyển sang giao diện tối"
aria-pressed="false"
title="Chuyển sang giao diện tối"
>
<span class="emoji-icon" aria-hidden="true">🌙</span>
</button>
</div>
</div>
</div>
</div>
</header>
<main id="content">
<!-- ============ Cảnh 1 · Cold open: chỗ trống bên cạnh ============ -->
<section class="home-hero film-scene" id="home" data-scene data-scene-pin>
<div class="site-shell hero-copy" data-reveal-group>
<p class="chapter-tag" data-reveal>Cảnh 1 · Chỗ trống bên cạnh</p>
<p class="eyebrow" data-reveal>Đang tìm một người đi đường dài</p>
<h1 data-reveal>Tiến Nguyễn Minh</h1>
<p class="lead" data-reveal>
Chỗ bên cạnh đã trống hơi lâu. Một anh dev hay ở nhà, cũng muốn đi chơi đấy — nhưng
lười đi một mình. Đang tìm một người cùng đi đường dài, nghiêm túc hơn cả cách mình
cày event Genshin.
</p>
<div class="button-row" data-reveal>
<a class="button" href="#applicant">Gặp mình</a>
<a class="button secondary" href="#offer">Đọc lời mời</a>
</div>
</div>
</section>
<!-- ============ Cảnh 2 · Nhân vật chính ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="applicant"
aria-labelledby="applicant-title"
data-scene
data-reveal-group
>
<div data-reveal>
<p class="chapter-tag">Cảnh 2 · Nhân vật chính</p>
<p class="eyebrow">Chân dung nhanh</p>
<h2 id="applicant-title">Mình là ai?</h2>
<!-- OWNER: thêm ảnh chân dung thật vào assets/ (khuyến nghị ~800×1000, .webp/.jpg đã nén),
rồi BỎ COMMENT thẻ <img> bên dưới và XOÁ khối .portrait__placeholder.
Giữ nguyên width/height để tránh giật layout (CLS). -->
<figure class="portrait">
<!--
<img
class="portrait__img"
src="assets/tien.jpg"
alt="Ảnh chân dung của Tiến Nguyễn Minh"
width="800"
height="1000"
loading="lazy"
decoding="async"
/>
-->
<div
class="portrait__placeholder"
role="img"
aria-label="Ảnh chân dung sẽ được thêm sau"
>
<svg viewBox="0 0 80 96" aria-hidden="true" focusable="false">
<circle cx="40" cy="32" r="18" />
<path d="M12 92c0-17 13-30 28-30s28 13 28 30" />
</svg>
<span>Ảnh thật cập nhật sau</span>
</div>
</figure>
</div>
<div class="panel-list">
<article class="panel" data-reveal>
<h3>Hướng nội có nghề</h3>
<p>
Tốt nghiệp Đại học Bờ Kênh TPHCM, hiện là công nhân đánh máy thuê tại Xí nghiệp gêm
Vê Nờ Gờ. Nói cách khác: một anh dev khá nghiện máy tính và thường chọn ở nhà.
</p>
</article>
<article class="panel" data-reveal>
<h3>Wibu nửa mùa</h3>
<p>
Thích light novel hơn manga và anime; isekai là thể loại chân ái. Thời gian rảnh
dành cho đọc truyện, xem phim, chơi Genshin, TFT, code vài thứ thú vị, và cổ vũ T1 —
nhất là Keria.
</p>
</article>
<article class="panel" data-reveal>
<h3>Playlist đủ mọi loại mood</h3>
<p>
Rap mainstream, nhạc tâm trạng, nhạc suy, nhạc wibu, nhạc Trung… Tâm trạng nào cũng
có bài lót sẵn, kể cả những tâm trạng chưa đặt tên.
</p>
<!-- OWNER: thay PLAYLIST_URL_HERE bằng link playlist công khai thật (Spotify/YouTube).
Dùng link thường, KHÔNG nhúng iframe (giữ trang nhẹ, không script bên thứ ba). -->
<p class="panel-link">
<a href="PLAYLIST_URL_HERE" target="_blank" rel="noopener noreferrer"
>Nghe thử playlist →</a
>
</p>
</article>
<!-- OWNER — "chi tiết cụ thể" beat: một chi tiết THẬT, cụ thể sẽ đáng nhớ hơn
mấy dòng chung chung (một buổi Thứ Bảy điển hình, món anh hay nấu, tuyến đi
bộ quen). Viết bằng giọng của anh rồi bỏ comment khối dưới. Giữ data-reveal
để nó hiện đúng theo cả ba tầng chuyển động.
<article class="panel" data-reveal>
<h3>[Tiêu đề: một chi tiết cụ thể]</h3>
<p>[Kể một điều thật, cụ thể — ví dụ Thứ Bảy của anh thường trôi qua thế nào,
hoặc món anh nấu ngon nhất.]</p>
</article>
-->
</div>
</section>
<!-- ============ Cảnh 3 · Thành thật từ đầu ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="honest"
aria-labelledby="honest-title"
data-scene
data-reveal-group
>
<div data-reveal>
<p class="chapter-tag">Cảnh 3 · Thành thật từ đầu</p>
<p class="eyebrow">Nói thẳng</p>
<h2 id="honest-title">Nói thẳng, để đỡ mất công đoán.</h2>
</div>
<div class="panel-list">
<article class="panel" data-reveal>
<h3>Sống đơn giản</h3>
<p>
Gia cảnh bình thường, lối sống tiết kiệm, không chạy theo hào nhoáng. Không thuốc
lá, thi thoảng rượu bia cho đúng thủ tục xã giao. Và xin nói trước: không thích thú
cưng.
</p>
</article>
<article class="panel" data-reveal>
<h3>Nghiêm túc với chuyện lâu dài</h3>
<p>
Từng trải qua một mối tình hơn 3 năm, chia tay cũng đã hơn 3 năm — đủ lâu để lành và
sẵn sàng cho một mối quan hệ mới. Chưa lập gia đình, chưa có con.
</p>
</article>
<article class="panel" data-reveal>
<h3>Thành thật đến cùng</h3>
<p>
Rất thích quan điểm của Phật giáo nhưng chưa/không quy y. Sống hơi tâm linh, và
cũng hơi… tà răm — fetish là chân 🌚. 162cm là số đo thật, không cộng dép.
</p>
</article>
<!-- OWNER — beat "thành thật đến tận cùng": mấy dòng trên đều là khuyết điểm dễ
thương. Một điều thật lòng, KHÔNG dễ thương (một nỗi sợ, một điều còn đang cố
sửa) sẽ khiến trang này khác hẳn kiểu diễn. Viết bằng giọng của anh rồi bỏ
comment. Giữ data-reveal để hiện đúng theo cả ba tầng chuyển động.
<article class="panel" data-reveal>
<h3>[Một điều thật lòng, không tô vẽ]</h3>
<p>[Một câu thành thật anh thấy hơi khó nói — điều anh đang cố hoàn thiện.]</p>
</article>
-->
</div>
</section>
<!-- ============ Cảnh 4 · Lời mời ============ -->
<section
class="site-shell page-section film-scene"
id="offer"
aria-labelledby="offer-title"
data-scene
data-reveal-group
>
<p class="chapter-tag" data-reveal>Cảnh 4 · Lời mời</p>
<p class="eyebrow" data-reveal>Gửi người sẽ đến</p>
<h2 class="page-title" id="offer-title" data-reveal>Điều mình có thể trao đi.</h2>
<p class="lead" data-reveal>
Mình không có gì to tát để hứa. Chủ yếu là sự chú ý, lòng chung thủy, những bữa ăn
chung, chuyện cười riêng, và một người biết thử lại sau sai lầm.
</p>
<!-- An unhurried list rather than a numbered package: scene 4 still needs a
shape of its own next to scenes 5 and 6, but the numbering and the table
rules read as a compensation schedule. Copy unchanged. -->
<ul class="gift-list">
<li data-reveal>
Ưu tiên hỗ trợ trong những ngày khó, ý tưởng lạ, và các buổi tối yên tĩnh.
</li>
<li data-reveal>Sự thành thật đều đặn, giao tiếp rõ ràng, và báo lỗi không đổ lỗi.</li>
<li data-reveal>
Một người có thể gỡ lỗi hệ thống đang vận hành và cũng nghĩ hơi nhiều chuyện ăn gì tối
nay.
</li>
<li data-reveal>
Đường dài phía trước: khỏe hơn, đi nhiều hơn, và có nhiều câu chuyện hơn.
</li>
</ul>
</section>
<!-- ============ Cảnh 5 · Điều cả hai cùng giữ ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="shared"
aria-labelledby="shared-title"
data-scene
data-reveal-group
>
<div data-reveal>
<p class="chapter-tag">Cảnh 5 · Điều cả hai cùng giữ</p>
<p class="eyebrow">Lời hứa nhỏ</p>
<h2 id="shared-title">Điều cả hai cùng bảo vệ.</h2>
</div>
<!-- Unboxed on purpose. As four large serif lines, each arriving as its
own beat, these read as a vow; inside the same rose-bordered
rectangle as every other scene they read as an HR policy. Copy
unchanged — only the container and the beat granularity differ. -->
<ul class="vow-list">
<li data-reveal>Xây niềm tin bằng lời nói thẳng thắn và những hành động nhỏ lặp lại.</li>
<li data-reveal>
Tôn trọng thời gian riêng, tham vọng nghề nghiệp, gia đình, bạn bè, và các nghi thức cá
nhân.
</li>
<li data-reveal>Mang theo sự tò mò, lòng tử tế, và thiện chí sửa chữa sau mâu thuẫn.</li>
<li data-reveal>Cùng duy trì một đời sống nơi cả hai được nghiêm túc và ngớ ngẩn đúng lúc.</li>
</ul>
</section>
<!-- ============ Cảnh 6 · Không có bài kiểm tra nào cả (điểm cộng + cao trào) ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="no-test"
aria-labelledby="no-test-title"
data-scene
data-reveal-group
>
<div data-reveal>
<p class="chapter-tag">Cảnh 6 · Không có bài kiểm tra nào cả</p>
<p class="eyebrow">Điểm cộng</p>
<h2 id="no-test-title">Điểm cộng thì vui, không có cũng chẳng sao.</h2>
</div>
<div class="panel-list">
<article class="panel" data-reveal>
<ul>
<li>
Thích đồ ăn, đi bộ, trò chơi, phim, hoặc học những thứ lạ không vì hạn chót nào
cả.
</li>
<li>
Có thể cười với những trò đùa nhảm, mà không biến tình cảm thành một bản
kế hoạch có hạn chót.
</li>
<li>Tin rằng tình cảm chạy tốt hơn nhờ kiên nhẫn, không phải trò đoán ý.</li>
<!-- Zodiac emoji carry meaning here, so they are labelled in Vietnamese;
unlabelled, a screen reader announces eight English emoji names
in the middle of a Vietnamese sentence. -->
<li>
Về tử vi: tuổi <span role="img" aria-label="Mão">🐈</span> này hợp các tuổi
<span role="img" aria-label="Thân">🐒</span>
<span role="img" aria-label="Dần">🐅</span>
<span role="img" aria-label="Tỵ">🐍</span>
<span role="img" aria-label="Ngọ">🐎</span>
<span role="img" aria-label="Hợi">🐖</span> hoặc
<span role="img" aria-label="Thìn">🐉</span>
<span role="img" aria-label="Tuất">🐕</span> — nhưng hợp sóng vẫn hơn hợp tuổi.
</li>
</ul>
</article>
<!-- The written climax of the page. Deliberately the quietest block in
the layout — no accent border, no halo, centred and given room —
so the calmest thing on screen is also the most important. -->
<article class="panel quiet" data-reveal>
<h3>Thật lòng mà nói</h3>
<p>
Không có bài kiểm tra nào cả. Không có vòng loại nào hết. Người mình mong gặp là
người vẫn tử tế khi mệt, nói thẳng khi rối, và sẵn sàng chọn nhau trong những
khoảnh khắc nhỏ rất đời thường.
</p>
</article>
</div>
</section>
<!-- ============ Cảnh 7 · Lời kết ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="closing"
aria-labelledby="closing-title"
data-scene
data-scene-pin
data-reveal-group
>
<div data-reveal="soft">
<p class="chapter-tag">Cảnh 7 · Lời kết</p>
<!-- The .eyebrow here read "Lời kết", repeating the chapter tag directly
above it verbatim. Removed rather than demoted; every other scene
keeps its eyebrow. -->
<h2 id="closing-title">Kết nối để tìm hiểu thêm nhé.</h2>
</div>
<article class="panel strong" data-reveal="soft">
<p>
Cảm ơn vì đã đến. Thước phim chỉ kể được một phần thôi — nếu thấy có chút hợp sóng, cứ
kết nối để mình tìm hiểu nhau thêm nhé.
</p>
<!-- OWNER: thay YOUR_HANDLE bằng tên tài khoản Facebook / Instagram thật của anh
(ví dụ facebook.com/tien.nguyen). Đây là cánh cửa để nhắn cho anh của cả trang. -->
<div class="button-row">
<a
class="button"
href="https://www.facebook.com/YOUR_HANDLE"
target="_blank"
rel="noopener noreferrer"
>Nhắn qua Facebook</a
>
<a
class="button secondary"
href="https://www.instagram.com/YOUR_HANDLE"
target="_blank"
rel="noopener noreferrer"
>Theo dõi Instagram</a
>
</div>
</article>
</section>
<!-- ============ Phụ lục · Vài điều cụ thể (credits roll) ============ -->
<section
class="site-shell page-section section-grid film-scene"
id="dossier"
aria-labelledby="dossier-title"
data-scene
data-reveal-group
>
<div data-reveal>
<p class="chapter-tag">Phụ lục · Vài điều cụ thể</p>
<p class="eyebrow">Thông tin nhanh</p>
<h2 id="dossier-title">Để đỡ mất công đoán.</h2>
</div>
<dl class="facts-list" data-reveal>
<div>
<dt>Tuổi</dt>
<dd>26 — sinh năm 1999, tuổi con 🐈</dd>
</div>
<div>
<dt>Tìm kiếm</dt>
<dd>Mối quan hệ lâu dài</dd>
</div>
<div>
<dt>Khu vực hẹn hò</dt>
<dd>TPHCM hoặc Long An cũ</dd>
</div>
<div>
<dt>Giới tính</dt>
<dd>Nam</dd>
</div>
<div>
<dt>Chiều cao</dt>
<dd>162cm — số đo thật, không cộng dép</dd>
</div>
<div>
<dt>Cân nặng</dt>
<dd>65kg, hơi béo — đang "thử" giảm cân</dd>
</div>
<div>
<dt>Quê quán</dt>
<dd>Long An cũ, nay là Tây Ninh</dd>
</div>
<div>
<dt>Đang ở</dt>
<dd>Đi làm và thuê trọ tại Quận 7</dd>
</div>
<div>
<dt>Ngôn ngữ</dt>
<dd>Tiếng Việt (tất nhiên) và một chút tiếng Anh</dd>
</div>
<div>
<dt>Học vấn</dt>
<dd>Bằng đại học — Đại học Bờ Kênh TPHCM</dd>
</div>
<div>
<dt>Công việc</dt>
<dd>Công nhân đánh máy thuê tại Xí nghiệp gêm Vê Nờ Gờ</dd>
</div>
<div>
<dt>Tình sử</dt>
<dd>Một mối tình hơn 3 năm; chia tay cũng đã hơn 3 năm, sẵn sàng cho mối quan hệ mới</dd>
</div>
<div>
<dt>Gia đình</dt>
<dd>Chưa lập gia đình, chưa có con</dd>
</div>
<div>
<dt>Thói quen</dt>
<dd>Không thuốc lá, thi thoảng rượu bia</dd>
</div>
<div>
<dt>Đức tin</dt>
<dd>Rất thích quan điểm của Phật giáo nhưng chưa/không quy y</dd>
</div>
<div>
<dt>Thú cưng</dt>
<dd>Không thích — xin thành thật từ đầu</dd>
</div>
<div>
<dt>Tâm linh</dt>
<dd>Tuổi 🐈; tìm các tuổi 🐒 🐅 🐍 🐎 🐖 hoặc 🐉 🐕</dd>
</div>
<div>
<dt>Góc riêng tư</dt>
<dd>Hơi… tà răm. Fetish là chân <span role="img" aria-label="mặt trăng quay lưng">🌚</span></dd>
</div>
</dl>
</section>
<!-- ============ Khung cuối · End card ============
The dossier is the longest block on the page and used to be the last
thing the reader saw, so the film ended on a reference table. This is
the last frame: it turns the dossier into a credits roll, gives the
freshness stamp a home outside the pinned #closing (where it shifted
layout after measurement), and repeats the apply door at the true
bottom, where the reader actually finishes. -->
<section class="site-shell page-section end-card film-scene" id="end" data-scene data-reveal-group>
<span class="brand-seal end-card__seal" aria-hidden="true">TN</span>
<!-- OWNER: một chữ duy nhất do máy thêm vào — đổi hoặc xoá tuỳ ý anh. -->
<p class="end-card__mark" data-reveal="soft">Hết.</p>
<div class="button-row" data-reveal="soft">
<a
class="button"
href="https://www.facebook.com/YOUR_HANDLE"
target="_blank"
rel="noopener noreferrer"
>Nhắn qua Facebook</a
>
</div>
<!-- Dấu "còn mở tính đến [ngày]" — assets/freshness-stamp.js tự điền theo ngày
commit mới nhất trên GitHub và bỏ ẩn khi thành công; nếu lỗi/offline thì để ẩn. -->
<p class="freshness-stamp" data-freshness hidden></p>
</section>
</main>
</body>
</html>