Commit Graph

750 Commits

Author SHA1 Message Date
Scott Idem
6b3fb36926 fix(badges): long names report edit button links to print page with icon
Changed href from /review to /print, added UserRoundPen icon, and
extended the title to include badge ID and name for hover context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:43:23 -04:00
Scott Idem
5cad150b0a fix(badges): move Reports link to trusted+edit toolbar, add reprint count
Reports link moved out of the enable_mass_print gate into the main
trusted+edit-mode toolbar, to the right of Templates — visible whenever
staff are in edit mode regardless of mass-print config.

Reports page header now shows reprint count in parentheses when > 0,
e.g. "142 badges · 98 printed (7 reprints)".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:38:25 -04:00
Scott Idem
8a41f02f0d feat(badges): add Long Names and Print Throughput reports
Two IDB-backed reports under /badges/reports:
- Long Names: filter badges by given/family/full name length (threshold
  adjustable), colour-coded by severity, links to review page
- Print Throughput: bucket print_last_datetime into 5/15/30/60-min
  windows with a horizontal bar chart and expandable badge name list

Also adds a "Badge Reports" nav link on the badges main page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:32:53 -04:00
Scott Idem
88ab5b27d4 fix(badges): skip PATCH and print immediately when offline or API unreachable
When navigator.onLine is false or the account is ghost (API unreachable),
bypass the 20-second API timeout entirely and fire window.print() at once.
The existing error state ("Printed — count NOT saved") already covers this
case. Staff can correct the print count manually after connectivity returns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 20:19:27 -04:00
Scott Idem
7d2b30b7ce fix(badges): open badge review access when no passcode is set
Badges without person_passcode are now viewable by anyone with the URL —
open access is granted on badge load. Previously this was explicitly
denied. The passcode entry form is only shown when the badge actually
has a passcode configured. Auto-validate effect expanded to cover the
no-passcode case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 18:35:47 -04:00
Scott Idem
c9b0acfa06 feat(badges): two-step confirm before sending email review link
Replace the single alert() call with an inline confirmation row per badge.
Clicking "Email Link" shows "Send / Cancel" in place so accidental sends
are avoided. Only one badge can be in confirm state at a time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 18:35:40 -04:00
Scott Idem
29a24812f4 fix(badges): perceptually uniform rainbow via OKLCH + @property
Replaces filter:hue-rotate() with CSS @property --ph-hue/--ph-lit animated
as numbers, applied as oklch() colors on SVG rect/line children. OKLCH keeps
perceptual lightness constant across hue rotation — no more brown/dark-blue
variance between slots. Pulse mode animates --ph-lit 0.42→0.78 for breathing.
Adds slow_pulse cfg_json flag + form checkbox. @property inherits:true lets
the animated value cascade from the div to its SVG children without per-child
animation declarations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:47:43 -04:00
Scott Idem
70fda25c95 feat(badges): slow pulse mode for rainbow punch hole markers
Adds punch_holes.slow_pulse cfg_json flag. When enabled, replaces the fast
2.5s linear hue-rotate with a 6s ease-in-out breathing animation that dims
(0.55 brightness) to bright (1.30) while shifting 180° of hue and back.
Same 120° phase offsets apply (2s apart). Form shows a Slow Pulse checkbox
below the slot cards whenever at least one slot has rainbow enabled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:42:23 -04:00
Scott Idem
8f815b7033 fix(badges): tri-phase rainbow cycling for punch hole markers
Each slot gets a fixed animation-delay (left: 0s, right: -0.833s, center: -1.667s)
so they are 120° apart in the hue cycle — same speed, different start points.
Replaces the shared-wrapper approach (all same phase) with per-slot CSS classes
that encode the phase offset, giving a proper tri-phase RGB cycling effect.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:35:31 -04:00
Scott Idem
ba4a0dc828 feat(badges): static RGB gradient for punch holes on print, cycling on screen
Each rainbow-enabled slot now has a companion print-only div with an inline
SVG linearGradient (R→Y→G→C→B→M spectrum). On screen: the animated
hue-rotate div cycles. On print: CSS hides the animated div and shows the
static gradient instead. X lines print in semi-transparent black over the
gradient fill for visibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:28:56 -04:00
Scott Idem
35c1324824 feat(badges): rainbow animation option for punch-out hole markers
Adds left/right/center_rainbow to punch_holes cfg_json. When enabled,
applies a CSS hue-rotate animation (2.5s loop) to the marker div using
a saturated red base color so the full visible spectrum appears. Template
form shows a Rainbow checkbox per slot; hides color pickers when active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:23:37 -04:00
Scott Idem
1a53a20995 feat(badges): per-side header padding configurable via template cfg_json
Adds header_padding_top/right/left alongside existing header_padding_bottom.
Removes hardcoded p-2 class — all four sides now set via inline style with
0.5rem default. Template form shows a 2×2 padding grid in Header & Branding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:17:04 -04:00
Scott Idem
04c2042060 feat(badges): per-slot fg/bg colors for punch-out hole markers
Adds left_fg/left_bg, right_fg/right_bg, center_fg/center_bg to punch_holes
cfg_json, plus shared fg/bg fallback. Template form shows color pickers per
slot (only when slot is enabled). Defaults: #777777 stroke, rgba white fill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:01:03 -04:00
Scott Idem
4831f4b81b fix(badges): punch hole markers — z-index above header + 1mm safety inset
z-index: 10 ensures markers always render above the header image regardless
of DOM order. Inset 1mm on all sides from physical hole boundary to account
for printer registration variance (3mm-tall slot has no margin for error).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:56:29 -04:00
Scott Idem
7bf76bf766 feat(badges): configurable punch-out hole markers for badge clip slots
Adds cfg_json.punch_holes.{left,right,center} to mark pre-perforated badge
clip slots with X overlays. Slots are 5/8in x 1/8in, 1/4in from top,
3/8in from left/right edges. Markers print on the badge so attendees know
where to push out the perforations. Template form exposes checkboxes in
Header & Branding. Documented in MODULE__AE_Events_Badge_Templates.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:52:59 -04:00
Scott Idem
b04202ecec feat(badges): configurable header bottom border and padding per template
Replaces hardcoded border-bottom/padding-bottom on badge_header div with
cfg_json fields: header_border_color, header_border_width, header_padding_bottom.
Empty color = no border. Template form exposes all three in Header & Branding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:40:18 -04:00
Scott Idem
84c4a2aa43 fix(badges): correct templates link URL — /events/[id]/templates not /badges/templates
Route group (badges) is parenthetical and doesn't contribute a URL segment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:05:08 -04:00
Scott Idem
399f98ce8e feat(badges): add Templates link on badge search page for manager access
Shows a Templates button (manager+ edit mode only) before Create Badge,
linking directly to the badge templates management page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:03:11 -04:00
Scott Idem
f5ccd2e3cf feat(badges): configurable header image vertical offset per template
Adds cfg_json.header_margin_top to BadgeTemplateCfg. Badge view replaces
hardcoded mt-8 (2rem) with this value; falls back to 2rem when unset.
Template form exposes the field in the Header & Branding section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:00:21 -04:00
Scott Idem
9d904446d4 feat(badges): search filter polish and result limit stepper
- Replace show_hidden checkbox with visibility_filter select (Default /
  Show Hidden / Show Disabled+Hidden) — collapses two orphaned boolean
  fields (show_hidden, show_not_enabled) into one purpose-built value;
  wires disabled-badge filter through to both IDB and API paths
- Add max-results stepper (edit mode only): steps of 25 up to 250,
  steps of 100 up to 2550; tier-capped (trusted=250, manager=2550);
  stepper uses pure reactivity — no handle_search_trigger() call needed
- Fix fallback liveQuery (SCENARIO 2): was hardcoded .limit(50);
  now reads qry_result_limit in outer $derived.by so Svelte tracks it
  and stepper updates the no-text browse list immediately
- Fix Search button disabled state: replace pointer-events-none +
  class:opacity-50 with HTML disabled attribute + disabled:cursor-not-allowed
  so hover cursor reflects disabled state correctly
- Global placeholder fix (app.css): add italic + opacity-0.6 rule for
  .input/.textarea ::placeholder in light mode; add italic to dark rule —
  prevents placeholder text from reading as typed content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 18:33:59 -04:00
Scott Idem
b45a27481a Forgot to switch this back to not equals for the last printed timestamp. 2026-06-04 17:08:20 -04:00
Scott Idem
74e0f752a6 More fine tuning of the look and feel. 2026-06-02 20:14:08 -04:00
Scott Idem
be3e56eece fix(badges): cap controls panel width and center badge+controls pair
- Controls column: max-w-sm (384px) prevents flex-1 from consuming all
  remaining horizontal space on wide screens
- Row wrapper: justify-center + items-center centers the badge+controls
  pair in the available width (equal margins on both sides)
- Mobile: full-width stacked layout unchanged; badge centered via items-center

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 19:44:16 -04:00
Scott Idem
e2d3c5a822 refactor(badges): replace fixed controls overlay with in-flow flex layout
- Print page: controls panel moves from position:fixed right overlay to an
  in-flow flex column next to the badge. Sticky on lg+ screens; stacks below
  badge on tablet/phone. Eliminates pr-64/pr-80 padding hacks on header and
  badge area. Print behavior unchanged — .event_badge_wrapper uses position:fixed
  relative to @page, so the surrounding layout structure is irrelevant.
- Remove is_editing (was only used to toggle fixed panel width; no longer needed).
- Debug JSON block removed from ae_comp__badge_obj_view (visual render component
  should not contain admin tooling) and moved to controls Staff section.
- Debug JSON uses whitespace-pre + overflow-x-auto so long lines scroll
  horizontally instead of wrapping into hundreds of short lines. Collapsible
  via native <details>/<summary> with no JS state required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 19:40:26 -04:00
Scott Idem
1b6aeb5b02 fix(badges): polish print page chrome; fix header overlap with controls panel
- Add pr-64/pr-80 + transition to page <header> so Review/Email actions
  stay clear of the fixed right controls panel (same as badge_render_area)
- Remove redundant Re-print button from header — controls panel Test button
  covers the same use case; having both caused clipping and confusion
- Fix datetime formatting: toLocaleString → ae_util.iso_datetime_formatter
  (date_full_no_year + time_12_long) for consistent display with badge list
- Unify loading state to p-16/text-xl/mb-2 matching badge list style
- Polish Badge Not Found layout; swap button weights (Back = primary action)
- Add left-edge shadow to controls panel for better visual separation
- Badge view debug section: gate to administrator_access, add object ID
  labels, add hover:max-h-64 expand and transition on pre blocks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 19:11:37 -04:00
Scott Idem
04018a27ed Fine tuning the styles 2026-06-02 18:14:55 -04:00
Scott Idem
4292aebc56 Fine tuning the layout of things. 2026-06-02 17:47:27 -04:00
Scott Idem
3466d6552c feat(badges): show print status strip for trusted staff on printed badges
Adds a compact print info row below each printed badge for trusted users
(not in edit mode — debug row already covers that):
  Printed 2×  ·  First: June 9 9:14 AM  ·  Last: June 9 11:32 AM

Gives staff quick at-a-glance confirmation that a badge was printed and when,
without needing to enter edit mode.

Also fixes a logic bug in the attendee "Checked in" card: the "last print"
line was comparing == (same datetime) instead of !== (different datetime),
so it only appeared when first = last (single print) — backwards. Fixed to
show only when multiple prints have occurred.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 17:27:40 -04:00
Scott Idem
b7969bc46e Making subtle changes based on actual usage 2026-06-02 17:05:34 -04:00
Scott Idem
99b8eb0b5e fix(badges): focus search input when Search is triggered with too-short query
Pressing the Search button or Enter with fewer than the required min chars
now focuses the input field instead of silently doing nothing, so the user
gets clear feedback about where to type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:55:38 -04:00
Scott Idem
9e361eae9b fix(badges): improve empty-state search hint to reflect actual search fields
Was: "Enter your name above to find your badge."
Now: "Search by name, email, or organization above to find your badge."

Mirrors the actual fast-path fields (given/family name, email, default_qry_str)
and the search input placeholder text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:52:35 -04:00
Scott Idem
e735d0c213 refactor(badges): remove redundant loading gate; fix BarChart2 deprecation
The +page.svelte {#if search_status=loading && ids.length===0} gate is now
redundant — ae_comp__badge_obj_li handles all states internally (Searching...,
Enter your name, No results). Removing it also fixes a UX regression where
trusted-user IDB fallback results would be hidden by the gate whenever a new
API search fired. Component is now always mounted and manages its own state.

Also replaces deprecated BarChart2 with ChartColumnBig (lucide rename).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:48:44 -04:00
Scott Idem
d05cc63459 fix(badges): remove transition from initial loader to fix double-DOM bounce
transition:fade on the initial spinner caused Svelte to keep the outgoing
element in the DOM for the full 200ms outro while the incoming badge list
was already rendered — both were live simultaneously, colliding on height
and producing the visible bounce. Initial cold-start load doesn't need a
transition; instant swap is fine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:44:35 -04:00
Scott Idem
ac17417f3c fix(badges): fix search-result layout shift + unify empty/loading states
Scrollbar shift:
- Add [scrollbar-gutter:stable] to #ae_main_content in events layout so a
  scrollbar appearing on first results load no longer reflows the centered
  search form (was shifting ~8px left on Linux)

Empty/loading state consistency:
- Move search_status prop into ae_comp__badge_obj_li so it can swap its own
  empty state: spinner + "Searching..." while a search is in progress,
  UserSearch icon + prompt text otherwise
- Unify p-16 / size-3em / mb-2 / text-xl across all three states (initial
  load, searching, no results) so height never jumps between transitions
- Pass search_status from +page.svelte to the component

Transitions:
- transition:fade on initial-load spinner div
- transition:slide on Create/Upload badge button row (appears with edit mode)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:38:30 -04:00
Scott Idem
3773758eb5 feat(badges): smooth transitions + polish for badge search UI
- Adds fade/slide transitions throughout the search form: form mount/unmount,
  filter row, QR scan button, QR scanner panel, Show Hidden, Remote First labels
- Min-chars hint switches from class:invisible to opacity-0/opacity-50 +
  transition-opacity so it fades instead of snapping
- Clear button switches from class:hidden to opacity-0 + pointer-events-none
  + transition-all so it fades without causing layout shifts
- "Start Here" button gets transition-opacity for smooth dim on first keystroke
- Replaces FileSearch with UserSearch icon in the empty state
- Adds w-full to empty state div to prevent subtle page-width shift between
  no-results and results states

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:25:31 -04:00
Scott Idem
60bdd2fdba feat(badges): public_access kiosk mode + manager access improvements
- Public (attendee) kiosk: unprinted badges link to /review; printed
  badges show green "Checked in · Nx · First/Last" row (non-clickable)
- Public attendees no longer see Print button (staff-only action)
- Printed badges sort to end of list for public non-trusted users
- Manager access: Print (reprint) and Email Link buttons always visible
  without requiring Edit Mode; main row behavior unchanged
- Empty state wording: context-aware — "Enter your name above to find
  your badge" for public users with no query vs "No badges found" after
  an actual search
- Docs: Epson C3500 fanfold section filled in (was empty placeholder);
  style_href/duplex implementation status corrected in badge templates
  doc; Axonius C3500 layout TODO marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 16:15:08 -04:00
Scott Idem
a74effa6ff feat(badges): add Cvent Splash XLSX import mode; fix server-side upload timeout
- Add 'Cvent Splash XLSX (registrant export)' upload mode hitting the new
  /event/{id}/badge/import/splash_xlsx endpoint
- Admin controls: begin_at/end_at/return_detail (shared with Zoom mode) +
  import_status_filter (splash only, default 'Attending')
- File picker accept attribute switches between .csv and .xlsx per mode
- Set timeout=300000 and retry_count=1 on both server-side upload paths to
  prevent false 'no response' failures on slow imports; upsert-by-email on
  the backend makes retries safe but a single attempt is sufficient
- Replace misleading 0/0 progress bar with an indeterminate progress bar
  during server-side processing; real counter kept for client-side CSV mode
- Show 'Processing on server…' message once upload completes and server work begins

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:37:48 -04:00
Scott Idem
f6c950abdf fix(pres_mgmt): fix hidden sessions toggle not showing hidden sessions
Three related fixes for the hide/show toggle in Pres Mgmt:

1. ae_events__event_session.ts: remove redundant search_query.and hide
   filter and instead pass `hidden` to api.search_ae_obj as a URL param.
   The backend StatusFilterParams defaults to hidden='not_hidden', so
   without this the API always filtered to hide=0 regardless of intent.

2. pres_mgmt/+page.svelte (SCENARIO 2): capture qry_hidden as a
   $derived.by dependency so the liveQuery instance is recreated on
   toggle — prevents hidden sessions briefly appearing before the
   debounce fires (blink fix).

3. pres_mgmt/+page.svelte (API call): use params.qry_hidden snapshot
   instead of the live store to prevent race if user toggles during a
   pending search.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 22:24:04 -04:00
Scott Idem
182a066d38 fix(pres_mgmt): use tmp_sort_2 for presentation sort in Pres Mgmt and Launcher
Compute presentation-specific tmp_sort_1/tmp_sort_2 in specific_processor,
overriding the generic values from _process_generic_props which had two bugs:
- priority encoded as 0/1 ASC (backwards — true should sort first)
- sort stored as unpadded string ("10" < "2" lexicographically)
- start_datetime and code not included (presentation-specific fields)

New encoding: priority(inv)_sort(8-padded)_start_datetime_code[_name]
Both liveQueries (Pres Mgmt session page, Launcher session view) now use
.sortBy('tmp_sort_2') — cleaner and uses the indexed field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:20:50 -04:00
Scott Idem
35fed53e2a fix(launcher): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy() (poster→name, oral→start_datetime) with
toArray() + JS comparator matching the same sort chain as Pres Mgmt.
Removes the sort_by branch since the comparator handles both session types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:11:14 -04:00
Scott Idem
322abc2691 fix(pres_mgmt): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy('name') with toArray() + JS comparator to
implement the full desired sort chain. Dexie's sortBy() only supports a
single indexed field, so multi-field ordering requires a JS sort pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:38:13 -04:00
Scott Idem
cfaf687717 fix(events): event location file load on mount + launcher pruning scope fix + remove legacy launcher btn
- Location page now calls load_ae_obj_li__event_file on mount so files
  appear immediately without requiring a manual Refresh press.
- _load_event_location_sub_data (Launcher 60s sync) now uses hidden='all'
  with default limit (100) instead of hidden='not_hidden'/limit=25, which
  was pruning valid Dexie records when Pres Mgmt and Launcher were both
  open on the same location simultaneously.
- Removed the legacy launcher button (Send icon, /event/ path) from the
  Locations list; removed unused Send icon import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:41:32 -04:00
Scott Idem
e4e2174c97 fix(upload): replace db_events.file.clear() with targeted per-object reload
db_events.file.clear() after every upload was nuking the entire Dexie file
table. Every liveQuery watching any file list (Launcher, other locations,
sessions, presenters) would immediately show 0 results. Only the uploaded-to
object's files were reloaded; all others remained empty until their own
background syncs fired — intermittent disappearance that depended on timing.

Fix: targeted load_ae_obj_li__event_file for only the current link_to_id,
which uses the SWR pattern (returns cache + background refresh that includes
the newly created file). Other objects' file caches are untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:33:12 -04:00
Scott Idem
d3bf314c62 fix(launcher): refresh file lists periodically to prune deleted/hidden files
The Launcher's background sync never called load_ae_obj_li__event_file for
presenter/session files. That function contains stale-record pruning that
removes deleted or hidden files from Dexie; without it, the Launcher's IDB
retained stale file records indefinitely until manually cleared.

Changes:
- refresh_presenter_data: add inc_file_li=true so presenter files are pruned
  every 120s via the existing presenter loop
- refresh_current_session_files(): new function that fetches/prunes session-
  level file lists for the selected session
- timer__file_list: 60s interval for refresh_current_session_files
- $effect on event_session_id: fires refresh_current_session_files immediately
  on session switch (no wait for next timer tick)

Propagation time: deleted/hidden files visible on remote Launchers within
~60s (session files) or ~120s (presenter files) automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:12:10 -04:00
Scott Idem
213eabd8c1 feat(launcher): migrate cfg menu to 7-tab sidebar layout (v3.1)
Replaces the 3-tab horizontal bar (Setup / Device / Dev) with a vertical
sidebar navigation matching the v3.1 design spec. New tab structure:

  General       — App Modes, Screen Saver (operator-facing)
  Connectivity  — Remote Controller & WebSocket
  Sync & Health — Sync Timers, System Health
  Native OS     — OS controls (native or edit_mode preview)
  Wallpaper     — Desktop wallpaper settings
  Advanced      — Launch Timing, Updates (edit_mode only)
  Maintenance   — Local Resets, Debug Panel (edit_mode only)

Layout changes:
- Sidebar nav (w-48) + scrollable main content area replace inline tab bar
- Tab header shows label + description subtitle
- Technical Mode toggle is now a labeled button (not hidden icon)
- Footer shows Account/Device context; Reload moved to header
- {#key active_tab} wrapper ensures clean component remount on tab switch
- Remove unused icons (SlidersHorizontal, HeartPulse, Timer, CloudDownload)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:14:52 -04:00
Scott Idem
872291b0a0 fix(launcher): replace Flowbite Modal with custom overlay for cfg panel
Two problems with the Flowbite <Modal> approach:
1. Built-in dismissable CloseButton rendered with no functional dismiss path
   (no title/form), appearing centered in the panel.
2. size="xl" (max-w-7xl) left no backdrop area on typical laptop screens,
   making outsideclose impossible to trigger.

Replace with a simple custom overlay: full-screen backdrop div that closes
on click, inner panel with stopPropagation. Matches the original Drawer
pattern. close_cfg() writes to store immediately on backdrop click for
reliable persistence independent of effect timing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:04:34 -04:00
Scott Idem
25d17841e4 fix(launcher): fix cfg modal default-open and outside-click persistence
Two bugs in the Launcher Config Modal after the Drawer→Modal migration:
1. Pre-existing persisted configs (missing hide_drawer__cfg field) caused
   !undefined = true, opening the modal on every fresh load. Fixed by adding
   a field-level initialization guard after the full-object guard.
2. $-syntax writes inside untrack() were suppressed by svelte-persisted-store,
   so outside-click closure was never persisted. Fixed by using events_loc.update()
   directly to ensure the write reaches localStorage serialization. Added equality
   guard to effect 1 to prevent spurious modal flicker from whole-store re-fires.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 21:36:01 -04:00
Scott Idem
6282fb167f fix(launcher): use $derived.by for session liveQueries to fix stale presentation/presenter data
When switching sessions within the same location, presentations and presenters
were not updating. The root cause: plain $derived(liveQuery(...)) never recreates
the Observable when slct__event_session_id changes, because liveQuery's async
callback runs in Dexie's zone where Svelte tracking is off. Dexie's range-level
change detection then ignores new session data (it arrives under a different
event_session_id index value, outside the originally observed range).

Replaced all four liveQuery declarations with $derived.by(() => { const id = ...;
return liveQuery(...id...); }) — the same pattern already used in +layout.svelte
for location-dependent queries. Svelte tracks the id read in the outer closure
and recreates the Observable on every session change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 19:55:17 -04:00
Scott Idem
194c89f6d1 style(launcher): layout and Tailwind class adjustments
+layout.svelte: add lg:min-h-8/12 and max-h-screen to main content area.
launcher_background_sync.svelte: reposition sync monitor panel (bottom-15,
left-2, z-10 — was bottom-20, left-4, z-9999).
launcher_menu.svelte: reorder Tailwind classes for readability, no change
to applied styles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:09:08 -04:00
Scott Idem
d1f5d0e2fd fix(launcher): clear ae_loc in cache cleanup; align tech help Clear & Reload
menu_launcher_controls: handle_cache_cleanup now removes both ae_events_loc
and ae_loc from localStorage, giving a true clean slate on reload.

e_app_help_tech: Clear & Reload button no longer silently re-saves ae_loc
after clearing — if edit mode wipes localStorage, ae_loc goes with it.
Updated confirm message and title tooltip to say "you will be signed out"
instead of the previous misleading "sign-in will be preserved."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:05:16 -04:00