From 6ff8b0151c09d25571caec60d186f4adc6ae3752 Mon Sep 17 00:00:00 2001
From: Claude
Date: Thu, 22 Oct 2026 09:09:47 +0000
Subject: [PATCH 1/5] Review follow-up 6: the matrix on desktop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The table comes straight after the head; the status key and the count sit
under it, and the filters fold into one button on the head's meta line.
The revision is named once. On wide screens the table fits the column:
a group whose label outgrows its columns takes the label's width, so the
clipped "Tra…" and the two groups hidden past the frame edge are gone.
Co-Authored-By: Claude Opus 5.5 (1M context)
Claude-Session: https://claude.ai/code/session_01KerMxC6ZiZWQwLScvy8Ym4
---
specs/016-visual-redesign/tasks.md | 1 +
src/components/Matrix.svelte | 16 ++-
src/components/MatrixPage.astro | 189 +++++++++++++++--------------
src/components/MatrixTable.astro | 62 +++++++++-
4 files changed, 175 insertions(+), 93 deletions(-)
diff --git a/specs/016-visual-redesign/tasks.md b/specs/016-visual-redesign/tasks.md
index 4e501e0..955f326 100644
--- a/specs/016-visual-redesign/tasks.md
+++ b/specs/016-visual-redesign/tasks.md
@@ -167,3 +167,4 @@ Items from the redesign review, one pull request each, in order.
- [x] R-03 Nav wording: the primary and footer navigation read Servers, Standards, Explorer, Breaches, Contribute (Scanner stays in the footer); every `` trail, the page-foot cross link on `/standards/` and the 404 buttons use the same words; `/mcp/` and `/standards/` take Servers and Standards as `` and eyebrow. "Atlas" stays the product word in ledes and body copy
- [x] R-04 Standards map rework (PR #62): the head is "The standards map" with the counts in the lede. A rail beside the drawing is legend, filter and reading pane in one: relation types as line-sample toggles (references off by default), publishing bodies as toggles (a band label in the drawing toggles the same), maturity chips, the live count, a reset, and a card that names the hovered or focused node's relations in words. The toggles are checkboxes that filter the drawing and the outline through `:has()` rules in the stylesheet, so filtering works without JavaScript; the island keeps the count, mirrors the state in the URL, shows the card and highlights the neighbourhood. "Recently revised" is a view of the map (dated nodes, the rest fades), not a list in the head. The drawing is laid out by `elkjs` at build time (`src/lib/graph.ts`): a spec sits a column right of what it builds on, columns group by body behind tinted bands, dependency edges are routed orthogonally, cross links stay curves. Below 40rem the drawing gives way to `StandardsOutline.astro`: the dependency forest (`buildForest`) as an indented outline, cross links as `` chips, the spine as a hairline; the outline replaces the flat list on every screen and carries body, family, revision and both links (FR-015). Baselines through the `refresh-screenshots` label
- [x] R-05 Matrix on phones: below 40rem the matrix is read one way at a time instead of the desktop table squeezed. A row of plain anchors (All and one per requirement group, with counts) picks the view through `:target`, so it works without JavaScript and every group stays in the HTML; the island turns the choice into `data-view` with `aria-current`, so switching keeps the scroll and adds no history entry. "All" draws every requirement as a strip of small glyphs per server, sized from the column with container units, so the whole atlas fits without sideways scroll; its glyphs are a picture and a group's view opens them. A group shows its own columns (one generated `nth-child` range each) with two-line horizontal labels instead of `vertical-rl`, two and a half columns in view so the next one peeks in, and scroll shadows at the frame edges. The server column is 7rem, names wrap to two lines and link to the server page, the transposed view. Desktop is unchanged. Baselines through the `refresh-screenshots` label
+- [x] R-06 Matrix on desktop: the table comes straight after the head, and the status key and the live count sit under it. "Filter and group" folds into one quiet button at the end of the head's meta line; opened, the form runs under the whole line. The revision is named once, in the meta line: the lede says "the MCP Authorization specification", the link to its text is "Specification text", and the published date shows only when it differs from the revision id. On wide screens the table fits the column instead of scrolling past its edge (at 1440 px three groups were hidden behind a clipped "Tra…"): its widths come from the group row, a group whose label is wider than its columns (`data-narrow`, from an estimate of the label's length) takes the label's width, and the other columns share the rest down to a 2.25rem floor, below which the frame scrolls. The island redoes the sums when a filter changes the groups. Phones keep R-05. Baselines through the `refresh-screenshots` label
diff --git a/src/components/Matrix.svelte b/src/components/Matrix.svelte
index 5270526..d8d0c7d 100644
--- a/src/components/Matrix.svelte
+++ b/src/components/Matrix.svelte
@@ -13,6 +13,8 @@ let opener: HTMLElement | null = null;
const PARAMS = ["level", "category", "party", "q", "access", "auth", "group"] as const;
type Param = (typeof PARAMS)[number];
+// the width in rem below which a group's label counts as wider than its columns (MatrixTable)
+const NARROW_COLUMN_REM = 2.75;
onMount(() => {
const table = document.getElementById("matrix");
@@ -117,10 +119,20 @@ onMount(() => {
perCategory.set(c, (perCategory.get(c) ?? 0) + 1);
}
}
+ // on wide screens a group whose label outgrows its columns takes the label's width
+ let narrowRem = 0;
+ let wideCols = 0;
for (const gh of groupHeads) {
const n = perCategory.get(gh.dataset.category ?? "") ?? 0;
gh.hidden = n === 0;
- if (n > 0) gh.colSpan = n;
+ if (n === 0) continue;
+ gh.colSpan = n;
+ gh.style.setProperty("--n", String(n));
+ const label = Number(gh.dataset.labelRem ?? 0);
+ const narrow = label > n * NARROW_COLUMN_REM;
+ gh.toggleAttribute("data-narrow", narrow);
+ if (narrow) narrowRem += label;
+ else wideCols += n;
}
const featureKey = [...visibleFeatures].join(" ");
const columnsChanged = featureKey !== shownFeatures;
@@ -141,6 +153,8 @@ onMount(() => {
if (columnsChanged) {
// the table's layout is fixed: its width and the feature column follow the columns shown
table.style.setProperty("--cols", String(visibleFeatures.size));
+ table.style.setProperty("--wide-cols", String(wideCols));
+ table.style.setProperty("--narrow-w", `${narrowRem}rem`);
if (featureCol) featureCol.span = Math.max(visibleFeatures.size, 1);
}
regroup(s.group, visibleFeatures.size);
diff --git a/src/components/MatrixPage.astro b/src/components/MatrixPage.astro
index 9d69a9d..c2fe9c9 100644
--- a/src/components/MatrixPage.astro
+++ b/src/components/MatrixPage.astro
@@ -68,20 +68,24 @@ const classWords = (counts: { value: string; count: number }[], label: RecordServers
Who supports what in MCP Authorization
- The public MCP servers we list, against what MCP Authorization {matrix.revision.id} requires
+ The public MCP servers we list, against what the MCP Authorization specification requires
of servers and their authorization servers. Each cell opens the observation behind it.
-
+
Revision {matrix.revision.id}{" "}
{isCurrent ? "current" : matrix.revision.status}
-
- published
-
- {spec.name} {matrix.revision.id}
+ {
+ matrix.revision.date !== matrix.revision.id && (
+
+ published
+
+ )
+ }
+ Specification textAbout this specification
{
revisions
@@ -93,73 +97,76 @@ const classWords = (counts: { value: string; count: number }[], label: RecordWhat changed since {diff.from.id}}
-
+
+ Filter and group
+
+
+
-
-
- Filter and group
-
-
+
+
+
+
{
STATUS_ORDER.map((s) => (
@@ -172,15 +179,12 @@ const classWords = (counts: { value: string; count: number }[], label: Record
-
+
{matrix.rows.length} of {matrix.rows.length} servers, {matrix.columns.length} of{" "}
{matrix.columns.length} features
-
-
-
MUST, SHOULD
@@ -277,16 +281,11 @@ const classWords = (counts: { value: string; count: number }[], label: Record summary {
list-style: none;
@@ -303,18 +302,32 @@ const classWords = (counts: { value: string; count: number }[], label: Record summary::after {
margin-top: 0.2em;
rotate: -135deg;
}
.filters[open] > .toolbar {
+ align-self: stretch;
margin: var(--space-3) 0 0;
+ color: var(--ink);
+ }
+
+ /* under the matrix: the status key and the live count */
+ .matrix-key {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--space-3) var(--space-5);
+ margin: var(--space-4) 0 0;
}
- .matrix-bar__count {
+ .matrix-key__count {
margin: 0 0 0 auto;
}
@@ -403,10 +416,10 @@ const classWords = (counts: { value: string; count: number }[], label: Record `:nth-child(${r.from + 1})`)
.join(",")}){border-left:1px solid var(--rule)}}}`;
+/*
+ * Wide screens (follow-up 6): the table fits the column instead of scrolling past its edge. A
+ * group whose label is wider than its columns, such as a one-column "Transport", takes the
+ * label's width; the other columns share what is left. The label width is an estimate from its
+ * length in --tiny Geist, a little generous; the island redoes the sums when a filter changes
+ * the groups.
+ */
+const NARROW_COLUMN_REM = 2.75;
+const labelOf = (c: string) => CATEGORY_LABEL[c as keyof typeof CATEGORY_LABEL] ?? c;
+const labelRem = (c: string) => Math.ceil((labelOf(c).length * 0.42 + 0.875) * 4) / 4;
+const narrow = groups.filter((g) => labelRem(g.category) > g.count * NARROW_COLUMN_REM);
+const narrowRem = narrow.reduce((sum, g) => sum + labelRem(g.category), 0);
+const wideCols = columns.length - narrow.reduce((sum, g) => sum + g.count, 0);
+
const changedIds = new Map(diff?.changed.map((c) => [c.feature.id, c]) ?? []);
const addedIds = new Set(diff?.added.map((f) => f.id) ?? []);
const changesHref = diff ? `/mcp/changes/${diff.from.id}/${diff.to.id}/` : undefined;
@@ -87,7 +101,7 @@ const shortLabel = (id: string) => id.split(".").slice(2).join(".") || id;
class="matrix"
id="matrix"
data-matrix-revision={revision.id}
- style={`--cols: ${columns.length}`}
+ style={`--cols: ${columns.length}; --wide-cols: ${wideCols}; --narrow-w: ${narrowRem}rem`}
>
Support for each feature of MCP Authorization {revision.id} by server. Rows are servers in
@@ -102,8 +116,15 @@ const shortLabel = (id: string) => id.split(".").slice(2).join(".") || id;
{
groups.map((g) => (
-
- {CATEGORY_LABEL[g.category as keyof typeof CATEGORY_LABEL] ?? g.category}
+
+ {labelOf(g.category)}
))
}
@@ -629,6 +650,36 @@ const shortLabel = (id: string) => id.split(".").slice(2).join(".") || id;
translate: none;
}
+ /*
+ * Wide screens: the table fits the column. Its widths come from the group row, so a group
+ * whose label needs more room than its columns (data-narrow) takes the label's width, and
+ * the other columns share the rest, down to a floor below which the frame scrolls.
+ */
+ @media (width > 40rem) {
+ .matrix {
+ --feature-w: max(
+ 2.25rem,
+ calc((100cqi - var(--server-w) - var(--narrow-w, 0rem)) / var(--wide-cols, var(--cols)))
+ );
+ width: calc(
+ var(--server-w) + var(--wide-cols, var(--cols)) * var(--feature-w) + var(--narrow-w, 0rem)
+ );
+ }
+
+ .matrix .matrix__feature-col {
+ width: auto;
+ }
+
+ .matrix .groups th {
+ width: calc(var(--n, 1) * var(--feature-w));
+ }
+
+ .matrix .groups th[data-narrow] {
+ width: var(--label);
+ padding-inline: var(--space-1);
+ }
+ }
+
/* the group picker and its hint exist for phones only */
.matrix-tabs,
.matrix-tabs__hint {
@@ -642,10 +693,13 @@ const shortLabel = (id: string) => id.split(".").slice(2).join(".") || id;
* peek of the next column and shadows at the edges that scroll. The names link to the server
* page, which is the same data transposed. .matrix-view:is([data-view="all"], :not([data-view]):not(:has(.matrix-tabs a:not(#mx-all):target))) is the "All" view, .matrix-view:is([data-view]:not([data-view="all"]), :not([data-view]):has(.matrix-tabs a:not(#mx-all):target)) a group's.
*/
+ .matrix-view {
+ container-type: inline-size;
+ }
+
@media (max-width: 40rem) {
.matrix-view {
--server-w: 7rem;
- container-type: inline-size;
}
.matrix-tabs {
From 2c71d96fd6a29a4b2a22fb77fab5748026552b2e Mon Sep 17 00:00:00 2001
From: Claude
Date: Thu, 22 Oct 2026 09:09:47 +0000
Subject: [PATCH 2/5] PR screenshots (removed in the next commit)
Co-Authored-By: Claude Opus 5.5 (1M context)
Claude-Session: https://claude.ai/code/session_01KerMxC6ZiZWQwLScvy8Ym4
---
pr-shots/matrix6-after-desktop-dark-below.png | Bin 0 -> 147899 bytes
pr-shots/matrix6-after-desktop-dark.png | Bin 0 -> 149541 bytes
pr-shots/matrix6-after-desktop-light-below.png | Bin 0 -> 147766 bytes
pr-shots/matrix6-after-desktop-light.png | Bin 0 -> 149128 bytes
pr-shots/matrix6-after-phone-dark.png | Bin 0 -> 315868 bytes
pr-shots/matrix6-after-phone-light.png | Bin 0 -> 315016 bytes
pr-shots/matrix6-before-desktop-dark-below.png | Bin 0 -> 138139 bytes
pr-shots/matrix6-before-desktop-dark.png | Bin 0 -> 156315 bytes
.../matrix6-before-desktop-light-below.png | Bin 0 -> 137888 bytes
pr-shots/matrix6-before-desktop-light.png | Bin 0 -> 156156 bytes
pr-shots/matrix6-before-phone-dark.png | Bin 0 -> 280476 bytes
pr-shots/matrix6-before-phone-light.png | Bin 0 -> 279347 bytes
12 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 pr-shots/matrix6-after-desktop-dark-below.png
create mode 100644 pr-shots/matrix6-after-desktop-dark.png
create mode 100644 pr-shots/matrix6-after-desktop-light-below.png
create mode 100644 pr-shots/matrix6-after-desktop-light.png
create mode 100644 pr-shots/matrix6-after-phone-dark.png
create mode 100644 pr-shots/matrix6-after-phone-light.png
create mode 100644 pr-shots/matrix6-before-desktop-dark-below.png
create mode 100644 pr-shots/matrix6-before-desktop-dark.png
create mode 100644 pr-shots/matrix6-before-desktop-light-below.png
create mode 100644 pr-shots/matrix6-before-desktop-light.png
create mode 100644 pr-shots/matrix6-before-phone-dark.png
create mode 100644 pr-shots/matrix6-before-phone-light.png
diff --git a/pr-shots/matrix6-after-desktop-dark-below.png b/pr-shots/matrix6-after-desktop-dark-below.png
new file mode 100644
index 0000000000000000000000000000000000000000..55321e2efd77cbc9091349d5ad4e245264885791
GIT binary patch
literal 147899
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