diff --git a/public/images/book-cover-dark-provenance.svg b/public/images/book-cover-dark-provenance.svg new file mode 100644 index 0000000..91434e8 --- /dev/null +++ b/public/images/book-cover-dark-provenance.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + Dark + Provenance + + Formal Verification + for the AI Age + + + COMING SOON + diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 91a7c9b..a79b93e 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -66,18 +66,22 @@ const currentYear = new Date().getFullYear(); diff --git a/src/components/Form/SharedForm.astro b/src/components/Form/SharedForm.astro index 451703e..758a8cf 100644 --- a/src/components/Form/SharedForm.astro +++ b/src/components/Form/SharedForm.astro @@ -120,7 +120,7 @@ const topicParam = Astro.url.searchParams.get('topic'); diff --git a/src/components/SEO.astro b/src/components/SEO.astro index 0728b2c..19f3c3b 100644 --- a/src/components/SEO.astro +++ b/src/components/SEO.astro @@ -38,6 +38,7 @@ function getJsonLd(pageType: string): string { 'https://linkedin.com/in/scottscoble', 'https://x.com/scottscoble', 'https://github.com/wscoble', + 'https://www.amazon.com/stores/Scott-Scoble/author/B0GKSSBDMK', ], knowsAbout: ['AI leadership', 'human cultivation', 'engineering teams', 'formal specifications', 'provenance systems'], knowsLanguage: ['en'], @@ -78,7 +79,63 @@ function getJsonLd(pageType: string): string { description: 'Human Cultivation Expert for the AI Age', url: siteUrl, }; - return JSON.stringify([personLd, websiteLd], null, 2); + const speakableSchema = { + '@context': 'https://schema.org', + '@type': 'SpeakableSpecification', + cssSelector: ['h1', '.hero p', '.hero-description'], + }; + return JSON.stringify([personLd, websiteLd, speakableSchema], null, 2); + } + + case 'blog': { + const blogSchema = { + '@context': 'https://schema.org', + '@type': 'Blog', + '@id': `${siteUrl}#blog`, + name: 'Scott Scoble Blog', + description: 'Articles and essays by Scott Scoble on AI leadership, team cultivation, developer experience, and the human side of technology.', + url: `${siteUrl}/blog`, + author: { + '@type': 'Person', + name: 'Scott Scoble', + url: siteUrl, + }, + blogPost: [ + { + '@type': 'BlogPosting', + headline: 'Why Cultivation Over Strip Mining', + description: 'Gallup 2026: 80% of the global workforce is disengaged. The $438B cost is not a tool problem; it is a people problem.', + url: `${siteUrl}/blog/strip-mining-cultivation`, + datePublished: '2026-05-18', + author: { '@type': 'Person', name: 'Scott Scoble' }, + }, + { + '@type': 'BlogPosting', + headline: '50 First Dates with AI', + description: "Every conversation with most AI systems is a first date. Here's the three-layer memory model that actually compounds.", + url: `${siteUrl}/blog/50-first-dates-with-ai`, + datePublished: '2026-05-24', + author: { '@type': 'Person', name: 'Scott Scoble' }, + }, + { + '@type': 'BlogPosting', + headline: 'The Soil Under Your Team', + description: "Tall stalks, ground cover, nitrogen fixers, pollinators, deep roots. Here's how to read the soil under your team.", + url: `${siteUrl}/blog/soil-health-teams`, + datePublished: '2026-05-18', + author: { '@type': 'Person', name: 'Scott Scoble' }, + }, + { + '@type': 'BlogPosting', + headline: 'The Soil Beneath the Code is Out', + description: 'A three-layer framework for understanding what makes engineering organizations healthy — or not.', + url: `${siteUrl}/blog/the-soil-beneath-the-code`, + datePublished: '2026-04-28', + author: { '@type': 'Person', name: 'Scott Scoble' }, + }, + ], + }; + return JSON.stringify([personLd, blogSchema], null, 2); } case 'speaking': @@ -177,19 +234,6 @@ function getJsonLd(pageType: string): string { description: 'Three questions that change how people learn. The simplest mentoring framework you\'ll actually use.', sameAs: 'https://a.co/d/0bRKZeUV', }, - { - '@context': 'https://schema.org', - '@type': 'Book', - name: 'Dark Provenance', - author: { - '@type': 'Person', - name: 'Scott Scoble', - url: siteUrl, - }, - datePublished: '2026', - bookFormat: 'https://schema.org/EBook', - description: 'Formal verification for the AI age. How to audit what your AI actually did.', - }, ], null, 2); case 'consulting': diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 0c2d708..c283135 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -17,7 +17,7 @@ export interface Props { const { title, description, - ogImage = '/social-card.png', + ogImage = '/images/hero-speaker-new.webp', ogType = 'website', canonicalUrl, pageType = 'home', diff --git a/src/pages/about.astro b/src/pages/about.astro index 2c01c74..1252655 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -70,18 +70,13 @@ import BaseLayout from '../layouts/BaseLayout.astro';

Three questions that change how people learn.

-
-

Dark Provenance

-

Coming 2026

-

Formal verification for the AI age. How to audit what your AI actually did.

-
-

Open Source Projects

+

Projects

@@ -91,6 +86,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';

ScobleClaw

+

Private

Agentic engineering framework — tools, workflows, and skills for building with AI agents. Patterns for subagent dispatch, skill-based development, and provenance tracking.

@@ -296,4 +292,17 @@ import BaseLayout from '../layouts/BaseLayout.astro'; color: var(--color-text-muted); line-height: 1.6; } + + .project-visibility { + display: inline-block; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--color-amber); + background: var(--color-cream-warm); + padding: 0.15rem 0.6rem; + border-radius: 3px; + margin-bottom: 0.5rem; + } diff --git a/src/pages/blog.astro b/src/pages/blog.astro index 84b2896..f83111f 100644 --- a/src/pages/blog.astro +++ b/src/pages/blog.astro @@ -4,8 +4,9 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; ---
@@ -20,6 +21,67 @@ import NewsletterSignup from '../components/NewsletterSignup.astro';
+ + +
+ + + + + + + + + + + + +
- -
diff --git a/src/pages/consulting.astro b/src/pages/consulting.astro index 7242697..f2d3130 100644 --- a/src/pages/consulting.astro +++ b/src/pages/consulting.astro @@ -129,7 +129,7 @@ import PackageCard from '../components/PackageCard.astro'; } .section-container { - max-width: 1000px; + max-width: 1200px; margin: 0 auto; padding: 4rem 2rem; } diff --git a/src/pages/index.astro b/src/pages/index.astro index 031735f..f313b25 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -33,7 +33,7 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; Book Scott for Your Event @@ -109,6 +109,39 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; + + +
@@ -420,7 +453,68 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; .talk-link:hover { color: var(--color-brown-dark); } - + + /* ===== FEATURED BOOKS ===== */ + .featured-books { + padding: 6rem 2rem; + background: white; + } + + .books-list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 2rem; + max-width: 1100px; + margin: 0 auto; + } + + .featured-books .book-card { + display: flex; + gap: 1.5rem; + padding: 2rem; + border-radius: 12px; + border: 1px solid var(--color-border-light); + background: var(--color-cream); + transition: all 0.3s ease; + } + + .featured-books .book-card:hover { + border-color: var(--color-amber); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06); + } + + .book-cover img { + width: 120px; + height: auto; + border-radius: 4px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + flex-shrink: 0; + } + + .book-info h3 { + font-family: var(--font-heading); + font-size: 1.375rem; + color: var(--color-brown-dark); + margin: 0 0 0.5rem; + } + + .book-info .book-desc { + color: var(--color-text-muted); + margin: 0 0 1rem; + line-height: 1.6; + font-size: 0.95rem; + } + + .book-info .book-cta { + color: var(--color-amber); + font-weight: 600; + text-decoration: none; + } + + .book-info .book-cta:hover { + color: var(--color-brown-dark); + } + /* ===== CTA SECTION ===== */ .cta-section { position: relative; @@ -492,7 +586,24 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; min-height: auto; padding: 4rem 1.5rem; } - + + .featured-books .books-list { + grid-template-columns: 1fr; + } + + .featured-books .book-card { + flex-direction: column; + align-items: center; + text-align: center; + } + + .book-info .book-desc { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + } + .hero-overlay { background: radial-gradient( @@ -506,26 +617,26 @@ import NewsletterSignup from '../components/NewsletterSignup.astro'; rgba(20, 18, 15, 0.6) 100% ); } - + .hero h1 { font-size: clamp(2.25rem, 10vw, 3.5rem); line-height: 1.05; } - + .hero h1 .accent { font-size: 0.88em; } - + .section-header { margin-bottom: 2.5rem; } - + .pillars, .featured-talks, .cta-section { padding: 4rem 1.5rem; } - + .talk-card { padding: 1.5rem; } diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts index 9e54635..360973f 100644 --- a/src/pages/rss.xml.ts +++ b/src/pages/rss.xml.ts @@ -130,6 +130,48 @@ const posts: PostEntry[] = [ date: "2026-04-28", tags: ["Engineering"], }, + { + title: "What a Dark Factory Actually Is (and Isn't)", + description: "The phrase is everywhere. The working meaning is gone. Here is what it is, what it isn't, and the five positions on the spectrum.", + url: "/blog/what-is-a-dark-factory", + date: "2026-05-22", + tags: ["Engineering"], + }, + { + title: "Light vs Dark Factories: Why the Middle Is Harder Than Either End", + description: "A light factory has too many gates. A dark factory has too few. The middle is where the engineering happens, and the middle is the part nobody talks about.", + url: "/blog/light-vs-dark-factories", + date: "2026-06-02", + tags: ["Engineering"], + }, + { + title: "Why Kubernetes for a Dark Factory", + description: "A dark factory is a control loop. Kubernetes is the most boring control loop in production. That is the reason.", + url: "/blog/why-kubernetes-for-dark-factory", + date: "2026-06-11", + tags: ["Engineering"], + }, + { + title: "Kubernetes Operator Patterns for Software Factories", + description: "An operator is a control loop with a domain in it. That is the whole definition. Here are the four operator patterns and the one anti-pattern to avoid.", + url: "/blog/operator-patterns-for-software-factories", + date: "2026-06-19", + tags: ["Engineering"], + }, + { + title: "The Taste Problem: What Dark Factories Can't Transfer", + description: "A dark factory can transfer code. It cannot transfer the judgment that knew the code was right. That is the problem provenance was invented to solve.", + url: "/blog/the-taste-problem", + date: "2026-06-29", + tags: ["Engineering"], + }, + { + title: "The Human-in-the-Loop Seam: Where Humans Belong in a Dark Factory", + description: "Human-in-the-loop is a phrase everyone uses. Almost nobody uses it correctly. The seam is in the spec, not in the implementation.", + url: "/blog/human-in-the-loop-seam", + date: "2026-07-08", + tags: ["Engineering"], + }, ]; const siteUrl = 'https://scott.scoble.me'; diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts index 2270e63..fc5f2ff 100644 --- a/src/pages/sitemap.xml.ts +++ b/src/pages/sitemap.xml.ts @@ -3,44 +3,56 @@ import type { APIRoute } from 'astro'; const siteUrl = 'https://scott.scoble.me'; const pages = [ - { url: '/', lastmod: '2026-05-24', priority: '1.0' }, - { url: '/speaking', lastmod: '2026-05-24', priority: '0.9' }, - { url: '/consulting', lastmod: '2026-05-24', priority: '0.8' }, - { url: '/books', lastmod: '2026-05-24', priority: '0.8' }, - { url: '/contact', lastmod: '2026-05-24', priority: '0.7' }, - { url: '/privacy', lastmod: '2026-05-24', priority: '0.3' }, - { url: '/about', lastmod: '2026-05-24', priority: '0.7' }, - { url: '/blog', lastmod: '2026-05-24', priority: '0.9' }, + { url: '/', lastmod: '2026-06-01', priority: '1.0' }, + { url: '/speaking', lastmod: '2026-06-01', priority: '0.9' }, + { url: '/consulting', lastmod: '2026-06-01', priority: '0.8' }, + { url: '/books', lastmod: '2026-06-01', priority: '0.8' }, + { url: '/contact', lastmod: '2026-06-01', priority: '0.7' }, + { url: '/privacy', lastmod: '2026-06-01', priority: '0.3' }, + { url: '/about', lastmod: '2026-06-01', priority: '0.7' }, + { url: '/blog', lastmod: '2026-06-01', priority: '0.9' }, +]; + +const speakingPages = [ + { url: '/speaking/50-first-dates', lastmod: '2026-06-01' }, + { url: '/speaking/strip-mining-to-cultivation', lastmod: '2026-06-01' }, + { url: '/speaking/soil-under-your-team', lastmod: '2026-06-01' }, ]; // All blog post URLs const blogPosts = [ - { url: '/blog/50-first-dates-with-ai', lastmod: '2026-05-24' }, - { url: '/blog/strip-mining-cultivation', lastmod: '2026-05-18' }, - { url: '/blog/soil-health-teams', lastmod: '2026-05-18' }, - { url: '/blog/30-years-software', lastmod: '2026-05-18' }, - { url: '/blog/spec-first-audit-surface', lastmod: '2026-05-24' }, - { url: '/blog/open-source-projects', lastmod: '2026-05-23' }, - { url: '/blog/prove-sqlite', lastmod: '2026-05-23' }, - { url: '/blog/ai-has-amnesia', lastmod: '2026-05-18' }, - { url: '/blog/agentic-wars', lastmod: '2026-05-08' }, - { url: '/blog/ai-brain-fry', lastmod: '2026-05-03' }, - { url: '/blog/surveillance-extraction', lastmod: '2026-05-03' }, - { url: '/blog/gallup-disengagement', lastmod: '2026-05-03' }, - { url: '/blog/devex-shift', lastmod: '2026-05-03' }, - { url: '/blog/token-anxiety', lastmod: '2026-05-04' }, - { url: '/blog/three-questions-mentoring', lastmod: '2026-04-28' }, - { url: '/blog/strip-mining-signs', lastmod: '2026-04-28' }, - { url: '/blog/the-soil-beneath-the-code', lastmod: '2026-04-28' }, - { url: '/blog/strip-mining-happening-right-now', lastmod: '2026-05-07' }, - { url: '/blog/mentorship-isnt-latency-its-leverage', lastmod: '2026-05-07' }, - { url: '/blog/ai-exposes-leaders-cultivation-test', lastmod: '2026-05-07' }, + { url: '/blog/50-first-dates-with-ai', lastmod: '2026-05-30' }, + { url: '/blog/strip-mining-cultivation', lastmod: '2026-05-30' }, + { url: '/blog/soil-health-teams', lastmod: '2026-05-30' }, + { url: '/blog/30-years-software', lastmod: '2026-05-30' }, + { url: '/blog/spec-first-audit-surface', lastmod: '2026-05-30' }, + { url: '/blog/open-source-projects', lastmod: '2026-05-30' }, + { url: '/blog/prove-sqlite', lastmod: '2026-05-30' }, + { url: '/blog/ai-has-amnesia', lastmod: '2026-05-30' }, + { url: '/blog/agentic-wars', lastmod: '2026-05-30' }, + { url: '/blog/ai-brain-fry', lastmod: '2026-05-30' }, + { url: '/blog/surveillance-extraction', lastmod: '2026-05-30' }, + { url: '/blog/gallup-disengagement', lastmod: '2026-05-30' }, + { url: '/blog/devex-shift', lastmod: '2026-05-30' }, + { url: '/blog/token-anxiety', lastmod: '2026-05-30' }, + { url: '/blog/three-questions-mentoring', lastmod: '2026-05-30' }, + { url: '/blog/strip-mining-signs', lastmod: '2026-05-30' }, + { url: '/blog/the-soil-beneath-the-code', lastmod: '2026-05-30' }, + { url: '/blog/strip-mining-happening-right-now', lastmod: '2026-05-30' }, + { url: '/blog/mentorship-isnt-latency-its-leverage', lastmod: '2026-05-30' }, + { url: '/blog/ai-exposes-leaders-cultivation-test', lastmod: '2026-05-30' }, + { url: '/blog/what-is-a-dark-factory', lastmod: '2026-05-22' }, + { url: '/blog/light-vs-dark-factories', lastmod: '2026-06-02' }, + { url: '/blog/why-kubernetes-for-dark-factory', lastmod: '2026-06-11' }, + { url: '/blog/operator-patterns-for-software-factories', lastmod: '2026-06-19' }, + { url: '/blog/the-taste-problem', lastmod: '2026-06-29' }, + { url: '/blog/human-in-the-loop-seam', lastmod: '2026-07-08' }, ]; -const allPages = [...pages, ...blogPosts.map(p => ({ ...p, priority: '0.7' }))]; +const allPages = [...pages, ...speakingPages.map(p => ({ ...p, priority: '0.7' })), ...blogPosts.map(p => ({ ...p, priority: '0.7' }))]; // Render the sitemap XML -const xml = ` +const xml = `\<\?xml version="1.0" encoding="UTF-8"?\> ${allPages.map(page => ` diff --git a/src/pages/speaking.astro b/src/pages/speaking.astro index 53e5766..2811223 100644 --- a/src/pages/speaking.astro +++ b/src/pages/speaking.astro @@ -53,6 +53,7 @@ import SharedForm from '../components/Form/SharedForm.astro';