Arx 0.4.3: app renamed to Arx, first-open help (installer window + website), colours
Browse files- .gitattributes +1 -0
- README.md +10 -7
- app/build/dmg-background.html +19 -0
- app/build/dmg-background.png +0 -0
- app/build/dmg-background@2x.png +3 -0
- app/main.cjs +8 -4
- app/package.json +27 -9
- app/renderer/index.html +4 -4
- app/renderer/report.js +1 -1
- index.html +59 -16
- site/site.css +55 -3
- site/site.js +27 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
app/build/dmg-background@2x.png filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -166,13 +166,16 @@ history. `mobile/` stays because the synthetic data generator uses its evidence
|
|
| 166 |
|
| 167 |
## Install on a Mac
|
| 168 |
|
| 169 |
-
Download from **https://devseis-arx.static.hf.space/#download** (universal app for Apple silicon and
|
| 170 |
-
|
| 171 |
-
Drag
|
| 172 |
-
is ad-hoc signed, not yet notarised). The
|
| 173 |
-
in `app/model-version.json` on this Space. Settings for
|
| 174 |
-
(`baseline.conf`, `organisational.conf`
|
| 175 |
-
|
|
|
|
|
|
|
|
|
|
| 176 |
|
| 177 |
## Role of the language model
|
| 178 |
|
|
|
|
| 166 |
|
| 167 |
## Install on a Mac
|
| 168 |
|
| 169 |
+
Download from **https://devseis-arx.static.hf.space/#download** (universal app for Apple silicon and Intel, macOS 13+;
|
| 170 |
+
files and checksums in [Devseis/endpoint-auditor-releases](https://huggingface.co/datasets/Devseis/endpoint-auditor-releases)).
|
| 171 |
+
Drag **Arx** to Applications; on first open, allow it once in *System Settings › Privacy & Security › Open Anyway* (the build
|
| 172 |
+
is ad-hoc signed, not yet notarised). The installer window and the website show these steps. The app downloads the AI
|
| 173 |
+
auditor model on first run and follows the model version in `app/model-version.json` on this Space. Settings for
|
| 174 |
+
organisations: `~/Library/Application Support/Devseis Endpoint Auditor/` (`baseline.conf`, `organisational.conf`; the
|
| 175 |
+
folder keeps its old name since the rename to Arx in 0.4.3). Reports: *Documents › Arx Reports*. Build it yourself:
|
| 176 |
+
`cd app && npm install && npm run dist`; smoke-test a build with `DEVSEIS_SMOKE=<folder> "<app>/Contents/MacOS/Arx"`
|
| 177 |
+
(add `DEVSEIS_SMOKE_MODEL=1` to include the model). The installer background is `app/build/dmg-background.html`,
|
| 178 |
+
rendered to `dmg-background.png` / `@2x.png`.
|
| 179 |
|
| 180 |
## Role of the language model
|
| 181 |
|
app/build/dmg-background.html
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html><html><head><meta charset="utf-8"><style>
|
| 2 |
+
html,body{margin:0;width:640px;height:440px;overflow:hidden}
|
| 3 |
+
body{font-family:-apple-system,'SF Pro Text','Helvetica Neue',sans-serif;color:#111;background:radial-gradient(420px 260px at 10% 0,rgba(237,41,57,.18),transparent 70%),radial-gradient(420px 260px at 95% 10%,rgba(124,58,237,.14),transparent 70%),#fafafa}
|
| 4 |
+
h1{position:absolute;top:26px;left:0;right:0;text-align:center;margin:0;font-size:21px;font-weight:700;letter-spacing:-.01em}
|
| 5 |
+
.sub{position:absolute;top:56px;left:0;right:0;text-align:center;font-size:12.5px;color:#666}
|
| 6 |
+
.arrow{position:absolute;top:150px;left:262px;width:116px;height:40px}
|
| 7 |
+
.steps{position:absolute;left:28px;right:28px;top:278px;display:flex;gap:10px}
|
| 8 |
+
.s{flex:1;background:#fff;border:1px solid #e5e5e5;border-radius:10px;padding:10px 11px;font-size:11.5px;line-height:1.4;color:#444}
|
| 9 |
+
.s b{display:block;color:#111;font-size:12.5px;margin-bottom:3px}
|
| 10 |
+
.n{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:50%;background:#ed2939;color:#fff;font-size:11px;font-weight:700;margin-right:5px;vertical-align:1px}
|
| 11 |
+
.s.hl{border-color:#ed2939;box-shadow:0 0 0 2px rgba(237,41,57,.15)}
|
| 12 |
+
</style></head><body>
|
| 13 |
+
<h1>Install Arx</h1><div class="sub">Drag the Arx icon onto the Applications folder</div>
|
| 14 |
+
<svg class="arrow" viewBox="0 0 116 40"><defs><linearGradient id="g" x1="0" x2="1"><stop offset="0" stop-color="#ed2939"/><stop offset="1" stop-color="#f97316"/></linearGradient></defs><path d="M4 20 H98" stroke="#ed2939" stroke-width="5" stroke-linecap="round"/><path d="M90 8 L108 20 L90 32" fill="none" stroke="#f97316" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
| 15 |
+
<div class="steps">
|
| 16 |
+
<div class="s"><b><span class="n">1</span>Drag to Applications</b>Drag Arx onto the folder above.</div>
|
| 17 |
+
<div class="s"><b><span class="n">2</span>Open Arx</b>From Applications. If macOS says “Not Opened”, click <b style="display:inline">Done</b>.</div>
|
| 18 |
+
<div class="s hl"><b><span class="n">3</span>Allow it once</b>Apple menu › System Settings › Privacy & Security › <b style="display:inline">Open Anyway</b>.</div>
|
| 19 |
+
</div></body></html>
|
app/build/dmg-background.png
ADDED
|
app/build/dmg-background@2x.png
ADDED
|
Git LFS Details
|
app/main.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
// Devseis Endpoint Auditor - Electron main process.
|
| 2 |
// Runs the read-only collector for this OS (with the OS's own administrator prompt), streams progress
|
| 3 |
// to the window, turns the report into a PDF and saves it where the user chooses or, after 60 seconds
|
| 4 |
-
// without an answer, in Documents/
|
| 5 |
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
| 6 |
const { spawn } = require('node:child_process');
|
| 7 |
const crypto = require('node:crypto');
|
|
@@ -10,6 +10,10 @@ const os = require('node:os');
|
|
| 10 |
const path = require('node:path');
|
| 11 |
const vulndb = require('./vulndb.cjs');
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
// WebGPU (used by WebLLM) is still behind a flag on Linux.
|
| 14 |
if (process.platform === 'linux') {
|
| 15 |
app.commandLine.appendSwitch('enable-unsafe-webgpu');
|
|
@@ -192,7 +196,7 @@ function defaultFolder(hostname) {
|
|
| 192 |
const d = new Date();
|
| 193 |
const stamp = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}-` +
|
| 194 |
`${String(d.getHours()).padStart(2, '0')}${String(d.getMinutes()).padStart(2, '0')}${String(d.getSeconds()).padStart(2, '0')}`;
|
| 195 |
-
return path.join(SMOKE || app.getPath('documents'), '
|
| 196 |
}
|
| 197 |
|
| 198 |
async function renderPdf(html) {
|
|
@@ -234,7 +238,7 @@ const CHAT_URL = 'https://devseis-arx.static.hf.space/index.html';
|
|
| 234 |
let chatWindow = null;
|
| 235 |
ipcMain.handle('chat:open', async (event, evidenceText) => {
|
| 236 |
if (chatWindow && !chatWindow.isDestroyed()) chatWindow.close();
|
| 237 |
-
chatWindow = new BrowserWindow({ width: 1000, height: 820, minWidth: 420, minHeight: 560, title: 'Arx ·
|
| 238 |
webPreferences: { contextIsolation: true, nodeIntegration: false, sandbox: true } });
|
| 239 |
chatWindow.webContents.setWindowOpenHandler(({ url }) => (url.startsWith('blob:') ? { action: 'allow' } : (shell.openExternal(url), { action: 'deny' })));
|
| 240 |
try {
|
|
|
|
| 1 |
+
// Arx (Devseis Endpoint Auditor) - Electron main process.
|
| 2 |
// Runs the read-only collector for this OS (with the OS's own administrator prompt), streams progress
|
| 3 |
// to the window, turns the report into a PDF and saves it where the user chooses or, after 60 seconds
|
| 4 |
+
// without an answer, in Documents/Arx Reports/<computer>-<date>/.
|
| 5 |
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
| 6 |
const { spawn } = require('node:child_process');
|
| 7 |
const crypto = require('node:crypto');
|
|
|
|
| 10 |
const path = require('node:path');
|
| 11 |
const vulndb = require('./vulndb.cjs');
|
| 12 |
|
| 13 |
+
// Renamed to Arx in 0.4.3: keep the old settings folder, so baseline.conf, organisational.conf, the vulnerability data
|
| 14 |
+
// and the downloaded AI model stay where earlier versions put them.
|
| 15 |
+
app.setPath('userData', path.join(app.getPath('appData'), 'Devseis Endpoint Auditor'));
|
| 16 |
+
|
| 17 |
// WebGPU (used by WebLLM) is still behind a flag on Linux.
|
| 18 |
if (process.platform === 'linux') {
|
| 19 |
app.commandLine.appendSwitch('enable-unsafe-webgpu');
|
|
|
|
| 196 |
const d = new Date();
|
| 197 |
const stamp = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}-` +
|
| 198 |
`${String(d.getHours()).padStart(2, '0')}${String(d.getMinutes()).padStart(2, '0')}${String(d.getSeconds()).padStart(2, '0')}`;
|
| 199 |
+
return path.join(SMOKE || app.getPath('documents'), 'Arx Reports', `${hostname.replace(/[^\w.-]/g, '_')}-${stamp}`);
|
| 200 |
}
|
| 201 |
|
| 202 |
async function renderPdf(html) {
|
|
|
|
| 238 |
let chatWindow = null;
|
| 239 |
ipcMain.handle('chat:open', async (event, evidenceText) => {
|
| 240 |
if (chatWindow && !chatWindow.isDestroyed()) chatWindow.close();
|
| 241 |
+
chatWindow = new BrowserWindow({ width: 1000, height: 820, minWidth: 420, minHeight: 560, title: 'Arx · report',
|
| 242 |
webPreferences: { contextIsolation: true, nodeIntegration: false, sandbox: true } });
|
| 243 |
chatWindow.webContents.setWindowOpenHandler(({ url }) => (url.startsWith('blob:') ? { action: 'allow' } : (shell.openExternal(url), { action: 'deny' })));
|
| 244 |
try {
|
app/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"name": "devseis-endpoint-auditor",
|
| 3 |
-
"productName": "
|
| 4 |
-
"version": "0.4.
|
| 5 |
"description": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act, with a local AI auditor.",
|
| 6 |
"author": {
|
| 7 |
"name": "Devseis",
|
|
@@ -28,7 +28,7 @@
|
|
| 28 |
"homepage": "https://huggingface.co/spaces/Devseis/Arx",
|
| 29 |
"build": {
|
| 30 |
"appId": "com.devseis.endpoint-auditor",
|
| 31 |
-
"productName": "
|
| 32 |
"copyright": "Copyright 2026 Devseis. Apache-2.0.",
|
| 33 |
"directories": {
|
| 34 |
"output": "dist"
|
|
@@ -79,10 +79,28 @@
|
|
| 79 |
"identity": "-",
|
| 80 |
"hardenedRuntime": false,
|
| 81 |
"gatekeeperAssess": false,
|
| 82 |
-
"artifactName": "
|
| 83 |
},
|
| 84 |
"dmg": {
|
| 85 |
-
"title": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
},
|
| 87 |
"asar": true,
|
| 88 |
"asarUnpack": [
|
|
@@ -97,7 +115,7 @@
|
|
| 97 |
]
|
| 98 |
}
|
| 99 |
],
|
| 100 |
-
"artifactName": "
|
| 101 |
"signAndEditExecutable": false
|
| 102 |
},
|
| 103 |
"nsis": {
|
|
@@ -105,7 +123,7 @@
|
|
| 105 |
"perMachine": false,
|
| 106 |
"allowToChangeInstallationDirectory": true,
|
| 107 |
"createDesktopShortcut": true,
|
| 108 |
-
"shortcutName": "
|
| 109 |
},
|
| 110 |
"linux": {
|
| 111 |
"target": [
|
|
@@ -115,8 +133,8 @@
|
|
| 115 |
"category": "Utility",
|
| 116 |
"maintainer": "Devseis <noreply@huggingface.co>",
|
| 117 |
"synopsis": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act",
|
| 118 |
-
"artifactName": "
|
| 119 |
-
"executableName": "
|
| 120 |
},
|
| 121 |
"deb": {
|
| 122 |
"depends": [
|
|
|
|
| 1 |
{
|
| 2 |
"name": "devseis-endpoint-auditor",
|
| 3 |
+
"productName": "Arx",
|
| 4 |
+
"version": "0.4.3",
|
| 5 |
"description": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act, with a local AI auditor.",
|
| 6 |
"author": {
|
| 7 |
"name": "Devseis",
|
|
|
|
| 28 |
"homepage": "https://huggingface.co/spaces/Devseis/Arx",
|
| 29 |
"build": {
|
| 30 |
"appId": "com.devseis.endpoint-auditor",
|
| 31 |
+
"productName": "Arx",
|
| 32 |
"copyright": "Copyright 2026 Devseis. Apache-2.0.",
|
| 33 |
"directories": {
|
| 34 |
"output": "dist"
|
|
|
|
| 79 |
"identity": "-",
|
| 80 |
"hardenedRuntime": false,
|
| 81 |
"gatekeeperAssess": false,
|
| 82 |
+
"artifactName": "Arx-${version}-mac-universal.${ext}"
|
| 83 |
},
|
| 84 |
"dmg": {
|
| 85 |
+
"title": "Arx ${version}",
|
| 86 |
+
"background": "build/dmg-background.png",
|
| 87 |
+
"window": {
|
| 88 |
+
"width": 640,
|
| 89 |
+
"height": 440
|
| 90 |
+
},
|
| 91 |
+
"contents": [
|
| 92 |
+
{
|
| 93 |
+
"x": 170,
|
| 94 |
+
"y": 170,
|
| 95 |
+
"type": "file"
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
"x": 470,
|
| 99 |
+
"y": 170,
|
| 100 |
+
"type": "link",
|
| 101 |
+
"path": "/Applications"
|
| 102 |
+
}
|
| 103 |
+
]
|
| 104 |
},
|
| 105 |
"asar": true,
|
| 106 |
"asarUnpack": [
|
|
|
|
| 115 |
]
|
| 116 |
}
|
| 117 |
],
|
| 118 |
+
"artifactName": "Arx-${version}-windows-x64-setup.${ext}",
|
| 119 |
"signAndEditExecutable": false
|
| 120 |
},
|
| 121 |
"nsis": {
|
|
|
|
| 123 |
"perMachine": false,
|
| 124 |
"allowToChangeInstallationDirectory": true,
|
| 125 |
"createDesktopShortcut": true,
|
| 126 |
+
"shortcutName": "Arx"
|
| 127 |
},
|
| 128 |
"linux": {
|
| 129 |
"target": [
|
|
|
|
| 133 |
"category": "Utility",
|
| 134 |
"maintainer": "Devseis <noreply@huggingface.co>",
|
| 135 |
"synopsis": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act",
|
| 136 |
+
"artifactName": "Arx-${version}-linux-x86_64.${ext}",
|
| 137 |
+
"executableName": "arx"
|
| 138 |
},
|
| 139 |
"deb": {
|
| 140 |
"depends": [
|
app/renderer/index.html
CHANGED
|
@@ -4,12 +4,12 @@
|
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; connect-src 'self' https://huggingface.co https://*.huggingface.co https://*.hf.co https://raw.githubusercontent.com; img-src 'self' data:; worker-src 'self' blob:">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 7 |
-
<title>Arx
|
| 8 |
<link rel="stylesheet" href="styles.css">
|
| 9 |
</head>
|
| 10 |
<body>
|
| 11 |
<header class="bar">
|
| 12 |
-
<div class="brand"><span class="dot"></span>
|
| 13 |
<div class="device" id="device"></div>
|
| 14 |
</header>
|
| 15 |
|
|
@@ -55,7 +55,7 @@
|
|
| 55 |
<div class="actions">
|
| 56 |
<button class="secondary" id="again">Run another audit</button>
|
| 57 |
<button class="primary" id="save-again">Save report as PDF</button>
|
| 58 |
-
<button class="secondary" id="ask-chat">
|
| 59 |
</div>
|
| 60 |
<p class="muted" id="saved-note"></p>
|
| 61 |
</section>
|
|
@@ -73,7 +73,7 @@
|
|
| 73 |
<div class="modal-box">
|
| 74 |
<h2 id="save-title">Save the audit report as PDF?</h2>
|
| 75 |
<p>Choose where to save it. If you do not answer, it is saved automatically in
|
| 76 |
-
<b>Documents ›
|
| 77 |
<div class="progress thin"><div id="countdown-bar"></div></div>
|
| 78 |
<div class="actions">
|
| 79 |
<button class="secondary" id="save-docs">Save to Documents now</button>
|
|
|
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; connect-src 'self' https://huggingface.co https://*.huggingface.co https://*.hf.co https://raw.githubusercontent.com; img-src 'self' data:; worker-src 'self' blob:">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 7 |
+
<title>Arx</title>
|
| 8 |
<link rel="stylesheet" href="styles.css">
|
| 9 |
</head>
|
| 10 |
<body>
|
| 11 |
<header class="bar">
|
| 12 |
+
<div class="brand"><span class="dot"></span> Arx</div>
|
| 13 |
<div class="device" id="device"></div>
|
| 14 |
</header>
|
| 15 |
|
|
|
|
| 55 |
<div class="actions">
|
| 56 |
<button class="secondary" id="again">Run another audit</button>
|
| 57 |
<button class="primary" id="save-again">Save report as PDF</button>
|
| 58 |
+
<button class="secondary" id="ask-chat">📋 Open report with fixes</button>
|
| 59 |
</div>
|
| 60 |
<p class="muted" id="saved-note"></p>
|
| 61 |
</section>
|
|
|
|
| 73 |
<div class="modal-box">
|
| 74 |
<h2 id="save-title">Save the audit report as PDF?</h2>
|
| 75 |
<p>Choose where to save it. If you do not answer, it is saved automatically in
|
| 76 |
+
<b>Documents › Arx Reports</b> in <b id="countdown">60</b> seconds.</p>
|
| 77 |
<div class="progress thin"><div id="countdown-bar"></div></div>
|
| 78 |
<div class="actions">
|
| 79 |
<button class="secondary" id="save-docs">Save to Documents now</button>
|
app/renderer/report.js
CHANGED
|
@@ -41,7 +41,7 @@ export function buildReportHtml({ evidence, findings, summary, ai, sha256, model
|
|
| 41 |
<td>${esc(t.gdpr)}</td><td>${esc(t.action)}</td></tr>`).join('')}
|
| 42 |
</tbody></table><p class="muted">${esc(ai.log_retention)} The purpose of use was not stated; the classification must be confirmed for each actual use.</p>` : '';
|
| 43 |
|
| 44 |
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>
|
| 45 |
<style>
|
| 46 |
body { font: 10.5pt/1.45 -apple-system, "Segoe UI", Roboto, Arial, sans-serif; color: #16181d; margin: 0; }
|
| 47 |
.cover { border-top: 6px solid #ED2939; padding: 18px 0 10px; margin-bottom: 14px; }
|
|
|
|
| 41 |
<td>${esc(t.gdpr)}</td><td>${esc(t.action)}</td></tr>`).join('')}
|
| 42 |
</tbody></table><p class="muted">${esc(ai.log_retention)} The purpose of use was not stated; the classification must be confirmed for each actual use.</p>` : '';
|
| 43 |
|
| 44 |
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Arx audit — ${esc(host.hostname)}</title>
|
| 45 |
<style>
|
| 46 |
body { font: 10.5pt/1.45 -apple-system, "Segoe UI", Roboto, Arial, sans-serif; color: #16181d; margin: 0; }
|
| 47 |
.cover { border-top: 6px solid #ED2939; padding: 18px 0 10px; margin-bottom: 14px; }
|
index.html
CHANGED
|
@@ -3,8 +3,8 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
| 6 |
-
<meta name="description" content="Arx
|
| 7 |
-
<meta name="theme-color" content="#
|
| 8 |
<title>Arx · Security audit for your computer</title>
|
| 9 |
<link rel="icon" href="app/build/icon.png">
|
| 10 |
<link rel="apple-touch-icon" href="app/build/icon.png">
|
|
@@ -17,7 +17,7 @@
|
|
| 17 |
<body>
|
| 18 |
<header class="nav">
|
| 19 |
<div class="wrap nav-inner">
|
| 20 |
-
<a class="brand" href="index.html"><img src="app/build/icon.png" alt=""><b>Arx</b><
|
| 21 |
<nav class="nav-links">
|
| 22 |
<a href="#checks">Checks</a><a href="#how">How it works</a><a href="#about">About</a>
|
| 23 |
</nav>
|
|
@@ -32,7 +32,7 @@
|
|
| 32 |
<main id="landing">
|
| 33 |
<section class="wrap hero">
|
| 34 |
<p class="eyebrow"><img src="app/build/icon.png" alt="">Arx security audit</p>
|
| 35 |
-
<h1>Is your computer secure?<br><span class="
|
| 36 |
<p class="lead">A free, read-only audit of your Mac, Windows or Linux computer: <b>68 checks</b> mapped to <b>ISO 27001</b>, <b>GDPR</b> and the <b>EU AI Act</b>. It runs offline, and a small AI on your computer writes the report. <u>Nothing is uploaded.</u></p>
|
| 37 |
|
| 38 |
<div class="device-card" id="deviceCard">
|
|
@@ -56,15 +56,15 @@
|
|
| 56 |
<label class="btn btn-lg" for="reportFile" title="Open the …-evidence.json file Arx saves next to each report">Open a report</label>
|
| 57 |
<input type="file" id="reportFile" accept=".json,application/json" hidden>
|
| 58 |
</div>
|
| 59 |
-
<p class="tiny muted" id="heroMeta">Free · open source · version 0.4.
|
| 60 |
</section>
|
| 61 |
|
| 62 |
<section class="wrap">
|
| 63 |
<div class="stats">
|
| 64 |
-
<div class="stat"><span class="tiny muted">Checks</span><b>68</b><span class="tiny muted">settings & controls</span></div>
|
| 65 |
-
<div class="stat"><span class="tiny muted">Time</span><b>~1 min</b><span class="tiny muted">for the whole audit</span></div>
|
| 66 |
-
<div class="stat"><span class="tiny muted">Uploaded</span><b>0 bytes</b><span class="tiny muted">runs offline</span></div>
|
| 67 |
-
<div class="stat"><span class="tiny muted">Frameworks</span><b>3</b><span class="tiny muted">ISO · GDPR · AI Act</span></div>
|
| 68 |
</div>
|
| 69 |
</section>
|
| 70 |
|
|
@@ -95,7 +95,7 @@
|
|
| 95 |
</section>
|
| 96 |
|
| 97 |
<section class="wrap section" id="download">
|
| 98 |
-
<div class="section-head"><h2>Download Arx</h2><span class="tiny muted" id="dlVersion">Version 0.4.
|
| 99 |
<div class="dl-grid">
|
| 100 |
<article class="dl-card" data-os="mac">
|
| 101 |
<span class="ribbon ribbon-you hidden">YOUR SYSTEM</span>
|
|
@@ -122,16 +122,50 @@
|
|
| 122 |
<details class="hash"><summary>SHA-256</summary><code data-hash="linux">loading…</code></details>
|
| 123 |
</article>
|
| 124 |
</div>
|
| 125 |
-
<p class="tiny muted">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
</section>
|
| 127 |
|
| 128 |
<section class="wrap section" id="about">
|
| 129 |
<div class="section-head"><h2>Why trust it</h2></div>
|
| 130 |
<div class="trust-grid">
|
| 131 |
-
<div class="card"><b>🔒 Read-only</b><p class="muted">Arx reads settings and never changes them. You decide what to fix.</p></div>
|
| 132 |
-
<div class="card"><b>📴 Offline and private</b><p class="muted">The audit and the AI run on your computer. The report stays there unless you share it.</p></div>
|
| 133 |
-
<div class="card"><b>🧾 Grounded report</b><p class="muted">The AI writes only from what the audit found and the Devseis library, and each answer is checked against both. If a check fails, Arx uses a fixed template instead.</p></div>
|
| 134 |
-
<div class="card"><b>📖 Open source</b><p class="muted">Code Apache-2.0, data CC BY 4.0. <a class="link" href="https://huggingface.co/spaces/Devseis/Arx/tree/main">Read the source</a>.</p></div>
|
| 135 |
</div>
|
| 136 |
<details class="faq"><summary>Is this a certification?</summary><p class="muted">No. ISO 27001 certification needs an accredited auditor, and much of GDPR and AI Act compliance is organisational. Arx collects evidence from the computer and flags the gaps.</p></details>
|
| 137 |
<details class="faq"><summary>I'm setting this up for a company</summary><p class="muted">Before running, edit <code>baseline.conf</code> (approved admins, approved AI tools, limits) and <code>organisational.conf</code> (8 company questions). They are in <code>~/Library/Application Support/Devseis Endpoint Auditor</code> on Mac, <code>%APPDATA%\Devseis Endpoint Auditor</code> on Windows and <code>~/.config/Devseis Endpoint Auditor</code> on Linux.</p></details>
|
|
@@ -162,10 +196,19 @@
|
|
| 162 |
|
| 163 |
<footer class="foot">
|
| 164 |
<div class="wrap foot-inner">
|
| 165 |
-
<div><b>Arx</b> <span class="muted">
|
| 166 |
<div class="foot-links"><a href="#download">Download</a><a href="https://huggingface.co/spaces/Devseis/Arx/tree/main">Source</a><a href="https://huggingface.co/datasets/Devseis/endpoint-auditor-releases">Releases</a><a href="https://huggingface.co/Devseis/endpoint-auditor-0.5b">AI model</a><a href="CITATION.cff">Cite</a></div>
|
| 167 |
</div>
|
| 168 |
</footer>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
<div class="toast hidden" id="toast" role="status"></div>
|
| 170 |
<script type="module" src="site/site.js"></script>
|
| 171 |
</body>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
| 6 |
+
<meta name="description" content="Arx: a free, read-only security audit for your Mac, Windows or Linux computer. 68 checks in about a minute, offline, mapped to ISO 27001, GDPR and the EU AI Act. Nothing is uploaded.">
|
| 7 |
+
<meta name="theme-color" content="#ed2939">
|
| 8 |
<title>Arx · Security audit for your computer</title>
|
| 9 |
<link rel="icon" href="app/build/icon.png">
|
| 10 |
<link rel="apple-touch-icon" href="app/build/icon.png">
|
|
|
|
| 17 |
<body>
|
| 18 |
<header class="nav">
|
| 19 |
<div class="wrap nav-inner">
|
| 20 |
+
<a class="brand" href="index.html"><img src="app/build/icon.png" alt=""><b>Arx</b></a>
|
| 21 |
<nav class="nav-links">
|
| 22 |
<a href="#checks">Checks</a><a href="#how">How it works</a><a href="#about">About</a>
|
| 23 |
</nav>
|
|
|
|
| 32 |
<main id="landing">
|
| 33 |
<section class="wrap hero">
|
| 34 |
<p class="eyebrow"><img src="app/build/icon.png" alt="">Arx security audit</p>
|
| 35 |
+
<h1>Is your computer secure?<br><span class="grad">Find out in a minute.</span></h1>
|
| 36 |
<p class="lead">A free, read-only audit of your Mac, Windows or Linux computer: <b>68 checks</b> mapped to <b>ISO 27001</b>, <b>GDPR</b> and the <b>EU AI Act</b>. It runs offline, and a small AI on your computer writes the report. <u>Nothing is uploaded.</u></p>
|
| 37 |
|
| 38 |
<div class="device-card" id="deviceCard">
|
|
|
|
| 56 |
<label class="btn btn-lg" for="reportFile" title="Open the …-evidence.json file Arx saves next to each report">Open a report</label>
|
| 57 |
<input type="file" id="reportFile" accept=".json,application/json" hidden>
|
| 58 |
</div>
|
| 59 |
+
<p class="tiny muted" id="heroMeta">Free · open source · version 0.4.3</p>
|
| 60 |
</section>
|
| 61 |
|
| 62 |
<section class="wrap">
|
| 63 |
<div class="stats">
|
| 64 |
+
<div class="stat c-red"><span class="tiny muted">Checks</span><b>68</b><span class="tiny muted">settings & controls</span></div>
|
| 65 |
+
<div class="stat c-blue"><span class="tiny muted">Time</span><b>~1 min</b><span class="tiny muted">for the whole audit</span></div>
|
| 66 |
+
<div class="stat c-green"><span class="tiny muted">Uploaded</span><b>0 bytes</b><span class="tiny muted">runs offline</span></div>
|
| 67 |
+
<div class="stat c-violet"><span class="tiny muted">Frameworks</span><b>3</b><span class="tiny muted">ISO · GDPR · AI Act</span></div>
|
| 68 |
</div>
|
| 69 |
</section>
|
| 70 |
|
|
|
|
| 95 |
</section>
|
| 96 |
|
| 97 |
<section class="wrap section" id="download">
|
| 98 |
+
<div class="section-head"><h2>Download Arx</h2><span class="tiny muted" id="dlVersion">Version 0.4.3</span></div>
|
| 99 |
<div class="dl-grid">
|
| 100 |
<article class="dl-card" data-os="mac">
|
| 101 |
<span class="ribbon ribbon-you hidden">YOUR SYSTEM</span>
|
|
|
|
| 122 |
<details class="hash"><summary>SHA-256</summary><code data-hash="linux">loading…</code></details>
|
| 123 |
</article>
|
| 124 |
</div>
|
| 125 |
+
<p class="tiny muted">Your computer may warn you the first time you open Arx, because it is free and not yet registered with Apple or Microsoft. <a class="link" href="#first-open">See how to open it →</a> All files: <a class="link" href="https://huggingface.co/datasets/Devseis/endpoint-auditor-releases">releases</a>.</p>
|
| 126 |
+
</section>
|
| 127 |
+
|
| 128 |
+
<section class="wrap section" id="first-open">
|
| 129 |
+
<div class="section-head"><h2>Opening Arx the first time</h2><span class="tiny muted">one-time, about 30 seconds</span></div>
|
| 130 |
+
<div class="seg seg-help" id="helpSeg">
|
| 131 |
+
<button type="button" data-help="mac">macOS</button><button type="button" data-help="windows">Windows</button><button type="button" data-help="linux">Linux</button>
|
| 132 |
+
</div>
|
| 133 |
+
<div class="help-panel" data-help="mac">
|
| 134 |
+
<p class="muted help-why">Arx is free and not yet registered with Apple, so macOS blocks it the first time. This is normal: you allow it once and it opens normally after that.</p>
|
| 135 |
+
<ol class="help-steps">
|
| 136 |
+
<li><span class="hs-n">1</span><div><b>Open the downloaded file</b><p class="muted">Double-click <code>Arx-…-mac-universal.dmg</code> in Downloads, then drag <b>Arx</b> onto <b>Applications</b>.</p></div></li>
|
| 137 |
+
<li><span class="hs-n">2</span><div><b>Open Arx from Applications</b><p class="muted">macOS shows <i>"Arx" Not Opened</i> or <i>Apple could not verify…</i>. Click <b>Done</b> (not Move to Bin).</p>
|
| 138 |
+
<div class="mock mock-alert"><div class="mock-icon">⚠️</div><b>"Arx" Not Opened</b><span>Apple could not verify "Arx" is free of malware…</span><div class="mock-btns"><span class="mock-btn">Move to Bin</span><span class="mock-btn mock-blue">Done</span></div></div></div></li>
|
| 139 |
+
<li><span class="hs-n">3</span><div><b>Allow it in System Settings</b><p class="muted">Open the Apple menu › <b>System Settings</b> › <b>Privacy & Security</b>. Scroll down to <b>Security</b> and click <b>Open Anyway</b> next to "Arx" was blocked…, then enter your Mac password.</p>
|
| 140 |
+
<div class="mock mock-settings"><span class="muted">Security</span><div class="mock-row"><span>"Arx" was blocked to protect your Mac.</span><span class="mock-btn mock-hl">Open Anyway</span></div></div></div></li>
|
| 141 |
+
<li><span class="hs-n">4</span><div><b>Click Open</b><p class="muted">macOS asks one last time: click <b>Open Anyway</b>. From now on Arx opens like any other app.</p></div></li>
|
| 142 |
+
</ol>
|
| 143 |
+
</div>
|
| 144 |
+
<div class="help-panel hidden" data-help="windows">
|
| 145 |
+
<p class="muted help-why">Arx is free and not yet signed with a Microsoft certificate, so Windows SmartScreen may warn you once.</p>
|
| 146 |
+
<ol class="help-steps">
|
| 147 |
+
<li><span class="hs-n">1</span><div><b>Run the downloaded file</b><p class="muted">Double-click <code>Arx-…-windows-x64-setup.exe</code> in Downloads.</p></div></li>
|
| 148 |
+
<li><span class="hs-n">2</span><div><b>If you see "Windows protected your PC"</b><p class="muted">Click <b>More info</b>, then <b>Run anyway</b>.</p>
|
| 149 |
+
<div class="mock mock-win"><b>Windows protected your PC</b><span>Microsoft Defender SmartScreen prevented an unrecognised app from starting…</span><span class="mock-link">More info</span><div class="mock-btns"><span class="mock-btn mock-hl">Run anyway</span><span class="mock-btn">Don't run</span></div></div></div></li>
|
| 150 |
+
<li><span class="hs-n">3</span><div><b>Install and open</b><p class="muted">Follow the installer; Arx is then on your desktop and in the Start menu.</p></div></li>
|
| 151 |
+
</ol>
|
| 152 |
+
</div>
|
| 153 |
+
<div class="help-panel hidden" data-help="linux">
|
| 154 |
+
<p class="muted help-why">No warning to get past: install the package or make the AppImage runnable.</p>
|
| 155 |
+
<ol class="help-steps">
|
| 156 |
+
<li><span class="hs-n">1</span><div><b>Ubuntu, Debian, Mint, Pop!_OS</b><p class="muted">Double-click the <code>.deb</code> file to install it with Software, or run <code>sudo apt install ./Arx-…-linux-x86_64.deb</code>.</p></div></li>
|
| 157 |
+
<li><span class="hs-n">2</span><div><b>Any other distribution</b><p class="muted">Run <code>chmod +x Arx-…-linux-x86_64.AppImage</code>, then double-click it.</p></div></li>
|
| 158 |
+
</ol>
|
| 159 |
+
</div>
|
| 160 |
</section>
|
| 161 |
|
| 162 |
<section class="wrap section" id="about">
|
| 163 |
<div class="section-head"><h2>Why trust it</h2></div>
|
| 164 |
<div class="trust-grid">
|
| 165 |
+
<div class="card c-red"><b>🔒 Read-only</b><p class="muted">Arx reads settings and never changes them. You decide what to fix.</p></div>
|
| 166 |
+
<div class="card c-blue"><b>📴 Offline and private</b><p class="muted">The audit and the AI run on your computer. The report stays there unless you share it.</p></div>
|
| 167 |
+
<div class="card c-green"><b>🧾 Grounded report</b><p class="muted">The AI writes only from what the audit found and the Devseis library, and each answer is checked against both. If a check fails, Arx uses a fixed template instead.</p></div>
|
| 168 |
+
<div class="card c-violet"><b>📖 Open source</b><p class="muted">Code Apache-2.0, data CC BY 4.0. <a class="link" href="https://huggingface.co/spaces/Devseis/Arx/tree/main">Read the source</a>.</p></div>
|
| 169 |
</div>
|
| 170 |
<details class="faq"><summary>Is this a certification?</summary><p class="muted">No. ISO 27001 certification needs an accredited auditor, and much of GDPR and AI Act compliance is organisational. Arx collects evidence from the computer and flags the gaps.</p></details>
|
| 171 |
<details class="faq"><summary>I'm setting this up for a company</summary><p class="muted">Before running, edit <code>baseline.conf</code> (approved admins, approved AI tools, limits) and <code>organisational.conf</code> (8 company questions). They are in <code>~/Library/Application Support/Devseis Endpoint Auditor</code> on Mac, <code>%APPDATA%\Devseis Endpoint Auditor</code> on Windows and <code>~/.config/Devseis Endpoint Auditor</code> on Linux.</p></details>
|
|
|
|
| 196 |
|
| 197 |
<footer class="foot">
|
| 198 |
<div class="wrap foot-inner">
|
| 199 |
+
<div><b>Arx</b> <span class="muted">· a free security audit for your computer</span></div>
|
| 200 |
<div class="foot-links"><a href="#download">Download</a><a href="https://huggingface.co/spaces/Devseis/Arx/tree/main">Source</a><a href="https://huggingface.co/datasets/Devseis/endpoint-auditor-releases">Releases</a><a href="https://huggingface.co/Devseis/endpoint-auditor-0.5b">AI model</a><a href="CITATION.cff">Cite</a></div>
|
| 201 |
</div>
|
| 202 |
</footer>
|
| 203 |
+
<div class="modal-back hidden" id="dlModal" role="dialog" aria-modal="true" aria-labelledby="dlModalTitle">
|
| 204 |
+
<div class="modal">
|
| 205 |
+
<button type="button" class="icon-btn modal-x" id="dlModalClose" aria-label="Close">✕</button>
|
| 206 |
+
<p class="eyebrow">⬇️ Downloading Arx…</p>
|
| 207 |
+
<h2 id="dlModalTitle">Next: open Arx</h2>
|
| 208 |
+
<div id="dlModalBody"></div>
|
| 209 |
+
<button type="button" class="btn btn-primary" id="dlModalOk">Got it</button>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
<div class="toast hidden" id="toast" role="status"></div>
|
| 213 |
<script type="module" src="site/site.js"></script>
|
| 214 |
</body>
|
site/site.css
CHANGED
|
@@ -3,7 +3,9 @@
|
|
| 3 |
--bg: #f7f7f7; --card: #ffffff; --fg: #0a0a0a; --muted: #737373; --soft: #a3a3a3; --border: #e5e5e5;
|
| 4 |
--primary: #171717; --primary-fg: #fafafa; --hover: #f2f2f2; --chip: #f2f2f2;
|
| 5 |
--high-bg: #fee2e2; --high-fg: #b91c1c; --med-bg: #fef3c7; --med-fg: #b45309; --low-bg: #e0f2fe; --low-fg: #0369a1;
|
| 6 |
-
--ok-bg: #dcfce7; --ok-fg: #15803d; --brand: #ed2939; --radius: 10px;
|
|
|
|
|
|
|
| 7 |
--font: 'Inconsolata', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
| 8 |
color-scheme: light;
|
| 9 |
}
|
|
@@ -12,14 +14,14 @@
|
|
| 12 |
--bg: #0a0a0a; --card: #171717; --fg: #fafafa; --muted: #a3a3a3; --soft: #737373; --border: rgba(255,255,255,.1);
|
| 13 |
--primary: #e5e5e5; --primary-fg: #171717; --hover: #262626; --chip: #262626;
|
| 14 |
--high-bg: rgba(239,68,68,.15); --high-fg: #f87171; --med-bg: rgba(245,158,11,.15); --med-fg: #fbbf24; --low-bg: rgba(14,165,233,.15); --low-fg: #38bdf8;
|
| 15 |
-
--ok-bg: rgba(34,197,94,.15); --ok-fg: #4ade80; color-scheme: dark;
|
| 16 |
}
|
| 17 |
}
|
| 18 |
:root[data-theme="dark"] {
|
| 19 |
--bg: #0a0a0a; --card: #171717; --fg: #fafafa; --muted: #a3a3a3; --soft: #737373; --border: rgba(255,255,255,.1);
|
| 20 |
--primary: #e5e5e5; --primary-fg: #171717; --hover: #262626; --chip: #262626;
|
| 21 |
--high-bg: rgba(239,68,68,.15); --high-fg: #f87171; --med-bg: rgba(245,158,11,.15); --med-fg: #fbbf24; --low-bg: rgba(14,165,233,.15); --low-fg: #38bdf8;
|
| 22 |
-
--ok-bg: rgba(34,197,94,.15); --ok-fg: #4ade80; color-scheme: dark;
|
| 23 |
}
|
| 24 |
|
| 25 |
* { box-sizing: border-box; }
|
|
@@ -212,3 +214,53 @@ p { margin: 0; }
|
|
| 212 |
.finding { break-inside: avoid; }
|
| 213 |
details.finding:not([open]) > .f-body, .other-results:not([open]) > .findings { display: flex !important; }
|
| 214 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
--bg: #f7f7f7; --card: #ffffff; --fg: #0a0a0a; --muted: #737373; --soft: #a3a3a3; --border: #e5e5e5;
|
| 4 |
--primary: #171717; --primary-fg: #fafafa; --hover: #f2f2f2; --chip: #f2f2f2;
|
| 5 |
--high-bg: #fee2e2; --high-fg: #b91c1c; --med-bg: #fef3c7; --med-fg: #b45309; --low-bg: #e0f2fe; --low-fg: #0369a1;
|
| 6 |
+
--ok-bg: #dcfce7; --ok-fg: #15803d; --brand: #ed2939; --brand-2: #f97316; --radius: 10px;
|
| 7 |
+
--red: #ed2939; --blue: #2563eb; --green: #16a34a; --violet: #7c3aed; --amber: #d97706;
|
| 8 |
+
--tint: 8%; --glow1: rgba(237,41,57,.16); --glow2: rgba(249,115,22,.12); --glow3: rgba(124,58,237,.12);
|
| 9 |
--font: 'Inconsolata', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
| 10 |
color-scheme: light;
|
| 11 |
}
|
|
|
|
| 14 |
--bg: #0a0a0a; --card: #171717; --fg: #fafafa; --muted: #a3a3a3; --soft: #737373; --border: rgba(255,255,255,.1);
|
| 15 |
--primary: #e5e5e5; --primary-fg: #171717; --hover: #262626; --chip: #262626;
|
| 16 |
--high-bg: rgba(239,68,68,.15); --high-fg: #f87171; --med-bg: rgba(245,158,11,.15); --med-fg: #fbbf24; --low-bg: rgba(14,165,233,.15); --low-fg: #38bdf8;
|
| 17 |
+
--ok-bg: rgba(34,197,94,.15); --ok-fg: #4ade80; --red: #f43f5e; --blue: #60a5fa; --green: #4ade80; --violet: #a78bfa; --amber: #fbbf24; --tint: 14%; --glow1: rgba(244,63,94,.18); --glow2: rgba(249,115,22,.12); --glow3: rgba(167,139,250,.14); color-scheme: dark;
|
| 18 |
}
|
| 19 |
}
|
| 20 |
:root[data-theme="dark"] {
|
| 21 |
--bg: #0a0a0a; --card: #171717; --fg: #fafafa; --muted: #a3a3a3; --soft: #737373; --border: rgba(255,255,255,.1);
|
| 22 |
--primary: #e5e5e5; --primary-fg: #171717; --hover: #262626; --chip: #262626;
|
| 23 |
--high-bg: rgba(239,68,68,.15); --high-fg: #f87171; --med-bg: rgba(245,158,11,.15); --med-fg: #fbbf24; --low-bg: rgba(14,165,233,.15); --low-fg: #38bdf8;
|
| 24 |
+
--ok-bg: rgba(34,197,94,.15); --ok-fg: #4ade80; --red: #f43f5e; --blue: #60a5fa; --green: #4ade80; --violet: #a78bfa; --amber: #fbbf24; --tint: 14%; --glow1: rgba(244,63,94,.18); --glow2: rgba(249,115,22,.12); --glow3: rgba(167,139,250,.14); color-scheme: dark;
|
| 25 |
}
|
| 26 |
|
| 27 |
* { box-sizing: border-box; }
|
|
|
|
| 214 |
.finding { break-inside: avoid; }
|
| 215 |
details.finding:not([open]) > .f-body, .other-results:not([open]) > .findings { display: flex !important; }
|
| 216 |
}
|
| 217 |
+
|
| 218 |
+
/* ---------- colour ---------- */
|
| 219 |
+
body { background: radial-gradient(900px 420px at 15% -80px, var(--glow1), transparent 70%), radial-gradient(800px 380px at 85% -60px, var(--glow3), transparent 70%), radial-gradient(700px 360px at 50% 260px, var(--glow2), transparent 70%), var(--bg); background-repeat: no-repeat; }
|
| 220 |
+
.grad { background: linear-gradient(90deg, var(--brand), var(--brand-2) 55%, var(--violet)); -webkit-background-clip: text; background-clip: text; color: transparent; }
|
| 221 |
+
.btn-primary { background: linear-gradient(135deg, var(--brand), #d61f3a); color: #fff; border-color: transparent; box-shadow: 0 6px 18px -8px var(--brand); }
|
| 222 |
+
.btn-primary:hover { background: linear-gradient(135deg, #f0384a, var(--brand)); }
|
| 223 |
+
.step-n { background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: #fff; }
|
| 224 |
+
.pill[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: #fff; }
|
| 225 |
+
.pill[aria-pressed="true"] .soft { color: rgba(255,255,255,.75); }
|
| 226 |
+
.c-red { --c: var(--red); } .c-blue { --c: var(--blue); } .c-green { --c: var(--green); } .c-violet { --c: var(--violet); }
|
| 227 |
+
.stat[class*="c-"], .card[class*="c-"] { border-top: 3px solid var(--c); background: linear-gradient(180deg, color-mix(in srgb, var(--c) var(--tint), var(--card)), var(--card) 70%); }
|
| 228 |
+
.stat[class*="c-"] b { color: var(--c); }
|
| 229 |
+
.check-card:hover { border-color: var(--red); box-shadow: 0 8px 24px -14px var(--red); }
|
| 230 |
+
.dl-card { border-top: 3px solid var(--c, var(--border)); }
|
| 231 |
+
.dl-card[data-os="mac"] { --c: var(--violet); } .dl-card[data-os="windows"] { --c: var(--blue); } .dl-card[data-os="linux"] { --c: var(--amber); }
|
| 232 |
+
.dl-card.you { box-shadow: 0 10px 30px -18px var(--c); border-color: var(--c); }
|
| 233 |
+
.bar i { background: linear-gradient(90deg, var(--brand), var(--brand-2)); }
|
| 234 |
+
.eyebrow { color: var(--brand); }
|
| 235 |
+
.link { color: var(--blue); }
|
| 236 |
+
.table tbody tr:hover td { background: color-mix(in srgb, var(--red) 5%, var(--card)); }
|
| 237 |
+
|
| 238 |
+
/* ---------- first-open help ---------- */
|
| 239 |
+
.seg-help { margin-bottom: 12px; }
|
| 240 |
+
.help-why { margin: 0 2px 12px; font-size: 14px; }
|
| 241 |
+
.help-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
|
| 242 |
+
.help-steps li { display: flex; gap: 12px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; }
|
| 243 |
+
.help-steps p { font-size: 14px; margin-top: 4px; }
|
| 244 |
+
.hs-n { flex: 0 0 26px; height: 26px; border-radius: 50%; background: var(--blue); color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 13px; }
|
| 245 |
+
.mock { margin-top: 10px; border-radius: 12px; padding: 12px; font-family: -apple-system, 'Segoe UI', system-ui, sans-serif; font-size: 12px; display: flex; flex-direction: column; gap: 6px; }
|
| 246 |
+
.mock-alert { background: var(--chip); align-items: center; text-align: center; max-width: 260px; }
|
| 247 |
+
.mock-icon { font-size: 22px; }
|
| 248 |
+
.mock-settings { background: var(--chip); }
|
| 249 |
+
.mock-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: var(--card); border-radius: 8px; padding: 8px 10px; }
|
| 250 |
+
.mock-win { background: #1e5aa8; color: #fff; border-radius: 4px; }
|
| 251 |
+
.mock-link { text-decoration: underline; }
|
| 252 |
+
.mock-btns { display: flex; gap: 6px; justify-content: center; }
|
| 253 |
+
.mock-btn { padding: 4px 10px; border-radius: 6px; background: var(--card); color: var(--fg); border: 1px solid var(--border); white-space: nowrap; }
|
| 254 |
+
.mock-blue { background: #0a84ff; color: #fff; border-color: #0a84ff; }
|
| 255 |
+
.mock-hl { background: #0a84ff; color: #fff; border-color: #0a84ff; box-shadow: 0 0 0 3px rgba(237,41,57,.55); }
|
| 256 |
+
.mock-win .mock-btns { justify-content: flex-end; }
|
| 257 |
+
.mock-win .mock-btn { background: #fff; color: #000; border-radius: 0; }
|
| 258 |
+
|
| 259 |
+
/* ---------- after-download modal ---------- */
|
| 260 |
+
.modal-back { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.45); display: grid; place-items: center; padding: 16px; }
|
| 261 |
+
.modal { position: relative; width: min(560px, 100%); max-height: calc(100vh - 32px); overflow: auto; background: var(--card); border: 1px solid var(--border); border-top: 4px solid var(--brand); border-radius: 14px; padding: 22px 20px 18px; display: flex; flex-direction: column; gap: 12px; }
|
| 262 |
+
.modal h2 { font-size: 22px; }
|
| 263 |
+
.modal-x { position: absolute; top: 12px; right: 12px; }
|
| 264 |
+
.modal .help-steps { grid-template-columns: 1fr; }
|
| 265 |
+
.modal .eyebrow { margin: 0; }
|
| 266 |
+
@media (max-width: 760px) { .help-steps { grid-template-columns: 1fr; } }
|
site/site.js
CHANGED
|
@@ -47,8 +47,35 @@ async function detect() {
|
|
| 47 |
return { phone, os, browser, version, arch };
|
| 48 |
}
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
function chooseOs(os) {
|
| 51 |
state.os = os;
|
|
|
|
| 52 |
document.querySelectorAll('#osSeg button').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.os === os)));
|
| 53 |
document.querySelectorAll('.dl-card').forEach(c => {
|
| 54 |
c.classList.toggle('you', c.dataset.os === os);
|
|
|
|
| 47 |
return { phone, os, browser, version, arch };
|
| 48 |
}
|
| 49 |
|
| 50 |
+
// ---------- first-open help + the pop-up after a download ----------
|
| 51 |
+
function showHelp(os) {
|
| 52 |
+
document.querySelectorAll('#helpSeg button').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.help === os)));
|
| 53 |
+
document.querySelectorAll('#first-open .help-panel').forEach(p => p.classList.toggle('hidden', p.dataset.help !== os));
|
| 54 |
+
}
|
| 55 |
+
document.querySelectorAll('#helpSeg button').forEach(b => b.addEventListener('click', () => showHelp(b.dataset.help)));
|
| 56 |
+
|
| 57 |
+
function openDlModal(os) {
|
| 58 |
+
const panel = document.querySelector(`#first-open .help-panel[data-help="${os}"]`);
|
| 59 |
+
$('dlModalBody').innerHTML = panel.innerHTML;
|
| 60 |
+
$('dlModal').classList.remove('hidden');
|
| 61 |
+
$('dlModalOk').focus();
|
| 62 |
+
}
|
| 63 |
+
const closeDlModal = () => $('dlModal').classList.add('hidden');
|
| 64 |
+
$('dlModalClose').addEventListener('click', closeDlModal);
|
| 65 |
+
$('dlModalOk').addEventListener('click', closeDlModal);
|
| 66 |
+
$('dlModal').addEventListener('click', e => { if (e.target === $('dlModal')) closeDlModal(); });
|
| 67 |
+
addEventListener('keydown', e => { if (e.key === 'Escape') closeDlModal(); });
|
| 68 |
+
// Any real download link: let the download start, then show what to do next for that system.
|
| 69 |
+
document.addEventListener('click', e => {
|
| 70 |
+
const a = e.target.closest('a[href]');
|
| 71 |
+
if (!a || !a.href.startsWith(RELEASES)) return;
|
| 72 |
+
const os = a.closest('.dl-card')?.dataset.os || state.os;
|
| 73 |
+
setTimeout(() => openDlModal(os), 400);
|
| 74 |
+
});
|
| 75 |
+
|
| 76 |
function chooseOs(os) {
|
| 77 |
state.os = os;
|
| 78 |
+
showHelp(os);
|
| 79 |
document.querySelectorAll('#osSeg button').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.os === os)));
|
| 80 |
document.querySelectorAll('.dl-card').forEach(c => {
|
| 81 |
c.classList.toggle('you', c.dataset.os === os);
|