diff --git a/e2e/reflow.spec.js b/e2e/reflow.spec.js
index 738f26f7..be08028b 100644
--- a/e2e/reflow.spec.js
+++ b/e2e/reflow.spec.js
@@ -63,6 +63,56 @@ test.describe('on a touch screen', () => {
expect(wide, 'the page does not scroll sideways').toBeLessThanOrEqual(320);
});
}
+
+ for (const language of ['fr', 'fa']) {
+ test(`the icon colour picker fits at 320px in ${language}`, async ({ page, request }) => {
+ await seedConfig(request, { items: [app('one', 'One')], settings: { language } });
+ await dismissSetupPrompt(request);
+ await page.setViewportSize({ width: 320, height: 700 });
+ await page.goto('/admin/#dashboard');
+ await page.locator('#al [data-act="edit"]').first().click();
+ await page.locator('#icon-color-slot .cc-swatch[data-v="custom"]').click();
+ const picker = page.locator('#icon-color-slot');
+ await picker.locator('.cc-hues').waitFor({ state: 'visible' });
+ await animationsDone(page);
+ const misfits = await picker.evaluate(slot => {
+ const out = [];
+ for (const row of slot.querySelectorAll('.row')) {
+ const r = row.getBoundingClientRect();
+ for (const n of row.querySelectorAll('.cc-swatch, .rl, .hsb-ico, .hsb-range')) {
+ const b = n.getBoundingClientRect();
+ if (!b.width) continue;
+ if (b.left < r.left - 0.5 || b.right > r.right + 0.5) out.push(`${n.className} leaves its row`);
+ if (n.classList.contains('rl') && n.scrollWidth > n.clientWidth)
+ out.push(`label "${n.textContent}" is cut off`);
+ }
+ const sw = [...row.querySelectorAll('.cc-swatch')].map(n => n.getBoundingClientRect());
+ for (let i = 1; i < sw.length; i++)
+ if (Math.abs(sw[i].top - sw[i - 1].top) < 1 && Math.abs(sw[i].left - sw[i - 1].left) < sw[i].width)
+ out.push('two swatches overlap');
+ }
+ return out;
+ });
+ expect(misfits).toEqual([]);
+ });
+ }
+});
+
+test('the colour sliders share one length', async ({ page, request }) => {
+ await seedConfig(request, { items: [app('one', 'One')] });
+ await dismissSetupPrompt(request);
+ await page.setViewportSize({ width: 1280, height: 900 });
+ await openDashboardList(page);
+ await page.locator('#al [data-act="edit"]').first().click();
+ await page.locator('#icon-color-slot .cc-swatch[data-v="custom"]').click();
+ const sliders = page.locator('#icon-color-slot .hsb-range');
+ await expect(sliders).toHaveCount(3);
+ await animationsDone(page);
+ const boxes = await Promise.all((await sliders.all()).map(box));
+ for (const b of boxes.slice(1)) {
+ expect(b.x, 'every slider starts where the first does').toBeCloseTo(boxes[0].x, 0);
+ expect(b.width, 'every slider is as long as the first').toBeCloseTo(boxes[0].width, 0);
+ }
});
test('the desktop Settings sidebar stays on screen while the list scrolls', async ({ page, request }) => {
diff --git a/ui/admin/index.html b/ui/admin/index.html
index 998dbaa3..28a56421 100644
--- a/ui/admin/index.html
+++ b/ui/admin/index.html
@@ -11,7 +11,7 @@
-
+
diff --git a/ui/css/admin.css b/ui/css/admin.css
index d195fea5..08b2ac4d 100644
--- a/ui/css/admin.css
+++ b/ui/css/admin.css
@@ -363,10 +363,12 @@ button.rnm{font-family:inherit;color:inherit;background:none;border:0;padding:0;
.cc-swatch.on{outline-color:Highlight}
}
.cc-rainbow{background:conic-gradient(from 90deg,#ff3b30,#ffcd00,#35c759,#0289ff,#cb30df,#ff3b30)}
-.hsb-row{min-height:46px}
-.hsb-track{display:flex;align-items:center;gap:10px;margin-inline-start:auto;flex:2;max-width:none}
+.cc-tune > .reveal-in{display:grid;grid-template-columns:max-content minmax(0,1fr);column-gap:10px}
+.cc-tune > .reveal-in > *{grid-column:1/-1}
+.hsb-row{min-height:46px;display:grid;grid-template-columns:subgrid;align-items:center}
+.hsb-track{display:flex;align-items:center;gap:10px}
.hsb-ico{width:17px;height:17px;color:var(--dm);flex-shrink:0;display:flex}
-.hsb-range{flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;cursor:pointer;outline:none}
+.hsb-range{flex:1;min-width:0;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;cursor:pointer;outline:none}
.hsb-hue{background:linear-gradient(var(--slider-dir),#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}
/* ── Segmented control (Container/Ping, Disk Health/System Summary) ──
@@ -734,6 +736,7 @@ a:focus-visible,button:focus-visible,[role="button"]:focus-visible{outline:2px s
.adm-range { height:44px; padding-block:19px; background-clip:content-box; border-radius:3px / 22px; }
.hsb-range { height:44px; padding-block:19px; background-clip:content-box; border-radius:3px / 22px; }
.cc-swatch { width:34px; height:34px; }
+ .cc-sw { grid-template-columns:repeat(auto-fit,34px); }
.cc-kw-clear { background-size:10px 10px; }
.cc-hues .cc-sw { grid-template-columns:repeat(7,34px); }
.cc-hues .cc-swatch { width:34px; height:34px; }
@@ -753,7 +756,9 @@ html.is-mobile .sb{display:none}
html.is-mobile .cp{width:100%}
html.is-mobile .sec{padding-block:16px calc(132px + env(safe-area-inset-bottom));padding-inline:max(16px,env(safe-area-inset-left)) max(16px,env(safe-area-inset-right))}
html.is-mobile .sec-title{font-size:var(--fs-large-title);line-height:var(--lh-large-title);letter-spacing:var(--tr-large-title)}
-html.is-mobile .hsb-track{max-width:min(240px,62%)}
+html.is-mobile .cc-row{flex-wrap:wrap;row-gap:10px}
+html.is-mobile .cc-row .rl{flex:0 0 100%}
+html.is-mobile .cc-sw{flex:1 1 100%;grid-template-columns:repeat(7,auto);column-gap:0;justify-content:space-between}
html.is-mobile .sec-hdr{padding:10px 0 10px;flex-wrap:wrap;row-gap:6px}
html.is-mobile .sec-title{order:1;flex-basis:100%;min-width:0;overflow-wrap:break-word}
html.is-mobile .sec-hdr-actions{margin-inline-start:auto}