@networkpro/web 1.13.3 → 1.13.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -22,6 +22,53 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
22
22
 
23
23
  ---
24
24
 
25
+ ## [1.13.5] - 2025-06-14
26
+
27
+ ### Added
28
+
29
+ - Introduced `links/` and `posts/` redirect routes for improved navigation and backward compatibility
30
+ - Added `proton-img` and `qrcode-img` utility classes to global stylesheet to eliminate inline styles in `PGPContent.svelte`
31
+ - Set `decoding="sync"` and `loading="eager"` on the first QR code image and the Proton Mail badge to improve perceived load performance and visual smoothness
32
+ - Added `rel="noopener noreferrer"` support to `RedirectPage.svelte`, now used by the new `/links` and `/posts` routes
33
+ - Revised `obtainium-img` class in stylesheets to improve Obtainium image rendering on mobile and enhance overall clarity
34
+ - Added a new `scripts/bootstrap.local.sh` script to streamline local development setup, including OS detection and Playwright dependencies
35
+ - Added a new “Environment Requirements” Wiki page to consolidate Node version constraints, setup instructions, and local dev tooling guidance
36
+ - Replaced the detailed "Getting Started" section in `README.md` with a concise reference to the Wiki and a minimal quickstart snippet
37
+
38
+ ### Changed
39
+
40
+ - Promoted Node.js and npm version enforcement details from README to the Wiki for centralized documentation
41
+ - Removed low-priority CSP report filtering in `csp-report.js` to allow all violations to be logged and reviewed
42
+ - Reordered CSS rules to resolve `no-descending-specificity` warnings triggered by focus selectors
43
+ - Updated `HeaderHome.svelte` and `HeaderDefault.svelte` to use `PAGE.SELF` and `PAGE.BLANK` constants for target behavior
44
+ - Updated `AboutContent.svelte` to use application constant instead of hardcoded value
45
+ - Removed unused `COMPANY_INFO` destructured constant from `PGPContent.svelte`
46
+ - Upgraded dependencies:
47
+ - `svelte` updated from `5.34.1` → `5.34.3`
48
+ - Fixed schema warning in GitHub issue template by replacing `assignees: []` with `assignees: SunDevil311`
49
+ - Version bumped to **v1.13.5**
50
+
51
+ ### Fixed
52
+
53
+ - Restored consistent `:visited` link color by forcing `color: #cba557 !important` across all visited interaction states
54
+ - Prevented gold-on-gold text issue when focusing visited links
55
+ - Rolled back enhanced `:focus-visible` styles to resolve flicker and override conflicts during fast navigation
56
+
57
+ ### Removed
58
+
59
+ - Removed unneeded demo unit test (`demo.test.js`) from `tests/unit`
60
+
61
+ ---
62
+
63
+ ## [1.13.4] - 2025-06-13
64
+
65
+ ### Changed
66
+
67
+ - Version bumped to **v1.13.4**
68
+ - Replaced legacy detached signature file `security.txt.asc` with a new `security.txt.sig` format for consistency and clarity
69
+
70
+ ---
71
+
25
72
  ## [1.13.3] - 2025-06-13
26
73
 
27
74
  ### Changed
@@ -377,7 +424,9 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
377
424
 
378
425
  <!-- Link references -->
379
426
 
380
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.13.3...HEAD
427
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.13.5...HEAD
428
+ [1.13.5]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.5
429
+ [1.13.4]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.4
381
430
  [1.13.3]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.3
382
431
  [1.13.2]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.2
383
432
  [1.13.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.1
@@ -390,3 +439,5 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
390
439
  [1.12.4]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.4
391
440
  [1.12.3]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.3
392
441
  [1.12.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.1
442
+
443
+ <!-- cspell:ignore qrcode -->
package/README.md CHANGED
@@ -156,113 +156,14 @@ tests/
156
156
 
157
157
  ## 🛠 Getting Started
158
158
 
159
- ### 📦 Environment Setup
159
+ For full setup guidance, including environment setup, version enforcement, and local tooling, refer to the 📚 [Environment Requirements Wiki](https://github.com/netwk-pro/netwk-pro.github.io/wiki/Environment-Requirements).
160
160
 
161
161
  ```bash
162
162
  git clone https://github.com/netwk-pro/netwk-pro.github.io.git
163
163
  cd netwk-pro.github.io
164
164
  cp .env.template .env
165
165
  npm install
166
- ```
167
-
168
- Edit .env to configure your environment mode:
169
-
170
- ```env
171
- ENV_MODE=dev # Options: dev, test, ci, preview, prod
172
- ```
173
-
174
- > `ENV_MODE` is used for tooling and workflows — not by SvelteKit itself.
175
- > Use `VITE_`-prefixed env variables for runtime values.
176
-
177
- &nbsp;
178
-
179
- ### 🧰 Local Setup Scripts
180
-
181
- To streamline onboarding and enforce project conventions, you may use the optional helper scripts:
182
-
183
- <!-- FIXME: Create a bootstrap.local.sh file -->
184
-
185
- | File/Script | Description |
186
- | ---------------------------------- | --------------------------------------------------------------------------------- |
187
- | `.env.template` | Template for local environment variables |
188
- | `scripts/checkNode.js` | Validates your Node.js and npm versions |
189
- | `scripts/bootstrap.local.sh` (TBD) | Interactive setup for local configuration and tooling |
190
- | `.vscode/` | Editor recommendations compatible with [VSCodium](https://vscodium.com) / VS Code |
191
-
192
- To get started quickly:
193
-
194
- ```bash
195
- cp .env.template .env
196
- npm install
197
- ```
198
-
199
- > You can also use `bootstrap.local.sh` to automate the steps above and more (optional).
200
- > `ENV_MODE` controls local tooling behavior — it is not used by the app runtime directly.
201
-
202
- &nbsp;
203
-
204
- ### 💾 Version Enforcement
205
-
206
- To ensure consistent environments across contributors and CI systems, this project enforces specific Node.js and npm versions via the `"engines"` field in `package.json`:
207
-
208
- ```json
209
- "engines": {
210
- "node": ">=22.0.0 <25",
211
- "npm": ">=11.0.0 <12"
212
- }
213
- ```
214
-
215
- Version compliance is **softly enforced** after installation via a postinstall lifecycle hook:
216
-
217
- ```bash
218
- npm run check:node
219
- ```
220
-
221
- This script runs `scripts/checkNode.js`, which compares your current Node.js and npm versions against the required ranges. During the install phase, it will log **warnings** for out-of-range versions but allow installation to continue. In all other contexts (manual runs, CI workflows, etc.), it will **fail** with a descriptive error if the versions are out of spec.
222
-
223
- **_Node Version Check (snippet from `scripts/checkNode.js`)_**
224
-
225
- ```javascript
226
- const semver = require('semver');
227
- const { engines } = require('../package.json');
228
-
229
- const requiredNode = engines.node;
230
- const requiredNpm = engines.npm;
231
- const isPostInstall = process.env.npm_lifecycle_event === 'postinstall';
232
-
233
- let hasError = false;
234
-
235
- if (!semver.satisfies(process.version, requiredNode)) {
236
- const msg = `Node.js ${process.version} does not satisfy required range: ${requiredNode}`;
237
- isPostInstall ? console.warn(`⚠️ ${msg}`) : console.error(`❌ ${msg}`);
238
- if (!isPostInstall) hasError = true;
239
- }
240
-
241
- const npmVersion = require('child_process')
242
- .execSync('npm -v')
243
- .toString()
244
- .trim();
245
-
246
- if (!semver.satisfies(npmVersion, requiredNpm)) {
247
- const msg = `npm ${npmVersion} does not satisfy required range: ${requiredNpm}`;
248
- isPostInstall ? console.warn(`⚠️ ${msg}`) : console.error(`❌ ${msg}`);
249
- if (!isPostInstall) hasError = true;
250
- }
251
-
252
- if (!hasError) {
253
- console.log('✅ Node and npm versions are valid.');
254
- } else {
255
- process.exit(1);
256
- }
257
- ```
258
-
259
- For full compatibility, `.nvmrc` and `.node-version` files are provided to work seamlessly with version managers like nvm, asdf, and Volta. This ensures consistent environments across local development, CI pipelines, and deployment targets.
260
-
261
- To manually verify your environment:
262
-
263
- ```bash
264
- node -v # Should fall within engines.node
265
- npm -v # Should fall within engines.npm
166
+ npx playwright install
266
167
  ```
267
168
 
268
169
  </section>
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Copyright © 2025 Network Pro Strategies (Network Pro™)
4
+ # SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
5
+ # This file is part of Network Pro
6
+
7
+ set -euo pipefail
8
+
9
+ echo "🛠 Bootstrapping local development environment..."
10
+
11
+ # Detect OS using uname
12
+ OS="$(uname -s)"
13
+
14
+ # Match OS string to normalized platform label
15
+ case "$OS" in
16
+ Linux*) PLATFORM="linux";;
17
+ Darwin*) PLATFORM="mac";;
18
+ MINGW*|CYGWIN*|MSYS*) PLATFORM="windows";; # Git Bash or similar
19
+ *) PLATFORM="unknown";;
20
+ esac
21
+
22
+ echo "🧭 Detected platform: $PLATFORM"
23
+
24
+ # Exit early for unsupported environments
25
+ if [[ "$PLATFORM" == "unknown" ]]; then
26
+ echo "❌ Unsupported OS. Please use macOS, Linux, WSL, or Git Bash."
27
+ exit 1
28
+ fi
29
+
30
+ # Handle Windows-specific case (Git Bash vs native PowerShell/CMD)
31
+ if [[ "$PLATFORM" == "windows" ]]; then
32
+ if [[ -z "${BASH_VERSION:-}" ]]; then
33
+ echo "⚠️ Detected native Windows shell (e.g., CMD or PowerShell)."
34
+ echo "ℹ️ Please use WSL or Git Bash for full compatibility with this script."
35
+ exit 1
36
+ else
37
+ echo "🪟 Detected Git Bash or compatible shell on Windows."
38
+ fi
39
+ fi
40
+
41
+ # macOS-specific setup logic
42
+ if [[ "$PLATFORM" == "mac" ]]; then
43
+ echo "🍎 Running macOS-specific setup..."
44
+
45
+ # Check for Homebrew presence
46
+ if ! command -v brew &> /dev/null; then
47
+ echo "🔧 Homebrew not found. You can install it via:"
48
+ echo '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
49
+ else
50
+ echo "✅ Homebrew is installed"
51
+ fi
52
+
53
+ # Linux-specific setup logic
54
+ elif [[ "$PLATFORM" == "linux" ]]; then
55
+ echo "🐧 Running Linux-specific setup..."
56
+
57
+ # Check for common dev tool dependencies
58
+ REQUIRED_CMDS=("curl" "git" "node" "npm")
59
+ for cmd in "${REQUIRED_CMDS[@]}"; do
60
+ if ! command -v "$cmd" &> /dev/null; then
61
+ echo "⚠️ Missing required command: $cmd"
62
+ fi
63
+ done
64
+ fi
65
+
66
+ # Log current Node.js and npm versions
67
+ echo "🔍 Checking Node.js and npm versions..."
68
+ node -v
69
+ npm -v
70
+
71
+ # Ensure .env file exists
72
+ if [ ! -f .env ]; then
73
+ echo "📋 Copying .env.template to .env..."
74
+ cp .env.template .env
75
+ else
76
+ echo "✅ .env already exists"
77
+ fi
78
+
79
+ # Install Node.js packages
80
+ echo "📦 Installing Node.js packages..."
81
+ npm install
82
+
83
+ # Install browser binaries for Playwright testing
84
+ echo "🧪 Installing Playwright dependencies..."
85
+ npx playwright install
86
+
87
+ echo "✅ Setup complete!"
88
+ echo "Next: run 'npm run dev' to start the development server."
package/cspell.json CHANGED
@@ -38,6 +38,7 @@
38
38
  "Mailvelope",
39
39
  "Maricopa",
40
40
  "mdsvex",
41
+ "MSYS",
41
42
  "navigations",
42
43
  "neteng",
43
44
  "netpro",
@@ -43,18 +43,20 @@ export default async (request, _context) => {
43
43
  const violated = report['violated-directive'] ?? '';
44
44
  const blockedUri = report['blocked-uri'] ?? '';
45
45
 
46
+ /*
46
47
  // Filter: Skip img-src violations and empty URIs
47
- const ignored = [
48
- violated.startsWith('img-src'),
49
- blockedUri === '',
50
- blockedUri === 'about',
51
- blockedUri.startsWith('chrome-extension://'),
52
- blockedUri.startsWith('moz-extension://'),
53
- ].some(Boolean);
54
-
55
- if (ignored) {
56
- return new Response(null, { status: 204 });
57
- }
48
+ const ignored = [
49
+ violated.startsWith('img-src'),
50
+ blockedUri === '',
51
+ blockedUri === 'about',
52
+ blockedUri.startsWith('chrome-extension://'),
53
+ blockedUri.startsWith('moz-extension://'),
54
+ ].some(Boolean);
55
+
56
+ if (ignored) {
57
+ return new Response(null, { status: 204 });
58
+ }
59
+ */
58
60
 
59
61
  // Send alert for high-risk directives
60
62
  await sendToNtfy(violated, blockedUri, report);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.13.3",
4
+ "version": "1.13.5",
5
5
  "description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advisory",
@@ -82,7 +82,7 @@
82
82
  "dompurify": "^3.2.6",
83
83
  "posthog-js": "^1.252.0",
84
84
  "semver": "^7.7.2",
85
- "svelte": "5.34.1"
85
+ "svelte": "5.34.3"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@eslint/compat": "^1.3.0",
@@ -11,6 +11,7 @@ This file is part of Network Pro.
11
11
  import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
12
 
13
13
  export let to;
14
+ export let rel = ''; // Accepts optional rel value
14
15
  export let delay = 3;
15
16
 
16
17
  onMount(() => {
@@ -39,7 +40,9 @@ This file is part of Network Pro.
39
40
  <h1>Redirecting…</h1>
40
41
  <p>You'll be taken to the destination in just a moment.</p>
41
42
  <div class="loading-spinner" aria-hidden="true"></div>
42
- <p>If nothing happens, <a href={to}>click here</a>.</p>
43
+ <p
44
+ >If nothing happens, <a href={to} rel={rel || undefined}>click here</a
45
+ >.</p>
43
46
  </div>
44
47
  </FullWidthSection>
45
48
 
@@ -8,12 +8,18 @@ This file is part of Network Pro.
8
8
 
9
9
  <script>
10
10
  import { base } from '$app/paths';
11
+ import { CONSTANTS } from '$lib';
11
12
 
12
13
  // Log the base path to verify its value
13
14
  //console.log("Base path:", base);
14
15
 
16
+ //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
17
+
18
+ const { PAGE } = CONSTANTS;
19
+
15
20
  const homeLink = base || '/';
16
21
  const aboutLink = `${base}/about`;
22
+ const lhubLink = `${base}/links`;
17
23
  const fossLink = `${base}/foss-spotlight`;
18
24
  const blogLink = 'https://blog.netwk.pro';
19
25
 
@@ -31,25 +37,25 @@ This file is part of Network Pro.
31
37
  * @type {NavItem[]}
32
38
  */
33
39
  const nav = [
34
- { label: 'home', href: homeLink, target: '_self', external: false },
35
- { label: 'about', href: aboutLink, target: '_self', external: false },
36
- { label: 'foss', href: fossLink, target: '_self', external: false },
40
+ { label: 'home', href: homeLink, target: PAGE.SELF, external: false },
41
+ { label: 'about', href: aboutLink, target: PAGE.SELF, external: false },
42
+ { label: 'foss', href: fossLink, target: PAGE.SELF, external: false },
37
43
  {
38
44
  label: 'blog',
39
45
  href: blogLink,
40
- target: '_self',
46
+ target: PAGE.SELF,
41
47
  external: false,
42
48
  },
43
49
  {
44
50
  label: 'discussions',
45
51
  href: 'https://github.com/netwk-pro/netwk-pro.github.io/discussions',
46
- target: '_blank',
52
+ target: PAGE.BLANK,
47
53
  external: true,
48
54
  },
49
55
  {
50
56
  label: 'link hub',
51
- href: 'https://linktr.ee/neteng_pro',
52
- target: '_blank',
57
+ href: lhubLink,
58
+ target: PAGE.BLANK,
53
59
  external: true,
54
60
  },
55
61
  ];
@@ -69,7 +75,7 @@ This file is part of Network Pro.
69
75
  </a>
70
76
  {#if external}
71
77
  <sup>
72
- <span style="color: #ffc627;">
78
+ <span class="gold">
73
79
  <i class="fas fa-arrow-up-right-from-square fa-2xs"></i>
74
80
  </span>
75
81
  </sup>
@@ -85,3 +91,5 @@ This file is part of Network Pro.
85
91
  {/each}
86
92
  </nav>
87
93
  <!-- END DEFAULT HEADER -->
94
+
95
+ <!-- cspell:ignore lhub -->
@@ -8,12 +8,18 @@ This file is part of Network Pro.
8
8
 
9
9
  <script>
10
10
  import { base } from '$app/paths';
11
+ import { CONSTANTS } from '$lib';
11
12
 
12
13
  // Log the base path to verify its value
13
14
  //console.log("Base path:", base);
14
15
 
16
+ //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
17
+
18
+ const { PAGE } = CONSTANTS;
19
+
15
20
  const aboutLink = `${base}/about`;
16
21
  const fossLink = `${base}/foss-spotlight`;
22
+ const lhubLink = `${base}/links`;
17
23
  const blogLink = 'https://blog.netwk.pro';
18
24
 
19
25
  /**
@@ -30,24 +36,24 @@ This file is part of Network Pro.
30
36
  * @type {NavItem[]}
31
37
  */
32
38
  const nav = [
33
- { label: 'about', href: aboutLink, target: '_self', external: false },
34
- { label: 'foss', href: fossLink, target: '_self', external: false },
39
+ { label: 'about', href: aboutLink, target: PAGE.SELF, external: false },
40
+ { label: 'foss', href: fossLink, target: PAGE.SELF, external: false },
35
41
  {
36
42
  label: 'blog',
37
43
  href: blogLink,
38
- target: '_self',
44
+ target: PAGE.SELF,
39
45
  external: false,
40
46
  },
41
47
  {
42
48
  label: 'discussions',
43
49
  href: 'https://github.com/netwk-pro/netwk-pro.github.io/discussions',
44
- target: '_blank',
50
+ target: PAGE.BLANK,
45
51
  external: true,
46
52
  },
47
53
  {
48
54
  label: 'link hub',
49
- href: 'https://linktr.ee/neteng_pro',
50
- target: '_blank',
55
+ href: lhubLink,
56
+ target: PAGE.BLANK,
51
57
  external: true,
52
58
  },
53
59
  ];
@@ -67,7 +73,7 @@ This file is part of Network Pro.
67
73
  </a>
68
74
  {#if external}
69
75
  <sup>
70
- <span style="color: #ffc627;">
76
+ <span class="gold">
71
77
  <i class="fas fa-arrow-up-right-from-square fa-2xs"></i>
72
78
  </span>
73
79
  </sup>
@@ -83,3 +89,5 @@ This file is part of Network Pro.
83
89
  {/each}
84
90
  </nav>
85
91
  <!-- END HOME HEADER -->
92
+
93
+ <!-- cspell:ignore lhub -->
@@ -209,8 +209,8 @@ This file is part of Network Pro.
209
209
 
210
210
  <p>
211
211
  <strong
212
- >Network Pro&trade; exists to bring strong, thoughtful security to
213
- organizations that value integrity—without sacrificing agility or trust.</strong>
212
+ >{COMPANY_INFO.APP_NAME}&trade; exists to bring strong, thoughtful security
213
+ to organizations that value integrity—without sacrificing agility or trust.</strong>
214
214
  We don't just secure infrastructure. We secure confidence.
215
215
  </p>
216
216
 
@@ -16,7 +16,7 @@ This file is part of Network Pro.
16
16
 
17
17
  //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
18
18
 
19
- const { COMPANY_INFO, PAGE } = CONSTANTS;
19
+ const { PAGE } = CONSTANTS;
20
20
 
21
21
  const keys = [
22
22
  {
@@ -83,14 +83,16 @@ This file is part of Network Pro.
83
83
  <img
84
84
  src="/img/powered-by-proton.svg"
85
85
  alt="Powered by Proton"
86
- style="width: 168px; height: 24px;" />
86
+ class="proton-img"
87
+ loading="eager"
88
+ decoding="sync" />
87
89
  </p>
88
90
  <p class="bquote">
89
91
  NOTE: Addresses under the <strong>s.neteng.pro</strong> domain are powered by Proton
90
92
  Mail to ensure strong end-to-end privacy protections.
91
93
  </p>
92
94
 
93
- {#each keys as key}
95
+ {#each keys as key, i}
94
96
  <section class="pgp-entry" aria-labelledby={`pgp-${key.img}`}>
95
97
  <div class="pgp-text">
96
98
  <h2 id={`pgp-${key.img}`}>{key.name}</h2>
@@ -131,9 +133,9 @@ This file is part of Network Pro.
131
133
  <img
132
134
  src={`/pgp/${key.img}.png`}
133
135
  alt={`QR code for ${key.email}`}
134
- loading="lazy"
135
- decoding="async"
136
- style="width: 150px; height: 150px;" />
136
+ class="pgp-image"
137
+ loading={i === 0 ? 'eager' : 'lazy'}
138
+ decoding={i === 0 ? 'sync' : 'async'} />
137
139
  </picture>
138
140
  </div>
139
141
  </section>
@@ -434,7 +434,7 @@ footer .container {
434
434
  }
435
435
 
436
436
  .gold {
437
- color: #FFC627;
437
+ color: #ffc627;
438
438
  }
439
439
 
440
440
  .visited {
@@ -443,7 +443,7 @@ footer .container {
443
443
 
444
444
  .goldseparator {
445
445
  margin: 0 0.5rem;
446
- color: #FFC627;
446
+ color: #ffc627;
447
447
  }
448
448
 
449
449
  .center-nav {
@@ -552,8 +552,8 @@ footer .container {
552
552
  }
553
553
 
554
554
  .obtainium-img {
555
- width: 201px;
556
- height: 60px;
555
+ width: 185px;
556
+ height: 55px;
557
557
  margin-bottom: 0.25rem;
558
558
  }
559
559
 
@@ -562,7 +562,7 @@ footer .container {
562
562
  }
563
563
 
564
564
  .obtainium-fa-down {
565
- color: #FFC627;
565
+ color: #ffc627;
566
566
  margin-left: 4px;
567
567
  }
568
568
 
@@ -570,3 +570,8 @@ footer .container {
570
570
  width: 50px;
571
571
  height: 50px;
572
572
  }
573
+
574
+ .proton-img {
575
+ width: 168px;
576
+ height: 24px;
577
+ }
@@ -125,28 +125,19 @@ a:hover {
125
125
 
126
126
  /* selected link */
127
127
  a:active {
128
- color: #e0b000;
128
+ color: #ffc627;
129
129
  text-decoration: underline;
130
130
  }
131
131
 
132
- /* visited link */
133
- a:visited {
134
- color: #cba557;
135
- }
136
-
137
132
  /* focused link */
138
- a:focus-visible {
133
+ a:focus {
139
134
  color: #111; /* Black text when focused */
140
135
  background-color: #ffc627; /* Gold background when focused */
141
- outline: 2px solid #ffc627;
142
- outline-offset: 4px;
143
136
  }
144
137
 
145
- /* Reset focus style to avoid duplication */
146
- a:focus:not(:focus-visible) {
147
- color: inherit;
148
- background-color: transparent;
149
- outline: none;
138
+ /* visited link */
139
+ a:visited {
140
+ color: #cba557;
150
141
  }
151
142
 
152
143
  /* visited and mouse over */
@@ -154,6 +145,11 @@ a:visited:hover {
154
145
  color: #cba557;
155
146
  }
156
147
 
148
+ a:visited:focus,
149
+ a:visited:focus-visible {
150
+ color: #111 !important;
151
+ }
152
+
157
153
  /* ==========================================================================
158
154
  Helper classes
159
155
  ========================================================================== */
@@ -3,4 +3,4 @@ Copyright © 2025 Network Pro Strategies (Network Pro™)
3
3
  SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
4
4
  This file is part of Network Pro.
5
5
  ========================================================================== */
6
- html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover{color:#ffc627;text-decoration:underline}a:active{color:#e0b000;text-decoration:underline}a:visited{color:#cba557}a:focus-visible{color:#111;outline-offset:4px;background-color:#ffc627;outline:2px solid #ffc627}a:focus:not(:focus-visible){color:inherit;background-color:#0000;outline:none}a:visited:hover{color:#cba557}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{page-break-inside:avoid;border:1px solid #999}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#cba557}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}.obtainium-direct-label{margin:.25rem 0 .75rem;font-weight:700}.obtainium-manual-label{margin-top:.75rem;font-weight:700}.obtainium-img{width:201px;height:60px;margin-bottom:.25rem}.obtainium-margin{margin-left:4px}.obtainium-fa-down{color:#ffc627;margin-left:4px}.obtainium-icon{width:50px;height:50px}
6
+ html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover,a:active{color:#ffc627;text-decoration:underline}a:focus{color:#111;background-color:#ffc627}a:visited,a:visited:hover{color:#cba557}a:visited:focus,a:visited:focus-visible{color:#111!important}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{page-break-inside:avoid;border:1px solid #999}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#cba557}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}.obtainium-direct-label{margin:.25rem 0 .75rem;font-weight:700}.obtainium-manual-label{margin-top:.75rem;font-weight:700}.obtainium-img{width:185px;height:55px;margin-bottom:.25rem}.obtainium-margin{margin-left:4px}.obtainium-fa-down{color:#ffc627;margin-left:4px}.obtainium-icon{width:50px;height:50px}.proton-img{width:168px;height:24px}
@@ -0,0 +1,33 @@
1
+ <!-- ==========================================================================
2
+ src/routes/contact/+page.svelte
3
+
4
+ Copyright © 2025 Network Pro Strategies (Network Pro™)
5
+ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
+ This file is part of Network Pro.
7
+ ========================================================================== -->
8
+
9
+ <script>
10
+ import RedirectPage from '$lib/components/RedirectPage.svelte';
11
+ import { appendUTM } from '$lib/utils/utm.js';
12
+ import { onMount } from 'svelte';
13
+ import { browser } from '$app/environment';
14
+
15
+ /** @type {string | null} */
16
+ let target = null;
17
+
18
+ /** @type {boolean} */
19
+ let show = false;
20
+
21
+ onMount(() => {
22
+ if (!browser) return;
23
+
24
+ target = appendUTM('https://linktr.ee/neteng_pro');
25
+ show = true;
26
+ });
27
+ </script>
28
+
29
+ {#if show && target}
30
+ <RedirectPage to={target} rel="noopener noreferrer" />
31
+ {:else}
32
+ <p style="text-align: center; margin-top: 4rem;">Preparing to redirect…</p>
33
+ {/if}
@@ -0,0 +1,33 @@
1
+ <!-- ==========================================================================
2
+ src/routes/contact/+page.svelte
3
+
4
+ Copyright © 2025 Network Pro Strategies (Network Pro™)
5
+ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
+ This file is part of Network Pro.
7
+ ========================================================================== -->
8
+
9
+ <script>
10
+ import RedirectPage from '$lib/components/RedirectPage.svelte';
11
+ import { appendUTM } from '$lib/utils/utm.js';
12
+ import { onMount } from 'svelte';
13
+ import { browser } from '$app/environment';
14
+
15
+ /** @type {string | null} */
16
+ let target = null;
17
+
18
+ /** @type {boolean} */
19
+ let show = false;
20
+
21
+ onMount(() => {
22
+ if (!browser) return;
23
+
24
+ target = appendUTM('https://pal.bio/netwk-pro');
25
+ show = true;
26
+ });
27
+ </script>
28
+
29
+ {#if show && target}
30
+ <RedirectPage to={target} rel="noopener noreferrer" />
31
+ {:else}
32
+ <p style="text-align: center; margin-top: 4rem;">Preparing to redirect…</p>
33
+ {/if}
@@ -30,6 +30,12 @@ export default {
30
30
  ],
31
31
  'property-no-vendor-prefix': null, // Allow vendor prefixes
32
32
  'selector-no-vendor-prefix': null,
33
+ 'no-descending-specificity': [
34
+ true,
35
+ {
36
+ ignore: ['selectors-within-list'],
37
+ },
38
+ ],
33
39
  'selector-pseudo-element-colon-notation': [
34
40
  'double',
35
41
  {
@@ -1,15 +0,0 @@
1
- /* ==========================================================================
2
- tests/unit/demo.spec.js
3
-
4
- Copyright © 2025 Network Pro Strategies (Network Pro™)
5
- SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
- This file is part of Network Pro.
7
- ========================================================================== */
8
-
9
- import { describe, expect, it } from 'vitest';
10
-
11
- describe('sum test', () => {
12
- it('adds 1 + 2 to equal 3', () => {
13
- expect(1 + 2).toBe(3);
14
- });
15
- });