From 901d4e86fcce56fffa8aee55cd71f4c649832ffc Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Mon, 2 Nov 2026 13:32:12 +0100 Subject: [PATCH 1/4] fix(manager): align action bar button text and drop the save button's bottom band - The save button and its stay toggle carried an inset 2px darker band along the bottom edge; the button is now one flat colour like the others. - The forms.css padding left the text of the fixed-height action buttons 1px below the middle; it moves 1px up. The stay toggle keeps its padding, so its chevron stays where it was. Co-Authored-By: Claude Opus 5.5 --- .../Unit/Manager/ActionButtonsStyleTest.php | 20 +++++++++++++++++++ manager/media/style/default/css/custom.css | 6 +++--- manager/media/style/default/css/forms.css | 1 - 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 core/tests/Unit/Manager/ActionButtonsStyleTest.php diff --git a/core/tests/Unit/Manager/ActionButtonsStyleTest.php b/core/tests/Unit/Manager/ActionButtonsStyleTest.php new file mode 100644 index 0000000000..bd1852ba14 --- /dev/null +++ b/core/tests/Unit/Manager/ActionButtonsStyleTest.php @@ -0,0 +1,20 @@ +not->toMatch('/#actions[^{]*\.btn-success[^{]*\{[^}]*box-shadow/'); +}); + +test('action button text sits 1px higher than the forms.css padding puts it', function () { + $css = actionButtonsCss(); + + expect($css)->toContain('#actions .btn-group .btn { padding-top: calc(.46153846em - 1px) }') + // the chevron toggle keeps the full padding, so it does not move with the text + ->and($css)->toMatch('/#actions \.btn-group \.plus \{[^}]*padding: \.46153846em 0;/'); +}); diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index cacbbada49..277540fdc7 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -47,10 +47,10 @@ select[name=context] + input[type=submit] { float: none; margin: 0; } #actions .btn-group > .btn-group { display: block } #actions .btn-group .btn, #actions .btn-group .form-control { font-size: .6772rem; height: 2.4em; line-height: 1.4 } +/* the forms.css padding sets the text 1px below the middle of these fixed-height buttons */ +#actions .btn-group .btn { padding-top: calc(.46153846em - 1px) } #actions .btn-group .btn .fa, #_actions .btn-group .btn .fa { display: none; width: 1em; font-size: 1em; text-align: center } #actions .btn-group .btn-group #Button1 { min-width: 100%; text-align: left; float: right; } -#actions .btn-group .btn-success { box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .07); } -#actions .btn-group .btn-success:hover { box-shadow: none } /* the in-place save: the join box between "Save" and the stay option shows +, a spinner, then a check mark, at one width */ #actions .btn-group #Button1 .save-join { display: inline-block; position: relative; width: 1.4em; margin: 0 .25em; text-align: center } #actions .btn-group #Button1.saving { pointer-events: none; opacity: .75 } @@ -58,7 +58,7 @@ select[name=context] + input[type=submit] { float: none; margin: 0; } #actions .btn-group #Button1.saving .save-join::before { content: ''; position: absolute; left: 50%; top: 50%; width: .8em; height: .8em; margin: -.45em 0 0 -.45em; border: 2px solid rgba(255, 255, 255, .45); border-top-color: #fff; border-radius: 50%; animation: evo-save-spin .7s linear infinite } #actions .btn-group #Button1.saved .save-join::before { content: '\2713'; position: absolute; left: 0; right: 0; top: 0; color: #fff } @keyframes evo-save-spin { to { transform: rotate(360deg) } } -#actions .btn-group .plus { z-index: 2; float: right; margin: -2.4em 0 0 0; width: 2rem; padding-left: 0; padding-right: 0; text-align: center; cursor: pointer; } +#actions .btn-group .plus { z-index: 2; float: right; margin: -2.4em 0 0 0; width: 2rem; padding: .46153846em 0; text-align: center; cursor: pointer; } #actions .btn-group .plus::before { content: "\f107"; font-weight: 900; font-family: 'Font Awesome 5 Free' } #actions .btn-group .show .plus::before { content: "\f106"; } #actions .btn-group select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; margin: -100% 0 -2rem 0; font-size: 0.675rem; opacity: 0; visibility: hidden; } diff --git a/manager/media/style/default/css/forms.css b/manager/media/style/default/css/forms.css index a1b5cbde82..ea8e6b2fa2 100644 --- a/manager/media/style/default/css/forms.css +++ b/manager/media/style/default/css/forms.css @@ -78,7 +78,6 @@ select:not([size]):not([multiple]) { text-indent: -2px } .darkness .btn-default { color: #bbb; background-color: #202329; border-color: #202329 } .darkness .btn-default:hover { color: #fff; background-color: #1a1c21; border-color: #1a1c21 } .darkness #actions { right: 0; background-color: #212328 } -.darkness #actions .btn-group .btn-success { box-shadow: none } .darkness #actions .dropdown-menu .btn { background-color: #343942; border-radius: 0; color: #fff; } .darkness #actions .dropdown-menu .btn:hover { background-color: #3c424e; color: #fff } .darkness optgroup { background-color: #202329 } From 0317d2976a99572e69487e08b15ce4f30425c675 Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Mon, 2 Nov 2026 13:41:33 +0100 Subject: [PATCH 2/4] fix(manager): centre the Clear cache icon beside its menu item Menu icons are inline SVGs, but the rule that drops their label gap in the icon-only button of an item group still matched only icon-font elements, so the recycle icon sat 2.75px left of centre in a wider block, and 0.75px low. Co-Authored-By: Claude Opus 5.5 --- core/tests/Unit/Manager/MenuItemGroupStyleTest.php | 9 +++++++++ manager/media/style/default/css/mainmenu.css | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 core/tests/Unit/Manager/MenuItemGroupStyleTest.php diff --git a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php new file mode 100644 index 0000000000..bdb5d1c6e0 --- /dev/null +++ b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php @@ -0,0 +1,9 @@ +toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) svg \{\s*margin-right: 0;/') + ->and($css)->toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) \{\s*vertical-align: middle;/'); +}); diff --git a/manager/media/style/default/css/mainmenu.css b/manager/media/style/default/css/mainmenu.css index 57b3670db7..6517276ce7 100755 --- a/manager/media/style/default/css/mainmenu.css +++ b/manager/media/style/default/css/mainmenu.css @@ -434,7 +434,12 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } #mainMenu .nav li.item-group > *:first-child { width: 100%; } -#mainMenu .nav li.item-group > *:not(:first-child) .fa { +/* an icon-only button beside the item: centred, without the gap menu icons keep before their label */ +#mainMenu .nav li.item-group > *:not(:first-child) { + vertical-align: middle; +} +#mainMenu .nav li.item-group > *:not(:first-child) .fa, +#mainMenu .nav li.item-group > *:not(:first-child) svg { margin-right: 0; } /* statusbar */ From 3a49f3c214eb468904702ffa6423d39f2155644e Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Mon, 2 Nov 2026 14:13:12 +0100 Subject: [PATCH 3/4] fix(manager): let the last top menu item take the dropdown's rounded corners The dropdowns kept 0.25rem of bottom padding to show their rounded corners, so a hovered last item stopped short of the edge above a thin white strip. Without it the last item reaches the edge, the list clips it to the corners, and every item keeps the same height. Co-Authored-By: Claude Opus 5.5 --- core/tests/Unit/Manager/MenuItemGroupStyleTest.php | 10 ++++++++++ manager/media/style/default/css/mainmenu.css | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php index bdb5d1c6e0..6a68c7582b 100644 --- a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php +++ b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php @@ -7,3 +7,13 @@ expect($css)->toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) svg \{\s*margin-right: 0;/') ->and($css)->toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) \{\s*vertical-align: middle;/'); }); + +test('top menu dropdowns end at their last item, which takes the rounded corners', function () { + $css = file_get_contents(dirname(__DIR__, 4) . '/manager/media/style/default/css/mainmenu.css'); + preg_match('/#mainMenu \.nav > li > ul \{([^}]*)\}/', $css, $rule); + + // bottom padding under the last item showed as a white strip below its hover background + expect($rule[1] ?? '')->toMatch('/\bpadding: 0;/') + ->and($rule[1] ?? '')->toContain('border-radius: 0 0 0.25rem 0.25rem;') + ->and($rule[1] ?? '')->toContain('overflow: auto;'); +}); diff --git a/manager/media/style/default/css/mainmenu.css b/manager/media/style/default/css/mainmenu.css index 6517276ce7..f355e70aae 100755 --- a/manager/media/style/default/css/mainmenu.css +++ b/manager/media/style/default/css/mainmenu.css @@ -266,7 +266,8 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } top: 100%; left: 0; margin: 0; - padding: 0 0 0.25rem; + /* no bottom padding: the last item reaches the rounded edge (overflow clips it), so its hover leaves no strip */ + padding: 0; min-width: 15rem; max-height: -webkit-calc(100vh - var(--manager-menu-height, 2.2rem)); max-height: calc(100vh - var(--manager-menu-height, 2.2rem)); From 7e7cd610bb4857b3eff487e4392e0b7f6eb8e89c Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Mon, 2 Nov 2026 14:24:16 +0100 Subject: [PATCH 4/4] fix(manager): make the last top menu item as tall as the others Items are 41px, a 40px link above a 1px separator, but the last one has no separator and was 40px. Its link takes one more pixel, which shows the menu background at rest and the hover colour when hovered. Co-Authored-By: Claude Opus 5.5 --- core/tests/Unit/Manager/MenuItemGroupStyleTest.php | 7 +++++++ manager/media/style/default/css/mainmenu.css | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php index 6a68c7582b..193d3aba81 100644 --- a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php +++ b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php @@ -17,3 +17,10 @@ ->and($rule[1] ?? '')->toContain('border-radius: 0 0 0.25rem 0.25rem;') ->and($rule[1] ?? '')->toContain('overflow: auto;'); }); + +test('the last top menu item is as tall as the others, which carry a 1px separator', function () { + $css = file_get_contents(dirname(__DIR__, 4) . '/manager/media/style/default/css/mainmenu.css'); + + expect($css)->toMatch('/#mainMenu \.nav > li > ul > li \{\s*border-bottom: 1px solid[^}]*margin-bottom: -1px;/') + ->and($css)->toMatch('/#mainMenu \.nav > li > ul > li:last-child > a:first-child,\s*#mainMenu \.nav > li > ul > li:last-child > span:first-child \{\s*padding-bottom: 1px;/'); +}); diff --git a/manager/media/style/default/css/mainmenu.css b/manager/media/style/default/css/mainmenu.css index f355e70aae..fc3f28bfaa 100755 --- a/manager/media/style/default/css/mainmenu.css +++ b/manager/media/style/default/css/mainmenu.css @@ -304,6 +304,11 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } border: none; margin-bottom: 0; } +/* no separator below the last item: one more pixel keeps it as tall as the others, in its own hover colour */ +#mainMenu .nav > li > ul > li:last-child > a:first-child, +#mainMenu .nav > li > ul > li:last-child > span:first-child { + padding-bottom: 1px; +} #mainMenu .nav > li > ul > li.item-input { padding: 0.375em 0.5em; }