clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

Square corners, and rules between things instead of boxes

cat committed 2874288
Nothing is rounded any more: boxes, menus, dialogs, inputs, code blocks
and the search overlay all have square corners.

Lists sit on the page, as in Vanilla: tables lose their outer border and
keep a hairline under each row, with headers in small uppercase
monospace. Section headings take the same type over a rule. A box is now
a heading row over its list or prose; only a file viewer (.viewer) and
the code views and diffs stay bordered regions, on a raised surface.
Comments are rows between rules, their quoted lines still a small code
box. The repos on the index and owner pages are rows too, name, what it
is, and its sites, reviews and last push, rather than cards.

Labels, numbers, dates, branches and shas are monospace; subjects and
prose keep the sans. Insights' tiles become figures under a rule.
commit
28742881e180f6c49287b4be428cdd9441039bb8
parent
e98033d5f013f26d8f8f979a667415607348549d
author
cat <admin@dev.site>
ci
✓ passed in 79s, signed by cat
kind
refactor risk score 2.5 of 3, Jev's estimate
review
#12 Square, hairline, textured: the site's design pass
ci attestation
forge-attestation 1
type ci
commit 28742881e180f6c49287b4be428cdd9441039bb8
tree 73984ef657fe7ca347e6274a128b0056d4124ffd
script .forge/ci 38df37c0d5a6382f60569079a0dd821094e37e4a
result pass
exit 0
started 2026-10-19T01:50:32Z
duration 79s
runner (not shown here; refs/notes/ci has it)
system Darwin 25.5.0 arm64
env host
log sha256:286994e01d6bc6646f8d06045f7fbc14aaf1620da14221e524e7e095f46dd3b6 253 lines
|remote: review #4: /dami/greet/reviews/4/
|pushed wip/i18n
|28b9f6d running .forge/ci: greet.sh: say what it is
|  | sh: /bin/sh
|  | ok   greet
|28b9f6d pass in 0s, signed
|pushed main
|remote: review #4: /dami/greet/reviews/4/
|pushed wip/i18n
|c411bd9 running .forge/ci: wave at the world
|  | sh: /bin/sh
|  | FAIL greet : got 'hello, world o/', want 'hello, world'
|c411bd9 fail in 0s, signed
|forge: 1 commit(s) did not pass
|remote: review #6: /dami/greet/reviews/6/
|pushed ana/wave
|b59e4d6 running .forge/ci: update the test for the wave
|  | sh: /bin/sh
|  | ok   greet
|b59e4d6 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 f8448d3 -> /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
|806b1c3 running .forge/ci: web, server and Python versions of greet
|  | sh: /bin/sh
|  | ok   greet
|806b1c3 pass in 0s, signed
|pushed main
|15cbf8d running .forge/ci: messages: notes for the later regions
|  | sh: /bin/sh
|  | ok   greet
|15cbf8d 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 a4edb28 -> /sites/dami/forge/guide/
|(node:82473) 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.eeLxlE/wt/demo/root/.forge/www
|(node:82597) 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.eeLxlE/wt/demo/root/.forge/www
|(node:82736) 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.eeLxlE/wt/demo/root/.forge/www
|(node:82869) 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.eeLxlE/wt/demo/root/.forge/www
|(node:83544) 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.eeLxlE/wt/demo/root/.forge/www
|226 of 226 pages render the same without 11ty
|guide: 4 files, links ok
|ok

Signature: good, cat

16 files changed, +189 -155
Msite/_includes/discussion.njk28+++---
Msite/_includes/help.njk6+-
Msite/_includes/insights-body.njk25+++---
Msite/_includes/login.njk2+-
Msite/_includes/macros.njk51++++++-----
Msite/_includes/search.njk19++--
Msite/assets/style.css140+++++++++++++++++-------------
Msite/repo/blob.njk2+-
Msite/repo/commit.njk4+-
Msite/repo/home.njk2+-
Msite/repo/releases.njk4+-
Msite/repo/review-diff.njk23+++--
Msite/repo/review.njk10+-
Msite/repo/reviews.njk9+-
Msite/repo/revision.njk8+-
Msite/repo/wiki.njk11++-
M site/_includes/discussion.njk +15 -13
@@ -5,29 +5,31 @@
55 discuss.ts finds who is signed in, and posts the tip the page shows. #}66 {% set u = p.repo.urls %}77 {% css %}8-ul.approvals { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 0.92em; }8+ul.approvals { list-style: none; margin: 0; padding: 10px 0; border-bottom: 1px solid var(--border); display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 0.92em; }99 ul.approvals .tick { color: var(--pass); }1010 ul.approvals .stale { color: var(--muted); }1111 ul.approvals .stale .tick { color: var(--warn); }12-ul.approvals .date { color: var(--muted); font-size: 0.92em; }12+ul.approvals .date { font: 12px var(--mono); color: var(--muted); }13+ul.approvals .date time { font-size: 1em; }1314 ol.comments { list-style: none; margin: 0; padding: 0; }14-.comment { margin: 0 0 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }15-.comment:target { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }16-.comment-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding: 6px 12px; background: var(--subtle); border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; font-size: 0.9em; }17-.comment-head .date { color: var(--muted); }18-.comment-head .rev { font-family: var(--mono); font-size: 0.92em; color: var(--muted); }19-.comment .tag { font-size: 0.8em; font-weight: 600; color: var(--warn); border: 1px solid currentColor; border-radius: 999px; padding: 0 7px; }20-.comment .quote { margin: 10px 12px 0; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }21-.comment .quote .where { padding: 3px 10px; font: 12px/1.6 var(--mono); background: var(--subtle); border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }15+.comment { border-bottom: 1px solid var(--border); padding: 0 0 4px; }16+.comment:target { box-shadow: inset 3px 0 0 var(--accent); }17+.comment-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 10px 12px 0; font-size: 0.9em; }18+.comment-head .date { font: 12px var(--mono); color: var(--muted); }19+.comment-head .date time { font-size: 1em; }20+.comment-head .rev { font: 12px var(--mono); color: var(--muted); }21+.comment .tag { font-size: 0.8em; font-weight: 600; color: var(--warn); border: 1px solid currentColor; padding: 0 7px; }22+.comment .quote { margin: 8px 12px 0; border: 1px solid var(--border); background: var(--raised); overflow: hidden; }23+.comment .quote .where { padding: 3px 10px; font: 12px/1.6 var(--mono); border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }2224 .comment .quote pre { margin: 0; padding: 4px 10px; font: 12.5px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4; }2325 .comment.outdated .quote pre { color: var(--muted); }24-.comment .markdown { padding: 8px 12px; font-size: 0.95rem; line-height: 1.55; }26+.comment .markdown { padding: 6px 12px 8px; font-size: 0.95rem; line-height: 1.55; }2527 .comment .markdown > :last-child { margin-bottom: 0; }2628 /* Sent from this page, until the rebuilt page shows it. */27-.comment.pending { border-style: dashed; }29+.comment.pending { border-bottom-style: dashed; }2830 .comment.pending .text { padding: 8px 12px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--muted); }2931 .reply { margin: 12px 0 0; }30-.reply textarea { display: block; width: 100%; min-height: 6em; resize: vertical; font: 14px/1.5 var(--sans); color: var(--fg); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; }32+.reply textarea { display: block; width: 100%; min-height: 6em; resize: vertical; font: 14px/1.5 var(--sans); color: var(--fg); background: var(--raised); border: 1px solid var(--border); padding: 8px 10px; }3133 .reply textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }3234 .reply-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; font-size: 0.92em; }3335 .reply-bar .grow { flex: 1; }
M site/_includes/help.njk +3 -3
M site/_includes/insights-body.njk +13 -12
@@ -23,18 +23,19 @@
2323 }2424 }2525 .insights .ins-meta { margin: 0.4em 0 1em; }26-.insights .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin: 0 0 8px; }27-.insights .kpi { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 14px; }28-.insights .kpi .label { color: var(--muted); font-size: 0.85em; }29-.insights .kpi .value { font-size: 1.6rem; font-weight: 600; line-height: 1.2; margin-top: 2px; }26+.insights > h3 { margin: 28px 0 0; padding-bottom: 6px; border-bottom: 1px solid var(--border); font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }27+.insights .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0 20px; margin: 0 0 8px; }28+.insights .kpi { border-top: 1px solid var(--border); padding: 10px 0; }29+.insights .kpi .label { font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }30+.insights .kpi .value { font: 600 1.5rem/1.2 var(--mono); margin-top: 4px; font-variant-numeric: tabular-nums; }3031 .insights .kpi .sub { color: var(--muted); font-size: 0.85em; }3132 .insights .charts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: 12px 20px; }3233 .insights figure { margin: 0; min-width: 0; position: relative; }33-.insights figcaption h3 { margin: 1.2em 0 0; }34+.insights figcaption h3 { margin: 1.6em 0 2px; font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }3435 .insights figcaption .desc { font-size: 0.85em; }3536 .insights .plot { position: relative; margin-top: 6px; }36-.insights .plot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }37-.insights svg { display: block; width: 100%; overflow: visible; font: 11px var(--sans); font-variant-numeric: tabular-nums; }37+.insights .plot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }38+.insights svg { display: block; width: 100%; overflow: visible; font: 10.5px var(--mono); font-variant-numeric: tabular-nums; }3839 .insights svg .grid { stroke: var(--viz-grid); stroke-width: 1; shape-rendering: crispEdges; }3940 .insights svg .base { stroke: var(--viz-axis); stroke-width: 1; shape-rendering: crispEdges; }4041 .insights svg .tick { fill: var(--muted); }
@@ -44,20 +45,20 @@
4445 .insights svg .hair { stroke: var(--muted); stroke-width: 1; shape-rendering: crispEdges; }4546 .insights svg .on { filter: brightness(1.15); }4647 .insights svg .mark-label { fill: var(--fg); paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; }47-.insights .empty-chart { color: var(--muted); font-size: 0.9em; padding: 28px 0; text-align: center; border: 1px solid var(--border); border-radius: var(--radius); }48+.insights .empty-chart { color: var(--muted); font-size: 0.9em; padding: 28px 0; text-align: center; border-block: 1px solid var(--border); }4849 .insights .legend { display: flex; gap: 14px; font-size: 0.85em; color: var(--muted); margin-top: 4px; }49-.insights .legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }50-.insights .tip { position: absolute; z-index: 2; pointer-events: none; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); padding: 6px 9px; font-size: 0.85em; white-space: nowrap; }50+.insights .legend i { display: inline-block; width: 10px; height: 10px; margin-right: 5px; vertical-align: -1px; }51+.insights .tip { position: absolute; z-index: 2; pointer-events: none; background: var(--raised); border: 1px solid var(--border); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); padding: 6px 9px; font-size: 0.85em; white-space: nowrap; }5152 .insights .tip b { font-size: 1.05em; }5253 .insights .tip .k { display: inline-block; width: 10px; height: 2px; margin-right: 6px; vertical-align: middle; }5354 .insights details.table { margin-top: 4px; font-size: 0.85em; }54-.insights details.table summary { color: var(--muted); cursor: pointer; }55+.insights details.table summary { color: var(--muted); cursor: pointer; font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; }5556 .insights details.table table { border-collapse: collapse; margin-top: 4px; font-variant-numeric: tabular-nums; }5657 .insights details.table td, .insights details.table th { padding: 2px 10px 2px 0; text-align: left; border-bottom: 1px solid var(--border); }5758 .insights details.table .scroll { max-height: 240px; overflow: auto; }5859 .insights .files td { vertical-align: top; padding: 1px 12px 1px 0; }5960 .insights .files td:first-child { white-space: nowrap; }60-.insights pre.cmd { overflow-x: auto; background: var(--subtle); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 12px; font-size: 0.85em; }61+.insights pre.cmd { overflow-x: auto; background: var(--subtle); border: 1px solid var(--border); padding: 8px 12px; font-size: 0.85em; }6162 @media (forced-colors: active) {6263 .insights svg .s1, .insights svg .fail { fill: CanvasText; }6364 }
M site/_includes/login.njk +1 -1
M site/_includes/macros.njk +28 -23
@@ -80,26 +80,26 @@
8080 {% macro reviewItem(r, repo, depth = 0) %}8181 {% css %}8282 .rv-list { list-style: none; margin: 0; padding: 0; }83-.rv { position: relative; display: grid; grid-template-columns: auto 1fr auto; column-gap: 10px; row-gap: 3px; align-items: baseline; padding: 11px 14px; border-top: 1px solid var(--border); }84-.rv:first-child { border-top: 0; }83+.rv { position: relative; display: grid; grid-template-columns: auto 1fr auto; column-gap: 10px; row-gap: 3px; align-items: baseline; padding: 10px 8px; border-bottom: 1px solid var(--border); }8584 .rv:hover, .rv.sel { background: var(--hover); }8685 .rv.sel { box-shadow: inset 2px 0 0 var(--accent); }87-.rv-mark { grid-row: 1 / 3; align-self: start; width: 9px; height: 9px; margin-top: 6px; border-radius: 50%; background: var(--muted); }86+.rv-mark { grid-row: 1 / 3; align-self: start; width: 9px; height: 9px; margin-top: 6px; background: var(--muted); }8887 .rv-mark.open { background: var(--pass); }8988 .rv-mark.draft { background: none; box-shadow: inset 0 0 0 2px var(--muted); }9089 .rv-mark.merged { background: var(--merged); }9190 .rv-mark.closed { background: var(--fail); }9291 .rv-title { min-width: 0; font-weight: 600; overflow-wrap: anywhere; }9392 .rv-title a::after { content: ''; position: absolute; inset: 0; }94-.rv-side { display: flex; gap: 12px; align-items: baseline; justify-content: flex-end; white-space: nowrap; font-size: 0.9em; }95-.rv-meta { grid-column: 2 / 4; display: flex; flex-wrap: wrap; column-gap: 14px; row-gap: 2px; font-size: 0.85em; color: var(--muted); }96-.rv-meta .mono { font-size: 0.95em; }93+.rv-side { display: flex; gap: 12px; align-items: baseline; justify-content: flex-end; white-space: nowrap; font: 12.5px var(--mono); }94+.rv-side .desc { font-family: var(--sans); font-size: 13px; }95+.rv-meta { grid-column: 2 / 4; display: flex; flex-wrap: wrap; column-gap: 14px; row-gap: 2px; font: 12px/1.5 var(--mono); color: var(--muted); }96+.rv-meta time { font-size: 1em; }9797 .rv-meta .num { font-variant-numeric: tabular-nums; }9898 .rv-meta .add { color: var(--pass); }9999 .rv-meta .del { color: var(--fail); }100100 .rv-meta a, .rv-side a { position: relative; z-index: 1; }101-.rv.layer { margin-left: calc(var(--depth) * 22px); border-left: 2px solid var(--border); }102-a.rev { font-size: 0.85em; color: var(--muted); border: 1px solid var(--border); border-radius: 4px; padding: 0 4px; }101+.rv.layer { margin-left: calc(var(--depth) * 22px); border-left: 1px solid var(--border); }102+a.rev { font-size: 0.85em; color: var(--muted); border: 1px solid var(--border); padding: 0 4px; }103103 .appr { white-space: nowrap; font-weight: 600; color: var(--pass); }104104 .appr + .appr { margin-left: 8px; }105105 .appr.stale { color: var(--warn); font-weight: normal; }
@@ -138,33 +138,38 @@ a.rev { font-size: 0.85em; color: var(--muted); border: 1px solid var(--border);
138138 </table>139139 {% endmacro %}140140 141-{# The index and owner pages: repos as cards on shelves by kind (the shelves141+{# The index and owner pages: repos as rows on shelves by kind (the shelves142142 filter), with chips that jump to a shelf. ui.ts makes the chips filters and143143 adds "has a site" and the sort; keys.ts walks the cards with j and k. #}144144 {% macro shelves(repos, owners = false) %}145145 {% css %}146146 .shelf-bar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 4px; }147147 .shelf-bar .grow { flex: 1; }148-.chip { font: inherit; font-size: 0.85em; color: var(--muted); background: none; border: 1px solid var(--border); border-radius: 999px; padding: 2px 11px; cursor: pointer; white-space: nowrap; }148+.chip { font: inherit; font-size: 0.85em; color: var(--muted); background: none; border: 1px solid var(--border); padding: 2px 11px; cursor: pointer; white-space: nowrap; }149149 .chip:hover { color: var(--fg); background: var(--hover); text-decoration: none; }150150 .chip[aria-pressed="true"] { color: var(--fg); background: var(--hover); border-color: var(--faint); }151151 .chip .n { color: var(--faint); margin-left: 4px; font-variant-numeric: tabular-nums; }152-.shelf-head { display: flex; align-items: baseline; gap: 8px; margin: 22px 0 10px; scroll-margin-top: 12px; }153-.shelf-head h2 { margin: 0; font-size: 0.78rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }154-.shelf-head .n { color: var(--faint); font-size: 0.78rem; }155-.shelf-head::after { content: ''; flex: 1; border-top: 1px solid var(--border); transform: translateY(-3px); }156-.cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 10px; }157-.card { position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--subtle); }158-.card:hover, .card:focus-within, .card.sel { border-color: var(--faint); background: var(--hover); }152+.shelf-head { display: flex; align-items: baseline; gap: 8px; margin: 26px 0 0; padding-bottom: 6px; border-bottom: 1px solid var(--border); scroll-margin-top: 12px; }153+.shelf-head h2 { margin: 0; padding: 0; border: 0; }154+.shelf-head .n { font: 600 11px var(--mono); color: var(--faint); }155+/* Repos as rows between hairlines: name, what it is, then its sites, reviews and last push. */156+.cards { list-style: none; margin: 0; padding: 0; }157+.card { position: relative; display: grid; grid-template-columns: minmax(8em, 15em) 1fr auto; column-gap: 16px; align-items: baseline; min-width: 0; padding: 9px 8px; border-bottom: 1px solid var(--border); }158+.card:hover, .card:focus-within, .card.sel { background: var(--hover); }159159 .card.sel { box-shadow: inset 2px 0 0 var(--accent); }160-.card-top { display: flex; align-items: center; gap: 10px; min-width: 0; }161-.card-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; }162-.card-name::after { content: ''; position: absolute; inset: 0; border-radius: var(--radius); }160+.card-top { min-width: 0; }161+.card-name { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; }162+.card-name::after { content: ''; position: absolute; inset: 0; }163163 .card-name .desc { font-weight: normal; }164-.card-desc { margin: 0; color: var(--muted); font-size: 0.9em; overflow-wrap: anywhere; }165-.card-foot { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 2px; font-size: 0.8em; color: var(--faint); }164+.card-desc { grid-column: 2; margin: 0; color: var(--muted); font-size: 0.92em; overflow-wrap: anywhere; }165+.card-foot { grid-column: 3; display: flex; align-items: baseline; gap: 14px; font: 12px var(--mono); color: var(--faint); white-space: nowrap; }166166 .card-foot a { position: relative; z-index: 1; }167-.card-foot .grow { flex: 1; }167+.card-foot .grow { display: none; }168+.card-foot time { font-size: 1em; }169+@media (max-width: 720px) {170+ .card { grid-template-columns: 1fr; row-gap: 3px; }171+ .card-desc, .card-foot { grid-column: 1; }172+}168173 .shelves-empty { color: var(--muted); padding: 24px 0; text-align: center; }169174 {% endcss %}170175 {% set list = repos | shelves %}
M site/_includes/search.njk +10 -9
@@ -8,12 +8,13 @@
88 .search-open[hidden] { display: none; }99 .search-open kbd { font-size: 0.8em; line-height: 1.3; }1010 #search { position: fixed; inset: 0; z-index: 20; background: rgba(0, 0, 0, 0.3); }11-#search .search-box { position: absolute; top: max(8px, 8vh); left: 50%; transform: translateX(-50%); width: min(680px, calc(100vw - 16px)); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.25); }12-#search input { width: 100%; font: 16px var(--sans); padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--subtle); color: var(--fg); }11+#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); }12+#search input { width: 100%; font: 16px var(--sans); padding: 8px 10px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); }13+#search input:focus, #finder input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }1314 #search ol { list-style: none; margin: 4px 0 0; padding: 0; max-height: 65vh; overflow: auto; }14-#search li.group { padding: 10px 8px 3px; font-size: 0.75em; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }15+#search li.group { margin: 0 0 2px; padding: 12px 8px 4px; font: 600 10.5px/1.4 var(--mono); color: var(--faint); text-transform: uppercase; letter-spacing: 0.08em; border-bottom: 1px solid var(--border); }1516 #search li.group span { font-weight: normal; margin-left: 4px; }16-#search li a { display: block; padding: 5px 8px; border-radius: 4px; color: var(--fg); }17+#search li a { display: block; padding: 5px 8px; color: var(--fg); }1718 #search li a:hover { background: var(--hover); text-decoration: none; }1819 #search li.sel a, #search li.sel button { background: var(--hover); box-shadow: inset 2px 0 0 var(--accent); }1920 #search .t, #search .m { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -21,16 +22,16 @@
2122 #search .m.mono { font-family: var(--mono); white-space: pre; }2223 #search .m { font-size: 0.82em; color: var(--muted); }2324 #search b { color: var(--link); font-weight: 600; }24-#search li.more button { border: 0; background: none; color: var(--link); padding: 3px 8px; width: 100%; text-align: left; border-radius: 4px; }25+#search li.more button { border: 0; background: none; color: var(--link); padding: 3px 8px; width: 100%; text-align: left; }2526 #search li.note { padding: 5px 8px; font-size: 0.85em; color: var(--muted); }2627 #search .hint { margin: 8px 8px 2px; font-size: 0.85em; color: var(--muted); }2728 #search .hint:empty { display: none; }2829 /* file finder */29-#finder { position: fixed; top: 10%; left: 50%; transform: translateX(-50%); z-index: 20; width: min(640px, 94vw); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.25); }30-#finder input { width: 100%; font: 15px var(--mono); padding: 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--subtle); color: var(--fg); }30+#finder { position: fixed; top: 10%; left: 50%; transform: translateX(-50%); z-index: 20; width: min(640px, 94vw); background: var(--raised); border: 1px solid var(--border); padding: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2); }31+#finder input { width: 100%; font: 15px var(--mono); padding: 8px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); }3132 #finder ol { list-style: none; margin: 6px 0 0; padding: 0; max-height: 60vh; overflow: auto; }32-#finder li a { display: block; padding: 4px 8px; border-radius: 4px; font-family: var(--mono); font-size: 0.9em; color: var(--fg); }33-#finder li.sel a { background: var(--hover); }33+#finder li a { display: block; padding: 4px 8px; font-family: var(--mono); font-size: 0.9em; color: var(--fg); }34+#finder li.sel a { background: var(--hover); box-shadow: inset 2px 0 0 var(--accent); }3435 #finder li b { color: var(--link); }3536 {% endcss %}3637 <button type="button" class="search-open" hidden data-search="{{ r.urls.search.href if r else '/repos.json' }}"{% if o and o.owner %} data-owner="{{ o.owner }}"{% endif %}{% if r %} data-code="{{ assets.codesearch }}" data-sqlite="{{ assets.sqlite3 }}" data-wasm="{{ assets.sqlite3wasm }}"{% endif %} title="Search (/)" aria-label="Search"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><circle cx="6.8" cy="6.8" r="4.6" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M10.3 10.3 14 14" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg><kbd class="hide-sm">/</kbd></button>
M site/assets/style.css +80 -60
@@ -1,9 +1,10 @@
11 /* forge: the base stylesheet, light and dark, phone first: tokens, layout,22 lists, code views. CSS for one feature lives with its markup, in a33 template or include ({% css %}), and reaches only the pages that use it. */4-/* The palette: ink on a light grey page, one accent (#3148F6) for links,5- the current tab, focus and primary actions, and a faint paper texture6- behind it all (plaster in dark mode). */4+/* The look: square corners, content on the page between 1px rules, labels5+ in small uppercase monospace, one accent (#3148F6) for links, the current6+ tab's bar, focus and primary actions, and a faint paper texture behind it7+ all (plaster in dark mode). */78 :root {89 --bg: #e9e9e9;910 --fg: #1c2127;
@@ -36,7 +37,6 @@
3637 --texture-opacity: 0.5;3738 --sans: "Ubuntu", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;3839 --mono: ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;39- --radius: 8px;4040 color-scheme: light dark;4141 }4242 @media (prefers-color-scheme: dark) {
@@ -70,7 +70,7 @@
7070 }7171 }7272 73-* { box-sizing: border-box; }73+*, ::before, ::after { box-sizing: border-box; border-radius: 0; }7474 html { -webkit-text-size-adjust: 100%; }7575 body { margin: 0; background: var(--bg); color: var(--fg); font: 15px/1.5 var(--sans); }7676 /* The texture: CC0 scans (ambientCG), fixed to the window behind the
@@ -79,33 +79,39 @@ body::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-even
7979 @media (prefers-reduced-transparency: reduce) { body::before { display: none; } }8080 a { color: var(--link); text-decoration: none; }8181 a:hover { color: var(--deep); text-decoration: underline; }82-:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }83-code, kbd, pre, .mono, .sha { font-family: var(--mono); }82+:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }83+code, kbd, pre, time, .mono, .sha { font-family: var(--mono); }84+time { font-size: 0.92em; }8485 .sha { font-size: 0.9em; }8586 h1, h2, h3 { line-height: 1.25; }86-h2 { font-size: 1.15rem; margin: 1.6em 0 0.6em; }87+/* Section headings: small uppercase monospace on a rule. */88+h2, .label { font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }89+h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 28px 0 0; padding-bottom: 6px; border-bottom: 1px solid var(--border); }90+h2 .desc, h2 a { font-weight: 600; }91+h2 .desc { color: var(--faint); }8792 h3 { font-size: 1rem; margin: 1.4em 0 0.5em; }8893 .desc, .muted { color: var(--muted); }8994 .i { color: var(--add-fg); }9095 .d { color: var(--del-fg); }9196 .wrap { max-width: 1280px; margin: 0 auto; padding: 0 16px; }92-kbd { border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 4px; padding: 0 0.35em; font-size: 0.8em; color: var(--muted); }97+kbd { border: 1px solid var(--border); padding: 0 0.35em; font-size: 0.8em; color: var(--muted); background: var(--subtle); }9398 hr { border: 0; border-top: 1px solid var(--border); margin: 1.5em 0; }9499 95-/* header */100+/* header: on the page, over a rule that the current tab's bar sits on */96101 header.site { border-bottom: 1px solid var(--border); }97102 .top { display: flex; align-items: center; gap: 10px; padding: 12px 0 8px; min-width: 0; }98103 .logo { display: block; color: var(--fg); line-height: 0; flex: none; }99104 .mark { display: block; width: 28px; height: 28px; }100-.title { font-size: 1.05rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }105+.title { font: 1.05rem var(--mono); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }101106 .title a { color: var(--fg); }107+.title a:hover { color: var(--deep); }102108 .title b { font-weight: 650; }103109 .top .spacer { flex: 1; }104-.repo-desc { margin: 0 0 8px; color: var(--muted); }110+.repo-desc { margin: 0 0 10px; color: var(--muted); font-size: 0.93em; }105111 nav.tabs { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px; }106112 nav.tabs::-webkit-scrollbar { display: none; }107113 nav.tabs a { color: var(--fg); padding: 8px 12px; border-bottom: 2px solid transparent; white-space: nowrap; }108-nav.tabs a:hover { text-decoration: none; background: var(--hover); border-radius: 6px 6px 0 0; }114+nav.tabs a:hover { text-decoration: none; background: var(--hover); }109115 nav.tabs a.cur { border-bottom-color: var(--accent); font-weight: 600; }110116 /* Tabs that don't fit scroll sideways. */111117 @media (max-width: 480px) {
@@ -116,21 +122,21 @@ nav.tabs a.cur { border-bottom-color: var(--accent); font-weight: 600; }
116122 117123 /* clone */118124 details.clone { position: relative; flex: none; }119-details.clone > summary { list-style: none; cursor: pointer; border: 1px solid var(--border); border-radius: 6px; padding: 3px 10px; background: var(--bg); font-size: 0.9em; }125+details.clone > summary { list-style: none; cursor: pointer; border: 1px solid var(--border); padding: 3px 10px; background: var(--bg); font-size: 0.9em; }120126 details.clone > summary::-webkit-details-marker { display: none; }121-details.clone .panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 10; width: min(440px, 92vw); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); }127+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); }122128 .copyrow { display: flex; gap: 6px; align-items: center; margin: 4px 0; }123129 .clone-note { margin: 6px 0 0; font-size: 0.85em; color: var(--muted); }124-.private-mark { font-size: 0.75em; font-weight: 600; color: var(--warn); border: 1px solid currentColor; border-radius: 999px; padding: 0 7px; vertical-align: 2px; }130+.private-mark { font-size: 0.75em; font-weight: 600; color: var(--warn); border: 1px solid currentColor; padding: 0 7px; vertical-align: 2px; }125131 .private-mark:hover { text-decoration: none; }126-.copyrow label { width: 44px; color: var(--muted); font-size: 0.85em; }127-.copyrow input { flex: 1; min-width: 0; font: 13px var(--mono); padding: 4px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--subtle); color: var(--fg); }128-button, .btn { font: inherit; font-size: 0.85em; color: var(--fg); background: var(--subtle); border: 1px solid var(--border); border-radius: 6px; padding: 3px 10px; cursor: pointer; }132+.copyrow label { width: 44px; font: 600 10.5px var(--mono); letter-spacing: 0.08em; color: var(--faint); }133+.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; }129135 button:hover, .btn:hover { background: var(--hover); text-decoration: none; }130136 131137 /* live status */132138 #live { font-size: 0.8em; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40vw; }133-#live span::before { content: ''; display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; }139+#live span::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 6px; vertical-align: 1px; }134140 #live .live-on::before { background: var(--pass); }135141 #live .live-off::before { background: var(--faint); }136142 #live .live-busy { color: var(--warn); }
@@ -138,6 +144,7 @@ button:hover, .btn:hover { background: var(--hover); text-decoration: none; }
138144 @keyframes live-pulse { to { opacity: 0.2; } }139145 140146 main.wrap { padding-top: 20px; padding-bottom: 40px; }147+main.wrap > :first-child { margin-top: 0; }141148 footer.site { color: var(--muted); padding-bottom: 24px; font-size: 0.85em; }142149 button[aria-pressed="true"] { background: var(--hover); border-color: var(--faint); }143150
@@ -146,26 +153,35 @@ button[aria-pressed="true"] { background: var(--hover); border-color: var(--fain
146153 .bar .grow { flex: 1; }147154 .crumbs { font-family: var(--mono); font-size: 0.95em; overflow-wrap: anywhere; }148155 details.picker { position: relative; }149-details.picker > summary { list-style: none; cursor: pointer; border: 1px solid var(--border); border-radius: 6px; padding: 3px 10px; background: var(--subtle); font-size: 0.9em; }156+details.picker > summary { list-style: none; cursor: pointer; border: 1px solid var(--border); padding: 3px 10px; background: var(--subtle); font: 12.5px/1.5 var(--mono); }157+details.picker > summary:hover { background: var(--hover); border-color: var(--faint); }150158 details.picker > summary::-webkit-details-marker { display: none; }151-details.picker #branch-menu { position: absolute; z-index: 10; top: calc(100% + 4px); left: 0; min-width: 220px; max-height: 60vh; overflow: auto; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); display: flex; flex-direction: column; }152-details.picker #branch-menu a { padding: 4px 8px; border-radius: 4px; font-family: var(--mono); font-size: 0.9em; }159+details.picker #branch-menu { position: absolute; z-index: 10; top: calc(100% + 4px); left: 0; min-width: 220px; max-height: 60vh; overflow: auto; background: var(--raised); border: 1px solid var(--border); padding: 4px 0; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); display: flex; flex-direction: column; }160+details.picker #branch-menu a { padding: 4px 12px; font-family: var(--mono); font-size: 0.9em; }153161 details.picker #branch-menu a:hover { background: var(--hover); text-decoration: none; }154162 155-/* lists (tables that restack on phones) */163+/* lists: tables without outer borders, rows between hairlines, headers in164+ small uppercase monospace; they restack on phones */156165 table.list { width: 100%; border-collapse: collapse; }157-table.list th, table.list td { text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--border); vertical-align: top; }158-table.list thead th { font-size: 0.8em; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }166+table.list th, table.list td { text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--border); vertical-align: baseline; }167+table.list thead th { font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); padding-top: 10px; padding-bottom: 6px; }159168 table.list .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }169+table.list td.num, table.list td.date { font: 12.5px/1.6 var(--mono); }170+table.list td.date { color: var(--muted); }171+table.list td.date time { font-size: 1em; }160172 table.list .nowrap, table.list .date, table.list .sha, table.list td.mono { white-space: nowrap; }161173 table.list td.main { width: 100%; overflow-wrap: anywhere; }162174 table.list tbody tr:hover td, table.list tbody tr:focus-within td, table.list tbody tr.sel td { background: var(--hover); }163175 table.list tbody tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--accent); }164-.box { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }165-.box + .box { margin-top: 16px; }166-.box > table.list tr:last-child td { border-bottom: 0; }167-.box-head { background: var(--subtle); border-bottom: 1px solid var(--border); padding: 8px 12px; display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; font-size: 0.92em; }176+/* A box holds a list or prose under a heading row; only a file viewer177+ (.viewer) is a bordered region. */178+.box + .box { margin-top: 24px; }179+.box-head { border-bottom: 1px solid var(--border); padding: 8px; display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline; font-size: 0.92em; }168180 .box-head .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }181+.box-head .label { margin-right: auto; }182+.box.viewer { border: 1px solid var(--border); background: var(--raised); }183+.box.viewer > .box-head { padding: 6px 12px; align-items: center; }184+.box.viewer > table.list tr:last-child td { border-bottom: 0; }169185 .files td.icon { width: 1.5em; color: var(--muted); padding-right: 0; }170186 .files td.size { color: var(--muted); }171187 .empty { color: var(--muted); padding: 24px; text-align: center; }
@@ -185,7 +201,6 @@ table.list tbody tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--accent)
185201 table.list.stack td.main { order: 0; }186202 table.list.stack td.id { order: 1; }187203 .hide-sm { display: none; }188- h2 { font-size: 1.05rem; }189204 }190205 191206 /* statuses and CI */
@@ -210,7 +225,7 @@ table.list tbody tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--accent)
210225 scrolls under it: every gutter cell is opaque, its row's tint (translucent211226 in dark mode) layered over the code's background. --w is the widest line212227 number's digit count, set per file, so the columns never overlap. */213-.code { --lnw: max(3.5em, calc(var(--w, 3) * 1ch + 20px)); font: 12.5px/1.5 var(--mono); tab-size: 4; -moz-tab-size: 4; overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--raised); }228+.code { --lnw: max(3.5em, calc(var(--w, 3) * 1ch + 20px)); font: 12.5px/1.5 var(--mono); tab-size: 4; -moz-tab-size: 4; overflow-x: auto; border: 1px solid var(--border); background: var(--raised); }214229 .code .rows { display: inline-block; min-width: 100%; padding: 4px 0; }215230 .code .l { --gut: transparent; display: flex; color: var(--fg); text-decoration: none; }216231 .code a.l:hover { text-decoration: none; }
@@ -239,17 +254,19 @@ body.wrap-lines .code .hunk { white-space: pre-wrap; overflow-wrap: anywhere; }
239254 body:not(.no-wrap) .code .lc, body:not(.no-wrap) .code .hunk { white-space: pre-wrap; overflow-wrap: anywhere; }240255 body:not(.no-wrap) .code .rows { display: block; }241256 }242-section.file { margin: 16px 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--raised); }243-.file > .code { border: 0; border-radius: 0 0 var(--radius) var(--radius); }244-.box > .code { border: 0; border-radius: 0; }245-.fh { position: sticky; top: 0; z-index: 2; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; padding: 8px 12px; background: var(--raised); border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; font-size: 0.9em; }257+section.file { margin: 16px 0; border: 1px solid var(--border); background: var(--raised); }258+.file > .code { border: 0; }259+.box > .code { border: 0; }260+.fh { position: sticky; top: 0; z-index: 2; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; padding: 8px 12px; background: var(--raised); border-bottom: 1px solid var(--border); font-size: 0.9em; }246261 /* A long path shares the line with the status and counts, wrapping at its247262 slashes, rather than wrapping onto a line of its own. */248263 .fh .fname { font-family: var(--mono); color: var(--fg); font-weight: 600; overflow-wrap: break-word; flex: 1 1 0; min-width: min(4em, 100%); max-width: max-content; }249264 .fh .counts { font-family: var(--mono); font-size: 0.9em; }250-.fh .view { margin-left: auto; font-size: 0.9em; }265+.fh .st { font-size: 0.9em; }266+.fh .view { margin-left: auto; font: 600 10.5px var(--mono); letter-spacing: 0.08em; text-transform: uppercase; }251267 .file .note { margin: 0; padding: 10px 12px; color: var(--muted); }252268 table.diffstat td { padding: 3px 8px; }269+table.diffstat td.num { font-size: 12px; color: var(--muted); }253270 table.diffstat td.graph { font-family: var(--mono); white-space: nowrap; letter-spacing: -1px; }254271 table.diffstat td.main { overflow-wrap: break-word; }255272 table.diffstat td.main a { font-family: var(--mono); font-size: 0.92em; }
@@ -299,9 +316,11 @@ table.diffstat td.main a { font-family: var(--mono); font-size: 0.92em; }
299316 .meta-head { margin: 0 0 16px; }300317 .meta-head h1 { font-size: 1.3rem; margin: 0 0 6px; overflow-wrap: anywhere; }301318 .meta-head .byline { color: var(--muted); font-size: 0.92em; }302-pre.msg { white-space: pre-wrap; overflow-wrap: anywhere; font: 13px/1.5 var(--mono); background: var(--subtle); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin: 12px 0; }303-details.att > summary, details.howto > summary { cursor: pointer; color: var(--muted); font-size: 0.92em; }304-details.att pre, details.howto pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.5 var(--mono); background: var(--subtle); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; }319+pre.msg { white-space: pre-wrap; overflow-wrap: anywhere; font: 13px/1.5 var(--mono); background: var(--subtle); border: 1px solid var(--border); padding: 12px; margin: 12px 0; }320+details.att > summary, details.howto > summary { cursor: pointer; color: var(--muted); font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; padding: 8px 0; }321+details.att > summary:hover, details.howto > summary:hover { color: var(--fg); }322+details.howto > summary .jev-sum { text-transform: none; letter-spacing: 0; font: 13px var(--sans); }323+details.att pre, details.howto pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.5 var(--mono); background: var(--subtle); border: 1px solid var(--border); padding: 10px; }305324 .depth { color: var(--faint); white-space: pre; }306325 307326 /* Above a diff: the diffstat, with the page's tools on its summary line. */
@@ -319,40 +338,40 @@ details.att pre, details.howto pre { white-space: pre-wrap; overflow-wrap: anywh
319338 .fh .fold::before { content: "\25BE"; display: inline-block; transition: transform 0.1s; }320339 .file.folded .fold::before { transform: rotate(-90deg); }321340 .file.folded > :not(.fh) { display: none; }322-.file.folded > .fh { border-bottom: 0; border-radius: var(--radius); }341+.file.folded > .fh { border-bottom: 0; }323342 .file.folded:has(.viewed input:checked) .fname { color: var(--muted); font-weight: normal; }324-.fh .viewed { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--muted); font-size: 0.9em; cursor: pointer; user-select: none; -webkit-user-select: none; }343+.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; }325344 .fh .view ~ .viewed { margin-left: 0; }326345 .fh .viewed:has(input:checked) { color: var(--fg); }327346 .fh .viewed input { margin: 0; }328347 329348 /* prose: README, wiki, rendered markdown */330-.markdown { font-size: 1rem; line-height: 1.6; overflow-wrap: break-word; padding: 8px 24px 16px; }331-.box > .markdown { padding: 16px 24px; }349+.markdown { font-size: 1rem; line-height: 1.6; overflow-wrap: break-word; padding: 16px 8px; }332350 .markdown > :first-child { margin-top: 0; }333351 .markdown h1, .markdown h2 { border-bottom: 1px solid var(--border); padding-bottom: 0.3em; }334352 .markdown h1 { font-size: 1.8em; margin: 0.8em 0 0.5em; }335-.markdown h2 { font-size: 1.4em; margin: 1.4em 0 0.6em; }353+.markdown h2 { display: block; font: 600 1.4em/1.25 var(--sans); letter-spacing: normal; text-transform: none; color: var(--fg); margin: 1.4em 0 0.6em; }336354 .markdown h3 { font-size: 1.15em; }355+.markdown a:visited { color: var(--deep); }337356 .markdown img { max-width: 100%; height: auto; }338357 .markdown p[align="center"], .markdown div[align="center"] { text-align: center; }339-.markdown code { font-size: 0.875em; background: var(--subtle); border-radius: 4px; padding: 0.15em 0.35em; }340-.markdown pre { font: 13px/1.5 var(--mono); background: var(--subtle); border-radius: var(--radius); padding: 12px 14px; overflow-x: auto; tab-size: 4; }341-.markdown pre code { background: none; padding: 0; font-size: 1em; }342-.markdown pre.mermaid { background: none; text-align: center; }343-.markdown blockquote { margin: 1em 0; padding: 0 1em; color: var(--muted); border-left: 4px solid var(--border); }358+.markdown code { font-size: 0.875em; background: var(--subtle); border: 1px solid var(--border); padding: 0.05em 0.3em; }359+.markdown pre { font: 13px/1.5 var(--mono); background: var(--subtle); border: 1px solid var(--border); padding: 12px 14px; overflow-x: auto; tab-size: 4; }360+.markdown pre code { background: none; border: 0; padding: 0; font-size: 1em; }361+.markdown pre.mermaid { background: none; border: 0; text-align: center; }362+.markdown blockquote { margin: 1em 0; padding: 0 1em; color: var(--muted); border-left: 3px solid var(--border); }344363 .markdown table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; margin: 1em 0; }345-.markdown th, .markdown td { border: 1px solid var(--border); padding: 6px 12px; text-align: left; vertical-align: top; }346-.markdown th { background: var(--subtle); font-weight: 600; }347-.markdown hr { border-top: 2px solid var(--border); }364+.markdown th, .markdown td { border-bottom: 1px solid var(--border); padding: 6px 12px 6px 0; text-align: left; vertical-align: top; }365+.markdown th { font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); padding-top: 8px; }366+.markdown hr { border-top: 1px solid var(--border); }348367 .markdown :target { scroll-margin-top: 16px; }349368 @media (max-width: 720px) {350- .markdown, .box > .markdown { padding: 12px 14px; font-size: 0.97rem; }369+ .markdown { padding: 12px 4px; font-size: 0.97rem; }351370 .markdown h1 { font-size: 1.5em; }352371 .markdown h2 { font-size: 1.25em; }353372 }354373 /* jev: commits and repos */355-.jev-kind, .jev-topic { display: inline-block; padding: 0 6px; border: 1px solid var(--border); border-radius: 999px; font-size: 0.75rem; line-height: 1.5; font-weight: 500; color: var(--muted); white-space: nowrap; vertical-align: 1px; }374+.jev-kind, .jev-topic { display: inline-block; padding: 0 6px; border: 1px solid var(--border); font-size: 0.75rem; line-height: 1.5; font-weight: 500; color: var(--muted); white-space: nowrap; vertical-align: 1px; }356375 .jev-kind.feat { color: var(--pass); }357376 .jev-kind.fix { color: var(--merged); }358377 /* Jev's risk score, 0 to 3: a small number, colored once it is moderate. */
@@ -371,16 +390,17 @@ table.log td.risk { width: 1%; }
371390 table.log td.kind { order: 1; }372391 table.log td.kind:empty { display: none; }373392 }374-.releases-link { margin-left: 8px; font-size: 0.8rem; font-weight: normal; }375-.notes { padding: 2px 16px 12px; font-size: 0.95em; }376-.notes h3 { margin: 12px 0 4px; font-size: 0.9rem; }393+.releases-link { margin-left: 4px; }394+.notes { padding: 2px 8px 12px; font-size: 0.95em; }395+.notes h3 { margin: 14px 0 4px; font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }377396 .notes ul { margin: 0; padding-left: 20px; }378397 .notes li { margin: 2px 0; overflow-wrap: anywhere; }379398 .notes details { margin-top: 12px; }380-.notes summary { cursor: pointer; font-size: 0.9rem; font-weight: 600; color: var(--muted); }399+.notes summary { cursor: pointer; font: 600 10.5px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }400+.notes summary:hover { color: var(--fg); }381401 382402 /* jev: review pages */383-.jev-mech, .jev-change { display: inline-block; padding: 0 6px; border: 1px dashed currentColor; border-radius: 999px; font-size: 0.75rem; line-height: 1.5; font-weight: 500; color: var(--muted); white-space: nowrap; }403+.jev-mech, .jev-change { display: inline-block; padding: 0 6px; border: 1px dashed currentColor; font-size: 0.75rem; line-height: 1.5; font-weight: 500; color: var(--muted); white-space: nowrap; }384404 .jev-change.behavior, .jev-sum.behavior { color: var(--warn); }385405 .jev-sum { font-size: 0.9em; color: var(--muted); }386406 summary .jev-sum { margin-left: 6px; font-weight: normal; }
M site/repo/blob.njk +1 -1
M site/repo/commit.njk +2 -2
M site/repo/home.njk +1 -1
M site/repo/releases.njk +2 -2
M site/repo/review-diff.njk +13 -10
@@ -12,30 +12,33 @@ pagination:
1212 {% block content %}1313 {% css %}1414 /* Line comments under their lines; they look like the discussion's (discussion.njk). */15-.cmt { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }16-.cmt:target { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }17-.cmt-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding: 6px 12px; background: var(--subtle); border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; font-size: 0.9em; }15+.cmt { border-top: 1px solid var(--border); }16+.cmt:target { box-shadow: inset 3px 0 0 var(--accent); }17+.cmt-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 8px 12px 0; font-size: 0.9em; }18+.cmt-head a, .cmt-head .date { font: 12px var(--mono); }19+.cmt-head time { font-size: 1em; }1820 .cmt-head a { color: var(--muted); }19-.cmt .markdown { padding: 8px 12px; font-size: 0.95rem; line-height: 1.55; }21+.cmt .markdown { padding: 4px 12px 8px; font-size: 0.95rem; line-height: 1.55; }2022 .cmt .markdown > :last-child { margin-bottom: 0; }2123 /* In a diff, a comment is as wide as the code box, not its longest line. */2224 .code:has(.cmts) { container-type: inline-size; }23-.code .cmts { position: sticky; left: 0; width: 100cqw; padding: 8px 10px; background: var(--subtle); border-block: 1px solid var(--border); font: 15px/1.5 var(--sans); white-space: normal; }24-.cmt + .cmt { margin-top: 8px; }25+.code .cmts { position: sticky; left: 0; width: 100cqw; padding: 0 10px 8px; background: var(--bg); border-block: 1px solid var(--border); font: 15px/1.5 var(--sans); white-space: normal; }26+.code .cmts > .cmt:first-child { border-top: 0; }27+.code .cmts > form { padding-top: 8px; }2528 /* A new line comment, signed in (discuss.ts): the + on the line under the2629 pointer (or the line last clicked) opens a form under it. */2730 .commenting .code.diff .rows { position: relative; }28-.addline { position: absolute; z-index: 2; width: 20px; height: 17px; padding: 0; font: 600 13px/15px var(--sans); text-align: center; color: #fff; background: var(--accent); border-color: var(--accent); border-radius: 4px; }29-.addline:hover { background: var(--accent); filter: brightness(1.1); }31+.addline { position: absolute; z-index: 2; width: 20px; height: 17px; padding: 0; font: 600 13px/15px var(--sans); letter-spacing: 0; text-align: center; color: #fff; background: var(--accent); border-color: var(--accent); }32+.addline:hover { color: #fff; background: var(--deep); border-color: var(--deep); }3033 .cmts .where { font: 12px/1.6 var(--mono); color: var(--muted); margin-bottom: 4px; overflow-wrap: anywhere; }31-.cmts textarea { display: block; width: 100%; min-height: 5em; resize: vertical; font: 14px/1.5 var(--sans); color: var(--fg); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; }34+.cmts textarea { display: block; width: 100%; min-height: 5em; resize: vertical; font: 14px/1.5 var(--sans); color: var(--fg); background: var(--raised); border: 1px solid var(--border); padding: 8px 10px; }3235 .cmts textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }3336 .cmts .reply-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; font-size: 0.92em; }3437 .cmts .reply-bar .grow { flex: 1; }3538 .cmts .reply-bar button.go { background: var(--accent); border-color: var(--accent); color: #fff; }3639 .cmts .reply-bar button:disabled { opacity: 0.6; cursor: default; }3740 .cmts .reply-status.bad { color: var(--fail); white-space: pre-line; }38-.cmt.pending { border-style: dashed; }41+.cmt.pending { border-top-style: dashed; }3942 .cmt.pending .text { padding: 8px 12px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--muted); }4043 {% endcss %}4144 <div class="meta-head">
M site/repo/review.njk +5 -5
@@ -12,22 +12,22 @@ pagination:
1212 {% endblock %}1313 {% block content %}1414 {% css %}15-.review-desc { margin: 0 0 16px; }15+.review-desc { margin: 0 0 16px; border-block: 1px solid var(--border); }1616 .review-desc .markdown > :last-child { margin-bottom: 0; }1717 .stacked { margin-top: 28px; }18-.stacked > h3 { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; margin: 0 0 4px; font-size: 1rem; }19-.stacked > h3 .step { color: var(--muted); font-weight: normal; font-family: var(--mono); font-size: 0.9em; }18+.stacked > h3 { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; margin: 0 0 4px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 1rem; }19+.stacked > h3 .step { color: var(--faint); font: 600 11px var(--mono); letter-spacing: 0.08em; }2020 #stack tr.this td { font-weight: 600; }2121 /* The sticky bar: layers of the stack, commits of the layer. It has a fixed2222 height so file headers can stick right below it. */23-.revnav { position: sticky; top: 0; z-index: 3; height: 2.75rem; display: flex; align-items: center; gap: 12px; margin: 28px 0 0; background: var(--bg); border-bottom: 1px solid var(--border); white-space: nowrap; overflow-x: auto; scrollbar-width: none; font-size: 0.9em; }23+.revnav { position: sticky; top: 0; z-index: 3; height: 2.75rem; display: flex; align-items: center; gap: 12px; margin: 28px 0 0; background: var(--bg); border-bottom: 1px solid var(--border); white-space: nowrap; overflow-x: auto; scrollbar-width: none; font: 12px var(--mono); }2424 .revnav::-webkit-scrollbar { display: none; }2525 @media (max-width: 480px) {2626 .revnav { gap: 8px; }2727 .revnav .seg > * { padding: 3px 8px; }2828 .revnav .n { display: none; }2929 }30-.revnav .seg { display: inline-flex; align-items: stretch; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }30+.revnav .seg { display: inline-flex; align-items: stretch; border: 1px solid var(--border); background: var(--subtle); overflow: hidden; }3131 .revnav .seg > * { padding: 3px 10px; }3232 .revnav .seg > .at { color: var(--fg); border-inline: 1px solid var(--border); font-variant-numeric: tabular-nums; }3333 .revnav .seg > a:hover { background: var(--hover); text-decoration: none; }
M site/repo/reviews.njk +4 -5
M site/repo/revision.njk +4 -4
@@ -11,15 +11,15 @@ pagination:
1111 {% block content %}1212 {% css %}1313 /* range-diff: a block per pair of commits */14-.pk { font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 0 5px; border: 1px solid currentColor; border-radius: 4px; }14+.pk { font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 0 5px; border: 1px solid currentColor; }1515 .pk.same { color: var(--muted); }1616 .pk.changed { color: var(--warn); }1717 .pk.add { color: var(--add-fg); }1818 .pk.del { color: var(--del-fg); }1919 .subj { font-weight: 600; overflow-wrap: anywhere; }20-.pairrow { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 12px 0; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.9em; }21-details.pairs { margin: 12px 0; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.9em; }22-details.pairs > summary { cursor: pointer; color: var(--muted); }20+.pairrow { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0; padding: 8px; border-bottom: 1px solid var(--border); font-size: 0.9em; }21+details.pairs { margin: 0; padding: 8px; border-bottom: 1px solid var(--border); font-size: 0.9em; }22+details.pairs > summary { cursor: pointer; color: var(--muted); font: 600 11px/1.4 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; }2323 details.pairs .pairrow { margin: 0; padding: 6px 0 0; border: 0; }2424 .pair .fh .subj { color: var(--fg); }2525
M site/repo/wiki.njk +7 -4