Merge pull request #39 from SteelDynamite/ink-theme-eink-css-cleanup
ink-theme-eink-css-cleanup
This commit is contained in:
commit
105d46775c
|
|
@ -10,6 +10,7 @@
|
||||||
"core:window:allow-minimize",
|
"core:window:allow-minimize",
|
||||||
"core:window:allow-toggle-maximize",
|
"core:window:allow-toggle-maximize",
|
||||||
"core:window:allow-start-dragging",
|
"core:window:allow-start-dragging",
|
||||||
"core:window:allow-is-maximized"
|
"core:window:allow-is-maximized",
|
||||||
|
"core:window:allow-set-decorations"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,18 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
app.loadConfig();
|
app.loadConfig();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
document.documentElement.classList.toggle("decorations-none", app.windowDecorations === "none");
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={app.isDark ? "dark" : ""} data-theme={app.currentTheme ?? ""}>
|
<div class={app.isDark ? "dark" : ""} data-theme={app.currentTheme ?? ""} data-decorations={app.windowDecorations}>
|
||||||
<div class="h-screen w-screen" class:p-2={isLinux} class:onyx-border={app.currentTheme === "onyx"}>
|
<div class="h-screen w-screen" class:p-2={isLinux && app.windowDecorations === "custom"}>
|
||||||
<div
|
<div
|
||||||
class="relative h-full w-full overflow-hidden bg-surface-light text-text-light dark:bg-surface-dark dark:text-text-dark"
|
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:rounded-xl={isLinux && app.windowDecorations === "custom"}
|
||||||
class:linux-window-border={isLinux}
|
class:linux-window-border={isLinux && app.windowDecorations !== "system"}
|
||||||
style="container-type: inline-size"
|
style="container-type: inline-size"
|
||||||
>
|
>
|
||||||
{#if app.error}
|
{#if app.error}
|
||||||
|
|
|
||||||
|
|
@ -195,10 +195,6 @@ body {
|
||||||
border-color: rgba(209, 191, 130, 0.15);
|
border-color: rgba(209, 191, 130, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thick gold window border */
|
|
||||||
[data-theme="onyx"] .onyx-border {
|
|
||||||
border: 3px solid #a6905a;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="solarized"] {
|
[data-theme="solarized"] {
|
||||||
--color-primary: #268bd2;
|
--color-primary: #268bd2;
|
||||||
|
|
@ -216,6 +212,64 @@ body {
|
||||||
--color-danger: #dc322f;
|
--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 ───────────────────────────────── */
|
/* ── Accessibility: Reduced motion ───────────────────────────────── */
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
<!-- Backdrop + sheet wrapper -->
|
<!-- Backdrop + sheet wrapper -->
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div
|
<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)"
|
style="background: rgba(0,0,0,0.4)"
|
||||||
onclick={handleClose}
|
onclick={handleClose}
|
||||||
onkeydown={(e) => { if (e.key === "Escape") handleClose(); }}
|
onkeydown={(e) => { if (e.key === "Escape") handleClose(); }}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{#if showMenu}
|
{#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
|
<button
|
||||||
onclick={handleToggle}
|
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"
|
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>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{#if showSubtaskMenu}
|
{#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
|
<button
|
||||||
onclick={() => { showSubtaskMenu = false; confirmDeleteCompleted = true; }}
|
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"
|
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"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { platform } from "@tauri-apps/plugin-os";
|
||||||
import { app } from "../stores/app.svelte";
|
import { app } from "../stores/app.svelte";
|
||||||
import ConfirmDialog from "../components/ConfirmDialog.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 { onclose, workspaceId, ondelete }: { onclose?: () => void; workspaceId: string; ondelete?: (id: string) => void } = $props();
|
||||||
|
|
||||||
let ws = $derived(app.config?.workspaces[workspaceId]);
|
let ws = $derived(app.config?.workspaces[workspaceId]);
|
||||||
|
|
@ -91,9 +94,10 @@
|
||||||
<svelte:window onclick={handleWindowClick} />
|
<svelte:window onclick={handleWindowClick} />
|
||||||
|
|
||||||
<header
|
<header
|
||||||
|
data-tauri-drag-region
|
||||||
class="flex items-center justify-between border-b border-border-light px-4 py-3 dark:border-border-dark"
|
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
|
<button
|
||||||
onclick={() => onclose?.()}
|
onclick={() => onclose?.()}
|
||||||
class="rounded-lg p-1.5 hover:bg-black/5 dark:hover:bg-white/10"
|
class="rounded-lg p-1.5 hover:bg-black/5 dark:hover:bg-white/10"
|
||||||
|
|
@ -132,7 +136,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{#if showKebab}
|
{#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
|
<button
|
||||||
onclick={startRename}
|
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"
|
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="dracula">Dracula</option>
|
||||||
<option value="solarized">Solarized Dark</option>
|
<option value="solarized">Solarized Dark</option>
|
||||||
<option value="onyx">Black and Gold</option>
|
<option value="onyx">Black and Gold</option>
|
||||||
|
<option value="ink">Ink</option>
|
||||||
</select>
|
</select>
|
||||||
</section>
|
</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>
|
<p class="mt-8 text-center text-xs opacity-30">Tauri v2 + Svelte</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@
|
||||||
{#if showWorkspacePicker}
|
{#if showWorkspacePicker}
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div
|
<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}
|
{#each workspaceIds as wsId}
|
||||||
{@const ws = app.config?.workspaces[wsId]}
|
{@const ws = app.config?.workspaces[wsId]}
|
||||||
|
|
@ -500,7 +500,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{#if showListMenu}
|
{#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
|
<button
|
||||||
onclick={startRenameList}
|
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"
|
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"
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ listen("fs-changed", () => {
|
||||||
|
|
||||||
// ── Reactive state ───────────────────────────────────────────────────
|
// ── 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 screen = $state<Screen>("setup");
|
||||||
let config = $state<AppConfig | null>(null);
|
let config = $state<AppConfig | null>(null);
|
||||||
let lists = $state<TaskList[]>([]);
|
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) {
|
async function setTheme(theme: string | null) {
|
||||||
if (!config?.current_workspace) return;
|
if (!config?.current_workspace) return;
|
||||||
try {
|
try {
|
||||||
|
|
@ -549,6 +563,9 @@ export const app = {
|
||||||
get lastSyncResult() {
|
get lastSyncResult() {
|
||||||
return lastSyncResult;
|
return lastSyncResult;
|
||||||
},
|
},
|
||||||
|
get windowDecorations() {
|
||||||
|
return windowDecorations;
|
||||||
|
},
|
||||||
get error() {
|
get error() {
|
||||||
return error;
|
return error;
|
||||||
},
|
},
|
||||||
|
|
@ -582,6 +599,7 @@ export const app = {
|
||||||
stopAutoSync,
|
stopAutoSync,
|
||||||
setSyncInterval,
|
setSyncInterval,
|
||||||
setSyncIntervalUnfocused,
|
setSyncIntervalUnfocused,
|
||||||
|
setWindowDecorations,
|
||||||
setTheme,
|
setTheme,
|
||||||
addWebdavWorkspace,
|
addWebdavWorkspace,
|
||||||
forgetMissingWorkspace,
|
forgetMissingWorkspace,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue