The repo tabs are small uppercase monospace on the header's rule, the current one in ink over a 3px accent bar. On a phone the ones that don't fit scroll sideways as before, and where scroll-driven animations work the edge that has more fades out, in place of the old shadows. Buttons are square and set the same way. Most are the page's raised surface with accent text, like Search; the one that does the thing is filled with ink: Clone, Comment, Sign in. Viewed boxes on diff files match them.
- commit
- 55789eee1ddb35b253f0b9b5e5574446f9bf11a2
- parent
- 0259f3c859c8886e14569ed24a00c874a5fef1ba
- author
- cat <admin@dev.site>
- ci
- ✓ passed in 81s, signed by cat
- kind
- feat risk score 2.0 of 3, Jev's estimate
- review
- #12 Square, hairline, textured: the site's design pass
ci attestation
forge-attestation 1 type ci commit 55789eee1ddb35b253f0b9b5e5574446f9bf11a2 tree 8647fb9f0fd0c8c10a873c9029968d47158e448f script .forge/ci 38df37c0d5a6382f60569079a0dd821094e37e4a result pass exit 0 started 2026-10-19T01:53:11Z duration 81s runner (not shown here; refs/notes/ci has it) system Darwin 25.5.0 arm64 env host log sha256:8f82b162d81d436728a7c361ae540cd28912f4ca0b1cb2d8f0286c714f6bad66 253 lines |remote: review #4: /dami/greet/reviews/4/ |pushed wip/i18n |e9542f9 running .forge/ci: greet.sh: say what it is | | sh: /bin/sh | | ok greet |e9542f9 pass in 0s, signed |pushed main |remote: review #4: /dami/greet/reviews/4/ |pushed wip/i18n |e851acb running .forge/ci: wave at the world | | sh: /bin/sh | | FAIL greet : got 'hello, world o/', want 'hello, world' |e851acb fail in 0s, signed |forge: 1 commit(s) did not pass |remote: review #6: /dami/greet/reviews/6/ |pushed ana/wave |1ce4b51 running .forge/ci: update the test for the wave | | sh: /bin/sh | | ok greet |1ce4b51 pass in 0s, signed |remote: review #6: /dami/greet/reviews/6/ |pushed ana/wave |warning: You appear to have cloned an empty repository. |site home: deployed 1e4259f -> /sites/ana/dotfiles/home/ |created ana/notes |remote: review #1: /ana/notes/reviews/1/ |pushed ana/todo |landing #1 A todo list: ana/todo -> main |e4453b3 running .forge/ci: web, server and Python versions of greet | | sh: /bin/sh | | ok greet |e4453b3 pass in 0s, signed |pushed main |416875f running .forge/ci: messages: notes for the later regions | | sh: /bin/sh | | ok greet |416875f pass in 0s, signed |remote: review #7: /dami/greet/reviews/7/ |pushed dami/regions |created dami/forge |warning: You appear to have cloned an empty repository. |site guide: deployed 30dfad6 -> /sites/dami/forge/guide/ |(node:46229) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built ana/dotfiles in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.dQTnxc/wt/demo/root/.forge/www |(node:46358) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built ana/notes in 0s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.dQTnxc/wt/demo/root/.forge/www |(node:46495) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built dami/forge in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.dQTnxc/wt/demo/root/.forge/www |(node:46626) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built dami/greet in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.dQTnxc/wt/demo/root/.forge/www |(node:47299) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built - in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.dQTnxc/wt/demo/root/.forge/www |226 of 226 pages render the same without 11ty |guide: 4 files, links ok |ok
Signature: good, cat
| M | site/ | 3 | -- |
| M | site/ | 4 | +- |
| M | site/ | 4 | +-- |
| M | site/ | 6 | ++-- |
| M | site/ | 42 | +++++++++++++++++++----------- |
| M | site/ | 2 | - |
@@ -33,9 +33,6 @@ ol.comments { list-style: none; margin: 0; padding: 0; }
3333 .reply textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }3434 .reply-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; font-size: 0.92em; }3535 .reply-bar .grow { flex: 1; }36-.reply-bar button.go { background: var(--accent); border-color: var(--accent); color: #fff; }37-.reply-bar button.go:hover { filter: brightness(1.1); }38-.reply-bar button:disabled { opacity: 0.6; cursor: default; filter: none; }3936 .reply-status.bad { color: var(--fail); white-space: pre-line; }4037 {% endcss %}4138 <section class="discussion" id="discussion">@@ -1,7 +1,7 @@
11 {# The footer, with the button that lists the keyboard shortcuts in a dialog (keys.ts). -#}22 {% css %}3-footer.site .keyhelp { background: none; border: 0; padding: 0; color: var(--muted); font-size: 1em; }4-footer.site .keyhelp:hover { color: var(--fg); }3+footer.site .keyhelp { background: none; border: 0; padding: 0; color: var(--muted); }4+footer.site .keyhelp:hover { color: var(--fg); background: none; }55 @media (pointer: coarse) and (hover: none) { footer.site .keyhelp { display: none; } }66 /* keyboard shortcuts (keys.ts) */77 #help { width: min(440px, 94vw); padding: 0; background: var(--raised); color: var(--fg); border: 1px solid var(--border); box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2); }@@ -15,9 +15,7 @@
1515 /* the sign-in page */1616 .login { padding: 0 0 16px; max-width: 40em; }1717 .login h1 { font-size: 1.3rem; margin: 4px 0 12px; }18-.login button.go { font-size: 1em; padding: 6px 14px; background: var(--accent); border-color: var(--accent); color: #fff; }19-.login button.go:hover { filter: brightness(1.1); background: var(--accent); }20-.login button.go:disabled { opacity: 0.6; cursor: default; }18+.login button.go { padding: 7px 14px; }2119 .login-status { min-height: 1.4em; }2220 .login-status.bad { color: var(--fail); }2321 .login form { display: inline; }@@ -4,9 +4,9 @@
44 someone searches file contents. -#}55 {% css %}66 /* search: the header button, and the overlay it and "/" open */7-.search-open { display: inline-flex; align-items: center; gap: 6px; flex: none; background: var(--bg); color: var(--muted); font-size: 0.9em; padding: 4px 9px; }7+.search-open { display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 4px 9px; }88 .search-open[hidden] { display: none; }9-.search-open kbd { font-size: 0.8em; line-height: 1.3; }9+.search-open kbd { line-height: 1.3; color: inherit; border-color: currentColor; background: none; }1010 #search { position: fixed; inset: 0; z-index: 20; background: rgba(0, 0, 0, 0.3); }1111 #search .search-box { position: absolute; top: max(8px, 8vh); left: 50%; transform: translateX(-50%); width: min(680px, calc(100vw - 16px)); background: var(--raised); border: 1px solid var(--border); padding: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2); }1212 #search input { width: 100%; font: 16px var(--sans); padding: 8px 10px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); }@@ -22,7 +22,7 @@
2222 #search .m.mono { font-family: var(--mono); white-space: pre; }2323 #search .m { font-size: 0.82em; color: var(--muted); }2424 #search b { color: var(--link); font-weight: 600; }25-#search li.more button { border: 0; background: none; color: var(--link); padding: 3px 8px; width: 100%; text-align: left; }25+#search li.more button { border: 0; background: none; padding: 5px 8px; width: 100%; text-align: left; }2626 #search li.note { padding: 5px 8px; font-size: 0.85em; color: var(--muted); }2727 #search .hint { margin: 8px 8px 2px; font-size: 0.85em; color: var(--muted); }2828 #search .hint:empty { display: none; }@@ -108,21 +108,35 @@ header.site { border-bottom: 1px solid var(--border); }
108108 .title b { font-weight: 650; }109109 .top .spacer { flex: 1; }110110 .repo-desc { margin: 0 0 10px; color: var(--muted); font-size: 0.93em; }111-nav.tabs { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px; }111+nav.tabs { display: flex; gap: 22px; overflow-x: auto; scrollbar-width: none; font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; }112112 nav.tabs::-webkit-scrollbar { display: none; }113-nav.tabs a { color: var(--fg); padding: 8px 12px; border-bottom: 2px solid transparent; white-space: nowrap; }114-nav.tabs a:hover { text-decoration: none; background: var(--hover); }115-nav.tabs a.cur { border-bottom-color: var(--accent); font-weight: 600; }116-/* Tabs that don't fit scroll sideways. */113+nav.tabs a { color: var(--muted); padding: 9px 0 10px; white-space: nowrap; }114+nav.tabs a:hover { color: var(--fg); text-decoration: none; }115+nav.tabs a.cur { color: var(--fg); box-shadow: inset 0 -3px 0 var(--accent); }117116 @media (max-width: 480px) {118- /* Six tabs fit a 360px phone: tighter, and sharing the width. */119- nav.tabs { gap: 0; padding: 0 8px; }120- nav.tabs a { flex: 1 0 auto; text-align: center; padding: 8px 6px; font-size: 14px; }117+ nav.tabs { gap: 16px; }121118 }119+/* Tabs that don't fit scroll sideways; the edge that has more fades out. */120+@property --tabs-l { syntax: "<length>"; inherits: false; initial-value: 0px; }121+@property --tabs-r { syntax: "<length>"; inherits: false; initial-value: 0px; }122+@supports (animation-timeline: scroll()) {123+ nav.tabs { mask-image: linear-gradient(to right, transparent, #000 var(--tabs-l), #000 calc(100% - var(--tabs-r)), transparent); animation: tabs-edge linear both; animation-timeline: scroll(self inline); }124+ @keyframes tabs-edge { from { --tabs-l: 0px; --tabs-r: 32px; } to { --tabs-l: 32px; --tabs-r: 0px; } }125+}126+127+/* buttons: square, small uppercase monospace; secondary is the page's128+ surface with accent text, primary (.go) is filled with ink */129+button, .btn, details.clone > summary { font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--link); background: var(--subtle); border: 1px solid var(--border); padding: 5px 10px; cursor: pointer; }130+button:hover, .btn:hover { color: var(--deep); background: var(--hover); border-color: var(--faint); text-decoration: none; }131+button[aria-pressed="true"] { color: var(--fg); border-color: var(--fg); }132+button.go, details.clone > summary { color: var(--bg); background: var(--fg); border-color: var(--fg); }133+button.go:hover, details.clone > summary:hover { color: var(--bg); background: var(--muted); border-color: var(--muted); }134+button:disabled { opacity: 0.6; cursor: default; }135+button kbd { font-size: 1em; padding: 0 0.3em; text-transform: none; }122136 123137 /* clone */124138 details.clone { position: relative; flex: none; }125-details.clone > summary { list-style: none; cursor: pointer; border: 1px solid var(--border); padding: 3px 10px; background: var(--bg); font-size: 0.9em; }139+details.clone > summary { list-style: none; }126140 details.clone > summary::-webkit-details-marker { display: none; }127141 details.clone .panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 10; width: min(440px, 92vw); background: var(--raised); border: 1px solid var(--border); padding: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); }128142 .copyrow { display: flex; gap: 6px; align-items: center; margin: 4px 0; }@@ -131,8 +145,6 @@ details.clone .panel { position: absolute; right: 0; top: calc(100% + 6px); z-in
131145 .private-mark:hover { color: var(--warn); }132146 .copyrow label { width: 44px; font: 600 10.5px var(--mono); letter-spacing: 0.08em; color: var(--faint); }133147 .copyrow input { flex: 1; min-width: 0; font: 13px var(--mono); padding: 4px 6px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); }134-button, .btn { font: inherit; font-size: 0.85em; color: var(--fg); background: var(--subtle); border: 1px solid var(--border); padding: 3px 10px; cursor: pointer; }135-button:hover, .btn:hover { background: var(--hover); text-decoration: none; }136148 137149 /* live status: words, no dot */138150 #live { font: 11px var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40vw; }@@ -144,7 +156,6 @@ button:hover, .btn:hover { background: var(--hover); text-decoration: none; }
144156 main.wrap { padding-top: 20px; padding-bottom: 40px; }145157 main.wrap > :first-child { margin-top: 0; }146158 footer.site { color: var(--muted); padding-bottom: 24px; font-size: 0.85em; }147-button[aria-pressed="true"] { background: var(--hover); border-color: var(--faint); }148159 149160 /* toolbars above lists and code */150161 .bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }@@ -333,16 +344,17 @@ details.att pre, details.howto pre { white-space: pre-wrap; overflow-wrap: anywh
333344 334345 /* Diff files fold (diffs.ts); review pages add a Viewed box. */335346 .fh.foldable { cursor: pointer; }336-.fh .fold { border: 0; background: none; padding: 0; width: 1.1em; color: var(--muted); font-size: 1.2em; line-height: 1; }347+.fh .fold { border: 0; background: none; padding: 0; width: 1.1em; color: var(--muted); font: 1.2em/1 var(--sans); letter-spacing: 0; }348+.fh .fold:hover { background: none; color: var(--fg); }337349 .fh .fold::before { content: "\25BE"; display: inline-block; transition: transform 0.1s; }338350 .file.folded .fold::before { transform: rotate(-90deg); }339351 .file.folded > :not(.fh) { display: none; }340352 .file.folded > .fh { border-bottom: 0; }341353 .file.folded:has(.viewed input:checked) .fname { color: var(--muted); font-weight: normal; }342-.fh .viewed { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px; border: 1px solid var(--border); background: var(--bg); color: var(--muted); font-size: 0.9em; cursor: pointer; user-select: none; -webkit-user-select: none; }354+.fh .viewed { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border: 1px solid var(--border); background: var(--bg); color: var(--muted); font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer; user-select: none; -webkit-user-select: none; }343355 .fh .view ~ .viewed { margin-left: 0; }344356 .fh .viewed:has(input:checked) { color: var(--fg); }345-.fh .viewed input { margin: 0; }357+.fh .viewed input { margin: 0; accent-color: var(--accent); }346358 347359 /* prose: README, wiki, rendered markdown */348360 .markdown { font-size: 1rem; line-height: 1.6; overflow-wrap: break-word; padding: 16px 8px; }@@ -36,8 +36,6 @@ pagination:
3636 .cmts textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }3737 .cmts .reply-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; font-size: 0.92em; }3838 .cmts .reply-bar .grow { flex: 1; }39-.cmts .reply-bar button.go { background: var(--accent); border-color: var(--accent); color: #fff; }40-.cmts .reply-bar button:disabled { opacity: 0.6; cursor: default; }4139 .cmts .reply-status.bad { color: var(--fail); white-space: pre-line; }4240 .cmt.pending { border-top-style: dashed; }4341 .cmt.pending .text { padding: 8px 12px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--muted); }