diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md
index 27e0b201..c5c9222d 100644
--- a/documentation/TODO__Agents.md
+++ b/documentation/TODO__Agents.md
@@ -84,7 +84,11 @@ Full audit: `src/routes/events/[event_id]/(leads)/` and `src/lib/ae_events/ae_ev
omit from demo or hide the payment tab via "Show Payment Tab" toggle in Manage settings
- [ ] **End-to-end smoke test** — sign in with shared passcode, scan/search a badge, add a lead,
view detail, add notes/responses, export CSV; verify on mobile (Chrome/Safari PWA)
-- [ ] **Install prompt** — spec calls for a PWA install nudge on the Start tab; not yet added
+- [x] **Install prompt** — PWA install nudge implemented (2026-03-16). `pwa_install.svelte.ts`
+ singleton captures `beforeinstallprompt` (Chrome/Android/desktop) and detects iOS Safari
+ for manual "Share → Add to Home Screen" instructions. Reusable `element_pwa_install_prompt.svelte`
+ placed on the Leads Start tab between the feature grid and sign-in. `pwa_install.init()` wired
+ into root `+layout.svelte`; dismiss persists 7 days via localStorage. svelte-check: 0 errors.
### [DevOps] Remaining deployment items
- [x] **Wire AE_APP_REPLICAS:** `docker-compose.yml` line 147 already has `scale: ${AE_APP_REPLICAS:-1}`. (verified 2026-03-11)
diff --git a/scripts/migrate_fa_to_lucide.py b/scripts/migrate_fa_to_lucide.py
index c9c789c9..6e127ac4 100644
--- a/scripts/migrate_fa_to_lucide.py
+++ b/scripts/migrate_fa_to_lucide.py
@@ -110,6 +110,55 @@ FA_TO_LUCIDE = {
'fa-archive': 'Archive',
'fa-link-slash': 'Unlink',
'fa-question-circle': 'HelpCircle',
+ # ── Additional unmapped icons ──────────────────────────────────────────────
+ 'fa-compress-arrows-alt':'Minimize2',
+ 'fa-expand-arrows-alt': 'Maximize2',
+ 'fa-secret': 'ShieldCheck',
+ 'fa-user-shield': 'ShieldUser',
+ 'fa-user-nurse': 'UserRound',
+ 'fa-user-friends': 'Users',
+ 'fa-user-plus': 'UserPlus',
+ 'fa-user-edit': 'UserRoundPen',
+ 'fa-palette': 'Palette',
+ 'fa-eraser': 'Eraser',
+ 'fa-code': 'Code',
+ 'fa-lock-open': 'LockOpen',
+ 'fa-unlock': 'LockOpen',
+ 'fa-trash-alt': 'Trash2',
+ 'fa-folder-open': 'FolderOpen',
+ 'fa-minus-circle': 'MinusCircle',
+ 'fa-plus-circle': 'PlusCircle',
+ 'fa-window-close': 'X',
+ 'fa-cut': 'Scissors',
+ 'fa-caret-down': 'ChevronDown',
+ 'fa-caret-right': 'ChevronRight',
+ 'fa-cogs': 'Settings2',
+ 'fa-phone': 'Phone',
+ 'fa-phone-slash': 'PhoneOff',
+ 'fa-flag': 'Flag',
+ 'fa-calendar-week': 'CalendarDays',
+ 'fa-address-book': 'BookUser',
+ 'fa-info-circle': 'Info',
+ 'fa-comment-slash': 'MessageX',
+ 'fa-paperclip': 'Paperclip',
+ 'fa-keyboard': 'Keyboard',
+ 'fa-crosshairs': 'Crosshair',
+ 'fa-redo': 'RotateCcw',
+ 'fa-tools': 'Wrench',
+ 'fa-video-slash': 'VideoOff',
+ 'fa-home': 'House',
+ 'fa-calendar': 'Calendar',
+ 'fa-check-square': 'SquareCheck',
+ 'fa-square': 'Square',
+ 'fa-times-circle': 'CircleX',
+ 'fa-undo': 'RotateCcw',
+ 'fa-trash-restore': 'ArchiveRestore',
+ 'fa-lock-open': 'LockOpen',
+ 'fa-compress': 'Minimize2',
+ 'fa-expand': 'Maximize2',
+ 'fa-grip-lines': 'GripHorizontal',
+ 'fa-bars': 'Menu',
+ 'fa-refresh': 'RefreshCw',
}
# Skip modifiers — not real icon names
@@ -125,7 +174,7 @@ SPAN_RE = re.compile(
COMMENT_RE = re.compile(r'()')
# ── Lucide import line ────────────────────────────────────────────────────────
-IMPORT_RE = re.compile(r"import\s*\{([^}]+)\}\s*from\s*'lucide-svelte'\s*;?")
+IMPORT_RE = re.compile(r"import\s*\{([^}]+)\}\s*from\s*'@lucide/svelte'\s*;?")
def parse_fa_class(class_str):
@@ -199,7 +248,7 @@ def add_import(content, icons):
if existing:
current = [s.strip() for s in existing.group(1).split(',') if s.strip()]
merged = sorted(set(current) | set(sorted_icons))
- new_import = f"import {{ {', '.join(merged)} }} from 'lucide-svelte';"
+ new_import = f"import {{ {', '.join(merged)} }} from '@lucide/svelte';"
return content[:existing.start()] + new_import + content[existing.end():]
else:
# Insert after the last COMPLETE import statement (handles multiline imports).
@@ -211,7 +260,7 @@ def add_import(content, icons):
all_imports = list(complete_import_re.finditer(content))
if all_imports:
pos = all_imports[-1].end()
- new_line = f"\n import {{ {', '.join(sorted_icons)} }} from 'lucide-svelte';"
+ new_line = f"\n import {{ {', '.join(sorted_icons)} }} from '@lucide/svelte';"
return content[:pos] + new_line + content[pos:]
# Fallback: add after
+
+{#if pwa_install.should_show}
+
+{/if}
diff --git a/src/lib/pwa/pwa_install.svelte.ts b/src/lib/pwa/pwa_install.svelte.ts
new file mode 100644
index 00000000..f999b327
--- /dev/null
+++ b/src/lib/pwa/pwa_install.svelte.ts
@@ -0,0 +1,142 @@
+/**
+ * src/lib/pwa/pwa_install.svelte.ts
+ *
+ * Global PWA install prompt state using Svelte 5 universal reactivity.
+ *
+ * Usage:
+ * - Call `pwa_install.init()` once in the root +layout.svelte (browser $effect).
+ * - Import `pwa_install` in any component to read state and trigger the prompt.
+ *
+ * Platform behaviour:
+ * - Chrome / Android / Desktop Chrome: intercepts `beforeinstallprompt`,
+ * lets us show a custom button that calls the native install flow.
+ * - iOS Safari: `beforeinstallprompt` never fires; we detect iOS + not-standalone
+ * and show manual "Share → Add to Home Screen" instructions instead.
+ * - If already running in standalone mode (i.e. already installed) → hide everything.
+ *
+ * Dismiss: persists for DISMISS_DAYS days via localStorage key `ae_pwa_install_dismissed`.
+ */
+import { browser } from '$app/environment';
+
+// `BeforeInstallPromptEvent` is non-standard and not included in TypeScript's default lib.
+interface BeforeInstallPromptEvent extends Event {
+ prompt(): Promise;
+ userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;
+}
+
+const DISMISS_KEY = 'ae_pwa_install_dismissed';
+const DISMISS_DAYS = 7;
+
+// --- Module-level reactive state (Svelte 5 universal reactivity) ---
+let _deferred_prompt = $state(null);
+let _is_installed = $state(false);
+let _is_dismissed = $state(false);
+let _initialized = false; // plain boolean — not reactive, guards against double-init
+
+// --- Private helpers (SSR-safe) ---
+
+function _in_standalone(): boolean {
+ if (!browser) return false;
+ return (
+ window.matchMedia('(display-mode: standalone)').matches ||
+ // iOS Safari sets navigator.standalone (non-standard)
+ ('standalone' in window.navigator && (window.navigator as any).standalone === true)
+ );
+}
+
+function _is_ios(): boolean {
+ if (!browser) return false;
+ // Cover iPhone/iPod/iPad (incl. iPadOS 13+ which reports MacIntel with touch points)
+ return (
+ /iphone|ipad|ipod/i.test(navigator.userAgent) ||
+ (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
+ );
+}
+
+// --- Public API ---
+
+export const pwa_install = {
+ /**
+ * True if the browser has captured a deferred install prompt
+ * (Chrome / Android / PWA-capable desktop browsers).
+ */
+ get can_prompt(): boolean {
+ return _deferred_prompt !== null && !_is_installed && !_is_dismissed;
+ },
+
+ /**
+ * True if on iOS Safari and NOT already installed.
+ * We cannot trigger a native prompt on iOS so we show manual instructions instead.
+ */
+ get is_ios_nudge(): boolean {
+ return _is_ios() && !_in_standalone() && !_is_dismissed && !_is_installed;
+ },
+
+ /** True if the install UI should be rendered at all. */
+ get should_show(): boolean {
+ return pwa_install.can_prompt || pwa_install.is_ios_nudge;
+ },
+
+ /** True once the app is confirmed installed (standalone mode or appinstalled event). */
+ get is_installed(): boolean {
+ return _is_installed;
+ },
+
+ /**
+ * Register browser event listeners. Call ONCE from root +layout.svelte.
+ * Safe to call multiple times (idempotent).
+ */
+ init(): void {
+ if (!browser || _initialized) return;
+ _initialized = true;
+
+ // Already running as installed PWA — nothing to prompt.
+ if (_in_standalone()) {
+ _is_installed = true;
+ return;
+ }
+
+ // Restore dismiss state from localStorage (with expiry check).
+ const raw = localStorage.getItem(DISMISS_KEY);
+ if (raw) {
+ const days_since = (Date.now() - parseInt(raw, 10)) / 86_400_000;
+ if (days_since < DISMISS_DAYS) {
+ _is_dismissed = true;
+ } else {
+ // Expired — clear so the nudge can reappear.
+ localStorage.removeItem(DISMISS_KEY);
+ }
+ }
+
+ // Capture the deferred install prompt (Chrome/Android/Desktop Chrome).
+ window.addEventListener('beforeinstallprompt', (e) => {
+ e.preventDefault();
+ _deferred_prompt = e as BeforeInstallPromptEvent;
+ });
+
+ // Fired by the browser after the user accepts the install prompt.
+ window.addEventListener('appinstalled', () => {
+ _is_installed = true;
+ _deferred_prompt = null;
+ });
+ },
+
+ /** Trigger the native install prompt. No-op if no deferred prompt is available. */
+ async prompt(): Promise {
+ if (!_deferred_prompt) return;
+ // Grab and clear to prevent double-fire.
+ const evt = _deferred_prompt;
+ _deferred_prompt = null;
+ await evt.prompt();
+ const { outcome } = await evt.userChoice;
+ if (outcome === 'accepted') {
+ _is_installed = true;
+ }
+ },
+
+ /** Dismiss the nudge; it will not re-appear for DISMISS_DAYS days. */
+ dismiss(): void {
+ _is_dismissed = true;
+ if (browser) localStorage.setItem(DISMISS_KEY, Date.now().toString());
+ },
+};
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index fa9a7c18..a14f7486 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -38,12 +38,13 @@
// *** Import Aether specific variables and functions
// import Analytics from '$lib/app_components/analytics.svelte';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger, ae_auth_error } from '$lib/stores/ae_stores';
- import { LoaderCircle } from 'lucide-svelte';
+ import { LoaderCircle } from '@lucide/svelte';
// import { events_loc, events_slct } from '$lib/stores/ae_events_stores';
// import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
import E_app_debug_menu from '$lib/app_components/e_app_debug_menu.svelte';
import E_app_sys_bar from '$lib/app_components/e_app_sys_bar.svelte';
+ import { pwa_install } from '$lib/pwa/pwa_install.svelte';
// import E_app_sys_menu from '$lib/app_components/e_app_sys_menu.svelte'; // replaced by E_app_sys_bar
interface Props {
@@ -227,6 +228,9 @@
$effect(() => {
if (!browser) return;
+ // Initialise PWA install prompt listener (captures beforeinstallprompt early).
+ pwa_install.init();
+
// Save DS to local
let ae_ds = ae_acct?.ds;
if (ae_ds) {
diff --git a/src/routes/core/+layout.svelte b/src/routes/core/+layout.svelte
index 3c6db072..29a41178 100644
--- a/src/routes/core/+layout.svelte
+++ b/src/routes/core/+layout.svelte
@@ -2,8 +2,7 @@
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { ae_loc, ae_sess, ae_api, slct } from '$lib/stores/ae_stores';
- import { Building, Globe, Users, ShieldCheck, List, LayoutDashboard, MapPin, Phone, History, Lock } from 'lucide-svelte';
-
+ import { Building, Globe, History, LayoutDashboard, List, Lock, MapPin, Phone, ShieldCheck, Users } from '@lucide/svelte';
interface Props {
data: any;
children?: import('svelte').Snippet;
diff --git a/src/routes/core/+page.svelte b/src/routes/core/+page.svelte
index ec01aaff..afc7df97 100644
--- a/src/routes/core/+page.svelte
+++ b/src/routes/core/+page.svelte
@@ -1,5 +1,5 @@
diff --git a/src/routes/events/[event_id]/sign_in_out.svelte b/src/routes/events/[event_id]/sign_in_out.svelte
index b6253022..96f8979d 100644
--- a/src/routes/events/[event_id]/sign_in_out.svelte
+++ b/src/routes/events/[event_id]/sign_in_out.svelte
@@ -33,8 +33,7 @@
events_trigger,
events_trig_kv
} from '$lib/stores/ae_events_stores';
- import { X, LogIn } from 'lucide-svelte';
-
+ import { LogIn, X } from '@lucide/svelte';
onMount(() => {
console.log('Browser environment detected.');
diff --git a/src/routes/events/ae_comp__event_file_obj_tbl.svelte b/src/routes/events/ae_comp__event_file_obj_tbl.svelte
index 8b7cbf07..639c6bde 100644
--- a/src/routes/events/ae_comp__event_file_obj_tbl.svelte
+++ b/src/routes/events/ae_comp__event_file_obj_tbl.svelte
@@ -51,8 +51,7 @@
// import { events_func } from '$lib/ae_events_functions';
import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
- import { Check, Download, FileImage, FileSpreadsheet, ListOrdered, LoaderCircle, Presentation, ToggleLeft, ToggleRight, TriangleAlert, User } from 'lucide-svelte';
-
+ import { Check, Download, FileImage, FileSpreadsheet, ListOrdered, LoaderCircle, Presentation, ToggleLeft, ToggleRight, TriangleAlert, User } from '@lucide/svelte';
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
// Variables
diff --git a/src/routes/events/ae_comp__event_files_upload.svelte b/src/routes/events/ae_comp__event_files_upload.svelte
index 37b00eef..109bbaa7 100644
--- a/src/routes/events/ae_comp__event_files_upload.svelte
+++ b/src/routes/events/ae_comp__event_files_upload.svelte
@@ -3,7 +3,7 @@
* src/routes/events/ae_comp__event_files_upload.svelte
* Specialized component for uploading files and automatically linking them to Event objects.
*/
- import { LoaderCircle, Upload, UploadCloud } from 'lucide-svelte';
+ import { LoaderCircle, Upload, UploadCloud } from '@lucide/svelte';
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
// Import storage, functions, and libraries
diff --git a/src/routes/events/ae_comp__event_presentation_obj_li.svelte b/src/routes/events/ae_comp__event_presentation_obj_li.svelte
index d8ddaa39..04bf569c 100644
--- a/src/routes/events/ae_comp__event_presentation_obj_li.svelte
+++ b/src/routes/events/ae_comp__event_presentation_obj_li.svelte
@@ -42,8 +42,7 @@
import Element_ae_obj_field_editor_v3 from '$lib/elements/element_ae_obj_field_editor_v3.svelte';
import Comp_event_presenter_obj_li from '../events/[event_id]/(pres_mgmt)/presenter/ae_comp__event_presenter_obj_li_wrapper.svelte';
import Element_manage_event_file_li_wrap from '$lib/elements/element_manage_event_file_li_all.svelte';
- import { Barcode, CalendarDays, Eye, EyeOff, ListOrdered, Plus } from 'lucide-svelte';
-
+ import { Barcode, CalendarDays, Eye, EyeOff, ListOrdered, Plus } from '@lucide/svelte';
// export let link_to_type: string;
// let ae_promises: key_val = {};
diff --git a/src/routes/events/ae_comp__event_session_obj_li.svelte b/src/routes/events/ae_comp__event_session_obj_li.svelte
index 8bb4bb8d..f0c19b5c 100644
--- a/src/routes/events/ae_comp__event_session_obj_li.svelte
+++ b/src/routes/events/ae_comp__event_session_obj_li.svelte
@@ -30,28 +30,7 @@
}: Props = $props();
import { ae_util } from '$lib/ae_utils/ae_utils';
- import {
- LoaderCircle,
- Presentation,
- Check,
- Eye,
- EyeOff,
- Mail,
- MapPin,
- User,
- ChevronDown,
- ChevronUp,
- SendHorizontal,
- Rocket,
- Bell,
- BellOff,
- Edit,
- FileSearch,
- Search,
- CalendarDays,
- Clock
- } from 'lucide-svelte';
-
+ import { Bell, BellOff, CalendarDays, Check, ChevronDown, ChevronUp, Clock, Edit, Eye, EyeOff, FileSearch, LoaderCircle, Mail, MapPin, Presentation, Rocket, Search, SendHorizontal, User } from '@lucide/svelte';
import { api } from '$lib/api/api';
import Comp_event_presenter_obj_li from './[event_id]/(pres_mgmt)/presenter/ae_comp__event_presenter_obj_li_wrapper.svelte';
import Element_manage_event_file_li from '$lib/elements/element_manage_event_file_li_direct.svelte';
diff --git a/src/routes/events/ae_comp__event_session_obj_tbl.svelte b/src/routes/events/ae_comp__event_session_obj_tbl.svelte
index 238e6dc1..6146deeb 100644
--- a/src/routes/events/ae_comp__event_session_obj_tbl.svelte
+++ b/src/routes/events/ae_comp__event_session_obj_tbl.svelte
@@ -21,7 +21,7 @@
// import { liveQuery } from "dexie";
import { ae_util } from '$lib/ae_utils/ae_utils';
- import { ListOrdered } from 'lucide-svelte';
+ import { ListOrdered } from '@lucide/svelte';
// Imports - events specific
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
// import { db_events } from "$lib/db_events";
diff --git a/src/routes/events/ae_comp__events_menu_opts.svelte b/src/routes/events/ae_comp__events_menu_opts.svelte
index 3fac2d95..efc3f7e5 100644
--- a/src/routes/events/ae_comp__events_menu_opts.svelte
+++ b/src/routes/events/ae_comp__events_menu_opts.svelte
@@ -21,7 +21,7 @@
events_trigger,
events_trig_kv
} from '$lib/stores/ae_events_stores';
- import { Ban, Barcode, CheckCircle, ChevronDown, ChevronUp, Eye, EyeOff, List, MapPin, Pencil, Plane, QrCode, Save, Send, Sparkles, StickyNote, ToggleLeft, ToggleRight, UserRound, Wand2 } from 'lucide-svelte';
+ import { Ban, Barcode, CheckCircle, ChevronDown, ChevronUp, Eye, EyeOff, List, MapPin, Pencil, Plane, QrCode, Save, Send, Sparkles, StickyNote, ToggleLeft, ToggleRight, UserRound, Wand2 } from '@lucide/svelte';
@@ -189,12 +189,7 @@
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
title="Toggle between showing hidden sessions"
>
-
+ {#if $events_loc.pres_mgmt.qry_hidden == 'all'}{:else}{/if}
{#if $events_loc.pres_mgmt.qry_hidden == 'all'}
@@ -226,12 +221,7 @@
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
title="Toggle between showing disabled sessions"
>
-
+ {#if $events_loc.pres_mgmt.qry_enabled == 'all'}{:else}{/if}
{#if $events_loc.pres_mgmt.qry_enabled == 'all'}
@@ -476,11 +466,7 @@
}}
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
>
-
+ {#if $events_loc.pres_mgmt.hide__launcher_link}{:else}{/if}
{$events_loc.pres_mgmt.hide__launcher_link
@@ -498,12 +484,7 @@
}}
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
>
-
+ {#if $events_loc.pres_mgmt.hide__launcher_link_legacy}{:else}{/if}
{$events_loc.pres_mgmt.hide__launcher_link_legacy
@@ -521,11 +502,7 @@
}}
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
>
-
+ {#if $events_loc.pres_mgmt.hide__location_link}{:else}{/if}
{$events_loc.pres_mgmt.hide__location_link
@@ -545,12 +522,7 @@
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
title="Toggle showing the Location column in session lists and tables"
>
-
+ {#if $events_loc.pres_mgmt.hide__session_li_location_field}{:else}{/if}
{$events_loc.pres_mgmt.hide__session_li_location_field
@@ -569,12 +541,7 @@
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
title="Toggle showing the POC column in session lists and tables"
>
-
+ {#if $events_loc.pres_mgmt.hide__session_li_poc_field}{:else}{/if}
{$events_loc.pres_mgmt.hide__session_li_poc_field
diff --git a/src/routes/hosted_files/+page.svelte b/src/routes/hosted_files/+page.svelte
index a8bcfe3a..ad2d522d 100644
--- a/src/routes/hosted_files/+page.svelte
+++ b/src/routes/hosted_files/+page.svelte
@@ -9,8 +9,7 @@
import type { key_val } from '$lib/stores/ae_stores';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
- import { Video } from 'lucide-svelte';
-
+ import { Video } from '@lucide/svelte';
let { data } = $props();
let log_lvl = 0;
diff --git a/src/routes/hosted_files/video_util/+page.svelte b/src/routes/hosted_files/video_util/+page.svelte
index e3141dd3..5b33e04a 100644
--- a/src/routes/hosted_files/video_util/+page.svelte
+++ b/src/routes/hosted_files/video_util/+page.svelte
@@ -15,8 +15,7 @@
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
- import { ArrowLeftRight, Trash2, Upload } from 'lucide-svelte';
-
+ import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let { data } = $props();
let log_lvl = 1;
diff --git a/src/routes/hosted_files/video_util/hold_video_util.svelte b/src/routes/hosted_files/video_util/hold_video_util.svelte
index 1b81156b..ac3dd6dd 100644
--- a/src/routes/hosted_files/video_util/hold_video_util.svelte
+++ b/src/routes/hosted_files/video_util/hold_video_util.svelte
@@ -9,8 +9,7 @@
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
- import { ArrowLeftRight, Trash2, Upload } from 'lucide-svelte';
-
+ import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let log_lvl = 1;
let ae_promises: key_val = {};
diff --git a/src/routes/journals/+page.svelte b/src/routes/journals/+page.svelte
index e7ceaf53..0999b2ea 100644
--- a/src/routes/journals/+page.svelte
+++ b/src/routes/journals/+page.svelte
@@ -8,15 +8,7 @@
import { goto } from '$app/navigation';
// *** Icons
- import {
- BookPlus,
- SquareLibrary,
- Wrench,
- FileUp,
- LoaderCircle,
- Sparkles
- } from 'lucide-svelte';
-
+ import { BookPlus, FileUp, LoaderCircle, Sparkles, SquareLibrary, Wrench } from '@lucide/svelte';
// *** Libraries & Stores
import { liveQuery } from 'dexie';
import { Modal } from 'flowbite-svelte';
diff --git a/src/routes/journals/[journal_id]/+page.svelte b/src/routes/journals/[journal_id]/+page.svelte
index a24ccd1e..fae4b122 100644
--- a/src/routes/journals/[journal_id]/+page.svelte
+++ b/src/routes/journals/[journal_id]/+page.svelte
@@ -289,7 +289,7 @@
);
}
- import { LoaderCircle } from 'lucide-svelte';
+ import { LoaderCircle } from '@lucide/svelte';
diff --git a/src/routes/journals/ae_comp__journal_entry_editor.svelte b/src/routes/journals/ae_comp__journal_entry_editor.svelte
index adce809b..43772da5 100644
--- a/src/routes/journals/ae_comp__journal_entry_editor.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_editor.svelte
@@ -4,7 +4,7 @@
* Extracted 2026-01-08 to modularize the massive Journal Entry view.
* Handles: CodeMirror vs Plain vs Rendered HTML for both View and Edit modes.
*/
- import { LockKeyhole, Save, RefreshCcw } from 'lucide-svelte';
+ import { LockKeyhole, RefreshCcw, Save } from '@lucide/svelte';
import { ae_loc } from '$lib/stores/ae_stores';
import {
journals_loc,
diff --git a/src/routes/journals/ae_comp__journal_entry_header.svelte b/src/routes/journals/ae_comp__journal_entry_header.svelte
index 81cfeba9..705850ee 100644
--- a/src/routes/journals/ae_comp__journal_entry_header.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_header.svelte
@@ -4,20 +4,7 @@
* Standardized Journal Entry Header.
* Manages name, sync status, and triggers the modular config.
*/
- import {
- Save,
- Eye,
- Pencil,
- Fingerprint,
- LockKeyhole,
- LockKeyholeOpen,
- Settings,
- ChevronLeft,
- CircleCheck,
- CircleX,
- LoaderCircle,
- RefreshCw
- } from 'lucide-svelte';
+ import { ChevronLeft, CircleCheck, CircleX, Eye, Fingerprint, LoaderCircle, LockKeyhole, LockKeyholeOpen, Pencil, RefreshCw, Save, Settings } from '@lucide/svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import {
journals_loc,
diff --git a/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte b/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte
index adb3d571..1cc2747a 100644
--- a/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte
@@ -6,16 +6,7 @@
*/
// *** Import Lucide Icons
- import {
- FileUp,
- Trash2,
- Download,
- Paperclip,
- ExternalLink,
- LoaderCircle,
- RefreshCw
- } from 'lucide-svelte';
-
+ import { Download, ExternalLink, FileUp, LoaderCircle, Paperclip, RefreshCw, Trash2 } from '@lucide/svelte';
// *** Import Aether specific variables and functions
import type { key_val } from '$lib/stores/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte
index 68570ab1..cfe5ea94 100644
--- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte
@@ -34,8 +34,7 @@
import AE_Comp_Modal_Journal_Entry_Config from './ae_comp__modal_journal_entry_config.svelte';
// Icons
- import { CircleAlert, CircleX, LoaderCircle } from 'lucide-svelte';
-
+ import { CircleAlert, CircleX, LoaderCircle } from '@lucide/svelte';
// *** Props
interface Props {
log_lvl?: number;
diff --git a/src/routes/journals/ae_comp__journal_entry_obj_li.svelte b/src/routes/journals/ae_comp__journal_entry_obj_li.svelte
index 5e68f670..393b2737 100644
--- a/src/routes/journals/ae_comp__journal_entry_obj_li.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_obj_li.svelte
@@ -15,32 +15,7 @@
// *** Import Svelte specific
import { goto } from '$app/navigation';
- import {
- CalendarClock,
- Check,
- CodeXml,
- Copy,
- Eye,
- EyeOff,
- Files,
- Fingerprint,
- Flag,
- Group,
- ListPlus,
- Lock,
- NotebookPen,
- NotebookText,
- NotepadTextDashed,
- RemoveFormatting,
- Shapes,
- Siren,
- Tags,
- TypeOutline,
- X,
- LoaderCircle,
- BookOpenText
- } from 'lucide-svelte';
-
+ import { BookOpenText, CalendarClock, Check, CodeXml, Copy, Eye, EyeOff, Files, Fingerprint, Flag, Group, ListPlus, LoaderCircle, Lock, NotebookPen, NotebookText, NotepadTextDashed, RemoveFormatting, Shapes, Siren, Tags, TypeOutline, X } from '@lucide/svelte';
// *** Import Aether specific variables and functions
import type { key_val } from '$lib/stores/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
diff --git a/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte b/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte
index f953a293..32a2ec22 100644
--- a/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte
@@ -16,8 +16,7 @@
}: Props = $props();
// *** Import other supporting libraries
- import { LoaderCircle } from 'lucide-svelte';
-
+ import { LoaderCircle } from '@lucide/svelte';
// *** Import Aether specific components
import Journal_entry_obj_li from './ae_comp__journal_entry_obj_li.svelte';
diff --git a/src/routes/journals/ae_comp__journal_entry_quick_add.svelte b/src/routes/journals/ae_comp__journal_entry_quick_add.svelte
index 3f443c9c..5617a3a2 100644
--- a/src/routes/journals/ae_comp__journal_entry_quick_add.svelte
+++ b/src/routes/journals/ae_comp__journal_entry_quick_add.svelte
@@ -7,8 +7,7 @@
journals_trig
} from '$lib/ae_journals/ae_journals_stores';
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
- import { BookType } from 'lucide-svelte';
-
+ import { BookType } from '@lucide/svelte';
// Props
let {
class: className = '',
diff --git a/src/routes/journals/ae_comp__journal_obj_id_edit.svelte b/src/routes/journals/ae_comp__journal_obj_id_edit.svelte
index 029dc5cd..8dac71d4 100644
--- a/src/routes/journals/ae_comp__journal_obj_id_edit.svelte
+++ b/src/routes/journals/ae_comp__journal_obj_id_edit.svelte
@@ -5,41 +5,7 @@
* Standardized Journal-level configuration.
* Restored missing visibility and button toggles.
*/
- import {
- Check,
- Database,
- CodeXml,
- ShieldCheck,
- BookOpenText,
- Trash2,
- Fingerprint,
- LockKeyhole,
- Plus,
- Minus,
- Palette,
- MonitorPlay,
- Layout,
- Eye,
- EyeOff,
- Siren,
- MessageSquareWarning,
- Copy,
- FilePlus,
- FileDown,
- FileUp,
- Globe,
- BookHeart,
- BriefcaseBusiness,
- Target,
- Expand,
- BetweenVerticalEnd,
- BetweenVerticalStart,
- X,
- Settings,
- CalendarClock,
- MousePointerClick,
- Zap
- } from 'lucide-svelte';
+ import { BetweenVerticalEnd, BetweenVerticalStart, BookHeart, BookOpenText, BriefcaseBusiness, CalendarClock, Check, CodeXml, Copy, Database, Expand, Eye, EyeOff, FileDown, FilePlus, FileUp, Fingerprint, Globe, Layout, LockKeyhole, MessageSquareWarning, Minus, MonitorPlay, MousePointerClick, Palette, Plus, Settings, ShieldCheck, Siren, Target, Trash2, X, Zap } from '@lucide/svelte';
import { Modal } from 'flowbite-svelte';
import { goto } from '$app/navigation';
diff --git a/src/routes/journals/ae_comp__journal_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_obj_id_view.svelte
index 2c5f43fc..72c855df 100644
--- a/src/routes/journals/ae_comp__journal_obj_id_view.svelte
+++ b/src/routes/journals/ae_comp__journal_obj_id_view.svelte
@@ -3,18 +3,7 @@
import { goto } from '$app/navigation';
// *** Import other supporting libraries
- import {
- BookPlus,
- BookOpenText,
- FilePlus,
- Menu,
- Pencil,
- FileDown,
- FileUp,
- Settings,
- LoaderCircle
- } from 'lucide-svelte';
-
+ import { BookOpenText, BookPlus, FileDown, FilePlus, FileUp, LoaderCircle, Menu, Pencil, Settings } from '@lucide/svelte';
// *** Import Aether specific variables and functions
import { ae_util } from '$lib/ae_utils/ae_utils';
import {
diff --git a/src/routes/journals/ae_comp__journal_obj_li.svelte b/src/routes/journals/ae_comp__journal_obj_li.svelte
index a8597e9e..904cb345 100644
--- a/src/routes/journals/ae_comp__journal_obj_li.svelte
+++ b/src/routes/journals/ae_comp__journal_obj_li.svelte
@@ -5,13 +5,7 @@
* Layout: Responsive Grid (1 col mobile, 2 col tablet, 3 col desktop)
* Style: Tailwind 4 + Skeleton UI Reference Standard
*/
- import {
- BookOpenText,
- BookType,
- Hash,
- Calendar,
- Clock
- } from 'lucide-svelte';
+ import { BookOpenText, BookType, Calendar, Clock, Hash } from '@lucide/svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { ae_loc } from '$lib/stores/ae_stores';
diff --git a/src/routes/journals/ae_comp__modal_journal_config.svelte b/src/routes/journals/ae_comp__modal_journal_config.svelte
index 71eef3b8..d950b69d 100644
--- a/src/routes/journals/ae_comp__modal_journal_config.svelte
+++ b/src/routes/journals/ae_comp__modal_journal_config.svelte
@@ -5,20 +5,7 @@
* Standardized Module-level settings for Journals.
* Fixed Svelte 5 state placement and reactivity loops.
*/
- import {
- Settings,
- Check,
- ShieldCheck,
- CodeXml,
- Layout,
- Palette,
- MonitorPlay,
- X,
- CalendarClock,
- MousePointerClick,
- Database,
- Wrench
- } from 'lucide-svelte';
+ import { CalendarClock, Check, CodeXml, Database, Layout, MonitorPlay, MousePointerClick, Palette, Settings, ShieldCheck, Wrench, X } from '@lucide/svelte';
import { Modal } from 'flowbite-svelte';
// *** Import Aether specific variables and functions
diff --git a/src/routes/journals/ae_comp__modal_journal_entry_append.svelte b/src/routes/journals/ae_comp__modal_journal_entry_append.svelte
index e52fbeca..0bdabe53 100644
--- a/src/routes/journals/ae_comp__modal_journal_entry_append.svelte
+++ b/src/routes/journals/ae_comp__modal_journal_entry_append.svelte
@@ -1,6 +1,6 @@
@@ -16,7 +16,7 @@
-
+
Visual Editor (AE_Comp_Editor_TipTap)
@@ -30,7 +30,7 @@
-
+
Source View (AE_Comp_Editor_CodeMirror)