Commit Graph

517 Commits

Author SHA1 Message Date
Scott Idem
9fc3ee0198 fix(imports): point to element_data_store_v3 and restore Data Store v3; commit workspace updates 2026-03-17 18:57:27 -04:00
Scott Idem
ce09dcd09b Removing old code. Updated dev/test doc. 2026-03-17 13:20:26 -04:00
Scott Idem
adef935188 chore: aggressive cleanup: remove legacy element_data_store.svelte (v1) after v3 migration 2026-03-17 12:22:00 -04:00
Scott Idem
e085a1d513 chore: remove broken/redundant components imported from WIP branch 2026-03-17 10:51:58 -04:00
Scott Idem
df34a85a89 cherry: import ae_comp__badge_obj_view.svelte (v1 with edit) from wip-modal-fix-attempt 2026-03-17 10:35:00 -04:00
Scott Idem
b543c8a930 chore: migrate all FA icons to Lucide (@lucide/svelte)
- Replaced all active FontAwesome <span class="fas fa-*"> icons with
  Lucide components across 145 files (excluding /idaa/ which is intentional)
- Fixed merge script bug: consolidated lucide-svelte imports into @lucide/svelte
- Replaced dynamic toggle patterns (fa-toggle-on/off) with ToggleRight/ToggleLeft
- Replaced fa-eye/fa-eye-slash with Eye/EyeOff
- Replaced fa-bug/fa-bug-slash with Bug/BugOff
- Replaced fa-sync fa-spin with RefreshCw + animate-spin
- Replaced fa-microchip with Cpu
- Fixed {@const} placement in element_manage_event_file_li.svelte
- Removed obsolete CSS hover rules for .unlock_icon/.lock_icon
- svelte-check: 0 errors, 0 warnings
2026-03-16 18:07:43 -04:00
Scott Idem
cf6aa1301b feat(leads): gate export button on leads_api_access flag
Export button now only renders when event_exhibit.leads_api_access === true,
preventing a 403 that would always fire otherwise. Endpoint confirmed live on
backend. TODO updated to reflect export + allow_tracking gate both resolved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:43:37 -04:00
Scott Idem
be24cfdeb5 feat(leads): allow_tracking gate + icon bug fix + docs update
- QR scanner: after badge loads, blocks add with 'Tracking Opt-Out' warning
  card if allow_tracking !== true; replaced deprecated CheckCircle → CircleCheck
- Manual search: shows ShieldOff 'Opt-Out' label per row for blocked badges;
  add_as_lead() also guards against programmatic bypass
- Fix: ae_comp__exhibit_tracking_obj_li — Loader2 from wrong package
  @lucide/svelte → LoaderCircle from lucide-svelte
- ae_types.ts: added allow_tracking and agree_to_tc to ae_EventBadge interface
- README.md (leads): full rewrite reflecting actual current state and known gaps
- TODO__Agents.md: updated Leads entry from stale 'NEXT MAJOR FEATURE' to
  accurate in-progress status with remaining checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:59:26 -04:00
Scott Idem
80baaa9d91 style: badge code_to_icon refactor + core variant-* → preset-* migration
badge ae_comp__badge_obj_view_v2.svelte:
- Replace FA HTML string dict (code_to_html) with Lucide component map
  (code_to_icon) — no FontAwesome dependency for dietary/option icons
- option_1 maps: Biohazard (generic/allergy), Utensils (dietary), Bone,
  Fish, Carrot for specific diets
- option_2 maps: Asterisk (generic flag), Hand (first-time attendee)
- Template: replace {@html option_other_*} with {@const Icon}<Icon /> pattern
- Back-of-badge: shows text label + inline icon

core/ (21 files):
- variant-soft-* → preset-tonal-* (6 variants)
- variant-filled-* → preset-filled-* (6 variants)
- variant-glass-surface → preset-tonal-surface (Skeleton v4 has no glass)
- bare variant-soft → preset-tonal-surface

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 14:42:28 -04:00
Scott Idem
37c9d830f6 style(badges): FA→Lucide migration in ae_comp__badge_obj_view_v2.svelte
Convert 6 template-level FA spans to Lucide components (Star, Biohazard,
Asterisk, Wifi). The code_to_html JS string dict (dietary symbols used
with {@html}) retains FA spans since they are raw HTML strings, not
Svelte template markup — FontAwesome CSS (app.html CDN) renders them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 14:30:30 -04:00
Scott Idem
478dedb898 style: FA→Lucide migration — events misc, badges, leads, hosted_files; variant-* fixes
- Batch-migrated 10 files via migrate_fa_to_lucide.py (53+18+10+1+4+2+1+1+6+4 FA instances)
  - events/ae_comp__events_menu_opts.svelte (53)
  - events/ae_comp__event_file_obj_tbl.svelte (18)
  - events/ae_comp__event_presentation_obj_li.svelte (10)
  - events/ae_comp__event_session_obj_tbl.svelte (1)
  - badges/print_list/+page.svelte (2), badges/templates/+page.svelte (1)
  - leads/ae_tab__manage.svelte (4)
  - hosted_files/+page.svelte (1), hold_video_util.svelte (6), video_util/+page.svelte (4)
- events/[event_id]/+page.svelte: converted JS icon strings to Lucide component refs
  (Presentation, Plane, IdCard, Contact) — rendered via <mod.icon size="2rem" />
- +page.svelte: hover:variant-outline-warning → hover:preset-outlined-warning (×2)
- migrate_fa_to_lucide.py: added 18 new icon mappings
  (ArrowLeft/Right, Ban, Broom→Trash2, calendar-alt, Database, DoorOpen, Download,
   exchange-alt, file-image, lock, magic→Sparkles, print, sticky-note, sync, tag,
   trash, user-ninja/tie→UserRound, video)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 14:25:18 -04:00
Scott Idem
8db806c6ab style(pres_mgmt): Phase 3 — FA→Lucide icon migration across all 24 pres_mgmt files
Used scripts/migrate_fa_to_lucide.py to batch-replace all FontAwesome
<span class="fas fa-*"> icons with Lucide SVG components across the
entire presentation management module (273 icon instances, 69 icon types).

Manual fixes applied post-script:
- presenter_view.svelte: remove duplicate @lucide/svelte Pencil import
- presenter_page_menu.svelte: remove duplicate X from @lucide/svelte import
- ae_comp__event_presenter_obj_tbl.svelte: fix Lucide import inserted
  inside multiline import block (script bug with multiline imports)
- ae_comp__event_session_alert.svelte: same multiline import fix
Script updated with fix: use complete-statement matching for import
insertion instead of single-line matching.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 14:01:56 -04:00
Scott Idem
1291b225c6 Svelte: fix 3 svelte-check warnings (non-IDAA) + Playwright test type error
- ae_comp__badge_print_controls: select_ref_badge_type declared as $state()
  so Svelte 5 tracks DOM ref assignment correctly (was plain let).
- launcher_cfg_section: <svelte:component this={icon}> replaced with
  let Icon = $derived(icon) + <Icon /> — svelte_component_deprecated fix.
- launcher_file_cont: same svelte_component_deprecated fix for FileIcon.
- badge_print_layout.test.ts: inject_idb signature changed from (badge, template)
  to ({ badge, template }) — page.evaluate() passes exactly one argument;
  all three call sites updated to pass { badge: mock_badge, template: mock_template }.
2026-03-16 13:51:01 -04:00
Scott Idem
6ca2314472 Badges: fix print page svelte-check error — extract print CSS to static file
Svelte 5 does not support <style> or conditional {#if} blocks wrapping
<style> tags inside <svelte:head>. The parser treats them as raw-text
elements and reports '<script> was left open' at EOF.

Fix:
- Print media CSS moved to static/ae-print-badge.css (plain static file,
  no framework magic needed — all selectors target global elements).
- svelte:head now uses a simple <link> to that file.
- $effect injects the @page size dynamically per template layout field,
  avoiding the Svelte 5 parser limitation for conditional style injection.
- Badge_template interface in db_events.ts: added cfg_json / data_json
  (standard Aether object fields that were missing from the type).
2026-03-16 13:50:28 -04:00
Scott Idem
338cfd4ec0 style: fix missed Phase 1/2 items — FA→Lucide, a11y, variant-* cleanup
- +layout.svelte: replace fa-cog/fa-spinner spinners with LoaderCircle;
  variant-filled-primary → preset-filled-primary on reload button
- events/+page.svelte: fa-calendar-alt → CalendarDays, fa-exclamation-triangle
  → TriangleAlert (+ text-red-500 → text-error-500), fa-spinner → LoaderCircle
- sign_in_out.svelte: fa-times → X, fa-sign-in-alt → LogIn
- journals/+layout.svelte: fa-arrow-right → ArrowRight
- journal_entry_header.svelte: fix focus:ring-0 → focus:ring-2 focus:ring-primary-500
  (WCAG 2.1 AA — removes keyboard focus indicator violation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 13:31:21 -04:00
Scott Idem
efc0f46079 style(launcher): Phase 3 — FA→Lucide icon migration across all launcher files
Replaces all FontAwesome <span class="fas/fab fa-*"> with Lucide Svelte
components across 20 launcher files. launcher_cfg_section.svelte icon prop
changed from FA string to AnyComponent (svelte:component for dynamic render).
Dynamic file-extension icon now uses ae_util.file_extension_icon_lucide().
Fixes class: directives on components (invalid in Svelte 5) → ternary class.
Removes title prop from Lucide components → wrapping <span title="...">.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 12:33:37 -04:00
Scott Idem
99df204763 style: Phase 1+2 — FA→Lucide, variant-* → preset-*, dark mode forms
Phase 1 (global quick wins):
- app.css: add global dark mode utility for .input/.select/.textarea
- events menu nav + layout: replace all FontAwesome icons with Lucide
- events settings: replace FA icons, standardize variant-* → preset-*

Phase 2 (module-by-module migration):
- root +layout.svelte: fix hardcoded banner colors → preset-filled-error/warning
- journals entry list: replace slate-* with gray-*, HSL eye colors → CSS tokens
- pres mgmt presenter view: variant-soft-warning → preset-tonal-warning, FA edit → Lucide
- badges (4 files): variant-* → preset-*, FA spinner → Lucide Loader2, dynamic alert fix
- events session list + event hub: variant-soft/filled → preset-tonal/filled
- leads module (12 files): complete variant-* → preset-* migration across all
  exhibitor sign-in, QR scanner, manual search, tracking list, manage tab,
  custom questions, license list, exhibit page, lead detail page + form

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 11:53:07 -04:00
Scott Idem
a79be722ae feat: add require_auth prop to hosted file download button
- Defaults to true (authenticated_access required) — no change to existing consumers
- Launcher file buttons set require_auth=false to allow unauthenticated downloads
2026-03-16 11:00:45 -04:00
Scott Idem
0d554e434d fix(launcher): sync monitor native-only, repositioned, always-visible chip, light/dark responsive; add mode button tooltips 2026-03-16 10:39:56 -04:00
Scott Idem
75e8a87713 feat(launcher): add launcher_menu/header/footer URL params to URL builder; strip after apply 2026-03-16 10:39:23 -04:00
Scott Idem
11d7632571 feat(events): collapse session description by default with toggle 2026-03-13 17:44:21 -04:00
Scott Idem
e4cb968659 fix(launcher): implement reliable click-outside-to-close for cfg drawer
Flowbite's built-in outsideclose was unreliable for this side-drawer setup.
Root cause: Flowbite's _onclick handler uses dlg.getBoundingClientRect() to
detect backdrop clicks. This works in theory for showModal() dialogs, but
something in the Svelte transition / stacking context prevented it firing.

Fix: bypass Flowbite's detection entirely.
- onclick prop on <Drawer> is spread through Flowbite's restProps chain
  to the native <dialog> element, overriding the broken _onclick handler.
  Handler: just closes the drawer unconditionally.
- A stopPropagation wrapper div around all visual panel content ensures
  that clicks INSIDE the panel never bubble up to the dialog element.
  Only genuine backdrop clicks (outside the visual panel area) reach
  the dialog and trigger the close handler.

ESC key is unaffected — it fires oncancel not onclick.
2026-03-13 15:53:01 -04:00
Scott Idem
456674cc3e fix(launcher): remove ghost Flowbite close btn; add working Close btn in footer
The Flowbite Dialog component (which Drawer wraps internally) renders a
<CloseButton type='submit'> by default when dismissable=true. Since the
Drawer does not use the form/dialog mechanism, that button appeared at the
bottom of the drawer but did nothing. Fix: dismissable={false} on the cfg
Drawer suppresses it.

launcher_cfg.svelte footer redesigned:
- Lower-left: Close button (always visible) — mirrors top-right X, useful
  when the user has scrolled down through long config sections
- Lower-right: Reload (always visible, shorter label)
- Full-width Debug Panel button (edit_mode only, below the row)

Click-outside behavior unchanged — Flowbite Dialog outsideclose defaults
to true, so tapping outside the drawer still closes it.
2026-03-13 15:07:46 -04:00
Scott Idem
bf22b4a512 fix(launcher): fix cfg drawer medium-width wrapping; rename Hardware→Device tab; native OS in edit_mode
- launcher_cfg_section.svelte: Remove md:grid-cols-2 from content wrapper.
  Root cause of the middle-width layout issue: at md breakpoint the drawer
  is only 384px wide but the section body switched to 2-column, cramming
  full-width content blocks into ~170px each. Always grid-cols-1 now.

- launcher_cfg.svelte: Rename Hardware tab to Device (neutral — applies
  even in browser). Reorder Device tab content: Sync Timers first (relevant
  to all devices), then native sections behind $ae_loc.is_native || edit_mode.
  Updates still hidden behind is_native only (no useful preview).

- launcher_cfg_native_os.svelte: Add dev-preview banner when edit_mode is
  on but not running in Electron. electron_relay.ts guards all calls with
  'if (!native) return null' so there are no import errors or crashes —
  controls simply show with a warning indicator. Removes stale placeholder
  comment left by a previous agent.
2026-03-13 14:54:28 -04:00
Scott Idem
71795461dd feat(launcher): reorganize cfg drawer into Setup/Hardware/Dev tabs
- Setup (default): Oral/Poster preset, WS Controller, Screen Saver
- Hardware: Electron health/OS/updates (native only) + Sync control
- Dev: Local reset/debug tools — tab hidden until Edit Mode is on

Edit Mode toggle added as subtle pencil icon in the cfg drawer header
(low opacity when off, primary-colored when active). This is intentional
— onsite kiosk operators should not stumble on it, but admins doing
setup can find and toggle it without leaving the drawer.

Dev tab visibility and the Debug Panel button both gate on edit_mode,
keeping the default view clean for non-technical operators.
2026-03-13 14:28:23 -04:00
Scott Idem
ce0c8b03c9 feat(launcher): Oral/Poster Kiosk mode preset toggle + ae_mode WS command
Adds a two-button Session Mode Preset toggle in Display & App Modes cfg:
- 'Oral / Default' restores all menus/headers/iframe off
- 'Poster Kiosk'   sets iframe=true + hides menu, header, footer

When WS is connected (local_push or remote controller), tapping a preset
sends ae_mode:poster / ae_mode:oral to all connected devices so an operator
can reconfigure the whole room from one device.

ae_mode:{poster|oral} command handler added to handle_ws_recv() in
+layout.svelte — receives and applies the same preset on remote devices.
2026-03-13 13:58:37 -04:00
Scott Idem
1417fafcd3 feat(launcher): auto-apply kiosk URL params on Launcher link for poster sessions
When on a Poster Session in Pres Mgmt, the Launcher nav link now appends
?iframe=true&launcher_menu=hide so the recipient opens a clean kiosk view
without the site header or left session panel.

- ae_comp__events_menu_nav: add events__launcher_extra_params prop; update
  launcher_sess_qry to merge extra params after session_id
- session_page_menu: derive is_poster from type_code and pass the kiosk
  params into the Launcher link
2026-03-13 13:41:49 -04:00
Scott Idem
a5a5022143 fix(launcher): remove wasted top space in iframe/menu-hidden mode; vh bottom buffer
events/+layout.svelte:
  the events nav is actually rendered. Adds pt-0 for the launcher case
  (nav never rendered there; launcher manages its own header offset).
- pb-48 (fixed 12rem) → pb-[25vh] — scrolls ~25% of viewport below
  last card on any screen size, scales properly on phone/tablet/desktop.

launcher/+layout.svelte outer wrapper:
- Static mt-4 replaced with conditional:
    mt-12 when launcher header is visible (matches h-12 header height,
           keeps content clear of the absolute overlay)
    mt-2  when launcher header is hidden (minimal breathing room only)
- Result: iframe mode + launcher_header=hide → near-zero top dead space
2026-03-13 13:24:03 -04:00
Scott Idem
e3e81226a0 feat(launcher): URL params to control iframe/menu/header/footer visibility
Allows sharing a clean link that auto-configures display state on any
device — no manual setup required, ideal for tablet PWA kiosk deployment.

All four params are optional and independent. Values persist in
localStorage so they survive reloads; the URL param always wins when
present. Read inside the existing reactive URL-sync $effect, which
fires on every SPA navigation (unlike the root onMount which only
fires once on initial load).

Supported params:
  ?iframe=true/false          — hide/show global sys & debug menus
  ?launcher_menu=hide/show    — hide/show left session/location panel
  ?launcher_header=hide/show  — hide/show 'Æ Launcher v3' header bar
  ?launcher_footer=hide/show  — hide/show the status footer

Example clean poster-kiosk link:
  /events/{id}/launcher/{loc_id}?session_id={sess_id}
    &iframe=true&launcher_menu=hide&launcher_header=hide
2026-03-13 13:16:26 -04:00
Scott Idem
0c18eea31c refactor(pres_mgmt): consistent layout, menu structure, and centering
- Add (pres_mgmt)/+layout.svelte with shared section wrapper (max-w-7xl mx-auto)
  so all child pages center correctly on wide viewports
- Strip per-page outer <section> tags from session, presenter, location pages;
  replace with inner <div max-w-7xl mx-auto> for detail constraint
- Restructure all page menus from flex-row to flex-col so nav bar occupies its
  own row and options/actions sit in a separate justified row below — prevents
  unwanted wrapping when nav is w-full
- Standardize Æ Core button visibility to edit_mode && manager_access across all
  menus; update button style to ae_btn_warning for visual distinction
- Add w-full + justify-between to ae_comp__events_menu_nav outer div

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 13:11:23 -04:00
Scott Idem
752dca290a feat(launcher): dedicated Digital Poster session card-grid view
Create launcher_session_view_posters.svelte — a touch-first card-grid
layout for Digital Poster sessions, designed for tablet/phone PWA use.

Layout:
- 1 column on mobile, 2 on sm, 3 on xl
- Each poster card: title (line-clamp-3) + presenter name/affiliation +
  'Open Poster' action button at card bottom
- Poster code (or 1-based index fallback) badge in top-right corner
- Card active:scale-[0.98] for tactile touch press feedback
- Sticky compact session header strip with name, code, and poster count
- Optional 'Session Resources' strip for rare session-level files
- overflow-y-auto + grow so the grid scrolls; header strip stays fixed

Integration:
- launcher_session_view.svelte: import + delegate when type_code==='poster'
- launcher_file_cont.svelte: min-w-96 → w-full on poster button so it
  fills its container (card or list row) without overflow on small screens
- WS open/close/zoom command pipeline unchanged (all in launcher_file_cont
  and +layout.svelte which were not modified for the WS paths)
2026-03-13 12:42:12 -04:00
Scott Idem
5f1169bb4c fix(launcher): use parent type_code for session_type, not per-file field
The event_session_type_code field on file objects is often null, causing
poster-mode files to fall back to 'oral' and render as download buttons
instead of modal openers.

- launcher_session_view: session-level files now use derived type_code
- launcher_presenter_view: add session_type prop (default 'oral'); parent passes type_code
- launcher_presenter_view_posters: hardcode poster/modal (only ever rendered in poster context)
- launcher_menu event/location files unchanged: no session context, field is the only signal
2026-03-13 11:46:17 -04:00
Scott Idem
c29ac9f9f5 fix(pres_mgmt): use w-full on Session and Presenter page sections
Session ID page: replace `container mx-auto` with `w-full` — removes the
Tailwind breakpoint max-width cap that was narrower than the outer layout's
max-w-7xl on smaller desktop viewports, and eliminates the double-padding
from nested container classes.

Presenter ID page: replace the conflicting `md:container items-center mx-auto
h-full min-w-full max-w-max` with a clean `w-full`. The `items-center` was
the main bug — in flex-col context it horizontally centered children (presenter
details, file upload form, file list) at their content width instead of
stretching them to fill the available space. Removes all of the conflicting
min/max width overrides.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 11:05:55 -04:00
Scott Idem
633930f65a refactor(pres_mgmt): menu consistency — modal pattern, prop cleanup, styling
All 6 *_page_menu.svelte files now consistently use:
- Flowbite Modal (not expandable panels) with matching header/close pattern
- interface Props (no export keyword) with only props actually used
- flex flex-row flex-wrap gap-0.5 on ae_menu__object_options span

Removed unused props and their call-site bindings:
- location_page_menu: removed data prop; +page.svelte drops data={data}
- locations_page_menu: removed unused log_lvl prop
- presenter_page_menu: removed data prop; +page.svelte drops {data}
- event_reports_page_menu: removed data prop; +page.svelte drops {lq__event_obj} data pass

event_page_menu: fixed interface export keyword (was export interface)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 11:05:02 -04:00
Scott Idem
26dbe57b22 fix(pres_mgmt): migrate QR generation from API to js_generate_qr_code
The API-based generate_qr_code was returning 404 (backend endpoint broken),
causing TypeError crashes on the Presenter, Session, and Location views.
Switch all three to the pure-JS js_generate_qr_code('str', { str: url_str })
which uses the qrcode npm library client-side — consistent with badge views.

- presenter_view.svelte: replace generate_qr_code, remove unused qr_id_url var
- session_view.svelte: replace generate_qr_code, remove unused slct import
- location_view.svelte: replace generate_qr_code, remove unused slct/slct_trigger imports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 11:02:04 -04:00
Scott Idem
b18cda98b7 feat(launcher): poster modal zoom sync, clean close buttons
- Add modal_zoom_fit state (default: fit); resets on every new poster open
- Zoom/Fit toggle button + image double-tap on controller tablet
- Both zoom triggers send ae_zoom:fit/zoom over WS to remote display (local_push)
- ae_zoom: handler added to handle_ws_recv() for remote device
- Replace 3 scattered close buttons with single bottom control bar:
    - [Zoom/Fit] always visible on controller
    - [Close Both] sends ae_close WS + clears local modal (local_push only)
    - [Back to List] clears local modal only; remote keeps showing current poster
- Bottom bar hidden on controller=remote (kiosk display-screen mode)
- native pinch-to-zoom via touch-action: pinch-zoom on img (no JS library needed)
- pb-14 on modal bodyClass prevents buttons from overlapping poster content
2026-03-12 19:57:33 -04:00
Scott Idem
cfa9e85d05 feat(badges): add demo background pattern toggle in edit mode
Adds a 🎨 button to the badge debug bar (edit-mode only) that cycles
through 5 SVG background patterns keyed by badge type color palette:
stripes, dots, diamonds, grid, swirls.

Swirl tile is 64×64 with corner-to-corner cubic bezier S-curves so
edges align seamlessly when tiled. Off by default; never prints.
2026-03-12 19:23:21 -04:00
Scott Idem
c867795f4d Badges: use position:fixed for print centering — bypasses all ancestor layout issues 2026-03-12 18:25:31 -04:00
Scott Idem
5410bb4a8c Badges: switch to transform-based print centering — fixes Firefox physical printer shift 2026-03-12 18:08:27 -04:00
Scott Idem
bc23e8a399 Badges: fix Firefox print centering (overflow:auto+display:contents); add print layout Playwright tests 2026-03-12 17:58:33 -04:00
Scott Idem
5ef66af98d Badges: fix print centering — override overflow:hidden on body/html in print 2026-03-12 17:46:50 -04:00
Scott Idem
1e70271002 Badges: add temp print debug outlines — diagnose centering issue 2026-03-12 17:32:31 -04:00
Scott Idem
05aa0288cb Badges: fix print centering — dissolve .main_content; hide footer/scroll buttons from print; document print layout architecture 2026-03-12 17:28:25 -04:00
Scott Idem
f26416de22 Badges: print centering via display:contents — collapse wrappers, body as flex center 2026-03-12 17:21:56 -04:00
Scott Idem
11a6d5d35c Badges: center badge vertically + horizontally in print preview; scaffold print_margin_cfg 2026-03-12 17:05:41 -04:00
Scott Idem
c3a4ff45c7 Badges: clean print output — suppress outlines, hide app chrome, reset layout container 2026-03-12 16:52:17 -04:00
Scott Idem
25359f12b8 Badges: soft feathered glow around badge wrapper in dark mode 2026-03-12 16:43:11 -04:00
Scott Idem
dd2deb1ab1 Badges: fix debug pre dark mode colors; white ring shadow around badge in dark mode 2026-03-12 16:31:26 -04:00
Scott Idem
745067b228 Badges: force light-mode rendering on badge print area — ignore dark theme 2026-03-12 16:26:21 -04:00
Scott Idem
6e8f44b009 Badges: center badge wrapper via mx-auto so Edit Mode debug div doesn't shift layout 2026-03-12 16:15:55 -04:00