sqzass.git

sqzass

~ A static site generator written in Rust
git clone https://github.com/debuman/sqzass.git
commit a223a19c857b853301b388d2d8b8a0d07a6816af
parent fa79d021fec6ababd54fd1eb4e820fdca1857748
Author: sqzer <110329244+sqzer-x@users.noreply.github.com>
Date: Thu, 30 Jul 2026 23:03:31 +0900

랜딩을 브랜드대로 다시 세운다 — squeeze, 양테마, 글래스 내비, 벤토

sqzass는 squeeze+ass고 로고는 엉덩이를 쥔 손이다 — 심해·오징어로
읽은 2차안은 전제부터 틀렸다. 3차안은 이름을 그대로 디자인으로:
카피가 '쥐어짜다'를 말하고(A thousand pages, squeezed into 25 ms /
천 페이지를 25밀리초로 쥐어짭니다), 강조 줄은 스프링으로 옆에서
눌려 들어오고, 버튼과 타일은 누르면 움츠러들고, 히어로 뒤에는
말랑하게 뭉개지는 블롭이 있다. 팔레트는 피치/코랄 — docs 악센트와
같은 warm 계열.

구조도 사용자 요구대로 갈아엎었다: 고정 반투명(blur) 내비 + 테마
토글(라이트/다크, docs와 같은 data-theme·localStorage 키를 공유해
사이트 전체에서 선택이 따라다닌다), 섹션 나열 대신 벤토 그리드
(벤치 2×2·설치·0바이트·기능 3·데모), 터미널 세션 블록은 반려로
삭제. 레퍼런스(hwaro·gori)는 품질 기준으로만 쓰고 룩은 빌리지
않았다.

Diffstat:
Mdocs/content/_index.ko.md | 39+++++++++++++--------------------------
Mdocs/content/_index.md | 39+++++++++++++--------------------------
Mdocs/static/css/landing.css | 544++++++++++++++++++++++++++++++++++++-------------------------------------------
Mdocs/static/js/landing.js | 60++++++++++++++++++++++++++++++++++++------------------------
Mdocs/templates/landing.html | 264++++++++++++++++++++++++++++++-------------------------------------------------
5 files changed, 411 insertion(+), 535 deletion(-)

diff --git a/docs/content/_index.ko.md b/docs/content/_index.ko.md
@@ -6,25 +6,24 @@ template = "landing.html"
 
 [extra]
 hero_kicker = "Rust로 만든 정적 사이트 생성기"
-hero_title_a = "천 페이지,"
-hero_title_b = "25밀리초."
-hero_sub = "sqzass는 빠르고, 그걸 증명합니다: 생성기 다섯을 같은 머신, 같은 코퍼스로 재고 방법을 공개했습니다. 출력물은 어느 호스트에서든 그대로 동작합니다."
+hero_title_a = "천 페이지를"
+hero_title_b = "25밀리초로 쥐어짭니다."
+hero_sub = "이름이 곧 약속입니다: 사이트 하나를 한 번에 눌러 짜냅니다. Hugo·Zola·Jekyll·Astro와 같은 머신에서 재고, 방법을 전부 공개했습니다."
 cta_start = "시작하기"
 cta_github = "GitHub에서 보기"
 
+bento_label = "왜 sqzass인가"
+
 bench_title = "주장이 아니라 측정입니다"
-bench_note = "각 줄은 우리가 잰 네 생성기 중 가장 빠른 Hugo와 비교합니다 — 같은 머신, 콜드 빌드, 3회 중앙값. 막대는 줄 안에서 실척이고, sqzass 시간에는 검색 색인·sitemap·llms.txt 생성이 포함돼 있습니다."
-zero_label = "같은 입력을 두 번 빌드한 출력물의 바이트 차이 — CI가 push마다 다시 빌드해 비교합니다"
+bench_note = "우리가 잰 네 생성기 중 가장 빠른 Hugo와 비교합니다 — 같은 머신, 콜드 빌드, 3회 중앙값. 막대는 실척이고, sqzass 시간에는 검색 색인·sitemap·llms.txt 생성이 포함돼 있습니다."
 bench_more = "전체 수치와 방법론 →"
+zero_label = "같은 입력을 두 번 빌드한 출력물의 바이트 차이 — CI가 push마다 확인합니다"
 
-features_title = "기본으로 얻는 것"
-features_more = "나머지는 문서에 있습니다 →"
+install_title = "설치는 한 줄"
+install_alt = "Rust가 있다면:"
 
-quick_title = "빠른 시작"
-quick_install = "설치 — 어느 줄이든 한 줄로 끝납니다"
-quick_use = "사이트 만들기"
-quick_note = "스크립트는 플랫폼을 판별하고 체크섬을 검증하며, cargo 줄은 소스에서 빌드합니다. 다른 방법은"
-quick_note_link = "설치 안내에 있습니다."
+demo_title = "문서가 곧 데모"
+demo_body = "이 사이트도 저장소의 docs/를 sqzass가 빌드한 것입니다 — 모든 페이지, 두 언어, 검색 색인과 피드까지요."
 
 foot_benchmark = "벤치마크"
 built_line = "이 사이트도 sqzass가 빌드했습니다 — 문서가 곧 데모입니다."
@@ -51,25 +50,13 @@ them_ms = "5,912"
 them_w = "100%"
 
 [[extra.features]]
-title = "결정적 빌드"
-body = "같은 입력은 스레드 수와 무관하게 같은 바이트를 냅니다. 렌더는 병렬이고, 결정성은 병합이 지킵니다."
+title = "한국어가 1급입니다"
+body = "영어와 한국어 페이지가 파일명으로 짝을 이루고, 링크는 언어별로 해석되며, 검색은 부분 문자열로 찾습니다 — 검색엔진최적화 안의 최적화가 걸리는 유일한 방법입니다."
 
 [[extra.features]]
 title = "깨진 참조는 빌드를 멈춥니다"
 body = "죽은 링크, 없는 템플릿, front matter 오타 — 전부 안정적인 식별자와 exit code를 가진 에러입니다. 스크롤로 지나치는 경고가 아닙니다."
 
-[[extra.features]]
-title = "하이라이팅은 빌드 타임에"
-body = "구문 강조는 인라인 style이 아니라 CSS 클래스를 냅니다 — 다크 모드가 싸게 유지되고, 엄격한 CSP도 가능합니다."
-
-[[extra.features]]
-title = "한국어를 읽는 검색"
-body = "단어 색인 대신 부분 문자열 색인입니다. 조사와 합성어는 형태소 분석기를 이기기 때문이고, 2,000페이지 코퍼스 실측으로 고른 결정입니다."
-
-[[extra.features]]
-title = "두 언어를 나란히"
-body = "영어와 한국어 페이지가 파일명으로 짝을 이룹니다. 링크는 언어별로 해석되고, 미번역 페이지는 죽은 링크를 남기지 않습니다."
-
 [[extra.features]]
 title = "작은 바이너리 하나"
 body = "7.3 MB 정적 바이너리에 라이브 리로드 개발 서버까지 들어 있습니다. 설치할 런타임도, 버전 맞출 플러그인도 없습니다."
diff --git a/docs/content/_index.md b/docs/content/_index.md
@@ -6,25 +6,24 @@ template = "landing.html"
 
 [extra]
 hero_kicker = "A static site generator, written in Rust"
-hero_title_a = "One thousand pages."
-hero_title_b = "Twenty-five milliseconds."
-hero_sub = "sqzass builds fast and proves it: five generators, one machine, one corpus, method published. The output is correct on any host."
+hero_title_a = "A thousand pages,"
+hero_title_b = "squeezed into 25 ms."
+hero_sub = "The name is the promise: press a whole site out in one go. Measured against Hugo, Zola, Jekyll and Astro on the same machine, with the method published."
 cta_start = "Get started"
 cta_github = "View on GitHub"
 
+bento_label = "Why sqzass"
+
 bench_title = "Measured, not claimed"
-bench_note = "Each row compares sqzass with Hugo, the fastest of the four generators we measured — same machine, cold builds, median of three. Bars are to scale within each row, and the sqzass times include building the search index, sitemap and llms.txt."
-zero_label = "bytes of difference between two builds of the same input — rebuilt and diffed in CI on every push"
+bench_note = "vs Hugo, the fastest of the four we measured — same machine, cold builds, median of three. Bars are to scale, and the sqzass times include the search index, sitemap and llms.txt."
 bench_more = "Full numbers and methodology →"
+zero_label = "bytes of difference between two builds of the same input — checked in CI on every push"
 
-features_title = "What you get"
-features_more = "Everything else is in the documentation →"
+install_title = "Install in one line"
+install_alt = "With Rust instead:"
 
-quick_title = "Quick start"
-quick_install = "Install — either line works"
-quick_use = "Make a site"
-quick_note = "The script detects your platform and verifies checksums; the cargo line builds from source. More options are in"
-quick_note_link = "the install guide."
+demo_title = "The docs are the demo"
+demo_body = "This site is built by sqzass itself, from docs/ in the repository — every page, both languages, the search index and the feeds."
 
 foot_benchmark = "Benchmark"
 built_line = "This site is built by sqzass itself — the docs are the demo."
@@ -51,25 +50,13 @@ them_ms = "5,912"
 them_w = "100%"
 
 [[extra.features]]
-title = "Deterministic builds"
-body = "The same input produces the same bytes, on any thread count. Rendering is parallel; determinism comes from the merge."
+title = "Korean is first-class"
+body = "Pages pair by filename in English and Korean, links resolve per language, and search matches substrings — the only way 최적화 is ever found inside 검색엔진최적화."
 
 [[extra.features]]
 title = "Broken references stop the build"
 body = "A dead link, a missing template, a typo in front matter — each is an error with a stable identifier and exit code, not a warning you scroll past."
 
-[[extra.features]]
-title = "Highlighting at build time"
-body = "Syntax highlighting emits CSS classes, never inline styles — so dark mode stays cheap and a strict CSP stays possible."
-
-[[extra.features]]
-title = "Search that can read Korean"
-body = "A substring index instead of a word index, because particles and compounds defeat stemmers. Measured on a 2,000-page corpus before it was chosen."
-
-[[extra.features]]
-title = "Two languages, side by side"
-body = "English and Korean pages pair by filename. Links resolve per language, and an untranslated page never leaves a dead link behind."
-
 [[extra.features]]
 title = "One small binary"
 body = "A 7.3 MB static binary with a live-reload dev server built in. No runtime to install, no plugins to version."
diff --git a/docs/static/css/landing.css b/docs/static/css/landing.css
@@ -1,8 +1,8 @@
-/* 랜딩 전용 스타일. docs(main.css)와 의도적으로 독립.
-   콘셉트: 심해 발광 — sqzass 로고(오징어)에서 먹물·심해·생물발광으로.
-   칠흑 인디고 캔버스, 시안 발광 악센트, 먹물결 원판 아트, 앰비언트 별점.
-   테마는 다크 하나로 커밋한다([data-theme] 없음). 인라인 style 금지 —
-   장식은 전부 이 시트와 인라인 SVG의 표현 속성이 진다. */
+/* 랜딩 전용 스타일. docs(main.css)와 독립.
+   브랜드: sqzass = squeeze — 웜 피치/코랄, 눌리는(스퀴즈) 상호작용,
+   말랑한 블롭. 구조: 고정 글래스 내비 / 히어로 / 벤토 그리드 / 푸터.
+   테마: docs와 같은 [data-theme] 계약으로 라이트·다크 둘 다.
+   인라인 style 금지 — 장식은 이 시트와 SVG 표현 속성이 진다. */
 
 @font-face {
   font-family: "JetBrains Mono";
@@ -20,74 +20,65 @@
 }
 
 :root {
-  --abyss: #05070d;          /* 심연 */
-  --abyss-2: #090d18;        /* 한 층 위 */
-  --panel: rgba(148, 184, 255, 0.04);
-  --line: rgba(148, 184, 255, 0.12);
-  --line-2: rgba(148, 184, 255, 0.22);
-  --text: #e9eef7;
-  --muted: #93a0b6;
-  --glow: #59d8ff;           /* 발광 시안 */
-  --glow-deep: #2e63ff;      /* 심층 블루 */
-  --bar-other: #38445c;
+  /* 다크가 기본 — 템플릿이 data-theme="dark"를 쓴다 */
+  --bg: #141110;
+  --bg-hi: #1b1715;
+  --panel: rgba(255, 226, 205, 0.05);
+  --panel-hi: rgba(255, 226, 205, 0.09);
+  --line: rgba(255, 214, 189, 0.13);
+  --text: #f4eee7;
+  --muted: #a79c92;
+  --accent: #ffa171;      /* 피치 — 큰 요소·그래픽 */
+  --accent-ink: #ffb98f;  /* 본문 위 링크·강조 텍스트 */
+  --coral: #ff5e42;
+  --grad: linear-gradient(98deg, #ffc296 0%, #ff9d63 45%, #ff5e42 100%);
+  --bar-other: #4d4540;
+  --btn-ink: #2a1408;
+  --glass: rgba(20, 17, 16, 0.72);
+  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
   --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
           "Noto Sans KR", "Apple SD Gothic Neo", sans-serif;
   --mono: "JetBrains Mono", ui-monospace, "SF Mono", Consolas, monospace;
-  --wrap: 72rem;
+  --wrap: 71rem;
   color-scheme: dark;
 }
+:root[data-theme="light"] {
+  --bg: #faf5ef;
+  --bg-hi: #ffffff;
+  --panel: rgba(255, 255, 255, 0.65);
+  --panel-hi: rgba(255, 255, 255, 0.95);
+  --line: rgba(84, 48, 24, 0.14);
+  --text: #261c15;
+  --muted: #75665b;
+  --accent: #e86a30;
+  --accent-ink: #c2440f;
+  --coral: #e04022;
+  --grad: linear-gradient(98deg, #f2924e 0%, #e86a30 50%, #d43a1a 100%);
+  --bar-other: #d4c8bd;
+  --btn-ink: #ffffff;
+  --glass: rgba(250, 245, 239, 0.75);
+  --shadow: 0 18px 44px rgba(120, 70, 30, 0.14);
+  color-scheme: light;
+}
 
 * { box-sizing: border-box; }
 
 html { scroll-behavior: smooth; }
 
 body {
-  position: relative;
   margin: 0;
-  background: var(--abyss);
+  background: var(--bg);
   color: var(--text);
   font-family: var(--sans);
   font-size: 1.0625rem;
   line-height: 1.7;
   -webkit-text-size-adjust: 100%;
-  overflow-x: hidden;
+  overflow-x: clip;
 }
 
-/* 앰비언트: 발광 플랑크톤. box-shadow 점묘 두 겹 + 히어로 뒤 방사 광. */
-body::before {
-  content: "";
-  position: absolute;
-  inset: 0;
-  height: 220vh;
-  pointer-events: none;
-  background:
-    radial-gradient(52rem 36rem at 78% 22rem, rgba(46, 99, 255, 0.13), transparent 65%),
-    radial-gradient(40rem 30rem at 18% 8rem, rgba(89, 216, 255, 0.06), transparent 60%);
-}
-.specks, .specks::after {
-  content: "";
-  position: absolute;
-  inset: 0;
-  height: 220vh;
-  pointer-events: none;
-}
-.specks {
-  background-image:
-    radial-gradient(1.5px 1.5px at 12% 18%, rgba(143, 229, 255, 0.8), transparent 100%),
-    radial-gradient(1px 1px at 34% 9%, rgba(143, 229, 255, 0.5), transparent 100%),
-    radial-gradient(1.5px 1.5px at 58% 26%, rgba(201, 242, 255, 0.7), transparent 100%),
-    radial-gradient(1px 1px at 71% 7%, rgba(143, 229, 255, 0.55), transparent 100%),
-    radial-gradient(1px 1px at 88% 33%, rgba(143, 229, 255, 0.45), transparent 100%),
-    radial-gradient(1.5px 1.5px at 44% 41%, rgba(143, 229, 255, 0.35), transparent 100%),
-    radial-gradient(1px 1px at 8% 55%, rgba(143, 229, 255, 0.3), transparent 100%),
-    radial-gradient(1px 1px at 93% 62%, rgba(143, 229, 255, 0.35), transparent 100%),
-    radial-gradient(1.5px 1.5px at 26% 74%, rgba(143, 229, 255, 0.25), transparent 100%),
-    radial-gradient(1px 1px at 66% 87%, rgba(143, 229, 255, 0.3), transparent 100%);
-}
-
-a { color: var(--glow); text-decoration: none; }
+a { color: var(--accent-ink); text-decoration: none; }
 a:hover { text-decoration: underline; text-underline-offset: 3px; }
-:focus-visible { outline: 2px solid var(--glow); outline-offset: 3px; border-radius: 3px; }
+:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
 
 img { max-width: 100%; }
 
@@ -95,20 +86,28 @@ img { max-width: 100%; }
   position: absolute;
   left: -999px;
   top: 0;
-  background: var(--glow);
-  color: #04121a;
+  background: var(--coral);
+  color: #fff;
   padding: 0.5rem 1rem;
-  z-index: 10;
+  z-index: 30;
   font-weight: 700;
 }
 .skip:focus { left: 0.5rem; top: 0.5rem; }
 
-/* ── 상단 스트립 ── */
-.topbar {
-  position: relative;
+/* ── 고정 글래스 내비 ── */
+.nav {
+  position: fixed;
+  inset: 0 0 auto 0;
+  z-index: 20;
+  background: var(--glass);
+  -webkit-backdrop-filter: blur(14px) saturate(1.5);
+  backdrop-filter: blur(14px) saturate(1.5);
+  border-bottom: 1px solid var(--line);
+}
+.nav-in {
   max-width: var(--wrap);
   margin: 0 auto;
-  padding: 1.15rem clamp(1.25rem, 4vw, 2.5rem);
+  padding: 0.72rem clamp(1.25rem, 4vw, 2.5rem);
   display: flex;
   align-items: center;
   justify-content: space-between;
@@ -117,86 +116,109 @@ img { max-width: 100%; }
 .mark {
   display: inline-flex;
   align-items: center;
-  gap: 0.6rem;
+  gap: 0.55rem;
   color: var(--text);
-  font-weight: 700;
-  font-size: 1.08rem;
-  letter-spacing: 0.01em;
+  font-weight: 800;
+  font-size: 1.06rem;
 }
 .mark:hover { text-decoration: none; }
-.mark img { width: 27px; height: 27px; filter: invert(1); }
-.topnav {
+.mark img { width: 26px; height: 26px; }
+:root[data-theme="dark"] .mark img { filter: invert(1); }
+.nav-links {
   display: flex;
   align-items: center;
-  gap: 1.35rem;
+  gap: 1.2rem;
   font-size: 0.93rem;
-  font-weight: 500;
+  font-weight: 600;
 }
-.topnav > a { color: var(--muted); }
-.topnav > a:hover { color: var(--text); text-decoration: none; }
-.langs {
+.nav-links > a { color: var(--muted); }
+.nav-links > a:hover { color: var(--text); text-decoration: none; }
+.nav-icon {
   display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 2.1rem;
+  height: 2.1rem;
   border: 1px solid var(--line);
-  border-radius: 999px;
-  overflow: hidden;
-}
-.lang-pill {
-  padding: 0.22rem 0.7rem;
-  font-family: var(--mono);
-  font-size: 0.72rem;
-  font-weight: 700;
+  border-radius: 9px;
+  background: transparent;
   color: var(--muted);
+  cursor: pointer;
+  padding: 0;
 }
-.lang-pill:hover { color: var(--text); background: var(--panel); text-decoration: none; }
-.gh { color: var(--muted); display: inline-flex; }
-.gh:hover { color: var(--text); }
+.nav-icon:hover { color: var(--text); border-color: var(--accent); }
+:root[data-theme="dark"] .theme-toggle .i-moon { display: none; }
+:root[data-theme="light"] .theme-toggle .i-sun { display: none; }
 
-main { position: relative; display: block; }
+main { display: block; }
 
-section, .foot { padding-inline: clamp(1.25rem, 4vw, 2.5rem); }
-.inner { max-width: var(--wrap); margin: 0 auto; }
+.inner { max-width: var(--wrap); margin: 0 auto; padding-inline: clamp(1.25rem, 4vw, 2.5rem); }
 
-/* ── 히어로 ── */
-.hero { padding-block: clamp(4rem, 9vw, 7rem) clamp(3.5rem, 7vw, 5.5rem); }
-.hero-grid {
-  display: grid;
-  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
-  align-items: center;
-  gap: clamp(2rem, 5vw, 4.5rem);
+/* ── 히어로: 말랑한 블롭 하나가 뒤를 받친다 ── */
+.hero {
+  position: relative;
+  padding-block: clamp(8rem, 16vw, 11.5rem) clamp(2.5rem, 5vw, 4rem);
+  overflow: clip;
+}
+.blob {
+  position: absolute;
+  top: clamp(2rem, 6vw, 5rem);
+  right: -12rem;
+  width: clamp(26rem, 46vw, 44rem);
+  aspect-ratio: 1;
+  background: var(--grad);
+  opacity: 0.24;
+  filter: blur(70px);
+  border-radius: 43% 57% 52% 48% / 55% 44% 56% 45%;
+  animation: squish 16s ease-in-out infinite;
+  pointer-events: none;
+}
+:root[data-theme="light"] .blob { opacity: 0.28; }
+@keyframes squish {
+  0%, 100% { border-radius: 43% 57% 52% 48% / 55% 44% 56% 45%; transform: scale(1); }
+  33%      { border-radius: 56% 44% 46% 54% / 46% 58% 42% 54%; transform: scale(1.06, 0.94); }
+  66%      { border-radius: 48% 52% 58% 42% / 52% 46% 54% 48%; transform: scale(0.95, 1.05); }
 }
+
+.hero .inner { position: relative; }
 .kicker {
-  margin: 0 0 1.3rem;
+  margin: 0 0 1.2rem;
   display: inline-flex;
   align-items: center;
-  gap: 0.5rem;
-  padding: 0.32rem 0.85rem;
-  border: 1px solid var(--line);
-  border-radius: 999px;
-  background: var(--panel);
-  color: var(--glow);
+  gap: 0.55rem;
+  color: var(--accent-ink);
   font-family: var(--mono);
-  font-size: 0.78rem;
+  font-size: 0.8rem;
   font-weight: 700;
 }
+.kicker::before {
+  content: "";
+  width: 1.5rem;
+  height: 3px;
+  border-radius: 2px;
+  background: var(--grad);
+}
 .display {
   margin: 0;
-  font-size: clamp(2.7rem, 5.6vw, 4.6rem);
-  line-height: 1.05;
+  font-size: clamp(2.8rem, 6.4vw, 5.2rem);
+  line-height: 1.03;
   font-weight: 800;
-  letter-spacing: -0.025em;
+  letter-spacing: -0.028em;
   text-wrap: balance;
 }
 .display em {
+  display: inline-block; /* 스퀴즈 스프링의 transform 대상 */
   font-style: normal;
-  background: linear-gradient(92deg, var(--glow) 10%, #7aa2ff 55%, var(--glow-deep) 100%);
+  background: var(--grad);
   -webkit-background-clip: text;
   background-clip: text;
   color: transparent;
+  transform-origin: left center;
 }
 .sub {
   margin: 1.5rem 0 0;
-  max-width: 44ch;
-  font-size: 1.13rem;
+  max-width: 52ch;
+  font-size: 1.14rem;
   line-height: 1.75;
   color: var(--muted);
   text-wrap: pretty;
@@ -205,243 +227,173 @@ section, .foot { padding-inline: clamp(1.25rem, 4vw, 2.5rem); }
 .btn {
   display: inline-flex;
   align-items: center;
-  min-height: 2.9rem;
-  padding: 0 1.45rem;
-  border-radius: 999px;
+  min-height: 2.95rem;
+  padding: 0 1.5rem;
+  border-radius: 14px;
   font-weight: 700;
-  font-size: 0.98rem;
-  transition: transform 0.16s ease, box-shadow 0.16s ease, background 0.16s ease,
-              border-color 0.16s ease;
+  font-size: 0.99rem;
+  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease;
   cursor: pointer;
 }
 .btn:hover { text-decoration: none; transform: translateY(-1px); }
+.btn:active { transform: scale(0.96); } /* 쥐어짜면 눌린다 */
 .btn-primary {
-  background: linear-gradient(120deg, #6fe0ff, #3d7bff);
-  color: #041220;
-  box-shadow: 0 0 24px rgba(89, 216, 255, 0.35), 0 1px 2px rgba(0, 0, 0, 0.5);
-}
-.btn-primary:hover { box-shadow: 0 0 34px rgba(89, 216, 255, 0.5), 0 2px 6px rgba(0, 0, 0, 0.5); }
-.btn-ghost {
-  color: var(--text);
-  border: 1px solid var(--line-2);
-  background: var(--panel);
+  background: var(--grad);
+  color: var(--btn-ink);
+  box-shadow: 0 6px 24px rgba(255, 110, 60, 0.35);
 }
-.btn-ghost:hover { border-color: var(--glow); }
+.btn-primary:hover { box-shadow: 0 8px 30px rgba(255, 110, 60, 0.48); }
+.btn-ghost { color: var(--text); border: 1px solid var(--line); background: var(--panel); }
+.btn-ghost:hover { border-color: var(--accent); }
 
-.install {
-  margin: 1.9rem 0 0;
-  display: inline-flex;
-  align-items: center;
-  gap: 0.4rem;
-  max-width: 100%;
-  border: 1px solid var(--line);
-  border-radius: 10px;
-  background: rgba(4, 8, 16, 0.8);
-  padding: 0.62rem 0.5rem 0.62rem 0.95rem;
-}
-.install code {
-  font-family: var(--mono);
-  font-size: 0.83rem;
-  color: #bfe9ff;
-  white-space: nowrap;
-  overflow-x: auto;
-  scrollbar-width: none;
-}
-.inst-copy {
-  flex: none;
-  display: inline-flex;
-  align-items: center;
-  justify-content: center;
-  width: 2rem;
-  height: 2rem;
-  border: 0;
-  border-radius: 7px;
-  background: transparent;
+.lede { margin-top: clamp(2.6rem, 5vw, 3.6rem); }
+.lede p {
+  max-width: 62ch;
+  margin: 0 0 1rem;
+  font-size: 1rem;
   color: var(--muted);
-  cursor: pointer;
-}
-.inst-copy:hover { color: var(--glow); background: var(--panel); }
-.inst-copy .i-check { display: none; }
-.inst-copy.is-done .i-copy { display: none; }
-.inst-copy.is-done .i-check { display: block; color: var(--glow); }
-
-.hero-art { display: flex; justify-content: center; min-width: 0; }
-.art {
-  width: min(100%, 30rem);
-  height: auto;
-  filter: drop-shadow(0 0 46px rgba(46, 99, 255, 0.28));
 }
 
-/* ── 포지셔닝 프로즈 ── */
-.intro { padding-block: 0 clamp(3rem, 6vw, 4.5rem); }
-.intro p {
-  max-width: 64ch;
-  margin: 0 0 1.1rem;
-  color: var(--muted);
-  font-size: 1.05rem;
+/* ── 벤토 ── */
+.bento-wrap { padding-block: clamp(2rem, 4vw, 3rem) clamp(4rem, 7vw, 6rem); }
+.bento {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  grid-auto-flow: dense;
+  gap: 0.9rem;
 }
+.tile {
+  border: 1px solid var(--line);
+  border-radius: 18px;
+  background: var(--panel);
+  padding: 1.5rem 1.6rem;
+  margin: 0;
+  transition: transform 0.16s ease, border-color 0.16s ease, background 0.16s ease;
+}
+.tile:hover {
+  transform: scale(0.988); /* 타일도 쥐면 눌린다 */
+  border-color: var(--accent);
+  background: var(--panel-hi);
+}
+.tile h2 { margin: 0 0 0.55rem; font-size: 1.08rem; font-weight: 800; letter-spacing: -0.01em; }
+/* keep-all은 CJK에만 작용한다 — 영문 페이지에 인용된 한국어 예시
+   (검색엔진최적화)가 단어 중간에서 꺾이지 않게 전역으로 준다. */
+.tile .note { margin: 0; font-size: 0.93rem; line-height: 1.65; color: var(--muted); word-break: keep-all; }
+.tile-link { margin: 1.1rem 0 0; font-weight: 700; font-size: 0.95rem; }
 
-/* ── 섹션 공통 ── */
-.band { border-top: 1px solid var(--line); padding-block: clamp(4rem, 8vw, 6.5rem); }
-.band h2 {
-  margin: 0 0 0.9rem;
-  font-size: clamp(1.7rem, 3.4vw, 2.3rem);
-  line-height: 1.15;
-  font-weight: 800;
-  letter-spacing: -0.02em;
-}
-.band-note { max-width: 62ch; margin: 0 0 2.2rem; color: var(--muted); font-size: 0.97rem; }
-.band-more { margin: 2.2rem 0 0; font-weight: 600; }
+.t-bench { grid-column: span 2; grid-row: span 2; }
+.t-install { grid-column: span 2; }
+.t-demo { grid-column: span 2; }
 
-/* ── 벤치마크 ── */
-.bench-card {
-  border: 1px solid var(--line);
-  border-radius: 14px;
-  background: linear-gradient(180deg, rgba(20, 34, 64, 0.35), rgba(9, 13, 24, 0.6));
-  padding: clamp(1.4rem, 3vw, 2.4rem);
-}
-.row { margin: 0 0 1.9rem; }
-.row h3 { margin: 0 0 0.55rem; font-size: 1rem; font-weight: 700; color: var(--text); }
+/* 벤치마크 타일 */
+.t-bench .note { margin-bottom: 1.4rem; }
+.row { margin: 0 0 1.25rem; }
+.row h3 { margin: 0 0 0.4rem; font-size: 0.94rem; font-weight: 700; }
 .meas {
   display: grid;
-  grid-template-columns: 5.2rem 1fr 7.5rem;
+  grid-template-columns: 4.6rem 1fr 6.8rem;
   align-items: center;
-  gap: 0.85rem;
-  margin: 0.4rem 0;
-}
-.who { font-size: 0.86rem; font-weight: 600; color: var(--muted); }
-.meas.us .who { color: var(--glow); }
-.track { width: 100%; height: 1.15rem; display: block; }
-.fill {
-  fill: var(--bar-other);
-  transform-box: fill-box;
-  transform-origin: left center;
-}
-.meas.us .fill { fill: var(--glow); }
-.meas.us .track { filter: drop-shadow(0 0 8px rgba(89, 216, 255, 0.55)); }
+  gap: 0.7rem;
+  margin: 0.3rem 0;
+}
+.who { font-size: 0.82rem; font-weight: 600; color: var(--muted); }
+.meas.us .who { color: var(--accent-ink); }
+.track { width: 100%; height: 1.05rem; display: block; }
+.fill { fill: var(--bar-other); transform-box: fill-box; transform-origin: left center; }
+.meas.us .fill { fill: var(--accent); }
 .val {
   font-family: var(--mono);
   font-variant-numeric: tabular-nums;
-  font-size: 0.95rem;
+  font-size: 0.9rem;
   font-weight: 700;
   color: var(--muted);
   white-space: nowrap;
 }
-.meas.us .val { color: var(--glow); }
-.zero {
-  margin: 2.4rem 0 0;
-  padding-top: 1.9rem;
-  border-top: 1px solid var(--line);
-  display: flex;
-  align-items: baseline;
-  gap: 1.1rem;
-  flex-wrap: wrap;
-}
+.meas.us .val { color: var(--accent-ink); }
+
+/* 0 바이트 타일 */
+.t-zero { display: flex; flex-direction: column; justify-content: center; gap: 0.5rem; }
 .zero-num {
+  margin: 0;
   font-family: var(--mono);
-  font-variant-numeric: tabular-nums;
-  font-size: clamp(3.2rem, 7vw, 5rem);
+  font-size: clamp(2.8rem, 5vw, 4rem);
   font-weight: 700;
   line-height: 1;
-  background: linear-gradient(180deg, var(--glow), var(--glow-deep));
+  background: var(--grad);
   -webkit-background-clip: text;
   background-clip: text;
   color: transparent;
 }
-.zero-label { max-width: 36ch; color: var(--muted); font-size: 0.95rem; line-height: 1.6; }
-
-/* ── 기능 카드 ── */
-.cards {
-  list-style: none;
-  margin: 2.2rem 0 0;
-  padding: 0;
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  gap: 1rem;
-}
-.card {
-  position: relative;
-  border: 1px solid var(--line);
-  border-radius: 12px;
-  background: var(--panel);
-  padding: 1.45rem 1.5rem;
-  transition: border-color 0.18s ease, transform 0.18s ease, background 0.18s ease;
-}
-.card:hover {
-  border-color: rgba(89, 216, 255, 0.45);
-  background: rgba(89, 216, 255, 0.05);
-  transform: translateY(-2px);
-}
-.card h3 { margin: 0 0 0.5rem; font-size: 1rem; font-weight: 700; }
-.card p { margin: 0; font-size: 0.92rem; line-height: 1.65; color: var(--muted); }
 
-/* ── 터미널 ── */
-.term {
+/* 설치 타일 */
+.install {
+  display: flex;
+  align-items: center;
+  gap: 0.3rem;
   border: 1px solid var(--line);
   border-radius: 12px;
-  background: #070b14;
-  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5), 0 0 40px rgba(46, 99, 255, 0.1);
-  overflow: hidden;
-  max-width: 46rem;
+  background: var(--bg-hi);
+  padding: 0.55rem 0.45rem 0.55rem 0.9rem;
+  margin: 0.2rem 0 0.9rem;
 }
-.term-bar {
-  display: flex;
-  gap: 0.45rem;
-  padding: 0.7rem 1rem;
-  border-bottom: 1px solid var(--line);
-  background: rgba(148, 184, 255, 0.03);
-}
-.term-bar i {
-  width: 0.68rem;
-  height: 0.68rem;
-  border-radius: 50%;
-  background: #2c3750;
-}
-.term pre {
-  margin: 0;
-  padding: 1.15rem 1.3rem 1.3rem;
-  overflow-x: auto;
+.install > code {
   font-family: var(--mono);
-  font-size: 0.84rem;
-  line-height: 1.85;
-  color: #d7e4f7;
+  font-size: 0.82rem;
+  color: var(--accent-ink);
+  white-space: nowrap;
+  overflow-x: auto;
+  scrollbar-width: none;
 }
-.t-p { color: var(--glow); font-weight: 700; }
-.t-o { color: #7d8ba3; }
-.quick-note { margin-top: 1.6rem; }
+.inline { font-family: var(--mono); font-size: 0.85em; color: var(--accent-ink); }
+.inst-copy {
+  flex: none;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 2rem;
+  height: 2rem;
+  border: 0;
+  border-radius: 8px;
+  background: transparent;
+  color: var(--muted);
+  cursor: pointer;
+}
+.inst-copy:hover { color: var(--accent-ink); background: var(--panel-hi); }
+.inst-copy:active { transform: scale(0.9); }
+.inst-copy .i-check { display: none; }
+.inst-copy.is-done .i-copy { display: none; }
+.inst-copy.is-done .i-check { display: block; color: var(--accent-ink); }
 
 /* ── 푸터 ── */
-.foot { border-top: 1px solid var(--line); padding-block: 2.6rem 3.4rem; }
-.foot .inner { display: grid; gap: 1.1rem; }
-.foot-nav { display: flex; flex-wrap: wrap; gap: 1.4rem; font-weight: 600; font-size: 0.93rem; }
+.foot { border-top: 1px solid var(--line); padding-block: 2.4rem 3.2rem; }
+.foot-in { display: grid; gap: 1rem; }
+.foot-nav { display: flex; flex-wrap: wrap; gap: 1.35rem; font-weight: 600; font-size: 0.92rem; }
 .foot-nav a { color: var(--muted); }
-.foot-nav a:hover { color: var(--glow); text-decoration: none; }
-.foot p { margin: 0; color: var(--muted); font-size: 0.9rem; max-width: 64ch; }
+.foot-nav a:hover { color: var(--accent-ink); text-decoration: none; }
+.foot p { margin: 0; color: var(--muted); font-size: 0.9rem; }
 
-/* ── 한국어: 자간·모노·대문자 장치를 한글에 적용하지 않는다.
-      kicker는 모노를 유지해도 되는 게 아니다 — 한글이 폴백 폰트로 가며
-      공백만 모노 폭이 되는 함정(main.css의 결정과 동일). ── */
+/* ── 한국어: 자간·모노·대문자 장치를 한글에 적용하지 않는다 ── */
 html[lang="ko"] .display { letter-spacing: 0; }
-html[lang="ko"] .band h2 { letter-spacing: 0; }
-html[lang="ko"] .kicker { font-family: var(--sans); font-size: 0.83rem; letter-spacing: 0; }
+html[lang="ko"] .kicker { font-family: var(--sans); font-size: 0.85rem; }
 html[lang="ko"] h1, html[lang="ko"] h2, html[lang="ko"] h3 { word-break: keep-all; }
-html[lang="ko"] .sub, html[lang="ko"] .zero-label, html[lang="ko"] .band-note { word-break: keep-all; }
+html[lang="ko"] .sub, html[lang="ko"] .note { word-break: keep-all; }
 
 /* ── 반응형 ── */
-@media (max-width: 64rem) {
-  .hero-grid { grid-template-columns: 1fr; }
-  .hero-art { order: -1; }
-  .art { width: min(70vw, 21rem); }
-  .cards { grid-template-columns: 1fr 1fr; }
-  .topnav > a:first-child { display: none; }
-}
-@media (max-width: 44rem) {
-  .cards { grid-template-columns: 1fr; }
-  .meas { grid-template-columns: 4rem 1fr 6rem; gap: 0.6rem; }
-  .display { font-size: clamp(2.3rem, 10vw, 2.9rem); }
+@media (max-width: 62rem) {
+  .bento { grid-template-columns: repeat(2, 1fr); }
+  .t-bench { grid-column: span 2; }
+  .nav-links > a:first-child { display: none; }
+}
+@media (max-width: 42rem) {
+  .bento { grid-template-columns: 1fr; }
+  .t-bench, .t-install, .t-demo { grid-column: span 1; }
+  .meas { grid-template-columns: 3.9rem 1fr 6rem; gap: 0.5rem; }
+  .display { font-size: clamp(2.3rem, 11vw, 3rem); }
+  .blob { right: -16rem; opacity: 0.18; }
 }
 
 @media (prefers-reduced-motion: reduce) {
   html { scroll-behavior: auto; }
-  .btn, .card { transition: none; }
+  .btn, .tile, .inst-copy { transition: none; }
+  .blob { animation: none; }
 }
diff --git a/docs/static/js/landing.js b/docs/static/js/landing.js
@@ -1,15 +1,26 @@
-/* 랜딩 연출·복사 버튼. 전부 점진적 향상이다 — Motion이 없거나
-   reduced-motion이면 연출은 생략되고, 페이지는 CSS만으로 완성 상태다. */
+/* 랜딩: 테마 토글·복사 버튼·연출. 연출은 전부 점진적 향상 — Motion이 없거나
+   reduced-motion이면 생략되고, 페이지는 CSS만으로 완성 상태다. */
 (function () {
   "use strict";
 
-  /* 설치 한 줄 복사. 연출과 무관하므로 reduced-motion과 상관없이 동작한다. */
+  /* 테마 토글. docs와 같은 localStorage 키("theme")를 쓰므로 사이트 전체에서
+     선택이 따라다닌다. */
+  var toggle = document.querySelector(".theme-toggle");
+  if (toggle) {
+    toggle.addEventListener("click", function () {
+      var root = document.documentElement;
+      var next = root.dataset.theme === "dark" ? "light" : "dark";
+      root.dataset.theme = next;
+      try { localStorage.setItem("theme", next); } catch (e) {}
+    });
+  }
+
+  /* 설치 한 줄 복사 */
   document.querySelectorAll(".inst-copy").forEach(function (btn) {
     var label = btn.getAttribute("aria-label");
     btn.addEventListener("click", function () {
-      var text = btn.getAttribute("data-copy-text") || "";
       if (!navigator.clipboard) return;
-      navigator.clipboard.writeText(text).then(function () {
+      navigator.clipboard.writeText(btn.getAttribute("data-copy-text") || "").then(function () {
         btn.classList.add("is-done");
         btn.setAttribute("aria-label", btn.getAttribute("data-copied"));
         setTimeout(function () {
@@ -26,44 +37,45 @@
 
   var EASE = [0.16, 1, 0.3, 1];
 
-  /* 히어로: 로드 시퀀스. 위에서 아래로 한 호흡씩. */
+  /* 히어로 로드 시퀀스 */
   var heroEls = document.querySelectorAll(".hero [data-reveal]");
   heroEls.forEach(function (el) { el.style.opacity = "0"; });
   M.animate(
     heroEls,
     { opacity: [0, 1], transform: ["translateY(16px)", "none"] },
-    { duration: 0.65, ease: EASE, delay: M.stagger(0.09) }
+    { duration: 0.6, ease: EASE, delay: M.stagger(0.08) }
   );
 
-  /* 아트워크: 등장 후 느린 부유. 물속이라는 뜻이지 장식 경련이 아니다. */
-  var art = document.querySelector("[data-float]");
-  if (art) {
-    M.animate(art, { opacity: [0, 1], transform: ["scale(0.96)", "scale(1)"] },
-      { duration: 1.1, ease: EASE });
-    M.animate(art,
-      { transform: ["translateY(0)", "translateY(-12px)", "translateY(0)"] },
-      { duration: 9, repeat: Infinity, ease: [0.45, 0, 0.55, 1], delay: 1.1 });
+  /* 이름값 하는 연출: 강조 줄이 옆으로 눌려 들어온다(squeeze). 스프링이
+     안 되는 빌드면 조용히 생략 — 등장 자체는 위 시퀀스가 이미 보장한다. */
+  var em = document.querySelector("[data-squeeze]");
+  if (em) {
+    try {
+      M.animate(
+        em,
+        { transform: ["scaleX(1.35)", "scaleX(1)"] },
+        { type: "spring", stiffness: 170, damping: 15, delay: 0.35 }
+      );
+    } catch (e) {}
   }
 
-  /* 나머지 섹션: 뷰포트에 들어올 때 한 번씩. */
-  var rest = document.querySelectorAll("main > :not(.hero) [data-reveal]");
-  rest.forEach(function (el) {
+  /* 벤토 타일: 뷰포트에 들어올 때 한 번씩 */
+  document.querySelectorAll(".bento-wrap [data-reveal], .foot [data-reveal]").forEach(function (el) {
     el.style.opacity = "0";
     M.inView(
       el,
       function () {
         M.animate(
           el,
-          { opacity: [0, 1], transform: ["translateY(16px)", "none"] },
-          { duration: 0.55, ease: EASE }
+          { opacity: [0, 1], transform: ["translateY(14px)", "none"] },
+          { duration: 0.5, ease: EASE }
         );
       },
-      { amount: 0.25 }
+      { amount: 0.2 }
     );
   });
 
-  /* 벤치마크 막대: 실척 폭은 SVG 속성이 이미 갖고 있고, 여기서는 왼쪽에서
-     자라는 등장만 준다. 값이 아니라 등장이 연출이다. */
+  /* 벤치 막대: 왼쪽에서 자라는 등장. 실척 폭은 SVG 속성이 이미 갖고 있다. */
   document.querySelectorAll(".row").forEach(function (row) {
     var bars = row.querySelectorAll("[data-bar]");
     bars.forEach(function (b) { b.style.transform = "scaleX(0)"; });
@@ -73,7 +85,7 @@
         M.animate(
           bars,
           { transform: ["scaleX(0)", "scaleX(1)"] },
-          { duration: 0.85, ease: EASE, delay: M.stagger(0.12) }
+          { duration: 0.8, ease: EASE, delay: M.stagger(0.1) }
         );
       },
       { amount: 0.5 }
diff --git a/docs/templates/landing.html b/docs/templates/landing.html
@@ -1,13 +1,14 @@
-{#- 랜딩. base.html을 상속하지 않는 완전 독립 문서다 — 문서 크롬(마스트헤드·
-    사이드바·검색·테마 토글)이 전부 없다. 테마는 다크 하나로 커밋한다: 심해
-    발광 콘셉트(오징어 로고 → 먹물 → 심해)의 페이지라 밝은 변형이 없다.
-    카피는 전부 front matter의 extra에 있고(양어 파일이 키를 1:1로 가진다),
-    이 파일은 구조만 안다. 아트워크는 손으로 쓴 인라인 SVG — 외부 이미지도,
-    인라인 style도 없다. #}
+{#- 랜딩. base.html을 상속하지 않는 독립 문서다 — 문서 크롬 없이 자체 구조를
+    가진다: 고정 반투명 내비 / 히어로 / 벤토 그리드 / 푸터.
+    브랜드는 이름 그대로 squeeze — 카피와 연출이 "쥐어짜기"를 말한다.
+    테마는 docs와 같은 계약: data-theme을 템플릿이 쓰고, localStorage("theme",
+    docs와 같은 키)가 프리페인트 스크립트로 덮는다. 그래서 문서에서 고른 테마가
+    랜딩에도 그대로 따라온다. 카피는 전부 extra에 있고(양어 키 1:1), 이 파일은
+    구조만 안다. #}
 {%- set ko = page.language == "ko" %}
 {%- set home = site.base_path ~ ("/ko/" if ko else "/") %}
 <!doctype html>
-<html lang="{{ page.language }}">
+<html lang="{{ page.language }}" data-theme="dark">
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
@@ -31,189 +32,126 @@
 <meta property="og:description" content="{{ page.description }}">
 <meta name="twitter:card" content="summary">
 <link rel="stylesheet" href="{{ asset("css/landing.css") }}">
+<script>
+/* 첫 페인트 전에 저장된 테마를 얹는다. base.html과 같은 키·같은 이유. */
+(function(){try{var t=localStorage.getItem("theme");if(t)document.documentElement.dataset.theme=t}catch(e){}})();
+</script>
 <script src="{{ asset("js/motion.js") }}" defer></script>
 <script src="{{ asset("js/landing.js") }}" defer></script>
 </head>
 <body>
-<div class="specks" aria-hidden="true"></div>
 <a class="skip" href="#main">{{ t("skip_to_content") }}</a>
 
-<header class="topbar">
-  <a class="mark" href="{{ home }}">
-    <img src="{{ asset("images/logo.png") }}" alt="" width="121" height="120">
-    <span>{{ site.title }}</span>
-  </a>
-  <nav class="topnav">
-    <a href="{{ home }}start/">{{ t("documentation") }}</a>
-    <a href="{{ home }}benchmark/">{{ page.extra.foot_benchmark }}</a>
-    <span class="langs">
-    {%- for lang in page.translations %}
-      <a class="lang-pill" href="{{ lang.url }}" hreflang="{{ lang.code }}">{{ lang.code | upper }}</a>
-    {%- endfor %}
-    </span>
-    <a class="gh" href="https://github.com/sqzer-x/sqzass" aria-label="GitHub" title="GitHub">
-      <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" focusable="false"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
+<header class="nav">
+  <div class="nav-in">
+    <a class="mark" href="{{ home }}">
+      <img src="{{ asset("images/logo.png") }}" alt="" width="121" height="120">
+      <span>{{ site.title }}</span>
     </a>
-  </nav>
+    <nav class="nav-links">
+      <a href="{{ home }}start/">{{ t("documentation") }}</a>
+      <a href="{{ home }}benchmark/">{{ page.extra.foot_benchmark }}</a>
+      {%- for lang in page.translations %}
+      <a href="{{ lang.url }}" hreflang="{{ lang.code }}">{{ lang.name }}</a>
+      {%- endfor %}
+      <a class="nav-icon" href="https://github.com/sqzer-x/sqzass" aria-label="GitHub" title="GitHub">
+        <svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true" focusable="false"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
+      </a>
+      <button class="nav-icon theme-toggle" type="button" aria-label="{{ t("theme") }}" title="{{ t("theme") }}">
+        <svg class="i-sun" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
+          <circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/>
+        </svg>
+        <svg class="i-moon" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+          <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/>
+        </svg>
+      </button>
+    </nav>
+  </div>
 </header>
 
 <main id="main">
   <section class="hero">
-    <div class="inner hero-grid">
-      <div class="hero-copy">
-        <p class="kicker" data-reveal>
-          <svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 3 14h7l-1 8 10-12h-7l1-8z"/></svg>
-          {{ page.extra.hero_kicker }}
-        </p>
-        <h1 class="display" data-reveal>{{ page.extra.hero_title_a }}<br><em>{{ page.extra.hero_title_b }}</em></h1>
-        <p class="sub" data-reveal>{{ page.extra.hero_sub }}</p>
-        <p class="cta" data-reveal>
-          <a class="btn btn-primary" href="{{ home }}start/">{{ page.extra.cta_start }}</a>
-          <a class="btn btn-ghost" href="https://github.com/sqzer-x/sqzass">{{ page.extra.cta_github }}</a>
-        </p>
-        <div class="install" data-reveal>
-          <code>$ curl -fsSL {{ site.origin }}{{ site.base_path }}/install.sh | sh</code>
-          <button class="inst-copy" type="button" data-copy-text="curl -fsSL {{ site.origin }}{{ site.base_path }}/install.sh | sh"
-                  aria-label="{{ t("copy") }}" data-copied="{{ t("copied") }}">
-            <svg class="i-copy" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>
-            <svg class="i-check" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
-          </button>
-        </div>
-      </div>
-
-      {#- 심해 먹물결 아트워크. 장식이므로 보조기기에는 숨긴다. #}
-      <div class="hero-art" aria-hidden="true" data-float>
-        <svg class="art" viewBox="0 0 520 520">
-          <defs>
-            <clipPath id="artclip"><circle cx="260" cy="260" r="238"/></clipPath>
-            <radialGradient id="abg" cx="50%" cy="30%" r="80%">
-              <stop offset="0%" stop-color="#132a4e"/>
-              <stop offset="55%" stop-color="#0b1830"/>
-              <stop offset="100%" stop-color="#060d1a"/>
-            </radialGradient>
-            <radialGradient id="alight" cx="50%" cy="50%" r="50%">
-              <stop offset="0%" stop-color="#59d8ff" stop-opacity="0.55"/>
-              <stop offset="100%" stop-color="#59d8ff" stop-opacity="0"/>
-            </radialGradient>
-            <linearGradient id="w1" x1="0" y1="0" x2="0" y2="1">
-              <stop offset="0%" stop-color="#1c3f6e"/><stop offset="100%" stop-color="#122a4d"/>
-            </linearGradient>
-            <linearGradient id="w2" x1="0" y1="0" x2="0" y2="1">
-              <stop offset="0%" stop-color="#152f56"/><stop offset="100%" stop-color="#0d1f3c"/>
-            </linearGradient>
-            <linearGradient id="w3" x1="0" y1="0" x2="0" y2="1">
-              <stop offset="0%" stop-color="#0f2342"/><stop offset="100%" stop-color="#081228"/>
-            </linearGradient>
-            <linearGradient id="w4" x1="0" y1="0" x2="0" y2="1">
-              <stop offset="0%" stop-color="#0a1830"/><stop offset="100%" stop-color="#050b16"/>
-            </linearGradient>
-            <filter id="soft" x="-40%" y="-40%" width="180%" height="180%">
-              <feGaussianBlur stdDeviation="6"/>
-            </filter>
-          </defs>
-          <circle cx="260" cy="260" r="238" fill="url(#abg)"/>
-          <g clip-path="url(#artclip)">
-            <ellipse cx="260" cy="118" rx="150" ry="120" fill="url(#alight)" filter="url(#soft)"/>
-            <path d="M-20 236 C 70 206, 150 268, 250 240 S 430 196, 540 244 L 540 560 L -20 560 Z" fill="url(#w1)"/>
-            <path d="M-20 232 C 70 202, 150 264, 250 236 S 430 192, 540 240" fill="none" stroke="#6fd8ff" stroke-opacity="0.65" stroke-width="2.5"/>
-            <path d="M-20 302 C 90 272, 180 330, 280 304 S 450 262, 540 306 L 540 560 L -20 560 Z" fill="url(#w2)"/>
-            <path d="M-20 298 C 90 268, 180 326, 280 300 S 450 258, 540 302" fill="none" stroke="#4fb6f5" stroke-opacity="0.4" stroke-width="2"/>
-            <path d="M-20 372 C 80 346, 170 398, 270 374 S 440 336, 540 376 L 540 560 L -20 560 Z" fill="url(#w3)"/>
-            <path d="M-20 368 C 80 342, 170 394, 270 370 S 440 332, 540 372" fill="none" stroke="#3b86d8" stroke-opacity="0.3" stroke-width="1.8"/>
-            <path d="M-20 442 C 90 420, 190 462, 290 444 S 460 414, 540 446 L 540 560 L -20 560 Z" fill="url(#w4)"/>
-            <circle cx="150" cy="160" r="2.4" fill="#8fe5ff" fill-opacity="0.9"/>
-            <circle cx="196" cy="120" r="1.6" fill="#8fe5ff" fill-opacity="0.7"/>
-            <circle cx="330" cy="146" r="2" fill="#8fe5ff" fill-opacity="0.8"/>
-            <circle cx="382" cy="190" r="1.4" fill="#8fe5ff" fill-opacity="0.6"/>
-            <circle cx="256" cy="86" r="1.8" fill="#c9f2ff" fill-opacity="0.9"/>
-            <circle cx="110" cy="210" r="1.3" fill="#8fe5ff" fill-opacity="0.5"/>
-            <circle cx="420" cy="130" r="1.6" fill="#8fe5ff" fill-opacity="0.6"/>
-            <circle cx="150" cy="160" r="7" fill="#59d8ff" fill-opacity="0.25" filter="url(#soft)"/>
-            <circle cx="330" cy="146" r="6" fill="#59d8ff" fill-opacity="0.22" filter="url(#soft)"/>
-            <circle cx="256" cy="86" r="6" fill="#59d8ff" fill-opacity="0.25" filter="url(#soft)"/>
-          </g>
-          <circle cx="260" cy="260" r="238" fill="none" stroke="#9fc8ff" stroke-opacity="0.16" stroke-width="1.5"/>
-          <circle cx="260" cy="260" r="252" fill="none" stroke="#9fc8ff" stroke-opacity="0.07" stroke-width="1"/>
-        </svg>
+    <div class="blob" aria-hidden="true"></div>
+    <div class="inner">
+      <p class="kicker" data-reveal>{{ page.extra.hero_kicker }}</p>
+      <h1 class="display" data-reveal>{{ page.extra.hero_title_a }}<br><em data-squeeze>{{ page.extra.hero_title_b }}</em></h1>
+      <p class="sub" data-reveal>{{ page.extra.hero_sub }}</p>
+      <p class="cta" data-reveal>
+        <a class="btn btn-primary" href="{{ home }}start/">{{ page.extra.cta_start }}</a>
+        <a class="btn btn-ghost" href="https://github.com/sqzer-x/sqzass">{{ page.extra.cta_github }}</a>
+      </p>
+      <div class="lede" data-reveal>
+        {{ page.content | safe }}
       </div>
     </div>
   </section>
 
-  <section class="intro">
-    <div class="inner" data-reveal>
-      {{ page.content | safe }}
-    </div>
-  </section>
-
-  <section class="band bench" aria-labelledby="bench-h">
+  <section class="bento-wrap" aria-label="{{ page.extra.bento_label }}">
     <div class="inner">
-      <h2 id="bench-h" data-reveal>{{ page.extra.bench_title }}</h2>
-      <p class="band-note" data-reveal>{{ page.extra.bench_note }}</p>
-      <div class="bench-card" data-reveal>
-        {%- for row in page.extra.bench %}
-        <div class="row">
-          <h3>{{ row.label }}</h3>
-          <div class="meas us">
-            <span class="who">sqzass</span>
-            <svg class="track" aria-hidden="true" preserveAspectRatio="none">
-              <rect class="fill" data-bar width="{{ row.us_w }}" height="100%" rx="3"></rect>
-            </svg>
-            <span class="val">{{ row.us_ms }} ms</span>
+      <div class="bento">
+
+        <article class="tile t-bench" data-reveal>
+          <h2>{{ page.extra.bench_title }}</h2>
+          <p class="note">{{ page.extra.bench_note }}</p>
+          {%- for row in page.extra.bench %}
+          <div class="row">
+            <h3>{{ row.label }}</h3>
+            <div class="meas us">
+              <span class="who">sqzass</span>
+              <svg class="track" aria-hidden="true" preserveAspectRatio="none">
+                <rect class="fill" data-bar width="{{ row.us_w }}" height="100%" rx="3"></rect>
+              </svg>
+              <span class="val">{{ row.us_ms }} ms</span>
+            </div>
+            <div class="meas">
+              <span class="who">Hugo</span>
+              <svg class="track" aria-hidden="true" preserveAspectRatio="none">
+                <rect class="fill" data-bar width="{{ row.them_w }}" height="100%" rx="3"></rect>
+              </svg>
+              <span class="val">{{ row.them_ms }} ms</span>
+            </div>
           </div>
-          <div class="meas">
-            <span class="who">Hugo</span>
-            <svg class="track" aria-hidden="true" preserveAspectRatio="none">
-              <rect class="fill" data-bar width="{{ row.them_w }}" height="100%" rx="3"></rect>
-            </svg>
-            <span class="val">{{ row.them_ms }} ms</span>
+          {%- endfor %}
+          <p class="tile-link"><a href="{{ home }}benchmark/">{{ page.extra.bench_more }}</a></p>
+        </article>
+
+        <article class="tile t-install" data-reveal>
+          <h2>{{ page.extra.install_title }}</h2>
+          <div class="install">
+            <code>curl -fsSL {{ site.origin }}{{ site.base_path }}/install.sh | sh</code>
+            <button class="inst-copy" type="button" data-copy-text="curl -fsSL {{ site.origin }}{{ site.base_path }}/install.sh | sh"
+                    aria-label="{{ t("copy") }}" data-copied="{{ t("copied") }}">
+              <svg class="i-copy" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>
+              <svg class="i-check" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
+            </button>
           </div>
-        </div>
-        {%- endfor %}
-        <p class="zero">
-          <span class="zero-num">0</span>
-          <span class="zero-label">{{ page.extra.zero_label }}</span>
-        </p>
-      </div>
-      <p class="band-more" data-reveal><a href="{{ home }}benchmark/">{{ page.extra.bench_more }}</a></p>
-    </div>
-  </section>
+          <p class="note">{{ page.extra.install_alt }} <code class="inline">cargo install --git https://github.com/sqzer-x/sqzass</code></p>
+        </article>
+
+        <article class="tile t-zero" data-reveal>
+          <p class="zero-num">0</p>
+          <p class="note">{{ page.extra.zero_label }}</p>
+        </article>
 
-  <section class="band feats" aria-labelledby="feats-h">
-    <div class="inner">
-      <h2 id="feats-h" data-reveal>{{ page.extra.features_title }}</h2>
-      <ul class="cards">
         {%- for f in page.extra.features %}
-        <li class="card" data-reveal>
-          <h3>{{ f.title }}</h3>
-          <p>{{ f.body }}</p>
-        </li>
+        <article class="tile" data-reveal>
+          <h2>{{ f.title }}</h2>
+          <p class="note">{{ f.body }}</p>
+        </article>
         {%- endfor %}
-      </ul>
-      <p class="band-more" data-reveal><a href="{{ home }}start/">{{ page.extra.features_more }}</a></p>
-    </div>
-  </section>
 
-  <section class="band quick" aria-labelledby="quick-h">
-    <div class="inner">
-      <h2 id="quick-h" data-reveal>{{ page.extra.quick_title }}</h2>
-      <div class="term" data-reveal>
-        <div class="term-bar" aria-hidden="true"><i></i><i></i><i></i></div>
-        {#- 아래 출력 줄들은 전부 실행 결과 원문이다. 지어낸 줄이 없다. #}
-        <pre><code><span class="t-p">$</span> curl -fsSL {{ site.origin }}{{ site.base_path }}/install.sh | sh
-<span class="t-o">설치했습니다: /usr/local/bin/sqzass (sqzass 0.1.0)</span>
-<span class="t-p">$</span> sqzass init demo
-<span class="t-o">  demo/sqzass.toml
-  demo/content/_index.md
-  demo/templates/page.html</span>
-<span class="t-p">$</span> sqzass build -i demo
-<span class="t-o">1 pages → demo/public</span></code></pre>
+        <article class="tile t-demo" data-reveal>
+          <h2>{{ page.extra.demo_title }}</h2>
+          <p class="note">{{ page.extra.demo_body }}</p>
+          <p class="tile-link"><a href="{{ home }}start/">{{ t("documentation") }} →</a></p>
+        </article>
+
       </div>
-      <p class="band-note quick-note" data-reveal>{{ page.extra.quick_note }} <a href="{{ home }}start/installation/">{{ page.extra.quick_note_link }}</a></p>
     </div>
   </section>
 
   <footer class="foot">
-    <div class="inner">
+    <div class="inner foot-in">
       <nav class="foot-nav">
         <a href="{{ home }}start/">{{ t("documentation") }}</a>
         <a href="{{ home }}benchmark/">{{ page.extra.foot_benchmark }}</a>