← Commit history

demo: ship the Adom pretty scrollbar (adom-ui-design/skills/scrollbars) - thin translucent pill on a transparent track, teal on hover, fade-in-while-scrolling on the consoles, stable both-edges gutter for the centered column, and inset tracks so the radius corners are not sliced

John Lauer ·185cd74ba6 ·2mo ago ·parent 3070a38
1 file changed +58
web-control-demo.html+58
@@ -10,6 +10,50 @@   :root { color-scheme: dark; }   html, body { margin: 0; padding: 0; background: #0d1117; color: #e6edf3; font-family: system-ui, "Segoe UI", sans-serif; }   .wrap { max-width: 1000px; margin: 0 auto; padding: 24px; }++  /* ── Scrollbars: the Adom pretty one, per adom-ui-design/skills/scrollbars ──+     A default OS scrollbar in an Adom app is hideous (John, 2026-08-18). The+     content is the subject; the scrollbar is a hint, not furniture. */++  /* Firefox + the standard property */+  * { scrollbar-width: thin; scrollbar-color: rgba(139,148,158,.38) transparent; }++  /* The centered .wrap is exactly the case the skill calls out: reserve the+     gutter on BOTH edges so the column does not jump sideways the moment a+     scrollbar appears. */+  html { scrollbar-gutter: stable both-edges; }++  /* Chromium / WebKit */+  ::-webkit-scrollbar { width: 10px; height: 10px; }+  ::-webkit-scrollbar-track { background: transparent; }   /* a solid track is what reads as "OS gutter" */+  ::-webkit-scrollbar-thumb {+    background: rgba(139,148,158,.32);+    border-radius: 999px;                 /* a pill, never a rectangle */+    border: 2px solid transparent;        /* with background-clip, insets the pill off the edge */+    background-clip: padding-box;+  }+  ::-webkit-scrollbar-thumb:hover { background: rgba(0,184,177,.55); background-clip: padding-box; }+  ::-webkit-scrollbar-corner { background: transparent; }++  /* Fade-in-while-scrolling, the variant the skill prefers for DENSE surfaces -+     and the per-card consoles are the densest thing on this page. Thumb is+     invisible at rest, appears while scrolling, and dims back out. */+  .slog::-webkit-scrollbar-thumb,+  pre#log::-webkit-scrollbar-thumb,+  .doc pre::-webkit-scrollbar-thumb { background: transparent; transition: background .25s ease; }+  .slog.is-scrolling::-webkit-scrollbar-thumb,+  pre#log.is-scrolling::-webkit-scrollbar-thumb,+  .doc pre.is-scrolling::-webkit-scrollbar-thumb { background: rgba(139,148,158,.38); background-clip: padding-box; }+  .slog:hover::-webkit-scrollbar-thumb,+  pre#log:hover::-webkit-scrollbar-thumb,+  .doc pre:hover::-webkit-scrollbar-thumb { background: rgba(139,148,158,.28); background-clip: padding-box; }++  /* ROUNDED CORNERS: each of these scrolls ITSELF and carries a radius, so an+     un-inset track paints straight through the top and bottom curves and the+     box reads as clipped. Inset the track by at least the radius. */+  .slog::-webkit-scrollbar-track { margin: 4px 0; }        /* radius 4 */+  pre#log::-webkit-scrollbar-track { margin: 6px 0; }      /* radius 6 */+  .doc pre::-webkit-scrollbar-track { margin: 6px 0; }     /* radius 6 */   h1 { font-size: 20px; margin: 0 0 4px; }   .sub { font-size: 12px; color: #8b949e; margin-bottom: 18px; }   .sub code { color: #79c0ff; }@@ -470,6 +514,20 @@ for (const w of mine) {     var timing = (elapsed != null && estimate != null) ? ' <span class="beat">- ' + elapsed + "s of ~" + estimate + "s</span>" : "";     p.meta.innerHTML = (pct != null ? pct + "% " : "") + esc(label || "") + beat + timing;   }+  // Drive the fade-in-while-scrolling scrollbar (adom-ui-design/skills/scrollbars).+  // Delegated + capturing, so it covers consoles created LATER by a card run+  // without re-wiring anything per element.+  (function () {+    var timers = new WeakMap();+    document.addEventListener('scroll', function (e) {+      var el = e.target;+      if (!el || !el.classList || !(el.matches && el.matches('.slog, pre#log, .doc pre'))) return;+      el.classList.add('is-scrolling');+      clearTimeout(timers.get(el));+      timers.set(el, setTimeout(function () { el.classList.remove('is-scrolling'); }, 900));+    }, true);+  })();+   function esc(s) { return String(s).replace(/[&<>]/g, function (c) { return { "&": "&amp;", "<": "&lt;", ">": "&gt;" }[c]; }); }    // ==========================================================================