www.git

www

~ Personal site — projects, posts, about. Built with sqzass.
git clone https://github.com/debuman/www.git
commit 18d578a3b11bbd6ba0f4fac751a3156a64cf7d99
parent a65e87750477cfeb53389d642bc2e9ce7c59d830
Author: sqzer <110329244+sqzer-x@users.noreply.github.com>
Date: Wed, 5 Aug 2026 20:03:45 +0900

Star counts on the mosaic, and colour only where the hand is

Two details from the reference I had left out.

Every tile carries its star count, zero included. The number lives in the home's
catalogue beside the picture, which means it would have gone stale the moment
the real one changed: stars.py only walked content/projects. It walks all of
content now, so any repo-and-stars pair anywhere gets refreshed on the daily run,
and its report names files by path rather than by basename since there is more
than one directory in scope.

The pictures are desaturated at rest and come back to full colour under the
cursor. That is the reference's device, and it is also the first line of this
stylesheet: colour is absent at rest and appears where a hand is. Applying it to
the pictures rather than only to links is the same sentence carried further. It
stays inside the rule that hover changes colour and nothing else — nothing
moves, nothing scales, and it runs on the sheet's single duration.

I removed exactly this filter once before, when it was a value copied from the
reference with nothing behind it. It comes back with a reason this time, which
is a different thing, and the note in the sheet says so rather than pretending
the earlier decision never happened.

Diffstat:
Mcontent/_index.md | 8++++++++
Mstatic/css/main.css | 17++++++++++++++++-
Mtemplates/home.html | 4++++
Mtools/stars.py | 10++++++----
4 files changed, 34 insertion(+), 5 deletion(-)

diff --git a/content/_index.md b/content/_index.md
@@ -28,24 +28,32 @@ url    = "/projects/sqzass/"
 cover  = ""
 mark   = "images/projects/sqzass.png"
 accent = "#e0a06a"
+repo   = "https://github.com/sqzer-x/sqzass"
+stars  = 0
 
 [[extra.mosaic]]
 url    = "/projects/ommp/"
 cover  = "images/projects/ommp-cover.png"
 mark   = ""
 accent = "#7fc0d4"
+repo   = "https://github.com/sqzer-x/ommp"
+stars  = 0
 
 [[extra.mosaic]]
 url    = "/projects/uaf/"
 cover  = ""
 mark   = ""
 accent = "#9aa6cc"
+repo   = "https://github.com/sqzer-x/uaf"
+stars  = 0
 
 [[extra.mosaic]]
 url    = "/projects/usfx/"
 cover  = ""
 mark   = ""
 accent = "#8fb9a2"
+repo   = "https://github.com/sqzer-x/usfx"
+stars  = 1
 
 [[extra.preview]]
 url    = "/posts/a-new-beginning/"
diff --git a/static/css/main.css b/static/css/main.css
@@ -734,12 +734,22 @@ html[lang="ko"] [data-tooltip]::after { letter-spacing: 0; text-transform: none;
 /* 작은 장의 키를 여기서 정한다. 큰 장은 셋의 합만큼 자라므로 자기 비율이 없다. */
 .mosaic > :not(:first-child) { aspect-ratio: 2.1 / 1; }
 
-/* 바탕. 그림이 있으면 그림이, 없으면 그 프로젝트의 색이 옅게 깔린다. */
+/* 바탕. 그림이 있으면 그림이, 없으면 그 프로젝트의 색이 깔린다.
+
+   평상시에는 색이 빠져 있고 손이 닿으면 돌아온다. 이 시트의 첫 줄에 적힌
+   전제가 그것이다 — "색은 평상시에 없고 손이 닿을 때만 나온다". 그림에까지
+   그 규칙을 적용한 것이고, 크기나 자리는 그대로이므로 hover 가 색만 바꾼다는
+   규칙도 지켜진다. 박자는 이 시트의 유일한 박자다.
+   (한때 이 탈색을 걷어냈던 적이 있다. 그때는 참조에서 그대로 가져온 값이라
+   뺐고, 지금은 이 사이트의 전제를 그림까지 밀고 간 것이라 뜻이 다르다.) */
 .mtile-art {
   position: absolute; inset: 0;
   display: grid; place-items: center;
   background: color-mix(in srgb, var(--tint) 30%, var(--bg-2));
+  filter: grayscale(1);
+  transition: filter var(--tr-ink);
 }
+.mtile:hover .mtile-art, .mtile:focus-visible .mtile-art { filter: grayscale(0); }
 .mtile-art img { width: 100%; height: 100%; object-fit: cover; }
 /* 마크는 잉크가 아니라 그 프로젝트의 색을 진하게 쓴 것이다 — 바탕과 같은 색의
    두 단이라 한 물건으로 읽힌다. */
@@ -775,6 +785,11 @@ html[lang="ko"] [data-tooltip]::after { letter-spacing: 0; text-transform: none;
   max-width: 44ch; font-size: 0.88rem; line-height: 1.5;
   color: var(--ink-2); text-wrap: pretty;
 }
+.mtile-stars {
+  margin-top: 0.15rem;
+  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.08em;
+  font-variant-numeric: tabular-nums; color: var(--ink-3);
+}
 /* 큰 장은 글도 한 단 크다 — 크기가 순서를 말한다. */
 .mosaic > :first-child .mtile-title { font-size: clamp(1.3rem, 1.1rem + 0.9vw, 1.75rem); }
 
diff --git a/templates/home.html b/templates/home.html
@@ -108,6 +108,10 @@
         {%- if p.description %}
         <span class="mtile-blurb">{{ p.description }}</span>
         {%- endif %}
+        {#- 별 개수는 stars.py 가 카탈로그에 구워 둔 값이다. 0 이어도 낸다. #}
+        {%- if m.repo %}
+        <span class="mtile-stars stars">{{ m.stars }} ★</span>
+        {%- endif %}
       </span>
     </a>
     {%- endif %}
diff --git a/tools/stars.py b/tools/stars.py
@@ -23,7 +23,9 @@ import urllib.request
 from pathlib import Path
 
 ROOT = Path(__file__).resolve().parent.parent
-PROJECTS = ROOT / "content" / "projects"
+# content/ 전체를 훑는다. 별 개수는 프로젝트 상세 페이지에도 있고 홈의 모자이크
+# 카탈로그에도 있는데, 후자를 빼 두면 홈의 숫자만 조용히 낡는다.
+CONTENT = ROOT / "content"
 
 # `repo<공백>= "https://github.com/owner/name"` — 뒤따르는 stars 줄까지 함께 잡아
 # 갈아 끼운다. 없으면 새로 붙인다.
@@ -59,8 +61,8 @@ def fetch(slug: str) -> int | None:
 
 def check() -> int:
     bad = [
-        f"{p.name} ({m.group('slug')})"
-        for p in sorted(PROJECTS.glob("*.md"))
+        f"{p.relative_to(ROOT)} ({m.group('slug')})"
+        for p in sorted(CONTENT.rglob("*.md"))
         for m in LINE.finditer(p.read_text(encoding="utf-8"))
         if not m.group("old")
     ]
@@ -76,7 +78,7 @@ def main() -> int:
     cache: dict[str, int | None] = {}
     changed = 0
 
-    for path in sorted(PROJECTS.glob("*.md")):
+    for path in sorted(CONTENT.rglob("*.md")):
         text = path.read_text(encoding="utf-8")
 
         def swap(m: re.Match) -> str: