diff --git a/static/css/dashboard.css b/static/css/dashboard.css index 38faf38..ed19e0d 100644 --- a/static/css/dashboard.css +++ b/static/css/dashboard.css @@ -30,20 +30,26 @@ header { } /* Service status pills — the Status section's only content, left-aligned - with every other section's content and wrapping among themselves so - every service stays visible at any width. Never scroll or clip: a - hidden pill is a service whose status you can't see. */ + with every other section's content. All six share the row equally and + shrink together, so the strip is always exactly one row: never two, + never a scroller. Every service stays visible at every width; what + gives way as space tightens is detail *within* a pill, in this order: + the stat drops below 1024px, then the name shortens below 560px. The + dot and the pill itself never go, so no service is ever hidden. */ .svc-strip { display: flex; align-items: center; gap: 0.5rem; - flex-wrap: wrap; + flex-wrap: nowrap; min-width: 0; } /* Full --tap height now they're content rather than header furniture. */ .svc-pill { + flex: 1 1 0; /* equal share of the row, all shrink together */ + min-width: 0; /* ...which flex items won't do without this */ display: inline-flex; align-items: center; + justify-content: center; gap: 0.45rem; padding: 0.35rem 0.9rem; min-height: var(--tap); @@ -54,13 +60,47 @@ header { color: var(--text-2); text-decoration: none; white-space: nowrap; + overflow: hidden; transition: border-color 0.2s, color 0.2s; } .svc-pill:hover { border-color: var(--border-lt); color: var(--text); } .svc-pill.down { color: var(--danger); border-color: var(--danger-border); } -.svc-name { font-weight: 600; } -.svc-stat { color: var(--text-3); } +.svc-name { + font-weight: 600; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; +} +.svc-stat { + color: var(--text-3); + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; +} .svc-pill.down .svc-stat { color: var(--danger); } +@media (max-width: 1024px) { + /* Six stats stop fitting here. The dot already carries up/down, so the + stat is the first thing that can go without losing any status. */ + .svc-stat { display: none; } +} +@media (max-width: 620px) { + /* Tighten the furniture so the names keep their characters longer. */ + .svc-strip { gap: 0.3rem; } + .svc-pill { padding: 0.35rem 0.5rem; gap: 0.3rem; } +} +@media (max-width: 560px) { + /* Six full names in one row leaves ~23px each — two characters and an + ellipsis, which identifies nothing. Swap in the short label instead. + The full name stays in the DOM (font-size: 0 — invisible but still + announced) and on the pill's title attribute. */ + .svc-strip { gap: 0.25rem; } + .svc-pill { padding: 0.35rem 0.35rem; gap: 0.25rem; } + .svc-name { font-size: 0; } + .svc-name::after { + content: attr(data-short); + font-size: var(--fs-xs); + } +} .status-light { width: 7px; height: 7px; border-radius: 50%; diff --git a/templates/dashboard.html b/templates/dashboard.html index 17bb60b..67d2d2a 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -38,12 +38,15 @@ {%- endif -%} {% endmacro %} -{#- One service status pill in the header strip. -#} -{% macro svc_pill(key, label, url, up, stat) %} +{#- One service status pill in the Status strip. `short` is swapped in for + `label` on phones, where six full names can't share one row without + ellipsising down to two characters — see the .svc-name rules. The full + name stays in the DOM for screen readers either way. -#} +{% macro svc_pill(key, label, short, url, up, stat) %} + href="{{ url }}" target="_blank" rel="noopener" title="{{ label }}"> - {{ label }} + {{ label }} {{ stat }} {% endmacro %} @@ -75,17 +78,17 @@ rows rather than scrolling or truncating. A hidden pill is a service whose status you can't see. #}