Keep the status pills on exactly one row at every width
All checks were successful
Deploy / deploy (push) Successful in 21s
All checks were successful
Deploy / deploy (push) Successful in 21s
The strip wrapped to two or three rows on narrow screens. It's now nowrap with flex: 1 1 0 pills, so all six share the row equally and shrink together instead of spilling onto a second line. Six pills can't hold full detail in 375px, so detail degrades inside the pill rather than the strip breaking: the stat drops at 1024px (the dot already carries up/down), then below 560px the name swaps to a short label — Son, Rad, Prow, SAB, Taut, Ombi. Without that swap the names ellipsised to ~23px, about two characters, which identifies nothing. The full name stays in the DOM at font-size: 0 so screen readers still announce it, and it's on the pill's title attribute. The dot and the pill itself never go, so no service is ever hidden — which was the point of the old wrapping rule. Verified one row with nothing clipped and no page overflow at 320, 375, 430, 560, 620, 700, 820, 1024, 1100 and 1400px. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
41205be83c
commit
3c931873b1
2 changed files with 59 additions and 16 deletions
|
|
@ -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%;
|
||||
|
|
|
|||
|
|
@ -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) %}
|
||||
<a class="svc-pill {{ 'up' if up else 'down' }}" id="svc-{{ key }}"
|
||||
href="{{ url }}" target="_blank" rel="noopener">
|
||||
href="{{ url }}" target="_blank" rel="noopener" title="{{ label }}">
|
||||
<span class="status-light {{ 'up' if up else 'down' }}" id="svc-light-{{ key }}"></span>
|
||||
<span class="svc-name">{{ label }}</span>
|
||||
<span class="svc-name" data-short="{{ short }}">{{ label }}</span>
|
||||
<span class="svc-stat" id="svc-stat-{{ key }}">{{ stat }}</span>
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
|
@ -75,17 +78,17 @@
|
|||
rows rather than scrolling or truncating. A hidden pill is a service
|
||||
whose status you can't see. #}
|
||||
<nav class="svc-strip" aria-label="Service status">
|
||||
{{ svc_pill('sonarr', 'Sonarr', service_urls.sonarr, sonarr.status == 'ok',
|
||||
{{ svc_pill('sonarr', 'Sonarr', 'Son', service_urls.sonarr, sonarr.status == 'ok',
|
||||
(sonarr.total_series ~ ' series') if sonarr.status == 'ok' else 'offline') }}
|
||||
{{ svc_pill('radarr', 'Radarr', service_urls.radarr, radarr.status == 'ok',
|
||||
{{ svc_pill('radarr', 'Radarr', 'Rad', service_urls.radarr, radarr.status == 'ok',
|
||||
(radarr.total_movies ~ ' movies') if radarr.status == 'ok' else 'offline') }}
|
||||
{{ svc_pill('prowlarr', 'Prowlarr', service_urls.prowlarr, prowlarr.status == 'ok',
|
||||
{{ svc_pill('prowlarr', 'Prowlarr', 'Prow', service_urls.prowlarr, prowlarr.status == 'ok',
|
||||
(prowlarr.up_count ~ '/' ~ prowlarr.total ~ ' up') if prowlarr.status == 'ok' else 'offline') }}
|
||||
{{ svc_pill('sabnzbd', 'SABnzbd', service_urls.sabnzbd, sabnzbd.status == 'ok',
|
||||
{{ svc_pill('sabnzbd', 'SABnzbd', 'SAB', service_urls.sabnzbd, sabnzbd.status == 'ok',
|
||||
sabnzbd.speed if sabnzbd.status == 'ok' else 'offline') }}
|
||||
{{ svc_pill('tautulli', 'Tautulli', service_urls.tautulli, tautulli.status == 'ok',
|
||||
{{ svc_pill('tautulli', 'Tautulli', 'Taut', service_urls.tautulli, tautulli.status == 'ok',
|
||||
((tautulli.active_streams ~ ' streaming') if tautulli.active_streams > 0 else '0 streams') if tautulli.status == 'ok' else 'offline') }}
|
||||
{{ svc_pill('ombi', 'Ombi', service_urls.ombi, ombi.status == 'ok',
|
||||
{{ svc_pill('ombi', 'Ombi', 'Ombi', service_urls.ombi, ombi.status == 'ok',
|
||||
(ombi.total_pending ~ ' pending') if ombi.status == 'ok' else 'offline') }}
|
||||
</nav>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue