@expressivecss/mcp-server 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "frameworkVersion": "0.14.1",
4
- "sourceRevision": "e48e958c184d2de2a972028a06c3a03e0e802197",
3
+ "frameworkVersion": "0.16.0",
4
+ "sourceRevision": "165ce2c04e03d738503898ca7eb5a34f565d668f",
5
5
  "basis": "Reviewed checkout snapshot, not proof of published package contents or target-browser conformance. Implemented means only the named scope. Full Material parity remains unassessed.",
6
6
  "browserRun": {
7
7
  "recordedOn": "2026-10-10",
@@ -239,6 +239,12 @@
239
239
  "name": "Panes preserve compact selection and independent scrolling (chromium)",
240
240
  "scope": "Active selection and first-pane fallback through resizing, independent body scrolling, DOM order, translated footer actions at enlarged root text size, both directions and motion preferences. Not native zoom or screen-reader verification.",
241
241
  "state": "stale"
242
+ },
243
+ {
244
+ "file": "tests/pane-resize-browser.test.js",
245
+ "name": "chromium: a drag handle between panes resizes by pointer, keyboard and click",
246
+ "scope": "Handle placed in the spacer column, pointer drag, arrow, Shift, Home and End keys, click and Enter stepping, the other pane's minimum, the supporting-pane token, RTL direction, hiding below 840px and named buttons. No spoken-output assertion.",
247
+ "state": "not-recorded"
242
248
  }
243
249
  ],
244
250
  "browserEvidence": "needs-rerun",
@@ -340,8 +346,8 @@
340
346
  "gaps": [
341
347
  {
342
348
  "kind": "integration",
343
- "description": "Native links use Tab and aria-current; runtime does not implement composite tab arrow keys.",
344
- "nextStep": "Retain native anchor semantics. Rendered selection, overflow geometry and teardown are covered; verify spoken current-state output and physical touch manually."
349
+ "description": "Native links keep Tab and aria-current; Left, Right, Home and End move focus between them as a shortcut, without the selection model a tablist would announce.",
350
+ "nextStep": "Retain native anchor semantics. Rendered selection, arrow focus, overflow geometry and teardown are covered; verify spoken current-state output and physical touch manually."
345
351
  }
346
352
  ],
347
353
  "browserChecks": [
@@ -374,6 +380,12 @@
374
380
  "name": "Tabs hash selection, native dragging and overflow geometry (chromium)",
375
381
  "scope": "Initial hash overrides stale authored panel state without initialization callbacks and restores it on teardown; actual pointer dragging, RTL overflow indicator geometry and initialization-only threshold; no physical touch or native zoom claim.",
376
382
  "state": "stale"
383
+ },
384
+ {
385
+ "file": "tests/arrow-keys-browser.test.js",
386
+ "name": "chromium: arrow keys move focus between tabs and between list rows",
387
+ "scope": "Right and Left move focus, skip a disabled tab and wrap; Home and End reach the ends; RTL swaps the arrows; focus does not change the selection until Enter; a modified arrow is left to the browser. Runs in all three engines.",
388
+ "state": "not-recorded"
377
389
  }
378
390
  ],
379
391
  "browserEvidence": "needs-rerun",
@@ -487,9 +499,9 @@
487
499
  "slug": "stepper",
488
500
  "title": "Stepper",
489
501
  "kind": "component",
490
- "support": "implemented",
502
+ "support": "unassessed",
491
503
  "lastReviewedSupport": "implemented",
492
- "sourceReview": "source-reviewed",
504
+ "sourceReview": "needs-review",
493
505
  "reviewedOn": "2026-10-06",
494
506
  "scope": "Horizontal and vertical ordered lists with current, complete and invalid steps, supporting text, links back to finished steps and a content panel in vertical steps.",
495
507
  "adaptation": "An <ol> with aria-current=\"step\"; CSS alt text speaks the complete and invalid states from translatable tokens.",
@@ -625,6 +637,106 @@
625
637
  "Google revises the linked guidance or before claiming a new release matches it"
626
638
  ]
627
639
  },
640
+ {
641
+ "slug": "mega-menu",
642
+ "title": "Mega menu",
643
+ "kind": "component",
644
+ "support": "unassessed",
645
+ "lastReviewedSupport": "implemented",
646
+ "sourceReview": "needs-review",
647
+ "reviewedOn": "2026-10-15",
648
+ "scope": "Links and disclosure buttons in a row, wide panels of grouped links below the bar, a turning chevron and current-page state.",
649
+ "adaptation": "Native popovers opened with popovertarget; the browser owns opening, light dismiss, Escape, focus order and the expanded state.",
650
+ "upstream": {
651
+ "source": "https://m3.material.io/components",
652
+ "reviewedOn": "2026-10-15",
653
+ "scope": "web-extension-inventory-reviewed",
654
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
655
+ "sections": [
656
+ "No standalone Material component"
657
+ ],
658
+ "sources": [],
659
+ "requirements": "Keep the top items as links and disclosure buttons in a named nav, expose the expanded state, keep the panel next in the focus order, close on Escape and do not claim menu roles."
660
+ },
661
+ "relationship": "none",
662
+ "sources": [
663
+ {
664
+ "path": "src/sass/components/_mega-menu.scss",
665
+ "sha256": "b758dd7848889422d714b8b1a6f36cb51d99aa74bc9e312de73f08bfbd481f22"
666
+ }
667
+ ],
668
+ "gaps": [
669
+ {
670
+ "kind": "verification",
671
+ "description": "Panel placement, the expanded state, Escape, focus order into the panel, the turning chevron and stacking on a phone are checked in a browser; screen reader output remains unverified.",
672
+ "nextStep": "Open and close each panel with a screen reader in each engine and confirm the expanded state is announced."
673
+ }
674
+ ],
675
+ "browserChecks": [
676
+ {
677
+ "file": "tests/mega-menu-browser.test.js",
678
+ "name": "chromium: mega menu opens a wide panel of link groups below its button",
679
+ "scope": "Popover opening from its button, the panel below the bar spanning the window, side-by-side groups, the turning chevron, Tab into the panel, Escape, closed links out of reach and stacked groups on a phone. No spoken-output assertion.",
680
+ "state": "not-recorded"
681
+ }
682
+ ],
683
+ "browserEvidence": "incomplete",
684
+ "recheckWhen": [
685
+ "A reviewed source changes",
686
+ "A mapped test or its recorded inputs change",
687
+ "Google revises the linked guidance or before claiming a new release matches it"
688
+ ]
689
+ },
690
+ {
691
+ "slug": "menubar",
692
+ "title": "Menubar",
693
+ "kind": "component",
694
+ "support": "unassessed",
695
+ "lastReviewedSupport": "implemented",
696
+ "sourceReview": "needs-review",
697
+ "reviewedOn": "2026-10-15",
698
+ "scope": "A menubar of menu triggers with one tab stop, Left, Right, Home and End along the bar, Down to open, and Left and Right between open menus.",
699
+ "adaptation": "Each item opens an ordinary Menu; the Menubar component adds the menubar and menuitem roles and the roving tab stop at runtime.",
700
+ "upstream": {
701
+ "source": "https://m3.material.io/components",
702
+ "reviewedOn": "2026-10-15",
703
+ "scope": "web-extension-inventory-reviewed",
704
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
705
+ "sections": [
706
+ "No standalone Material component"
707
+ ],
708
+ "sources": [],
709
+ "requirements": "Name the menubar, give it one tab stop, move between items with Left and Right, open a menu with Down, Enter or Space, move between open menus with Left and Right, and close with Escape back to the bar."
710
+ },
711
+ "relationship": "none",
712
+ "sources": [
713
+ {
714
+ "path": "src/ts/components/menubar.ts",
715
+ "sha256": "73c7307ad8cf681f85fd4834d90a862e3a941513861529ec25a0663cf81c6e64"
716
+ }
717
+ ],
718
+ "gaps": [
719
+ {
720
+ "kind": "verification",
721
+ "description": "Roles, the roving tab stop, arrow, Home and End movement, opening, moving between open menus, flyout rows, Escape and RTL are checked in a browser; screen reader output remains unverified.",
722
+ "nextStep": "Operate the menubar with a screen reader in each engine and confirm menu and item announcements; check typeahead across the bar."
723
+ }
724
+ ],
725
+ "browserChecks": [
726
+ {
727
+ "file": "tests/menubar-browser.test.js",
728
+ "name": "chromium: a menubar has one tab stop and moves between its menus with the arrow keys",
729
+ "scope": "Menubar and menuitem roles, one tab stop that follows focus, Left, Right, Home and End with wrapping, Down opening on the first item, Right and Left between open menus, flyout rows keeping Right, Escape back to the bar and RTL. No spoken-output assertion.",
730
+ "state": "not-recorded"
731
+ }
732
+ ],
733
+ "browserEvidence": "incomplete",
734
+ "recheckWhen": [
735
+ "A reviewed source changes",
736
+ "A mapped test or its recorded inputs change",
737
+ "Google revises the linked guidance or before claiming a new release matches it"
738
+ ]
739
+ },
628
740
  {
629
741
  "slug": "scrollspy",
630
742
  "title": "Scrollspy",
@@ -650,7 +762,7 @@
650
762
  "sources": [
651
763
  {
652
764
  "path": "src/sass/components/_scrollspy.scss",
653
- "sha256": "39e23fb90c5b0bc2a5d34513bec7342a9a12d0a080043074f287ab8594d87c69"
765
+ "sha256": "98b9bd486ee144f96b047ad98708c85fd7c8f06ed19d06d24199553a52ab5324"
654
766
  },
655
767
  {
656
768
  "path": "src/sass/components/_table_of_contents.scss",
@@ -732,7 +844,7 @@
732
844
  "sources": [
733
845
  {
734
846
  "path": "src/sass/components/_tree.scss",
735
- "sha256": "3d290dec16e25b71a3e06cbd5fafd3340253659fbf9d95953193dab29b10aa21"
847
+ "sha256": "eab178534285441e9245aecc0d2787e5c8d9bc417260cd69a9b5587310d01187"
736
848
  }
737
849
  ],
738
850
  "gaps": [
@@ -762,7 +874,7 @@
762
874
  "title": "Buttons",
763
875
  "kind": "component",
764
876
  "support": "unassessed",
765
- "lastReviewedSupport": "partial",
877
+ "lastReviewedSupport": "implemented",
766
878
  "sourceReview": "needs-review",
767
879
  "reviewedOn": "2026-09-12",
768
880
  "scope": "Filled, tonal, outlined, elevated, and text; xsmall through xlarge.",
@@ -794,13 +906,7 @@
794
906
  "sha256": "2aaccb38cfd12b3829cbaa753e572ffc95f135a1f7f18d8de4f56764e94c3ec4"
795
907
  }
796
908
  ],
797
- "gaps": [
798
- {
799
- "kind": "feature",
800
- "description": "Standalone common buttons do not document a square/toggle shape-morph contract; do not borrow icon-button or connected-group modifiers.",
801
- "nextStep": "Define and test a standalone shape-morph contract without borrowing connected-group or icon-button modifiers."
802
- }
803
- ],
909
+ "gaps": [],
804
910
  "browserChecks": [
805
911
  {
806
912
  "file": "tests/expressivecss-examples-browser.test.js",
@@ -1137,6 +1243,66 @@
1137
1243
  "Google revises the linked guidance or before claiming a new release matches it"
1138
1244
  ]
1139
1245
  },
1246
+ {
1247
+ "slug": "back-to-top",
1248
+ "title": "Back to top",
1249
+ "kind": "component",
1250
+ "support": "implemented",
1251
+ "lastReviewedSupport": "implemented",
1252
+ "sourceReview": "source-reviewed",
1253
+ "reviewedOn": "2026-10-25",
1254
+ "scope": "An in-page link styled with the FAB classes, hidden and inert until the window scrolls past a threshold option (one viewport height by default), a focused link kept until focus leaves, a smooth scroll to the top that is instant under reduced motion, focus moved to the href target with a temporary tabindex, the body as the fallback target, modified and already prevented clicks left to the browser, a threshold that is not a CSS length replaced by the default with a warning, markup options, offset and stacking tokens, and a link that still jumps to its target without the script.",
1255
+ "adaptation": "An IntersectionObserver on an empty element at the threshold instead of a scroll listener. The hidden state is the inert attribute plus visibility: hidden, with a fade in and an immediate hide, so a script that starts after the first paint does not show the link fading out, and a page without the script never hides the link.",
1256
+ "upstream": {
1257
+ "source": "https://m3.material.io/components",
1258
+ "reviewedOn": "2026-10-25",
1259
+ "scope": "web-extension-inventory-reviewed",
1260
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1261
+ "sections": [
1262
+ "No standalone Material component"
1263
+ ],
1264
+ "sources": [],
1265
+ "requirements": "Keep the control out of reach while it is hidden, move focus to the top of the content along with the scroll, honor reduced motion, and keep the link working without the script."
1266
+ },
1267
+ "relationship": "none",
1268
+ "sources": [
1269
+ {
1270
+ "path": "src/sass/components/_back-to-top.scss",
1271
+ "sha256": "1c0afbbbf3ef51e1da38773d5f9c64d28a4e8244f46fefcaa9e19cac1e813f1e"
1272
+ },
1273
+ {
1274
+ "path": "src/ts/components/backToTop.ts",
1275
+ "sha256": "23ea9b49c6250aefa363eb85feb7703cab225aedc143e2d93445e595f609328f"
1276
+ }
1277
+ ],
1278
+ "gaps": [
1279
+ {
1280
+ "kind": "verification",
1281
+ "description": "The threshold, the return to the top with focus on the target by click and Enter, the hidden state's Tab order, hit testing and ARIA snapshot, a focused link kept through Home, a script that starts after the first paint, reduced motion, markup options, placement in both directions and the link without the script are checked in Chromium, Firefox and WebKit; spoken output, forced colors and real phones remain unverified. Only the window's scroll is watched.",
1282
+ "nextStep": "Activate the link with VoiceOver and NVDA and confirm focus lands on the main content; check it in forced colors."
1283
+ }
1284
+ ],
1285
+ "browserChecks": [
1286
+ {
1287
+ "file": "tests/back-to-top-browser.test.js",
1288
+ "name": "chromium: the link returns to the top and focuses its target, by click and by Enter",
1289
+ "scope": "Scroll past the threshold, activate by click and by Enter, and find the page at the top, focus on the target, the next Tab on the first control and no tabindex left behind.",
1290
+ "state": "not-recorded"
1291
+ },
1292
+ {
1293
+ "file": "tests/back-to-top-browser.test.js",
1294
+ "name": "chromium: the link is out of reach above the threshold",
1295
+ "scope": "Above the threshold, before and after scrolling past it, the link is hidden, skipped by Tab, missed by hit testing and absent from the ARIA snapshot. No spoken-output assertion.",
1296
+ "state": "not-recorded"
1297
+ }
1298
+ ],
1299
+ "browserEvidence": "incomplete",
1300
+ "recheckWhen": [
1301
+ "A reviewed source changes",
1302
+ "A mapped test or its recorded inputs change",
1303
+ "Google revises the linked guidance or before claiming a new release matches it"
1304
+ ]
1305
+ },
1140
1306
  {
1141
1307
  "slug": "cards",
1142
1308
  "title": "Cards",
@@ -1228,9 +1394,9 @@
1228
1394
  "slug": "aura",
1229
1395
  "title": "Aura",
1230
1396
  "kind": "component",
1231
- "support": "implemented",
1397
+ "support": "unassessed",
1232
1398
  "lastReviewedSupport": "implemented",
1233
- "sourceReview": "source-reviewed",
1399
+ "sourceReview": "needs-review",
1234
1400
  "reviewedOn": "2026-10-08",
1235
1401
  "scope": "A turning light on a ring around one wrapped element, with dual, rainbow and glow styles, token color, width, corner and speed, a reversed turn in RTL, a static ring under reduced motion and a Highlight ring in forced colors.",
1236
1402
  "adaptation": "A wrapper whose pseudo-element draws a masked conic gradient; it adds nothing to the accessibility tree.",
@@ -1249,7 +1415,7 @@
1249
1415
  "sources": [
1250
1416
  {
1251
1417
  "path": "src/sass/components/_aura.scss",
1252
- "sha256": "e95db68ef71c6f5b3262379825dc52b4ef75968d621df6ae2aa441e2d4caf002"
1418
+ "sha256": "67a0781b94946d4e15b68718179f39c5af55cde89169fe45f5f6e4f402c216da"
1253
1419
  }
1254
1420
  ],
1255
1421
  "gaps": [
@@ -1313,8 +1479,8 @@
1313
1479
  "gaps": [
1314
1480
  {
1315
1481
  "kind": "integration",
1316
- "description": "Ordinary native lists and child controls do not implement Google composite arrow navigation.",
1317
- "nextStep": "Retain native semantics unless a complete composite is supplied; test row control names and selection meaning."
1482
+ "description": "Lists of single link or button rows move focus with Up, Down, Home and End as a shortcut; rows stay Tab stops, and lists with several controls per row, selection lists and listbox semantics are not provided.",
1483
+ "nextStep": "Add a listbox only with a complete selection contract; test row control names and selection meaning."
1318
1484
  }
1319
1485
  ],
1320
1486
  "browserChecks": [
@@ -1329,6 +1495,12 @@
1329
1495
  "name": "chromium: remaining web navigation, badges and list controls expose their meaning",
1330
1496
  "scope": "Named navigation, document footer, unavailable pagination non-link, named badge count, list checkbox and scoped TOC aria-current. No spoken-output assertion.",
1331
1497
  "state": "stale"
1498
+ },
1499
+ {
1500
+ "file": "tests/arrow-keys-browser.test.js",
1501
+ "name": "chromium: arrow keys move focus between tabs and between list rows",
1502
+ "scope": "Up and Down move focus between single-control rows, skip a disabled row and stop at the ends; Home and End reach the ends; rows with several controls keep native keys. Runs in all three engines.",
1503
+ "state": "not-recorded"
1332
1504
  }
1333
1505
  ],
1334
1506
  "browserEvidence": "needs-rerun",
@@ -1363,7 +1535,7 @@
1363
1535
  "sources": [
1364
1536
  {
1365
1537
  "path": "src/sass/components/_message.scss",
1366
- "sha256": "a1b7c89089ac37ccbf2127c1c7bc4f394fd1a27253ec07208caf379a2ffa8240"
1538
+ "sha256": "b491e02e2ad4587859b83252fba303d6513d848d70d8a88ce47f58325d2ea21d"
1367
1539
  }
1368
1540
  ],
1369
1541
  "gaps": [
@@ -1413,11 +1585,11 @@
1413
1585
  "sources": [
1414
1586
  {
1415
1587
  "path": "src/sass/components/_message-scroller.scss",
1416
- "sha256": "c535f903268ac93bff12aa12dc647bdb9cc3dde34062a8a7ff850dc95ab06e6d"
1588
+ "sha256": "5b0f79f866d59b6d54966cde45e95fbc3370cec79685ed43fe527cb7ea9a71bb"
1417
1589
  },
1418
1590
  {
1419
1591
  "path": "src/ts/components/messageScroller.ts",
1420
- "sha256": "0ddbd41f71725cc27a318c92f12eabf329d92dc79402752c2520ce8a049fd799"
1592
+ "sha256": "857aeed955c93192e5cf0e003ca9f0c18900284083e97d4547da04fbc936866e"
1421
1593
  }
1422
1594
  ],
1423
1595
  "gaps": [
@@ -1455,49 +1627,59 @@
1455
1627
  ]
1456
1628
  },
1457
1629
  {
1458
- "slug": "accordion",
1459
- "title": "Accordion",
1630
+ "slug": "pull-to-refresh",
1631
+ "title": "Pull-to-refresh",
1460
1632
  "kind": "component",
1461
1633
  "support": "implemented",
1462
1634
  "lastReviewedSupport": "implemented",
1463
1635
  "sourceReview": "source-reviewed",
1464
- "reviewedOn": "2026-10-06",
1465
- "scope": "Joined tiles on native details and summary, exclusive groups through the name attribute, a leading icon, a turning chevron and an animated open where the engine supports it.",
1466
- "adaptation": "Native <details> and <summary>; the browser owns the toggle, its keyboard support and its expanded state.",
1636
+ "reviewedOn": "2026-10-24",
1637
+ "scope": "A touch pull from a scroll position of 0 past a threshold, a refresh button and refresh() method that start the same refresh, an expressive:refresh event and onRefresh callback whose detail takes waitUntil(), complete(), aria-busy while refreshing, a status region that announces the start and the finish with i18n strings, contained overscroll on the container and the page, and containers that scroll themselves or pull the page.",
1638
+ "adaptation": "Touch events with a non-passive touchmove, because a pointer drag the browser takes for a pan ends in pointercancel. The author's loading indicator carries the role and name; the script sets a class, two custom properties and aria-busy, and adds a visually hidden role=\"status\" region because the indicator is hidden once the refresh ends.",
1467
1639
  "upstream": {
1468
1640
  "source": "https://m3.material.io/components",
1469
- "reviewedOn": "2026-10-06",
1641
+ "reviewedOn": "2026-10-24",
1470
1642
  "scope": "web-extension-inventory-reviewed",
1471
1643
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1472
1644
  "sections": [
1473
1645
  "No standalone Material component"
1474
1646
  ],
1475
1647
  "sources": [],
1476
- "requirements": "Expose each header as a button with its expanded state, keep controls out of the header, keep the reading order equal to the visual order and respect reduced motion."
1648
+ "requirements": "Offer a control that refreshes without the gesture, keep the native browser pull from running as well, report the busy state, and do not take scrolling away from a drag that is not a pull."
1477
1649
  },
1478
1650
  "relationship": "none",
1479
1651
  "sources": [
1480
1652
  {
1481
- "path": "src/sass/components/_accordion.scss",
1482
- "sha256": "cd9c2657f1f840f721575335ffd05d8cd176b2f94c37637341121485901833ee"
1653
+ "path": "src/sass/components/_pull-to-refresh.scss",
1654
+ "sha256": "82683a82db3309935575713659b0df1707de087802f20aa87d7ac3f875e4ae98"
1655
+ },
1656
+ {
1657
+ "path": "src/ts/components/pullToRefresh.ts",
1658
+ "sha256": "861006bffd5074cca9a5f34f0b75ac01d2490b77e35d6a63c12718846807ebba"
1483
1659
  }
1484
1660
  ],
1485
1661
  "gaps": [
1486
1662
  {
1487
1663
  "kind": "verification",
1488
- "description": "Tile corners, the chevron turn, exclusive groups and the expanded state Chromium reports are checked in a browser; the open animation, enlarged text and spoken output remain unverified.",
1489
- "nextStep": "Toggle items with a screen reader in each engine and confirm the expanded state is announced; test enlarged text and reduced motion."
1664
+ "description": "The pull threshold, waitUntil() and complete(), drags that do nothing, inner and surrounding scrollers, a second finger, the busy state, the refresh button, page scrolling, reduced motion and destroy() are checked in a browser, with real touch in Chromium and dispatched touch events in Firefox and WebKit; real phones, pen input, spoken output from the status region and forced colors remain unverified.",
1665
+ "nextStep": "Pull on Chrome and Firefox for Android and Safari on iOS and confirm the browser's own refresh does not run; read a refresh with a screen reader."
1490
1666
  }
1491
1667
  ],
1492
1668
  "browserChecks": [
1493
1669
  {
1494
- "file": "tests/accordion-browser.test.js",
1495
- "name": "chromium: accordion joins its tiles, turns the chevron and keeps one item open per name",
1496
- "scope": "Outer, inner and open corner radii, chevron rotation, hidden native marker, exclusive name groups, Enter on a focused summary and the expanded state Chromium reports for each summary. No spoken-output assertion.",
1497
- "state": "stale"
1670
+ "file": "tests/pull-to-refresh-browser.test.js",
1671
+ "name": "chromium: a pull past the threshold refreshes once and the indicator stays until the page reports the finish",
1672
+ "scope": "Real touch input. Contained overscroll, one event per pull past the threshold, the indicator and aria-busy kept until a waitUntil() promise settles or complete() runs. No spoken-output assertion.",
1673
+ "state": "not-recorded"
1674
+ },
1675
+ {
1676
+ "file": "tests/pull-to-refresh-browser.test.js",
1677
+ "name": "chromium: the refresh button, by click, Enter or Space, and refresh() each start a refresh",
1678
+ "scope": "The refresh button by click, Enter and Space, and refresh(), each firing one event and showing the indicator.",
1679
+ "state": "not-recorded"
1498
1680
  }
1499
1681
  ],
1500
- "browserEvidence": "needs-rerun",
1682
+ "browserEvidence": "incomplete",
1501
1683
  "recheckWhen": [
1502
1684
  "A reviewed source changes",
1503
1685
  "A mapped test or its recorded inputs change",
@@ -1505,49 +1687,59 @@
1505
1687
  ]
1506
1688
  },
1507
1689
  {
1508
- "slug": "data-table",
1509
- "title": "Data table",
1690
+ "slug": "swipe-actions",
1691
+ "title": "Swipe actions",
1510
1692
  "kind": "component",
1511
1693
  "support": "implemented",
1512
1694
  "lastReviewedSupport": "implemented",
1513
1695
  "sourceReview": "source-reviewed",
1514
- "reviewedOn": "2026-10-06",
1515
- "scope": "Scrolling wrapper with an outline, sticky header row, numeric columns, dense rows, a sort arrow drawn from aria-sort and checkbox row selection.",
1516
- "adaptation": "A plain div wraps a native <table>, so the table keeps its role; the page owns sorting, select-all and the scroll region name.",
1696
+ "reviewedOn": "2026-10-24",
1697
+ "scope": "A touch swipe toward a row's inline start that reveals its .swipe-actions group, opening past half the group's width or on a flick and closing short of it, a [data-swipe-toggle] button with aria-expanded, focus on an action opening its row, Escape, an outside tap or an action closing it, one open row per list, an expressive:swipetoggle event and onToggle callback with { row, open }, open(row) and close(), right-to-left pages and reduced motion.",
1698
+ "adaptation": "Touch events with a non-passive touchmove, because a pointer drag the browser takes for a pan ends in pointercancel. The row slides by a translate on one custom property, and the actions wait past its inline end in a list clipped on the inline axis, so focus on a closed row's action scrolls nothing. The author names the toggle and the actions; the script keeps aria-expanded.",
1517
1699
  "upstream": {
1518
1700
  "source": "https://m3.material.io/components",
1519
- "reviewedOn": "2026-10-06",
1701
+ "reviewedOn": "2026-10-24",
1520
1702
  "scope": "web-extension-inventory-reviewed",
1521
1703
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1522
1704
  "sections": [
1523
1705
  "No standalone Material component"
1524
1706
  ],
1525
1707
  "sources": [],
1526
- "requirements": "Keep native table semantics with column and row headers, expose sort state on the header cell, name selection checkboxes after their rows and make a scrolling region reachable and named."
1708
+ "requirements": "Offer a single-pointer and keyboard path to every action a swipe reveals (WCAG 2.5.1), keep the actions named and reachable while the row is closed, run nothing on the gesture alone, and do not take scrolling away from a drag that is not a swipe."
1527
1709
  },
1528
1710
  "relationship": "none",
1529
1711
  "sources": [
1530
1712
  {
1531
- "path": "src/sass/components/_data-table.scss",
1532
- "sha256": "dbce2d8f374bb0f5bc7008725c0e8ed680df39d9bb111fea4219b8d120558e9c"
1713
+ "path": "src/sass/components/_swipe-actions.scss",
1714
+ "sha256": "2e096de408f17827ff3276bcef2ba88df1bc52109454b0efb357f4bd7a39d49b"
1715
+ },
1716
+ {
1717
+ "path": "src/ts/components/swipeActions.ts",
1718
+ "sha256": "334ca2c40da4df9722425852ad7e97692d0b4d03e9d17a87ca1911bd51da574c"
1533
1719
  }
1534
1720
  ],
1535
1721
  "gaps": [
1536
1722
  {
1537
1723
  "kind": "verification",
1538
- "description": "Table semantics, the sticky header, numeric alignment, the sort arrow and selected rows are checked in a browser; sort announcements, enlarged text and spoken output remain unverified.",
1539
- "nextStep": "Sort and select rows with a screen reader in each engine and confirm the sort state and selection are announced; test enlarged text and RTL."
1724
+ "description": "Swipe reveal, the slide limit, short, vertical, mouse, two-finger and cancelled drags, the toggle, focus on an action, Escape, an outside tap, closing after an action, one open row, the event and onToggle, right-to-left pages, reduced motion and destroy() are checked in a browser, with real touch in Chromium and dispatched touch events in Firefox and WebKit; real phones, flick velocity, pen input, spoken output and forced colors remain unverified.",
1725
+ "nextStep": "Swipe on Chrome for Android and Safari on iOS and confirm the browser's back gesture and vertical scrolling still work; read a row's actions with a screen reader."
1540
1726
  }
1541
1727
  ],
1542
1728
  "browserChecks": [
1543
1729
  {
1544
- "file": "tests/data-table-browser.test.js",
1545
- "name": "chromium: data table keeps table semantics, sticks its header and draws sort and selection",
1546
- "scope": "Table, column header and row counts through the wrapper, sticky header offset after scrolling, end-aligned numeric cells in LTR and RTL, sort arrow opacity and rotation, selected row fill and the named scroll region. No spoken-output assertion.",
1547
- "state": "stale"
1730
+ "file": "tests/swipe-actions-browser.test.js",
1731
+ "name": "chromium: a swipe reveals a row's actions, and a keyboard user reaches the same actions",
1732
+ "scope": "Real touch input. A swipe reveals the actions without running one, and Tab, Enter and the toggle reach and run an action from the keyboard.",
1733
+ "state": "not-recorded"
1734
+ },
1735
+ {
1736
+ "file": "tests/swipe-actions-browser.test.js",
1737
+ "name": "chromium: the toggle opens and closes a row, and a tap outside, Escape or an action closes it",
1738
+ "scope": "The toggle and aria-expanded, focus on an action opening its row, an outside tap, Escape with focus returned to the toggle, closing after an action, and an action that removes its row.",
1739
+ "state": "not-recorded"
1548
1740
  }
1549
1741
  ],
1550
- "browserEvidence": "needs-rerun",
1742
+ "browserEvidence": "incomplete",
1551
1743
  "recheckWhen": [
1552
1744
  "A reviewed source changes",
1553
1745
  "A mapped test or its recorded inputs change",
@@ -1555,15 +1747,15 @@
1555
1747
  ]
1556
1748
  },
1557
1749
  {
1558
- "slug": "stat",
1559
- "title": "Stat",
1750
+ "slug": "accordion",
1751
+ "title": "Accordion",
1560
1752
  "kind": "component",
1561
1753
  "support": "implemented",
1562
1754
  "lastReviewedSupport": "implemented",
1563
1755
  "sourceReview": "source-reviewed",
1564
1756
  "reviewedOn": "2026-10-06",
1565
- "scope": "Wrapping tiles in a description list with headline values, and a change line with up, down and negative states.",
1566
- "adaptation": "A <dl> pairs each value with its label; the arrow is decoration and the text carries the direction.",
1757
+ "scope": "Joined tiles on native details and summary, exclusive groups through the name attribute, a leading icon, a turning chevron and an animated open where the engine supports it.",
1758
+ "adaptation": "Native <details> and <summary>; the browser owns the toggle, its keyboard support and its expanded state.",
1567
1759
  "upstream": {
1568
1760
  "source": "https://m3.material.io/components",
1569
1761
  "reviewedOn": "2026-10-06",
@@ -1573,27 +1765,27 @@
1573
1765
  "No standalone Material component"
1574
1766
  ],
1575
1767
  "sources": [],
1576
- "requirements": "Pair every value with its label, state the direction and comparison of a change in text and keep long values from overflowing their tile."
1768
+ "requirements": "Expose each header as a button with its expanded state, keep controls out of the header, keep the reading order equal to the visual order and respect reduced motion."
1577
1769
  },
1578
1770
  "relationship": "none",
1579
1771
  "sources": [
1580
1772
  {
1581
- "path": "src/sass/components/_stat.scss",
1582
- "sha256": "c8f50278bd01fd4ef8d38a5b26fb7b91869f30b9cfc59cef4d482651e9bae9ad"
1773
+ "path": "src/sass/components/_accordion.scss",
1774
+ "sha256": "42847790221df3bb20d7c035611dbbc79725c9ad469877781041c1959b4127f8"
1583
1775
  }
1584
1776
  ],
1585
1777
  "gaps": [
1586
1778
  {
1587
1779
  "kind": "verification",
1588
- "description": "Tiling, wrapping, the value type role, arrow direction, the negative color and term-definition pairing are checked in a browser; enlarged text and spoken output remain unverified.",
1589
- "nextStep": "Read a stats row with a screen reader in each engine and confirm each label is announced with its value; test enlarged text at narrow widths."
1780
+ "description": "Tile corners, the chevron turn, exclusive groups and the expanded state Chromium reports are checked in a browser; the open animation, enlarged text and spoken output remain unverified.",
1781
+ "nextStep": "Toggle items with a screen reader in each engine and confirm the expanded state is announced; test enlarged text and reduced motion."
1590
1782
  }
1591
1783
  ],
1592
1784
  "browserChecks": [
1593
1785
  {
1594
- "file": "tests/stat-browser.test.js",
1595
- "name": "chromium: stats tile their figures, wrap when narrow and mark the change",
1596
- "scope": "One row when wide and stacked when narrow, the headline value size, up and down arrows, the negative color and term-definition pairs in the accessibility tree. No spoken-output assertion.",
1786
+ "file": "tests/accordion-browser.test.js",
1787
+ "name": "chromium: accordion joins its tiles, turns the chevron and keeps one item open per name",
1788
+ "scope": "Outer, inner and open corner radii, chevron rotation, hidden native marker, exclusive name groups, Enter on a focused summary and the expanded state Chromium reports for each summary. No spoken-output assertion.",
1597
1789
  "state": "stale"
1598
1790
  }
1599
1791
  ],
@@ -1605,49 +1797,65 @@
1605
1797
  ]
1606
1798
  },
1607
1799
  {
1608
- "slug": "kpi",
1609
- "title": "KPI",
1800
+ "slug": "show-more",
1801
+ "title": "Show more",
1610
1802
  "kind": "component",
1611
1803
  "support": "implemented",
1612
1804
  "lastReviewedSupport": "implemented",
1613
1805
  "sourceReview": "source-reviewed",
1614
- "reviewedOn": "2026-10-08",
1615
- "scope": "A card with a labelled value in a description list, a trend chip with up, down and negative states, a tonal icon, a corner action, a sparkline, a progress bar and a footer.",
1616
- "adaptation": "A <dl> pairs the value with its label inside a card <article>; the arrow is decoration, the text carries the direction and the sparkline's table is its text alternative.",
1806
+ "reviewedOn": "2026-10-25",
1807
+ "scope": "A .show-more holding text with a line-clamp-1, -2 or -3 class and a <button type=\"button\">; the button sets aria-expanded and aria-controls, shows the full text, reads \"Show less\" while it is open (i18n.showLess or data-show-less), and hides while the clamped text fits, checking again on resize, after web fonts load and on blur.",
1808
+ "adaptation": "The component unclamps with inline -webkit-line-clamp and line-clamp, because the utilities layer and prefixed clamp classes beat any component rule. A ResizeObserver on the text and document.fonts.ready run the fit check, scrollHeight against clientHeight with 1px for Firefox's rounding.",
1617
1809
  "upstream": {
1618
1810
  "source": "https://m3.material.io/components",
1619
- "reviewedOn": "2026-10-08",
1811
+ "reviewedOn": "2026-10-25",
1620
1812
  "scope": "web-extension-inventory-reviewed",
1621
1813
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1622
1814
  "sections": [
1623
1815
  "No standalone Material component"
1624
1816
  ],
1625
1817
  "sources": [],
1626
- "requirements": "Pair the value with its label, state the direction and unit of a change in text, caption the sparkline and name the action after the figure."
1818
+ "requirements": "Keep the control a native button named by visible text, report its expanded state, point it at the text it controls, and hide it from sight and the tab order when there is nothing more to show."
1627
1819
  },
1628
1820
  "relationship": "none",
1629
1821
  "sources": [
1630
1822
  {
1631
- "path": "src/sass/components/_kpi.scss",
1632
- "sha256": "8b54fdf69302d605376d10091bd533054030c3ddffd0384c9c7076b9bcf2c8eb"
1823
+ "path": "src/ts/components/showMore.ts",
1824
+ "sha256": "d6a961f6810f004ac7d5cdf1575717a2cdbd20cb4ca6d4e08e2ba413f00713d3"
1825
+ },
1826
+ {
1827
+ "path": "src/sass/components/_show-more.scss",
1828
+ "sha256": "430401c741e9628d553e836fb98078fd39a1f64e42f2fa49264a34427638e650"
1633
1829
  }
1634
1830
  ],
1635
1831
  "gaps": [
1636
1832
  {
1637
1833
  "kind": "verification",
1638
- "description": "Part placement, the value type role, arrow direction, the negative chip and chart colors and term-definition pairing are checked in a browser; enlarged text and spoken output remain unverified.",
1639
- "nextStep": "Read a KPI row with a screen reader in each engine and confirm the label, value, trend and sparkline caption are announced in order; test enlarged text at narrow widths."
1834
+ "description": "Toggling, the fit check, the focused-button cases, a web-font swap, labels, events and destroy() are checked in a browser or jsdom; spoken output with VoiceOver and NVDA is unverified.",
1835
+ "nextStep": "Activate the button with VoiceOver and NVDA and check that the expanded state and label are announced."
1640
1836
  }
1641
1837
  ],
1642
1838
  "browserChecks": [
1643
1839
  {
1644
- "file": "tests/kpi-browser.test.js",
1645
- "name": "chromium: kpi lays out its label, value, trend, actions, chart and footer",
1646
- "scope": "Trend beside the value, actions in the label row's end corner, chart under the value, an edge-to-edge footer closing the card, the headline value size, up and down arrows, the negative chip and chart colors and term-definition pairs in the accessibility tree. No spoken-output assertion.",
1647
- "state": "stale"
1840
+ "file": "tests/show-more-browser.test.js",
1841
+ "name": "chromium: the button shows the full text and collapses it again",
1842
+ "scope": "A click and Enter that unclamp and clamp the text, with aria-expanded and aria-controls.",
1843
+ "state": "not-recorded"
1844
+ },
1845
+ {
1846
+ "file": "tests/show-more-browser.test.js",
1847
+ "name": "chromium: the button hides while the clamped text fits",
1848
+ "scope": "Text that fits, a fractional line height, a container widened and narrowed, a window-size prefix, Tab order, and a focused button kept through a resize and until blur.",
1849
+ "state": "not-recorded"
1850
+ },
1851
+ {
1852
+ "file": "tests/show-more-browser.test.js",
1853
+ "name": "chromium: a web font that swaps in hides the button once its text fits",
1854
+ "scope": "A held-back web font that makes cut text fit, and an instance destroyed before the font loads.",
1855
+ "state": "not-recorded"
1648
1856
  }
1649
1857
  ],
1650
- "browserEvidence": "needs-rerun",
1858
+ "browserEvidence": "incomplete",
1651
1859
  "recheckWhen": [
1652
1860
  "A reviewed source changes",
1653
1861
  "A mapped test or its recorded inputs change",
@@ -1655,46 +1863,52 @@
1655
1863
  ]
1656
1864
  },
1657
1865
  {
1658
- "slug": "countdown",
1659
- "title": "Countdown",
1866
+ "slug": "data-table",
1867
+ "title": "Data table",
1660
1868
  "kind": "component",
1661
- "support": "implemented",
1869
+ "support": "unassessed",
1662
1870
  "lastReviewedSupport": "implemented",
1663
- "sourceReview": "source-reviewed",
1664
- "reviewedOn": "2026-10-08",
1665
- "scope": "Digits from 0 to 999 that roll up or down when --md-comp-countdown-value changes, with zero padding to two or three digits and a reduced-motion fallback.",
1666
- "adaptation": "The element's text is the accessible value; the digit strips are generated content with empty alternative text. A page script sets the property and the text together.",
1871
+ "sourceReview": "needs-review",
1872
+ "reviewedOn": "2026-10-06",
1873
+ "scope": "Scrolling native tables with sticky headers, numeric/dense rows, sorting, page-scoped selection, column resizing/visibility, text filtering and local paging with record/detail groups and authored counts.",
1874
+ "adaptation": "A plain div wraps a native table. Shared DataTables handlers own opt-in sorting, filtering, select-all and column operations; authors name controls and the scroll region, and keep native row and header semantics.",
1667
1875
  "upstream": {
1668
1876
  "source": "https://m3.material.io/components",
1669
- "reviewedOn": "2026-10-08",
1877
+ "reviewedOn": "2026-10-06",
1670
1878
  "scope": "web-extension-inventory-reviewed",
1671
1879
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1672
1880
  "sections": [
1673
1881
  "No standalone Material component"
1674
1882
  ],
1675
1883
  "sources": [],
1676
- "requirements": "Keep the number in the element's text for assistive technology, avoid announcing every tick and stop the motion when the user asks for reduced motion."
1884
+ "requirements": "Keep native table semantics with column and row headers, expose sort state on the header cell, name selection checkboxes after their rows and make a scrolling region reachable and named."
1677
1885
  },
1678
1886
  "relationship": "none",
1679
1887
  "sources": [
1680
1888
  {
1681
- "path": "src/sass/components/_countdown.scss",
1682
- "sha256": "74330fcc3e02b6462f40019d7cd37c680e8a71bf54d7a0be0e7fe3ffaa733d05"
1889
+ "path": "src/sass/components/_data-table.scss",
1890
+ "sha256": "dbce2d8f374bb0f5bc7008725c0e8ed680df39d9bb111fea4219b8d120558e9c"
1683
1891
  }
1684
1892
  ],
1685
1893
  "gaps": [
1686
1894
  {
1687
1895
  "kind": "verification",
1688
- "description": "Width, digit positions, the baseline, the roll transition, reduced motion and the accessibility tree text are checked in a browser; spoken output inside role=\"timer\" and aria-live regions remains unverified.",
1689
- "nextStep": "Run a ticking timer and a polite live count with a screen reader in each engine and confirm the timer stays quiet and the live count announces each value once."
1896
+ "description": "Table semantics, the sticky header, numeric alignment, the sort arrow and selected rows are checked in a browser; sort announcements, enlarged text and spoken output remain unverified.",
1897
+ "nextStep": "Sort and select rows with a screen reader in each engine and confirm the sort state and selection are announced; test enlarged text and RTL."
1690
1898
  }
1691
1899
  ],
1692
1900
  "browserChecks": [
1693
1901
  {
1694
- "file": "tests/countdown-browser.test.js",
1695
- "name": "chromium: countdown shows 0 to 999 as rolling digits and keeps the text for assistive technology",
1696
- "scope": "Box width per digit count and padding, strip positions for in-range and clamped values, baseline alignment, the translate transition on change, reduced motion and the accessibility tree text. No spoken-output assertion.",
1902
+ "file": "tests/data-table-browser.test.js",
1903
+ "name": "chromium: data table keeps table semantics, sticks its header and draws sort and selection",
1904
+ "scope": "Table, column header and row counts through the wrapper, sticky header offset after scrolling, end-aligned numeric cells in LTR and RTL, sort arrow opacity and rotation, selected row fill and the named scroll region. No spoken-output assertion.",
1697
1905
  "state": "stale"
1906
+ },
1907
+ {
1908
+ "file": "tests/data-table-browser.test.js",
1909
+ "name": "chromium: data table joins a bulk-action bar and expands detail rows",
1910
+ "scope": "Bar joined to the table's top edge, squared table corners, a hidden bar leaving the table alone, the selected tint, end-aligned buttons, detail rows hidden and shown by aria-expanded, the turned chevron and the detail row kept a table row. No spoken-output assertion.",
1911
+ "state": "not-recorded"
1698
1912
  }
1699
1913
  ],
1700
1914
  "browserEvidence": "needs-rerun",
@@ -1705,15 +1919,15 @@
1705
1919
  ]
1706
1920
  },
1707
1921
  {
1708
- "slug": "line-chart",
1709
- "title": "Line chart",
1922
+ "slug": "stat",
1923
+ "title": "Stat",
1710
1924
  "kind": "component",
1711
- "support": "implemented",
1925
+ "support": "unassessed",
1712
1926
  "lastReviewedSupport": "implemented",
1713
- "sourceReview": "source-reviewed",
1927
+ "sourceReview": "needs-review",
1714
1928
  "reviewedOn": "2026-10-06",
1715
- "scope": "Smooth monotone lines drawn from a figure's data table, with area, stacked, fade and sparkline modifiers, dashed series, gaps, a fixed y range, x labels, a legend, and a pointer and keyboard tooltip.",
1716
- "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the SVG is aria-hidden and the plot is one Tab stop with a polite live tooltip.",
1929
+ "scope": "Wrapping tiles in a description list with headline values, and a change line with up, down and negative states.",
1930
+ "adaptation": "A <dl> pairs each value with its label; the arrow is decoration and the text carries the direction.",
1717
1931
  "upstream": {
1718
1932
  "source": "https://m3.material.io/components",
1719
1933
  "reviewedOn": "2026-10-06",
@@ -1723,14 +1937,214 @@
1723
1937
  "No standalone Material component"
1724
1938
  ],
1725
1939
  "sources": [],
1726
- "requirements": "Keep the data available as text, name the chart, keep series distinguishable and let a keyboard reach every value the pointer can."
1940
+ "requirements": "Pair every value with its label, state the direction and comparison of a change in text and keep long values from overflowing their tile."
1727
1941
  },
1728
1942
  "relationship": "none",
1729
1943
  "sources": [
1730
1944
  {
1731
- "path": "src/sass/abstracts/_mixins.scss",
1732
- "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
1733
- },
1945
+ "path": "src/sass/components/_stat.scss",
1946
+ "sha256": "d16e8c5dab7af93c9b9601548dc32953cc5e095a249e7c7c4e5859e3ebbc4f71"
1947
+ }
1948
+ ],
1949
+ "gaps": [
1950
+ {
1951
+ "kind": "verification",
1952
+ "description": "Tiling, wrapping, the value type role, arrow direction, the negative color and term-definition pairing are checked in a browser; enlarged text and spoken output remain unverified.",
1953
+ "nextStep": "Read a stats row with a screen reader in each engine and confirm each label is announced with its value; test enlarged text at narrow widths."
1954
+ }
1955
+ ],
1956
+ "browserChecks": [
1957
+ {
1958
+ "file": "tests/stat-browser.test.js",
1959
+ "name": "chromium: stats tile their figures, wrap when narrow and mark the change",
1960
+ "scope": "One row when wide and stacked when narrow, the headline value size, up and down arrows, the negative color and term-definition pairs in the accessibility tree. No spoken-output assertion.",
1961
+ "state": "stale"
1962
+ }
1963
+ ],
1964
+ "browserEvidence": "needs-rerun",
1965
+ "recheckWhen": [
1966
+ "A reviewed source changes",
1967
+ "A mapped test or its recorded inputs change",
1968
+ "Google revises the linked guidance or before claiming a new release matches it"
1969
+ ]
1970
+ },
1971
+ {
1972
+ "slug": "description-list",
1973
+ "title": "Description list",
1974
+ "kind": "component",
1975
+ "support": "implemented",
1976
+ "lastReviewedSupport": "implemented",
1977
+ "sourceReview": "source-reviewed",
1978
+ "reviewedOn": "2026-10-15",
1979
+ "scope": "Label and value columns with a divider per pair, a compact stacked layout, div-wrapped groups and several values per label.",
1980
+ "adaptation": "A native dl, dt and dd; the browser exposes the label-value pairing.",
1981
+ "upstream": {
1982
+ "source": "https://m3.material.io/components",
1983
+ "reviewedOn": "2026-10-15",
1984
+ "scope": "web-extension-inventory-reviewed",
1985
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
1986
+ "sections": [
1987
+ "No standalone Material component"
1988
+ ],
1989
+ "sources": [],
1990
+ "requirements": "Keep the native dl so each value stays paired with its label, keep the reading order label before value and let long values wrap."
1991
+ },
1992
+ "relationship": "none",
1993
+ "sources": [
1994
+ {
1995
+ "path": "src/sass/components/_description-list.scss",
1996
+ "sha256": "d989d090fccadc4ef1ab8ec1ef84237ad9ce552508135c6a5ad9b3acae99d77f"
1997
+ }
1998
+ ],
1999
+ "gaps": [
2000
+ {
2001
+ "kind": "verification",
2002
+ "description": "Two columns, the compact stack, one divider per pair, div-wrapped groups and several values per label are checked in a browser; enlarged text and spoken output remain unverified.",
2003
+ "nextStep": "Read a description list with a screen reader in each engine and confirm each value is announced with its label; test enlarged text."
2004
+ }
2005
+ ],
2006
+ "browserChecks": [
2007
+ {
2008
+ "file": "tests/description-list-browser.test.js",
2009
+ "name": "chromium: description list pairs labels and values in two columns and stacks them when compact",
2010
+ "scope": "Label and value columns, shared rows, div-wrapped groups, stacked extra values, one divider per pair, the compact stacked layout and unchanged reading order. No spoken-output assertion.",
2011
+ "state": "not-recorded"
2012
+ }
2013
+ ],
2014
+ "browserEvidence": "incomplete",
2015
+ "recheckWhen": [
2016
+ "A reviewed source changes",
2017
+ "A mapped test or its recorded inputs change",
2018
+ "Google revises the linked guidance or before claiming a new release matches it"
2019
+ ]
2020
+ },
2021
+ {
2022
+ "slug": "kpi",
2023
+ "title": "KPI",
2024
+ "kind": "component",
2025
+ "support": "unassessed",
2026
+ "lastReviewedSupport": "implemented",
2027
+ "sourceReview": "needs-review",
2028
+ "reviewedOn": "2026-10-08",
2029
+ "scope": "A card with a labelled value in a description list, a trend chip with up, down and negative states, a tonal icon, a corner action, a sparkline, a progress bar and a footer.",
2030
+ "adaptation": "A <dl> pairs the value with its label inside a card <article>; the arrow is decoration, the text carries the direction and the sparkline's table is its text alternative.",
2031
+ "upstream": {
2032
+ "source": "https://m3.material.io/components",
2033
+ "reviewedOn": "2026-10-08",
2034
+ "scope": "web-extension-inventory-reviewed",
2035
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2036
+ "sections": [
2037
+ "No standalone Material component"
2038
+ ],
2039
+ "sources": [],
2040
+ "requirements": "Pair the value with its label, state the direction and unit of a change in text, caption the sparkline and name the action after the figure."
2041
+ },
2042
+ "relationship": "none",
2043
+ "sources": [
2044
+ {
2045
+ "path": "src/sass/components/_kpi.scss",
2046
+ "sha256": "0597d0fc81f4f1a874729e5ca7ca4e7b7cb0fbcd0de92894741e3d2ce91f4d31"
2047
+ }
2048
+ ],
2049
+ "gaps": [
2050
+ {
2051
+ "kind": "verification",
2052
+ "description": "Part placement, the value type role, arrow direction, the negative chip and chart colors and term-definition pairing are checked in a browser; enlarged text and spoken output remain unverified.",
2053
+ "nextStep": "Read a KPI row with a screen reader in each engine and confirm the label, value, trend and sparkline caption are announced in order; test enlarged text at narrow widths."
2054
+ }
2055
+ ],
2056
+ "browserChecks": [
2057
+ {
2058
+ "file": "tests/kpi-browser.test.js",
2059
+ "name": "chromium: kpi lays out its label, value, trend, actions, chart and footer",
2060
+ "scope": "Trend beside the value, actions in the label row's end corner, chart under the value, an edge-to-edge footer closing the card, the headline value size, up and down arrows, the negative chip and chart colors and term-definition pairs in the accessibility tree. No spoken-output assertion.",
2061
+ "state": "stale"
2062
+ }
2063
+ ],
2064
+ "browserEvidence": "needs-rerun",
2065
+ "recheckWhen": [
2066
+ "A reviewed source changes",
2067
+ "A mapped test or its recorded inputs change",
2068
+ "Google revises the linked guidance or before claiming a new release matches it"
2069
+ ]
2070
+ },
2071
+ {
2072
+ "slug": "countdown",
2073
+ "title": "Countdown",
2074
+ "kind": "component",
2075
+ "support": "implemented",
2076
+ "lastReviewedSupport": "implemented",
2077
+ "sourceReview": "source-reviewed",
2078
+ "reviewedOn": "2026-10-08",
2079
+ "scope": "Digits from 0 to 999 that roll up or down when --md-comp-countdown-value changes, with zero padding to two or three digits and a reduced-motion fallback.",
2080
+ "adaptation": "The element's text is the accessible value; the digit strips are generated content with empty alternative text. A page script sets the property and the text together.",
2081
+ "upstream": {
2082
+ "source": "https://m3.material.io/components",
2083
+ "reviewedOn": "2026-10-08",
2084
+ "scope": "web-extension-inventory-reviewed",
2085
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2086
+ "sections": [
2087
+ "No standalone Material component"
2088
+ ],
2089
+ "sources": [],
2090
+ "requirements": "Keep the number in the element's text for assistive technology, avoid announcing every tick and stop the motion when the user asks for reduced motion."
2091
+ },
2092
+ "relationship": "none",
2093
+ "sources": [
2094
+ {
2095
+ "path": "src/sass/components/_countdown.scss",
2096
+ "sha256": "2918d1710b0858696b359789273316fe9fd9b3ed9023b606c6f4b2a90b878357"
2097
+ }
2098
+ ],
2099
+ "gaps": [
2100
+ {
2101
+ "kind": "verification",
2102
+ "description": "Width, digit positions, the baseline, the roll transition, reduced motion and the accessibility tree text are checked in a browser; spoken output inside role=\"timer\" and aria-live regions remains unverified.",
2103
+ "nextStep": "Run a ticking timer and a polite live count with a screen reader in each engine and confirm the timer stays quiet and the live count announces each value once."
2104
+ }
2105
+ ],
2106
+ "browserChecks": [
2107
+ {
2108
+ "file": "tests/countdown-browser.test.js",
2109
+ "name": "chromium: countdown shows 0 to 999 as rolling digits and keeps the text for assistive technology",
2110
+ "scope": "Box width per digit count and padding, strip positions for in-range and clamped values, baseline alignment, the translate transition on change, reduced motion and the accessibility tree text. No spoken-output assertion.",
2111
+ "state": "stale"
2112
+ }
2113
+ ],
2114
+ "browserEvidence": "needs-rerun",
2115
+ "recheckWhen": [
2116
+ "A reviewed source changes",
2117
+ "A mapped test or its recorded inputs change",
2118
+ "Google revises the linked guidance or before claiming a new release matches it"
2119
+ ]
2120
+ },
2121
+ {
2122
+ "slug": "line-chart",
2123
+ "title": "Line chart",
2124
+ "kind": "component",
2125
+ "support": "unassessed",
2126
+ "lastReviewedSupport": "implemented",
2127
+ "sourceReview": "needs-review",
2128
+ "reviewedOn": "2026-10-06",
2129
+ "scope": "Smooth monotone lines drawn from a figure's data table, with area, stacked, fade and sparkline modifiers, dashed series, gaps, a fixed y range, x labels, round y axis labels with .axis, a legend, and a pointer and keyboard tooltip.",
2130
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the SVG is aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2131
+ "upstream": {
2132
+ "source": "https://m3.material.io/components",
2133
+ "reviewedOn": "2026-10-06",
2134
+ "scope": "web-extension-inventory-reviewed",
2135
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2136
+ "sections": [
2137
+ "No standalone Material component"
2138
+ ],
2139
+ "sources": [],
2140
+ "requirements": "Keep the data available as text, name the chart, keep series distinguishable and let a keyboard reach every value the pointer can."
2141
+ },
2142
+ "relationship": "none",
2143
+ "sources": [
2144
+ {
2145
+ "path": "src/sass/abstracts/_mixins.scss",
2146
+ "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
2147
+ },
1734
2148
  {
1735
2149
  "path": "src/sass/components/_line-chart.scss",
1736
2150
  "sha256": "cf8029ceb68d9abb123876fbccc2f83567aaf373354edeab57add74be375c957"
@@ -1745,11 +2159,6 @@
1745
2159
  "kind": "verification",
1746
2160
  "description": "Drawing, the hidden table, gaps, the y range, RTL, the tooltip, keyboard movement, forced-color swatches and destroy are checked in a browser; screen reader output and enlarged text remain unverified.",
1747
2161
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; test enlarged text."
1748
- },
1749
- {
1750
- "kind": "feature",
1751
- "description": "There are no y axis value labels; the grid lines carry no numbers.",
1752
- "nextStep": "Add optional y labels if charts need values readable without the tooltip."
1753
2162
  }
1754
2163
  ],
1755
2164
  "browserChecks": [
@@ -1770,6 +2179,12 @@
1770
2179
  "name": "chromium: line chart handles cards, headerless tables, RTL, strict values and forced colors",
1771
2180
  "scope": "A chart in a sized card and in a primary action keeps its own layout and caption, a header row without <thead> is not data, the RTL axis matches its labels and arrow keys, ambiguous cell text is a gap, show() is safe without data and skips a repeated row, stacked bands fill down to the series below or the plot bottom with cursor points on the totals and each cell in the tooltip, a stacked gap breaks the series above it, the stacked range keeps 10% headroom above zero, and swatches keep their series colors in forced colors.",
1772
2181
  "state": "stale"
2182
+ },
2183
+ {
2184
+ "file": "tests/chart-axis-browser.test.js",
2185
+ "name": "chromium: .axis labels chart scales at round values on their grid lines",
2186
+ "scope": "Labels widen the scale to round values, repeat the cells' currency sign, sit beside the plot with a grid line each, and leave author-set ends in place. No rendering comparison.",
2187
+ "state": "not-recorded"
1773
2188
  }
1774
2189
  ],
1775
2190
  "browserEvidence": "needs-rerun",
@@ -1783,11 +2198,11 @@
1783
2198
  "slug": "column-chart",
1784
2199
  "title": "Column chart",
1785
2200
  "kind": "component",
1786
- "support": "implemented",
2201
+ "support": "unassessed",
1787
2202
  "lastReviewedSupport": "implemented",
1788
- "sourceReview": "source-reviewed",
2203
+ "sourceReview": "needs-review",
1789
2204
  "reviewedOn": "2026-10-07",
1790
- "scope": "Columns drawn from zero from a figure's data table, grouped by row or stacked, with fade, track and sparkline modifiers, negative values, gaps, a fixed y range, x labels, a legend, and a pointer and keyboard tooltip with a highlight band.",
2205
+ "scope": "Columns drawn from zero from a figure's data table, grouped by row or stacked, with fade, track and sparkline modifiers, negative values, gaps, a fixed y range, x labels, round y axis labels with .axis, a legend, and a pointer and keyboard tooltip with a highlight band.",
1791
2206
  "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the columns are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
1792
2207
  "upstream": {
1793
2208
  "source": "https://m3.material.io/components",
@@ -1822,13 +2237,8 @@
1822
2237
  "gaps": [
1823
2238
  {
1824
2239
  "kind": "verification",
1825
- "description": "Drawing, the hidden table, grouped and stacked geometry, gaps, negative values, the y range, RTL, the tooltip, the band, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2240
+ "description": "Drawing, the hidden table, grouped and stacked geometry, range columns, gaps, negative values, the y range, RTL, the tooltip, the band, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
1826
2241
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
1827
- },
1828
- {
1829
- "kind": "feature",
1830
- "description": "There are no y axis value labels or range columns.",
1831
- "nextStep": "Add optional y labels if charts need values readable without the tooltip; add range columns when a page needs them."
1832
2242
  }
1833
2243
  ],
1834
2244
  "browserChecks": [
@@ -1843,6 +2253,12 @@
1843
2253
  "name": "chromium: column chart tooltip and band follow the pointer and the arrow keys",
1844
2254
  "scope": "Pointer position to row, tooltip text without empty cells, no cursor points, the band's width and position, hiding on leave, focus, End and Escape, and the first row on the right in RTL. No spoken-output assertion.",
1845
2255
  "state": "stale"
2256
+ },
2257
+ {
2258
+ "file": "tests/chart-axis-browser.test.js",
2259
+ "name": "chromium: .axis labels chart scales at round values on their grid lines",
2260
+ "scope": "Shares the line chart's axis code; the line, mixed and bar cases cover it. No column-specific rendering comparison.",
2261
+ "state": "not-recorded"
1846
2262
  }
1847
2263
  ],
1848
2264
  "browserEvidence": "needs-rerun",
@@ -1856,11 +2272,11 @@
1856
2272
  "slug": "bar-chart",
1857
2273
  "title": "Bar chart",
1858
2274
  "kind": "component",
1859
- "support": "implemented",
2275
+ "support": "unassessed",
1860
2276
  "lastReviewedSupport": "implemented",
1861
- "sourceReview": "source-reviewed",
2277
+ "sourceReview": "needs-review",
1862
2278
  "reviewedOn": "2026-10-07",
1863
- "scope": "Horizontal bars drawn from zero from a figure's data table, grouped by row or stacked, with split, track, values and sparkline modifiers, negative values, gaps, a fixed value range, row labels, a legend, and a pointer and keyboard tooltip with a highlight band.",
2279
+ "scope": "Horizontal bars drawn from zero from a figure's data table, grouped by row or stacked, with split, track, values and sparkline modifiers, negative values, gaps, a fixed value range, row labels, round value axis labels with .axis, a legend, and a pointer and keyboard tooltip with a highlight band.",
1864
2280
  "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the bars and their values are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
1865
2281
  "upstream": {
1866
2282
  "source": "https://m3.material.io/components",
@@ -1901,11 +2317,6 @@
1901
2317
  "kind": "verification",
1902
2318
  "description": "Drawing, the hidden table, grouped, stacked and split geometry, values, gaps, negative values, the value range, RTL, the tooltip, the band, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
1903
2319
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
1904
- },
1905
- {
1906
- "kind": "feature",
1907
- "description": "There are no value axis labels.",
1908
- "nextStep": "Add optional value labels if charts need numbers readable without the tooltip."
1909
2320
  }
1910
2321
  ],
1911
2322
  "browserChecks": [
@@ -1920,6 +2331,12 @@
1920
2331
  "name": "chromium: bar chart tooltip and band follow the pointer and the up and down arrows",
1921
2332
  "scope": "Pointer height to row, tooltip text, the band's height and position, flipping above the row in the lower half, hiding on leave, focus, arrows, End and Escape, the first row at the top in RTL, and a touch tap showing the tapped row in bar and column charts, kept on lift and hidden on pointer cancel. No spoken-output assertion.",
1922
2333
  "state": "stale"
2334
+ },
2335
+ {
2336
+ "file": "tests/chart-axis-browser.test.js",
2337
+ "name": "chromium: .axis labels chart scales at round values on their grid lines",
2338
+ "scope": "Labels sit under the plot at round values from zero, mirrored in RTL. No rendering comparison.",
2339
+ "state": "not-recorded"
1923
2340
  }
1924
2341
  ],
1925
2342
  "browserEvidence": "needs-rerun",
@@ -1937,7 +2354,7 @@
1937
2354
  "lastReviewedSupport": "implemented",
1938
2355
  "sourceReview": "needs-review",
1939
2356
  "reviewedOn": "2026-10-07",
1940
- "scope": "Slices drawn clockwise from the top from a figure's data table, with a legend of each row's cell and share, donut, values and sparkline modifiers, a <tfoot> total in the donut hole, further columns in the tooltip, and a pointer and keyboard tooltip that highlights the slice.",
2357
+ "scope": "Slices drawn clockwise from the top from a figure's data table, with a legend of each row's cell and share, donut, values and sparkline modifiers, a <tfoot> total in the donut hole, labels with each slice's name outside it, further columns in the tooltip, and a pointer and keyboard tooltip that highlights the slice.",
1941
2358
  "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the slices, values, total and legend are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
1942
2359
  "upstream": {
1943
2360
  "source": "https://m3.material.io/components",
@@ -1958,7 +2375,7 @@
1958
2375
  },
1959
2376
  {
1960
2377
  "path": "src/sass/components/_pie-chart.scss",
1961
- "sha256": "ea811ee29aff2b8e8407ed419d13491b6b1eb639e28669cdd8c5de512b1dd87e"
2378
+ "sha256": "e8af880485cebacccd8a23b7387f675cf1f54e58e913bc7314f9fe41b10bd690"
1962
2379
  },
1963
2380
  {
1964
2381
  "path": "src/ts/components/lineChart.ts",
@@ -1972,13 +2389,13 @@
1972
2389
  "gaps": [
1973
2390
  {
1974
2391
  "kind": "verification",
1975
- "description": "Drawing, the hidden table, slice geometry and colors, the legend and shares, the donut hole and total, values, zero and missing values, RTL, the tooltip, pointer angle hit testing, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2392
+ "description": "Drawing, the hidden table, slice geometry and colors, the legend and shares, the donut hole and total, values, outside names and their leader lines, data-other grouping, zero and missing values, RTL, the tooltip, pointer angle hit testing, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
1976
2393
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
1977
2394
  },
1978
2395
  {
1979
2396
  "kind": "feature",
1980
- "description": "There are no labels outside the pie, and rows past six reuse the colors.",
1981
- "nextStep": "Add outside labels with leader lines if charts need names on the pie; group small parts into an Other row meanwhile."
2397
+ "description": "Rows past six reuse the colors, and .labels names only move up or down their side, so many thin slices at the top or bottom push names into the caption or legend unless data-other groups them.",
2398
+ "nextStep": "Set data-other on pies with many small parts; lay names out in two dimensions if grouped pies still crowd."
1982
2399
  }
1983
2400
  ],
1984
2401
  "browserChecks": [
@@ -1993,6 +2410,12 @@
1993
2410
  "name": "chromium: pie chart tooltip follows the pointer round the pie and the arrow keys",
1994
2411
  "scope": "Pointer angle to slice, the active slice, tooltip text with the share and further columns, swatches in the slice color, opening leftwards on the right half, hiding off the pie, focus, all four arrows, wrapping past either end, End and Escape, and clockwise slices and arrows in RTL. No spoken-output assertion.",
1995
2412
  "state": "stale"
2413
+ },
2414
+ {
2415
+ "file": "tests/pie-chart-browser.test.js",
2416
+ "name": "chromium: pie chart .labels writes each slice's name outside it",
2417
+ "scope": "A name for every drawn slice in its color and none for a zero row, every name outside the grown pie, right-half names running rightwards and left-half names leftwards, four thin neighbouring slices pushed apart without overlap, names either side of the middle line kept apart, a 160px figure keeping half its width for the pie with the names inside it, the names aria-hidden, and none on a sparkline. No rendering comparison.",
2418
+ "state": "not-recorded"
1996
2419
  }
1997
2420
  ],
1998
2421
  "browserEvidence": "needs-rerun",
@@ -2045,13 +2468,8 @@
2045
2468
  "gaps": [
2046
2469
  {
2047
2470
  "kind": "verification",
2048
- "description": "Drawing, the hidden table, cell shades and gaps, the fixed scale, values and their text color, short and running labels, the scale ends, RTL, page overflow from a wide table, the tooltip, pointer and keyboard movement round the grid and destroy are checked in Chromium, Firefox and WebKit; screen reader output, forced colors and enlarged text remain unverified.",
2471
+ "description": "Drawing, the hidden table, cell shades and gaps, the fixed, diverging and stepped scales, values and their text color, short and running labels, the scale ends, RTL, page overflow from a wide table, scrolling a wide grid, the tooltip, pointer and keyboard movement round the grid and destroy are checked in Chromium, Firefox and WebKit; screen reader output, forced colors and enlarged text remain unverified.",
2049
2472
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2050
- },
2051
- {
2052
- "kind": "feature",
2053
- "description": "A wide grid narrows its cells to fit instead of scrolling, and the scale is one color with no diverging or stepped option.",
2054
- "nextStep": "Add a scrolling layout that keeps the tooltip visible if year-long grids must work on phones, and a diverging scale if charts need a midpoint."
2055
2473
  }
2056
2474
  ],
2057
2475
  "browserChecks": [
@@ -2079,11 +2497,11 @@
2079
2497
  "slug": "radar-chart",
2080
2498
  "title": "Radar chart",
2081
2499
  "kind": "component",
2082
- "support": "implemented",
2500
+ "support": "unassessed",
2083
2501
  "lastReviewedSupport": "implemented",
2084
- "sourceReview": "source-reviewed",
2502
+ "sourceReview": "needs-review",
2085
2503
  "reviewedOn": "2026-10-07",
2086
- "scope": "Spokes drawn clockwise from the top from a figure's data table, one shape per series from zero in the middle to the scale's top at the rim, row labels past each spoke, a legend for several series, area, points, dashed and sparkline modifiers, data-min and data-max, and a pointer and keyboard tooltip with a cursor spoke.",
2504
+ "scope": "Spokes drawn clockwise from the top from a figure's data table, one shape per series from zero in the middle to the scale's top at the rim, row labels past each spoke, a legend for several series, area, points, dashed and sparkline modifiers, data-min and data-max, round labelled rings with .axis, and a pointer and keyboard tooltip with a cursor spoke.",
2087
2505
  "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the grid, shapes, labels and legend are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2088
2506
  "upstream": {
2089
2507
  "source": "https://m3.material.io/components",
@@ -2104,7 +2522,7 @@
2104
2522
  },
2105
2523
  {
2106
2524
  "path": "src/sass/components/_radar-chart.scss",
2107
- "sha256": "a5f8e6984dfc02b0c7fb2a23f6c1311f733de6b853e0b675c95a58d18da05006"
2525
+ "sha256": "32e7d3cc1886b1f396244cf102f2537c9e57c096909f9dd4990fcde046f20ab7"
2108
2526
  },
2109
2527
  {
2110
2528
  "path": "src/ts/components/lineChart.ts",
@@ -2123,25 +2541,330 @@
2123
2541
  },
2124
2542
  {
2125
2543
  "kind": "feature",
2126
- "description": "A gap joins the spokes either side of it rather than breaking the shape, the rings have no value labels, and series past four reuse the colors.",
2127
- "nextStep": "Mark gaps and label the rings if charts need them; keep to three series meanwhile."
2544
+ "description": "Series past four reuse the colors.",
2545
+ "nextStep": "Keep to three series, or compare more in a line or bar chart."
2546
+ }
2547
+ ],
2548
+ "browserChecks": [
2549
+ {
2550
+ "file": "tests/radar-chart-browser.test.js",
2551
+ "name": "chromium: radar chart draws a grid, shapes, labels and a legend from its table",
2552
+ "scope": "Hidden table in the accessibility tree, the named plot and its role description, the square plot, four rings and spokes, shape geometry from zero to data-max with a joined gap and a clamped value, series colors and the dashed class, points, the area fill, labels on their spokes, the legend, separate instances from line charts, no fill, points or legend by default, the sparkline size, focus and hidden labels, and destroy restoring the table.",
2553
+ "state": "stale"
2554
+ },
2555
+ {
2556
+ "file": "tests/radar-chart-browser.test.js",
2557
+ "name": "chromium: radar chart tooltip follows the pointer round the spokes and the arrow keys",
2558
+ "scope": "Nearest spoke by pointer angle inside and past the rim, tooltip text without gaps, opening leftwards on the right half, the cursor spoke and its points, focus, all four arrows, wrapping past either end, End and Escape, and clockwise spokes and arrows in RTL. No spoken-output assertion.",
2559
+ "state": "stale"
2560
+ },
2561
+ {
2562
+ "file": "tests/chart-axis-browser.test.js",
2563
+ "name": "chromium: .axis labels chart scales at round values on their grid lines",
2564
+ "scope": "Rings and labels fall at round values with zero unlabelled. No rendering comparison.",
2565
+ "state": "not-recorded"
2566
+ }
2567
+ ],
2568
+ "browserEvidence": "needs-rerun",
2569
+ "recheckWhen": [
2570
+ "A reviewed source changes",
2571
+ "A mapped test or its recorded inputs change",
2572
+ "Google revises the linked guidance or before claiming a new release matches it"
2573
+ ]
2574
+ },
2575
+ {
2576
+ "slug": "radial-chart",
2577
+ "title": "Radial chart",
2578
+ "kind": "component",
2579
+ "support": "unassessed",
2580
+ "lastReviewedSupport": "implemented",
2581
+ "sourceReview": "needs-review",
2582
+ "reviewedOn": "2026-10-07",
2583
+ "scope": "Rings drawn clockwise from the top from a figure's data table as a share of data-max, with tracks, a legend of each row's cell for more than one row, gauge, labels and sparkline modifiers, a <tfoot> total in the middle, further columns in the tooltip, and a pointer and keyboard tooltip that highlights the ring.",
2584
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the rings, total and legend are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2585
+ "upstream": {
2586
+ "source": "https://m3.material.io/components",
2587
+ "reviewedOn": "2026-10-07",
2588
+ "scope": "web-extension-inventory-reviewed",
2589
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2590
+ "sections": [
2591
+ "No standalone Material component"
2592
+ ],
2593
+ "sources": [],
2594
+ "requirements": "Keep the data available as text, name the chart, keep rings distinguishable and their values readable, and let a keyboard reach every ring the pointer can."
2595
+ },
2596
+ "relationship": "none",
2597
+ "sources": [
2598
+ {
2599
+ "path": "src/sass/abstracts/_mixins.scss",
2600
+ "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
2601
+ },
2602
+ {
2603
+ "path": "src/sass/components/_radial-chart.scss",
2604
+ "sha256": "7bbf15655da199f7ea4c87245dd0bc644fa36f5fbc12fbde959cac940347cd18"
2605
+ },
2606
+ {
2607
+ "path": "src/ts/components/lineChart.ts",
2608
+ "sha256": "6fdb7471049d342a5e66aa30ba84857208c7d2ed167223b26578e62b9437d960"
2609
+ },
2610
+ {
2611
+ "path": "src/ts/components/radialChart.ts",
2612
+ "sha256": "2d6acf36785432d8c8ad32adc3aabe0441ad41efe7f14e78c707b1077b7e548e"
2613
+ }
2614
+ ],
2615
+ "gaps": [
2616
+ {
2617
+ "kind": "verification",
2618
+ "description": "Drawing, the hidden table, ring geometry and colors, tracks, the legend, the <tfoot> total, the gauge's half circles, ring names, gauge names under the base line, segments, gradient fills, values past the maximum and missing values, thinning crowded rings, RTL, the tooltip, pointer distance hit testing, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2619
+ "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2620
+ },
2621
+ {
2622
+ "kind": "feature",
2623
+ "description": "Rings past four reuse the colors.",
2624
+ "nextStep": "Keep to four rings and use the legend for more."
2625
+ }
2626
+ ],
2627
+ "browserChecks": [
2628
+ {
2629
+ "file": "tests/radial-chart-browser.test.js",
2630
+ "name": "chromium: radial chart draws rings, a legend and a total from its table",
2631
+ "scope": "Hidden table in the accessibility tree, the named plot and its role description, the square plot, ring radii, widths, colors and dash shares, tracks, an empty ring for a missing value, legend cells, separate instances from line charts, the gauge's box, half-circle dash, round track caps and <tfoot> total, no legend for one ring, thinner crowded rings, a value past the maximum, the sparkline size and focus in a flex row, and destroy restoring the table.",
2632
+ "state": "stale"
2633
+ },
2634
+ {
2635
+ "file": "tests/radial-chart-browser.test.js",
2636
+ "name": "chromium: radial chart tooltip follows the pointer across the rings and the arrow keys",
2637
+ "scope": "Pointer distance to ring, gaps split between rings, the active ring, tooltip text with further columns, swatches in the ring color, opening direction, hiding in the middle, off the rings and below a gauge's base line, focus, all four arrows, End and Escape, and clockwise rings with swapped arrows in RTL. No spoken-output assertion.",
2638
+ "state": "stale"
2639
+ },
2640
+ {
2641
+ "file": "tests/radial-chart-browser.test.js",
2642
+ "name": "chromium: radial chart .labels names each ring at its start",
2643
+ "scope": "A name per ring in on-surface-variant, centred on its ring's top and inside the top left quarter, no overlaps, smaller names for eight crowded rings, three-quarter tracks with round ends, the tooltip at a full ring's end, hovering across a name picking its own ring, the names aria-hidden, and none on a gauge or sparkline, which keep their half and whole tracks. No rendering comparison.",
2644
+ "state": "not-recorded"
2645
+ }
2646
+ ],
2647
+ "browserEvidence": "needs-rerun",
2648
+ "recheckWhen": [
2649
+ "A reviewed source changes",
2650
+ "A mapped test or its recorded inputs change",
2651
+ "Google revises the linked guidance or before claiming a new release matches it"
2652
+ ]
2653
+ },
2654
+ {
2655
+ "slug": "mixed-chart",
2656
+ "title": "Mixed chart",
2657
+ "kind": "component",
2658
+ "support": "unassessed",
2659
+ "lastReviewedSupport": "implemented",
2660
+ "sourceReview": "needs-review",
2661
+ "reviewedOn": "2026-10-07",
2662
+ "scope": "Columns, smooth lines and areas drawn per series from a figure's data table by header class, with dashed lines, a second scale for end series with its own fixed range, x labels, round labels for both scales with .axis, aligned to shared grid lines, a legend, a sparkline modifier, and a pointer and keyboard tooltip with points on the lines.",
2663
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the columns and SVG are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2664
+ "upstream": {
2665
+ "source": "https://m3.material.io/components",
2666
+ "reviewedOn": "2026-10-07",
2667
+ "scope": "web-extension-inventory-reviewed",
2668
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2669
+ "sections": [
2670
+ "No standalone Material component"
2671
+ ],
2672
+ "sources": [],
2673
+ "requirements": "Keep the data available as text, name the chart, keep series distinguishable without color alone, state each scale's units, and let a keyboard reach every row the pointer can."
2674
+ },
2675
+ "relationship": "none",
2676
+ "sources": [
2677
+ {
2678
+ "path": "src/sass/abstracts/_mixins.scss",
2679
+ "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
2680
+ },
2681
+ {
2682
+ "path": "src/sass/components/_mixed-chart.scss",
2683
+ "sha256": "4195fbf13249ef7bf4da8560f5b0ccbc715367f2b5771c3b96a255af4b9e39bb"
2684
+ },
2685
+ {
2686
+ "path": "src/ts/components/columnChart.ts",
2687
+ "sha256": "3c8ad721e3abc034c763870081d87a2df0aaf2470d212f03c51086e0ee5deb7d"
2688
+ },
2689
+ {
2690
+ "path": "src/ts/components/lineChart.ts",
2691
+ "sha256": "6fdb7471049d342a5e66aa30ba84857208c7d2ed167223b26578e62b9437d960"
2692
+ },
2693
+ {
2694
+ "path": "src/ts/components/mixedChart.ts",
2695
+ "sha256": "3c4bc2efee52a5ec53e9318467e9802efbe17b016b4d977c0b3a95ba0f4b52ba"
2696
+ }
2697
+ ],
2698
+ "gaps": [
2699
+ {
2700
+ "kind": "verification",
2701
+ "description": "Drawing, the hidden table, both scales, gaps, stacked columns, points, straight lines, the legend, the tooltip, cursor points and keyboard movement are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2702
+ "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2703
+ }
2704
+ ],
2705
+ "browserChecks": [
2706
+ {
2707
+ "file": "tests/mixed-chart-browser.test.js",
2708
+ "name": "chromium: mixed chart draws columns, areas and lines on two scales",
2709
+ "scope": "Hidden table, the named plot and its role description, column positions on the start scale with an empty slot for a gap, area and dashed line classes and colors, an area fill only on area series, a fixed end scale, a fitted end scale shared by two series, legend order, separate instances from column charts, a chart of gaps showing its table, and the tooltip and cursor points from the keyboard. No spoken-output assertion.",
2710
+ "state": "stale"
2711
+ },
2712
+ {
2713
+ "file": "tests/chart-axis-browser.test.js",
2714
+ "name": "chromium: .axis labels chart scales at round values on their grid lines",
2715
+ "scope": "The end scale stretches to the start scale's steps so both label sets share the grid lines, each with its own percent sign. No rendering comparison.",
2716
+ "state": "not-recorded"
2717
+ }
2718
+ ],
2719
+ "browserEvidence": "needs-rerun",
2720
+ "recheckWhen": [
2721
+ "A reviewed source changes",
2722
+ "A mapped test or its recorded inputs change",
2723
+ "Google revises the linked guidance or before claiming a new release matches it"
2724
+ ]
2725
+ },
2726
+ {
2727
+ "slug": "scatter-chart",
2728
+ "title": "Scatter chart",
2729
+ "kind": "component",
2730
+ "support": "implemented",
2731
+ "lastReviewedSupport": "implemented",
2732
+ "sourceReview": "source-reviewed",
2733
+ "reviewedOn": "2026-10-24",
2734
+ "scope": "Points drawn from a figure's data table, with a shared x column and one series per further column, gaps for cells that are not numbers, fixed ranges for both scales, round labels for both scales with .axis, a legend with .toggle, update() motion, data-watch, a pointer and keyboard tooltip that steps through points in table order, and .bubble sizes from the last column with areas proportional to its values.",
2735
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the SVG is aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2736
+ "upstream": {
2737
+ "source": "https://m3.material.io/components",
2738
+ "reviewedOn": "2026-10-24",
2739
+ "scope": "web-extension-inventory-reviewed",
2740
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2741
+ "sections": [
2742
+ "No standalone Material component"
2743
+ ],
2744
+ "sources": [],
2745
+ "requirements": "Keep the data available as text, name the chart, keep series distinguishable, state each scale's units, and let a keyboard reach every point the pointer can."
2746
+ },
2747
+ "relationship": "none",
2748
+ "sources": [
2749
+ {
2750
+ "path": "src/sass/abstracts/_mixins.scss",
2751
+ "sha256": "2a7fa8e2ff3322c41da6c1ad663ea69f53322be84146b0f45711837fb84decb1"
2752
+ },
2753
+ {
2754
+ "path": "src/sass/components/_scatter-chart.scss",
2755
+ "sha256": "f064ff1fa5a08cd19c244531df9c85cc3b877908d9d21a237adad1ad7f73390f"
2756
+ },
2757
+ {
2758
+ "path": "src/ts/components/lineChart.ts",
2759
+ "sha256": "06a7be0f88231c0368d299a6506643e9aac6fc9a99ac7143ae1d180f98541c71"
2760
+ },
2761
+ {
2762
+ "path": "src/ts/components/scatterChart.ts",
2763
+ "sha256": "6e5098db6b538b9609957e23e3a752ef65bb59b235ecb8c3a79fdda629031bbe"
2764
+ }
2765
+ ],
2766
+ "gaps": [
2767
+ {
2768
+ "kind": "verification",
2769
+ "description": "Point placement, gaps, both axes, the tooltip, keyboard steps, the pointer, update() motion, data-watch and the toggle legend are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2770
+ "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2771
+ }
2772
+ ],
2773
+ "browserChecks": [
2774
+ {
2775
+ "file": "tests/scatter-chart-browser.test.js",
2776
+ "name": "chromium: scatter chart places one point per row at its x and y values",
2777
+ "scope": "Hidden table, the named plot and its role description, the x column read as the axis, one point per row per series at its value in left-to-right and right-to-left pages, legend order, and separate instances from line charts. No spoken-output assertion.",
2778
+ "state": "not-recorded"
2779
+ },
2780
+ {
2781
+ "file": "tests/scatter-chart-browser.test.js",
2782
+ "name": "chromium: bubble chart sizes each point so its area follows the last column",
2783
+ "scope": "With .bubble, the last column leaves the series and legend, and each bubble's area is proportional to its row's size, the largest 48px across, at its scatter position in left-to-right and right-to-left pages. No spoken-output assertion.",
2784
+ "state": "not-recorded"
2785
+ },
2786
+ {
2787
+ "file": "tests/scatter-chart-browser.test.js",
2788
+ "name": "chromium: scatter chart arrow keys step through the points in table order",
2789
+ "scope": "Keyboard focus shows the first point; arrows, Home, End and Escape step through points in table order and skip gaps; the live tooltip text. No spoken-output assertion.",
2790
+ "state": "not-recorded"
2791
+ }
2792
+ ],
2793
+ "browserEvidence": "incomplete",
2794
+ "recheckWhen": [
2795
+ "A reviewed source changes",
2796
+ "A mapped test or its recorded inputs change",
2797
+ "Google revises the linked guidance or before claiming a new release matches it"
2798
+ ]
2799
+ },
2800
+ {
2801
+ "slug": "funnel-chart",
2802
+ "title": "Funnel chart",
2803
+ "kind": "component",
2804
+ "support": "unassessed",
2805
+ "lastReviewedSupport": "implemented",
2806
+ "sourceReview": "needs-review",
2807
+ "reviewedOn": "2026-10-25",
2808
+ "scope": "Stages drawn from a figure's data table, one per row from the second column in table order, centered and as wide as their value against the largest, gaps and values of zero or less left without a stage, row labels at the inline start, a pointer and keyboard tooltip that adds each stage's percentage of the first row, update() width motion and data-watch.",
2809
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the stages are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2810
+ "upstream": {
2811
+ "source": "https://m3.material.io/components",
2812
+ "reviewedOn": "2026-10-25",
2813
+ "scope": "web-extension-inventory-reviewed",
2814
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2815
+ "sections": [
2816
+ "No standalone Material component"
2817
+ ],
2818
+ "sources": [],
2819
+ "requirements": "Keep the data available as text, name the chart, label each stage, and let a keyboard reach every row the pointer can."
2820
+ },
2821
+ "relationship": "none",
2822
+ "sources": [
2823
+ {
2824
+ "path": "src/sass/abstracts/_mixins.scss",
2825
+ "sha256": "47a0a21ff5ea47c1030e3730605cadb4498d868202a88d89670c3aa55cf09702"
2826
+ },
2827
+ {
2828
+ "path": "src/sass/components/_funnel-chart.scss",
2829
+ "sha256": "8d5e737c1090062a8978bddd105fe485c2f56e16160c89c942caae3d1e641035"
2830
+ },
2831
+ {
2832
+ "path": "src/ts/components/funnelChart.ts",
2833
+ "sha256": "f11baa23053f0e4bf649b5c6eb3500fc8b4224f97d85e30455b9d29f4bafacb8"
2834
+ },
2835
+ {
2836
+ "path": "src/ts/components/lineChart.ts",
2837
+ "sha256": "06a7be0f88231c0368d299a6506643e9aac6fc9a99ac7143ae1d180f98541c71"
2838
+ }
2839
+ ],
2840
+ "gaps": [
2841
+ {
2842
+ "kind": "verification",
2843
+ "description": "Stage widths, gaps, labels, the tooltip, keyboard steps, the pointer, update() motion and data-watch are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2844
+ "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2128
2845
  }
2129
2846
  ],
2130
2847
  "browserChecks": [
2131
2848
  {
2132
- "file": "tests/radar-chart-browser.test.js",
2133
- "name": "chromium: radar chart draws a grid, shapes, labels and a legend from its table",
2134
- "scope": "Hidden table in the accessibility tree, the named plot and its role description, the square plot, four rings and spokes, shape geometry from zero to data-max with a joined gap and a clamped value, series colors and the dashed class, points, the area fill, labels on their spokes, the legend, separate instances from line charts, no fill, points or legend by default, the sparkline size, focus and hidden labels, and destroy restoring the table.",
2135
- "state": "stale"
2849
+ "file": "tests/funnel-chart-browser.test.js",
2850
+ "name": "chromium: funnel chart sizes each stage by its value, in table order",
2851
+ "scope": "Hidden table, separate instances from line charts, and each stage's width proportional to its value against the largest, centered and in table order, in left-to-right and right-to-left pages. No spoken-output assertion.",
2852
+ "state": "not-recorded"
2136
2853
  },
2137
2854
  {
2138
- "file": "tests/radar-chart-browser.test.js",
2139
- "name": "chromium: radar chart tooltip follows the pointer round the spokes and the arrow keys",
2140
- "scope": "Nearest spoke by pointer angle inside and past the rim, tooltip text without gaps, opening leftwards on the right half, the cursor spoke and its points, focus, all four arrows, wrapping past either end, End and Escape, and clockwise spokes and arrows in RTL. No spoken-output assertion.",
2141
- "state": "stale"
2855
+ "file": "tests/funnel-chart-browser.test.js",
2856
+ "name": "chromium: funnel chart moves between rows with the up and down arrows",
2857
+ "scope": "Keyboard focus shows the first row; the down and up arrows, Home, End and Escape move or hide the live tooltip, with the same keys in a right-to-left page. No spoken-output assertion.",
2858
+ "state": "not-recorded"
2859
+ },
2860
+ {
2861
+ "file": "tests/funnel-chart-browser.test.js",
2862
+ "name": "chromium: funnel chart tooltip gives each stage's share of the first",
2863
+ "scope": "The tooltip text names the row and each column, adds each stage's percentage of the first row with a tenth below 10%, and leaves it out for gaps and values of zero or less. No spoken-output assertion.",
2864
+ "state": "not-recorded"
2142
2865
  }
2143
2866
  ],
2144
- "browserEvidence": "needs-rerun",
2867
+ "browserEvidence": "incomplete",
2145
2868
  "recheckWhen": [
2146
2869
  "A reviewed source changes",
2147
2870
  "A mapped test or its recorded inputs change",
@@ -2149,72 +2872,67 @@
2149
2872
  ]
2150
2873
  },
2151
2874
  {
2152
- "slug": "radial-chart",
2153
- "title": "Radial chart",
2875
+ "slug": "sankey-chart",
2876
+ "title": "Sankey chart",
2154
2877
  "kind": "component",
2155
- "support": "implemented",
2878
+ "support": "unassessed",
2156
2879
  "lastReviewedSupport": "implemented",
2157
- "sourceReview": "source-reviewed",
2158
- "reviewedOn": "2026-10-07",
2159
- "scope": "Rings drawn clockwise from the top from a figure's data table as a share of data-max, with tracks, a legend of each row's cell for more than one row, gauge and sparkline modifiers, a <tfoot> total in the middle, further columns in the tooltip, and a pointer and keyboard tooltip that highlights the ring.",
2160
- "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the rings, total and legend are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2880
+ "sourceReview": "needs-review",
2881
+ "reviewedOn": "2026-10-25",
2882
+ "scope": "Nodes and links drawn from a figure's data table of source, target and value columns, with nodes in columns by their longest path from a source, stacked in the order they first appear, links and nodes on one scale, rows skipped for values that are not positive, missing names, self links and cycles, node names and colors, right-to-left mirroring, update() motion, data-watch, and a pointer and keyboard tooltip that steps through links in table order.",
2883
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the SVG and node names are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2161
2884
  "upstream": {
2162
2885
  "source": "https://m3.material.io/components",
2163
- "reviewedOn": "2026-10-07",
2886
+ "reviewedOn": "2026-10-25",
2164
2887
  "scope": "web-extension-inventory-reviewed",
2165
2888
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2166
2889
  "sections": [
2167
2890
  "No standalone Material component"
2168
2891
  ],
2169
2892
  "sources": [],
2170
- "requirements": "Keep the data available as text, name the chart, keep rings distinguishable and their values readable, and let a keyboard reach every ring the pointer can."
2893
+ "requirements": "Keep the flows available as text, name the chart, keep nodes distinguishable, name each node on the chart, and let a keyboard reach every link the pointer can."
2171
2894
  },
2172
2895
  "relationship": "none",
2173
2896
  "sources": [
2174
2897
  {
2175
2898
  "path": "src/sass/abstracts/_mixins.scss",
2176
- "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
2899
+ "sha256": "47a0a21ff5ea47c1030e3730605cadb4498d868202a88d89670c3aa55cf09702"
2177
2900
  },
2178
2901
  {
2179
- "path": "src/sass/components/_radial-chart.scss",
2180
- "sha256": "4ebff333a3820b516fac11c5be053041d0d5c8a9841b579f35ef47e6cdc247fb"
2902
+ "path": "src/sass/components/_sankey-chart.scss",
2903
+ "sha256": "d81458fecaf2d41f4baea9a80a1da970eddef6df3c66e28d8667f46d1c0323d6"
2181
2904
  },
2182
2905
  {
2183
2906
  "path": "src/ts/components/lineChart.ts",
2184
- "sha256": "6fdb7471049d342a5e66aa30ba84857208c7d2ed167223b26578e62b9437d960"
2907
+ "sha256": "06a7be0f88231c0368d299a6506643e9aac6fc9a99ac7143ae1d180f98541c71"
2185
2908
  },
2186
2909
  {
2187
- "path": "src/ts/components/radialChart.ts",
2188
- "sha256": "2d6acf36785432d8c8ad32adc3aabe0441ad41efe7f14e78c707b1077b7e548e"
2910
+ "path": "src/ts/components/sankeyChart.ts",
2911
+ "sha256": "dd1cf4c14eda375f994c1cdb534802ef8c4b5611a24c8aebd8aec29b433d3b6a"
2189
2912
  }
2190
2913
  ],
2191
2914
  "gaps": [
2192
2915
  {
2193
2916
  "kind": "verification",
2194
- "description": "Drawing, the hidden table, ring geometry and colors, tracks, the legend, the <tfoot> total, the gauge's half circles, values past the maximum and missing values, thinning crowded rings, RTL, the tooltip, pointer distance hit testing, keyboard movement and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2917
+ "description": "Link and node sizes, columns, skipped rows, names, colors, right-to-left mirroring, keyboard steps, the pointer, update() motion and data-watch are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2195
2918
  "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2196
- },
2197
- {
2198
- "kind": "feature",
2199
- "description": "There are no labels on the rings, no gradient or segmented fills, and rings past four reuse the colors.",
2200
- "nextStep": "Add ring-start labels if charts need names on the rings; keep to four rings and use the legend meanwhile."
2201
2919
  }
2202
2920
  ],
2203
2921
  "browserChecks": [
2204
2922
  {
2205
- "file": "tests/radial-chart-browser.test.js",
2206
- "name": "chromium: radial chart draws rings, a legend and a total from its table",
2207
- "scope": "Hidden table in the accessibility tree, the named plot and its role description, the square plot, ring radii, widths, colors and dash shares, tracks, an empty ring for a missing value, legend cells, separate instances from line charts, the gauge's box, half-circle dash, round track caps and <tfoot> total, no legend for one ring, thinner crowded rings, a value past the maximum, the sparkline size and focus in a flex row, and destroy restoring the table.",
2208
- "state": "stale"
2923
+ "file": "tests/sankey-chart-browser.test.js",
2924
+ "name": "chromium: sankey chart sizes links and nodes on one scale",
2925
+ "scope": "Hidden table, the named plot and its role description, each link as thick as its value at both ends, each node as tall as the larger of its in and out totals, columns from the inline start, stacking in order of first appearance, links that do not overlap on a node edge, the tallest column filling the plot, and separate instances from line charts. No spoken-output assertion.",
2926
+ "state": "not-recorded"
2209
2927
  },
2210
2928
  {
2211
- "file": "tests/radial-chart-browser.test.js",
2212
- "name": "chromium: radial chart tooltip follows the pointer across the rings and the arrow keys",
2213
- "scope": "Pointer distance to ring, gaps split between rings, the active ring, tooltip text with further columns, swatches in the ring color, opening direction, hiding in the middle, off the rings and below a gauge's base line, focus, all four arrows, End and Escape, and clockwise rings with swapped arrows in RTL. No spoken-output assertion.",
2214
- "state": "stale"
2929
+ "file": "tests/sankey-chart-browser.test.js",
2930
+ "name": "chromium: sankey chart arrow keys step through the drawn links in table order",
2931
+ "scope": "Keyboard focus shows the first link; arrows, Home, End and Escape step through the drawn links in table order and skip the rows that draw nothing; the marked link and the live tooltip text. No spoken-output assertion.",
2932
+ "state": "not-recorded"
2215
2933
  }
2216
2934
  ],
2217
- "browserEvidence": "needs-rerun",
2935
+ "browserEvidence": "incomplete",
2218
2936
  "recheckWhen": [
2219
2937
  "A reviewed source changes",
2220
2938
  "A mapped test or its recorded inputs change",
@@ -2222,70 +2940,67 @@
2222
2940
  ]
2223
2941
  },
2224
2942
  {
2225
- "slug": "mixed-chart",
2226
- "title": "Mixed chart",
2943
+ "slug": "treemap-chart",
2944
+ "title": "Treemap chart",
2227
2945
  "kind": "component",
2228
- "support": "implemented",
2946
+ "support": "unassessed",
2229
2947
  "lastReviewedSupport": "implemented",
2230
- "sourceReview": "source-reviewed",
2231
- "reviewedOn": "2026-10-07",
2232
- "scope": "Columns, smooth lines and areas drawn per series from a figure's data table by header class, with dashed lines, a second scale for end series with its own fixed range, x labels, a legend, a sparkline modifier, and a pointer and keyboard tooltip with points on the lines.",
2233
- "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the columns and SVG are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2948
+ "sourceReview": "needs-review",
2949
+ "reviewedOn": "2026-10-25",
2950
+ "scope": "Rectangles drawn from a figure's data table, one per row of the first value column with its area in proportion to the total, in a squarified layout that mirrors in right-to-left pages, with names and cells written in rectangles that hold them, no rectangle for cells that are not positive numbers, six colors, update(), data-watch, and a pointer and keyboard tooltip with each row's share that steps through rows in table order.",
2951
+ "adaptation": "The <table> stays in the page as the text alternative and the no-JavaScript fallback; the rectangles are aria-hidden and the plot is one Tab stop with a polite live tooltip.",
2234
2952
  "upstream": {
2235
2953
  "source": "https://m3.material.io/components",
2236
- "reviewedOn": "2026-10-07",
2954
+ "reviewedOn": "2026-10-25",
2237
2955
  "scope": "web-extension-inventory-reviewed",
2238
2956
  "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
2239
2957
  "sections": [
2240
2958
  "No standalone Material component"
2241
2959
  ],
2242
2960
  "sources": [],
2243
- "requirements": "Keep the data available as text, name the chart, keep series distinguishable without color alone, state each scale's units, and let a keyboard reach every row the pointer can."
2961
+ "requirements": "Keep the data available as text, name the chart, keep each part identifiable without relying on color alone, and let a keyboard reach every part the pointer can."
2244
2962
  },
2245
2963
  "relationship": "none",
2246
2964
  "sources": [
2247
2965
  {
2248
2966
  "path": "src/sass/abstracts/_mixins.scss",
2249
- "sha256": "df530a22fb6b17740054c81ec3ae63c2199726c103e661885ec9bcad0d0f8f4c"
2250
- },
2251
- {
2252
- "path": "src/sass/components/_mixed-chart.scss",
2253
- "sha256": "4195fbf13249ef7bf4da8560f5b0ccbc715367f2b5771c3b96a255af4b9e39bb"
2967
+ "sha256": "47a0a21ff5ea47c1030e3730605cadb4498d868202a88d89670c3aa55cf09702"
2254
2968
  },
2255
2969
  {
2256
- "path": "src/ts/components/columnChart.ts",
2257
- "sha256": "3c8ad721e3abc034c763870081d87a2df0aaf2470d212f03c51086e0ee5deb7d"
2970
+ "path": "src/sass/components/_treemap-chart.scss",
2971
+ "sha256": "a18d6c6bff6123070064a01ac0c6fabbbf4e248d02ebbdcddffcc2d20f3739e9"
2258
2972
  },
2259
2973
  {
2260
2974
  "path": "src/ts/components/lineChart.ts",
2261
- "sha256": "6fdb7471049d342a5e66aa30ba84857208c7d2ed167223b26578e62b9437d960"
2975
+ "sha256": "06a7be0f88231c0368d299a6506643e9aac6fc9a99ac7143ae1d180f98541c71"
2262
2976
  },
2263
2977
  {
2264
- "path": "src/ts/components/mixedChart.ts",
2265
- "sha256": "3c4bc2efee52a5ec53e9318467e9802efbe17b016b4d977c0b3a95ba0f4b52ba"
2978
+ "path": "src/ts/components/treemapChart.ts",
2979
+ "sha256": "146294b6f97121b990cca2e1de1dd96489707e38bdc4c969d52cddba6210be3f"
2266
2980
  }
2267
2981
  ],
2268
2982
  "gaps": [
2269
2983
  {
2270
2984
  "kind": "verification",
2271
- "description": "Drawing, the hidden table, both scales, gaps, the legend, the tooltip, cursor points and keyboard movement are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
2272
- "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text."
2273
- },
2274
- {
2275
- "kind": "feature",
2276
- "description": "There are no y axis labels for either scale, no always-on line markers, no stacked columns and no straight-line option.",
2277
- "nextStep": "Add y axis labels to the shared chart parts if charts need them; name the units in the caption meanwhile."
2985
+ "description": "Areas, layout, gaps, colors, text fitting, keyboard steps, the pointer, the tooltip, update() and data-watch are checked in a browser; screen reader output, forced colors in a browser and enlarged text remain unverified.",
2986
+ "nextStep": "Read a chart with a screen reader in each engine and confirm the table and the live tooltip are announced; check forced colors and enlarged text in a browser."
2278
2987
  }
2279
2988
  ],
2280
2989
  "browserChecks": [
2281
2990
  {
2282
- "file": "tests/mixed-chart-browser.test.js",
2283
- "name": "chromium: mixed chart draws columns, areas and lines on two scales",
2284
- "scope": "Hidden table, the named plot and its role description, column positions on the start scale with an empty slot for a gap, area and dashed line classes and colors, an area fill only on area series, a fixed end scale, a fitted end scale shared by two series, legend order, separate instances from column charts, a chart of gaps showing its table, and the tooltip and cursor points from the keyboard. No spoken-output assertion.",
2285
- "state": "stale"
2991
+ "file": "tests/treemap-chart-browser.test.js",
2992
+ "name": "chromium: treemap chart draws each row as a rectangle whose area follows its value",
2993
+ "scope": "Hidden table, the named plot and its role description, separate instances from line charts, each rectangle's area in proportion to its value, the areas covering the plot without overlap, and the squarified layout in left-to-right and right-to-left pages. No spoken-output assertion.",
2994
+ "state": "not-recorded"
2995
+ },
2996
+ {
2997
+ "file": "tests/treemap-chart-browser.test.js",
2998
+ "name": "chromium: treemap chart steps through its rectangles by key in table order, in either direction",
2999
+ "scope": "Keyboard focus skips a row with no rectangle; arrows, Home, End and Escape step through rows in table order without swapping in a right-to-left page; the outlined rectangle and the live tooltip text with each row's share. No spoken-output assertion.",
3000
+ "state": "not-recorded"
2286
3001
  }
2287
3002
  ],
2288
- "browserEvidence": "needs-rerun",
3003
+ "browserEvidence": "incomplete",
2289
3004
  "recheckWhen": [
2290
3005
  "A reviewed source changes",
2291
3006
  "A mapped test or its recorded inputs change",
@@ -2317,7 +3032,7 @@
2317
3032
  "sources": [
2318
3033
  {
2319
3034
  "path": "src/sass/components/_timeline.scss",
2320
- "sha256": "75d0c9d03e48ca32661b641bdab7890e2e50b3f6d17338bdfc4cb1977c7fc817"
3035
+ "sha256": "4016dd3c8821db410a6af8d0ba7b6bb7e6c9423ba960e10dcc83913ff5b870b8"
2321
3036
  }
2322
3037
  ],
2323
3038
  "gaps": [
@@ -2342,6 +3057,62 @@
2342
3057
  "Google revises the linked guidance or before claiming a new release matches it"
2343
3058
  ]
2344
3059
  },
3060
+ {
3061
+ "slug": "calendar",
3062
+ "title": "Calendar",
3063
+ "kind": "component",
3064
+ "support": "implemented",
3065
+ "lastReviewedSupport": "implemented",
3066
+ "sourceReview": "source-reviewed",
3067
+ "reviewedOn": "2026-10-22",
3068
+ "scope": "A seven-column month grid with weekday headers, today, days outside the month and event chips that ellipsize; week and day hourly grids with events placed by start and duration; a year of small months in as many columns as fit.",
3069
+ "adaptation": "A native table with a caption; the page renders the dates, navigation and events.",
3070
+ "upstream": {
3071
+ "source": "https://m3.material.io/components",
3072
+ "reviewedOn": "2026-10-15",
3073
+ "scope": "web-extension-inventory-reviewed",
3074
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
3075
+ "sections": [
3076
+ "No standalone Material component"
3077
+ ],
3078
+ "sources": [],
3079
+ "requirements": "Name the month in a caption, keep weekday column headers, mark today in text as well as color, and keep each event a reachable link or text."
3080
+ },
3081
+ "relationship": "none",
3082
+ "sources": [
3083
+ {
3084
+ "path": "src/sass/components/_calendar.scss",
3085
+ "sha256": "bf230eb2f7f9f0d3956ffc9e2cc853dab36fe248b47da7c6d615ab0ffddbbcdf"
3086
+ }
3087
+ ],
3088
+ "gaps": [
3089
+ {
3090
+ "kind": "verification",
3091
+ "description": "Equal columns, today, outside days, ellipsized event chips, column headers, hourly event placement, the year tiling and the phone width are checked in a browser; screen reader output remains unverified.",
3092
+ "nextStep": "Read a month with a screen reader in each engine and confirm the day and weekday are announced with each event."
3093
+ }
3094
+ ],
3095
+ "browserChecks": [
3096
+ {
3097
+ "file": "tests/calendar-browser.test.js",
3098
+ "name": "chromium: calendar lays out a month grid with today, outside days and event chips",
3099
+ "scope": "Seven equal columns, day height, the today mark, muted outside days, event chips that stay inside their day and ellipsize, event links, column headers and the month at phone width. No spoken-output assertion.",
3100
+ "state": "not-recorded"
3101
+ },
3102
+ {
3103
+ "file": "tests/calendar-browser.test.js",
3104
+ "name": "chromium: calendar week and day views place events on an hourly grid, and the year view tiles months",
3105
+ "scope": "Hour row height, event top and height from start and duration, events inside their day column, event links, today in the header, hour row headers, a day view event across its column, months side by side and stacked at phone width. No spoken-output assertion.",
3106
+ "state": "not-recorded"
3107
+ }
3108
+ ],
3109
+ "browserEvidence": "incomplete",
3110
+ "recheckWhen": [
3111
+ "A reviewed source changes",
3112
+ "A mapped test or its recorded inputs change",
3113
+ "Google revises the linked guidance or before claiming a new release matches it"
3114
+ ]
3115
+ },
2345
3116
  {
2346
3117
  "slug": "dialogs",
2347
3118
  "title": "Dialogs",
@@ -2386,7 +3157,7 @@
2386
3157
  "lastReviewedSupport": "implemented",
2387
3158
  "sourceReview": "needs-review",
2388
3159
  "reviewedOn": "2026-09-18",
2389
- "scope": "Standard and modal bottom sheets.",
3160
+ "scope": "Standard and modal bottom sheets, with partial and full heights for .expandable sheets.",
2390
3161
  "adaptation": "Native dialog.show()/showModal(); shared runtime handles dragging and dismissal.",
2391
3162
  "upstream": {
2392
3163
  "source": "https://m3.material.io/components/bottom-sheets/overview",
@@ -2433,7 +3204,7 @@
2433
3204
  "gaps": [
2434
3205
  {
2435
3206
  "kind": "integration",
2436
- "description": "The shared handle dismisses rather than cycling sheet heights. Interrupted-drag cleanup, long-content scrolling and enlarged-text action access have rendered coverage; application-owned height changes, native zoom and physical touch remain pending.",
3207
+ "description": "An .expandable sheet switches between a partial and a full height by drag or handle; there are only those two heights, and an application that sets the height itself owns it. Interrupted-drag cleanup, long-content scrolling and enlarged-text action access have rendered coverage; application-owned height changes, native zoom and physical touch remain pending.",
2437
3208
  "nextStep": "Use explicit close controls; verify application-owned height changes, native zoom and physical touch separately."
2438
3209
  }
2439
3210
  ],
@@ -2455,6 +3226,12 @@
2455
3226
  "name": "Bottom sheets keep long content and actions reachable at compact widths (chromium)",
2456
3227
  "scope": "Bottom sheets at 320px and 599px, modal and nonmodal, with 200% root text size, long-body scrolling, horizontal-overflow checks, wrapped headings and action labels, unobscured actions, keyboard dismissal and preserved icon-button/FAB geometry. Root text enlargement is not native browser zoom.",
2457
3228
  "state": "stale"
3229
+ },
3230
+ {
3231
+ "file": "tests/bottom-sheet-expand-browser.test.js",
3232
+ "name": "chromium: an expandable bottom sheet switches between two heights by handle and by drag",
3233
+ "scope": "The handle button switches heights with Enter and Space and keeps aria-expanded current, a drag up expands without the ending click switching back, a drag down collapses from expanded and dismisses from partial, and closing resets to partial. Runs in all three engines. No physical touch.",
3234
+ "state": "not-recorded"
2458
3235
  }
2459
3236
  ],
2460
3237
  "browserEvidence": "needs-rerun",
@@ -2665,9 +3442,9 @@
2665
3442
  "slug": "avatar",
2666
3443
  "title": "Avatar",
2667
3444
  "kind": "component",
2668
- "support": "implemented",
3445
+ "support": "unassessed",
2669
3446
  "lastReviewedSupport": "implemented",
2670
- "sourceReview": "source-reviewed",
3447
+ "sourceReview": "needs-review",
2671
3448
  "reviewedOn": "2026-10-06",
2672
3449
  "scope": "Image, initials and icon avatars in three sizes, and overlapping groups with a surface ring and a count avatar.",
2673
3450
  "adaptation": "An <img> or a <span> with role=\"img\" and a name; initials scale with the size token.",
@@ -2711,6 +3488,56 @@
2711
3488
  "Google revises the linked guidance or before claiming a new release matches it"
2712
3489
  ]
2713
3490
  },
3491
+ {
3492
+ "slug": "org-chart",
3493
+ "title": "Organization chart",
3494
+ "kind": "component",
3495
+ "support": "unassessed",
3496
+ "lastReviewedSupport": "implemented",
3497
+ "sourceReview": "needs-review",
3498
+ "reviewedOn": "2026-10-16",
3499
+ "scope": "Nested lists of native disclosures drawn as cards under their manager, with connector lines, a role band, an avatar and a name, profile links on cards without reports, mirrored order in RTL and sideways scrolling when wide.",
3500
+ "adaptation": "Native <details> managers and nested lists; every manager is a Tab stop and no tree role is promised.",
3501
+ "upstream": {
3502
+ "source": "https://m3.material.io/components",
3503
+ "reviewedOn": "2026-10-16",
3504
+ "scope": "web-extension-inventory-reviewed",
3505
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
3506
+ "sections": [
3507
+ "No standalone Material component"
3508
+ ],
3509
+ "sources": [],
3510
+ "requirements": "Carry the hierarchy in nested lists, expose each manager's expanded state, keep every manager reachable by keyboard, keep the drawn lines silent and avoid a tree role without its arrow-key contract."
3511
+ },
3512
+ "relationship": "none",
3513
+ "sources": [
3514
+ {
3515
+ "path": "src/sass/components/_org-chart.scss",
3516
+ "sha256": "7b342738b7029990224426661ab35b6b95215eb66ee29052439f9a4ea8d3704b"
3517
+ }
3518
+ ],
3519
+ "gaps": [
3520
+ {
3521
+ "kind": "verification",
3522
+ "description": "Cards side by side under their manager in LTR and RTL, the connector bar and drops, a wide chart scrolling with its start reachable, Enter folding a team away, the caret under reduced motion, the caret in forced colors in Chromium and the nested lists in the accessibility tree are checked in a browser; spoken output, the rest of forced colors and enlarged text remain unverified.",
3523
+ "nextStep": "Read a chart with a screen reader in each engine and confirm each list's level and size and each manager's expanded state are announced; check forced colors and 200% text."
3524
+ }
3525
+ ],
3526
+ "browserChecks": [
3527
+ {
3528
+ "file": "tests/org-chart-browser.test.js",
3529
+ "name": "chromium: org chart centres each manager over its reports, collapses a team and scrolls when wide",
3530
+ "scope": "Reports side by side below their manager in order, the manager over its reports, the bar stopping at the end reports, the drop from the manager, mirrored order and bar in RTL, a narrow chart scrolling with every card's start reachable, Enter folding a team, the caret under reduced motion, the CanvasText caret in forced colors and nested lists in the accessibility tree. No spoken-output assertion.",
3531
+ "state": "not-recorded"
3532
+ }
3533
+ ],
3534
+ "browserEvidence": "incomplete",
3535
+ "recheckWhen": [
3536
+ "A reviewed source changes",
3537
+ "A mapped test or its recorded inputs change",
3538
+ "Google revises the linked guidance or before claiming a new release matches it"
3539
+ ]
3540
+ },
2714
3541
  {
2715
3542
  "slug": "tooltips",
2716
3543
  "title": "Tooltips",
@@ -2797,7 +3624,7 @@
2797
3624
  "sources": [
2798
3625
  {
2799
3626
  "path": "src/sass/components/_popover.scss",
2800
- "sha256": "62b149ae34e4e786a1a02a4a12e2208eaff63c08e54fe0a090397b6dd24e4437"
3627
+ "sha256": "ea20e95c04b1ef46cfdd365edfae0441792f4e2c96412cfba853cf9114404616"
2801
3628
  }
2802
3629
  ],
2803
3630
  "gaps": [
@@ -2822,6 +3649,112 @@
2822
3649
  "Google revises the linked guidance or before claiming a new release matches it"
2823
3650
  ]
2824
3651
  },
3652
+ {
3653
+ "slug": "hover-card",
3654
+ "title": "Hover card",
3655
+ "kind": "component",
3656
+ "support": "implemented",
3657
+ "lastReviewedSupport": "implemented",
3658
+ "sourceReview": "source-reviewed",
3659
+ "reviewedOn": "2026-10-25",
3660
+ "scope": "A link with hover-card-trigger whose aria-details names a .popover with popover=\"hint\"; the card shows against the link after enterDelay of hover or keyboard focus, stays while the pointer or focus is on the link or card, hides after exitDelay or at once on Escape with focus back on the link, and a tap or click follows the link.",
3661
+ "adaptation": "Script timers decide when the card shows, and showPopover({ source }) makes the link its anchor and invoker, so the browser places it, puts it next in the Tab order and light-dismisses it. Interest invokers (interestfor) exist only in Chromium, so they are not used.",
3662
+ "upstream": {
3663
+ "source": "https://m3.material.io/components",
3664
+ "reviewedOn": "2026-10-25",
3665
+ "scope": "web-extension-inventory-reviewed",
3666
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
3667
+ "sections": [
3668
+ "No standalone Material component"
3669
+ ],
3670
+ "sources": [],
3671
+ "requirements": "Show the card on hover and keyboard focus after a delay, keep it open while the pointer or focus is on the link or the card, hide it on Escape with focus back on the link, leave the link's click alone and relate the card to the link with aria-details."
3672
+ },
3673
+ "relationship": "none",
3674
+ "sources": [
3675
+ {
3676
+ "path": "src/ts/components/hoverCard.ts",
3677
+ "sha256": "6e08cd305135d7280bc515e9e1b262f51c86959b3339270f312c7ae53a34e2bf"
3678
+ }
3679
+ ],
3680
+ "gaps": [
3681
+ {
3682
+ "kind": "verification",
3683
+ "description": "Hover delay, a pointer that passes over, staying open on the card, hiding after exitDelay, keyboard focus, Tab into the card, Escape with focus back on the link, focus leaving the card and a click that focuses the link are checked in Chromium, Firefox and WebKit; spoken output and aria-details support in screen readers remain unverified.",
3684
+ "nextStep": "Tab to a hover card link with VoiceOver and NVDA and confirm the details relationship is announced and the card is reachable."
3685
+ }
3686
+ ],
3687
+ "browserChecks": [
3688
+ {
3689
+ "file": "tests/hover-card-browser.test.js",
3690
+ "name": "chromium: hovering the link shows the card after the delay, and it stays while the pointer is on the card",
3691
+ "scope": "Nothing before enterDelay, the card against the link's bottom edge plus the popover gap, staying open with the pointer on the card past exitDelay, and hiding once the pointer has left both.",
3692
+ "state": "not-recorded"
3693
+ },
3694
+ {
3695
+ "file": "tests/hover-card-browser.test.js",
3696
+ "name": "chromium: keyboard focus shows the card, Tab moves into it, and Escape hides it with focus back on the link",
3697
+ "scope": "Tab to the link shows the card after enterDelay with focus kept on the link, Tab into the card keeps it open, and Escape hides it with focus back on the link.",
3698
+ "state": "not-recorded"
3699
+ }
3700
+ ],
3701
+ "browserEvidence": "incomplete",
3702
+ "recheckWhen": [
3703
+ "A reviewed source changes",
3704
+ "A mapped test or its recorded inputs change",
3705
+ "Google revises the linked guidance or before claiming a new release matches it"
3706
+ ]
3707
+ },
3708
+ {
3709
+ "slug": "tour",
3710
+ "title": "Tour",
3711
+ "kind": "component",
3712
+ "support": "unassessed",
3713
+ "lastReviewedSupport": "implemented",
3714
+ "sourceReview": "needs-review",
3715
+ "reviewedOn": "2026-10-15",
3716
+ "scope": "One step at a time beside its target, a highlight ring, Back, Next and Done, progress text, skipped missing targets, Escape and focus return.",
3717
+ "adaptation": "A manual native popover placed with CSS anchor positioning; the Tour behavior moves the anchor and focus.",
3718
+ "upstream": {
3719
+ "source": "https://m3.material.io/components",
3720
+ "reviewedOn": "2026-10-15",
3721
+ "scope": "web-extension-inventory-reviewed",
3722
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
3723
+ "sections": [
3724
+ "No standalone Material component"
3725
+ ],
3726
+ "sources": [],
3727
+ "requirements": "Let the user start, skip and end the tour, name the card by the step heading, move focus to it and back afterwards, and skip steps whose target is not shown."
3728
+ },
3729
+ "relationship": "none",
3730
+ "sources": [
3731
+ {
3732
+ "path": "src/ts/behaviors/tour.ts",
3733
+ "sha256": "f7aa25d13a8b392871cbe6d601366418fb6b975b6b540a77f220fc143ec79278"
3734
+ }
3735
+ ],
3736
+ "gaps": [
3737
+ {
3738
+ "kind": "verification",
3739
+ "description": "Placement beside each target, the card name, progress, button visibility, skipped targets, Escape, focus return and cleanup after a scripted close are checked in a browser; screen reader output remains unverified.",
3740
+ "nextStep": "Take a tour with a screen reader in each engine and confirm each step is announced when it opens."
3741
+ }
3742
+ ],
3743
+ "browserChecks": [
3744
+ {
3745
+ "file": "tests/tour-browser.test.js",
3746
+ "name": "chromium: a tour steps through its targets beside each one and returns focus",
3747
+ "scope": "Opening from a start button, the card named by the step heading, progress text, skipped missing targets, button visibility per step, placement below each target, releasing the previous target, Escape, focus return and cleanup after hidePopover. No spoken-output assertion.",
3748
+ "state": "not-recorded"
3749
+ }
3750
+ ],
3751
+ "browserEvidence": "incomplete",
3752
+ "recheckWhen": [
3753
+ "A reviewed source changes",
3754
+ "A mapped test or its recorded inputs change",
3755
+ "Google revises the linked guidance or before claiming a new release matches it"
3756
+ ]
3757
+ },
2825
3758
  {
2826
3759
  "slug": "snackbar",
2827
3760
  "title": "Snackbar",
@@ -2930,11 +3863,6 @@
2930
3863
  "kind": "verification",
2931
3864
  "description": "Forced-colors rendering is checked in browser emulation; Windows high-contrast and spoken output still require manual review.",
2932
3865
  "nextStep": "Verify native and custom indicators with Windows contrast themes and screen readers before claiming platform-wide support."
2933
- },
2934
- {
2935
- "kind": "feature",
2936
- "description": "Version 0.10.0 mirrors custom linear fill and motion in RTL. End-stop and wavy Expressive variants remain unverified.",
2937
- "nextStep": "Assess an end stop for insufficient track contrast and review wavy variants before claiming current variant parity."
2938
3866
  }
2939
3867
  ],
2940
3868
  "browserChecks": [
@@ -3015,7 +3943,67 @@
3015
3943
  "state": "stale"
3016
3944
  }
3017
3945
  ],
3018
- "browserEvidence": "needs-rerun",
3946
+ "browserEvidence": "needs-rerun",
3947
+ "recheckWhen": [
3948
+ "A reviewed source changes",
3949
+ "A mapped test or its recorded inputs change",
3950
+ "Google revises the linked guidance or before claiming a new release matches it"
3951
+ ]
3952
+ },
3953
+ {
3954
+ "slug": "loading-overlay",
3955
+ "title": "Loading overlay",
3956
+ "kind": "component",
3957
+ "support": "implemented",
3958
+ "lastReviewedSupport": "implemented",
3959
+ "sourceReview": "source-reviewed",
3960
+ "reviewedOn": "2026-10-25",
3961
+ "scope": "A region the page marks aria-busy=\"true\" shows a surface scrim and its loading indicator and is made inert until the attribute goes, with focus taken from the control inside it, keeps an inert state the author set, announces the start and the finish in a status region after it with i18n strings, returns focus to the control that had it, and stops following the attribute on destroy().",
3962
+ "adaptation": "The native inert attribute blocks pointer and keyboard input instead of script handlers. The page owns aria-busy, and the script follows it with a MutationObserver. Inert content leaves the accessibility tree, so the script adds a visually hidden role=\"status\" region outside the region.",
3963
+ "upstream": {
3964
+ "source": "https://m3.material.io/components",
3965
+ "reviewedOn": "2026-10-25",
3966
+ "scope": "web-extension-inventory-reviewed",
3967
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
3968
+ "sections": [
3969
+ "No standalone Material component"
3970
+ ],
3971
+ "sources": [],
3972
+ "requirements": "Block input to the busy region only, report the busy state and its end to assistive technology, keep focus from being lost for good, and keep the content visibly unavailable in forced colors."
3973
+ },
3974
+ "relationship": "none",
3975
+ "sources": [
3976
+ {
3977
+ "path": "src/sass/components/_loading-overlay.scss",
3978
+ "sha256": "4d8f10f145a92143a541e454c733756680162970a29382e24e603e849b8aca70"
3979
+ },
3980
+ {
3981
+ "path": "src/ts/components/loadingOverlay.ts",
3982
+ "sha256": "5544177df22e5fcc5aa30f2764414498b48620387f8df7cbc2de8170ed94240d"
3983
+ }
3984
+ ],
3985
+ "gaps": [
3986
+ {
3987
+ "kind": "verification",
3988
+ "description": "Input blocking, the author's inert state, the status region, focus return, the scrim and indicator geometry and destroy() are checked in Chromium, Firefox and WebKit; spoken output from the status region and real forced-colors themes remain unverified.",
3989
+ "nextStep": "Mark a region busy and clear it with VoiceOver and NVDA running, and view it under a Windows high-contrast theme."
3990
+ }
3991
+ ],
3992
+ "browserChecks": [
3993
+ {
3994
+ "file": "tests/loading-overlay-browser.test.js",
3995
+ "name": "chromium: a busy region takes no click or Tab, and clearing it gives both back",
3996
+ "scope": "A real mouse click and Tab while aria-busy is \"true\", and again after it is set to \"false\" and after it is removed.",
3997
+ "state": "not-recorded"
3998
+ },
3999
+ {
4000
+ "file": "tests/loading-overlay-browser.test.js",
4001
+ "name": "chromium: focus goes back to where it was when the region clears",
4002
+ "scope": "Focus dropped by inert and returned on clear, a focus move made while busy kept, and a removed control not refocused. No spoken-output assertion.",
4003
+ "state": "not-recorded"
4004
+ }
4005
+ ],
4006
+ "browserEvidence": "incomplete",
3019
4007
  "recheckWhen": [
3020
4008
  "A reviewed source changes",
3021
4009
  "A mapped test or its recorded inputs change",
@@ -3047,7 +4035,7 @@
3047
4035
  "sources": [
3048
4036
  {
3049
4037
  "path": "src/sass/components/_skeleton.scss",
3050
- "sha256": "f22efd82847af981cf225a0991a471e5fd25f7cdb07c1e0ec80195e937b13818"
4038
+ "sha256": "f5b2a97773d171ad5d535f638324ed329aa93c1c957b601c59471838cfbd12d6"
3051
4039
  }
3052
4040
  ],
3053
4041
  "gaps": [
@@ -3122,6 +4110,62 @@
3122
4110
  "Google revises the linked guidance or before claiming a new release matches it"
3123
4111
  ]
3124
4112
  },
4113
+ {
4114
+ "slug": "alert",
4115
+ "title": "Alert",
4116
+ "kind": "component",
4117
+ "support": "implemented",
4118
+ "lastReviewedSupport": "implemented",
4119
+ "sourceReview": "source-reviewed",
4120
+ "reviewedOn": "2026-10-15",
4121
+ "scope": "A tonal container with an optional leading icon, a heading and text, an end-aligned actions row, a close button and a critical error-container tone.",
4122
+ "adaptation": "A plain div around authored text and buttons; a changing alert puts role=\"status\" or role=\"alert\" on its text, never on the controls.",
4123
+ "upstream": {
4124
+ "source": "https://m3.material.io/components",
4125
+ "reviewedOn": "2026-10-15",
4126
+ "scope": "web-extension-inventory-reviewed",
4127
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
4128
+ "sections": [
4129
+ "No standalone Material component"
4130
+ ],
4131
+ "sources": [],
4132
+ "requirements": "Keep the message in the reading order next to what it describes, convey tone in text as well as color, keep controls out of any live region and return focus when an alert is dismissed."
4133
+ },
4134
+ "relationship": "none",
4135
+ "sources": [
4136
+ {
4137
+ "path": "src/sass/components/_alert.scss",
4138
+ "sha256": "bae889fd978f89022c7e1fad03be39b63ae845984f178499eb195127e05cec52"
4139
+ }
4140
+ ],
4141
+ "gaps": [
4142
+ {
4143
+ "kind": "verification",
4144
+ "description": "The layout, both tones, enlarged-text wrapping and the authored role are checked in a browser; live announcements and spoken output remain unverified.",
4145
+ "nextStep": "Show and update an alert with a screen reader in each engine and confirm status and alert roles are announced once, without the button labels; test forced colors."
4146
+ }
4147
+ ],
4148
+ "browserChecks": [
4149
+ {
4150
+ "file": "tests/alert-browser.test.js",
4151
+ "name": "chromium: alert lays out icon, text, close and actions, and colors the critical tone",
4152
+ "scope": "Icon, heading, text, close and actions placement, end-aligned actions, 16px corners, title-small heading, underlined links, text start without an icon, secondary and critical container colors, the authored alert role and controls kept inside at 280px. No spoken-output assertion.",
4153
+ "state": "not-recorded"
4154
+ },
4155
+ {
4156
+ "file": "tests/error-summary-browser.test.js",
4157
+ "name": "chromium: error summary lists invalid fields, takes focus and links to each field",
4158
+ "scope": "Blocked invalid submit, page handlers not reached, one labelled link per invalid field and radio group, focus on the summary, links focusing fields, generated ids, formnovalidate, and hiding after a valid submit. No spoken-output assertion.",
4159
+ "state": "not-recorded"
4160
+ }
4161
+ ],
4162
+ "browserEvidence": "incomplete",
4163
+ "recheckWhen": [
4164
+ "A reviewed source changes",
4165
+ "A mapped test or its recorded inputs change",
4166
+ "Google revises the linked guidance or before claiming a new release matches it"
4167
+ ]
4168
+ },
3125
4169
  {
3126
4170
  "slug": "carousel",
3127
4171
  "title": "Carousel",
@@ -3202,6 +4246,56 @@
3202
4246
  "Google revises the linked guidance or before claiming a new release matches it"
3203
4247
  ]
3204
4248
  },
4249
+ {
4250
+ "slug": "image-compare",
4251
+ "title": "Image compare",
4252
+ "kind": "component",
4253
+ "support": "implemented",
4254
+ "lastReviewedSupport": "implemented",
4255
+ "sourceReview": "source-reviewed",
4256
+ "reviewedOn": "2026-10-15",
4257
+ "scope": "Two stacked images, a divider and handle driven by a native range input, keyboard and pointer control, RTL and a focus ring.",
4258
+ "adaptation": "A native range input covers the images invisibly; the ImageCompare behavior writes its value to the divider position.",
4259
+ "upstream": {
4260
+ "source": "https://m3.material.io/components",
4261
+ "reviewedOn": "2026-10-15",
4262
+ "scope": "web-extension-inventory-reviewed",
4263
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
4264
+ "sections": [
4265
+ "No standalone Material component"
4266
+ ],
4267
+ "sources": [],
4268
+ "requirements": "Give both images alt text that says which is which, name the range, and keep it operable by keyboard and pointer."
4269
+ },
4270
+ "relationship": "none",
4271
+ "sources": [
4272
+ {
4273
+ "path": "src/sass/components/_image-compare.scss",
4274
+ "sha256": "1dea70f8b47092f064348912efedfa0b29a52be680a7d402e4d84f883d669f8e"
4275
+ }
4276
+ ],
4277
+ "gaps": [
4278
+ {
4279
+ "kind": "verification",
4280
+ "description": "The initial position, the reveal by arrow keys, the focus ring, RTL, the named slider and Slider staying off are checked in a browser; screen reader output remains unverified.",
4281
+ "nextStep": "Move the divider with a screen reader in each engine and confirm the value is announced."
4282
+ }
4283
+ ],
4284
+ "browserChecks": [
4285
+ {
4286
+ "file": "tests/image-compare-browser.test.js",
4287
+ "name": "chromium: image compare reveals the second image up to the range's value",
4288
+ "scope": "The initial value applied on load, each image on its side of the divider, arrow keys moving the divider, the handle focus ring, RTL, named native sliders and Slider leaving the range alone. No spoken-output assertion.",
4289
+ "state": "not-recorded"
4290
+ }
4291
+ ],
4292
+ "browserEvidence": "incomplete",
4293
+ "recheckWhen": [
4294
+ "A reviewed source changes",
4295
+ "A mapped test or its recorded inputs change",
4296
+ "Google revises the linked guidance or before claiming a new release matches it"
4297
+ ]
4298
+ },
3205
4299
  {
3206
4300
  "slug": "marquee",
3207
4301
  "title": "Marquee",
@@ -3227,7 +4321,7 @@
3227
4321
  "sources": [
3228
4322
  {
3229
4323
  "path": "src/sass/components/_marquee.scss",
3230
- "sha256": "e76d8380b53cf788c1304e9331c632083468109f8b726c2e1eeaa3a20adb95eb"
4324
+ "sha256": "b7494c72fa5de69416b87830f020425ac91a1fb123711917534e4dc46d6e8f95"
3231
4325
  }
3232
4326
  ],
3233
4327
  "gaps": [
@@ -3277,11 +4371,11 @@
3277
4371
  "sources": [
3278
4372
  {
3279
4373
  "path": "src/sass/components/_confetti.scss",
3280
- "sha256": "0dc01d28e2bf26877ab57e5d5504b6dbd734b3ef64f593bf67e34753922a3d63"
4374
+ "sha256": "f0491b4174a1cb86bcc8e089b2b719f072440594641eb039ee27dca1a56ac24e"
3281
4375
  },
3282
4376
  {
3283
4377
  "path": "src/ts/components/confetti.ts",
3284
- "sha256": "c5f6f8782548d71bce17e1f701b7f7c1376c2a88252fc3e07238699125c6503e"
4378
+ "sha256": "3eeacd4eabd4ffe48586e85b874a394f2bc96fe35133678e1a06f14ac751ebf2"
3285
4379
  }
3286
4380
  ],
3287
4381
  "gaps": [
@@ -3331,7 +4425,7 @@
3331
4425
  "sources": [
3332
4426
  {
3333
4427
  "path": "src/sass/components/_particles.scss",
3334
- "sha256": "5d2d67515f7152d5b86d506e7fe42d9c66f058bd7b9e30a06a7b8fedc4738cc3"
4428
+ "sha256": "7c9f562cdcac1fca51eea032786fa324c708e1972d10f4cd08e61f4982f31efd"
3335
4429
  },
3336
4430
  {
3337
4431
  "path": "src/ts/components/particles.ts",
@@ -3622,9 +4716,9 @@
3622
4716
  "slug": "command-palette",
3623
4717
  "title": "Command palette",
3624
4718
  "kind": "component",
3625
- "support": "implemented",
4719
+ "support": "unassessed",
3626
4720
  "lastReviewedSupport": "implemented",
3627
- "sourceReview": "source-reviewed",
4721
+ "sourceReview": "needs-review",
3628
4722
  "reviewedOn": "2026-10-06",
3629
4723
  "scope": "A modal dialog with a filtering combobox and listbox, group headings, keywords, an empty message, a Ctrl or Command shortcut and native commandfor opening.",
3630
4724
  "adaptation": "A native modal <dialog>; commands are links and buttons, and the component adds the combobox and listbox roles and the active option.",
@@ -3643,11 +4737,11 @@
3643
4737
  "sources": [
3644
4738
  {
3645
4739
  "path": "src/sass/components/_command-palette.scss",
3646
- "sha256": "d9d4dd1fe2b3bc60aa29203a7526139e8e75e6d7b2a76bbe2dd59e671f62ed0d"
4740
+ "sha256": "6dddb9ebc73009d7b45e09430c3abb40e0775d05c2fc5c2c89ee6f34e90e5d37"
3647
4741
  },
3648
4742
  {
3649
4743
  "path": "src/ts/components/commandPalette.ts",
3650
- "sha256": "55fb823a7e70d5cc7d22cd10a84054badac5a7d5df7274d3b67aa044349a642e"
4744
+ "sha256": "8e3d5b555365df4ba28b4d915f6f717ac20be9d6d76390dd0a024b0816630725"
3651
4745
  }
3652
4746
  ],
3653
4747
  "gaps": [
@@ -3785,12 +4879,124 @@
3785
4879
  ]
3786
4880
  },
3787
4881
  {
3788
- "slug": "rich-text-editor",
3789
- "title": "Rich text editor",
4882
+ "slug": "input-mask",
4883
+ "title": "Input mask",
4884
+ "kind": "component",
4885
+ "support": "implemented",
4886
+ "lastReviewedSupport": "implemented",
4887
+ "sourceReview": "source-reviewed",
4888
+ "reviewedOn": "2026-10-25",
4889
+ "scope": "A data-mask pattern on a text, tel, search, url or password input, where 0 takes a digit, a a letter, * either and a backslash escapes a literal; typed, pasted, autofilled and composed text formatted with the caret after the edit, Backspace and Delete across literals, saved and reset values formatted, the formatted value submitted and validated, and formatting before the page's input listeners.",
4890
+ "adaptation": "A capture-phase input listener rewrites the native value, so the form, constraint validation and FormData see what the field shows. Composing input is skipped and the field formats on compositionend, and a beforeinput listener turns a one-character delete next to a literal into a delete of the slot character across it.",
4891
+ "upstream": {
4892
+ "source": "https://m3.material.io/components",
4893
+ "reviewedOn": "2026-10-25",
4894
+ "scope": "web-extension-inventory-reviewed",
4895
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
4896
+ "sections": [
4897
+ "No standalone Material component"
4898
+ ],
4899
+ "sources": [],
4900
+ "requirements": "Keep the field a labelled native input, show the expected format in visible text, leave IME composition alone until it ends, keep the caret where the person is editing, and submit and validate the value the person sees."
4901
+ },
4902
+ "relationship": "none",
4903
+ "sources": [
4904
+ {
4905
+ "path": "src/ts/components/inputMask.ts",
4906
+ "sha256": "cd8df794a9148bcf3a112066dd662beea863dd8228c83c878dc15ac0e0420ea0"
4907
+ }
4908
+ ],
4909
+ "gaps": [
4910
+ {
4911
+ "kind": "verification",
4912
+ "description": "Typing, inserted pastes, deletes across literals, composition in both event orders, saved and reset values, listener order, Keypad keys and destroy() are checked in a browser; real IMEs, Android keyboards, clipboard pastes and spoken output remain unverified.",
4913
+ "nextStep": "Type into a masked field with a Japanese IME, Chinese pinyin and Gboard on Android, and read it with VoiceOver and NVDA."
4914
+ }
4915
+ ],
4916
+ "browserChecks": [
4917
+ {
4918
+ "file": "tests/input-mask-browser.test.js",
4919
+ "name": "chromium: typed and pasted digits take the mask's pattern, and the form submits it",
4920
+ "scope": "Real keyboard typing and an insertText paste formatted with the caret after the last digit, and the formatted value in FormData and the submit event.",
4921
+ "state": "not-recorded"
4922
+ },
4923
+ {
4924
+ "file": "tests/input-mask-browser.test.js",
4925
+ "name": "chromium: the field waits for a composition to end, in either event order",
4926
+ "scope": "Composition dispatched with the last input before and after compositionend, and a CDP composition of full-width digits.",
4927
+ "state": "not-recorded"
4928
+ }
4929
+ ],
4930
+ "browserEvidence": "incomplete",
4931
+ "recheckWhen": [
4932
+ "A reviewed source changes",
4933
+ "A mapped test or its recorded inputs change",
4934
+ "Google revises the linked guidance or before claiming a new release matches it"
4935
+ ]
4936
+ },
4937
+ {
4938
+ "slug": "currency-input",
4939
+ "title": "Currency input",
3790
4940
  "kind": "component",
3791
4941
  "support": "implemented",
3792
4942
  "lastReviewedSupport": "implemented",
3793
4943
  "sourceReview": "source-reviewed",
4944
+ "reviewedOn": "2026-10-25",
4945
+ "scope": "A data-currency ISO 4217 code on a text input; the amount shown with Intl.NumberFormat in the nearest lang and that currency on blur, the plain number in the locale's decimal mark on focus, typed and pasted amounts read in either decimal mark, a validity message for text with no digit that i18n can replace, saved and reset values formatted, a value property, and the plain number in the form data.",
4946
+ "adaptation": "The native value holds the formatted text, and a capture-phase formdata listener on the document swaps the field's entry for the plain number, so submits and new FormData(form) read a number while the field keeps its name. setCustomValidity reports text with no amount, so constraint validation and .validate show the message.",
4947
+ "upstream": {
4948
+ "source": "https://m3.material.io/components",
4949
+ "reviewedOn": "2026-10-25",
4950
+ "scope": "web-extension-inventory-reviewed",
4951
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
4952
+ "sections": [
4953
+ "No standalone Material component"
4954
+ ],
4955
+ "sources": [],
4956
+ "requirements": "Keep the field a labelled native input that names the currency, show the amount in the reader's locale, let people edit a plain number, report text that holds no amount as invalid, and submit a number a server can read whatever the locale."
4957
+ },
4958
+ "relationship": "none",
4959
+ "sources": [
4960
+ {
4961
+ "path": "src/ts/components/currencyInput.ts",
4962
+ "sha256": "a3c806c79bccdb2e96234d6428483ac3bec1be9c213a97df6e3008f00212c28b"
4963
+ }
4964
+ ],
4965
+ "gaps": [
4966
+ {
4967
+ "kind": "verification",
4968
+ "description": "Typing and blur, focus editing, listener order, pasted amounts submitted with Enter, the validity message, saved and reset values and destroy() are checked in a browser, and the parsing rules in jsdom; mobile decimal keypads and spoken output remain unverified.",
4969
+ "nextStep": "Type an amount on iOS Safari and Android Chrome decimal keypads under lang=\"de\", and read the field with VoiceOver and NVDA."
4970
+ }
4971
+ ],
4972
+ "browserChecks": [
4973
+ {
4974
+ "file": "tests/currency-input-browser.test.js",
4975
+ "name": "chromium: a typed amount shows in the locale and currency after blur, and the form gets the number",
4976
+ "scope": "Real keyboard typing under lang=\"de\" with euros formatted on blur, and the plain number in FormData and the submit event.",
4977
+ "state": "not-recorded"
4978
+ },
4979
+ {
4980
+ "file": "tests/currency-input-browser.test.js",
4981
+ "name": "chromium: text that holds no amount stays as typed and marks the field invalid until it does",
4982
+ "scope": "Text with no digit kept, the validity message and aria-invalid set, cleared once the field holds an amount, and the message replaced through data-currency-input-options.",
4983
+ "state": "not-recorded"
4984
+ }
4985
+ ],
4986
+ "browserEvidence": "incomplete",
4987
+ "recheckWhen": [
4988
+ "A reviewed source changes",
4989
+ "A mapped test or its recorded inputs change",
4990
+ "Google revises the linked guidance or before claiming a new release matches it"
4991
+ ]
4992
+ },
4993
+ {
4994
+ "slug": "rich-text-editor",
4995
+ "title": "Rich text editor",
4996
+ "kind": "component",
4997
+ "support": "unassessed",
4998
+ "lastReviewedSupport": "implemented",
4999
+ "sourceReview": "needs-review",
3794
5000
  "reviewedOn": "2026-10-08",
3795
5001
  "scope": "A Tiptap editor mounted from a textarea, toolbar buttons that run Tiptap commands with JSON arguments, pressed and disabled button state, form submission through the textarea, label naming and read-only textareas.",
3796
5002
  "adaptation": "The page supplies Tiptap's Editor class and extensions; the component mounts it, names the contenteditable textbox from the textarea and keeps the textarea in sync. The toolbar is the docked toolbar.",
@@ -3809,7 +5015,7 @@
3809
5015
  "sources": [
3810
5016
  {
3811
5017
  "path": "src/sass/components/_rich-text-editor.scss",
3812
- "sha256": "4ff745197d37043297861b0a4166e0bda0fd3adcdb160baed5dffb6a6821dd46"
5018
+ "sha256": "226fa4214606a435d08a15df773dd220e9eb10b2c4e05f006e8b43c1329a360c"
3813
5019
  },
3814
5020
  {
3815
5021
  "path": "src/ts/components/richTextEditor.ts",
@@ -3869,7 +5075,7 @@
3869
5075
  "sources": [
3870
5076
  {
3871
5077
  "path": "src/sass/components/forms/_drop-zone.scss",
3872
- "sha256": "dcc9dc0e721c0057266092591634249620143d8b7350ff867651806c59ad10b1"
5078
+ "sha256": "f85c6545be72c10b8fea56495c248556cccb801b550f7491e4d211353c12fb0d"
3873
5079
  },
3874
5080
  {
3875
5081
  "path": "src/ts/behaviors/forms.ts",
@@ -3905,8 +5111,8 @@
3905
5111
  "support": "unassessed",
3906
5112
  "lastReviewedSupport": "implemented",
3907
5113
  "sourceReview": "needs-review",
3908
- "reviewedOn": "2026-09-17",
3909
- "scope": "Single/multiple selection, optgroups, and browser-default fallback.",
5114
+ "reviewedOn": "2026-10-27",
5115
+ "scope": "Single/multiple selection, optgroups, browser-default fallback, and opt-in single and multiple select search with a separate popup field and native form values.",
3910
5116
  "adaptation": "Native select enhanced by runtime; this is related to menu/text-field patterns.",
3911
5117
  "upstream": {
3912
5118
  "source": "https://m3.material.io/components/menus/overview",
@@ -3927,79 +5133,233 @@
3927
5133
  "https://m3.material.io/components/text-fields/guidelines",
3928
5134
  "https://m3.material.io/components/text-fields/accessibility"
3929
5135
  ],
3930
- "requirements": "Google menu guidance includes select and text-field dropdown menus. Single selection replaces the previous value; multiple selection remains open. Preserve field labels and associated errors."
5136
+ "requirements": "Google menu guidance includes select and text-field dropdown menus. Single selection replaces the previous value; multiple selection remains open. Preserve field labels and associated errors."
5137
+ },
5138
+ "relationship": "related",
5139
+ "sources": [
5140
+ {
5141
+ "path": "src/sass/components/forms/_select.scss",
5142
+ "sha256": "d72f66ebe96038d8dcee434ed75bcff1f9e2f6995f8cf0a578a3abd747327315"
5143
+ },
5144
+ {
5145
+ "path": "src/sass/components/_menu.scss",
5146
+ "sha256": "586e869181fda28efcf9f511ba90908b6f6788d7eff614f90c89fe1d7a56c396"
5147
+ },
5148
+ {
5149
+ "path": "src/ts/components/select.ts",
5150
+ "sha256": "2d66f7211e68fb92c061ab4df6e872ba9853fb858111ec43e00833639783c3f7"
5151
+ },
5152
+ {
5153
+ "path": "src/ts/components/menu.ts",
5154
+ "sha256": "52b3f0016e521f1785a76a44b8ba91051c675a4c2c0c95afac9d8a397ff0a6f8"
5155
+ }
5156
+ ],
5157
+ "gaps": [
5158
+ {
5159
+ "kind": "verification",
5160
+ "description": "Native zoom, screen-reader announcements, Windows contrast themes and physical-device form interaction remain unverified.",
5161
+ "nextStep": "Complete the Select native-forms manual-review fixture and record actual browser, assistive technology and device results."
5162
+ }
5163
+ ],
5164
+ "browserChecks": [
5165
+ {
5166
+ "file": "tests/expressivecss-lifecycle-browser.test.js",
5167
+ "name": "partial replacement and client navigation preserve shell ownership across repeated mounts",
5168
+ "scope": "Rail shell ownership; enhanced select interaction; generated Menu registry/resource cleanup; tooltip ownership across route replacement.",
5169
+ "state": "stale"
5170
+ },
5171
+ {
5172
+ "file": "tests/expressivecss-lifecycle-browser.test.js",
5173
+ "name": "resource observations detect omitted teardown after a partial replacement",
5174
+ "scope": "Negative control proves resources remain without destroy; no visual parity assertion.",
5175
+ "state": "stale"
5176
+ },
5177
+ {
5178
+ "file": "tests/menu-field-browser.test.js",
5179
+ "name": "enhanced select keeps enlarged multiline labels clear of values (chromium)",
5180
+ "scope": "Filled enhanced select label/value separation with multiline LTR/RTL labels at 16px and 32px root text size. Native zoom, native and outlined selects are not covered. Equivalent Firefox and WebKit cases run in the same file.",
5181
+ "state": "stale"
5182
+ },
5183
+ {
5184
+ "file": "tests/menu-field-browser.test.js",
5185
+ "name": "Select native form synchronization: disabled (chromium)",
5186
+ "scope": "Single/multiple selected labels, disabled options and optgroups, empty selections and native FormData. Equivalent Firefox and WebKit cases run in the same file.",
5187
+ "state": "stale"
5188
+ },
5189
+ {
5190
+ "file": "tests/menu-field-browser.test.js",
5191
+ "name": "Select native form synchronization: reset (chromium)",
5192
+ "scope": "Successful and canceled native resets, default selections, generated selection semantics and no synthetic change events. Equivalent Firefox and WebKit cases run in the same file.",
5193
+ "state": "stale"
5194
+ },
5195
+ {
5196
+ "file": "tests/menu-field-browser.test.js",
5197
+ "name": "Select native form synchronization: refresh (chromium)",
5198
+ "scope": "Disabled/enabled refresh, changed and removed options, open-menu focus, Escape, stale rows, native change events and unrelated focus preservation. Equivalent Firefox and WebKit cases run in the same file.",
5199
+ "state": "stale"
5200
+ },
5201
+ {
5202
+ "file": "tests/menu-field-browser.test.js",
5203
+ "name": "Select native form synchronization: interaction (chromium)",
5204
+ "scope": "Pointer and keyboard multiple selection, event counts, checkbox state, native FormData, LTR/RTL, both motion preferences, reset teardown and instance isolation. Equivalent Firefox and WebKit cases run in the same file.",
5205
+ "state": "stale"
5206
+ },
5207
+ {
5208
+ "file": "tests/select-search-browser.test.js",
5209
+ "name": "chromium: searchable select filters grouped options and submits the chosen value by pointer",
5210
+ "scope": "Grouped literal filtering, pointer selection, native form submission and one change event. Equivalent Firefox and WebKit cases run in the same file.",
5211
+ "state": "not-recorded"
5212
+ },
5213
+ {
5214
+ "file": "tests/select-search-browser.test.js",
5215
+ "name": "chromium: searchable select keeps text editing separate from row navigation and restores focus",
5216
+ "scope": "Search editing, arrow navigation, selection, Escape and focus recovery. Equivalent Firefox and WebKit cases run in the same file.",
5217
+ "state": "not-recorded"
5218
+ },
5219
+ {
5220
+ "file": "tests/select-search-browser.test.js",
5221
+ "name": "chromium: searchable select refreshes a live query, preserves the caret, and resets native state",
5222
+ "scope": "Live-query refresh, disabled rows, caret/focus, successful and canceled reset and disabling the control. Equivalent Firefox and WebKit cases run in the same file.",
5223
+ "state": "not-recorded"
5224
+ },
5225
+ {
5226
+ "file": "tests/select-search-browser.test.js",
5227
+ "name": "chromium: searchable select works in a native modal dialog and an open shadow root",
5228
+ "scope": "Popup operation, keyboard selection and focus recovery inside a native modal dialog and an open shadow root. Equivalent Firefox and WebKit cases run in the same file.",
5229
+ "state": "not-recorded"
5230
+ },
5231
+ {
5232
+ "file": "tests/select-search-browser.test.js",
5233
+ "name": "chromium: searchable select keeps search visible while results scroll with enlarged RTL text and forced colors",
5234
+ "scope": "Scrolling results, visible search/focus ring, enlarged RTL text, forced colors and reduced motion. Programmatic font scaling does not prove native zoom or spoken output. Equivalent Firefox and WebKit cases run in the same file.",
5235
+ "state": "not-recorded"
5236
+ },
5237
+ {
5238
+ "file": "tests/select-search-browser.test.js",
5239
+ "name": "chromium: searchable select multiple picks across queries, keeps the query and focus, and submits every value",
5240
+ "scope": "Multiple-select search: keyboard, box and row picks across queries, retained query and row focus, checkbox state, Escape, Tab exit and native FormData with every chosen value. Equivalent Firefox and WebKit cases run in the same file.",
5241
+ "state": "not-recorded"
5242
+ },
5243
+ {
5244
+ "file": "tests/select-search-browser.test.js",
5245
+ "name": "chromium: searchable select multiple picks within an open shadow root and dismisses outside without losing picks",
5246
+ "scope": "Multiple-select search inside an open shadow root, pointer picks and outside dismissal that clears the query and keeps selections. Equivalent Firefox and WebKit cases run in the same file.",
5247
+ "state": "not-recorded"
5248
+ }
5249
+ ],
5250
+ "browserEvidence": "needs-rerun",
5251
+ "recheckWhen": [
5252
+ "A reviewed source changes",
5253
+ "A mapped test or its recorded inputs change",
5254
+ "Google revises the linked guidance or before claiming a new release matches it"
5255
+ ]
5256
+ },
5257
+ {
5258
+ "slug": "tree-select",
5259
+ "title": "Tree select",
5260
+ "kind": "component",
5261
+ "support": "unassessed",
5262
+ "lastReviewedSupport": "implemented",
5263
+ "sourceReview": "needs-review",
5264
+ "reviewedOn": "2026-10-25",
5265
+ "scope": "A native select[data-tree] whose flat options name their parent's value in data-parent; a role=\"tree\" popup with the ARIA tree keyboard contract over visible, enabled rows, mirrored under RTL; single or native multiple independent leaf choices, with branches normalized out of multiple selection; branch options disabled while it runs; optional single/multiple leaf search retaining ancestor paths and restoring pre-query expansion; refresh() preserving the query, expansion baseline and focus.",
5266
+ "adaptation": "TreeSelect extends FormSelect, so the native select keeps the form value, reset, validity and disabled state. The popup is a ul role=\"tree\" inside the Menu surface, one list below the rows Menu styles, named as the field is. Search reuses the labelled dialog/search/status controls around that tree without a listbox wrapper.",
5267
+ "upstream": {
5268
+ "source": "https://m3.material.io/components",
5269
+ "reviewedOn": "2026-10-25",
5270
+ "scope": "web-extension-inventory-reviewed",
5271
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
5272
+ "sections": [
5273
+ "No standalone Material component"
5274
+ ],
5275
+ "sources": [],
5276
+ "requirements": "Keep a labelled native select as the form control, expose the hierarchy as an ARIA tree with its keyboard contract, let people choose only a leaf, and submit that leaf's value whatever the nesting."
3931
5277
  },
3932
- "relationship": "related",
5278
+ "relationship": "none",
3933
5279
  "sources": [
3934
5280
  {
3935
- "path": "src/sass/components/forms/_select.scss",
3936
- "sha256": "d360405d6a315e4ff8be9936ac1bc0e7ec0c01ad300d177a87de54a096937bec"
3937
- },
3938
- {
3939
- "path": "src/sass/components/_menu.scss",
3940
- "sha256": "fc7456249caec5118a379c9d56c7a7bfb211c147f5fd318bbcf8de6ea1d33654"
3941
- },
3942
- {
3943
- "path": "src/ts/components/select.ts",
3944
- "sha256": "b375715a62baae95a7ba2c97d85d60ee2c619d5d261ee0abf9aea7ab28c3ae74"
3945
- },
3946
- {
3947
- "path": "src/ts/components/menu.ts",
3948
- "sha256": "0ca7f4c0d80012adad3babdfc23005792dbaa2655c3fe5595bc9bcc7e2c35ce8"
5281
+ "path": "src/ts/components/treeSelect.ts",
5282
+ "sha256": "0fefba309bbd4046963a2a4fd61a6352746beadb1dfc1a10675c4d9062fb2178"
3949
5283
  }
3950
5284
  ],
3951
5285
  "gaps": [
3952
5286
  {
3953
5287
  "kind": "verification",
3954
- "description": "Native zoom, screen-reader announcements, Windows contrast themes and physical-device form interaction remain unverified.",
3955
- "nextStep": "Complete the Select native-forms manual-review fixture and record actual browser, assistive technology and device results."
5288
+ "description": "Keys in both directions, typeahead, pointer toggling, refresh(), validation focus, form data, indentation, chevrons and disabled rows are checked in a browser, and the tree from data-parent in jsdom; spoken output and touch remain unverified.",
5289
+ "nextStep": "Move through the tree and choose a leaf with VoiceOver and NVDA, and tap branches and leaves on iOS Safari and Android Chrome."
3956
5290
  }
3957
5291
  ],
3958
5292
  "browserChecks": [
3959
5293
  {
3960
- "file": "tests/expressivecss-lifecycle-browser.test.js",
3961
- "name": "partial replacement and client navigation preserve shell ownership across repeated mounts",
3962
- "scope": "Rail shell ownership; enhanced select interaction; generated Menu registry/resource cleanup; tooltip ownership across route replacement.",
3963
- "state": "stale"
3964
- },
3965
- {
3966
- "file": "tests/expressivecss-lifecycle-browser.test.js",
3967
- "name": "resource observations detect omitted teardown after a partial replacement",
3968
- "scope": "Negative control proves resources remain without destroy; no visual parity assertion.",
3969
- "state": "stale"
5294
+ "file": "tests/tree-select-browser.test.js",
5295
+ "name": "chromium: ArrowRight expands a branch, Enter chooses a leaf, and the form submits its value",
5296
+ "scope": "Opening with Enter, expanding two branches with ArrowRight, choosing a leaf with Enter, and its value in FormData and the submit event.",
5297
+ "state": "not-recorded"
3970
5298
  },
3971
5299
  {
3972
- "file": "tests/menu-field-browser.test.js",
3973
- "name": "enhanced select keeps enlarged multiline labels clear of values (chromium)",
3974
- "scope": "Filled enhanced select label/value separation with multiline LTR/RTL labels at 16px and 32px root text size. Native zoom, native and outlined selects are not covered. Equivalent Firefox and WebKit cases run in the same file.",
3975
- "state": "stale"
3976
- },
5300
+ "file": "tests/tree-select-browser.test.js",
5301
+ "name": "chromium: rtl: the arrows, Home, End and * follow the tree pattern over visible, enabled rows",
5302
+ "scope": "Opening, entering, closing and leaving branches with the mirrored arrows, Home, End and *, skipping a disabled placeholder and leaf without wrapping.",
5303
+ "state": "not-recorded"
5304
+ }
5305
+ ],
5306
+ "browserEvidence": "incomplete",
5307
+ "recheckWhen": [
5308
+ "A reviewed source changes",
5309
+ "A mapped test or its recorded inputs change",
5310
+ "Google revises the linked guidance or before claiming a new release matches it"
5311
+ ]
5312
+ },
5313
+ {
5314
+ "slug": "cascader",
5315
+ "title": "Cascader",
5316
+ "kind": "component",
5317
+ "support": "implemented",
5318
+ "lastReviewedSupport": "implemented",
5319
+ "sourceReview": "source-reviewed",
5320
+ "reviewedOn": "2026-10-25",
5321
+ "scope": "Nested lists with data-value read into listbox columns in a popover anchored to a read-only combobox input; click and keyboard navigation with arrows, Home, End, Enter, Space, Escape and Tab, swapped under rtl; leaf-only commits shown as joined labels with input and change events; one form entry per level through a form-associated control; data-selected starting path, reset, required with i18n.required, aria-invalid and disabled state.",
5322
+ "adaptation": "The author's nested lists stay hidden as the source. A manual popover opened with the input as its source uses CSS anchor positioning, and a form-associated expressive-cascader-control wraps the input and submits the path, so the browser handles reset, validity and disabled state.",
5323
+ "upstream": {
5324
+ "source": "https://m3.material.io/components",
5325
+ "reviewedOn": "2026-10-25",
5326
+ "scope": "web-extension-inventory-reviewed",
5327
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
5328
+ "sections": [
5329
+ "No standalone Material component"
5330
+ ],
5331
+ "sources": [],
5332
+ "requirements": "Keep the field a labelled input that reads as a combobox, name every column, show which options form the open path, reach every option from the keyboard in both directions, close without committing on Escape, and submit every level of the path."
5333
+ },
5334
+ "relationship": "none",
5335
+ "sources": [
3977
5336
  {
3978
- "file": "tests/menu-field-browser.test.js",
3979
- "name": "Select native form synchronization: disabled (chromium)",
3980
- "scope": "Single/multiple selected labels, disabled options and optgroups, empty selections and native FormData. Equivalent Firefox and WebKit cases run in the same file.",
3981
- "state": "stale"
3982
- },
5337
+ "path": "src/ts/components/cascader.ts",
5338
+ "sha256": "9ef77d466edd9c8cde4b66a043cecd8ef55da76ea544b8ef88831051fdabb544"
5339
+ }
5340
+ ],
5341
+ "gaps": [
3983
5342
  {
3984
- "file": "tests/menu-field-browser.test.js",
3985
- "name": "Select native form synchronization: reset (chromium)",
3986
- "scope": "Successful and canceled native resets, default selections, generated selection semantics and no synthetic change events. Equivalent Firefox and WebKit cases run in the same file.",
3987
- "state": "stale"
3988
- },
5343
+ "kind": "verification",
5344
+ "description": "Clicks and keys through three columns, rtl, roles, names and states, form data, reset, required, disabled state and destroy() are checked in Chromium, Firefox and WebKit, and parsing in jsdom; spoken output remains unverified.",
5345
+ "nextStep": "Move through three columns and commit a leaf with NVDA in Firefox and VoiceOver in Safari."
5346
+ }
5347
+ ],
5348
+ "browserChecks": [
3989
5349
  {
3990
- "file": "tests/menu-field-browser.test.js",
3991
- "name": "Select native form synchronization: refresh (chromium)",
3992
- "scope": "Disabled/enabled refresh, changed and removed options, open-menu focus, Escape, stale rows, native change events and unrelated focus preservation. Equivalent Firefox and WebKit cases run in the same file.",
3993
- "state": "stale"
5350
+ "file": "tests/cascader-browser.test.js",
5351
+ "name": "chromium: the roadmap check: choosing an option in each of three columns submits the three values as one path",
5352
+ "scope": "Clicks through three columns, the joined labels in the input, and the three values in FormData and the submit event, through the wrapping control.",
5353
+ "state": "not-recorded"
3994
5354
  },
3995
5355
  {
3996
- "file": "tests/menu-field-browser.test.js",
3997
- "name": "Select native form synchronization: interaction (chromium)",
3998
- "scope": "Pointer and keyboard multiple selection, event counts, checkbox state, native FormData, LTR/RTL, both motion preferences, reset teardown and instance isolation. Equivalent Firefox and WebKit cases run in the same file.",
3999
- "state": "stale"
5356
+ "file": "tests/cascader-browser.test.js",
5357
+ "name": "chromium: the keyboard opens the field, moves through the columns, commits a leaf and closes",
5358
+ "scope": "Each opening key, arrows without wrapping, Home and End, the next and previous column, Escape, Tab and Shift+Tab closing without committing, and Space committing a leaf.",
5359
+ "state": "not-recorded"
4000
5360
  }
4001
5361
  ],
4002
- "browserEvidence": "needs-rerun",
5362
+ "browserEvidence": "incomplete",
4003
5363
  "recheckWhen": [
4004
5364
  "A reviewed source changes",
4005
5365
  "A mapped test or its recorded inputs change",
@@ -4070,6 +5430,72 @@
4070
5430
  "Google revises the linked guidance or before claiming a new release matches it"
4071
5431
  ]
4072
5432
  },
5433
+ {
5434
+ "slug": "transfer-list",
5435
+ "title": "Transfer list",
5436
+ "kind": "component",
5437
+ "support": "implemented",
5438
+ "lastReviewedSupport": "implemented",
5439
+ "sourceReview": "source-reviewed",
5440
+ "reviewedOn": "2026-10-25",
5441
+ "scope": "Two .list groups of labelled checkbox rows with add, add-all, remove and remove-all buttons between them, chosen rows kept in the order they arrived, rows returned to their original slots, the chosen values submitted under data-name in order, form reset, a polite announcement, an expressive:transfer event, and a layout that follows the page direction and stacks below the medium window size.",
5442
+ "adaptation": "A document-delegated behavior moves the rows and appends the chosen values in a formdata listener, so the checkboxes carry no name. The rows stay native checkboxes rather than a listbox, so Tab and Space work without an arrow-key contract.",
5443
+ "upstream": {
5444
+ "source": "https://m3.material.io/components",
5445
+ "reviewedOn": "2026-10-25",
5446
+ "scope": "web-extension-inventory-reviewed",
5447
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
5448
+ "sections": [
5449
+ "No standalone Material component"
5450
+ ],
5451
+ "sources": [],
5452
+ "requirements": "Name both lists, keep every row and button reachable by keyboard, announce each move, keep focus on the pressed button, and submit the chosen options in a stable order."
5453
+ },
5454
+ "relationship": "none",
5455
+ "sources": [
5456
+ {
5457
+ "path": "src/sass/components/_transfer-list.scss",
5458
+ "sha256": "2b6a2f8a42df55e7fb79c887cecb245c822c1b535d4a9c4caad9083abe13f73f"
5459
+ },
5460
+ {
5461
+ "path": "src/ts/behaviors/transferList.ts",
5462
+ "sha256": "e13632859b9e57b81c55f0f84d13e5ad5f974c699e54f05d17316d8d1c024aff"
5463
+ }
5464
+ ],
5465
+ "gaps": [
5466
+ {
5467
+ "kind": "verification",
5468
+ "description": "The add, remove and move-all buttons, original slots on the way back, disabled rows, focus, the announcement, the expressive:transfer event, the form data order, disabled fieldsets, nested lists, form reset, right-to-left pages and the stacked narrow layout are checked in a browser; spoken output and forced colors remain unverified.",
5469
+ "nextStep": "Move rows with NVDA in Firefox and VoiceOver in Safari and confirm each move is announced once; check the lists and icons in forced colors mode."
5470
+ }
5471
+ ],
5472
+ "browserChecks": [
5473
+ {
5474
+ "file": "tests/transfer-list-browser.test.js",
5475
+ "name": "chromium: moving two options to the chosen list puts both in the form data, in order",
5476
+ "scope": "Two checked rows moved one at a time arrive unchecked, and new FormData and a real submit both hold their values in the order they were moved.",
5477
+ "state": "not-recorded"
5478
+ },
5479
+ {
5480
+ "file": "tests/transfer-list-browser.test.js",
5481
+ "name": "chromium: remove returns rows to their original slots, the all buttons skip disabled rows, and a second Init adds nothing",
5482
+ "scope": "Rows moved back land in their recorded slots, add-all and remove-all leave a disabled row in place, and each press fires one event after repeated Init calls.",
5483
+ "state": "not-recorded"
5484
+ },
5485
+ {
5486
+ "file": "tests/transfer-list-browser.test.js",
5487
+ "name": "chromium: a form reset puts the rows back where they started",
5488
+ "scope": "A reset button and form.reset() restore both lists and the default checked state, a removed row stays removed, and a cancelled reset moves nothing. No spoken-output assertion.",
5489
+ "state": "not-recorded"
5490
+ }
5491
+ ],
5492
+ "browserEvidence": "incomplete",
5493
+ "recheckWhen": [
5494
+ "A reviewed source changes",
5495
+ "A mapped test or its recorded inputs change",
5496
+ "Google revises the linked guidance or before claiming a new release matches it"
5497
+ ]
5498
+ },
4073
5499
  {
4074
5500
  "slug": "radio-buttons",
4075
5501
  "title": "Radio buttons",
@@ -4153,7 +5579,7 @@
4153
5579
  "sources": [
4154
5580
  {
4155
5581
  "path": "src/sass/components/forms/_rating.scss",
4156
- "sha256": "8b0c0e77791f4e88681a12ff2c78758be20d5ece7129c914e4cf6881a6b61300"
5582
+ "sha256": "f0e053d5504a2b507cd10f080d78975eca50e97d0d5846cfd3cac56776ade994"
4157
5583
  }
4158
5584
  ],
4159
5585
  "gaps": [
@@ -4178,6 +5604,110 @@
4178
5604
  "Google revises the linked guidance or before claiming a new release matches it"
4179
5605
  ]
4180
5606
  },
5607
+ {
5608
+ "slug": "color-swatches",
5609
+ "title": "Color swatches",
5610
+ "kind": "component",
5611
+ "support": "implemented",
5612
+ "lastReviewedSupport": "implemented",
5613
+ "sourceReview": "source-reviewed",
5614
+ "reviewedOn": "2026-10-18",
5615
+ "scope": "A fieldset of native radios drawn as round chips of their colors, a ring around the checked one, the shared focus ring, a 48px target and an optional native color input for a custom value.",
5616
+ "adaptation": "Native radios keep one Tab stop, arrow keys and form submission; each swatch is named by visually hidden text in its label.",
5617
+ "upstream": {
5618
+ "source": "https://m3.material.io/components",
5619
+ "reviewedOn": "2026-10-18",
5620
+ "scope": "web-extension-inventory-reviewed",
5621
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
5622
+ "sections": [
5623
+ "No standalone Material component"
5624
+ ],
5625
+ "sources": [],
5626
+ "requirements": "Keep a native radio group with a legend and a name for every swatch, mark the choice by shape as well as color, show focus and keep the swatch colors under forced colors."
5627
+ },
5628
+ "relationship": "none",
5629
+ "sources": [
5630
+ {
5631
+ "path": "src/sass/components/forms/_color-swatches.scss",
5632
+ "sha256": "264193228b3b777055639586059f7e5dff2600212f989151c5007d1364dd21e2"
5633
+ }
5634
+ ],
5635
+ "gaps": [
5636
+ {
5637
+ "kind": "verification",
5638
+ "description": "Swatch color, size and shape, the checked ring, the group name, arrow keys, the form value, the focus ring after arrow keys and the swatch color under forced colors are checked in Chromium; other engines, spoken output and enlarged text remain unverified.",
5639
+ "nextStep": "Choose a swatch with a keyboard and a screen reader in Firefox and Safari, and confirm each color name and the checked state are announced; check 200% text."
5640
+ }
5641
+ ],
5642
+ "browserChecks": [
5643
+ {
5644
+ "file": "tests/color-swatches-browser.test.js",
5645
+ "name": "chromium: color swatches draw each radio as its color and keep native radio behavior",
5646
+ "scope": "Swatch color, 40px round shape and checked ring, the named group, arrow keys moving the choice, the form value, the focus ring after arrow keys and the swatch color under forced colors. No spoken-output assertion.",
5647
+ "state": "not-recorded"
5648
+ }
5649
+ ],
5650
+ "browserEvidence": "incomplete",
5651
+ "recheckWhen": [
5652
+ "A reviewed source changes",
5653
+ "A mapped test or its recorded inputs change",
5654
+ "Google revises the linked guidance or before claiming a new release matches it"
5655
+ ]
5656
+ },
5657
+ {
5658
+ "slug": "color-picker",
5659
+ "title": "Color picker",
5660
+ "kind": "component",
5661
+ "support": "unassessed",
5662
+ "lastReviewedSupport": "implemented",
5663
+ "sourceReview": "needs-review",
5664
+ "reviewedOn": "2026-10-18",
5665
+ "scope": "A saturation and brightness area as a keyboard slider, a hue range on the framework slider, a hex field and the native color input as form value and preview, with input, change and onChange events.",
5666
+ "adaptation": "Progressive enhancement of <input type=\"color\">: without JavaScript the native picker remains, and the browser picker still opens from the input after enhancement.",
5667
+ "upstream": {
5668
+ "source": "https://m3.material.io/components",
5669
+ "reviewedOn": "2026-10-18",
5670
+ "scope": "web-extension-inventory-reviewed",
5671
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
5672
+ "sections": [
5673
+ "No standalone Material component"
5674
+ ],
5675
+ "sources": [],
5676
+ "requirements": "Keep a native color input as the value, name the group and each control, make every axis reachable by keyboard with its value announced, keep the colors under forced colors and keep Enter in the hex field from submitting the form."
5677
+ },
5678
+ "relationship": "none",
5679
+ "sources": [
5680
+ {
5681
+ "path": "src/sass/components/forms/_color-picker.scss",
5682
+ "sha256": "d4bff9e9896e104ae3842e94155d23591bd29c3741e4c66cfeb299f52f126d8c"
5683
+ },
5684
+ {
5685
+ "path": "src/ts/components/colorPicker.ts",
5686
+ "sha256": "f21cb593636261f0bd56515bfaa3bf24284d00e517406672a9823cc06f52be16"
5687
+ }
5688
+ ],
5689
+ "gaps": [
5690
+ {
5691
+ "kind": "verification",
5692
+ "description": "Arrow keys, Shift steps, pointer press and drag with clamping, the unmirrored area in RTL, the hue range, the hex field with Enter and invalid values, the value property, native input changes, the form value and destroy are checked in Chromium, Firefox and WebKit; spoken output, forced colors and touch remain unverified.",
5693
+ "nextStep": "Pick a color with a screen reader and with touch in each engine, and confirm the area valuetext and the hex field are announced; check forced colors and 200% text."
5694
+ }
5695
+ ],
5696
+ "browserChecks": [
5697
+ {
5698
+ "file": "tests/color-picker-browser.test.js",
5699
+ "name": "chromium: color picker drives the native input from the area, hue and hex field",
5700
+ "scope": "Group and control names, Down and Shift+Left steps with valuetext, input, change and onChange order, a press and a drag past the corner in an RTL page, hue changes keeping saturation and brightness, hex Enter without form submission, an invalid hex reverting, the silent value setter, a native input event updating the hue, one submitted field and destroy leaving only the native input. No spoken-output assertion.",
5701
+ "state": "not-recorded"
5702
+ }
5703
+ ],
5704
+ "browserEvidence": "incomplete",
5705
+ "recheckWhen": [
5706
+ "A reviewed source changes",
5707
+ "A mapped test or its recorded inputs change",
5708
+ "Google revises the linked guidance or before claiming a new release matches it"
5709
+ ]
5710
+ },
4181
5711
  {
4182
5712
  "slug": "switches",
4183
5713
  "title": "Switches",
@@ -4456,8 +5986,8 @@
4456
5986
  "gaps": [
4457
5987
  {
4458
5988
  "kind": "feature",
4459
- "description": "Version 0.10.0 exposes localized loading, result counts and multi-selection updates through a polite live region. Spoken delivery and application-owned async ordering remain unverified.",
4460
- "nextStep": "Check screen-reader delivery and application request cancellation, error handling and stale-response ordering."
5989
+ "description": "Version 0.10.0 exposes localized loading, result counts and multi-selection updates through a polite live region, and onSearch gets an AbortSignal that aborts a stale search. Spoken delivery remains unverified.",
5990
+ "nextStep": "Check screen-reader delivery of the loading, count and selection announcements in each engine."
4461
5991
  }
4462
5992
  ],
4463
5993
  "browserChecks": [
@@ -4495,8 +6025,8 @@
4495
6025
  "lastReviewedSupport": "partial",
4496
6026
  "sourceReview": "needs-review",
4497
6027
  "reviewedOn": "2026-09-17",
4498
- "scope": "Inline single-date, range, and multiple-date calendar.",
4499
- "adaptation": "Default inline presentation with optional docked display plugin; no open()/close() methods or modal implementation.",
6028
+ "scope": "Inline single-date, range, and multiple-date calendar, with an optional modal dialog.",
6029
+ "adaptation": "Default inline presentation with optional docked and modal display plugins; displayPlugin: 'modal' opens it in a dialog from the input. No open()/close() methods.",
4500
6030
  "upstream": {
4501
6031
  "source": "https://m3.material.io/components/date-pickers/overview",
4502
6032
  "reviewedOn": "2026-09-13",
@@ -4521,7 +6051,7 @@
4521
6051
  },
4522
6052
  {
4523
6053
  "path": "src/sass/components/_docked-display.scss",
4524
- "sha256": "39107a3b4cde4c0763fff6c077fd7ebf7b964d5312f2435c9786e22c018709a5"
6054
+ "sha256": "dfc657828280fc683a67ed5d9b55b84f3323a9365df5c590d73f769ed4adf470"
4525
6055
  },
4526
6056
  {
4527
6057
  "path": "src/ts/components/datepicker.ts",
@@ -4537,15 +6067,10 @@
4537
6067
  }
4538
6068
  ],
4539
6069
  "gaps": [
4540
- {
4541
- "kind": "feature",
4542
- "description": "Modal picker parity is not provided by the documented inline API.",
4543
- "nextStep": "Decide the modal picker contract, focus behavior and dismissal before adding it; preserve inline and docked APIs."
4544
- },
4545
6070
  {
4546
6071
  "kind": "verification",
4547
6072
  "description": "Range-end typing and keyboard selection, multiple-date defaults, shrink/regrow/clear, form values and generated-input teardown have rendered coverage. Custom parsing, range constraints through typed input and spoken calendar context need further review.",
4548
- "nextStep": "Complete the manual picker checklist and separately verify custom parsing and typed range constraints. Do not infer modal or complete accessibility parity."
6073
+ "nextStep": "Complete the manual picker checklist and separately verify custom parsing and typed range constraints. Do not infer complete accessibility parity."
4549
6074
  }
4550
6075
  ],
4551
6076
  "browserChecks": [
@@ -4578,6 +6103,12 @@
4578
6103
  "name": "chromium: date picker selection lifecycle: clear",
4579
6104
  "scope": "Clearing a native date input resets its value and data-date without throwing.",
4580
6105
  "state": "stale"
6106
+ },
6107
+ {
6108
+ "file": "tests/modal-picker-browser.test.js",
6109
+ "name": "chromium: a modal date picker writes the input on Ok and nothing on Cancel, Escape or the scrim",
6110
+ "scope": "The dialog is modal and named by the input label, focus moves to the selected day and back to the input, Ok writes the date, and Cancel, Escape and a scrim press leave it and call onCancel. Runs in all three engines. No screen reader output.",
6111
+ "state": "not-recorded"
4581
6112
  }
4582
6113
  ],
4583
6114
  "browserEvidence": "needs-rerun",
@@ -4595,8 +6126,8 @@
4595
6126
  "lastReviewedSupport": "partial",
4596
6127
  "sourceReview": "needs-review",
4597
6128
  "reviewedOn": "2026-09-18",
4598
- "scope": "Inline clock and digital input; 12-hour and 24-hour formats.",
4599
- "adaptation": "Default inline presentation with optional docked display plugin; no open()/close() methods or modal implementation.",
6129
+ "scope": "Inline clock and digital input; 12-hour and 24-hour formats, with an optional modal dialog.",
6130
+ "adaptation": "Default inline presentation with optional docked and modal display plugins; displayPlugin: 'modal' opens it in a dialog from the input. No open()/close() methods.",
4600
6131
  "upstream": {
4601
6132
  "source": "https://m3.material.io/components/time-pickers/overview",
4602
6133
  "reviewedOn": "2026-09-13",
@@ -4624,7 +6155,7 @@
4624
6155
  },
4625
6156
  {
4626
6157
  "path": "src/sass/components/_docked-display.scss",
4627
- "sha256": "39107a3b4cde4c0763fff6c077fd7ebf7b964d5312f2435c9786e22c018709a5"
6158
+ "sha256": "dfc657828280fc683a67ed5d9b55b84f3323a9365df5c590d73f769ed4adf470"
4628
6159
  },
4629
6160
  {
4630
6161
  "path": "src/ts/components/timepicker.ts",
@@ -4637,14 +6168,9 @@
4637
6168
  ],
4638
6169
  "gaps": [
4639
6170
  {
4640
- "kind": "feature",
4641
- "description": "Modal picker parity is not provided by the documented inline API.",
4642
- "nextStep": "Decide the modal picker contract, focus behavior and dismissal before adding it; preserve inline and docked APIs."
4643
- },
4644
- {
4645
- "kind": "feature",
4646
- "description": "Version 0.10.0 names hour/minute inputs and exposes AM/PM button state. Clock-dial arrow navigation and modal keyboard behavior remain unimplemented.",
4647
- "nextStep": "Use the digital inputs for keyboard entry; separately assess dial navigation and modal focus before claiming complete keyboard parity."
6171
+ "kind": "integration",
6172
+ "description": "The dial takes pointer input only. The hour and minute spin buttons set the same values from the keyboard, move the hand, and step hours round the day, switching AM and PM past 12, so a focusable dial would add a second Tab stop with nothing new.",
6173
+ "nextStep": "Revisit a focusable dial only if testing shows readers need it beyond the spin buttons."
4648
6174
  }
4649
6175
  ],
4650
6176
  "browserChecks": [
@@ -4671,6 +6197,12 @@
4671
6197
  "name": "chromium: time picker digital values: boundaries",
4672
6198
  "scope": "Reinitialization from midnight, noon, late-night 24-hour strings and lowercase AM/PM preserves twelve-hour display and period state.",
4673
6199
  "state": "stale"
6200
+ },
6201
+ {
6202
+ "file": "tests/modal-picker-browser.test.js",
6203
+ "name": "chromium: a modal time picker steps its fields with the arrow keys and writes the time on Enter",
6204
+ "scope": "The fields are spin buttons with their range, Up, Down and Page Up step and wrap them, the hand follows, Enter writes the time and closes the dialog, and Escape closes it without a change. Runs in all three engines. No screen reader output.",
6205
+ "state": "not-recorded"
4674
6206
  }
4675
6207
  ],
4676
6208
  "browserEvidence": "needs-rerun",
@@ -4680,13 +6212,67 @@
4680
6212
  "Google revises the linked guidance or before claiming a new release matches it"
4681
6213
  ]
4682
6214
  },
6215
+ {
6216
+ "slug": "keypad",
6217
+ "title": "Keypad and Keyboard",
6218
+ "kind": "component",
6219
+ "support": "unassessed",
6220
+ "lastReviewedSupport": "implemented",
6221
+ "sourceReview": "needs-review",
6222
+ "reviewedOn": "2026-10-11",
6223
+ "scope": "A three-column keypad of round keys with two-cell wide keys and a keyboard of rows sized from a column count with an optional number row, typing into the field named by aria-controls with value keys, Backspace, Enter, a one-shot Shift, data-key keys inside the field's wrapper, dial-pad letters, styled call keys, an onKey callback and a pressed shape morph.",
6224
+ "adaptation": "Keys are native buttons in a named group; edits go through the field's value and fire a composed input event, Enter uses requestSubmit() so validation runs, and inputmode=\"none\" on the field keeps the device keyboard closed. Browsers check minlength only on what a person types, so the keypad checks it on its own edits.",
6225
+ "upstream": {
6226
+ "source": "https://m3.material.io/components",
6227
+ "reviewedOn": "2026-10-11",
6228
+ "scope": "web-extension-inventory-reviewed",
6229
+ "note": "Requirements and boundaries: design reference web-extensions-review. The inventory page renders client-side, so this review relies on the 2026-09-13 inventory review. Full visual parity and spoken output unverified.",
6230
+ "sections": [
6231
+ "No standalone Material component"
6232
+ ],
6233
+ "sources": [],
6234
+ "requirements": "Name the group and every icon key, keep keys from submitting the form, keep the field labelled and usable from a hardware keyboard, and keep keys at a usable target size."
6235
+ },
6236
+ "relationship": "none",
6237
+ "sources": [
6238
+ {
6239
+ "path": "src/sass/components/_keypad.scss",
6240
+ "sha256": "b530b6c62630f0bb86f146db24d4d7b363491355b2f2d3302a34b2274b42bf13"
6241
+ },
6242
+ {
6243
+ "path": "src/ts/components/keypad.ts",
6244
+ "sha256": "074900c8486ebcb978cb33bff7d51c47e1721e738eb593651768c3d17e768752"
6245
+ }
6246
+ ],
6247
+ "gaps": [
6248
+ {
6249
+ "kind": "verification",
6250
+ "description": "Typing at the caret, maxlength, pattern validation on Enter, Backspace including emoji, Enter submitting a form and adding a new line in a textarea, a one-shot Shift with capitals shown, Caps Lock, Layer keys, hardware key highlight, minlength on keypad edits, number inputs, disabled fieldsets, in-field keys, shadow roots, focus staying in the field, the keypad grid and wide keys, keyboard key widths and the number row, the pressed shape and destroy are checked in a browser; screen reader output, forced colors, enlarged text and touch devices remain unverified.",
6251
+ "nextStep": "Type a PIN and a message with a screen reader and on a touch device in each engine, and check forced colors and enlarged text."
6252
+ }
6253
+ ],
6254
+ "browserChecks": [
6255
+ {
6256
+ "file": "tests/keypad-browser.test.js",
6257
+ "name": "chromium: keypad and keyboard type at the caret, edit, submit, shift and lay out their keys",
6258
+ "scope": "Digits typed at the caret, maxlength, focus kept in the field on a pointer press, Backspace including emoji, Enter submitting once, a pattern mismatch blocking Enter, onKey values, composed input events from a shadow root, number, decimal and signed input, a disabled fieldset and its legend, a trailing Backspace in the field that runs once for two keypads, for a field inside its keyboard and for a field rendered after init, a password toggle that is not a key, a prefilled untouched field typed at the end, a caret placed at the start kept for keys activated from the keyboard, Shift showing capitals and releasing after one character, space and a textarea new line, three 72px round keypad columns, a two-cell wide key, a tenth-of-row letter key, the half-key indent, a one-and-a-half-key Shift, the space bar filling its row, a 40px number row that types and that hidden drops, the pressed corner, destroy, and the shared listeners leaving with the last keypad. No spoken-output assertion.",
6259
+ "state": "not-recorded"
6260
+ }
6261
+ ],
6262
+ "browserEvidence": "incomplete",
6263
+ "recheckWhen": [
6264
+ "A reviewed source changes",
6265
+ "A mapped test or its recorded inputs change",
6266
+ "Google revises the linked guidance or before claiming a new release matches it"
6267
+ ]
6268
+ },
4683
6269
  {
4684
6270
  "slug": "questionnaire",
4685
6271
  "title": "Questionnaire",
4686
6272
  "kind": "component",
4687
- "support": "implemented",
6273
+ "support": "unassessed",
4688
6274
  "lastReviewedSupport": "implemented",
4689
- "sourceReview": "source-reviewed",
6275
+ "sourceReview": "needs-review",
4690
6276
  "reviewedOn": "2026-10-08",
4691
6277
  "scope": "A native form of fieldsets shown one at a time, with single choice, multiple choice and text answers, choice descriptions, required and data-required questions, Skip for optional ones, authored or generated errors, a progress row, Enter to advance, disabled questions for branching and normal form submission.",
4692
6278
  "adaptation": "Each question is a native fieldset named by its legend; the browser's constraint validation checks answers, hidden questions use hidden, and without JavaScript the form shows every question and still submits.",
@@ -4715,13 +6301,8 @@
4715
6301
  "gaps": [
4716
6302
  {
4717
6303
  "kind": "verification",
4718
- "description": "Showing one question, required radios, data-required checkboxes that ignore disabled ones, generated and authored errors, aria-invalid and aria-describedby, Enter, Skip clearing an answer, Back focus, a disabled question left out, submit and requestSubmit() opening the first unanswered question, FormData and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
6304
+ "description": "Showing one question, required radios, data-required checkboxes that ignore disabled ones, generated and authored errors, aria-invalid and aria-describedby, Enter, Skip clearing an answer, Back focus, a disabled question left out, submit and requestSubmit() opening the first unanswered question, answer shortcuts, the review step, saved progress, FormData and destroy are checked in a browser; screen reader output, forced colors and enlarged text remain unverified.",
4719
6305
  "nextStep": "Answer a questionnaire with a screen reader in each engine and confirm the question, its description, errors and the progress are announced; check forced colors and enlarged text."
4720
- },
4721
- {
4722
- "kind": "feature",
4723
- "description": "There are no letter or number shortcuts for answers, no summary step and no saved progress.",
4724
- "nextStep": "Add answer shortcuts or a review step when a page needs them; pages can save progress with FormData and goTo()."
4725
6306
  }
4726
6307
  ],
4727
6308
  "browserChecks": [
@@ -4753,7 +6334,7 @@
4753
6334
  "lastReviewedSupport": "partial",
4754
6335
  "sourceReview": "needs-review",
4755
6336
  "reviewedOn": "2026-09-12",
4756
- "scope": "Fifteen baseline type-role utilities and rem-based tokens; semantic element defaults; separate brand/plain/fallback font tokens; bundled Latin Roboto and Noto Sans 400/500. Existing role-weight tokens permit scoped application emphasis.",
6337
+ "scope": "Fifteen baseline type-role utilities and rem-based tokens, and their M3 Expressive emphasized counterparts as .{role}-emphasized classes and emphasized weight tokens; semantic element defaults; separate brand/plain/fallback font tokens; bundled Roboto and Noto Sans 400/500/700 in Latin, Latin Extended, Cyrillic, Greek and Vietnamese subsets, plus Devanagari for Noto Sans and Noto Sans Arabic, Hebrew and Thai in their own scripts, each gated by unicode-range.",
4757
6338
  "adaptation": "Use supported web component and application overrides; Android attributes and APIs are design references only.",
4758
6339
  "upstream": {
4759
6340
  "source": "https://github.com/material-components/material-components-android/blob/master/docs/theming/Typography.md",
@@ -4776,19 +6357,14 @@
4776
6357
  },
4777
6358
  {
4778
6359
  "path": "src/sass/base/_fonts.scss",
4779
- "sha256": "0b768be36675e97378e1ba9567896ee6bb87437352e3e6a059c56a9dde11a628"
6360
+ "sha256": "61c0b4c9dae40b791beab0382a668664354db2ce11314bbc58cea6cfcc7c47e4"
4780
6361
  }
4781
6362
  ],
4782
6363
  "gaps": [
4783
6364
  {
4784
- "kind": "feature",
4785
- "description": "No emphasized role utilities or emphasized token family; emphasized labels and smaller titles requiring 700 need an application-supplied real face.",
4786
- "nextStep": "Define an additive emphasized-scale contract and a font-loading policy before implementing public names."
4787
- },
4788
- {
4789
- "kind": "feature",
4790
- "description": "Bundled text fonts cover Latin and 400/500 only; a Noto Sans fallback declaration does not establish non-Latin coverage.",
4791
- "nextStep": "Add browser checks for actual rendered font faces/weights, representative scripts, and all type-role metrics; retain native zoom/assistive review separately."
6365
+ "kind": "integration",
6366
+ "description": "Noto Sans Arabic, Hebrew and Thai are bundled with script-only ranges; CJK text uses the system font the browser picks from the element's lang, as CJK families are megabytes each, and other scripts need an application-supplied family in --md-ref-typeface-fallback.",
6367
+ "nextStep": "Bundle another script's Noto family when pages need it; keep lang set on CJK text."
4792
6368
  }
4793
6369
  ],
4794
6370
  "browserChecks": [
@@ -4803,6 +6379,12 @@
4803
6379
  "name": "Material browser exposes wrong hierarchy contracts and motion while keeping design judgments pending",
4804
6380
  "scope": "Application-scoped headline size, line-height and 500 weight repair is accepted while qualitative judgment stays pending; no synthesized-font detection.",
4805
6381
  "state": "stale"
6382
+ },
6383
+ {
6384
+ "file": "tests/font-subsets-browser.test.js",
6385
+ "name": "chromium: the browser fetches only the font subsets and weights a page renders",
6386
+ "scope": "Latin and Cyrillic text fetch their two Roboto subsets, an emphasized label fetches the bundled 700 face rather than synthesizing it, and unused Greek, Devanagari and Vietnamese subsets are not fetched. No rendering comparison of glyphs.",
6387
+ "state": "not-recorded"
4806
6388
  }
4807
6389
  ],
4808
6390
  "browserEvidence": "needs-rerun",
@@ -4820,7 +6402,7 @@
4820
6402
  "lastReviewedSupport": "partial",
4821
6403
  "sourceReview": "needs-review",
4822
6404
  "reviewedOn": "2026-09-12",
4823
- "scope": "Per-component shape properties and variants; common button scoped radius; separate FAB geometry; icon-button and button-group pressed/selected corner changes; logical connected-group edges.",
6405
+ "scope": "Shared md.sys.shape.corner scale from none to full, read by component shape tokens on that scale, and a corner family token (round or bevel) that a corners attribute switches for container surfaces, with a .corner-cut utility. Per-component shape properties and variants; common button scoped radius; separate FAB geometry; icon-button and button-group pressed/selected corner changes; logical connected-group edges.",
4824
6406
  "adaptation": "Use supported web component and application overrides; Android attributes and APIs are design references only.",
4825
6407
  "upstream": {
4826
6408
  "source": "https://github.com/material-components/material-components-android/blob/master/docs/theming/Shape.md",
@@ -4845,8 +6427,8 @@
4845
6427
  "gaps": [
4846
6428
  {
4847
6429
  "kind": "feature",
4848
- "description": "No shared md-sys-shape token family or general rounded/cut-corner theming system.",
4849
- "nextStep": "Inventory existing component corner defaults against proposed shared roles before introducing an additive shape scale; preserve existing component overrides and state shapes."
6430
+ "description": "Cut corners rely on CSS corner-shape, which Firefox 157 lacks, so they stay rounded there; off-scale component corners stay literal.",
6431
+ "nextStep": "Re-check corner-shape support in Firefox each release and remove the caveat once it ships; map off-scale corners only where Material names a role."
4850
6432
  }
4851
6433
  ],
4852
6434
  "browserChecks": [
@@ -4884,7 +6466,7 @@
4884
6466
  "lastReviewedSupport": "partial",
4885
6467
  "sourceReview": "needs-review",
4886
6468
  "reviewedOn": "2026-09-12",
4887
- "scope": "Component-owned CSS/runtime motion, sampled fast-spatial linear easing for button-group width/radius, expanding-card container transition, and scale utility. Button groups, expanding cards and the scale utility suppress transitions under reduced motion. Expanding-card close cleanup follows the actual container transition, including CSS timing overrides and cancellation.",
6469
+ "scope": "Shared md.sys.motion easing and duration tokens; M3 Expressive spring tokens for the standard and expressive schemes, solved at compile time into linear() easings with settle durations, a motion attribute that selects the scheme, every duration token set to 0s under reduced motion, and public Sass spring() and spring-duration() functions. Button groups and the keypad press on the fast spatial spring tokens; component-owned CSS/runtime motion for the expanding-card container transition and the scale utility. Button groups, expanding cards and the scale utility suppress transitions under reduced motion.",
4888
6470
  "adaptation": "Use supported web component and application overrides; Android attributes and APIs are design references only.",
4889
6471
  "upstream": {
4890
6472
  "source": "https://github.com/material-components/material-components-android/blob/master/docs/theming/Motion.md",
@@ -4917,8 +6499,8 @@
4917
6499
  "gaps": [
4918
6500
  {
4919
6501
  "kind": "feature",
4920
- "description": "No shared md-sys-motion token family, general spring solver, or unified motion-theme selector.",
4921
- "nextStep": "Define shared semantic timing/spring roles only after mapping existing component needs; distinguish spatial and effects motion without presenting sampled CSS easing as a general solver."
6502
+ "description": "CSS springs are sampled at compile time, so an interrupted CSS transition restarts without carrying velocity; dragged sheets solve their snap-back spring at run time and keep the finger's speed. Sheets, the navigation rail, FAB menu actions, basic dialogs, the expanding card, button groups, the keypad, the tabs indicator, switches and chip sets run on spring tokens.",
6503
+ "nextStep": "Solve springs at run time for other interruptible motion, such as the navigation rail, where testing shows the restart."
4922
6504
  }
4923
6505
  ],
4924
6506
  "browserChecks": [