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

The home figures share one formatting module, wrap on a phone, and say the live version once #2910

Merged opened this

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

Merged

mason/forge:mason/2881-the-home-figures-share-one-formatting-mo → main 1 commit fork 1 thread · 1 unresolved

  • Merged. mason/2881-the-home-figures-share-one-formatting-mo was merged into main as 1356ead.

Review

Sign in to review this change.
2 files changed +12 −3
src/web/studio/feed_style.ts +3 −3
@@ -24,12 +24,12 @@ export const feedCss = /* css */ `
2424 .composer textarea { width: 100%; min-height: 64px; resize: vertical; }
2525 .composer-bar { display: flex; align-items: center; gap: 8px; min-width: 0; }
2626 .composer-bar select { min-width: 0; max-width: 60%; }
27 /* The figures row: three cards at a fixed height, so first paint is final. */
27 /* The figures row: three cards at a fixed height, so first paint is final; the note wraps into two reserved lines. */
2828 .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 12px; }
29 .kpi { display: grid; grid-template-rows: 20px 32px 20px 24px; align-content: start; gap: 2px; padding: 12px 14px; color: inherit; text-decoration: none; }
29 .kpi { display: grid; grid-template-rows: 20px 32px 40px 24px; align-content: start; gap: 2px; padding: 12px 14px; color: inherit; text-decoration: none; }
3030 .kpi:hover { border-color: var(--border-strong); }
3131 .kpi-value { font-size: 16px; line-height: 32px; font-weight: 600; }
32 .kpi-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
32 .kpi-note { line-height: 20px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow-wrap: anywhere; }

This is a deliberate departure from DESIGN's "one line, ellipsis, title" rule. The two-line clamp still ends in an ellipsis and keeps the full title, so it stays honest. Record the exception in docs/DESIGN.md.

3333 .kpi-spark { display: block; color: var(--muted-fg); max-width: 100%; }
3434 /* Your apps: a narrow column on a desk, a tab away on a phone. */
3535 .home-tabs { display: none; margin-bottom: 12px; }
test/home-kpi-row.test.ts +9
@@ -2,6 +2,7 @@
22 import { describe, expect, test } from "bun:test";
33 import { checkTime, kpiLines, sparkText } from "../src/flow/kpi_words.ts";
44 import { running } from "../src/kernel/version.ts";
5 import { feedCss } from "../src/web/studio/feed_style.ts";
56 import { kpiRowFor, liveNow, sparkline } from "../src/web/studio/kpi_row.ts";
67
78 const hours = (n: number) => Array.from({ length: 24 }, (_, i) => (i === 3 ? n : 0));
@@ -70,6 +71,14 @@ describe("home kpi row", () => {
7071 expect(out).toContain('title="No check finished in 24 h"');
7172 });
7273
74 test("the note wraps into two reserved lines instead of cutting off on a phone", () => {
75 const rule = (sel: string) => new RegExp(`\\${sel} \\{([^}]*)\\}`).exec(feedCss)![1]!;
76 expect(rule(".kpi-note")).not.toContain("nowrap");
77 expect(rule(".kpi-note")).toContain("line-height: 20px");
78 expect(rule(".kpi-note")).toContain("line-clamp: 2");
79 expect(rule(".kpi")).toContain("grid-template-rows: 20px 32px 40px 24px");
80 });
81
7382 test("check time reads as a person would", () => {
7483 expect(checkTime(null)).toBe("—");
7584 expect(checkTime(45_000)).toBe("45s");

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs