From 7bcb83b1076f45a8f0a1ac58586c60d6460a66fe Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Thu, 15 Oct 2026 10:10:05 +0900 Subject: feat(ui): raised '+ Add view' sidebar button (mirror of the view wells) with gap-matched bottom spacing; dvh app-shell height for iOS toolbars --- src/app.css | 53 ++++++++++++++++++++++++ src/app/App.svelte | 2 +- src/features/layout/ui/TilePanels.svelte | 15 +++++-- src/features/workspaces/ui/WorkspacesHome.svelte | 2 +- 4 files changed, 67 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/app.css b/src/app.css index 3f3f8ae..d7e0967 100644 --- a/src/app.css +++ b/src/app.css @@ -179,6 +179,48 @@ } } +/* Raised button — the exact mirror of `.inset-well`, for a neutral surface + that pops OUT where the wells sink in (the sidebar's "+ Add view" under the + view wells). The well = page colour darkened 18%, dark shadow INSIDE under + the top edge (inset 0 1px 7px), light catch-line OUTSIDE below (0 1px 0). + Mirrored: page colour LIFTED toward the text colour, light highlight INSIDE + the top edge (inset 0 1px 0), the dark shadow OUTSIDE below (0 1px 7px), + plus a faint top-lit gradient. Pressed → it becomes the well (pushed in). */ +@layer components { + .raised-btn { + display: flex; + align-items: center; + justify-content: center; + border: 0; + border-radius: var(--radius-box); + cursor: pointer; + color: color-mix(in srgb, var(--color-primary) 75%, white); + background-color: color-mix(in srgb, var(--color-base-100) 90%, var(--color-base-content)); + background-image: linear-gradient(to bottom, rgb(255 255 255 / 0.06), rgb(0 0 0 / 0.1)); + box-shadow: + inset 0 1px 0 color-mix(in srgb, var(--color-base-content) 18%, transparent), + 0 1px 7px 0 rgb(0 0 0 / 0.6); + transition: + filter 120ms ease-out, + box-shadow 120ms ease-out; + } + .raised-btn:hover { + filter: brightness(1.12); + } + .raised-btn:active { + filter: none; + background-image: none; + background-color: color-mix(in srgb, var(--color-base-100) 82%, black); + box-shadow: + 0 1px 0 color-mix(in srgb, var(--color-base-content) 10%, transparent), + inset 0 1px 7px 0 rgb(0 0 0 / 0.6); + } + .raised-btn:focus-visible { + outline: 2px solid var(--color-primary); + outline-offset: 2px; + } +} + /* Raised — the INVERSE of `.inset-well`, for things that pop OUT of the page (the home page's workspace tiles). Where the well has a dark shadow INSIDE under its top edge and a light catch-line OUTSIDE below it, a raised surface @@ -317,6 +359,17 @@ body { overflow: hidden; } +/* App-shell height. NOT `h-screen` (100vh): on iOS/iPadOS WebKit (Safari, + Vivaldi, …) 100vh is the viewport with the browser toolbars RETRACTED, so + while they're showing the bottom of the app sits underneath them (the + sidebar's last item / the composer looked flush against the bottom edge). + 100dvh tracks the visible viewport as the toolbars show/hide; 100vh stays as + the fallback for engines without dvh (the cascade drops the unknown unit). */ +.h-app { + height: 100vh; + height: 100dvh; +} + /* Transcript rows: skip layout + paint for rows scrolled out of view. A long turn has hundreds of rows; without this every one is laid out on first paint (and on every resize). `contain-intrinsic-size: auto ` makes the diff --git a/src/app/App.svelte b/src/app/App.svelte index 034f3e7..d557149 100644 --- a/src/app/App.svelte +++ b/src/app/App.svelte @@ -88,7 +88,7 @@ } -
+
{#each node.panels as panel, idx (idx)} @@ -78,13 +82,18 @@ {/each} {#if addView !== null} + {/if}
diff --git a/src/features/workspaces/ui/WorkspacesHome.svelte b/src/features/workspaces/ui/WorkspacesHome.svelte index b330e1d..630c67f 100644 --- a/src/features/workspaces/ui/WorkspacesHome.svelte +++ b/src/features/workspaces/ui/WorkspacesHome.svelte @@ -249,7 +249,7 @@ -
+