Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8d7108753 |
@@ -160,6 +160,9 @@
|
||||
"profile_theme_amber": "Amber",
|
||||
"profile_theme_slate": "Slate",
|
||||
"profile_theme_rose": "Rose",
|
||||
"profile_theme_light": "Light",
|
||||
"profile_theme_light_slate": "Light Blue",
|
||||
"profile_theme_light_rose": "Light Rose",
|
||||
"profile_reading_heading": "Reading settings",
|
||||
"profile_voice_label": "Default voice",
|
||||
"profile_speed_label": "Playback speed",
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
"profile_theme_amber": "Ambre",
|
||||
"profile_theme_slate": "Ardoise",
|
||||
"profile_theme_rose": "Rose",
|
||||
"profile_theme_light": "Light",
|
||||
"profile_theme_light_slate": "Light Blue",
|
||||
"profile_theme_light_rose": "Light Rose",
|
||||
"profile_reading_heading": "Paramètres de lecture",
|
||||
"profile_voice_label": "Voix par défaut",
|
||||
"profile_speed_label": "Vitesse de lecture",
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
"profile_theme_amber": "Amber",
|
||||
"profile_theme_slate": "Abu-abu",
|
||||
"profile_theme_rose": "Mawar",
|
||||
"profile_theme_light": "Light",
|
||||
"profile_theme_light_slate": "Light Blue",
|
||||
"profile_theme_light_rose": "Light Rose",
|
||||
"profile_reading_heading": "Pengaturan membaca",
|
||||
"profile_voice_label": "Suara default",
|
||||
"profile_speed_label": "Kecepatan pemutaran",
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
"profile_theme_amber": "Âmbar",
|
||||
"profile_theme_slate": "Ardósia",
|
||||
"profile_theme_rose": "Rosa",
|
||||
"profile_theme_light": "Light",
|
||||
"profile_theme_light_slate": "Light Blue",
|
||||
"profile_theme_light_rose": "Light Rose",
|
||||
"profile_reading_heading": "Configurações de leitura",
|
||||
"profile_voice_label": "Voz padrão",
|
||||
"profile_speed_label": "Velocidade de reprodução",
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
"profile_theme_amber": "Янтарь",
|
||||
"profile_theme_slate": "Сланец",
|
||||
"profile_theme_rose": "Роза",
|
||||
"profile_theme_light": "Light",
|
||||
"profile_theme_light_slate": "Light Blue",
|
||||
"profile_theme_light_rose": "Light Rose",
|
||||
"profile_reading_heading": "Настройки чтения",
|
||||
"profile_voice_label": "Голос по умолчанию",
|
||||
"profile_speed_label": "Скорость воспроизведения",
|
||||
|
||||
@@ -55,6 +55,48 @@
|
||||
--color-success: #4ade80; /* green-400 */
|
||||
}
|
||||
|
||||
/* ── Light amber theme ────────────────────────────────────────────────── */
|
||||
[data-theme="light"] {
|
||||
--color-brand: #d97706; /* amber-600 */
|
||||
--color-brand-dim: #b45309; /* amber-700 */
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-2: #f4f4f5; /* zinc-100 */
|
||||
--color-surface-3: #e4e4e7; /* zinc-200 */
|
||||
--color-muted: #71717a; /* zinc-500 */
|
||||
--color-text: #18181b; /* zinc-900 */
|
||||
--color-border: #d4d4d8; /* zinc-300 */
|
||||
--color-danger: #dc2626; /* red-600 */
|
||||
--color-success: #16a34a; /* green-600 */
|
||||
}
|
||||
|
||||
/* ── Light slate theme ────────────────────────────────────────────────── */
|
||||
[data-theme="light-slate"] {
|
||||
--color-brand: #4f46e5; /* indigo-600 */
|
||||
--color-brand-dim: #4338ca; /* indigo-700 */
|
||||
--color-surface: #f8fafc; /* slate-50 */
|
||||
--color-surface-2: #f1f5f9; /* slate-100 */
|
||||
--color-surface-3: #e2e8f0; /* slate-200 */
|
||||
--color-muted: #64748b; /* slate-500 */
|
||||
--color-text: #0f172a; /* slate-900 */
|
||||
--color-border: #cbd5e1; /* slate-300 */
|
||||
--color-danger: #dc2626; /* red-600 */
|
||||
--color-success: #16a34a; /* green-600 */
|
||||
}
|
||||
|
||||
/* ── Light rose theme ─────────────────────────────────────────────────── */
|
||||
[data-theme="light-rose"] {
|
||||
--color-brand: #e11d48; /* rose-600 */
|
||||
--color-brand-dim: #be123c; /* rose-700 */
|
||||
--color-surface: #fff1f2; /* rose-50 */
|
||||
--color-surface-2: #ffe4e6; /* rose-100 */
|
||||
--color-surface-3: #fecdd3; /* rose-200 */
|
||||
--color-muted: #9f1239; /* rose-800 at 60% */
|
||||
--color-text: #0f0a0b; /* near black */
|
||||
--color-border: #fda4af; /* rose-300 */
|
||||
--color-danger: #dc2626; /* red-600 */
|
||||
--color-success: #16a34a; /* green-600 */
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
let langMenuOpen = $state(false);
|
||||
|
||||
const THEMES = [
|
||||
{ id: 'amber', color: '#f59e0b' },
|
||||
{ id: 'slate', color: '#818cf8' },
|
||||
{ id: 'rose', color: '#fb7185' },
|
||||
{ id: 'amber', color: '#f59e0b' },
|
||||
{ id: 'slate', color: '#818cf8' },
|
||||
{ id: 'rose', color: '#fb7185' },
|
||||
{ id: 'light', color: '#d97706', light: true },
|
||||
{ id: 'light-slate', color: '#4f46e5', light: true },
|
||||
{ id: 'light-rose', color: '#e11d48', light: true },
|
||||
];
|
||||
|
||||
// Chapter list drawer state for the mini-player
|
||||
@@ -316,12 +319,15 @@
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
<!-- Theme dots (desktop) -->
|
||||
<div class="hidden sm:flex items-center gap-1 mr-1">
|
||||
{#each THEMES as t}
|
||||
{#each THEMES as t, i}
|
||||
{#if i === 3}
|
||||
<span class="w-px h-3 bg-(--color-border) mx-0.5"></span>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => { currentTheme = t.id; }}
|
||||
title={t.id}
|
||||
class="w-3.5 h-3.5 rounded-full border-2 transition-all {currentTheme === t.id ? 'border-(--color-text) scale-110' : 'border-transparent opacity-50 hover:opacity-100'}"
|
||||
class="w-3.5 h-3.5 rounded-full border-2 transition-all {currentTheme === t.id ? 'border-(--color-text) scale-110' : t.light ? 'border-(--color-border) opacity-70 hover:opacity-100' : 'border-transparent opacity-50 hover:opacity-100'}"
|
||||
style="background: {t.color};"
|
||||
></button>
|
||||
{/each}
|
||||
@@ -498,13 +504,16 @@
|
||||
<div class="my-1 border-t border-(--color-border)/60"></div>
|
||||
<div class="px-3 py-2.5 flex items-center justify-between">
|
||||
<span class="text-xs text-(--color-muted) uppercase tracking-widest">{m.profile_theme_label()}</span>
|
||||
<div class="flex items-center gap-2">
|
||||
{#each THEMES as t}
|
||||
<div class="flex items-center gap-1.5">
|
||||
{#each THEMES as t, i}
|
||||
{#if i === 3}
|
||||
<span class="w-px h-4 bg-(--color-border) mx-0.5"></span>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => { currentTheme = t.id; }}
|
||||
title={t.id}
|
||||
class="w-5 h-5 rounded-full border-2 transition-all {currentTheme === t.id ? 'border-(--color-text) scale-110' : 'border-transparent opacity-50 hover:opacity-100'}"
|
||||
class="w-5 h-5 rounded-full border-2 transition-all {currentTheme === t.id ? 'border-(--color-text) scale-110' : t.light ? 'border-(--color-border) opacity-70 hover:opacity-100' : 'border-transparent opacity-50 hover:opacity-100'}"
|
||||
style="background: {t.color};"
|
||||
></button>
|
||||
{/each}
|
||||
|
||||
@@ -44,7 +44,7 @@ export const PUT: RequestHandler = async ({ request, locals }) => {
|
||||
}
|
||||
|
||||
// theme is optional — if provided it must be a known value
|
||||
const validThemes = ['amber', 'slate', 'rose'];
|
||||
const validThemes = ['amber', 'slate', 'rose', 'light', 'light-slate', 'light-rose'];
|
||||
if (body.theme !== undefined && !validThemes.includes(body.theme)) {
|
||||
error(400, `Invalid theme — must be one of: ${validThemes.join(', ')}`);
|
||||
}
|
||||
|
||||
@@ -83,10 +83,13 @@
|
||||
let selectedFontFamily = $state(untrack(() => data.settings?.fontFamily ?? settingsCtx?.fontFamily ?? 'system'));
|
||||
let selectedFontSize = $state(untrack(() => data.settings?.fontSize ?? settingsCtx?.fontSize ?? 1.0));
|
||||
|
||||
const THEMES: { id: string; label: () => string; swatch: string }[] = [
|
||||
{ id: 'amber', label: () => m.profile_theme_amber(), swatch: '#f59e0b' },
|
||||
{ id: 'slate', label: () => m.profile_theme_slate(), swatch: '#818cf8' },
|
||||
{ id: 'rose', label: () => m.profile_theme_rose(), swatch: '#fb7185' },
|
||||
const THEMES: { id: string; label: () => string; swatch: string; light?: boolean }[] = [
|
||||
{ id: 'amber', label: () => m.profile_theme_amber(), swatch: '#f59e0b' },
|
||||
{ id: 'slate', label: () => m.profile_theme_slate(), swatch: '#818cf8' },
|
||||
{ id: 'rose', label: () => m.profile_theme_rose(), swatch: '#fb7185' },
|
||||
{ id: 'light', label: () => m.profile_theme_light(), swatch: '#d97706', light: true },
|
||||
{ id: 'light-slate', label: () => m.profile_theme_light_slate(), swatch: '#4f46e5', light: true },
|
||||
{ id: 'light-rose', label: () => m.profile_theme_light_rose(), swatch: '#e11d48', light: true },
|
||||
];
|
||||
|
||||
const FONTS = [
|
||||
@@ -332,8 +335,11 @@
|
||||
<!-- Theme -->
|
||||
<div class="px-6 py-5 space-y-3">
|
||||
<p class="text-sm font-medium text-(--color-text)">{m.profile_theme_label()}</p>
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
{#each THEMES as t}
|
||||
<div class="flex gap-2 flex-wrap items-center">
|
||||
{#each THEMES as t, i}
|
||||
{#if i === 3}
|
||||
<span class="w-px h-6 bg-(--color-border) mx-1 self-center"></span>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (selectedTheme = t.id)}
|
||||
@@ -343,7 +349,7 @@
|
||||
: 'border-(--color-border) bg-(--color-surface-3) text-(--color-muted) hover:border-(--color-brand)/50 hover:text-(--color-text)'}"
|
||||
aria-pressed={selectedTheme === t.id}
|
||||
>
|
||||
<span class="w-3 h-3 rounded-full shrink-0" style="background: {t.swatch};"></span>
|
||||
<span class="w-3 h-3 rounded-full shrink-0 {t.light ? 'ring-1 ring-(--color-border)' : ''}" style="background: {t.swatch};"></span>
|
||||
{t.label()}
|
||||
</button>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user