Skip to content

feat(Captive Portal): update styling, add support for theme.css per connection profile#9071

Merged
satkunas merged 29 commits into
develfrom
INV-263/captive-templates_rebranding
Jul 7, 2026
Merged

feat(Captive Portal): update styling, add support for theme.css per connection profile#9071
satkunas merged 29 commits into
develfrom
INV-263/captive-templates_rebranding

Conversation

@takrasiu-inv

@takrasiu-inv takrasiu-inv commented May 29, 2026

Copy link
Copy Markdown
Contributor

Description

Provide the way to customize Captive Portal, by adding branded background image and applying own brand theme.
Update the resolving assets mechanism for background, logo png files and theme.css file to file-based instead of config ( only logo has it's as a fallback ).
By default new customers will have new files for a captive portal: background.png and theme.css ( empty CSS rules which might be edit ) for a default connection profile. The inheritance for these files works for new connection profiles until files will be overridden.

By removing background.png file from default connection profile the branded backgroung color will be applied.

Core changes

  • New /common/background.png branded Akamai file.

  • New /common/theme.css as a placeholder CSS file.

  • Updated Captive Portal *.scss styling, added CSS variables in order to apply customer's branded theme.

  • Added light | dark themes to Captive Portal.

  • Updated the way for resolving theme assets based on file existence in connection profile.

  • Updated documentation customizing_packetfence.asciidoc by adding description for modifying the theme and changing background image.

  • Provide the CSS variables ( for configuration and for internal use ).

  • Updated styles in order to support modern and old browsers.

  • Updated packetfence-cp.png logo and default background Akamai branded background.png from Akamai resources

Impacts

  • Captive portal templates html/captive-portal/templates
  • JS, CSS files which is used by Captive Portal html/common/*
  • Changes to docs customization_packetfence.asciidoc
  • Updated thehtml/captive-portal/lib/captiveportal/PacketFence/DynamicRouting/Application.pm to resolve required assets "background_url", "theme_path", "logo" as well.
  • Replaced default log html/common/packetfence-cp.png with a new branded PF.
  • Removed unused CSS classes and JS funcs
  • Fixed incorrect styling in docs/styles/app.css for navigation links ( sidebar ) which has <code/>
  • Updated root Makefile added 2 commands to copy background and theme from /common/* to default connection profile.
  • Updated the installation rpm steps, with commands above.
  • Updated the httpdportalpreview.go ( httpd.admin_dispatcher ) for updating src urls for the new element source.

Delete branch after merge

YES

Checklist

(REQUIRED) - [yes, no or n/a]

  • Updated styles.css should be minified and present in PR.
  • Removed styles-dark.css, styles-map.css no need.
  • Minify styles.css
  • Dark | Light theming switch should work
  • Should be possible to create own theme.css in separate connection profile.
  • CSS documentation should be present in theme.css, only major rules.
  • Update the documentation customization_packetfence.asciidoc
  • Should be possible to add background image
  • Should be possible to DISABLE background image and use static background color.
  • The background image should not be downloaded for smaller screens ( < tablet ).

Attachments

Screenshot 2026-06-03 at 21 05 38 Screenshot 2026-06-03 at 21 05 52 Screenshot 2026-06-03 at 21 06 09 Screenshot 2026-06-03 at 21 07 03 Screenshot 2026-06-03 at 21 09 25 Screenshot 2026-06-03 at 21 09 39

@takrasiu-inv takrasiu-inv marked this pull request as ready for review June 3, 2026 18:24
@takrasiu-inv takrasiu-inv changed the title Inv 263/captive templates rebranding feat(Captive Portal) - add theme.css, update CSS rebrading Jun 11, 2026
@takrasiu-inv takrasiu-inv changed the title feat(Captive Portal) - add theme.css, update CSS rebrading feat(Captive Portal): update styling, add support for theme.css per connection profile Jun 11, 2026
@takrasiu-inv takrasiu-inv force-pushed the INV-263/captive-templates_rebranding branch 2 times, most recently from d17ae9c to 8ca6ccf Compare June 11, 2026 11:59
@satkunas satkunas added this to the PacketFence-15.2 milestone Jun 16, 2026
@takrasiu-inv takrasiu-inv marked this pull request as draft June 18, 2026 09:25
@takrasiu-inv takrasiu-inv marked this pull request as ready for review June 18, 2026 12:23
@jrouzierinverse jrouzierinverse requested a review from Copilot June 22, 2026 15:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes PacketFence Captive Portal theming by introducing CSS-variable–based styling (light/dark support) and enabling per-connection-profile asset overrides via file presence (theme.css/background.png/logo.png), with packaging/install hooks to seed defaults.

Changes:

  • Add theme.css and background.png support per connection profile, and update asset resolution in the captive portal renderer.
  • Rework captive portal CSS/SCSS to use --pf-* CSS custom properties and add light/dark theming (including removal of the old styles-dark.css).
  • Update build/packaging/docs and portal preview URL rewriting to account for the new assets and markup.

Reviewed changes

Copilot reviewed 58 out of 62 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
rpm/packetfence.spec RPM install step now seeds default profile theme.css and background.png.
Makefile Adds targets to copy theme.css/background.png into default profile templates.
html/common/theme.css New theme customization template documenting --pf-* variables.
html/common/styles.css Updated/minified compiled CSS with CSS variables + dark mode support.
html/common/styles-dark.css Removes legacy dark stylesheet.
html/common/scss/styles.scss Imports new theme settings and updates heading size.
html/common/scss/_utilities.text.scss Updates caption styling to use CSS vars; adds .no-select.
html/common/scss/_settings.theme.scss New layer exporting theme tokens as CSS custom properties (light/dark/light-dark()).
html/common/scss/_settings.packetfence.scss Defines light/dark palette tokens and layout constants.
html/common/scss/_settings.global.scss Removes global transition variable (no longer used).
html/common/scss/_settings.colors.scss Replaces static SCSS colors with CSS-var wrappers + internal constants.
html/common/scss/_objects.tables.scss Uses new $pf-primary-color.
html/common/scss/_objects.media.scss Restyles notice/error blocks with theme tokens + dark overrides.
html/common/scss/_objects.box.scss Updates backgrounds/border accents to use theme tokens.
html/common/scss/_objects.aup.scss Adds themed scrollbar styling.
html/common/scss/_elements.page.scss Sets base typography from CSS vars; adds responsive background image styling.
html/common/scss/_elements.headings.scss Adjusts h1 weight and color via theme tokens.
html/common/scss/_elements.header.scss Adds .pf-logo styling and removes header background override.
html/common/scss/_elements.footer.scss Moves client info styling into .c-footer-info; suppresses stray <footer>.
html/common/scss/_components.timerbar.scss Theme-aware timerbar styling with layered fallbacks.
html/common/scss/_components.input.scss Theme-aware inputs + focus ring fallbacks; mobile tap improvements.
html/common/scss/_components.iconic.scss Theme-aware SVG icon fill colors.
html/common/scss/_components.frame.scss Theme-aware frame styling + modern border/shadow strategy.
html/common/scss/_components.dot.scss Adds tap UX tweaks and theme-aware dot styling.
html/common/scss/_components.divider.scss Divider now uses --pf-divider-color.
html/common/scss/_components.buttons.scss Theme-aware button styles, disabled styling, and dark-mode variants.
html/common/pf.js Improves key handling using classList + e.key.
html/common/package.json Adds postcss-custom-properties dependency (used by Grunt postcss).
html/common/package-lock.json Locks the new PostCSS plugin and its transitive deps.
html/common/Makefile Excludes styles.css.map from distribution file list.
html/common/Gruntfile.js Disables dist sourcemaps; runs postcss-custom-properties in dist/dev pipelines.
html/captive-portal/templates/sms/validate.html Fixes invalid HTML inside <a> elements.
html/captive-portal/templates/layout.html Adds theme link + responsive background picture + logo class + client info block changes.
html/captive-portal/templates/emails/emails-security_event-triggered.html Removes body background inline style (wrapper still provides background).
html/captive-portal/templates/emails/emails-renewal_certificate.html Same body style adjustment.
html/captive-portal/templates/emails/emails-pki_certificate.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_sponsor_preregistration.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_sponsor_confirmed.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_sponsor_activation.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_password_reset.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_password_of_the_day.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_local_account_creation.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_email_preregistration.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_email_preregistration_confirmed.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_email_activation.html Same body style adjustment.
html/captive-portal/templates/emails/emails-guest_admin_pregistration.html Same body style adjustment.
html/captive-portal/templates/emails/emails-fleetdm-policy-violation.html Same body style adjustment.
html/captive-portal/templates/emails/emails-fleetdm-cve.html Same body style adjustment.
html/captive-portal/templates/emails/emails-billing_stripe_customer.subscription.deleted.html Same body style adjustment.
html/captive-portal/templates/emails/emails-billing_confirmation.html Same body style adjustment.
html/captive-portal/lib/captiveportal/PacketFence/DynamicRouting/Application.pm Adds _resolve_theme_assets() and passes theme/background/logo to layout.
html/captive-portal/content/guest-management.js Removes unused legacy JS.
html/captive-portal/content/ChilliLibrary.js Removes unused legacy JS library.
html/captive-portal/content/billing/authorizenet.js Removes unused billing JS.
html/captive-portal/content/autosubmit.js Removes unused autosubmit JS.
go/httpdportalpreview/httpdportalpreview.go Adds rewriting support for <source> tags and srcset.
docs/styles/app.css Fixes code styling in sidebar TOC by scoping code colors.
docs/developer/customizing_packetfence.asciidoc Documents logo/background/theme.css customization and inheritance behavior.
debian/packetfence.postinst Seeds default profile theme/background assets during Debian install/upgrade.
Files not reviewed (1)
  • html/common/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread html/captive-portal/templates/layout.html
Comment thread html/common/package.json Outdated
Comment thread debian/packetfence.postinst Outdated
Comment thread html/common/scss/_components.divider.scss Outdated
Comment thread html/common/scss/_components.buttons.scss
Comment thread html/common/scss/_components.buttons.scss Outdated
Comment thread html/common/scss/_components.buttons.scss
Comment thread html/common/scss/_components.dot.scss
Comment thread html/common/theme.css
@takrasiu-inv takrasiu-inv force-pushed the INV-263/captive-templates_rebranding branch from ed1bf53 to 115b299 Compare June 23, 2026 10:28
@takrasiu-inv takrasiu-inv force-pushed the INV-263/captive-templates_rebranding branch 3 times, most recently from 88506d6 to dde2d9c Compare July 7, 2026 08:36
…er-profile theme.css

- Add CSS custom property system (--pf-*) for full runtime theming without
  a build step; light/dark token values defined as flat SCSS variables in
  _settings.packetfence.scss and emitted via _settings.theme.scss
- Dark mode via @media (prefers-color-scheme: dark) fallback (Chrome 76+,
  FF 67+, Safari 12.1+) and light-dark() progressive enhancement (Chrome
  123+, FF 120+, Safari 17.5+); operator can force a mode with color-scheme
- Logo filter defaults to none (light) / brightness(0) invert(1) (dark);
  note: light-dark() does not apply to filter values, only @media is used
- Add captive-portal/templates/theme.css: per-profile customisation template
  with all --pf-* vars commented out and FORCE DARK fallback block
- layout.html: load theme via [% IF theme_path %] before page renders;
  remove data-color-scheme JS attribute approach
- Delete unused html/common/theme.css and html/common/styles-dark.css
- _settings.colors.scss: all vars use var(--pf-*, fallback) including
  $pf-footer-background-color; fix stale filename reference
- styles.css, _elements.page.scss: wire --pf-font-size-base,
  --pf-font-weight-normal/heading; rename settings.css-vars → settings.theme
…tton state

- Remove transition: all (buttons) and border-color/box-shadow (inputs)
- Replace all rgba() and opacity transparency with pre-computed solid colors
- Disabled buttons: absolute ::after backdrop + muted text via CSS variables
  (--pf-btn-disabled-text, --pf-btn-primary/secondary-disabled-overlay)
  with light/dark values in _settings.packetfence/theme/colors.scss
- Expose disabled button vars in captive-portal/templates/theme.css
… remove .o-page wrapper

- Move IP/MAC client info from <footer> into the card bottom with a full-width
  divider; remove the <footer> element from layout.html
- Add --pf-background-image CSS variable (default: none); background-color,
  background-image, background-size/position/repeat and background-attachment:
  fixed all on html so the image is viewport-pinned on long pages
- Remove .o-page wrapper div (no longer needed now that background lives on html)
- Make header transparent so background image shows through it
- Remove dead 'footer .c-divider' rule from _components.divider.scss
- Add --pf-background-image: none default to _settings.theme.scss (:root)
- Comment out --pf-background-image entry in theme.css operator reference
- Docs: add 'CSS Background Image' section with dimension/format recommendations
  (1920×1080 min, 2560×1440 preferred, 16:9 JPEG ≤ 300 KB)
- touch-action: manipulation on .c-btn, .dot, checkbox labels — eliminates
  the 300ms tap delay on older iOS / Android browsers
- -webkit-tap-highlight-color: transparent on all tappable elements — removes
  the default gray/blue tap flash on iOS and Android Chrome
- pf.js: replace deprecated e.which with e.key in tabbable keyup handler;
  replace strict className equality check with classList.contains() so elements
  with multiple classes are matched correctly
- Add bg-akamai.png (Akamai Orange 1440×900) as background on tablet+ (≥740px)
- Replace packetfence-cp.png with new PacketFence-only logo (372×110px)
- Dark mode secondary ghost buttons render filled (#1878bd); darken on hover
- Card border visible in light (#d4d4d4) and dark (#2c2f43) mode; no box-shadow
- Remove title/logo divider from layout.html; add margin-top to .pf-logo
- Trim theme.css; Gruntfile/Makefile: disable sourceMap in dist
- Update docs: single bg image, logo size guidance
- Remove unused JS: ChilliLibrary.js, authorizenet.js, guest-management.js,
  captive-portal/content/autosubmit.js (duplicate of common/autosubmit.js)
- o-media--notice/error: tinted solid backgrounds (mix() pre-computed),
  4px colored left border, dark text; dark mode tints and lighter border colors
- c-timerbar: track uses --pf-media-border-color; fill uses --pf-color-secondary
- c-frame--raised: modern 0 2px 8px shadow; dark mode restores 1px border ring
- c-btn--tertiary: transparent background in dark mode (link appearance)
- c-btn--ghost.c-btn--secondary: filled in dark mode, darkens on hover
- Status colors are fixed SCSS values — not overridable via theme.css
- Remove background-color from <body> inline style in all email templates
  (background now controlled by layout/captive portal wrapper)
- Keep background-color:#F2F2F2 on wrapper <div> for email client rendering
- Fix email preview footer: email templates contain </body></html> which
  causes browser HTML error recovery to push layout content into a
  browser-generated <footer> element; suppress with body > footer { display:none }
- sms/validate.html: remove stray </p> tags inside <a> elements
Add _resolve_theme_path helper that checks profile-specific theme.css first,
falls back to default connection profile, and returns undef if neither exists —
matching the same fallback pattern used by the logo field.
An empty profile-templates/default/theme.css would shadow the base
templates/theme.css, causing _resolve_theme_path to serve a blank theme.
Add a -s guard so zero-byte files are skipped in the lookup.
Renames all public CSS custom properties to a consistent semantic scheme
(--pf-primary-color, --pf-text-base-color, --pf-error-color, etc.) and
removes implementation-detail variables from the operator-facing API:

- Hover/disabled/overlay button states → compile-time SCSS constants
- Border colors (frame, media) → derived via color-mix() from their parent
  background; three-tier fallback: IE static hex → var() → color-mix()
- Footer background, input label/border/border-width → removed or aliased
- Spacing collapsed to --pf-spacing-base: 6px (atomic unit)

Internal CSS custom properties (frame/media border fallbacks, input
background, focus ring, font-family) are blocked in _settings.theme.scss
with a clear INTERNAL comment banner.

Updates theme.css template, customizing_packetfence.asciidoc reference
table, and rebuilds styles.css.
- Background rendered on body::before pseudo-element (fixed, full
  viewport, tablet+ only); default is packetfence-background.png
- Renamed html/common/img/bg-akamai.png → packetfence-background.png
- Removed --pf-background-image CSS custom property; background is set
  via a direct url() rule in the profile's theme.css using a relative
  path (constraint: absolute paths bypass the admin preview proxy)
- theme.css template: concise how-to comment with constraint note
- customizing_packetfence.asciidoc: background image section updated
- SCSS: remove decorative/obvious comments, keep only non-obvious ones
  (three-tier cascade rationale, internal markers, Sass color-function
  constraint, computed-value origins)
- Dark mode: add @media block for disabled button colours — compile-time
  vars had no dark override after CSS custom property removal
- Button hover (primary, secondary, tertiary): derive shade from
  --pf-*-color via color-mix() so operator color overrides apply to hover
- Ghost secondary dark-mode hover: same fix
- Input focus ring: color-mix() tints to match --pf-primary-color
- c-frame--raised dark-mode border ring: fix @media query
- customizing_packetfence.asciidoc: replace 7 variable tables with a
  single practical example; remove tiny 6th-level heading
- Auto-resolve logo, theme and background from filesystem in Profile.pm:
  profile-specific file in profile-templates/{name}/ takes priority,
  falls back to /common/theme.css and /common/background.png for theme
  and background, or the configured value for logo
- Move html/common/theme.css from captive-portal/templates/ (pure CSS,
  no TT directives; served as static asset alongside background.png)
- Remove profile-templates/default/{background,theme} install targets
  from Makefile — /common/ fallback makes them unnecessary
- Document per-profile theme.css customization in developer guide
Remove stale /common/theme.css fallback from the documented asset
resolution order and the _resolve_theme_assets pod comment — the fallback
was dropped in f8863d2. Clarify that /common/theme.css is the shipped
source copied to the default connection profile on install, and that if
neither the profile nor the default has a theme.css, no stylesheet is loaded.
… on decorative elements

Apply to background image, logo, and logout icon link in layout.html.
@takrasiu-inv takrasiu-inv force-pushed the INV-263/captive-templates_rebranding branch from dde2d9c to 46a4228 Compare July 7, 2026 08:37
@satkunas satkunas merged commit 78d79f2 into devel Jul 7, 2026
10 checks passed
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