diff --git a/apps/clock/apps/web/src/app.css b/apps/clock/apps/web/src/app.css
new file mode 100644
index 000000000..c29749613
--- /dev/null
+++ b/apps/clock/apps/web/src/app.css
@@ -0,0 +1,10 @@
+@import "tailwindcss";
+@import "@manacore/shared-tailwind/themes.css";
+
+/* Scan shared packages for Tailwind classes */
+@source "../../../../packages/shared-ui/src";
+@source "../../../../packages/shared-auth-ui/src";
+@source "../../../../packages/shared-branding/src";
+@source "../../../../packages/shared-theme-ui/src";
+@source "../../../../packages/shared-theme-ui/src/components";
+@source "../../../../packages/shared-theme-ui/src/pages";
diff --git a/apps/clock/apps/web/src/lib/components/ToastContainer.svelte b/apps/clock/apps/web/src/lib/components/ToastContainer.svelte
new file mode 100644
index 000000000..28d60f24c
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/components/ToastContainer.svelte
@@ -0,0 +1,72 @@
+
+
+
+ {#each $toasts as toast (toast.id)}
+
+
+ {getIcon(toast.type)}
+
+ {toast.message}
+
+
+ {/each}
+
+
+
diff --git a/apps/clock/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte b/apps/clock/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte
new file mode 100644
index 000000000..21f6f848a
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte
@@ -0,0 +1,90 @@
+
+
+
+
+
diff --git a/apps/clock/apps/web/src/lib/components/skeletons/index.ts b/apps/clock/apps/web/src/lib/components/skeletons/index.ts
new file mode 100644
index 000000000..c6b8952ad
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/components/skeletons/index.ts
@@ -0,0 +1,8 @@
+/**
+ * Clock App Skeleton Components
+ *
+ * App-specific skeleton loaders for loading states.
+ */
+
+// App Loading Skeleton
+export { default as AppLoadingSkeleton } from './AppLoadingSkeleton.svelte';
diff --git a/apps/clock/apps/web/src/lib/i18n/index.ts b/apps/clock/apps/web/src/lib/i18n/index.ts
new file mode 100644
index 000000000..e6c3a0023
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/i18n/index.ts
@@ -0,0 +1,49 @@
+import { browser } from '$app/environment';
+import { init, register, locale, waitLocale } from 'svelte-i18n';
+
+// List of supported locales
+export const supportedLocales = ['de', 'en'] as const;
+export type SupportedLocale = (typeof supportedLocales)[number];
+
+// Default locale
+const defaultLocale = 'de';
+
+// Register all available locales
+register('de', () => import('./locales/de.json'));
+register('en', () => import('./locales/en.json'));
+
+// Get initial locale from browser or localStorage
+function getInitialLocale(): SupportedLocale {
+ if (browser) {
+ // Check localStorage first
+ const stored = localStorage.getItem('clock_locale');
+ if (stored && supportedLocales.includes(stored as SupportedLocale)) {
+ return stored as SupportedLocale;
+ }
+
+ // Fall back to browser language
+ const browserLang = navigator.language.split('-')[0];
+ if (supportedLocales.includes(browserLang as SupportedLocale)) {
+ return browserLang as SupportedLocale;
+ }
+ }
+
+ return defaultLocale;
+}
+
+// Initialize i18n at module scope (required for SSR)
+init({
+ fallbackLocale: defaultLocale,
+ initialLocale: getInitialLocale(),
+});
+
+// Set locale and persist to localStorage
+export function setLocale(newLocale: SupportedLocale) {
+ locale.set(newLocale);
+ if (browser) {
+ localStorage.setItem('clock_locale', newLocale);
+ }
+}
+
+// Wait for locale to be loaded (useful for SSR)
+export { waitLocale };
diff --git a/apps/clock/apps/web/src/lib/i18n/locales/de.json b/apps/clock/apps/web/src/lib/i18n/locales/de.json
new file mode 100644
index 000000000..fc35180f9
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/i18n/locales/de.json
@@ -0,0 +1,23 @@
+{
+ "app": {
+ "name": "Clock"
+ },
+ "common": {
+ "back": "Zurück",
+ "cancel": "Abbrechen",
+ "loading": "Lade..."
+ },
+ "nav": {
+ "home": "Startseite",
+ "settings": "Einstellungen"
+ },
+ "clock": {
+ "title": "Life Clock",
+ "remaining": "Verbleibende Zeit",
+ "elapsed": "Vergangene Zeit"
+ },
+ "messages": {
+ "saved": "Gespeichert",
+ "error": "Ein Fehler ist aufgetreten"
+ }
+}
diff --git a/apps/clock/apps/web/src/lib/i18n/locales/en.json b/apps/clock/apps/web/src/lib/i18n/locales/en.json
new file mode 100644
index 000000000..f6f978137
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/i18n/locales/en.json
@@ -0,0 +1,23 @@
+{
+ "app": {
+ "name": "Clock"
+ },
+ "common": {
+ "back": "Back",
+ "cancel": "Cancel",
+ "loading": "Loading..."
+ },
+ "nav": {
+ "home": "Home",
+ "settings": "Settings"
+ },
+ "clock": {
+ "title": "Life Clock",
+ "remaining": "Time remaining",
+ "elapsed": "Time elapsed"
+ },
+ "messages": {
+ "saved": "Saved",
+ "error": "An error occurred"
+ }
+}
diff --git a/apps/clock/apps/web/src/lib/stores/theme.svelte.ts b/apps/clock/apps/web/src/lib/stores/theme.svelte.ts
new file mode 100644
index 000000000..5784cfeec
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/stores/theme.svelte.ts
@@ -0,0 +1,7 @@
+import { createThemeStore } from '@manacore/shared-theme';
+
+// Create theme store with Clock's styling
+export const theme = createThemeStore({
+ appId: 'clock',
+ defaultVariant: 'lume',
+});
diff --git a/apps/clock/apps/web/src/lib/stores/toast.ts b/apps/clock/apps/web/src/lib/stores/toast.ts
new file mode 100644
index 000000000..eb45c4b3c
--- /dev/null
+++ b/apps/clock/apps/web/src/lib/stores/toast.ts
@@ -0,0 +1,44 @@
+import { writable } from 'svelte/store';
+
+export interface Toast {
+ id: string;
+ type: 'success' | 'error' | 'info' | 'warning';
+ message: string;
+ duration?: number;
+}
+
+function createToastStore() {
+ const { subscribe, update } = writable([]);
+
+ function addToast(toast: Omit) {
+ const id = crypto.randomUUID();
+ const newToast = { ...toast, id };
+
+ update((toasts) => [...toasts, newToast]);
+
+ // Auto-remove after duration
+ const duration = toast.duration || 5000;
+ setTimeout(() => {
+ removeToast(id);
+ }, duration);
+
+ return id;
+ }
+
+ function removeToast(id: string) {
+ update((toasts) => toasts.filter((t) => t.id !== id));
+ }
+
+ return {
+ subscribe,
+ success: (message: string, duration?: number) =>
+ addToast({ type: 'success', message, duration }),
+ error: (message: string, duration?: number) => addToast({ type: 'error', message, duration }),
+ info: (message: string, duration?: number) => addToast({ type: 'info', message, duration }),
+ warning: (message: string, duration?: number) =>
+ addToast({ type: 'warning', message, duration }),
+ remove: removeToast,
+ };
+}
+
+export const toasts = createToastStore();