@layer base { /* small widgets a view or a third-party luci-app-* can drop anywhere: tooltip, progress bar, * zone badge, button states, close cross, alert box, .label pill */ /* .cbi-title-ref colour: theme/45-misc.css — absorbed. The arrow stays: content, * not paint. */ .cbi-title-ref::after { content: "➙"; } .cbi-tooltip-container { cursor: help; } .cbi-tooltip { position: absolute; z-index: var(--fs-z-tooltip); /* logical: `left: -10000px` in an RTL document parks the tooltip past the INLINE-END edge, * which is scrollable overflow — every page grew a 10000px horizontal scrollbar in ar/fa/he * (measured). Past the inline-start edge is unreachable in both directions. */ inset-inline-start: -10000px; /* box-shadow: theme/35-alerts.css — absorbed */ border-radius: var(--fs-radius-sm); background: var(--fs-panel); white-space: pre; padding: var(--fs-space-0-5) var(--fs-space-1); opacity: 0; transition: opacity var(--fs-dur-fade); } .cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { inset-inline-start: auto; opacity: 1; transition: opacity var(--fs-dur-fade); } /* .cbi-progressbar paint: theme/25-progressbar.css — absorbed. The fill's starting * width stays: the poll JS animates the inline width up from it. */ .cbi-progressbar > div { width: 0%; } .zonebadge .cbi-tooltip { padding: 1px; background: inherit; margin: -1.6em 0 0 -5px; border-radius: var(--fs-radius-sm); pointer-events: none; /* box-shadow: theme/35-alerts.css states one elevation for every .cbi-tooltip */ } .zonebadge .cbi-tooltip > * { margin: 1px; z-index: var(--fs-z-raise); position: relative; } .zone-forwards { display: flex; flex-wrap: nowrap; } .zone-forwards > * { flex: 1 1 40%; padding: 1px; text-wrap: auto; } .zone-forwards > span { flex-basis: 10%; text-align: center; } .zone-forwards .zone-src, .zone-forwards .zone-dest { display: flex; flex-direction: column; } /* pressed-state shadow (.btn.active/:active): theme/55-buttons.css — absorbed */ .btn.disabled, .btn[disabled] { cursor: default; opacity: var(--fs-disabled-opacity); } /* `.btn.large` / `.btn.small`: theme/55-buttons.css, in full — absorbed. */ /* close cross — colour, shadow, opacities: theme/70-modal.css — absorbed. Left: * geometry. */ /* `line-height: 1` centres the glyph in its own box; it was 13.5px under a 20px face, and a * hand-nudged length only lands for one font size */ /* Physical, and mirrored by hand below — the same shape as `::-webkit-resizer` * (theme/60-inputs.css) and the two chevrons (theme/20-shell.css). `float` takes no logical * keyword this theme can rely on: `inline-end` is newer than * the `oklch(from …)` and `:has()` this sheet already requires only in Chromium, and a browser * that does not know the keyword drops the declaration and leaves the cross floating * nowhere. Measured in a live document at 1400px: the cross sat 549px from the reading edge in * LTR and 41px in RTL, i.e. it jumped from the end of the heading to its start — in front of * the title, where a dismissal control is not. It appears in every modal and in every * `.alert-message`, so this is the RTL bug with the widest reach. */ .close { float: right; font-size: var(--fs-type-xl); font-weight: var(--fs-weight-bold); line-height: 1; } :root[dir="rtl"] .close { float: left; } .close:hover { text-decoration: none; } /* alert paint: theme/35-alerts.css — absorbed. Left: geometry and the white-space reset. */ .alert-message { position: relative; margin-bottom: var(--fs-space-2); white-space: unset; } .alert-message .close { margin-top: 1px; } /* colour, margin and the content reset: theme/35-alerts.css — absorbed with the heading ramp */ .alert-message button { margin: var(--fs-space-1) 0; } /* `.label` pill and variants: theme/35-alerts.css — absorbed, as is the indicator pill * (showIndicator() only ever emits into #indicators, which theme/20-shell.css paints). */ header [data-indicator] { white-space: nowrap; text-shadow: none; margin: var(--fs-space-1) 0 var(--fs-space-1) var(--fs-space-1); } }