{item.name}
{item.text}
-From 27c1ec3836b481f3eadd515be9ec042d60797306 Mon Sep 17 00:00:00 2001
From: "https://www.ayushdoesdev.in/"
<66489925+ayushdoesdev@users.noreply.github.com>
Date: Sat, 31 Oct 2026 13:30:31 +0530
Subject: [PATCH 1/4] feat(landing): port original interactive marketing page
---
landing/package-lock.json | 55 ++-
landing/package.json | 4 +-
landing/src/app/globals.css | 320 +++++++++++-------
landing/src/app/page.tsx | 214 ++----------
.../marketing/landing/dependency-graph.tsx | 180 ++++++++++
.../src/components/marketing/landing/hero.tsx | 283 ++++++++++++++++
.../marketing/landing/migration-demo.tsx | 199 +++++++++++
.../marketing/landing/primitives.tsx | 254 ++++++++++++++
.../marketing/landing/scan-demo.tsx | 233 +++++++++++++
.../marketing/landing/security-dashboard.tsx | 113 +++++++
.../marketing/landing/simulator-demo.tsx | 211 ++++++++++++
.../marketing/landing/social-sections.tsx | 89 +++++
landing/src/components/marketing/nav.tsx | 142 ++++++++
landing/src/lib/utils.ts | 3 +
14 files changed, 1992 insertions(+), 308 deletions(-)
create mode 100644 landing/src/components/marketing/landing/dependency-graph.tsx
create mode 100644 landing/src/components/marketing/landing/hero.tsx
create mode 100644 landing/src/components/marketing/landing/migration-demo.tsx
create mode 100644 landing/src/components/marketing/landing/primitives.tsx
create mode 100644 landing/src/components/marketing/landing/scan-demo.tsx
create mode 100644 landing/src/components/marketing/landing/security-dashboard.tsx
create mode 100644 landing/src/components/marketing/landing/simulator-demo.tsx
create mode 100644 landing/src/components/marketing/landing/social-sections.tsx
create mode 100644 landing/src/components/marketing/nav.tsx
create mode 100644 landing/src/lib/utils.ts
diff --git a/landing/package-lock.json b/landing/package-lock.json
index 0477d1d..d1b39fe 100644
--- a/landing/package-lock.json
+++ b/landing/package-lock.json
@@ -10,7 +10,9 @@
"dependencies": {
"next": "16.4.3",
"react": "19.2.8",
- "react-dom": "19.2.8"
+ "react-dom": "19.2.8",
+ "framer-motion": "^12.43.0",
+ "lucide-react": "^0.488.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.4",
@@ -6858,6 +6860,57 @@
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
+ },
+ "node_modules/framer-motion": {
+ "version": "12.43.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.43.0.tgz",
+ "integrity": "sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.43.0",
+ "motion-utils": "^12.39.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.43.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.43.0.tgz",
+ "integrity": "sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.39.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.39.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz",
+ "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==",
+ "license": "MIT"
+ },
+ "node_modules/lucide-react": {
+ "version": "0.488.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.488.0.tgz",
+ "integrity": "sha512-ronlL0MyKut4CEzBY/ai2ZpKPxyWO4jUqdAkm2GNK5Zn3Rj+swDz+3lvyAUXN0PNqPKIX6XM9Xadwz/skLs/pQ==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
}
}
}
diff --git a/landing/package.json b/landing/package.json
index 94f96ee..39daaef 100644
--- a/landing/package.json
+++ b/landing/package.json
@@ -12,7 +12,9 @@
"dependencies": {
"next": "16.4.3",
"react": "19.2.8",
- "react-dom": "19.2.8"
+ "react-dom": "19.2.8",
+ "framer-motion": "^12.43.0",
+ "lucide-react": "^0.488.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.4",
diff --git a/landing/src/app/globals.css b/landing/src/app/globals.css
index 3e445eb..4cf12a3 100644
--- a/landing/src/app/globals.css
+++ b/landing/src/app/globals.css
@@ -1,120 +1,208 @@
@import "tailwindcss";
+@custom-variant dark (&:is(.dark *));
+
:root {
- --ink: #070b12;
- --panel: #0a1018;
- --panel-raised: #0d151f;
- --line: rgba(220, 234, 245, .095);
- --text: #e8eef6;
- --muted: #91a0b2;
- --quiet: #657488;
- --teal: #3dd6c6;
- --teal-dim: #163b39;
- --mono: "IBM Plex Mono", ui-monospace, monospace;
- --sans: "DM Sans", ui-sans-serif, system-ui, sans-serif;
- --display: "Syne", "DM Sans", ui-sans-serif, sans-serif;
-}
-
-* { box-sizing: border-box; }
-html { scroll-behavior: smooth; scroll-padding-top: 88px; color-scheme: dark; }
-body { margin: 0; min-width: 320px; background: var(--ink); color: var(--text); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
-body::before { position: fixed; z-index: -1; inset: 0; content: ""; pointer-events: none; background: radial-gradient(ellipse at 12% -10%, rgba(61,214,198,.09), transparent 36%), radial-gradient(ellipse at 88% 5%, rgba(48,111,122,.08), transparent 31%); }
-a { color: inherit; text-decoration: none; }
-button { font: inherit; }
-::selection { background: rgba(61,214,198,.28); color: white; }
-.container { width: min(1160px, calc(100% - 64px)); margin-inline: auto; }
-.skip-link { position: fixed; z-index: 100; top: 8px; left: 8px; transform: translateY(-150%); border-radius: 8px; background: var(--teal); padding: 12px 16px; color: #04201c; font-weight: 700; }
-.skip-link:focus { transform: translateY(0); }
-.site-header { position: sticky; z-index: 50; top: 0; border-bottom: 1px solid rgba(255,255,255,.08); background: rgba(7,11,18,.86); backdrop-filter: blur(16px); }
-.nav-inner { width: min(1320px, calc(100% - 64px)); height: 76px; margin: auto; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 28px; }
-.brand { display: inline-flex; width: fit-content; align-items: center; gap: 10px; color: #fff; font-family: var(--display); font-size: 17px; font-weight: 650; letter-spacing: -.04em; }
-.brand-mark { display: grid; width: 34px; height: 34px; place-items: center; border: 1px solid rgba(61,214,198,.3); border-radius: 10px; background: rgba(61,214,198,.11); color: var(--teal); }
-.brand-mark svg { width: 21px; height: 21px; }
-.desktop-nav { display: flex; align-items: center; gap: clamp(14px, 2vw, 29px); }
-.desktop-nav a, .nav-github { color: #aeb9c7; font-size: 13px; font-weight: 550; white-space: nowrap; transition: color .18s ease; }
-.desktop-nav a:hover, .nav-github:hover { color: #fff; }
-.nav-github { justify-self: end; display: inline-flex; align-items: center; gap: 9px; border: 1px solid rgba(61,214,198,.28); border-radius: 999px; background: rgba(61,214,198,.08); padding: 10px 16px; color: #c6f8f1; }
-.nav-github span { color: var(--teal); }
-.menu-toggle, .mobile-nav { display: none; }
-.menu-toggle:focus-visible, a:focus-visible, button:focus-visible { outline: 2px solid #7af2e4; outline-offset: 4px; }
-
-.hero { position: relative; overflow: hidden; padding: 94px 0 76px; }
-.section-grid { background-image: linear-gradient(rgba(255,255,255,.022) 1px, transparent 1px), linear-gradient(90deg,rgba(255,255,255,.022) 1px,transparent 1px); background-size: 68px 68px; background-position: center -1px; }
-.hero::after { position: absolute; inset: 0; content: ""; pointer-events: none; background: radial-gradient(ellipse at center 18%, transparent 4%, rgba(7,11,18,.28) 69%, var(--ink) 100%); }
-.hero-glow { position: absolute; top: 60px; left: 50%; width: 780px; height: 520px; transform: translateX(-50%); border-radius: 50%; background: rgba(27,159,148,.09); filter: blur(100px); }
-.hero-content { position: relative; z-index: 1; }
-.hero-copy { max-width: 910px; margin: auto; text-align: center; }
-.eyebrow { display: inline-flex; align-items: center; gap: 9px; color: #85d8d0; font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: .14em; line-height: 1.5; text-transform: uppercase; }
-.status-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 12px rgba(61,214,198,.65); }
-h1, h2, h3, p { margin-top: 0; }
-.hero h1 { margin: 24px 0 20px; font-family: var(--display); font-size: clamp(38px, 5.3vw, 67px); font-weight: 600; letter-spacing: -.065em; line-height: 1.1; }
-.hero h1 span, .hosting-copy h2 span, .final-cta h2 span { color: var(--teal); }
-.hero-lede { max-width: 740px; margin: 0 auto; color: #9eacbc; font-size: 16px; line-height: 1.78; }
-.hero-actions, .hosting-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
-.button { min-height: 47px; display: inline-flex; justify-content: center; align-items: center; gap: 11px; border: 1px solid transparent; border-radius: 999px; padding: 0 20px; font-size: 13px; font-weight: 700; transition: background .18s, border-color .18s, transform .18s; }
-.button:hover { transform: translateY(-1px); }
-.button-primary { background: var(--teal); color: #04201c; box-shadow: 0 7px 28px rgba(61,214,198,.14); }
-.button-primary:hover { background: #6de5d9; }
-.button-secondary { border-color: rgba(255,255,255,.14); background: rgba(255,255,255,.025); color: #e4eaf0; }
-.button-secondary:hover { border-color: rgba(61,214,198,.38); background: rgba(61,214,198,.06); }
-.product-attributes { display: flex; justify-content: center; flex-wrap: wrap; gap: 19px; margin: 25px 0 0; padding: 0; list-style: none; color: #8a98a9; font-family: var(--mono); font-size: 10px; }
-.product-attributes li { display: flex; align-items: center; gap: 6px; }
-.product-attributes li span { color: #4da99f; font-size: 9px; }
-.hero-preview { position: relative; min-height: 380px; margin: 61px auto 0; display: grid; grid-template-columns: 1.3fr .77fr; align-items: center; gap: 16px; }
-.preview-shadow { position: absolute; top: 15%; left: 14%; width: 72%; height: 70%; border-radius: 50%; background: rgba(25,117,111,.16); filter: blur(68px); }
-.window { position: relative; overflow: hidden; border: 1px solid rgba(214,230,241,.13); border-radius: 15px; background: rgba(10,16,24,.96); box-shadow: 0 24px 75px -42px rgba(0,0,0,.95), 0 4px 12px rgba(0,0,0,.18); }
-.window-title { min-height: 42px; display: flex; align-items: center; gap: 11px; border-bottom: 1px solid rgba(255,255,255,.07); background: rgba(255,255,255,.018); padding: 0 14px; color: #8190a1; font-family: var(--mono); font-size: 9px; }
-.window-title > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.window-title > b { margin-left: auto; flex-shrink: 0; border: 1px solid rgba(61,214,198,.2); border-radius: 4px; padding: 3px 6px; color: #79c9c0; font-size: 8px; font-weight: 500; letter-spacing: .05em; }
-.window-dots { display: flex; gap: 5px; flex-shrink: 0; }
-.window-dots i { width: 7px; height: 7px; border-radius: 50%; background: #f07178a6; }
-.window-dots i:nth-child(2) { background: #e6b450a6; }.window-dots i:nth-child(3) { background: #7fd962a6; }
-.terminal-window { z-index: 1; transform: perspective(1400px) rotateY(3deg) rotateX(1deg); }
-.terminal-body { min-height: 300px; display: grid; grid-template-columns: 168px 1fr; }
-.terminal-sidebar { position: relative; display: flex; flex-direction: column; gap: 12px; border-right: 1px solid rgba(255,255,255,.06); padding: 17px 12px; color: #768598; font-size: 9px; }
-.side-label { margin: 0 0 2px 5px; color: #586779; font-family: var(--mono); font-size: 8px; letter-spacing: .11em; }
-.side-active { border-radius: 5px; background: rgba(61,214,198,.1); padding: 7px 5px; color: #a6e8e1; }
-.side-user { position: absolute; right: 12px; bottom: 13px; left: 12px; display: flex; align-items: center; gap: 7px; border-top: 1px solid rgba(255,255,255,.06); padding-top: 11px; color: #647286; font-size: 8px; }
-.user-dot { display: grid; width: 19px; height: 19px; place-items: center; border-radius: 50%; background: #213b3b; color: #8edbd2; font-family: var(--mono); }
-.terminal-main { min-width: 0; padding: 17px 16px; font-family: var(--mono); }
-.terminal-command { overflow: hidden; color: #cbd5df; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }.terminal-prompt { margin-right: 7px; color: var(--teal); }
-.terminal-divider { height: 1px; margin: 14px 0 11px; background: rgba(255,255,255,.07); }
-.terminal-step { display: grid; grid-template-columns: 15px minmax(0,1fr) auto; align-items: center; gap: 6px; min-height: 35px; border-bottom: 1px solid rgba(255,255,255,.035); color: #91a0af; font-size: 9px; }
-.step-check { color: #54d4c3; }.step-state { color: #5c6c7d; font-size: 8px; white-space: nowrap; }
-.scan-progress { position: relative; display: flex; justify-content: space-between; margin-top: 16px; color: #667587; font-size: 8px; letter-spacing: .06em; }.scan-progress i { position: absolute; top: 17px; left: 0; width: 100%; height: 3px; border-radius: 4px; background: linear-gradient(90deg,var(--teal) 0 100%,#17202b 100%); box-shadow: 0 0 8px rgba(61,214,198,.25); }
-.metrics-window { z-index: 2; margin-left: -47px; transform: translateY(27px); }
-.metrics-content { padding: 17px 16px 19px; }.metric-top { display: flex; align-items: center; justify-content: space-between; }.metric-top > div { display: grid; gap: 5px; }.metric-label, .metric-card span, .bar-row span { color: #6d7a8b; font-family: var(--mono); font-size: 8px; letter-spacing: .07em; }.metric-top strong { color: white; font-family: var(--display); font-size: 36px; letter-spacing: -.06em; }.metric-pill { border: 1px solid rgba(61,214,198,.16); border-radius: 999px; padding: 4px 7px; color: #73bdb5; font-family: var(--mono); font-size: 8px; }
-.metric-cards { display: grid; grid-template-columns: repeat(3,1fr); gap: 6px; margin: 14px 0 18px; }.metric-card { display: grid; gap: 6px; border: 1px solid rgba(255,255,255,.06); border-radius: 7px; background: rgba(255,255,255,.02); padding: 8px 7px; }.metric-card span { font-size: 7px; letter-spacing: 0; }.metric-card b { color: #dce7ee; font-family: var(--mono); font-size: 14px; font-weight: 500; }
-.metric-bars { display: grid; gap: 10px; }.bar-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center; }.bar-row b { color: #a2afbd; font-family: var(--mono); font-size: 8px; font-weight: 400; }.bar-row i { grid-column: 1 / -1; height: 3px; overflow: hidden; border-radius: 3px; background: rgba(255,255,255,.06); }.bar-row em { display: block; height: 100%; border-radius: inherit; background: var(--teal); }
-.illustrative-note { display: flex; justify-content: center; gap: 7px; margin: 22px auto 0; color: #6f7c8d; font-size: 10px; }.illustrative-note span { color: #69c9c0; }
-
-.section { border-top: 1px solid rgba(255,255,255,.06); padding: 104px 0; }
-.section-muted { background: linear-gradient(180deg, rgba(255,255,255,.014), rgba(255,255,255,.009)); }
-.section-heading { max-width: 690px; margin-bottom: 43px; }.section-heading h2, .activity-row h2 { margin: 12px 0 14px; color: #f0f4f7; font-family: var(--display); font-size: clamp(30px, 3.3vw, 43px); font-weight: 550; letter-spacing: -.055em; line-height: 1.16; }.section-heading p, .activity-row p { max-width: 620px; margin: 0; color: var(--muted); font-size: 15px; line-height: 1.75; }
-.capability-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 13px; }.capability-card { position: relative; min-height: 208px; border: 1px solid var(--line); border-radius: 13px; background: linear-gradient(145deg,rgba(255,255,255,.033),rgba(255,255,255,.012)); padding: 22px; transition: border-color .2s, transform .2s, background .2s; }.capability-card:hover { transform: translateY(-2px); border-color: rgba(61,214,198,.26); background: linear-gradient(145deg,rgba(61,214,198,.055),rgba(255,255,255,.012)); }.capability-icon { width: 34px; height: 34px; display: grid; place-items: center; border: 1px solid rgba(61,214,198,.2); border-radius: 9px; background: rgba(61,214,198,.07); color: #70d8cd; font-family: var(--mono); font-size: 17px; }.card-index { position: absolute; top: 26px; right: 22px; color: #4c5a6c; font-family: var(--mono); font-size: 9px; }.capability-card h3 { margin: 23px 0 8px; color: #e7edf2; font-size: 15px; font-weight: 600; }.capability-card p, .workflow-card p { margin: 0; color: #8997a8; font-size: 12px; line-height: 1.7; }
-.split-layout { display: grid; grid-template-columns: .86fr 1.14fr; align-items: center; gap: 70px; }.split-layout .section-heading { margin-bottom: 19px; }.split-layout .section-heading h2 { font-size: clamp(30px, 3vw, 39px); }.reverse-on-wide { grid-template-columns: 1.05fr .95fr; }.reverse-on-wide > :first-child { order: 1; }.reverse-on-wide > :last-child { order: 2; }.body-copy { color: #94a1b1; font-size: 13px; line-height: 1.8; }.check-list { display: grid; gap: 12px; margin: 25px 0 0; padding: 0; list-style: none; color: #b2bdc9; font-size: 12px; }.check-list li { display: flex; align-items: center; gap: 10px; }.check-list li::before { content: "✓"; color: var(--teal); font-family: var(--mono); }
-.scan-window, .upgrade-window, .migration-window, .insight-window { width: 100%; }.scan-timeline { padding: 18px 21px 10px; }.scan-line { min-height: 43px; display: grid; grid-template-columns: 28px 1fr auto; align-items: center; gap: 10px; border-bottom: 1px solid rgba(255,255,255,.045); }.scan-line > span { color: #59706f; font-family: var(--mono); font-size: 9px; }.scan-line b { color: #c4ced7; font-size: 11px; font-weight: 500; }.scan-line em { color: #76cfc5; font-family: var(--mono); font-size: 8px; font-style: normal; }.scan-footer { display: flex; align-items: center; gap: 8px; border-top: 1px solid rgba(255,255,255,.06); background: rgba(255,255,255,.015); padding: 13px 20px; color: #728192; font-size: 9px; }
-.upgrade-body { padding: 18px; }.package-select { display: grid; gap: 8px; }.package-select > span, .version-compare span, .security-summary span { color: #68778a; font-family: var(--mono); font-size: 8px; letter-spacing: .08em; }.package-select b { display: flex; justify-content: space-between; border: 1px solid rgba(255,255,255,.08); border-radius: 7px; background: rgba(255,255,255,.02); padding: 10px 12px; color: #e1eaf0; font-family: var(--mono); font-size: 11px; font-weight: 400; }.package-select i { color: #76879a; font-style: normal; }.version-compare { display: grid; grid-template-columns: 1fr 24px 1fr; align-items: center; gap: 10px; margin: 17px 0; border: 1px solid rgba(255,255,255,.06); border-radius: 8px; background: rgba(255,255,255,.015); padding: 12px; }.version-compare div { display: grid; gap: 7px; }.version-compare strong { color: #d7e1ea; font-family: var(--mono); font-size: 13px; font-weight: 500; }.compare-arrow { color: var(--teal); text-align: center; }.evidence-box { display: grid; gap: 8px; }.evidence-box > div { display: grid; grid-template-columns: 20px 1fr; align-items: center; gap: 2px 7px; border: 1px solid rgba(255,255,255,.055); border-radius: 7px; padding: 9px; }.evidence-icon { grid-row: span 2; color: #72d6cb; font-family: var(--mono); }.muted-icon { color: #a6ad74; }.evidence-box b { color: #c7d0da; font-size: 10px; font-weight: 550; }.evidence-box small { color: #718092; font-size: 9px; }.risk-note { display: flex; gap: 9px; margin-top: 12px; border: 1px solid rgba(230,180,80,.16); border-radius: 7px; background: rgba(230,180,80,.04); padding: 10px; }.risk-note > span { color: #e6b450; font-family: var(--mono); font-size: 11px; }.risk-note p { margin: 0; color: #a5a08a; font-size: 9px; line-height: 1.55; }.demo-tag { display: inline-flex; border: 1px solid rgba(61,214,198,.18); border-radius: 999px; padding: 7px 10px; color: #77c3bb; font-family: var(--mono); font-size: 8px; }
-.migration-content { padding: 17px; }.migration-context { display: grid; gap: 7px; }.migration-context > span { color: #68bfb6; font-family: var(--mono); font-size: 8px; letter-spacing: .06em; }.migration-context b { color: #d9e2e9; font-size: 11px; font-weight: 550; }.migration-context small { color: #718092; font-size: 9px; }.code-diff { overflow: auto; margin-top: 15px; border: 1px solid rgba(255,255,255,.06); border-radius: 7px; background: #080d13; padding: 9px 0; }.code-diff > div { min-width: max-content; display: flex; gap: 12px; padding: 7px 12px; color: #bcbfc3; font-family: var(--mono); font-size: 9px; }.code-diff > div span { color: #eb8589; }.code-diff .diff-add { background: rgba(61,214,198,.08); color: #b4e6df; }.code-diff .diff-add span { color: #64dacb; }.code-diff code { font: inherit; }.migration-explain { display: flex; gap: 10px; margin-top: 12px; border: 1px solid rgba(61,214,198,.12); border-radius: 8px; background: rgba(61,214,198,.035); padding: 11px; }.ai-spark { color: var(--teal); }.migration-explain p { margin: 0; color: #8897a7; font-size: 9px; line-height: 1.6; }.migration-explain b { color: #d0e2df; font-weight: 550; }.migration-foot { display: flex; justify-content: space-between; gap: 8px; margin-top: 14px; color: #68798a; font-family: var(--mono); font-size: 8px; }.migration-foot span:last-child { color: #72cfc5; }
-.insights-grid { display: grid; grid-template-columns: 1.07fr .93fr; align-items: stretch; gap: 15px; }.insight-window { display: flex; flex-direction: column; }.graph-canvas { padding: 15px 12px 6px; }.graph-canvas svg { width: 100%; overflow: visible; }.graph-edges path { fill: none; stroke: rgba(61,214,198,.27); stroke-width: 1.2; }.graph-node rect { fill: #121c27; stroke: rgba(255,255,255,.14); }.graph-node text { fill: #bec9d3; font: 10px var(--mono); }.graph-node.root rect { fill: #1b4743; stroke: rgba(61,214,198,.65); }.graph-node.root text { fill: #bdf6ee; }.graph-node.risk rect { fill: #321d23; stroke: rgba(240,113,120,.58); }.graph-node.risk text { fill: #f09ca0; }.graph-legend { display: flex; justify-content: center; flex-wrap: wrap; gap: 17px; color: #788697; font-family: var(--mono); font-size: 8px; }.graph-legend span { display: inline-flex; align-items: center; gap: 6px; }.graph-legend i { width: 7px; height: 7px; border: 1px solid #8392a2; border-radius: 50%; }.graph-legend .legend-root { border-color: var(--teal); background: #358b81; }.graph-legend .legend-risk { border-color: #e27c82; background: #8c4247; }.card-caption { margin: auto 0 0; border-top: 1px solid rgba(255,255,255,.06); padding: 13px 16px; color: #69788a; font-size: 9px; line-height: 1.5; }.security-body { display: grid; gap: 14px; padding: 17px; }.security-summary { display: grid; grid-template-columns: repeat(3,1fr); gap: 7px; }.security-summary > div { display: grid; gap: 7px; border: 1px solid rgba(255,255,255,.06); border-radius: 7px; background: rgba(255,255,255,.018); padding: 9px; }.security-summary b { color: #d5dfe7; font-family: var(--mono); font-size: 10px; font-weight: 500; }.security-summary .severity { color: #f18d93; }.finding-card { border: 1px solid rgba(240,113,120,.18); border-radius: 8px; background: rgba(240,113,120,.025); padding: 12px; }.finding-card > div:first-child { display: flex; align-items: center; gap: 7px; }.finding-dot { width: 6px; height: 6px; border-radius: 50%; background: #ed777f; box-shadow: 0 0 8px #ed777f88; }.finding-card b { color: #d8dfe5; font-size: 10px; font-weight: 550; }.finding-id { margin-left: auto; color: #8e7378; font-family: var(--mono); font-size: 8px; }.finding-card p { margin: 10px 0 14px; color: #9a8990; font-size: 9px; line-height: 1.5; }.range-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; color: #788596; font-size: 8px; }.range-row code { color: #dfadb0; font-family: var(--mono); font-size: 8px; }.range-line { width: 25px; height: 1px; background: #b86f76; }.security-foot { color: #718092; font-size: 9px; line-height: 1.5; }
-.ecosystem-layout { display: grid; grid-template-columns: 1.04fr .96fr; align-items: center; gap: 78px; }.ecosystem-layout .section-heading { margin-bottom: 17px; }.text-link { display: inline-flex; gap: 7px; margin-top: 10px; color: #7dd8cf; font-size: 12px; font-weight: 550; }.text-link:hover { color: #b3f3ec; }.ecosystem-card { border: 1px solid var(--line); border-radius: 12px; background: rgba(10,16,24,.72); padding: 20px 22px 17px; }.ecosystem-card-head { display: flex; justify-content: space-between; border-bottom: 1px solid rgba(255,255,255,.065); padding-bottom: 14px; color: #728193; font-family: var(--mono); font-size: 8px; letter-spacing: .1em; }.ecosystem-card-head .mono { color: #506171; }.ecosystem-card ul { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; margin: 5px 0 0; padding: 0; list-style: none; }.ecosystem-card li { display: grid; grid-template-columns: 23px 1fr 12px; align-items: center; gap: 8px; min-height: 47px; border-bottom: 1px solid rgba(255,255,255,.045); color: #c4ced7; font-size: 11px; }.ecosystem-number { color: #526274; font-family: var(--mono); font-size: 8px; }.ecosystem-arrow { color: #5cb7ae; font-size: 10px; }.ecosystem-card > p { margin: 13px 0 0; color: #718092; font-size: 9px; line-height: 1.5; }
-.workflow-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 13px; }.workflow-card { position: relative; min-height: 190px; border: 1px solid var(--line); border-radius: 11px; background: rgba(255,255,255,.018); padding: 20px; }.workflow-num { color: #66cfc4; font-family: var(--mono); font-size: 11px; }.workflow-connector { position: absolute; top: 27px; right: -14px; z-index: 2; width: 14px; height: 1px; background: rgba(61,214,198,.38); }.workflow-card:last-child .workflow-connector { display: none; }.workflow-card h3 { margin: 24px 0 9px; color: #e0e8ee; font-size: 14px; font-weight: 600; }
-.hosting-section { padding-block: 90px; }.hosting-panel { position: relative; overflow: hidden; display: grid; grid-template-columns: 1.15fr .85fr; align-items: center; gap: 60px; border: 1px solid rgba(61,214,198,.19); border-radius: 17px; background: linear-gradient(112deg,#0c171c 0%,#0b121a 60%,#0b141b 100%); padding: 57px 57px; }.hosting-orbit { position: absolute; top: -220px; right: -120px; width: 520px; height: 520px; border: 1px solid rgba(61,214,198,.08); border-radius: 50%; box-shadow: 0 0 0 43px rgba(61,214,198,.022), 0 0 0 90px rgba(61,214,198,.018); pointer-events: none; }.hosting-copy, .hosting-facts { position: relative; }.hosting-copy h2 { margin: 19px 0 15px; font-family: var(--display); font-size: clamp(35px, 4vw, 49px); font-weight: 550; letter-spacing: -.06em; line-height: 1.12; }.hosting-copy > p { max-width: 490px; margin: 0; color: #98a6b4; font-size: 13px; line-height: 1.8; }.hosting-actions { justify-content: flex-start; margin-top: 24px; }.hosting-actions .button { font-size: 11px; padding-inline: 16px; }.hosting-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }.hosting-fact { min-height: 91px; display: flex; flex-direction: column; justify-content: center; gap: 10px; border: 1px solid rgba(255,255,255,.075); border-radius: 9px; background: rgba(5,10,15,.25); padding: 14px; }.hosting-fact span { color: #78899a; font-family: var(--mono); font-size: 8px; letter-spacing: .04em; }.hosting-fact b { color: #d8e5e8; font-size: 12px; font-weight: 550; }.license-note { display: grid; grid-template-columns: 32px 1fr auto; align-items: start; gap: 14px; margin-top: 16px; border: 1px solid rgba(255,255,255,.065); border-radius: 10px; background: rgba(255,255,255,.015); padding: 18px 20px; }.license-mark { display: grid; width: 27px; height: 27px; place-items: center; border-radius: 7px; background: rgba(61,214,198,.08); color: #74cfc5; font-family: var(--mono); }.license-note p { margin: 0; color: #8795a5; font-size: 10px; line-height: 1.7; }.license-note code { color: #b4c3cf; font-family: var(--mono); font-size: 9px; }.license-note > div { display: flex; gap: 14px; white-space: nowrap; }.license-note a { color: #7bd2c9; font-size: 9px; }
-.activity-row { display: grid; grid-template-columns: .85fr 1.15fr; align-items: center; gap: 72px; }.activity-row h2 { font-size: clamp(28px,3vw,38px); }.activity-row p { font-size: 13px; }.activity-links { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }.activity-link { display: flex; justify-content: space-between; align-items: center; min-height: 65px; border: 1px solid rgba(255,255,255,.07); border-radius: 9px; background: rgba(255,255,255,.018); padding: 12px 14px; transition: border-color .18s, background .18s; }.activity-link:hover { border-color: rgba(61,214,198,.28); background: rgba(61,214,198,.035); }.activity-link > span { display: grid; gap: 5px; }.activity-link b { color: #dbe3eb; font-size: 11px; font-weight: 550; }.activity-link small { color: #728193; font-size: 9px; }.activity-link i { color: #62c7bd; font-style: normal; }
-.faq-layout { display: grid; grid-template-columns: .75fr 1.25fr; align-items: start; gap: 78px; }.faq-layout .section-heading { position: sticky; top: 115px; }.faq-list { border-top: 1px solid rgba(255,255,255,.09); }.faq-item { border-bottom: 1px solid rgba(255,255,255,.09); }.faq-item h3 { margin: 0; }.faq-item button { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 20px; border: 0; background: transparent; padding: 18px 0; color: #d8e1e8; text-align: left; font-size: 13px; font-weight: 550; cursor: pointer; }.faq-item button:hover { color: #fff; }.faq-plus { color: #6ed0c6; font-family: var(--mono); font-size: 18px; font-weight: 400; }.faq-answer p { max-width: 620px; margin: -2px 30px 19px 0; color: #8b99a9; font-size: 12px; line-height: 1.8; }
-.final-cta { position: relative; overflow: hidden; border-top: 1px solid rgba(255,255,255,.06); background: #080e14; padding: 92px 0 100px; text-align: center; }.final-cta-inner { position: relative; }.cta-glow { position: absolute; top: -120px; left: 50%; z-index: 0; width: 540px; height: 320px; transform: translateX(-50%); border-radius: 50%; background: rgba(35,144,134,.12); filter: blur(90px); pointer-events: none; }.final-cta .eyebrow, .final-cta h2, .final-cta p, .final-cta .hero-actions { position: relative; }.final-cta h2 { margin: 18px 0 13px; font-family: var(--display); font-size: clamp(35px,4.4vw,52px); font-weight: 550; letter-spacing: -.06em; line-height: 1.14; }.final-cta p { margin: 0 auto; color: #97a4b3; font-size: 14px; line-height: 1.7; }.final-cta .hero-actions { margin-top: 25px; }
-.footer { border-top: 1px solid rgba(255,255,255,.075); background: #05080d; padding: 56px max(32px,calc((100% - 1160px)/2)) 22px; }.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1.25fr 1fr; gap: 40px; }.footer-brand-col > p { max-width: 210px; margin: 15px 0 14px; color: #788697; font-size: 11px; line-height: 1.7; }.footer-license { color: #637284; font-family: var(--mono); font-size: 8px; }.footer-column { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; }.footer-column h2 { margin: 2px 0 6px; color: #d5dfe7; font-size: 11px; font-weight: 600; }.footer-column a { color: #7d8b9b; font-size: 10px; line-height: 1.5; transition: color .18s; }.footer-column a:hover { color: #a9eee6; }.footer-column a span { color: #4fa79f; }.footer-bottom { display: flex; justify-content: space-between; gap: 15px; margin-top: 46px; border-top: 1px solid rgba(255,255,255,.06); padding-top: 17px; color: #576577; font-size: 9px; }
-
-@media (max-width: 1100px) {
- .nav-inner { grid-template-columns: 1fr auto auto; gap: 19px; }.desktop-nav { gap: 15px; }.desktop-nav a { font-size: 12px; }.container { width: min(100% - 56px, 1000px); }.split-layout { gap: 42px; }.hosting-panel { gap: 32px; padding: 42px; }.ecosystem-layout, .faq-layout { gap: 46px; }
-}
-@media (max-width: 850px) {
- .nav-inner { width: calc(100% - 44px); height: 68px; grid-template-columns: 1fr auto auto; }.desktop-nav { display: none; }.nav-github { grid-column: 2; }.menu-toggle { grid-column: 3; width: 40px; height: 40px; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 5px; border: 1px solid rgba(255,255,255,.12); border-radius: 9px; background: transparent; cursor: pointer; }.menu-toggle span { width: 16px; height: 1.5px; background: #cbd7df; }.mobile-nav:not([hidden]) { display: grid; gap: 2px; border-top: 1px solid rgba(255,255,255,.07); background: #080d14; padding: 9px 22px 15px; }.mobile-nav a { min-height: 43px; display: flex; align-items: center; border-radius: 6px; padding: 0 11px; color: #aab6c3; font-size: 13px; }.mobile-nav a:hover { background: rgba(255,255,255,.04); color: white; }.container { width: calc(100% - 48px); }.hero { padding-top: 75px; }.hero-preview { min-height: unset; grid-template-columns: 1.18fr .82fr; }.terminal-body { grid-template-columns: 130px 1fr; }.terminal-sidebar { font-size: 8px; }.metrics-window { margin-left: -30px; }.section { padding-block: 78px; }.split-layout, .ecosystem-layout { grid-template-columns: 1fr 1fr; gap: 28px; }.section-heading h2 { font-size: 34px; }.capability-card { min-height: 225px; padding: 18px; }.hosting-panel { grid-template-columns: 1fr; gap: 30px; }.hosting-facts { grid-template-columns: repeat(4,1fr); }.hosting-fact { min-height: 77px; padding: 10px; }.hosting-fact b { font-size: 10px; }.license-note { grid-template-columns: 30px 1fr; }.license-note > div { grid-column: 2; }.activity-row { grid-template-columns: 1fr 1.1fr; gap: 32px; }.faq-layout { grid-template-columns: .7fr 1.3fr; gap: 35px; }.footer { padding-inline: 28px; }
-}
-@media (max-width: 620px) {
- html { scroll-padding-top: 72px; }.container { width: calc(100% - 40px); }.nav-inner { width: calc(100% - 36px); height: 64px; }.brand { font-size: 16px; }.brand-mark { width: 31px; height: 31px; }.nav-github { padding: 9px 12px; font-size: 11px; }.menu-toggle { width: 37px; height: 37px; }.hero { padding: 63px 0 58px; }.hero h1 { margin-top: 22px; font-size: clamp(34px,9.2vw,48px); letter-spacing: -.06em; }.hero-lede { font-size: 13px; line-height: 1.75; }.hero-actions { gap: 9px; margin-top: 23px; }.button { min-height: 44px; padding-inline: 15px; font-size: 11px; }.product-attributes { gap: 11px 13px; margin-top: 19px; font-size: 8px; }.hero-preview { display: flex; min-height: unset; flex-direction: column; align-items: stretch; gap: 13px; margin-top: 39px; }.terminal-window { transform: none; }.terminal-body { min-height: 250px; grid-template-columns: 1fr; }.terminal-sidebar { display: none; }.terminal-main { padding: 14px 12px; }.terminal-step { min-height: 34px; grid-template-columns: 14px minmax(0,1fr) auto; font-size: 8px; }.step-state { font-size: 7px; }.metrics-window { width: 84%; align-self: flex-end; margin: -1px 2px 0 0; transform: none; }.metrics-content { padding: 12px; }.metric-top strong { font-size: 31px; }.illustrative-note { margin-top: 16px; font-size: 9px; text-align: center; }
- .section { padding-block: 68px; }.section-heading { margin-bottom: 30px; }.section-heading h2, .split-layout .section-heading h2 { font-size: 30px; }.section-heading p { font-size: 13px; }.capability-grid { grid-template-columns: 1fr; gap: 9px; }.capability-card { min-height: unset; padding: 17px; }.capability-card h3 { margin-top: 17px; }.capability-card p { font-size: 11px; }.split-layout, .ecosystem-layout, .activity-row, .faq-layout { grid-template-columns: 1fr; gap: 31px; }.split-layout > div:first-child { order: 0; }.reverse-on-wide > :first-child { order: 1; }.reverse-on-wide > :last-child { order: 0; }.scan-line { min-height: 41px; grid-template-columns: 22px 1fr auto; gap: 7px; }.scan-line b { font-size: 9px; }.scan-line em { font-size: 7px; }.scan-timeline { padding: 14px 12px 7px; }.upgrade-body, .migration-content { padding: 13px; }.insights-grid { grid-template-columns: 1fr; gap: 12px; }.graph-canvas { padding-inline: 5px; }.graph-canvas svg { min-height: 180px; }.ecosystem-card ul { gap: 0 10px; }.ecosystem-card { padding: 16px; }.workflow-grid { grid-template-columns: 1fr 1fr; gap: 9px; }.workflow-card { min-height: 170px; padding: 15px; }.workflow-connector { display: none; }.workflow-card h3 { margin-top: 20px; font-size: 12px; }.workflow-card p { font-size: 10px; }.hosting-section { padding-block: 60px; }.hosting-panel { gap: 25px; border-radius: 13px; padding: 26px 20px; }.hosting-copy h2 { font-size: 36px; }.hosting-copy > p { font-size: 12px; }.hosting-actions { align-items: stretch; flex-direction: column; }.hosting-actions .button { width: 100%; }.hosting-facts { grid-template-columns: 1fr 1fr; }.hosting-fact { min-height: 72px; }.license-note { gap: 10px; padding: 14px; }.license-note p { font-size: 9px; }.license-note > div { flex-wrap: wrap; gap: 10px 14px; }.activity-row { gap: 20px; }.activity-links { gap: 7px; }.activity-link { min-height: 62px; padding: 10px; }.activity-link b { font-size: 10px; }.activity-link small { font-size: 8px; }.faq-layout { gap: 17px; }.faq-layout .section-heading { position: static; margin-bottom: 9px; }.faq-item button { padding: 16px 0; font-size: 12px; }.faq-answer p { font-size: 11px; }.final-cta { padding: 69px 0 74px; }.final-cta h2 { font-size: 36px; }.final-cta p { font-size: 12px; }.final-cta .hero-actions { flex-direction: column; align-items: stretch; }.footer { padding: 39px 20px 18px; }.footer-grid { grid-template-columns: 1fr 1fr; gap: 30px 18px; }.footer-brand-col { grid-column: 1 / -1; }.footer-bottom { flex-direction: column; gap: 8px; margin-top: 32px; font-size: 8px; }
-}
-@media (prefers-reduced-motion: reduce) {
- *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
+ --background: #0c1117;
+ --foreground: #e8eef6;
+ --card: #121a24;
+ --card-foreground: #e8eef6;
+ --popover: #121a24;
+ --popover-foreground: #e8eef6;
+ --primary: #3dd6c6;
+ --primary-foreground: #04201c;
+ --secondary: #1a2433;
+ --secondary-foreground: #c5d0de;
+ --muted: #1a2433;
+ --muted-foreground: #8b9bb0;
+ --accent: #243044;
+ --accent-foreground: #e8eef6;
+ --destructive: #f07178;
+ --destructive-foreground: #1a0a0b;
+ --border: #243044;
+ --input: #243044;
+ --ring: #3dd6c6;
+ --success: #7fd962;
+ --warning: #e6b450;
+ --chart-1: #3dd6c6;
+ --chart-2: #6c9eff;
+ --chart-3: #e6b450;
+ --chart-4: #f07178;
+ --chart-5: #c3a6ff;
+ --radius: 0.625rem;
+ --sidebar: #0a0f14;
+ --font-sans: "DM Sans", ui-sans-serif, system-ui, sans-serif;
+ --font-display: "Syne", ui-sans-serif, system-ui, sans-serif;
+ --font-mono: "IBM Plex Mono", ui-monospace, monospace;
+}
+
+.light {
+ --background: #f4f7fb;
+ --foreground: #0c1117;
+ --card: #ffffff;
+ --card-foreground: #0c1117;
+ --popover: #ffffff;
+ --popover-foreground: #0c1117;
+ --primary: #0d9488;
+ --primary-foreground: #f0fdfa;
+ --secondary: #e8eef6;
+ --secondary-foreground: #1a2433;
+ --muted: #e8eef6;
+ --muted-foreground: #5a6b80;
+ --accent: #dce6f2;
+ --accent-foreground: #0c1117;
+ --destructive: #dc2626;
+ --destructive-foreground: #fff;
+ --border: #d0dae8;
+ --input: #d0dae8;
+ --ring: #0d9488;
+ --sidebar: #eef3f9;
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-success: var(--success);
+ --color-warning: var(--warning);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --color-sidebar: var(--sidebar);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --font-sans: var(--font-sans);
+ --font-mono: var(--font-mono);
+}
+
+* {
+ border-color: var(--border);
+}
+
+html {
+ color-scheme: dark;
+}
+
+body {
+ background:
+ radial-gradient(1200px 600px at 10% -10%, rgba(61, 214, 198, 0.12), transparent 55%),
+ radial-gradient(900px 500px at 90% 0%, rgba(108, 158, 255, 0.10), transparent 50%),
+ var(--background);
+ color: var(--foreground);
+ font-family: var(--font-sans);
+ min-height: 100vh;
+}
+
+.light body {
+ background:
+ radial-gradient(1200px 600px at 10% -10%, rgba(13, 148, 136, 0.08), transparent 55%),
+ radial-gradient(900px 500px at 90% 0%, rgba(59, 130, 246, 0.06), transparent 50%),
+ var(--background);
+}
+
+@keyframes fade-up {
+ from {
+ opacity: 0;
+ transform: translateY(8px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes pulse-soft {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.55; }
+}
+
+@keyframes shimmer {
+ 0% { background-position: 200% 0; }
+ 100% { background-position: -200% 0; }
+}
+
+.animate-fade-up {
+ animation: fade-up 0.45s ease-out both;
+}
+
+.animate-pulse-soft {
+ animation: pulse-soft 2s ease-in-out infinite;
+}
+
+.skeleton-shimmer {
+ background-image: linear-gradient(
+ 90deg,
+ transparent 0%,
+ color-mix(in oklab, var(--foreground) 8%, transparent) 50%,
+ transparent 100%
+ );
+ background-size: 200% 100%;
+ animation: shimmer 1.6s ease-in-out infinite;
+}
+
+/* Instant click affordance for in-app navigation */
+.nav-interactive {
+ transition:
+ transform 110ms cubic-bezier(0.2, 0.8, 0.2, 1),
+ opacity 110ms ease,
+ background-color 140ms ease,
+ border-color 140ms ease;
+ will-change: transform, opacity;
+ transform-origin: center;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.nav-interactive:active,
+.nav-interactive-pressed {
+ transform: scale(0.985);
+ opacity: 0.82;
+}
+
+.nav-interactive-pending {
+ pointer-events: none !important;
+ cursor: default;
+ opacity: 0.68;
+ transform: scale(0.992);
+}
+
+.nav-interactive-card:active,
+.nav-interactive-card.nav-interactive-pressed,
+.nav-interactive-card.nav-interactive-pending {
+ border-color: color-mix(in oklab, var(--primary) 35%, var(--border));
+}
+
+.nav-interactive-row:active,
+.nav-interactive-row.nav-interactive-pressed {
+ background-color: color-mix(in oklab, var(--accent) 70%, transparent);
+}
+
+.nav-interactive-nav:active,
+.nav-interactive-nav.nav-interactive-pressed {
+ background-color: color-mix(in oklab, var(--primary) 12%, transparent);
+ transform: scale(0.99);
+}
+
+.nav-interactive-nav.nav-interactive-pending {
+ transform: none;
+ opacity: 0.75;
}
diff --git a/landing/src/app/page.tsx b/landing/src/app/page.tsx
index 9048aed..e5edd96 100644
--- a/landing/src/app/page.tsx
+++ b/landing/src/app/page.tsx
@@ -1,194 +1,28 @@
-import Link from "next/link";
-import { Faq } from "@/components/faq";
-import { SiteFooter } from "@/components/site-footer";
-import { SiteNav } from "@/components/site-nav";
-
-const repository = "https://github.com/ayushdoesdev/verspect";
-const install = `${repository}#quick-start-with-docker-compose`;
-
-const capabilities = [
- { icon: "↗", name: "Dependency intelligence", text: "Explore direct and transitive dependencies, package inventory, and relationships revealed by supported manifests and lockfiles." },
- { icon: "⌁", name: "Security analysis", text: "Match package versions with OSV advisories and review severity and affected-version evidence where available." },
- { icon: "§", name: "License analysis", text: "Inspect package license information and policy concerns, with gaps shown when source or registry metadata is incomplete." },
- { icon: "◷", name: "Package health", text: "Review signals such as release freshness and registry activity when the underlying metadata is available." },
- { icon: "⇄", name: "Upgrade simulator", text: "Compare current and target versions against detected usage and available upgrade rules. Findings depend on the evidence present." },
- { icon: "⌘", name: "Migration assistant", text: "Use structured rules and optional AI-assisted suggestions or patch drafts. Review and test every proposed change." },
-];
-
-const ecosystems = ["Python", "JavaScript / TypeScript", "Go", "Java", "Rust", "PHP", "Ruby"];
+import { MarketingFooter, MarketingNav } from "@/components/marketing/nav";
+import { LandingHero } from "@/components/marketing/landing/hero";
+import { ScanDemoSection } from "@/components/marketing/landing/scan-demo";
+import { SimulatorDemoSection } from "@/components/marketing/landing/simulator-demo";
+import { MigrationDemoSection } from "@/components/marketing/landing/migration-demo";
+import { DependencyGraphSection } from "@/components/marketing/landing/dependency-graph";
+import { SecurityDashboardSection } from "@/components/marketing/landing/security-dashboard";
+import { FaqSection, FinalCtaSection, RoadmapTeaserSection } from "@/components/marketing/landing/social-sections";
export default function Home() {
- return <>
- Skip to content
- Dependency intelligence for GitHub repositories. Discover what your software depends on, understand security and license risks, explore package health, and evaluate upgrade impact with evidence-led analysis and AI-assisted migration guidance. Illustrative product preview · example repository data, not a live scan {item.text} A version jump is not automatically labeled breaking. The simulator reports what its rules and repository evidence support, and leaves uncertainty visible. Deterministic migration knowledge is currently deepest for selected Python packages. AI-generated guidance and patch drafts are suggestions: review, run, and test them before adoption. Python has the deepest deterministic usage and migration analysis. Other ecosystems provide varying levels of inventory, import or module usage, vulnerability, license, and health analysis. Full API-level and language-specific breaking-change analysis remains limited. Capabilities vary by ecosystem and available repository evidence. {text} Verspect runs on infrastructure you manage. Docker Compose is the recommended setup, AI integrations are optional, and the complete source is available for inspection. The current main-branch source uses Apache-2.0. The original Explore releases, report an issue, contribute a change, or review the security policy. Explore Verspect, inspect its implementation, and run it on your own infrastructure.Know your dependencies.
-
Understand your risks.
Upgrade with confidence.
-
- {item.name}
- {ecosystems.map((name, index) =>
{title}
Your infrastructure.
Your control.v0.1.0-beta.1 release remains under AGPL-3.0-or-later. Third-party dependencies keep their respective licenses. Verspect name, logo, and official branding are reserved; Apache-2.0 does not grant trademark rights.Follow the project as it develops.
Explore the source.
Understand your dependencies.
{description}
Example only. Compatibility and impact depend on repository evidence and available rules.
from package import LegacyClientfrom package import Clientclient = Client(timeout=30)Suggested draft
Review API compatibility and validate this change against the target release.
Illustrative graph · relationships depend on available manifests and lockfiles.
Version range and ecosystem are checked against vulnerability data.
1.2.0Fixed versioncheck source+ Verspect +
++ Product previews use illustrative example data and are not live repository scans. +
++ Generating patch from AST match… +
+
+ {code}
+
+ );
+}
+
+function DiffLines() {
+ const rows = [
+ { type: "del", text: "- from django.conf.urls import url" },
+ { type: "add", text: "+ from django.urls import re_path" },
+ { type: "del", text: "- from django.utils.translation import ugettext_lazy as _" },
+ { type: "add", text: "+ from django.utils.translation import gettext_lazy as _" },
+ { type: "del", text: "- url(r'^health/$', views.health)," },
+ { type: "add", text: "+ re_path(r'^health/$', views.health)," },
+ ];
+ return (
+ + {eyebrow} +
+ )} + {title && ( ++ {description} +
+ )} +
+ {f.api}
+
+ + {targetIdx === 2 + ? "9 breaking APIs across 28 files. Estimated effort: 2–3 engineer days. Suggested patches available for 18 call sites." + : "4 breaking APIs across 11 files. Intermediate hop recommended before 5.1."} +
+Open source · Built in the open
+Browse the source, follow releases, report issues, and contribute improvements. Project changes are tracked publicly.
+ +{faq.a}
+Verspect
+Explore the source, read the installation guide, and run Verspect on infrastructure you control.
+ +=t-Lm&HM-4De z4(j9n@xW@g&X%tI6QQG%;w79lyO zlMv)0`1F@xIkc&%NdyI0{PObQa>S#yoTKU216sTKpVF|VX5OVb&xIxq39H}zj{JH5 zhLgnN_<$(A#eTKg#kfCYRPxfLM%)(Gv7uDhDJ6TxOk}Iiwe@V1_NU!GTPIew2m_Z) zT~~JkxCF9bi5VWl@6Mtod%7bxkxQlU#BV0asDXK#Yj?a-7b_bbbV+V#DbE+_cwD-K z$F`Rz;eD80D&kP9u4Mb3dU0kZq5T=t>15$JtcKH;&E|va^@)LwPT2&Nz)w;Qlt}&a zP>Na4o1<9#gSg6D=x1gH(>%&TCWCcDS{RIT9USBRRhr$5q(rs)g-v(@cWMs~`>at4 zcV&|Djm_P+Nare~mT$xuT~y6xoH$}Hes e ztVyXr-UNDmtC9b-N{$BQ*{;x7uP8TU=b<#en{ $M-Gn`GE<}VpG)|k1uTFFr3 zI9fm)6)G|}=2jO*bjhDA9|7ZRon 3 z>Dg6Q(kUCKnwuA5CaTlYboKjj+qbs2>uT%IK2D$LO%}G3v|h|C9r;K3XuhdXR59uz zPLYzle9D5SDHb+0X;ZGa9TM@|OfD^L@mYgY8tS=c`Upv&HY iWm4Wtc%&0D4`=dhE{ZoB?^UAOUD_EyPHaahPCcI&rd3v4M#?&{MeL`m zRLtV7 4Yx`7rcTw}%rV8uR R`f36LD=3mNQ~5IHk!|L$i(UNENua5d;}k1^$tCwPhLsipsQ&}DlY9ytST zQuM$bm~hkC>fTNi4xS +A--|0IRXvxO_kW+d z#P;! TjZ zhWT&Cx#%r*zUvL-`6z}|d>GFO%Hd1q{y~%}8jeP5K1gRx%&2L=#q%1)M=4G|iFx~1 zhn>&WR35fn0pZ6bqPcg!`<7q5ks0mg4oPHq#&YzwA+q9#a`AJZKh*j+1+KVz7qq70 zUb>|6D(lS~l31L<-$tx)CQbJ6p6=om95PL~3CXaQomhku>_^3$I yJv8 zY>&Q}5fc)=Vfy7TmMu#lTPhVPV&otDw$9@G>AyQD<;i+#&e!#NKk#OCYO2w8*$ne> z1YdAN;P#<-JM `u=6oTJcv?L56tlizdU~lrqCtaSdA=i( z;qWvNtDU}=@scg!9VP#IluuWj7$)AzX~>~fl}6VJ1`d1z^GQuGfy|LM{vmO7Vu3Q| z3=ve7<^WvVIaonjUdeuBk`Q*E_Zp@=rtDAXxJ^e!baCqvucP^75*SJ!|{dP{*r_ zsnk#`-X_c}Qsd~ZdE)d-j4 @kt>bHzK4IzLh3mlkw^Oio`e^w_rfHs zcCa`SH>IoglYNp*@#+uetTSmAW4jkM30QXbb7LTcRByPs`-hbOvNAVZf5ERd1T4K_ z<0Fu=({qX!a17g+40Dp%mvrUSUi99`o&&GBXnh`~sbWXpedU(jk6 zlaXA59gD5WsqmL}O0pHh$G(pfK2w%l>KDozYQ$4a?%eR#wtk&w Vd%@aF<4TDm@fR#WOq^Sg&cQC$hv3D?3RzuPNQ+G^Oo`z9_A6{nT#3>< zC=YUKZ9Uw<%E8ih?FL=*FD}+ISLevQ7%eFef#1$SIodA*=pzL4OH18n!hi*|G+yVX z2r}58FF74qy(f!=mg==_JU19H6xnAd!dmVYDm)*7k<_$UZ;>Lj{f?>(@q7!HD{nqu z>y8+JaVFglU_N8w(2fqAi)h dN!9qN2j> zWFU|Ox^oC*<4m@x^j+XD^j=OM#1EN5o;qi(?v3;;aVstdu@!riyY$h!LKA3I%RdE; zJ2}bE?K8(S_b*_*xsM1BhEdWVXJZ9*V`8fI?i6AUyZy~GeERY+#Y|7BuJphlR&V L PiK=-JfNue^+Up0k ?AI&d$j(*}FQWA7JN)e7?OI2-7%JIT6+R(MYs&g*+$6BHn&Pjz z`%#;Xca#~OjsFgB)uDwZwO(T;{e*Cd9x0#hY4TUtQq8N@Z^rr>kC7b;I?SOo^pobO z^PBInM?y2+t+e6DW0xT5M%;krQ?E-$+)8lFc=B?u+fqu|j0XSnW*9Itb8!6r^T*!c zVH24hlyyIJ3Q_<5{ogf1+s}SuWs&l!skvX1W?-<2Txe8QTx_h0s&1FDQ1nP>NQj^u zmq_hukdiF5(*YE5jv4cQ?sI40ZJ;<}GSl-hHsC>M 9vev8h-1ar!oVDiH^mD7Q;~bBLoXxg{s&9Sm6LIK7y>;0i z+}S2umP~Jp*eLF&E-8I4NT`2=CNVt!O5vsr*P0d1y(^;IpRA*pIGO_}OvP9}5^g@V z--dJ_J|%Z18kREv31y543rj@(-&h;uLyQtD_iOeps={s_z!p;0ixdnFfL0O}(n}%6 zyQItQzoOa)S`-PSeY5~^ql`J-O)=wkk=X Fas~9nI1q}8TTpb3Y<;? z^pjr8^<2G)%9$l_b5 LS&A4r_Z!ZNeRj!=8Sm+V|Sma8j6?9S!I679G_*%SOKh zkxbvea`{@iyj5&dc>p`VT9pgN4c?usQy9DzoiH)!jCLdXazBK >5dexCTD&JiNA)-U`X)KIE>fK43we%meY34pPud)%UNwT+0d`E>eX;F(5dw0ki_a6y&Z`A`c(j5? zHjs7M((M8-Lb@Xa9Ip?y0}5Z#j;;ku8W}0c$%V#ahiw_SIh`c>_KwHt5uplP_5?S? zz)%GomXX2S(jjc2APZ-^kkAmF6rG7FqDnTEA9O1%Mpa=Ow8Gt?PWD|avGtbAex`+= zv|Gv^-v5Jf8uoY^t!i_uumTz6y8L+Qe|zeqPNq&eJv1hmwc5c(b2CvBQjm;PsdO1; z78c8Ok3L=SJ)HIs#q{;dmoLF~;Kk~)5({MNuN$Io?|hIo*l+(PSCDifnT!`t*8If% z%;Oqa*DDls@M)<^^QR2$v)LdI$m-u`Y{nlbyXV!(wNwL% z>{T#3=Q{MpiC5oI=WXhr$(t!1w~;r&2N^646r@)(?QQ+Jtg6+n)x{qHe$K;^XrYL9 z@?|ptZtgmX+coV;^mo0w!*GoZS~oIY-YMwaaIV{(e)FH(QH>1Gr|d`g)72(EyH2&2 z`)}_88VpBmER&D9T{rby@D8a_v0G*5?K=XPz{MVcyyairQO z!MRoyVC`|bYurcmQ!Vx2z1m>=!>35$y?W|Z+ii!2S6Mv(DAadZ9(lTXF~h;a(sE`!ovrYmJW ~IUD{96pZ`VoXV~}UVHXXE zbi)$$Jm{I$_1@#W8M6=CW@LUBUmkXOi4DEX748E$2jzGLoebM-RRQqiruS`0RBGyD zI`!&!5t!tWaoOz#zH{q&K63ipYAj<`-OvRHT24nV3S--dI9hi4cwhq;-|P9$l8*Qc z9%r09-TUG6{V`#*q*)eP4&(`?NJ46sjO^jRLLXk70~764SREEIb_fT7bi=xYJ4cn{ z>0LFtP%lHoSmujReQiD3ZztL@Uvhu_4wW8b4XEl+Jsi8{n)`A f~;?zU `HVL@g+(qW hvFHdW0ZR+?Y}j}xk&{v4 zb%qd ZkDSaT?I5`U6TEHvMZzE?#Az|EG M8}0qQg9Ix0j#=+JUTfi~OUZ>SGLP|E{)=u(zR +g7jo76d}cuJY{$;hq}iR;yz}Ft z^)Yp@?{U1pQNS@5={SY$oH8pa{nhPbB@S8xv()taFX3TD4))i_`*fP|auu>|eWWVW zvGY;d3!k(CBluTb7x$_#Kf-0h1 0v!{`lZz?Z$?CYmSW6=ntc6rJ{2RmA<9zeDteS{0R zO+MP-9pM-Lgh-0z3p!jo#2R=+Ozyx;!I#Q`Gw})Wg)2$mq=BKK)1~~9)UPk3W)uVq zD=Wu1!T(s8*>T#3IGK+o@+m3^{8}~2v`2kSTGMu4<=|ysRO6l9({Pdy5j*TJl||jE zegED;rcQVJ1O*g;IKo7 Sxqw)y4AVB_rGEM1${RRXHjS*C&7= zcean7U1nK^y$jo6lm83(DjP2PYb7li-k%0MTQItWWuBPw=%>K04LT iY>F?(g5$ct7T*;zx~TASb&|7(@Ec>Q)Zk^FEJ4jKGlbuyu7dy z-v0fd2bks(A|*9-rb1`Za}3B-!BH_Z)Q%ULO(wHwADad#1b*!m$Wt5~{LvMX>16 2M{N zq~YG(Oy6R@7P1>*sT L*So_Uzf-uBO@>FfTmmhUxTkR ziY) _BpDa|n0E_Jw~d z+a1wvM$JM4g66v9jTo7beOxnL#LCh@4$A4 nOXlbfW2+bOqQkAHfSfMr;t;i_DF7oF9g$f|P0a33v&gmB n^bTGnKK}BQ`-%XK0^T+4`@Jy%jfxeQ#@vWuZw}Ss37h(W zAniOVE`GsY6Yl%aMar*)9D{y9Tq8MF^~#QnuJ2=~)vn*GBy>p=`1#I9ep-?@sYuu< zQno@~d*LBpUlYBJA{^;t8%iNyqj7&^d}p-JLp$L(C!%j#*;f5_;6)B&P8`EK-vsIR zo|KbW-{KazCXdO&8_U@iuQ(G-#EPu!lzt}tGQ`pjb7TqoTuPho*jNDA**V4B9`Y{x z!bHbRVn{{>9z`Hke{MNgwR0`1csqQEuyH>6+R2@G{+0PI;FnY9?@2q)xk7vL;;kV{ zA3G|H*7O?(k7mMqWXll~yv%Q@c59M>*Qer*#jdk(%&_O#HqR}-kdRPV+gb>qPXne* zz@pi9_q2I9>(S>1-A_1$-aQeRtCty$W;@TW-YxSpK`Slhb8rvEHZ>xI9`d?!et-xC z45#MIGF^Y}Pxu#Ry1*;fb5l~t?>P` ki(H};mJx{sBE0R=kdLX9LdE?j_c`?1ZtPzf!^NUC#yo8+YBlp zd)*q-ZA6Cim>`I4_o`-8+;D4dVS(I U>V=2+qLm2!jwqeyd z*npGm(0LR+5v)L-PO;B~c>IqNJWGu|g`dsBo=?S@G9B^EcHnM^tv{(HS0UzB&5tnX zPPSCTEH-D8V|PFub?faXE;`*yoe$RTh~ f1hXnxcE^=!uBq*KTIZvM*c*6p @%aqoqsy+FopB}J!2~e4yLqY0tK;>rlRQ8gG+D7 z@phpL??IPb#rEOww81k*rT{+T(Rv9K7sypKM_qVl%eokZvtr#7ViKyYqm7AA*8U4l zsc!;wc9f{IuQMtuYrA$b%sL({@i7J3m1nqYWLxU+R~R%1P5=3KMxZF@c2cSsA-o@^ z#Z%aJegGzDJnBy;=Ne#&Mtp1wyq7Ax p|t$P)v&=FF3)ov!_Xc)}7tkz^a2t3=1^h~iwsH}R$86M@+ z!aH&2-S9*b&NN}8jdfW}oZ)ZpB|hRyaWrm`k3Q+d8rY|Q%@jlBY bIrkI)8(r=*=l0$6oHAJ!isi z;&(GQ$k#Ui`LbZ|jzG5knVJ?bamgGfew)GWuVOb9#lSORzbl{@7J!i280MbjOd5ze ziMU 5 z`2nW2?TWKJs7zq $w=dw_ zVb}PkS+?rcxvOtaWSc|rpR_&c{m7w^UJ@F41UR^^M=3aMTgczr;Z*Pd{w yQA*Q6qMhR^Q*35&z?cv`Oa z)U>tRf6R9kW;%Zss`zSBP*fG| PcB8t! sDK>p%o`HZHeY>k>VGyV;%lWF-5UwU9nGrR4%Q;maCqR(~3=( zw0 l8QPG5WP#J zV2c~ik6h=Kxwq7O9F^4iyECWHPy7AUcNQaGBfS^MN6+G%^fS-T3IBQNAg;cUoUak` zQ+z3BfXrO_`9=zC4_`Wa*ZilQSwrE 1}k6W9f%q@PAs!NL &YoGOsmc6Q5rRYD2)jbV?UuFKy z!jTQ^?e5tSs`^Xq9jwfFp-GUBb7K4X8x^+)w!;x!74ptVdM{hr`+X4&8ql!ow!hg9 zER|{@g9yRi;gzw5B?3t*rDA>RqDeAA(UMMi>lNQ2hB+#dHJZJnZsPP6i-6B=aPgzD zN_W4?s_;b;!Tl%%xN2LRj<-AvY|f|E)LIZ1{RY4Sj-cerz|;aYo^rORRCq+6eaVAi zxi|8e9{J%Hv<~FHbN6)DJ*dyyIB9`QPAn`ntaiv%G(sNh%XAv7e4uYWw}L#5uo5y8 zJ&(={Md5qUyLR_~W6${F2X{n6#KQeDEwr`=J!|-`C;PIAoH{+$>J|3~{C(k>cl%*Q z-2tcKKljd{@cl%2dHFy}M;xfR#~vK2jN<7Ql;JSSAQHrNo$CY!+i^k<0=gqbPTHK9 zF0ES}4?C@W5stIgFR@>awgDC=nCp%w!Zs~&F$rhcy2nVC^7agRx)XAssbo7JZ?NfP z-&$fEvFq&>&;kKwMaib3$mUfIhx3-Vo9?m=D8u>48<^neqwbplbvhp`N%_~uim3A- zsI@u`Ad#?(iA%+f*U9{582ELqh?B!KR%jEsZO2|e2+kCFaVF_vV=?Sc)U=im
Dgv4*v^gVZauU3 d4aD87*nHZ z89yF#hM `u?%IpRXn$g_1p6!=~BA+{r37!g4u;X*=<{erwZy%CuF~P?0-DM~E z?Yf(yh>5c8m;F$fsKS@CsHobyTJ|Jy^Q)v6fYB^>l*(F3X}mfgI{@#JbWUsFU6V?P z_n>7tAqQsWHxEQ>Xt^umctBw)0OZ I2j=tb8J?`qYunr9l-oH9CB#tb|$7z(~2eCHq z!k|UP3%#d(oY0*DmeX$;_XB| lA+%W88gZ7%DX`gf@TxYPr($1nxWr!o4--E1Aw|4K(%DgYBI z9I!9jNNI53ta@I75pG+_OrR~~Qgf?2V*Gjt_jOy`N`%mQrzbo)@U4*Jk$tZNKX?(Y znnd68`f>~N -TPTm6h!BlRUtQy~6X2B33PcLCzkVnhi;349^LD*%?PoP4%9WlB!tM8f; zsNu|2-fE1#8xqLrg0G7&GSTdC`RRlb0}piL1UKxkHP XrEP#pZ#+YTgYq~89 zNVv1Cf8B{xb7$~8Zig;w>9y(b>yzl6tHFaF6%kHugNtFA|BPpD;l~Zb;==KPh))q> zXVG)xY_JRV@*ZpRMpVWWR@FYn9MuP+RvRX1`Qxpxa7e@+q)@Sd&FKp=qo4G-g!H LZ1QhFUjaO*k0 zqn|C5H`Kk6>0v=6C_j@GN_u{9Eiw6_|BnmEtA5tZtu#DgKj^7+zMm$^+#Y9}NAbvD zdGJ-xELF~lbWw$s1(BKvwW4|2in;i6d3)d)*2l>w`)T-ae6IJ3PUa~9W}flUov*lE z4(pSa2NdqR0(q8! K~ z>Awb(g*su+qgI#60061HKKHQx7!)VcXDerpUE#UrC*^j%-(a^LBMW*Gj?_nAZMG)6 zd<-!eB0ldrDb{04-~@ztPEM!Ny;g^zg1!PqeSPQ&4+K1#XZ9sd D(+?=;He&&;emw>`kMdmLf8mIGzc3yoGEjYgmi|O$OYhv zdl`7{jwEJ!?o=tHx7g&Lr(Wu}Jz%&M;)^?*5A9sD@cEplz|Z4eU{dX@{813O+C#rI zljBDcVb%EleXar_p}%5%_Zg(T)cX6`OH#@iE&I={0_gH!EPJz>0sG!k&_REA%c;1c z?THsUxpq`vUtgf=G-d?QQJd$DvY@+`xaTUwzxUMgE<7^P`S$-#6J(FX7q%ljxA+}e zb+?Oo^N~^DNwf6<;GufU^Tjv&?@3V)6rM*idB9Ui=cBC2uC~ifo~GThVUBTHV`XlU zT|RUWiVqfZ$Q*%7egz(PR#JMRzm2c!>O@im&!ckLgdDcd;~Mlm2XbZhw>18HJ1G2K zHY?d3&S*y<8z(IuH}e6!nqJE-Gc&t(yZbq$8-Hz9mXgbK+((dNrtkudg8Y!$ZI7Bw zgTn!Lye47|+R^3S`g=1VAt3=I`UtGj;6R?c@WX&>^GjvZvDnq9-Q8Vl&4y+mwUgQY zoXDZw(YrrU_n4w42gu%T*9Qd5-jU-aoT9yfkviP?5jOLe7gY1u*!MQ4{67e3B|`mL zuOEPA^qd(os&}u)3mrI}Zs8 Tzdj9QC79gE? z$q3H$9`nR6_0J6wg}RIxjX%xv0Xc{8lU6Mr;9bnY%4%EUadtvcw3$Y_>EQg$4575S zB-UuB@3LOB%(7jH?0Z{MQL;@NuR3dKY260@cnfNCzO%lMLD$uA56L&(2vTxawpeIP zz{2=SJet~@tI_i%Wz$ {C; z@HA26q;1>zYsLL={G|#1?yME}HKW(JQ>+HV=Vv-66rlD~&P>P!t&^6=Bi`D$C1^fu zE3hA}No8SeYv@d~`_UTup-X&yaeO7V{AP&_@Y})Yfm@)~d7TpY(A>+26*Xz=N?Ifh z3}jQc-!fAB74-F?gT;^cnZavO&(40o76MQ6bd7Zu15cp?;VRoV#{--qk5k?0&Gv_< zTGry?)|m>Bd$Li|FASJvDVO{G-neJG41nox_;HI$G4n?3*3>ru#|gRt0fY!^{=6B& z4}XsQ@ `}RZJ)vBiVS^@ zrJBvoD`Q5OXC37?&9+{I45#)rRb%HHRh4lKF2^pnvyh#UjL|mv2t>)(KuQR^MprKW z(=sl1A7(*ka-9tHHDV1y)3b2UsS)=2NgS|dYT;-QevG2TLB;QcuyshwhX)r5vgs9> z)4nHV{rKtE33x>FO0(ktW13DLDV76)v&Z@L(*CUz8_yu2%&YJntb%2Guc8Ixmnssm zf0g}8T;B!6=UaOX1kQ23|HNzU=~pimW^7j2-54VEK4~@V_xs?ku>zBkH#7p0@lkEu z3K|?kBIaBwgKxCT)Qyo<2BS5JSl6aY3Pf+e-o5==^nF5^IDT^iYba@^qe eGPEIsOsp9aGpK>fq!e9@#r6EI{#a`1lZ;9 zQ4F3KvT(R79WR9WcZ+^1C~&N5ULuVk)3@ow%_Jn$&wLP%3jb-ijTUJ`>T;FsN$J{S zyPM&O?%68x9E&fOa#2r!?etf0L_kjRF4eln?dnKgWq^AqLhNSC7f&p0wf|ygD3K#a zIV!X21t#_Arflj5%QaxO9>lqJcNuxDx}C|cTDjbw=!qb$C;0vnnw40Eqq_X{xnFmK z#40L7>-hJscsS?UJ>>K(-|c>I5Fi -th zdM$%0Bw(GQbTLYHFGBR(9=PeMa6sC2Z#bBtl3PwOXT!M%#d=oR)poM4khfj~D%A5V zAZ?~O-;F=DKaUK+F5hpbgNcq8nqu!@9c&GjR6KA)a(f*{`=N@<#nxWzT@0B0;i37V zO5reCq^=0TPu|aE0phts>J_>lY|h349v;-#5-%17^ 5-D$cf9E39`B1jo8Mpozsa^eR1v$6xKiqJy)*+FVzbpx!U1-`q8vr=e zS^%cB*`NEU{xJQFoaCP?02@so61j?c*wd{j{#v)8e$ehoLRsGL4I>eIyhu}lP;NV8 zEVaqPjw8Nv#P1ZCf<7M1v}tTd9E*f;yB?u|?np&XvYLwg+P%mksht m?&| z{D3B*^6yFS`K33F3rs*^A7(WJy`A_F1 z-y1FOvi&pDQ9bEPu#^v{!yH1!-3aXHsuoU;wqvCmo0&OC0G4Y{Ll@wptD9D{N)&PB zHs9fezk?oE{M|d^)`&9bu+CZfTXTqeXON1p30P%4dp_5(Zf&*eeUq5`^yIGK=dIc3 zhDR7_p7&us%;9UgaK=MH<=-IdECY}G-|%dwRfvXx6E^hO@pfC;Vp;EZvXdwgJsUIo z7Jj!& ?x_7bP1a& z`%e?S9MxI*&FD^j+B_1gDEfHJub(1*ssgcv8UaC`Y6FQ;PiC2{{@sRZo i8VY=F0kK-cjg9G&^o@%eOajq-K1%PZaT7-NE_Q zV71&}wX*hdsxEahp+lDM%r $2=sd{jhqGn&qqlmY@8-!WiU|!5VCz5~ zM})20kCb5}z!&N$tt=+IqY!pDIS}P4^y{YqGUAP2yI-4nBlVE@q8B=pYB%| AmM;>xVGwp|YDrCRc=zwjOI+A=n z5I?*8)ah1n`Q>~997)hQRoh{i@rVXuv9hpuvX~AjqHYE1`xUJ#plDYCKZBeO$Ia6( zA<6Wnin7ByYj3Ts8e~D>i)GJ;c#5CvwEJSu7+y1X7?7cza7l?kfz#XbGw;U(vNSjc z7hQxuC?_e}$Xq~3jA_}e7<2^87`Mwhk{#hw))W38TWi_+9BNkj2T|99$NFi}{S3Yh zPfM?Cke*5a4d5$X-qLLSJL~ov_cPz(`+Ibej-CoI$l2MWWK}1ze7VVbi}j_D$i^N) z(=9~M ^dsRHJh2REYB-ND|CV0f zd)*zLoS5l)1g{xwyV{x@b=jQW{hWf-D{Gx)LH=erS*(({rbC-}Y&skbGy9ifUJPm9 zT%Jul?T4 n>^eUW?jp}mhFUQTvCDthd8=u5jXK*x7pB&iauwE# zG>5wxgG?0&@Pa5w3JlLIdBuM?sRN!$%26uM){nWj?`flVq feo>-vI`vr8SBx0mHS!& z-EZ-5`4t?KQp|cwgrV3>W5(EHgff@BtJ@`<#^crp(C?4-JGE0SZiG+uftSL;t!qyf z1jo}Yr+ZZdy5%e{2xWTv!+1O7h)1Y-;A?;`{(5)qhQbQI0#~pj(};c){;oSg|FjC` zMTHWbj@R7wbVtB@+<4?LAeS9d7G@b9;|K9_%Usm|$J0B8SJHJ|+p%riwr$(#I6HR7 zwrzB5c5J(2+jfT?C-1)Q<9oh8`|m!gYE`Yd#vJn;#7Xgl^rK~HSXPFHUtZXT&J*XS zRfxREs{x-}&rHpHDujs^`@y_G=e0`&5+*Qf=DWWETIonzY%*v 7BwT=q+hS{gTq+(YeV0`qQpTJBdtMFN`Mupgb_$0OcVE6hi^m|hRlbG& z>D`W7xHHl+9>R({y)%TBLZxGrgfGQbo5K;d1FqUbuxIm!CV^vj$8;`+L9(Ak>v6j; zq8IM*$s_P5w+%O&9wf{UK8^59J+0dL{@p-^n~st8Smn`?^N`GOM?1Bp`uw=oZ=IFj z-z5Hhoi49v+B<3V>Hn^Ut@a8&Uuqe?b@bJn+^6aMzw_Us#It{{p^o_-kN!PTlY{w{ zm1n}MK(w&wl?AlR3<3X_G+!Mf6VEM}d_;2O<_FJ3X3Ey(Qw!&>t;+KJoSgi($^lg~ zB!TyjNj<$BYr11|>b6t0I-0-I{IY@AGw-QC{m1vEXLAL&kB#q&I?Rv-C`x@#6Law$ zKlg#RLq23&Ts~hZf8zbLZ32HK0E&qB^%KpgY>)oO)*MZ|z&~@MEz-(%+0{d3UfUq_ zhqS4aCe2Csc6y!*&x?<_J?j*vt$P3K895@u!jHV%7%$+skTWF@bEIf^3(NV(q-XUy zyKo+mS^(Sufo_DVmHmBuBC5-srZ(P@K>hhOaAd_E*Q<-`9AWoIst}qJ3e_o%nxKTF zcl1)h4tP8d7Gtwhpn$WLkE$X2fJ2b5)lrfl{5l1x Pw1hX%b;qc`(@)Z_fGUE Kj(74+Hk3{oNwHDKI9Cp6x*5ut<`ny>q zx%$qD3%B=3kn}~q=TR>z`52M^60E}zkj9d%R!s{V7=~!iD%`Kkqm!d^Vfv7p6zp zT0kLyi17hUSn?=s-0N6B-Jf?%&Jf|cPkg3P4p|I0oeB0^iPA4BR-GL*u84NnIu^1_ zFM<+tG9c6#9_vhEsG JxJ~ooq+^xa^Jtvqct?I}N@gDvR-xspcplAC8|MNsc1LT86 z-~B<;hpE>XTy!jgoW2Jphx_?!CSCE37F=wuNR6+Pb8=8xe+K^2c(Zo6GS~2_acIS? z2o5~@+7O$k=7jZ8TE5qPlI*F$eVk*tl4EV%#^=<>!UVA=AK(~z%deuES#b5R}|3Q;4;-7 zl8uK?-S@T?7$p9J%}>|%aQ~m3p`oy_qTTbYnYNOEjH6RYHc@cst~p_+=Qi0k9GUnJ z_Z?8w(P?p6|EVl|vDN6Ee7)9d4-{k!{k9oD20U$T;S+u$;tM5vzUoUT;lm1-+-5IN z?)rb0!ZY }3pS^i7X+PY43rvpDXl%FE z&iMn6`dTKU``QjKTnRVMp1|5kNrkEgBwtBpmR`vFdwMV!Z0;ZAGl&IhKhLW&qZWgK zD-gDDwbfvDnI2asTc_J{aJ_2Oy?0=%Ho+iA`x7|w2|f+2csiT4UaXy;(|adQba~_) zr)}grL3j ii=zDsD$Nq8P_Wq~&Sxr_Uw&v3g({a)a zw}Y3r*4|zo`=Qh+T>cC=#Kr&CuFmV@@p*Ilo`A=1eilgyf7+meTp3VZ?eXAArd^4y zpx~^nt>0sRN#!q3&|UM`M@_`@98BN$^l5~0x?EdM9MB&}1eS82w_Rh{@=^PT`G?cF z8&b+hzJgCc9(ruxth1rdYgW@t$5A4A{PgT>z Nl&N{)b{P)I&9?{*p;|nOz>r?Lon4UQH zy<$SZ$(%?NR>zf?fIdzfN^lPFpFc#J?hpPcjit>3S9c-*`wcH6G6J>zYd7H3tq2Es z_0|me>+=e}?udJI%euy>>+MeZ2L6O1;p3kFqMWEl_=*FrOv&rLh`yK4_j}%Vd2A)J2hSBI*9OuxOd< zb6zM-l+n1eYILvy1jsC=OCLCV{k!(P!s{3ccs(bPYcZb}AcA=Pha52CHi`HSyxQ7I zQ6%lRy&mrN6UVoegl$fsZGfnHE6E$xk JTY zdQ
iqQ#8w>nlhPIBP<6KjBe*tn1wzj6NgTcU R%wzI~ZRh{`C{AFUo1Q_cjWBY7+wI zR5DAlH-g*T3{*Fa6__{kla;ahObSiLIRF0}Y)fvYcD?2@2adBP^Rgso%o5*V@lZFy zqqjHL)D-siF7qB3z!pWZ??h>3q`6hp?Estr$H# jM4PyP5kGt)|d63 z^hsTq<6pDcHoWQzHF-H1leA?s`p)t9#2n^pK*qxTs_;iL-)T1eFCMcaw@o+?r!5Tm ziHQpvTU^^AUNZ`6?(*6e#Rh0oSl`~;J!^vthK{pRf($_rIdv(`5FAZ9Zd&2|S<&QC zC@_V^#{1Ny(EDf>psH>bFZ`6(%Rm{ bqr4Ej0zaVY4qjY>;J zEP5m5{&(Y#4uWoEivNi0m^~nzBa@bi_BbUb!nK7{ZDsRMgP|jY7eRz{A`p>dc>}t? zy!S#u6jph*^a>nW`1A8bIrn=eyY=s{UyZ5YyR~SHjEo^;T(bQwV~lWL7e?J*erG!K zS)0o}0iVL>1oUyzWJ>qgtd;a|Y7Y5LJ4@zX+bkksl9C;~9gWFpcX0i8T#%v_O3**7 zlTz^Pr57NgjnobDBr*NmT3F*2MQjMBsTSeV?d#EmS`+2eZ3>d-btJ}3H&gODorttL z^~Mn@PBf=q2uBv{%J?Y1m`n73F&+<|7IV|Xyp~R6>DDV0&(3b-IETgx?Z}I^P|EVz z00;LmP*dqUAFH-Hl?v12m4-KWZxJpj!0Chh;Od*I>mRBrrq?x{F1%yvq{$63PJ{K` z!6>J9+@ATNSNr)PGFvDF{+bF=*Hn3Dcu-1)2Q|v`V46ZJgqC0PP;0^(SxpcL&e)eL z?V}oepmHEn!t{~uFCF ;z<17|5Y(LYSo;%qBBGEaw&Ms8utH0DntIs zas}>gK}VoqVqm%C?|o@VQmGhV`nk8fuC4>!q;tD}C+jyKNf0eAicJ-^pq5gWJ{>i% zFF=t;ti;kyk(CTtHd;u%C2LyBuXiK r0(&Vw6F?B)BX28$@TTZh51A4IyTP*1TGV?fTma< zVXjG>m3v{CPC5L;0!or~sTW3ceR>@tT2+-ZIgzFUaVkpIKwdI-LQ=}?pfrejw6$^& z{;p`L^su(~<;FgnXpU~eI2Eb-6l%zc;jRN^RUM^C0O 3O$tqu&)hl^j|C#n}W2A zih)B*l+v$RU?#^!O#r|UaLuL*Ap;JhJheacZZK=lmar+W#@{iMQOt_zYtmE<)0m1R z`o-Jvx&Vmrcv$drv)Dx`^ZC8ef5c%`6s*64#67nxZ)(oR_g)FYa*J}1(RFa?rRcf3 zUpF2sjhsf>!KqhPS3Ry*%z*BcR=W)mAT7~g&t%RS9m(%N_&Eup5q#+&8X)e3>J}rX zSr~nwt>}8}hoLj6a9we9ThU$3TCdQ+MB5))($*`1BIQ-c#^o9Z#Za(dKRQT*14-$O zf6xov&+!8eAEU|+)atQ1yM2Y0by>zXmH}KOyLV`^h#(dBG|4Lkv@Dp3U4G5*kB^U! z yZwNJY+Y!L3mrMK io9+n7_?O+O*G1!-792TpRk7gwE!(>f+gssb>C zx5ZCLskz(g3+jn_7tr+oWe)0`g`(o)vd?+0m^YL36BA%!9Gx5it9m)*p#><1hbP1* z|LpM6)<$p+>hhu@by1V~f3-QAo79n}R48C<_I|*5)&kyUpzGEbm4uqQyrP2VUT_TJ z0OSI6qtAY-OvlZnrSZb33^TzJ@o7yj1`*7J_L&ZGLaNl# )#(QE`i5PiV+3{tv-78P+FsCR{T|G3qE5jEqqw1 zWl*#&iT|y14`b#0Ai!}@CRYIz_6rUZJ$d9cN3mI8GL7!fJ|nwvD;Y-VN&~Nce$%}y zM1(6iM+%*6UjeIKFVvhW6DIRqm)Nc9X6yfwCg15w{F-Esl^G7=xm*UK3Qjaj@9-mf z%=^VRq6fXBMTOWqvjZii%uHzE$wwhrCmlFICj?>7T=KM}8yJ~v5;+ox*zp&8@b;vn zo#5=0(^x+sp_VnxaJ=fTZ`>BuqkclIY&5&UlozB1VJggZx2u!1k@OYRaQv=kp=RdZ z#?1qUT^iTambR2OG*p(gw$Q%yBb9Q-{6Hl;Ew0>Jk+N3u9On6ztPqi<24%$lG9&Ph zsV8E&LZrlFfU?OnYmecQB?wS$7^Sw;gfa;;2<42oSsjGJTO1v{dwx5rGqOKeY!HY$ zjDy_j4U-e)_>TS^jcs%X>e6({d(93HFr0+ZkfTDeg_IjkESciMrvUlQ zzULr(5KCrj925sOXvT$g%SGj8pho7wiYiB!7DU8+Tmx_bYUaSTpb!|$wS^YA8WupD z$S7GVp@~G_Srs9qjsWsx4SGc9Hxo(}A2PhAM9B*I^8nSHgZ<%s2n~!0*eat#`vtEA zs-+pMos>{Ot41P2hbVlOu{Kial`P_9(6BB8^e1}B6?;i)Q*g1U{Mv;zo%#e$I3H}? z p5+7 eQ{NG*o?==UWrC`H;~=JL+reUqb}5@0-j!<;p1x z9Oav%RoZaj+}sFRfuAy}f`t)ENJ7-MY>OWd!Q);!PO}V6(sPJ$?O&rp$nu3rcQ~RW zl9%j*XnqV67+zdhSL(Kn`|@RFAoMO@s*(0%c!z3Z&QzH?8Jpl%ddF824nqX)juiuW zlq{@W(ZPb$QJtktdm6nhN}rt$Kq+CFCLUDUnCEih5cii4rKp3bD(qRN^(R; o9tT^! z#_Z#9_*zx8pbQ0;RVQl=bLWVxK?RNbie{^1!;-SQH|w)Q(bCPL7@mNcNLB6`)q@}q z5Yiun_wRMZ{_r`Fk9zZB{K8_n&ohNM<0s-%EC)^u%b;+~lTA+80y`e|d)dr0uKDL# zh3@?#(qU;~dR?%BpGBOaAD7YSArW@9`KE^w0E$b%vH~6374VA`SsGxR#n+gTm&K=s zp{k;?u(GnTv{qnkGhYsQ6vb8Cl3x@ZFOUt~h>T~!+V~uNp7=d -v +NrU=naZW^X=AU;aGof6lk}q(9FcMmAm5Voa|KQi3Bc}Pph(#`GBK? z<{&U^)6+UHC;>WA`M!gv=KdoI=ZK_ nIm%WAv*dc^@=6Vv@JlXG*{{~R{-^mF9p=y@FMZBctw z%Ecf?8!KqGEsfSUQ&8l?bnWdf78vP})#o7y5m!n;H*eE98yFA;KhxLeJhAwrWl7j5 zyMSxR9|$x;tA}(&&NoEHMNa^76z)h~RkS|YlXbb$f6d2Qn3dKlf}4Z}wEHMjlmAi| z2c8(j)l2c6rXOt#OMZBUynHkdd7fA3vY9XIbG2io0(kK0r(=2D7|4#-$Li_2U^R*{ z9(VoMHR;fytPy y_Hd{)MBa!6`TeG3f= zCARha23%UrT-HnB@)Z)15>netI51X?4I&;Zhhi-Y5R^v(433K0`c|uQ`3^_6IT{0| ze;i6 Ye~mVLxiL&zGIqD9TMa!n{LXG!Sn z9NT~G8 b0mCrP36V~Tt$qVhqs?4} zbcd( o)(RJMooH+Op>4(4wl53hHzFKG2N2`UXw^YvBD flnllJrv!@LxcPUto zgXC`pOXCrtOSp7VE-V@|tb&&6+d?ig=T*o>f>_?HqJDuA)q6C!e??a1DDcW@l|Lkt z1n*@SQ&@(jPL29sbAWfHnSA(PfsB3%_>*6utM2p-Ya@sjXO#sRy1M!}73O;C&)-vn z(S~VsJQRQ{sCJXMI*w@wU5xn0=A$iourwxXk{)Mg`L`wjY@JzjO`5m*0>PSc 4sEYj$PoZxH68amI^k->c?Ptg!lR>X_-8)?10#l}Yh;yJv4HCjgtXFh^p|AN z(zvc_a@zs+dbNUVWrP|ZWPvATeSLXb+n-)u&nM}ltt;s~20r(RN23cw3}f? yvRL}fG0;UCO@0V_rhB7zE3 zg3bK!8ognI?1h7k?hS?49z ~F!1|rK*0LBPw^`WAAhUa5d zbN5gC<@mC)@W?N-`>XKg!P>TjkR`gNwDn9J&50~yQwHk9Kr9+HvWqO9`dAYiI`oYt zogs1?LcV`Tq)lbv*^$3!8Gh3J_`SbT>xPw1B>BYTGZ@##yw-))(z_0$LV$RHwJ~O$ z=XjhZPIQpx2 ym}yu@N 42<2xv3sEV zjUjyu4S(8%s->RlbV1l*|55p|YF_9_v$whp l`(l{Yo6JHqVNC0dk955w$EGQ7DEbYSK=<7N;DVBg2d m6c!R=+hNkF$8ZESUke$`smw%n2-4u%_;9U-*(sn^t$#L4 z3kbrK{ht=VONe6LJlR>4y~@!zlsG{U{j_|YeS(Q`I|uZ4h(6uaPAkS~eU2ULqL)ls zKxyeFIK1ckcsq#pzIRwWv`Q-X4Z}nKaMIG9b+{Q>DLWaN?a^xj @j!~UyIQi2*5bFr;!mt`3b(J*4C2~pl>{UWd)097Okl+5y-?M4zcB FJrS zDtC 0>E>_NuU*U@Tx>#?Q?Vn*0An;^6Vi-v$Lq??=R!W<8E_|UPiE>D)X*M`mH1QcO6C8%-bm=wvhNct zPCqkueSfa_LcRtH!Y)=r+08gljKIHt>~TjbF8jni(nu?L@D|h}-e+NYOf+ME+e;+_ z@JJWW!gYQ{VA@Ae5MIU{E%w~GcfheLrn1J7b}Eqi<&gsk>0^_%O!+CtT1DaPO$&oe z=4#=_Keu~-+1K#WLGTe)1G8y-?MWLKBh!c3(YO5?TyHcnJhQZJ`1bj$HL_6u_Fxh7 zKR!tKm$>|>v6X)#V%uTFaHp}Ysamn6E^Q~JCK5a z6i|4+@9b#cnN|us21 6FbK@bpTN!Xiu~~rg* W(;%f@Xho*Us8boBg(nG3E44+3lODg%bo;J5n8L77GO zp-#4*ACr1YR~KG0-fZ>OmbyG19Z)%KsWC+8Y_tMgpDAxRnj3Mnd>sL)VHlkQMO8)i zXIfs)SA!NymU_7S^)@~}yzTk0oOU=GusGl!G+9&!exVk@9ef%@9KpjF(CEGym{yg`rsAHjl6cm48ii>JjQHbNR~m6EM)eLL$8rrM&|6`^42+Y ze|0(=9ej=p+YJBuuWoF8ockr<{SZ-d*a1Dw=e-P~2Ce}(zV%LEY7w@f@ZMlkD}xT( z?U^`!wJrB_-e3Psukiw=At>g6YeGXJrzI1?vG}7U?y1bf-ew&gL!rl1vy9%475{RA z&6N$k9&34j**i;O--89Z%XPE =MfuVXvV@iUAJKe+9wWQ~=94mT3J$<)R^ z6y3cST%ArB4xPj$7X|{DN%Q$yR^KafB0*8-*t`i0Q%7j&k6d_69W!Gq4j0u*1>eRS z_aW=bUn7CMrhsl1gkOy_kk+1MJgt0}a#kg))N^D}5Oe25f|qcORBLG^=n2^&s)A?r zoXC;(R_yhz>>OvvnT(=Tv4KNH+M6k>pJ?MVIHNr#uFjno% ScrZ4Ws{l`XW_242g{}g~We0 zN;y^$K%5!1RZC>6*9(JEEUTvK!n{Zy-BTn!i2$xXk-bDp)t^Jj!VyfiJ+TfK!T@xC z{|v{nXfV}JqAgJ!?rE2ZV_iX~f$rosq|Ce}jinA`l_;@ 8_xq~+Q|kw6d= zFoqWzD_#w{m@3VQwI5E8d%Jf0$0P^TK>s1`YM>49&FJYPxy}pH?6Y01-u-}W2#*f( z^NO`ztm#OOy)2)_^O`UDNG8ipVZS(#&9RvM`5T%4P=YA^AWhnkr}8<-EWPiG$=Vj* zZC_UslTfSs%RyB4f#_7~v{usPbO?1<8mQ2kmz~;ihicT VrX%jlBe>ZK_oW zSg@wYD6FS6d~!w5_y9=GV^DKB-2vbpbk?gj%63vT76}39r}piKa#b3X5l+^`Fg9Tb zev L!y|N#af_G(`G^36)2O&$blkA6y5>1*rkBEXB&F(Dg)n_tysn zLP>O)@E`#&0MFNBCw@MM_3ig)Rv~aXYasZM)&Pb7ww`f}C3P8$T`I87#>trO4CG^! zTROCPYC3qAdeplcpU_jr;oqVmRpWRzot5E=erjt6