New homepage (#2172)

* two new sections

* enterprise capabilities and enterprise ready sections

* sections: engineered-for-builders and performance-by-design

* sections: cta-banner, integrations-logos, solutions

# Conflicts:
#	qdrant-landing/themes/qdrant-2024/assets/css/partials/_cta-banner.scss
#	qdrant-landing/themes/qdrant-2024/layouts/partials/cta-banner.html

* remove old sections from index.html

* wip: home page

* reuse links, carousel width

* globe and globe lights

* globe lights

* finalyzing the globe, add customers icons

* new icons set + svg partial update

* upd icons in the enterprise-ready section

* lines background

* globe lights as gradient and svg

* fix carousel responsiveness

* fix cut box shadow

* accordion slider responsiveness

* new hero

* hero customers

* some hero responsiveness

* customers layout fix

* cards responsiveness

* fixes

* remove floating github link

* hero - bigger screens

* refactor css

* more hero responsiveness

* fix

* hero parallax

* replace svg as img with embedded svg logos

* fix marquee

* slider's tabs responsiveness

* remove horizontal scroll on the mobile

* moved images

* images optim

* moved paths to markdown

* svg -> png

* some refactoring and clean up

* moved scss

* svg to png

* more images optimization and cleaning

* optimizing png

* fix globe cards height

* add reveal effect

* improve reveal effect

* fix for the hero animation in Safari

* removed type:page preventing use-cases page from rendering with newer version of Hugo

* restore static/img/home/reranking.webp

* remove unused files

* formatting

* hero and reveal fixes

* fixes

* update cta banner

* links and content fix

* fixes: content, links, web-ui illustration

* canva testimonial

* upd link

* fix

* replace links

* slider links
This commit is contained in:
trean
2026-03-11 23:27:37 +01:00
committed by GitHub
parent 724821b675
commit 305aea6b9a
442 changed files with 7194 additions and 829 deletions
@@ -0,0 +1,8 @@
---
review: "Qdrant's technical architecture and performance capabilities have proven to be exactly what we need as we scale our AI-powered features across the platform. They are an ideal partner as we standardize our vector search infrastructure to serve millions of users worldwide."
logo:
src: /img/customer-logo/canva.svg
alt: Canva
gradient: true
sitemapExclude: true
---
@@ -0,0 +1,42 @@
---
title: One Engine, Endless Applications
caseStudies:
- id: tripadvisor
text: "Powers AI Trip Planner on billions of reviews and images, driving"
highlight: "2-3x"
textAfter: "revenue."
logoIcon: tripadvisor-vertical
logoAlt: Tripadvisor
link: /blog/case-study-tripadvisor/
- id: hubspot
text: "Powers Breeze AI with real-time, personalized responses and deep contextual"
highlight: "awareness"
textAfter: "."
logoIcon: hubspot
logoAlt: HubSpot
link: /blog/case-study-hubspot/
- id: telekom
text: "Powers multi-agent platform with real-time context across"
highlight: "2M+"
textAfter: "AI-driven conversations."
logoIcon: telekom
logoAlt: Deutsche Telekom
link: /blog/case-study-deutsche-telekom/
- id: dust
text: "Powers Dust's AI agents platform with scalable vector search across"
highlight: "5,000+"
textAfter: "data sources."
logoIcon: dust
logoAlt: Dust
link: /blog/case-study-dust-v2/
- id: lyzr
text: "Powers Lyzr's AI agents, reducing latency by"
highlight: "90%"
textAfter: "and increasing throughput by"
highlight2: "150%"
textAfter2: "."
logoIcon: lyzr
logoAlt: Lyzr
link: /blog/case-study-lyzr/
sitemapExclude: true
---
@@ -1,36 +0,0 @@
---
title: AI Meets Advanced Vector Search
description: The leading open source vector database and similarity search engine designed to handle high-dimensional vectors for performance and massive-scale AI applications.
link:
text: All features
url: /qdrant-vector-database/
cloudFeature:
title: Cloud-Native Scalability & High-Availability
content: Enterprise-grade Managed Cloud. Vertical and horizontal scaling and zero-downtime upgrades.
link:
text: Qdrant Cloud
url: /cloud/
featureCards:
- id: 0
icon: <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M46.9984 2.05668C47.0145 1.77301 46.9092 1.49588 46.7087 1.29452C46.5083 1.09315 46.2317 0.986558 45.9479 1.00136C37.0707 1.46444 30.0935 4.25608 24.7137 7.83694C18.4933 5.42823 10.8057 7.26505 5.21369 14.3822C4.90098 14.7802 4.93495 15.3491 5.2928 15.707L11.4716 21.8876C11.2831 22.2041 11.1066 22.5094 10.9418 22.802C10.298 23.9455 9.83217 24.8976 9.52567 25.568C9.37238 25.9032 9.25884 26.1683 9.18275 26.3518C9.14469 26.4436 9.11599 26.515 9.09635 26.5647L9.07365 26.6228L9.06733 26.6392L9.06541 26.6443L9.06477 26.646C9.06453 26.6466 9.06432 26.6472 10 27L9.06432 26.6472C8.92573 27.0147 9.01515 27.4294 9.2929 27.7071L20.2929 38.7071C20.5722 38.9864 20.9898 39.0751 21.3585 38.9335L21 38C21.3585 38.9335 21.359 38.9333 21.3597 38.9331L21.3614 38.9324L21.3664 38.9305L21.3827 38.9241L21.4405 38.9011C21.4899 38.8812 21.561 38.8522 21.6523 38.8137C21.8349 38.7367 22.0986 38.622 22.4323 38.4672C23.0994 38.1576 24.0471 37.6876 25.1857 37.0392C25.4758 36.8739 25.7785 36.697 26.0923 36.5082L32.2932 42.7072C32.6511 43.0651 33.22 43.099 33.618 42.7863C40.7668 37.1694 42.5882 29.4384 40.1309 23.2035C43.7022 17.8303 46.4977 10.8779 46.9984 2.05668ZM38.6994 25.2233C37.0693 27.3836 35.3298 29.2523 33.606 30.8533C31.5913 32.7243 29.5977 34.2303 27.8238 35.4111L33.0676 40.6534C38.5284 36.0064 40.0518 30.1286 38.6994 25.2233ZM13.5743 22.2786C13.5812 22.2679 13.5878 22.2572 13.5942 22.2464C14.7933 20.3155 16.4295 18.0251 18.5697 15.7089C20.435 13.6903 22.6823 11.6522 25.3582 9.81488C25.3843 9.7987 25.4098 9.78128 25.4344 9.76268C26.7141 8.88849 28.0914 8.0604 29.5712 7.30229L40.6485 18.3787C38.2791 22.9865 35.2389 26.6073 32.245 29.3878C29.2837 32.1379 26.3683 34.0641 24.196 35.3012C23.1105 35.9194 22.2127 36.3642 21.5905 36.6529C21.4577 36.7146 21.3375 36.769 21.2308 36.8166L11.1804 26.7662C11.2279 26.6576 11.2826 26.5351 11.3446 26.3996C11.6303 25.7746 12.0711 24.8729 12.6846 23.7832C12.9489 23.3138 13.245 22.8099 13.5743 22.2786ZM41.5655 16.4673C43.2718 12.6445 44.5064 8.20268 44.9238 3.07129C39.7698 3.46669 35.3149 4.68846 31.4854 6.38806L41.5655 16.4673ZM22.6874 9.27655C20.543 10.8999 18.6889 12.6328 17.1008 14.3516C15.2354 16.3704 13.7363 18.3697 12.5621 20.1496L7.34658 14.9326C11.9655 9.50489 17.8002 7.96701 22.6874 9.27655Z" fill="url(#paint0_linear_1651_6118)"/><path d="M27 25C29.2091 25 31 23.2091 31 21C31 18.7909 29.2091 17 27 17C24.7909 17 23 18.7909 23 21C23 23.2091 24.7909 25 27 25Z" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M4.464 36.464C5.40181 35.5262 6.67374 34.9993 8 34.9993C9.32626 34.9993 10.5982 35.5262 11.536 36.464C12.4738 37.4018 13.0007 38.6737 13.0007 40C13.0007 41.3262 12.4738 42.5982 11.536 43.536C9.583 45.488 2 46 2 46C2 46 2.512 38.417 4.464 36.464Z" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><defs><linearGradient id="paint0_linear_1651_6118" x1="26" y1="1" x2="26" y2="43" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient></defs></svg>
title: Ease of Use & Simple Deployment
content: Quick deployment in any environment with Docker and a lean API for easy integration, ideal for local testing.
link:
text: Quick Start Guide
url: /documentation/quick-start/
- id: 1
icon: <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M38 46V42L45.123 33.1C45.6908 32.3905 46.0001 31.5088 46 30.6V19C46 18.2044 45.6839 17.4413 45.1213 16.8787C44.5587 16.3161 43.7956 16 43 16C42.2044 16 41.4413 16.3161 40.8787 16.8787C40.3161 17.4413 40 18.2044 40 19V26" stroke="url(#paint0_linear_1651_6734)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M28 46V35.657C28 35.1316 28.1035 34.6113 28.3046 34.1259C28.5057 33.6405 28.8004 33.1995 29.172 32.828L36 26C36.2626 25.7373 36.5744 25.5289 36.9176 25.3867C37.2607 25.2446 37.6285 25.1714 38 25.1714C38.3715 25.1714 38.7393 25.2446 39.0824 25.3867C39.4256 25.5289 39.7374 25.7373 40 26C40.2627 26.2626 40.4711 26.5744 40.6133 26.9176C40.7554 27.2607 40.8286 27.6285 40.8286 28C40.8286 28.3714 40.7554 28.7393 40.6133 29.0824C40.4711 29.4256 40.2627 29.7374 40 30L34 36" stroke="url(#paint1_linear_1651_6734)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 46V42L2.877 33.1C2.30917 32.3905 1.99986 31.5088 2 30.6V19C2 18.2044 2.31607 17.4413 2.87868 16.8787C3.44129 16.3161 4.20435 16 5 16C5.79565 16 6.55871 16.3161 7.12132 16.8787C7.68393 17.4413 8 18.2044 8 19V26" stroke="url(#paint2_linear_1651_6734)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M20 46V35.657C20 35.1316 19.8965 34.6113 19.6954 34.1259C19.4943 33.6405 19.1996 33.1995 18.828 32.828L12 26C11.7374 25.7373 11.4256 25.5289 11.0824 25.3867C10.7393 25.2446 10.3714 25.1714 9.99999 25.1714C9.62854 25.1714 9.26073 25.2446 8.91756 25.3867C8.5744 25.5289 8.26261 25.7373 7.99999 26C7.7373 26.2626 7.52891 26.5744 7.38674 26.9176C7.24456 27.2607 7.17139 27.6285 7.17139 28C7.17139 28.3714 7.24456 28.7393 7.38674 29.0824C7.52891 29.4256 7.7373 29.7374 7.99999 30L14 36" stroke="url(#paint3_linear_1651_6734)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M13 13H35" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10"/><path d="M24 24C30.0751 24 35 19.0751 35 13C35 6.92487 30.0751 2 24 2C17.9249 2 13 6.92487 13 13C13 19.0751 17.9249 24 24 24Z" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/><path d="M24.0001 24C26.6036 24 28.7141 19.0751 28.7141 13C28.7141 6.92487 26.6036 2 24.0001 2C21.3967 2 19.2861 6.92487 19.2861 13C19.2861 19.0751 21.3967 24 24.0001 24Z" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/><defs><linearGradient id="paint0_linear_1651_6734" x1="42" y1="16" x2="42" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient><linearGradient id="paint1_linear_1651_6734" x1="34.4143" y1="25.1714" x2="34.4143" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient><linearGradient id="paint2_linear_1651_6734" x1="6" y1="16" x2="6" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient><linearGradient id="paint3_linear_1651_6734" x1="13.5857" y1="25.1714" x2="13.5857" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient></defs></svg>
title: Cost Efficiency with Storage Options
content: Dramatically reduce memory usage with built-in compression options and offload data to disk.
link:
text: Quantization
url: /documentation/guides/quantization/
- id: 2
icon: <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M28 28H20V46H28V28Z" stroke="url(#paint0_linear_1651_8186)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 38H2V46H10V38Z" stroke="url(#paint1_linear_1651_8186)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M46 18H38V46H46V18Z" stroke="url(#paint2_linear_1651_8186)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6 18L16 8L24 16L38 2" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M29 2H38V11" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><defs><linearGradient id="paint0_linear_1651_8186" x1="24" y1="28" x2="24" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient><linearGradient id="paint1_linear_1651_8186" x1="6" y1="38" x2="6" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient><linearGradient id="paint2_linear_1651_8186" x1="42" y1="18" x2="42" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#717C99"/><stop offset="1" stop-color="#161E33"/></linearGradient></defs></svg>
title: Rust-Powered Reliability & Performance
content: Purpose built in Rust for unmatched speed and reliability even when processing billions of vectors.
link:
text: Benchmarks
url: /benchmarks/
sitemapExclude: true
---
@@ -0,0 +1,8 @@
---
title: "Engines Ready. Awaiting Your Command."
description: "Cloud Quickstart - spin up a cluster in seconds."
button:
text: "Start Free in Qdrant Cloud"
url: "https://cloud.qdrant.io/signup"
sitemapExclude: true
---
File diff suppressed because one or more lines are too long
@@ -0,0 +1,31 @@
---
title: Engineered for Builders
subtitle: Intuitive APIs and built-in tools — crafted for developers who demand more.
illustration:
src: /img/home/web-ui.png
alt: Engineered for Builders
width: 2220
height: 1340
srcset: "/img/home/web-ui-1x.png 1x, /img/home/web-ui.png 2x"
webpSrcset: "/img/home/web-ui-1x.webp 1x, /img/home/web-ui.webp 2x"
features:
- id: apis
title: Developer friendly APIs
description: Start with a single API call — scale to advanced control over HNSW, hybrid fusion, reranking, and multi-vector retrieval, all via REST, gRPC, or official clients (Python, JavaScript, etc.).
link:
text: Explore the API Docs
url: https://api.qdrant.tech/api-reference
- id: web-ui
title: Built-In Web UI & Visualizations
description: Explore collections, test vector and metadata queries, apply filters, and inspect results — all from a clean visual interface.
link:
text: Try Web UI
url: /documentation/web-ui/
- id: inference
title: Native Cloud Inference
description: Generate text and image embeddings and run vector search in Qdrant Cloud — no separate pipeline or infrastructure needed.
link:
text: Learn More About Inference
url: /cloud-inference/
sitemapExclude: true
---
@@ -0,0 +1,46 @@
---
title: Deploy Anywhere at Enterprise Scale
subtitle: Open-source DNA with enterprise-grade security and flexibility — run on-prem, hybrid, edge, or move seamlessly to Qdrant Cloud.
deploymentOptions:
- id: cloud
title: Qdrant Cloud
description: Fully managed with high availability and auto-sharding on AWS, GCP, or Azure.
icon: cloud-managed
iconColor: primary
connector: /img/home/connector-line-1.svg
link:
text: Explore Qdrant Cloud
url: /cloud/
position: left
- id: hybrid
title: Qdrant Hybrid Cloud
description: Bring your own Kubernetes with decoupled control and data planes. Scale anywhere with full data control.
icon: cloud-hybrid
iconColor: teal
connector: /img/home/connector-line-2.svg
link:
text: Learn about Hybrid Cloud
url: /hybrid-cloud/
position: center-left
- id: private
title: Qdrant Private Cloud
description: Maximum control with air-gapped, compliant deployments.
icon: cloud-private
iconColor: blue
connector: /img/home/connector-line-3.svg
link:
text: Explore Private Cloud
url: /private-cloud/
position: center-right
- id: edge
title: Qdrant Edge (Beta)
description: Lightweight, low-latency vector search close to where data is generated.
icon: cloud-connections
iconColor: violet
connector: /img/home/connector-line-4.svg
link:
text: Discover Qdrant Edge
url: /edge/
position: right
sitemapExclude: true
---
@@ -0,0 +1,58 @@
---
title: Enterprise-ready tooling
subtitle: Deploy on any cloud, hybrid, or edge environment with full data control. Choose the setup that fits your infrastructure and scale securely without compromise.
largeCards:
- id: compliance
title: SOC 2 · GDPR-aligned Options
visual: compliance
image:
src: /img/home/soc-2-and-gdpr-compliance.svg
alt: SOC 2 and GDPR compliance badges
link:
url: https://qdrant.to/trust-center
- id: monitoring
title: Prometheus · Grafana · Datadog
visual: monitoring
image:
src: /img/home/monitoring-and-observability.svg
alt: Monitoring and observability integrations
link:
url: /documentation/guides/monitoring/
- id: sso
title: SSO (SAML/OIDC)
visual: sso
image:
src: /img/home/enterprise-sso-integration.svg
alt: Enterprise SSO integration options
link:
url: /documentation/cloud-account-setup/
smallCards:
- id: multitenancy
title: Multitenancy & Granular RBAC
icon:
name: multitenancy
color: blue
- id: networking
title: Private Networking #/VPC Peering
icon:
name: cloud-system
color: blue
# link:
# url: /
- id: downtime
title: Zero-downtime upgrades
icon:
name: downtime
fill: blue
- id: backups
title: Backups & Point-in-time restore
icon:
name: backups
color: blue
- id: api-keys
title: Vector-scoped API Keys
icon:
name: vectors
color: blue
sitemapExclude: true
---
+30 -24
View File
@@ -1,33 +1,39 @@
---
title: High-Performance Vector Search at Scale
subtitle: Powering the next generation of AI applications with advanced, open-source vector similarity search technology.
subtitle: Qdrant helps you build the AI retrieval you want. Ship high performance, full-feature vector search at any scale and with any deployment model.
startFree:
text: Get Started
text: Start Free in Qdrant Cloud
url: https://cloud.qdrant.io/signup
learnMore:
text: Learn More
text: See How It Works
url: /qdrant-vector-database/
heroImageSources:
- minWidth: 2881px
srcset: /img/hero-home-illustration-x3.webp
type: image/webp
- minWidth: 2881px
srcset: /img/hero-home-illustration-x3.png
type: image/png
- minWidth: 1441px
srcset: /img/hero-home-illustration-x2.webp
type: image/webp
- minWidth: 1441px
srcset: /img/hero-home-illustration-x2.png
type: image/png
- srcset: /img/hero-home-illustration-x1.webp
type: image/webp
- srcset: /img/hero-home-illustration-x1.png
type: image/png
fallbackHeroImage:
src: /img/hero-home-illustration-x1.png
alt: 'Hero image: an astronaut looking at dark hole from the planet surface.'
valueBadges:
- icon: /img/home/hero/github-icon.svg
text: 25k+ GitHub Stars
url: https://github.com/qdrant/qdrant
- icon: /img/home/hero/users-icon.svg
text: 60k+ Community Members
url: /community/
- icon: /img/home/hero/rust-icon.svg
text: Rust Powered
- icon: /img/home/hero/cross-icon.svg
text: SOC2 & HIPAA compliant
url: https://qdrant.to/trust-center
planet:
blur: /img/home/hero/blur.svg
blur2: /img/home/hero/blur2.svg
sphere: /img/home/hero/planet.svg
texture:
webp: /img/home/hero/planet-texture.webp
png: /img/home/hero/planet-texture.png
blueHaze: /img/home/hero/blue-haze.svg
astronauts:
alt: Qdrant astronauts exploring a planetary landscape
width: 3840
height: 1169
webpSrcset: "/img/home/hero/astronauts-960.webp 960w, /img/home/hero/astronauts-1920.webp 1920w, /img/home/hero/astronauts.webp 3840w"
pngSrcset: "/img/home/hero/astronauts-960.png 960w, /img/home/hero/astronauts-1920.png 1920w, /img/home/hero/astronauts.png 3840w"
fallbackSrc: /img/home/hero/astronauts.png
githubStars:
logo: <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_1825_5122)"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 0.800003C5.4 0.800003 0 6.2 0 12.8C0 18.1 3.4 22.6 8.2 24.2C8.8 24.3 9 23.9 9 23.6C9 23.3 9 22.6 9 21.6C5.7 22.3 5 20 5 20C4.5 18.6 3.7 18.2 3.7 18.2C2.5 17.5 3.7 17.5 3.7 17.5C4.9 17.6 5.5 18.7 5.5 18.7C6.6 20.5 8.3 20 9 19.7C9.1 18.9 9.4 18.4 9.8 18.1C7.1 17.8 4.3 16.8 4.3 12.2C4.3 10.9 4.8 9.8 5.5 9C5.5 8.6 5 7.4 5.7 5.8C5.7 5.8 6.7 5.5 9 7C10 6.7 11 6.6 12 6.6C13 6.6 14 6.7 15 7C17.3 5.4 18.3 5.8 18.3 5.8C19 7.5 18.5 8.7 18.4 9C19.2 9.8 19.6 10.9 19.6 12.2C19.6 16.8 16.8 17.8 14.1 18.1C14.5 18.5 14.9 19.2 14.9 20.3C14.9 21.9 14.9 23.2 14.9 23.6C14.9 23.9 15.1 24.3 15.7 24.2C20.5 22.6 23.9 18.1 23.9 12.8C24 6.2 18.6 0.800003 12 0.800003Z" fill="#E1E5F0"/></g><defs><clipPath id="clip0_1825_5122"><rect width="24" height="24" fill="white" transform="translate(0 0.5)"/></clipPath></defs></svg>
starIcon: <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_1825_5127)"><path d="M13.2508 5.25913L9.47345 4.70963L7.78732 1.2875C7.7072 1.14966 7.5923 1.03526 7.4541 0.955747C7.31591 0.876231 7.15926 0.834381 6.99983 0.834381C6.84039 0.834381 6.68374 0.876231 6.54555 0.955747C6.40735 1.03526 6.29245 1.14966 6.21232 1.2875L4.5262 4.7105L0.748825 5.25913C0.587068 5.28233 0.435041 5.35036 0.309962 5.45552C0.184882 5.56068 0.0917505 5.69876 0.0411146 5.85413C-0.0095213 6.0095 -0.0156375 6.17594 0.0234587 6.33461C0.0625549 6.49328 0.145301 6.63782 0.262325 6.75188L2.99495 9.41625L2.35007 13.1788C2.3225 13.3397 2.3405 13.5051 2.40203 13.6563C2.46356 13.8075 2.56617 13.9385 2.69826 14.0345C2.83035 14.1304 2.98665 14.1875 3.14948 14.1993C3.31232 14.211 3.4752 14.177 3.6197 14.101L6.99983 12.3239L10.3782 14.0993C10.5227 14.1752 10.6856 14.2093 10.8484 14.1975C11.0113 14.1857 11.1675 14.1287 11.2996 14.0327C11.4317 13.9368 11.5343 13.8058 11.5959 13.6546C11.6574 13.5033 11.6754 13.3379 11.6478 13.177L11.0029 9.4145L13.7373 6.75188C13.8541 6.6379 13.9366 6.49356 13.9756 6.33515C14.0147 6.17674 14.0086 6.01057 13.9582 5.85541C13.9078 5.70025 13.815 5.56227 13.6903 5.45706C13.5656 5.35185 13.414 5.2836 13.2526 5.26L13.2508 5.25913Z" fill="#DC244C"/></g><defs><clipPath id="clip0_1825_5127"><rect width="14" height="14" fill="white" transform="translate(0 0.5)"/></clipPath></defs></svg>
@@ -0,0 +1,86 @@
---
title: "Integrates with leading AI tools & frameworks"
logosFirstRow:
- id: 0
name: CrewAI
logo:
icon: crewai
alt: CrewAI logo
- id: 1
name: LangChain
logo:
icon: langchain
alt: LangChain logo
- id: 2
name: LlamaIndex
logo:
icon: llamaindex
alt: LlamaIndex logo
- id: 3
name: n8n
logo:
icon: n8n
alt: n8n logo
- id: 4
name: TwelveLabs
logo:
icon: twelvelabs
alt: TwelveLabs logo
- id: 5
name: OpenAI
logo:
icon: openai
alt: OpenAI logo
- id: 6
name: Cohere
logo:
icon: cohere
alt: Cohere logo
- id: 7
name: Hugging Face
logo:
icon: hugging-face
alt: Hugging Face logo
logosSecondRow:
- id: 0
name: CamelAI
logo:
icon: camelai
alt: CamelAI logo
- id: 1
name: mem0
logo:
icon: mem0
alt: mem0 logo
- id: 2
name: Cognee
logo:
icon: cognee
alt: Cognee logo
- id: 3
name: Neo4j
logo:
icon: neo4j
alt: Neo4j logo
- id: 4
name: CamelAI
logo:
icon: camelai
alt: CamelAI logo
- id: 5
name: Mistral AI
logo:
icon: mistralai
alt: Mistral AI logo
- id: 6
name: Superlinked
logo:
icon: superlinked
alt: Superlinked logo
- id: 7
name: Deepset
logo:
icon: deepset
alt: Deepset logo
sitemapExclude: true
---
@@ -1,13 +0,0 @@
---
title: Integrations
link:
text: See Integrations
url: /documentation/frameworks/
embedLink:
text: embeddings
url: /documentation/embeddings/
frameworkLink:
text: frameworks
url: /documentation/frameworks/
sitemapExclude: true
---
@@ -0,0 +1,31 @@
---
tagline: ARCHITECTURE FOR THE AI - NOT KEYWORD - ERA
title: Performance by Design
subtitle: We research, engineer, and optimize each component from first principles for the fastest, most scalable, and most customizable AI retrieval and search engine.
features:
- id: high-performance
title: Highest‑Performance Vector Search Engine
description: Built entirely in Rust with SIMD and a custom storage engine (Gridstore) — no wrappers, no bolt-ons. Just fast, scalable vector search.
image:
src: /img/home/vertical-slider/performanceimage.jpg
alt: High performance vector search engine benchmark chart
- id: real-time
title: Real‑Time Indexing
description: Index new data instantly without rebuilding the entire index. Your vectors are searchable the moment they're added.
image:
src: /img/home/vertical-slider/real-time-indexing-by-qdrant.jpg
alt: Real-time indexing illustration
- id: memory-efficient
title: Memory‑Efficient Storage
description: Store billions of vectors with minimal memory footprint using our optimized storage architecture.
image:
src: /img/home/vertical-slider/memory-efficient-storage-by-qdrant.jpg
alt: Memory efficient storage illustration
- id: quantization
title: Asymmetric, Scalar and Binary Quantization
description: Reduce memory usage by up to 64x while maintaining search quality with advanced quantization techniques.
image:
src: /img/home/vertical-slider/scalar-binary-quantization-by-qdrant.jpg
alt: Scalar and binary quantization illustration
sitemapExclude: true
---
@@ -0,0 +1,62 @@
---
label: "SOLUTIONS"
title: "Build AI Search the Way You Want"
subtitle: "From RAG to AI agents, Qdrant delivers hybrid dense–sparse retrieval with advanced metadata filtering and real-time updates."
tabs:
- id: "rag"
name: "RAG & GenAI"
label: "RAG & GenAI"
title: "RAG & GenAI"
description: "Deliver context-rich answers with hybrid dense – sparse retrieval, metadata filters, and fresh updates."
image:
src: /img/home/horizontal-slider/rag.png
alt: RAG and GenAI illustration
link:
text: "Learn More"
url: "/rag/"
- id: "ai-agents"
name: "AI Agents"
label: "AI Agents"
title: "AI Agents"
description: "Build intelligent agents with persistent memory and fast similarity search for context-aware interactions."
image:
src: /img/home/horizontal-slider/qdrant-use-caseai-agents.png
alt: AI Agents illustration
link:
text: "Learn More"
url: "/ai-agents/"
- id: "semantic-search"
name: "Semantic Search"
label: "Semantic Search"
title: "Semantic Search"
description: "Go beyond keywords with neural search that understands intent and delivers relevant results."
image:
src: /img/home/horizontal-slider/advanced-search.png
alt: Semantic Search illustration
link:
text: "Learn More"
url: "/advanced-search/"
- id: "recommendations"
name: "Recommendation Systems"
label: "Recommendation Systems"
title: "Recommendation Systems"
description: "Power personalized recommendations with real-time similarity matching across millions of items."
image:
src: /img/home/horizontal-slider/recommendation-systems.png
alt: Recommendation Systems illustration
link:
text: "Learn More"
url: "/recommendations/"
- id: "anomaly-detection"
name: "Data Analysis & Anomaly Detection"
label: "Data Analysis & Anomaly Detection"
title: "Data Analysis & Anomaly Detection"
description: "Detect outliers and anomalies by finding patterns that deviate from normal behavior in your data."
image:
src: /img/home/horizontal-slider/anomaly-detection.png
alt: Data Analysis and Anomaly Detection illustration
link:
text: "Learn More"
url: "/data-analysis-anomaly-detection/"
sitemapExclude: true
---
@@ -0,0 +1,57 @@
---
title: Build for Production-Grade AI Search
subtitle: Engineered for real-time retrieval with the speed, accuracy, and scale that modern AI demands.
pill: WHY QDRANT?
featureCards:
- id: metadata-filters
title: Expansive Metadata Filters
description: "Store metadata in JSON and use advanced filters, such as <code>nested</code>, <code>text</code>, <code>geo</code>, <code>has_vector</code>, and more."
image:
src: /img/home/metadata-filters.png
alt: Metadata filters code illustration
link:
text: Learn About Metadata Filters
url: /documentation/concepts/payload/
size: large
- id: hybrid-search
title: Native Hybrid Search (Dense + Sparse)
description: Blend keyword and vector search in one query – use dense or sparse vectors. Supports BM25, SPLADE++, and miniCOIL.
image:
src: /img/home/native-hybrid-search.png
alt: Native hybrid search illustration
link:
text: Explore Hybrid Search
url: /documentation/concepts/hybrid-queries/
size: large
- id: multivector
title: Built-in Multivector
description: Set new standards for relevance; make the retrieval layer more expressive, flexible, and multimodal with multiple vectors per object.
image:
src: /img/home/multivector.png
alt: Multivector illustration
link:
text: See Documentation
url: /documentation/advanced-tutorials/using-multivector-representations/
size: small
- id: one-stage-filtering
title: Efficient, One-Stage Filtering
description: Filters are applied during HNSW traversal — no pre- or post-filtering. High recall with low latency, even under complex conditions.
image:
src: /img/home/one-stage-filtering.png
alt: One-stage filtering illustration
link:
text: See Documentation
url: /articles/filterable-hnsw/
size: small
- id: reranking
title: Full-Spectrum Reranking
description: Infuse business logic with score boosting, achieve token-level precision with late interaction models (e.g. ColBERT), diversify results with Maximum Marginal Relevance (MMR)
image:
src: /img/home/reranking.png
alt: Reranking illustration
link:
text: See Documentation
url: /documentation/tutorials-search-engineering/reranking-hybrid-search/
size: small
sitemapExclude: true
---
@@ -5,7 +5,7 @@ button:
text: Talk to Sales
url: /contact-us/
illustration:
src: /img/hr-tech/cta-illustration.png
src: /img/cta-illustration.png
alt: Rocket flying over globe illustration
background:
src: /img/hr-tech/space-background.svg
@@ -4,11 +4,5 @@ description: Get guidance on scaling search, matching, and recommendations beyon
button:
text: Talk to Sales
url: /contact-us/
illustration:
src: /img/hr-tech/cta-illustration.png
alt: Rocket flying over globe illustration
background:
src: /img/hr-tech/space-background.svg
alt: Space background
sitemapExclude: true
---
@@ -1,7 +1,6 @@
---
title: Vector Database Use Cases
section_title: Apps and ideas Qdrant make possible
type: page
description: Discover the diverse applications of Qdrant vector database, from retrieval and augmented generation to anomaly detection, advanced search, and more.
build:
render: always
@@ -83,6 +83,9 @@ $theme-colors: (
'light': $neutral-98,
'mid-gray': $neutral-94,
'dark': $neutral-20,
'teal': $secondary-teal-50,
'violet': $secondary-violet-50,
'blue': $secondary-blue-50,
);
$body-bg: $neutral-98;
@@ -109,10 +112,12 @@ $table-striped-bg: $neutral-94;
$font-family-sans-serif: 'Mona Sans', 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
$font-family-monospace: 'Geist Mono', 'Overpass Mono', SFMono-Regular, 'Droid Sans Mono', Menlo, Monaco, Consolas, 'Lucida Console', 'Monaco', monospace;
$font-family-monospace: 'Geist Mono', 'Overpass Mono', SFMono-Regular, 'Droid Sans Mono', Menlo, Monaco, Consolas,
'Lucida Console', 'Monaco', monospace;
$font-family-base: 'Mona Sans', 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
$font-family-code: 'Geist Mono', 'Overpass Mono', SFMono-Regular, 'Droid Sans Mono', Menlo, Monaco, Consolas, 'Lucida Console', 'Monaco', monospace;
$font-family-code: 'Geist Mono', 'Overpass Mono', SFMono-Regular, 'Droid Sans Mono', Menlo, Monaco, Consolas,
'Lucida Console', 'Monaco', monospace;
$font-size-xs: pxToRem(12);
$font-size-s: pxToRem(14);
@@ -210,3 +215,15 @@ $spacers: (
$code-snippet-border-radius: $border-radius * 2;
$post-content-width: pxToRem(920);
$grid-breakpoints: (
xxs: 0,
xs: 375px,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1900px,
);
@include _assert-ascending($grid-breakpoints, '$grid-breakpoints');
@include _assert-starts-at-zero($grid-breakpoints, '$grid-breakpoints');
@@ -68,7 +68,7 @@ body {
// Apply Mona Sans width variation setting globally
// This ensures all text using Mona Sans (via font-family-base) uses width axis at 100
font-variation-settings: 'wdth' 100;
font-feature-settings: "ss05" on;
font-feature-settings: 'ss05' on;
font-weight: 350;
}
@@ -1,11 +1,9 @@
@import 'base';
@import 'partials/customers';
@import 'partials/hero';
@import 'partials/core-features';
@import 'partials/scroll-reveal';
@import 'partials/home/index';
@import 'partials/customer-stories';
@import 'partials/docker-deploy';
@import 'partials/vectors';
@import 'partials/integrations';
@import 'partials/get-started';
@import 'partials/additional-resources';
@import 'partials/feature-overview';
@@ -11,9 +11,12 @@
$background-color: #090e1a,
$pauseOnHover: false,
$speed: 25s,
$pseudoElementDisplay: block
$pseudoElementDisplay: block,
$keyframePrefix: ''
) {
$inner-width: math.div($total-marquee-items, $visible-marquee-items) * 2 * 100%;
$leftKeyframe: if($keyframePrefix != '', #{$keyframePrefix}marqueeLeft, marqueeLeft);
$rightKeyframe: if($keyframePrefix != '', #{$keyframePrefix}marqueeRight, marqueeRight);
max-width: 100%;
text-align: center;
@@ -68,11 +71,11 @@
}
&_to-left {
animation: marqueeLeft $speed linear infinite;
animation: $leftKeyframe $speed linear infinite;
}
&_to-right {
animation: marqueeRight $speed linear infinite;
animation: $rightKeyframe $speed linear infinite;
}
}
@@ -91,7 +94,7 @@
}
}
@keyframes marqueeLeft {
@keyframes #{$leftKeyframe} {
0% {
left: 0;
}
@@ -99,7 +102,7 @@
left: $inner-width * 0.5 * -1;
}
}
@keyframes marqueeRight {
@keyframes #{$rightKeyframe} {
0% {
left: $inner-width * 0.5 * -1;
}
@@ -1,162 +0,0 @@
@use '../helpers/functions' as *;
.core-features {
background-color: $neutral-94;
padding-top: $spacer * 4;
padding-bottom: $spacer * 4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&__title {
font-size: pxToRem(40);
line-height: pxToRem(48);
text-align: start;
margin-bottom: $spacer * 1.5;
max-width: 100%;
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
line-height: pxToRem(27);
margin-bottom: $spacer * 1.5;
max-width: 100%;
text-align: start;
}
&__card-title {
color: $neutral-20;
margin-top: $spacer * 1.5;
margin-bottom: $spacer;
line-height: pxToRem(34);
}
&__cloud-native {
@include media-breakpoint-up(xl) {
flex-direction: row;
}
&.card {
padding-top: 0;
padding-right: 0;
padding-bottom: 0;
}
& div:first-child {
padding-right: $spacer * 2;
padding-top: $spacer * 2;
@include media-breakpoint-up(xl) {
padding-right: pxToRem(122);
padding-top: $spacer * 5;
}
}
.core-features__card-title {
font-size: pxToRem(24);
line-height: pxToRem(34);
margin-top: 0;
margin-bottom: pxToRem(12);
}
.core-features__card-content {
font-size: map-get($font-sizes-text, 'l');
line-height: pxToRem(27);
margin-bottom: pxToRem(12);
}
}
&__cloud-native-image {
margin-top: $spacer;
background: url('/img/qdrant-cloud.png') right bottom no-repeat;
background-size: contain;
max-width: 100% !important;
width: pxToRem(372);
height: pxToRem(214);
border-radius: 0 0 calc($spacer / 2) 0;
aspect-ratio: 1.45/1;
align-self: end;
}
&__card-content {
color: $neutral-30;
margin-bottom: $spacer * 1.5;
}
&__card-link {
color: $neutral-20;
font-size: map-get($font-sizes-text, 'm');
text-decoration: none;
}
@include media-breakpoint-up(xl) {
padding-top: $spacer * 6.5;
padding-bottom: $spacer * 6.5;
&__title {
font-size: map-get($font-sizes, 2);
text-align: center;
line-height: pxToRem(67);
max-width: pxToRem(920);
}
&__subtitle {
font-size: map-get($font-sizes-text, 'xl');
line-height: pxToRem(30);
max-width: pxToRem(920);
text-align: center;
}
&__cards {
margin-left: pxToRem(-15);
margin-right: pxToRem(-15);
}
&__cards > div {
padding: 0 pxToRem(15);
}
&__card {
padding-top: $spacer * 2.5;
padding-bottom: $spacer * 2.5;
padding-left: $spacer * 2.5;
padding-right: $spacer * 2.5;
min-height: pxToRem(390);
svg {
max-width: pxToRem(48);
max-height: pxToRem(48);
}
}
&__cloud-native {
padding-top: pxToRem(75);
padding-bottom: pxToRem(75);
max-width: pxToRem(1110);
min-height: pxToRem(420);
padding-left: $spacer * 3;
padding-right: $spacer * 3;
margin-top: $spacer * 5;
.core-features__card-title {
font-size: map-get($font-sizes-text, 'xxl');
line-height: pxToRem(48);
margin-bottom: $spacer * 1.5;
}
.core-features__card-content {
font-size: map-get($font-sizes-text, 'l');
line-height: pxToRem(27);
margin-bottom: $spacer * 1.5;
}
}
&__cloud-native-image {
width: pxToRem(540);
height: pxToRem(372);
}
}
}
@@ -19,6 +19,7 @@
left: 0;
right: 0;
bottom: 0;
z-index: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
@@ -36,27 +37,25 @@
display: flex;
flex-direction: column;
align-items: center;
gap: $spacer * 0.75;
text-align: center;
}
&__title {
margin: 0;
margin: 0 0 0.75rem;
font-size: $spacer * 2;
line-height: pxToRem(38);
color: $neutral-98;
}
&__description {
margin: 0;
margin: 0 0 1.5rem;
font-size: pxToRem(18);
line-height: pxToRem(28);
line-height: 1;
color: $neutral-70;
}
&__button {
white-space: nowrap;
margin-top: $spacer * 0.5;
}
&__illustration {
@@ -75,7 +74,6 @@
align-items: flex-start;
text-align: left;
max-width: pxToRem(500);
gap: $spacer * 0.5;
}
&__title {
@@ -1,52 +0,0 @@
@use '../helpers/functions' as *;
@use '../mixins/marquee' as marquee;
.customers {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
gap: $spacer * 3;
padding-top: $spacer * 4;
padding-bottom: $spacer * 4;
background: $neutral-10;
&__title {
color: $neutral-70;
text-align: center;
font-size: map-get($font-sizes-text, 'l');
margin: 0 auto calc($spacer / 2);
}
&__description {
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
padding-left: pxToRem(20);
padding-right: pxToRem(20);
}
&__link {
color: $primary-60;
font-size: map-get($font-sizes-text, 'l');
text-decoration: none;
}
.customers__logos {
@include marquee.base(64px, 224px, 24, 24, 52px, $neutral-10, false, 50s, block);
}
@include media-breakpoint-up(xl) {
&__title {
margin: 0;
}
&__description {
flex-direction: row;
justify-content: center;
padding: 0;
gap: calc($spacer / 2);
}
}
}
@@ -1,173 +0,0 @@
@use '../helpers/functions' as *;
@use 'sass:math';
.hero {
padding-top: $spacer * 2.5;
position: relative;
background: url('/img/stars-pattern.png') $neutral-10;
&__content {
text-align: center;
max-width: 100%;
margin: 0 auto;
width: 100%;
}
&__image {
width: 100%;
min-height: pxToRem(480);
margin: pxToRem(-142) auto 0;
overflow: hidden;
@include media-breakpoint-up(md) {
$height: math.div(-100vw, 2.46); // image's aspect ratio 2.46 / 1
margin-top: calc(#{$height} * 0.34);
}
img {
display: block;
width: 250%;
height: auto;
margin-left: -75%;
@include media-breakpoint-up(md) {
width: 100%;
margin-left: 0;
}
}
}
&__title {
color: $neutral-98;
text-align: center;
width: 100%;
margin-bottom: $spacer;
font-size: map-get($font-sizes, 4);
line-height: pxToRem(48);
}
&__subtitle {
color: $neutral-70;
text-align: center;
font-size: pxToRem(18);
line-height: pxToRem(27);
max-width: 100%;
margin: 0 auto $spacer * 1.5;
}
&__buttons {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: $spacer * 1.5;
margin-bottom: $spacer * 5;
}
&__buttons a {
min-width: pxToRem(200);
}
&__stars {
position: absolute;
right: $spacer;
bottom: $spacer;
border-radius: 8px;
border: none;
outline: none;
display: flex;
align-items: center;
justify-content: center;
padding-top: calc($spacer / 2);
padding-bottom: calc($spacer / 2);
padding-left: pxToRem(20);
padding-right: pxToRem(20);
background-color: $neutral-10;
transition: bottom 1s ease-in-out;
}
&__stars svg {
max-width: pxToRem(24);
max-height: pxToRem(24);
}
&__stars-text {
color: $neutral-98;
margin-right: calc($spacer / 2);
margin-left: calc($spacer / 2);
font-size: map-get($font-sizes-text, 's');
line-height: pxToRem(21);
font-weight: 500;
}
&__stars-count {
border-radius: 6px;
border: 1px solid $neutral-30;
color: $neutral-98;
padding-left: calc($spacer / 2);
padding-right: calc($spacer / 2);
display: flex;
align-items: center;
justify-content: center;
gap: calc($spacer / 4);
height: pxToRem(25);
font-size: map-get($font-sizes-text, 's');
line-height: pxToRem(21);
}
@include media-breakpoint-up(xl) {
padding-top: $spacer * 5;
&__content {
padding: 0;
max-width: pxToRem(920);
}
&__title {
font-size: map-get($font-sizes, 1);
line-height: pxToRem(76);
}
&__subtitle {
font-size: map-get($font-sizes-text, 'xl');
line-height: pxToRem(30);
max-width: pxToRem(640);
margin: 0 auto $spacer * 2;
}
&__buttons {
flex-direction: row;
align-items: flex-start;
}
&__buttons a {
min-width: auto;
}
&__stars {
position: fixed;
right: $spacer * 1.5;
bottom: $spacer * 1.5;
transition: background-color 0.2s;
z-index: 2;
&:hover {
background-color: $neutral-100;
.hero__stars-text,
.hero__stars-count {
color: $neutral-20;
}
& > svg path {
fill: $neutral-20;
}
}
}
}
}
@@ -1,89 +0,0 @@
@use '../helpers/functions' as *;
.integrations {
background: $neutral-10;
padding-top: $spacer * 4;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&__title {
font-size: map-get($font-sizes, 4);
line-height: pxToRem(48);
text-align: center;
margin-bottom: $spacer * 1.5;
max-width: 100%;
color: $neutral-98;
}
&__subtitle {
color: $neutral-70;
font-size: map-get($font-sizes-text, 'l');
line-height: pxToRem(27);
margin-bottom: $spacer * 1.5;
text-align: center;
}
&__link {
color: $primary-60;
font-size: $font-size-xl;
&:hover {
text-decoration: underline;
}
}
&__preview {
margin-top: $spacer * 3;
width: 100%;
height: pxToRem(440);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
background-image: url('/img/mobile/integrations.svg');
}
&__overlay {
display: none;
}
@include media-breakpoint-up(xl) {
background: url('/img/stars-pattern.png') $neutral-10;
padding-top: $spacer * 6.5;
&__title {
font-size: map-get($font-sizes, 2);
line-height: pxToRem(67);
max-width: pxToRem(726);
}
&__subtitle {
font-size: map-get($font-sizes-text, 'xl');
line-height: pxToRem(30);
}
&__preview {
margin-top: $spacer * 5;
width: pxToRem(920);
height: pxToRem(440);
background-image: url('/img/integrations.svg');
}
&__overlay {
display: block;
width: 100%;
height: pxToRem(240);
position: absolute;
bottom: pxToRem(-255);
left: 0;
filter: blur(60px);
background: linear-gradient(90deg, #dc244c 7%, #2567eb 30%, #f54c71 50%, #7335f0 70%, #bb3987 100%);
}
}
}
@@ -0,0 +1,50 @@
// Scroll reveal animations
// Entry: CSS animation (slide-up + fade-in) — keeps translateY out of the
// static hidden state so removing .revealed never shifts layout and can't
// cause an intersection-observer feedback loop.
// Exit: opacity-only CSS transition — smooth fade, no position change.
@keyframes reveal-in {
from {
opacity: 0;
transform: translateY(24px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
// Fallback: show content if JS hasn't loaded
[data-reveal] {
opacity: 1;
transform: none;
}
// Only apply hidden state when JS is ready
.js-loaded [data-reveal] {
opacity: 0;
transition: opacity 0.5s ease-out;
will-change: opacity, transform;
}
.js-loaded [data-reveal].revealed {
opacity: 1;
animation: reveal-in 0.6s ease-out backwards;
}
// Stagger delays for grouped items
.js-loaded [data-reveal-delay="1"] { transition-delay: 0.1s; animation-delay: 0.1s; }
.js-loaded [data-reveal-delay="2"] { transition-delay: 0.2s; animation-delay: 0.2s; }
.js-loaded [data-reveal-delay="3"] { transition-delay: 0.3s; animation-delay: 0.3s; }
.js-loaded [data-reveal-delay="4"] { transition-delay: 0.4s; animation-delay: 0.4s; }
// Respect reduced motion preference
@media (prefers-reduced-motion: reduce) {
.js-loaded [data-reveal] {
opacity: 1;
transform: none;
transition: none;
animation: none;
}
}
@@ -14,6 +14,10 @@
&__review {
margin-bottom: $spacer * 2.5;
font-size: pxToRem(20);
&:last-child {
margin-bottom: 0;
}
line-height: 1.5;
color: $neutral-20;
letter-spacing: pxToRem(-0.2);
@@ -61,6 +65,54 @@
img {
width: pxToRem(150);
}
&--gradient {
min-height: pxToRem(300);
background-color: $neutral-10;
background-image: url('/img/testimonial-logo-glow.svg');
background-repeat: no-repeat;
background-position: center bottom;
background-size: 100% auto;
position: relative;
overflow: hidden;
img {
position: relative;
z-index: 1;
filter: brightness(0) invert(1);
}
}
}
/* Gradient layout: equal-height cards, Figma-style (only when gradient: true) */
&--gradient-layout {
.row {
align-items: stretch;
--bs-gutter-x: #{pxToRem(30)};
}
.testimonial-light__content,
.testimonial-light__logo {
min-height: pxToRem(300);
height: 100%;
}
.testimonial-light__content {
display: flex;
flex-direction: column;
justify-content: center;
padding: pxToRem(56);
}
.testimonial-light__logo--gradient {
padding: pxToRem(32);
}
.testimonial-light__review {
font-size: pxToRem(24);
line-height: 1.3;
letter-spacing: pxToRem(-0.5);
}
}
&__partners {
@@ -0,0 +1,229 @@
@use '../../helpers/functions' as *;
.case-studies {
background-color: $neutral-94;
padding-top: $spacer * 4;
padding-bottom: $spacer * 4;
@include media-breakpoint-up(xl) {
padding-top: $spacer * 5;
padding-bottom: $spacer * 5;
}
// Header
&__header {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: $spacer * 1.5;
margin-bottom: $spacer * 3;
@include media-breakpoint-up(xl) {
margin-bottom: $spacer * 4;
}
}
&__title {
flex: 1 1 auto;
min-width: 0;
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.2;
letter-spacing: -0.5px;
color: $neutral-20;
margin: 0;
@include media-breakpoint-up(xl) {
font-size: pxToRem(40);
}
}
// Controls
&__controls {
flex-shrink: 0;
margin-left: auto;
display: flex;
gap: $spacer * 2;
}
&__arrow {
display: flex;
align-items: center;
justify-content: center;
width: pxToRem(40);
height: pxToRem(40);
padding: 0;
background: transparent;
border: none;
cursor: pointer;
color: $neutral-20;
transition:
color 0.2s ease,
opacity 0.2s ease;
&:hover:not(:disabled) {
color: $primary-50;
}
&:disabled {
color: $neutral-80;
cursor: not-allowed;
}
svg {
width: pxToRem(24);
height: pxToRem(14);
}
}
// Carousel constrained to container width
&__carousel-outer {
overflow: hidden;
margin-top: pxToRem(-12);
margin-bottom: pxToRem(-60); // negative margin so card shadow not clipped below
padding-top: pxToRem(12);
position: relative;
@include media-breakpoint-up(sm) {
margin-right: pxToRem(-24);
padding-right: pxToRem(24);
}
&::after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: pxToRem(20);
background: linear-gradient(to left, rgba($neutral-94, 0.3), transparent);
pointer-events: none;
@include media-breakpoint-down(sm) {
display: none;
}
}
}
&__carousel {
overflow: hidden;
padding-bottom: pxToRem(80);
@include media-breakpoint-up(sm) {
margin-right: pxToRem(-24);
padding-right: pxToRem(24);
}
}
&__track {
display: flex;
gap: pxToRem(30);
transition: transform 0.3s ease;
}
&__slide {
flex-shrink: 0;
width: var(--case-studies-slide-width, pxToRem(280));
}
&__card-link {
display: block;
text-decoration: none;
color: inherit;
&:hover {
color: inherit;
text-decoration: none;
}
}
// Card
&__card {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
min-width: 0;
height: pxToRem(280);
padding: $spacer * 2;
background-color: $neutral-98;
border: 1px solid rgba($neutral-80, 0.2);
border-radius: pxToRem(16);
box-shadow:
2px 2px 8px 0 rgba(155, 162, 184, 0.1),
8px 8px 14px 0 rgba(155, 162, 184, 0.09),
18px 18px 18px 0 rgba(155, 162, 184, 0.05),
32px 32px 22px 0 rgba(155, 162, 184, 0.01),
48px 48px 24px 0 rgba(155, 162, 184, 0);
transition: box-shadow 0.2s ease;
&:hover {
box-shadow:
3px 2px 9px 0 rgba(22, 30, 51, 0.1),
12px 6px 16px 0 rgba(22, 30, 51, 0.09),
28px 14px 22px 0 rgba(22, 30, 51, 0.05),
48px 24px 26px 0 rgba(22, 30, 51, 0.01),
72px 36px 28px 0 rgba(22, 30, 51, 0);
}
}
&__card-text {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
color: $neutral-30;
margin: 0;
}
&__phrase--no-break {
white-space: nowrap; // Keeps last word + period together to avoid orphan punctuation
}
&__highlight {
font-weight: 600;
color: $primary-50;
}
&__card-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: pxToRem(16);
}
&__card-logo {
height: pxToRem(48);
display: flex;
align-items: flex-end;
svg {
max-height: pxToRem(48);
width: auto;
height: auto;
object-fit: contain;
filter: brightness(0) saturate(100%);
}
}
&__card-arrow {
display: flex;
align-items: center;
justify-content: center;
width: pxToRem(28);
height: pxToRem(28);
flex-shrink: 0;
color: $neutral-20;
opacity: 0;
transition: opacity 0.2s ease;
.case-studies__card:hover & {
opacity: 1;
}
svg {
width: pxToRem(24);
height: pxToRem(14);
}
}
}
@@ -0,0 +1,44 @@
@use '../../helpers/functions' as *;
.customers {
display: flex;
justify-content: center;
align-items: center;
padding: pxToRem(64) pxToRem(20) pxToRem(80);
background: $neutral-10;
.container {
width: 100%;
max-width: pxToRem(1110);
padding-left: 0;
padding-right: 0;
}
&__grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: pxToRem(24) pxToRem(8);
width: 100%;
}
&__logo {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
width: pxToRem(103); // (1110 - 9*8)/10 so 10 logos fit per row on 2 lines
height: pxToRem(56);
padding: 0 pxToRem(10);
svg {
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
}
}
}
@@ -0,0 +1,227 @@
@use '../../helpers/functions' as *;
.engineered-for-builders {
background-color: $neutral-10;
padding-top: pxToRem(120);
padding-bottom: pxToRem(120);
position: relative;
overflow: hidden;
.container {
max-width: pxToRem(1110);
position: relative;
z-index: 1;
}
// Background decoration
&__background {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(ellipse at 50% 0%, rgba(87, 0, 201, 0.15) 0%, transparent 60%);
pointer-events: none;
// Two line backgrounds
&::before {
content: '';
position: absolute;
background-image: url('/img/home/blured-line.svg');
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: 80% auto;
background-position: 50% 69%;
background-repeat: no-repeat;
mix-blend-mode: plus-lighter;
filter: blur(78px);
@media (max-width: 2300px) {
background-size: 90% auto;
}
@include media-breakpoint-down(xxl) {
background-size: cover;
}
}
&::after {
content: '';
position: absolute;
background-image: url('/img/home/blured-line-2.svg');
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: 80% auto;
background-position: 50% 69%;
background-repeat: no-repeat;
mix-blend-mode: plus-lighter;
filter: blur(26px);
@media (max-width: 2300px) {
background-size: 90% auto;
}
@include media-breakpoint-down(xxl) {
background-size: cover;
}
}
}
&__background-texture {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('/img/home/engineered-texture.png');
background: image-set(
url('/img/home/engineered-texture.webp') type('image/webp'),
url('/img/home/engineered-texture.png') type('image/png')
);
background-size: cover;
background-position: 50% 69%;
background-repeat: no-repeat;
opacity: 0.7;
mix-blend-mode: overlay;
}
// Header
&__header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: pxToRem(8);
margin-bottom: pxToRem(64);
max-width: pxToRem(920);
margin-left: auto;
margin-right: auto;
}
&__title {
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.5px;
color: $neutral-90;
margin: 0;
@include media-breakpoint-up(xl) {
font-size: pxToRem(48);
}
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
color: $neutral-70;
margin: 0;
}
// Illustration
&__illustration {
position: relative;
margin-bottom: pxToRem(40);
img {
width: 100%;
//max-width: pxToRem(1026);
height: auto;
display: block;
margin: 0 auto;
border-radius: pxToRem(16);
}
// Gradient overlay at bottom
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: pxToRem(1026);
height: pxToRem(112);
background: linear-gradient(180deg, rgba(9, 14, 26, 0) 0%, rgb(9, 14, 26) 100%);
pointer-events: none;
}
}
&__image-note {
font-size: pxToRem(14);
font-weight: 350;
opacity: 0.7;
}
// Features
&__features {
display: flex;
flex-direction: column;
gap: pxToRem(48);
padding-top: pxToRem(40);
@include media-breakpoint-up(md) {
flex-direction: row;
}
}
&__feature {
flex: 1;
display: flex;
flex-direction: column;
gap: $spacer;
}
&__feature-title {
font-size: pxToRem(18);
font-weight: 600;
line-height: 1.5;
letter-spacing: -0.2px;
color: $neutral-90;
margin: 0;
@include media-breakpoint-up(xl) {
font-size: pxToRem(20);
}
}
&__feature-description {
font-size: map-get($font-sizes-text, 'md');
font-weight: 350;
line-height: 1.5;
color: $neutral-70;
margin: 0;
}
&__feature-link {
display: inline-flex;
align-items: center;
gap: pxToRem(2);
font-size: map-get($font-sizes-text, 'md');
font-weight: 500;
line-height: 1.5;
color: $neutral-98;
text-decoration: none;
transition: opacity 0.2s ease;
&:hover {
opacity: 0.8;
}
svg {
width: pxToRem(16);
height: pxToRem(16);
margin-top: pxToRem(2);
transition: transform 0.2s ease;
}
&:hover svg {
transform: translateX(4px);
}
}
}
@@ -0,0 +1,298 @@
@use '../../helpers/functions' as *;
.enterprise-capabilities {
position: relative;
background: radial-gradient(
107.37% 114.83% at 50% 94.96%,
rgba(67, 37, 174, 0) 0%,
rgba(67, 37, 174, 0) 75%,
rgba(67, 37, 174, 0.8) 90%,
#6143e0 100%
),
#090e1a;
padding-top: pxToRem(120);
padding-bottom: 31rem;
overflow: hidden;
isolation: isolate;
&__stars {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: pxToRem(1440);
height: pxToRem(800);
pointer-events: none;
z-index: 1;
background-image: url('/img/home/stars-bg.svg');
background-size: 1440px 800px;
background-position: center top;
background-repeat: no-repeat;
}
&__background {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;
}
&__white-light {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;
aspect-ratio: 1/1;
max-width: pxToRem(1600);
&:before {
content: '';
display: none;
position: absolute;
inset: 0;
filter: blur(5px);
mix-blend-mode: plus-lighter;
background: radial-gradient(
49.61% 49.61% at 50% 50%,
transparent 0%,
transparent 35.59%,
#d6d6d6 71.07%,
transparent 100%
)
center bottom / pxToRem(1800) auto no-repeat;
background-blend-mode: color-dodge;
transform: translateY(120%);
margin-right: -100px;
margin-left: -100px;
@include media-breakpoint-up(lg) {
display: block;
transform: translateY(90%);
}
}
}
&__globe-blue-light {
content: '';
position: absolute;
inset: 0;
//background: $secondary-blue-30;
background: url(/img/home/globe/globe-light.svg) center bottom / pxToRem(1800) auto no-repeat;
mix-blend-mode: plus-lighter;
filter: blur(40px);
margin-right: -100px;
margin-left: -100px;
}
&__globe-front {
position: absolute;
inset: 0;
z-index: 2;
&::before {
content: '';
position: absolute;
inset: 0;
background-image: url('/img/home/globe/globe.png');
background-size: pxToRem(1600) auto;
background-position: center bottom;
background-repeat: no-repeat;
z-index: 1;
}
&::after {
content: '';
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 240px;
background: linear-gradient(180deg, rgba(9, 14, 26, 0) 4.25%, #090e1a 88.85%);
background-position: center bottom;
background-repeat: no-repeat;
z-index: 1;
}
}
// Content
&__content {
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
gap: $spacer * 4;
}
// Header
&__header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: $spacer;
max-width: pxToRem(920);
}
&__title {
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.5px;
color: $neutral-98;
margin: 0;
@include media-breakpoint-up(xl) {
font-size: pxToRem(48);
}
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
letter-spacing: -0.2px;
color: $neutral-70;
margin: 0;
max-width: pxToRem(730);
@include media-breakpoint-up(xl) {
font-size: map-get($font-sizes-text, 'xl');
}
}
// Cards
&__cards {
display: grid;
grid-template-columns: 1fr;
gap: $spacer * 2;
width: 100%;
max-width: pxToRem(1114);
@include media-breakpoint-up(md) {
grid-template-columns: repeat(2, 1fr);
}
@include media-breakpoint-up(xl) {
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto;
gap: pxToRem(30);
align-items: stretch;
}
}
&__card {
display: flex;
flex-direction: column;
gap: $spacer;
min-width: 0;
padding: $spacer * 1.5 pxToRem(20);
background: linear-gradient(180deg, rgba(22, 30, 51, 0.95) 0%, rgba(14, 20, 36, 0.95) 100%);
border: 1px solid transparent;
border-top-color: $neutral-40;
border-radius: pxToRem(8);
overflow: visible;
position: relative;
text-decoration: none;
color: inherit;
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
&:hover {
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
background: linear-gradient(180deg, rgba(28, 38, 64, 0.98) 0%, rgba(20, 28, 48, 0.98) 100%);
}
@include media-breakpoint-up(xl) {
&--left {
grid-column: 1;
grid-row: 1 / 3;
align-self: end;
}
&--center-left {
grid-column: 2;
grid-row: 1;
}
&--center-right {
grid-column: 3;
grid-row: 1;
}
&--right {
grid-column: 4;
grid-row: 1 / 3;
align-self: end;
}
}
}
&__connector {
display: none;
@include media-breakpoint-up(xl) {
display: block;
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
width: pxToRem(36);
height: pxToRem(200);
pointer-events: none;
z-index: -1;
}
}
&__card-icon {
width: pxToRem(32);
height: pxToRem(32);
svg {
width: 100%;
height: 100%;
}
}
&__card-content {
display: flex;
flex-direction: column;
gap: $spacer * 0.5;
flex: 1;
}
&__card-title {
font-size: map-get($font-sizes-text, 'md');
font-weight: 600;
line-height: 1.5;
color: $neutral-98;
margin: 0;
}
&__card-description {
font-size: map-get($font-sizes-text, 'md');
font-weight: 350;
line-height: 1.5;
color: $neutral-70;
margin: 0;
}
&__card-link {
align-self: flex-start;
font-size: pxToRem(14);
font-weight: 500;
line-height: 1.5;
white-space: nowrap;
min-width: 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
&__card:hover &__card-link {
padding-right: calc(#{pxToRem(20)} + 6px);
&::before,
&::after {
animation: dash 0.3s ease-in-out forwards;
}
}
}
@@ -0,0 +1,215 @@
@use '../../helpers/functions' as *;
.enterprise-ready {
background-color: $neutral-94;
padding-top: pxToRem(80);
padding-bottom: pxToRem(80);
.container {
max-width: pxToRem(1110);
}
// Header
&__header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: $spacer;
margin-bottom: pxToRem(64);
}
&__title {
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.5px;
color: $neutral-20;
margin: 0;
@include media-breakpoint-up(xl) {
font-size: pxToRem(48);
}
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
letter-spacing: -0.2px;
color: $neutral-30;
margin: 0;
max-width: pxToRem(728);
@include media-breakpoint-up(xl) {
font-size: map-get($font-sizes-text, 'xl');
}
}
// Content wrapper
&__content {
display: flex;
flex-direction: column;
gap: pxToRem(30);
}
// Row containers
&__row {
display: flex;
flex-wrap: wrap;
gap: pxToRem(30);
}
&__row--large {
@include media-breakpoint-up(md) {
flex-wrap: nowrap;
}
}
&__row--small {
gap: pxToRem(30);
@include media-breakpoint-up(xl) {
flex-wrap: nowrap;
}
}
// Cards base
&__card {
background-color: $neutral-98;
border: 1px solid $neutral-90;
border-radius: pxToRem(8);
overflow: hidden;
}
// Large cards
&__card--large {
display: flex;
flex-direction: column;
width: 100%;
min-width: 0;
text-decoration: none;
transition:
box-shadow 0.2s ease,
border-color 0.2s ease;
@include media-breakpoint-up(md) {
flex: 1 1 0;
}
&#{&}__card--link:hover {
border-color: $neutral-80;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
}
&__card-visual {
position: relative;
height: pxToRem(144);
background-color: $neutral-98;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
&__card-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
&__card-footer {
display: flex;
align-items: center;
padding: pxToRem(24);
}
&__card-link {
align-self: flex-start;
font-weight: 500;
}
&__card--large#{&}__card--link:hover &__card-link {
$icon-width: pxToRem(20);
color: $primary-50;
padding-right: calc($icon-width + 6px);
&::before {
background: linear-gradient(to right, $primary-50 50%, transparent 50%);
background-size: 200% 100%;
background-position: 0 0;
animation: link-dash 0.3s ease-in-out forwards;
}
&::after {
background: $primary-50;
animation: link-dash 0.3s ease-in-out forwards;
}
}
@keyframes link-dash {
to {
background-position: 0 0;
}
}
// Small cards — flex to fill container width at all breakpoints
&__card--small {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
min-width: 0;
height: pxToRem(160);
padding: pxToRem(24);
text-decoration: none;
color: inherit;
transition:
box-shadow 0.2s ease,
border-color 0.2s ease;
@include media-breakpoint-up(sm) {
flex: 1 1 calc((100% - 60px) / 3);
}
@include media-breakpoint-up(xl) {
flex: 1 1 0;
}
&#{&}__card--link:hover {
border-color: $neutral-80;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
.enterprise-ready__card-label {
color: $primary-50;
}
}
}
&__card-icon {
width: pxToRem(24);
height: pxToRem(24);
svg,
img {
width: 100%;
height: 100%;
}
}
&__icon-svg {
display: block;
width: pxToRem(24);
height: pxToRem(24);
}
&__card-label {
font-size: map-get($font-sizes-text, 'md');
font-weight: 500;
line-height: 1.5;
color: $neutral-20;
transition: color 0.2s ease;
}
}
@@ -0,0 +1,515 @@
@use '../../helpers/functions' as *;
@use 'sass:math';
.hero {
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
align-items: center;
background: url('/img/home/hero/hero-bg-pattern.png') repeat $neutral-10;
background-size: 400px 400px;
padding: 0;
padding-bottom: 6rem;
&__container {
position: relative;
width: 100%;
max-width: pxToRem(1360);
overflow: hidden;
background: radial-gradient(
ellipse at center top,
rgba(1, 17, 54, 0) 10%,
rgba(7, 28, 78, 0.1) 40%,
rgba(28, 58, 130, 1) 64%,
rgba(34, 71, 152, 1) 100%
);
min-height: pxToRem(800);
padding-bottom: pxToRem(138);
}
&__grid {
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
opacity: 0.5;
mix-blend-mode: overlay;
background: url('/img/home/hero/grid.svg') center top / cover no-repeat;
will-change: transform;
transition: transform 0.1s linear;
}
&__content {
position: relative;
z-index: 5;
display: flex;
flex-direction: column;
align-items: center;
gap: pxToRem(24);
padding: pxToRem(48) pxToRem(20) 0;
}
&__heading {
display: flex;
flex-direction: column;
align-items: center;
gap: pxToRem(12);
max-width: pxToRem(730);
text-align: center;
}
&__title {
color: $neutral-98;
font-size: map-get($font-sizes, 4);
line-height: pxToRem(48);
font-weight: 600;
letter-spacing: -0.5px;
width: 100%;
}
&__subtitle {
color: $neutral-80;
font-size: pxToRem(16);
line-height: 1.5;
width: 100%;
}
&__buttons {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: pxToRem(16);
}
&__buttons a {
min-width: pxToRem(180);
}
&__planet {
position: absolute;
width: pxToRem(506);
height: pxToRem(480);
left: 50%;
transform: translate3d(-50%, 0, 0);
top: pxToRem(420);
z-index: 2;
will-change: transform;
transition: transform 0.1s linear;
}
&__planet-blur {
position: absolute;
width: calc(100% + 12%);
height: calc(100% + 13%);
top: -6.67%;
left: -6.32%;
mix-blend-mode: plus-lighter;
}
&__planet-blur--alt {
mix-blend-mode: plus-lighter;
}
&__planet-sphere {
position: absolute;
width: calc(100% + 1.58%);
height: calc(100% + 1.67%);
top: 0;
left: -0.79%;
}
&__planet-texture {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
mix-blend-mode: overlay;
object-fit: cover;
}
&__blue-haze {
position: absolute;
width: pxToRem(1200);
height: pxToRem(600);
left: 50%;
transform: translate3d(-50%, 0, 0);
bottom: pxToRem(80);
mix-blend-mode: lighten;
z-index: 2;
pointer-events: none;
will-change: transform;
transition: transform 0.1s linear;
}
&__astronauts {
position: absolute;
bottom: 0;
left: 50%;
transform: translate3d(-50%, 0, 0);
width: 100%;
max-width: pxToRem(1360);
height: pxToRem(360);
z-index: 3;
will-change: transform;
transition: transform 0.1s linear;
img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
}
&__fade-top {
position: absolute;
top: 0;
left: 0;
right: 0;
height: pxToRem(500);
background: linear-gradient(
to bottom,
$neutral-10 0%,
rgba($neutral-10, 0.7) 30%,
rgba($neutral-10, 0.3) 60%,
transparent 100%
);
z-index: 4;
pointer-events: none;
}
&__fade-bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 4;
height: 5vh;
min-height: pxToRem(20);
background: linear-gradient(
to top,
$neutral-10 0%,
rgba($neutral-10, 0.98) 35%,
rgba($neutral-10, 0.7) 50%,
rgba($neutral-10, 0.2) 90%,
transparent 100%
);
}
&__fade-left,
&__fade-right {
display: none;
}
&__fade-left {
left: 0;
background: linear-gradient(to right, $neutral-10 0%, rgba($neutral-10, 0.6) 40%, transparent 100%);
}
&__fade-right {
right: 0;
background: linear-gradient(to left, $neutral-10 0%, rgba($neutral-10, 0.6) 40%, transparent 100%);
}
&__badges {
position: absolute;
bottom: 0;
left: 0;
right: 0;
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: pxToRem(12);
z-index: 5;
padding: 0 pxToRem(16);
}
&__badge {
display: flex;
align-items: center;
justify-content: center;
gap: pxToRem(8);
padding: pxToRem(4) pxToRem(10);
background-color: rgba(17, 24, 36, 0.8);
border-radius: pxToRem(4);
white-space: nowrap;
text-decoration: none;
color: inherit;
transition: background-color 0.2s ease;
&--link:hover {
background-color: rgba(17, 24, 36, 1);
.hero__badge-text {
color: $neutral-98;
}
}
}
&__badge-icon {
width: pxToRem(16);
height: pxToRem(16);
flex-shrink: 0;
}
&__badge-text {
color: $neutral-90;
font-size: pxToRem(14);
line-height: 1.5;
font-weight: 500;
transition: color 0.2s ease;
}
&__stars {
position: absolute;
right: $spacer;
bottom: $spacer;
border-radius: 8px;
border: none;
outline: none;
display: flex;
align-items: center;
justify-content: center;
padding: calc($spacer / 2) pxToRem(20);
background-color: $neutral-10;
transition: bottom 1s ease-in-out;
}
&__stars svg {
max-width: pxToRem(24);
max-height: pxToRem(24);
}
&__stars-text {
color: $neutral-98;
margin-right: calc($spacer / 2);
margin-left: calc($spacer / 2);
font-size: map-get($font-sizes-text, 's');
line-height: pxToRem(21);
font-weight: 500;
}
&__stars-count {
border-radius: 6px;
border: 1px solid $neutral-30;
color: $neutral-98;
padding-left: calc($spacer / 2);
padding-right: calc($spacer / 2);
display: flex;
align-items: center;
justify-content: center;
gap: calc($spacer / 4);
height: pxToRem(25);
font-size: map-get($font-sizes-text, 's');
line-height: pxToRem(21);
}
@include media-breakpoint-up(xs) {
padding-bottom: $spacer * 2;
}
@include media-breakpoint-up(md) {
padding-left: $spacer * 2.5;
padding-right: $spacer * 2.5;
&__container {
padding-bottom: pxToRem(108);
}
&__buttons {
flex-direction: row;
gap: pxToRem(24);
}
&__buttons a {
min-width: auto;
}
&__fade-left,
&__fade-right {
display: block;
position: absolute;
top: 0;
bottom: 0;
width: pxToRem(80);
z-index: 4;
pointer-events: none;
}
}
@include media-breakpoint-up(lg) {
&__badges {
bottom: pxToRem(60);
}
}
@include media-breakpoint-up(xl) {
padding: 0 $spacer * 2.5;
padding-bottom: 0;
&__container {
min-height: pxToRem(940);
padding-bottom: 0;
}
&__content {
gap: pxToRem(32);
padding: pxToRem(64) pxToRem(125) 0;
}
&__heading {
gap: pxToRem(16);
}
&__title {
font-size: pxToRem(64);
line-height: 1.1;
letter-spacing: -1.5px;
}
&__subtitle {
font-size: pxToRem(20);
letter-spacing: -0.2px;
}
&__planet {
top: pxToRem(440);
}
&__blue-haze {
width: pxToRem(800);
height: pxToRem(200);
bottom: pxToRem(200);
}
&__astronauts {
height: pxToRem(482);
}
&__fade-bottom {
height: 5vh;
background: linear-gradient(
to top,
$neutral-10 0%,
rgba($neutral-10, 0.98) 40%,
rgba($neutral-10, 0.7) 50%,
rgba($neutral-10, 0.2) 90%,
transparent 100%
);
}
&__badges {
gap: pxToRem(40);
bottom: pxToRem(40);
flex-wrap: nowrap;
}
&__stars {
position: fixed;
right: $spacer * 1.5;
bottom: $spacer * 1.5;
transition: background-color 0.2s;
z-index: 2;
&:hover {
background-color: $neutral-100;
.hero__stars-text,
.hero__stars-count {
color: $neutral-20;
}
& > svg path {
fill: $neutral-20;
}
}
}
}
@include media-breakpoint-up(xxl) {
padding-left: $spacer * 6;
padding-right: $spacer * 6;
&__grid {
mask-image: linear-gradient(to bottom, black 0%, black 45%, transparent 70%);
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 45%, transparent 70%);
mask-size: 100% 100%;
-webkit-mask-size: 100% 100%;
}
&__container {
max-width: none;
width: 100%;
min-height: max(#{pxToRem(1000)}, 43vw);
}
&__fade-left,
&__fade-right {
width: pxToRem(120);
}
&__planet {
width: 37.2%;
height: auto;
aspect-ratio: 506 / 480;
top: pxToRem(430);
}
&__blue-haze {
width: 100%;
height: auto;
aspect-ratio: 4 / 1;
}
&__astronauts {
max-width: none;
width: 100%;
height: auto;
aspect-ratio: 1360 / 482;
img {
object-fit: contain;
}
}
&__fade-bottom {
height: 12vh;
min-height: pxToRem(100);
background: linear-gradient(
to top,
$neutral-10 0%,
rgba($neutral-10, 0.98) 40%,
rgba($neutral-10, 0.7) 50%,
rgba($neutral-10, 0.2) 90%,
transparent 100%
);
}
&__badges {
bottom: pxToRem(100);
}
}
@media (min-width: 2600px) {
padding-left: $spacer * 12;
padding-right: $spacer * 12;
&__container {
min-height: max(#{pxToRem(1000)}, 38vw);
}
&__planet {
top: pxToRem(420);
}
&__fade-bottom {
height: 15vh;
min-height: pxToRem(150);
}
&__badges {
bottom: pxToRem(120);
}
}
}
@@ -0,0 +1,118 @@
@use 'sass:math';
@use '../../helpers/functions' as *;
@use '../../mixins/marquee' as marquee;
$integrations-logos-bg: #090e1a;
$integrations-logos-border: #161e33;
$integrations-logos-text: #8f98b2;
.integrations-logos {
padding: pxToRem(80) 0;
background-color: $integrations-logos-bg;
&__title {
margin: 0 0 pxToRem(48);
font-family: 'Geist Mono', monospace;
font-size: pxToRem(14);
font-weight: 500;
line-height: pxToRem(21);
letter-spacing: pxToRem(2);
text-transform: uppercase;
text-align: center;
color: $integrations-logos-text;
}
&__content {
position: relative;
display: flex;
flex-direction: column;
padding-bottom: pxToRem(1);
}
&__cards {
@include marquee.base(80px, 240px, 8, 8, 0, $integrations-logos-bg, false, 40s, none);
&__container {
margin-bottom: pxToRem(-1);
}
&__item {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: pxToRem(240);
height: pxToRem(80);
border-top: 1px solid $integrations-logos-border;
border-right: 1px solid $integrations-logos-border;
border-bottom: 1px solid $integrations-logos-border;
svg {
height: pxToRem(56);
width: auto;
object-fit: contain;
filter: brightness(0) invert(1);
}
}
&__inner > span:first-child > &__item:first-child {
border-left: 1px solid $integrations-logos-border;
}
}
&__gradient-left,
&__gradient-right {
position: absolute;
top: 0;
bottom: 0;
width: pxToRem(80);
z-index: 1;
pointer-events: none;
@include media-breakpoint-up(lg) {
width: pxToRem(165);
}
}
&__gradient-left {
left: 0;
background: linear-gradient(
90deg,
$integrations-logos-bg 0.5%,
$integrations-logos-bg 38.79%,
rgba(9, 14, 26, 0) 100%
);
}
&__gradient-right {
right: 0;
background: linear-gradient(270deg, $integrations-logos-bg 38.79%, rgba(9, 14, 26, 0) 100%);
}
@include media-breakpoint-down(md) {
padding: pxToRem(48) 0;
&__title {
margin-bottom: pxToRem(32);
font-size: pxToRem(12);
line-height: pxToRem(18);
padding: 0 pxToRem(16);
}
&__cards {
@include marquee.base(64px, 180px, 8, 6, 0, $integrations-logos-bg, false, 35s, none);
&__item {
width: pxToRem(180);
height: pxToRem(64);
svg {
height: pxToRem(40);
width: auto;
object-fit: contain;
filter: brightness(0) invert(1);
}
}
}
}
}
@@ -0,0 +1,267 @@
@use '../../helpers/functions' as *;
.performance-by-design {
background-color: $neutral-94;
padding-top: pxToRem(80);
padding-bottom: pxToRem(80);
.container {
max-width: pxToRem(1110);
}
// Header
&__header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: $spacer;
margin-bottom: pxToRem(64);
max-width: pxToRem(920);
margin-left: auto;
margin-right: auto;
}
&__tagline {
font-family: 'Geist Mono', monospace;
font-size: pxToRem(14);
font-weight: 500;
line-height: pxToRem(21);
letter-spacing: 2px;
color: $neutral-30;
text-transform: uppercase;
}
&__title {
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.5px;
color: $neutral-20;
margin: 0;
@include media-breakpoint-up(md) {
font-size: pxToRem(48);
}
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
color: $neutral-30;
margin: 0;
@include media-breakpoint-up(md) {
font-size: map-get($font-sizes-text, 'l');
}
}
// Slider: visible from md up (big screens)
&__slider {
display: none;
@include media-breakpoint-up(md) {
display: block;
}
}
// Card grid: visible below md. 1 col on xs, 2 per row from sm.
&__grid {
display: grid;
grid-template-columns: 1fr;
gap: pxToRem(30);
@include media-breakpoint-up(sm) {
grid-template-columns: repeat(2, 1fr);
}
@include media-breakpoint-up(md) {
display: none;
}
}
// Card (why-qdrant--large style)
&__card {
background-color: $neutral-98;
border: 1px solid $neutral-90;
border-radius: pxToRem(8);
overflow: hidden;
display: flex;
flex-direction: column;
min-height: pxToRem(400);
}
&__card-visual {
position: relative;
overflow: hidden;
min-height: pxToRem(200);
background: linear-gradient(180deg, $neutral-98 0%, rgba($neutral-94, 0.3) 100%);
display: flex;
align-items: center;
justify-content: center;
}
&__card-image {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
&__card-content {
padding: pxToRem(24);
display: flex;
flex-direction: column;
gap: $spacer;
}
&__card-title {
font-size: pxToRem(20);
font-weight: 600;
line-height: 1.5;
letter-spacing: -0.2px;
color: $neutral-20;
margin: 0;
}
&__card-description {
font-size: map-get($font-sizes-text, 'md');
font-weight: 350;
line-height: 1.5;
color: $neutral-40;
margin: 0;
}
// Content layout (slider, visible from md up)
&__content {
display: flex;
flex-direction: column;
gap: pxToRem(48);
align-items: center;
@include media-breakpoint-up(md) {
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
gap: pxToRem(80);
}
}
// Features list (vertical slider nav)
&__features {
display: flex;
flex-direction: column;
width: 100%;
@include media-breakpoint-up(md) {
width: pxToRem(444);
flex-shrink: 0;
}
}
&__feature {
display: flex;
flex-direction: column;
padding: pxToRem(24) 0;
border-bottom: pxToRem(2) solid $neutral-90;
cursor: pointer;
transition: border-color 0.2s ease;
overflow: hidden;
&:first-child {
padding-top: 0;
}
}
&__feature-title {
font-size: pxToRem(20);
font-weight: 600;
line-height: 1.3;
letter-spacing: -0.5px;
color: $neutral-50;
margin: 0;
transition: color 0.2s ease;
@include media-breakpoint-up(md) {
font-size: pxToRem(24);
}
.performance-by-design__feature--active & {
color: $neutral-20;
}
.performance-by-design__feature:hover & {
color: $neutral-30;
}
}
&__feature-body {
max-height: 0;
opacity: 0;
overflow: hidden;
transition:
max-height 0.4s ease,
opacity 0.3s ease,
margin 0.3s ease;
margin-top: 0;
.performance-by-design__feature--active & {
max-height: pxToRem(200);
opacity: 1;
margin-top: $spacer;
}
}
&__feature-description {
font-size: map-get($font-sizes-text, 'md');
font-weight: 350;
line-height: 1.5;
color: $neutral-40;
margin: 0;
}
&__feature--active {
border-bottom-color: $primary-50;
}
// Visual / Image area (slider, visible from md up)
&__visual {
position: relative;
width: 100%;
min-height: pxToRem(300);
@include media-breakpoint-up(md) {
flex: 1 1 0%;
min-width: 0;
min-height: pxToRem(540);
}
}
&__image {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
visibility: hidden;
transition:
opacity 0.4s ease,
visibility 0.4s ease;
pointer-events: none;
&--active {
position: relative;
opacity: 1;
visibility: visible;
pointer-events: auto;
}
img {
width: 100%;
height: auto;
border-radius: pxToRem(8);
display: block;
}
}
}
@@ -0,0 +1,469 @@
@use 'sass:math';
@use '../../helpers/functions' as *;
$solutions-bg-dark: #090e1a;
$solutions-text-label: #8f98b2;
$solutions-text-title: #d4d9e6;
$solutions-text-subtitle: #8f98b2;
$solutions-tab-bg: #161e33;
$solutions-tab-border: #28324d;
$solutions-tab-active-bg: #3d4866;
$solutions-tab-text: #8f98b2;
$solutions-tab-text-active: #f0f3fa;
$solutions-panel-title: #e1e5f0;
$solutions-panel-text: #8f98b2;
$solutions-button-border: #717c99;
.solutions {
position: relative;
z-index: 0;
padding: pxToRem(60) 0;
background: radial-gradient(
104.31% 111.56% at 50% 0%,
rgba(67, 37, 174, 0) 0%,
rgba(67, 37, 174, 0) 80%,
rgba(67, 37, 174, 0.8) 90%,
rgba(97, 67, 224, 0.9) 100%
),
$solutions-bg-dark;
overflow: hidden;
&__background {
display: none;
}
&__header {
text-align: center;
margin-bottom: pxToRem(40);
}
&__label {
display: inline-block;
margin-bottom: pxToRem(16);
font-family: 'Geist Mono', monospace;
font-size: pxToRem(14);
font-weight: 500;
line-height: pxToRem(21);
letter-spacing: pxToRem(2);
text-transform: uppercase;
color: $solutions-text-label;
}
&__title {
margin: 0 auto pxToRem(16);
font-size: pxToRem(28);
font-weight: 600;
line-height: 1.1;
letter-spacing: pxToRem(-0.5);
color: $solutions-text-title;
}
&__subtitle {
max-width: pxToRem(730);
margin: 0 auto;
font-size: pxToRem(16);
line-height: 1.5;
color: $solutions-text-subtitle;
}
// Tabs
&__tabs-wrapper {
text-align: center;
}
&__tabs {
position: relative;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 0;
padding: pxToRem(4);
margin: 0 auto pxToRem(40);
background-color: $solutions-tab-bg;
border: 1px solid $solutions-tab-border;
border-radius: pxToRem(12);
overflow: hidden;
width: 100%;
}
&__tab {
position: relative;
z-index: 2;
flex-shrink: 0;
width: 100%;
height: pxToRem(36);
padding: 0 pxToRem(16);
font-family: inherit;
font-size: pxToRem(16);
font-weight: 500;
line-height: pxToRem(36);
color: $solutions-tab-text;
background: transparent;
border: none;
border-radius: pxToRem(8);
cursor: pointer;
transition: color 0.2s ease;
white-space: nowrap;
text-align: left;
&:hover {
color: $solutions-tab-text-active;
}
&--active {
color: $solutions-tab-text-active;
font-weight: 600;
background-color: $solutions-tab-active-bg;
}
}
&__tab-indicator {
display: none;
}
// Slider
&__slider {
position: relative;
min-height: pxToRem(250);
padding-bottom: pxToRem(40);
}
&__slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
visibility: hidden;
transition:
opacity 0.4s ease,
visibility 0.4s ease;
pointer-events: none;
&--active {
position: relative;
opacity: 1;
visibility: visible;
pointer-events: auto;
}
}
// Controls
&__controls {
display: flex;
align-items: center;
justify-content: center;
gap: pxToRem(40);
}
&__arrow {
display: flex;
align-items: center;
justify-content: center;
width: pxToRem(40);
height: pxToRem(40);
padding: 0;
background: none;
border: 1px solid $solutions-tab-border;
border-radius: pxToRem(8);
color: $solutions-tab-text;
cursor: pointer;
transition:
color 0.2s ease,
border-color 0.2s ease;
&:hover {
color: $solutions-tab-text-active;
border-color: $solutions-button-border;
}
svg {
width: pxToRem(20);
height: pxToRem(20);
}
}
&__dots {
display: flex;
align-items: center;
gap: pxToRem(20);
}
&__dot {
display: flex;
align-items: center;
justify-content: center;
width: pxToRem(24);
height: pxToRem(24);
background: none;
border: none;
cursor: pointer;
padding: 0;
span {
display: block;
width: pxToRem(6);
height: pxToRem(6);
background-color: $solutions-tab-border;
border-radius: 50%;
transition: background-color 0.2s ease;
}
&:hover span {
background-color: $solutions-tab-text;
}
&--active span {
background-color: $solutions-tab-text-active;
}
}
// Panel content
&__panel-content {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
padding-top: 0;
margin-bottom: pxToRem(32);
text-align: center;
}
&__panel-title {
margin: 0 0 pxToRem(24);
font-size: pxToRem(24);
font-weight: 600;
line-height: 1.3;
letter-spacing: pxToRem(-0.5);
color: $solutions-panel-title;
}
&__panel-description {
margin: 0 0 pxToRem(24);
font-size: pxToRem(16);
line-height: 1.5;
letter-spacing: pxToRem(-0.2);
color: $solutions-panel-text;
}
&__panel-link {
display: inline-flex;
align-items: center;
justify-content: center;
gap: pxToRem(12);
height: pxToRem(48);
padding: 0 pxToRem(28);
font-size: pxToRem(18);
font-weight: 600;
line-height: 1.5;
color: #fff;
text-decoration: none;
background: transparent;
border: 1px solid $solutions-button-border;
border-radius: pxToRem(8);
transition:
background-color 0.2s ease,
border-color 0.2s ease;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
border-color: #fff;
color: #fff;
}
}
&__panel-illustration {
display: flex;
align-items: center;
justify-content: center;
min-height: pxToRem(250);
padding: pxToRem(10);
img {
max-width: 100%;
max-height: pxToRem(250);
height: auto;
width: auto;
object-fit: contain;
}
}
&__panel-placeholder {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: pxToRem(250);
background: linear-gradient(135deg, rgba(22, 30, 51, 0.8) 0%, rgba(13, 19, 36, 0.9) 100%);
border: 1px dashed rgba(143, 152, 178, 0.3);
border-radius: pxToRem(16);
&::after {
content: attr(data-label) ' illustration';
font-family: 'Geist Mono', monospace;
font-size: pxToRem(12);
color: rgba(143, 152, 178, 0.5);
text-transform: uppercase;
letter-spacing: pxToRem(2);
}
}
@include media-breakpoint-up(sm) {
padding: pxToRem(80) 0;
&__header {
margin-bottom: pxToRem(40);
}
&__title {
font-size: pxToRem(36);
}
&__subtitle {
font-size: pxToRem(16);
}
&__slider {
min-height: auto;
}
&__panel-content {
padding-top: 0;
margin-bottom: pxToRem(32);
text-align: center;
}
&__panel-title {
font-size: pxToRem(24);
}
&__panel-description {
font-size: pxToRem(16);
}
&__panel-illustration {
min-height: pxToRem(300);
img {
max-height: pxToRem(300);
}
}
&__panel-placeholder {
height: pxToRem(300);
}
}
@include media-breakpoint-up(md) {
&__tabs {
flex-direction: row;
display: inline-flex;
width: fit-content;
max-width: 100%;
margin-bottom: pxToRem(40);
}
&__tab {
width: auto;
text-align: center;
padding: 0 pxToRem(8);
font-size: pxToRem(12);
height: pxToRem(36);
line-height: pxToRem(36);
}
&__tab--active {
background-color: transparent;
}
&__tab-indicator {
display: block;
position: absolute;
z-index: 1;
top: pxToRem(4);
left: pxToRem(4);
height: pxToRem(36);
background-color: $solutions-tab-active-bg;
border-radius: pxToRem(8);
transition:
left 0.3s ease,
width 0.3s ease;
}
}
@include media-breakpoint-up(lg) {
&__tab {
font-size: pxToRem(14);
padding: 0 pxToRem(20);
}
}
@include media-breakpoint-up(xl) {
padding: pxToRem(120) 0;
&__header {
margin-bottom: pxToRem(64);
}
&__title {
font-size: pxToRem(48);
}
&__subtitle {
font-size: pxToRem(18);
}
&__tabs {
margin-bottom: pxToRem(64);
}
&__tab {
font-size: pxToRem(16);
height: pxToRem(40);
line-height: pxToRem(40);
}
&__tab-indicator {
top: pxToRem(4);
left: pxToRem(4);
height: pxToRem(40);
}
&__slider {
min-height: pxToRem(400);
}
&__panel-content {
padding-top: pxToRem(40);
margin-bottom: 0;
text-align: left;
}
&__panel-title {
font-size: pxToRem(32);
}
&__panel-description {
font-size: pxToRem(20);
}
&__panel-illustration {
min-height: pxToRem(400);
padding: pxToRem(20);
img {
max-height: pxToRem(400);
}
}
&__panel-placeholder {
height: pxToRem(400);
&::after {
font-size: pxToRem(14);
}
}
}
}
@@ -0,0 +1,166 @@
@use '../../helpers/functions' as *;
// Mobile-first: base styles (no min-width), then enhance from xxl only
.why-qdrant {
background-color: $neutral-94;
padding-top: $spacer * 5;
padding-bottom: $spacer * 5;
&__header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin-bottom: $spacer * 4;
gap: $spacer;
}
&__pill {
font-family: 'Geist Mono', $font-family-monospace;
font-size: pxToRem(14);
font-weight: 500;
line-height: 1.5;
letter-spacing: 2px;
color: $neutral-30;
text-transform: uppercase;
}
&__title {
font-size: pxToRem(32);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.5px;
color: $neutral-20;
margin: 0;
max-width: pxToRem(838);
}
&__subtitle {
font-size: map-get($font-sizes-text, 'l');
font-weight: 350;
line-height: 1.5;
color: $neutral-30;
margin: 0;
max-width: pxToRem(780);
}
&__grid {
display: flex;
flex-direction: column;
gap: $spacer * 2;
}
&__card {
background-color: $neutral-98;
border: 1px solid $neutral-90;
border-radius: pxToRem(8);
overflow: hidden;
display: flex;
flex-direction: column;
min-height: pxToRem(400);
}
&__card-visual {
flex: 1;
position: relative;
overflow: hidden;
min-height: pxToRem(200);
background: linear-gradient(180deg, $neutral-98 0%, rgba($neutral-94, 0.3) 100%);
display: flex;
align-items: center;
justify-content: center;
}
&__card-image {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
&__card-content {
padding: pxToRem(24);
display: flex;
flex-direction: column;
gap: $spacer;
}
&__card-title {
font-size: pxToRem(20);
font-weight: 600;
line-height: 1.5;
letter-spacing: -0.2px;
color: $neutral-20;
margin: 0;
}
&__card-description {
font-size: map-get($font-sizes-text, 'md');
font-weight: 350;
line-height: 1.5;
color: $neutral-40;
margin: 0;
code {
font-family: 'Geist Mono', $font-family-monospace;
font-size: pxToRem(14);
color: $success-50;
background: transparent;
padding: 0;
}
}
&__card-link {
align-self: flex-start;
font-weight: 500;
line-height: 1.5;
}
@include media-breakpoint-up(md) {
&__title {
font-size: pxToRem(48);
}
&__grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: auto auto;
gap: pxToRem(30);
}
&__card {
min-height: pxToRem(440);
&--large {
grid-column: span 3;
}
&--small {
grid-column: span 2;
&:nth-child(3) {
grid-column: 1 / span 2;
grid-row: 2;
}
&:nth-child(4) {
grid-column: 3 / span 2;
grid-row: 2;
}
&:nth-child(5) {
grid-column: 5 / span 2;
grid-row: 2;
}
}
}
&__card-visual {
min-height: pxToRem(266);
.why-qdrant__card--small & {
min-height: pxToRem(218);
}
}
}
}
@@ -0,0 +1,10 @@
@import 'home-hero';
@import 'home-customers';
@import 'home-why-qdrant';
@import 'home-case-studies';
@import 'home-enterprise-capabilities';
@import 'home-enterprise-ready';
@import 'home-performance-by-design';
@import 'home-engineered-for-builders';
@import 'home-integrations-logos';
@import 'home-solutions';
@@ -0,0 +1,41 @@
/**
* Hero parallax for home page.
* Only runs when on home page (script loaded conditionally).
* Uses translate3d for Safari GPU acceleration and smooth rendering.
*/
function initHeroParallax() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const hero = document.querySelector('.hero');
if (!hero) return;
const layers = [
{ el: hero.querySelector('.hero__grid'), factor: 0.06, centered: false },
{ el: hero.querySelector('.hero__planet'), factor: 0.2, centered: true },
{ el: hero.querySelector('.hero__blue-haze'), factor: 0.08, centered: true },
{ el: hero.querySelector('.hero__astronauts'), factor: 0.12, centered: true },
].filter(({ el }) => el);
let ticking = false;
function updateParallax() {
const scrollY = window.scrollY;
layers.forEach(({ el, factor, centered }) => {
const y = Math.round(scrollY * factor * 10) / 10;
el.style.transform = centered ? `translate3d(-50%, ${y}px, 0)` : `translate3d(0, ${y}px, 0)`;
});
ticking = false;
}
function onScroll() {
if (!ticking) {
requestAnimationFrame(updateParallax);
ticking = true;
}
}
window.addEventListener('scroll', onScroll, { passive: true });
updateParallax();
}
document.addEventListener('DOMContentLoaded', initHeroParallax);
@@ -1,10 +1,6 @@
import scrollHandler from './scroll-handler';
import { XXL_BREAKPOINT } from './constants';
import {
addUTMToLinks,
initGoToTopButton,
persistUTMParams
} from './helpers';
import { addUTMToLinks, initGoToTopButton, persistUTMParams } from './helpers';
import { handleSegmentReady } from './segment-helpers';
import { addOneTrustPreferencesToLinks, registerAndCall } from './onetrust-helpers';
import TableOfContents from './table-of-content';
@@ -17,8 +13,10 @@ persistUTMParams();
document.addEventListener('DOMContentLoaded', function () {
addUTMToLinks();
const handleOneTrustLoaded = () => { // One Trust Loaded
window.OneTrust.OnConsentChanged(async () => { // One Trust Preference Updated
const handleOneTrustLoaded = () => {
// One Trust Loaded
window.OneTrust.OnConsentChanged(async () => {
// One Trust Preference Updated
addOneTrustPreferencesToLinks();
registerAndCall();
@@ -176,5 +174,4 @@ document.addEventListener('DOMContentLoaded', function () {
scrollIntoViewWithOffset(target.replace('#', ''), offset);
});
});
});
@@ -0,0 +1,29 @@
/**
* Lightweight scroll reveal using IntersectionObserver.
* Respects prefers-reduced-motion.
*/
document.documentElement.classList.add('js-loaded');
function initScrollReveal() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const elements = document.querySelectorAll('[data-reveal]');
if (!elements.length) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entry.target.classList.toggle('revealed', entry.isIntersecting);
});
},
{
threshold: 0.15,
rootMargin: '0px 0px -40px 0px',
},
);
elements.forEach((el) => observer.observe(el));
}
document.addEventListener('DOMContentLoaded', initScrollReveal);
@@ -1,19 +1,20 @@
{{ define "main" }}
{{ partial "site-header" . }}
{{ partial "hero" . }}
{{ partial "customers" . }}
{{ partial "home/hero" . }}
{{ partial "home/customers" . }}
{{ partial "core-features" . }}
{{ partial "customer-stories" . }}
{{ partial "integrations" . }}
{{ with (.Site.GetPage "/headless/main/docker-deploy") }}
{{ partial "docker-deploy" (dict "context" . "class" "") }}
{{ partial "home/why-qdrant" . }}
{{ partial "home/case-studies" . }}
{{ partial "home/enterprise-capabilities" . }}
{{ partial "home/enterprise-ready" . }}
{{ with (.Site.GetPage "/headless/main/canva") }}
{{ partial "testimonial-light" (dict "context" . "class" "customers-testimonial pb-5 pb-lg-7") }}
{{ end }}
{{ with (.Site.GetPage "/headless/main/vectors") }}
{{ partial "vectors" . }}
{{ partial "home/performance-by-design" . }}
{{ partial "home/engineered-for-builders" . }}
{{ partial "home/integrations-logos" . }}
{{ partial "home/solutions" . }}
{{ with (.Site.GetPage "/headless/main/cta-banner") }}
{{ partial "cta-banner" . }}
{{ end }}
{{ partial "get-started" . }}
{{ end }}
@@ -1,39 +0,0 @@
{{ with (.Site.GetPage "/headless/main/core-features") }}
<section class="core-features">
<div class="container">
<div class="row gy-4">
<div class="col-12">
<h2 class="core-features__title mx-auto">{{ .Params.title }}</h2>
<p class="core-features__subtitle mx-auto">{{ .Params.description }}</p>
<div class="text-start text-lg-center">
<a class="link link_xl" href="{{ .Params.link.url }}">{{ .Params.link.text }}</a>
</div>
</div>
<div class="col-12">
<a href="{{ .Params.cloudFeature.link.url }}" class="card core-features__cloud-native">
<div>
<h4 class="core-features__card-title">{{ .Params.cloudFeature.title }}</h4>
<p class="core-features__card-content">{{ .Params.cloudFeature.content }}</p>
<span class="link link_dark link_md">
{{ .Params.cloudFeature.link.text }}
</span>
</div>
<div class="core-features__cloud-native-image"></div>
</a>
</div>
{{ range .Params.featureCards }}
<div class="col-12 col-xl-4">
<a href="{{ .link.url }}" class="card core-features__card">
<div>
{{ .icon | safeHTML }}
<h6 class="core-features__card-title">{{ .title }}</h6>
<p class="core-features__card-content">{{ .content }}</p>
</div>
<span class="link link_dark link_md align-self-start"> {{ .link.text }} </span>
</a>
</div>
{{ end }}
</div>
</div>
</section>
{{ end }}
@@ -1,9 +1,9 @@
{{ $background := default (dict "src" "/img/cta-banner-stars.png" "webp" "/img/cta-banner-stars.webp") .Params.background }}
{{ $illustration := default (dict "src" "/img/cta-illustration.png" "alt" "Rocket flying over globe illustration") .Params.illustration }}
<section class="cta-banner">
<div class="container">
<div class="cta-banner__banner">
{{ if .Params.background }}
<div class="cta-banner__background" style="background-image: url('{{ .Params.background.src }}');"></div>
{{ end }}
<div class="cta-banner__background" style="background-image: url('{{ $background.src }}');{{ if $background.webp }} background-image: image-set(url('{{ $background.webp }}') type('image/webp'), url('{{ $background.src }}') type('image/png'));{{ end }}"></div>
<div class="cta-banner__content">
<div class="cta-banner__text">
<h2 class="cta-banner__title">{{ .Params.title }}</h2>
@@ -14,11 +14,9 @@
{{ .Params.button.text }}
</a>
</div>
{{ if .Params.illustration }}
<div class="cta-banner__illustration">
<img src="{{ .Params.illustration.src }}" alt="{{ .Params.illustration.alt }}" />
</div>
{{ end }}
<div class="cta-banner__illustration">
{{ partial "picture" (dict "src" $illustration.src "alt" $illustration.alt "loading" "lazy" "decoding" "async") }}
</div>
</div>
</div>
</div>
@@ -1,17 +0,0 @@
{{ with (.Site.GetPage "/headless/main/customers") }}
<section class="customers">
{{ $context := slice }}
{{ range .Params.customers }}
{{ $context = $context | append (dict "svg" .logo "name" .name) }}
{{ end }}
{{ partial "marquee.html" (dict "context" $context "marqueeClass" "customers__logos") }}
<div class="customers__description">
<span class="customers__title">{{ .Params.customerStories.text }}</span>
{{ if .Params.customerStories.url }}
<a class="link link_xl" href="{{ .Params.customerStories.url }}"> {{ .Params.customerStories.textLink }} </a>
{{ end }}
</div>
</section>
{{ end }}
@@ -29,6 +29,17 @@
{{ partial "css" . }}
{{ if .IsHome }}
{{ with .Site.GetPage "/headless/main/hero" }}
{{ with .Params.astronauts }}
<link rel="preload" as="image" type="image/webp" fetchpriority="high"
imagesrcset="{{ .webpSrcset }}"
imagesizes="100vw"
/>
{{ end }}
{{ end }}
{{ end }}
{{ hugo.Generator }}
{{ with .OutputFormats.Get "RSS" }}
@@ -1,48 +0,0 @@
{{ with (.Site.GetPage "/headless/main/hero") }}
<section class="hero">
<div class="container">
<div class="row">
<div class="col-12">
<div class="hero__content">
<h1 class="hero__title">{{ .Params.title }}</h1>
<p class="hero__subtitle">{{ .Params.subtitle }}</p>
<div class="hero__buttons">
<a data-metric-loc="hero" href="{{ .Params.startFree.url }}" class="button button_contained button_lg"
>{{ .Params.startFree.text }}</a
>
<a data-metric-loc="hero" href="{{ .Params.learnMore.url }}" class="button button_outlined button_lg"
>{{ .Params.learnMore.text }}</a
>
</div>
</div>
</div>
</div>
<a href="{{ .Params.githubStars.actionUrl }}" type="button" class="hero__stars" target="_blank">
{{ .Params.githubStars.logo | safeHTML }}
<span class="hero__stars-text">{{ .Params.githubStars.actionText }}</span>
<span class="hero__stars-count">
{{ .Params.githubStars.starIcon | safeHTML }}
{{ with (.Site.GetPage "/headless/stats") }}
{{ .Params.stats.githubStars }}
{{ end }}
</span>
</a>
</div>
<div class="hero__image">
<picture>
{{ range .Params.heroImageSources }}
<source
{{ if
.minWidth
}}
media="(min-width: {{ .minWidth }})"
{{ end }}
srcset="{{ .srcset }}"
type="{{ .type }}"
/>
{{ end }}
<img src="{{ .Params.fallbackHeroImage.src }}" alt="{{ .Params.fallbackHeroImage.alt }}" draggable="false" />
</picture>
</div>
</section>
{{ end }}
@@ -0,0 +1,152 @@
{{ with (.Site.GetPage "/headless/main/case-studies") }}
<section class="case-studies">
<div class="container case-studies__container">
<div class="case-studies__header">
<h2 class="case-studies__title">{{ .Params.title }}</h2>
<div class="case-studies__controls">
<button type="button" class="case-studies__arrow case-studies__arrow--prev" aria-label="Previous slide">
<svg width="24" height="14" viewBox="0 0 17 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 1L1.5 5L5.5 9M1.5 5H16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button type="button" class="case-studies__arrow case-studies__arrow--next" aria-label="Next slide">
<svg width="24" height="14" viewBox="0 0 17 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.5 1L15.5 5M15.5 5L11.5 9M15.5 5H1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>
<div class="case-studies__carousel-outer">
<div class="case-studies__carousel">
<div class="case-studies__track">
{{ range .Params.caseStudies }}
<div class="case-studies__slide">
{{ if .link }}<a href="{{ .link }}" class="case-studies__card-link">{{ end }}
<div class="case-studies__card">
<p class="case-studies__card-text">
{{ .text }}
{{ if .highlight }}
<span class="case-studies__phrase{{ if eq (trim .textAfter " ") "." }} case-studies__phrase--no-break{{ end }}"><span class="case-studies__highlight">{{ .highlight }}</span>{{ if ne (trim .textAfter " ") "." }} {{ end }}{{ .textAfter }}</span>
{{ end }}
{{ if and (not .highlight) .textAfter }}{{ .textAfter }}{{ end }}
{{ if .highlight2 }}
<span class="case-studies__phrase{{ if eq (trim .textAfter2 " ") "." }} case-studies__phrase--no-break{{ end }}"><span class="case-studies__highlight">{{ .highlight2 }}</span>{{ if ne (trim .textAfter2 " ") "." }} {{ end }}{{ .textAfter2 }}</span>
{{ end }}
{{ if and (not .highlight2) .textAfter2 }}{{ .textAfter2 }}{{ end }}
</p>
<div class="case-studies__card-footer">
<div class="case-studies__card-logo" role="img" aria-label="{{ .logoAlt }}">
{{ partial "svg" (dict "icon" .logoIcon "path" "themes/qdrant-2024/static/img/customer-logo/") }}
</div>
<div class="case-studies__card-arrow">
<svg width="24" height="14" viewBox="0 0 17 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.5 1L15.5 5M15.5 5L11.5 9M15.5 5H1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
</div>
</div>
{{ if .link }}</a>{{ end }}
</div>
{{ end }}
</div>
</div>
</div>
</div>
</section>
<script>
(function() {
const container = document.querySelector('.case-studies__container');
const carousel = document.querySelector('.case-studies__carousel');
const track = document.querySelector('.case-studies__track');
const prevBtn = document.querySelector('.case-studies__arrow--prev');
const nextBtn = document.querySelector('.case-studies__arrow--next');
if (!container || !carousel || !track || !prevBtn || !nextBtn) return;
const slides = track.querySelectorAll('.case-studies__slide');
const gap = 30;
const breakpoints = { sm: 576, md: 768, xl: 1200 };
let currentOffset = 0;
function getVisibleCount() {
const w = window.innerWidth;
if (w < breakpoints.sm) return 1;
if (w < breakpoints.md) return 2;
if (w < breakpoints.xl) return 3;
return 4;
}
function getContainerContentWidth() {
const style = getComputedStyle(container);
const paddingLeft = parseFloat(style.paddingLeft) || 0;
const paddingRight = parseFloat(style.paddingRight) || 0;
return container.offsetWidth - paddingLeft - paddingRight;
}
function getSlideWidth() {
const contentWidth = getContainerContentWidth();
const count = Math.min(getVisibleCount(), slides.length);
const gaps = Math.max(0, count - 1) * gap;
return Math.floor((contentWidth - gaps) / count);
}
function applySlideWidth() {
const slideWidth = getSlideWidth();
carousel.style.setProperty('--case-studies-slide-width', slideWidth + 'px');
}
function getMaxOffset() {
applySlideWidth();
const slideWidth = getSlideWidth();
const trackWidth = slides.length * slideWidth + (slides.length - 1) * gap;
const contentWidth = getContainerContentWidth();
return Math.max(0, trackWidth - contentWidth);
}
function updateTrack() {
const maxOffset = getMaxOffset();
currentOffset = Math.min(Math.max(0, currentOffset), maxOffset);
track.style.transform = `translateX(-${currentOffset}px)`;
}
function updateButtons() {
const maxOffset = getMaxOffset();
prevBtn.disabled = currentOffset <= 0;
nextBtn.disabled = currentOffset >= maxOffset;
}
prevBtn.addEventListener('click', function() {
const slideWidth = getSlideWidth();
currentOffset = Math.max(0, currentOffset - (slideWidth + gap));
updateTrack();
updateButtons();
});
nextBtn.addEventListener('click', function() {
const maxOffset = getMaxOffset();
const slideWidth = getSlideWidth();
currentOffset = Math.min(maxOffset, currentOffset + (slideWidth + gap));
updateTrack();
updateButtons();
});
function onResize() {
applySlideWidth();
updateTrack();
updateButtons();
}
let resizeTimer;
window.addEventListener('resize', function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
requestAnimationFrame(onResize);
}, 100);
});
applySlideWidth();
updateTrack();
updateButtons();
})();
</script>
{{ end }}
@@ -0,0 +1,15 @@
{{ with (.Site.GetPage "/headless/main/customers") }}
<section class="customers">
<div class="container">
<div class="customers__grid">
{{ range .Params.logoRows }}
{{ range .logos }}
<div class="customers__logo">
{{ partial "svg.html" (dict "icon" .src "path" "static" "fill" "#B4BACC") }}
</div>
{{ end }}
{{ end }}
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,53 @@
{{ with (.Site.GetPage "/headless/main/engineered-for-builders") }}
<section class="engineered-for-builders">
<div class="engineered-for-builders__background" aria-hidden="true"></div>
<div class="engineered-for-builders__background-texture" aria-hidden="true"></div>
<div class="container">
<div class="engineered-for-builders__header">
<h2 class="engineered-for-builders__title">{{ .Params.title }}</h2>
<p class="engineered-for-builders__subtitle">{{ .Params.subtitle }}</p>
</div>
{{ with .Params.illustration }}
<div class="engineered-for-builders__illustration">
{{ if .srcset }}
<picture>
{{ with .webpSrcset }}<source type="image/webp" srcset="{{ . }}" />{{ end }}
<img
src="{{ .src }}"
srcset="{{ .srcset }}"
alt="{{ .alt }}"
class="engineered-for-builders__illustration-image"
width="{{ .width }}"
height="{{ .height }}"
loading="lazy"
decoding="async"
/>
</picture>
{{ else }}
{{ partial "picture" (dict "src" .src "alt" .alt "class" "engineered-for-builders__illustration-image" "loading" "lazy" "decoding" "async" "width" .width "height" .height) }}
{{ end }}
</div>
{{ end }}
<div class="engineered-for-builders__features">
{{ range .Params.features }}
<div class="engineered-for-builders__feature">
<h3 class="engineered-for-builders__feature-title">{{ .title }}</h3>
<p class="engineered-for-builders__feature-description">{{ .description }}</p>
<a href="{{ .link.url }}" class="engineered-for-builders__feature-link">
{{ .link.text }}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M3.33 8H12.67M12.67 8L8.67 4M12.67 8L8.67 12"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</a>
</div>
{{ end }}
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,45 @@
{{ with (.Site.GetPage "/headless/main/enterprise-capabilities") }}
{{ $iconsPath := "static/img/components/icons/" }}
<section class="enterprise-capabilities">
<div class="enterprise-capabilities__stars" aria-hidden="true"></div>
<div class="container enterprise-capabilities__white-light" aria-hidden="true"></div>
<div class="enterprise-capabilities__background" aria-hidden="true">
<div class="enterprise-capabilities__globe-blue-light"></div>
<div class="enterprise-capabilities__globe-blue-light"></div>
<div class="enterprise-capabilities__globe-blue-light"></div>
<div class="enterprise-capabilities__globe-front"></div>
</div>
<div class="container enterprise-capabilities__white-light" aria-hidden="true"></div>
<div class="enterprise-capabilities__background" aria-hidden="true">
<div class="enterprise-capabilities__globe-front"></div>
</div>
<div class="container">
<div class="enterprise-capabilities__content">
<div class="enterprise-capabilities__header">
<h2 class="enterprise-capabilities__title">{{ .Params.title }}</h2>
<p class="enterprise-capabilities__subtitle">{{ .Params.subtitle }}</p>
</div>
<div class="enterprise-capabilities__cards">
{{ range .Params.deploymentOptions }}
<a href="{{ .link.url }}" class="enterprise-capabilities__card enterprise-capabilities__card--{{ .position }}">
{{ if .connector }}
<img src="{{ .connector }}" alt="" class="enterprise-capabilities__connector" />
{{ end }}
<div class="enterprise-capabilities__card-icon">
{{ partial "svg" (dict "icon" .icon "path" $iconsPath "color" .iconColor ) }}
</div>
<div class="enterprise-capabilities__card-content">
<h3 class="enterprise-capabilities__card-title">{{ .title }}</h3>
<p class="enterprise-capabilities__card-description">{{ .description }}</p>
</div>
<span class="link link_white link_md enterprise-capabilities__card-link"
>{{ .link.text }}</span
>
</a>
{{ end }}
</div>
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,50 @@
{{ with (.Site.GetPage "/headless/main/enterprise-ready") }}
<section class="enterprise-ready">
<div class="container">
<div class="enterprise-ready__header">
<h2 class="enterprise-ready__title">{{ .Params.title }}</h2>
<p class="enterprise-ready__subtitle">{{ .Params.subtitle }}</p>
</div>
<div class="enterprise-ready__content">
{{/* Large cards row */}}
<div class="enterprise-ready__row enterprise-ready__row--large">
{{ range .Params.largeCards }}
{{ if and .link .link.url }}
<a href="{{ .link.url }}" class="enterprise-ready__card enterprise-ready__card--large enterprise-ready__card--link"{{ if or (hasPrefix .link.url "http://") (hasPrefix .link.url "https://") }} target="_blank" rel="noopener noreferrer"{{ end }}>
{{ else }}
<div class="enterprise-ready__card enterprise-ready__card--large">
{{ end }}
<div class="enterprise-ready__card-visual enterprise-ready__card-visual--{{ .visual }}">
{{ if .image }}
{{ partial "picture" (dict "src" .image.src "alt" .image.alt "class" "enterprise-ready__card-img" "loading" "lazy" "decoding" "async") }}
{{ end }}
</div>
<div class="enterprise-ready__card-footer">
<span class="link link_dark link_md enterprise-ready__card-link">{{ .title }}</span>
</div>
{{ if and .link .link.url }}</a>{{ else }}</div>{{ end }}
{{ end }}
</div>
{{/* Small cards row */}}
{{ $iconsPath := "static/img/components/icons/" }}
<div class="enterprise-ready__row enterprise-ready__row--small">
{{ range .Params.smallCards }}
{{ if and .link .link.url }}
<a href="{{ .link.url }}" class="enterprise-ready__card enterprise-ready__card--small enterprise-ready__card--link"{{ if or (hasPrefix .link.url "http://") (hasPrefix .link.url "https://") }} target="_blank" rel="noopener noreferrer"{{ end }}>
{{ else }}
<div class="enterprise-ready__card enterprise-ready__card--small">
{{ end }}
<div class="enterprise-ready__card-icon">
{{ if .icon }}
{{ partial "svg" (dict "icon" .icon.name "path" $iconsPath "color" .icon.color "stroke" .icon.stroke "fill" .icon.fill) }}
{{ end }}
</div>
<span class="enterprise-ready__card-label">{{ .title }}</span>
{{ if and .link .link.url }}</a>{{ else }}</div>{{ end }}
{{ end }}
</div>
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,95 @@
{{ with (.Site.GetPage "/headless/main/hero") }}
<section class="hero">
<div class="hero__container">
<div class="hero__grid"></div>
<div class="hero__content">
<div class="hero__heading">
<h1 class="hero__title">{{ .Params.title }}</h1>
<p class="hero__subtitle">{{ .Params.subtitle }}</p>
</div>
<div class="hero__buttons">
<a data-metric-loc="hero" href="{{ .Params.startFree.url }}" class="button button_contained button_lg"
data-metric-loc="hero">{{ .Params.startFree.text }}</a>
<a data-metric-loc="hero" href="{{ .Params.learnMore.url }}" class="button button_outlined button_lg"
data-metric-loc="hero">{{ .Params.learnMore.text }}</a>
</div>
</div>
<div class="hero__planet">
{{ with .Params.planet }}
<img class="hero__planet-blur" src="{{ .blur }}" alt="" width="570" height="544" decoding="async" />
<img
class="hero__planet-blur hero__planet-blur--alt"
src="{{ .blur2 }}"
alt=""
width="570"
height="544"
decoding="async"
/>
<img class="hero__planet-sphere" src="{{ .sphere }}" alt="" width="514" height="488" decoding="async" />
{{ with .texture }}
<picture>
<source srcset="{{ .webp }}" type="image/webp" />
<img
class="hero__planet-texture"
src="{{ .png }}"
alt=""
width="1012"
height="960"
loading="eager"
decoding="async"
/>
</picture>
{{ end }}
{{ end }}
</div>
{{ with .Params.blueHaze }}
<img class="hero__blue-haze" src="{{ . }}" alt="" width="1200" height="600" decoding="async" />
{{ end }}
<div class="hero__astronauts">
{{ with .Params.astronauts }}
<picture>
<source type="image/webp" srcset="{{ .webpSrcset }}" sizes="100vw" />
<img
src="{{ .fallbackSrc }}"
srcset="{{ .pngSrcset }}"
sizes="100vw"
alt="{{ .alt }}"
width="{{ .width }}"
height="{{ .height }}"
draggable="false"
loading="eager"
decoding="async"
fetchpriority="high"
/>
</picture>
{{ end }}
</div>
<div class="hero__fade-top"></div>
<div class="hero__fade-bottom"></div>
<div class="hero__fade-left"></div>
<div class="hero__fade-right"></div>
</div>
{{ if .Params.valueBadges }}
<div class="hero__badges">
{{ range .Params.valueBadges }}
{{ if .url }}
<a href="{{ .url }}" class="hero__badge hero__badge--link"{{ if or (hasPrefix .url "http://") (hasPrefix .url "https://") }} target="_blank" rel="noopener noreferrer"{{ end }}>
<img src="{{ .icon }}" alt="" class="hero__badge-icon" width="16" height="16" decoding="async" />
<span class="hero__badge-text">{{ .text }}</span>
</a>
{{ else }}
<span class="hero__badge">
<img src="{{ .icon }}" alt="" class="hero__badge-icon" width="16" height="16" decoding="async" />
<span class="hero__badge-text">{{ .text }}</span>
</span>
{{ end }}
{{ end }}
</div>
{{ end }}
</section>
{{ end }}
@@ -0,0 +1,46 @@
{{ with (.Site.GetPage "/headless/main/integrations-logos") }}
{{ $logosFirstRow := .Params.logosFirstRow }}
{{ $logosSecondRow := .Params.logosSecondRow }}
<section class="integrations-logos">
<div class="container">
<p class="integrations-logos__title">{{ .Params.title }}</p>
</div>
<div class="integrations-logos__content">
<div class="integrations-logos__cards">
<div class="integrations-logos__cards__container">
<div class="integrations-logos__cards__block">
<div class="integrations-logos__cards__inner integrations-logos__cards__inner_to-left">
<span>
{{ partial "integrations-logos-cards" (dict "context" $logosFirstRow) }}
</span>
<span>
{{ partial "integrations-logos-cards" (dict "context" $logosFirstRow) }}
</span>
</div>
</div>
</div>
</div>
<div class="integrations-logos__cards">
<div class="integrations-logos__cards__container">
<div class="integrations-logos__cards__block">
<div class="integrations-logos__cards__inner integrations-logos__cards__inner_to-right">
<span>
{{ partial "integrations-logos-cards" (dict "context" $logosSecondRow) }}
</span>
<span>
{{ partial "integrations-logos-cards" (dict "context" $logosSecondRow) }}
</span>
</div>
</div>
</div>
</div>
<div class="integrations-logos__gradient-left"></div>
<div class="integrations-logos__gradient-right"></div>
</div>
</section>
{{ end }}
@@ -0,0 +1,110 @@
{{ with (.Site.GetPage "/headless/main/performance-by-design") }}
<section class="performance-by-design">
<div class="container">
<div class="performance-by-design__header">
<span class="performance-by-design__tagline">{{ .Params.tagline }}</span>
<h2 class="performance-by-design__title">{{ .Params.title }}</h2>
<p class="performance-by-design__subtitle">{{ .Params.subtitle }}</p>
</div>
{{/* Slider layout: visible only below md */}}
<div class="performance-by-design__slider">
<div class="performance-by-design__content">
<div class="performance-by-design__features">
{{ range $index, $feature := .Params.features }}
<div class="performance-by-design__feature{{ if eq $index 0 }} performance-by-design__feature--active{{ end }}" data-feature-index="{{ $index }}">
<h3 class="performance-by-design__feature-title">{{ $feature.title }}</h3>
<div class="performance-by-design__feature-body">
<p class="performance-by-design__feature-description">{{ $feature.description }}</p>
</div>
</div>
{{ end }}
</div>
<div class="performance-by-design__visual">
{{ range $index, $feature := .Params.features }}
<div class="performance-by-design__image{{ if eq $index 0 }} performance-by-design__image--active{{ end }}" data-image-index="{{ $index }}">
{{ if $feature.image }}
{{ partial "picture" (dict "src" $feature.image.src "alt" $feature.image.alt "loading" "lazy" "decoding" "async") }}
{{ end }}
</div>
{{ end }}
</div>
</div>
</div>
{{/* Card grid: visible from md up, 2 cards per row */}}
<div class="performance-by-design__grid">
{{ range .Params.features }}
<div class="performance-by-design__card">
{{ if .image }}
<div class="performance-by-design__card-visual">
{{ partial "picture" (dict "src" .image.src "alt" .image.alt "class" "performance-by-design__card-image" "loading" "lazy" "decoding" "async") }}
</div>
{{ end }}
<div class="performance-by-design__card-content">
<h3 class="performance-by-design__card-title">{{ .title }}</h3>
<p class="performance-by-design__card-description">{{ .description }}</p>
</div>
</div>
{{ end }}
</div>
</div>
</section>
<script>
(function () {
var section = document.querySelector('.performance-by-design');
if (!section) return;
var features = section.querySelectorAll('.performance-by-design__feature');
var images = section.querySelectorAll('.performance-by-design__image');
if (!features.length) return;
var currentIndex = 0;
var autoplayInterval = null;
var AUTOPLAY_DELAY = 5000;
function goToFeature(index) {
if (index < 0 || index >= features.length) return;
features.forEach(function (f) {
f.classList.remove('performance-by-design__feature--active');
});
images.forEach(function (img) {
img.classList.remove('performance-by-design__image--active');
});
features[index].classList.add('performance-by-design__feature--active');
if (images[index]) images[index].classList.add('performance-by-design__image--active');
currentIndex = index;
}
function nextFeature() {
var next = (currentIndex + 1) % features.length;
goToFeature(next);
}
function startAutoplay() {
stopAutoplay();
autoplayInterval = setInterval(nextFeature, AUTOPLAY_DELAY);
}
function stopAutoplay() {
if (autoplayInterval) {
clearInterval(autoplayInterval);
autoplayInterval = null;
}
}
features.forEach(function (feature, i) {
feature.addEventListener('click', function () {
goToFeature(i);
startAutoplay();
});
});
startAutoplay();
})();
</script>
{{ end }}
@@ -0,0 +1,23 @@
{{ with (.Site.GetPage "/headless/main/solutions") }}
<section class="solutions">
<div class="solutions__background"></div>
<div class="container">
<div class="solutions__header">
<span class="solutions__label">{{ .Params.label }}</span>
<h2 class="solutions__title">{{ .Params.title }}</h2>
<p class="solutions__subtitle">{{ .Params.subtitle }}</p>
</div>
<div>
{{ partial "tab-slider" (dict
"sectionClass" "solutions"
"tabs" .Params.tabs
"items" .Params.tabs
"slidePartial" "solutions-slide-content"
"showControls" true
)
}}
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,27 @@
{{ with (.Site.GetPage "/headless/main/why-qdrant") }}
<section class="why-qdrant">
<div class="container">
<div class="why-qdrant__header">
<span class="why-qdrant__pill">{{ .Params.pill }}</span>
<h2 class="why-qdrant__title">{{ .Params.title }}</h2>
<p class="why-qdrant__subtitle">{{ .Params.subtitle }}</p>
</div>
<div class="why-qdrant__grid">
{{ range .Params.featureCards }}
<div class="why-qdrant__card why-qdrant__card--{{ .size }}" data-card-id="{{ .id }}">
<div class="why-qdrant__card-visual why-qdrant__card-visual--{{ .id }}">
{{ if .image }}
{{ partial "picture" (dict "src" .image.src "alt" .image.alt "class" "why-qdrant__card-image" "loading" "lazy" "decoding" "async") }}
{{ end }}
</div>
<div class="why-qdrant__card-content">
<h3 class="why-qdrant__card-title">{{ .title }}</h3>
<p class="why-qdrant__card-description">{{ .description | safeHTML }}</p>
<a href="{{ .link.url }}" class="link link_md why-qdrant__card-link">{{ .link.text }}</a>
</div>
</div>
{{ end }}
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,10 @@
{{ range .context }}
<div class="integrations-logos__cards__item" role="img" aria-label="{{ .logo.alt }}">
{{ partial "svg" (dict "icon" .logo.icon "path" "themes/qdrant-2024/static/img/customer-logo/") }}
</div>
{{ end }}
{{ range .context }}
<div class="integrations-logos__cards__item" role="img" aria-label="{{ .logo.alt }}">
{{ partial "svg" (dict "icon" .logo.icon "path" "themes/qdrant-2024/static/img/customer-logo/") }}
</div>
{{ end }}
@@ -1,15 +0,0 @@
{{ with (.Site.GetPage "/headless/main/integrations") }}
<section class="integrations">
<div class="container">
<h2 class="integrations__title mx-auto">{{ .Params.title }}</h2>
<p class="integrations__subtitle">
Qdrant integrates with all leading
<a class="integrations__link" href="{{ .Params.embedLink.url }}">{{ .Params.embedLink.text }}</a> and
<a class="integrations__link" href="{{ .Params.frameworkLink.url }}">{{ .Params.frameworkLink.text }}</a>.
</p>
<div class="text-center">{{ .Scratch.Set "cssClass" "link_light link_xl" }} {{ partial "link" . }}</div>
<div class="integrations__preview mx-auto"></div>
<div class="integrations__overlay"></div>
</div>
</section>
{{ end }}
@@ -7,7 +7,12 @@
<!-- OneTrust Cookies Consent Notice start for local.qdrant.tech -->
{{ if .Site.Params.onetrustScriptID }}
<script src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="{{ .Site.Params.onetrustScriptID }}" ></script>
<script
src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js"
type="text/javascript"
charset="UTF-8"
data-domain-script="{{ .Site.Params.onetrustScriptID }}"
></script>
<script async type="text/javascript">
function OptanonWrapper() {
const onetrustAnalyticsChoice = new CustomEvent('onetrust_loaded');
@@ -36,6 +41,7 @@
</script>
{{ end }}
<!--Google Measurement ID-->
{{ $googleJs := resources.Get "js/google-setup.js" | js.Build (dict "params" (dict "gaMeasurementId" .Site.Config.Services.GoogleAnalytics.ID)) | minify | resources.Fingerprint "sha512" }}
<script src="{{ $googleJs.RelPermalink }}"></script>
@@ -44,6 +50,12 @@
<script src="{{ $indexJs.RelPermalink }}"></script>
{{ if .IsHome }}
{{ $homeAnimationsJs := resources.Get "/js/home-animations.js" | js.Build | minify | resources.Fingerprint "sha512" }}
<script src="{{ $homeAnimationsJs.RelPermalink }}"></script>
{{ $scrollRevealJs := resources.Get "/js/scroll-reveal.js" | js.Build | minify | resources.Fingerprint "sha512" }}
<script src="{{ $scrollRevealJs.RelPermalink }}"></script>
<!--splide.js carousel-->
{{ $splideJs := resources.Get "/js/vendor/splide.js" | js.Build | minify | resources.Fingerprint "sha512" }}
<script src="{{ $splideJs.RelPermalink }}"></script>
@@ -153,27 +165,22 @@
{{ if and (eq .Section "blog") (.IsPage) }}
<script>
document.addEventListener("scroll", () => {
const article = document.getElementById("article");
const progress = document.getElementById("progress");
document.addEventListener('scroll', () => {
const article = document.getElementById('article');
const progress = document.getElementById('progress');
const articleHeight = article.scrollHeight - window.innerHeight;
const scrollTop = window.scrollY - article.offsetTop;
progress.value = Math.min(
Math.max((scrollTop / articleHeight) * 100, 0),
100
);
progress.value = Math.min(Math.max((scrollTop / articleHeight) * 100, 0), 100);
});
</script>
{{ end }}
<script>
window.addEventListener("message", event => {
if (
event.data.type === "hsFormCallback" &&
event.data.eventName === "onFormReady"
) {
window.addEventListener('message', (event) => {
if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormReady') {
const formEl = document.querySelector(`form[data-form-id="${event.data.id}"]`);
if (formEl) {
const hiddenCurrentUrl = formEl.querySelector('[name="last_form_fill_url"]');
@@ -0,0 +1,30 @@
{{- $src := .src -}}
{{- $alt := .alt | default "" -}}
{{- $ext := path.Ext $src -}}
{{- if eq $ext ".svg" -}}
<img
src="{{ $src }}"
alt="{{ $alt }}"
{{- with .class }}class="{{ . }}"{{ end -}}
{{- with .loading }}loading="{{ . }}"{{ end -}}
{{- with .decoding }}decoding="{{ . }}"{{ end -}}
{{- with .width }}width="{{ . }}"{{ end -}}
{{- with .height }}height="{{ . }}"{{ end -}}
/>
{{- else -}}
{{- $webpSrc := replace $src $ext ".webp" -}}
<picture>
<source srcset="{{ $webpSrc }}" type="image/webp" />
<img
src="{{ $src }}"
alt="{{ $alt }}"
{{- with .class }}class="{{ . }}"{{ end -}}
{{- with .loading }}loading="{{ . }}"{{ end -}}
{{- with .decoding }}decoding="{{ . }}"{{ end -}}
{{- with .fetchpriority }}fetchpriority="{{ . }}"{{ end -}}
{{- with .width }}width="{{ . }}"{{ end -}}
{{- with .height }}height="{{ . }}"{{ end -}}
/>
</picture>
{{- end -}}
@@ -0,0 +1,21 @@
{{ $item := .item }}
<div class="row align-items-center">
<div class="col-12 col-lg-5">
<div class="solutions__panel-content">
<h3 class="solutions__panel-title">{{ $item.title }}</h3>
<p class="solutions__panel-description">{{ $item.description }}</p>
<a href="{{ $item.link.url }}" class="solutions__panel-link">
{{ $item.link.text }}
</a>
</div>
</div>
<div class="col-12 col-lg-7">
<div class="solutions__panel-illustration">
{{ if $item.image }}
{{ partial "picture" (dict "src" $item.image.src "alt" $item.image.alt "loading" "lazy" "decoding" "async") }}
{{ else }}
<div class="solutions__panel-placeholder" data-label="{{ $item.title }}"></div>
{{ end }}
</div>
</div>
</div>
@@ -1 +1,77 @@
{{ $path := "static/icons/outline/" }} {{ $filename := . }} {{ readFile (printf "%s%s" $path $filename) | safeHTML }}
<!-- {{/* svg.html partial
-----------------
This partial renders SVG icons dynamically with Hugo templating.
- Usage:
{{ partial "svg.html" (dict "icon" "icon-filename" "stroke" "color" "fill" "path" "custom/path/")
}}
OR just:
{{ partial "svg.html" "icon-filename" }}
- Parameters:
- icon / filename: Name of SVG file (without or with .svg extension).
- path (optional): Folder path (default: static/icons/outline/).
- stroke, fill, color (optional): Override respective SVG attributes, using CSS variables (e.g. "primary", "teal", etc).
* For Bootstrap color variables, use just the color name (e.g., "primary", "violet"), which becomes: var(--bs-primary).
* You can also use "currentColor" to inherit from CSS context.
* HEX values are supported as well.
- How it works:
- Loads the SVG file as text.
- Replaces stroke/fill/color attributes if provided.
- Allows color to be controlled via style or CSS variables.
- Safe for direct HTML inclusion.
- Typical use:
For icons in cards, buttons, menus, etc.
Maintainers: Update this file if icon assets or color conventions change.
*/}} -->
{{ $path := "static/icons/outline/" }}
{{ $filename := "" }}
{{ $stroke := "" }}
{{ $fill := "" }}
{{ $color := "" }}
{{ if reflect.IsMap . }}
{{ $path = default $path .path }}
{{ $filename = default .filename .icon }}
{{ $stroke = .stroke }}
{{ $fill = .fill }}
{{ $color = .color }}
{{ else }}
{{ $filename = . }}
{{ end }}
{{ if not (strings.HasSuffix $filename ".svg") }}
{{ $filename = printf "%s.svg" $filename }}
{{ end }}
{{ $svg := readFile (printf "%s%s" $path $filename) }}
{{ if $stroke }}
{{ $strokeVal := $stroke }}
{{ if and (ne (strings.HasPrefix $stroke "#") true) (ne (strings.HasPrefix $stroke "var(") true) (ne $stroke "currentColor") (ne $stroke "inherit") (ne $stroke "none") }}
{{ $strokeVal = printf "var(--bs-%s)" $stroke }}
{{ end }}
{{ $svg = replaceRE `stroke="[^"]*"` (printf `stroke="%s"` $strokeVal) $svg }}
{{ $svg = replaceRE `stroke='[^']*'` (printf `stroke="%s"` $strokeVal) $svg }}
{{ end }}
{{ if $fill }}
{{ $fillVal := $fill }}
{{ if and (ne (strings.HasPrefix $fill "#") true) (ne (strings.HasPrefix $fill "var(") true) (ne $fill "currentColor") (ne $fill "inherit") (ne $fill "none") }}
{{ $fillVal = printf "var(--bs-%s)" $fill }}
{{ end }}
{{ $svg = replaceRE `fill="[^"]*"` (printf `fill="%s"` $fillVal) $svg }}
{{ $svg = replaceRE `fill='[^']*'` (printf `fill="%s"` $fillVal) $svg }}
{{ end }}
{{ if $color }}
{{ $colorVal := $color }}
{{ if and (ne (strings.HasPrefix $color "#") true) (ne (strings.HasPrefix $color "var(") true) (ne $color "currentColor") (ne $color "inherit") (ne $color "none") }}
{{ $colorVal = printf "var(--bs-%s)" $color }}
{{ end }}
{{ $svg = replaceRE `(<svg)(\s)` (printf `$1 style="color:%s"$2` $colorVal) $svg }}
{{ $svg = replaceRE `stroke="[^"]*"` `stroke="currentColor"` $svg }}
{{ $svg = replaceRE `stroke='[^']*'` `stroke="currentColor"` $svg }}
{{ end }}
{{ $svg | safeHTML }}
@@ -0,0 +1,133 @@
{{/*
Reusable Tab-Slider Partial
Params (passed via dict):
- sectionClass: CSS class prefix for the section (e.g., "solutions", "healthcare-use-cases")
- tabs: array of tab objects with at least .id and .label (or .name)
- items: array of slide items to render
- slidePartial: name of the partial to render each slide's content
- showControls: (optional) whether to show arrow/dot controls (default: true)
*/}}
{{ $sectionClass := .sectionClass }}
{{ $tabs := .tabs }}
{{ $items := .items }}
{{ $slidePartial := .slidePartial }}
{{ $showControls := true }}
{{ if isset . "showControls" }}
{{ $showControls = .showControls }}
{{ end }}
<div class="{{ $sectionClass }}__tabs-wrapper">
<div class="{{ $sectionClass }}__tabs">
{{ range $index, $tab := $tabs }}
<button
type="button"
class="{{ $sectionClass }}__tab{{ if eq $index 0 }} {{ $sectionClass }}__tab--active{{ end }}"
data-tab-index="{{ $index }}"
>
{{ with $tab.label }}{{ . }}{{ else }}{{ $tab.name }}{{ end }}
</button>
{{ end }}
<div class="{{ $sectionClass }}__tab-indicator"></div>
</div>
</div>
<div class="{{ $sectionClass }}__slider">
{{ range $index, $item := $items }}
<div class="{{ $sectionClass }}__slide{{ if eq $index 0 }} {{ $sectionClass }}__slide--active{{ end }}" data-slide="{{ $index }}">
{{ partial $slidePartial (dict "item" $item "index" $index "sectionClass" $sectionClass) }}
</div>
{{ end }}
</div>
{{ if $showControls }}
<div class="{{ $sectionClass }}__controls">
<button type="button" class="{{ $sectionClass }}__arrow {{ $sectionClass }}__arrow--prev" aria-label="Previous slide">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5 15L7.5 10L12.5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="{{ $sectionClass }}__dots">
{{ range $index, $tab := $tabs }}
<button
type="button"
class="{{ $sectionClass }}__dot{{ if eq $index 0 }} {{ $sectionClass }}__dot--active{{ end }}"
data-slide-index="{{ $index }}"
aria-label="Go to slide {{ add $index 1 }}"
>
<span></span>
</button>
{{ end }}
</div>
<button type="button" class="{{ $sectionClass }}__arrow {{ $sectionClass }}__arrow--next" aria-label="Next slide">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.5 5L12.5 10L7.5 15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
{{ end }}
<script>
(function() {
var section = document.querySelector('.{{ $sectionClass }}');
if (!section) return;
var tabs = section.querySelectorAll('.{{ $sectionClass }}__tab');
var dots = section.querySelectorAll('.{{ $sectionClass }}__dot');
var slides = section.querySelectorAll('.{{ $sectionClass }}__slide');
var prevBtn = section.querySelector('.{{ $sectionClass }}__arrow--prev');
var nextBtn = section.querySelector('.{{ $sectionClass }}__arrow--next');
var indicator = section.querySelector('.{{ $sectionClass }}__tab-indicator');
var currentIndex = 0;
var totalSlides = slides.length;
function updateIndicator(activeTab) {
if (indicator && activeTab) {
indicator.style.width = activeTab.offsetWidth + 'px';
indicator.style.left = activeTab.offsetLeft + 'px';
}
}
function goToSlide(index) {
if (index < 0) index = totalSlides - 1;
if (index >= totalSlides) index = 0;
currentIndex = index;
slides.forEach(function(slide, i) {
slide.classList.toggle('{{ $sectionClass }}__slide--active', i === index);
});
tabs.forEach(function(tab, i) {
tab.classList.toggle('{{ $sectionClass }}__tab--active', i === index);
if (i === index) updateIndicator(tab);
});
dots.forEach(function(dot, i) {
dot.classList.toggle('{{ $sectionClass }}__dot--active', i === index);
});
}
tabs.forEach(function(tab, i) {
tab.addEventListener('click', function() { goToSlide(i); });
});
dots.forEach(function(dot, i) {
dot.addEventListener('click', function() { goToSlide(i); });
});
if (prevBtn) prevBtn.addEventListener('click', function() { goToSlide(currentIndex - 1); });
if (nextBtn) nextBtn.addEventListener('click', function() { goToSlide(currentIndex + 1); });
// Initialize indicator
var activeTab = section.querySelector('.{{ $sectionClass }}__tab--active');
if (activeTab) updateIndicator(activeTab);
window.addEventListener('resize', function() {
var activeTab = section.querySelector('.{{ $sectionClass }}__tab--active');
if (activeTab) updateIndicator(activeTab);
});
})();
</script>
@@ -1,7 +1,11 @@
{{ $class := .class }}
<section class="testimonial-light {{ $class }}">
{{ $ctx := .context }}
{{ $hasReview := and $ctx.Params.review (ne (trim (string $ctx.Params.review) " \t\n\r") "") }}
{{ $hasEmployees := and $ctx.Params.avatar $ctx.Params.avatar.src }}
{{ $hasContent := or $hasReview $hasEmployees }}
<section class="testimonial-light {{ $class }}{{ if $ctx.Params.gradient }} testimonial-light--gradient-layout{{ end }}">
<div class="container">
{{ with .context.Params.partners }}
{{ with $ctx.Params.partners }}
<div class="testimonial-light__partners">
<p class="testimonial-light__partners-title">{{ .title }}</p>
<div class="testimonial-light__partners-logos">
@@ -14,25 +18,35 @@
</div>
{{ end }}
<div class="row gy-4 gx-3">
{{ if $hasContent }}
<div class="col-12 col-xl-9">
<div class="testimonial-light__content">
<p class="testimonial-light__review">{{ .context.Params.review | safeHTML }}</p>
{{ if $hasReview }}
<p class="testimonial-light__review">{{ $ctx.Params.review | safeHTML }}</p>
{{ end }}
{{ with $ctx.Params.avatar }}
{{ if .src }}
<div class="testimonial-light__employees">
<div class="testimonial-light__employees-avatar">
<img src="{{ .context.Params.avatar.src }}" alt="{{ .context.Params.avatar.alt }}" />
<img src="{{ .src }}" alt="{{ .alt }}" />
</div>
<div class="testimonial-light__employees-position">
<p>{{ .context.Params.names }}</p>
<p>{{ .context.Params.positions }}</p>
{{ with $ctx.Params.names }}<p>{{ . }}</p>{{ end }}
{{ with $ctx.Params.positions }}<p>{{ . }}</p>{{ end }}
</div>
</div>
{{ end }}
{{ end }}
</div>
</div>
<div class="col-12 col-xl-3">
<div class="testimonial-light__logo">
<img src="{{ .context.Params.logo.src }}" alt="{{ .context.Params.logo.alt }}" />
{{ end }}
{{ with $ctx.Params.logo }}
<div class="col-12 {{ if $hasContent }}col-xl-3{{ else }}col-12{{ end }}">
<div class="testimonial-light__logo{{ if $ctx.Params.gradient }} testimonial-light__logo--gradient{{ end }}">
<img src="{{ .src }}" alt="{{ .alt }}" />
</div>
</div>
{{ end }}
</div>
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

@@ -0,0 +1,4 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.4375 7H13.5625" stroke="#161E33" stroke-width="0.875" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.1875 2.625L13.5625 7L9.1875 11.375" stroke="#161E33" stroke-width="0.875" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 353 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5981 17.1962C19.033 18.0246 19.5246 19.8594 18.6962 21.2943C17.8677 22.7291 16.033 23.2208 14.5981 22.3923C13.1632 21.5639 12.6716 19.7291 13.5 18.2943C14.3284 16.8594 16.1632 16.3678 17.5981 17.1962ZM17.5981 17.1962L20.5981 12M20.0981 12.866L21.8301 13.866M13.3712 13.3573C12.6219 13.1251 11.8256 13 11 13C6.582 13 3 16.582 3 21C5.16655 21.5415 7.33326 21.8631 9.5 21.9646M11 10C13.2091 10 15 8.20914 15 6C15 3.79086 13.2091 2 11 2C8.79086 2 7 3.79086 7 6C7 8.20914 8.79086 10 11 10Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

@@ -0,0 +1,10 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38 46.0001V35.7251C40.4862 33.6998 42.4193 31.0782 43.6194 28.1046C44.8194 25.1309 45.2473 21.9019 44.8632 18.7183C44.4791 15.5347 43.2955 12.5001 41.4226 9.8972C39.5498 7.29428 37.0486 5.20772 34.1521 3.83187C31.2556 2.45603 28.0579 1.83566 24.8571 2.02855C21.6562 2.22145 18.5562 3.22133 15.8459 4.93507C13.1356 6.6488 10.9031 9.02063 9.35633 11.8296C7.80962 14.6386 6.999 17.7934 7 21.0001V23.0001L3 32.0001L7 34.0001V42.0001C7 43.0609 7.42143 44.0783 8.17157 44.8285C8.92172 45.5786 9.93913 46.0001 11 46.0001H19C20.3132 46.0001 21.6136 45.7414 22.8268 45.2389C24.0401 44.7363 25.1425 43.9997 26.0711 43.0711C26.9997 42.1425 27.7362 41.0402 28.2388 39.8269C28.7413 38.6136 29 37.3133 29 36.0001V25.0001" stroke="url(#paint0_linear_7807_40064)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M36.0709 28.071C37.9462 26.1956 38.9997 23.6521 38.9997 21C38.9997 18.3478 37.9462 15.8043 36.0709 13.929M21.9289 13.929C20.0535 15.8043 19 18.3478 19 21C19 23.6521 20.0535 26.1956 21.9289 28.071M32.9999 21C32.9999 23.2091 31.209 25 28.9999 25C26.7907 25 24.9999 23.2091 24.9999 21C24.9999 18.7908 26.7907 17 28.9999 17C31.209 17 32.9999 18.7908 32.9999 21Z" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/>
<defs>
<linearGradient id="paint0_linear_7807_40064" x1="24" y1="-54.2357" x2="24" y2="46.0001" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#28324D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 2L22 22M22 22H12M22 22V12" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 225 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2V22M12 22L19 15M12 22L5 15" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 228 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2 19.6C11.2972 19.7181 11.4193 19.8133 11.5577 19.8786C11.696 19.9439 11.847 19.9777 12 19.9777C12.153 19.9777 12.304 19.9439 12.4423 19.8786C12.5807 19.8133 12.7028 19.7181 12.8 19.6L21.8 7.6C21.9114 7.45143 21.9793 7.27477 21.996 7.08981C22.0126 6.90484 21.9775 6.71889 21.8944 6.55279C21.8114 6.38668 21.6837 6.24698 21.5257 6.14935C21.3678 6.05171 21.1857 6 21 6H3C2.81429 6 2.63225 6.05171 2.47427 6.14935C2.31629 6.24698 2.18863 6.38668 2.10557 6.55279C2.02252 6.71889 1.98736 6.90484 2.00404 7.08981C2.02072 7.27477 2.08857 7.45143 2.2 7.6L11.2 19.6Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 692 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.447 2.10503C17.2802 2.02348 17.0942 1.98966 16.9094 2.0073C16.7246 2.02495 16.5483 2.09339 16.4 2.20503L4.4 11.205C4.2758 11.2982 4.175 11.419 4.10557 11.5578C4.03614 11.6967 4 11.8498 4 12.005C4 12.1603 4.03614 12.3134 4.10557 12.4522C4.175 12.5911 4.2758 12.7119 4.4 12.805L16.4 21.805C16.5489 21.9167 16.726 21.9846 16.9114 22.0011C17.0968 22.0176 17.2832 21.982 17.4495 21.8983C17.6157 21.8147 17.7554 21.6863 17.8526 21.5276C17.9499 21.3689 18.0009 21.1862 18 21V3.00003C18.0001 2.8142 17.9484 2.63202 17.8507 2.47393C17.753 2.31584 17.6132 2.1881 17.447 2.10503Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 703 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.6 2.2C7.45143 2.08857 7.27477 2.02072 7.08981 2.00404C6.90484 1.98736 6.71889 2.02252 6.55279 2.10557C6.38668 2.18863 6.24698 2.31629 6.14935 2.47427C6.05171 2.63225 6 2.81429 6 3V21C6 21.1857 6.05171 21.3678 6.14935 21.5257C6.24698 21.6837 6.38668 21.8114 6.55279 21.8944C6.71889 21.9775 6.90484 22.0126 7.08981 21.996C7.27477 21.9793 7.45143 21.9114 7.6 21.8L19.6 12.8C19.7242 12.7069 19.825 12.5861 19.8944 12.4472C19.9639 12.3084 20 12.1552 20 12C20 11.8448 19.9639 11.6916 19.8944 11.5528C19.825 11.4139 19.7242 11.2931 19.6 11.2L7.6 2.2Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 677 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.8 4.40003C12.7028 4.28191 12.5807 4.18678 12.4423 4.12146C12.304 4.05615 12.153 4.02228 12 4.02228C11.847 4.02228 11.696 4.05615 11.5577 4.12146C11.4193 4.18678 11.2972 4.28191 11.2 4.40003L2.2 16.4C2.08857 16.5486 2.02072 16.7253 2.00404 16.9102C1.98736 17.0952 2.02252 17.2811 2.10557 17.4472C2.18863 17.6133 2.31629 17.753 2.47427 17.8507C2.63225 17.9483 2.81429 18 3 18H21C21.1857 18 21.3678 17.9483 21.5257 17.8507C21.6837 17.753 21.8114 17.6133 21.8944 17.4472C21.9775 17.2811 22.0126 17.0952 21.996 16.9102C21.9793 16.7253 21.9114 16.5486 21.8 16.4L12.8 4.40003Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 704 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 12H2M2 12L9 19M2 12L9 5" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 224 B

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 5L22 12L15 19" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 12H22" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 22L22 2M22 2H12M22 2V12" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 223 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 22V2M12 2L5 9M12 2L19 9" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 224 B

@@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 1H3V23H21V1Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 6H17" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 10H17" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 14H17" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 18H17" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 6H7V10H11V6Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 732 B

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 4V1" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 16C2 7.083 7.029 4 12 4C16.971 4 22 7.083 22 16C22 20.971 16.971 23 12 23C7.029 23 2 20.971 2 16Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.0001 8C8.19609 8 6.18909 10.463 6.01709 15.312C6.07809 15.907 6.34909 16.426 7.19609 16.935C8.32209 17.612 10.0731 18 12.0001 18C13.9271 18 15.6781 17.612 16.8041 16.935C17.6511 16.426 17.9211 15.907 17.9831 15.312C17.8111 10.463 15.8041 8 12.0001 8Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 746 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 12C3 7.02944 7.02944 3 12 3V12V21C7.02944 21 3 16.9706 3 12ZM12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 346 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 0C1.65342 0 1.33156 0.179452 1.14935 0.474269C0.967144 0.769085 0.95058 1.13723 1.10557 1.44721L5.83353 10.9031C4.68826 12.2872 4 14.0632 4 16C4 20.4183 7.58172 24 12 24C16.4183 24 20 20.4183 20 16C20 14.0632 19.3117 12.2872 18.1665 10.9031L22.8944 1.44721C23.0494 1.13723 23.0329 0.769085 22.8507 0.474269C22.6684 0.179452 22.3466 0 22 0H16C15.6212 0 15.275 0.214002 15.1056 0.552786L12 6.76393L8.89443 0.552786C8.72504 0.214002 8.37877 0 8 0H2ZM7.776 11.7388C7.75516 11.7619 7.73315 11.784 7.70999 11.8053C6.65208 12.887 6 14.3674 6 16C6 19.3137 8.68629 22 12 22C15.3137 22 18 19.3137 18 16C18 14.3674 17.3479 12.887 16.29 11.8053C16.2669 11.784 16.2448 11.7619 16.224 11.7388C15.1441 10.6683 13.6595 10.0054 12.02 10L12 10.0002L11.98 10C10.3405 10.0054 8.85589 10.6683 7.776 11.7388ZM20.382 2L16.6406 9.48273C15.7313 8.83412 14.6806 8.37105 13.5436 8.1488L16.618 2H20.382ZM7.38197 2L10.4564 8.1488C9.31942 8.37105 8.26867 8.83412 7.3594 9.48273L3.61804 2H7.38197ZM13.1758 14.764L11.9998 12.382L10.8238 14.764L8.1958 15.146L10.0978 17L9.6488 19.618L11.9998 18.382L14.3508 19.618L13.9018 17L15.8038 15.146L13.1758 14.764Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.999 16.5L12 17.5M12 17.5V9.50001M12 17.5L15 14.5M12 17.5L9 14.5M3 9H21M21 19V9.32456C21 9.10959 20.9653 8.89603 20.8974 8.6921L19.4558 4.36754C19.1836 3.55086 18.4193 3 17.5585 3H6.44152C5.58066 3 4.81638 3.55086 4.54415 4.36754L3.10263 8.6921C3.03466 8.89603 3 9.10959 3 9.32456V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 541 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 6H19M8 2H16M15.1716 21.8284L20.8284 16.1716M15.1716 16.1716L20.8284 21.8284M22 12V10H2V21H10" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 292 B

@@ -0,0 +1,21 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28 28H20V46H28V28Z" stroke="url(#paint0_linear_630_1104)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 38H2V46H10V38Z" stroke="url(#paint1_linear_630_1104)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M46 18H38V46H46V18Z" stroke="url(#paint2_linear_630_1104)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 18L16 8L24 16L38 2" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M29 2H38V11" stroke="#DC244C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<linearGradient id="paint0_linear_630_1104" x1="24" y1="28" x2="24" y2="46" gradientUnits="userSpaceOnUse">
<stop stop-color="#717C99"/>
<stop offset="1" stop-color="#161E33"/>
</linearGradient>
<linearGradient id="paint1_linear_630_1104" x1="6" y1="38" x2="6" y2="46" gradientUnits="userSpaceOnUse">
<stop stop-color="#717C99"/>
<stop offset="1" stop-color="#161E33"/>
</linearGradient>
<linearGradient id="paint2_linear_630_1104" x1="42" y1="18" x2="42" y2="46" gradientUnits="userSpaceOnUse">
<stop stop-color="#717C99"/>
<stop offset="1" stop-color="#161E33"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 1H3V23H21V1Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 17C14.7614 17 17 14.7614 17 12C17 9.23858 14.7614 7 12 7C9.23858 7 7 9.23858 7 12C7 14.7614 9.23858 17 12 17Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 12H17C17 10.6739 16.4732 9.40215 15.5355 8.46447C14.5979 7.52678 13.3261 7 12 7V12Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 535 B

@@ -0,0 +1,11 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M46 31.634C46 36.366 38 44 38 44C38 44 30 36.366 30 31.634C30 26.748 34.16 24 38 24C41.84 24 46 26.748 46 31.634Z" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square" stroke-linejoin="round"/>
<path d="M38 34C39.1046 34 40 33.1046 40 32C40 30.8954 39.1046 30 38 30C36.8954 30 36 30.8954 36 32C36 33.1046 36.8954 34 38 34Z" stroke="#DC244C" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square" stroke-linejoin="round"/>
<path d="M24 31H2C2 34.314 4.686 37 8 37H24M6 26V10C6 7.791 7.791 6 10 6H38C40.209 6 42 7.791 42 10V18M23 12H25" stroke="url(#paint0_linear_8032_39226)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<linearGradient id="paint0_linear_8032_39226" x1="22" y1="-33.6111" x2="22" y2="37" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="0.74254" stop-color="#28324D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1012 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.314 12L14.7606 11.1671L13.507 12L14.7606 12.8329L15.314 12ZM8.686 12L9.23939 12.8329L10.493 12L9.23939 11.1671L8.686 12ZM4 1H3V3H4V1ZM20 3H21V1H20V3ZM4 21H3V23H4V21ZM20 23H21V21H20V23ZM19 22V17H17V22H19ZM19 17C19 14.5622 17.7517 12.419 15.8674 11.1671L14.7606 12.8329C16.1123 13.731 17 15.2618 17 17H19ZM15.8674 12.8329C17.7517 11.581 19 9.43782 19 7H17C17 8.73818 16.1123 10.269 14.7606 11.1671L15.8674 12.8329ZM19 7V2H17V7H19ZM5 2V7H7V2H5ZM5 7C5 9.43782 6.24831 11.581 8.13261 12.8329L9.23939 11.1671C7.88769 10.269 7 8.73818 7 7H5ZM8.13261 11.1671C6.24831 12.419 5 14.5622 5 17H7C7 15.2618 7.88769 13.731 9.23939 12.8329L8.13261 11.1671ZM5 17V22H7V17H5ZM4 3H20V1H4V3ZM4 23H20V21H4V23Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 822 B

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3825_30277)">
<path d="M24 14V12H20.902C20.685 10.252 20.092 8.61097 19.2 7.21597L21.414 4.99897L19.999 3.58597L17.945 5.64297C17.585 5.27097 17.2 4.93197 16.787 4.62897C16.645 4.13497 16.426 3.68097 16.151 3.26397L17.708 1.70697L16.294 0.292969L14.743 1.84397C13.948 1.31697 13.008 0.999969 12 0.999969C10.992 0.999969 10.052 1.31697 9.258 1.84397L7.707 0.292969L6.293 1.70697L7.85 3.26397C7.575 3.67997 7.356 4.13397 7.214 4.62697C6.801 4.92997 6.416 5.27097 6.055 5.64297L4.001 3.58597L2.586 4.99897L4.8 7.21497C3.908 8.60997 3.315 10.252 3.098 12H0V14H3.022C3.11 16.164 3.758 18.154 4.806 19.782L2.586 21.999L3.999 23.414L6.054 21.362C7.406 22.755 9.115 23.682 11 23.928V8.99997H13V23.928C14.885 23.681 16.594 22.755 17.946 21.362L20.001 23.414L21.414 21.999L19.194 19.782C20.242 18.153 20.89 16.163 20.978 14H24Z" fill="#161E33"/>
</g>
<defs>
<clipPath id="clip0_3825_30277">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 1L14.7071 0.292893L14.4142 0H14V1ZM14 7H13V8H14V7ZM20 7H21V6.58579L20.7071 6.29289L20 7ZM6 6C5.44772 6 5 6.44772 5 7C5 7.55228 5.44772 8 6 8V6ZM10 8C10.5523 8 11 7.55228 11 7C11 6.44772 10.5523 6 10 6V8ZM6 11C5.44772 11 5 11.4477 5 12C5 12.5523 5.44772 13 6 13V11ZM11 13C11.5523 13 12 12.5523 12 12C12 11.4477 11.5523 11 11 11V13ZM6 16C5.44772 16 5 16.4477 5 17C5 17.5523 5.44772 18 6 18V16ZM10 18C10.5523 18 11 17.5523 11 17C11 16.4477 10.5523 16 10 16V18ZM21.2929 22.7071C21.6834 23.0976 22.3166 23.0976 22.7071 22.7071C23.0976 22.3166 23.0976 21.6834 22.7071 21.2929L21.2929 22.7071ZM19.8281 18.4139C19.4376 18.0234 18.8044 18.0234 18.4139 18.4139C18.0234 18.8044 18.0234 19.4376 18.4139 19.8281L19.8281 18.4139ZM19 10C19 10.5523 19.4477 11 20 11C20.5523 11 21 10.5523 21 10H19ZM2 1V0C1.44772 0 1 0.447715 1 1L2 1ZM2 23H1C1 23.5523 1.44772 24 2 24V23ZM12 24C12.5523 24 13 23.5523 13 23C13 22.4477 12.5523 22 12 22V24ZM13 1V7H15V1H13ZM14 8H20V6H14V8ZM20.7071 6.29289L14.7071 0.292893L13.2929 1.70711L19.2929 7.70711L20.7071 6.29289ZM6 8H10V6H6V8ZM6 13H11V11H6V13ZM6 18H10V16H6V18ZM22.7071 21.2929L19.8281 18.4139L18.4139 19.8281L21.2929 22.7071L22.7071 21.2929ZM19 17C19 18.1046 18.1046 19 17 19V21C19.2091 21 21 19.2091 21 17H19ZM17 19C15.8954 19 15 18.1046 15 17H13C13 19.2091 14.7909 21 17 21V19ZM15 17C15 15.8954 15.8954 15 17 15V13C14.7909 13 13 14.7909 13 17H15ZM17 15C18.1046 15 19 15.8954 19 17H21C21 14.7909 19.2091 13 17 13V15ZM21 10V7H19V10H21ZM14 0H2V2H14V0ZM1 1V23H3V1H1ZM2 24H12V22H2V24Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_713_2473)">
<path d="M14 14H10V23H14V14Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5 18H1V23H5V18Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M23 10H19V23H23V10Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 10L8 5L12 9L20 1" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 1H20V6" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_713_2473">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 800 B

@@ -0,0 +1,15 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7807_39667)">
<path d="M14 2V8V10L17 8H22C22.552 8 23 7.552 23 7V2C23 1.448 22.552 1 22 1H15C14.448 1 14 1.448 14 2Z" stroke="#161E33" stroke-width="2" stroke-miterlimit="10"/>
<path d="M10 11H3C1.895 11 1 11.895 1 13V21C1 22.105 1.895 23 3 23H17C18.105 23 19 22.105 19 21V13" stroke="#161E33" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M6 7V5" stroke="#161E33" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M6 5C6.55228 5 7 4.55228 7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4C5 4.55228 5.44772 5 6 5Z" fill="#161E33" stroke="#161E33" stroke-width="2" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M6.5 17C7.32843 17 8 16.3284 8 15.5C8 14.6716 7.32843 14 6.5 14C5.67157 14 5 14.6716 5 15.5C5 16.3284 5.67157 17 6.5 17Z" fill="#161E33"/>
<path d="M13.5 17C14.3284 17 15 16.3284 15 15.5C15 14.6716 14.3284 14 13.5 14C12.6716 14 12 14.6716 12 15.5C12 16.3284 12.6716 17 13.5 17Z" fill="#161E33"/>
</g>
<defs>
<clipPath id="clip0_7807_39667">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.25 6.5L12 1L21.75 6.5V17.5L12 23L2.25 17.5V6.5ZM17.6585 10.2526L18.4111 9.59407L17.0941 8.08892L16.3415 8.74742L10.3789 13.9647L7.70711 11.2929L7 10.5858L5.58579 12L6.29289 12.7071L9.62623 16.0404L10.2878 16.702L10.9918 16.0859L17.6585 10.2526Z" fill="#161E33"/>
</svg>

After

Width:  |  Height:  |  Size: 418 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 7L12 17L22 7" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2L6 12L16 22" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 2L18 12L8 22" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 17L12 7L2 17" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_10008_50706)">
<path d="M12 6V12H18M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12Z" stroke="#161E33" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_10008_50706">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 471 B

Some files were not shown because too many files have changed in this diff Show More