Skip to content
Open
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
198 changes: 198 additions & 0 deletions src/components/landing/CodeBlock.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
---
/**
* Theme-aware syntax-highlighted code block for the landing page.
* Renders both light and dark variants at build time, toggles via CSS on [data-theme].
* Includes a copy-to-clipboard button.
*/
import { Code } from 'astro:components'

interface Props {
code: string
lang?: string
filename?: string
}

const { code, lang = 'python', filename } = Astro.props
---

<div class="code-block" data-code={code}>
{filename && (
<div class="code-header">
<span class="code-filename">{filename}</span>
<button class="copy-button" aria-label="Copy code">
<svg class="copy-icon" width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" stroke-width="1.3"/>
<path d="M3 10.5V3a1.5 1.5 0 0 1 1.5-1.5H11" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
</svg>
<svg class="check-icon" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M3.5 8.5L6.5 11.5L12.5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
)}
{!filename && (
<button class="copy-button copy-button-floating" aria-label="Copy code">
<svg class="copy-icon" width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" stroke-width="1.3"/>
<path d="M3 10.5V3a1.5 1.5 0 0 1 1.5-1.5H11" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
</svg>
<svg class="check-icon" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M3.5 8.5L6.5 11.5L12.5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
)}
<div class="code-theme-light">
<Code code={code} lang={lang} theme="github-light" />
</div>
<div class="code-theme-dark">
<Code code={code} lang={lang} theme="github-dark" />
</div>
</div>

<style>
.code-block {
position: relative;
border-radius: 12px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(0, 0, 0, 0.6);
font-size: 0.875rem;
line-height: 1.6;
}

:global([data-theme='light']) .code-block {
background: rgba(0, 0, 0, 0.03);
border-color: rgba(0, 0, 0, 0.1);
}

.code-header {
padding: 0.5rem 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
}

:global([data-theme='light']) .code-header {
border-bottom-color: rgba(0, 0, 0, 0.06);
}

.code-filename {
font-family: 'Figtree', sans-serif;
font-size: 0.8rem;
color: var(--sl-color-gray-3);
display: flex;
align-items: center;
gap: 0.5rem;
}

.code-filename::before {
content: '';
display: inline-flex;
width: 44px;
height: 12px;
background:
radial-gradient(circle 5px at 6px 6px, #ff5f57 5px, transparent 5px),
radial-gradient(circle 5px at 22px 6px, #febc2e 5px, transparent 5px),
radial-gradient(circle 5px at 38px 6px, #28c840 5px, transparent 5px);
opacity: 0.7;
flex-shrink: 0;
}

:global([data-theme='light']) .code-filename {
color: var(--sl-color-gray-2);
}

/* Copy button */
.copy-button {
background: none;
border: none;
color: var(--sl-color-gray-4);
cursor: pointer;
padding: 4px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.2s ease, background 0.2s ease;
margin-left: auto;
}

.copy-button:hover {
color: var(--sl-color-white);
background: rgba(255, 255, 255, 0.08);
}

:global([data-theme='light']) .copy-button:hover {
background: rgba(0, 0, 0, 0.06);
color: var(--sl-color-gray-1);
}

.copy-button-floating {
position: absolute;
top: 8px;
right: 8px;
z-index: 1;
}

.copy-button .check-icon { display: none; }
.copy-button.copied .copy-icon { display: none; }
.copy-button.copied .check-icon { display: block; }
.copy-button.copied { color: var(--strands-green, #00cc5f); }

/* Theme switching */
.code-theme-light { display: none; }
.code-theme-dark { display: block; }

:global([data-theme='light']) .code-theme-light { display: block; }
:global([data-theme='light']) .code-theme-dark { display: none; }

/* Override Astro Code component styles */
.code-block :global(pre) {
margin: 0;
padding: 1rem 1.25rem;
background: transparent !important;
border: none;
border-radius: 0;
overflow-x: auto;
}

.code-block :global(code) {
font-size: inherit;
line-height: inherit;
}

@media (max-width: 480px) {
.code-block {
font-size: 0.8rem;
border-radius: 8px;
}

.code-block :global(pre) {
padding: 0.75rem 0.875rem;
-webkit-overflow-scrolling: touch;
}

.code-header {
padding: 0.375rem 0.75rem;
min-height: 28px;
}
}
</style>

<script>
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll<HTMLElement>('.code-block').forEach((block) => {
const btn = block.querySelector<HTMLButtonElement>('.copy-button')
const code = block.dataset.code
if (!btn || !code) return

btn.addEventListener('click', async () => {
await navigator.clipboard.writeText(code)
btn.classList.add('copied')
setTimeout(() => btn.classList.remove('copied'), 2000)
})
})
})
</script>
181 changes: 181 additions & 0 deletions src/components/landing/CredibilityStrip.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
/**
* Credibility strip: company logos + deployment targets.
* Sits between feature cards and testimonials as a trust bridge.
*/

// Import logos directly — Astro handles SVG/PNG optimization
import smartsheetLogo from '../../content/testimonials/smartsheet-logo.svg'
import smartsheetLogoDark from '../../content/testimonials/smartsheet-logo-white.svg'
import swisscomLogo from '../../content/testimonials/swisscom-logo.svg'
import eightcapLogo from '../../content/testimonials/eightcap-logo.svg'
import zafranLogo from '../../content/testimonials/zafran-logo.svg'
import jitLogo from '../../content/testimonials/jit_logo.svg'
import tavilyLogo from '../../content/testimonials/tavily-logo.svg'

const logos = [
{ name: 'Smartsheet', light: smartsheetLogo, dark: smartsheetLogoDark },
{ name: 'Swisscom', light: swisscomLogo, dark: swisscomLogo },
{ name: 'Eightcap', light: eightcapLogo, dark: eightcapLogo },
{ name: 'Zafran', light: zafranLogo, dark: zafranLogo },
{ name: 'Jit', light: jitLogo, dark: jitLogo },
{ name: 'Tavily', light: tavilyLogo, dark: tavilyLogo },
]

const deployTargets = ['AgentCore', 'Lambda', 'Fargate', 'EKS', 'Docker', 'Terraform']
---

<section class="credibility-strip">
<div class="credibility-inner">
<div class="credibility-row">
<span class="credibility-label">Trusted in production by</span>
<div class="logo-strip">
{logos.map((logo) => (
<img
class="company-logo logo-light"
src={logo.light.src}
alt={logo.name}
loading="lazy"
/>
<img
class="company-logo logo-dark"
src={logo.dark.src}
alt={logo.name}
loading="lazy"
/>
))}
</div>
</div>
<div class="credibility-row">
<span class="credibility-label">Deploy anywhere</span>
<div class="deploy-targets">
{deployTargets.map((target, i) => (
<>
{i > 0 && <span class="deploy-sep" aria-hidden="true">&middot;</span>}
<span class="deploy-target">{target}</span>
</>
))}
</div>
</div>
</div>
</section>

<style>
.credibility-strip {
padding: 2rem 2rem 1rem;
display: flex;
justify-content: center;
}

.credibility-inner {
max-width: 1200px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 1.5rem;
}

.credibility-row {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
}

.credibility-label {
font-family: 'Figtree', sans-serif;
font-size: 0.75rem;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--sl-color-gray-4);
}

.logo-strip {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 2rem;
}

.company-logo {
height: 26px;
width: auto;
opacity: 0.55;
filter: grayscale(100%);
transition: opacity 0.3s ease, filter 0.3s ease;
}

.company-logo:hover {
opacity: 0.9;
filter: grayscale(0%);
}

/* Theme switching for logos */
.logo-dark { display: none; }
.logo-light { display: inline; }

:global([data-theme='dark']) .logo-dark { display: inline; }
:global([data-theme='dark']) .logo-light { display: none; }

:global([data-theme='dark']) .company-logo {
filter: grayscale(100%) brightness(1.5);
}

:global([data-theme='dark']) .company-logo:hover {
filter: grayscale(0%) brightness(1);
}

:global([data-theme='light']) .company-logo {
filter: grayscale(100%);
}

.deploy-targets {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 0.5rem;
}

.deploy-target {
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', monospace;
font-size: 0.8rem;
color: var(--sl-color-gray-3);
}

.deploy-sep {
color: var(--sl-color-gray-5);
font-size: 0.8rem;
}

@media (max-width: 900px) {
.credibility-strip {
padding: 1.5rem 1.5rem 1rem;
}

.logo-strip {
gap: 1.5rem;
}

.company-logo {
height: 16px;
}
}

@media (max-width: 430px) {
.credibility-strip {
padding: 1.5rem 1rem 1rem;
}

.logo-strip {
gap: 1rem;
}

.company-logo {
height: 14px;
}
}
</style>
Loading
Loading