feat(ui): Youreka favicon, logout confirmation, nav active states, brand alignment

- favicon is the Youreka logo (64px PNG generated from the source mark),
  on the tools pages and server error pages
- signing out asks first: a Carbon cds-modal (Cancel / danger Sign out)
  shared by the header and the mobile side nav; Cancel closes, Sign out
  confirms and logs out
- the current tool is now visibly selected: Carbon marks active nav via
  a[aria-current=page] INSIDE the shadow, but aria-current sits on the
  host, so the rule never matched — the header item now gets a blue
  underline and the side-nav link a blue left border (via ::part(link)
  for colour, plus the host for the marker)
- logo and wordmark are middle-aligned inside a flex brand wrapper
- tests: favicon/modal/signout-trigger markup and the active-tool marking
  on both navs (45 total)
This commit is contained in:
2026-10-01 04:08:09 +01:00
parent 17c407883d
commit 2e4a51d018
7 changed files with 83 additions and 8 deletions
+22 -1
View File
@@ -312,6 +312,22 @@ test('injected session values cannot break out of the script tag', async () => {
}
});
test('the active tool is marked on both navigation surfaces', async () => {
const { base, stop } = await bootApp();
try {
const cookies = await login(base);
const cropper = await (await fetch(`${base}/cropper`, { headers: { cookie: cookies } })).text();
assert.match(cropper, /cds-header-nav-item href="\/cropper" aria-current="page"/);
assert.match(cropper, /cds-side-nav-link href="\/cropper" aria-current="page"/);
assert.ok(
!/cds-header-nav-item href="\/fingerprint" aria-current/.test(cropper),
'the other tool is not marked current'
);
} finally {
await stop();
}
});
test('all pages render on the g100 dark theme', async () => {
const { base, stop } = await bootApp();
try {
@@ -342,11 +358,16 @@ test('landing header is server-rendered for the session', async () => {
assert.match(anon, /cds-side-nav-link href="\/auth\/logout"/);
assert.match(anon, /youreka-logo\.png/);
assert.match(anon, /header-menu-button/);
// favicon is the Youreka logo; sign-out is confirmed via a Carbon modal
assert.match(anon, /rel="icon"[^>]*youreka-favicon\.png/);
assert.match(anon, /data-signout/);
assert.match(anon, /cds-modal id="signout-modal"/);
assert.match(anon, /id="signout-confirm"/);
const cookies = await login(base);
const authed = await (await fetch(`${base}/`, { headers: { cookie: cookies } })).text();
assert.match(authed, /Ada/);
assert.match(authed, /href="\/auth\/logout">Sign out</);
assert.match(authed, /href="\/auth\/logout"[^>]*>Sign out</);
} finally {
await stop();
}