Fledge v0.6.2.1 "Plumage"
The Customizing Update: administrators can make the panel their own. Rename it, give it a logo, choose colours and a font, offer light and dark, restyle the sign-in page, add sidebar links and an announcement, all from Settings, Appearance, with readable colours enforced, a preview that rolls itself back, version history and a way out of a bad theme.
Highlights
- Appearance. A new editor with a live preview: identity, colours, type and shape, the sign-in page, navigation, an announcement and advanced tools. Until someone changes something, the panel looks exactly as before.
- Your name everywhere. The panel name, short name and logo appear in the sidebar, sign-in page, browser tab and icon, home-screen icon, emails, notifications, authenticator apps and the passkey prompt.
- A light theme, and your own palette. Eight presets (Fledge, Midnight, Ember, Terminal, Paper, Snow, Violet, High contrast), each in dark and light, or an accent colour and a tint from which Fledge calculates the rest. Every person can pick light, dark or "match this device" for themselves.
- Readable by construction. Every text and colour pair is checked (WCAG ratios, a stricter AAA mode, colour-blind-safe status colours). A theme that fails cannot be saved, and a dim accent is moved until it passes.
- Safe to experiment. Try on this browser shows the draft on the real panel for 60 seconds and then goes back by itself; the last 20 versions are kept with their images;
?safe=1shows the built-in look when a theme is unusable;BRANDING_DISABLED=trueis the last resort. - Sign-in page, sidebar and banner. Welcome text, centred or split layout, soft glow or picture background, links; renamed pages ("Servers" to "Worlds"); extra sidebar links; a scheduled announcement for everyone, customers or administrators.
- Share it. Export a theme (images included) and import it into another panel.
Added
Appearance
- Settings, Appearance (administrators). Tabs: Identity, Colours, Type and shape, Sign-in page, Navigation, Announcement, Advanced. A preview drawn from the draft (panel or sign-in, dark or light), a save bar, a warning before leaving with unsaved changes, and unsaved drafts that survive leaving the page.
- Identity. Panel name (1 to 40 characters), short name, tagline, logo, optional wide logo, optional tab icon, email sender name, email footer, source-code address, and a switch for the "Powered by Fledge" link.
- Images are stored in PostgreSQL and served by the panel itself (
/branding/<kind>), so the content security policy stays strict and no extra volume is needed. PNG, WebP, JPEG, plain SVG (logo, wide logo), ICO (tab icon); size and dimension limits per slot; files are identified by their bytes, not by what they claim to be; SVGs with scripts, styles, external references or a DOCTYPE are refused; images are served withnosniffand a sandboxing policy. - Colours and themes.
shared/theme.ts, one file used by the panel (preview, server-side rendering) and the API (validation), derives about 30 colour tokens in OKLCH from an accent and a tint, adjusts text to pass the contrast floors, and generates the stylesheet. Light and dark palettes are separate; High contrast raises text and borders to 7:1; individual colours can be pinned and are checked like everything else. See Theme tokens and presets. - Type and shape. Fonts: Geist (default), Inter, Atkinson Hyperlegible, the system font, monospace (all bundled; nothing is loaded from other sites). Text size 90 to 120 percent, corner radius square to 18 px, density (compact, comfortable, spacious), motion.
- Modes. Default mode dark, light or match the device; people may choose for themselves from the account menu (stored in a cookie so the server renders the right mode on the first byte, and on the account so it follows them).
PUT /api/auth/preferences;GET /api/auth/menow returnspreferences. - Sign-in page. Welcome text, centred or split layout, plain, soft glow or picture background (with a darkening gradient), up to five links, and the announcement when it is for everyone.
- Navigation. Rename any of the eleven sidebar pages (used in the sidebar, page titles, the browser tab and search); up to eight extra links with icons.
- Announcement. A banner with tone, audience, start and end, dismissible per message (a new id on every edit).
- Custom CSS (off by default). Checked on save and on every read: no
@import,@font-face, remoteurl(),image-set(),expression()or markup; embedded images up to 20 KB; at most 32 KB; balanced braces. It cannot contact other servers. - History and recovery. The last 20 versions with who and what, restore (as a new version), reset to the Fledge look, optimistic concurrency (a stale save answers 409), export and import of
fledge-themefiles with a review step. - Try on this browser. Applies the draft to the real panel in this browser only, with a 60-second countdown drawn in system colours so it stays readable; leaving the page ends it.
- About. The account menu has an About Fledge dialog (product, version, licence, source link) that cannot be switched off.
- Web app manifest and address-bar colour from the panel name, icon and colours.
- API.
GET /api/brandingandGET /api/branding/assets/:kindare public; the rest are administrator endpoints, browser session only (API tokens are refused): validate, save, upload, preview, history, restore, reset, export, import, plusGET /api/branding/announcementfor the signed-in person. All appear in the API reference. - Configuration.
BRANDING_DISABLED,BRAND_NAME(seed) andAPI_INTERNAL_URL(how the panel's server reaches the API; Compose sets it). - Audit events
branding.update,branding.asset.upload,branding.restore,branding.reset. - Documentation. New pages Appearance, Recovering from a bad theme and the generated theme reference; a "Make it yours" section on the landing page; screenshots of themed panels.
Infrastructure
shared/holds code used by both the API and the panel. Both images copy it; the panel enablesexternalDir.- The stylesheets were converted to tokens (colours, text size, corner radius, density). A test (
css-tokens.test.ts) fails if a fixed font size, radius or colour appears again. docs-site/screenshots/regress.mjsrecords and compares the computed style of every element on every screen, to prove a CSS refactor changes nothing.
Changed
- The root layout is rendered on the server with the saved appearance (cached for 3 seconds, 0.9 s timeout, built-in look as the fallback), so a reload never flashes the wrong name or mode. The pages are no longer statically prerendered.
- Server-written text uses the panel name: invitation, reset and test emails (subject and body), notification emails (
[Short name] ...), Discord, Slack and webhook messages, failover webhook text, the authenticator entry (existing entries keep working) and the passkey relying-party name. The Updates page, release notes and plugin messages keep saying "Fledge". - The default Fledge mark has a dark-ink version for light themes (
/fledge-symbol-light.png). - The content security policy allows
blob:images (for upload previews). The API lets a route set its own policy (used for images). - Pattern checks for template and plugin settings compile their scripts once and run them with a 100 ms limit (was 50 ms including compilation), so a busy machine cannot make a good pattern fail.
- Version 0.6.2.1 for the API, panel, plugin host and tools. The agent has no functional change; release builds stamp it with the tag, so nodes will offer an update to 0.6.2.1.
Fixed
- A good pattern could be rejected as "invalid format" when the machine was busy (see Changed).
Verified
- Theme engine (19 tests): colour maths, WCAG ratios, every preset in both modes passes the floors with no adjusted accent, any tint and accent keeps body text readable, pinned failures are reported, validation messages, stylesheet generation.
- Appearance API (10 unit tests, 260 integration assertions against real PostgreSQL and API processes): public document and caching, who may change what (customers and API tokens cannot), saving, history (20 kept), conflicts, restore, reset; colours and contrast; images (valid PNG, SVG, WebP, ICO, JPEG; hostile SVGs, fake files, oversize, wrong slot); caching headers; announcements by audience and time; custom CSS rules with a corpus of hostile inputs; panel name in emails, notifications and the authenticator URI; export and import; preferences;
BRANDING_DISABLED; orphaned-image sweep. - Regression: API unit 35, plugins 208 and 128, templates v2 101, quotas and clone 142, autopilot about 240, accounts 171, the original smoke test (about 216 to 235 assertions, varying slightly with timing), CORS 3, Pterodactyl 4, pack tool 2; plugin host 24; panel helpers 29 (including the stylesheet token test); type checks and production build of the panel.
- Stylesheet refactor: the computed style of 4,671 elements on 17 screens before and after: 141 differ, all from the new logo images, the Appearance card and random demo data.
- In a real browser (Chrome, GPU): the editor on every tab, a full edit and save, try-on with the automatic rollback after 60 seconds, draft restore, safe mode, the split sign-in page on desktop and phone width, the account menu and About dialog, light, dark and four themes across every main screen, no console errors, no hydration warnings.
- Container images: the API and panel images build with
shared/.
Known limits
- One look per panel: no different brand per domain, and no per-customer themes.
- Only the eleven sidebar pages can be renamed; other words in the panel still say "server", "node" and so on. English only.
- Fonts are the bundled set; custom font files are not supported. Emails are plain text (a name, a sender name and a footer, no logo).
- Fledge's own dark palette keeps its original hint and placeholder colour (3.6:1, below the 4.5:1 of WCAG AA) so that an untouched panel looks exactly as before. Calculated palettes, every other preset and High contrast keep hints at 4.5:1 or better.
- Contrast follows WCAG ratios, which is a floor: a readable theme can still be ugly. Custom CSS can hide or rearrange parts of the panel; safe mode and
BRANDING_DISABLEDexist for that. - Changes reach an open tab when it regains focus, and a new page load within a few seconds.
- The panel's server must reach the API at
API_INTERNAL_URLto show custom images and the saved colours before the page loads; without it the built-in look is used. - Not exercised in this release: the Compose job on a hosted runner, the PowerShell scripts end to end, a real phone, Safari and Firefox rendering of the theme (only Chrome), screen readers with the editor.
- Everything listed under earlier releases' known limits still applies.
Upgrading
Update from Updates in the panel or with update.sh / update.ps1. The database gains two tables and one column automatically (additive; nothing is rewritten). Then:
- Nothing changes visually until an administrator saves something. Open Settings, Appearance to start.
- The panel image now needs
API_INTERNAL_URL(Compose setshttp://api:4000). If you run the panel outside Compose, set it to the API's internal address. - Optional
.envsettings (see.env.example):BRAND_NAME,BRANDING_DISABLED,API_INTERNAL_URL. - Node agents report 0.6.2.1 after their next update; there is no functional change, so there is no need to hurry.
- Docker Compose 2.20 or newer is still required.
