diff --git a/docs/VISUAL_CONTRACT.md b/docs/VISUAL_CONTRACT.md
index ec02736..a5751d4 100644
--- a/docs/VISUAL_CONTRACT.md
+++ b/docs/VISUAL_CONTRACT.md
@@ -63,3 +63,11 @@ Structural tests support release review, while visual quality remains a separate
- Independent-policy disclosure remains adjacent to the policy reference
- No ordinary executable JavaScript, remote runtime dependencies, or protected company information
- Responsive single-column mobile transformation and direct-preview behavior
+
+## Protected Partner journey
+
+- **Partner** is the global public pathway for aligned organizations and remains present exactly once in every primary navigation.
+- The homepage **Strategic Partners** orbital node and Convergence card both route to Partner.
+- Partner and Golden Age cross-link contextually while Golden Age remains outside primary navigation.
+- Partner is marked as the current page only on `/partner/`.
+- Sticky-anchor destinations remain fully visible below the navigation at desktop and mobile widths.
diff --git a/partner/index.html b/partner/index.html
index ade4773..baeb2f7 100644
--- a/partner/index.html
+++ b/partner/index.html
@@ -28,6 +28,7 @@
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
+section[id]{scroll-margin-top:110px}
body{
margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--text);
background:radial-gradient(circle at 14% 7%,rgba(120,215,255,.15),transparent 28rem),radial-gradient(circle at 86% 13%,rgba(198,167,255,.14),transparent 30rem),radial-gradient(circle at 50% 52%,rgba(241,200,107,.08),transparent 36rem),linear-gradient(180deg,var(--bg),#071425 48%,#04070f);overflow-x:hidden
@@ -104,7 +105,7 @@
.footer a{color:#fff;display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:6px 4px}
.footer p{line-height:1.7;margin:8px 0}
@media(max-width:920px){.grid-4{grid-template-columns:repeat(2,1fr)}.pathway{grid-template-columns:repeat(3,1fr)}.pathway>div:first-child{grid-column:1/-1;min-height:auto;border-bottom:1px solid var(--line)}.pathway>div:nth-child(2){border-left:0}}
-@media(max-width:700px){.nav-inner{padding:12px 16px;flex-direction:column;justify-content:center}.brand{font-size:11.5px;gap:9px}.mark{width:34px;height:34px}.nav-links{width:100%;justify-content:center;gap:6px}.nav-links a{font-size:12px;padding:8px 9px}.shell{padding:0 16px}.hero{padding:54px 0 44px}.actions{display:grid}.btn{width:100%}.pathway,.grid-3,.grid-4,.platform{grid-template-columns:1fr}.pathway>div:first-child{grid-column:auto}.pathway>div+div,.pathway>div:nth-child(2),.platform article+article{border-left:0;border-top:1px solid var(--line)}section{padding:56px 0}.card,.platform article{min-height:auto}.inquiry-box{padding:28px 20px}}
+@media(max-width:700px){section[id]{scroll-margin-top:150px}.nav-inner{padding:12px 16px;flex-direction:column;justify-content:center}.brand{font-size:11.5px;gap:9px}.mark{width:34px;height:34px}.nav-links{width:100%;justify-content:center;gap:6px}.nav-links a{font-size:12px;padding:8px 9px}.shell{padding:0 16px}.hero{padding:54px 0 44px}.actions{display:grid}.btn{width:100%}.pathway,.grid-3,.grid-4,.platform{grid-template-columns:1fr}.pathway>div:first-child{grid-column:auto}.pathway>div+div,.pathway>div:nth-child(2),.platform article+article{border-left:0;border-top:1px solid var(--line)}section{padding:56px 0}.card,.platform article{min-height:auto}.inquiry-box{padding:28px 20px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}.btn{transition:none}.btn:hover{transform:none}}
diff --git a/scripts/validate_site.py b/scripts/validate_site.py
index 9e5e5cf..0417c3f 100644
--- a/scripts/validate_site.py
+++ b/scripts/validate_site.py
@@ -165,6 +165,20 @@
"404.html": "privacy/index.html#security",
}
+EXPECTED_PARTNER_NAV = {
+ "index.html": "partner/index.html",
+ "materials/index.html": "../partner/index.html",
+ "readiness/index.html": "../partner/index.html",
+ "partner/index.html": "../partner/index.html",
+ "golden-age/index.html": "../partner/index.html",
+ "privacy/index.html": "../partner/index.html",
+ "404.html": "partner/index.html",
+}
+HOME_PARTNER_NODE = ''
+HOME_PARTNER_CARD = ''
+PARTNER_GOLDEN_AGE_LINK = 'Explore A New Golden Age'
+GOLDEN_AGE_PARTNER_LINK = 'Partner with Bridge Node 7'
+
class PageParser(HTMLParser):
def __init__(self) -> None:
super().__init__(convert_charrefs=True)
@@ -208,6 +222,22 @@ def handle_endtag(self, tag: str) -> None:
self._script_text = []
+
+def primary_nav_links(text: str) -> list[tuple[str, str, bool]] | None:
+ match = re.search(r'', text, re.I | re.S)
+ if not match:
+ return None
+ links: list[tuple[str, str, bool]] = []
+ for attrs, body in re.findall(r']*)>(.*?)', match.group(1), re.I | re.S):
+ href_match = re.search(r'\bhref=(["\'])(.*?)\1', attrs, re.I | re.S)
+ href = href_match.group(2) if href_match else ""
+ current = bool(re.search(r'\baria-current=(["\'])page\1', attrs, re.I | re.S))
+ label = re.sub(r'<[^>]+>', '', body)
+ label = re.sub(r'\s+', ' ', label).strip()
+ links.append((label, href, current))
+ return links
+
+
def fail(errors: list[str], msg: str) -> None:
errors.append(msg)
@@ -331,6 +361,22 @@ def main() -> int:
if ' int:
fail(errors, f"index.html: expected 22 radial path lines, found {radial_path_count}")
if domain_node_count != 7:
fail(errors, f"index.html: expected 7 domain nodes, found {domain_node_count}")
+
+ if home.count(HOME_PARTNER_NODE) != 1:
+ fail(errors, f"index.html: expected exactly one Strategic Partners orbital link to Partner, found {home.count(HOME_PARTNER_NODE)}")
+ if home.count(HOME_PARTNER_CARD) != 1:
+ fail(errors, f"index.html: expected exactly one Strategic Partners card link to Partner, found {home.count(HOME_PARTNER_CARD)}")
+ partner_text = (ROOT / "partner/index.html").read_text(encoding="utf-8")
+ if partner_text.count(PARTNER_GOLDEN_AGE_LINK) != 1:
+ fail(errors, "partner/index.html: exact Golden Age pathway missing")
+ golden_age_text = (ROOT / "golden-age/index.html").read_text(encoding="utf-8")
+ if golden_age_text.count(GOLDEN_AGE_PARTNER_LINK) != 1:
+ fail(errors, "golden-age/index.html: exact Partner pathway missing")
if MAIL_SUBJECT not in home:
fail(errors, "index.html: full strategic inquiry interaction missing")
if "Strategic Inquiry
" in home:
@@ -372,6 +429,8 @@ def main() -> int:
print(f"Required files: {len(REQUIRED)}")
print("Direct-preview paths: PASS")
print("Protected homepage interactions: PASS")
+ print("Protected Partner navigation: PASS")
+ print("Protected Partner and Golden Age journey: PASS")
print("Protected content-page experience: PASS")
print("Remote runtime dependencies: NONE")
print("Public material-specific routes: NONE")