From b52bfbcbe27d71d24586e332d5a43595b70a1786 Mon Sep 17 00:00:00 2001 From: s0lray Date: Tue, 24 Mar 2026 18:46:05 -0400 Subject: [PATCH] feat(ui): responsive SVG viewport, Inter typography, expanded CSS tokens (THE-72) - Replace fixed SVG width/height attrs with viewBox + preserveAspectRatio so the tree scales naturally across screen sizes - Switch font-family to Inter/system-font stack via --font-family token - Add spacing tokens (--space-1 through --space-6, 4px scale) - Add border-radius tokens (--radius-sm, --radius-md) - Add shadow tokens (--shadow-sm, --shadow-md) with light-mode overrides - Add --color-accent and --color-border for future theming use - Add font-size tokens (--font-size-sm/base/lg/xl) - Wire up new tokens throughout existing CSS rules Co-Authored-By: Paperclip --- public/css/arf.css | 120 +++++++++++++++++++++++++++++++++++++++++++-- public/js/arf.js | 7 ++- 2 files changed, 120 insertions(+), 7 deletions(-) diff --git a/public/css/arf.css b/public/css/arf.css index 3238f8b..913e807 100644 --- a/public/css/arf.css +++ b/public/css/arf.css @@ -1,5 +1,6 @@ -/* === Color tokens === */ +/* === Design tokens === */ :root { + /* Colors */ --color-bg: #1a1a1a; --color-surface: #2d2d2d; --color-text-primary: #e0e0e0; @@ -12,6 +13,32 @@ --color-noscript-border: #7a4a00; --color-legend: #e0e0e0; --color-header: #e0e0e0; + --color-accent: #4a9eda; + --color-border: #444; + + /* Shadows */ + --shadow-sm: 0 1px 3px rgba(0,0,0,0.4); + --shadow-md: 0 4px 12px rgba(0,0,0,0.5); + + /* Border radius */ + --radius-sm: 3px; + --radius-md: 6px; + + /* Spacing (4px base scale) */ + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 24px; + --space-6: 32px; + + /* Typography */ + --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, sans-serif; + --font-size-sm: 11px; + --font-size-base: 14px; + --font-size-lg: 16px; + --font-size-xl: 40px; } body.light-mode { @@ -27,13 +54,16 @@ body.light-mode { --color-noscript-border: rgb(255, 204, 153); --color-legend: #000000; --color-header: #000000; + --color-border: #ddd; + --shadow-sm: 0 1px 3px rgba(0,0,0,0.12); + --shadow-md: 0 4px 12px rgba(0,0,0,0.15); } body { background-color: var(--color-bg); color: var(--color-text-primary); - font-size: 14px; - font-family: "Helvetica Neue", Helvetica; + font-size: var(--font-size-base); + font-family: var(--font-family); } noscript p { @@ -55,8 +85,14 @@ noscript p { position: relative; } +svg { + display: block; + width: 100%; + height: auto; +} + #header { - font-size: 40px; + font-size: var(--font-size-xl); font-weight: bold; top: 20px; text-align: center; @@ -68,7 +104,7 @@ noscript p { top: 0px; right: 0; width: 330px; - font-size: 11px; + font-size: var(--font-size-sm); color: var(--color-legend); } @@ -105,3 +141,77 @@ h3 { a { color: var(--color-node-stroke); } + +/* Search */ +#search-container { + text-align: center; + padding: var(--space-2) 0 var(--space-1); +} + +#search-input { + width: 400px; + max-width: 90vw; + padding: var(--space-2) var(--space-3); + font-size: var(--font-size-base); + font-family: var(--font-family); + background: var(--color-surface); + color: var(--color-text-primary); + border: 1px solid var(--color-link); + border-radius: var(--radius-sm); + outline: none; +} + +#search-input:focus { + border-color: var(--color-accent); + box-shadow: 0 0 0 2px rgba(74, 158, 218, 0.25); +} + +#search-results { + margin: var(--space-2) auto 0; + width: 600px; + max-width: 90vw; + text-align: left; + background: var(--color-surface); + border: 1px solid var(--color-link); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-md); + max-height: 400px; + overflow-y: auto; + display: none; +} + +#search-results.visible { + display: block; +} + +.search-result-item { + padding: var(--space-2) var(--space-3); + border-bottom: 1px solid var(--color-link); + font-size: 13px; +} + +.search-result-item:last-child { + border-bottom: none; +} + +.search-result-item a { + font-weight: bold; + color: var(--color-node-stroke); + text-decoration: none; +} + +.search-result-item a:hover { + text-decoration: underline; +} + +.search-result-path { + color: var(--color-text-secondary); + font-size: var(--font-size-sm); + margin-top: 2px; +} + +.search-no-results { + padding: var(--space-3); + color: var(--color-text-secondary); + text-align: center; +} diff --git a/public/js/arf.js b/public/js/arf.js index b3fa05f..0da0161 100644 --- a/public/js/arf.js +++ b/public/js/arf.js @@ -12,9 +12,12 @@ var diagonal = d3.linkHorizontal() .x(function(d) { return d.y; }) .y(function(d) { return d.x; }); +var svgW = width + margin[1] + margin[3]; +var svgH = height + margin[0] + margin[2]; + var vis = d3.select("#body").append("svg") - .attr("width", width + margin[1] + margin[3]) - .attr("height", height + margin[0] + margin[2]) + .attr("viewBox", "0 0 " + svgW + " " + svgH) + .attr("preserveAspectRatio", "xMidYMid meet") .append("g") .attr("transform", "translate(" + margin[3] + "," + margin[0] + ")");