diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index bd2265dc..7a2b3869 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -10,6 +10,7 @@ @import "search_project.scss"; @import "videos.scss"; @import "subscription.scss"; +@import "video-landing.scss"; .navbar-dark { min-height: 5rem; diff --git a/assets/scss/_videos.scss b/assets/scss/_videos.scss index 9071407b..23f1e04e 100644 --- a/assets/scss/_videos.scss +++ b/assets/scss/_videos.scss @@ -1,4 +1,4 @@ -.video-btn-wrapper { +.videobtn-wrapper { height: 60px; width: 60px; background-color: #00b39f; @@ -10,7 +10,7 @@ transform: translate(-50%, -50%); } - .video-btn-wrapper svg { + .videobtn-wrapper svg { height: 50%; width: 50%; margin-top: 5px; @@ -25,7 +25,7 @@ .play-icon-path { fill: #00b39f; } - .video-btn-wrapper { + .videobtn-wrapper { background-color: #ddd; } > .card-title { diff --git a/assets/scss/video-landing.scss b/assets/scss/video-landing.scss new file mode 100644 index 00000000..c967b00d --- /dev/null +++ b/assets/scss/video-landing.scss @@ -0,0 +1,453 @@ + +.video-page-container { + background: linear-gradient(270deg, rgba(71, 126, 150, 0.26) 0%, rgba(0, 179, 159, 0.54) 100%); + /* or,linear-gradient(135deg, #6a3093 0%, #1a4b94 50%, #00b39f 100%);*/ + /* or, linear-gradient(270deg, rgba(18, 18, 18, 0.16) 0.01%, rgba(71, 126, 150, 0.26) 51.1%, rgba(0, 179, 159, 0.54) 99.99%) */ + background-size: cover; + width: 100%; + position: relative; + overflow: hidden; + + nav { + //background-color: rgba(0, 0, 0, 0.3) !important; + background-color: transparent !important; + border: none; + } + nav.scrolled { + background-color: #121212 !important; + border: 1px solid #333 !important; + } +} + +.video-page-container::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9Ii0xNiAtMTMgNjYgNjYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxzdHlsZT4KLmNvbG9yTW9kZTEgewogICAgc3Ryb2tlOiAjZmZmOwogICAgc3Ryb2tlLW9wYWNpdHk6IDAuMgp9Cjwvc3R5bGU+CjxwYXRoIGQ9Ik0xNy41IDE0TDE3LjUgMjMiIGNsYXNzPSJjb2xvck1vZGUxIi8+CjxsaW5lIHgxPSIyMiIgeTE9IjE4LjczNTQiIHgyPSIxMyIgeTI9IjE4LjczNTQiIGNsYXNzPSJjb2xvck1vZGUxIi8+Cjwvc3ZnPgo="); + background-size: 2.5rem 2.5rem; + pointer-events: none; + z-index: 0; +} + +.hero-section-wrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 2rem 1rem 7rem; + position: relative; + z-index: 1; + color: #fff; +} + +.hero-section-wrapper h1 { + font-size: 3rem; + font-weight: 700; + margin-bottom: 1rem; + text-align: center; +} + +.hero-subtitle { + font-size: 1.25rem; + text-align: center; + max-width: 800px; + margin: 0 auto 3rem; + opacity: 0.9; +} + +.hero-video-wrapper { + max-width: 800px; + width: 90%; + margin: 0 auto; +} + +.hero-video-container { + border-radius: 12px; + overflow: hidden; + box-shadow: 0 15px 50px rgba(0, 0, 0, 0.3); + position: relative; + width: 100%; + padding-bottom: 56.25%; /* for 16:9 aspect ratio */ +} + +.bg-gradient-overlay { + background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.4)); +} + +.video-btn-wrapper { + width: 80px; + height: 80px; + background-color: #fff; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 10px 30px rgba(0, 179, 159, 0.4); + cursor: pointer; + transition: all 0.3s ease; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.video-btn-wrapper svg { + width: 40px; + height: 40px; +} + +.play-icon-svg-path { + fill: #00b39f; + transition: fill 0.3s ease; +} + +.video-btn-wrapper:hover { + background-color: #00b39f; + .play-icon-svg-path { + fill: #fff; + } +} + +.video-btn-wrapper:hover .play-icon-path { + fill: #fff; +} + +.video-tabs-container { + background: linear-gradient(to right top, #3d3d3d, #343434, #2b2b2b, #222222, #1a1a1a, #181818, #161616, #141414, #181818, #1c1c1c, #212121, #252525); + border-radius: 16px 16px 0 0; + padding: 2rem; + max-width: 1200px; + margin: -5rem auto 0; + position: relative; + z-index: 2; + box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.2); +} + +.category-tabs { + display: flex; + flex-wrap: wrap; + // overflow-x: auto; + gap: 0.5rem; + margin-bottom: 2rem; + padding-bottom: 0.5rem; +} + +.category-tabs::-webkit-scrollbar { + height: 4px; +} + +.category-tabs::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.05); + border-radius: 10px; +} + +.category-tabs::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 10px; +} + +.category-tab { + background: none; + border: none; + color: rgba(255,255,255,0.50); + padding: 0.75rem 1.5rem; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + gap: 0.75rem; + flex: 0 0 auto; + white-space: nowrap; + text-decoration: none; + display: flex; + flex-direction: column; +} + +.category-tab .tab-icon { + width: 2.5rem; + height: 2.5rem; + background-color: rgba(0, 0, 0, 0.05); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; +} + +.category-tab .tab-icon i { + font-size: 1.25rem; + color: #555; +} + +.category-tab:hover { + color: #fff; +} + +.category-tab:hover .tab-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.category-tab.active { + border-radius: 0; + border-bottom: 2px solid #00b39f; + color: #fff; +} + +.category-tab.active .tab-icon { + background-color: #00b39f; +} + +.category-tab.active .tab-icon i { + color: #fff; +} + +.subcategory-buttons { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-bottom: 2.5rem; +} + +.subcategory-btn { + background-color: rgba(0, 0, 0, 0.05); + color: #555; + padding: 0.5rem 1.25rem; + border-radius: 20px; + cursor: pointer; + transition: all 0.2s ease; + text-decoration: none; + box-shadow: 0 0 1px white; +} + +.subcategory-btn:hover { + background-color: rgba(0, 0, 0, 0.1); + color: #333; +} + +.subcategory-btn.active { + background-color: #00b39f; + color: #fff; +} + +.video-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1.5rem; + margin-bottom: 2rem; +} + +.video-card { + background-color: rgba(18,18,18,1); + border-radius: 12px; + overflow: hidden; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.video-card:hover { + transform: translateY(-5px); + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); + cursor: pointer; +} + +.video-thumbnail { + position: relative; + overflow: hidden; + aspect-ratio: 16/9; +} + +.video-thumbnail img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.3s ease; +} + +.video-card:hover .video-thumbnail img { + transform: scale(1.05); +} + +.play-button-overlay { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.3s ease, background 0.3s ease; +} + +.video-card:hover .play-button-overlay { + opacity: 1; + background: rgba(0, 0, 0, 0.3); +} + +.play-button { + width: 50px; + height: 50px; + background-color: rgba(0, 179, 159, 0.9); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transform: scale(0.8); + transition: transform 0.3s ease, background-color 0.3s ease; +} + +.play-button i { + font-size: 1.75rem; + color: #fff; +} + +.video-card:hover .play-button { + transform: scale(1); +} + +.video-info { + padding: 1.25rem; +} + +.video-info h3 { + margin-top: 0; + margin-bottom: 0.5rem; + font-size: 1.1rem; + font-weight: 600; +} + +.video-duration { + color: #00b39f; + font-size: 0.875rem; + margin-bottom: 0.45rem; +} + +.video-description { + color: #666; + font-size: 0.9375rem; + line-height: 1.5; + margin-bottom: 0; + font-style: italic; + margin-top: 0.6rem; +} + +.video-overlay, .video-iframe-container, .video-iframe-container iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.video-overlay { + z-index: 2; +} + +.video-iframe-container { + z-index: 1; + display: none; +} + +.video-iframe-container iframe { + border: none; +} + +@media (max-width: 992px) { + .hero-section-wrapper h1 { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1.125rem; + } + + .video-btn-wrapper { + width: 70px; + height: 70px; + } + + .video-btn-wrapper svg { + width: 35px; + height: 35px; + } +} + +@media (max-width: 768px) { + div.video-main-wrapper { + padding: 0 1.25rem; + } + .category-tabs { + gap: 0; + } + .hero-section-wrapper { + padding: 4rem 1rem 7rem; + } + + .hero-section-wrapper h1 { + font-size: 2rem; + } + + .video-grid { + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + } + + .category-tab { + padding: 0.6rem 1rem; + width: 50%; + } + + .category-tab .tab-icon { + width: 2rem; + height: 2rem; + } + + .category-tab .tab-icon i { + font-size: 1rem; + } +} + +@media (max-width: 576px) { + .hero-section-wrapper { + padding: 3rem 1rem 7rem; + } + + .hero-section-wrapper h1 { + font-size: 1.75rem; + } + + .hero-subtitle { + font-size: 1rem; + } + + .video-btn-wrapper { + width: 60px; + height: 60px; + } + + .video-btn-wrapper svg { + width: 30px; + height: 30px; + } + + .video-tabs-container { + padding: 1.5rem; + } + + .video-grid { + grid-template-columns: 1fr; + } + + .subcategory-buttons { + gap: 0.5rem; + margin-bottom: 2rem; + } + + .subcategory-btn { + padding: 0.4rem 1rem; + font-size: 0.875rem; + } + .category-tab { + width: 50%; + } +} diff --git a/content/en/videos/_index.md b/content/en/videos/_index.md index 95163b04..cab02646 100644 --- a/content/en/videos/_index.md +++ b/content/en/videos/_index.md @@ -1,10 +1,14 @@ --- -title: Videos +title: Layer5’s Cloud and Kanvas Video Resources description: > - Videos on Cloud and Kanvas + A curated library of videos to help you get started, personalize your environment, and navigate the features of Layer5 Cloud and Kanvas with confidence. linkTitle: Videos type: video cascade: type: video +weight: 2 +featured_video: true +featured_image: /images/kanvas/layer5-kanvas-designer.webp +layout: "video" +video_id: Do7htKrRzDA --- - diff --git a/content/en/videos/advanced/_index.md b/content/en/videos/advanced/_index.md index 3f455be1..4cbd9848 100644 --- a/content/en/videos/advanced/_index.md +++ b/content/en/videos/advanced/_index.md @@ -1,9 +1,10 @@ --- -title: Advanced Videos +title: Advanced description: > Advanced Videos on Cloud and Kanvas linkTitle: Advanced Videos weight: 4 videoGrid: true +icon: bi-diagram-3-fill --- diff --git a/content/en/videos/intermediate/_index.md b/content/en/videos/features/_index.md similarity index 82% rename from content/en/videos/intermediate/_index.md rename to content/en/videos/features/_index.md index 601eff5c..79fe507b 100644 --- a/content/en/videos/intermediate/_index.md +++ b/content/en/videos/features/_index.md @@ -1,9 +1,10 @@ --- -title: Feature Videos +title: Features description: > Watch these videos to learn more about the features of the Layer5 Cloud and Kanvas platforms. linkTitle: Features weight: 3 videoGrid: true +icon: bi-gear-fill --- diff --git a/content/en/videos/features/cloud/_index.md b/content/en/videos/features/cloud/_index.md new file mode 100644 index 00000000..97536ae7 --- /dev/null +++ b/content/en/videos/features/cloud/_index.md @@ -0,0 +1,4 @@ +--- +title: Cloud +videoGrid: true +--- \ No newline at end of file diff --git a/content/en/videos/features/cloud/white-label.md b/content/en/videos/features/cloud/white-label.md new file mode 100644 index 00000000..a3299369 --- /dev/null +++ b/content/en/videos/features/cloud/white-label.md @@ -0,0 +1,9 @@ +--- +title: White-labelling +description: "Layer5 Cloud deployments are highly customizable See https://docs.layer5.io/cloud/self-hos... for more details." +video_id: "hZuhmP7lenk" +videoType: "youtube" +tags: [cloud] +duration: "0:18" +--- +{{< youtube hZuhmP7lenk >}} \ No newline at end of file diff --git a/content/en/videos/features/kanvas/_index.md b/content/en/videos/features/kanvas/_index.md new file mode 100644 index 00000000..0653c918 --- /dev/null +++ b/content/en/videos/features/kanvas/_index.md @@ -0,0 +1,3 @@ +--- +title: Kanvas +--- \ No newline at end of file diff --git a/content/en/videos/features/kanvas/design-review.md b/content/en/videos/features/kanvas/design-review.md new file mode 100644 index 00000000..8a109a67 --- /dev/null +++ b/content/en/videos/features/kanvas/design-review.md @@ -0,0 +1,13 @@ +--- +title: "Design Reviews in Kanvas" +description: > + Add comments to your designs in Kanvas's Designer Mode to enhance collaboration and streamline design reviews. +video_id: "bb6J--aApk8" +videoType: youtube # or "local" +categories: [Designer] +formats: [video] +tags: [review, collaboration, comments] +duration: "0:17" +--- + +{{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/features/meshery/_index.md b/content/en/videos/features/meshery/_index.md new file mode 100644 index 00000000..04ccdb69 --- /dev/null +++ b/content/en/videos/features/meshery/_index.md @@ -0,0 +1,3 @@ +--- +title: Meshery +--- \ No newline at end of file diff --git a/content/en/videos/intermediate/meshery/meshery-teaser.md b/content/en/videos/features/meshery/meshery-teaser.md similarity index 100% rename from content/en/videos/intermediate/meshery/meshery-teaser.md rename to content/en/videos/features/meshery/meshery-teaser.md diff --git a/content/en/videos/getting-started/_index.md b/content/en/videos/getting-started/_index.md index fa3ec0fa..af3cc465 100644 --- a/content/en/videos/getting-started/_index.md +++ b/content/en/videos/getting-started/_index.md @@ -1,8 +1,9 @@ --- -title: Getting Started Videos +title: Getting Started description: > - Getting started Video on Cloud and Kanvas + Getting started videos on Cloud and Kanvas linkTitle: Getting Started weight: 2 +icon: bi-rocket-takeoff-fill videoGrid: true --- \ No newline at end of file diff --git a/content/en/videos/getting-started/comments/_index.md b/content/en/videos/getting-started/comments/_index.md new file mode 100644 index 00000000..2c20ba29 --- /dev/null +++ b/content/en/videos/getting-started/comments/_index.md @@ -0,0 +1,4 @@ +--- +title: Design Review +videoGrid: true +--- diff --git a/content/en/videos/getting-started/comments/adding-cm4.md b/content/en/videos/getting-started/comments/adding-cm4.md index 9613a6c5..0562b7a4 100644 --- a/content/en/videos/getting-started/comments/adding-cm4.md +++ b/content/en/videos/getting-started/comments/adding-cm4.md @@ -10,6 +10,7 @@ loop: true #optional categories: [Designer] formats: [video] tags: [review, collaboration, comments] +duration: "0:17" --- {{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/getting-started/comments/adding-comments.md b/content/en/videos/getting-started/comments/adding-comments.md index 9613a6c5..0562b7a4 100644 --- a/content/en/videos/getting-started/comments/adding-comments.md +++ b/content/en/videos/getting-started/comments/adding-comments.md @@ -10,6 +10,7 @@ loop: true #optional categories: [Designer] formats: [video] tags: [review, collaboration, comments] +duration: "0:17" --- {{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/getting-started/configuration/_index.md b/content/en/videos/getting-started/configuration/_index.md new file mode 100644 index 00000000..242234e7 --- /dev/null +++ b/content/en/videos/getting-started/configuration/_index.md @@ -0,0 +1,4 @@ +--- +title: Configuration +videoGrid: true +--- \ No newline at end of file diff --git a/content/en/videos/getting-started/configuration/configuration.md b/content/en/videos/getting-started/configuration/configuration.md new file mode 100644 index 00000000..b2f72c62 --- /dev/null +++ b/content/en/videos/getting-started/configuration/configuration.md @@ -0,0 +1,13 @@ +--- +title: "Design Reviews: Adding Comments 2" +description: > + Add comments to your designs in Kanvas's Designer Mode to enhance collaboration and streamline design reviews. +video_id: "bb6J--aApk8" +videoType: youtube +categories: [Designer] +formats: [video] +tags: [review, collaboration, comments] +duration: "0:17" +--- + +{{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/getting-started/onboarding/_index.md b/content/en/videos/getting-started/onboarding/_index.md new file mode 100644 index 00000000..e3a66522 --- /dev/null +++ b/content/en/videos/getting-started/onboarding/_index.md @@ -0,0 +1,4 @@ +--- +title: Onboarding +videoGrid: true +--- \ No newline at end of file diff --git a/content/en/videos/getting-started/comments/adding-c.md b/content/en/videos/getting-started/onboarding/video-1.md similarity index 86% rename from content/en/videos/getting-started/comments/adding-c.md rename to content/en/videos/getting-started/onboarding/video-1.md index 9613a6c5..535c1b2a 100644 --- a/content/en/videos/getting-started/comments/adding-c.md +++ b/content/en/videos/getting-started/onboarding/video-1.md @@ -1,5 +1,5 @@ --- -title: "Design Reviews: Adding Comments" +title: "Design Reviews: Adding Comments 1" description: > Add comments to your designs in Kanvas's Designer Mode to enhance collaboration and streamline design reviews. video_id: "bb6J--aApk8" @@ -10,6 +10,7 @@ loop: true #optional categories: [Designer] formats: [video] tags: [review, collaboration, comments] +duration: 2:30 --- {{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/getting-started/comments/adding-cm2.md b/content/en/videos/getting-started/onboarding/video-2.md similarity index 86% rename from content/en/videos/getting-started/comments/adding-cm2.md rename to content/en/videos/getting-started/onboarding/video-2.md index 9613a6c5..4640f878 100644 --- a/content/en/videos/getting-started/comments/adding-cm2.md +++ b/content/en/videos/getting-started/onboarding/video-2.md @@ -1,5 +1,5 @@ --- -title: "Design Reviews: Adding Comments" +title: "Design Reviews: Adding Comments 2" description: > Add comments to your designs in Kanvas's Designer Mode to enhance collaboration and streamline design reviews. video_id: "bb6J--aApk8" @@ -10,6 +10,7 @@ loop: true #optional categories: [Designer] formats: [video] tags: [review, collaboration, comments] +duraiton: 3:40 --- {{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/getting-started/onboarding/video-3.md b/content/en/videos/getting-started/onboarding/video-3.md new file mode 100644 index 00000000..c6c0b3ff --- /dev/null +++ b/content/en/videos/getting-started/onboarding/video-3.md @@ -0,0 +1,16 @@ +--- +title: "Design Reviews: Adding Comments 3" +description: > + Add comments to your designs in Kanvas's Designer Mode to enhance collaboration and streamline design reviews. +video_id: "bb6J--aApk8" +videoType: youtube # or "local" +muted: true # optional +autoplay: true # optional +loop: true #optional +categories: [Designer] +formats: [video] +tags: [review, collaboration, comments] +duration: 5:30 +--- + +{{< youtube bb6J--aApk8 >}} \ No newline at end of file diff --git a/content/en/videos/product/_index.md b/content/en/videos/product/_index.md new file mode 100644 index 00000000..d850ba7f --- /dev/null +++ b/content/en/videos/product/_index.md @@ -0,0 +1,9 @@ +--- +title: Products +description: > + Product Related videos +linkTitle: Product Videos +weight: 3 +icon: bi-box-seam +videoGrid: true +--- \ No newline at end of file diff --git a/content/en/videos/product/kanvas/_index.md b/content/en/videos/product/kanvas/_index.md new file mode 100644 index 00000000..0653c918 --- /dev/null +++ b/content/en/videos/product/kanvas/_index.md @@ -0,0 +1,3 @@ +--- +title: Kanvas +--- \ No newline at end of file diff --git a/content/en/videos/product/kanvas/kanvas-birth.md b/content/en/videos/product/kanvas/kanvas-birth.md new file mode 100644 index 00000000..c7ef6b4c --- /dev/null +++ b/content/en/videos/product/kanvas/kanvas-birth.md @@ -0,0 +1,15 @@ +--- +title: "Birth of Kanvas Logo" +description: "A visually transformation of the Meshery logo into the Kanvas logo." +videoType: "youtube" +video_id: "4WcofErPTx4" +muted: true # optional +autoplay: true # optional +loop: true #optional +tags: [meshery] +duration: "2:10" +--- + +{{< youtube 4WcofErPTx4 >}} + +This video captures the evolutionary transition of Meshery into Kanvas. As a distribution of Meshery, Kanvas is and opinionated user experience. \ No newline at end of file diff --git a/content/en/videos/product/meshery/_index.md b/content/en/videos/product/meshery/_index.md new file mode 100644 index 00000000..72376dc8 --- /dev/null +++ b/content/en/videos/product/meshery/_index.md @@ -0,0 +1,3 @@ +--- +title: meshery +--- \ No newline at end of file diff --git a/content/en/videos/intermediate/layer5/kanvas.md b/content/en/videos/product/meshery/meshery-teaser.md similarity index 51% rename from content/en/videos/intermediate/layer5/kanvas.md rename to content/en/videos/product/meshery/meshery-teaser.md index fd1f80e4..4ee068a4 100644 --- a/content/en/videos/intermediate/layer5/kanvas.md +++ b/content/en/videos/product/meshery/meshery-teaser.md @@ -1,10 +1,12 @@ --- -title: "Layer5 Kanvas Designer" -description: "Layer5 Kanvas is like Figma for DevOps. Design, deploy and manage your cloud native infrastructure." +title: "Meshery Playground Teaser Video" +description: "Meshery Playground - Explore features and capabilities of Meshery." video_id: "Do7htKrRzDA" videoType: youtube # or "local" muted: true # optional autoplay: true # optional loop: true #optional +tags: [meshery] +duration: "2:10" --- {{< youtube Do7htKrRzDA >}} \ No newline at end of file diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 9188d552..d4e9c05b 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -18,7 +18,7 @@ - + {{ partialCached "favicon.html" . }} {{- if .IsHome -}} diff --git a/layouts/partials/landing-page-videos.html b/layouts/partials/landing-page-videos.html new file mode 100644 index 00000000..ea5b1cd0 --- /dev/null +++ b/layouts/partials/landing-page-videos.html @@ -0,0 +1,301 @@ +{{ $videoContentDir := .Site.GetPage "section" "videos" }} + + <!-- video categories section --> + <div class="video-tabs-container"> + + <!-- category tabs --> + <div class="category-tabs"> + {{ $currentPage := . }} + {{ range $index, $section := $videoContentDir.Sections }} + <a href="#category-{{ $index }}" class="category-tab" data-category="{{ $index }}"> + <div class="tab-icon"> + {{ if .Params.icon }} + <i class="bi {{ .Params.icon }}"></i> + {{ else }} + <i class="bi bi-collection-play"></i> + {{ end }} + </div> + <span>{{ .Title }}</span> + </a> + {{ end }} + </div> + + <!-- subcategory container --> + <div class="subcategory-container"> + {{ range $mainIndex, $mainSection := $videoContentDir.Sections }} + <div class="subcategory-group" id="subcategory-group-{{ $mainIndex }}" style="display: none;"> + <div class="subcategory-buttons"> + <!-- if a category has at least 1 subcategory --> + {{ if gt (len .Sections) 0 }} + {{ range $subIndex, $subSection := .Sections }} + <a href="#category-{{ $mainIndex }}-subcategory-{{ $subIndex }}" class="subcategory-btn" + data-main-category="{{ $mainIndex }}" data-subcategory="{{ $subIndex }}"> + {{ .Title }} + </a> + {{ end }} + {{ else }} + <!-- if no subcategories i.e. videos are directly in category folder: set a default "All" subcategory --> + <a href="#category-{{ $mainIndex }}-subcategory-main" class="subcategory-btn" + data-main-category="{{ $mainIndex }}" data-subcategory="main"> + All + </a> + {{ end }} + </div> + </div> + {{ end }} + </div> + + + <!-- video grid container --> + <div class="video-grid-container"> + {{ range $mainIndex, $mainSection := $videoContentDir.Sections }} + <!-- display videos from subcategories --> + {{ range $subIndex, $subSection := .Sections }} + <div class="video-group" id="video-group-{{ $mainIndex }}-{{ $subIndex }}" style="display: none;"> + <div class="video-grid"> + {{ range $subSection.Pages }} + <div class="video-card" + data-video-id="{{ .Params.video_id }}" + data-video-title="{{ .Title }}" + data-video-url="{{ .RelPermalink }}" + > + <div class="video-thumbnail"> + {{ if .Params.videoType }} + {{ if eq .Params.videoType "youtube" }} + <img src="https://i.ytimg.com/vi/{{ .Params.video_id }}/maxresdefault.jpg" alt="{{ .Title }}"> + {{ else if .Params.thumbnail }} + <img src="{{ .Params.thumbnail }}" alt="{{ .Title }}"> + {{ else }} + <img src="/images/video-placeholder-thumbnail.jpg" alt="{{ .Title }}"> + {{ end }} + {{ else }} + <img src="/images/video-placeholder-thumbnail.jpg" alt="{{ .Title }}"> + {{ end }} + <div class="play-button-overlay"> + <div class="play-button"> + <i class="bi bi-play-fill"></i> + </div> + </div> + </div> + <div class="video-info"> + <h3>{{ .Title }}</h3> + {{ if .Params.duration }} + <div class="video-duration"> + <i class="bi bi-clock"></i> + <p class="video-duration" style="display: inline; margin-left: .25rem;">{{ .Params.duration }} min</p> + </div> + {{ end }} + {{ if .Params.tags }} + <div class="taxonomy-terms" style="margin-bottom: 0.6rem;"> + {{ range .Params.tags }} + <a href="/tags/{{ . }}"><span class="taxonomy-term" style="font-size: .9rem">{{ . }}</span></a> + {{ end }} + </div> + {{ end }} + <p class="video-description">{{ .Description | truncate 100 }}</p> + </div> + </div> + {{ end }} + </div> + </div> + {{ end }} + + <!-- for direct videos in main category (when no subcategories) --> + {{ if eq (len .Sections) 0 }} + <div class="video-group" id="video-group-{{ $mainIndex }}-0" style="display: none;"> + <div class="video-grid"> + {{ range where $mainSection.Pages "Kind" "page" }} + <div class="video-card" + data-video-id="{{ .Params.video_id }}" + data-video-title="{{ .Title }}" + data-video-url="{{ .RelPermalink }}" + > + <div class="video-thumbnail"> + {{ if .Params.videoType }} + {{ if eq .Params.videoType "youtube" }} + <img src="https://i.ytimg.com/vi/{{ .Params.video_id }}/maxresdefault.jpg" alt="{{ .Title }}"> + {{ else if .Params.thumbnail }} + <img src="{{ .Params.thumbnail }}" alt="{{ .Title }}"> + {{ else }} + <img src="/images/video-placeholder-thumbnail.jpg" alt="{{ .Title }}"> + {{ end }} + {{ else }} + <img src="/images/video-placeholder-thumbnail.jpg" alt="{{ .Title }}"> + {{ end }} + <div class="play-button-overlay"> + <div class="play-button"> + <i class="bi bi-play-fill"></i> + </div> + </div> + </div> + <div class="video-info"> + <h3>{{ .Title }}</h3> + {{ if .Params.duration }} + <div class="video-duration"> + <i class="bi bi-clock"></i> + <p class="video-duration" style="display: inline; margin-left: .25rem;">{{ .Params.duration }} min</p> + </div> + {{ end }} + {{ if .Params.tags }} + <div class="taxonomy-terms"> + {{ range .Params.tags }} + <a href="/tags/{{ . }}"><span class="taxonomy-term" style="font-size: .9rem">{{ . }}</span></a> + {{ end }} + </div> + {{ end }} + <p class="video-description">{{ .Description | truncate 100 }}</p> + </div> + </div> + {{ end }} + </div> + </div> + {{ end }} + {{ end }} + </div> + </div> + + <div class="modal fade" id="videoModal" tabindex="-1" aria-labelledby="videoModalLabel" aria-hidden="true"> + <div class="modal-dialog modal-lg"> + <div class="modal-content" style="padding: 20px 20px 0;background-color: #333;"> + <div class="modal-header"> + <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" style="background-color: #00d3a9;"></button> + </div> + <div class="modal-body p-0"> + <div class="ratio ratio-16x9"> + <iframe + id="vidIframe" + src="" + title="" + frameborder="0" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" + allowfullscreen> + </iframe> + </div> + <a href="" id="videoPageLink"><h4 id="videoModalTitle" style="padding: 1rem 0 2rem !important;"></h4></a> + </div> + </div> + + </div> + </div> + </div> + <script> + document.addEventListener('DOMContentLoaded', function() { + const categoryTabs = document.querySelectorAll('.category-tab'); + const subcategoryBtns = document.querySelectorAll('.subcategory-btn'); + + // update active states and show/hide content + function updateContent(mainCategoryIndex, subCategoryIndex = 0) { + // update active main category + categoryTabs.forEach(tab => tab.classList.remove('active')); + categoryTabs[mainCategoryIndex].classList.add('active'); + + // show/hide subcategory groups + const subcategoryGroups = document.querySelectorAll('.subcategory-group'); + subcategoryGroups.forEach(group => group.style.display = 'none'); + const activeSubcategoryGroup = document.getElementById(`subcategory-group-${mainCategoryIndex}`); + if (activeSubcategoryGroup) { + activeSubcategoryGroup.style.display = 'block'; + } + + // update active subcategory + const currentSubcategoryBtns = document.querySelectorAll(`.subcategory-btn[data-main-category="${mainCategoryIndex}"]`); + currentSubcategoryBtns.forEach(btn => btn.classList.remove('active')); + if (currentSubcategoryBtns.length > 0 && subCategoryIndex < currentSubcategoryBtns.length) { + currentSubcategoryBtns[subCategoryIndex].classList.add('active'); + } + + // show/hide video groups + const videoGroups = document.querySelectorAll('.video-group'); + videoGroups.forEach(group => group.style.display = 'none'); + const activeVideoGroup = document.getElementById(`video-group-${mainCategoryIndex}-${subCategoryIndex}`); + if (activeVideoGroup) { + activeVideoGroup.style.display = 'block'; + } + + // update url hash, can later modify this to have + // this: category-getting-started-subcategory-onboarding + // instead of: category-0-subcategory-1 + + window.location.hash = `category-${mainCategoryIndex}-subcategory-${subCategoryIndex}`; + } + + // Add click handlers to main category tabs + categoryTabs.forEach((tab, index) => { + tab.addEventListener('click', function(e) { + e.preventDefault(); + updateContent(index); + }); + }); + + // Add click handlers to subcategory buttons + subcategoryBtns.forEach(btn => { + btn.addEventListener('click', function(e) { + e.preventDefault(); + const mainCategoryIndex = parseInt(this.getAttribute('data-main-category')); + const subCategoryIndex = parseInt(this.getAttribute('data-subcategory')); + updateContent(mainCategoryIndex, subCategoryIndex); + }); + }); + + // handle initial load and urL hash changes + function handleHashChange() { + const hash = window.location.hash; + if (hash) { + // parse hash like #category-0-subcategory-1 + const matches = hash.match(/#category-(\d+)(?:-subcategory-(\d+))?/); + if (matches) { + const mainCategoryIndex = parseInt(matches[1]); + const subCategoryIndex = matches[2] ? parseInt(matches[2]) : 0; + updateContent(mainCategoryIndex, subCategoryIndex); + return; + } + } + + // default to first category and subcategory if no hash or invalid hash (alphabetially for now) + updateContent(0, 0); + } + + // handle hash changes + window.addEventListener('hashchange', handleHashChange); + + // hndle initial load + handleHashChange(); + }); + + </script> + +<script> + document.addEventListener('DOMContentLoaded', function () { + const modalElement = document.getElementById('videoModal'); + const modal = new bootstrap.Modal(modalElement); + const iframe = document.getElementById('vidIframe'); + const videoTitleElem = document.getElementById('videoModalTitle'); + const linkElem = document.getElementById('videoPageLink'); + + const videoCards = document.querySelectorAll('.video-card'); + + videoCards.forEach(card => { + card.addEventListener('click', function () { + const videoId = card.getAttribute('data-video-id'); + const videoTitle = card.getAttribute('data-video-title'); + const videoUrl = card.getAttribute('data-video-url'); + + // prep the modal + videoTitleElem.textContent = videoTitle; + linkElem.href = videoUrl; + iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&modestbranding=1&showinfo=0`; // autoplay=1 starts playing the vid + + modal.show(); + }); + }); + + // on modal close, clear iframe src to stop the vid + modalElement.addEventListener('hidden.bs.modal', function () { + iframe.src = ''; + }); + }); + + document.getElementById('videoModal').addEventListener('hidden.bs.modal', () => { + console.log('Modal closed event fired'); + }); + </script> \ No newline at end of file diff --git a/layouts/partials/video-section-index.html b/layouts/partials/video-section-index.html index fda64662..80335bbd 100644 --- a/layouts/partials/video-section-index.html +++ b/layouts/partials/video-section-index.html @@ -21,7 +21,26 @@ {{ else if $page.Params.videoGrid -}} <div class="container"> <div class="row"> - {{ range $pages -}} + + {{ $currentPage := . }} + + {{ $videoPages := slice }} + + {{ if .File }} + <!-- {{/* get videos directly inside this section */}} + + --> + {{ $directChildren := (where .Pages "Kind" "page") }} + {{ $videoPages = $videoPages | append $directChildren }} + + <!-- {{/* get videos from immediate sub sections */}} --> + {{ range .Sections }} + {{ $subpages := (where .Pages "Kind" "page") }} + {{ $videoPages = $videoPages | append $subpages }} + {{ end }} + {{ end }} + + {{ range $videoPages -}} {{ $manualLink := cond (isset .Params "manuallink") .Params.manualLink ( cond (isset .Params "manuallinkrelref") (relref . .Params.manualLinkRelref) .RelPermalink) }} <a href="{{ $manualLink }}" {{ with .Params.manualLinkTitle }} title="{{ . }}"{{ end }} @@ -53,7 +72,7 @@ </div> {{ end }} <div class="position-absolute top-0 start-0 w-100 h-100 bg-gradient-overlay"> - <div class="video-btn-wrapper position-absolute top-50 start-50"> + <div class="videobtn-wrapper position-absolute top-50 start-50"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57 60"> <path class="play-icon-path" d="M39.5298 29.028L21.7045 39.395C21.6471 39.4284 21.5893 39.4603 21.5311 39.4908C20.9134 39.8161 20.2107 40 19.4654 40C16.9992 40 15 37.9861 15 35.5018V14.5102C15 13.6377 15.2466 12.8233 15.6734 12.1337C16.9369 10.0722 19.6075 9.38388 21.7044 10.6034L39.5291 20.97C40.2869 21.3504 40.9459 21.9517 41.401 22.7457C41.811 23.4611 42.0038 24.2428 41.9999 25.0133C41.999 25.7747 41.806 26.5461 41.4009 27.2527C40.9461 28.0464 40.2873 28.6476 39.5298 29.028Z"/> </svg> diff --git a/layouts/partials/video-section-related.html b/layouts/partials/video-section-related.html index c8dc7cd1..1d98e6c6 100644 --- a/layouts/partials/video-section-related.html +++ b/layouts/partials/video-section-related.html @@ -61,7 +61,7 @@ <h2>Related Videos</h2> </div> <div class="position-absolute top-0 start-0 w-100 h-100 bg-gradient-overlay"> <div - class="video-btn-wrapper position-absolute top-50 start-50 translate-middle"> + class="videobtn-wrapper position-absolute top-50 start-50 translate-middle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57 60"> <path class="play-icon-path" d="M39.5298 29.028L21.7045 39.395C21.6471 39.4284 21.5893 39.4603 21.5311 39.4908C20.9134 39.8161 20.2107 40 19.4654 40C16.9992 40 15 37.9861 15 35.5018V14.5102C15 13.6377 15.2466 12.8233 15.6734 12.1337C16.9369 10.0722 19.6075 9.38388 21.7044 10.6034L39.5291 20.97C40.2869 21.3504 40.9459 21.9517 41.401 22.7457C41.811 23.4611 42.0038 24.2428 41.9999 25.0133C41.999 25.7747 41.806 26.5461 41.4009 27.2527C40.9461 28.0464 40.2873 28.6476 39.5298 29.028Z" /> @@ -89,7 +89,7 @@ <h4 class="video-title text-white mb-0">{{ .page.Title }}</h4> </div> <div class="position-absolute top-0 start-0 w-100 h-100 bg-gradient-overlay"> <div - class="video-btn-wrapper position-absolute top-50 start-50 translate-middle"> + class="videobtn-wrapper position-absolute top-50 start-50 translate-middle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57 60"> <path class="play-icon-path" d="M39.5298 29.028L21.7045 39.395C21.6471 39.4284 21.5893 39.4603 21.5311 39.4908C20.9134 39.8161 20.2107 40 19.4654 40C16.9992 40 15 37.9861 15 35.5018V14.5102C15 13.6377 15.2466 12.8233 15.6734 12.1337C16.9369 10.0722 19.6075 9.38388 21.7044 10.6034L39.5291 20.97C40.2869 21.3504 40.9459 21.9517 41.401 22.7457C41.811 23.4611 42.0038 24.2428 41.9999 25.0133C41.999 25.7747 41.806 26.5461 41.4009 27.2527C40.9461 28.0464 40.2873 28.6476 39.5298 29.028Z" /> diff --git a/layouts/video/video.html b/layouts/video/video.html new file mode 100644 index 00000000..634926fe --- /dev/null +++ b/layouts/video/video.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html itemscope itemtype="http://schema.org/WebPage" lang="{{ .Site.Language.Lang }}" class="no-js"> + +<head> + {{ partial "head.html" . }} +</head> +<body class="td-{{ .Kind }}{{ with .Page.Params.body_class }} {{ . }}{{ end }}"> + <div class="video-page-container"> + <div class="navbar-sticky-wrapper" style="min-height: 5rem;"> + <header>{{ partial "navbar.html" . }}</header> + </div> + <div class="hero-section-wrapper"> + <h1>{{ .Title }}</h1> + <p class="hero-subtitle">{{ .Description }}</p> + + {{ if .Params.featured_video }} + <div class="hero-video-wrapper"> + <div class="hero-video-container" id="videoContainer"> + <div class="video-overlay bg-gradient-overlay"> + <div style="max-height: 100%;"> + <img src="{{ .Params.featured_image }}" alt="{{ .Title }}" style="width: 100%; height: 100%; object-fit: cover;"> + </div> + <div class="video-btn-wrapper"> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57 60"> + <path class="play-icon-svg-path" d="M39.5298 29.028L21.7045 39.395C21.6471 39.4284 21.5893 39.4603 21.5311 39.4908C20.9134 39.8161 20.2107 40 19.4654 40C16.9992 40 15 37.9861 15 35.5018V14.5102C15 13.6377 15.2466 12.8233 15.6734 12.1337C16.9369 10.0722 19.6075 9.38388 21.7044 10.6034L39.5291 20.97C40.2869 21.3504 40.9459 21.9517 41.401 22.7457C41.811 23.4611 42.0038 24.2428 41.9999 25.0133C41.999 25.7747 41.806 26.5461 41.4009 27.2527C40.9461 28.0464 40.2873 28.6476 39.5298 29.028Z" /> + </svg> + </div> + </div> + + <div class="video-iframe-container"> + <iframe + id="videoIframe" + src="" + title="{{ .Title }}" + frameborder="0" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" + allowfullscreen + ></iframe> + </div> + </div> + </div> + {{ end }} + </div> + </div> + + <div class="container-fluid video-main-wrapper"> + {{ partial "landing-page-videos.html" . }} + {{ partial "footer.html" . }} + </div> + {{ partial "scripts.html" . }} + {{ partial "image-modal.html" . }} + + +<script> +var navbar = document.querySelector('nav'); +window.onscroll = function() { + // pageYOffset or scrollY + if (window.pageYOffset > 0) { + navbar.classList.add('scrolled') + } else { + navbar.classList.remove('scrolled') + } +} + +document.addEventListener('DOMContentLoaded', function() { + const videoContainer = document.getElementById('videoContainer'); + const videoOverlay = videoContainer.querySelector('.video-overlay'); + const iframeContainer = videoContainer.querySelector('.video-iframe-container'); + const videoIframe = document.getElementById('videoIframe'); + + videoContainer.addEventListener('click', function() { + // set the iframe src with autoplay parameter + videoIframe.src = "https://www.youtube.com/embed/{{ .Params.video_id }}?autoplay=1"; + + // hide the overlay, show the iframe + videoOverlay.style.display = 'none'; + iframeContainer.style.display = 'block'; + }); + }); +</script> + +</body> + +</html> diff --git a/static/images/kanvas/layer5-kanvas-designer.webp b/static/images/kanvas/layer5-kanvas-designer.webp new file mode 100644 index 00000000..0bc9841f Binary files /dev/null and b/static/images/kanvas/layer5-kanvas-designer.webp differ diff --git a/static/images/video-placeholder-thumbnail.jpg b/static/images/video-placeholder-thumbnail.jpg new file mode 100644 index 00000000..77332a4e Binary files /dev/null and b/static/images/video-placeholder-thumbnail.jpg differ