refactor(locale-switcher): single flag-sized dropdown, drop 4-inline-flag UI
The nav previously showed 4 inline flag buttons (DE/EN/UK/RU) on desktop and a details-based dropdown on mobile. Martin asked for one dropdown with a trigger the size of a single flag, and the 4 inline flags to go away. - LocaleSwitcher: render a single <details class='locale-switcher'> everywhere; trigger is one flag + tiny caret; menu lists all 4 with labels. - Drop the 4-inline <ul> and the locale-switcher-mobile duplicate. - CSS: replace both blocks with one compact dropdown (flag-sized trigger, 44px touch target via padding, scrolled/transparent-nav variants). - Tests: assert 4 menu options, 5 flag SVGs, single <details> dropdown, active locale is a <span aria-current>, others are <a> with hreflang. - 141/141 PHPUnit green.
This commit is contained in:
@@ -100,7 +100,6 @@ nav {
|
||||
padding: 0.95rem 3rem;
|
||||
background: var(--nav-bg);
|
||||
backdrop-filter: saturate(180%) blur(14px);
|
||||
backdrop-filter: saturate(180%) blur(14px);
|
||||
border-bottom: 1px solid var(--nav-border);
|
||||
transition:
|
||||
padding 0.3s ease,
|
||||
@@ -962,8 +961,6 @@ nav.scrolled {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: var(--accent);
|
||||
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 110-5 2.5 2.5 0 010 5z'/></svg>")
|
||||
center/contain no-repeat;
|
||||
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 110-5 2.5 2.5 0 010 5z'/></svg>")
|
||||
center/contain no-repeat;
|
||||
margin-bottom: 0.5rem;
|
||||
@@ -1131,8 +1128,6 @@ nav.scrolled {
|
||||
}
|
||||
|
||||
.form-field select {
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%237a7062' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
|
||||
background-repeat: no-repeat;
|
||||
@@ -1367,19 +1362,6 @@ footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Locale switcher: replace 4-flag list with single-trigger dropdown */
|
||||
.locale-switcher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile[open] > .locale-switcher-mobile__menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Mobile slide-down nav */
|
||||
nav.mobile-open .nav-links {
|
||||
display: flex;
|
||||
@@ -1494,79 +1476,94 @@ footer {
|
||||
}
|
||||
}
|
||||
|
||||
/* LOCALE SWITCHER (sub-Issue D) — desktop only */
|
||||
@media (width > 900px) {
|
||||
.locale-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/* LOCALE SWITCHER — single <details> dropdown, flag-sized trigger */
|
||||
.locale-switcher {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.locale-switcher__item {
|
||||
display: flex;
|
||||
.locale-switcher__trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
padding: 14px 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
color: var(--dark);
|
||||
transition:
|
||||
background 0.2s,
|
||||
transform 0.15s;
|
||||
}
|
||||
|
||||
.locale-switcher__trigger::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.locale-switcher__trigger:hover,
|
||||
.locale-switcher__trigger:focus-visible {
|
||||
background: rgb(0 0 0 / 6%);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.locale-switcher__current {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.locale-switcher__caret {
|
||||
font-size: 0.65rem;
|
||||
line-height: 1;
|
||||
color: inherit;
|
||||
transition: transform 0.2s ease;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.locale-switcher[open] .locale-switcher__caret {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.locale-switcher__menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
right: 0;
|
||||
min-width: 180px;
|
||||
margin: 0;
|
||||
padding: 0.4rem;
|
||||
list-style: none;
|
||||
background: var(--white);
|
||||
border: 1px solid var(--warm);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 24px rgb(0 0 0 / 14%);
|
||||
z-index: 60;
|
||||
}
|
||||
|
||||
.locale-switcher__option {
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
padding: 0.45rem 0.55rem;
|
||||
border: 1px solid transparent;
|
||||
gap: 0.6rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--text-muted-on-dark);
|
||||
background: transparent;
|
||||
transition:
|
||||
background 0.2s,
|
||||
border-color 0.2s,
|
||||
color 0.2s,
|
||||
transform 0.15s;
|
||||
cursor: pointer;
|
||||
color: var(--dark);
|
||||
font-size: 0.85rem;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.locale-switcher__option.is-current {
|
||||
background: var(--cream);
|
||||
color: var(--accent-strong);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.locale-switcher__option:hover,
|
||||
.locale-switcher__option:focus-visible {
|
||||
background: rgb(255 255 255 / 14%);
|
||||
border-color: rgb(255 255 255 / 30%);
|
||||
color: var(--white);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.locale-switcher__option.is-current {
|
||||
background: rgb(255 255 255 / 20%);
|
||||
border-color: var(--accent-light);
|
||||
color: var(--white);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.locale-switcher__option.is-current:hover {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
nav.scrolled .locale-switcher__option {
|
||||
color: var(--stone);
|
||||
}
|
||||
|
||||
nav.scrolled .locale-switcher__option:hover,
|
||||
nav.scrolled .locale-switcher__option:focus-visible {
|
||||
background: var(--warm);
|
||||
border-color: var(--stone);
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
nav.scrolled .locale-switcher__option.is-current {
|
||||
background: var(--cream);
|
||||
border-color: var(--accent);
|
||||
color: var(--dark);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.locale-switcher__option .flag {
|
||||
@@ -1582,26 +1579,18 @@ nav.scrolled .locale-switcher__option.is-current {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Hide labels on small screens, keep the 44px flag target */
|
||||
@media (width <= 720px) {
|
||||
.locale-switcher__label {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.locale-switcher__option {
|
||||
min-width: 44px;
|
||||
padding: 0.55rem;
|
||||
}
|
||||
/* Trigger on transparent nav (top-of-page): white caret on dark bg */
|
||||
nav:not(.scrolled) .locale-switcher__trigger {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
nav:not(.scrolled) .locale-switcher__trigger:hover,
|
||||
nav:not(.scrolled) .locale-switcher__trigger:focus-visible {
|
||||
background: rgb(255 255 255 / 12%);
|
||||
}
|
||||
|
||||
/* Flag stays the same regardless of nav state — SVG defines its own colours */
|
||||
|
||||
/* VISUALLY HIDDEN (a11y) */
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
@@ -1615,110 +1604,6 @@ nav.scrolled .locale-switcher__option.is-current {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* MOBILE LOCALE SWITCHER (dropdown — defaults to hidden on desktop) */
|
||||
@media (width > 900px) {
|
||||
.locale-switcher-mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.locale-switcher-mobile {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.55rem 0.7rem;
|
||||
border: 1px solid rgb(0 0 0 / 12%);
|
||||
border-radius: 6px;
|
||||
background: rgb(255 255 255 / 95%);
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
min-height: 44px;
|
||||
color: var(--dark);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__trigger::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__current {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__current-code {
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__caret {
|
||||
font-size: 0.7rem;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile[open] .locale-switcher-mobile__caret {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
right: 0;
|
||||
min-width: 180px;
|
||||
margin: 0;
|
||||
padding: 0.4rem;
|
||||
list-style: none;
|
||||
background: var(--white);
|
||||
border: 1px solid var(--warm);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
|
||||
z-index: 60;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
color: var(--dark);
|
||||
font-size: 0.85rem;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__option.is-current {
|
||||
background: var(--cream);
|
||||
color: var(--accent-strong);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.locale-switcher-mobile__option:hover,
|
||||
.locale-switcher-mobile__option:focus-visible {
|
||||
background: var(--warm);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
nav.scrolled .locale-switcher-mobile__trigger {
|
||||
background: var(--white);
|
||||
color: var(--dark);
|
||||
border-color: var(--warm);
|
||||
}
|
||||
|
||||
nav:not(.scrolled) .locale-switcher-mobile__trigger {
|
||||
background: rgb(255 255 255 / 12%);
|
||||
color: var(--white);
|
||||
border-color: rgb(255 255 255 / 30%);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
/* FORM FIELD ERRORS (sub-Issue E) */
|
||||
.form-field-error {
|
||||
margin: 0.375rem 0 0;
|
||||
|
||||
Reference in New Issue
Block a user