Repository navigation
Aurora Design
EN | FR | Aurora | design system of the administration pages
Dark, dependency-free, honest about its data. One page = one HTML file.
"Aurora" (the reference project profile, named 2026-10-11) is the common style of the redesigned administration pages: WAF overview and its six tabs, Guardian, DPI and its five ndpid tabs, SOC, Actor Intelligence, Threats, Metrics and the Toolbox. This guide gives the principles, the colour tokens, the page anatomy and the rules to follow when you add or port a page. The living model is packages/secubox-waf-ng/composants/waf/www/waf/vue.html; when in doubt, the code wins. See the result in Admin-Panels-Gallery.
| Rule | Why |
|---|---|
| One self-contained HTML file: inline CSS and JS | The vhost CSP (default-src 'self'; script-src 'self' 'unsafe-inline') forbids more, and every dependency is extra surface |
No library, no remote font, no <script src>
|
Same reason; nothing to download |
| Charts are hand-written SVG | No canvas, no chart library |
Font stack "IBM Plex Sans","Inter",system-ui,… with tabular-nums on aligned numbers |
System fallback; monospace only for technical identifiers (interfaces, hashes, IPs) |
| SPDX CMSD-1.0 header, no secret ever displayed | A truncated public key is enough |
| Single dark theme | No light theme in this profile |
Copy them as they are:
:root{--fond:#060d1b;--trait:rgba(86,150,255,.22);--trait2:rgba(86,150,255,.38);--texte:#eaf1ff;--doux:#9fb3d6;--faible:#6f84a8;
--cyan:#29b6f6;--bleu:#3b82f6;--vert:#2ecc71;--rouge:#ff4d5e;--orange:#ff9f1c;--violet:#a78bfa;--jaune:#ffd23f}| Token | Meaning |
|---|---|
--cyan |
information, incoming, primary |
--vert |
healthy, active, successfully blocked |
--orange |
attention, demonstration, stale |
--rouge |
threat, critical, dropped packets, offline |
--jaune |
outgoing |
--violet, --bleu
|
secondary series |
--texte / --doux / --faible
|
value / label / note and unit |
A colour keeps the same meaning on every page. Background: two radial gradients (blue top right rgba(59,130,246,.2), red or cyan bottom left at .10) over --fond. Severity badges: critical red, high orange, medium yellow, low blue or green.
.cadre container-type:inline-size; container-name:a; padding:10px (NO min-height)
└ .app border --trait2, radius 16, 160deg dark gradient, cyan shadow, grid gap 10
├ .tete brand · status pill · right side: time + Refresh button
├ banners .demo (orange) · .info "session required" (cyan)
├ .tuiles 2 columns, 4 to 6 wider (container query)
└ .grille of .pan panels (h3 title, faint note on the right)
| Element | Spec |
|---|---|
| Tile | radius 12, --trait border; label .74rem --doux, value 1.45rem/700 tabular-nums, sub-line .68rem --faible. Every tile carries its definition as a tooltip (title)
|
Panel .pan
|
radius 12, --trait border, background rgba(10,22,46,.6); shadowed cards only for objects worth singling out |
| Pill | radius 999, border and text in the semantic colour, background the same colour at 12 % |
| List / bar | row name · value · bar (6 px bar) |
| Table | small-caps header .66rem, sort/filter/search client side, horizontal scroll inside its own container |
| Curve | one scale (the larger of the two series), real graduations, translucent area fill-opacity .14, vector-effect:non-scaling-stroke. Never an invented series |
The grid is decided on the width of .cadre (@container a (min-width:700px|900px|1100px)), not on the viewport, so the same page serves as a card, an embedded tab and full screen.
-
?embed=1or width under 900 px: a single column; give text-bearing grid childrenmin-width:0. - At 420 px (phone): no horizontal page scroll. Only tables, code and diagrams scroll, each in its own container.
| Situation | What the page does |
|---|---|
| Measurement missing | "—", never 0. Zero is a measurement |
| API does not provide a series | no curve |
| Value derived on the page (family, category, confidence, trend) | the page says so (note or tooltip) |
| Partial figure | announced as partial |
| 401 / failure | banner "No measurement: session required. Log in", tiles in "—" |
?demo=1 |
realistic demo data, orange banner, documentation addresses (RFC 5737 / 3849), fictitious names, no write call |
| Collector stopped / stale data | visible state (orange pill "STALE DATA — COLLECTOR STOPPED?"), not silence |
Corollaries: a timeline without empty days is not padded with zeros (the axis shows measured days only and averages count only those); "unique visitor = 1" can be a proxy IP, and the tooltip explains it instead of hiding the figure.
-
fetch(url, {headers:{Accept:'application/json'}, credentials:'same-origin', cache:'no-store'}); addAuthorization: BearerfromlocalStorage.sbx_tokenwhen present (wrap the read intry/catch,localStoragecan throw). - Same origin only: routes
/api/v1/<module>/…of the page's own host. - Prefer aggregated reads (
/pub/…) over removed legacy routes: on the admin host/api/v1/dpi/statsanswered "removed" with noconnectedfield and the view wrongly showed OFFLINE (#2368). - Refresh every 15-60 s only while
document.hiddenis false, and never during typing or an open confirmation.
A framed page measures its frame, not the document:
parent.postMessage({sbxVue: Math.ceil(document.querySelector('.cadre').getBoundingClientRect().bottom + scrollY), onglet:'name'}, location.origin)Post on load, on resize and after each render (ResizeObserver on body).
-
Forbidden:
documentElement.scrollHeightandmin-height:100vhon the frame. The measure could then only grow (the document is never shorter than the iframe) and you get thousands of pixels of blank (#2323, #2354, #2358). - Existing keys:
sbxwafVue(WAF overview, lowercase w),sbxWafVue+onglet(WAF tabs),sbxdpiVue,sbxSocVue,sbxNdpidVue,sbxThreatsVue,sbxMetricsVue,sbxToolboxVue, and the genericsbxVue(SOC/Toolbox). A new page postssbxVue+onglet. - The host clamps the value (WAF 300-4000 px, SOC 400-4000 px, plus 4 px) and checks
e.origin === location.origin; with several frames,ongletmust match the frame. A page that announces nothing keeps the iframe's default height.
- A page is read-only unless the old tab wrote. Existing actions keep exactly the same call (route, body, headers): you re-skin, you do not change the contract. Invent no action.
- Confirmation is inside the page (Confirm / Cancel buttons in the panel). Never
confirm(),alert()orprompt(): the viewer's browser ignores them (confirm()silently returns false). Show result or error in the page. - Actions are inert in
?demo=1. Anything irreversible asks for confirmation; never offer to wipe learned lists.
- Each tab of a tabbed page is a standalone page framed in a same-origin iframe; the old content stays in the DOM, hidden, so the rest of the script keeps working.
-
One source: the SOC frames
/waf/*.html,/dpi/vue.html,/actor-intelligence/; the Toolbox frames/soc/reseau.html. Never copy a page. The host must list inDependsthe packages carrying the pages it frames (otherwise the tab is empty); theliteProfils pulls them through dependency closure. - Pages are served by a static
root, neveralias+try_files(it loses the extension). A Hall relay is a list of exact routes behindauth_request. - The common side menu (
/shared/sidebar.js) stays loaded outside?embed=1and outside demo.
| Pitfall | Remedy |
|---|---|
The shared hybrid-skin.css is injected after the page and sets its tints with !important
|
A page keeping that skin must answer with higher specificity (html :is(.hybrid-skin, body) …); a full Aurora page does not load it |
| Frame height only grows | See section 7 |
| Browser dialogs ignored | In-page confirmation |
Relative fetch fails under file://
|
That is the "no session" empty case, useful for testing |
-
Static test (pytest, no browser) per page: SPDX header, height key posted,
demo, no external<script src=, no "lorem", no secret, noconfirm(/alert(/prompt(, API routes cited, write routes identical to the old page, and for a read-only page noPOST. -
Real capture (Playwright,
file://…?demo=1) at 1400x900 then 420 px wide; read the PNGs; fix until nothing overflows horizontally and no text is cut.scripts/snapshots-aurora.pyregenerates the gallery. -
Empty case: without
?demo=1expect "—", the banner and no JS error (page.on('pageerror')). -
Integration: switch every tab, note the iframe
srcand height, no error. -
On the box:
curlthe pages (200) and have a human look at the real data; an empty capture does not prove real series are legible.
French UI vocabulary of the project; sober titles; a definition tooltip on every measure; explicit labels ("Incoming now", not "In"); aria-selected on tabs, visible focus, comfortable touch targets, contrast per the tokens above.
- Admin-Panels-Gallery — the 28 pages with screenshots (demo data)
- WAF — sbxwaf and its tabs
- DPI-Vivant — live DPI
- ToolBox — Toolbox pages
- Profils — profiles and what they embed
SecuBox-Deb · Licence : CMSD-1.0 (Source-Disclosed)
Contact : CyberMind · Gérald Kerma · Notre-Dame-du-Cruet, Savoie
Hardware-Matrix · Acknowledgments · Wiki v2.5.0
SecuBox | FR | DE | 中文 | v3.0.0-alpha.12
- Home
- Architecture
- Trixie | FR
- Hardware-Matrix
- Roadmap
- Profils
- Modules-by-Profile 📦 lite / isp / full : ce qu'embarque chaque profil | FR
- Modules-by-Family 🗂️ les modules par famille | FR
- DNS-Filtrage
- Multiboot ⭐
-
Live-USB-VirtualBox
run-vbox.sh -
Live-USB-QEMU
run-qemu.sh - Live-USB | FR | DE | 中文
- Auto-Load 🚚 boxes sans écran | FR
- First-Boot-Premier-Pas 🧭 premier pas | FR
- Installation | FR | DE | 中文
- ARM-Installation | FR | DE | 中文
- Netboot-Install 🔧 MOCHAbin netboot + signed install
- ESPRESSObin | FR | DE | 中文
- Eye-Remote 📡
- Android-ToolBox 📱 one-tap R3
- Browser-Extension 🧩 cartographie
- QEMU-ARM64 🖥️
- Configuration | FR | DE | 中文
- Troubleshooting | FR | DE | 中文
- ToolBox 👁️ cabine numérique · rapport vie privée
- Anti-Track 🛡️ bloque · empoisonne · anonymise
- Billets 📮 micro-blog gateway · média vignette zoomable
- Messagerie 💬 mur public, messages privés, radio/Billets/BBS centralisés
- Identite-SBX-OS 🪪 personnes, appareils, comptes liés, connexion passive
- Metalogue 🕸️ OSINT suite · Maigret + SpiderFoot (Maltego-style)
- WAF 🛡️ pare-feu applicatif autonome (nft direct, hors-HTTP) | FR
- SOC 🎯 vues rassemblées | FR
- Actor-Intelligence 🕵️ acteurs, échelle de réponse | FR
- NAC 🔐 contrôle d'accès réseau | FR
- Webfilter 🧹 filtrage DNS par catégories et par appareil | FR
- Interceptor 🎯 supervision de l'inspection (sbxmitm, sbxwaf, nDPI) | FR
- Network-Modes 🌐 modes réseau, WAN, interfaces | FR
- Caches-and-Mirrors 💾 caches de la box et dépôt APT local | FR
- Portal 🚪 portail de session | FR
- Certificates 📜 certificats | FR
- Metrics 📊 mesures, sites, cartes, rapport PDF | FR
- SBX-OS 🧩 le Hall en application | FR
- Aurora-Design 🎨 design system admin | FR
- Admin-Panels-Gallery 🖼️ galerie des 37 pages | FR
- ThreatMesh 🛰️ blocklist souveraine (feeds + mesh, sans CAPI) | FR
- Modules 🇬🇧
- MODULES-FR 🇫🇷
- MODULES-DE 🇩🇪
- MODULES-ZH 🇨🇳
-
Operations-Runbook 🛠️ incidents | FR
-
API-Reference | FR | DE | 中文
- Multi-Agent-Worktree — un agent · une issue · une branche