diff --git a/docs/screenshots/admin.png b/docs/screenshots/admin.png index 92cfe83..9bd1b27 100644 Binary files a/docs/screenshots/admin.png and b/docs/screenshots/admin.png differ diff --git a/docs/screenshots/board.png b/docs/screenshots/board.png index 4a5a982..c6935f6 100644 Binary files a/docs/screenshots/board.png and b/docs/screenshots/board.png differ diff --git a/docs/screenshots/calendar-light.png b/docs/screenshots/calendar-light.png index f14c171..c5de3f6 100644 Binary files a/docs/screenshots/calendar-light.png and b/docs/screenshots/calendar-light.png differ diff --git a/docs/screenshots/delegated.png b/docs/screenshots/delegated.png index fbbae69..6ac5e2f 100644 Binary files a/docs/screenshots/delegated.png and b/docs/screenshots/delegated.png differ diff --git a/docs/screenshots/detail.png b/docs/screenshots/detail.png index 3bd702b..03edf3f 100644 Binary files a/docs/screenshots/detail.png and b/docs/screenshots/detail.png differ diff --git a/docs/screenshots/history.png b/docs/screenshots/history.png index 23a5125..63c278b 100644 Binary files a/docs/screenshots/history.png and b/docs/screenshots/history.png differ diff --git a/docs/screenshots/notes-shared-light.png b/docs/screenshots/notes-shared-light.png index a2e5123..03dae4b 100644 Binary files a/docs/screenshots/notes-shared-light.png and b/docs/screenshots/notes-shared-light.png differ diff --git a/docs/screenshots/notes-source.png b/docs/screenshots/notes-source.png index 14e7794..418a99a 100644 Binary files a/docs/screenshots/notes-source.png and b/docs/screenshots/notes-source.png differ diff --git a/docs/screenshots/notes.png b/docs/screenshots/notes.png index c4f865f..e143ec7 100644 Binary files a/docs/screenshots/notes.png and b/docs/screenshots/notes.png differ diff --git a/docs/screenshots/sections.png b/docs/screenshots/sections.png index 368af55..a0510e1 100644 Binary files a/docs/screenshots/sections.png and b/docs/screenshots/sections.png differ diff --git a/docs/screenshots/settings.png b/docs/screenshots/settings.png index 4c7ec54..41a82b8 100644 Binary files a/docs/screenshots/settings.png and b/docs/screenshots/settings.png differ diff --git a/docs/screenshots/themes.png b/docs/screenshots/themes.png index a0f2438..cf4c9c7 100644 Binary files a/docs/screenshots/themes.png and b/docs/screenshots/themes.png differ diff --git a/docs/screenshots/today-light.png b/docs/screenshots/today-light.png index 1cf6717..7ed0ce1 100644 Binary files a/docs/screenshots/today-light.png and b/docs/screenshots/today-light.png differ diff --git a/docs/screenshots/today.png b/docs/screenshots/today.png index 13b7206..56bc8da 100644 Binary files a/docs/screenshots/today.png and b/docs/screenshots/today.png differ diff --git a/docs/screenshots/upcoming.png b/docs/screenshots/upcoming.png index c467f29..2231e06 100644 Binary files a/docs/screenshots/upcoming.png and b/docs/screenshots/upcoming.png differ diff --git a/docs/screenshots/week.png b/docs/screenshots/week.png index 79b4ac8..9a2cdfb 100644 Binary files a/docs/screenshots/week.png and b/docs/screenshots/week.png differ diff --git a/site/screenshots/admin.webp b/site/screenshots/admin.webp index 95fd13e..32376a2 100644 Binary files a/site/screenshots/admin.webp and b/site/screenshots/admin.webp differ diff --git a/site/screenshots/board.webp b/site/screenshots/board.webp index 744bc9c..b64ab6a 100644 Binary files a/site/screenshots/board.webp and b/site/screenshots/board.webp differ diff --git a/site/screenshots/calendar-light.webp b/site/screenshots/calendar-light.webp index f258d4c..066db7e 100644 Binary files a/site/screenshots/calendar-light.webp and b/site/screenshots/calendar-light.webp differ diff --git a/site/screenshots/delegated.webp b/site/screenshots/delegated.webp index 6c6ed62..5fe6a88 100644 Binary files a/site/screenshots/delegated.webp and b/site/screenshots/delegated.webp differ diff --git a/site/screenshots/detail.webp b/site/screenshots/detail.webp index fa60d9b..d6fc044 100644 Binary files a/site/screenshots/detail.webp and b/site/screenshots/detail.webp differ diff --git a/site/screenshots/history.webp b/site/screenshots/history.webp index 21eea9a..67d68b7 100644 Binary files a/site/screenshots/history.webp and b/site/screenshots/history.webp differ diff --git a/site/screenshots/notes-shared-light.webp b/site/screenshots/notes-shared-light.webp index 851f2c5..f10a4bb 100644 Binary files a/site/screenshots/notes-shared-light.webp and b/site/screenshots/notes-shared-light.webp differ diff --git a/site/screenshots/notes-source.webp b/site/screenshots/notes-source.webp index b9fa0e6..bc5b469 100644 Binary files a/site/screenshots/notes-source.webp and b/site/screenshots/notes-source.webp differ diff --git a/site/screenshots/notes.webp b/site/screenshots/notes.webp index 41bcd7c..26c5b47 100644 Binary files a/site/screenshots/notes.webp and b/site/screenshots/notes.webp differ diff --git a/site/screenshots/sections.webp b/site/screenshots/sections.webp index 44a0fd4..a2c33ed 100644 Binary files a/site/screenshots/sections.webp and b/site/screenshots/sections.webp differ diff --git a/site/screenshots/settings.webp b/site/screenshots/settings.webp index e2ece23..36f61fc 100644 Binary files a/site/screenshots/settings.webp and b/site/screenshots/settings.webp differ diff --git a/site/screenshots/themes.webp b/site/screenshots/themes.webp index 4c93f30..3e002f1 100644 Binary files a/site/screenshots/themes.webp and b/site/screenshots/themes.webp differ diff --git a/site/screenshots/today-light.webp b/site/screenshots/today-light.webp index 830f647..f0b5e55 100644 Binary files a/site/screenshots/today-light.webp and b/site/screenshots/today-light.webp differ diff --git a/site/screenshots/today.webp b/site/screenshots/today.webp index 91b992f..b105321 100644 Binary files a/site/screenshots/today.webp and b/site/screenshots/today.webp differ diff --git a/site/screenshots/upcoming.webp b/site/screenshots/upcoming.webp index d8c15a1..abf9898 100644 Binary files a/site/screenshots/upcoming.webp and b/site/screenshots/upcoming.webp differ diff --git a/site/screenshots/week.webp b/site/screenshots/week.webp index 8eb7b8c..3a6b11c 100644 Binary files a/site/screenshots/week.webp and b/site/screenshots/week.webp differ diff --git a/web/e2e/smoke.spec.js b/web/e2e/smoke.spec.js index c20539b..fe4a087 100644 --- a/web/e2e/smoke.spec.js +++ b/web/e2e/smoke.spec.js @@ -383,19 +383,19 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me await expect(heading).toBeVisible(); await expect(sidebar.getByText('Træk et projekt herop')).toBeVisible(); - // A group's name must be readable in full, and must start where a project's - // name starts. + // A group's name must be readable in full, and must line up with the other + // headings — not with the projects filed under it. // - // Both halves are here because both were once broken at the same time and for - // different reasons. "Omdøb" and "Slet" sat in the flow reserving their width - // even while invisible, so ARBEJDE was drawn as "ARBE"; and the fold chevron - // sat before the name, pushing a group 22px further in than the projects it - // contains — so a group read as if it were filed under them. Every assertion - // in this file passed through both, because both buttons still worked. + // The clipping half is here because it was once broken: "Omdøb" and "Slet" sat + // in the flow reserving their width even while invisible, so ARBEJDE was drawn + // as "ARBE". The alignment half changed meaning with the redesign: a group now + // carries a fold chevron and a section icon just like "Projekter" above it, and + // belongs to that heading tier rather than to the project rows below. const shape = await sidebar.locator('.folder-head').evaluate((el) => { const link = el.querySelector('h2 a'); - const name = { ...link.querySelector('.dot').getBoundingClientRect().toJSON() }; - // The last child of the link is the name itself; the dot is a span before it. + // The leading mark is now the section icon, the same folder/funnel/tag glyph + // the system headings carry — a group and a section read identically. + const name = { ...link.querySelector('.head-icon').getBoundingClientRect().toJSON() }; return { clipped: link.scrollWidth > link.clientWidth + 1, left: name.left, @@ -407,17 +407,17 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me expect(shape.clipped, 'gruppens navn bliver klippet').toBe(false); expect(shape.count, 'navnet og tallet overlapper').toBeGreaterThanOrEqual(shape.right); - // Measured dot to dot, not box to box: both rows begin with the same coloured - // mark, and it is the only thing in them that means the same on both sides. - // Comparing the group's inner link with the project's outer box reported the - // row's own padding as a misalignment. - const projectLeft = await sidebar - .getByRole('link', { name: 'Regnskab' }) - .evaluate((el) => el.querySelector('.dot').getBoundingClientRect().left); + // A group is a heading, not a project row: it belongs to the same tier as + // "Projekter" and the other system sections — chevron, icon, bold name — and + // starts where they start, not where the projects filed under it do. Measured + // icon to icon, the one mark both headings share. + const sectionLeft = await sidebar + .getByRole('heading', { name: 'Projekter' }) + .evaluate((el) => el.querySelector('.head-icon').getBoundingClientRect().left); expect( - Math.abs(shape.left - projectLeft), - `gruppen starter ${Math.round(shape.left - projectLeft)}px fra projekterne` - ).toBeLessThanOrEqual(2); + Math.abs(shape.left - sectionLeft), + `gruppen starter ${Math.round(shape.left - sectionLeft)}px fra sektionsoverskrifterne` + ).toBeLessThanOrEqual(4); // Dragged in, then dragged back out onto "Projekter" — which is the reason // that heading is a drop target at all: with every project filed away there @@ -440,18 +440,13 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me 'false' ); - // En foldet gruppe står med sin chevron fremme permanent, og den lå oven i - // prikken med et felt i --surface bag sig — en lys firkant ud for navnet på - // den sænkede bjælke, hele tiden. Nu tones prikken ud i stedet, så der er - // ingenting at male henover den med. - const chevron = await sidebar + // A group's chevron is in the flow now, the same one the system sections carry — + // no absolute mark with a --surface field behind it, so a folded group no longer + // leaves a pale square beside its name on the sunken bar. + const chevronBg = await sidebar .locator('.folder-head .chevron-button') - .evaluate((el) => ({ - background: getComputedStyle(el).backgroundColor, - dot: getComputedStyle(el.closest('.folder-head').querySelector('.group-dot')).opacity - })); - expect(chevron.background, 'chevronen har en firkant bag sig').toBe('rgba(0, 0, 0, 0)'); - expect(chevron.dot, 'prikken ligger stadig under chevronen').toBe('0'); + .evaluate((el) => getComputedStyle(el).backgroundColor); + expect(chevronBg, 'chevronen har en firkant bag sig').toBe('rgba(0, 0, 0, 0)'); await sidebar.getByRole('button', { name: /^Fold Arbejde/ }).click(); @@ -467,11 +462,7 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me // button on click. await expect(sidebar.getByLabel('Gruppens navn')).toBeVisible(); await sidebar.getByLabel('Gruppens navn').press('Enter'); - - const painted = await sidebar - .locator('.folder-head .group-dot') - .evaluate((el) => getComputedStyle(el).backgroundColor); - expect(painted, 'gruppens prik fik ikke sin farve').not.toBe('rgba(0, 0, 0, 0)'); + await expect(sidebar.getByRole('link', { name: 'Arbejde', exact: true })).toBeVisible(); // The heading itself is *not* indented — only what is filed under it. A heading // that starts further in than the rows above it says the heading is inside diff --git a/web/src/lib/components/Sidebar.svelte b/web/src/lib/components/Sidebar.svelte index 119373f..50be9a4 100644 --- a/web/src/lib/components/Sidebar.svelte +++ b/web/src/lib/components/Sidebar.svelte @@ -690,6 +690,64 @@ The whole heading is the target, not the chevron. At this size a lone chevron is something you miss, and the name is where the eye already is. --> + + {#snippet sectionIcon(key)} + {#if key === 'filters'} + + {:else if key === 'labels'} + + {:else if key === 'shared'} + + {:else} + + + {/if} + {/snippet} + {#snippet foldHeading(key, label)}

@@ -916,11 +975,7 @@ }, 200); }} > - + {@render sectionIcon('group')} {group.name} @@ -1087,14 +1142,16 @@ } .scroller::-webkit-scrollbar { - width: 10px; + width: 6px; } + /* No transparent border and no padding-box clip: those centred a 4px bar in a + 10px track, so the thumb floated three pixels shy of the divider. The bar is + the track now — a thin rounded thumb sitting flush against the line on the + right, which is where a scrollbar belongs. */ .scroller::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; - border: 3px solid transparent; - background-clip: padding-box; } .scroller::-webkit-scrollbar-track { @@ -1267,12 +1324,22 @@ background: var(--surface-sunken); } + /* Every heading — the system sections and the user's groups — reads the same: + a mark, then a bold plainly-cased name. What used to set them apart (one a + faint uppercase label, the other a bold name with a coloured dot) is gone. */ h2 { - font-size: var(--text-xs); - font-weight: 560; - text-transform: uppercase; - letter-spacing: 0.06em; - color: var(--ink-faint); + font-size: var(--menu-size); + font-weight: 600; + color: var(--ink); + } + + /* The heading's mark, in the muted ink so the bold name still leads. Sized and + nudged like a row's own mark, so the icons line up down the sidebar. */ + .head-icon { + width: 14px; + height: 14px; + flex: none; + color: var(--ink-muted); } /* Only the square icon buttons — "+" and the folder — and asked for by class @@ -1373,39 +1440,17 @@ klods ud for navnet permanent, fordi chevronen bliver stående, når gruppen er lukket. Prikken tones ud i stedet for at blive dækket — det er samme skifte, uden noget at male henover den med. */ + /* A group folds from its own chevron, the same one the system sections carry — + in the flow before the name now, not an absolute mark that appeared on hover, + so a group and a section read identically at rest. The name beside it is still + a link to the group's page; the chevron is the second intention. */ .chevron-button { - position: absolute; - left: calc(var(--s2) - 5px); - width: 18px; - height: 18px; + flex: none; + width: 14px; + height: 14px; display: grid; place-items: center; - border-radius: var(--radius-sm); color: inherit; - opacity: 0; - /* Fordi prikken herunder tones ud frem for at blive dækket. En `opacity` - under 1 laver en stakkontekst og maler elementet, som var det placeret - med `z-index: 0` — så prikken, der står senere i DOM'en, lagde sig oven - på knappen i det øjeblik den forsvandt. Den var usynlig og tog stadig - klikket: prøven brugte tredive sekunder på at folde en gruppe, der ikke - ville foldes. Ét lag op, og rækkefølgen er den samme som før. */ - z-index: 1; - } - - .folder-head:hover .chevron-button, - .chevron-button:focus-visible, - .chevron-button[aria-expanded='false'] { - opacity: 1; - } - - /* Præcis de tre tilfælde ovenfor, læst nedad i stedet for opad: står chevronen - der, er prikken væk. `opacity` og ikke `display`, for de to ligger oven i - hinanden — forsvandt prikken ud af flowet, ville navnet rykke sig hver gang - pilen kom frem. */ - .folder-head:hover .group-dot, - .folder-head:has(.chevron-button:focus-visible) .group-dot, - .folder-head:has(.chevron-button[aria-expanded='false']) .group-dot { - opacity: 0; } .chevron-button:hover { @@ -1485,14 +1530,6 @@ white-space: nowrap; } - /* The group's own mark, between the chevron and the name — inside the fold - button, so it cannot push the heading in. It is a mark now and not a - control: the colour is chosen while renaming, which is the other edit to - the same thing. */ - .group-dot { - flex: none; - } - /* Projects sit at the same left margin whether or not they are in an area — one straight edge down the whole sidebar reads calmer than a staircase, and the bold area heading above already does the grouping the indent used to. */ @@ -1508,18 +1545,6 @@ padding-left: var(--s2); } - /* An area is the sidebar's own heading — Things treats it as bold and plainly - cased, a thing the eye lands on, not another faint uppercase label like the - system sections. So an area's name is set apart while "Projekter", "Filtre" - and "Etiketter" stay quiet. */ - .folder-head h2 { - font-size: var(--menu-size); - font-weight: 600; - text-transform: none; - letter-spacing: 0; - color: var(--ink); - } - /* Inside the rename form now, so it needs no padding of its own — the form already sits where the heading did. */ .renaming {