diff --git a/content/demos/_index.md b/content/demos/_index.md new file mode 100644 index 0000000000..d323188819 --- /dev/null +++ b/content/demos/_index.md @@ -0,0 +1,47 @@ +--- +title: Interactive demos +description: Hands-on interactive walkthroughs of Validated Patterns. +menu: + main: + name: Demos + weight: 22 +demos: + - id: 5nsew2VgJfkkdd5sQ0Mr + title: Deploy a Validated Pattern on RHDP + thumbnail: /images/demos/deploy-pattern-on-rhdp.png + description: Deploy a Validated Pattern on the Red Hat Demo Platform (RHDP) without provisioning your own cluster. Walk through the steps to launch a pattern in a pre-built environment. + pattern_link: https://demo.redhat.com + pattern_label: Red Hat Demo Platform + - id: UusleQSZch8ZZyimr7aj + title: RAG VP UI — Red Hat Summit 2026 + thumbnail: /images/demos/rag-vp-ui-summit-2026.png + description: A walkthrough of the RAG Validated Pattern UI as shown at Red Hat Summit 2026. See the end-to-end experience from cluster deployment to a running AI application. + - id: 6SxOiDc3P7uMg38jAOLw + title: RAG-LLM GitOps pattern on Microsoft Azure + thumbnail: /images/demos/rag-llm-gitops-azure.png + description: LLM-based document generation on Azure with Red Hat OpenShift AI, from vector database ingestion to a running chatbot interface. + pattern_link: /patterns/azure-rag-llm-gitops/ + pattern_label: RAG-LLM pattern on Microsoft Azure + - id: WBiokIqAOZRlk7aXkvuU + title: RAG LLM on Lenovo SNO + thumbnail: /images/demos/rag-llm-lenovo-sno.png + description: RAG LLM on a Lenovo Single Node OpenShift cluster — CPU-based RAG without GPU hardware on compact infrastructure. + pattern_link: /patterns/rag-llm-cpu/ + pattern_label: RAG LLM Chatbot on CPU + - id: Qla3IzaQVM9yQP27TWDU + title: Performing disaster recovery with RamenDR backed by Dell PowerStore + thumbnail: /images/demos/ramendr-dell-powerstore-dr.png + description: Walk through regional disaster recovery for OpenShift Virtualization workloads using RamenDR with Dell PowerStore storage backing the recovery workflow. + pattern_link: /patterns/ramendr-starter-kit/ + pattern_label: RamenDR Starter Kit +next_steps: + - url: /patterns/ + label: Explore all patterns + text: browse the full catalog by tier and use case + - url: /learn/quickstart/ + label: Read the quickstart guide + text: step-by-step instructions for your first deployment + - url: /learn/about-validated-patterns/ + label: Learn the concepts + text: understand how the framework works +--- diff --git a/content/patterns/azure-rag-llm-gitops/_index.adoc b/content/patterns/azure-rag-llm-gitops/_index.adoc index 8a4cfd0cb8..a3b8e7c72d 100644 --- a/content/patterns/azure-rag-llm-gitops/_index.adoc +++ b/content/patterns/azure-rag-llm-gitops/_index.adoc @@ -22,6 +22,7 @@ links: install: getting-started bugs: https://github.com/validatedpatterns/rag-llm-gitops/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: 6SxOiDc3P7uMg38jAOLw --- :toc: diff --git a/content/patterns/multicloud-gitops/_index.adoc b/content/patterns/multicloud-gitops/_index.adoc index 6e5e7079b1..4b609f0f1a 100644 --- a/content/patterns/multicloud-gitops/_index.adoc +++ b/content/patterns/multicloud-gitops/_index.adoc @@ -20,6 +20,7 @@ links: arch: https://www.redhat.com/architect/portfolio/detail/8-hybrid-multicloud-management-with-gitops bugs: https://github.com/validatedpatterns/multicloud-gitops/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: U3ztnJKzMjsNM05f0ff5 ci: mcgitops --- :toc: diff --git a/content/patterns/rag-llm-cpu/_index.md b/content/patterns/rag-llm-cpu/_index.md index c82eae1e92..6da9c5d3d4 100644 --- a/content/patterns/rag-llm-cpu/_index.md +++ b/content/patterns/rag-llm-cpu/_index.md @@ -21,6 +21,7 @@ links: install: getting-started bugs: https://github.com/validatedpatterns-sandbox/rag-llm-cpu/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: WBiokIqAOZRlk7aXkvuU --- # **CPU-based RAG LLM chatbot** diff --git a/content/patterns/rag-llm-gitops/_index.md b/content/patterns/rag-llm-gitops/_index.md index fd0e622970..56ad9b06c8 100644 --- a/content/patterns/rag-llm-gitops/_index.md +++ b/content/patterns/rag-llm-gitops/_index.md @@ -24,6 +24,7 @@ links: install: getting-started bugs: https://github.com/validatedpatterns/rag-llm-gitops/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: drMY04qRCqQuq2BkZWpn ci: ragllm --- diff --git a/content/patterns/rag-quickstart/_index.adoc b/content/patterns/rag-quickstart/_index.adoc index 037bd55245..b9ea2b3e69 100644 --- a/content/patterns/rag-quickstart/_index.adoc +++ b/content/patterns/rag-quickstart/_index.adoc @@ -15,6 +15,7 @@ links: install: getting-started bugs: https://github.com/validatedpatterns-sandbox/ai-quickstart-rag/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: drMY04qRCqQuq2BkZWpn --- :toc: :imagesdir: /images diff --git a/content/patterns/ramendr-starter-kit/_index.adoc b/content/patterns/ramendr-starter-kit/_index.adoc index 2cc09257a7..d0d02b004d 100644 --- a/content/patterns/ramendr-starter-kit/_index.adoc +++ b/content/patterns/ramendr-starter-kit/_index.adoc @@ -23,6 +23,7 @@ links: install: getting-started bugs: https://github.com/validatedpatterns/ramendr-starter-kit/issues feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform + demo: Qla3IzaQVM9yQP27TWDU ci: ramendr-starter-kit --- diff --git a/layouts/blog/list.html b/layouts/blog/list.html index e659986d4c..ba155a2680 100644 --- a/layouts/blog/list.html +++ b/layouts/blog/list.html @@ -32,6 +32,6 @@

{{ partial "paginator.html" . }} - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} \ No newline at end of file diff --git a/layouts/blog/single.html b/layouts/blog/single.html index 19605bbf1e..cb5a467fd6 100644 --- a/layouts/blog/single.html +++ b/layouts/blog/single.html @@ -49,6 +49,6 @@

- {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/blog_tags/list.html b/layouts/blog_tags/list.html index 0bb2545b78..35d96c92ab 100644 --- a/layouts/blog_tags/list.html +++ b/layouts/blog_tags/list.html @@ -35,6 +35,6 @@

{{ partial "paginator.html" . }} - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/ci/single.html b/layouts/ci/single.html index 53456caddd..d10c7244f0 100644 --- a/layouts/ci/single.html +++ b/layouts/ci/single.html @@ -26,6 +26,6 @@

{{- .Title -}}

- {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/contribute/list.html b/layouts/contribute/list.html index 58a2e50091..776b6e5a14 100644 --- a/layouts/contribute/list.html +++ b/layouts/contribute/list.html @@ -34,6 +34,6 @@

- {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/contribute/single.html b/layouts/contribute/single.html index 65eaa303ed..3333274b7f 100644 --- a/layouts/contribute/single.html +++ b/layouts/contribute/single.html @@ -16,6 +16,6 @@ - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/demos/list.html b/layouts/demos/list.html new file mode 100644 index 0000000000..28376cde0a --- /dev/null +++ b/layouts/demos/list.html @@ -0,0 +1,70 @@ +{{ define "main" }} +{{ $demos := .Params.demos }} +{{ $heroMain := index $demos 0 }} +
+
+
+
+
+

{{ .Title }}

+ {{ with .Description }} +

{{ . }}

+ {{ end }} +
+
+
+
+ +
+
+
+ {{ if $demos }} +
+
+ {{ partial "arcade-embed.html" (dict "id" $heroMain.id "title" $heroMain.title "eager" true) }} +
+ + + +
+

{{ $heroMain.title }}

+

{{ $heroMain.description }}

+ {{ if $heroMain.pattern_link }} +

+ For more information, see: {{ $heroMain.pattern_label | default "View pattern" }} +

+ {{ else }} + + {{ end }} +
+
+ {{ end }} + + {{ with .Params.next_steps }} +
+

Next steps

+
    + {{ range . }} +
  • {{ .label }} — {{ .text }}
  • + {{ end }} +
+
+ {{ end }} +
+
+
+ + {{ partialCached "footer.html" . }} +
+ + +{{ end }} diff --git a/layouts/index.html b/layouts/index.html index fc147f344a..6124f21a8d 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -16,6 +16,40 @@ + +
@@ -549,7 +583,7 @@

Deploy with conf

- {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} diff --git a/layouts/learn/list.html b/layouts/learn/list.html index 0c383aa225..37c3f8ed2f 100644 --- a/layouts/learn/list.html +++ b/layouts/learn/list.html @@ -30,6 +30,6 @@

{{ partial "paginator.html" . }} - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/learn/single.html b/layouts/learn/single.html index 0396a3878a..0f50e24052 100644 --- a/layouts/learn/single.html +++ b/layouts/learn/single.html @@ -43,6 +43,6 @@ - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/partials/arcade-embed.html b/layouts/partials/arcade-embed.html new file mode 100644 index 0000000000..0b2c47c27a --- /dev/null +++ b/layouts/partials/arcade-embed.html @@ -0,0 +1,21 @@ +{{- /* + Arcade iframe with skeleton placeholder. + Params: id (required), title, eager (bool), compact (bool) +*/ -}} +{{- $id := .id -}} +{{- $title := .title | default "Interactive demo" -}} +{{- $eager := .eager | default false -}} +{{- $compact := .compact | default false -}} +{{- $src := printf "https://demo.arcade.software/%s?embed&embed_mobile=tab&embed_desktop=inline&squared=true&show_copy_link=true" $id -}} +
+ + +
diff --git a/layouts/partials/demo-select-card.html b/layouts/partials/demo-select-card.html new file mode 100644 index 0000000000..cc850ecf0f --- /dev/null +++ b/layouts/partials/demo-select-card.html @@ -0,0 +1,28 @@ +{{- /* + Clickable demo thumbnail (loads in main player via demos.js). + dict: demo, variant (sidebar|grid), active (bool) +*/ -}} +{{- $d := .demo -}} +{{- $variant := .variant | default "sidebar" -}} +{{- $active := .active | default false -}} +
+ + {{ partial "demo-thumbnail.html" (dict "id" $d.id "title" $d.title "thumbnail" $d.thumbnail) }} + Now playing + + + {{ if eq $variant "grid" }} +

{{ $d.title }}

+ {{ end }} +
diff --git a/layouts/partials/demo-thumbnail.html b/layouts/partials/demo-thumbnail.html new file mode 100644 index 0000000000..dab08d9deb --- /dev/null +++ b/layouts/partials/demo-thumbnail.html @@ -0,0 +1,13 @@ +{{- /* + Thumbnail for a demo card. Pass dict: title, thumbnail (required image path). +*/ -}} +{{- $title := .title | default "Demo" -}} +{{- $src := .thumbnail -}} +{{ $title }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 2bdb939d1c..6de2a56e02 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -71,5 +71,4 @@ - {{ partial "search-index.html" . }} diff --git a/layouts/partials/links.html b/layouts/partials/links.html index e4cc85dada..92a8682b1d 100644 --- a/layouts/partials/links.html +++ b/layouts/partials/links.html @@ -41,4 +41,59 @@ Share Feedback {{ end }} +{{ if (isset .Params.links "demo") }} +{{ $demoId := .Params.links.demo }} +
  • + + + + View demo +
  • + +{{ end }} diff --git a/layouts/partials/patterns-browser.html b/layouts/partials/patterns-browser.html index 1f31b0fd1f..c1a925eb31 100644 --- a/layouts/partials/patterns-browser.html +++ b/layouts/partials/patterns-browser.html @@ -60,5 +60,5 @@

    - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} diff --git a/layouts/partials/patterns-index.html b/layouts/partials/patterns-index.html index 515034b8c5..ad8e0fde53 100644 --- a/layouts/partials/patterns-index.html +++ b/layouts/partials/patterns-index.html @@ -142,5 +142,5 @@

    {{ .Title }}

    - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} diff --git a/layouts/patterns/single.html b/layouts/patterns/single.html index 387db3d1e7..8674c53c29 100644 --- a/layouts/patterns/single.html +++ b/layouts/patterns/single.html @@ -43,6 +43,6 @@ - {{ partial "footer.html" . }} + {{ partialCached "footer.html" . }} {{ end }} diff --git a/layouts/search/list.html b/layouts/search/list.html index bed9e6ca97..41e346e676 100644 --- a/layouts/search/list.html +++ b/layouts/search/list.html @@ -18,7 +18,8 @@

    - {{ partial "footer.html" . }} + {{ partial "search-index.html" . }} + {{ partialCached "footer.html" . }} {{ end }} \ No newline at end of file diff --git a/layouts/shortcodes/arcade.html b/layouts/shortcodes/arcade.html new file mode 100644 index 0000000000..13a1a84a22 --- /dev/null +++ b/layouts/shortcodes/arcade.html @@ -0,0 +1,15 @@ +{{- $url := .Get "url" -}} +{{- $title := .Get "title" | default "Interactive Demo" -}} +
    + +
    diff --git a/static/css/custom.css b/static/css/custom.css index 2528552527..d23109f4fe 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -3583,3 +3583,57 @@ a.ci-status-unavailable-link:hover { min-width: 180px; } } + +/* Homepage featured demo shell */ +.homepage-featured-demo__wrap { + max-width: 1120px; + margin: 0 auto var(--pf-global--spacer--lg); +} + +.homepage-featured-demo__shell { + position: relative; + width: 100%; + height: 0; + padding-bottom: calc(62.793% + 41px); + border-radius: 10px; + overflow: hidden; + background: radial-gradient(circle at 25% 25%, rgba(0, 102, 204, 0.22), transparent 45%), + radial-gradient(circle at 80% 20%, rgba(115, 89, 253, 0.24), transparent 42%), + linear-gradient(120deg, #0f1218 0%, #151922 50%, #10131a 100%); + box-shadow: 0 16px 44px rgba(0, 0, 0, 0.45); +} + +.homepage-featured-demo__ambient { + position: absolute; + inset: 0; + z-index: 1; + background: linear-gradient(100deg, transparent 12%, rgba(255, 255, 255, 0.14) 50%, transparent 88%); + background-size: 240% 100%; + animation: homepage-demo-sheen 2.8s ease-in-out infinite; + opacity: 1; + transition: opacity 0.35s ease; +} + +.homepage-featured-demo__shell.is-loaded .homepage-featured-demo__ambient { + opacity: 0; + pointer-events: none; +} + +.homepage-featured-demo__iframe { + position: absolute; + inset: 0; + z-index: 2; + width: 100%; + height: 100%; + border: 0; + color-scheme: light; +} + +@keyframes homepage-demo-sheen { + 0% { + background-position: 210% 0; + } + 100% { + background-position: -160% 0; + } +} diff --git a/static/css/demos.css b/static/css/demos.css new file mode 100644 index 0000000000..75b43fe825 --- /dev/null +++ b/static/css/demos.css @@ -0,0 +1,309 @@ +/* Interactive demos page */ + +.demos-page { + --demos-sidebar-width: min(360px, 36%); +} + +/* Hero: player + scrollable playlist (row 1), meta under player (row 2) */ +.demos-hero { + display: grid; + gap: var(--pf-global--spacer--lg); + margin-bottom: var(--pf-global--spacer--3xl); +} + +.demos-player { + min-width: 0; + scroll-margin-top: 5rem; +} + +.demos-hero__sidebar { + min-width: 0; +} + +.demos-sidebar__scroll { + display: flex; + flex-direction: column; + gap: var(--pf-global--spacer--md); +} + +.demos-sidebar-item { + flex-shrink: 0; + min-width: 0; +} + +/* Desktop: playlist matches player height; clip next item; scroll wheel stays in list */ +@media (min-width: 993px) { + .demos-hero { + grid-template-columns: minmax(0, 1fr) var(--demos-sidebar-width); + grid-template-rows: auto auto; + align-items: stretch; + } + + .demos-player { + grid-column: 1; + grid-row: 1; + } + + .demos-hero__sidebar { + grid-column: 2; + grid-row: 1; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + } + + .demos-sidebar__scroll { + flex: 1; + min-height: 0; + max-height: 100%; + overflow-y: auto; + overflow-x: hidden; + overscroll-behavior: contain; + scrollbar-width: none; + -ms-overflow-style: none; + outline: none; + } + + .demos-sidebar__scroll::-webkit-scrollbar { + display: none; + width: 0; + height: 0; + } + + .demos-hero__meta-main { + grid-column: 1; + grid-row: 2; + margin-top: 0; + } +} + +.demos-sidebar-item__title { + margin: var(--pf-global--spacer--sm) 0 0; + font-size: var(--pf-global--FontSize--sm); + font-weight: var(--pf-global--FontWeight--bold); + line-height: var(--pf-global--LineHeight--sm); + color: var(--pf-global--Color--100); + pointer-events: none; +} + +.demos-hero__meta-main { + margin-top: var(--pf-global--spacer--md); + min-width: 0; +} + +.demos-hero__title { + margin: 0 0 var(--pf-global--spacer--sm); + font-size: var(--pf-global--FontSize--2xl); + font-weight: var(--pf-global--FontWeight--bold); + line-height: var(--pf-global--LineHeight--md); +} + +.demos-hero__desc { + margin: 0 0 var(--pf-global--spacer--sm); + color: var(--pf-global--Color--200); + font-size: var(--pf-global--FontSize--md); + line-height: var(--pf-global--LineHeight--md); +} + +/* Clickable thumbnail cards — no iframes, YouTube-style selection */ +.demos-select { + display: block; + width: 100%; + border: 2px solid var(--pf-global--BorderColor--100); + border-radius: var(--pf-global--BorderRadius--sm); + overflow: hidden; + cursor: pointer; + background: #1a1a1a; + transition: border-color 0.15s ease, box-shadow 0.15s ease; + user-select: none; +} + +.demos-select:hover, +.demos-select:focus-visible { + border-color: var(--pf-global--primary-color--100); + box-shadow: var(--pf-global--BoxShadow--md); + outline: none; +} + +.demos-select--active { + border-color: var(--pf-global--primary-color--100); + box-shadow: 0 0 0 1px var(--pf-global--primary-color--100); +} + +.demos-select--active .demos-select__play { + opacity: 0; +} + +.demos-select__now-playing { + position: absolute; + top: var(--pf-global--spacer--sm); + left: var(--pf-global--spacer--sm); + z-index: 2; + padding: 0.15rem 0.5rem; + font-size: var(--pf-global--FontSize--xs); + font-weight: var(--pf-global--FontWeight--bold); + line-height: 1.2; + text-transform: uppercase; + letter-spacing: 0.03em; + color: #fff; + background: var(--pf-global--primary-color--100, #0066cc); + border-radius: var(--pf-global--BorderRadius--sm); + pointer-events: none; +} + +.demos-select__now-playing[hidden] { + display: none; +} + +.demos-select__media { + position: relative; + display: block; + aspect-ratio: 16 / 9; + overflow: hidden; + background: #1a1a1a; +} + +.demos-thumb__img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.demos-select__play { + position: absolute; + inset: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.35); + color: #fff; + font-size: 2.25rem; + transition: background 0.15s ease; + pointer-events: none; +} + +.demos-select:hover .demos-select__play { + background: rgba(0, 0, 0, 0.5); +} + +.demos-select--grid .demos-select__title { + margin: 0; + padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--md); + font-size: var(--pf-global--FontSize--md); + font-weight: var(--pf-global--FontWeight--bold); + line-height: var(--pf-global--LineHeight--sm); + color: var(--pf-global--Color--100); + background: var(--pf-global--BackgroundColor--100); + pointer-events: none; +} + +/* Single Arcade player (main area only) */ +.arcade-embed { + position: relative; + width: 100%; + padding-bottom: calc(62.793% + 41px); + height: 0; + overflow: hidden; + border-radius: var(--pf-global--BorderRadius--sm); + background: #e8e8e8; +} + +.arcade-embed__skeleton { + position: absolute; + inset: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(90deg, #e8e8e8 0%, #f5f5f5 50%, #e8e8e8 100%); + background-size: 200% 100%; + animation: demos-shimmer 1.4s ease-in-out infinite; +} + +.arcade-embed__skeleton::after { + content: ""; + width: 2.5rem; + height: 2.5rem; + border: 3px solid #d2d2d2; + border-top-color: var(--pf-global--primary-color--100, #0066cc); + border-radius: 50%; + animation: demos-spin 0.8s linear infinite; +} + +.arcade-embed--loaded .arcade-embed__skeleton { + opacity: 0; + visibility: hidden; + transition: opacity 0.2s ease; +} + +.arcade-embed__iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; + color-scheme: light; + opacity: 0; + transition: opacity 0.25s ease; +} + +.arcade-embed--loaded .arcade-embed__iframe { + opacity: 1; +} + +@keyframes demos-shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +@keyframes demos-spin { + to { transform: rotate(360deg); } +} + +.demos-next-steps { + padding-top: var(--pf-global--spacer--xl); + border-top: 1px solid var(--pf-global--BorderColor--100); +} + +.demos-next-steps ul { + margin: 0; + padding-left: 1.25rem; +} + +@media (max-width: 992px) { + .demos-hero { + grid-template-columns: 1fr; + } + + .demos-player, + .demos-hero__sidebar, + .demos-hero__meta-main { + grid-column: auto; + grid-row: auto; + } + + .demos-sidebar__scroll { + flex-direction: row; + flex-wrap: wrap; + overflow: visible; + } + + .demos-sidebar-item { + flex: 1 1 calc(50% - var(--pf-global--spacer--md)); + min-width: 200px; + } +} + +@media (max-width: 576px) { + .demos-sidebar__scroll { + flex-direction: column; + } + + .demos-sidebar-item { + flex: 1 1 100%; + } +} diff --git a/static/images/demos/deploy-pattern-on-rhdp.png b/static/images/demos/deploy-pattern-on-rhdp.png new file mode 100644 index 0000000000..2613dd53c6 Binary files /dev/null and b/static/images/demos/deploy-pattern-on-rhdp.png differ diff --git a/static/images/demos/placeholder.svg b/static/images/demos/placeholder.svg new file mode 100644 index 0000000000..92dbf4ba54 --- /dev/null +++ b/static/images/demos/placeholder.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/images/demos/rag-ai-application.png b/static/images/demos/rag-ai-application.png new file mode 100644 index 0000000000..19a9efa305 Binary files /dev/null and b/static/images/demos/rag-ai-application.png differ diff --git a/static/images/demos/rag-llm-gitops-azure.png b/static/images/demos/rag-llm-gitops-azure.png new file mode 100644 index 0000000000..663b3a8ed8 Binary files /dev/null and b/static/images/demos/rag-llm-gitops-azure.png differ diff --git a/static/images/demos/rag-llm-lenovo-sno.png b/static/images/demos/rag-llm-lenovo-sno.png new file mode 100644 index 0000000000..e2a97a3ef9 Binary files /dev/null and b/static/images/demos/rag-llm-lenovo-sno.png differ diff --git a/static/images/demos/rag-vp-ui-summit-2026.png b/static/images/demos/rag-vp-ui-summit-2026.png new file mode 100644 index 0000000000..a0648fe9d0 Binary files /dev/null and b/static/images/demos/rag-vp-ui-summit-2026.png differ diff --git a/static/images/demos/ramendr-dell-powerstore-dr.png b/static/images/demos/ramendr-dell-powerstore-dr.png new file mode 100644 index 0000000000..40bd2be12f Binary files /dev/null and b/static/images/demos/ramendr-dell-powerstore-dr.png differ diff --git a/static/images/demos/validated-patterns-ui.png b/static/images/demos/validated-patterns-ui.png new file mode 100644 index 0000000000..1d47b8c3ba Binary files /dev/null and b/static/images/demos/validated-patterns-ui.png differ diff --git a/static/js/demos.js b/static/js/demos.js new file mode 100644 index 0000000000..93426cf87f --- /dev/null +++ b/static/js/demos.js @@ -0,0 +1,175 @@ +(function () { + 'use strict'; + + var embedQuery = '[data-arcade-embed]'; + var embedBase = + 'https://demo.arcade.software/{id}?embed&embed_mobile=tab&embed_desktop=inline&squared=true&show_copy_link=true'; + + function markLoaded(iframe) { + var wrap = iframe.closest(embedQuery); + if (wrap) wrap.classList.add('arcade-embed--loaded'); + } + + function bindIframe(iframe, onLoad) { + iframe.addEventListener( + 'load', + function () { + markLoaded(iframe); + if (onLoad) onLoad(); + }, + { once: true } + ); + } + + function initSidebarScroll() { + var hero = document.querySelector('[data-demos-hero]'); + var player = document.querySelector('[data-demos-player]'); + var scrollEl = document.querySelector('[data-demos-sidebar-scroll]'); + var desktop = window.matchMedia('(min-width: 993px)'); + + if (!hero || !player || !scrollEl) return; + + function syncHeight() { + if (!desktop.matches) { + scrollEl.style.maxHeight = ''; + return; + } + var embed = player.querySelector('[data-arcade-embed]'); + if (!embed) return; + scrollEl.style.maxHeight = embed.offsetHeight + 'px'; + } + + syncHeight(); + + if ('ResizeObserver' in window) { + var ro = new ResizeObserver(syncHeight); + var embed = player.querySelector('[data-arcade-embed]'); + if (embed) ro.observe(embed); + } else { + window.addEventListener('resize', syncHeight); + } + + desktop.addEventListener('change', syncHeight); + } + + var mobileLayout = window.matchMedia('(max-width: 992px)'); + + function scrollToPlayer(player, instant) { + if (!mobileLayout.matches || !player) return; + player.scrollIntoView({ + behavior: instant ? 'auto' : 'smooth', + block: 'start', + }); + } + + function scrollToPlayerAfterLayout(player) { + if (!mobileLayout.matches || !player) return; + scrollToPlayer(player, true); + requestAnimationFrame(function () { + requestAnimationFrame(function () { + scrollToPlayer(player, true); + }); + }); + } + + function initPlayer() { + var page = document.querySelector('.demos-page'); + var hero = document.querySelector('[data-demos-hero]'); + if (!page || !hero) return; + + var player = page.querySelector('[data-demos-player]'); + var mainEmbed = player && player.querySelector(embedQuery); + var mainIframe = player && player.querySelector('iframe'); + var mainTitle = hero.querySelector('[data-demos-main-title]'); + var mainDesc = hero.querySelector('[data-demos-main-desc]'); + var mainPattern = hero.querySelector('[data-demos-main-pattern]'); + var selects = page.querySelectorAll('[data-demo-select]'); + + if (!mainIframe || !selects.length) return; + + var currentId = mainIframe.src.match(/demo\.arcade\.software\/([^?]+)/); + currentId = currentId ? currentId[1] : null; + + function setNowPlaying(demoId) { + selects.forEach(function (el) { + var match = el.getAttribute('data-demo-id') === demoId; + el.classList.toggle('demos-select--active', match); + var badge = el.querySelector('[data-demo-now-playing]'); + if (badge) badge.hidden = !match; + }); + } + + function playDemo(el) { + var id = el.getAttribute('data-demo-id'); + if (!id) return; + + var alreadyPlaying = id === currentId && mainIframe.src.indexOf(id) !== -1; + if (alreadyPlaying) { + scrollToPlayer(player, false); + return; + } + + /* Scroll before iframe reload so the first tap reaches the player on mobile */ + scrollToPlayerAfterLayout(player); + + if (mainEmbed) mainEmbed.classList.remove('arcade-embed--loaded'); + + mainIframe.title = el.getAttribute('data-demo-title') || 'Interactive demo'; + mainIframe.src = embedBase.replace('{id}', id); + bindIframe(mainIframe, function () { + scrollToPlayer(player, true); + }); + currentId = id; + + if (mainTitle) mainTitle.textContent = el.getAttribute('data-demo-title') || ''; + if (mainDesc) mainDesc.textContent = el.getAttribute('data-demo-desc') || ''; + + if (mainPattern) { + var link = el.getAttribute('data-demo-pattern-link'); + var label = el.getAttribute('data-demo-pattern-label'); + if (link && label) { + mainPattern.innerHTML = + 'For more information, see: ' + label + ''; + mainPattern.hidden = false; + } else { + mainPattern.hidden = true; + mainPattern.innerHTML = ''; + } + } + + setNowPlaying(id); + } + + selects.forEach(function (el) { + el.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + playDemo(el); + }); + + el.addEventListener('keydown', function (e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + playDemo(el); + } + }); + }); + + if (currentId) { + setNowPlaying(currentId); + } + + bindIframe(mainIframe); + } + + function init() { + initPlayer(); + initSidebarScroll(); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})();