@@ -107,6 +107,18 @@ jobs:
|
||||
SKIP_INTEGRATION: '1'
|
||||
run: npm test
|
||||
|
||||
- name: Verify branding icons
|
||||
timeout-minutes: 2
|
||||
run: |
|
||||
set -euo pipefail
|
||||
test -f build/icon.png
|
||||
test -f build/icon.ico
|
||||
test -f assets/favicons/favicon.ico
|
||||
test -f assets/logo/peardata-icon-64.png
|
||||
node scripts/build-branding.cjs --sync-only
|
||||
ls -la build/icon.png build/icon.ico assets/logo/peardata-icon-64.png
|
||||
file build/icon.png build/icon.ico || true
|
||||
|
||||
- name: Install rcodesign (macOS codesign on Linux)
|
||||
timeout-minutes: 2
|
||||
run: |
|
||||
|
||||
@@ -66,6 +66,19 @@ jobs:
|
||||
SKIP_INTEGRATION: '1'
|
||||
run: npm test
|
||||
|
||||
- name: Verify branding icons
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Committed runtime copies (master package is peardata-branding/)
|
||||
test -f build/icon.png
|
||||
test -f build/icon.ico
|
||||
test -f assets/favicons/favicon.ico
|
||||
test -f assets/logo/peardata-icon-64.png
|
||||
# Sync is a no-op when masters already exist (no sharp required)
|
||||
node scripts/build-branding.cjs --sync-only
|
||||
ls -la build/icon.png build/icon.ico assets/logo/peardata-icon-64.png
|
||||
file build/icon.png build/icon.ico
|
||||
|
||||
- name: Install rcodesign
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# PearData
|
||||
|
||||
<p align="center">
|
||||
<img src="peardata-branding/logo/peardata-icon-512.png" alt="PearData" width="160" />
|
||||
</p>
|
||||
|
||||
**Decentralized, P2P, real-time monitoring for the Pear / Holepunch ecosystem.**
|
||||
|
||||
Each machine runs a lightweight **PearMonitor agent**. A Pear desktop client dials agents by public key and shows fleet + per-node live dashboards. Agents also expose an **agent-compatible REST API** (`/api/v1`, `/api/v2`, `/api/v3`) for scripts, Grafana, and Prometheus.
|
||||
@@ -15,6 +19,18 @@ Built from the [pear-app-template](https://github.com/snxraven) HyperDHT + proto
|
||||
| HTTP | agent-style REST on `127.0.0.1:18888` |
|
||||
| Desktop | **Pear** (`pear-electron` + `pear-bridge` + `<pear-ctrl>`) |
|
||||
|
||||
### Branding
|
||||
|
||||
Master assets live in **`peardata-branding/`** (logo ladder, app icons, favicons, social/web).
|
||||
Runtime copies: `build/icon.{png,icns,ico}`, `assets/logo/`, `assets/favicons/`.
|
||||
|
||||
```bash
|
||||
npm run build:branding # regenerate from masters (needs sharp)
|
||||
npm run sync:branding # copy masters → build/ + assets/
|
||||
```
|
||||
|
||||
See [docs/BRANDING.md](./docs/BRANDING.md).
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "PearData",
|
||||
"version": "1.0.0",
|
||||
"description": "Decentralized P2P real-time monitoring and fleet observability",
|
||||
"colors": {
|
||||
"background": {
|
||||
"primary": "#0a0c10",
|
||||
"secondary": "#0f131a",
|
||||
"tertiary": "#151b24",
|
||||
"elevated": "#1a222e",
|
||||
"hover": "#232d3b"
|
||||
},
|
||||
"accent": {
|
||||
"primary": "#34d399",
|
||||
"secondary": "#2dd4bf",
|
||||
"success": "#4ade80",
|
||||
"warning": "#fbbf24",
|
||||
"danger": "#f87171",
|
||||
"info": "#38bdf8"
|
||||
},
|
||||
"text": {
|
||||
"primary": "#f4f7fb",
|
||||
"secondary": "#c8d1df",
|
||||
"muted": "#9aa8bc",
|
||||
"faint": "#7d8b9f"
|
||||
},
|
||||
"logo": {
|
||||
"peer": "#34d399",
|
||||
"peerSecondary": "#2dd4bf",
|
||||
"link": "#2dd4bf",
|
||||
"sparkline": "#34d399",
|
||||
"core": "#0a0c10",
|
||||
"text": "#f4f7fb"
|
||||
},
|
||||
"border": "rgba(255,255,255,0.1)"
|
||||
},
|
||||
"typography": {
|
||||
"fontFamily": "'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
|
||||
"monoFamily": "'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace",
|
||||
"baseSize": "14px",
|
||||
"lineHeight": 1.5
|
||||
},
|
||||
"radius": {
|
||||
"default": "14px",
|
||||
"small": "10px",
|
||||
"large": "18px"
|
||||
},
|
||||
"logoUsage": {
|
||||
"minSize": "24px",
|
||||
"clearSpace": "0.5x logo height",
|
||||
"preferredBg": "dark #0a0c10 or pure white",
|
||||
"source": "logo/peardata-icon-master.svg — flat P2P mesh + metrics sparkline"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* PearData brand color tokens — matches ui/styles.css */
|
||||
:root {
|
||||
--pd-bg-primary: #0a0c10;
|
||||
--pd-bg-secondary: #0f131a;
|
||||
--pd-bg-tertiary: #151b24;
|
||||
--pd-bg-elevated: #1a222e;
|
||||
--pd-bg-hover: #232d3b;
|
||||
|
||||
--pd-accent-primary: #34d399;
|
||||
--pd-accent-secondary: #2dd4bf;
|
||||
--pd-accent-success: #4ade80;
|
||||
--pd-accent-warning: #fbbf24;
|
||||
--pd-accent-danger: #f87171;
|
||||
--pd-accent-info: #38bdf8;
|
||||
|
||||
--pd-text-primary: #f4f7fb;
|
||||
--pd-text-secondary: #c8d1df;
|
||||
--pd-text-muted: #9aa8bc;
|
||||
--pd-text-faint: #7d8b9f;
|
||||
|
||||
--pd-border: rgba(255, 255, 255, 0.1);
|
||||
|
||||
--pd-logo-peer: #34d399;
|
||||
--pd-logo-peer-secondary: #2dd4bf;
|
||||
--pd-logo-link: #2dd4bf;
|
||||
--pd-logo-sparkline: #34d399;
|
||||
--pd-logo-core: #0a0c10;
|
||||
|
||||
--pd-radius: 14px;
|
||||
--pd-radius-sm: 10px;
|
||||
--pd-radius-lg: 18px;
|
||||
--pd-theme-color: #34d399;
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="mstile-150x150.png"/>
|
||||
<TileColor>#0a0c10</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "PearData",
|
||||
"short_name": "PearData",
|
||||
"description": "Decentralized P2P real-time monitoring — fleet observability on Holepunch",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#0a0c10",
|
||||
"theme_color": "#34d399",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "apple-touch-icon.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 88 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 64" width="320" height="64" role="img" aria-label="PearData">
|
||||
<text x="0" y="46" font-family="Outfit, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" font-weight="700" font-size="44" fill="#0f172a" letter-spacing="-0.03em">PearData</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 362 B |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 64" width="320" height="64" role="img" aria-label="PearData">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#34d399"/>
|
||||
<stop offset="100%" stop-color="#2dd4bf"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<text x="0" y="46" font-family="Outfit, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" font-weight="700" font-size="44" fill="url(#g)" letter-spacing="-0.03em">PearData</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 555 B |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 64" width="320" height="64" role="img" aria-label="PearData">
|
||||
<text x="0" y="46" font-family="Outfit, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" font-weight="700" font-size="44" fill="#f4f7fb" letter-spacing="-0.03em">PearData</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 362 B |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 361 KiB |
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,42 @@
|
||||
# PearData branding
|
||||
|
||||
Master brand package: **`peardata-branding/`** (source of truth).
|
||||
Runtime copies used by the desktop app and Electron packager:
|
||||
|
||||
| Path | Role |
|
||||
|------|------|
|
||||
| `build/icon.png` / `icon.icns` / `icon.ico` | Electron Forge packager + window icon |
|
||||
| `assets/logo/` | Titlebar mark, README, UI |
|
||||
| `assets/favicons/` | Browser / PWA icons + webmanifest |
|
||||
| `assets/brand/` | `colors.css` + `brand-tokens.json` |
|
||||
|
||||
## Regenerate
|
||||
|
||||
Requires `sharp` + `png-to-ico` (not a production dependency — install when regenerating):
|
||||
|
||||
```bash
|
||||
npm install --no-save sharp png-to-ico
|
||||
npm run build:branding
|
||||
```
|
||||
|
||||
Sync existing masters into `build/` + `assets/` without regenerating:
|
||||
|
||||
```bash
|
||||
npm run sync:branding
|
||||
```
|
||||
|
||||
## Wire-up
|
||||
|
||||
- **HTML** — favicons, theme-color, titlebar `<img src="assets/logo/peardata-icon-64.png">`
|
||||
- **Electron** — `electron/main.cjs` → `resolveAppIcon()` reads `build/icon.*`
|
||||
- **Forge** — `packagerConfig.icon = build/icon`; `prePackage` warns if missing; ignores `peardata-branding/`
|
||||
- **make / CI** — client builds ensure icons; release workflows verify `build/icon.png` + favicons
|
||||
- **install.sh** — Linux desktop entry picks packaged `icon.png`
|
||||
|
||||
## Brand mark
|
||||
|
||||
**Minimal flat design:** P2P mesh (three peer nodes linked) + metrics sparkline.
|
||||
Master: `peardata-branding/logo/peardata-icon-master.svg` (raster ladder built from SVG).
|
||||
Colors match `ui/styles.css` (`#0a0c10` bg, `#34d399` / `#2dd4bf` accents).
|
||||
|
||||
See `peardata-branding/README.md` for the full package map.
|
||||
@@ -73,7 +73,12 @@ Pear provides a custom element **`<pear-ctrl>`** for platform window controls:
|
||||
<div id="titlebar" role="banner">
|
||||
<div class="titlebar-left">
|
||||
<pear-ctrl></pear-ctrl>
|
||||
<div class="app-brand">…</div>
|
||||
<div class="app-brand">
|
||||
<div class="app-brand-mark">
|
||||
<img src="assets/logo/peardata-icon-64.png" alt="" width="22" height="22">
|
||||
</div>
|
||||
<div class="app-brand-text">PearData <span>P2P observability</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="titlebar-right">
|
||||
<!-- status chips, non-drag interactive bits -->
|
||||
|
||||
@@ -161,9 +161,19 @@ function buildPreloadPath() {
|
||||
|
||||
function resolveAppIcon() {
|
||||
const appRoot = app.isPackaged ? app.getAppPath() : path.resolve(__dirname, '..')
|
||||
const preferred =
|
||||
process.platform === 'win32'
|
||||
? 'icon.ico'
|
||||
: process.platform === 'darwin'
|
||||
? 'icon.icns'
|
||||
: 'icon.png'
|
||||
const candidates = [
|
||||
path.join(appRoot, 'build', process.platform === 'win32' ? 'icon.ico' : 'icon.png'),
|
||||
path.join(appRoot, 'build', preferred),
|
||||
path.join(appRoot, 'build', 'icon.png'),
|
||||
path.join(appRoot, 'build', 'icon.ico'),
|
||||
// Fallbacks when packaged under resources
|
||||
path.join(appRoot, 'assets', 'logo', 'peardata-icon-512.png'),
|
||||
path.join(appRoot, 'assets', 'logo', 'peardata-icon-256.png'),
|
||||
]
|
||||
for (const p of candidates) {
|
||||
if (fs.existsSync(p)) return p
|
||||
|
||||
@@ -98,6 +98,8 @@ const IGNORE_PREFIXES = [
|
||||
'/.cache',
|
||||
'/build/stubs',
|
||||
'/build/shims',
|
||||
// Master brand package (runtime copies live in build/ + assets/)
|
||||
'/peardata-branding',
|
||||
'/README.md',
|
||||
'/LICENSE',
|
||||
// Packaging / Bare server toolchain (not needed at Electron runtime)
|
||||
@@ -465,6 +467,27 @@ module.exports = {
|
||||
`[forge] rebuild: ${skipRebuild ? 'skip (onlyModules:[])' : 'enabled'}`
|
||||
)
|
||||
|
||||
// Branding: packager uses build/icon.{png,icns,ico} when present
|
||||
const iconPng = path.join(__dirname, 'build', 'icon.png')
|
||||
if (!fs.existsSync(iconPng)) {
|
||||
try {
|
||||
require('child_process').execFileSync(
|
||||
process.execPath,
|
||||
[path.join(__dirname, 'scripts', 'build-branding.cjs'), '--sync-only'],
|
||||
{ stdio: 'inherit', cwd: __dirname }
|
||||
)
|
||||
} catch (err) {
|
||||
console.warn('[forge] branding sync failed:', err?.message || err)
|
||||
}
|
||||
}
|
||||
if (fs.existsSync(iconPng)) {
|
||||
console.log('[forge] app icon:', iconPng)
|
||||
} else {
|
||||
console.warn(
|
||||
'[forge] missing build/icon.png — run: npm run build:branding (or npm run sync:branding)'
|
||||
)
|
||||
}
|
||||
|
||||
// QVAC Bare worker needs bare-runtime + platform binary in the app package.
|
||||
// On Linux CI, optional deps skip darwin/win32 — force-install the target host.
|
||||
if (qvacEnabled) {
|
||||
|
||||
@@ -4,6 +4,26 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PearData — P2P Fleet Monitoring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Decentralized P2P real-time monitoring — fleet observability on the Holepunch stack"
|
||||
/>
|
||||
<meta name="theme-color" content="#0a0c10" />
|
||||
<meta name="msapplication-TileColor" content="#0a0c10" />
|
||||
<meta name="msapplication-config" content="assets/favicons/browserconfig.xml" />
|
||||
<link rel="icon" href="assets/favicons/favicon.ico" sizes="any" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicons/favicon-16x16.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicons/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="assets/favicons/favicon-48x48.png" />
|
||||
<link rel="apple-touch-icon" href="assets/favicons/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="assets/favicons/site.webmanifest" />
|
||||
<meta property="og:title" content="PearData" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Decentralized P2P real-time monitoring for the Pear / Holepunch ecosystem"
|
||||
/>
|
||||
<meta property="og:image" content="peardata-branding/website/og-image.png" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
@@ -16,6 +36,12 @@
|
||||
var s = JSON.parse(raw)
|
||||
var theme = s.theme || (s.settings && s.settings.theme)
|
||||
if (theme) document.documentElement.dataset.theme = theme
|
||||
if (theme === 'light') {
|
||||
var meta = document.querySelector('meta[name="theme-color"]')
|
||||
if (meta) meta.setAttribute('content', '#f3f5f8')
|
||||
var tile = document.querySelector('meta[name="msapplication-TileColor"]')
|
||||
if (tile) tile.setAttribute('content', '#f3f5f8')
|
||||
}
|
||||
} catch (e) {}
|
||||
</script>
|
||||
<link rel="stylesheet" href="./ui/styles.css" />
|
||||
@@ -26,7 +52,15 @@
|
||||
<div class="titlebar-left">
|
||||
<pear-ctrl></pear-ctrl>
|
||||
<div class="app-brand" aria-hidden="true">
|
||||
<div class="app-brand-mark">◈</div>
|
||||
<div class="app-brand-mark">
|
||||
<img
|
||||
src="assets/logo/peardata-icon-64.png"
|
||||
alt=""
|
||||
width="22"
|
||||
height="22"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="app-brand-text">
|
||||
PearData <span>P2P observability</span>
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"gui": {
|
||||
"main": "index.html",
|
||||
"backgroundColor": "#0a0c10",
|
||||
"icon": "build/icon.png",
|
||||
"height": 860,
|
||||
"width": 1280,
|
||||
"minWidth": 900,
|
||||
@@ -55,6 +56,8 @@
|
||||
"release:notes": "node -e \"console.log('See docs/RELEASE.md')\"",
|
||||
"build:client-bundle": "node scripts/build-client-bundle.cjs",
|
||||
"build:qvac-worker": "node scripts/build-qvac-worker.cjs",
|
||||
"build:branding": "node scripts/build-branding.cjs",
|
||||
"sync:branding": "node scripts/build-branding.cjs --sync-only",
|
||||
"ensure:qvac-bare-runtimes": "node scripts/ensure-qvac-bare-runtimes.cjs --all",
|
||||
"start:client": "npm run build:client-bundle && electron electron/main.cjs",
|
||||
"package:client": "electron-forge package",
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# PearData Branding Package v1.0.0
|
||||
|
||||
Master brand assets for **PearData** — decentralized P2P real-time monitoring.
|
||||
|
||||
Source of truth: `logo/peardata-icon-master.svg` — **P2P peer triangle** + **metrics sparkline** (flat, no fruit motif).
|
||||
Raster sizes are regenerated from the SVG (true alpha).
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
logo/ Master icon + size ladder + wordmarks + mono/dark/light
|
||||
app-icons/ electron/ linux/ windows/ macos iconset + store icons
|
||||
favicons/ ico + PWA sizes + webmanifest + browserconfig
|
||||
website/ og-image, twitter-card, hero/banner assets
|
||||
social/ avatars + banner
|
||||
brand-assets/ colors.css + brand-tokens.json (matches ui/styles.css)
|
||||
```
|
||||
|
||||
## Color tokens
|
||||
|
||||
| Token | Hex | Role |
|
||||
|-------|-----|------|
|
||||
| `--bg-primary` | `#0a0c10` | Main bg |
|
||||
| `--accent-primary` | `#34d399` | Emerald CTA / live |
|
||||
| `--accent-secondary` | `#2dd4bf` | Teal secondary |
|
||||
| `--text-primary` | `#f4f7fb` | Body text |
|
||||
|
||||
See `brand-assets/colors.css` and `brand-assets/brand-tokens.json`.
|
||||
|
||||
## Drop-in usage
|
||||
|
||||
This package is the **source of truth**. Runtime copies:
|
||||
|
||||
| Destination | Contents |
|
||||
|-------------|----------|
|
||||
| `../build/icon.{png,icns,ico}` | Electron Forge / packager icons |
|
||||
| `../assets/logo/` | Titlebar + README logos |
|
||||
| `../assets/favicons/` | Favicons + webmanifest |
|
||||
| `../assets/brand/` | colors.css + brand-tokens.json |
|
||||
|
||||
Regenerate + sync:
|
||||
|
||||
```bash
|
||||
npm run build:branding
|
||||
```
|
||||
|
||||
```html
|
||||
<link rel="icon" href="assets/favicons/favicon.ico" sizes="any">
|
||||
<link rel="apple-touch-icon" href="assets/favicons/apple-touch-icon.png">
|
||||
<link rel="manifest" href="assets/favicons/site.webmanifest">
|
||||
<meta name="theme-color" content="#34d399">
|
||||
```
|
||||
|
||||
Electron Forge:
|
||||
|
||||
```js
|
||||
icon: path.join(__dirname, 'build', 'icon')
|
||||
```
|
||||
|
||||
## Quality
|
||||
|
||||
- Masters use soft alpha keyed from near-black backgrounds (LANCZOS resize)
|
||||
- Prefer `logo/peardata-icon-master.svg` as the only resize source
|
||||
- Wordmarks are SVG (crisp at any size)
|
||||
|
||||
---
|
||||
|
||||
© 2026 snxraven · AGPL-3.0
|
||||
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 361 KiB |
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "PearData",
|
||||
"version": "1.0.0",
|
||||
"description": "Decentralized P2P real-time monitoring and fleet observability",
|
||||
"colors": {
|
||||
"background": {
|
||||
"primary": "#0a0c10",
|
||||
"secondary": "#0f131a",
|
||||
"tertiary": "#151b24",
|
||||
"elevated": "#1a222e",
|
||||
"hover": "#232d3b"
|
||||
},
|
||||
"accent": {
|
||||
"primary": "#34d399",
|
||||
"secondary": "#2dd4bf",
|
||||
"success": "#4ade80",
|
||||
"warning": "#fbbf24",
|
||||
"danger": "#f87171",
|
||||
"info": "#38bdf8"
|
||||
},
|
||||
"text": {
|
||||
"primary": "#f4f7fb",
|
||||
"secondary": "#c8d1df",
|
||||
"muted": "#9aa8bc",
|
||||
"faint": "#7d8b9f"
|
||||
},
|
||||
"logo": {
|
||||
"peer": "#34d399",
|
||||
"peerSecondary": "#2dd4bf",
|
||||
"link": "#2dd4bf",
|
||||
"sparkline": "#34d399",
|
||||
"core": "#0a0c10",
|
||||
"text": "#f4f7fb"
|
||||
},
|
||||
"border": "rgba(255,255,255,0.1)"
|
||||
},
|
||||
"typography": {
|
||||
"fontFamily": "'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
|
||||
"monoFamily": "'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace",
|
||||
"baseSize": "14px",
|
||||
"lineHeight": 1.5
|
||||
},
|
||||
"radius": {
|
||||
"default": "14px",
|
||||
"small": "10px",
|
||||
"large": "18px"
|
||||
},
|
||||
"logoUsage": {
|
||||
"minSize": "24px",
|
||||
"clearSpace": "0.5x logo height",
|
||||
"preferredBg": "dark #0a0c10 or pure white",
|
||||
"source": "logo/peardata-icon-master.svg — flat P2P mesh + metrics sparkline"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* PearData brand color tokens — matches ui/styles.css */
|
||||
:root {
|
||||
--pd-bg-primary: #0a0c10;
|
||||
--pd-bg-secondary: #0f131a;
|
||||
--pd-bg-tertiary: #151b24;
|
||||
--pd-bg-elevated: #1a222e;
|
||||
--pd-bg-hover: #232d3b;
|
||||
|
||||
--pd-accent-primary: #34d399;
|
||||
--pd-accent-secondary: #2dd4bf;
|
||||
--pd-accent-success: #4ade80;
|
||||
--pd-accent-warning: #fbbf24;
|
||||
--pd-accent-danger: #f87171;
|
||||
--pd-accent-info: #38bdf8;
|
||||
|
||||
--pd-text-primary: #f4f7fb;
|
||||
--pd-text-secondary: #c8d1df;
|
||||
--pd-text-muted: #9aa8bc;
|
||||
--pd-text-faint: #7d8b9f;
|
||||
|
||||
--pd-border: rgba(255, 255, 255, 0.1);
|
||||
|
||||
--pd-logo-peer: #34d399;
|
||||
--pd-logo-peer-secondary: #2dd4bf;
|
||||
--pd-logo-link: #2dd4bf;
|
||||
--pd-logo-sparkline: #34d399;
|
||||
--pd-logo-core: #0a0c10;
|
||||
|
||||
--pd-radius: 14px;
|
||||
--pd-radius-sm: 10px;
|
||||
--pd-radius-lg: 18px;
|
||||
--pd-theme-color: #34d399;
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="mstile-150x150.png"/>
|
||||
<TileColor>#0a0c10</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "PearData",
|
||||
"short_name": "PearData",
|
||||
"description": "Decentralized P2P real-time monitoring — fleet observability on Holepunch",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#0a0c10",
|
||||
"theme_color": "#34d399",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "apple-touch-icon.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 88 KiB |
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
PearData — professional flat mark.
|
||||
Hub + three peers (P2P). Metric columns only inside the hub (data).
|
||||
Solid geometry, no crossing decorative lines.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512" role="img" aria-label="PearData">
|
||||
<!-- Links: hub → peers only (star topology reads as P2P fabric when combined with outer ring) -->
|
||||
<g fill="none" stroke="#2DD4BF" stroke-width="20" stroke-linecap="round">
|
||||
<line x1="256" y1="248" x2="256" y2="128"/>
|
||||
<line x1="256" y1="268" x2="148" y2="372"/>
|
||||
<line x1="256" y1="268" x2="364" y2="372"/>
|
||||
</g>
|
||||
<!-- Outer peer ring (fleet mesh) -->
|
||||
<g fill="none" stroke="#14B8A6" stroke-width="16" stroke-linecap="round" opacity="0.75">
|
||||
<line x1="256" y1="112" x2="140" y2="380"/>
|
||||
<line x1="256" y1="112" x2="372" y2="380"/>
|
||||
<line x1="140" y1="380" x2="372" y2="380"/>
|
||||
</g>
|
||||
|
||||
<!-- Peers — solid, no hollow cores -->
|
||||
<circle cx="256" cy="112" r="44" fill="#34D399"/>
|
||||
<circle cx="140" cy="380" r="44" fill="#2DD4BF"/>
|
||||
<circle cx="372" cy="380" r="44" fill="#2DD4BF"/>
|
||||
|
||||
<!-- Hub plate -->
|
||||
<circle cx="256" cy="258" r="72" fill="#0F131A" stroke="#34D399" stroke-width="18"/>
|
||||
<!-- Metric columns (data) — contained, not overlapping links -->
|
||||
<g fill="#34D399">
|
||||
<rect x="222" y="250" width="16" height="40" rx="4"/>
|
||||
<rect x="248" y="230" width="16" height="60" rx="4"/>
|
||||
<rect x="274" y="242" width="16" height="48" rx="4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 53 KiB |