Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion SITE-ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,10 @@ Replaces the default anchor element to enable MkDocs-style relative linking. Res

These override default Starlight components:

- **`Head.astro`**: Adds Mermaid diagram support by transforming code blocks with `language="mermaid"` into rendered diagrams.
- **`Head.astro`**: Adds Mermaid diagram support and loads `SiteScripts` (Shortbread + WebSDK).
- **`Header.astro`**: Custom header with navigation tabs and theme-aware logos (see [Header Navigation](#header-navigation) below).
- **`MarkdownContent.astro`**: Injects the custom frontmatter banners (experimental, community, languages) at the top of page content.
- **`PageFrame.astro`**: Extends Starlight's default `PageFrame` to add a full-width site footer containing the `Copyright` component. The footer spans the content area (respecting sidebar offset) with `--sl-color-bg-nav` background to match the header.
- **`Sidebar.astro`** and **`SidebarSublist.astro`**: Custom sidebar navigation that mimics MkDocs Material theme's `navigation.sections` behavior.

#### Sidebar Navigation Style
Expand Down Expand Up @@ -579,6 +580,7 @@ The landing page uses a custom layout that provides the Starlight header without
- Mocks `Astro.locals.starlightRoute` with minimal data needed for the Header component
- Mocks `Astro.locals.t` translation function (with `.all()` method for Search component)
- Loads Figtree font from Google Fonts for landing page typography
- Includes `SiteScripts` for Shortbread consent and WebSDK

**Usage:**
```astro
Expand All @@ -598,6 +600,7 @@ The main landing page includes:
- Hero section with frosted glass effect
- Feature cards that expand on hover to show descriptions
- Testimonials slider with fade transitions and auto-play
- Footer with `Copyright` component (left-aligned, `--sl-color-bg-nav` background)

**Assets:**
- `src/assets/curve-primary.svg` and `src/assets/curve-secondary.svg` - Animated strand patterns
Expand Down
1 change: 1 addition & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default defineConfig({
Header: './src/components/overrides/Header.astro',
MarkdownContent: './src/components/overrides/MarkdownContent.astro',
Sidebar: './src/components/overrides/Sidebar.astro',
PageFrame: './src/components/overrides/PageFrame.astro',
},
}),
astroBrokenLinksChecker({
Expand Down
34 changes: 34 additions & 0 deletions src/components/Copyright.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
/**
* AWS legal footer links and copyright notice.
* Used in PageFrame.astro (docs pages) and index.astro (landing page).
*/
---

<p class="copyright">
<a href="https://aws.amazon.com/privacy" target="_blank" rel="noopener noreferrer">Privacy</a>
|
<a href="https://aws.amazon.com/terms" target="_blank" rel="noopener noreferrer">Site Terms</a>
|
<a href="#" id="cookie-preferences">Cookie Preferences</a>
|
&copy; 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved.
</p>

<style>
.copyright {
font-size: var(--sl-text-sm);
color: var(--sl-color-gray-3);
margin: 0;
}

.copyright a {
color: var(--sl-color-gray-3);
text-decoration: none;
}

.copyright a:hover {
color: var(--sl-color-white);
text-decoration: underline;
}
</style>
84 changes: 84 additions & 0 deletions src/components/SiteScripts.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
/**
* AWS Shortbread cookie consent and Analytics WebSDK initialization.
* Included in both Head.astro (docs pages) and LandingLayout.astro (index page).
*/
---

<link rel="stylesheet" href="https://prod.assets.shortbread.aws.dev/shortbread.css" />
<script is:inline src="https://prod.assets.shortbread.aws.dev/shortbread.js"></script>
<script is:inline>
/**
* Shortbread Cookie Consent and AWS Analytics WebSDK Initialization
* CRITICAL: Site must operate even if Shortbread is unavailable.
*/
;(function () {
'use strict'

const hostname = window.location.hostname
const isLocal = hostname === 'localhost' || hostname === '127.0.0.1'
const isCloudFrontPreview = hostname === 'd3ehv1nix5p99z.cloudfront.net'
const isProduction = hostname.endsWith('.strandsagents.com') || hostname === 'strandsagents.com'

const domain = isLocal || isCloudFrontPreview ? hostname : '.strandsagents.com'

let webSdkStage, webSdkDomain
if (isProduction) {
webSdkStage = 'prod'
webSdkDomain = 'https://d0.m.awsstatic.com'
} else if (isLocal) {
webSdkStage = 'alpha'
webSdkDomain = 'https://da0.m.awsstatic.com'
} else {
webSdkStage = 'gamma'
webSdkDomain = 'https://dg0.m.awsstatic.com'
}

if (typeof AWSCShortbread === 'undefined') {
console.warn('Shortbread unavailable. Using essential cookies only.')
return
}

try {
const existingShortbreadEl = document.getElementById('awsccc-sb-ux-c')
if (existingShortbreadEl) existingShortbreadEl.remove()

const shortbread = AWSCShortbread({
domain,
registry: {
GitHubRepoCache: { category: 'essential' },
},
language: AWSCShortbread.Locale?.getLocaleIdShortbread(
AWSCShortbread.Locale.getCurrentLocale()
),
})

shortbread.checkForCookieConsent()
window.strandsShortbread = shortbread

document.addEventListener('click', function (e) {
if (e.target.id === 'cookie-preferences') {
e.preventDefault()
shortbread.customizeCookies()
}
})

loadWebSDK(webSdkStage, webSdkDomain)
} catch (error) {
console.error('Shortbread error:', error)
}

function loadWebSDK(stage, sdkDomain) {
try {
const script = document.createElement('script')
script.type = 'module'
script.id = 'awsm-csa'
script.src = sdkDomain + '/awsm-acslibs/1.0.0/bundle/slim/wsdk.js'
script.setAttribute('data-awsm-csa-meta', JSON.stringify({ env: { stage } }))
document.head.appendChild(script)
} catch (error) {
console.error('WebSDK loading error:', error)
}
}
})()
</script>
7 changes: 6 additions & 1 deletion src/components/overrides/Head.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
/**
* Custom Head override to add Mermaid diagram support and favicon.
* Custom Head override to add Mermaid diagram support, favicon, and AWS Shortbread cookie consent.
* See ARCHITECTURE.md for details.
*/
import SiteScripts from '../SiteScripts.astro'

const { head } = Astro.locals.starlightRoute

// Get base path for favicon
Expand All @@ -15,6 +17,9 @@ const faviconHref = base.endsWith('/') ? `${base}favicon.svg` : `${base}/favicon
<!-- Favicon - uses logo-auto.svg which adapts to light/dark mode via prefers-color-scheme -->
<link rel="icon" type="image/svg+xml" href={faviconHref} />

<!-- AWS Shortbread cookie consent -->
<SiteScripts />

<script>
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'

Expand Down
113 changes: 113 additions & 0 deletions src/components/overrides/PageFrame.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
/**
* PageFrame override — adds a full-width site footer with copyright below the main content.
* All other markup and styles are identical to Starlight's default PageFrame.
*/
import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle'
import Copyright from '../Copyright.astro'

const { hasSidebar } = Astro.locals.starlightRoute
---

<div class="page sl-flex">
<header class="header"><slot name="header" /></header>
{hasSidebar && (
<nav class="sidebar print:hidden" aria-label={Astro.locals.t('sidebarNav.accessibleLabel')}>
<MobileMenuToggle />
<div id="starlight__sidebar" class="sidebar-pane">
<div class="sidebar-content sl-flex">
<slot name="sidebar" />
</div>
</div>
</nav>
)}
<div class="main-frame"><slot /></div>
<footer class="site-footer print:hidden">
<Copyright />
</footer>
</div>

<style>
@layer starlight.core {
.page {
flex-direction: column;
min-height: 100vh;
}

.header {
z-index: var(--sl-z-index-navbar);
position: fixed;
inset-inline-start: 0;
inset-block-start: 0;
width: 100%;
height: var(--sl-nav-height);
border-bottom: 1px solid var(--sl-color-hairline-shade);
padding: var(--sl-nav-pad-y) var(--sl-nav-pad-x);
padding-inline-end: var(--sl-nav-pad-x);
background-color: var(--sl-color-bg-nav);
}

:global([data-has-sidebar]) .header {
padding-inline-end: calc(
var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size)
);
}

.sidebar-pane {
visibility: var(--sl-sidebar-visibility, hidden);
position: fixed;
z-index: var(--sl-z-index-menu);
inset-block: var(--sl-nav-height) 0;
inset-inline-start: 0;
width: 100%;
background-color: var(--sl-color-black);
overflow-y: auto;
}

:global([aria-expanded='true']) ~ .sidebar-pane {
--sl-sidebar-visibility: visible;
}

.sidebar-content {
height: 100%;
min-height: max-content;
padding: 1rem var(--sl-sidebar-pad-x) 0;
flex-direction: column;
gap: 1rem;
}

@media (min-width: 50rem) {
.sidebar-content::after {
content: '';
padding-bottom: 1px;
}
}

.main-frame {
padding-top: calc(var(--sl-nav-height) + var(--sl-mobile-toc-height));
padding-inline-start: var(--sl-content-inline-start);
flex: 1;
}

@media (min-width: 50rem) {
:global([data-has-sidebar]) .header {
padding-inline-end: var(--sl-nav-pad-x);
}
.sidebar-pane {
--sl-sidebar-visibility: visible;
width: var(--sl-sidebar-width);
background-color: var(--sl-color-bg-sidebar);
border-inline-end: 1px solid var(--sl-color-hairline-shade);
}
}

.site-footer {
padding-block: 1.25rem;
padding-inline-end: var(--sl-nav-pad-x);
border-top: 1px solid var(--sl-color-hairline-shade);
background-color: var(--sl-color-bg-nav);
text-align: left;
padding-inline-start: calc(var(--sl-content-inline-start, 0em) + var(--sl-nav-pad-x));
}
}
</style>
6 changes: 5 additions & 1 deletion src/layouts/LandingLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import config from 'virtual:starlight/user-config'
import ThemeProvider from 'virtual:starlight/components/ThemeProvider'

import Header from '../components/overrides/Header.astro'
import SiteScripts from '../components/SiteScripts.astro'
import { pathWithBase } from '../util/links'

interface Props {
Expand Down Expand Up @@ -119,7 +120,10 @@ Astro.locals.t = mockT
<meta property="og:title" content={title} />
{description && <meta property="og:description" content={description} />}
<meta property="og:type" content="website" />


<!-- AWS Shortbread cookie consent -->
<SiteScripts />

<ThemeProvider />

<style is:global>
Expand Down
19 changes: 19 additions & 0 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { getCollection, render } from 'astro:content'
import { Image } from 'astro:assets'
import LandingLayout from '../layouts/LandingLayout.astro'
import Copyright from '../components/Copyright.astro'
import curvePrimary from '../assets/curve-primary.svg'
import curveSecondary from '../assets/curve-secondary.svg'
import iconZap from '../assets/icons/icon-zap.svg?raw'
Expand Down Expand Up @@ -130,6 +131,12 @@ const testimonials = await Promise.all(
</div>
</section>
</div>

<footer class="landing-footer">
<div class="landing-footer-inner">
<Copyright />
</div>
</footer>
</LandingLayout>

<style>
Expand Down Expand Up @@ -535,6 +542,18 @@ const testimonials = await Promise.all(
.hero-section { min-height: 50vh; padding: 1.5rem; }
.features-section, .testimonials-section, .cta-section { padding: 2rem 1.5rem; }
}

.landing-footer {
padding: 1.5rem 2rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
background-color: var(--sl-color-bg-nav);
}

.landing-footer-inner {
max-width: 1200px;
text-align: left;
margin: 0 auto;
}
</style>

<script>
Expand Down