Merge pull request #39 from SteelDynamite/ink-theme-eink-css-cleanup

ink-theme-eink-css-cleanup
This commit is contained in:
SteelDynamite 2026-04-14 14:31:23 +01:00 committed by GitHub
commit 105d46775c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 114 additions and 16 deletions

View file

@ -10,6 +10,7 @@
"core:window:allow-minimize",
"core:window:allow-toggle-maximize",
"core:window:allow-start-dragging",
"core:window:allow-is-maximized"
"core:window:allow-is-maximized",
"core:window:allow-set-decorations"
]
}

View file

@ -11,14 +11,18 @@
onMount(() => {
app.loadConfig();
});
$effect(() => {
document.documentElement.classList.toggle("decorations-none", app.windowDecorations === "none");
});
</script>
<div class={app.isDark ? "dark" : ""} data-theme={app.currentTheme ?? ""}>
<div class="h-screen w-screen" class:p-2={isLinux} class:onyx-border={app.currentTheme === "onyx"}>
<div class={app.isDark ? "dark" : ""} data-theme={app.currentTheme ?? ""} data-decorations={app.windowDecorations}>
<div class="h-screen w-screen" class:p-2={isLinux && app.windowDecorations === "custom"}>
<div
class="relative h-full w-full overflow-hidden bg-surface-light text-text-light dark:bg-surface-dark dark:text-text-dark"
class:rounded-xl={isLinux}
class:linux-window-border={isLinux}
class:rounded-xl={isLinux && app.windowDecorations === "custom"}
class:linux-window-border={isLinux && app.windowDecorations !== "system"}
style="container-type: inline-size"
>
{#if app.error}

View file

@ -195,10 +195,6 @@ body {
border-color: rgba(209, 191, 130, 0.15);
}
/* Thick gold window border */
[data-theme="onyx"] .onyx-border {
border: 3px solid #a6905a;
}
[data-theme="solarized"] {
--color-primary: #268bd2;
@ -216,6 +212,64 @@ body {
--color-danger: #dc322f;
}
/* ── Ink (e-ink screen) theme ────────────────────────────────────── */
[data-theme="ink"] {
--color-primary: #000000;
--color-primary-hover: #1a1a1a;
--color-surface-light: #ffffff;
--color-surface-dark: #ffffff;
--color-card-light: #f0f0f0;
--color-card-dark: #f0f0f0;
--color-text-light: #000000;
--color-text-dark: #000000;
--color-text-secondary-light: #444444;
--color-text-secondary-dark: #444444;
--color-border-light: #000000;
--color-border-dark: #000000;
--color-danger: #000000;
}
/* Suppress all shadows and decorative effects on ink screens */
[data-theme="ink"] * {
box-shadow: none !important;
text-shadow: none !important;
scrollbar-color: #444444 transparent;
}
[data-theme="ink"] ::-webkit-scrollbar-thumb {
background: #444444;
}
[data-theme="ink"] select option {
background-color: #ffffff;
color: #000000;
}
[data-theme="ink"] .linux-window-border {
border-color: rgba(0, 0, 0, 0.5);
}
/* ── Dropdown/kebab menu shadow ──────────────────────────────────── */
.menu-shadow {
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.12);
}
.dark .menu-shadow {
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.3);
}
/* ── Borderless mode: square corners on all popups/overlays ─────── */
.decorations-none .rounded-sm,
.decorations-none .rounded,
.decorations-none .rounded-md,
.decorations-none .rounded-lg,
.decorations-none .rounded-xl,
.decorations-none .rounded-2xl,
.decorations-none .rounded-3xl,
.decorations-none .dropdown-menu button {
border-radius: 0 !important;
}
/* ── Accessibility: Reduced motion ───────────────────────────────── */
@media (prefers-reduced-motion: reduce) {

View file

@ -62,7 +62,7 @@
<!-- Backdrop + sheet wrapper -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-50 flex flex-col justify-end transition-opacity duration-250 ease-out {newTaskState.open ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}"
class="absolute inset-0 z-50 flex flex-col justify-end overflow-hidden transition-opacity duration-250 ease-out {newTaskState.open ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}"
style="background: rgba(0,0,0,0.4)"
onclick={handleClose}
onkeydown={(e) => { if (e.key === "Escape") handleClose(); }}

View file

@ -160,7 +160,7 @@
</svg>
</button>
{#if showMenu}
<div class="absolute right-0 top-full z-40 mt-1 min-w-[200px] rounded-lg border border-border-light bg-surface-light py-1 shadow-lg dark:border-border-dark dark:bg-surface-dark">
<div class="dropdown-menu absolute right-0 top-full z-40 mt-1 min-w-[200px] rounded-lg border border-border-light bg-surface-light py-1 menu-shadow dark:border-border-dark dark:bg-surface-dark">
<button
onclick={handleToggle}
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-black/5 dark:hover:bg-white/10"
@ -278,7 +278,7 @@
</svg>
</button>
{#if showSubtaskMenu}
<div class="absolute right-0 top-full z-40 mt-1 min-w-[240px] rounded-lg border border-border-light bg-surface-light py-1 shadow-lg dark:border-border-dark dark:bg-surface-dark">
<div class="dropdown-menu absolute right-0 top-full z-40 mt-1 min-w-[240px] rounded-lg border border-border-light bg-surface-light py-1 menu-shadow dark:border-border-dark dark:bg-surface-dark">
<button
onclick={() => { showSubtaskMenu = false; confirmDeleteCompleted = true; }}
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm text-danger hover:bg-black/5 dark:hover:bg-white/10"

View file

@ -1,8 +1,11 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { platform } from "@tauri-apps/plugin-os";
import { app } from "../stores/app.svelte";
import ConfirmDialog from "../components/ConfirmDialog.svelte";
const isLinux = platform() === "linux";
let { onclose, workspaceId, ondelete }: { onclose?: () => void; workspaceId: string; ondelete?: (id: string) => void } = $props();
let ws = $derived(app.config?.workspaces[workspaceId]);
@ -91,9 +94,10 @@
<svelte:window onclick={handleWindowClick} />
<header
data-tauri-drag-region
class="flex items-center justify-between border-b border-border-light px-4 py-3 dark:border-border-dark"
>
<h1 class="text-lg font-bold">Workspace Settings</h1>
<h1 class="text-lg font-bold" data-tauri-drag-region>Workspace Settings</h1>
<button
onclick={() => onclose?.()}
class="rounded-lg p-1.5 hover:bg-black/5 dark:hover:bg-white/10"
@ -132,7 +136,7 @@
</svg>
</button>
{#if showKebab}
<div class="absolute right-0 top-full z-10 mt-1 w-40 rounded-xl border border-border-light bg-surface-light py-1 shadow-lg dark:border-border-dark dark:bg-surface-dark">
<div class="dropdown-menu absolute right-0 top-full z-10 mt-1 w-40 rounded-xl border border-border-light bg-surface-light py-1 menu-shadow dark:border-border-dark dark:bg-surface-dark">
<button
onclick={startRename}
class="flex w-full items-center gap-2 px-4 py-2 text-sm hover:bg-black/5 dark:hover:bg-white/10"
@ -260,9 +264,26 @@
<option value="dracula">Dracula</option>
<option value="solarized">Solarized Dark</option>
<option value="onyx">Black and Gold</option>
<option value="ink">Ink</option>
</select>
</section>
{#if isLinux}
<!-- Window decorations (Linux only) -->
<section class="mt-6">
<label class="mb-1 block text-xs font-medium opacity-60">Window decorations</label>
<select
value={app.windowDecorations}
onchange={(e) => app.setWindowDecorations((e.target as HTMLSelectElement).value as "custom" | "none" | "system")}
class="w-full appearance-none rounded-lg border border-border-light bg-surface-light px-3 py-2 text-sm text-text-light outline-none focus:border-primary dark:border-border-dark dark:bg-surface-dark dark:text-text-dark"
>
<option value="custom">Custom border</option>
<option value="none">Borderless</option>
<option value="system">System title bar</option>
</select>
</section>
{/if}
<p class="mt-8 text-center text-xs opacity-30">Tauri v2 + Svelte</p>
</main>

View file

@ -290,7 +290,7 @@
{#if showWorkspacePicker}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="absolute left-0 top-full z-40 mt-1 w-full rounded-lg border border-border-light bg-surface-light py-1 shadow-lg dark:border-border-dark dark:bg-surface-dark"
class="dropdown-menu absolute left-0 top-full z-40 mt-1 w-full rounded-lg border border-border-light bg-surface-light py-1 menu-shadow dark:border-border-dark dark:bg-surface-dark"
>
{#each workspaceIds as wsId}
{@const ws = app.config?.workspaces[wsId]}
@ -500,7 +500,7 @@
</svg>
</button>
{#if showListMenu}
<div class="absolute right-0 top-full z-40 mt-1 min-w-[200px] rounded-lg border border-border-light bg-surface-light py-1 shadow-lg dark:border-border-dark dark:bg-surface-dark">
<div class="dropdown-menu absolute right-0 top-full z-40 mt-1 min-w-[200px] rounded-lg border border-border-light bg-surface-light py-1 menu-shadow dark:border-border-dark dark:bg-surface-dark">
<button
onclick={startRenameList}
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-black/5 dark:hover:bg-white/10"

View file

@ -18,6 +18,13 @@ listen("fs-changed", () => {
// ── Reactive state ───────────────────────────────────────────────────
const LS_DECORATIONS_KEY = "windowDecorations";
let windowDecorations = $state<"custom" | "none" | "system">(
(localStorage.getItem(LS_DECORATIONS_KEY) as "custom" | "none" | "system") ?? "custom"
);
if (windowDecorations === "system") getCurrentWindow().setDecorations(true);
if (windowDecorations === "none") document.documentElement.classList.add("decorations-none");
let screen = $state<Screen>("setup");
let config = $state<AppConfig | null>(null);
let lists = $state<TaskList[]>([]);
@ -429,6 +436,13 @@ async function setSyncIntervalUnfocused(secs: number | null) {
}
}
function setWindowDecorations(value: "custom" | "none" | "system") {
windowDecorations = value;
localStorage.setItem(LS_DECORATIONS_KEY, value);
getCurrentWindow().setDecorations(value === "system");
document.documentElement.classList.toggle("decorations-none", value === "none");
}
async function setTheme(theme: string | null) {
if (!config?.current_workspace) return;
try {
@ -549,6 +563,9 @@ export const app = {
get lastSyncResult() {
return lastSyncResult;
},
get windowDecorations() {
return windowDecorations;
},
get error() {
return error;
},
@ -582,6 +599,7 @@ export const app = {
stopAutoSync,
setSyncInterval,
setSyncIntervalUnfocused,
setWindowDecorations,
setTheme,
addWebdavWorkspace,
forgetMissingWorkspace,