From 072e7de934acd187c6bfe711ef9d0bc5cff1e6aa Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:44:55 +0200 Subject: [PATCH 01/21] Build SightAdapt static site: site/index.html Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/index.html diff --git a/site/index.html b/site/index.html new file mode 100644 index 00000000..8aba285f --- /dev/null +++ b/site/index.html @@ -0,0 +1 @@ +SightAdapt™ — per-application visual accessibility for Windows | Aiteracja
SightAdapt is currently an alpha release. Core functionality is available, but broad compatibility and endurance testing are still in progress.

Free and open source · Windows 10 and 11 · Alpha

Adapt the application in front of you.

SightAdapt™ applies configurable color correction to individual Windows application windows. Keep the rest of the desktop unchanged, assign profiles per application and stop every overlay immediately when needed.

Per-application control

Change one application, not your entire desktop.

System-wide display filters can affect every monitor, application and notification. SightAdapt targets the active application through a separate overlay, allowing different applications to use different visual profiles while unrelated windows remain unchanged.

Profiles per application

Assign a saved color profile to an application and let SightAdapt activate it when that application becomes active.

Separate native-menu correction

Use the application profile for native popup menus or assign a different menu profile when menu contrast needs separate treatment.

Flexible overlay scope

Choose the client area, full window, current screen or all screens according to the application and display setup.

Editable visual profiles

Adjust output black and white levels, brightness, contrast, saturation and hue, then preview the result before assigning it.

Manual and automatic controls

Toggle the active window temporarily or save an automatic application assignment.

Immediate shutdown

Remove active overlays from the notification-area menu through the emergency-disable command.

Three steps to a per-application profile.

  1. Select or activate an application.
  2. Choose or create a visual profile.
  3. Enable the assignment or use the temporary shortcut.

See the complete quick start.

Profile examples

  • None — leave the application unchanged.
  • Exact invert — apply a fixed full inversion.
  • Soft invert — use an editable lower-intensity starting profile.
  • Custom profiles — duplicate and adjust a profile for a particular application or display.

Visual preferences are individual. SightAdapt does not choose a medically appropriate profile and does not replace professional advice.

Local settings. No screen-content upload.

SightAdapt stores its configuration locally. The current alpha does not transmit captured screen content, does not inject code into target applications and does not install a kernel driver. Application assignments may include executable paths and file metadata stored in the local settings file.

Read privacy details · Review security boundaries

Built in public.

SightAdapt is developed in a public GitHub repository and distributed under the MIT License. Source code, architecture documentation, test results, issues and release history are available for inspection.

Browse the source · Report an issue · Read the license

Current alpha limitations

  • one foreground application session is corrected at a time;
  • native menu-specific handling applies only to Win32 #32768 popup menus;
  • protected or DRM-controlled content may not be capturable;
  • elevated applications may require a compatible integrity level;
  • remote desktop and some graphics drivers may behave differently;
  • broad compatibility and endurance testing are incomplete.

Read the current release notes.

Try SightAdapt™ and inspect every part of it.

\ No newline at end of file From c5600c7f9453ad3751f0c71817864e6786a41ed1 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:44:57 +0200 Subject: [PATCH 02/21] Build SightAdapt static site: site/features/index.html Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/features/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/features/index.html diff --git a/site/features/index.html b/site/features/index.html new file mode 100644 index 00000000..14aec0b3 --- /dev/null +++ b/site/features/index.html @@ -0,0 +1 @@ +SightAdapt™ features — profiles, overlays and Windows controls

SightAdapt™ features

Features designed around individual applications.

Application assignments

Saved executable-based assignments can be enabled or disabled and are resolved automatically when the matching application becomes foreground.

Visual profile management

Use built-in profiles or duplicate a profile into a user-defined copy that can be renamed, edited and deleted. Built-in profiles remain protected.

Available controls

Profiles expose output black, output white, brightness, contrast, saturation and hue. They are display adjustments, not color-calibration measurements.

Native popup menus

Supported native Win32 #32768 popup menus can inherit the application profile or use a separate profile. Custom-rendered menus are not detected as native popup menus.

Overlay scopes

Choose client area, full window, current screen or all screens. Wider scopes may affect content beyond the application window while the session is active.

Shortcuts and tray controls

Ctrl+Alt+I toggles temporary correction for the active window. Ctrl+Alt+Shift+I toggles the active application assignment. The tray menu includes an emergency command that removes active overlays.

Multi-monitor and DPI behavior

SightAdapt is designed for per-monitor-aware Windows behavior. Remote sessions, unusual graphics drivers and mixed scaling can require application-specific testing.

Settings and migration

Configuration is stored locally in schema-versioned JSON. Supported older settings are migrated; writes are designed to avoid leaving a partially written settings file.

What SightAdapt does not do

  • does not modify another application's files;
  • does not inject code into another process;
  • does not install a driver;
  • does not upload screen content;
  • does not bypass DRM or access controls;
  • does not guarantee compatibility with every rendering framework;
  • does not provide medical diagnosis or treatment.
\ No newline at end of file From 2c0271136ac09ae4306d2daeef74734a7abd0f49 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:45:00 +0200 Subject: [PATCH 03/21] Build SightAdapt static site: site/download/index.html Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/download/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/download/index.html diff --git a/site/download/index.html b/site/download/index.html new file mode 100644 index 00000000..a359adfe --- /dev/null +++ b/site/download/index.html @@ -0,0 +1 @@ +Download SightAdapt™ for Windows
SightAdapt is currently an alpha release. Core functionality is available, but broad compatibility and endurance testing are still in progress.

SightAdapt™ download

Download the current SightAdapt™ release.

{{VERSION}}

Release date{{RELEASE_DATE}}
StatusAlpha prerelease
WindowsWindows 10 version 2004 or later, or Windows 11
Architecturex64
Archive size{{ARCHIVE_SIZE}}
SHA-256{{SHA256}}

Release notes · Source tag · SBOM · Checksums · Legal and compliance files

System requirements

  • Windows 10 version 2004 or later, or Windows 11;
  • x64 processor;
  • user permission to start a desktop application;
  • compatible desktop composition and graphics driver.

Install and start

  1. Download only from a project-controlled Aiteracja page, the official GitHub repository or an approved package listing.
  2. Verify the checksum when practical.
  3. Extract the archive to a user-controlled directory.
  4. Start SightAdapt.exe.
  5. Use the notification-area icon to open configuration.

Verify the checksum in PowerShell

Get-FileHash .\SightAdapt-0.5.0.50-alpha-win-x64.zip -Algorithm SHA256

The resulting hash must match {{SHA256}}.

Windows reputation warning

Unsigned or newly published open-source binaries may trigger Microsoft Defender SmartScreen. Do not disable system protection. Verify the project-controlled source, the published hash and the GitHub Release before deciding whether to run a file.

Removal

Exit SightAdapt, remove the extracted application files and, if you also want to remove saved configuration, delete %LOCALAPPDATA%\SightAdapt\settings.json. Deleting that settings file removes saved profiles and assignments.

Alpha warning. Keep the emergency-disable command available and test the application with non-critical work before relying on it for extended sessions.
\ No newline at end of file From 6a8eba52801c63d51bb6664e9b2392bad863e736 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:45:19 +0200 Subject: [PATCH 04/21] Add static website styles Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/assets/styles.css | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/assets/styles.css diff --git a/site/assets/styles.css b/site/assets/styles.css new file mode 100644 index 00000000..080a4f4a --- /dev/null +++ b/site/assets/styles.css @@ -0,0 +1 @@ +:root{--bg:#f7f8fb;--ink:#121826;--muted:#5d667a;--panel:#fff;--line:#dce1ea;--accent:#1c5cff;--dark:#10182f;--focus:#ffbf47;--max:1120px}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;background:var(--bg);color:var(--ink)}a{color:#164fc9}a:focus-visible,button:focus-visible,summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px}.skip{position:absolute;left:-9999px}.skip:focus{left:1rem;top:1rem;background:#fff;padding:.7rem 1rem;z-index:1000}.wrap{width:min(var(--max),calc(100% - 2rem));margin:auto}.site-header{background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50}.nav{display:flex;align-items:center;gap:1rem;min-height:72px}.brand img{width:205px;height:auto;display:block}.nav-links{display:flex;flex-wrap:wrap;gap:.8rem;margin-left:auto;align-items:center}.nav-links a{color:var(--ink);text-decoration:none;padding:.45rem .55rem;border-radius:.4rem}.nav-links a[aria-current=page]{background:#eef3ff;color:#123a91;font-weight:700}.button{display:inline-block;background:var(--accent);color:#fff!important;text-decoration:none!important;padding:.75rem 1rem;border-radius:.55rem;font-weight:700}.button.secondary{background:#fff;color:#163b85!important;border:1px solid #8aa5e8}.hero{background:var(--dark);color:#fff;padding:4rem 0}.hero a{color:#d9e7ff}.hero-grid{display:grid;grid-template-columns:1.4fr .9fr;gap:2rem;align-items:center}.eyebrow{font-weight:700;color:#b8c8ee}.hero h1{font-size:clamp(2.5rem,6vw,4.8rem);line-height:1.02;margin:.35rem 0 1rem}.lead{font-size:1.22rem;max-width:48rem}.actions{display:flex;gap:.75rem;flex-wrap:wrap;margin:1.5rem 0}.release-card,.card,.notice{background:var(--panel);border:1px solid var(--line);border-radius:.8rem;padding:1.2rem}.hero .release-card{background:#172341;border-color:#34456e;color:#fff}.alpha{background:#fff4d6;border-bottom:1px solid #e6c76c;padding:.7rem 0}.trust{display:grid;grid-template-columns:repeat(4,1fr);gap:.75rem;margin:1.5rem 0}.trust a{display:block;background:#fff;border:1px solid var(--line);padding:1rem;border-radius:.7rem;text-decoration:none;font-weight:700}.section{padding:3rem 0}.section h1,.section h2{line-height:1.2}.section h1{font-size:clamp(2rem,4vw,3rem)}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}.two{grid-template-columns:repeat(2,1fr)}.kicker{color:var(--muted);font-weight:700}.muted{color:var(--muted)}code,pre{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}pre{background:#111827;color:#f9fafb;padding:1rem;overflow:auto;border-radius:.6rem}.architecture{width:100%;height:auto;border:1px solid var(--line);border-radius:.8rem;background:#fff}.site-footer{background:#0f172a;color:#dbe4f3;padding:2.5rem 0}.site-footer a{color:#dbeafe}.footer-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}.footer-grid h2{font-size:1rem;color:#fff}.footer-grid ul{list-style:none;padding:0;margin:0}.small{font-size:.92rem}table{width:100%;border-collapse:collapse;background:#fff}th,td{border:1px solid var(--line);padding:.7rem;text-align:left;vertical-align:top}th{background:#eef1f6}@media(max-width:800px){.hero-grid,.grid,.two,.trust,.footer-grid{grid-template-columns:1fr}.nav{align-items:flex-start;padding:.7rem 0;flex-wrap:wrap}.brand img{width:180px}.nav-links{width:100%;margin-left:0}.hero{padding:2.5rem 0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}} From b0624f0b5b44f3d3510fb76b546502c70ef041bc Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:45:40 +0200 Subject: [PATCH 05/21] Add website asset site/assets/site.js Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/assets/site.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/assets/site.js diff --git a/site/assets/site.js b/site/assets/site.js new file mode 100644 index 00000000..3c8d9f80 --- /dev/null +++ b/site/assets/site.js @@ -0,0 +1 @@ +document.documentElement.classList.add('js'); From 3b5c789b366e42081fc1778b3fc804ee71301e53 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:45:42 +0200 Subject: [PATCH 06/21] Add website asset site/assets/architecture.svg Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/assets/architecture.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/assets/architecture.svg diff --git a/site/assets/architecture.svg b/site/assets/architecture.svg new file mode 100644 index 00000000..3b74c9cb --- /dev/null +++ b/site/assets/architecture.svg @@ -0,0 +1 @@ +SightAdapt architectureForeground Windows application metadata flows to SightAdapt assignment and profile logic, which controls an input-transparent overlay through the Windows Magnification API.Foreground appwindow + process metadataSightAdaptassignment resolutionvisual profile selectionoverlay scope + menu handlingemergency disableWindows overlayMagnification APIinput-transparent From 19b84edf4c17b9f3339afe5ead59b310c9eed30d Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:46:59 +0200 Subject: [PATCH 07/21] Add documentation website page Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/docs/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/docs/index.html diff --git a/site/docs/index.html b/site/docs/index.html new file mode 100644 index 00000000..3fb92f1c --- /dev/null +++ b/site/docs/index.html @@ -0,0 +1 @@ +SightAdapt™ documentation
SightAdapt is currently an alpha release. Core functionality is available, but broad compatibility and endurance testing are still in progress.

SightAdapt™ documentation

Set up SightAdapt and understand each control.

Getting started

  1. Download and extract the current release.
  2. Start SightAdapt.exe.
  3. Open configuration from the notification-area icon.
  4. Assign a profile to an application or use temporary correction.

Applications

Add an application, enable or disable the assignment, choose its profile and configure automatic mode. Saved assignments use executable identity and local path data.

Profiles

Choose a built-in profile, duplicate one into a custom profile, edit output levels, brightness, contrast, saturation and hue, then rename or delete user-created profiles when no longer needed.

Menus and scopes

Native Win32 popup menus can inherit or override the application profile. Overlay scope can target the client area, full window, current screen or all screens. WPF, WinUI, Electron, Qt and custom-rendered menus may not appear as native #32768 menus.

Keyboard and emergency controls

  • Ctrl+Alt+I — temporary active-window correction.
  • Ctrl+Alt+Shift+I — toggle the active application assignment.
  • Emergency disable all overlays — remove overlays and disable automatic mode.

If another program already owns a shortcut, registration may fail.

Troubleshooting

  • For elevated targets, use a compatible integrity level.
  • If the tray icon is missing, check whether SightAdapt is still running.
  • If no overlay appears, confirm assignment state, automatic mode and scope.
  • Test mixed scaling, remote desktop and unusual graphics drivers separately.
  • For damaged settings, exit SightAdapt and back up or remove %LOCALAPPDATA%\SightAdapt\settings.json.
  • Protected content may remain unavailable or unfilterable.

Developer documentation

Architecture and repository documentation · Contributing · Security policy · CI and test runs

\ No newline at end of file From 174b43890ce8aac0fa227b7606fef595f7d7ce4d Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:47:16 +0200 Subject: [PATCH 08/21] Add how-it-works website page Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/how-it-works/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/how-it-works/index.html diff --git a/site/how-it-works/index.html b/site/how-it-works/index.html new file mode 100644 index 00000000..abf12fd9 --- /dev/null +++ b/site/how-it-works/index.html @@ -0,0 +1 @@ +How SightAdapt™ works on Windows

SightAdapt™ architecture

A separate overlay, not a modification of the target application.

  1. SightAdapt observes the foreground window and resolves the corresponding application assignment.
  2. It creates or retargets an input-transparent overlay.
  3. The Windows Magnification API applies the selected color transform to the chosen source area.
  4. Filtering prevents the overlay from recursively capturing itself.
  5. Native popup menus may receive transient overlays when supported.
  6. Emergency shutdown removes active overlays.
Foreground application metadata flows into SightAdapt assignment and profile logic, which controls an input-transparent Windows Magnification API overlay.
Security boundary. SightAdapt does not inject DLLs, write target-process memory or modify target application files. It reads limited window and process metadata required to identify the selected application.

Read the full architecture documentation on GitHub.

\ No newline at end of file From 7867883775f0430b2fbb6152cc423d2b81aef519 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:47:37 +0200 Subject: [PATCH 09/21] Add FAQ website page Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/faq/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/faq/index.html diff --git a/site/faq/index.html b/site/faq/index.html new file mode 100644 index 00000000..83811c2b --- /dev/null +++ b/site/faq/index.html @@ -0,0 +1 @@ +SightAdapt™ FAQ

SightAdapt™ FAQ

Frequently asked questions.

Is SightAdapt free?

Yes. SightAdapt is free and open source under the MIT License.

Does SightAdapt change application files?

No. It uses a separate Windows overlay and does not modify the target application's installed files.

Does it inject code into other applications?

No. The current alpha does not use DLL injection or write another process's memory.

Does it record or upload my screen?

The current alpha does not save or transmit captured screen content. See privacy and security for the exact boundaries.

Why does it store executable paths?

Paths are used locally to identify saved application assignments. A path can contain a Windows account or organization name, so redact it from public bug reports when necessary.

Does it work with every application?

No guarantee is made. Framework, privilege level, digital rights management (DRM), remote sessions and graphics drivers can affect behavior.

Can it correct only menus?

For supported native Win32 popup menus, an application can use None while an explicit menu profile is assigned. Custom-rendered menus are not separately detected.

Is SightAdapt a medical device?

The project is a general-purpose visual-accessibility and display-personalization utility. It does not diagnose or treat medical conditions.

Why might Windows show a warning?

New or unsigned binaries may have limited reputation. Download only from official project-controlled sources and verify the published checksum.

How do I stop all overlays?

Use Emergency disable all overlays from the notification-area menu, or exit SightAdapt.

Can I build it myself?

Yes. The repository documents the .NET 8 build and publish process. Browse the source.

\ No newline at end of file From 8014d0c79d72aed1e0651423f4ff53b73d55239c Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:47:51 +0200 Subject: [PATCH 10/21] Add release history website page Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/releases/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/releases/index.html diff --git a/site/releases/index.html b/site/releases/index.html new file mode 100644 index 00000000..e333c5f8 --- /dev/null +++ b/site/releases/index.html @@ -0,0 +1 @@ +SightAdapt™ release history

SightAdapt™ releases

Public, dated SightAdapt releases.

GitHub Releases are authoritative. This website does not host a separate copy of the Windows binary.

{{VERSION}}

Published: {{RELEASE_DATE}} · Status: Alpha prerelease · Platform: Windows x64

The immutable release contains the official Windows binary, SHA-256 checksums, compliance report, SPDX software bill of materials (SBOM), dependency and license reports, privacy notice and third-party notices.

Open GitHub Release Source tag Checksums SBOM

If a release is withdrawn, its dated record remains visible rather than silently replacing its tag or assets.

\ No newline at end of file From 36eb79ab3fc7d66612bfb41bc57ddc49f5c4fff2 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:48:09 +0200 Subject: [PATCH 11/21] Add privacy website page Addresses #99 and prepares #103. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/privacy/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/privacy/index.html diff --git a/site/privacy/index.html b/site/privacy/index.html new file mode 100644 index 00000000..38e5b833 --- /dev/null +++ b/site/privacy/index.html @@ -0,0 +1 @@ +SightAdapt™ privacy

SightAdapt™ privacy

Local configuration and explicit support sharing.

The current SightAdapt alpha stores configuration locally and does not transmit captured screen content or behavioral telemetry.

What is processed locally

SightAdapt may read active-window handles, process identifiers, application display names, executable file names and full executable paths, window geometry, monitor state, saved assignments, overlay scopes and visual-profile settings. These values are used to identify the selected application and render the configured overlay.

Local storage

Settings are stored at %LOCALAPPDATA%\SightAdapt\settings.json. The file can contain application names, executable names and paths, enabled states, selected profile identifiers, overlay scopes and user-defined profile values.

Screen content and network behavior

The current release does not intentionally save screenshots, record the screen, build a screen-content history, perform content recognition or transmit captured screen content. It includes no telemetry, product analytics, advertising, remote crash reporting, automatic diagnostic upload, account, cloud synchronization or automatic update check.

Delete or reset

Exit SightAdapt and delete %LOCALAPPDATA%\SightAdapt\settings.json. Starting the application again recreates default settings.

Support data

Information reaches the project owner only when you voluntarily submit it through GitHub or another support route. Paths, screenshots, settings and logs can reveal private data. Redact usernames, organization names, private directories, unrelated windows, tokens and confidential content before sharing.

Publisher contact for submitted support data

KeyffMS / aiteracja.pl. Use the repository owner or issue tracker for public support; for non-public material, request a private communication channel before sending it.

Policy source

This page must remain synchronized with the repository privacy notice. Read the complete current PRIVACY.md. Repository notice last updated: 2026-07-29.

\ No newline at end of file From 9e249e65f5f2591af2f28214f8ee69a3e8c0ebf4 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:48:28 +0200 Subject: [PATCH 12/21] Add legal website page Addresses #99 and prepares #103. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/legal/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/legal/index.html diff --git a/site/legal/index.html b/site/legal/index.html new file mode 100644 index 00000000..148f8a2a --- /dev/null +++ b/site/legal/index.html @@ -0,0 +1 @@ +SightAdapt™ license and legal notices

SightAdapt™ legal

License and legal notices.

SightAdapt MIT License

SightAdapt source code is distributed under the MIT License. The license permits use, copying, modification, merging, publishing, distribution, sublicensing and sale subject to preservation of the copyright and permission notice, and it provides the software without warranty.

Read the complete MIT License.

Third-party components

Official releases include exact-version third-party notices and Microsoft/.NET redistribution material. Use the release-specific files as the authoritative binary-distribution record.

Open the current release legal bundle · SPDX SBOM · Compliance report

Trademark notice

SightAdapt™ is an unregistered product mark used by KeyffMS / aiteracja.pl. The ™ notation identifies product branding and does not represent a registered trademark.

Third-party product names and trademarks are the property of their respective owners and are used only to identify applications selected or configured by the user. SightAdapt is not affiliated with, sponsored by or endorsed by Microsoft or those owners unless an explicit written relationship is identified.

Protected content and DRM

SightAdapt does not circumvent digital rights management (DRM) or other access controls. Protected content may remain unavailable or unfilterable.

Warranty

The software is provided under the warranty limitation in the MIT License. Alpha status does not create a compatibility or availability guarantee.

\ No newline at end of file From 083e05f21c0aa2b4bfa0bc6a4f620a5dd03b5d3e Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:48:43 +0200 Subject: [PATCH 13/21] Add security website page Addresses #99 and prepares #103. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/security/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/security/index.html diff --git a/site/security/index.html b/site/security/index.html new file mode 100644 index 00000000..b3961918 --- /dev/null +++ b/site/security/index.html @@ -0,0 +1 @@ +SightAdapt™ security and reporting

SightAdapt™ security

Security boundaries and reporting.

Current application boundaries

  • no code injection into other processes;
  • no driver installation;
  • no saved or transmitted captured screen content;
  • runs with the current user's privileges;
  • provides an emergency tray command to remove active overlays.

Elevated applications

A target running at a higher integrity level may require a compatible integrity level before SightAdapt can interact with the relevant windows as expected.

Alpha review status

The current alpha has not completed a formal security review and must not be treated as production-ready assistive software.

Report a vulnerability privately

Do not disclose security-sensitive issues in a public GitHub issue. Until a dedicated private reporting channel is configured, contact the repository owner through GitHub and request a private communication channel.

Do not publish credentials, private screenshots, unredacted paths, confidential settings or exploit details that would increase risk.

Read the repository SECURITY.md · Review current limitations

\ No newline at end of file From 9365fa7a9c1aa57c1bb7f5ca6dbe21dd4ae99112 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:48:58 +0200 Subject: [PATCH 14/21] Add support website page Addresses #99 and prepares #103. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/support/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 site/support/index.html diff --git a/site/support/index.html b/site/support/index.html new file mode 100644 index 00000000..c5b7da86 --- /dev/null +++ b/site/support/index.html @@ -0,0 +1 @@ +SightAdapt™ support and contact

SightAdapt™ support

Support and contact.

Defects and feature requests

Use the GitHub issue tracker for reproducible non-sensitive reports and feature requests.

Bug-report checklist

  • SightAdapt version;
  • Windows version;
  • monitor arrangement and scaling;
  • target application and framework when known;
  • target privilege level;
  • exact reproduction steps;
  • whether emergency disable remained available;
  • sanitized logs or paths.
Privacy warning. Do not attach screenshots containing private information or publish unredacted paths, usernames, organization names or confidential application content.
\ No newline at end of file From abe22c4eb5eadbe4de5e5fb5b526ee30e291b18b Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:49:29 +0200 Subject: [PATCH 15/21] Add immutable website release metadata Addresses #99 and prepares #104. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/release.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 site/release.json diff --git a/site/release.json b/site/release.json new file mode 100644 index 00000000..27197ba2 --- /dev/null +++ b/site/release.json @@ -0,0 +1,15 @@ +{ + "version": "0.5.0.50-alpha", + "releaseDate": "2026-09-24", + "status": "Alpha prerelease", + "architecture": "Windows x64", + "archiveName": "SightAdapt-0.5.0.50-alpha-win-x64.zip", + "archiveSizeBytes": 74486106, + "sha256": "c6dc5ba5c0356c84b32a74d298015d63158c57886b835e411da0b60f306fd711", + "releaseUrl": "https://github.com/KeyffMS/SightAdapt/releases/tag/v0.5.0.50-alpha", + "tagUrl": "https://github.com/KeyffMS/SightAdapt/tree/v0.5.0.50-alpha", + "downloadUrl": "https://github.com/KeyffMS/SightAdapt/releases/download/v0.5.0.50-alpha/SightAdapt-0.5.0.50-alpha-win-x64.zip", + "checksumUrl": "https://github.com/KeyffMS/SightAdapt/releases/download/v0.5.0.50-alpha/SHA256SUMS.txt", + "sbomUrl": "https://github.com/KeyffMS/SightAdapt/releases/download/v0.5.0.50-alpha/SBOM.spdx.json", + "complianceUrl": "https://github.com/KeyffMS/SightAdapt/releases/download/v0.5.0.50-alpha/SightAdapt-0.5.0.50-alpha-win-x64-compliance.json" +} From b7a31ea6992b621feeb7de95a9903c9bd41ef894 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:49:33 +0200 Subject: [PATCH 16/21] Document static website build and preview Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 site/README.md diff --git a/site/README.md b/site/README.md new file mode 100644 index 00000000..3c9637ff --- /dev/null +++ b/site/README.md @@ -0,0 +1,35 @@ +# SightAdapt website source + +The public product site is a dependency-free static site whose content follows issue #124. + +- Canonical production URL: `https://aiteracja.pl/sightadapt/` +- GitHub Pages fallback: `https://keyffms.github.io/SightAdapt/` +- GitHub Releases remain the authoritative binary source. + +## Build for GitHub Pages + +```powershell +python .\tools\build-site.py --base-path /SightAdapt/ --output .\artifacts\site +``` + +## Build for the canonical Aiteracja path + +```powershell +python .\tools\build-site.py --base-path /sightadapt/ --output .\artifacts\site +``` + +## Validate + +```powershell +python .\tools\verify-site.py .\artifacts\site --base-path /SightAdapt/ +``` + +## Preview + +```powershell +python -m http.server 8000 --directory .\artifacts\site +``` + +The build copies the canonical SVG brand assets from `assets/brand/` into the generated site, so the deployed site does not depend on a third-party CDN or raw GitHub asset request. + +The initial site intentionally contains no analytics, cookies, remote fonts, advertising, session replay or third-party embeds. From 4ed2230878023e516369b14609c18305d1969f2b Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:49:46 +0200 Subject: [PATCH 17/21] Add dependency-free SightAdapt site builder Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- tools/build-site.py | 78 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tools/build-site.py diff --git a/tools/build-site.py b/tools/build-site.py new file mode 100644 index 00000000..a6574102 --- /dev/null +++ b/tools/build-site.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +import argparse +import json +import shutil +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +SITE = ROOT / "site" +BRAND = ROOT / "assets" / "brand" + +def normalize_base(value: str) -> str: + value = value.strip() + if not value.startswith("/"): + value = "/" + value + if not value.endswith("/"): + value += "/" + return value + +def main() -> int: + parser = argparse.ArgumentParser(description="Build the SightAdapt static product site.") + parser.add_argument("--base-path", default="/SightAdapt/", help="Deployment path, e.g. /SightAdapt/ or /sightadapt/.") + parser.add_argument("--canonical-root", default="https://aiteracja.pl/sightadapt/") + parser.add_argument("--output", default=str(ROOT / "artifacts" / "site")) + args = parser.parse_args() + + base = normalize_base(args.base_path) + canonical = args.canonical_root.rstrip("/") + "/" + output = Path(args.output).resolve() + + if output.exists(): + shutil.rmtree(output) + output.mkdir(parents=True) + + release = json.loads((SITE / "release.json").read_text(encoding="utf-8")) + size_mib = release["archiveSizeBytes"] / (1024 * 1024) + + replacements = { + "{{BASE}}": base, + "{{CANONICAL}}": canonical, + "{{VERSION}}": release["version"], + "{{RELEASE_DATE}}": release["releaseDate"], + "{{ARCHIVE_SIZE}}": f'{release["archiveSizeBytes"]:,} bytes ({size_mib:.1f} MiB)', + "{{SHA256}}": release["sha256"], + "{{RELEASE_URL}}": release["releaseUrl"], + "{{TAG_URL}}": release["tagUrl"], + "{{DOWNLOAD_URL}}": release["downloadUrl"], + "{{CHECKSUM_URL}}": release["checksumUrl"], + "{{SBOM_URL}}": release["sbomUrl"], + "{{LEGAL_BUNDLE_URL}}": release["complianceUrl"], + } + + for source in SITE.rglob("*"): + if source.is_dir() or source.name in {"README.md", "release.json"}: + continue + relative = source.relative_to(SITE) + target = output / relative + target.parent.mkdir(parents=True, exist_ok=True) + if source.suffix.lower() in {".html", ".css", ".js", ".svg", ".txt"}: + text = source.read_text(encoding="utf-8") + for key, value in replacements.items(): + text = text.replace(key, value) + target.write_text(text, encoding="utf-8", newline="\n") + else: + shutil.copy2(source, target) + + brand_target = output / "assets" / "brand" + brand_target.mkdir(parents=True, exist_ok=True) + for name in ("sightadapt-mark.svg", "sightadapt-lockup-dark.svg", "sightadapt-lockup-light.svg"): + shutil.copy2(BRAND / name, brand_target / name) + + (output / ".nojekyll").write_text("", encoding="utf-8") + print(f"Built SightAdapt site at {output}") + print(f"Base path: {base}") + print(f"Canonical root: {canonical}") + return 0 + +if __name__ == "__main__": + raise SystemExit(main()) From d207e5797e8607baca03d5da1942cdf9bffd6e3e Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:50:07 +0200 Subject: [PATCH 18/21] Add static site validation checks Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- tools/verify-site.py | 160 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 tools/verify-site.py diff --git a/tools/verify-site.py b/tools/verify-site.py new file mode 100644 index 00000000..ef624010 --- /dev/null +++ b/tools/verify-site.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 +import argparse +import re +from html.parser import HTMLParser +from pathlib import Path +from urllib.parse import urlparse + +REQUIRED = [ + "", "features", "download", "docs", "how-it-works", "faq", + "releases", "privacy", "legal", "security", "support" +] +FORBIDDEN = [ + "google-analytics", "googletagmanager", "gtag(", "plausible.io", + "matomo", "hotjar", "clarity.ms", "segment.com", "facebook.com/tr", + "")) + elif tag == "a": + href = attrs.get("href") + if href: + self.links.append(href) + if attrs.get("class") == "skip" and href == "#main": + self.has_skip = True + elif tag == "main" and attrs.get("id") == "main": + self.has_main = True + +def expected_file(root: Path, base: str, href: str): + clean = href.split("#", 1)[0].split("?", 1)[0] + if not clean.startswith(base): + return None + rel = clean[len(base):] + if not rel: + return root / "index.html" + p = root / rel + if rel.endswith("/"): + return p / "index.html" + return p + +def main() -> int: + parser = argparse.ArgumentParser(description="Validate generated SightAdapt static site.") + parser.add_argument("site") + parser.add_argument("--base-path", default="/SightAdapt/") + parser.add_argument("--canonical-root", default="https://aiteracja.pl/sightadapt/") + args = parser.parse_args() + + root = Path(args.site).resolve() + base = args.base_path + if not base.startswith("/"): + base = "/" + base + if not base.endswith("/"): + base += "/" + canonical = args.canonical_root.rstrip("/") + "/" + + failures = [] + + for name in REQUIRED: + path = root / name / "index.html" if name else root / "index.html" + if not path.is_file(): + failures.append(f"Missing required page: {path}") + + for html_file in root.rglob("*.html"): + text = html_file.read_text(encoding="utf-8") + lower = text.lower() + if "{{" in text or "}}" in text: + failures.append(f"Unresolved template token in {html_file}") + for marker in FORBIDDEN: + if marker in lower: + failures.append(f"Forbidden tracking/embed marker '{marker}' in {html_file}") + + inspector = Inspector() + inspector.feed(text) + + if inspector.lang != "en": + failures.append(f"{html_file}: html lang must be 'en'") + if inspector.titles != 1: + failures.append(f"{html_file}: expected one title, found {inspector.titles}") + if inspector.h1 != 1: + failures.append(f"{html_file}: expected one h1, found {inspector.h1}") + if inspector.meta_description != 1: + failures.append(f"{html_file}: expected one meta description") + if len(inspector.canonical) != 1 or not inspector.canonical[0].startswith(canonical): + failures.append(f"{html_file}: invalid canonical URL {inspector.canonical}") + if inspector.images_without_alt: + failures.append(f"{html_file}: images missing alt: {inspector.images_without_alt}") + if not inspector.has_skip or not inspector.has_main: + failures.append(f"{html_file}: missing skip link or main landmark") + + previous = 0 + for level in inspector.heading_levels: + if previous and level > previous + 1: + failures.append(f"{html_file}: heading level skips from h{previous} to h{level}") + previous = level + + for href in inspector.links: + parsed = urlparse(href) + if parsed.scheme in {"http", "https", "mailto"}: + continue + if href.startswith("#"): + continue + target = expected_file(root, base, href) + if target is not None and not target.exists(): + failures.append(f"{html_file}: broken internal link {href} -> {target}") + + required_assets = [ + root / "assets" / "styles.css", + root / "assets" / "site.js", + root / "assets" / "architecture.svg", + root / "assets" / "brand" / "sightadapt-mark.svg", + root / "assets" / "brand" / "sightadapt-lockup-dark.svg", + root / "assets" / "brand" / "sightadapt-lockup-light.svg", + ] + for asset in required_assets: + if not asset.is_file(): + failures.append(f"Missing required asset: {asset}") + + if failures: + print("SightAdapt site validation failed:") + for failure in failures: + print(f"- {failure}") + return 1 + + pages = len(list(root.rglob("*.html"))) + print(f"SightAdapt site validation passed: {pages} HTML pages.") + print("No analytics, remote fonts or third-party embeds detected.") + return 0 + +if __name__ == "__main__": + raise SystemExit(main()) From 6ffcff201fcd9f1466e5855a9e78d7fa13716bac Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:50:20 +0200 Subject: [PATCH 19/21] Add validated GitHub Pages deployment workflow Addresses #99. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- .github/workflows/pages.yml | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 00000000..ac1e0aff --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,72 @@ +name: Validate and deploy SightAdapt website + +on: + workflow_dispatch: + pull_request: + branches: [main] + paths: + - "site/**" + - "tools/build-site.py" + - "tools/verify-site.py" + - "assets/brand/**" + - ".github/workflows/pages.yml" + push: + branches: [main] + paths: + - "site/**" + - "tools/build-site.py" + - "tools/verify-site.py" + - "assets/brand/**" + - ".github/workflows/pages.yml" + +concurrency: + group: sightadapt-pages-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Build GitHub Pages fallback + run: python tools/build-site.py --base-path /SightAdapt/ --output artifacts/site + + - name: Validate GitHub Pages fallback + run: python tools/verify-site.py artifacts/site --base-path /SightAdapt/ + + - name: Build canonical Aiteracja path + run: python tools/build-site.py --base-path /sightadapt/ --output artifacts/site-canonical + + - name: Validate canonical Aiteracja path + run: python tools/verify-site.py artifacts/site-canonical --base-path /sightadapt/ + + - name: Upload validated GitHub Pages artifact + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v3 + with: + path: artifacts/site + + deploy: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: validate + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy GitHub Pages fallback + id: deployment + uses: actions/deploy-pages@v4 From 137e0cf083b70365ae803c215291fe3bde65cf4b Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:50:50 +0200 Subject: [PATCH 20/21] Add accessible mobile navigation disclosure Addresses #99 and follows #124. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/assets/site.js | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/site/assets/site.js b/site/assets/site.js index 3c8d9f80..076f9396 100644 --- a/site/assets/site.js +++ b/site/assets/site.js @@ -1 +1,33 @@ -document.documentElement.classList.add('js'); +document.documentElement.classList.add("js"); +(() => { + const nav = document.querySelector(".nav-links"); + const host = document.querySelector(".nav"); + if (!nav || !host) return; + + nav.id = "site-navigation"; + const button = document.createElement("button"); + button.type = "button"; + button.className = "menu-toggle"; + button.textContent = "Menu"; + button.setAttribute("aria-controls", nav.id); + button.setAttribute("aria-expanded", "false"); + host.insertBefore(button, nav); + + const mobile = window.matchMedia("(max-width: 800px)"); + const sync = () => { + if (!mobile.matches) { + nav.hidden = false; + button.setAttribute("aria-expanded", "false"); + return; + } + nav.hidden = button.getAttribute("aria-expanded") !== "true"; + }; + + button.addEventListener("click", () => { + const open = button.getAttribute("aria-expanded") === "true"; + button.setAttribute("aria-expanded", String(!open)); + sync(); + }); + mobile.addEventListener?.("change", sync); + sync(); +})(); From 708d9ae6e58ba224db3fb804cfc87d9d72fd2f23 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Thu, 24 Sep 2026 12:50:53 +0200 Subject: [PATCH 21/21] Style accessible mobile navigation disclosure Addresses #99 and follows #124. Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- site/assets/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/assets/styles.css b/site/assets/styles.css index 080a4f4a..5261f42d 100644 --- a/site/assets/styles.css +++ b/site/assets/styles.css @@ -1 +1 @@ -:root{--bg:#f7f8fb;--ink:#121826;--muted:#5d667a;--panel:#fff;--line:#dce1ea;--accent:#1c5cff;--dark:#10182f;--focus:#ffbf47;--max:1120px}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;background:var(--bg);color:var(--ink)}a{color:#164fc9}a:focus-visible,button:focus-visible,summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px}.skip{position:absolute;left:-9999px}.skip:focus{left:1rem;top:1rem;background:#fff;padding:.7rem 1rem;z-index:1000}.wrap{width:min(var(--max),calc(100% - 2rem));margin:auto}.site-header{background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50}.nav{display:flex;align-items:center;gap:1rem;min-height:72px}.brand img{width:205px;height:auto;display:block}.nav-links{display:flex;flex-wrap:wrap;gap:.8rem;margin-left:auto;align-items:center}.nav-links a{color:var(--ink);text-decoration:none;padding:.45rem .55rem;border-radius:.4rem}.nav-links a[aria-current=page]{background:#eef3ff;color:#123a91;font-weight:700}.button{display:inline-block;background:var(--accent);color:#fff!important;text-decoration:none!important;padding:.75rem 1rem;border-radius:.55rem;font-weight:700}.button.secondary{background:#fff;color:#163b85!important;border:1px solid #8aa5e8}.hero{background:var(--dark);color:#fff;padding:4rem 0}.hero a{color:#d9e7ff}.hero-grid{display:grid;grid-template-columns:1.4fr .9fr;gap:2rem;align-items:center}.eyebrow{font-weight:700;color:#b8c8ee}.hero h1{font-size:clamp(2.5rem,6vw,4.8rem);line-height:1.02;margin:.35rem 0 1rem}.lead{font-size:1.22rem;max-width:48rem}.actions{display:flex;gap:.75rem;flex-wrap:wrap;margin:1.5rem 0}.release-card,.card,.notice{background:var(--panel);border:1px solid var(--line);border-radius:.8rem;padding:1.2rem}.hero .release-card{background:#172341;border-color:#34456e;color:#fff}.alpha{background:#fff4d6;border-bottom:1px solid #e6c76c;padding:.7rem 0}.trust{display:grid;grid-template-columns:repeat(4,1fr);gap:.75rem;margin:1.5rem 0}.trust a{display:block;background:#fff;border:1px solid var(--line);padding:1rem;border-radius:.7rem;text-decoration:none;font-weight:700}.section{padding:3rem 0}.section h1,.section h2{line-height:1.2}.section h1{font-size:clamp(2rem,4vw,3rem)}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}.two{grid-template-columns:repeat(2,1fr)}.kicker{color:var(--muted);font-weight:700}.muted{color:var(--muted)}code,pre{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}pre{background:#111827;color:#f9fafb;padding:1rem;overflow:auto;border-radius:.6rem}.architecture{width:100%;height:auto;border:1px solid var(--line);border-radius:.8rem;background:#fff}.site-footer{background:#0f172a;color:#dbe4f3;padding:2.5rem 0}.site-footer a{color:#dbeafe}.footer-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}.footer-grid h2{font-size:1rem;color:#fff}.footer-grid ul{list-style:none;padding:0;margin:0}.small{font-size:.92rem}table{width:100%;border-collapse:collapse;background:#fff}th,td{border:1px solid var(--line);padding:.7rem;text-align:left;vertical-align:top}th{background:#eef1f6}@media(max-width:800px){.hero-grid,.grid,.two,.trust,.footer-grid{grid-template-columns:1fr}.nav{align-items:flex-start;padding:.7rem 0;flex-wrap:wrap}.brand img{width:180px}.nav-links{width:100%;margin-left:0}.hero{padding:2.5rem 0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}} +:root{--bg:#f7f8fb;--ink:#121826;--muted:#5d667a;--panel:#fff;--line:#dce1ea;--accent:#1c5cff;--dark:#10182f;--focus:#ffbf47;--max:1120px}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;background:var(--bg);color:var(--ink)}a{color:#164fc9}a:focus-visible,button:focus-visible,summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px}.skip{position:absolute;left:-9999px}.skip:focus{left:1rem;top:1rem;background:#fff;padding:.7rem 1rem;z-index:1000}.wrap{width:min(var(--max),calc(100% - 2rem));margin:auto}.site-header{background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50}.nav{display:flex;align-items:center;gap:1rem;min-height:72px}.brand img{width:205px;height:auto;display:block}.nav-links{display:flex;flex-wrap:wrap;gap:.8rem;margin-left:auto;align-items:center}.nav-links a{color:var(--ink);text-decoration:none;padding:.45rem .55rem;border-radius:.4rem}.nav-links a[aria-current=page]{background:#eef3ff;color:#123a91;font-weight:700}.button{display:inline-block;background:var(--accent);color:#fff!important;text-decoration:none!important;padding:.75rem 1rem;border-radius:.55rem;font-weight:700}.button.secondary{background:#fff;color:#163b85!important;border:1px solid #8aa5e8}.hero{background:var(--dark);color:#fff;padding:4rem 0}.hero a{color:#d9e7ff}.hero-grid{display:grid;grid-template-columns:1.4fr .9fr;gap:2rem;align-items:center}.eyebrow{font-weight:700;color:#b8c8ee}.hero h1{font-size:clamp(2.5rem,6vw,4.8rem);line-height:1.02;margin:.35rem 0 1rem}.lead{font-size:1.22rem;max-width:48rem}.actions{display:flex;gap:.75rem;flex-wrap:wrap;margin:1.5rem 0}.release-card,.card,.notice{background:var(--panel);border:1px solid var(--line);border-radius:.8rem;padding:1.2rem}.hero .release-card{background:#172341;border-color:#34456e;color:#fff}.alpha{background:#fff4d6;border-bottom:1px solid #e6c76c;padding:.7rem 0}.trust{display:grid;grid-template-columns:repeat(4,1fr);gap:.75rem;margin:1.5rem 0}.trust a{display:block;background:#fff;border:1px solid var(--line);padding:1rem;border-radius:.7rem;text-decoration:none;font-weight:700}.section{padding:3rem 0}.section h1,.section h2{line-height:1.2}.section h1{font-size:clamp(2rem,4vw,3rem)}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}.two{grid-template-columns:repeat(2,1fr)}.kicker{color:var(--muted);font-weight:700}.muted{color:var(--muted)}code,pre{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}pre{background:#111827;color:#f9fafb;padding:1rem;overflow:auto;border-radius:.6rem}.architecture{width:100%;height:auto;border:1px solid var(--line);border-radius:.8rem;background:#fff}.site-footer{background:#0f172a;color:#dbe4f3;padding:2.5rem 0}.site-footer a{color:#dbeafe}.footer-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}.footer-grid h2{font-size:1rem;color:#fff}.footer-grid ul{list-style:none;padding:0;margin:0}.small{font-size:.92rem}.menu-toggle{display:none;background:#fff;border:1px solid var(--line);border-radius:.45rem;padding:.55rem .8rem;font:inherit;font-weight:700}table{width:100%;border-collapse:collapse;background:#fff}th,td{border:1px solid var(--line);padding:.7rem;text-align:left;vertical-align:top}th{background:#eef1f6}@media(max-width:800px){.js .menu-toggle{display:block;margin-left:auto}.js .nav-links[hidden]{display:none}.hero-grid,.grid,.two,.trust,.footer-grid{grid-template-columns:1fr}.nav{align-items:flex-start;padding:.7rem 0;flex-wrap:wrap}.brand img{width:180px}.nav-links{width:100%;margin-left:0}.hero{padding:2.5rem 0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}