Commit Graph
100 Commits
Author SHA1 Message Date
najdek 3c42e3cf0e fix: bound JSON extraction and decode Unicode escapes 2026-10-12 18:48:23 +02:00
najdek 0d39bd5cf4 fix: preserve Unicode and complete escapes in JSON encoding 2026-10-12 18:02:02 +02:00
najdek 608d7fa5f2 fix: clean up terminated HTTP requests and bound autoload lists 2026-10-12 17:54:16 +02:00
najdek 9b863e8020 fix: release HTTP responses and report allocation failures 2026-10-12 17:09:40 +02:00
najdek 60ac0bb988 fix: integrate external link modal with history navigation to prevent exiting page on back button 2026-10-12 03:23:10 +02:00
najdek 9e4978dc2c fix: constrain README width, add link confirmation modal and support non-GitHub sources 2026-10-12 03:10:07 +02:00
najdek 27541b197f fix: include source in repository payload JSON to enable README fetching
- Serialize source and source_direct in /repository_payloads JSON response
- Serialize source and description in /list_payloads for installed repository slots
- Add source_direct fallback for repository URL resolution in PayloadDetailPanel
2026-10-12 03:00:26 +02:00
najdek 8c627657fa fix: visual indication during payload install and live status update in details panel
- Add installing/updating button loading states with spinner in PayloadDetailPanel
- Prevent abrupt modal and detail dismiss on install click
- Dynamically resolve statusInfo to reflect installed state immediately upon completion
- Add Installed badge in details screen header
- Resolve friendly repository names for 'Also installed from <repo name>' and conflict dialogs instead of raw URLs
- Populate fallback repository name during slot metadata load and legacy migration
2026-10-12 02:53:55 +02:00
najdek dd29218f06 fix: resolve stack overflow crash during repository install and improve DNS failure resilience 2026-10-12 02:36:59 +02:00
najdek e3362e3527 feat: restrict repository icons to inline data URIs and document specifications 2026-10-12 02:22:47 +02:00
najdek ba529e8917 refactor: remove kill disc player on startup functionality
- Remove disc player termination call from daemon startup in main.c
- Remove ps5_kill_disc_player, get_pid_by_name, and unused LncUtil externs
- Remove KILL_DISC_PLAYER_ON_STARTUP from config storage and HTTP endpoints
- Remove Kill Disc Player toggle row from SettingsView
2026-10-12 01:40:09 +02:00
najdek 265c827e7f feat(frontend): redesign autoload view layout, card styling, and instant sync
- Place Available Payloads on the left and Autoload Sequence on the right
- Style payload cards in both columns to match dashboard (icons, badges, and title scroll on focus)
- Wrap available payloads in matching glass-panel container with visible borders
- Remove subtitle from Add Delay card
- Reduce top and bottom margins on autoload view to fill viewport cleanly
- Implement instant configuration saving with keepalive and pagehide/beforeunload sync
2026-10-12 01:33:55 +02:00
najdek e23c017961 style(frontend): compact dashboard payload card spacing and center row items vertically 2026-10-12 00:51:55 +02:00
najdek fec2928b14 fix(frontend): dismiss modals and exit dashboard modes on back button 2026-10-12 00:51:42 +02:00
najdek a1c152a203 feat: persist dashboard favorites in backend across all browsers
- Store favorites in /data/pldmgr/favorites.txt on backend
- Return FAVORITES and FAVORITES_INITIALIZED in /get_config
- Parse and save FAVORITES in /set_config POST handler
- Automatically update/remove favorites entries on slot delete, replace, and legacy migration
- Sync favorites state from backend in frontend on startup and persist updates
- Include one-time migration from localStorage for existing clients
2026-10-12 00:06:09 +02:00
najdek fde985c7d8 feat(frontend): display repository source badge under version on dashboard
- Move repository badge to a new line under version and author
- Style with matching badge aesthetics as version pill
- Replace "Manual" badge for local/manual payloads with "Other Source"
- Remove legacy absolute bottom-right placement to prevent overlaps
2026-10-11 23:56:39 +02:00
najdek 125d628dd0 chore: remove translations submodule and add TRANSLATIONS.md
- Remove frontend/src/locales git submodule and track translation files directly
- Credit JensJ56 for Dutch translation
- Move supported languages and past translator credits to TRANSLATIONS.md
- Document that translations since v0.6.0 are generated via Google Gemini AI
- Add issue reporting link for translation feedback
2026-10-11 23:37:56 +02:00
najdek 37f5b3b6cf fix(installer): recursively create app directories for fresh systems
On clean PS5 systems with no prior apps or games installed, /user/app does not exist yet, causing direct mkdir() on /user/app/<title_id> to fail with ENOENT (errno: 2).

Use recursive mkdir_p to create the required directory tree (/user/app/<title_id>/sce_sys).

Resolves #108
2026-10-11 23:12:30 +02:00
najdek aedf1bf31a Merge pull request #109 from kianborg/fix/repository-timeout-autoload 2026-10-11 23:07:05 +02:00
najdek 098f1c3a47 refactor: remove self-update mechanism and exclude pldmgr from repo listings
- Remove startup self-update check and chainloading in main.c
- Remove self-update logic and ELF version inspection from repository.c and repository.h
- Neuter /update_check route to return status none
- Remove update banners, notifications, and settings toggle from frontend
- Exclude pldmgr from repository payload listings and block installing pldmgr as a payload
- Add launch guards in HTTP server and autoload worker preventing pldmgr self-execution
2026-10-11 23:04:18 +02:00
najdek bb9deccc7e fix(frontend): resolve PS5 WebKit onload popstate exit and add runtime polyfills
- Ignore WebKit initial onload popstate on root dashboard to prevent premature exit
- Add polyfills for RegExp named capture groups, Array/String at, replaceAll, and queueMicrotask
- Add top-level React ErrorBoundary and window error diagnostic overlays
- Configure Vite/Terser for safari10/11 compatibility and keep console errors
- Defensively guard version formatting, URLs, and favorite move directional arrows
2026-10-11 18:27:57 +02:00
najdek 13a034175f feat: redesign payload storage with managed slots and stable identifiers
- Implement managed slot layout: repo/<id>@<srchash8> and local/<key> with meta.json sidecars
- Decouple user uploads and USB imports from repository matching and updates
- Use stable slot keys for autoload.txt, favorites, launching, and deletion
- Add strict token-based version comparison in C and JS, hiding install button when repo is older
- Support cross-source duplicate handling (keep both vs replace) with conflict modals
- Auto-refresh stale repository caches on install and retry seamlessly
- Implement one-time legacy storage migration on startup (layout version 2)
- Update CUSTOM_REPOSITORIES.md with id field specifications and comparison rules
- Remove deprecated /repository_push and /repository_install_push routes
- Add full test suite for versions, payloadStatus, helpers, and markdown
2026-10-11 11:33:31 +02:00
najdek 9b4c73168e feat(frontend): overhaul Get Payloads grid, detail view, and add URL state persistence
- Redesign Get Payloads grid into wide 3-column cards with icon on left, version top-right, dynamic title width, max 3-line description, and bottom-right installed checkmark

- Overhaul Payload Details panel with hero header, compact action button, author, repository link, short description, and raw GitHub README rendering with stripped images

- Implement URL hash state persistence and hierarchical history navigation for views and deep payload links (#/payload/:filename?src=:id)

- Add unit test suite for history navigation and route parsing

- Update locales submodule pointer with new detail view translations
2026-10-10 23:38:55 +02:00
najdek 8e395dca4d feat(frontend): implement PS5 browser back button history navigation
- Port history navigation strategy from pkg-manager to prevent PS5 Circle button from exiting browser
- Seed baseline history stack with Dashboard at root entry 0
- Navigate between top-level pages via replaceState so Back always returns directly to Dashboard
- Allow deep sub-views (Sources under Settings, Move from USB under Storage) to pop back to parent views
- Intercept modal/panel closures (confirmations, downloads, logs, payload details, dashboard edit modes) on Back press
- Exit browser via window.close / history.back only when Back is pressed from Dashboard root
2026-10-10 22:28:57 +02:00
najdek dea099432a feat(ui): redesign Get Payloads section header and controls 2026-10-10 22:16:43 +02:00
najdek eb4795b1b1 fix(ui): allow clicking anywhere on payload button to delete in manage mode 2026-10-10 22:00:10 +02:00
najdek e4e72dc9d8 Bump version to 0.5.2 2026-09-29 12:30:50 +02:00
najdek 8fd3212ec5 fix: resolve minor ui and backend validation issues
This addresses the remaining minor issues outlined in ISSUES.md.

- Extracted remaining hardcoded English strings into i18n locales

- Fixed stale state and implemented lazy-loaded images in PayloadDetailPanel

- Revived 'installed' payload state in StorageHub by no longer filtering them out

- Fixed event propagation bug in dashboard manage mode where clicking anywhere triggered delete

- Hardened C backend 'is_pldmgr_filename' to strictly match pldmgr prefixes, preventing false positives
2026-08-10 18:32:42 +02:00
najdek 675a1df0ef chore(i18n): update locales submodule 2026-08-10 18:11:22 +02:00
najdek 8534a75584 feat(ui): add update notifications toggle to settings
This addresses the missing UI toggle for the SHOW_UPDATE_NOTIFICATIONS config key.

- Added toggle to SettingsView under Startup section

- Wired toggle state directly to the config file via /set_config

- Included i18n keys for the new settings labels
2026-08-10 18:11:13 +02:00
najdek 701ac66f9b fix(ui): inject dashboard icons and metadata from repository context
This addresses the issue where dashboard payloads lacked icons.

Instead of passing the icon through the C backend's payload list, this leverages the existing `RepositoryContext` remote catalog.

- Wrapped the root `App` in `RepositoryProvider` inside `main.jsx`.

- Added `filenameMap` to `RepositoryContext` to build a fast O(1) lookup map of all payload metadata across sources.

- Injected the map data directly into Dashboard `PayloadButton` cards.
2026-08-10 18:01:08 +02:00
najdek b1f4fa0044 fix(core): resolve critical json parsing and self-update issues
This addresses the top two critical issues identified in ISSUES.md.

Backend C Fixes:

- Added `skip_top_level_wrapper()` and `find_next_object_start()` to `repository.c` to correctly parse payloads even when wrapped in a top-level JSON object or containing stringified braces.

- Updated `repository_check_self_update` and `repository_check_repo_update` to return full version, filename, and source metadata required by the frontend.

Frontend React Fixes:

- Updated the `App.jsx` update banner to properly consume the API contract.

- Added a functional `handleApplyUpdate` to load the downloaded self-update elf.

- Added a functional `handleInstallUpdate` to trigger repository installation when a new version is available.
2026-08-10 17:42:32 +02:00
najdek 56c7a7e0bf perf(ui): optimize payload icons and refine text marquee behaviors
- Removed heavy CSS shadows from payload icons for smoother scrolling

- Implemented dual-element approach for payload name marquee animations

- Re-labeled manage view to 'Remove Payload' when active
2026-08-10 16:02:51 +02:00
najdek 087093a872 fix(ui): center short payload names in repository grid 2026-08-10 15:57:40 +02:00
najdek cb3fbf4716 feat(repository): overhaul payload repository to app store experience
This commit completely redesigns how users browse, view, and install payloads.

Backend C Changes:
- Updated C structures to support multiple concurrent payload sources (config.h, repository.h).
- Modified repository.c and config.c to parse and retain multi-source JSON payloads.
- Allowed the HTTP server to serve the dynamically merged JSON sources.

Frontend React Changes:
- Converted StorageHub.jsx into a grid-based "App Shop" catalog layout.
- Replaced the modal payload view with a seamless full-page PayloadDetailPanel.jsx component for extended markdown reading and details.
- Added RepositoryContext.jsx to unify repository fetching across views.
- Styled payload cards with a dynamic marquee animation for overflowing text names (PayloadName.jsx).
- Allowed external icons, with a fallback placeholder for payloads without one.
- Polished padding, margins, and transition effects for spatial controller navigation.
- Removed duplicate versioning strings in payload titles and tweaked dashboard header text.
2026-08-10 15:56:38 +02:00
najdek 218f291d0e docs: fix crowdin badge IDs after adding new language 2026-08-06 10:07:33 +02:00
najdek eaa2d0a884 bump version to v0.5.1 and update changelog 2026-08-02 15:06:54 +02:00
najdek 38125c9123 i18n: update translations 2026-08-02 15:05:55 +02:00
najdek 0e09431349 frontend: fix race condition when killing processes (#79) 2026-07-23 22:50:15 +02:00
najdek bb6a425bf0 bump version to v0.5.0 and update changelog 2026-07-21 22:50:31 +02:00
najdek 3d3721e523 update translations and readme 2026-07-21 22:46:40 +02:00
najdek 3b15b5ca26 feat: Add payload launch indicator
Introduces a visual indicator to help track payloads launched during the current session.

Backend:
- Create history_mgr.c to track the last 20 launched payload paths
- Log payloads in ps5_launcher.c upon successful launch
- Add /history_list API endpoint to expose the launch history
- Update Makefile

Frontend:
- Fetch and poll /history_list in App.jsx to maintain launch history state
- Add isLaunched prop to PayloadButton.jsx to render a checkmark indicator

Closes #44
2026-07-21 22:19:50 +02:00
najdek 8195cd0c0f i18n: rename All Payloads to Others 2026-07-21 20:51:10 +02:00
najdek d84dcc41e0 i18n: update translations 2026-07-21 20:04:34 +02:00
najdek 19cbde2912 bump version to 0.4.2 and update changelog 2026-07-20 21:56:07 +02:00
najdek 312dbb5b8b i18n: add new translations 2026-07-20 21:52:51 +02:00
najdek 1174447254 Merge branch 'fix/frontend-build-missing-locales' 2026-07-20 20:46:32 +02:00
najdek 45f411c9a8 i18n: sync latest translations and update supported languages
- Update `frontend/src/locales` submodule to pull in the latest translations from Crowdin
- Add translators for newly supported languages: German, Persian, and Ukrainian to README
- Fix Crowdin badge URLs for Italian, Portuguese (Brazilian), and Russian which shifted after adding Persian
2026-07-20 20:32:43 +02:00
najdek 7b454e6164 bump version to 0.4.1 and update changelog 2026-07-20 01:09:11 +02:00
najdek 1c1eda870f i18n: add new translations 2026-07-20 00:58:17 +02:00
najdek dabd5dfde7 i18n: add translations for default repository categories 2026-07-19 18:25:57 +02:00
najdek e5997d968e docs: update README.md 2026-07-19 17:43:11 +02:00
najdek 1a73d1e8bc bump version to 0.4.0 and update changelog 2026-07-19 17:16:20 +02:00
najdek b88336f8ed i18n: enable automatic browser language detection
The app will now automatically detect and use the user's browser language on first load. We can safely do this since only high-quality languages (70%+ translated) are enabled anyway.
2026-07-19 16:57:02 +02:00
najdek 09f9f41d6b i18n: update translations 2026-07-19 16:43:28 +02:00
najdek 18111a65d0 docs: add translator credits and progress badges to README 2026-07-19 14:24:04 +02:00
najdek 6baaa76a96 i18n: standardise "Installation failed" fallback string 2026-07-19 13:41:33 +02:00
Mateusz Najdek 915e643f97 Merge pull request #66 from owendswang/fix/static-third-party-linking
build: link third-party dependencies statically
2026-07-19 03:37:10 +02:00
Mateusz Najdek 4a7f3c9204 docs: Add translation guidelines to README
Added translation guidelines for community contributions.
2026-07-19 03:29:06 +02:00
najdek 832fab5950 feat: introduce multi-language support (i18n)
Introduces a complete localization system using i18next, enabling the application to be translated into multiple languages by the community via Crowdin.

Key additions:
- Core i18next integration with English as the default base language.
- A language selector in the Settings menu for users to easily switch languages.
- Full UI localization, including support for complex grammar rules (e.g., dynamic pluralization) and responsive text layouts.
- A dedicated `locales` git submodule to seamlessly sync community-driven translations.
- Automatic filtering of incomplete languages (under 70% translated) to ensure a high-quality user experience.

Note:
This implementation currently applies exclusively to the frontend web UI. Native PS5 system notifications (triggered by the backend C code) remain in English and are not yet covered by this localization system.
2026-07-19 03:11:12 +02:00
Mateusz Najdek a0fcc0c742 docs: update CHANGELOG.md 2026-07-17 19:09:26 +02:00
najdek 1f90d9f1ce docs: update CHANGELOG.md for v0.3.3 release 2026-07-17 18:16:25 +02:00
najdekandlucaszhongsj 5d91c61b8f fix(frontend): use version field from repository payloads
When a repository payload explicitly defines a version, use it instead of trying to guess the version out of the filename.

Closes #60

Co-authored-by: lucaszhongsj <20980720+lucaszhongsj@users.noreply.github.com>
2026-07-17 18:00:19 +02:00
najdekandlucaszhongsj 1eb4e4b556 feat: move launcher icon to Media category
Sets applicationCategoryType to 65536 so the app appears in the Media tab rather than the Games tab on the PS5 home screen.

Closes #62

Co-authored-by: lucaszhongsj <20980720+lucaszhongsj@users.noreply.github.com>
2026-07-17 17:51:01 +02:00
najdek cd9ad1f0fe fix: restart MHD server after standby wake and network loss
After suspend/resume, the listening socket becomes stale but the
watchdog only checked for IP changes — if WiFi was already off,
no restart happened and 127.0.0.1:8084 became unreachable.

Force a full MHD stop/start on SIGCONT and also when network is
lost, so loopback access always works.
2026-07-17 12:49:41 +02:00
najdek 352860a472 fix: ensure application installer utility is terminated on error and completion paths 2026-07-03 01:00:47 +02:00
najdek 5715c0f11f feat(frontend): add payload sorting options to cloud repository
- Added a dropdown to sort repository payloads by Category (default), Update Time, or Name
- Sorting by Update Time or Name automatically flattens the list (disables category grouping)
- Sort preference is persisted across sessions via `localStorage`

Resolves #47
2026-06-25 19:46:29 +02:00
najdek 5551aaa24d feat(frontend): add search functionality to cloud repository view
- Added a search input to the repository view that filters payloads by name, filename, and description
- Searching automatically un-collapses all sources
- Searching automatically disables category grouping to show a flat list of matching results
2026-06-25 19:38:37 +02:00
najdek a44346b8e0 feat: add custom payload categories & increase source limits
- Increased MAX_SOURCES to 50 and refactored SourceEntry allocations to the heap
- Added `category` field to payload schema (defaults to "Uncategorized")
- Updated repository UI to group payloads into collapsible category sections
- Auto-expand categories if 10 or fewer payloads are available
- Updated CUSTOM_REPOSITORIES.md

Resolves #30
2026-06-25 19:22:40 +02:00
najdek bacab16df7 fix: Add fallback to insecure download on SSL verification failure
Fixes #42

If github.com (Sectigo ECC) or its redirects cause mbedTLS to fail
verification due to cross-signed certificate chains or unsupported
ECC curves in the PS5 SDK, curl will now catch CURLE_PEER_FAILED_VERIFICATION
and automatically retry the download without SSL verification.

This is completely safe because repository.c securely verifies the
SHA256 checksum of the downloaded ELF against the trusted payloads.json
metadata before installing it.
2026-06-17 19:56:02 +02:00
najdek 9049eec7ba fix: Resolve intermittent SSL verification failures with mbedTLS
Older versions of curl using the mbedTLS backend require the PEM buffer
passed via CURLOPT_CAINFO_BLOB to be explicitly NUL-terminated, with the
length field including the NUL byte. Since the auto-generated
assets_cacert_pem array lacked this terminator, mbedTLS would read past
the buffer bounds, causing sporadic 'SSL peer certificate or SSH remote
key was not OK' errors depending on the memory layout.

This commit dynamically allocates a slightly larger buffer to append the
missing NUL terminator before passing it to curl, ensuring deterministic
certificate parsing across all environments.

Also bumped version to 0.3.2.
2026-06-15 21:31:24 +02:00
najdek 21f4fded71 fix(frontend): resolve iOS file upload restriction
Omit `accept` attribute on iOS so payload files are not greyed out in the Files app. Also drops unused lua support.
Fixes #39
2026-06-12 21:02:09 +02:00
najdek cfbc70f30f bump version to v0.3.1 2026-06-07 01:23:25 +02:00
najdek 5c88211d49 feat: allow users to copy instead of move when importing from USB
Updates the USB import flow to provide explicit buttons for 'Copy to Internal' and 'Move to Internal'. The backend route now accepts a keep_original flag to optionally skip removing the source file.
2026-06-07 01:16:13 +02:00
najdek 897e8df455 fix: remove original file after importing USB payload to internal storage
The `payload_mgr_usb_move` function was only copying the file and leaving the original on the USB drive, despite returning a 'Moved successfully' message. It now correctly deletes the source file to complete the move operation.
2026-06-07 01:08:40 +02:00
najdek c2daee9e30 fix: limit payload scanning depth to prevent infinite loading on large USB drives
The big refactor in 2189ee9 accidentally removed the max_depth constraint on the recursive scanner. This caused SCAN_USB_PAYLOADS to exhaustively scan the entire drive rather than just the root folder, resulting in infinite loading states on the dashboard.
2026-06-07 01:05:25 +02:00
najdek 69216b8de9 fix: increase RESPONSE_BUFFER_SIZE to 1MB to prevent JSON truncation 2026-06-06 23:53:44 +02:00
najdek 7093de7208 docs: update CHANGELOG.md for v0.3.0 release 2026-06-04 23:45:52 +02:00
najdek 2a12e84283 fix: restore overwrite confirmation prompt for payload uploads
During the recent storage refactoring, `payload_mgr_check_existing` was updated to return a simplified `{"exists": true}` structure. However, the frontend (`App.jsx`) still relied on the `file_exists` and `folder_exists` boolean flags to display the overwrite confirmation modal when a duplicate payload is uploaded. Because those fields were missing, the frontend silently fell through and overwrote the files without asking.

This change restores the original JSON output format for the `/manage:check` endpoint (`file_exists`, `folder_exists`, and `folder_name`), ensuring the overwrite prompt appears again when an uploaded ELF already exists.
2026-06-03 19:37:56 +02:00
Mateusz Najdek 72e781867a Update credits section in README.md 2026-06-02 13:43:45 +02:00
Mateusz Najdek 09a95ccd82 Update CHANGELOG for version 0.2.0 release 2026-06-02 08:51:55 +02:00
najdek 10b786b555 ci: add on-demand release workflow 2026-06-02 00:48:55 +02:00
najdek 9e5ea12bf1 bump version to v0.2.0 2026-06-02 00:36:47 +02:00
najdek 0380757957 backend: remove payload scanning logs 2026-06-02 00:36:10 +02:00
najdek 6d14acf665 frontend: scroll to USB Storage section when navigating from Autoload 2026-06-02 00:33:29 +02:00
najdek 75b20ceff4 frontend: scroll to top of main content container on view change 2026-06-02 00:30:08 +02:00
najdek 7dee294ad0 frontend: update download modal title 2026-06-02 00:25:11 +02:00
najdek 2e7de34648 frontend: update SettingsView layout to responsive grid and improve UI consistency 2026-06-01 23:36:03 +02:00
najdek 10c4233eea frontend: fix DonateView layout 2026-06-01 23:14:29 +02:00
najdek 75700847e8 frontend: persist sidebar expanded state
The sidebar's expanded/collapsed state is now saved in `localStorage`. This ensures that if the user collapses the sidebar, it stays collapsed after reloading the page or returning to the app later.
Implemented via a `useState` lazy initializer and `useEffect` hook in `App.jsx`.
2026-06-01 23:06:42 +02:00
najdek 5ff5295120 fix: clean up empty directory after payload deletion
fixes issue #24
2026-06-01 22:57:44 +02:00
najdek bfc4d096c5 Fix loading payloads from USB root
- Allow /mnt/usb paths in is_allowed_payload_path
- Expose pldmgr_read_config_bool globally

Closes #18
2026-05-28 13:03:29 +02:00
najdek 1ebcf988d4 Update deploy.sh to remove deprecated curl shutdown step 2026-05-28 00:14:00 +02:00
najdek 6772ae3a4e Merge branches 'pr-12', 'pr-13', 'pr-15' and 'pr-17' 2026-05-28 00:13:55 +02:00
najdek cfba6b8237 build: use dedicated docker image ps5-payload-sdk-pldmgr to prevent image tag conflicts 2026-05-24 01:54:49 +02:00
Mateusz Najdek cad957fa21 Update GitHub funding username to itsPLK 2026-05-11 18:16:30 +02:00
najdek 1baa48e4f3 release: v0.1.1 - stability and ui refinements 2026-05-02 14:02:27 +02:00
najdek 193807f70c fix: autoload sync, log viewer overlay, and layout refinements 2026-05-02 13:53:40 +02:00
najdek 90cd196f5b fix: resolve autoload synchronization, rendering, and layout issues 2026-05-02 13:40:08 +02:00
najdek 1535c7baed fix(frontend): improve compatibility for older firmware (PS5 4.03, iOS 12)
- Downgrade to Tailwind 3 for better legacy support
- Target Safari 12 in build pipeline
- Add CSS fallbacks for critical layout classes
- Flatten CSS layers via Tailwind 3 output
2026-05-02 12:16:29 +02:00