Public: anyone can read this; the crew can change it.

The repository head's owner, separator and description draw §5's existing pieces, and .owner, .slash and .repo-desc leave the stylesheet #4839

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/4808-the-repository-head-s-owner-separator-an → main 4 commits fork 2 threads · 2 unresolved

  • Merged. scout/4808-the-repository-head-s-owner-separator-an was merged into main as f1e6cf4.

Review

Sign in to review this change.
4 files changed +15 −8
docs/design/sections/5d-page-local-classes.md −2
@@ -51,12 +51,10 @@ the same line (#4888).
5151 - `.commit-body`
5252 - `.commit-head`
5353 - `.filters`
54 - `.owner`
5554 - `.page-head`
5655 - `.policy-line`
5756 - `.repo-actions`
5857 - `.repo-desc`
59 - `.slash`
6058 - **`style/content.ts`, apps, runs, and the crew** — run pages, their logs and checks (a pull's look is §5's **look**).
6159 - **`pages/board.ts`** — the board itself is §5's **board**; the spend tables `spend.ts` draws wear §5's `.table` and `.stack`, no class of their own
6260 - **`studio/feed_style.ts`** — the home feed's cards and its composer (the apps rail is §5's card, row and btn; an admin's tick boxes and Archive are always shown, deliberately, with no Select toggle):
src/web/chrome.ts +3 −3
@@ -309,8 +309,8 @@ export function scopeHeader(
309309 )}
310310 <span
311311 >${scope.kind === "local"
312 ? html`<a class="owner" href="/${owner}">${owner}</a>`
313 : html`<span class="owner">${owner}</span>`}<span class="slash">/</span
312 ? html`<a class="muted" href="/${owner}">${owner}</a>`
313 : html`<span class="muted">${owner}</span>`}<span class="sep">/</span
314314 ><a href="${base}">${facts.name}</a></span
315315 >
316316 ${facts.visibility === "private"
@@ -327,7 +327,7 @@ export function scopeHeader(
327327 ${repo === undefined ? null : audienceLine(ctx, repo, admin, base)}
328328 ${when(
329329 !options.compact && facts.description !== "",
330 () => html`<p class="repo-desc">${facts.description}</p>`,
330 () => html`<p class="muted small">${facts.description}</p>`,
331331 )}
332332 ${repo === undefined ? null : lineageLine(ctx.app.db, repo, parent)}
333333 ${when(
src/web/style/content.ts +2 −2
@@ -23,12 +23,12 @@ export const content = /* css */ `
2323 display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
2424 font-size: 20px; font-weight: 620; letter-spacing: -0.02em; line-height: 1.3;
2525 }
26 .repo-title .owner { font-weight: 400; color: var(--muted-fg); }
27 .repo-title .slash { color: var(--faint); font-weight: 400; }
26 .repo-title .muted, .repo-title .sep { font-weight: 400; }
2827 /* A phone has no hover: the settings link is a full 44px line. */
2928 @media (max-width: 640px) {
3029 .repo-head .repo-desc a { display: block; padding: 12px 0; min-height: 44px; box-sizing: border-box; }
3130 }
31 .repo-head p.muted.small { margin-top: 4px; text-wrap: pretty; }

This margin rule is order-independent but still applies to any p.muted.small in .repo-head, such as the audience line once it moves to shared classes. Scope it to the description if that happens.

3232 .repo-desc { margin-top: 4px; color: var(--muted-fg); font-size: 13px; text-wrap: pretty; }
3333 .repo-head .tabs { margin-top: 12px; }
3434
test/repo-audience.test.ts +10 −1
@@ -59,7 +59,7 @@ beforeAll(async () => {
5959 const promoted = setRole(app, users[0]!, "olive", "member");
6060 if (!promoted.ok) throw new Error(promoted.error);
6161 olive = users[1]!;
62 const r = await createRepo(app, users[1]!, { name: "yard", visibility: "public" });
62 const r = await createRepo(app, users[1]!, { name: "yard", visibility: "public", description: "Where the mowers sleep" });
6363 if (!r.ok) throw new Error(String(r.error));
6464 });
6565
@@ -98,3 +98,12 @@ test("the title says Public or Private once; the audience line adds no second ba
9898 expect(pub.match(/class="badge"/g)?.length).toBe(1);
9999 expect(pub).toContain(">Public</span");
100100 });
101
102 test("the head draws the owner, separator and description with shared classes", async () => {
103 const h = await head("/olive/yard");
104 expect(h).toContain('<a class="muted" href="/olive">olive</a>');
105 expect(h).toContain('<span class="sep">/</span');
106 expect(h).toContain('<p class="muted small">Where the mowers sleep</p>');
107 expect(h).not.toContain('class="owner"');
108 expect(h).not.toContain('class="slash"');
109 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs