kaddidlehopper 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +104 -208
- package/dist/index.js +1 -31
- package/dist/types/cli.d.ts +1 -8
- package/dist/types/types.d.ts +7 -12
- package/package.json +1 -2
- package/src/cli.ts +129 -271
- package/src/index.ts +1 -47
- package/src/types.ts +7 -13
- package/CONTEXT.md +0 -139
- package/add-ons/ai/README.md +0 -34
- package/add-ons/ai/assets/AGENTS.md.append +0 -24
- package/add-ons/ai/assets/_dot_env.local.append +0 -13
- package/add-ons/ai/assets/src/components/AIAssistant.tsx +0 -149
- package/add-ons/ai/assets/src/lib/ai-hook.ts +0 -21
- package/add-ons/ai/assets/src/lib/weather-tools.ts +0 -30
- package/add-ons/ai/assets/src/routes/api.chat.ts +0 -94
- package/add-ons/ai/assets/src/routes/chat.css +0 -175
- package/add-ons/ai/assets/src/routes/chat.tsx +0 -141
- package/add-ons/ai/info.json +0 -22
- package/add-ons/ai/package.json +0 -17
- package/add-ons/ai/small-logo.svg +0 -8
- package/add-ons/db/assets/AGENTS.md.append +0 -22
- package/add-ons/db/assets/DB-SETUP.md +0 -65
- package/add-ons/db/assets/_dot_env.local.append +0 -2
- package/add-ons/db/assets/drizzle.config.ts +0 -10
- package/add-ons/db/assets/src/db/index.ts +0 -8
- package/add-ons/db/assets/src/db/schema.ts +0 -8
- package/add-ons/db/assets/src/routes/db-example.tsx +0 -118
- package/add-ons/db/assets/src/server/guestbook.functions.ts +0 -23
- package/add-ons/db/info.json +0 -22
- package/add-ons/db/package.json +0 -10
- package/add-ons/forms/assets/AGENTS.md.append +0 -13
- package/add-ons/forms/assets/public/form-example.html +0 -14
- package/add-ons/forms/assets/src/routes/form-example.tsx +0 -76
- package/add-ons/forms/info.json +0 -18
- package/add-ons/forms/package.json +0 -3
- package/examples/ai-chat/README.md +0 -36
- package/examples/ai-chat/assets/AGENTS.md.append +0 -24
- package/examples/ai-chat/assets/src/lib/ai-hook.ts +0 -21
- package/examples/ai-chat/assets/src/lib/weather-tools.ts +0 -30
- package/examples/ai-chat/assets/src/routes/__root.tsx +0 -57
- package/examples/ai-chat/assets/src/routes/api.chat.ts +0 -94
- package/examples/ai-chat/assets/src/routes/index.tsx +0 -141
- package/examples/ai-chat/assets/src/styles.css +0 -165
- package/examples/ai-chat/info.json +0 -25
- package/examples/ai-chat/package.json +0 -14
- package/examples/blog/README.md +0 -60
- package/examples/blog/assets/AGENTS.md.append +0 -18
- package/examples/blog/assets/content/posts/beach.md +0 -12
- package/examples/blog/assets/content/posts/jungle.md.ejs +0 -12
- package/examples/blog/assets/content/posts/mountains.md.ejs +0 -12
- package/examples/blog/assets/content/posts/snorkeling.md.ejs +0 -12
- package/examples/blog/assets/content/posts/waterfall.md.ejs +0 -12
- package/examples/blog/assets/content-collections.ts +0 -30
- package/examples/blog/assets/public/beach.jpg +0 -0
- package/examples/blog/assets/public/jungle.jpg +0 -0
- package/examples/blog/assets/public/mountains.jpg +0 -0
- package/examples/blog/assets/public/snorkeling.jpg +0 -0
- package/examples/blog/assets/public/waterfall.jpg +0 -0
- package/examples/blog/assets/src/components/Header.tsx +0 -52
- package/examples/blog/assets/src/components/VacayAssistant.tsx +0 -205
- package/examples/blog/assets/src/components/blog-posts.tsx +0 -78
- package/examples/blog/assets/src/components/ui/card.tsx +0 -92
- package/examples/blog/assets/src/lib/blog-ai-hook.ts +0 -25
- package/examples/blog/assets/src/lib/blog-tools.ts +0 -111
- package/examples/blog/assets/src/lib/utils.ts +0 -6
- package/examples/blog/assets/src/routes/__root.tsx +0 -57
- package/examples/blog/assets/src/routes/api.blog-chat.ts +0 -117
- package/examples/blog/assets/src/routes/category.$category.tsx +0 -19
- package/examples/blog/assets/src/routes/index.tsx +0 -19
- package/examples/blog/assets/src/routes/posts.$slug.tsx +0 -63
- package/examples/blog/assets/src/styles.css +0 -138
- package/examples/blog/info.json +0 -40
- package/examples/blog/package.json +0 -23
- package/examples/calculator/README.md +0 -16
- package/examples/calculator/assets/AGENTS.md.append +0 -9
- package/examples/calculator/assets/src/components/Calculator.tsx +0 -238
- package/examples/calculator/assets/src/components/Header.tsx +0 -17
- package/examples/calculator/assets/src/routes/__root.tsx +0 -57
- package/examples/calculator/assets/src/routes/index.tsx +0 -14
- package/examples/calculator/info.json +0 -20
- package/examples/calculator/package.json +0 -1
- package/examples/dashboard/README.md +0 -17
- package/examples/dashboard/assets/AGENTS.md.append +0 -12
- package/examples/dashboard/assets/src/components/Header.tsx +0 -17
- package/examples/dashboard/assets/src/routes/__root.tsx +0 -57
- package/examples/dashboard/assets/src/routes/index.tsx +0 -158
- package/examples/dashboard/info.json +0 -19
- package/examples/dashboard/package.json +0 -6
- package/examples/ecommerce/README.md +0 -48
- package/examples/ecommerce/assets/AGENTS.md.append +0 -22
- package/examples/ecommerce/assets/public/logo.png +0 -0
- package/examples/ecommerce/assets/public/motorcycle-scooter.jpg +0 -0
- package/examples/ecommerce/assets/src/components/BuyButton.tsx +0 -35
- package/examples/ecommerce/assets/src/components/Header.tsx +0 -36
- package/examples/ecommerce/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
- package/examples/ecommerce/assets/src/components/MotorcycleRecommendation.tsx +0 -53
- package/examples/ecommerce/assets/src/data/motorcycles.ts +0 -27
- package/examples/ecommerce/assets/src/lib/motorcycle-ai-hook.ts +0 -24
- package/examples/ecommerce/assets/src/lib/motorcycle-tools.ts +0 -42
- package/examples/ecommerce/assets/src/lib/stripe.server.ts +0 -39
- package/examples/ecommerce/assets/src/routes/__root.tsx +0 -57
- package/examples/ecommerce/assets/src/routes/api.motorcycle-chat.ts +0 -78
- package/examples/ecommerce/assets/src/routes/checkout/cancel.tsx +0 -25
- package/examples/ecommerce/assets/src/routes/checkout/success.tsx +0 -25
- package/examples/ecommerce/assets/src/routes/index.tsx +0 -76
- package/examples/ecommerce/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -55
- package/examples/ecommerce/assets/src/store/motorcycle-assistant.ts +0 -3
- package/examples/ecommerce/assets/src/styles.css +0 -212
- package/examples/ecommerce/info.json +0 -38
- package/examples/ecommerce/package.json +0 -13
- package/examples/events/README.md +0 -110
- package/examples/events/assets/AGENTS.md.append +0 -21
- package/examples/events/assets/content/speakers/andre-costa.md +0 -22
- package/examples/events/assets/content/speakers/hans-mueller.md.ejs +0 -22
- package/examples/events/assets/content/speakers/isabella-martinez.md.ejs +0 -22
- package/examples/events/assets/content/speakers/kenji-nakamura.md.ejs +0 -22
- package/examples/events/assets/content/speakers/marie-dubois.md.ejs +0 -20
- package/examples/events/assets/content/speakers/priya-sharma.md.ejs +0 -22
- package/examples/events/assets/content/talks/croissant-lamination-secrets.md +0 -39
- package/examples/events/assets/content/talks/french-macaron-mastery.md.ejs +0 -39
- package/examples/events/assets/content/talks/neapolitan-pizza-tradition-meets-innovation.md.ejs +0 -39
- package/examples/events/assets/content/talks/savory-breads-of-the-mediterranean.md.ejs +0 -39
- package/examples/events/assets/content/talks/sourdough-from-starter-to-masterpiece.md.ejs +0 -36
- package/examples/events/assets/content/talks/the-art-of-the-perfect-tart.md.ejs +0 -32
- package/examples/events/assets/content/talks/the-science-of-sugar.md.ejs +0 -39
- package/examples/events/assets/content/talks/umami-in-pastry-east-meets-west.md.ejs +0 -39
- package/examples/events/assets/content-collections.ts +0 -56
- package/examples/events/assets/public/background-1.jpg +0 -0
- package/examples/events/assets/public/background-2.jpg +0 -0
- package/examples/events/assets/public/background-3.jpg +0 -0
- package/examples/events/assets/public/background-4.jpg +0 -0
- package/examples/events/assets/public/conference-logo.png +0 -0
- package/examples/events/assets/public/favicon.ico +0 -0
- package/examples/events/assets/public/speakers/andre-costa.jpg +0 -0
- package/examples/events/assets/public/speakers/hans-mueller.jpg +0 -0
- package/examples/events/assets/public/speakers/isabella-martinez.jpg +0 -0
- package/examples/events/assets/public/speakers/kenji-nakamura.jpg +0 -0
- package/examples/events/assets/public/speakers/marie-dubois.jpg +0 -0
- package/examples/events/assets/public/speakers/priya-sharma.jpg +0 -0
- package/examples/events/assets/public/talks/croissant-lamination-secrets.jpg +0 -0
- package/examples/events/assets/public/talks/french-macaron-mastery.jpg +0 -0
- package/examples/events/assets/public/talks/neapolitan-pizza-tradition-meets-innovation.jpg +0 -0
- package/examples/events/assets/public/talks/savory-breads-of-the-mediterranean.jpg +0 -0
- package/examples/events/assets/public/talks/sourdough-from-starter-to-masterpiece.jpg +0 -0
- package/examples/events/assets/public/talks/the-art-of-the-perfect-tart.jpg +0 -0
- package/examples/events/assets/public/talks/the-science-of-sugar.jpg +0 -0
- package/examples/events/assets/public/talks/umami-in-pastry-east-meets-west.jpg +0 -0
- package/examples/events/assets/public/tanstack-circle-logo.png +0 -0
- package/examples/events/assets/public/tanstack-word-logo-white.svg +0 -1
- package/examples/events/assets/src/components/Header.tsx +0 -59
- package/examples/events/assets/src/components/HeaderNav.tsx +0 -67
- package/examples/events/assets/src/components/HeroCarousel.tsx +0 -61
- package/examples/events/assets/src/components/RemyAssistant.tsx +0 -207
- package/examples/events/assets/src/components/SpeakerCard.tsx +0 -67
- package/examples/events/assets/src/components/TalkCard.tsx +0 -77
- package/examples/events/assets/src/components/ui/card.tsx +0 -92
- package/examples/events/assets/src/lib/conference-ai-hook.ts +0 -26
- package/examples/events/assets/src/lib/conference-tools.ts +0 -210
- package/examples/events/assets/src/lib/model-selection.ts +0 -1
- package/examples/events/assets/src/lib/utils.ts +0 -6
- package/examples/events/assets/src/routes/__root.tsx +0 -70
- package/examples/events/assets/src/routes/api.remy-chat.ts +0 -119
- package/examples/events/assets/src/routes/index.tsx +0 -192
- package/examples/events/assets/src/routes/schedule.index.tsx +0 -274
- package/examples/events/assets/src/routes/speakers.$slug.tsx +0 -122
- package/examples/events/assets/src/routes/speakers.index.tsx +0 -40
- package/examples/events/assets/src/routes/talks.$slug.tsx +0 -116
- package/examples/events/assets/src/routes/talks.index.tsx +0 -40
- package/examples/events/assets/src/styles.css +0 -182
- package/examples/events/info.json +0 -61
- package/examples/events/package.json +0 -23
- package/examples/marketing/README.md +0 -60
- package/examples/marketing/assets/AGENTS.md.append +0 -15
- package/examples/marketing/assets/public/logo.png +0 -0
- package/examples/marketing/assets/public/motorcycle-adventure.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-cruiser.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-scooter.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-sport.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-supersport.jpg +0 -0
- package/examples/marketing/assets/src/components/Header.tsx +0 -36
- package/examples/marketing/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
- package/examples/marketing/assets/src/components/MotorcycleRecommendation.tsx +0 -53
- package/examples/marketing/assets/src/data/motorcycles.ts.ejs +0 -77
- package/examples/marketing/assets/src/lib/motorcycle-ai-hook.ts +0 -24
- package/examples/marketing/assets/src/lib/motorcycle-tools.ts +0 -42
- package/examples/marketing/assets/src/routes/__root.tsx +0 -57
- package/examples/marketing/assets/src/routes/api.motorcycle-chat.ts +0 -78
- package/examples/marketing/assets/src/routes/index.tsx +0 -72
- package/examples/marketing/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -56
- package/examples/marketing/assets/src/store/motorcycle-assistant.ts +0 -3
- package/examples/marketing/assets/src/styles.css +0 -212
- package/examples/marketing/info.json +0 -33
- package/examples/marketing/package.json +0 -14
- package/examples/portfolio/README.md +0 -49
- package/examples/portfolio/assets/AGENTS.md.append +0 -21
- package/examples/portfolio/assets/content/blog/getting-started-with-tanstack.md +0 -53
- package/examples/portfolio/assets/content/blog/react-19-features.md +0 -78
- package/examples/portfolio/assets/content/blog/tailwind-css-v4-guide.md +0 -60
- package/examples/portfolio/assets/content/education/code-school.md +0 -17
- package/examples/portfolio/assets/content/jobs/initech-junior.md +0 -20
- package/examples/portfolio/assets/content/projects/portfolio-site.md +0 -15
- package/examples/portfolio/assets/content/projects/task-manager.md +0 -15
- package/examples/portfolio/assets/content-collections.ts +0 -65
- package/examples/portfolio/assets/public/contact.html +0 -6
- package/examples/portfolio/assets/public/headshot-on-white.jpg +0 -0
- package/examples/portfolio/assets/src/components/Header.tsx +0 -33
- package/examples/portfolio/assets/src/components/ResumeAssistant.tsx +0 -193
- package/examples/portfolio/assets/src/components/ui/badge.tsx +0 -46
- package/examples/portfolio/assets/src/components/ui/card.tsx +0 -92
- package/examples/portfolio/assets/src/components/ui/checkbox.tsx +0 -30
- package/examples/portfolio/assets/src/components/ui/hover-card.tsx +0 -44
- package/examples/portfolio/assets/src/components/ui/separator.tsx +0 -26
- package/examples/portfolio/assets/src/lib/resume-ai-hook.ts +0 -21
- package/examples/portfolio/assets/src/lib/resume-tools.ts +0 -165
- package/examples/portfolio/assets/src/lib/utils.ts +0 -6
- package/examples/portfolio/assets/src/routes/__root.tsx +0 -57
- package/examples/portfolio/assets/src/routes/api.resume-chat.ts +0 -116
- package/examples/portfolio/assets/src/routes/blog/$slug.tsx +0 -73
- package/examples/portfolio/assets/src/routes/contact.tsx +0 -121
- package/examples/portfolio/assets/src/routes/index.tsx +0 -55
- package/examples/portfolio/assets/src/routes/projects.tsx +0 -62
- package/examples/portfolio/assets/src/routes/resume.tsx +0 -220
- package/examples/portfolio/assets/src/styles.css +0 -138
- package/examples/portfolio/info.json +0 -50
- package/examples/portfolio/package.json +0 -26
- package/examples/resume/README.md +0 -82
- package/examples/resume/assets/AGENTS.md.append +0 -19
- package/examples/resume/assets/content/education/code-school.md +0 -17
- package/examples/resume/assets/content/jobs/freelance.md.ejs +0 -13
- package/examples/resume/assets/content/jobs/initech-junior.md +0 -20
- package/examples/resume/assets/content/jobs/initech-lead.md.ejs +0 -29
- package/examples/resume/assets/content/jobs/initrode-senior.md.ejs +0 -28
- package/examples/resume/assets/content-collections.ts +0 -36
- package/examples/resume/assets/public/headshot-on-white.jpg +0 -0
- package/examples/resume/assets/src/components/Header.tsx +0 -33
- package/examples/resume/assets/src/components/ResumeAssistant.tsx +0 -193
- package/examples/resume/assets/src/components/ui/badge.tsx +0 -46
- package/examples/resume/assets/src/components/ui/card.tsx +0 -92
- package/examples/resume/assets/src/components/ui/checkbox.tsx +0 -30
- package/examples/resume/assets/src/components/ui/hover-card.tsx +0 -44
- package/examples/resume/assets/src/components/ui/separator.tsx +0 -26
- package/examples/resume/assets/src/lib/resume-ai-hook.ts +0 -21
- package/examples/resume/assets/src/lib/resume-tools.ts +0 -165
- package/examples/resume/assets/src/lib/utils.ts +0 -6
- package/examples/resume/assets/src/routes/api.resume-chat.ts +0 -110
- package/examples/resume/assets/src/routes/index.tsx +0 -220
- package/examples/resume/assets/src/styles.css +0 -138
- package/examples/resume/info.json +0 -35
- package/examples/resume/package.json +0 -26
- package/examples/saas/README.md +0 -16
- package/examples/saas/assets/AGENTS.md.append +0 -9
- package/examples/saas/assets/src/components/Header.tsx +0 -17
- package/examples/saas/assets/src/routes/__root.tsx +0 -57
- package/examples/saas/assets/src/routes/faq.tsx +0 -94
- package/examples/saas/assets/src/routes/index.tsx +0 -197
- package/examples/saas/info.json +0 -23
- package/examples/saas/package.json +0 -1
- package/examples/survey/README.md +0 -20
- package/examples/survey/assets/AGENTS.md.append +0 -9
- package/examples/survey/assets/public/form-survey.html +0 -15
- package/examples/survey/assets/src/components/SurveyForm.tsx +0 -128
- package/examples/survey/assets/src/routes/index.tsx +0 -14
- package/examples/survey/info.json +0 -19
- package/examples/survey/package.json +0 -1
- package/project/base/AGENTS.md +0 -86
- package/project/base/_dot_claude/skills/content-collections/SKILL.md +0 -505
- package/project/base/_dot_claude/skills/netlify-blobs/SKILL.md +0 -410
- package/project/base/_dot_claude/skills/netlify-db/SKILL.md +0 -424
- package/project/base/_dot_claude/skills/netlify-debugging/SKILL.md +0 -419
- package/project/base/_dot_claude/skills/netlify-forms/SKILL.md +0 -243
- package/project/base/_dot_claude/skills/netlify-functions/SKILL.md +0 -372
- package/project/base/_dot_claude/skills/tanstack-start-api-routes/SKILL.md +0 -421
- package/project/base/_dot_claude/skills/tanstack-start-loaders/SKILL.md +0 -426
- package/project/base/_dot_claude/skills/tanstack-start-project-setup/SKILL.md +0 -493
- package/project/base/_dot_claude/skills/tanstack-start-routes/SKILL.md +0 -430
- package/project/base/_dot_claude/skills/tanstack-start-server-functions/SKILL.md +0 -445
- package/project/base/_dot_claude/skills/tanstack-start-typesafe-routing/SKILL.md +0 -494
- package/project/base/_dot_gitignore +0 -8
- package/project/base/netlify.toml +0 -7
- package/project/base/package.json +0 -33
- package/project/base/public/favicon.ico +0 -0
- package/project/base/public/tanstack-circle-logo.png +0 -0
- package/project/base/public/tanstack-word-logo-white.svg +0 -1
- package/project/base/src/components/Header.tsx +0 -17
- package/project/base/src/components/HeaderNav.tsx.ejs +0 -179
- package/project/base/src/router.tsx +0 -15
- package/project/base/src/routes/__root.tsx +0 -57
- package/project/base/src/routes/index.tsx +0 -48
- package/project/base/src/styles.css +0 -15
- package/project/base/tsconfig.json +0 -28
- package/project/base/vite.config.ts.ejs +0 -25
- package/project/info.json +0 -17
- package/project/packages.json +0 -22
- package/scripts/check-outdated-packages.js +0 -421
- package/src/agents-md.ts +0 -139
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Link, createFileRoute } from '@tanstack/react-router'
|
|
2
|
-
|
|
3
|
-
export const Route = createFileRoute('/checkout/success')({
|
|
4
|
-
component: CheckoutSuccess,
|
|
5
|
-
})
|
|
6
|
-
|
|
7
|
-
function CheckoutSuccess() {
|
|
8
|
-
return (
|
|
9
|
-
<div className="bg-black text-white min-h-screen flex items-center justify-center p-5">
|
|
10
|
-
<div className="bg-gray-900/60 backdrop-blur-md rounded-2xl p-12 border border-gray-800/50 shadow-xl text-center max-w-lg">
|
|
11
|
-
<div className="text-emerald-400 text-6xl mb-6">✓</div>
|
|
12
|
-
<h1 className="text-3xl font-bold mb-4">Payment Successful!</h1>
|
|
13
|
-
<p className="text-gray-300 mb-8">
|
|
14
|
-
Thank you for your purchase. Your new motorcycle is on its way!
|
|
15
|
-
</p>
|
|
16
|
-
<Link
|
|
17
|
-
to="/"
|
|
18
|
-
className="inline-block bg-emerald-600 hover:bg-emerald-500 text-white px-6 py-3 rounded-lg transition-colors"
|
|
19
|
-
>
|
|
20
|
-
Back to Home
|
|
21
|
-
</Link>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { Link, createFileRoute } from '@tanstack/react-router'
|
|
2
|
-
import motorcycles from '@/data/motorcycles'
|
|
3
|
-
import { BuyButton } from '@/components/BuyButton'
|
|
4
|
-
|
|
5
|
-
export const Route = createFileRoute('/')({
|
|
6
|
-
component: MotorcyclesIndex,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
function MotorcyclesIndex() {
|
|
10
|
-
return (
|
|
11
|
-
<div className="bg-black text-white p-5">
|
|
12
|
-
<h1 className="text-3xl font-bold mb-16 text-center">
|
|
13
|
-
Luna-C Motorcycles
|
|
14
|
-
</h1>
|
|
15
|
-
<div className="max-w-7xl mx-auto">
|
|
16
|
-
{motorcycles.map((motorcycle, index) => (
|
|
17
|
-
<div
|
|
18
|
-
key={motorcycle.id}
|
|
19
|
-
className={`relative flex flex-col md:flex-row items-stretch gap-8 mb-32 ${
|
|
20
|
-
index % 2 === 1 ? 'md:flex-row-reverse' : ''
|
|
21
|
-
}`}
|
|
22
|
-
>
|
|
23
|
-
<div className="w-full md:w-[60%] relative">
|
|
24
|
-
<Link
|
|
25
|
-
to="/motorcycles/$motorcycleId"
|
|
26
|
-
params={{
|
|
27
|
-
motorcycleId: motorcycle.id.toString(),
|
|
28
|
-
}}
|
|
29
|
-
className="group block relative"
|
|
30
|
-
>
|
|
31
|
-
<div className="relative z-0 w-full aspect-[4/3]">
|
|
32
|
-
<div className="w-full h-full overflow-hidden rounded-2xl border border-gray-800/50 shadow-2xl">
|
|
33
|
-
<img
|
|
34
|
-
src={motorcycle.image}
|
|
35
|
-
alt={motorcycle.name}
|
|
36
|
-
className="w-full h-full object-cover motorcycle-image group-hover:scale-105 transition-transform duration-500"
|
|
37
|
-
/>
|
|
38
|
-
<div className="absolute inset-0 bg-linear-to-t from-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
39
|
-
</div>
|
|
40
|
-
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 bg-emerald-500/80 text-white px-4 py-2 rounded-full text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity duration-300 backdrop-blur-sm">
|
|
41
|
-
View Details
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
</Link>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<div
|
|
48
|
-
className={`w-full md:w-[50%] relative ${index % 2 === 0 ? 'md:-ml-24' : 'md:-mr-24'} md:my-12`}
|
|
49
|
-
>
|
|
50
|
-
<div className="bg-gray-900/40 backdrop-blur-xl rounded-2xl p-8 border border-gray-500/20 shadow-2xl relative z-10">
|
|
51
|
-
<div className="absolute inset-0 rounded-2xl bg-linear-to-br from-white/5 to-white/0"></div>
|
|
52
|
-
<div className="relative z-10">
|
|
53
|
-
<h2 className="text-2xl font-bold mb-3">{motorcycle.name}</h2>
|
|
54
|
-
<p className="text-gray-300 mb-2 font-medium">
|
|
55
|
-
{motorcycle.engineSize}cc •{' '}
|
|
56
|
-
{motorcycle.type.charAt(0).toUpperCase() +
|
|
57
|
-
motorcycle.type.slice(1)}
|
|
58
|
-
</p>
|
|
59
|
-
<p className="text-gray-100 mb-4 leading-relaxed">
|
|
60
|
-
{motorcycle.shortDescription}
|
|
61
|
-
</p>
|
|
62
|
-
<div className="flex items-center justify-between">
|
|
63
|
-
<div className="text-2xl font-bold text-emerald-400">
|
|
64
|
-
${motorcycle.price.toLocaleString()}
|
|
65
|
-
</div>
|
|
66
|
-
<BuyButton motorcycleId={motorcycle.id} />
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
))}
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
)
|
|
76
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { Link, createFileRoute } from '@tanstack/react-router'
|
|
2
|
-
import motorcycles from '../../data/motorcycles'
|
|
3
|
-
import { BuyButton } from '@/components/BuyButton'
|
|
4
|
-
|
|
5
|
-
export const Route = createFileRoute('/motorcycles/$motorcycleId')({
|
|
6
|
-
component: RouteComponent,
|
|
7
|
-
loader: async ({ params }) => {
|
|
8
|
-
const motorcycle = motorcycles.find(
|
|
9
|
-
(motorcycle) => motorcycle.id === +params.motorcycleId,
|
|
10
|
-
)
|
|
11
|
-
if (!motorcycle) {
|
|
12
|
-
throw new Error('Motorcycle not found')
|
|
13
|
-
}
|
|
14
|
-
return motorcycle
|
|
15
|
-
},
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
function RouteComponent() {
|
|
19
|
-
const motorcycle = Route.useLoaderData()
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div className="relative min-h-[100vh] flex items-center bg-black text-white p-5">
|
|
23
|
-
<div className="relative z-10 w-[60%] bg-gray-900/60 backdrop-blur-md rounded-2xl p-8 border border-gray-800/50 shadow-xl">
|
|
24
|
-
<Link
|
|
25
|
-
to="/"
|
|
26
|
-
className="inline-block mb-4 text-emerald-400 hover:text-emerald-300"
|
|
27
|
-
>
|
|
28
|
-
← Back to all motorcycles
|
|
29
|
-
</Link>
|
|
30
|
-
<h1 className="text-3xl font-bold mb-2">{motorcycle.name}</h1>
|
|
31
|
-
<p className="text-gray-400 mb-2">
|
|
32
|
-
{motorcycle.engineSize}cc •{' '}
|
|
33
|
-
{motorcycle.type.charAt(0).toUpperCase() + motorcycle.type.slice(1)}
|
|
34
|
-
</p>
|
|
35
|
-
<p className="text-gray-300 mb-6">{motorcycle.description}</p>
|
|
36
|
-
<div className="flex items-center justify-between">
|
|
37
|
-
<div className="text-2xl font-bold text-emerald-400">
|
|
38
|
-
${motorcycle.price.toLocaleString()}
|
|
39
|
-
</div>
|
|
40
|
-
<BuyButton motorcycleId={motorcycle.id} />
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
|
|
44
|
-
<div className="absolute top-0 right-0 w-[55%] h-full z-0">
|
|
45
|
-
<div className="w-full h-full overflow-hidden rounded-2xl border-4 border-gray-800 shadow-2xl">
|
|
46
|
-
<img
|
|
47
|
-
src={motorcycle.image}
|
|
48
|
-
alt={motorcycle.name}
|
|
49
|
-
className="w-full h-full object-cover motorcycle-image"
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
@import "highlight.js/styles/github-dark.css";
|
|
3
|
-
|
|
4
|
-
/* Custom scrollbar styles */
|
|
5
|
-
::-webkit-scrollbar {
|
|
6
|
-
width: 8px;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
::-webkit-scrollbar-track {
|
|
10
|
-
background: transparent;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
::-webkit-scrollbar-thumb {
|
|
14
|
-
background-color: rgba(156, 163, 175, 0.5);
|
|
15
|
-
border-radius: 4px;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
::-webkit-scrollbar-thumb:hover {
|
|
19
|
-
background-color: rgba(156, 163, 175, 0.7);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/* Smooth transitions for dark mode */
|
|
23
|
-
html {
|
|
24
|
-
transition: background-color 0.3s ease;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/* Markdown content styles */
|
|
28
|
-
.prose {
|
|
29
|
-
max-width: none;
|
|
30
|
-
color: #e5e7eb; /* text-gray-200 */
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.prose code {
|
|
34
|
-
color: #e5e7eb;
|
|
35
|
-
background-color: rgba(31, 41, 55, 0.5);
|
|
36
|
-
padding: 0.2em 0.4em;
|
|
37
|
-
border-radius: 0.375rem;
|
|
38
|
-
font-size: 0.875em;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.prose pre {
|
|
42
|
-
background-color: rgba(31, 41, 55, 0.5);
|
|
43
|
-
border-radius: 0.5rem;
|
|
44
|
-
padding: 1rem;
|
|
45
|
-
margin: 1.25em 0;
|
|
46
|
-
overflow-x: auto;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.prose pre code {
|
|
50
|
-
background-color: transparent;
|
|
51
|
-
padding: 0;
|
|
52
|
-
border-radius: 0;
|
|
53
|
-
color: inherit;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.prose h1, .prose h2, .prose h3, .prose h4 {
|
|
57
|
-
color: #f9fafb; /* text-gray-50 */
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.prose ul, .prose ol {
|
|
61
|
-
margin-top: 1.25em;
|
|
62
|
-
margin-bottom: 1.25em;
|
|
63
|
-
padding-left: 1.625em;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.prose li {
|
|
67
|
-
margin-top: 0.5em;
|
|
68
|
-
margin-bottom: 0.5em;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.prose blockquote {
|
|
72
|
-
border-left-color: #f97316; /* orange-500 */
|
|
73
|
-
background-color: rgba(249, 115, 22, 0.1);
|
|
74
|
-
padding: 1em;
|
|
75
|
-
margin: 1.25em 0;
|
|
76
|
-
border-radius: 0.5rem;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.prose hr {
|
|
80
|
-
border-color: rgba(249, 115, 22, 0.2);
|
|
81
|
-
margin: 2em 0;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.prose a {
|
|
85
|
-
color: #f97316; /* orange-500 */
|
|
86
|
-
text-decoration: underline;
|
|
87
|
-
text-decoration-thickness: 0.1em;
|
|
88
|
-
text-underline-offset: 0.2em;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.prose a:hover {
|
|
92
|
-
color: #fb923c; /* orange-400 */
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.prose table {
|
|
96
|
-
width: 100%;
|
|
97
|
-
border-collapse: collapse;
|
|
98
|
-
margin: 1.25em 0;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.prose th, .prose td {
|
|
102
|
-
padding: 0.75em;
|
|
103
|
-
border: 1px solid rgba(249, 115, 22, 0.2);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.prose th {
|
|
107
|
-
background-color: rgba(249, 115, 22, 0.1);
|
|
108
|
-
font-weight: 600;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* Message transition animations */
|
|
112
|
-
.message-enter {
|
|
113
|
-
opacity: 0;
|
|
114
|
-
transform: translateY(10px);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.message-enter-active {
|
|
118
|
-
opacity: 1;
|
|
119
|
-
transform: translateY(0);
|
|
120
|
-
transition: opacity 300ms, transform 300ms;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.message-exit {
|
|
124
|
-
opacity: 1;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.message-exit-active {
|
|
128
|
-
opacity: 0;
|
|
129
|
-
transition: opacity 300ms;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/* Add/update these styles to match AI formatting capabilities */
|
|
133
|
-
.prose h1 {
|
|
134
|
-
font-size: 2em;
|
|
135
|
-
margin-bottom: 0.5em;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.prose h2 {
|
|
139
|
-
font-size: 1.5em;
|
|
140
|
-
margin-top: 1em;
|
|
141
|
-
margin-bottom: 0.5em;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.prose h3 {
|
|
145
|
-
font-size: 1.25em;
|
|
146
|
-
margin-top: 1em;
|
|
147
|
-
margin-bottom: 0.5em;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.prose ul {
|
|
151
|
-
list-style-type: disc;
|
|
152
|
-
padding-left: 1.5em;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.prose ol {
|
|
156
|
-
list-style-type: decimal;
|
|
157
|
-
padding-left: 1.5em;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.prose table {
|
|
161
|
-
width: 100%;
|
|
162
|
-
border-collapse: collapse;
|
|
163
|
-
margin: 1em 0;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.prose th,
|
|
167
|
-
.prose td {
|
|
168
|
-
border: 1px solid rgba(249, 115, 22, 0.2);
|
|
169
|
-
padding: 0.5em;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.prose th {
|
|
173
|
-
background-color: rgba(249, 115, 22, 0.1);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.prose strong {
|
|
177
|
-
color: #f9fafb; /* text-gray-50 */
|
|
178
|
-
font-weight: 600;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.prose em {
|
|
182
|
-
font-style: italic;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.prose blockquote {
|
|
186
|
-
border-left: 4px solid #f97316; /* orange-500 */
|
|
187
|
-
padding-left: 1em;
|
|
188
|
-
margin: 1em 0;
|
|
189
|
-
color: #d1d5db; /* text-gray-300 */
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/* Ensure code blocks match the AI's formatting */
|
|
193
|
-
.prose code {
|
|
194
|
-
color: #e5e7eb;
|
|
195
|
-
background-color: rgba(31, 41, 55, 0.5);
|
|
196
|
-
padding: 0.2em 0.4em;
|
|
197
|
-
border-radius: 0.375rem;
|
|
198
|
-
font-size: 0.875em;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.prose pre {
|
|
202
|
-
background-color: rgba(31, 41, 55, 0.5);
|
|
203
|
-
border-radius: 0.5rem;
|
|
204
|
-
padding: 1rem;
|
|
205
|
-
margin: 1em 0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.prose pre code {
|
|
209
|
-
background-color: transparent;
|
|
210
|
-
padding: 0;
|
|
211
|
-
border-radius: 0;
|
|
212
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Ecommerce",
|
|
3
|
-
"description": "A motorcycle ecommerce site with Stripe checkout and AI shopping assistant built with TanStack Start for Netlify.",
|
|
4
|
-
"phase": "example",
|
|
5
|
-
"modes": ["file-router"],
|
|
6
|
-
"type": "example",
|
|
7
|
-
"priority": 10,
|
|
8
|
-
"link": "",
|
|
9
|
-
"routes": [
|
|
10
|
-
{"url": "/", "name": "Home", "path": "src/routes/index.tsx", "jsName": "MotorcyclesIndex"},
|
|
11
|
-
{"url": "/motorcycles/$motorcycleId", "path": "src/routes/motorcycles/$motorcycleId.tsx", "jsName": "MotorcycleDetail"},
|
|
12
|
-
{"url": "/checkout/success", "path": "src/routes/checkout/success.tsx", "jsName": "CheckoutSuccess"},
|
|
13
|
-
{"url": "/checkout/cancel", "path": "src/routes/checkout/cancel.tsx", "jsName": "CheckoutCancel"},
|
|
14
|
-
{"url": "/api/motorcycle-chat", "path": "src/routes/api.motorcycle-chat.ts", "jsName": "MotorcycleChatAPI"}
|
|
15
|
-
],
|
|
16
|
-
"features": ["tanstack-start", "stripe", "tanstack-ai"],
|
|
17
|
-
"integrations": [],
|
|
18
|
-
"dependsOn": [],
|
|
19
|
-
"variables": [],
|
|
20
|
-
"packageFileDescriptions": {
|
|
21
|
-
"src/routes/index.tsx": "Motorcycle catalog home with MotorcycleAIAssistant.",
|
|
22
|
-
"src/routes/motorcycles/$motorcycleId.tsx": "Motorcycle detail page with BuyButton, recommendation.",
|
|
23
|
-
"src/routes/checkout/success.tsx": "Stripe checkout success page.",
|
|
24
|
-
"src/routes/checkout/cancel.tsx": "Stripe checkout cancel page.",
|
|
25
|
-
"src/routes/api.motorcycle-chat.ts": "POST handler for motorcycle AI chat with getMotorcycles, recommendMotorcycle tools.",
|
|
26
|
-
"src/routes/__root.tsx": "Root layout: Header, styles.",
|
|
27
|
-
"src/styles.css": "Global styles: Tailwind, prose.",
|
|
28
|
-
"src/data/motorcycles.ts": "Motorcycle catalog data.",
|
|
29
|
-
"src/lib/motorcycle-tools.ts": "AI tools: getMotorcycles, recommendMotorcycle.",
|
|
30
|
-
"src/lib/motorcycle-ai-hook.ts": "useMotorcycleChat hook for /api/motorcycle-chat.",
|
|
31
|
-
"src/lib/stripe.server.ts": "Stripe server utilities for checkout.",
|
|
32
|
-
"src/store/motorcycle-assistant.ts": "Zustand store for assistant open state.",
|
|
33
|
-
"src/components/Header.tsx": "Header with nav.",
|
|
34
|
-
"src/components/MotorcycleAIAssistant.tsx": "AI shopping assistant component.",
|
|
35
|
-
"src/components/MotorcycleRecommendation.tsx": "Motorcycle recommendation card display.",
|
|
36
|
-
"src/components/BuyButton.tsx": "Stripe checkout button component."
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"dependencies": {
|
|
3
|
-
"@tanstack/ai": "0.2.2",
|
|
4
|
-
"@tanstack/ai-anthropic": "0.2.0",
|
|
5
|
-
"@tanstack/ai-client": "0.2.2",
|
|
6
|
-
"@tanstack/ai-react": "0.2.2",
|
|
7
|
-
"@tanstack/react-ai-devtools": "0.2.1",
|
|
8
|
-
"highlight.js": "^11.11.1",
|
|
9
|
-
"streamdown": "^2.1.0",
|
|
10
|
-
"stripe": "^20.3.1",
|
|
11
|
-
"zod": "^4.3.6"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
# Events Example - Haute Pâtisserie 2026
|
|
2
|
-
|
|
3
|
-
A beautiful pastry conference website built with TanStack Start and Netlify, featuring:
|
|
4
|
-
|
|
5
|
-
- **Speakers & Sessions**: Managed with content-collections for easy markdown-based content
|
|
6
|
-
- **Conference Schedule**: Day-by-day timeline of all sessions
|
|
7
|
-
- **AI Assistant (Remy)**: An AI-powered chat assistant to help attendees navigate the conference
|
|
8
|
-
- **Elegant Dark Theme**: Custom typography with Playfair Display and copper/gold accents
|
|
9
|
-
|
|
10
|
-
## Features
|
|
11
|
-
|
|
12
|
-
### Content Management
|
|
13
|
-
- Speaker profiles with bios, awards, and specialty information
|
|
14
|
-
- Session details with topics, duration, and speaker attribution
|
|
15
|
-
- All content in markdown files using content-collections
|
|
16
|
-
|
|
17
|
-
### AI-Powered Assistance
|
|
18
|
-
- Chat with "Remy" the culinary assistant
|
|
19
|
-
- Search for speakers and sessions by topic
|
|
20
|
-
- Get recommendations based on interests
|
|
21
|
-
- Supports multiple AI providers (Anthropic, OpenAI, Gemini, Ollama)
|
|
22
|
-
|
|
23
|
-
### Routes
|
|
24
|
-
- `/` - Home page with featured speakers and sessions
|
|
25
|
-
- `/schedule` - Conference schedule with day-by-day timeline
|
|
26
|
-
- `/speakers` - All speakers grid
|
|
27
|
-
- `/speakers/:slug` - Individual speaker detail page
|
|
28
|
-
- `/talks` - All sessions grid
|
|
29
|
-
- `/talks/:slug` - Individual session detail page
|
|
30
|
-
|
|
31
|
-
## Getting Started
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# Create a new project with this example
|
|
35
|
-
npx netlify-cta my-conference --example events
|
|
36
|
-
|
|
37
|
-
# Navigate to the project
|
|
38
|
-
cd my-conference
|
|
39
|
-
|
|
40
|
-
# Install dependencies
|
|
41
|
-
pnpm install
|
|
42
|
-
|
|
43
|
-
# Start the development server
|
|
44
|
-
pnpm dev
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## AI Configuration
|
|
48
|
-
|
|
49
|
-
To use the AI assistant, set one of the following environment variables:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# Anthropic (Claude)
|
|
53
|
-
ANTHROPIC_API_KEY=your-key-here
|
|
54
|
-
|
|
55
|
-
# OpenAI
|
|
56
|
-
OPENAI_API_KEY=your-key-here
|
|
57
|
-
|
|
58
|
-
# Google Gemini
|
|
59
|
-
GEMINI_API_KEY=your-key-here
|
|
60
|
-
|
|
61
|
-
# Ollama (local, no API key needed)
|
|
62
|
-
# Just ensure Ollama is running locally
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
The assistant will automatically use the first available provider.
|
|
66
|
-
|
|
67
|
-
## Customization
|
|
68
|
-
|
|
69
|
-
### Adding Speakers
|
|
70
|
-
Create a new markdown file in `content/speakers/`:
|
|
71
|
-
|
|
72
|
-
```markdown
|
|
73
|
-
---
|
|
74
|
-
name: "Chef Name"
|
|
75
|
-
title: "Executive Pastry Chef"
|
|
76
|
-
specialty: "French Pastry"
|
|
77
|
-
restaurant: "Restaurant Name"
|
|
78
|
-
location: "City, Country"
|
|
79
|
-
headshot: "speakers/chef-name.jpg"
|
|
80
|
-
awards:
|
|
81
|
-
- "Award 1"
|
|
82
|
-
- "Award 2"
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
Bio content here...
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Adding Sessions
|
|
89
|
-
Create a new markdown file in `content/talks/`:
|
|
90
|
-
|
|
91
|
-
```markdown
|
|
92
|
-
---
|
|
93
|
-
title: "Session Title"
|
|
94
|
-
speaker: "Chef Name"
|
|
95
|
-
duration: "90 minutes"
|
|
96
|
-
image: "talks/session-image.jpg"
|
|
97
|
-
topics:
|
|
98
|
-
- "Topic 1"
|
|
99
|
-
- "Topic 2"
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
Session description here...
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Theme
|
|
106
|
-
|
|
107
|
-
The example uses a custom dark theme with:
|
|
108
|
-
- **Font**: Playfair Display (display) and Cormorant Garamond (body)
|
|
109
|
-
- **Colors**: Copper and gold accents on a dark charcoal background
|
|
110
|
-
- **Effects**: Elegant card hover animations, grain texture overlay
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
### Conference Site Integration
|
|
2
|
-
|
|
3
|
-
Pastry conference website with Content Collections (speakers, talks) and Remy AI assistant.
|
|
4
|
-
|
|
5
|
-
**Content Collections:**
|
|
6
|
-
- `speakers` - name, title, specialty, restaurant, headshot, awards
|
|
7
|
-
- `talks` - title, speaker, duration, topics, image
|
|
8
|
-
- Schemas in `content-collections.ts`
|
|
9
|
-
|
|
10
|
-
**AI tools available (RemyAssistant):**
|
|
11
|
-
- `getSpeakerBySlug` - Get speaker profile by slug
|
|
12
|
-
- `getTalkBySlug` - Get talk details by slug
|
|
13
|
-
- `getAllSpeakers` - List all speakers
|
|
14
|
-
- `getAllTalks` - List all talks
|
|
15
|
-
- `getSchedule` - Get full schedule
|
|
16
|
-
|
|
17
|
-
**Components:** HeroCarousel (background images), RemyAssistant (conference Q&A)
|
|
18
|
-
|
|
19
|
-
## Environment Variables
|
|
20
|
-
|
|
21
|
-
For AI: ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or OLLAMA_BASE_URL (same as ai add-on).
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: "André Costa"
|
|
3
|
-
title: "Master Confeiteiro"
|
|
4
|
-
specialty: "Portuguese Pastries & Mediterranean Breads"
|
|
5
|
-
restaurant: "Pastelaria Ouro"
|
|
6
|
-
location: "Lisbon, Portugal"
|
|
7
|
-
headshot: "speakers/andre-costa.jpg"
|
|
8
|
-
awards:
|
|
9
|
-
- "Portuguese National Gastronomy Prize 2020"
|
|
10
|
-
- "Pastéis de Belém Certified Master"
|
|
11
|
-
- "European Baker of the Year 2019"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
André Costa is the guardian of Portugal's rich pastry heritage and an ambassador for Mediterranean bread traditions. His life's work has been dedicated to preserving, perfecting, and sharing the techniques behind iconic Portuguese sweets — from the legendary pastel de nata to the lesser-known regional treasures that deserve global recognition.
|
|
15
|
-
|
|
16
|
-
André's training began at age sixteen at Pastéis de Belém, the historic Lisbon bakery that has guarded the original pastel de nata recipe since 1837. For twelve years, he worked within their closely guarded production, eventually becoming one of only a handful of people entrusted with the complete, secret recipe. The discipline and precision required to produce thousands of identical custard tarts daily became the foundation of his craft.
|
|
17
|
-
|
|
18
|
-
But André's curiosity extended beyond Lisbon. He spent years traveling the Mediterranean coast — from the Algarve to Morocco, Sicily to Lebanon — studying the bread traditions that connect these cultures. He became fascinated by how similar techniques evolved differently across regions, and how the sea, the wheat, and the olive oil created distinct but related culinary identities.
|
|
19
|
-
|
|
20
|
-
Pastelaria Ouro, opened in Lisbon's Alfama district in 2018, showcases both Portuguese classics and André's Mediterranean discoveries. The morning pastry case features perfect pastéis de nata alongside Sicilian brioche, Moroccan msemen, and his own creations that blend traditions. The afternoon bread service offers naturally leavened loaves baked in a wood-fired oven built to his specifications.
|
|
21
|
-
|
|
22
|
-
André is also a passionate historian, having written two books on Portuguese pastry traditions and consulting for UNESCO on the cultural preservation of Mediterranean baking heritage.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<% if (addOnOption.project?.bareBones) { ignoreFile() } %>---
|
|
2
|
-
name: "Hans Mueller"
|
|
3
|
-
title: "Master Baker"
|
|
4
|
-
specialty: "Viennoiserie & Laminated Doughs"
|
|
5
|
-
restaurant: "Das Brotwerk"
|
|
6
|
-
location: "Munich, Germany"
|
|
7
|
-
headshot: "speakers/hans-mueller.jpg"
|
|
8
|
-
awards:
|
|
9
|
-
- "German Master Baker Certification"
|
|
10
|
-
- "Coupe du Monde de la Boulangerie Silver 2016"
|
|
11
|
-
- "Austrian Chamber of Commerce Gold Medal"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
Hans Mueller represents the sixth generation of his family to pursue the art of baking, carrying forward a tradition that began in a small Austrian village in 1847. His mastery of laminated doughs — the painstaking process of folding butter into dough to create hundreds of flaky layers — is considered unparalleled in the German-speaking world.
|
|
15
|
-
|
|
16
|
-
Hans's formal training began at age fourteen as an apprentice in his father's bakery in Salzburg. He later refined his skills at the prestigious bakery of the Vienna State Opera, where he spent eight years supplying pastries for intermission service and exclusive galas. The pressure of producing hundreds of perfect croissants and Kipferl daily, with no margin for error, forged his legendary precision.
|
|
17
|
-
|
|
18
|
-
What sets Hans apart is his scientific approach to an ancient craft. He has collaborated with food scientists at the Technical University of Munich to study the crystalline structure of butter at various temperatures, the gluten networks in different flour types, and the fermentation kinetics that create flavor. His findings have been published in academic journals and have influenced professional bakers worldwide.
|
|
19
|
-
|
|
20
|
-
Das Brotwerk, his Munich bakery and teaching academy, opened in 2017. The space features a glass-walled production kitchen where visitors can observe the lamination process in real-time. His signature "288-Layer Croissant" — a technical feat requiring three days of preparation — has been called "the platonic ideal of the form" by *Die Zeit*.
|
|
21
|
-
|
|
22
|
-
Hans is also dedicated to preserving traditional Germanic baking techniques, maintaining an archive of historical recipes and training the next generation in methods that might otherwise be lost.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<% if (addOnOption.project?.bareBones) { ignoreFile() } %>---
|
|
2
|
-
name: "Isabella Martinez"
|
|
3
|
-
title: "Head Baker & Founder"
|
|
4
|
-
specialty: "Artisan Bread & Sourdough"
|
|
5
|
-
restaurant: "Madre Masa"
|
|
6
|
-
location: "San Francisco, USA"
|
|
7
|
-
headshot: "speakers/isabella-martinez.jpg"
|
|
8
|
-
awards:
|
|
9
|
-
- "San Francisco Chronicle Rising Star 2021"
|
|
10
|
-
- "Bread Bakers Guild of America Master Baker"
|
|
11
|
-
- "Slow Food Presidium Recognition"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
Isabella Martinez's love affair with bread began in her grandmother's kitchen in Mexico City, where she learned that bread is more than sustenance — it's culture, community, and love made tangible. That foundation led her on a journey through the world's great bread traditions, ultimately landing at San Francisco's legendary Tartine Bakery.
|
|
15
|
-
|
|
16
|
-
During her four years at Tartine, Isabella immersed herself in the art and science of long-fermentation breads. She developed an obsession with understanding the living ecosystems within sourdough starters, eventually cultivating over twenty distinct cultures from around the world, each with unique flavor profiles and characteristics.
|
|
17
|
-
|
|
18
|
-
Her technical mastery is matched by her commitment to sustainable sourcing. Isabella works directly with small-scale grain farmers throughout California and Mexico, championing heritage wheat varieties that were nearly lost to industrial agriculture. Her "Oaxacan Heritage Loaf," made with ancestral Mexican wheat and local California grains, has become a symbol of the neo-locavore bread movement.
|
|
19
|
-
|
|
20
|
-
Madre Masa, which Isabella founded in 2019 in San Francisco's Mission District, operates as both bakery and community hub. The space hosts weekly bread-making workshops, partners with local food banks, and has become a gathering place for the Bay Area's food community. Her naturally leavened pizza, served only on weekend evenings, regularly draws three-hour waits.
|
|
21
|
-
|
|
22
|
-
Isabella believes that bread connects us to millennia of human history and that every loaf tells a story of the land, the grain, and the hands that shaped it.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<% if (addOnOption.project?.bareBones) { ignoreFile() } %>---
|
|
2
|
-
name: "Kenji Nakamura"
|
|
3
|
-
title: "Creative Director of Pastry"
|
|
4
|
-
specialty: "Japanese-French Fusion"
|
|
5
|
-
restaurant: "Umami Flour"
|
|
6
|
-
location: "Kyoto, Japan"
|
|
7
|
-
headshot: "speakers/kenji-nakamura.jpg"
|
|
8
|
-
awards:
|
|
9
|
-
- "Asia's Best Pastry Chef 2022"
|
|
10
|
-
- "James Beard Rising Star 2018"
|
|
11
|
-
- "Tokyo Pastry Academy Distinguished Alumni"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
Kenji Nakamura stands at the fascinating intersection of Japanese precision and French artistry. His unique perspective emerged from a childhood spent between his grandmother's traditional wagashi shop in Kyoto and summers visiting his aunt's Parisian boulangerie — an upbringing that would define his revolutionary approach to pastry.
|
|
15
|
-
|
|
16
|
-
After formal training at the Tokyo Pastry Academy, Kenji sought to deepen his French technique at Pierre Hermé Tokyo, where he spent five transformative years. There, he began experimenting with umami-forward flavor profiles in desserts — miso caramel, toasted nori chocolate, and yuzu integrated into classic French preparations.
|
|
17
|
-
|
|
18
|
-
His creations challenge Western notions of sweetness while honoring both traditions. The "Matcha Millefeuille" — layers of impossibly thin, crisp pastry with ceremonial-grade matcha cream and white chocolate miso — has been called "a masterpiece of cultural synthesis" by the *Japan Times*.
|
|
19
|
-
|
|
20
|
-
In 2020, Kenji opened Umami Flour in a converted machiya townhouse in Kyoto's historic Gion district. The space blends minimalist Japanese aesthetics with the warmth of a French salon de thé. His tasting menu of eight courses explores the full spectrum of umami in desserts, from subtle to profound, and has earned three stars from the Michelin Guide Japan.
|
|
21
|
-
|
|
22
|
-
Kenji's philosophy centers on "finding harmony between cultures without erasing either" — a principle that guides both his recipes and his teaching.
|