@sleep2agi/agent-network-dashboard 0.5.1-preview.2 → 0.5.1-preview.21
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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +6 -6
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +2 -2
- package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +2 -2
- package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +2 -2
- package/.next/server/app/node.segments/_full.segment.rsc +2 -2
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +2 -2
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/node.segments/node.segment.rsc +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +2 -2
- package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +2 -2
- package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +2 -2
- package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/0lh3wu1zlx_a5.js +1 -0
- package/.next/static/chunks/0mjn4oij3zu6y.js +4 -0
- package/.next/static/chunks/0tvbbhnjh61u8.js +1 -0
- package/.next/static/chunks/0~oj~gm3ck7o8.css +2 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/TopoGraph.tsx +383 -43
- package/package.json +1 -1
- package/scripts/topo-active-links-freshness-color-test.mjs +86 -0
- package/scripts/topo-filter-pill-hover-opacity-test.mjs +110 -0
- package/scripts/topo-filter-pill-weight-test.mjs +75 -0
- package/scripts/topo-filter-pill-x-hover-scale-test.mjs +99 -0
- package/scripts/topo-freshness-floor-lift-test.mjs +92 -0
- package/scripts/topo-freshness-suffix-tabular-test.mjs +88 -0
- package/scripts/topo-fullscreen-icon-hover-scale-test.mjs +91 -0
- package/scripts/topo-hub-digit-fontsize-test.mjs +86 -0
- package/scripts/topo-layout-toggle-hover-tracking-test.mjs +109 -0
- package/scripts/topo-minimap-viewport-hover-test.mjs +109 -0
- package/scripts/topo-more-flows-hover-letterspacing-test.mjs +98 -0
- package/scripts/topo-panel-count-letterspacing-test.mjs +89 -0
- package/scripts/topo-panel-rect-opacity-hover-test.mjs +109 -0
- package/scripts/topo-panel-title-hover-letterspacing-test.mjs +97 -0
- package/scripts/topo-recent-pip-radius-test.mjs +76 -0
- package/scripts/topo-reset-hover-rotate-test.mjs +102 -0
- package/scripts/topo-vendor-letter-hover-scale-test.mjs +129 -0
- package/scripts/topo-zoom-icon-hover-scale-test.mjs +114 -0
- package/scripts/topo-zoom-level-hover-letterspacing-test.mjs +91 -0
- package/.next/static/chunks/0aauz~36q5n2a.css +0 -2
- package/.next/static/chunks/0ap~cvzkt4_.w.js +0 -1
- package/.next/static/chunks/0bu~3a_lb2vr1.js +0 -4
- package/.next/static/chunks/14d3w289h5vr0.js +0 -1
- /package/.next/static/{U2ie3REU1St9mnDvCTXzE → OLsgiMVJR1MAtUHtDD9yq}/_buildManifest.js +0 -0
- /package/.next/static/{U2ie3REU1St9mnDvCTXzE → OLsgiMVJR1MAtUHtDD9yq}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{U2ie3REU1St9mnDvCTXzE → OLsgiMVJR1MAtUHtDD9yq}/_ssgManifest.js +0 -0
|
@@ -1026,6 +1026,42 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1026
1026
|
// navigation footer. Drives the on-hover opacity boost + underline
|
|
1027
1027
|
// that signals interactivity, mirroring the hoveredHub idiom above.
|
|
1028
1028
|
const [hoveredRecentMore, setHoveredRecentMore] = useState(false);
|
|
1029
|
+
// Round 346 / Loop: minimap-container hover affordance. The minimap
|
|
1030
|
+
// is a click-target (role=button at line ~7810, recenter-on-click +
|
|
1031
|
+
// Enter→resetView) but pre-R346 nothing visually changed on hover —
|
|
1032
|
+
// the only hint was the `cursor: crosshair` style. R346 lifts the
|
|
1033
|
+
// viewport rect (strokeWidth 1.5 → 1.75 + opacity 0.9 → 1.0) when
|
|
1034
|
+
// the user enters the minimap, marking "this is the recenter target
|
|
1035
|
+
// and it's alive". Sibling polish to the R332 minimap rounded-md →
|
|
1036
|
+
// rounded-lg corner family — that round refined geometry, this one
|
|
1037
|
+
// gives the viewport indicator inside the geometry a hover state.
|
|
1038
|
+
// 280ms ease-out transition list matches R199 smoothView vocabulary
|
|
1039
|
+
// so the visual joins the existing rhythm on the same rect.
|
|
1040
|
+
const [hoveredMinimap, setHoveredMinimap] = useState(false);
|
|
1041
|
+
// Round 347 / Loop: zoom-level readout hover-state letter-spacing
|
|
1042
|
+
// tween (0 → 0.5 px). The readout sandwiched between zoom-out /
|
|
1043
|
+
// zoom-in is a passive percent display — pre-R347 it had no hover
|
|
1044
|
+
// feedback at all (only a `title` tooltip). R347 extends the R344
|
|
1045
|
+
// (`+N more flows` footer) + R345 (panel titles) hover-letter-
|
|
1046
|
+
// spacing family from panel/footer surfaces into the HTML chrome
|
|
1047
|
+
// strip. Hovering the readout spreads its digits 0.5 px, signalling
|
|
1048
|
+
// "this is alive". tabular-nums + minWidth: 46 from R225 still lock
|
|
1049
|
+
// the column so the tween doesn't shove neighbouring controls.
|
|
1050
|
+
// 200ms ease-out joins the existing R264 color/border transition
|
|
1051
|
+
// list on the same span.
|
|
1052
|
+
const [hoveredZoomLevel, setHoveredZoomLevel] = useState(false);
|
|
1053
|
+
// Round 350 / Loop: reset-button icon hover-rotate preview of the
|
|
1054
|
+
// R184 click-spin. Pre-R350 hovering the reset button only changed
|
|
1055
|
+
// the button bg (white/5); the icon inside stayed perfectly still.
|
|
1056
|
+
// R350 nudges the icon -8° on hover — a tactile hint that this
|
|
1057
|
+
// button rotates the icon on click. When the click fires, the
|
|
1058
|
+
// R184 anet-reset-spin keyframe animation overrides the hover
|
|
1059
|
+
// transform for its 450 ms run (CSS animations win over transitions
|
|
1060
|
+
// on the same property); when the animation ends + React removes
|
|
1061
|
+
// the className, the inline transform eases back to whatever the
|
|
1062
|
+
// hover state says — either -8° (still hovering) or 0 (mouse left).
|
|
1063
|
+
// 350th-round milestone polish.
|
|
1064
|
+
const [hoveredReset, setHoveredReset] = useState(false);
|
|
1029
1065
|
// R135: panel-wide hover-elevation. The recent-signal + legend
|
|
1030
1066
|
// panels both already host clickable rows (R56/R116 recent rows,
|
|
1031
1067
|
// R55/R61 legend rows) and a clickable footer (R133), so the
|
|
@@ -1826,7 +1862,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1826
1862
|
weight; cyan-400/60 + ring-inset retained. The
|
|
1827
1863
|
R163/R196 hover/active deeps + R249 chrome-pop
|
|
1828
1864
|
click feedback continue unchanged. */
|
|
1829
|
-
|
|
1865
|
+
// R351: hover:tracking-wide extends the R344/R345/R347
|
|
1866
|
+
// hover-letter-spacing family to a 4th surface (chrome-
|
|
1867
|
+
// strip Ring/Grid pair). transition-colors className
|
|
1868
|
+
// dropped in favour of an inline transition spec that
|
|
1869
|
+
// bundles bg/color (150ms ease) + letter-spacing
|
|
1870
|
+
// (200ms ease-out) — Tailwind's transition-colors
|
|
1871
|
+
// doesn't list letter-spacing, so without this the
|
|
1872
|
+
// hover:tracking-wide would snap. Sibling change on
|
|
1873
|
+
// the Grid button below.
|
|
1874
|
+
className={`px-2.5 py-1 focus:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset hover:tracking-wide ${layout === 'ring' ? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25' : 'text-gray-400 hover:text-cyan-300 hover:bg-cyan-500/5 active:bg-cyan-500/15'} ${chromePopping === 'layout-ring' ? ' anet-chrome-pop' : ''}`}
|
|
1875
|
+
style={{ transition: 'background-color 150ms ease, color 150ms ease, letter-spacing 200ms ease-out' }}
|
|
1830
1876
|
>
|
|
1831
1877
|
Ring
|
|
1832
1878
|
</button>
|
|
@@ -1843,14 +1889,20 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1843
1889
|
// Round 306 / Loop: focus-visible:ring-2 → ring-1 sibling
|
|
1844
1890
|
// change to Ring above — unifies focus-ring width across
|
|
1845
1891
|
// all chrome buttons.
|
|
1846
|
-
|
|
1892
|
+
// R351 sibling — Grid button picks up hover:tracking-wide
|
|
1893
|
+
// + inline transition spec. Same vocabulary as Ring.
|
|
1894
|
+
className={`px-2.5 py-1 border-l focus:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset hover:tracking-wide ${layout === 'grid' ? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25' : 'text-gray-400 hover:text-cyan-300 hover:bg-cyan-500/5 active:bg-cyan-500/15'} ${chromePopping === 'layout-grid' ? ' anet-chrome-pop' : ''}`}
|
|
1847
1895
|
/* Round 268 / Loop: Grid button's left border (the
|
|
1848
1896
|
internal divider between Ring and Grid) picks up
|
|
1849
1897
|
pal.containerBorder, matching the wrapper change at
|
|
1850
1898
|
line ~1460 and the chrome strip's segmented borders
|
|
1851
|
-
(nodeSize, zoom). transition-colors className
|
|
1852
|
-
the border-color
|
|
1853
|
-
|
|
1899
|
+
(nodeSize, zoom). The R268 transition-colors className
|
|
1900
|
+
used to carry the border-color ease; R351 unfolds the
|
|
1901
|
+
transition list into the inline spec below so the
|
|
1902
|
+
letter-spacing tween rides alongside without snapping
|
|
1903
|
+
the border-color flip — border-color 200ms ease-out
|
|
1904
|
+
keeps R268's theme-toggle smoothness intact. */
|
|
1905
|
+
style={{ borderColor: pal.containerBorder, transition: 'background-color 150ms ease, color 150ms ease, border-color 200ms ease-out, letter-spacing 200ms ease-out' }}
|
|
1854
1906
|
>
|
|
1855
1907
|
Grid
|
|
1856
1908
|
</button>
|
|
@@ -2259,7 +2311,10 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2259
2311
|
data-active-filter="status"
|
|
2260
2312
|
data-filter-match-count={matchCount}
|
|
2261
2313
|
data-filter-match-aliases={matchAliases.join(',')}
|
|
2262
|
-
|
|
2314
|
+
// R355: `group` lets the inner opacity-70 spans (prefix
|
|
2315
|
+
// `filter:` + count `· N`) brighten to 100 % on pill hover.
|
|
2316
|
+
// Sibling treatment on group + vendor pills below.
|
|
2317
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus"
|
|
2263
2318
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear filter'}
|
|
2264
2319
|
onClick={() => setPinnedStatus(null)}
|
|
2265
2320
|
style={{
|
|
@@ -2273,12 +2328,26 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2273
2328
|
cursor: 'pointer',
|
|
2274
2329
|
}}
|
|
2275
2330
|
>
|
|
2276
|
-
<span><span className="hidden sm:inline opacity-70" data-filter-prefix>filter: </span>{pinnedStatus}<span className="opacity-70 tabular-nums" data-filter-pill-count> · {matchCount}</span></span>
|
|
2331
|
+
<span><span className="hidden sm:inline opacity-70 transition-opacity duration-200 group-hover:opacity-100" data-filter-prefix>filter: </span>{pinnedStatus}<span className="opacity-70 tabular-nums transition-opacity duration-200 group-hover:opacity-100" data-filter-pill-count> · {matchCount}</span></span>
|
|
2277
2332
|
<button
|
|
2278
2333
|
type="button"
|
|
2279
2334
|
aria-label={`Clear ${pinnedStatus} filter`}
|
|
2280
2335
|
onClick={(e) => { e.stopPropagation(); setPinnedStatus(null); }}
|
|
2281
|
-
|
|
2336
|
+
/* Round 356 / Loop: filter pin pill × buttons gain
|
|
2337
|
+
hover:scale-110 (Tailwind 4 modern CSS `scale` property,
|
|
2338
|
+
not legacy transform). Sibling polish to R354 vendor
|
|
2339
|
+
letter glyph + R350/R352/R353 chrome icon hover-scales.
|
|
2340
|
+
Pre-R356 the × had only hover:opacity-70 — the target
|
|
2341
|
+
dimmed under cursor but didn't lift. R356 adds a 10 %
|
|
2342
|
+
scale on hover so the click-target reads as "press me"
|
|
2343
|
+
alongside the dim. transform-gpu hint promotes the
|
|
2344
|
+
button to its own compositor layer for crisper edges
|
|
2345
|
+
during the scale tween. transition-transform duration-
|
|
2346
|
+
200 matches the chrome icon hover-scale timing family.
|
|
2347
|
+
inline-block is default for <button> so no display
|
|
2348
|
+
tweak needed. replace_all covers all 4 filter pin
|
|
2349
|
+
pills (status / group / vendor / edge) at once. */
|
|
2350
|
+
className="ml-0.5 leading-none hover:opacity-70 transition-transform duration-200 ease-out hover:scale-110 transform-gpu"
|
|
2282
2351
|
style={{ background: 'transparent', color: 'inherit', cursor: 'pointer', padding: 0 }}
|
|
2283
2352
|
>×</button>
|
|
2284
2353
|
</span>
|
|
@@ -2297,7 +2366,8 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2297
2366
|
data-active-filter="group"
|
|
2298
2367
|
data-filter-match-count={matchCount}
|
|
2299
2368
|
data-filter-match-aliases={matchAliases.join(',')}
|
|
2300
|
-
|
|
2369
|
+
// R355 sibling — `group` parent + group-hover on inner spans.
|
|
2370
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus"
|
|
2301
2371
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear filter'}
|
|
2302
2372
|
onClick={() => setPinnedGroup(null)}
|
|
2303
2373
|
style={{
|
|
@@ -2307,12 +2377,26 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2307
2377
|
cursor: 'pointer',
|
|
2308
2378
|
}}
|
|
2309
2379
|
>
|
|
2310
|
-
<span><span className="hidden sm:inline opacity-70" data-filter-prefix>filter: </span>{pinnedGroup}<span className="opacity-70 tabular-nums" data-filter-pill-count> · {matchCount}</span></span>
|
|
2380
|
+
<span><span className="hidden sm:inline opacity-70 transition-opacity duration-200 group-hover:opacity-100" data-filter-prefix>filter: </span>{pinnedGroup}<span className="opacity-70 tabular-nums transition-opacity duration-200 group-hover:opacity-100" data-filter-pill-count> · {matchCount}</span></span>
|
|
2311
2381
|
<button
|
|
2312
2382
|
type="button"
|
|
2313
2383
|
aria-label={`Clear group filter ${pinnedGroup}`}
|
|
2314
2384
|
onClick={(e) => { e.stopPropagation(); setPinnedGroup(null); }}
|
|
2315
|
-
|
|
2385
|
+
/* Round 356 / Loop: filter pin pill × buttons gain
|
|
2386
|
+
hover:scale-110 (Tailwind 4 modern CSS `scale` property,
|
|
2387
|
+
not legacy transform). Sibling polish to R354 vendor
|
|
2388
|
+
letter glyph + R350/R352/R353 chrome icon hover-scales.
|
|
2389
|
+
Pre-R356 the × had only hover:opacity-70 — the target
|
|
2390
|
+
dimmed under cursor but didn't lift. R356 adds a 10 %
|
|
2391
|
+
scale on hover so the click-target reads as "press me"
|
|
2392
|
+
alongside the dim. transform-gpu hint promotes the
|
|
2393
|
+
button to its own compositor layer for crisper edges
|
|
2394
|
+
during the scale tween. transition-transform duration-
|
|
2395
|
+
200 matches the chrome icon hover-scale timing family.
|
|
2396
|
+
inline-block is default for <button> so no display
|
|
2397
|
+
tweak needed. replace_all covers all 4 filter pin
|
|
2398
|
+
pills (status / group / vendor / edge) at once. */
|
|
2399
|
+
className="ml-0.5 leading-none hover:opacity-70 transition-transform duration-200 ease-out hover:scale-110 transform-gpu"
|
|
2316
2400
|
style={{ background: 'transparent', color: 'inherit', cursor: 'pointer', padding: 0 }}
|
|
2317
2401
|
>×</button>
|
|
2318
2402
|
</span>
|
|
@@ -2347,7 +2431,8 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2347
2431
|
data-active-filter="vendor"
|
|
2348
2432
|
data-filter-match-count={matchCount}
|
|
2349
2433
|
data-filter-match-aliases={matchAliases.join(',')}
|
|
2350
|
-
|
|
2434
|
+
// R355 sibling — `group` parent + group-hover on inner spans.
|
|
2435
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus"
|
|
2351
2436
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear vendor filter'}
|
|
2352
2437
|
onClick={() => setPinnedVendor(null)}
|
|
2353
2438
|
style={{
|
|
@@ -2357,12 +2442,26 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2357
2442
|
cursor: 'pointer',
|
|
2358
2443
|
}}
|
|
2359
2444
|
>
|
|
2360
|
-
<span><span className="hidden sm:inline opacity-70" data-filter-prefix>filter: </span>{pinnedVendor}<span className="opacity-70 tabular-nums" data-filter-pill-count> · {matchCount}</span></span>
|
|
2445
|
+
<span><span className="hidden sm:inline opacity-70 transition-opacity duration-200 group-hover:opacity-100" data-filter-prefix>filter: </span>{pinnedVendor}<span className="opacity-70 tabular-nums transition-opacity duration-200 group-hover:opacity-100" data-filter-pill-count> · {matchCount}</span></span>
|
|
2361
2446
|
<button
|
|
2362
2447
|
type="button"
|
|
2363
2448
|
aria-label={`Clear vendor filter ${pinnedVendor}`}
|
|
2364
2449
|
onClick={(e) => { e.stopPropagation(); setPinnedVendor(null); }}
|
|
2365
|
-
|
|
2450
|
+
/* Round 356 / Loop: filter pin pill × buttons gain
|
|
2451
|
+
hover:scale-110 (Tailwind 4 modern CSS `scale` property,
|
|
2452
|
+
not legacy transform). Sibling polish to R354 vendor
|
|
2453
|
+
letter glyph + R350/R352/R353 chrome icon hover-scales.
|
|
2454
|
+
Pre-R356 the × had only hover:opacity-70 — the target
|
|
2455
|
+
dimmed under cursor but didn't lift. R356 adds a 10 %
|
|
2456
|
+
scale on hover so the click-target reads as "press me"
|
|
2457
|
+
alongside the dim. transform-gpu hint promotes the
|
|
2458
|
+
button to its own compositor layer for crisper edges
|
|
2459
|
+
during the scale tween. transition-transform duration-
|
|
2460
|
+
200 matches the chrome icon hover-scale timing family.
|
|
2461
|
+
inline-block is default for <button> so no display
|
|
2462
|
+
tweak needed. replace_all covers all 4 filter pin
|
|
2463
|
+
pills (status / group / vendor / edge) at once. */
|
|
2464
|
+
className="ml-0.5 leading-none hover:opacity-70 transition-transform duration-200 ease-out hover:scale-110 transform-gpu"
|
|
2366
2465
|
style={{ background: 'transparent', color: 'inherit', cursor: 'pointer', padding: 0 }}
|
|
2367
2466
|
>×</button>
|
|
2368
2467
|
</span>
|
|
@@ -2395,7 +2494,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2395
2494
|
data-filter-match-count={link.count}
|
|
2396
2495
|
data-filter-match-aliases={`${link.from},${link.to}`}
|
|
2397
2496
|
data-active-filter-edge-hot={isHot ? 'true' : 'false'}
|
|
2398
|
-
className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono text-xs border anet-fade-in anet-topo-chip-focus"
|
|
2497
|
+
className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus"
|
|
2399
2498
|
title={`${link.from} → ${link.to} (${link.count} msg${link.count === 1 ? '' : 's'}${isHot ? ', hot lane · ≥ 10' : ''}) — click to clear`}
|
|
2400
2499
|
onClick={() => setPinnedEdgeKey(null)}
|
|
2401
2500
|
style={{
|
|
@@ -2439,7 +2538,21 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2439
2538
|
type="button"
|
|
2440
2539
|
aria-label={`Clear edge filter ${link.from} → ${link.to}`}
|
|
2441
2540
|
onClick={(e) => { e.stopPropagation(); setPinnedEdgeKey(null); }}
|
|
2442
|
-
|
|
2541
|
+
/* Round 356 / Loop: filter pin pill × buttons gain
|
|
2542
|
+
hover:scale-110 (Tailwind 4 modern CSS `scale` property,
|
|
2543
|
+
not legacy transform). Sibling polish to R354 vendor
|
|
2544
|
+
letter glyph + R350/R352/R353 chrome icon hover-scales.
|
|
2545
|
+
Pre-R356 the × had only hover:opacity-70 — the target
|
|
2546
|
+
dimmed under cursor but didn't lift. R356 adds a 10 %
|
|
2547
|
+
scale on hover so the click-target reads as "press me"
|
|
2548
|
+
alongside the dim. transform-gpu hint promotes the
|
|
2549
|
+
button to its own compositor layer for crisper edges
|
|
2550
|
+
during the scale tween. transition-transform duration-
|
|
2551
|
+
200 matches the chrome icon hover-scale timing family.
|
|
2552
|
+
inline-block is default for <button> so no display
|
|
2553
|
+
tweak needed. replace_all covers all 4 filter pin
|
|
2554
|
+
pills (status / group / vendor / edge) at once. */
|
|
2555
|
+
className="ml-0.5 leading-none hover:opacity-70 transition-transform duration-200 ease-out hover:scale-110 transform-gpu"
|
|
2443
2556
|
style={{ background: 'transparent', color: 'inherit', cursor: 'pointer', padding: 0 }}
|
|
2444
2557
|
>×</button>
|
|
2445
2558
|
</span>
|
|
@@ -2750,7 +2863,40 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2750
2863
|
}
|
|
2751
2864
|
}}
|
|
2752
2865
|
>
|
|
2753
|
-
|
|
2866
|
+
{/* Round 354 / Loop: vendor letter glyph scales
|
|
2867
|
+
1.0 → 1.1 on hover. R88 already dims OTHER
|
|
2868
|
+
vendors on hover via canvas-wide opacity
|
|
2869
|
+
masking; R202 added a chip-level bg tint
|
|
2870
|
+
(color-mix 12 % alpha) so the chip itself
|
|
2871
|
+
responds. R354 closes the trio with a glyph-
|
|
2872
|
+
level lift: the focused vendor LETTER actively
|
|
2873
|
+
rises (transform scale) rather than the chip
|
|
2874
|
+
merely changing colour. Three layers of positive
|
|
2875
|
+
feedback on the hovered vendor + canvas-wide
|
|
2876
|
+
negative feedback on the others — a clean
|
|
2877
|
+
figure/ground separation.
|
|
2878
|
+
|
|
2879
|
+
display: inline-block is required for transform
|
|
2880
|
+
to apply (inline elements ignore transform).
|
|
2881
|
+
transformOrigin: 'center' so the glyph pivots
|
|
2882
|
+
around its centre instead of arcing from the
|
|
2883
|
+
baseline anchor. transition rides the existing
|
|
2884
|
+
Tailwind 4 transform/scale list (no new
|
|
2885
|
+
property — Tailwind already lists transform in
|
|
2886
|
+
the default transition-property set). 200ms
|
|
2887
|
+
matches the R202 chip bg-tint timing so the
|
|
2888
|
+
glyph lift and chip background ease in concert. */}
|
|
2889
|
+
<span
|
|
2890
|
+
data-vendor-letter-glyph={v.initial}
|
|
2891
|
+
data-vendor-letter-glyph-hover={hoveredVendor === v.initial ? 'true' : 'false'}
|
|
2892
|
+
style={{
|
|
2893
|
+
color: v.color,
|
|
2894
|
+
display: 'inline-block',
|
|
2895
|
+
transform: hoveredVendor === v.initial ? 'scale(1.1)' : 'scale(1)',
|
|
2896
|
+
transformOrigin: 'center',
|
|
2897
|
+
transition: 'transform 200ms ease-out',
|
|
2898
|
+
}}
|
|
2899
|
+
>{v.initial}</span>
|
|
2754
2900
|
{/* Round 333 / Loop: vendor count suffix `:{N}` joins
|
|
2755
2901
|
the R317 subordinate-text-lift family (gray-500 →
|
|
2756
2902
|
gray-400) plus picks up tabular-nums for digit
|
|
@@ -2909,14 +3055,46 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2909
3055
|
const alpha = ageSec <= 30
|
|
2910
3056
|
? 1
|
|
2911
3057
|
: ageSec <= 300
|
|
2912
|
-
? 1 - ((ageSec - 30) / 270) * 0.
|
|
2913
|
-
: 0.25
|
|
3058
|
+
? 1 - ((ageSec - 30) / 270) * 0.70 /* R358: floor 0.25 → 0.30 lift across 3 freshness scopes */
|
|
3059
|
+
: 0.30; /* R358: stale floor lifted 0.25 → 0.30 — 20% legibility bump while preserving fresh/stale ratio */
|
|
2914
3060
|
// Cyan dark / teal light to match palette legendAccent.
|
|
2915
3061
|
const dotColor = isLight
|
|
2916
3062
|
? `rgba(13, 148, 136, ${alpha.toFixed(2)})`
|
|
2917
3063
|
: `rgba(34, 211, 238, ${alpha.toFixed(2)})`;
|
|
3064
|
+
// Round 342 / Loop: active-links chip freshness suffix
|
|
3065
|
+
// wrapper text-gray-500 → text-gray-400 (R317
|
|
3066
|
+
// subordinate-text-lift family applied to chrome
|
|
3067
|
+
// inactive Layout toggle + R333 vendor count suffix).
|
|
3068
|
+
// The "last 5s ago" suffix is chip-subordinate
|
|
3069
|
+
// metadata; gray-500 sat near-invisible against the
|
|
3070
|
+
// chip's outer color, gray-400 lifts it into the band
|
|
3071
|
+
// where the eye reads it as deliberate freshness
|
|
3072
|
+
// annotation. The freshness DOT keeps its own inline
|
|
3073
|
+
// color: dotColor — the lift only affects the trailing
|
|
3074
|
+
// literal "last {rel}" text.
|
|
2918
3075
|
return (
|
|
2919
|
-
|
|
3076
|
+
// Round 357 / Loop: active-links chip freshness
|
|
3077
|
+
// suffix wrapper picks up `tabular-nums` for digit
|
|
3078
|
+
// width-lock. Pre-R357 the literal "last {rel}"
|
|
3079
|
+
// text (e.g. "last 5s ago", "last 10s ago",
|
|
3080
|
+
// "last 1m ago") had natural-figure digits — the
|
|
3081
|
+
// freshness ticker updates every second, so the
|
|
3082
|
+
// 9→10 boundary on the seconds counter and the
|
|
3083
|
+
// 59→60s → 1m flip both jittered ~1-2 px of glyph
|
|
3084
|
+
// width which propagated through the chip-row's
|
|
3085
|
+
// inline-flex layout, nudging the freshness DOT
|
|
3086
|
+
// and the chip's left edge. Tabular-nums on the
|
|
3087
|
+
// wrapper applies to all descendant digits only
|
|
3088
|
+
// (letters render at natural widths) so the
|
|
3089
|
+
// ticker stays planted across every count cross.
|
|
3090
|
+
// Joins the R224-R232 info-density tabular-nums
|
|
3091
|
+
// sweep at the chip-row freshness scope. Pure
|
|
3092
|
+
// paint-level change, no geometry shift on rest.
|
|
3093
|
+
// The R342 text-gray-400 lift + R161 dot freshness
|
|
3094
|
+
// alpha ramp + R317 subordinate-text-lift family
|
|
3095
|
+
// all preserved. data-active-links-freshness-
|
|
3096
|
+
// wrapper attr exposes the wrapper for tests.
|
|
3097
|
+
<span className="text-gray-400 tabular-nums" data-active-links-freshness-wrapper>
|
|
2920
3098
|
<span
|
|
2921
3099
|
data-active-links-freshness-dot
|
|
2922
3100
|
data-active-links-freshness-alpha={alpha.toFixed(2)}
|
|
@@ -4842,11 +5020,27 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
4842
5020
|
textAnchor="middle"
|
|
4843
5021
|
dy="0.36em"
|
|
4844
5022
|
fill={isLight ? '#d1fae5' : '#ecfdf5'}
|
|
4845
|
-
fontSize
|
|
5023
|
+
/* Round 360 / Loop: hub working-count digit fontSize 11
|
|
5024
|
+
→ 12. The hub is the canvas's focal point — its digit
|
|
5025
|
+
is the most-read scalar on the whole topology. R130
|
|
5026
|
+
sized it at 11 (well inside the r=10 / 20-px core);
|
|
5027
|
+
R360 nudges it to 12 (~13 px wide × 12 px tall, still
|
|
5028
|
+
well inside the 20-px diameter) for ~9 % more presence.
|
|
5029
|
+
Sibling visual-weight bump family:
|
|
5030
|
+
R287 minimap viewport stroke 1 → 1.5
|
|
5031
|
+
R295 legend swatch base radius 5.5 → 6
|
|
5032
|
+
R359 recent-row pip radius 1.6 → 1.8
|
|
5033
|
+
R360 hub digit fontSize 11 → 12 (this round)
|
|
5034
|
+
The R209 scale-1.08-on-hub-hover, R225 tabular-nums,
|
|
5035
|
+
R253 fill transition, R213 always-mount opacity gate
|
|
5036
|
+
all preserved. data-topo-hub-working-count-font-size
|
|
5037
|
+
attr exposes the value for tests. */
|
|
5038
|
+
fontSize="12"
|
|
4846
5039
|
fontFamily="monospace"
|
|
4847
5040
|
fontWeight="700"
|
|
4848
5041
|
opacity={workingCount > 0 ? 1 : 0}
|
|
4849
5042
|
data-topo-hub-working-count={workingCount}
|
|
5043
|
+
data-topo-hub-working-count-font-size="12"
|
|
4850
5044
|
data-topo-hub-working-count-hovered={hoveredHub ? 'true' : 'false'}
|
|
4851
5045
|
data-topo-hub-working-count-visible={workingCount > 0 ? 'true' : 'false'}
|
|
4852
5046
|
// Round 209 / Loop: hub workingCount digit scales 1.0 →
|
|
@@ -6213,7 +6407,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6213
6407
|
x="0" y="0" width="230" height="88" rx="10"
|
|
6214
6408
|
fill={pal.legendBox.fill}
|
|
6215
6409
|
stroke={pal.legendBox.stroke}
|
|
6216
|
-
|
|
6410
|
+
// Round 348 / Loop: recent-signal panel rect opacity hover-
|
|
6411
|
+
// state bump — joins the panel-hover cue stack (R135 drop-
|
|
6412
|
+
// shadow boost + R345 title letter-spacing tween 0.3 → 0.4
|
|
6413
|
+
// + R266 fill theme-flip). Cyber 0.92 → 0.97, light 0.97 →
|
|
6414
|
+
// 1.0 on hoveredPanel === 'recent'. The panel "solidifies"
|
|
6415
|
+
// on hover — pure paint-level change, geometry-safe (bbox
|
|
6416
|
+
// unchanged so topo-overlap-test invariants hold). The
|
|
6417
|
+
// R247 transition list already includes `opacity 200ms
|
|
6418
|
+
// ease-out` so the value tween is automatic. Sibling
|
|
6419
|
+
// change at legend panel rect below (~line 7222).
|
|
6420
|
+
opacity={hoveredPanel === 'recent' ? (isLight ? 1 : 0.97) : (isLight ? 0.97 : 0.92)}
|
|
6217
6421
|
style={{
|
|
6218
6422
|
/* R135: drop-shadow intensifies on panel hover. Base
|
|
6219
6423
|
shadow (2px / 6px blur) signals card elevation
|
|
@@ -6265,7 +6469,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6265
6469
|
title (line ~6556) — both panels share the same
|
|
6266
6470
|
editorial-text-spacing convention. data-recent-panel-
|
|
6267
6471
|
title handle unchanged so R266 test still resolves. */}
|
|
6268
|
-
|
|
6472
|
+
{/* Round 345 / Loop: recent-signal panel title gains
|
|
6473
|
+
letter-spacing tween 0.3 → 0.4 on panel hover.
|
|
6474
|
+
hoveredPanel === 'recent' is set by the panel <g>
|
|
6475
|
+
wrapper's onMouseEnter (line ~6263 area). Sibling to
|
|
6476
|
+
R344 hover-letter-spacing applied to the +N more
|
|
6477
|
+
flows footer — same gesture vocabulary at a panel-
|
|
6478
|
+
title scope: hovering the panel chrome spreads the
|
|
6479
|
+
title 0.1 px, signalling "this is a coherent unit
|
|
6480
|
+
you're entering". transition list extends letter-
|
|
6481
|
+
spacing 200ms ease-out alongside existing fill 200ms. */}
|
|
6482
|
+
<text x="13" y="21" fill={pal.legendHeadline} fontSize="12" fontFamily="monospace" fontWeight="700" letterSpacing={hoveredPanel === 'recent' ? '0.4' : '0.3'} style={{ transition: 'fill 200ms ease-out, letter-spacing 200ms ease-out' }} data-recent-panel-title>recent signal</text>
|
|
6269
6483
|
{/* R96: header count now matches what the rows show. Pre-R96
|
|
6270
6484
|
this read "X msgs" off the raw messages array, but the
|
|
6271
6485
|
rows below render DEDUPED flowLinks — so a fleet with 10
|
|
@@ -6326,8 +6540,8 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6326
6540
|
const alpha = ageSec <= 30
|
|
6327
6541
|
? 1
|
|
6328
6542
|
: ageSec <= 300
|
|
6329
|
-
? 1 - ((ageSec - 30) / 270) * 0.
|
|
6330
|
-
: 0.25
|
|
6543
|
+
? 1 - ((ageSec - 30) / 270) * 0.70 /* R358: floor 0.25 → 0.30 lift across 3 freshness scopes */
|
|
6544
|
+
: 0.30; /* R358: stale floor lifted 0.25 → 0.30 — 20% legibility bump while preserving fresh/stale ratio */
|
|
6331
6545
|
// Dark cyan-400 / light teal-600 with alpha — same
|
|
6332
6546
|
// palette as R161's chip bullet so the two scopes
|
|
6333
6547
|
// visually align even side-by-side.
|
|
@@ -6340,6 +6554,21 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6340
6554
|
textAnchor="end"
|
|
6341
6555
|
fontSize="10"
|
|
6342
6556
|
fontFamily="monospace"
|
|
6557
|
+
// Round 349 / Loop: editorial letter-spacing 0.2 on the
|
|
6558
|
+
// recent-signal panel header count. Sits one tier below
|
|
6559
|
+
// the R301 panel title letterSpacing="0.3" so the panel
|
|
6560
|
+
// header reads as a 2-step hierarchy (title 0.3 / count
|
|
6561
|
+
// 0.2). Sibling change on the legend panel count below
|
|
6562
|
+
// closes the panel-pair editorial symmetry. Joins the
|
|
6563
|
+
// R285 / R289 / R301 / R302 / R304 / R325 editorial-
|
|
6564
|
+
// letterspacing tier at the panel-summary scope. The
|
|
6565
|
+
// R162 freshness fill, R225 tabular-nums, R311 fw=600,
|
|
6566
|
+
// R336 unit-tspan opacity-0.7 split all preserved —
|
|
6567
|
+
// the tier propagates to all descendant tspans via
|
|
6568
|
+
// SVG inheritance. data-recent-panel-count-letter-
|
|
6569
|
+
// spacing exposes the value for tests.
|
|
6570
|
+
letterSpacing="0.2"
|
|
6571
|
+
data-recent-panel-count-letter-spacing="0.2"
|
|
6343
6572
|
>
|
|
6344
6573
|
{/* Round 225 / Loop: tabular-nums on the panel-header
|
|
6345
6574
|
flow-count tspan. The "{N} flows" string lives in
|
|
@@ -6808,17 +7037,38 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6808
7037
|
const alpha = ageSec <= 30
|
|
6809
7038
|
? 1
|
|
6810
7039
|
: ageSec <= 300
|
|
6811
|
-
? 1 - ((ageSec - 30) / 270) * 0.
|
|
6812
|
-
: 0.25
|
|
7040
|
+
? 1 - ((ageSec - 30) / 270) * 0.70 /* R358: floor 0.25 → 0.30 lift across 3 freshness scopes */
|
|
7041
|
+
: 0.30; /* R358: stale floor lifted 0.25 → 0.30 — 20% legibility bump while preserving fresh/stale ratio */
|
|
6813
7042
|
return (
|
|
6814
7043
|
<circle
|
|
6815
7044
|
cx={10}
|
|
6816
7045
|
cy={38 + index * 16 - 3}
|
|
6817
|
-
|
|
7046
|
+
/* Round 359 / Loop: recency pip base radius
|
|
7047
|
+
1.6 → 1.8. Sibling lift to R358's freshness-
|
|
7048
|
+
floor bump (alpha 0.25 → 0.30) — pre-R358/
|
|
7049
|
+
R359 the stale pip painted at r=1.6 + α=0.25
|
|
7050
|
+
which read as near-invisible chrome. R358
|
|
7051
|
+
gave it more alpha; R359 gives it more area
|
|
7052
|
+
(1.8² / 1.6² ≈ 1.27, so ~27 % more glyph)
|
|
7053
|
+
so the pip stays distinguishable across the
|
|
7054
|
+
freshness ramp. Geometry: 1.8-radius dot
|
|
7055
|
+
centred at (10, row_y - 3) is bbox 3.6×3.6,
|
|
7056
|
+
still well inside the 7-px left margin
|
|
7057
|
+
(x=6 rect-start → x=13 text-start) the R160
|
|
7058
|
+
pip was placed in. Overlap-test reads the
|
|
7059
|
+
parent row rect's bbox, not this pip's, so
|
|
7060
|
+
grid+ring invariants hold. Matches the same
|
|
7061
|
+
1.6 → 1.8 visual-weight bump R295 applied
|
|
7062
|
+
to the legend swatch (5.5 → 6 base radius)
|
|
7063
|
+
and R287 to the minimap viewport stroke
|
|
7064
|
+
(1 → 1.5). data-recent-row-freshness-radius
|
|
7065
|
+
attr exposes the value for tests. */
|
|
7066
|
+
r={1.8}
|
|
6818
7067
|
fill={pal.legendAccent}
|
|
6819
7068
|
opacity={alpha}
|
|
6820
7069
|
data-recent-row-freshness={link.key}
|
|
6821
7070
|
data-recent-row-freshness-alpha={alpha.toFixed(2)}
|
|
7071
|
+
data-recent-row-freshness-radius="1.8"
|
|
6822
7072
|
style={{ pointerEvents: 'none', transition: 'opacity 200ms ease-out' }}
|
|
6823
7073
|
/>
|
|
6824
7074
|
);
|
|
@@ -7100,6 +7350,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7100
7350
|
preserved for the <title> tooltip — only the SVG
|
|
7101
7351
|
render splits. data-recent-panel-more-unit exposes
|
|
7102
7352
|
the unit tspan for tests. */}
|
|
7353
|
+
{/* Round 344 / Loop: footer hover gains letter-spacing
|
|
7354
|
+
tween 0.2 → 0.3. R325 set rest letter-spacing
|
|
7355
|
+
0.2 to join the editorial-spacing family; R344
|
|
7356
|
+
adds a 0.1px hover spread that layers on top of
|
|
7357
|
+
R195 cyan fill + R325 spacing + R133 underline
|
|
7358
|
+
so the footer reads "lit up and spaced" on
|
|
7359
|
+
hover — sibling to R218/R219/R220 pin-signature
|
|
7360
|
+
letter-spacing family applied to a hover-only
|
|
7361
|
+
surface. transition list extends letter-spacing
|
|
7362
|
+
200ms ease-out alongside the existing opacity/
|
|
7363
|
+
fill easings. */}
|
|
7103
7364
|
<text
|
|
7104
7365
|
x="115" y="82"
|
|
7105
7366
|
textAnchor="middle"
|
|
@@ -7107,12 +7368,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7107
7368
|
fontSize="9"
|
|
7108
7369
|
fontFamily="monospace"
|
|
7109
7370
|
fontStyle="italic"
|
|
7110
|
-
letterSpacing=
|
|
7371
|
+
letterSpacing={hoveredRecentMore ? '0.3' : '0.2'}
|
|
7111
7372
|
opacity={hoveredRecentMore ? 0.85 : 0.55}
|
|
7112
7373
|
textDecoration={hoveredRecentMore ? 'underline' : 'none'}
|
|
7113
7374
|
data-recent-panel-more={moreCount}
|
|
7114
7375
|
data-recent-panel-more-hovered={hoveredRecentMore ? 'true' : 'false'}
|
|
7115
|
-
style={{ transition: 'opacity 150ms ease-out, fill 200ms ease-out' }}
|
|
7376
|
+
style={{ transition: 'opacity 150ms ease-out, fill 200ms ease-out, letter-spacing 200ms ease-out' }}
|
|
7116
7377
|
>
|
|
7117
7378
|
{`+ ${moreCount}`}
|
|
7118
7379
|
<tspan opacity="0.7" data-recent-panel-more-unit>{` more flow${moreCount === 1 ? '' : 's'}`}</tspan>
|
|
@@ -7164,7 +7425,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7164
7425
|
x="0" y="0" width="224" height="88" rx="10"
|
|
7165
7426
|
fill={pal.legendBox.fill}
|
|
7166
7427
|
stroke={pal.legendBox.stroke}
|
|
7167
|
-
|
|
7428
|
+
// R348 sibling — legend panel rect opacity hover-state
|
|
7429
|
+
// bump 0.92 → 0.97 (cyber) / 0.97 → 1 (light) on
|
|
7430
|
+
// hoveredPanel === 'legend'. Pairs with the recent-signal
|
|
7431
|
+
// panel rect above so the two corner panels' hover cues
|
|
7432
|
+
// stay symmetric. Geometry-safe (paint-only).
|
|
7433
|
+
opacity={hoveredPanel === 'legend' ? (isLight ? 1 : 0.97) : (isLight ? 0.97 : 0.92)}
|
|
7168
7434
|
style={{
|
|
7169
7435
|
filter: hoveredPanel === 'legend'
|
|
7170
7436
|
? (isLight ? 'drop-shadow(0 4px 12px rgba(15,23,42,0.14))'
|
|
@@ -7187,7 +7453,9 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7187
7453
|
surrounding chrome eased; R266 closes both at once. */}
|
|
7188
7454
|
{/* R301: sibling to recent-signal panel title above —
|
|
7189
7455
|
same letterSpacing 0.3 for editorial parity. */}
|
|
7190
|
-
|
|
7456
|
+
{/* R345 sibling — legend panel title same hover letter-
|
|
7457
|
+
spacing tween 0.3 → 0.4 on panel hover. */}
|
|
7458
|
+
<text x="13" y="21" fill={pal.legendHeadline} fontSize="12" fontFamily="monospace" fontWeight="700" letterSpacing={hoveredPanel === 'legend' ? '0.4' : '0.3'} style={{ transition: 'fill 200ms ease-out, letter-spacing 200ms ease-out' }} data-legend-panel-title>legend</text>
|
|
7191
7459
|
{/* Round 257 / Loop: legend panel header count picks up the
|
|
7192
7460
|
symmetric 13L/13R inner-padding pattern from the recent-
|
|
7193
7461
|
signal panel. Pre-R257 the legend header was 13px from
|
|
@@ -7251,7 +7519,14 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7251
7519
|
<text
|
|
7252
7520
|
x="211" y="21" textAnchor="end"
|
|
7253
7521
|
fill={pal.legendAccent} fontSize="10" fontFamily="monospace" fontWeight="600"
|
|
7522
|
+
// R349 sibling — legend panel header count picks up
|
|
7523
|
+
// letterSpacing="0.2", one tier below the R301 panel
|
|
7524
|
+
// title 0.3. Pairs with the recent-signal panel count
|
|
7525
|
+
// letter-spacing above so the two corner panels' header
|
|
7526
|
+
// typography stays editorially symmetric.
|
|
7527
|
+
letterSpacing="0.2"
|
|
7254
7528
|
data-legend-panel-count
|
|
7529
|
+
data-legend-panel-count-letter-spacing="0.2"
|
|
7255
7530
|
style={{
|
|
7256
7531
|
transition: 'fill 200ms ease-out',
|
|
7257
7532
|
fontVariantNumeric: 'tabular-nums',
|
|
@@ -7793,7 +8068,13 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7793
8068
|
resetView();
|
|
7794
8069
|
}
|
|
7795
8070
|
}}
|
|
8071
|
+
// R346: viewport rect hover affordance driven by parent.
|
|
8072
|
+
onMouseEnter={() => setHoveredMinimap(true)}
|
|
8073
|
+
onMouseLeave={() => setHoveredMinimap(false)}
|
|
8074
|
+
onFocus={() => setHoveredMinimap(true)}
|
|
8075
|
+
onBlur={() => setHoveredMinimap(false)}
|
|
7796
8076
|
data-topo-minimap
|
|
8077
|
+
data-topo-minimap-hovered={hoveredMinimap ? 'true' : 'false'}
|
|
7797
8078
|
>
|
|
7798
8079
|
<svg width={MW} height={MH} viewBox={`0 0 ${MW} ${MH}`} style={{ display: 'block' }}>
|
|
7799
8080
|
{/* Round 198 / Loop: minimap dots gain smooth status
|
|
@@ -7872,13 +8153,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
7872
8153
|
x={Math.max(0, rectX)} y={Math.max(0, rectY)}
|
|
7873
8154
|
width={Math.max(0, Math.min(MW - Math.max(0, rectX), rectW))}
|
|
7874
8155
|
height={Math.max(0, Math.min(MH - Math.max(0, rectY), rectH))}
|
|
7875
|
-
fill="none" stroke={pal.legendAccent}
|
|
8156
|
+
fill="none" stroke={pal.legendAccent}
|
|
8157
|
+
// R346: strokeWidth + opacity tween on container hover.
|
|
8158
|
+
strokeWidth={hoveredMinimap ? '1.75' : '1.5'}
|
|
8159
|
+
opacity={hoveredMinimap ? '1' : '0.9'}
|
|
7876
8160
|
data-topo-minimap-viewport
|
|
7877
8161
|
data-topo-minimap-viewport-smooth={smoothView ? 'true' : 'false'}
|
|
8162
|
+
data-topo-minimap-viewport-hover={hoveredMinimap ? 'true' : 'false'}
|
|
7878
8163
|
style={{
|
|
7879
8164
|
transition: smoothView
|
|
7880
|
-
? 'x 280ms ease-out, y 280ms ease-out, width 280ms ease-out, height 280ms ease-out'
|
|
7881
|
-
: '
|
|
8165
|
+
? 'x 280ms ease-out, y 280ms ease-out, width 280ms ease-out, height 280ms ease-out, stroke-width 200ms ease-out, opacity 200ms ease-out'
|
|
8166
|
+
: 'stroke-width 200ms ease-out, opacity 200ms ease-out',
|
|
7882
8167
|
} as React.CSSProperties}
|
|
7883
8168
|
/>
|
|
7884
8169
|
</svg>
|
|
@@ -8031,7 +8316,8 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8031
8316
|
// R196: press-state deepens bg one tier above hover (white/5
|
|
8032
8317
|
// → white/10) so mouse-down has a tactile dim before the
|
|
8033
8318
|
// R186 icon pop fires on release.
|
|
8034
|
-
|
|
8319
|
+
// R352: `group` lets the inner svg respond via group-hover.
|
|
8320
|
+
className="group px-2 py-1 hover:bg-white/5 active:bg-white/10 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset"
|
|
8035
8321
|
style={{ color: pal.legendText }}
|
|
8036
8322
|
aria-label="Zoom out"
|
|
8037
8323
|
title="Zoom out (−)"
|
|
@@ -8039,11 +8325,25 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8039
8325
|
{/* R186: icon pop on click. CSS animation runs once;
|
|
8040
8326
|
React removes the class after 240ms so a quick
|
|
8041
8327
|
re-click can replay. */}
|
|
8328
|
+
{/* Round 352 / Loop: zoom-out icon picks up group-hover:
|
|
8329
|
+
scale-110 — sibling to R350 reset hover-rotate. Pre-
|
|
8330
|
+
R352 hovering the zoom button only changed the bg
|
|
8331
|
+
(white/5); the icon inside stayed perfectly still.
|
|
8332
|
+
R352 lifts the icon 10% on hover for a tactile "this
|
|
8333
|
+
button does something" cue. The R186 anet-chrome-pop
|
|
8334
|
+
keyframe (220ms scale 1→1.06→1) still owns transform
|
|
8335
|
+
during click via CSS-animation precedence over
|
|
8336
|
+
transition-transform; after the pop ends + className
|
|
8337
|
+
is removed, the group-hover scale-110 picks up
|
|
8338
|
+
smoothly. `transform-gpu` hint promotes the svg to
|
|
8339
|
+
its own compositor layer for crisper edges during
|
|
8340
|
+
the scale tween. Sibling change on zoom-in icon
|
|
8341
|
+
below. */}
|
|
8042
8342
|
<svg
|
|
8043
8343
|
width="12" height="12" viewBox="0 0 24 24"
|
|
8044
8344
|
fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"
|
|
8045
8345
|
aria-hidden
|
|
8046
|
-
className={chromePopping === 'zoom-out' ? 'anet-chrome-pop' :
|
|
8346
|
+
className={`transition-transform duration-200 ease-out group-hover:scale-110 transform-gpu${chromePopping === 'zoom-out' ? ' anet-chrome-pop' : ''}`}
|
|
8047
8347
|
data-topo-chrome-zoom-out-icon
|
|
8048
8348
|
><path d="M5 12h14" /></svg>
|
|
8049
8349
|
</button>
|
|
@@ -8089,11 +8389,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8089
8389
|
chromePopping === 'zoom-in' || chromePopping === 'zoom-out'
|
|
8090
8390
|
? 'true' : 'false'
|
|
8091
8391
|
}
|
|
8392
|
+
data-topo-chrome-zoom-level-hover={hoveredZoomLevel ? 'true' : 'false'}
|
|
8393
|
+
onMouseEnter={() => setHoveredZoomLevel(true)}
|
|
8394
|
+
onMouseLeave={() => setHoveredZoomLevel(false)}
|
|
8092
8395
|
style={{
|
|
8093
8396
|
color: pal.legendText,
|
|
8094
8397
|
borderColor: pal.containerBorder,
|
|
8095
8398
|
minWidth: 46,
|
|
8096
8399
|
display: 'inline-block',
|
|
8400
|
+
// R347: letter-spacing hover tween — extends R344/R345
|
|
8401
|
+
// hover-letter-spacing family into the chrome strip.
|
|
8402
|
+
letterSpacing: hoveredZoomLevel ? '0.5px' : '0',
|
|
8097
8403
|
/* Round 264 / Loop: zoom level readout gains theme-toggle
|
|
8098
8404
|
transition. The span has theme-driven color (pal.
|
|
8099
8405
|
legendText) + border-x (pal.containerBorder via the
|
|
@@ -8102,7 +8408,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8102
8408
|
on theme flip while siblings eased. Sibling treatment
|
|
8103
8409
|
to the nodeSize + zoom wrapper transitions added this
|
|
8104
8410
|
round. */
|
|
8105
|
-
transition: 'color 200ms ease-out, border-color 200ms ease-out',
|
|
8411
|
+
transition: 'color 200ms ease-out, border-color 200ms ease-out, letter-spacing 200ms ease-out',
|
|
8106
8412
|
}}
|
|
8107
8413
|
title="Current zoom level"
|
|
8108
8414
|
>
|
|
@@ -8113,18 +8419,22 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8113
8419
|
data-topo-chrome-zoom-in
|
|
8114
8420
|
data-topo-chrome-zoom-in-popping={chromePopping === 'zoom-in' ? 'true' : 'false'}
|
|
8115
8421
|
// R196: press-state (mirror of zoom-out above).
|
|
8116
|
-
|
|
8422
|
+
// R352: `group` lets the inner svg respond via group-hover.
|
|
8423
|
+
className="group px-2 py-1 hover:bg-white/5 active:bg-white/10 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset"
|
|
8117
8424
|
style={{ color: pal.legendText }}
|
|
8118
8425
|
aria-label="Zoom in"
|
|
8119
8426
|
title="Zoom in (+)"
|
|
8120
8427
|
>
|
|
8121
8428
|
{/* R186: icon pop on click. Same one-shot CSS animation
|
|
8122
8429
|
as zoom-out; React removes the class after 240ms. */}
|
|
8430
|
+
{/* R352 sibling — zoom-in icon picks up the same
|
|
8431
|
+
group-hover:scale-110 family. Mirror change at
|
|
8432
|
+
the zoom-out icon above. */}
|
|
8123
8433
|
<svg
|
|
8124
8434
|
width="12" height="12" viewBox="0 0 24 24"
|
|
8125
8435
|
fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"
|
|
8126
8436
|
aria-hidden
|
|
8127
|
-
className={chromePopping === 'zoom-in' ? 'anet-chrome-pop' :
|
|
8437
|
+
className={`transition-transform duration-200 ease-out group-hover:scale-110 transform-gpu${chromePopping === 'zoom-in' ? ' anet-chrome-pop' : ''}`}
|
|
8128
8438
|
data-topo-chrome-zoom-in-icon
|
|
8129
8439
|
><path d="M12 5v14M5 12h14" /></svg>
|
|
8130
8440
|
</button>
|
|
@@ -8133,6 +8443,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8133
8443
|
onClick={() => { armResetSpin(); resetView(); }}
|
|
8134
8444
|
data-topo-chrome-reset
|
|
8135
8445
|
data-topo-chrome-reset-spinning={resetSpinning ? 'true' : 'false'}
|
|
8446
|
+
data-topo-chrome-reset-hover={hoveredReset ? 'true' : 'false'}
|
|
8447
|
+
// R350: hover state drives the icon transform below.
|
|
8448
|
+
onMouseEnter={() => setHoveredReset(true)}
|
|
8449
|
+
onMouseLeave={() => setHoveredReset(false)}
|
|
8450
|
+
onFocus={() => setHoveredReset(true)}
|
|
8451
|
+
onBlur={() => setHoveredReset(false)}
|
|
8136
8452
|
// R196: press-state deepens before R184 reset-spin fires on
|
|
8137
8453
|
// release — mouse-down dim then 450ms spin = full handshake.
|
|
8138
8454
|
className="p-1.5 rounded-md border hover:bg-white/5 active:bg-white/10 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60"
|
|
@@ -8162,6 +8478,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8162
8478
|
aria-hidden
|
|
8163
8479
|
className={resetSpinning ? 'anet-reset-spin' : undefined}
|
|
8164
8480
|
data-topo-chrome-reset-icon
|
|
8481
|
+
// R350: hover-rotate preview of the R184 click-spin.
|
|
8482
|
+
// Gated on !resetSpinning so the anet-reset-spin keyframe
|
|
8483
|
+
// owns transform during its 450ms run. transformOrigin
|
|
8484
|
+
// 'center' so rotation pivots around the icon's centre
|
|
8485
|
+
// (default would be top-left and the icon would arc).
|
|
8486
|
+
style={{
|
|
8487
|
+
transform: hoveredReset && !resetSpinning ? 'rotate(-8deg)' : 'rotate(0deg)',
|
|
8488
|
+
transformOrigin: 'center',
|
|
8489
|
+
transition: 'transform 200ms ease-out',
|
|
8490
|
+
}}
|
|
8491
|
+
data-topo-chrome-reset-icon-hover={hoveredReset && !resetSpinning ? 'true' : 'false'}
|
|
8165
8492
|
>
|
|
8166
8493
|
<path d="M3 12a9 9 0 1 0 9-9 9 9 0 0 0-6.4 2.6L3 8" />
|
|
8167
8494
|
<path d="M3 3v5h5" />
|
|
@@ -8195,7 +8522,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8195
8522
|
its inactive state benefits from the same "hover previews
|
|
8196
8523
|
active state" idiom R163 designed. Sibling treatment to
|
|
8197
8524
|
the nodeSize buttons at line ~6711. */
|
|
8198
|
-
|
|
8525
|
+
// R353: `group` lets the inner svg respond via group-hover —
|
|
8526
|
+
// sibling to R352 zoom buttons. Closes the chrome-strip per-
|
|
8527
|
+
// icon hover-affordance arc (zoom-out / zoom-in / reset /
|
|
8528
|
+
// fullscreen now all carry an icon-level hover gesture in
|
|
8529
|
+
// addition to the bg hover).
|
|
8530
|
+
className={`group p-1.5 rounded-md border transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 ${
|
|
8199
8531
|
isFullscreen
|
|
8200
8532
|
? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25'
|
|
8201
8533
|
: 'hover:bg-cyan-500/5 active:bg-cyan-500/15'
|
|
@@ -8214,12 +8546,20 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
8214
8546
|
at the reset icon above. data-topo-chrome-fullscreen-
|
|
8215
8547
|
icon attribute exposes BOTH variants (entered / exited)
|
|
8216
8548
|
for the round's stroke-width regression probe. */}
|
|
8549
|
+
{/* Round 353 / Loop: fullscreen icon (both enter + exit
|
|
8550
|
+
variants) picks up the R352 family group-hover:scale-110.
|
|
8551
|
+
Pre-R353 hovering the button only changed the bg; the
|
|
8552
|
+
icon stayed still. R353 lifts the icon 10 % on hover —
|
|
8553
|
+
same gesture vocabulary as the zoom buttons. transform-
|
|
8554
|
+
gpu hint promotes the svg to its own compositor layer
|
|
8555
|
+
for crisper edges during the scale tween. Closes the
|
|
8556
|
+
chrome-strip per-icon hover-affordance arc. */}
|
|
8217
8557
|
{isFullscreen ? (
|
|
8218
|
-
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden data-topo-chrome-fullscreen-icon="exit">
|
|
8558
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden className="transition-transform duration-200 ease-out group-hover:scale-110 transform-gpu" data-topo-chrome-fullscreen-icon="exit">
|
|
8219
8559
|
<path d="M8 3v4a1 1 0 0 1-1 1H3M21 8h-4a1 1 0 0 1-1-1V3M3 16h4a1 1 0 0 1 1 1v4M16 21v-4a1 1 0 0 1 1-1h4" />
|
|
8220
8560
|
</svg>
|
|
8221
8561
|
) : (
|
|
8222
|
-
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden data-topo-chrome-fullscreen-icon="enter">
|
|
8562
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden className="transition-transform duration-200 ease-out group-hover:scale-110 transform-gpu" data-topo-chrome-fullscreen-icon="enter">
|
|
8223
8563
|
<path d="M3 8V5a2 2 0 0 1 2-2h3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M21 16v3a2 2 0 0 1-2 2h-3" />
|
|
8224
8564
|
</svg>
|
|
8225
8565
|
)}
|