Skip to content

style: Enhance server HTML files (phase 2)#837

Open
cdmoro wants to merge 28 commits intocrosspoint-reader:masterfrom
cdmoro:improve-html-server-style
Open

style: Enhance server HTML files (phase 2)#837
cdmoro wants to merge 28 commits intocrosspoint-reader:masterfrom
cdmoro:improve-html-server-style

Conversation

@cdmoro
Copy link
Contributor

@cdmoro cdmoro commented Feb 11, 2026

Summary

  • What is the goal of this PR? (e.g., Implements the new feature for file uploading.)

Overall improvement of the server HTML files, use of SVG (minified) instead of emojis, javascript enhacement, better support for mobile, etc.

File size increase

I know that file size is very important due to device memory restrictions, so I calculated the size of the modified files.

File Original size New size Difference (%)
HomePage 4.18 KB 4.94 KB +18.18%
FilesPage 43.7 KB 46.3 KB +5.95%
SettingsPage 11.2 KB 12.1 KB +8.04%

Changes

  • What changes are included?
  • Add logo
  • Enhance responsiveness
  • Move from specific styles (.upload-button) to Bootstrap-like styles (.btn-warning)
  • Clean JavaScript code (for example, use of switch instead of multiples ifs)
  • Use SVGs instead of emojis
  • Improve header and footer

Changes per file

  • Home Page
    • Improve responsiveness
  • Files Page
    • Highlight row when is selected
    • Use dialog (HTML element) instead of divs
    • Improve folder-summary legend, only shows what is in the folder:
      • Full: 1 folder, 5 files, 3.93 MB
      • Only files 5 files, 3.93 MB
      • Only folders 3 folders
  • Settings Page
    • Hide setting fields when a setting type is invalid
    • Implement toast instead of alerts

Additional Context

About the accent color

The green-ish color was taken from the title of this repository:
image

Phases

Next steps/Phases:

  1. Light/Dark themes [MERGED]
  2. HTML enhancement, use SVG instead of emojis [THIS PR]
  3. Use Vite + Typescript to improve DX and have better minification
  4. Load external CSS file to avoid duplication

Not included in this PR (hopefully more PRs will come)

  • Favicon
  • Load external CSS files (it would be super useful to avoid code duplication and reduce file size)
  • Load external JS files (same as above)
  • Internationalisation
  • Use of LocalStorage to save potential settings (like theme, language, etc.)
  • Light/Dark toggle button

Most of this are tied to the ability to import external files into the HTMLs.

Screenshots

Home Page

Desktop

Before After (light) After (dark)
image image image

Mobile

Before After (light) After (dark)
image image image

Files Page

Desktop

Before After (light) After (dark)
image image image

Mobile

Before After (light) After (dark)
image image image

Settings Page

Desktop

Before After (light) After (dark)
image image image

Mobile

Before After (light) After (dark)
image image image

AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? < NO >

@cdmoro cdmoro changed the title Update server style style: Update server style Feb 11, 2026
@cdmoro cdmoro changed the title style: Update server style [WIP] style: Update server style Feb 12, 2026
@cdmoro cdmoro changed the title [WIP] style: Update server style [WIP] style: Enhance server HTML files Feb 12, 2026
@cdmoro cdmoro changed the title [WIP] style: Enhance server HTML files style: Enhance server HTML files Feb 14, 2026
@cdmoro cdmoro marked this pull request as ready for review February 14, 2026 18:55
@jdk2pq
Copy link
Contributor

jdk2pq commented Feb 15, 2026

@cdmoro Thank you for the contribution! Here are some of my thoughts:

  • I'm a sucker for dark mode, so I'm always happy to see support for it. The actual CSS changes needed for this kind of support seem minor and not a significant factor in the increase in size of the HTML files.
  • However, I am a bit hesitant to approve this as is due to the file size increase in the HTML files.
  • Switching from an emoji glyph to an SVG icon has tradeoffs when it comes to file size: the emoji glyph is a text character and significantly smaller than its SVG equivalent, but emojis will render differently on different devices and SVGs solve that. Personally, I'm okay with the tradeoff of rendering emojis differently on different devices, since it results in a smaller footprint in these HTML files. I would suggest reverting back to emojis for that reason.
  • We currently have duplicated CSS across the 3 HTML files. I think we can factor these shared styles out into a .css file and include it with a <link> tag in each file to save on file size here.

TL;DR I do like this change and think it makes the Wifi Upload HTML look better, but I think we need some reduction in the file size increase that these changes come with before we can get this in.

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 15, 2026

@jdk2pq I'm totally agree with you. In fact, in the PR description I mentioned some of your points. It would be nice if we could put the JS and the CSS files in separate files (but I don't know if the server could serve those files with the current implementation), the same with the SVG icons.

I could try to optimize the files even more, for example, in the FilesPage.html file there are a lot of repetitive functions that can be grouped using parameters (each modal has its own openModal and closeModal function).

But apart from this change, I think we can go even further, have a Vite + Vanilla JS + TS web project that build the files (minified by Vite, with inline CSS and JS if needed), which improve a lot the developer experience (I was doing some test running this locally and hitting 192.168.0.68 successfully, which is great as we could see the changes live without flashing the device). But I will leave this for a future PR :D

Btw, thanks for the feedback, I will work on it.

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 15, 2026

@jdk2pq regarding the svg icons, I could try to reduce then as much as I can, removing the unnecessary ones like the upload button, for instance.

@Eloren1
Copy link
Contributor

Eloren1 commented Feb 20, 2026

Header logo doesn't look like original one

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 20, 2026

Header logo doesn't look like original one

@Eloren1 you're right, but I just copied the svg from https://github.com/crosspoint-reader/crosspoint-reader/blob/master/src/images/logo.svg which doesn't have the white background, so in that case I'd need to edit that SVG myself and use the modified version.

Good catch, thanks!

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 20, 2026

BTW, @jdk2pq it would be really useful to have the ability of importing external CSSs and SVGs, this will avoid duplication and the files will be smaller :) would you think that is possible?

btw, I'm working on another PR, a simpler one (#1006) that only adds the light & dark themes, I think we could move forward with that in the meantime. Let me know what you think.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Three HTML pages updated to a themable UI with CSS variables and dark mode, inline SVG iconography, responsive/card layouts, modernized modals; FilesPage adds a WebSocket-backed upload flow with per-file progress, HTTP fallback, and enhanced file-table rendering and retry UI.

Changes

Cohort / File(s) Summary
Files UI & Upload Flow
src/network/html/FilesPage.html
Reworked file listing to a grid/table hybrid; added CSS tokens and dark-mode support; introduced inline SVG icons and icon-based badges; consolidated modal header/footer layout; implemented WebSocket upload with per-file progress and HTTP fallback; added failed-uploads banner with per-item Retry and Retry All; mobile/responsive adjustments.
Home UI Theming
src/network/html/HomePage.html
Added CSS custom properties and prefers-color-scheme dark tokens; replaced header with inline logo SVG and structured H1; updated typography, card styles, nav layout, responsive tweaks, active nav state, and footer with GitHub link; preserved existing status-fetch logic.
Settings UI & API
src/network/html/SettingsPage.html
Introduced theme tokens and dark-mode rules; added inline logo and updated header/nav; replaced showMessage with toast API (showToast(text, type)); added VALID_SETTING_TYPES; changed saveSettings signature to saveSettings(event) and updated save flow to disable/reenable button and surface toast feedback; improved control rendering and validation.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Browser
participant WS as WebSocketEndpoint
participant HTTP as HTTPUploadEndpoint
participant Store as FileStorage
Browser->>Browser: Open Upload modal & select file(s)
Browser->>WS: Open WebSocket upload connection
alt WS connected
Browser->>WS: Send file metadata
loop per chunk
Browser->>WS: Send chunk
WS-->>Browser: Progress update
end
WS->>Store: Stream/store received file
Store-->>WS: Acknowledge complete
WS-->>Browser: Upload success
else WS fails
Browser->>HTTP: POST file via HTTP fallback
HTTP->>Store: Save file
Store-->>HTTP: Acknowledge
HTTP-->>Browser: Upload success/failure
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'style: Enhance server HTML files (phase 2)' clearly summarizes the main change: a comprehensive styling and UI/UX enhancement to the three server HTML files (HomePage, FilesPage, SettingsPage).
Description check ✅ Passed The PR description clearly outlines the goals (UI enhancement with SVGs, responsiveness, theming), details file-by-file changes, reports file size impacts, includes screenshots, and explains future phases and context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 20, 2026

Header logo doesn't look like original one

Logo updated @Eloren1 :)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/network/html/SettingsPage.html (1)

395-427: ⚠️ Potential issue | 🟡 Minor

renderControl returns undefined for unrecognized types, causing "undefined" to render in HTML.

When setting.type doesn't match any known type (toggle, enum, value, string), the function implicitly returns undefined. This value gets concatenated into HTML via renderControl(s) at line 480, rendering the literal string "undefined" in the DOM.

While line 476 filters by VALID_SETTING_TYPES, if any future code path bypasses this check or if VALID_SETTING_TYPES diverges from renderControl's switch cases, stale "undefined" text would appear.

Proposed fix: return empty string for unknown types
     if (setting.type === 'string') {
       const inputType = setting.name.toLowerCase().includes('password') ? 'password' : 'text';
       const val = setting.value || '';
       return '<input type="' + inputType + '" id="' + id + '" value="' + escapeHtml(val) + '"' +
         ' oninput="markChanged()">';
     }
+
+    return '';
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/SettingsPage.html` around lines 395 - 427, The renderControl
function can return undefined for unknown setting.type values which leads to the
literal "undefined" being inserted into the DOM; update renderControl (the
function named renderControl) to handle unknown/unsupported types by returning
an empty string ('' ) as the default fallback (e.g., after the existing type
branches) so any unrecognized setting types produce no output rather than the
string "undefined". Ensure the change covers the branches for 'toggle', 'enum',
'value', and 'string' and that callers using renderControl(s) will receive a
safe string result.
🧹 Nitpick comments (5)
src/network/html/SettingsPage.html (2)

366-371: Add rel="noopener noreferrer" to external link.

Same issue as in HomePage.html - the external link opens in a new tab but lacks the security attribute.

Proposed fix
     <a
       href="https://github.com/crosspoint-reader/crosspoint-reader"
       target="_blank"
+      rel="noopener noreferrer"
       >CrossPoint E-Reader • Open Source</a
     >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/SettingsPage.html` around lines 366 - 371, The external
anchor in SettingsPage.html (the <a
href="https://github.com/crosspoint-reader/crosspoint-reader"
target="_blank">CrossPoint E-Reader • Open Source</a> link) opens a new tab but
is missing the security attributes; update that anchor element to include
rel="noopener noreferrer" so the link uses the recommended security/safety
attributes when target="_blank".

265-269: Missing semicolon in CSS declaration.

Line 268 is missing a semicolon after color: var(--muted-color). While browsers tolerate this when it's the last declaration before a closing brace, it's inconsistent with the rest of the codebase and can cause issues if properties are added later.

Proposed fix
     .btn-primary:disabled {
       background-color: var(--accent-color-50);
       cursor: not-allowed;
-      color: var(--muted-color)
+      color: var(--muted-color);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/SettingsPage.html` around lines 265 - 269, The CSS rule for
the selector ".btn-primary:disabled" is missing a trailing semicolon after
"color: var(--muted-color)"; update the declaration in the .btn-primary:disabled
block to add the semicolon so the rule becomes "color: var(--muted-color);" to
match project style and avoid future parsing issues when adding properties.
src/network/html/FilesPage.html (2)

790-795: Add rel="noopener noreferrer" to external link.

Same issue as other pages - the external link opens in a new tab but lacks the security attribute.

Proposed fix
   <a
     href="https://github.com/crosspoint-reader/crosspoint-reader"
     target="_blank"
+    rel="noopener noreferrer"
     >CrossPoint E-Reader • Open Source</a
   >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` around lines 790 - 795, The external anchor
linking to "https://github.com/crosspoint-reader/crosspoint-reader" (the link
text "CrossPoint E-Reader • Open Source") opens in a new tab but lacks security
attributes; update that <a> element in FilesPage.html to include rel="noopener
noreferrer" alongside target="_blank" so the external link uses the recommended
security/privacy attributes.

443-445: Missing semicolon in CSS declaration.

Line 444 is missing a semicolon after color: var(--accent-color). While browsers tolerate this, it's inconsistent and can cause issues if properties are added later.

Proposed fix
     .delete-btn,
     .rename-btn,
     .move-btn {
       background: none;
       border: none;
       cursor: pointer;
       padding: 2px 3px;
       border-radius: 4px;
       transition: all 0.15s;
-      color: var(--accent-color)
+      color: var(--accent-color);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` around lines 443 - 445, The CSS rule that
currently reads "transition: all 0.15s; color: var(--accent-color)" is missing a
trailing semicolon after the color declaration; update the rule in
FilesPage.html to "transition: all 0.15s; color: var(--accent-color);" (add the
semicolon) and reformat to match surrounding style so future properties can be
added safely.
src/network/html/HomePage.html (1)

205-209: Add rel="noopener noreferrer" to external link for security.

The external link opens in a new tab via target="_blank" but lacks rel="noopener noreferrer". While modern browsers mitigate the window.opener vulnerability by default, adding this attribute is a defense-in-depth practice and ensures compatibility with older browsers.

Proposed fix
       <a
         href="https://github.com/crosspoint-reader/crosspoint-reader"
         target="_blank"
+        rel="noopener noreferrer"
         >CrossPoint E-Reader • Open Source</a
       >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/HomePage.html` around lines 205 - 209, The external anchor
element with href "https://github.com/crosspoint-reader/crosspoint-reader" (the
link text "CrossPoint E-Reader • Open Source") uses target="_blank" but lacks
rel attributes; update that <a> tag to include rel="noopener noreferrer" to
prevent window.opener attacks and ensure compatibility with older browsers.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a21082 and 370164c.

📒 Files selected for processing (3)
  • src/network/html/FilesPage.html
  • src/network/html/HomePage.html
  • src/network/html/SettingsPage.html
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cppcheck
  • GitHub Check: build
🔇 Additional comments (1)
src/network/html/HomePage.html (1)

1-233: LGTM for HomePage.html!

The theming implementation using CSS variables is clean, dark mode support via prefers-color-scheme is correctly implemented, and the fetchStatus JavaScript function has proper error handling. The code is well-structured overall.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/network/html/FilesPage.html`:
- Around line 829-834: The createFolder handler wired via the form's onsubmit
("createFolder(event)") doesn't accept or use the event and thus doesn't prevent
the browser's native submit; update the createFolder function to accept the
event parameter (e.g., function createFolder(event) {...}) and call
event.preventDefault() at the top (or alternatively return false) before
performing the XHR/async logic so the form doesn't perform a normal submit and
cause duplicate requests; ensure the function name createFolder referenced in
the HTML and JS match exactly.
- Around line 557-562: The hover rule for the CSS class .delete-btn-cancel
currently sets background-color to the same value as its non-hover state so
users get no hover feedback; update the .delete-btn-cancel:hover selector to use
a visibly different color (e.g., a slightly darker or lighter shade) or adjust
another property (border-color, box-shadow, filter:brightness) to provide clear
hover feedback while keeping the cancel button visually consistent with
.delete-btn-cancel.
- Around line 1070-1072: The openUploadModal function inserts user-controlled
currentPath into the DOM via uploadPathDisplay.innerHTML causing XSS; change
this to safely render the path by either HTML-escaping currentPath before
setting innerHTML or, simpler and safer, use uploadPathDisplay.textContent (or
create a text node) and append the home SVG separately so raw HTML is never
injected; update references in openUploadModal to set textContent for the path
and only add the SVG via DOM methods, ensuring uploadModal.classList.add('open')
remains unchanged.
- Around line 1468-1471: The modal title insertion uses innerHTML with unescaped
filename (openRenameModal, openMoveModal, openDeleteModal) which allows XSS;
change the implementation to avoid injecting the raw name into innerHTML — set
only the SVG/icon markup via innerHTML (or create the SVG element), then set the
filename using textContent or append a text node to the same container (e.g.,
element with id 'renameItemName', 'moveItemName', 'deleteItemName') so the icon
remains but the filename is rendered as plain text; likewise ensure the
corresponding path inputs ('renameItemPath' etc.) remain unchanged but never
populate any element via innerHTML with untrusted name values.

In `@src/network/html/SettingsPage.html`:
- Around line 387-393: showToast currently creates a new 4s timeout on every
call so earlier timeouts can hide a newer toast; modify showToast to store the
timeout id (e.g., on the toast element via toast._hideTimeout or
toast.dataset.hideTimeout) and call clearTimeout on the existing id before
creating a new setTimeout, then save the new id so repeated calls reset the
timer and prevent premature dismissal.

---

Outside diff comments:
In `@src/network/html/SettingsPage.html`:
- Around line 395-427: The renderControl function can return undefined for
unknown setting.type values which leads to the literal "undefined" being
inserted into the DOM; update renderControl (the function named renderControl)
to handle unknown/unsupported types by returning an empty string ('' ) as the
default fallback (e.g., after the existing type branches) so any unrecognized
setting types produce no output rather than the string "undefined". Ensure the
change covers the branches for 'toggle', 'enum', 'value', and 'string' and that
callers using renderControl(s) will receive a safe string result.

---

Nitpick comments:
In `@src/network/html/FilesPage.html`:
- Around line 790-795: The external anchor linking to
"https://github.com/crosspoint-reader/crosspoint-reader" (the link text
"CrossPoint E-Reader • Open Source") opens in a new tab but lacks security
attributes; update that <a> element in FilesPage.html to include rel="noopener
noreferrer" alongside target="_blank" so the external link uses the recommended
security/privacy attributes.
- Around line 443-445: The CSS rule that currently reads "transition: all 0.15s;
color: var(--accent-color)" is missing a trailing semicolon after the color
declaration; update the rule in FilesPage.html to "transition: all 0.15s; color:
var(--accent-color);" (add the semicolon) and reformat to match surrounding
style so future properties can be added safely.

In `@src/network/html/HomePage.html`:
- Around line 205-209: The external anchor element with href
"https://github.com/crosspoint-reader/crosspoint-reader" (the link text
"CrossPoint E-Reader • Open Source") uses target="_blank" but lacks rel
attributes; update that <a> tag to include rel="noopener noreferrer" to prevent
window.opener attacks and ensure compatibility with older browsers.

In `@src/network/html/SettingsPage.html`:
- Around line 366-371: The external anchor in SettingsPage.html (the <a
href="https://github.com/crosspoint-reader/crosspoint-reader"
target="_blank">CrossPoint E-Reader • Open Source</a> link) opens a new tab but
is missing the security attributes; update that anchor element to include
rel="noopener noreferrer" so the link uses the recommended security/safety
attributes when target="_blank".
- Around line 265-269: The CSS rule for the selector ".btn-primary:disabled" is
missing a trailing semicolon after "color: var(--muted-color)"; update the
declaration in the .btn-primary:disabled block to add the semicolon so the rule
becomes "color: var(--muted-color);" to match project style and avoid future
parsing issues when adding properties.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/network/html/FilesPage.html (2)

1296-1298: Remove unused speed variable or implement speed calculation.

The speed variable is declared but never used. Either remove it or implement the speed calculation as the comment suggests.

Proposed fix (remove)
     const onProgress = (loaded, total) => {
       const percent = Math.round((loaded / total) * 100);
       progressFill.style.width = percent + '%';
-      const speed = ''; // Could calculate speed here
       progressText.textContent = `Uploading ${file.name} (${currentIndex + 1}/${files.length})${methodText} — ${percent}%`;
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` around lines 1296 - 1298, Remove the unused
local variable speed declared in the upload progress handler (the const speed =
'' line) or implement an actual upload speed calculation and use it in
progressText.textContent; locate the handler that sets progressText.textContent
(`progressText`, `file`, `currentIndex`, `files`, `methodText`, `percent`) and
either delete the `speed` declaration or compute bytes/time delta and replace
`speed` with the computed value in the template so the variable is used.

897-930: Consider extracting shared SVG icons and CSS to external files.

The inline SVG icon set (~34 lines) and CSS variables/theme styles are duplicated across HomePage, FilesPage, and SettingsPage. Per PR discussion, this contributes significantly to the file size increase. If the ESP32 server can serve static assets, extracting shared CSS and SVG sprites to external files would:

  1. Reduce per-page payload through caching
  2. Improve maintainability by centralizing theme/icon definitions
  3. Enable minification in a future build pipeline
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` around lines 897 - 930, Extract the repeated
inline SVG sprite (symbols like id="icon-trash", "icon-edit", "icon-folder",
etc.) into a single external SVG sprite file (e.g., sprites.svg) and move
duplicated CSS variables/theme styles into a shared stylesheet (e.g.,
theme.css); then update FilesPage.html to remove the embedded <symbol> block and
instead reference the shared stylesheet with a <link rel="stylesheet"> and
reference icons with <use href="sprites.svg#icon-..."> (or the equivalent method
your server supports) so all pages (HomePage, FilesPage, SettingsPage) can reuse
the same assets served as static files. Ensure you keep the same symbol ids
(icon-trash, icon-edit, icon-folder, icon-epub, icon-file, icon-move-file,
icon-upload, icon-home, icon-warning, icon-info) and export the CSS custom
properties exactly as they appear so existing markup and classes continue to
work without further changes.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 25d6e5f and 6c7de9d.

📒 Files selected for processing (1)
  • src/network/html/FilesPage.html
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (9)
src/network/html/FilesPage.html (9)

937-952: LGTM!

The k constant is now properly defined at module scope (line 937), fixing the previous ReferenceError issue in formatFileSize.


1062-1064: LGTM!

The currentPath is now properly escaped with escapeHtml() before being inserted into innerHTML, addressing the previous XSS concern.


1241-1243: LGTM!

The uploadFile function now correctly accepts the event parameter and calls event.preventDefault(), preventing double form submission.


1422-1424: LGTM!

The createFolder function now correctly accepts the event parameter and calls event.preventDefault(), preventing double form submission.


1461-1464: LGTM!

The name parameter is now properly escaped with escapeHtml() in openRenameModal, addressing the previous XSS concern.


1577-1580: LGTM!

The name parameter is now properly escaped with escapeHtml() in openMoveModal, addressing the previous XSS concern.


1627-1630: LGTM!

The name parameter is now properly escaped with escapeHtml() in openDeleteModal, addressing the previous XSS concern.


1094-1203: LGTM!

The WebSocket upload implementation handles backpressure appropriately (line 1142-1144) and includes proper fallback logic. The chunked upload with progress tracking and error handling is well-structured for the ESP32 target environment.


1341-1369: LGTM!

The showFailedUploadsBanner function properly escapes both failedFile.name and failedFile.error before inserting into the DOM, preventing XSS.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/network/html/FilesPage.html`:
- Around line 806-808: The file input with id "fileInput" has no accessible
label; update the markup so the file chooser is announced by assistive tech —
either add a visible <label for="fileInput"> (e.g., "Choose files to upload")
placed before the input or add an aria-label/aria-labelledby attribute on the
input, and ensure any JS handlers (uploadFile(event), validateFile()) still
reference id "fileInput" unchanged; prefer a visible label for usability and
keyboard focus.

---

Duplicate comments:
In `@src/network/html/FilesPage.html`:
- Around line 560-562: The hover rule .delete-btn-cancel:hover currently sets
background-color to `#7f8c8d` which matches the non-hover .delete-btn-cancel, so
change the hover styling to provide visible feedback: update
.delete-btn-cancel:hover to use a different background-color (e.g., a slightly
darker or lighter hex) or add a visual change such as a border or box-shadow;
locate the CSS for .delete-btn-cancel and modify the :hover selector accordingly
to ensure a distinct hover state.
- Around line 790-794: The external anchor element that uses target="_blank"
(the <a href="https://github.com/crosspoint-reader/crosspoint-reader"
target="_blank">CrossPoint E-Reader • Open Source</a>) should include
rel="noopener noreferrer" to prevent tabnabbing and avoid giving the opened page
access to window.opener; update the anchor element where it renders that link to
add rel="noopener noreferrer" alongside target="_blank".
- Around line 1029-1050: The inline onclick attributes (calls to
openDeleteModal, openMoveModal, openRenameModal) are not safely escaping file
names/paths and risk JS injection; replace these inline handlers by storing
sanitized data in data-attributes (e.g., data-name, data-path, data-is-epub)
when building fileTableContent and remove the onclick strings, then add event
delegation listeners (or per-button listeners) that read and JSON.parse/unwrap
those attributes and call openMoveModal/openRenameModal/openDeleteModal;
alternatively, if you must keep inline calls, wrap each arg via JSON.stringify
when inserting into the template (use file.name/filePath through JSON.stringify)
to correctly escape quotes, backslashes and newlines—update the code that
constructs fileTableContent and the button elements (the move-btn, rename-btn,
delete-btn lines) and ensure escapeHtml, FILE_EXTENSION_REGEX and formatFileSize
usage remains unchanged.

---

Nitpick comments:
In `@src/network/html/FilesPage.html`:
- Around line 1296-1298: Remove the unused local variable speed declared in the
upload progress handler (the const speed = '' line) or implement an actual
upload speed calculation and use it in progressText.textContent; locate the
handler that sets progressText.textContent (`progressText`, `file`,
`currentIndex`, `files`, `methodText`, `percent`) and either delete the `speed`
declaration or compute bytes/time delta and replace `speed` with the computed
value in the template so the variable is used.
- Around line 897-930: Extract the repeated inline SVG sprite (symbols like
id="icon-trash", "icon-edit", "icon-folder", etc.) into a single external SVG
sprite file (e.g., sprites.svg) and move duplicated CSS variables/theme styles
into a shared stylesheet (e.g., theme.css); then update FilesPage.html to remove
the embedded <symbol> block and instead reference the shared stylesheet with a
<link rel="stylesheet"> and reference icons with <use
href="sprites.svg#icon-..."> (or the equivalent method your server supports) so
all pages (HomePage, FilesPage, SettingsPage) can reuse the same assets served
as static files. Ensure you keep the same symbol ids (icon-trash, icon-edit,
icon-folder, icon-epub, icon-file, icon-move-file, icon-upload, icon-home,
icon-warning, icon-info) and export the CSS custom properties exactly as they
appear so existing markup and classes continue to work without further changes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/network/html/FilesPage.html (1)

1114-1118: ⚠️ Potential issue | 🟠 Major

WebSocket protocol message is vulnerable to delimiter injection via filenames containing colons.

The START message parsing logic uses only the first two colons as delimiters, without escaping values. A filename containing colons (e.g., report:2024:draft.pdf) will corrupt the message parsing. The server will extract only the portion before the first unexpected colon as the filename, and interpret the remaining colons as delimiters, leading to incorrect file uploads or failures.

Since ESP32 SPIFFS/LittleFS filesystems allow colons in filenames, this is a real issue that can be triggered by legitimate user input.

Use JSON or a safe encoding instead:

Proposed fix using JSON
     ws.onopen = function() {
       console.log('[WS] Connected, starting upload:', file.name);
-      // Send start message: START:<filename>:<size>:<path>
-      ws.send(`START:${file.name}:${file.size}:${currentPath}`);
+      // Send start message as JSON for safe parsing
+      ws.send(JSON.stringify({ cmd: 'START', name: file.name, size: file.size, path: currentPath }));
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` around lines 1114 - 1118, The START
WebSocket message built in ws.onopen using
ws.send(`START:${file.name}:${file.size}:${currentPath}`) is vulnerable to
delimiter injection from colons in file.name or currentPath; change the protocol
to send a safe payload instead (e.g., JSON or Base64-encoded fields) so the
server can parse unambiguously: replace the START string construction with a
JSON object containing filename, size, and path (or otherwise escape/encode
file.name and currentPath) and update the server to parse that JSON; ensure the
change references ws.onopen, ws.send, and the fields file.name, file.size,
currentPath, and the START message handling on the server.
🧹 Nitpick comments (1)
src/network/html/FilesPage.html (1)

934-934: decodeURIComponent can throw on malformed URL encoding.

If the path query parameter contains malformed percent-encoding (e.g., ?path=%E0%A4%A), decodeURIComponent will throw a URIError, crashing page initialization.

Proposed defensive fix
-  const currentPath = decodeURIComponent(new URLSearchParams(window.location.search).get('path') || '/');
+  let currentPath = '/';
+  try {
+    currentPath = decodeURIComponent(new URLSearchParams(window.location.search).get('path') || '/');
+  } catch (e) {
+    console.error('Invalid path encoding:', e);
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/network/html/FilesPage.html` at line 934, The current assignment to
currentPath uses decodeURIComponent on the raw query value and can throw a
URIError for malformed percent-encoding; wrap the decode attempt in a try/catch
around the decodeURIComponent(new
URLSearchParams(window.location.search).get('path') || '/') expression (or
decode the retrieved rawPath into a variable first) and on failure fall back to
a safe default (e.g., '/') or the raw undecoded string, and ensure currentPath
is always a string; reference the currentPath variable and the
decodeURIComponent/URLSearchParams(window.location.search).get('path') call when
making the change.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7de9d and f98cf94.

📒 Files selected for processing (1)
  • src/network/html/FilesPage.html
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: cppcheck
🔇 Additional comments (4)
src/network/html/FilesPage.html (4)

1460-1471: LGTM on XSS fixes in modal functions.

The openRenameModal, openMoveModal, and openDeleteModal functions now properly escape the name parameter with escapeHtml() before inserting into innerHTML. This addresses the previously identified XSS vulnerability.


897-930: Good use of SVG sprite pattern.

The inline SVG sprite with <symbol> elements and <use href="#icon-..."> references is an efficient pattern for icon reuse, reducing DOM duplication while keeping icons self-contained in the HTML file.


8-75: LGTM on CSS theming implementation.

The CSS custom properties with light/dark mode support via prefers-color-scheme is well-structured. The use of --accent-color-rgb for alpha channel manipulation is a good pattern.


654-688: Good responsive table-to-grid transformation.

The approach of hiding table headers on mobile and using CSS Grid to restructure table rows provides a clean mobile experience while maintaining the semantic table structure for larger viewports.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/network/html/FilesPage.html`:
- Around line 1114-1118: The START WebSocket message built in ws.onopen using
ws.send(`START:${file.name}:${file.size}:${currentPath}`) is vulnerable to
delimiter injection from colons in file.name or currentPath; change the protocol
to send a safe payload instead (e.g., JSON or Base64-encoded fields) so the
server can parse unambiguously: replace the START string construction with a
JSON object containing filename, size, and path (or otherwise escape/encode
file.name and currentPath) and update the server to parse that JSON; ensure the
change references ws.onopen, ws.send, and the fields file.name, file.size,
currentPath, and the START message handling on the server.

---

Duplicate comments:
In `@src/network/html/FilesPage.html`:
- Around line 790-794: The external anchor element (the <a> tag with
href="https://github.com/crosspoint-reader/crosspoint-reader" and
target="_blank") is missing rel="noopener noreferrer"; update that anchor to
include rel="noopener noreferrer" alongside target="_blank" to prevent
tabnabbing and ensure the opened page cannot access window.opener.
- Around line 560-562: The .delete-btn-cancel hover rule is identical to its
default state so users get no visual feedback; update the .delete-btn-cancel
:hover selector to visibly differ (for example a slightly lighter/darker
background, a subtle border or box-shadow, or a scale/translate transform) and
add a transition on the base .delete-btn-cancel to animate the change—locate the
.delete-btn-cancel rule and its :hover rule and modify the hover properties and
add transition on the main selector to provide clear hover feedback.
- Line 1029: The inline onclick builds JS string arguments with
file.name.replaceAll("'", "\\'") which fails for backslashes/newlines and can
enable injection; fix by emitting safe JS literals using JSON.stringify for the
values (e.g. change onclick="openDeleteModal('${file.name.replaceAll...}',
'${folderPath.replaceAll...}', true)" to
onclick="openDeleteModal(${JSON.stringify(file.name)},
${JSON.stringify(folderPath)}, true)"), or better, remove the inline onclick and
attach the handler via an event listener reading data attributes (e.g. set
data-name and data-path on the .delete-btn and call openDeleteModal from a
delegated click listener); apply the same change to the other occurrences (lines
around 1047-1049) and update references to fileTableContent, .delete-btn, and
openDeleteModal accordingly.
- Around line 805-807: The file input lacks an accessible label and the
aria-label is incorrectly placed on the paragraph; move the accessibility markup
to the actual input by removing aria-label="fileInput" from the <p> and adding a
proper label associated with the input (either a <label for="fileInput">Select a
file (or multiple files) to upload to <strong
id="uploadPathDisplay"></strong></label> or an aria-label/aria-labelledby on the
input itself), keep the existing id="fileInput", multiple and required
attributes, and ensure existing handlers (validateFile(), uploadFile()) continue
to reference the same id so the code and accessibility are consistent.

---

Nitpick comments:
In `@src/network/html/FilesPage.html`:
- Line 934: The current assignment to currentPath uses decodeURIComponent on the
raw query value and can throw a URIError for malformed percent-encoding; wrap
the decode attempt in a try/catch around the decodeURIComponent(new
URLSearchParams(window.location.search).get('path') || '/') expression (or
decode the retrieved rawPath into a variable first) and on failure fall back to
a safe default (e.g., '/') or the raw undecoded string, and ensure currentPath
is always a string; reference the currentPath variable and the
decodeURIComponent/URLSearchParams(window.location.search).get('path') call when
making the change.

daveallie pushed a commit that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
@cdmoro cdmoro marked this pull request as draft February 22, 2026 10:21
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 22, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
crosspoint-reader#837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <[email protected]>
@cdmoro cdmoro changed the title style: Enhance server HTML files style: Enhance server HTML files (phase 2) Feb 26, 2026
@cdmoro cdmoro marked this pull request as ready for review February 27, 2026 21:18
@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 27, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 28, 2026

@lukestein @Eloren1 @jdk2pq I really appreciate your review here 😃

@cdmoro
Copy link
Contributor Author

cdmoro commented Feb 28, 2026

I minified the icons so I can also attach the unminified icons.svg to update the icons in the future, I used svgo to minify it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants