diff --git a/app/static/css/layout.css b/app/static/css/layout.css index 5fae678..83f03f5 100644 --- a/app/static/css/layout.css +++ b/app/static/css/layout.css @@ -173,27 +173,60 @@ body.drawer-open .drawer-backdrop { opacity: 1; } color: var(--bg); } -/* Collapse-when-idle behaviour: on hover-capable devices, hide the - * non-active option until the user hovers (or keyboard-focuses) the - * toggle. The mobile drawer overrides this further down. */ +/* Collapse-when-idle behaviour: on hover-capable devices each toggle + * shows only its active option. Hover or keyboard focus reveals the + * other option STACKED ABSOLUTELY BELOW so the toggle's in-flow size + * never changes — neighbouring controls don't shift when the user + * mouses over one of them. */ @media (hover: hover) { + .tone-toggle, + .theme-toggle, + .lang-toggle { + position: relative; + } + + /* Hide every option by default. The active option's higher-specificity + rule below puts it back into the static flow. */ .tone-toggle button, .theme-toggle button, .lang-toggle button { display: none; } + + /* Hover / focus: render every option as an absolutely-positioned + button immediately under the container. The active-button rule + immediately below wins on specificity and pins it back into the + static flow at the top — only the non-active option(s) actually + end up absolutely-positioned, so the popup grows downward only. */ + .tone-toggle:hover button, + .tone-toggle:focus-within button, + .theme-toggle:hover button, + .theme-toggle:focus-within button, + .lang-toggle:hover button, + .lang-toggle:focus-within button { + display: block; + position: absolute; + top: 100%; + left: 0; + right: 0; + margin-top: -1px; /* share the container's bottom border */ + background: var(--surface); + border: 1px solid var(--border); + z-index: 60; /* above the markets bar (z-50) */ + } + + /* Active option stays in static flow at the top of the container + even while hovered. Two-attribute specificity (.X[data=Y] btn[data=Y]) + beats the .X:hover button rule above. */ .tone-toggle[data-tone="NOVICE"] button[data-value="NOVICE"], .tone-toggle[data-tone="INTERMEDIATE"] button[data-value="INTERMEDIATE"], .theme-toggle[data-theme="light"] button[data-value="light"], .theme-toggle[data-theme="dark"] button[data-value="dark"], .lang-toggle[data-lang="en"] button[data-value="en"], .lang-toggle[data-lang="it"] button[data-value="it"] { - display: inline-block; + display: block; + position: static; + margin-top: 0; + border: 0; } - .tone-toggle:hover button, - .tone-toggle:focus-within button, - .theme-toggle:hover button, - .theme-toggle:focus-within button, - .lang-toggle:hover button, - .lang-toggle:focus-within button { display: inline-block; } } .app-main {