diff --git a/qdrant-landing/content/hr-tech/_index.md b/qdrant-landing/content/hr-tech/_index.md
index edddbdab1..846fce929 100644
--- a/qdrant-landing/content/hr-tech/_index.md
+++ b/qdrant-landing/content/hr-tech/_index.md
@@ -1,6 +1,369 @@
---
title: HR Tech & Talent Marketplaces
description: Discover how Qdrant's vector search technology can transform HR marketplaces and recruitment platforms by powering intelligent job matching, resume search, and candidate recommendations.
+sections:
+ #hero-section
+ - type: hero
+ badge:
+ title: HR Tech
+ icon:
+ src: /icons/outline/briefcase-business.svg
+ alt: Case
+ title: Recruitment Data is Fuzzy. Hiring Constraints Aren't.
+ description: Power job search, candidate matching, and recommendation systems for scaled talent platforms.
+ containedButton:
+ text: Talk to an Expert
+ url: /contact-us/
+ outlinedButton:
+ text: Read the Docs
+ url: /documentation/
+ language: Python
+ code: |
+ result = client.query_points(
+ collection_name="jobs",
+ prefetch=[
+ models.Prefetch(
+ query=dense_emb, using="dense",
+ ),
+ models.Prefetch(
+ query=sparse_vec, using="sparse",
+ ),
+ ],
+ query=models.FusionQuery(
+ fusion=models.Fusion.RRF),
+ query_filter=models.Filter(must=[
+ models.FieldCondition(
+ key="location",
+ match=models.MatchAny(any=["london", "remote"]),
+ ),
+ models.FieldCondition(
+ key="salary_max",
+ range=models.Range(gte=60000),
+ ),
+ ]),
+ limit=20,
+ )
+ steps:
+ - id: 0
+ title: Step 1
+ description: Embed - Parse + Embed Resume / JD
+ icon:
+ src: /icons/outline/square-code.svg
+ alt: Code
+ - id: 1
+ title: Step 2
+ description: Search - Semantic Search + Strict Filter
+ icon:
+ src: /icons/outline/filter-blue-small.svg
+ alt: Filter
+ - id: 2
+ title: Step 3
+ description: Rank - Rank + Rerank (Optional)
+ icon:
+ src: /icons/outline/list.svg
+ alt: List
+ - id: 3
+ title: Step 4
+ description: Result - Evidence-based Match
+ icon:
+ src: /icons/outline/circle-check.svg
+ alt: Check
+ badges:
+ - id: 0
+ title: Advanced filters for hiring constraints
+ icon:
+ src: /icons/outline/filter-green.svg
+ alt: Filter
+ - id: 1
+ title: Real-time matching speed
+ icon:
+ src: /icons/outline/rocket-blue-small.svg
+ alt: Rocket
+ - id: 2
+ title: Optimize at scale to meet budget
+ icon:
+ src: /icons/outline/circle-dollar-sign.svg
+ alt: Dollar
+ - id: 3
+ title: Native inference capability
+ icon:
+ src: /icons/outline/server.svg
+ alt: Server
+
+ #testimonials-section
+ - type: testimonials
+ testimonials:
+ - id: 0
+ reverse: true
+ review: “Qdrant is the last thing I worry about breaking.”
+ author:
+ name: Elvis Moraa
+ role: Engineering Lead, Pariti
+ avatar:
+ src: /img/hr-tech/image.svg
+ alt: Elvis Moraa avatar
+ metric:
+ - id: 0
+ title: 2.4x
+ description: increase in hiring fill rate
+ - id: 1
+ title: 70%
+ description: reduction in candidate vetting time
+ logo:
+ src: /img/hr-tech/pariti-light.svg
+ alt: Pariti logo
+
+ #bento-cards-section
+ - type: bento-cards
+ subtitle: Why Teams Choose Qdrant
+ title: Recruitment Search is Broken at Scale
+ description: Many HR tech teams don't start with vector search. They start with Elasticsearch, PGVector, or a managed API, and hit a wall when the product needs compound filters at scale, multi-language support, or sub-second latency on millions of vectors. These are the engineering problems that surface, and the pain we hear from teams switching.
+ cards:
+ - id: 0
+ icon:
+ src: /icons/outline/circle-alert.svg
+ alt: Alert
+ title: Inconsistent Taxonomies
+ description: '"Senior Software Engineer," "Staff Dev," and "Lead SWE" might be the same role. Keyword search misses these. Semantic search doesn''t. Embeddings catch them.'
+ - id: 1
+ icon:
+ src: /icons/outline/circle-alert.svg
+ alt: Alert
+ title: Fuzzy Data with Constraints
+ description: Skills and titles are inconsistent across resumes, but location, work authorization, and certifications are hard constraints. You need semantic similarity AND hard filters on the same query.
+
+ #case-studies-section
+ - type: case-studies
+ title: What Our Clients Say
+ caseStudies:
+ - id: 0
+ title: “Our managed search API is a black box.”
+ description: No tuning, debugging, or control over ranking, even though you're paying a premium for convenience. With Qdrant, you can inspect every result, tune every parameter, and debug without guessing.
+ - id: 1
+ title: “Filters destroy our recall.”
+ description: Post-filter architectures degrade when you add location + salary + category + level. Apply filters during HNSW traversal with Qdrant? No need to reduce recall or spike latency.
+ - id: 2
+ title: “We over-provision and still get spikes.”
+ description: Burst traffic during peak hiring seasons, latency spikes during daily ingestion, clusters sized for worst-case that idle most of the day. Qdrant's Rust-based engine and quantization options mean you provision for actual usage, not theoretical peaks.
+ - id: 3
+ title: “Our solution doesn't scale past two languages.”
+ description: PGVector worked at first for your home market. Now you're expanding to new countries and your search infrastructure can't handle multi-language embeddings or regional deployment. Qdrant supports any embedding model and deploys across regions.
+
+ #get-contacted-section
+ - type: get-contacted
+ title: Evaluating Migration?
+ description: Our solutions engineers do technical deep-dives with HR tech teams weekly.
+ contactUs:
+ text: Book a Session
+ url: /contact-us/
+
+ #bento-cards-section
+ - type: bento-cards
+ title: What you can build with Qdrant
+ cards:
+ - id: 0
+ icon:
+ src: /icons/outline/search-blue.svg
+ alt: Search
+ title: Modernized Job Search
+ description: Layer semantic relevance on top of existing keyword/Boolean patterns with hybrid search. Apply strict metadata filters alongside vector similarity, no post-filter penalty.
+ chips:
+ - id: 0
+ title: Hybrid Search
+ link: /documentation/search/hybrid-queries/
+ - id: 1
+ title: Payload Filters
+ link: /documentation/search/filtering/
+ - id: 2
+ title: Reciprocal Rank Fusion
+ link: /documentation/search/hybrid-queries/#reciprocal-rank-fusion-rrf
+ - id: 1
+ icon:
+ src: /icons/outline/heart-handshake.svg
+ alt: Alert
+ title: Similar Jobs & Candidates
+ description: Layer semantic relevance on top of existing keyword/Boolean patterns with hybrid search. Apply strict metadata filters alongside vector similarity, no post-filter penalty.
+ chips:
+ - id: 0
+ title: Recommendation API
+ link: /documentation/search/explore/#recommendation-api
+
+ #architecture-section
+ - type: architecture
+ title: How It Works Under the Hood
+ description: Architecture patterns with API examples for the problems above.
+ sections:
+ - id: 0
+ title: Semantic Match with Hard Hiring Constraints
+ description: Embed the job description or resume, then apply must-match payload filters for non-negotiable constraints. Filters applied during HNSW traversal, not after, so recall doesn't degrade.
+ link:
+ href: /documentation/search/hybrid-queries/
+ text: View Full Example
+ steps:
+ - id: 0
+ title: Pre-filter during graph traversal
+ description: Compound filters on location, salary, category don't cause latency spikes.
+ - id: 1
+ title: Hybrid Search
+ description: Combine dense + sparse vectors with Reciprocal Rank Fusion in a single query.
+ - id: 2
+ title: Native Inferencing
+ description: Use Qdrant Cloud inference to simplify your data pipeline.
+ language: Python
+ code: |
+ # Pattern: hybrid semantic + keyword with filters
+ # → see docs for complete example
+ result = client.query_points(
+ collection_name="jobs",
+ prefetch=[
+ models.Prefetch(
+ query=dense_emb, using="dense",
+ limit=100),
+ models.Prefetch(
+ query=sparse_vec, using="sparse",
+ limit=100),
+ ],
+ query=models.FusionQuery(
+ fusion=models.Fusion.RRF),
+ query_filter=models.Filter(must=[
+ models.FieldCondition(
+ key="location",
+ match=models.MatchAny(any=["london", "remote"]),
+ ),
+ models.FieldCondition(
+ key="salary_max",
+ range=models.Range(gte=60000),
+ ),
+ ]),
+ limit=20,
+ )
+ - id: 1
+ title: Quantization for 10M+ Vectors
+ description: Scalar and binary quantization compress vectors 4-32x in memory. At 10M+ candidate or job vectors.
+ link:
+ href: /documentation/manage-data/quantization/
+ text: View Full Example
+ steps:
+ - id: 0
+ title: Scalar Quantization
+ description: 4x memory reduction with minimal recall loss. One config flag.
+ - id: 1
+ title: Predictable Cost
+ description: fixed infra cost for vector search means retrieval across multiple pipeline stages without margin erosion.
+ language: Python
+ code: |
+ # Pattern: quantized collection for scale
+ # → see docs for complete example
+ client.create_collection(
+ collection_name="candidates_quantized",
+ vectors_config={
+ "dense": models.VectorParams(
+ size=1536,
+ distance=models.Distance.COSINE,
+ ),
+ },
+ sparse_vectors_config={
+ "sparse": models.SparseVectorParams(
+ modifier=models.Modifier.IDF,
+ ),
+ },
+ quantization_config=models.ScalarQuantization(
+ scalar=models.ScalarQuantizationConfig(
+ type=models.ScalarType.INT8,
+ quantile=0.99,
+ always_ram=True,
+ )
+ ),
+ )
+ - id: 2
+ title: '"Similar Jobs" and Candidate Discovery'
+ description: Recommendation-style retrieval using existing points as query inputs. Pass positive and negative examples, no embedding step needed on the query side.
+ link:
+ href: /documentation/search/explore/
+ text: View Full Example
+ steps:
+ - id: 0
+ title: Recommend by Point ID
+ description: No re-embedding required. Just pass the job or candidate ID.
+ - id: 1
+ title: Positive + Negative Examples
+ description: '"More like these 3, less like that one": refine without retraining.'
+ language: Python
+ code: |
+ # Pattern: recommend by point ID
+ # → see docs for complete example
+ result = client.query_points(
+ collection_name="jobs",
+ query=models.RecommendQuery(
+ recommend=models.RecommendInput(
+ positive=[0], # job_id_0
+ negative=[1], # job_id_1
+ )
+ ),
+ using="dense",
+ query_filter=models.Filter(
+ must=[
+ models.FieldCondition(
+ key="category",
+ match=models.MatchValue(value="engineering"),
+ ),
+ models.FieldCondition(
+ key="remote",
+ match=models.MatchValue(value=True),
+ ),
+ ]
+ ),
+ limit=20,
+ )
+
+ #dark-banner-section
+ - type: dark-banner
+ description: Pariti is referral-driven hiring marketplace in Africa. Qdrant vector search ranks 70k candidates in real time.
+ industry: Pariti · HR Tech
+ metric:
+ rate: 20% → 48%
+ description: Hiring Fill Rate
+ logo:
+ src: /img/hr-tech/pariti-light-small.svg
+ alt: Pariti logo
+ link:
+ href: /blog/case-study-pariti/?q=Pariti
+ text: Read the Full Case Study
+
+ #faq-section
+ - type: faq
+ title: FAQs
+ questions:
+ - id: 0
+ question: How Does Vector Search Improve Job Matching Compared to Keyword Search?
+ answer: Keyword search requires candidates to guess the exact terms employers use. A job seeker searching "development" gets "business development" results mixed in with software engineering roles. Vector search converts job descriptions, resumes, and queries into embeddings that capture meaning, so "Senior Software Engineer," "Staff Dev," and "Lead SWE" all surface as semantically similar. Qdrant combines this semantic matching with strict payload filters (location, salary range, work authorization) in a single query, so results are both relevant and compliant with hard hiring constraints.
+ - id: 1
+ question: Can Qdrant Handle Millions of Job or Candidate Vectors Without Performance Degradation?
+ answer: Yes. Qdrant is built in Rust with a custom HNSW implementation and storage engine designed for high-throughput, concurrent read/write workloads. Recruiting platforms commonly maintain millions of vectors (candidates and jobs combined) with heavy daily update loads. Scalar and binary quantization compress vectors 4 to 32x in memory, which helps keep infrastructure costs predictable as you scale. Filters are applied during HNSW graph traversal, not after, so compound queries on location, salary, category, and experience level avoid the recall degradation and latency spikes that other architectures can produce.
+ - id: 2
+ question: Is Qdrant Compliant with HIPAA, GDPR, and Data Residency Requirements for HR Data?
+ answer: "Qdrant Cloud is SOC 2 Type 2 certified and supports HIPAA-compliant deployments with a Business Associate Agreement (BAA) for healthcare recruiting platforms. For teams with GDPR or data residency requirements, Qdrant offers Hybrid Cloud deployment: your data stays on your own AWS, GCP, or Azure infrastructure while Qdrant manages the control plane. On-premises and fully air-gapped deployments are also available for organizations that require complete data sovereignty."
+ - id: 3
+ question: How Does Qdrant Compare to Elasticsearch or OpenSearch for Recruiting Search?
+ answer: "Elasticsearch and OpenSearch were designed for full-text keyword search and log analytics, not semantic vector retrieval. Teams that bolt vector search onto these systems often report filter performance degradation, over-provisioned clusters to handle burst traffic, and complex operational overhead. Qdrant is purpose-built for vector workloads: filters execute during graph traversal (not as a post-processing step), hybrid search combines dense semantic vectors with sparse BM25 keyword vectors in a single query, and the Rust-based engine provides consistent low-latency performance without the memory overhead of JVM-based systems. Some HR tech teams that evaluate Qdrant are replacing an existing search stack, not building from scratch."
+ - id: 4
+ question: Does Qdrant Support Geospatial Search for Location-Based Job Matching?
+ answer: Yes. Qdrant has native geospatial filtering that lets you run radius queries and bounding-box filters alongside vector search in the same request. For job boards operating across multiple countries or regions, this means you can combine semantic job matching with location constraints without maintaining a separate geospatial index. This is a common reason teams explore alternatives to solutions where geospatial and vector search are difficult to combine without custom engineering.
+ - id: 5
+ question: Can Qdrant Support Multi-Language Job Search for International Job Boards?
+ answer: Qdrant is embedding-model agnostic, which means it supports any multi-language embedding model your team selects (such as multilingual-e5, Cohere multilingual, or OpenAI embeddings). For teams that want to simplify their pipeline, Qdrant Cloud Inference handles embedding directly within Qdrant, so you can send raw text (job descriptions, resumes, queries in any language) and skip managing a separate inference service. Job boards expanding from a single market to multiple countries can store all language variants in the same collection and query across them with consistent performance. Combined with regional deployment options and geospatial filtering, this lets you scale from one market to dozens without re-architecting your search infrastructure.
+ - id: 6
+ question: What Latency Can I Expect from Qdrant for Real-Time Candidate or Job Search?
+ answer: "Qdrant helps teams meet aggressive latency goals on collections with billions of vectors, including filtered queries. This matters for recruiting platforms because search latency directly affects candidate experience: slow search times lead to measurable user abandonment. Qdrant maintains performance during concurrent ingestion (daily job or candidate updates) and search traffic, helping avoid the latency spikes that commonly occur during peak hours or batch update windows."
+
+ #cta-banner-section
+ - type: cta-banner
+ title: Talk to an expert about
HR marketplace retrieval.
+ description: Get guidance on scaling search, matching, and recommendations beyond 20M vectors.
+ button:
+ text: Talk to an Expert
+ url: /contact-us/
+
build:
render: always
cascade:
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/main.scss b/qdrant-landing/themes/qdrant-2024/assets/css/main.scss
index 222c11751..9203c7955 100644
--- a/qdrant-landing/themes/qdrant-2024/assets/css/main.scss
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/main.scss
@@ -128,6 +128,14 @@
@import 'partials/hr-tech/index';
@import 'partials/healthcare/index';
@import 'partials/cta-banner';
+@import 'partials/industries/industries-faq';
+@import 'partials/industries/industries-bento-cards';
+@import 'partials/industries/industries-case-studies';
+@import 'partials/industries/industries-get-contacted';
+@import 'partials/industries/industries-hero';
+@import 'partials/industries/industries-testimonials';
+@import 'partials/industries/industries-architecture';
+@import 'partials/industries/industries-dark-banner';
@import 'partials/vsd/vsd-speaker-lineup';
@import 'partials/vsd/vsd-last-year';
@import 'partials/vsd/vsd-sponsors';
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/_cta-banner.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/_cta-banner.scss
index 6a6a10dda..6a6f89906 100644
--- a/qdrant-landing/themes/qdrant-2024/assets/css/partials/_cta-banner.scss
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/_cta-banner.scss
@@ -47,6 +47,10 @@
line-height: pxToRem(38);
letter-spacing: -0.5px;
color: $neutral-98;
+
+ span {
+ color: $primary-50;
+ }
}
&__description {
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-architecture.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-architecture.scss
new file mode 100644
index 000000000..b87082f33
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-architecture.scss
@@ -0,0 +1,207 @@
+@use '../../helpers/functions' as *;
+@use 'sass:math';
+
+.industries-architecture {
+ padding-top: $spacer * 2.5;
+ padding-bottom: $spacer * 2.5;
+ background-color: $neutral-10;
+
+ &__title {
+ margin-bottom: pxToRem(30);
+ color: $neutral-98;
+ font-size: $h4-font-size;
+ line-height: $spacer * 3;
+ text-align: center;
+ }
+
+ &__description {
+ margin-bottom: pxToRem(30);
+ color: $neutral-70;
+ text-align: center;
+ }
+
+ &__sections {
+ display: flex;
+ flex-direction: column;
+ gap: pxToRem(30);
+ }
+
+ &__checklist {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ border-radius: $spacer * 0.5;
+ border: pxToRem(1) solid $neutral-30;
+ background-color: $neutral-10;
+
+ &-top {
+ padding: $spacer * 1.5 $spacer * 1.5 $spacer * 2.5;
+ }
+
+ &-title {
+ margin-bottom: $spacer;
+ font-size: $h5-font-size;
+ line-height: pxToRem(42);
+ color: $neutral-100;
+ }
+
+ &-description {
+ margin-bottom: 0;
+ color: $neutral-70;
+ }
+
+ &-link {
+ margin: 0 $spacer * 1.5 $spacer * 1.5;
+ }
+
+ &-bottom {
+ margin-top: auto;
+ }
+
+ &-step {
+ padding: $spacer $spacer * 1.5;
+ border-top: pxToRem(1) solid $neutral-30;
+
+ &-top {
+ display: flex;
+ gap: $spacer * 0.5;
+ align-items: center;
+
+ img {
+ height: pxToRem(18);
+ width: pxToRem(18);
+ }
+ }
+
+ &-title {
+ margin-bottom: 0;
+ font-size: $font-size-md;
+ line-height: $spacer * 1.5;
+ color: $neutral-100;
+ }
+
+ &-description {
+ margin-bottom: 0;
+ color: $neutral-70;
+ }
+ }
+ }
+
+ &__code {
+ height: 100%;
+ padding: pxToRem(3);
+ border-radius: $spacer * 0.5;
+ border: pxToRem(1) solid $neutral-30;
+ background-color: $neutral-10;
+
+ &-tabs {
+ display: flex;
+ justify-content: space-between;
+ height: $spacer * 2.5;
+ padding: 0 $spacer;
+
+ &-button {
+ padding: 0 $spacer * 2;
+ border: 0;
+ border-bottom: pxToRem(2) solid $primary-50;
+ font-size: $font-size-s;
+ line-height: $spacer * 2.5;
+ background-color: transparent;
+ color: $neutral-100;
+ }
+ }
+
+ &-button {
+ height: $spacer * 1.5;
+ width: $spacer * 1.5;
+ padding: math.div($spacer, 4);
+ border: 0;
+ background-color: transparent;
+
+ img {
+ height: $spacer;
+ width: $spacer;
+ }
+ }
+
+ &-done {
+ display: none;
+ }
+
+ .highlight {
+ width: 100%;
+ margin-bottom: 0;
+ padding: $spacer * 1.5;
+ border: pxToRem(1) solid $neutral-30;
+ border-radius: $spacer * 0.5;
+ background: linear-gradient($neutral-20, #0e1424);
+
+ pre {
+ display: block;
+ width: 100%;
+ padding: 0;
+ background: transparent;
+ white-space: pre-wrap;
+ overflow-x: hidden;
+ }
+
+ code {
+ display: block;
+ width: 100%;
+ overflow-wrap: anywhere;
+ word-break: break-word;
+
+ .line {
+ margin-bottom: 0;
+ }
+
+ * {
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ color: #C5C8C6;
+ }
+
+ .c1 {
+ color: #7C7C7C;
+ }
+
+ .s2, .nb {
+ color: #A8FF60;
+ }
+
+ .k {
+ color: #96CBFE;
+ }
+
+ .mi {
+ color: #FF73FD;
+ }
+ }
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ padding-top: $spacer * 7.5;
+ padding-bottom: $spacer * 7.5;
+ background-image: url("/img/blurred/blurred-light-29.png");
+ background-position: top pxToRem(-52) left 0;
+ background-size: contain;
+ background-repeat: no-repeat;
+
+ &__title {
+ margin-bottom: $spacer;
+ font-size: $h3-font-size;
+ line-height: pxToRem(52);
+ }
+
+ &__description {
+ margin-bottom: $spacer * 4;
+ font-size: $font-size-l;
+ line-height: $line-height-lg;
+ }
+
+ &__sections {
+ gap: $spacer * 4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-bento-cards.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-bento-cards.scss
new file mode 100644
index 000000000..4b2ad2fd0
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-bento-cards.scss
@@ -0,0 +1,125 @@
+@use '../../helpers/functions' as *;
+@use 'sass:math';
+
+.industries-bento-cards {
+ padding-top: $spacer * 2.5;
+ padding-bottom: $spacer * 2.5;
+ background-color: $neutral-94;
+
+ &__subtitle {
+ margin-bottom: pxToRem(30);
+ text-align: center;
+ font-family: $font-family-code;
+ font-size: $font-size-s;
+ font-weight: 500;
+ line-height: $line-height-sm;
+ text-transform: uppercase;
+ color: $neutral-30;
+ }
+
+ &__title {
+ margin-bottom: 0;
+ text-align: center;
+ font-size: $h4-font-size;
+ line-height: $spacer * 3;
+ color: $neutral-20;
+ }
+
+ &__description {
+ margin-top: pxToRem(30);
+ margin-bottom: 0;
+ text-align: center;
+ color: $neutral-30;
+ }
+
+ &__header {
+ margin-bottom: pxToRem(30);
+ }
+
+ &__card {
+ justify-content: flex-start;
+ gap: $spacer;
+
+ &-icon {
+ height: $spacer * 1.5;
+ width: $spacer * 1.5;
+ }
+
+ &-title {
+ margin-bottom: 0;
+ font-size: $font-size-xl;
+ line-height: pxToRem(30);
+ color: $neutral-20;
+ }
+
+ &-description {
+ margin-bottom: 0;
+ color: $neutral-30;
+ }
+
+ &-chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: $spacer * 0.5;
+
+ &-link {
+ display: flex;
+ gap: pxToRem(6);
+ padding: math.div($spacer, 4) pxToRem(10);
+ border-radius: math.div($spacer, 4);
+ background: $neutral-94;
+ font-size: $font-size-xs;
+ line-height: pxToRem(18);
+ color: $neutral-30;
+
+ &:hover {
+ background: $neutral-90;
+ }
+
+ &:after {
+ content: "";
+ display: block;
+ width: $spacer;
+ height: $spacer;
+ background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.6665 4.66675H11.3332M11.3332 4.66675V11.3334M11.3332 4.66675L4.6665 11.3334' stroke='%2328324D' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ }
+ }
+ }
+ }
+
+ &__card-with-chips {
+ gap: $spacer * 1.5;
+ }
+
+ @include media-breakpoint-up(lg) {
+ padding-top: $spacer * 2.5;
+ padding-bottom: $spacer * 7.5;
+
+ &-with-subtitle {
+ padding-top: $spacer * 6.5;
+ padding-bottom: $spacer * 4;
+ }
+
+ &__subtitle {
+ margin-bottom: $spacer;
+ }
+
+ &__title {
+ font-size: $h3-font-size;
+ line-height: pxToRem(52);
+ }
+
+ &__description {
+ margin-top: $spacer;
+ font-size: $font-size-l;
+ line-height: $line-height-lg;
+ }
+
+ &__header {
+ margin-bottom: $spacer * 4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-case-studies.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-case-studies.scss
new file mode 100644
index 000000000..2f25fdff5
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-case-studies.scss
@@ -0,0 +1,154 @@
+@use '../../helpers/functions' as *;
+
+.industries-case-studies {
+ padding-top: $spacer * 2.5;
+ padding-bottom: $spacer * 2.5;
+ background-color: $neutral-94;
+
+ &__header {
+ text-align: center;
+ margin-bottom: pxToRem(30);
+ }
+
+ &__title {
+ flex: 1 1 auto;
+ min-width: 0;
+ font-size: $h5-font-size;
+ line-height: 1.3;
+ font-weight: 600;
+ letter-spacing: -0.5px;
+ color: $neutral-20;
+ margin: 0;
+ }
+
+ &__controls {
+ flex-shrink: 0;
+ margin-left: auto;
+ display: none;
+ gap: $spacer * 2;
+ }
+
+ &__active-slider {
+ .industries-case-studies__controls {
+ display: none;
+ }
+ }
+
+ &__arrow {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: $spacer * 2.5;
+ height: $spacer * 2.5;
+ padding: 0;
+ background: transparent;
+ border: none;
+ cursor: pointer;
+ color: $neutral-20;
+
+ &:hover:not(:disabled) {
+ svg path {
+ stroke: $primary-50;
+ }
+ }
+
+ &:disabled {
+ cursor: not-allowed;
+
+ svg path {
+ stroke: $neutral-80;
+ }
+ }
+
+ svg {
+ width: 100%;
+ height: 100%;
+
+ path {
+ transition: stroke 0.2s ease;
+ }
+ }
+ }
+
+ &__carousel {
+ overflow: hidden;
+ }
+
+ &__track {
+ display: flex;
+ flex-direction: column;
+ gap: var(--industries-case-studies-gap, #{pxToRem(30)});
+ transition: transform 0.3s ease;
+ }
+
+ &__slide {
+ flex-shrink: 0;
+ width: var(
+ --industries-case-studies-slide-width,
+ calc((100% - (2 * #{pxToRem(30)})) / 3)
+ );
+ }
+
+ &__card {
+ justify-content: flex-start;
+ gap: $spacer * 2;
+ width: 100%;
+ min-width: 0;
+
+ &-title {
+ margin: 0;
+ font-size: $h6-font-size;
+ line-height: $spacer * 2;
+ font-weight: 500;
+ color: $neutral-20;
+ }
+
+ &-description {
+ margin: 0;
+ color: $neutral-30;
+ }
+ }
+
+ @include media-breakpoint-up(md) {
+ &__track {
+ flex-direction: row;
+ }
+
+ &__active-slider {
+ .industries-case-studies__header {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ gap: $spacer * 1.5;
+ text-align: left;
+ }
+
+ .industries-case-studies__controls {
+ display: flex;
+ }
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ padding-top: $spacer * 5;
+ padding-bottom: $spacer * 5;
+
+ &__header {
+ margin-bottom: $spacer * 2.5;
+ }
+
+ &__title {
+ font-size: $h4-font-size;
+ line-height: 1.2;
+ }
+
+ &__card {
+ &-title {
+ min-height: $spacer * 4;
+ }
+ }
+ }
+}
+
+
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-dark-banner.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-dark-banner.scss
new file mode 100644
index 000000000..37ef37d38
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-dark-banner.scss
@@ -0,0 +1,110 @@
+@use '../../helpers/functions' as *;
+
+.industries-dark-banner {
+ padding-top: $spacer * 5;
+ padding-bottom: $spacer * 5;
+ background-color: $neutral-10;
+
+ &__block {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ padding: $spacer * 2;
+ border-radius: $spacer * 0.5;
+ border: pxToRem(1) solid $neutral-30;
+ background: linear-gradient($neutral-20, #0e1424);
+ }
+
+ &__logo {
+ margin-bottom: pxToRem(30);
+
+ img {
+ height: $spacer * 3;
+ }
+ }
+
+ &__content {
+ border-bottom: pxToRem(1) solid $neutral-30;
+
+ &-description {
+ margin-bottom: pxToRem(30);
+ font-size: $h6-font-size;
+ line-height: $spacer * 2;
+ color: $neutral-94;
+ }
+
+ &-industry {
+ margin-bottom: pxToRem(30);
+ color: $neutral-70;
+ }
+ }
+
+ &__metric {
+ &-rate {
+ margin-top: pxToRem(30);
+ margin-bottom: $spacer;
+ font-size: $h5-font-size;
+ line-height: pxToRem(42);
+ color: #1FC7C7;
+ }
+
+ &-description {
+ margin-bottom: $spacer * 5;
+ color: $neutral-70;
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ padding-top: 0;
+ padding-bottom: $spacer * 7.5;
+
+ &__block {
+ flex-direction: row;
+ padding: $spacer * 3.5;
+ }
+
+ &__logo {
+ flex-shrink: 0;
+ padding-right: $spacer * 3;
+ }
+
+ &__content {
+ display: flex;
+ flex-direction: column;
+ padding: 0 $spacer * 3;
+ border-left: pxToRem(1) solid $neutral-30;
+ border-right: pxToRem(1) solid $neutral-30;
+ border-bottom: 0;
+
+ &-industry {
+ margin-top: auto;
+ margin-bottom: 0;
+ }
+ }
+
+ &__metric {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ align-items: flex-start;
+ width: pxToRem(293);
+ padding-left: $spacer * 3;
+
+ &-rate {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: $h4-font-size;
+ line-height: $spacer * 3;
+ }
+
+ &-description {
+ margin-bottom: $spacer * 5;
+ color: $neutral-70;
+ }
+
+ &-link {
+ margin-top: auto;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-faq.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-faq.scss
new file mode 100644
index 000000000..b7ef02345
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-faq.scss
@@ -0,0 +1,15 @@
+@use '../../helpers/functions' as *;
+
+.industries-faq {
+ padding-top: $spacer * 5;
+ padding-bottom: $spacer * 2.5;
+ background-color: $neutral-94;
+
+ &__title {
+ margin-bottom: $spacer * 5;
+ font-size: $h2-font-size;
+ line-height: pxToRem(62);
+ color: $neutral-20;
+ text-align: center;
+ }
+}
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-get-contacted.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-get-contacted.scss
new file mode 100644
index 000000000..7df044aa4
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-get-contacted.scss
@@ -0,0 +1,24 @@
+@use '../../helpers/functions' as *;
+@use '../../mixins/get-contacted' as get-contacted;
+
+.industries-get-contacted {
+ @include get-contacted.base($spacer * 4, pxToRem(30), $spacer * 7.5, $spacer * 2.5, pxToRem(620));
+
+ h3 {
+ margin-bottom: $spacer * 0.5;
+ text-align: center;
+ font-size: $h6-font-size;
+ line-height: $spacer * 2;
+ color: $neutral-98;
+
+ @include media-breakpoint-up(lg) {
+ text-align: left;
+ }
+ }
+
+ p {
+ color: $neutral-70;
+ font-size: $font-size-md;
+ line-height: $spacer * 1.5;
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-hero.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-hero.scss
new file mode 100644
index 000000000..6ff01f9eb
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-hero.scss
@@ -0,0 +1,382 @@
+@use '../../helpers/functions' as *;
+@use 'sass:math';
+
+.industries-hero {
+ padding-top: $spacer * 5;
+ padding-bottom: $spacer * 5;
+ background-color: $neutral-10;
+ background-image:
+ radial-gradient(
+ 105.1% 114.35% at 50% 2%,
+ rgba($neutral-10, 0) 0%,
+ rgba($neutral-10, 0.32) 81.57%,
+ rgba($secondary-blue-50, 0.8) 99.31%
+ );
+ background-position: 0 0;
+ background-size: auto;
+ background-repeat: no-repeat;
+ position: relative;
+
+ .container {
+ position: relative;
+ z-index: 1;
+ }
+
+ &:before {
+ content: "";
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ background-image: url("/img/stars-pattern.png");
+ background-position: 0 0;
+ background-size: pxToRem(350) pxToRem(350);
+ background-repeat: repeat;
+ opacity: .5;
+ z-index: 1;
+ }
+
+ &__content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: $spacer;
+ margin-bottom: $spacer * 4.5;
+ }
+
+ &__badge {
+ display: flex;
+ gap: $spacer * 0.5;
+ align-items: center;
+ padding: math.div($spacer, 4) $spacer;
+ border-radius: math.div($spacer, 4);
+ background: linear-gradient($neutral-20, #0e1424);
+
+ img {
+ height: pxToRem(20);
+ width: pxToRem(20);
+ }
+
+ span {
+ color: $neutral-98;
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ }
+ }
+
+ &__title {
+ margin-bottom: 0;
+ color: $neutral-98;
+ font-size: $h5-font-size;
+ line-height: pxToRem(42);
+ text-align: center;
+ }
+
+ &__description {
+ margin-bottom: 0;
+ color: $neutral-70;
+ text-align: center;
+ }
+
+ &__mobile-buttons {
+ display: flex;
+ flex-direction: column;
+ gap: $spacer * 1.5;
+ margin-top: $spacer * 2;
+ align-items: center;
+
+ a {
+ width: pxToRem(170)
+ }
+ }
+
+ &__buttons {
+ display: none;
+ gap: $spacer * 1.5;
+ }
+
+ &__block {
+ overflow: hidden;
+ width: 100%;
+ border-radius: $spacer;
+ background-color: $neutral-20;
+ border: pxToRem(1) solid $neutral-20;
+ }
+
+ &__tabs {
+ display: flex;
+ padding: pxToRem(3) pxToRem(3) math.div($spacer, 4) pxToRem(3);
+
+ button {
+ width: 50%;
+ border: 0;
+ padding: $spacer * 0.5 $spacer * 1.5;
+ border-radius: pxToRem(12);
+ background-color: $neutral-20;
+ color: $neutral-70;
+
+ &.active {
+ background-color: $neutral-40;
+ color: $neutral-98;
+ font-weight: 500;
+ }
+ }
+ }
+
+ &__code {
+ border-radius: $spacer * 0.5;
+ background-color: $neutral-10;
+
+ &-tabs {
+ display: flex;
+ justify-content: space-between;
+ padding: 0 $spacer;
+ }
+
+ &-tab {
+ height: $spacer * 2.5;
+ padding: 0 $spacer * 2;
+ font-size: $font-size-s;
+ line-height: $spacer * 2.5;
+ color: $neutral-94;
+ border: 0;
+ background-color: transparent;
+ border-bottom: pxToRem(2) solid $primary-50;
+ }
+
+ &-button {
+ display: flex;
+ gap: $spacer * 0.5;
+ align-items: center;
+ justify-content: flex-end;
+ border: 0;
+ padding: 0;
+ background-color: transparent;
+
+ span {
+ display: none;
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ color: $neutral-80;
+ }
+
+ &:hover {
+ span {
+ display: block;
+ }
+ }
+ }
+
+ &-collapse {
+ display: none;
+ }
+
+ &.is-expanded {
+ .industries-hero__code-expand {
+ display: none;
+ }
+
+ .industries-hero__code-collapse {
+ display: flex;
+ }
+
+ .industries-hero__code-content {
+ overflow-y: visible;
+ }
+ }
+
+ &-content {
+ display: flex;
+ align-items: flex-start;
+ height: pxToRem(280);
+ transition: height 0.2s;
+ margin: 0 pxToRem(3);
+ padding: $spacer * 1.5 $spacer $spacer * 1.5 $spacer * 1.5;
+ border-radius: $spacer * 0.5 $spacer * 0.5 0 0;
+ background: linear-gradient($neutral-20, #0e1424);
+ border: pxToRem(1) solid $neutral-20;
+ overflow-y: auto;
+ overflow-x: hidden;
+ word-break: break-word;
+ overflow-wrap: anywhere;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ }
+
+ .highlight {
+ width: calc(100% - pxToRem(24));
+ margin-bottom: 0;
+ background: transparent;
+
+ pre {
+ display: block;
+ width: 100%;
+ padding: 0;
+ background: transparent;
+ white-space: pre-wrap;
+ overflow-x: hidden;
+ }
+
+ code {
+ display: block;
+ width: 100%;
+ overflow-wrap: anywhere;
+ word-break: break-word;
+
+ .line {
+ margin-bottom: 0;
+ }
+
+ * {
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ color: #C5C8C6;
+ }
+
+ .c1 {
+ color: #7C7C7C;
+ }
+
+ .s2, .nb {
+ color: #A8FF60;
+ }
+
+ .k {
+ color: #96CBFE;
+ }
+
+ .mi {
+ color: #FF73FD;
+ }
+ }
+ }
+
+ &-button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: pxToRem(5);
+ border: pxToRem(1) solid $neutral-30;
+ border-radius: math.div($spacer, 4);
+ background: linear-gradient($neutral-20, #0e1424);
+
+ svg {
+ height: pxToRem(12);
+ width: pxToRem(12);
+ }
+ }
+ }
+
+ &-done {
+ display: none;
+ }
+ }
+
+ &__steps {
+ height: pxToRem(320);
+ border-radius: $spacer * 0.5;
+ background-color: $neutral-10;
+
+ &-item {
+ height: $spacer * 5;
+ padding: $spacer $spacer * 1.5;
+
+ &:not(:last-of-type) {
+ border-bottom: pxToRem(1) solid $neutral-20;
+ }
+
+ &-header {
+ display: flex;
+ gap: $spacer * 0.5;
+ align-items: center;
+
+ h6 {
+ color: $neutral-94;
+ font-size: $font-size-md;
+ line-height: $spacer * 1.5;
+ margin: 0;
+ }
+
+ img {
+ height: pxToRem(18);
+ width: pxToRem(18);
+ }
+ }
+
+ p {
+ color: $neutral-70;
+ margin: 0;
+ }
+ }
+ }
+
+ &__badges {
+ display: none;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ gap: $spacer * 1.5;
+ margin-top: $spacer * 5;
+
+ &-item {
+ display: flex;
+ gap: $spacer * 0.5;
+ align-items: center;
+ padding: pxToRem(6) pxToRem(10);
+ border-radius: math.div($spacer, 4);
+ background: linear-gradient($neutral-20, #0e1424);
+
+ img {
+ height: $spacer;
+ width: $spacer;
+ }
+
+ span {
+ color: $neutral-98;
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ }
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ padding-top: $spacer * 7.5;
+ padding-bottom: $spacer * 7.5;
+
+ &__content {
+ gap: $spacer * 1.5;
+ align-items: flex-start;
+ margin-bottom: 0;
+ }
+
+ &__title {
+ font-size: $h4-font-size;
+ line-height: $spacer * 3;
+ text-align: left;
+ }
+
+ &__description {
+ font-size: $font-size-xl;
+ line-height: pxToRem(30);
+ text-align: left;
+ }
+
+ &__buttons {
+ display: flex;
+ }
+
+ &__mobile-buttons {
+ display: none;
+ }
+
+ &__badges {
+ display: flex;
+ }
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-testimonials.scss b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-testimonials.scss
new file mode 100644
index 000000000..d45c4f0fe
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/css/partials/industries/_industries-testimonials.scss
@@ -0,0 +1,198 @@
+@use '../../helpers/functions' as *;
+
+.industries-testimonials {
+ padding-top: $spacer * 5;
+ padding-bottom: $spacer * 5;
+ background-color: $neutral-94;
+
+ &__item {
+ &:not(:last-of-type) {
+ margin-bottom: $spacer * 5;
+ }
+ }
+
+ &__logo {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: $spacer * 10;
+ width: 100%;
+ border-radius: $spacer * 0.5;
+ border: pxToRem(1) solid $neutral-90;
+ background-color: $neutral-10;
+ background-image: url("/img/stars-pattern.png");
+ background-position: 0;
+ background-size: pxToRem(350) pxToRem(350);
+ background-repeat: no-repeat;
+ position: relative;
+ overflow: hidden;
+
+ &:after {
+ content: "";
+ display: block;
+ position: absolute;
+ left: 0;
+ bottom: pxToRem(-20);
+ background-image: url("/img/blurred/blurred-light-28.svg");
+ background-position: 0;
+ background-size: cover;
+ background-repeat: no-repeat;
+ width: 100%;
+ aspect-ratio: 4 / 1;
+ }
+ }
+
+ &__card {
+ display: flex;
+ flex-direction: column-reverse;
+ padding: $spacer * 2 0;
+
+ &-review {
+ display: flex;
+ flex-direction: column;
+ padding: $spacer * 5 $spacer * 2 0;
+
+ &-text {
+ margin-bottom: $spacer * 2;
+ font-size: $h6-font-size;
+ line-height: $spacer * 2;
+ color: $neutral-20;
+ }
+
+ &-block {
+ display: flex;
+ gap: $spacer;
+
+ img {
+ height: $spacer * 3;
+ width: $spacer * 3;
+ }
+ }
+
+ &-name {
+ margin: 0;
+ color: $neutral-20;
+ }
+
+ &-role {
+ margin: 0;
+ font-size: $font-size-s;
+ line-height: $line-height-sm;
+ color: $neutral-60;
+ }
+ }
+
+ &-metric {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ &-divider {
+ display: block;
+ width: 100%;
+ height: pxToRem(1);
+ margin: 0;
+ padding: 0;
+ background-color: $neutral-90;
+ }
+
+ &-item {
+ padding: $spacer * 1.5 0 $spacer * 1.5 $spacer * 2;
+
+ img {
+ height: $spacer * 2;
+ width: $spacer * 2;
+ }
+
+ &:nth-of-type(1) {
+ padding: $spacer 0 $spacer * 1.5 $spacer * 2;
+
+ .industries-testimonials__card-metric-count {
+ color: $secondary-blue-50;
+ }
+ }
+
+ &:nth-of-type(2) {
+ .industries-testimonials__card-metric-count {
+ color: $secondary-teal-50;
+ }
+ }
+
+ &:nth-of-type(3) {
+ .industries-testimonials__card-metric-count {
+ color: $secondary-violet-50;
+ }
+ }
+ }
+
+ &-count {
+ margin-bottom: 0;
+ font-weight: 500;
+ }
+
+ &-description {
+ margin-bottom: 0;
+ font-size: $font-size-l;
+ line-height: $line-height-lg;
+ color: $neutral-50;
+ }
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ &__item {
+ &:not(:last-of-type) {
+ margin-bottom: pxToRem(30);
+ }
+ }
+
+ &__logo {
+ height: pxToRem(300);
+
+ &:after {
+ bottom: 0;
+ }
+ }
+
+ &__card {
+ height: pxToRem(300);
+ flex-direction: row;
+ padding: $spacer * 3.5;
+
+ &-review {
+ justify-content: space-between;
+ padding: 0 $spacer * 0.5 0 0;
+
+ &-text {
+ margin-bottom: $spacer * 0.2;
+ }
+ }
+
+ &-metric {
+ width: pxToRem(232);
+ justify-content: space-between;
+ flex-shrink: 0;
+ border-left: pxToRem(1) solid $neutral-90;
+
+ &-item {
+ padding: 0 0 0 $spacer * 2;
+ border-bottom: 0;
+
+ &:nth-of-type(1) {
+ padding: 0 $spacer * 0.5 0 $spacer * 2;
+ }
+
+ &:last-of-type {
+ border-bottom: 0;
+ }
+ }
+
+ &-divider {
+ &:last-of-type {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/assets/js/industries.js b/qdrant-landing/themes/qdrant-2024/assets/js/industries.js
new file mode 100644
index 000000000..09905db45
--- /dev/null
+++ b/qdrant-landing/themes/qdrant-2024/assets/js/industries.js
@@ -0,0 +1,252 @@
+(function () {
+ const initTabs = (root) => {
+ const tabsWrap = root.querySelector(".industries-hero__tabs");
+ if (!tabsWrap) return;
+ const [btnCode, btnSteps] = tabsWrap.querySelectorAll("button");
+ const codeBlock = root.querySelector(".industries-hero__code");
+ const stepsBlock = root.querySelector(".industries-hero__steps");
+ if (!btnCode || !btnSteps || !codeBlock || !stepsBlock) return;
+
+ const setActive = (view) => {
+ const isCode = view === "code";
+ codeBlock.hidden = !isCode;
+ stepsBlock.hidden = isCode;
+ btnCode.classList.toggle("active", isCode);
+ btnSteps.classList.toggle("active", !isCode);
+ btnCode.type = "button";
+ btnSteps.type = "button";
+ btnCode.setAttribute("aria-selected", String(isCode));
+ btnSteps.setAttribute("aria-selected", String(!isCode));
+ };
+
+ btnCode.addEventListener("click", () => setActive("code"));
+ btnSteps.addEventListener("click", () => setActive("steps"));
+ setActive("code");
+ };
+
+ const initCodeExpandCollapse = (root) => {
+ const code = root.querySelector(".industries-hero__code");
+ if (!code) return;
+
+ const content = code.querySelector(".industries-hero__code-content");
+ const btnExpand = code.querySelector(".industries-hero__code-expand");
+ const btnCollapse = code.querySelector(".industries-hero__code-collapse");
+ if (!content || !btnExpand || !btnCollapse) return;
+
+ const collapsedHeightPx = parseFloat(getComputedStyle(content).height);
+
+ btnExpand.type = "button";
+ btnCollapse.type = "button";
+
+ const expand = () => {
+ code.classList.add("is-expanded");
+
+ const startHeight = content.getBoundingClientRect().height;
+ content.style.height = `${startHeight}px`;
+ content.offsetHeight;
+
+ const targetHeight = content.scrollHeight;
+ content.style.height = `${targetHeight}px`;
+
+ const onEnd = (e) => {
+ if (e.propertyName !== "height") return;
+ content.style.height = "auto";
+ content.removeEventListener("transitionend", onEnd);
+ };
+ content.addEventListener("transitionend", onEnd);
+ };
+
+ const collapse = () => {
+ code.classList.remove("is-expanded");
+
+ const startHeight = content.getBoundingClientRect().height;
+
+ content.style.height = `${startHeight}px`;
+ content.offsetHeight;
+ content.style.height = `${collapsedHeightPx}px`;
+ };
+
+ btnExpand.addEventListener("click", expand);
+ btnCollapse.addEventListener("click", collapse);
+ };
+
+ const initCopyCode = (root) => {
+ const bindCopy = (codeWrap, { copyDisplay = "block", doneDisplay = "block" } = {}) => {
+ const btnCopy = codeWrap.querySelector(".industries-architecture__code-copy, .industries-hero__code-copy");
+ const btnDone = codeWrap.querySelector(".industries-architecture__code-done, .industries-hero__code-done");
+ const codeEl = codeWrap.querySelector(".highlight code");
+
+ if (!btnCopy || !btnDone || !codeEl) return;
+
+ btnCopy.type = "button";
+ btnDone.type = "button";
+
+ btnCopy.addEventListener("click", async () => {
+ const text = codeEl.textContent || "";
+
+ try {
+ await navigator.clipboard.writeText(text);
+ btnCopy.style.display = "none";
+ btnDone.style.display = doneDisplay;
+
+ setTimeout(() => {
+ btnDone.style.display = "none";
+ btnCopy.style.display = copyDisplay;
+ }, 1200);
+ } catch (e) {
+ console.error(e);
+ }
+ });
+ };
+
+ // industries-architecture
+ root.querySelectorAll(".industries-architecture__code").forEach((codeWrap) => {
+ bindCopy(codeWrap, { copyDisplay: "block", doneDisplay: "block" });
+ });
+
+ // industries-hero
+ const codeWrap = root.querySelector(".industries-hero__code");
+ if (!codeWrap) return;
+ bindCopy(codeWrap, { copyDisplay: "flex", doneDisplay: "flex" });
+ };
+
+ const initCaseStudiesCarousel = () => {
+ const root = document.querySelector('.industries-case-studies');
+ const container = document.querySelector('.industries-case-studies__container');
+ const carousel = document.querySelector('.industries-case-studies__carousel');
+ const track = document.querySelector('.industries-case-studies__track');
+ const prevBtn = document.querySelector('.industries-case-studies__arrow--prev');
+ const nextBtn = document.querySelector('.industries-case-studies__arrow--next');
+
+ if (!root || !container || !carousel || !track || !prevBtn || !nextBtn) return;
+
+ const slides = track.querySelectorAll('.industries-case-studies__slide');
+ const breakpoints = { sm: 576, md: 768, xl: 1200 };
+ let currentOffset = 0;
+ let gap = 0;
+ let lastSlideWidth = 0;
+ let lastGap = 0;
+ let sliderEnabled = false;
+
+ function readGap() {
+ const style = getComputedStyle(track);
+ gap = parseFloat(style.columnGap || style.gap) || 0;
+ carousel.style.setProperty('--industries-case-studies-gap', gap + 'px');
+ }
+
+ function getVisibleCount() {
+ const w = window.innerWidth;
+ if (w < breakpoints.md) return 1;
+ if (w < breakpoints.xl) return 2;
+ return 3;
+ }
+
+ 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('--industries-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() {
+ if (!sliderEnabled) {
+ currentOffset = 0;
+ track.style.transform = 'translateX(0px)';
+ return;
+ }
+ const maxOffset = getMaxOffset();
+ currentOffset = Math.min(Math.max(0, currentOffset), maxOffset);
+ track.style.transform = `translateX(-${currentOffset}px)`;
+ }
+
+ function updateButtons() {
+ if (!sliderEnabled) {
+ prevBtn.disabled = true;
+ nextBtn.disabled = true;
+ return;
+ }
+ const maxOffset = getMaxOffset();
+ prevBtn.disabled = currentOffset <= 0;
+ nextBtn.disabled = currentOffset >= maxOffset;
+ }
+
+ prevBtn.addEventListener('click', function() {
+ if (!sliderEnabled) return;
+ const slideWidth = getSlideWidth();
+ currentOffset = Math.max(0, currentOffset - (slideWidth + gap));
+ updateTrack();
+ updateButtons();
+ });
+
+ nextBtn.addEventListener('click', function() {
+ if (!sliderEnabled) return;
+ const maxOffset = getMaxOffset();
+ const slideWidth = getSlideWidth();
+ currentOffset = Math.min(maxOffset, currentOffset + (slideWidth + gap));
+ updateTrack();
+ updateButtons();
+ });
+
+ function onResize() {
+ const prevStep = (lastSlideWidth || getSlideWidth()) + (lastGap || gap || 0);
+ const prevIndex = prevStep > 0 ? Math.round(currentOffset / prevStep) : 0;
+
+ readGap();
+ applySlideWidth();
+
+ const visible = Math.min(getVisibleCount(), slides.length);
+ const isSmall = window.innerWidth < breakpoints.md;
+ sliderEnabled = !isSmall && slides.length > visible;
+ root.classList.toggle('industries-case-studies__active-slider', sliderEnabled);
+
+ if (!sliderEnabled) {
+ currentOffset = 0;
+ } else {
+ const nextStep = getSlideWidth() + gap;
+ currentOffset = prevIndex * nextStep;
+ }
+
+ updateTrack();
+ updateButtons();
+
+ lastGap = gap;
+ lastSlideWidth = getSlideWidth();
+ }
+
+ let resizeRaf = 0;
+ window.addEventListener('resize', function() {
+ if (resizeRaf) return;
+ resizeRaf = requestAnimationFrame(function() {
+ resizeRaf = 0;
+ onResize();
+ });
+ });
+
+ onResize();
+ }
+
+ initTabs(document);
+ initCodeExpandCollapse(document);
+ initCopyCode(document);
+ initCaseStudiesCarousel();
+})();
\ No newline at end of file
diff --git a/qdrant-landing/themes/qdrant-2024/layouts/hr-tech/list.html b/qdrant-landing/themes/qdrant-2024/layouts/hr-tech/list.html
index cafc2094f..4775ae12c 100644
--- a/qdrant-landing/themes/qdrant-2024/layouts/hr-tech/list.html
+++ b/qdrant-landing/themes/qdrant-2024/layouts/hr-tech/list.html
@@ -1,28 +1,14 @@
{{ define "main" }}
{{ partial "site-header" . }}
- {{ with (.Site.GetPage "hr-tech/hero") }}
- {{ partial "hr-tech/hr-tech-hero" . }}
- {{ end }}
+ {{ range .Params.sections }}
+ {{ $type := .type }}
+ {{ $special := dict
+ "cta-banner" "partials/cta-banner.html"
+ }}
- {{ with (.Site.GetPage "/hr-tech/testimonial-light") }}
- {{ partial "testimonial-light" (dict "context" . "class" "customers-testimonial pb-5 pb-lg-7") }}
- {{ end }}
-
- {{ with (.Site.GetPage "/hr-tech/help") }}
- {{ partial "hr-tech/hr-tech-help" . }}
- {{ end }}
-
- {{ with (.Site.GetPage "/hr-tech/features") }}
- {{ partial "hr-tech/hr-tech-features" . }}
- {{ end }}
-
- {{ with (.Site.GetPage "/hr-tech/why-qdrant") }}
- {{ partial "hr-tech/hr-tech-why-qdrant" . }}
- {{ end }}
-
- {{ with (.Site.GetPage "/hr-tech/get-contacted") }}
- {{ partial "cta-banner" . }}
+ {{ $partialPath := (index $special $type) | default (printf "partials/industries/industries-%s.html" $type) }}
+ {{ partial $partialPath (dict "Params" .) }}
{{ end }}
{{ end }}
diff --git a/qdrant-landing/themes/qdrant-2024/layouts/partials/cta-banner.html b/qdrant-landing/themes/qdrant-2024/layouts/partials/cta-banner.html
index 9356f3e15..3ae5d96a1 100644
--- a/qdrant-landing/themes/qdrant-2024/layouts/partials/cta-banner.html
+++ b/qdrant-landing/themes/qdrant-2024/layouts/partials/cta-banner.html
@@ -6,7 +6,7 @@