diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 27ee2b857..8da99624f 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -20,6 +20,11 @@ const config: Config = { organizationName: "/HaudinFlorence/", // Usually your GitHub org/user name. projectName: "quantstack.github.io", // Usually your repo name. + clientModules: [ + require.resolve("./src/clientModules/navbarScroll.ts"), + require.resolve("./src/clientModules/backgroundScene.ts"), + ], + onBrokenLinks: "warn", onBrokenMarkdownLinks: "warn", staticDirectories: ["static"], @@ -107,6 +112,12 @@ const config: Config = { }, items: [ + { + to: "/", + className: "custom_navbar_item navbar_hide_mid", + label: "Home", + position: "left", + }, { to: "/projects/", className: "custom_navbar_item", @@ -122,7 +133,7 @@ const config: Config = { { to: "/about/", className: "custom_navbar_item", - label: "About us", + label: "About", position: "left", }, { @@ -138,16 +149,22 @@ const config: Config = { position: "left", }, { - to: "/fundable/", - label: "Fundable projects", - position: "right", - className: "fundable_projects" + to: "/sponsor/", + className: "custom_navbar_item", + label: "Sponsor", + position: "left", }, { to: "/contact/", - label: "Contact us", + className: "custom_navbar_item", + label: "Contact", + position: "left", + }, + { + to: "/notebooklink/", + className: "navbar_notebooklink", + label: "Notebook.link", position: "right", - className: "contact", }, { to: "https://github.com/QuantStack", diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..0b0400ab4 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1778443072, + "narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..4a1005f9e --- /dev/null +++ b/flake.nix @@ -0,0 +1,24 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShells.${system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nodejs_20 + python3 + pkg-config + cairo + pango + libpng + libjpeg + giflib + librsvg + pixman + ]; + }; + }; +} diff --git a/scripts/generate-atom-feed.mjs b/scripts/generate-atom-feed.mjs index 33d92bb5b..59e3744e5 100644 --- a/scripts/generate-atom-feed.mjs +++ b/scripts/generate-atom-feed.mjs @@ -1,6 +1,6 @@ import fs from 'fs'; import { Feed } from 'feed'; -import { blogpostsDetails } from '../src/components/blog/blogpostsDetails.js'; +import { blogpostsDetails } from '../src/pages/blogs/_blogpostsDetails.js'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); diff --git a/scripts/generate-rss-feed.mjs b/scripts/generate-rss-feed.mjs index 6fbde0bf2..e1ec21605 100644 --- a/scripts/generate-rss-feed.mjs +++ b/scripts/generate-rss-feed.mjs @@ -1,6 +1,6 @@ import fs from 'fs'; import RSS from 'rss'; -import { blogpostsDetails } from '../src/components/blog/blogpostsDetails.js'; +import { blogpostsDetails } from '../src/pages/blogs/_blogpostsDetails.js'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); diff --git a/src/clientModules/backgroundScene.ts b/src/clientModules/backgroundScene.ts new file mode 100644 index 000000000..04a7f4998 --- /dev/null +++ b/src/clientModules/backgroundScene.ts @@ -0,0 +1,147 @@ +// Injects a fixed full-page background scene (planets, graph, code snippets) +// directly into document.body. Color switches to white when a dark section +// is in the centre of the viewport, detected via a scroll listener. + +// ─── SVG data ──────────────────────────────────────────────────────────────── + +const NODES: [number, number][] = [ + [110, 95], [360, 60], [680, 85], [990, 50], [1230, 105], + [1385, 190], [1350, 410], [1160, 330], [1030, 190], [870, 295], + [760, 470], [1210, 590], [1030, 740], [800, 830], [570, 775], + [340, 845], [140, 755], [62, 510], +]; + +const EDGES: [number, number][] = [ + [0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[4,8],[8,9],[9,10], + [7,6],[6,11],[11,12],[12,13],[13,14],[14,15],[15,16],[16,17], + [2,9],[10,14],[7,11],[3,8],[0,17], +]; + +const SNIPPETS = [ + { text: "mamba install xtensor", x: 770, y: 765, angle: -4 }, + { text: "import ipywidgets as w", x: 1075, y: 540, angle: -6 }, + { text: "voila dashboard.ipynb", x: 1295, y: 435, angle: 5 }, + { text: "xt::arange(10)", x: 305, y: 855, angle: 7 }, + { text: "jupyter lite build", x: 920, y: 115, angle: -3 }, + { text: "import pyarrow as pa", x: 180, y: 380, angle: 4 }, +]; + +function buildSVG(): string { + const edges = EDGES.map(([a, b]) => + ``, + ).join(""); + + const nodes = NODES.map(([x, y]) => + ``, + ).join(""); + + const snippets = SNIPPETS.map(({ text, x, y, angle }) => + `${text}`, + ).join(""); + + return ` + + + + + + + + + + + + + + + ${edges}${nodes} + ${snippets} +`; +} + +// ─── DOM element ────────────────────────────────────────────────────────────── + +let bgEl: HTMLDivElement | null = null; + +function mount(): void { + // Recover existing element after HMR resets the module variable + if (!bgEl) { + bgEl = document.getElementById("page-background-scene") as HTMLDivElement | null; + } + if (bgEl) return; + + bgEl = document.createElement("div"); + bgEl.setAttribute("aria-hidden", "true"); + bgEl.setAttribute("id", "page-background-scene"); + Object.assign(bgEl.style, { + position: "fixed", + inset: "0", + zIndex: "1", + pointerEvents: "none", + userSelect: "none", + overflow: "hidden", + color: "#1d1d1b", + transition: "color 0.6s ease", + }); + bgEl.innerHTML = buildSVG(); + document.body.appendChild(bgEl); +} + +function applyDark(dark: boolean): void { + if (!bgEl) return; + bgEl.style.color = dark ? "#ffffff" : "#1d1d1b"; + const p = bgEl.querySelector("#_pbg_p"); + const g = bgEl.querySelector("#_pbg_g"); + const s = bgEl.querySelector("#_pbg_s"); + if (p) p.setAttribute("opacity", dark ? "0.12" : "0.09"); + if (g) g.setAttribute("opacity", dark ? "0.18" : "0.14"); + if (s) s.setAttribute("opacity", dark ? "0.15" : "0.11"); +} + +// ─── Scroll-based dark detection ────────────────────────────────────────────── +// Re-queries the DOM on every scroll so it always reflects the current page. + +function updateColor(): void { + const vh = window.innerHeight; + const darkEls = document.querySelectorAll("[data-section-bg='dark']"); + let anyDark = false; + darkEls.forEach((el) => { + const { top, bottom } = el.getBoundingClientRect(); + // Trigger when the dark section covers the middle 60 % of the viewport + if (top < vh * 0.8 && bottom > vh * 0.2) anyDark = true; + }); + applyDark(anyDark); +} + +let scrollListenerAdded = false; + +// ─── Route lifecycle ────────────────────────────────────────────────────────── + +export function onRouteDidUpdate(): void { + mount(); + + // Add the scroll listener once (persists across SPA navigations) + if (!scrollListenerAdded) { + window.addEventListener("scroll", updateColor, { passive: true }); + scrollListenerAdded = true; + } + + // Always reset to light first, then re-check after the DOM settles + applyDark(false); + requestAnimationFrame(updateColor); +} diff --git a/src/clientModules/navbarScroll.ts b/src/clientModules/navbarScroll.ts new file mode 100644 index 000000000..5b2311456 --- /dev/null +++ b/src/clientModules/navbarScroll.ts @@ -0,0 +1,31 @@ +const THRESHOLD = 20; +const DARK_HERO_PAGES = ["/notebooklink/"]; +const LOGO_DEFAULT = "/img/quantstack/logo-website-smaller.svg"; +const LOGO_WHITE_TEXT = "/img/quantstack/logo-website-white-text.svg"; + +function update(): void { + const scrolled = window.scrollY > THRESHOLD; + const { pathname } = window.location; + const isHome = pathname === "/"; + const isDarkHero = DARK_HERO_PAGES.some((p) => pathname.startsWith(p)); + const useDarkLogo = isDarkHero && !scrolled; + document.documentElement.toggleAttribute("data-navbar-scrolled", scrolled); + document.documentElement.toggleAttribute( + "data-navbar-home-top", + isHome && !scrolled + ); + document.documentElement.toggleAttribute("data-navbar-dark-top", useDarkLogo); + const logoImg = document.querySelector(".navbar__logo img") as HTMLImageElement | null; + if (logoImg) { + logoImg.src = useDarkLogo ? LOGO_WHITE_TEXT : LOGO_DEFAULT; + } +} + +export function onRouteDidUpdate(): void { + update(); +} + +if (typeof window !== "undefined") { + window.addEventListener("scroll", update, { passive: true }); + update(); +} diff --git a/src/components/Blog.tsx b/src/components/Blog.tsx new file mode 100644 index 000000000..c2c682b65 --- /dev/null +++ b/src/components/Blog.tsx @@ -0,0 +1,32 @@ +import React, { useState } from "react"; +import CardGrid from "./layout/CardGrid"; +import BlogpostCard from "./BlogpostCard"; +import { blogpostsDetails } from "../pages/blogs/_blogpostsDetails"; +import styles from "../pages/blog.module.css"; + +export default function BlogGrid() { + const [searchField, setSearchField] = useState(""); + + const filtered = blogpostsDetails.filter((blogpost) => + [blogpost.title, blogpost.authors, blogpost.date, blogpost.summary] + .some((field) => field.toLowerCase().includes(searchField.toLowerCase())) + ); + + return ( + <> + setSearchField(e.target.value)} + /> + + {filtered.map((blogpost, index) => ( +
  • + +
  • + ))} +
    + + ); +} diff --git a/src/components/BlogpostCard.tsx b/src/components/BlogpostCard.tsx new file mode 100644 index 000000000..5716e1d67 --- /dev/null +++ b/src/components/BlogpostCard.tsx @@ -0,0 +1,33 @@ +import styles from "../pages/blog.module.css"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import Card from "./layout/Card"; + +export default function BlogpostCard({ blogpost }) { + return ( + + +
    + Illustration for the blog post. +
    +
    {blogpost.title}
    +
    + {blogpost.summary.length < 200 + ? blogpost.summary + : blogpost.summary.substring(0, 200) + "..."} +
    +
    +
    + + {blogpost.date} +
    +
    {blogpost.authors}
    +
    + +
    + ); +} diff --git a/src/components/ContactForm.tsx b/src/components/ContactForm.tsx new file mode 100644 index 000000000..4ef02efa2 --- /dev/null +++ b/src/components/ContactForm.tsx @@ -0,0 +1,32 @@ +import styles from "../pages/contact.module.css"; + +export default function ContactForm() { + return ( +
    + {[ + { label: "Your name", name: "name", type: "text" }, + { label: "Your company", name: "company", type: "text" }, + { label: "Your email", name: "email", type: "text" }, + { label: "Your phone number", name: "phone-number", type: "text" }, + ].map(({ label, name, type }) => ( +
    + +
    + +
    +
    + ))} +
    + + -
    - -
    -
    - -
    -
    -
    - - ); - } \ No newline at end of file diff --git a/src/components/contact/index.tsx b/src/components/contact/index.tsx deleted file mode 100644 index eb0614f2d..000000000 --- a/src/components/contact/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import styles from "./styles.module.css"; -import ContactForm from "./ContactForm"; -import { useEffect, useState } from "react"; -import ContactIllustration from "/img/illustrations/contact.svg"; - -export function Contact() { - return ( -
    -

    Contact us

    -
    -
    - -
    -
    - -
    -
    -
    - ); -} -export default Contact; diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx index 2e0682037..f864a398c 100644 --- a/src/components/footer/Footer.tsx +++ b/src/components/footer/Footer.tsx @@ -41,7 +41,7 @@ export default function Footer() {
    • - Home + Home
    • diff --git a/src/components/footer/styles.module.css b/src/components/footer/styles.module.css index 6b0cc7760..b5253eb87 100644 --- a/src/components/footer/styles.module.css +++ b/src/components/footer/styles.module.css @@ -1,6 +1,8 @@ .footer_container { background-color: var(--ifm-color-primary-p1); padding: var(--ifm-spacing-xl) var(--ifm-spacing-2xl) 0 var(--ifm-spacing-2xl); + position: relative; + z-index: 2; } .copyright_container { diff --git a/src/components/fundable/FundableProjectCard.tsx b/src/components/fundable/FundableProjectCard.tsx new file mode 100644 index 000000000..bdf3ffeeb --- /dev/null +++ b/src/components/fundable/FundableProjectCard.tsx @@ -0,0 +1,35 @@ +import styles from "./styles.module.css"; +import { useHistory } from "@docusaurus/router"; +import ProgressBar from "./ProgressBar"; +import Card from "../layout/Card"; + +export default function FundableProjectCard({ project }) { + const history = useHistory(); + + function open() { + history.push({ + pathname: `/sponsor/${project.pageName}`, + state: { fromFundable: true, scrollY: window.scrollY }, + }); + } + + const desc = project.shortDescription.length > 160 + ? project.shortDescription.substring(0, 160) + "…" + : project.shortDescription; + + return ( + +
      {project.category}
      +
      {project.title}
      +

      {desc}

      +
      +
      {project.price}
      + +
      + {project.currentFundingPercentage}% funded + {project.currentNbOfFunders > 0 && ` · ${project.currentNbOfFunders} funder${project.currentNbOfFunders > 1 ? "s" : ""}`} +
      +
      +
      + ); +} diff --git a/src/components/fundable/GetAQuotePage.tsx b/src/components/fundable/GetAQuotePage.tsx index 0c0510876..6e5a03346 100644 --- a/src/components/fundable/GetAQuotePage.tsx +++ b/src/components/fundable/GetAQuotePage.tsx @@ -6,7 +6,7 @@ import { useHistory, useLocation } from "@docusaurus/router"; import Layout from "@theme/Layout"; import { Route } from 'react-router-dom'; import { getCategoryFromProjectPageName } from "."; -import FundableProjects from "."; +import { FundableContent as FundableProjects } from "@site/src/pages/sponsor"; function GetAQuoteComponent({ project }) { return ( @@ -32,14 +32,14 @@ export default function GetAQuotePage() { const history = useHistory(); const handleClose = () => { - history.push('/fundable'); + history.push('/sponsor'); } return ( { const { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/ const projectsByCategory = getCategoryFromProjectPageName(pageName); diff --git a/src/components/fundable/LargeProjectCard.tsx b/src/components/fundable/LargeProjectCard.tsx index 2c29adfe6..22e0ef631 100644 --- a/src/components/fundable/LargeProjectCard.tsx +++ b/src/components/fundable/LargeProjectCard.tsx @@ -11,7 +11,7 @@ export function LargeProjectCardContent({ project }) { const pageName = project.pageName; history.push({ - pathname: `/fundable/${pageName}/GetAQuote`, + pathname: `/sponsor/${pageName}/GetAQuote`, state: { from: location.pathname, scrollY: window.scrollY }, }); } diff --git a/src/components/fundable/LargeProjectCardPage.tsx b/src/components/fundable/LargeProjectCardPage.tsx index 708342515..f8842904c 100644 --- a/src/components/fundable/LargeProjectCardPage.tsx +++ b/src/components/fundable/LargeProjectCardPage.tsx @@ -4,8 +4,8 @@ import { useHistory, useLocation } from '@docusaurus/router'; import { useEffect } from 'react'; import { Route } from 'react-router-dom'; import { getCategoryFromProjectPageName } from "."; +import { FundableContent } from "@site/src/pages/sponsor"; import styles from "@site/src/components/about/styles.module.css"; -import FundableProjects from '.'; import LargeProjectCard from './LargeProjectCard'; export default function LargeProjectCardPage() { @@ -25,13 +25,13 @@ export default function LargeProjectCardPage() { window.scrollTo({ top: scrollY, behavior: 'auto' }); } }, 0); - history.replace('/fundable'); + history.replace('/sponsor'); }; const handleClose = () => { const scrollY = location.state?.scrollY; if (location.state?.fromFundable) { - history.replace('/fundable'); + history.replace('/sponsor'); setTimeout(() => { if (scrollY !== undefined) { @@ -44,9 +44,9 @@ export default function LargeProjectCardPage() { } return ( - + { const { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/ const projectsByCategory = getCategoryFromProjectPageName(pageName); diff --git a/src/components/fundable/LinkToGetAQuote.tsx b/src/components/fundable/LinkToGetAQuote.tsx index 7219bb941..cbc41266f 100644 --- a/src/components/fundable/LinkToGetAQuote.tsx +++ b/src/components/fundable/LinkToGetAQuote.tsx @@ -6,7 +6,7 @@ export default function LinkToGetAQuote({ label, pageName }) {
      {label} diff --git a/src/components/fundable/SmallProjectCard.tsx b/src/components/fundable/SmallProjectCard.tsx index dba7e93d9..1dc0c3021 100644 --- a/src/components/fundable/SmallProjectCard.tsx +++ b/src/components/fundable/SmallProjectCard.tsx @@ -13,7 +13,7 @@ export function SmallProjectCard({ project }) { const pageName = project.pageName; history.push({ - pathname: `/fundable/${pageName}`, + pathname: `/sponsor/${pageName}`, state: { fromFundable: true, scrollY: window.scrollY }, }); } diff --git a/src/components/fundable/index.tsx b/src/components/fundable/index.tsx index 976fa64de..ad220d0f2 100644 --- a/src/components/fundable/index.tsx +++ b/src/components/fundable/index.tsx @@ -1,73 +1,61 @@ +import { useState, useEffect } from "react"; import styles from "./styles.module.css"; -import { fundableProjectsDetails } from "./projectsDetails"; -import ProjectCategory from "./ProjectCategory"; -import MenuSidebar from "./MenuSideBar"; -import LinkToContact from "../home/LinkToContact"; +import CardGrid from "../layout/CardGrid"; +import { fundableProjectsDetails } from "@site/src/pages/sponsor/_projectsDetails"; +import FundableProjectCard from "./FundableProjectCard"; + +const ALL_PROJECTS = Object.values(fundableProjectsDetails).flat(); +const CATEGORIES = ["All", ...new Set(ALL_PROJECTS.map((p) => p.category))]; export function getCategoryFromProjectPageName(pageName: string) { - for (const [categoryName, projectsByCategory] of Object.entries(fundableProjectsDetails)) { - const project = projectsByCategory.find((project) => project.pageName === pageName); - if (project) { - return projectsByCategory; - } + for (const projects of Object.values(fundableProjectsDetails)) { + const found = projects.find((p) => p.pageName === pageName); + if (found) return projects; } return null; } export function MainAreaFundableProjects() { - return ( -
      -

      Check out our projects available for funding!

      + const [active, setActive] = useState(() => { + if (typeof window === "undefined") return "All"; + const param = new URLSearchParams(window.location.search).get("category"); + return CATEGORIES.includes(param) ? param : "All"; + }); -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      -

      Can't find a project?

      -

      If you have a project in mind that you think would be relevant to our expertise, please contact us to discuss it.

      - -
      -
      - ) -} + useEffect(() => { + const url = new URL(window.location.href); + if (active === "All") { + url.searchParams.delete("category"); + } else { + url.searchParams.set("category", active); + } + window.history.replaceState(null, "", url.toString()); + }, [active]); -export default function FundableProjects() { - return ( + const visible = active === "All" + ? ALL_PROJECTS + : ALL_PROJECTS.filter((p) => p.category === active); -
      -
      -
      - -
      -
      - -
      -
      - -
      + return ( + <> +
      + {CATEGORIES.map((cat) => ( + + ))}
      -
      - + + {visible.map((project) => ( +
    • + +
    • + ))} + + ); } diff --git a/src/components/fundable/styles.module.css b/src/components/fundable/styles.module.css index a327b4996..c0f16fe70 100644 --- a/src/components/fundable/styles.module.css +++ b/src/components/fundable/styles.module.css @@ -1,11 +1,104 @@ +/* ── Filter + grid layout ──────────────────────────────── */ + +.filter_tags { + display: flex; + flex-wrap: wrap; + gap: var(--ifm-spacing-sm); + margin-bottom: var(--ifm-spacing-xl); +} + +.filter_tag { + padding: 6px var(--ifm-spacing-md); + border-radius: 20px; + border: 1.5px solid var(--ifm-color-secondary-s3); + background: transparent; + color: var(--ifm-color-secondary-s3); + font-family: var(--ifm-font-family-roboto); + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: background 0.15s, color 0.15s, border-color 0.15s; +} + +.filter_tag:hover { + background: var(--ifm-color-secondary-s1); + color: var(--ifm-color-secondary-s2); + border-color: var(--ifm-color-secondary-s1); +} + +.filter_tag_active { + background: var(--ifm-bg-emphasis); + color: white; + border-color: var(--ifm-bg-emphasis); +} + + +.fund_card { + gap: var(--ifm-spacing-sm); +} + +.fund_card_category { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.6px; + color: var(--ifm-color-secondary-s3); +} + +.fund_card_title { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-weight: 600; + color: var(--ifm-color-primary-p2); + line-height: 1.4; +} + +.fund_card_desc { + font-size: 13px !important; + color: var(--ifm-color-neutral-n1); + line-height: 1.5; + flex: 1; + padding: 0 !important; + margin: 0 !important; +} + +.fund_card_footer { + margin-top: auto; + padding-top: var(--ifm-spacing-sm); + border-top: 1px solid var(--ifm-color-neutral-n3); + display: flex; + flex-direction: column; + gap: 4px; +} + +.fund_card_price { + font-family: var(--ifm-font-family-roboto); + font-size: 17px; + font-weight: 700; + color: var(--ifm-color-primary-p2); +} + +.fund_card_pct { + font-size: 12px; + color: var(--ifm-color-neutral-n1); +} + +.propose_section { + border-top: 1px solid var(--ifm-color-neutral-n3); + padding-top: var(--ifm-spacing-2xl); + margin-top: var(--ifm-spacing-xl); +} + +/* ── Legacy card (kept for SmallProjectCard / ProjectCategory) ── */ + .small_project_card:hover { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); } .project_category_header { - font-family: var(--ifm-font-family-rubik-one); + font-family: var(--ifm-font-family-roboto); font-style: normal; - font-weight: 400; + font-weight: 700; line-height: 20px; text-align: center; margin-bottom: var(--ifm-spacing-xl); @@ -15,7 +108,7 @@ .project_title { color: var(--ifm-text-color-main-title); - font-family: var(--ifm-font-family-bebas-neue); + font-family: var(--ifm-font-family-roboto); font-size: 32px; font-style: normal; font-weight: 600; @@ -43,7 +136,7 @@ left: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.3); + background-color: var(--ifm-overlay-background); z-index: 1000; } @@ -52,7 +145,7 @@ top: 50%; left: 50%; transform: translate(-50%, -50%); - background-color: white; + background-color: var(--ifm-bg-neutral); border: 1px solid #ccc; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); border-radius: 20px; @@ -96,7 +189,6 @@ .link_to_get_a_quote { background-color: var(--ifm-color-orange-jupyter); color: white; - width: 358px; font-weight: 700; } @@ -106,41 +198,6 @@ margin: var(--ifm-spacing-md) 0; } -.menu_sidebar { - padding: 1rem; - overflow-y: auto; -} - -.menu_sidebar_item { - font-family: var(--ifm-font-family-roboto); - font-size: 16px; - font-style: normal; - font-weight: 500; - line-height: 48px; - /* 300% */ - letter-spacing: 0.15px; -} - -.menu_sidebar_container { - position: fixed; - display: flex; - height: auto; -} - -.menu_sidebar_indicator { - display: inline-block; - width: 6px; - height: 20px; - border-radius: 4px; - background-color: transparent; - margin-right: 10px; - transition: background-color 0.3s ease; - vertical-align: middle; -} - -.active_section .menu_sidebar_indicator { - background-color: #D9D9D9; -} .send_button { width: 258px; @@ -158,7 +215,7 @@ .form_label { font-size: 12px; color: var(--ifm-text-color); - background-color: var(--ifm-background-color); + background-color: var(--ifm-bg-neutral); } .project_information_container { @@ -302,14 +359,6 @@ padding: var(--ifm-spacing-md); } - .main_area_desktop { - display: none - } - - .menu_sidebar { - display: none - } - .small_project_card { width: 90vw; margin-bottom: var(--ifm-spacing-lg); @@ -409,10 +458,6 @@ max-height: 95vh; } - .main_area_desktop { - display: none - } - .small_input { width: 400px; height: 56px; @@ -435,10 +480,6 @@ height: 200px; } - .menu_sidebar { - display: none - } - .get_a_quote_dialog { width: 80vw; padding: 40px; @@ -486,14 +527,6 @@ max-height: 95vh; } - .main_area_mobile { - display: none; - } - - .main_area_desktop { - padding-left: 80px; - } - .small_input { width: 400px; height: 56px; diff --git a/src/components/home/AboutQS/index.tsx b/src/components/home/AboutQS/index.tsx deleted file mode 100644 index 14e5903d6..000000000 --- a/src/components/home/AboutQS/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import styles from "./styles.module.css"; -import GroupPhotoUrl from "@site/static/img/group/QuantStack-2000-58.png"; -import LinkToAboutUs from "../LinkToAboutUs"; - -export default function AboutQS() { - return ( -
      -
      -
      -
      - We are a team of expert of open-source developers, the very same - people behind a number of technologies that you already use. -
      -
      -
      -
      -
      -
      - { -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      - ); -} diff --git a/src/components/home/AboutQS/styles.module.css b/src/components/home/AboutQS/styles.module.css deleted file mode 100644 index 90fa260f8..000000000 --- a/src/components/home/AboutQS/styles.module.css +++ /dev/null @@ -1,30 +0,0 @@ -@media only screen and (max-width: 996px) { - .aboutQS_container { - background-color: var(--ifm-color-secondary-s2); - color: white; - padding: var(--ifm-spacing-2xl) var(--ifm-spacing-2xl) 0 - var(--ifm-spacing-2xl); - text-align: center; - } - - .aboutQS_text { - font-size: 14px; - text-align: center; - margin-bottom: var(--ifm-spacing-xl); - } -} - -@media only screen and (min-width: 996px) { - .aboutQS_container { - background-color: var(--ifm-color-primary-p1); - color: var(--ifm-color-primary-p2); - padding: var(--ifm-spacing-2xl) var(--ifm-spacing-5xl) 0 - var(--ifm-spacing-5xl); - } - - .aboutQS_text { - font-size: 24px; - text-align: center; - margin-bottom: var(--ifm-spacing-lg); - } -} diff --git a/src/components/home/Hero/Banner.tsx b/src/components/home/Hero/Banner.tsx deleted file mode 100644 index f70731341..000000000 --- a/src/components/home/Hero/Banner.tsx +++ /dev/null @@ -1,40 +0,0 @@ -// src/components/PageBanner.tsx -import React from 'react'; -import styles from "./styles.module.css"; -import LinkToNotebookLink from './LinkToNotebookLink'; - -export default function Banner() { - return ( -
      -
      -
      -
      Introducing Notebook.link
      -
      The future of notebook sharing
      - -
      -
      -
      - -
      -
      Introducing Notebook.link
      -
      The future of notebook sharing
      - -
      -
      -
      -
      -
      Introducing Notebook.link
      -
      The future of notebook sharing
      - -
      -
      -
      -
      -
      Introducing Notebook.link
      -
      The future of notebook sharing
      - -
      -
      -
      - ); -} diff --git a/src/components/home/Hero/LinkToNotebookLink.tsx b/src/components/home/Hero/LinkToNotebookLink.tsx deleted file mode 100644 index ca31445f6..000000000 --- a/src/components/home/Hero/LinkToNotebookLink.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import styles from "./styles.module.css"; - -export default function LinkToNotebookLink({label}) { - return ( - - ); -} diff --git a/src/components/home/Hero/LogosTableBy8.tsx b/src/components/home/Hero/LogosTableBy8.tsx deleted file mode 100644 index 1f485e89e..000000000 --- a/src/components/home/Hero/LogosTableBy8.tsx +++ /dev/null @@ -1,382 +0,0 @@ -import styles from "./styles.module.css"; -import BloombergLogoUrl from "@site/static/img/logos/Bloomberg.png"; -import SGLogoUrl from "@site/static/img/logos/SG.png"; -import RapyutaLogoUrl from "@site/static/img/logos/Rapyuta.png"; -import CFMLogoUrl from "@site/static/img/logos/CFM.png"; -import EngieLogoUrl from "@site/static/img/logos/Engie.png"; -import JRCLogoUrl from "@site/static/img/logos/JRC.png"; -import ERDCLogoUrl from "@site/static/img/logos/ERDC.png"; -import PandaLogoUrl from "@site/static/img/logos/Panda.png"; -import UniversiteParisCiteLogoUrl from "@site/static/img/logos/UniversiteParisCite.png"; -import AirbusLogoUrl from "@site/static/img/logos/Airbus.png"; -import INRIALogoUrl from "@site/static/img/logos/INRIA.png"; -import CNAMLogoUrl from "@site/static/img/logos/CNAM.png"; -import NatixisLogoUrl from "@site/static/img/logos/Natixis.png"; -import NumfocusLogoUrl from "@site/static/img/logos/Numfocus.png"; -import RobocorpLogoUrl from "@site/static/img/logos/Robocorp.png"; -import CalPolyLogoUrl from "@site/static/img/logos/CalPoly.png"; -import MaxFordhamLogoUrl from "@site/static/img/logos/MaxFordham.png"; -import GainTheoryUrl from "@site/static/img/logos/GainTheory.png"; -import EnthoughtLogoUrl from "@site/static/img/logos/Enthought.png"; -import CressetLogoUrl from "@site/static/img/logos/Cresset.png"; -import TDKLogoUrl from "@site/static/img/logos/TDK.png"; -import HarvardLogoUrl from "@site/static/img/logos/Harvard.png"; -import EMBLLogoUrl from "@site/static/img/logos/EMBL.png"; -import QuantCoUrl from "@site/static/img/logos/QuantCo.png"; -import VoltronDataLogoUrl from "@site/static/img/logos/VoltronData.png"; -import SafranLogoUrl from "@site/static/img/logos/Safran.png"; -import DEShawLogoUrl from "@site/static/img/logos/DEShaw.png"; -import UniversiteParisSaclayLogoUrl from "@site/static/img/logos/UniversiteParisSaclay.png"; -import UnitedRoboticsLogoUrl from "@site/static/img/logos/UnitedRobotics.png"; -import CEALogoUrl from "@site/static/img/logos/CEA.png"; -import EcolePolytechniqueLogoUrl from "@site/static/img/logos/EcolePolytechnique.png"; -import ESALogoUrl from "@site/static/img/logos/ESA.png"; -import CNESLogoUrl from "@site/static/img/logos/CNES.png"; -import GatesFoundationLogoUrl from "@site/static/img/logos/GatesFoundation.png"; -import SovereignTechAgencyLogoUrl from "@site/static/img/logos/SovereignTechAgency.png"; - -import Slider from "react-slick"; -// Import css files -import "slick-carousel/slick/slick.css"; -import "slick-carousel/slick/slick-theme.css"; - -export default function SimpleSlider() { - let settings = { - dots: true, - infinite: true, - speed: 1000, - slidesToShow: 1, - slidesToScroll: 1, - arrows: false, - autoplay: true, - }; - return ( - -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      - ); -} - -export function LogosTable1() { - return ( -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      - -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      - ); -} - -export function LogosTable2() { - return ( -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      - ); -} - -export function LogosTable3() { - return ( -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      - -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      - ); -} - -export function LogosTable4() { - return ( -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      - ); -} - -export function LogosTable5() { - return ( -
      -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      - {"Logo -
      -
      -
      - ); -} diff --git a/src/components/home/Hero/index.tsx b/src/components/home/Hero/index.tsx deleted file mode 100644 index 8dfa4ea7a..000000000 --- a/src/components/home/Hero/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import styles from "./styles.module.css"; -import SimpleSlider from "./LogosTableBy8"; -import Astronaut from "/img/quantstack/astronaut.svg"; -import Banner from "./Banner"; - - -export function Hero() { - return ( -
      - -
      -
      -
      -
      -
      -
      -

      - Open-source for discovery, science, and education -

      -

      - A team behind major open-source projects of the scientific - computing ecosystem -

      -

      - Jupyter, Conda-forge, Mamba, Voilà, Xtensor and more. -

      -
      - -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      We have worked with
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      - ); -} -export default Hero; diff --git a/src/components/home/Hero/styles.module.css b/src/components/home/Hero/styles.module.css deleted file mode 100644 index 89e31f669..000000000 --- a/src/components/home/Hero/styles.module.css +++ /dev/null @@ -1,225 +0,0 @@ -.h2_custom { - color: var(--ifm-color-blue-jupyter); -} - -.sub_header { - text-align: left; -} - -.hero_container { - background-color: var(--ifm-color-primary-p0); - padding-bottom: var(--ifm-spacing-3xl); -} - -.row_max_width { - max-width: 1500px; - display: flex; -} - -.banner_container_small { - position: relative; - width: 100%; - display: flex; - align-items: center; - background-image: url('/img/banner/notebook-link-banner-small.svg'); - background-position: center; - background-repeat: no-repeat; - height: 464px; - padding-bottom: 110px; -} - -.banner_container_medium { - position: relative; - width: 100%; - display: flex; - align-items: center; - background-image: url('/img/banner/notebook-link-banner-medium.svg'); - background-position: center; - background-repeat: no-repeat; - height: 464px; - padding-bottom: 110px; -} - -.banner_container_large { - position: relative; - width: 100%; - display: flex; - align-items: center; - background-image: url('/img/banner/notebook-link-banner-large.svg'); - background-position: center; - background-repeat: no-repeat; - height: 464px; - padding-bottom: 110px; -} - -.banner_container_very_large { - position: relative; - width: 100%; - display: flex; - align-items: center; - background-image: url('/img/banner/notebook-link-banner-very-large.svg'); - background-position: center; - background-repeat: no-repeat; - height: 464px; - padding-bottom: 110px; -} - - -.banner_image { - width: 100%; - height: auto; - display: block; -} - -.banner_text_overlay { - margin-top: 50px; - margin-left: auto; - margin-right: auto; - text-align: center; - color: white; - /* or whatever contrasts with your SVG */ - font-size: 2rem; - font-family: var(--ifm-font-family-kode-mono); -} - -.banner_text_overlay_title { - font-size: 48px; - font-weight: 400; - font-style: normal; - line-height: 100%; -} - -.banner_text_overlay_subtitle { - font-size: 32px; - font-style: normal; -} - -.notebook_link { - color: #FCF12B; - font-weight: 700; - font-style: bold; - line-height: 100%; - font-family: var(--ifm-font-family-inter); -} - -:global(.link-to-button).link_to_notebook_link { - display: flex; - align-items: center; - justify-content: center; - background: linear-gradient(135deg, - #5242FF, - #2A2A2A); - color: white; - width: 358px; - font-weight: 700; - font-family: var(--ifm-font-family-roboto); - font-weight: 600; - font-size: 24px; -} - -@media only screen and (max-width: 576px) { - - /*Mobile*/ - .logos_carousel { - display: none; - } - - .banner_container_medium { - display: none - } - - .banner_container_large { - display: none - } - - .banner_container_very_large { - display: none - } -} - -@media screen and (min-width: 576px) and (max-width: 996px) { - - /*Tablet*/ - .logos_carousel { - display: none; - } - - .banner_container_small { - display: none - } - - .banner_container_large { - display: none - } - - .banner_container_very_large { - display: none - } -} - -@media screen and (min-width: 996px) and (max-width: 1511px) { - - /*Desktop: small screen*/ - .table_with_8_customers { - margin-bottom: var(--ifm-spacing-xl); - } - - .customer_logo { - filter: grayscale(1); - width: 100px; - } - - .worked_with { - font-size: 24px; - font-weight: 200; - font-family: var(--ifm-font-family-rubik-one); - color: var(--ifm-color-primary-p2); - text-align: center; - margin: var(--ifm-spacing-2xl) 0; - } - - .banner_container_small { - display: none - } - - .banner_container_medium { - display: none - } - - .banner_container_very_large { - display: none - } -} - -@media only screen and (min-width: 1511px) { - /* Desktop : large screen*/ - .table_with_8_customers { - margin-bottom: var(--ifm-spacing-xl); - } - - .customer_logo { - filter: grayscale(1); - width: 100px; - } - - .worked_with { - font-size: 24px; - font-weight: 200; - font-family: var(--ifm-font-family-rubik-one); - color: var(--ifm-color-primary-p2); - text-align: center; - margin: var(--ifm-spacing-2xl) 0; - } - - .banner_container_small { - display: none - } - - .banner_container_medium { - display: none - } - - .banner_container_large { - display: none - } -} \ No newline at end of file diff --git a/src/components/home/Home.tsx b/src/components/home/Home.tsx deleted file mode 100644 index 9c3c95ca3..000000000 --- a/src/components/home/Home.tsx +++ /dev/null @@ -1,23 +0,0 @@ - -import Hero from "./Hero"; -import WhatWeDo from "./WhatWeDo"; -import ProjectsOverview from "./ProjectsOverview"; -import AboutQS from "./AboutQS"; -import News from "./News"; -import LearnMore from "./LearnMore"; - - -export function Home(): JSX.Element { - return ( - <> - - - - - - - - ); -} - -export default Home; \ No newline at end of file diff --git a/src/components/home/LearnMore/index.tsx b/src/components/home/LearnMore/index.tsx deleted file mode 100644 index ce20d37e8..000000000 --- a/src/components/home/LearnMore/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import LinkToContact from "../LinkToContact"; -import styles from "./styles.module.css"; - -export default function LearnMore() { - return ( -
      -
      Want to learn more?
      - Schedule a meeting and benefit from our expertise on Jupyter, Conda-forge, - high-performance computing, and open-source development. - -
      - ); -} diff --git a/src/components/home/LearnMore/styles.module.css b/src/components/home/LearnMore/styles.module.css deleted file mode 100644 index 838b19f99..000000000 --- a/src/components/home/LearnMore/styles.module.css +++ /dev/null @@ -1,6 +0,0 @@ -@media only screen and (max-width: 996px) { - /*Mobile*/ - .learn_more_container { - display: none; - } -} \ No newline at end of file diff --git a/src/components/home/LinkToAboutUs.tsx b/src/components/home/LinkToAboutUs.tsx deleted file mode 100644 index adbe99591..000000000 --- a/src/components/home/LinkToAboutUs.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from "./styles.module.css"; -import Link from "@docusaurus/Link"; - -export default function LinkToAboutUs({label}) { - return ( -
      - - {label} - -
      - ); -} diff --git a/src/components/home/LinkToBlogs.tsx b/src/components/home/LinkToBlogs.tsx deleted file mode 100644 index 2ae3acb53..000000000 --- a/src/components/home/LinkToBlogs.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from "./styles.module.css"; -import Link from "@docusaurus/Link"; - -export default function LinkToBlogs({label}) { - return ( -
      - - {label} - -
      - ); -} diff --git a/src/components/home/LinkToContact.tsx b/src/components/home/LinkToContact.tsx deleted file mode 100644 index d3936b01d..000000000 --- a/src/components/home/LinkToContact.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from "./styles.module.css"; -import Link from "@docusaurus/Link"; - -export default function LinkToContact({label}) { - return ( -
      - - {label} - -
      - ); -} diff --git a/src/components/home/LinkToProjects.tsx b/src/components/home/LinkToProjects.tsx deleted file mode 100644 index 03860ddf1..000000000 --- a/src/components/home/LinkToProjects.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from "./styles.module.css"; -import Link from "@docusaurus/Link"; - -export default function LinkToProjects({label}) { - return ( -
      - - {label} - -
      - ); -} diff --git a/src/components/home/LinkToServices.tsx b/src/components/home/LinkToServices.tsx deleted file mode 100644 index 7c7c7252e..000000000 --- a/src/components/home/LinkToServices.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from "./styles.module.css"; -import Link from "@docusaurus/Link"; - -export default function LinkToServices({label}) { - return ( -
      - - {label} - -
      - ); -} diff --git a/src/components/home/News/index.tsx b/src/components/home/News/index.tsx deleted file mode 100644 index fa594a3e2..000000000 --- a/src/components/home/News/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import BlogpostCard from "../../blog/BlogpostCard"; -import { blogpostsDetails } from "../../blog/blogpostsDetails"; -import styles from "./styles.module.css"; -import LinkToBlogs from "../LinkToBlogs"; - -export default function News() { - const numberOfBlogs = blogpostsDetails.length; - return ( -
      -
      -
      -

      Recent blog contributions

      -
      -
      -
      -
        -
      • -
        - -
        -
      • -
      • -
        - -
        -
      • -
      • -
        - -
        -
      • -
      - - -
      - ); -} diff --git a/src/components/home/News/styles.module.css b/src/components/home/News/styles.module.css deleted file mode 100644 index 2096f772d..000000000 --- a/src/components/home/News/styles.module.css +++ /dev/null @@ -1,10 +0,0 @@ -@media only screen and (max-width: 996px) { - /*Mobile */ - .news_container { - display: none; - } -} - -.news_container { - margin-top: var(--ifm-spacing-2xl); -} diff --git a/src/components/home/ProjectsOverview/Computing.tsx b/src/components/home/ProjectsOverview/Computing.tsx deleted file mode 100644 index 1ce02eaaf..000000000 --- a/src/components/home/ProjectsOverview/Computing.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import styles from "./styles.module.css"; -import ComputingMD from "@site/src/components/home/ProjectsOverview/descriptions/Computing.md"; -import XTensorXSIMDPicture from "@site/static/img/projects/xtensor_xsimd.svg"; - -export default function ComputingProjects() { - return ( -
      -
      -
      -

      Scientific computing

      -

      - Supporting the development of several C++ scientific computing - packages. -

      - - -
      -
      - -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/DataAnalysis.tsx b/src/components/home/ProjectsOverview/DataAnalysis.tsx deleted file mode 100644 index 577026a13..000000000 --- a/src/components/home/ProjectsOverview/DataAnalysis.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import styles from "./styles.module.css"; -import DataAnalysisMD from "@site/src/components/home/ProjectsOverview/descriptions/DataAnalysis.md"; -import ApacheArrowPicture from "@site/static/img/projects/apache_arrow.svg"; - -export default function DataAnalysisProjects() { - return ( -
      -
      -
      -

      Data Analysis

      -

      - Supporting the development of key data analysis technologies. -

      - -
      -
      - -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/Jupyter.tsx b/src/components/home/ProjectsOverview/Jupyter.tsx deleted file mode 100644 index 580800442..000000000 --- a/src/components/home/ProjectsOverview/Jupyter.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import styles from "./styles.module.css"; -import JupyterMD from "./descriptions/Jupyter.md"; -import JupyterPictureUrl from "@site/static/img/projects/jupyterlab_examples.png"; - -export default function JupyterProject() { - return ( -
      -
      -
      -

      Jupyter project

      -

      We strive to sustain the project in the long term.

      - -
      - -
      - {"Picture -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/Robotics.tsx b/src/components/home/ProjectsOverview/Robotics.tsx deleted file mode 100644 index 3374bb199..000000000 --- a/src/components/home/ProjectsOverview/Robotics.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import styles from "./styles.module.css"; -import RoboticsMD from "@site/src/components/home/ProjectsOverview/descriptions/Robotics.md"; -import RoboticsPictureUrl from "@site/static/img/projects/robotics.png"; - -export default function RoboticsProjects() { - return ( -
      -
      -
      -

      Robotics

      -

      - We just kicked off a new initiative to Robotics education. -

      - -
      -
      - { -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/RoboticsReverse.tsx b/src/components/home/ProjectsOverview/RoboticsReverse.tsx deleted file mode 100644 index 54a99d39e..000000000 --- a/src/components/home/ProjectsOverview/RoboticsReverse.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import styles from "./styles.module.css"; -import RoboticsMD from "@site/src/components/home/ProjectsOverview/descriptions/Robotics.md"; -import RoboticsPictureUrl from "@site/static/img/projects/robotics.png"; - -export default function RoboticsProjects() { - return ( -
      -
      -
      - {"Picture -
      -
      -

      Robotics

      -

      - We just kicked off a new initiative to Robotics education. -

      - -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/SpecialProjects.tsx b/src/components/home/ProjectsOverview/SpecialProjects.tsx deleted file mode 100644 index e624bf2f8..000000000 --- a/src/components/home/ProjectsOverview/SpecialProjects.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import styles from "./styles.module.css"; -import SpecialProjectsMD from "@site/src/components/home/ProjectsOverview/descriptions/SpecialProjects.md"; -import SpecialProjectsPictureUrl from "@site/static/img/projects/special_projects.png"; - -export default function SpecialProjects() { - return ( -
      -
      -
      -

      Special projects

      -

      - Applications built from the ground up and addressing a complete use - case. -

      - - -
      -
      - {"Picture -
      -
      -
      - ); - } \ No newline at end of file diff --git a/src/components/home/ProjectsOverview/SupplyChain.tsx b/src/components/home/ProjectsOverview/SupplyChain.tsx deleted file mode 100644 index 98c5f4162..000000000 --- a/src/components/home/ProjectsOverview/SupplyChain.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import styles from "./styles.module.css"; -import SupplyChainMD from "./descriptions/SupplyChain.md"; -import MambaPictureUrl from "@site/static/img/projects/mamba_console.png"; - -export default function SupplyChainProjects() { - return ( -
      -
      -
      -

      Software supply chain

      -

      - We are the main organization supporting the mamba package manager. -

      -
      - -
      -
      - {"Picture -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/SupplyChainReversed.tsx b/src/components/home/ProjectsOverview/SupplyChainReversed.tsx deleted file mode 100644 index 33d06cd57..000000000 --- a/src/components/home/ProjectsOverview/SupplyChainReversed.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import styles from "./styles.module.css"; -import SupplyChainMD from "./descriptions/SupplyChain.md"; -import MambaPictureUrl from "@site/static/img/projects/mamba_console.png"; - -export default function SupplyChainProjects() { - return ( -
      -
      -
      - {"Picture -
      -
      -

      Software supply chain

      -

      - We are the main organization supporting the mamba package manager. -

      -
      - -
      -
      -
      - ); -} diff --git a/src/components/home/ProjectsOverview/descriptions/Computing.md b/src/components/home/ProjectsOverview/descriptions/Computing.md deleted file mode 100644 index a5d453c99..000000000 --- a/src/components/home/ProjectsOverview/descriptions/Computing.md +++ /dev/null @@ -1,5 +0,0 @@ -QuantStack is the main organization supporting the development of several C++ scientific computing packages such as: - -- Xsimd, a unified API for SIMD operations, used by projects such as Apache Arrow, Firefox, Krita, Pythran, and naturally, xtensor. - -- Xtensor, a multi-dimensional array library in C++, supporting NumPy-style API and features, such as universal functions and broadcasting, while being lazy-evaluated. Language bindings for Python, R, and Julia are also available. \ No newline at end of file diff --git a/src/components/home/ProjectsOverview/descriptions/DataAnalysis.md b/src/components/home/ProjectsOverview/descriptions/DataAnalysis.md deleted file mode 100644 index 32292dd1f..000000000 --- a/src/components/home/ProjectsOverview/descriptions/DataAnalysis.md +++ /dev/null @@ -1,8 +0,0 @@ - -Since 2024, QuantStack is involved in the development of: - -- Apache Arrow, a memory format designed for efficient columnar data storage. It serves as the foundation for many data science frameworks, enabling seamless interoperability between various data systems and programming languages, - -- Apache Parquet, a column-oriented data file format designed for efficient data storage and retrieval. - -QuantStack is home to several maintainers of the project who are committed to its continuous improvement and advancement. \ No newline at end of file diff --git a/src/components/home/ProjectsOverview/descriptions/Jupyter.md b/src/components/home/ProjectsOverview/descriptions/Jupyter.md deleted file mode 100644 index d88641391..000000000 --- a/src/components/home/ProjectsOverview/descriptions/Jupyter.md +++ /dev/null @@ -1,4 +0,0 @@ -Our team is deeply involved in the development of the Jupyter project, at both technical and organizational levels, with several members participating in the project governance in various capacities. - -We are responsible for some of the main innovations of the past years (JupyterLite, Collaborative editing in JupyterLab, the Voilà dashboard system, the JupyterLab visual debugger). - diff --git a/src/components/home/ProjectsOverview/descriptions/Robotics.md b/src/components/home/ProjectsOverview/descriptions/Robotics.md deleted file mode 100644 index b24e067aa..000000000 --- a/src/components/home/ProjectsOverview/descriptions/Robotics.md +++ /dev/null @@ -1,11 +0,0 @@ - - QuantStack created the RoboStack distribution of ROS, the first - multi-platform distribution of ROS, as conda packages. - - We are bootstrapping the jupyter-ros project, a - Jupyterlab-basedrobotics development environment for the ROS - ecosystem. - - We just kicked off a new initiative to Robotics education.
      - Stay tuned for more on this subject! - \ No newline at end of file diff --git a/src/components/home/ProjectsOverview/descriptions/SpecialProjects.md b/src/components/home/ProjectsOverview/descriptions/SpecialProjects.md deleted file mode 100644 index c570799aa..000000000 --- a/src/components/home/ProjectsOverview/descriptions/SpecialProjects.md +++ /dev/null @@ -1,12 +0,0 @@ -Special projects leverage the open-source software stack that we -maintain. They can rely, for instance, on the JupyterLab -application framework and assemble JupyterLab components to produce -a different application. - - Such examples include: - - - Glue-Web: a JupyterLab extension to link visualizations of scientific datasets across many files, - - JupyterCAD: a JupyterLab extension for collaborative 3D geometry modeling, - - JupyterGIS : a JupyterLab extension for collaborative GIS (Geographical Information System) editor in Jupyter. - - diff --git a/src/components/home/ProjectsOverview/descriptions/SupplyChain.md b/src/components/home/ProjectsOverview/descriptions/SupplyChain.md deleted file mode 100644 index 67b014cc1..000000000 --- a/src/components/home/ProjectsOverview/descriptions/SupplyChain.md +++ /dev/null @@ -1,9 +0,0 @@ - - We contribute to the conda-forge project, by maintaining a large - number of package recipes, and contributing to the underlying - infrastructure. - - - We created the first conda/mamba-based package distribution for - WebAssembly, emscripten-forge. - \ No newline at end of file diff --git a/src/components/home/ProjectsOverview/index.tsx b/src/components/home/ProjectsOverview/index.tsx deleted file mode 100644 index 29ff08841..000000000 --- a/src/components/home/ProjectsOverview/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import JupyterProject from "./Jupyter"; -import SupplyChainProjects from "./SupplyChain"; -import SpecialProjects from "./SpecialProjects"; -import RoboticsProjects from "./Robotics"; -import ComputingProjects from "./Computing"; -import DataAnalysisProjects from "./DataAnalysis"; -import styles from "./styles.module.css"; - -export default function ProjectsOverview() { - return ( -
      - - - - - - -
      - ); -} diff --git a/src/components/home/ProjectsOverview/styles.module.css b/src/components/home/ProjectsOverview/styles.module.css deleted file mode 100644 index 81f624a1a..000000000 --- a/src/components/home/ProjectsOverview/styles.module.css +++ /dev/null @@ -1,26 +0,0 @@ -@media (max-width: 996px) { - .projects_overview_container { - display: none; - } -} - -.h2_custom { - color: var(--ifm-color-blue-jupyter); -} - -.col_project_overview_with_padding { - padding: var(--ifm-spacing-4xl) var(--ifm-spacing-3xl); -} - -.project_yellow { - background-color: var(--ifm-color-primary-p1); -} - -.project_light_yellow { - background-color: var(--ifm-color-primary-p0); -} -.container_projects { - padding: 0; - display: flex; - justify-content: center; -} \ No newline at end of file diff --git a/src/components/home/WhatWeDo/Topics.tsx b/src/components/home/WhatWeDo/Topics.tsx deleted file mode 100644 index 16478e2c0..000000000 --- a/src/components/home/WhatWeDo/Topics.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { topicsDetails } from "./topics/topicsDetails"; -import { TopicsCard } from "./TopicsCard"; -import JupyterMD from "./topics/Jupyter.md"; -import SupplyChainMD from "./topics/SupplyChain.md"; -import ComputingMD from "./topics/Computing.md"; - -const TopicsDescriptions = [JupyterMD, SupplyChainMD, ComputingMD]; - -export function Topics() { - return ( -
      -
      -
        - {topicsDetails.map((topics, index) => ( -
      • - -
      • - ))} -
      -
      -
      - ); -} - -export default Topics; diff --git a/src/components/home/WhatWeDo/TopicsCard.tsx b/src/components/home/WhatWeDo/TopicsCard.tsx deleted file mode 100644 index d1557e3c0..000000000 --- a/src/components/home/WhatWeDo/TopicsCard.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import styles from "./styles.module.css"; - -export function TopicsCard({ topics, TopicsDescriptionMD }) { - return ( -
      -
      - {topics.name} -
      -
      - -
      -
      - ); -} - -export default TopicsCard; diff --git a/src/components/home/WhatWeDo/index.tsx b/src/components/home/WhatWeDo/index.tsx deleted file mode 100644 index 6e43cbb8c..000000000 --- a/src/components/home/WhatWeDo/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import styles from "./styles.module.css"; -import Topics from "./Topics"; -import LinkToServices from "../LinkToServices"; -import LinkToProjects from "../LinkToProjects"; - -export function WhatWeDo() { - return ( -
      -
      -
      - -
      -
      -
      -

      What we do

      -
      -
      - -
      -
      -
      - - -
      - -
      -
      -
      -
      - ); -} - -export default WhatWeDo; diff --git a/src/components/home/WhatWeDo/styles.module.css b/src/components/home/WhatWeDo/styles.module.css deleted file mode 100644 index 353f6dada..000000000 --- a/src/components/home/WhatWeDo/styles.module.css +++ /dev/null @@ -1,72 +0,0 @@ -.topics_header { - font-family: var(--ifm-font-family-rubik-one); - font-size: var(--ifm-font-size-secondary-title); - font-style: normal; - font-weight: 400; - line-height: 28px; - text-align: center; - margin-bottom: var(--ifm-spacing-xl); -} - -div .topics_header { - color: var(--ifm-color-neutral-n2); -} - -@media only screen and (max-width: 996px) { - /*Mobile*/ - .header { - display: none; - } - - .whatwedo_container { - /*background-color: var(--ifm-color-primary-p1);*/ - padding: 0; - margin-top: 0; - } - - .topics_card { - width: 80%; - text-align: justify; - background-color: var(--ifm-color-primary-p0); - margin: var(--ifm-spacing-lg) auto var(--ifm-spacing-lg) auto ; - } - - .topics_card .p { - padding: var(--ifm-spacing-xs) var(--ifm-spacing-xs); - } - - - .services_link_desktop { - display: none; - } -} - -@media only screen and (min-width: 996px) { - .header { - color: var(--ifm-color-primary-p2); - } - - .projects_link{ - display: none; - } - - .services_link_mobile { - display: none; - } - - .whatwedo_container { - background-color: var(--ifm-color-primary-p1); - padding: var(--ifm-spacing-3xl) var(--ifm-spacing-2xl) 0 - var(--ifm-spacing-2xl); - } - - .topics_card { - height: 462px; - width: 350px; - padding: var(--ifm-spacing-2xl) var(--ifm-spacing-lg); - border-radius: 8px; - box-shadow: 0px 0px 8px 1px #c8c8c7; - background-color: var(--ifm-color-primary-p0); - margin: 0 var(--ifm-spacing-lg) var(--ifm-spacing-xl) var(--ifm-spacing-lg); - } -} diff --git a/src/components/home/WhatWeDo/topics/Computing.md b/src/components/home/WhatWeDo/topics/Computing.md deleted file mode 100644 index 79297a227..000000000 --- a/src/components/home/WhatWeDo/topics/Computing.md +++ /dev/null @@ -1 +0,0 @@ -We created several popular scientific computing packages. XSimd, an unified API for SIMD operations, adopted by projects such as Apache Arrow, FireFox, Kytra, Pythran... Xtensor, a C++ n-dimensional array library with broadcasting and lazy evaluation. \ No newline at end of file diff --git a/src/components/home/WhatWeDo/topics/Jupyter.md b/src/components/home/WhatWeDo/topics/Jupyter.md deleted file mode 100644 index 7ff88a240..000000000 --- a/src/components/home/WhatWeDo/topics/Jupyter.md +++ /dev/null @@ -1 +0,0 @@ -Our team comprises key maintainers of the Jupyter project. We are responsible for a large part of the maintenance and continuous improvement of the project, ensuring its long-term sustainability. \ No newline at end of file diff --git a/src/components/home/WhatWeDo/topics/SupplyChain.md b/src/components/home/WhatWeDo/topics/SupplyChain.md deleted file mode 100644 index 07f55be5d..000000000 --- a/src/components/home/WhatWeDo/topics/SupplyChain.md +++ /dev/null @@ -1 +0,0 @@ -We contribute to the conda-forge project, which provides thousands of packages and accounts for billions of downloads. We created the mamba package manager, which underlies a lot of conda-forge’s infrastructure. \ No newline at end of file diff --git a/src/components/home/WhatWeDo/topics/topicsDetails.ts b/src/components/home/WhatWeDo/topics/topicsDetails.ts deleted file mode 100644 index adb3fbe61..000000000 --- a/src/components/home/WhatWeDo/topics/topicsDetails.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const topicsDetails = [ - { - topics: "jupyter", - name: "Project Jupyter", - imageRoute: "", - }, - { - topics: "supplychain", - name: "Software Supply Chain", - imageRoute: "", - }, - { - topics: "computing", - name: "Scientific Computing", - imageRoute: "", - }, -]; diff --git a/src/components/home/styles.module.css b/src/components/home/styles.module.css deleted file mode 100644 index 54c987305..000000000 --- a/src/components/home/styles.module.css +++ /dev/null @@ -1,48 +0,0 @@ - -@media only screen and (max-width: 996px) { - /*Mobile*/ - .link_to { - background-color: var(--ifm-color-primary-p1); - color: var(--ifm-text-color-on-primary-p1); - width: 358px; - font-weight: 700; - } - - .link_to_services { - background-color: var(--ifm-color-primary-p1); - color: var(--ifm-text-color-on-primary-p1); - width: 358px; - font-weight: 700; - } - - .link_to_about_us { - background-color: var(--ifm-color-primary-p1); - color: var(--ifm-text-color-on-primary-p1); - width: 358px; - font-weight: 700; - } -} - -@media only screen and (min-width: 996px) { - .link_to { - background-color: var(--ifm-color-secondary-s2); - color: white; - width: 358px; - font-weight: 700; - } - - .link_to_services { - background-color: var(--ifm-color-blue-jupyter); - color: white; - width: 358px; - font-weight: 700; - } - - - .link_to_about_us { - background-color: var(--ifm-color-secondary-s2); - color: white; - width: 358px; - font-weight: 700; - } -} diff --git a/src/components/layout/BackgroundScene.module.css b/src/components/layout/BackgroundScene.module.css new file mode 100644 index 000000000..9b200130e --- /dev/null +++ b/src/components/layout/BackgroundScene.module.css @@ -0,0 +1,39 @@ +.container { + position: absolute; + inset: 0; + overflow: hidden; + pointer-events: none; + user-select: none; + z-index: 0; +} + +.planets { + animation: bg-planets 58s ease-in-out infinite; +} + +.graph { + animation: bg-graph 72s ease-in-out infinite; + animation-delay: -18s; +} + +.snippets { + animation: bg-snippets 44s ease-in-out infinite; + animation-delay: -9s; +} + +@keyframes bg-planets { + 0%, 100% { transform: translate(0px, 0px); } + 33% { transform: translate(11px, -16px); } + 66% { transform: translate(-8px, 10px); } +} + +@keyframes bg-graph { + 0%, 100% { transform: translate(0px, 0px); } + 50% { transform: translate(-13px, 8px); } +} + +@keyframes bg-snippets { + 0%, 100% { transform: translate(0px, 0px); } + 40% { transform: translate(7px, -11px); } + 75% { transform: translate(-5px, 13px); } +} diff --git a/src/components/layout/BackgroundScene.tsx b/src/components/layout/BackgroundScene.tsx new file mode 100644 index 000000000..4db65d6dc --- /dev/null +++ b/src/components/layout/BackgroundScene.tsx @@ -0,0 +1,110 @@ +import clsx from "clsx"; +import styles from "./BackgroundScene.module.css"; + +const NODES: [number, number][] = [ + [110, 95], [360, 60], [680, 85], [990, 50], [1230, 105], + [1385, 190], [1350, 410], [1160, 330], [1030, 190], [870, 295], + [760, 470], [1210, 590], [1030, 740], [800, 830], [570, 775], + [340, 845], [140, 755], [62, 510], +]; + +const EDGES: [number, number][] = [ + [0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[4,8],[8,9],[9,10], + [7,6],[6,11],[11,12],[12,13],[13,14],[14,15],[15,16],[16,17], + [2,9],[10,14],[7,11],[3,8],[0,17], +]; + +const SNIPPETS = [ + { text: "import xarray as xr", x: 770, y: 765, angle: -4 }, + { text: "conda install -c conda-forge", x: 1075, y: 540, angle: -6 }, + { text: "∂L/∂θ = ∇θ L", x: 1295, y: 435, angle: 5 }, + { text: "df.groupby('date').sum()", x: 305, y: 855, angle: 7 }, + { text: "kernel = rbf(X, X.T)", x: 920, y: 115, angle: -3 }, +]; + +type Props = { variant?: "light" | "dark" }; + +export default function BackgroundScene({ variant = "light" }: Props) { + const c = variant === "dark" ? "#ffffff" : "#1d1d1b"; + const planetOp = variant === "dark" ? 0.10 : 0.07; + const graphOp = variant === "dark" ? 0.15 : 0.11; + const snippetOp = variant === "dark" ? 0.13 : 0.09; + + return ( + + ); +} diff --git a/src/components/layout/Banner.tsx b/src/components/layout/Banner.tsx new file mode 100644 index 000000000..44f811f29 --- /dev/null +++ b/src/components/layout/Banner.tsx @@ -0,0 +1,28 @@ +import clsx from "clsx"; +import styles from "./styles.module.css"; +import type { ReactNode } from "react"; + +type Props = { + bg?: "dark" | "light"; + title?: string; + cta?: ReactNode; + fullHeight?: boolean; + children: ReactNode; +}; + +export default function Banner({ bg = "dark", title, cta, fullHeight = false, children }: Props) { + return ( +
      + {title && ( +
      + {title} +
      + )} +
      {children}
      + {cta &&
      {cta}
      } +
      + ); +} diff --git a/src/components/layout/Card.tsx b/src/components/layout/Card.tsx new file mode 100644 index 000000000..22075073b --- /dev/null +++ b/src/components/layout/Card.tsx @@ -0,0 +1,28 @@ +import clsx from "clsx"; +import styles from "./styles.module.css"; +import React from "react"; + +type Props = { + bg?: "white" | "yellow" | "transparent"; + hover?: boolean; + className?: string; + onClick?: () => void; + children: React.ReactNode; +}; + +export default function Card({ bg = "white", hover = false, className, onClick, children }: Props) { + return ( +
      + {children} +
      + ); +} diff --git a/src/components/layout/CardGrid.tsx b/src/components/layout/CardGrid.tsx new file mode 100644 index 000000000..e090e54a3 --- /dev/null +++ b/src/components/layout/CardGrid.tsx @@ -0,0 +1,24 @@ +import clsx from "clsx"; +import styles from "./styles.module.css"; +import type { ReactNode } from "react"; + +type Props = { + cols?: 2 | 3 | 4; + children: ReactNode; + className?: string; +}; + +export default function CardGrid({ cols = 3, children, className }: Props) { + return ( +
        + {children} +
      + ); +} diff --git a/src/components/layout/PageBackground.module.css b/src/components/layout/PageBackground.module.css new file mode 100644 index 000000000..f2258a4d1 --- /dev/null +++ b/src/components/layout/PageBackground.module.css @@ -0,0 +1,45 @@ +.container { + position: fixed; + inset: 0; + pointer-events: none; + user-select: none; + z-index: 1; + /* color drives currentColor on all SVG children */ + color: var(--bg-scene-color, #1d1d1b); + transition: color 0.7s ease; + overflow: hidden; +} + +.planets { + opacity: var(--bg-planet-op, 0.07); + animation: bg-planets 58s ease-in-out infinite; +} + +.graph { + opacity: var(--bg-graph-op, 0.11); + animation: bg-graph 72s ease-in-out infinite; + animation-delay: -18s; +} + +.snippets { + opacity: var(--bg-snippet-op, 0.09); + animation: bg-snippets 44s ease-in-out infinite; + animation-delay: -9s; +} + +@keyframes bg-planets { + 0%,100% { transform: translate(0, 0); } + 33% { transform: translate(11px, -16px); } + 66% { transform: translate(-8px, 10px); } +} + +@keyframes bg-graph { + 0%,100% { transform: translate(0, 0); } + 50% { transform: translate(-13px, 8px); } +} + +@keyframes bg-snippets { + 0%,100% { transform: translate(0, 0); } + 40% { transform: translate(7px, -11px); } + 75% { transform: translate(-5px, 13px); } +} diff --git a/src/components/layout/PageBackground.tsx b/src/components/layout/PageBackground.tsx new file mode 100644 index 000000000..6963e6949 --- /dev/null +++ b/src/components/layout/PageBackground.tsx @@ -0,0 +1,101 @@ +import styles from "./PageBackground.module.css"; + +const NODES: [number, number][] = [ + [110, 95], [360, 60], [680, 85], [990, 50], [1230, 105], + [1385, 190], [1350, 410], [1160, 330], [1030, 190], [870, 295], + [760, 470], [1210, 590], [1030, 740], [800, 830], [570, 775], + [340, 845], [140, 755], [62, 510], +]; + +const EDGES: [number, number][] = [ + [0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[4,8],[8,9],[9,10], + [7,6],[6,11],[11,12],[12,13],[13,14],[14,15],[15,16],[16,17], + [2,9],[10,14],[7,11],[3,8],[0,17], +]; + +const SNIPPETS = [ + { text: "import xarray as xr", x: 770, y: 765, angle: -4 }, + { text: "conda install -c conda-forge", x: 1075, y: 540, angle: -6 }, + { text: "∂L/∂θ = ∇θ L", x: 1295, y: 435, angle: 5 }, + { text: "df.groupby('date').sum()", x: 305, y: 855, angle: 7 }, + { text: "kernel = rbf(X, X.T)", x: 920, y: 115, angle: -3 }, +]; + +export default function PageBackground() { + return ( + + ); +} diff --git a/src/components/layout/ScrollDownCTA.tsx b/src/components/layout/ScrollDownCTA.tsx new file mode 100644 index 000000000..90ed9dd17 --- /dev/null +++ b/src/components/layout/ScrollDownCTA.tsx @@ -0,0 +1,29 @@ +import React from "react"; + +export default function ScrollDownCTA({ label = "Read more" }: { label?: string }) { + return ( + + ); +} diff --git a/src/components/layout/Section.tsx b/src/components/layout/Section.tsx new file mode 100644 index 000000000..6a20836c0 --- /dev/null +++ b/src/components/layout/Section.tsx @@ -0,0 +1,42 @@ +import clsx from "clsx"; +import styles from "./styles.module.css"; +import type { ReactNode } from "react"; + +type Props = { + bg?: "white" | "yellow" | "dark" | "light-blue" | "light-grey"; + spacing?: "normal" | "tight" | "loose"; + pageTop?: boolean; + fullHeight?: boolean; + background?: ReactNode; + children: ReactNode; + className?: string; +}; + +export default function Section({ + bg = "white", + spacing = "normal", + pageTop = false, + fullHeight = false, + background, + children, + className, +}: Props) { + return ( +
      + {background &&
      {background}
      } +
      +
      {children}
      +
      +
      + ); +} diff --git a/src/components/layout/SectionSeparator.tsx b/src/components/layout/SectionSeparator.tsx new file mode 100644 index 000000000..670d4ce56 --- /dev/null +++ b/src/components/layout/SectionSeparator.tsx @@ -0,0 +1,58 @@ +type Color = "dark" | "blue" | "red" | "white"; +type Segment = { w: number; c: Color }; + +const D = (w: number): Segment => ({ w, c: "dark" }); +const B = (w: number): Segment => ({ w, c: "blue" }); +const R = (w: number): Segment => ({ w, c: "red" }); +const W = (w: number): Segment => ({ w, c: "white" }); + +const VARIANTS: Record = { + // home: after hero | blog: after header + 1: [ D(21), B(7), D(22), B(7), D(15), B(8), D(14), B(6) ], + + // home: after "Who we work with" | careers: after header + 2: [ B(6), D(22), B(19), D(19), B(8), D(15), B(11) ], + + // home: after "How we work with you" | sponsor: after header + 3: [ D(26), B(17), D(24), B(15), D(11), B(7) ], + + // services: after header — no accent, dense rhythm + 4: [ D(8), B(5), D(12), B(8), D(13), B(8), D(10), B(9), D(13), B(7), D(7) ], + + // (unused) — pure blue/dark + 5: [ B(14), D(4), B(17), D(13), B(9), D(11), B(11), D(15), B(6) ], + + // home: before blog + 6: [ D(7), B(7), D(9), B(7), D(11), B(7), D(11), B(7), D(10), B(8), D(9), B(7) ], + + 7: [ D(5), B(6), D(7), B(7), D(9), B(7), D(10), B(6), D(8), B(7), D(9), B(6), D(7), B(6) ], + + 8: [ D(3), B(6), D(19), B(8), D(5), B(17), D(11), B(6), D(13), B(12) ], +}; + +const COLOR_MAP: Record = { + dark: "#1d1d1b", + blue: "var(--ifm-color-blue-jupyter)", + red: "var(--ifm-color-accent-red)", + white: "#ffffff", +}; + +type Variant = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; + +export default function SectionSeparator({ variant = 1 }: { variant?: Variant }) { + const segments = VARIANTS[variant]; + return ( +
      + {segments.map(({ w, c }, i) => ( +
      + ))} +
      + ); +} diff --git a/src/components/layout/SplitSection.tsx b/src/components/layout/SplitSection.tsx new file mode 100644 index 000000000..ba48beb3c --- /dev/null +++ b/src/components/layout/SplitSection.tsx @@ -0,0 +1,43 @@ +import clsx from "clsx"; +import styles from "./styles.module.css"; +import Section from "./Section"; +import type { ReactNode } from "react"; + +type Props = { + image: ReactNode; + reverse?: boolean; + ratio?: "60/40" | "50/50"; + bg?: "white" | "yellow" | "dark" | "light-blue" | "light-grey"; + spacing?: "normal" | "tight" | "loose"; + pageTop?: boolean; + fullHeight?: boolean; + background?: ReactNode; + children: ReactNode; +}; + +export default function SplitSection({ + image, + reverse = false, + ratio = "60/40", + bg = "white", + spacing = "normal", + pageTop = false, + fullHeight = false, + background, + children, +}: Props) { + return ( +
      +
      +
      {children}
      +
      {image}
      +
      +
      + ); +} diff --git a/src/components/layout/styles.module.css b/src/components/layout/styles.module.css new file mode 100644 index 000000000..7bbd7a99d --- /dev/null +++ b/src/components/layout/styles.module.css @@ -0,0 +1,286 @@ +/* ─── Section ─── */ + +.section { + width: 100%; + padding: var(--ifm-spacing-4xl) 0; + position: relative; +} + +.section_bg_slot { + position: absolute; + inset: 0; + overflow: hidden; + pointer-events: none; + z-index: 0; +} + +.section_content { + position: relative; + z-index: 2; +} + +.section_page_top { + margin-top: calc(-1 * var(--ifm-navbar-height)); + padding-top: calc(var(--ifm-spacing-3xl) + var(--ifm-navbar-height)); +} + +.section_white { + background: var(--ifm-bg-neutral); +} + +.section_yellow { + background: var(--ifm-bg-brand); +} + +.section_dark { + background: var(--ifm-bg-emphasis); + color: white; +} + +.section_light_blue { + background: var(--ifm-bg-light-blue); +} + +.section_light_grey { + background: var(--ifm-bg-light-grey); +} + +.section_tight { + padding: var(--ifm-spacing-2xl) 0; +} + +.section_loose { + padding: var(--ifm-spacing-5xl) 0; +} + +.section_full_height { + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + box-sizing: border-box; +} + +/* ─── SectionSeparator — rendered as pill divs in SectionSeparator.tsx ─── */ + +@media (max-width: 996px) { + .section { + padding: var(--ifm-spacing-3xl) 0; + } + + .section_page_top { + padding-top: calc(var(--ifm-spacing-2xl) + var(--ifm-navbar-height)); + } +} + +/* ─── SplitSection ─── */ + +.split { + display: flex; + align-items: center; + gap: var(--ifm-spacing-2xl); +} + +.split_reverse { + flex-direction: row-reverse; +} + +.split_text { + flex: 3; + min-width: 0; +} + +.split_image { + flex: 2; + display: flex; + align-items: center; + justify-content: center; + min-width: 0; +} + +.split_50 > .split_text { + flex: 1; +} + +.split_50 > .split_image { + flex: 1; +} + +@media (max-width: 996px) { + .split { + flex-direction: column; + align-items: stretch; + } + + .split_reverse { + flex-direction: column; + } + + .split_text, + .split_image { + width: 100%; + } +} + +/* ─── Card ─── */ + +.card { + background: var(--ifm-bg-neutral); + border-radius: 10px; + padding: var(--ifm-spacing-lg); + box-shadow: var(--ifm-shadow-card); + height: 100%; + box-sizing: border-box; + display: flex; + flex-direction: column; +} + +.card_yellow { + background: var(--ifm-bg-brand); +} + +.card_transparent { + background: transparent; + box-shadow: none; +} + +.card_hover { + cursor: pointer; + border: 1px solid transparent; + transition: box-shadow 0.2s, border-color 0.2s; +} + +.card_hover:hover { + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + border-color: var(--ifm-color-neutral-n3); +} + +@media (min-width: 996px) { + .card { + padding: var(--ifm-spacing-xl) var(--ifm-spacing-lg); + } +} + +/* ─── CardGrid ─── */ + +.card_grid { + display: grid; + gap: var(--ifm-spacing-xl); + grid-template-columns: repeat(3, 1fr); + list-style: none; + padding: 0; + margin: 0; +} + +.card_grid li { + margin-left: 0; +} + +.card_grid_2 { + grid-template-columns: repeat(2, 1fr); +} + +.card_grid_4 { + grid-template-columns: repeat(4, 1fr); +} + +@media (max-width: 996px) { + .card_grid { + grid-template-columns: repeat(2, 1fr); + } + + .card_grid_4 { + grid-template-columns: repeat(2, 1fr); + } + + .card_grid_2 { + grid-template-columns: 1fr; + } +} + +@media (max-width: 600px) { + .card_grid { + grid-template-columns: 1fr; + } + + .card_grid_4 { + grid-template-columns: 1fr; + } +} + +/* ─── Banner ─── */ + +.banner { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: var(--ifm-spacing-lg); + padding: var(--ifm-spacing-4xl) var(--ifm-spacing-4xl); + font-family: var(--ifm-font-family-roboto); + font-weight: 500; + line-height: 150%; +} + +.banner_dark { + background: var(--ifm-bg-emphasis); + color: white; + font-size: 28px; +} + +.banner_dark :global(.link-to-button) { + background: var(--ifm-color-accent-yellow); + color: var(--ifm-color-primary-p2); +} + +.banner_dark :global(.link-to-button):hover { + color: var(--ifm-color-primary-p2); + box-shadow: 0 8px 28px rgba(245, 229, 59, 0.5); +} + + +.banner_title { + font-style: normal; + font-weight: 600; + line-height: 150%; + letter-spacing: 2.112px; + margin-bottom: var(--ifm-spacing-md); +} + +.banner_title_dark { + font-size: 48px; + color: var(--ifm-color-primary-p1); +} + +.banner_title_light { + font-size: 32px; + color: var(--ifm-color-primary-p2); +} + +.banner_body { + max-width: 800px; +} + +.banner_full_height { + min-height: 100vh; + justify-content: center; +} + +@media (max-width: 996px) { + .banner { + padding: var(--ifm-spacing-2xl) var(--ifm-spacing-lg); + font-size: 16px; + line-height: 20px; + letter-spacing: 0.1px; + } + + .banner_title { + font-size: 32px; + letter-spacing: 2.112px; + } + + .banner_title_dark { + font-size: 32px; + } +} diff --git a/src/components/projects/AllProjects.tsx b/src/components/projects/AllProjects.tsx deleted file mode 100644 index 8ed3881c3..000000000 --- a/src/components/projects/AllProjects.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { projectsDetails } from "./descriptions/projectsDetails"; -import ProjectCard from "./ProjectCard"; -import styles from "./styles.module.css"; - -export default function AllProjects() { - return ( -
      -
        - {projectsDetails.map((project, index) => { - return ( -
      • -
        - -
        -
      • - ); - })} -
      -
      - ) -} diff --git a/src/components/projects/Header.tsx b/src/components/projects/Header.tsx deleted file mode 100644 index 0d9f7a57e..000000000 --- a/src/components/projects/Header.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import styles from "./styles.module.css"; -import HeaderMD from "./descriptions/Header.md"; - -export default function Header() { - return ( -
      -
      -
      -

      Working in the open

      -
      - -
      -
      -
      -
      - ); -} diff --git a/src/components/projects/ProjectCard.tsx b/src/components/projects/ProjectCard.tsx deleted file mode 100644 index f921b5890..000000000 --- a/src/components/projects/ProjectCard.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import styles from "./styles.module.css"; - -export default function ProjectCard({ project }): JSX.Element { - const prefix = "project_picture_"; - const base = `${prefix}${project.name}` - return ( -
      -
      -
      -
      {project.title}
      -
      - -
      -
      -
      -
      - {project.pictureAltText} -
      -
      -
      - ); -} diff --git a/src/components/projects/ScheduleAMeeting.tsx b/src/components/projects/ScheduleAMeeting.tsx deleted file mode 100644 index c83539b7b..000000000 --- a/src/components/projects/ScheduleAMeeting.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import styles from "./styles.module.css"; -import LinkToContact from "../home/LinkToContact"; - -export default function ScheduleAMeeting() { - return ( -
      - Schedule a meeting and benefit from our experience in Python, C++, - in-browser data visualization, and high-performance computing. - -
      - ); -} diff --git a/src/components/projects/descriptions/ApacheArrow.md b/src/components/projects/descriptions/ApacheArrow.md deleted file mode 100644 index 58e149a59..000000000 --- a/src/components/projects/descriptions/ApacheArrow.md +++ /dev/null @@ -1,3 +0,0 @@ -The QuantStack team comprises key maintainers of the Apache Arrow project. The Apache Arrow team at QuantStack provides commercial support and custom development services in the Apache Arrow ecosystem. - -Check out our recent [announcement](https://medium.com/@QuantStack/quantstack-steps-up-to-support-apache-arrow-with-new-dedicated-team-9ddc952f20e2) on the launch of the Apache Arrow team at QuantStack. diff --git a/src/components/projects/descriptions/CondaForge.md b/src/components/projects/descriptions/CondaForge.md deleted file mode 100644 index b8078ea05..000000000 --- a/src/components/projects/descriptions/CondaForge.md +++ /dev/null @@ -1,14 +0,0 @@ -QuantStack is one of the key organizations supporting the -conda-forge project, a community-led collection of recipes, build -infrastructure and distributions for the conda/mamba package -manager. - -Adopted at the global scale, conda-forge has become the reference -source of build artifacts for the scientific computing ecosystem, -accounting for over 150 million package downloads monthly. - -QuantStack developed key components of the conda-forge -infrastructure, including the mamba package manager and the -mamba-build utility, which underlie the build system of conda-forge. -QuantStack team members also maintain a large number of conda-forge -packages. diff --git a/src/components/projects/descriptions/Header.md b/src/components/projects/descriptions/Header.md deleted file mode 100644 index 1c87c9b4f..000000000 --- a/src/components/projects/descriptions/Header.md +++ /dev/null @@ -1,9 +0,0 @@ -Projects developed at QuantStack have reached millions of end users, -from healthcare to education, from aerospace to geosciences, and -from data sciences to robotics. - - -Open-source development is a unique -way to break down collaboration barriers and reach users with -unexpected use cases. Enabling customization and extensions of the -tools enables this diversity of applications. diff --git a/src/components/projects/descriptions/Jupyter.md b/src/components/projects/descriptions/Jupyter.md deleted file mode 100644 index 9b582d64c..000000000 --- a/src/components/projects/descriptions/Jupyter.md +++ /dev/null @@ -1,15 +0,0 @@ - QuantStack is one of the main organizations supporting the Jupyter - project, an open-source ecosystem of developer tools meant to - improve the workflows of scientists and engineers. - - In the past years, Jupyter has become a de-facto standard in both - industry and academia, at the foundation of the main open-source and - commercial data science platforms, with millions of users. - - The team comprises nine core contributors and maintainers of the - project. We are also behind popular extensions for data - visualization, robotics, and dashboarding. - - The QuantStack team is responsible for major evolutions in the - project, such as the JupyterLab visual debugger, collaborative - editing, or the development of JupyterLite. \ No newline at end of file diff --git a/src/components/projects/descriptions/Robotics.md b/src/components/projects/descriptions/Robotics.md deleted file mode 100644 index a79602055..000000000 --- a/src/components/projects/descriptions/Robotics.md +++ /dev/null @@ -1,7 +0,0 @@ - QuantStack supports the open-source robotics ecosystem. - - We created the RoboStack distribution of ROS, the first conda/mamba - based distribution of ROS, and the first cross-platform - distribution of ROS. We are behind the jupyter-robotics project, a - collection of JupyterLab and Jupyter extensions integrating ROS with - the Jupyter ecosystem. \ No newline at end of file diff --git a/src/components/projects/descriptions/XTensorXSIMD.md b/src/components/projects/descriptions/XTensorXSIMD.md deleted file mode 100644 index da7e05022..000000000 --- a/src/components/projects/descriptions/XTensorXSIMD.md +++ /dev/null @@ -1,16 +0,0 @@ - QuantStack kickstarted the development of the xtensor and xsimd - projects, popular C++ libraries meant for numerical analysis with - multi-dimensional array expressions, and accelerated computing. - - xtensor provides: - - - an extensible expression system enabling lazy broadcasting, - - - an API following the idioms of the C++ standard library, - - - tools to manipulate array expressions and build upon xtensor. - - The xsimd project provides a unified API for utilizing SIMD - instructions of modern microprocessors.XSimd has seen a growing - adoption in the past years, by projects such as Firefox, Krita, - Pythran, and Apache Arrow. \ No newline at end of file diff --git a/src/components/projects/descriptions/projectsDetails.ts b/src/components/projects/descriptions/projectsDetails.ts deleted file mode 100644 index 54417eadb..000000000 --- a/src/components/projects/descriptions/projectsDetails.ts +++ /dev/null @@ -1,64 +0,0 @@ -import jupyterLogoUrl from "@site/static/img/projects/Jupyter.png"; -import xtensorLogoUrl from "@site/static/img/projects/xtensor.png"; -import condaforgeLogoUrl from "@site/static/img/projects/conda_forge.png"; -import apachearrowLogoUrl from "@site/static/img/projects/apache_arrow.png"; -import robostackPictureUrl from "@site/static/img/projects/robostack.png"; -import JupyterMD from "./Jupyter.md"; -import CondaForgeMD from "./CondaForge.md"; -import XTensorXSIMDMD from "./XTensorXSIMD.md"; -import ApacheArrowMD from "./ApacheArrow.md"; -import RoboticsMD from "./Robotics.md"; - - -export const projectsDetails = [ - { - name: "jupyter", - title: "Jupyter", - pictureRoute: jupyterLogoUrl, - pictureWidth: "198px", - pictureHeight: "234px", - pictureAltText: "Picture for Jupyter project showing its logo.", - ProjectMD: JupyterMD, - reverse: "false" - }, - { - name: "xtensorxsimd", - title: "Xtensor & Xsimd", - pictureRoute: xtensorLogoUrl, - pictureWidth: "257px", - pictureHeight: "257px", - pictureAltText: "Picture for Xtensor and Xsimd showing their respective logo.", - ProjectMD: XTensorXSIMDMD, - reverse: "true", - }, - { - name: "condaforge", - title: "Conda-forge", - pictureRoute: condaforgeLogoUrl, - pictureWidth: "196px", - pictureHeight: "180px", - pictureAltText: "Picture for Condaforge project showing its forge logo.", - ProjectMD: CondaForgeMD, - reverse:"false" - }, - { - name: "apache_arrow", - title: "Apache Arrow and Parquet", - pictureRoute: apachearrowLogoUrl, - pictureWidth: "176px", - pictureHeight: "63px", - pictureAltText: "Picture for Apache Arrow project showing the logo made of arrows.", - ProjectMD: ApacheArrowMD, - reverse:"false" - }, - { - name: "robotics", - title: "Robotics", - pictureRoute: robostackPictureUrl, - pictureWidth: "189px", - pictureHeight: "210px", - pictureAltText: "Picture for robotics project showing an illustration with a robotics device.", - ProjectMD: RoboticsMD, - reverse:"true" - }, -]; diff --git a/src/components/projects/index.tsx b/src/components/projects/index.tsx deleted file mode 100644 index fc43e6173..000000000 --- a/src/components/projects/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import styles from "./styles.module.css"; -import Header from "./Header"; -import ScheduleAMeeting from "./ScheduleAMeeting"; -import AllProjects from "./AllProjects"; - -export default function Projects() { - return ( - <> -
      -
      - -
      - - - - ); -} diff --git a/src/components/projects/styles.module.css b/src/components/projects/styles.module.css deleted file mode 100644 index 362f0f78c..000000000 --- a/src/components/projects/styles.module.css +++ /dev/null @@ -1,147 +0,0 @@ - -.project_title { - margin-bottom: var(--ifm-spacing-md); - margin-top: var(--ifm-spacing-xl); - font-family: var(--ifm-font-family-bebas-neue); - font-size: var(--ifm-font-size-secondary-title); - font-style: normal; - font-weight: bolder; - line-height: 150%; - text-align: start; -} - -div .project_title { - color: var(--ifm-color-primary-p2); - padding-left: var(--ifm-spacing-xl); -} - -.project_description { - padding: var(--ifm-spacing-md) var(--ifm-spacing-xl); - text-align: justify; -} - -.project_description p { - color: var(--ifm-color-primary-p2); -} - -@media only screen and (max-width: 996px) { - /*Mobile*/ - .all_projects_container { - margin-bottom: var(--ifm-spacing-3xl); - - } - - .header_container { - padding-top: var(--ifm-spacing-2xl); - background-color: var(--ifm-color-primary-p1); - } - - .header_title { - padding-left: none; - } - - .header_text { - font-family: var(--ifm-font-family-roboto); - color: var(--ifm-color-primary-p2); - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 20px; - letter-spacing: 0.25px; - text-align: justify; - margin-bottom: var(--ifm-spacing-lg); - padding: var(--ifm-spacing-lg) var(--ifm-spacing-xl); - } - - .project_text { - background-color: white; - text-align: justify; - } - - .project_picture_jupyter { - border: none; - margin-bottom: var(--ifm-spacing-xl); - } - - .project_picture_xtensorxsimd { - border: none; - margin-bottom: var(--ifm-spacing-xl); - } - - .project_picture_condaforge { - border: none; - margin-bottom: var(--ifm-spacing-xl); - } - - .project_picture_apache_arrow { - border: none; - margin-bottom: var(--ifm-spacing-xl); - } - - .project_picture_robotics { - border: none; - margin-bottom: var(--ifm-spacing-xl); - } -} - -@media only screen and (min-width: 996px) { - /*Desktop*/ - - .all_projects_container { - margin: 0 0 var(--ifm-spacing-5xl) 0 ; - } - .header_container { - margin-top: var(--ifm-spacing-6xl); - } - .header_title { - padding-left: var(--ifm-spacing-4xl); - } - - .header_text { - font-family: var(--ifm-font-family-roboto); - color: var(--ifm-color-primary-p2); - font-size: 22px; - font-style: normal; - font-weight: 400; - line-height: 28px; - margin-bottom: var(--ifm-spacing-3xl); - padding: var(--ifm-spacing-lg) var(--ifm-spacing-4xl); - } - - .project_text { - background-color: var(--ifm-color-orange-light); - padding: var(--ifm-spacing-4xl) var(--ifm-spacing-3xl); - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } - - .project_picture_jupyter { - border: solid 1px var(--ifm-color-orange-jupyter); - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } - - .project_picture_xtensorxsimd { - border: solid 1px var(--ifm-color-green-xtensor); - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } - - .project_picture_condaforge { - border: solid 1px var(--ifm-color-grey-condaforge); - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } - - .project_picture_apache_arrow { - border: solid 1px black; - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } - - .project_picture_robotics { - border: solid 1px rgb(146, 95, 218); - margin-bottom: var(--ifm-spacing-lg); - border-radius: 10px; - } -} diff --git a/src/components/services/Header.tsx b/src/components/services/Header.tsx deleted file mode 100644 index 0bc1d7aba..000000000 --- a/src/components/services/Header.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import styles from "./styles.module.css"; - -export default function Header() { - return ( -
      -
      -
      -
      -

      - Hire QuantStack to build upon the Jupyter, Mamba, and the PyData - ecosystem. -

      -
      -
      -
      -
      - ); -} diff --git a/src/components/services/SpecialProjects.tsx b/src/components/services/SpecialProjects.tsx deleted file mode 100644 index 13f298f51..000000000 --- a/src/components/services/SpecialProjects.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import SpecialProjectsMD from "./descriptions/SpecialProjects.md"; -import SpecialProjectsIllustration from "@site/static/img/illustrations/special_projects.svg"; - -export default function SpecialProjects() { - return ( - <> -
      -
      -
      -
      -

      Special projects

      - -
      -
      - -
      -
      -
      -
      -
      - - ); -} diff --git a/src/components/services/Support.tsx b/src/components/services/Support.tsx deleted file mode 100644 index 82a9a2d73..000000000 --- a/src/components/services/Support.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import SupportMD from "./descriptions/Support.md"; -import SupportIllustration from "/img/illustrations/support.svg"; - -export default function Support() { - return ( -
      -
      -
      -
      -
      - -
      -
      -
      -

      Professional Support

      - -
      -
      -
      -
      - ); -} \ No newline at end of file diff --git a/src/components/services/descriptions/SpecialProjects.md b/src/components/services/descriptions/SpecialProjects.md deleted file mode 100644 index 97745a196..000000000 --- a/src/components/services/descriptions/SpecialProjects.md +++ /dev/null @@ -1,9 +0,0 @@ - We develop new packages from the ground up. Such special projects built upon our open-source stack include: - -- JupyterCAD, -- JupyterLab-ROS, -- Glue Web, -- ipygany -and many more. - -You can contract with us to leverage the Jupyter, conda and the general PyData ecosystem in an optimal way. \ No newline at end of file diff --git a/src/components/services/descriptions/Support.md b/src/components/services/descriptions/Support.md deleted file mode 100644 index 473374bcd..000000000 --- a/src/components/services/descriptions/Support.md +++ /dev/null @@ -1,5 +0,0 @@ -We support organizations that depend on Jupyter, conda-forge, or the broader PyData ecosytem. - -We help deploy, extend, or customize software of the open-source scientific computing ecosystem. - -Work with the people behind the technology, and develop your strategy around the open-source stack. \ No newline at end of file diff --git a/src/components/services/index.tsx b/src/components/services/index.tsx deleted file mode 100644 index 911b924d0..000000000 --- a/src/components/services/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import styles from "./styles.module.css"; -import Support from "./Support"; -import SpecialProjects from "./SpecialProjects"; -import Header from "./Header"; -import LinkToContact from "../home/LinkToContact"; - -export default function Services() { - return ( -
      -
      - - -
      -
      - Sign a support retainer for QuantStack services in our ecosystem. -
      - -
      -
      - ); -} diff --git a/src/components/services/styles.module.css b/src/components/services/styles.module.css deleted file mode 100644 index f8b585dfc..000000000 --- a/src/components/services/styles.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.h2_custom { - color: var(--ifm-color-indigo-i1); -} - -ul { - padding-left: 20px; -} \ No newline at end of file diff --git a/src/css/custom.css b/src/css/custom.css index 803abaaa8..fa4e8d81f 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,14 +1,15 @@ -@import url("https://fonts.googleapis.com/css2?family=Roboto"); -@import url("https://fonts.cdnfonts.com/css/bebas-neue"); -@import url("https://fonts.cdnfonts.com/css/rubik-one"); -@import url("https://fonts.cdnfonts.com/css/roboto-flex"); -@import url("https://fonts.googleapis.com/css2?family=Dosis"); -@import url('https://fonts.googleapis.com/css2?family=Kode+Mono:wght@400;500;600;700&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700;800;900&display=swap"); +@import url("https://fonts.cdnfonts.com/css/bebas-neue?display=swap"); :root { + /* ── Page background scene ── */ + --bg-scene-color: #1d1d1b; + --bg-planet-op: 0.07; + --bg-graph-op: 0.11; + --bg-snippet-op: 0.09; + --ifm-color-orange-jupyter: #f37726; - --ifm-color-blue-jupyter: #1976d2; + --ifm-color-blue-jupyter: #0052cc; --ifm-color-green-xtensor: #4ecb71; --ifm-color-grey-condaforge: #7a7865; --ifm-color-orange-light: #fef9ec; @@ -19,18 +20,34 @@ --ifm-text-color-on-primary-p1: #1e1c00; --ifm-color-secondary-s1: #a0c9ff; - --ifm-color-secondary-s2: #002646; + --ifm-color-secondary-s2: #0A0E2E; --ifm-color-secondary-s3: #00497F; --ifm-color-neutral-n1: #605e58; --ifm-color-neutral-n2: #371300; + --ifm-color-neutral-n3: #c8c8c7; + + --ifm-color-accent-yellow: #F5E53B; + --ifm-color-accent-red: #E8462A; + + --ifm-shadow-card: 0px 2px 12px rgba(160, 140, 40, 0.15); + --ifm-shadow-dialog: 0 8px 16px rgba(0, 0, 0, 0.2); + --ifm-overlay-background: rgba(0, 0, 0, 0.3); --ifm-text-color: var(--ifm-color-primary-p2); - --ifm-background-color: white; + --ifm-background-color: var(--ifm-bg-neutral); + + /* Semantic background roles */ + --ifm-bg-neutral: #ffffff; /* default reading surface */ + --ifm-bg-brand: #ffffff; /* yellow dropped — white throughout */ + --ifm-bg-emphasis: var(--ifm-color-secondary-s2); /* CTA / strong contrast — navy */ + --ifm-bg-light-blue: #edf2fb; /* subtle blue tint — section alternation */ + --ifm-bg-light-grey: #f5f5f3; /* neutral grey — section alternation */ + /* footer */ - --ifm-background-color-footer: var(--ifm-color-primary-p1); + --ifm-background-color-footer: #f5f5f3; --ifm-text-color-footer: black; /*popup overlay*/ @@ -45,12 +62,7 @@ /*Font families */ --ifm-font-family-roboto: "Roboto"; - --ifm-font-family-roboto-flex: "Roboto Flex"; - --ifm-font-family-bebas-neue: "Bebas Neue"; - --ifm-font-family-rubik-one: "Rubik One"; - --ifm-font-family-dosis: "Dosis"; - --ifm-font-family-kode-mono: "Kode Mono"; - --ifm-font-family-inter: "Inter"; + --ifm-font-family-display: "Bebas Neue"; /* Spacing for margins and paddings */ --ifm-spacing-none: 0px; @@ -69,6 +81,8 @@ --ifm-spacing-8xl: 400px; --ifm-navbar-item-padding-horizontal: 2px; + + --ifm-content-width: 1200px; } .flex-full-centered { @@ -94,10 +108,6 @@ padding: 0; } -.row-reverse { - flex-direction: column-reverse; -} - ul { padding-left: 0; margin-left: 0; @@ -108,12 +118,6 @@ ul { padding: 0; } -.row-max-width { - max-width: 1500px; - display: flex; -} - - /***footer*****/ .footer__item { color: var(--ifm-text-color-footer); @@ -162,13 +166,6 @@ ul { color: var(--ifm-text-color-footer); } -.footer-astronaut { - display: flex; - width: 35px; - height: 35px; - padding: 10px; -} - @media (min-width: 1440px) { .container { max-width: none; @@ -177,50 +174,25 @@ ul { /****** Class that are specific for smaller screens*/ @media (max-width: 996px) { - .main-container-with-margins { - margin-left: 42px; - margin-right: 42px; - } - - .upper-container-with-margin-top { - margin-top: var(--ifm-spacing-2xl); - } - - .row-with-margin-top { - margin-top: var(--ifm-spacing-xl); - } - - .row-with-margin-bottom { - margin-bottom: var(--ifm-spacing-xl); - } - - .row-with-margins { - margin: var(--ifm-spacing-xl) 0; - } - - .col { - padding: 0; - } - h1 { color: var(--ifm-text-color-main-title); - font-family: var(--ifm-font-family-bebas-neue); - font-size: 32px; + font-family: var(--ifm-font-family-display); + font-size: 44px; font-style: normal; - font-weight: 600; - line-height: 150%; - /* 36px */ - letter-spacing: 1.056px; + font-weight: 900; + line-height: 110%; + letter-spacing: 0; text-align: center; padding: 0; } h2 { - font-family: var(--ifm-font-family-bebas-neue); - font-size: 24px; + font-family: var(--ifm-font-family-display); + font-size: 36px; font-style: normal; - font-weight: bolder; - line-height: 150%; + font-weight: 800; + line-height: 115%; + letter-spacing: 0; text-align: center; } @@ -239,101 +211,50 @@ ul { margin-left: 24px; } - .blue-banner-container { - font-family: var(--ifm-font-family-roboto); - font-size: 16px; - font-weight: 500; - color: var(--ifm-color-secondary-s2); - padding: var(--ifm-spacing-2xl) var(--ifm-spacing-lg) 0 var(--ifm-spacing-lg); - background-color: var(--ifm-color-secondary-s1); - line-height: 20px; - letter-spacing: 0.1px; - text-align: center; - } - - .blue-banner-header { - text-align: center; - font-family: var(--ifm-font-family-bebas-neue); - font-size: 32px; - font-style: normal; - font-weight: 600; - line-height: 150%; - letter-spacing: 2.112px; - background-color: var(--ifm-color-secondary-s1); - color: var(--ifm-color-secondary-s2); - } - .link-to-button { - width: 258px; - height: 56px; - font-family: var(--ifm-font-family-roboto); - border-radius: 35px; - background: var(--ifm-color-secondary-s2); - color: white; - font-size: 16px; - font-style: normal; - font-weight: 600; - line-height: 150%; - letter-spacing: -0.176px; - padding: 16px 36px; - border: none; - text-align: center; margin-top: var(--ifm-spacing-lg); margin-bottom: var(--ifm-spacing-lg); } - - .link-box { - height: 59px; - width: auto; - display: flex; - align-items: center; - justify-content: center; - } } -/****** Class that are specific to larger screens*/ -@media (min-width: 996px) { - .main-container-with-margins { - margin-left: 96px; - margin-right: 96px; - display: flex; - justify-content: center; - } - - .upper-container-with-margin-top { - margin-top: var(--ifm-spacing-6xl); +/* Tablet range: overrides phone sizes for wider mobile viewports. */ +@media (max-width: 996px) and (min-width: 600px) { + body h1 { + font-size: 56px; } - .row-with-margin-top { - margin-top: var(--ifm-spacing-2xl); + body h2 { + font-size: 42px; } - .row-with-margin-bottom { - margin-bottom: var(--ifm-spacing-2xl); - } - - .row-with-margins { - margin: var(--ifm-spacing-2xl) 0; + body p { + font-size: 16px; + line-height: 24px; } +} +/****** Class that are specific to larger screens*/ +@media (min-width: 996px) { h1 { color: var(--ifm-color-primary-p2); - font-family: var(--ifm-font-family-bebas-neue); - font-size: var(--ifm-font-size-main-title); + font-family: var(--ifm-font-family-display); + font-size: 64px; font-style: normal; - font-weight: 800; - line-height: 150%; - letter-spacing: 2.112px; + font-weight: 900; + line-height: 110%; + letter-spacing: 0; text-align: start; - padding: 8px 36px 8px 20px; + padding: 0; + margin: var(--ifm-spacing-md) 0; } h2 { - font-family: var(--ifm-font-family-bebas-neue); - font-size: var(--ifm-font-size-secondary-title); + font-family: var(--ifm-font-family-display); + font-size: 40px; font-style: normal; - font-weight: bolder; - line-height: 150%; + font-weight: 800; + line-height: 115%; + letter-spacing: 0; text-align: start; } @@ -342,155 +263,98 @@ ul { font-size: var(--ifm-font-size-normal); font-style: normal; letter-spacing: 0.25px; - text-align: justify; - } - - .blue-banner-container { - text-align: center; - font-family: var(--ifm-font-family-roboto); - font-size: 28px; - font-style: normal; - font-weight: 500; - line-height: 150%; - background-color: var(--ifm-color-secondary-s1); - color: var(--ifm-color-secondary-s2); - padding: var(--ifm-spacing-2xl) var(--ifm-spacing-4xl) 0 var(--ifm-spacing-4xl); - } - - .blue-banner-header { - text-align: center; - font-family: var(--ifm-font-family-bebas-neue); - font-size: 48px; - font-style: normal; - font-weight: 600; - line-height: 150%; - letter-spacing: 2.112px; - background-color: var(--ifm-color-secondary-s1); - color: var(--ifm-color-secondary-s2); - margin-bottom: var(--ifm-spacing-2xl); + text-align: left; } .link-to-button { - width: 258px; - height: 56px; - font-family: var(--ifm-font-family-roboto); - border-radius: 35px; - background: var(--ifm-color-secondary-s2); - color: white; - font-size: 16px; - font-style: normal; - font-weight: 600; - line-height: 150%; - letter-spacing: -0.176px; - padding: 16px 36px; - border: none; - text-align: center; margin-top: var(--ifm-spacing-2xl); margin-bottom: var(--ifm-spacing-2xl); } - - .link-box { - height: 59px; - width: auto; - display: flex; - align-items: center; - justify-content: center; - } } /***********************************************************/ -.social-media-links { - margin-left: var(--ifm-spacing-3xl); - text-align: start; -} - -.spacing-none { - height: var(--ifm-spacing-none); -} - -.spacing-2xs { - height: var(--ifm-spacing-2xs); -} - -.spacing-xs { - height: var(--ifm-spacing-xs); -} - -.spacing-sm { - height: var(--ifm-spacing-sm); -} - -.spacing-md { - height: var(--ifm-spacing-md); -} - -.spacing-lg { - height: var(--ifm-spacing-lg); +/* Headings inside dark sections need explicit white */ +[class*="section_dark"] h1, +[class*="section_dark"] h2, +[class*="section_dark"] h3 { + color: white; } -.spacing-xl { - height: var(--ifm-spacing-xl); +/* Single-word red accent inside headings for energy */ +.highlight { + color: var(--ifm-color-accent-red); } -.spacing-2xl { - height: var(--ifm-spacing-2xl); +/* Punchy blue tagline used in page header sections */ +.page-tagline { + color: var(--ifm-color-blue-jupyter); + font-weight: 700; + padding: 0; } -.spacing-3xl { - height: var(--ifm-spacing-3xl); +/* BD-style red accent bar below section headings */ +.page-content h2::after { + content: ''; + display: block; + width: 36px; + height: 3px; + background: var(--ifm-color-accent-red); + margin-top: 10px; + clip-path: polygon(3px 0%, 100% 0%, calc(100% - 3px) 100%, 0% 100%); } -.spacing-4xl { - height: var(--ifm-spacing-4xl); +.page-content h2.text--center::after { + margin-left: auto; + margin-right: auto; } -.spacing-5xl { - height: var(--ifm-spacing-5xl); +@media (max-width: 996px) { + .page-content h2::after { + margin-left: auto; + margin-right: auto; + } } -.spacing-6xl { - height: var(--ifm-spacing-6xl); +/* No red bar on dark-background sections */ +[class*="section_dark"] .page-content h2::after { + display: none; } -.spacing-7xl { - height: var(--ifm-spacing-7xl); -} -.spacing-8xl { - height: var(--ifm-spacing-8xl); -} +/***********************************************************/ .link-to-button { - width: 258px; - height: 56px; + display: inline-flex; + align-items: center; + justify-content: center; + width: auto; font-family: var(--ifm-font-family-roboto); border-radius: 35px; background: var(--ifm-color-secondary-s2); color: white; - font-size: 16px; + font-size: 15px; font-style: normal; - font-weight: 600; - line-height: 150%; - letter-spacing: -0.176px; - padding: 16px 36px; + font-weight: 700; + letter-spacing: 0.5px; + padding: 14px 36px; border: none; text-align: center; - margin-top: var(--ifm-spacing-2xl); - margin-bottom: var(--ifm-spacing-2xl); + cursor: pointer; + transition: transform 0.15s ease, box-shadow 0.15s ease; + text-decoration: none; } -.link-box { - height: 59px; - width: auto; - display: flex; - align-items: center; - justify-content: center; +.link-to-button:hover { + color: white; + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(10, 14, 46, 0.35); + text-decoration: none; } -.social-media-links { - margin-left: var(--ifm-spacing-3xl); - text-align: start; +.link-to-button:active { + transform: translateY(0); + box-shadow: none; } /* @@ -548,7 +412,7 @@ so they are already assumed to be clickable anyway */ .pagination-nav__link:active, a.card:active, a.menu__link:active { - background: white; + background: var(--ifm-bg-neutral); color: #000; } @@ -568,43 +432,157 @@ a.menu__link:active { transform: scale(1); } -.contact { + + +/* Scroll-adaptive navbar */ +.navbar { + transition: background-color 0.25s ease, box-shadow 0.25s ease; + background-color: var(--ifm-navbar-background-color); +} + +html[data-bg-dark] { + --bg-scene-color: #ffffff; + --bg-planet-op: 0.10; + --bg-graph-op: 0.15; + --bg-snippet-op: 0.13; +} + +html:not([data-navbar-scrolled]) .navbar { + background-color: transparent !important; + box-shadow: none !important; +} + +html[data-navbar-scrolled] .navbar { + background-color: var(--ifm-bg-neutral) !important; + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08) !important; +} + +/* Home page at top: dark links over white hero */ +html[data-navbar-home-top] .navbar__link, +html[data-navbar-home-top] .custom_navbar_item { + color: var(--ifm-color-primary-p2); +} + +html[data-navbar-home-top] .custom_navbar_item:hover { background-color: var(--ifm-color-primary-p1); - color: var(--ifm-color-text-on-primary-p1); - font-size: 14px; - border-radius: 4px; - font-weight: bolder; - font-style: normal; - margin: var(--ifm-navbar-item-padding-vertical) 4px; - padding: 8px; + color: var(--ifm-color-primary-p2); } -.contact:hover { - background-color: white; +html[data-navbar-home-top] .navbar__link:hover { + color: var(--ifm-color-primary-p2); } -.fundable_projects { - background-color: var(--ifm-color-secondary-s1); - font-size: 14px; - color: black; - border-radius: 4px; - font-weight: bolder; - font-style: normal; - margin: var(--ifm-navbar-item-padding-vertical) 4px; - padding: 8px; +/* Dark-hero pages (e.g. /notebooklink/): white links over dark section */ +html[data-navbar-dark-top] .navbar__link, +html[data-navbar-dark-top] .custom_navbar_item { + color: white; +} + +html[data-navbar-dark-top] .custom_navbar_item:hover { + background-color: var(--ifm-color-primary-p1); + color: var(--ifm-color-primary-p2); +} + +html[data-navbar-dark-top] .navbar__link:hover { + color: var(--ifm-color-primary-p1); +} + +html[data-navbar-dark-top] .github-icon, +html[data-navbar-dark-top] .linkedin-icon, +html[data-navbar-dark-top] .bluesky-icon, +html[data-navbar-dark-top] .mastodon-icon, +html[data-navbar-dark-top] .rss-circle-icon { + filter: invert(1); +} + +html[data-navbar-dark-top] .navbar__toggle { + color: white; +} + +/* Sidebar opens over a light background — reset dark-top overrides */ +html[data-navbar-dark-top] .navbar-sidebar a { + color: var(--ifm-color-primary-p2) !important; +} + +html[data-navbar-dark-top] .navbar-sidebar a:hover { + color: black !important; +} + +html[data-navbar-dark-top] .navbar-sidebar .navbar__logo img { + filter: invert(1); +} + +html[data-navbar-dark-top] .navbar-sidebar .github-icon, +html[data-navbar-dark-top] .navbar-sidebar .linkedin-icon, +html[data-navbar-dark-top] .navbar-sidebar .bluesky-icon, +html[data-navbar-dark-top] .navbar-sidebar .mastodon-icon, +html[data-navbar-dark-top] .navbar-sidebar .rss-circle-icon { + filter: none; +} + +.navbar__inner { + position: relative; +} + +.navbar__inner .navbar__brand { + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); +} + +.theme-layout-navbar-left { + flex: 1; + justify-content: center; } -.fundable_projects:hover { - background-color: var(--ifm-color-primary-p0); +@media (max-width: 996px) { + .theme-layout-navbar-left { + justify-content: flex-end; + } } +.theme-layout-navbar-right { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); +} + +/* At 997–1300px: switch to left-aligned to avoid overlap */ +@media (max-width: 1300px) and (min-width: 997px) { + .navbar__inner .navbar__brand { + position: static; + transform: none; + } + + .theme-layout-navbar-left { + justify-content: flex-start; + } + + .theme-layout-navbar-right { + position: static; + transform: none; + } + + .navbar_hide_mid { + display: none; + } +} + +/* Tighten item padding at narrower intermediate widths */ +@media (max-width: 1150px) and (min-width: 997px) { + .custom_navbar_item { + padding: 6px 8px; + } +} .custom_navbar_item { font-family: var(--ifm-font-family-roboto); - width: 117px; height: 36px; padding: 6px 14px; text-align: center; + white-space: nowrap; } .custom_navbar_item:hover { @@ -613,17 +591,39 @@ a.menu__link:active { border-radius: 4px; } -.navbar__link:hover { - color: black; +.navbar_notebooklink { + font-family: var(--ifm-font-family-roboto); + font-size: 14px; + font-weight: 700; + letter-spacing: 0.3px; + padding: 6px 14px; + border: 2px solid var(--ifm-color-accent-red); + border-radius: 4px; + color: var(--ifm-color-accent-red) !important; + white-space: nowrap; + transition: background-color 0.15s ease, color 0.15s ease; + margin-right: var(--ifm-spacing-sm); } -.astronaut-footer { - background: url(@site/static/img/quantstack/astronaut-footer.svg); - content: ""; - display: flex; - height: 240px; - width: 240px; - background-repeat: no-repeat; +.navbar_notebooklink:hover { + background-color: var(--ifm-color-accent-red) !important; + color: white !important; + text-decoration: none; +} + +html[data-navbar-dark-top] .navbar_notebooklink { + border-color: var(--ifm-color-accent-yellow); + color: var(--ifm-color-accent-yellow) !important; +} + +html[data-navbar-dark-top] .navbar_notebooklink:hover { + background-color: var(--ifm-color-accent-yellow) !important; + color: var(--ifm-color-primary-p2) !important; +} + +html[data-navbar-scrolled] .navbar__link:hover, +html:not([data-navbar-home-top]) .navbar__link:hover { + color: black; } .rss-circle-icon:hover { @@ -701,38 +701,17 @@ a.menu__link:active { border: 0px solid; } -.cards-list { - list-style-type: none; - padding: 0; - margin: 0; -} - -ul.row { - margin: 0; - padding: 0; -} - -.projects-list { - list-style-type: none; - padding: none; - margin-left: 0; +.page-content { + max-width: var(--ifm-content-width); width: 100%; + margin: 0 auto; + padding-left: var(--ifm-spacing-2xl); + padding-right: var(--ifm-spacing-2xl); } -.row { - display: flex; - flex-wrap: wrap; - margin: 0 0; -} - -.items-list { - list-style-type: none; -} - -.custom-progress-bar::-webkit-progress-value { - background-color: var(--ifm-color-primary-p1); -} - -.custom-progress-bar::-webkit-progress-bar { - background-color: #eee; +@media (max-width: 996px) { + .page-content { + padding-left: var(--ifm-spacing-lg); + padding-right: var(--ifm-spacing-lg); + } } diff --git a/src/components/about/Team/Alexis.md b/src/pages/about/Team/Alexis.md similarity index 100% rename from src/components/about/Team/Alexis.md rename to src/pages/about/Team/Alexis.md diff --git a/src/components/about/Team/Anastasiia.md b/src/pages/about/Team/Anastasiia.md similarity index 100% rename from src/components/about/Team/Anastasiia.md rename to src/pages/about/Team/Anastasiia.md diff --git a/src/components/about/Team/Andreas.md b/src/pages/about/Team/Andreas.md similarity index 100% rename from src/components/about/Team/Andreas.md rename to src/pages/about/Team/Andreas.md diff --git a/src/components/about/Team/Antoine.md b/src/pages/about/Team/Antoine.md similarity index 100% rename from src/components/about/Team/Antoine.md rename to src/pages/about/Team/Antoine.md diff --git a/src/components/about/Team/AntoinePrv.md b/src/pages/about/Team/AntoinePrv.md similarity index 100% rename from src/components/about/Team/AntoinePrv.md rename to src/pages/about/Team/AntoinePrv.md diff --git a/src/components/about/Team/Anutosh.md b/src/pages/about/Team/Anutosh.md similarity index 100% rename from src/components/about/Team/Anutosh.md rename to src/pages/about/Team/Anutosh.md diff --git a/src/components/about/Team/Arjun.md b/src/pages/about/Team/Arjun.md similarity index 100% rename from src/components/about/Team/Arjun.md rename to src/pages/about/Team/Arjun.md diff --git a/src/components/about/Team/Darian.md b/src/pages/about/Team/Darian.md similarity index 100% rename from src/components/about/Team/Darian.md rename to src/pages/about/Team/Darian.md diff --git a/src/components/about/Team/David.md b/src/pages/about/Team/David.md similarity index 100% rename from src/components/about/Team/David.md rename to src/pages/about/Team/David.md diff --git a/src/components/about/Team/Denisa.md b/src/pages/about/Team/Denisa.md similarity index 100% rename from src/components/about/Team/Denisa.md rename to src/pages/about/Team/Denisa.md diff --git a/src/components/about/Team/Fanny.md b/src/pages/about/Team/Fanny.md similarity index 100% rename from src/components/about/Team/Fanny.md rename to src/pages/about/Team/Fanny.md diff --git a/src/components/about/Team/Florence.md b/src/pages/about/Team/Florence.md similarity index 100% rename from src/components/about/Team/Florence.md rename to src/pages/about/Team/Florence.md diff --git a/src/components/about/Team/Gabriela.md b/src/pages/about/Team/Gabriela.md similarity index 100% rename from src/components/about/Team/Gabriela.md rename to src/pages/about/Team/Gabriela.md diff --git a/src/components/about/Team/Greg.md b/src/pages/about/Team/Greg.md similarity index 100% rename from src/components/about/Team/Greg.md rename to src/pages/about/Team/Greg.md diff --git a/src/components/about/Team/Hind.md b/src/pages/about/Team/Hind.md similarity index 100% rename from src/components/about/Team/Hind.md rename to src/pages/about/Team/Hind.md diff --git a/src/components/about/Team/Ian.md b/src/pages/about/Team/Ian.md similarity index 100% rename from src/components/about/Team/Ian.md rename to src/pages/about/Team/Ian.md diff --git a/src/components/about/Team/Isabel.md b/src/pages/about/Team/Isabel.md similarity index 100% rename from src/components/about/Team/Isabel.md rename to src/pages/about/Team/Isabel.md diff --git a/src/components/about/Team/Jeremy.md b/src/pages/about/Team/Jeremy.md similarity index 100% rename from src/components/about/Team/Jeremy.md rename to src/pages/about/Team/Jeremy.md diff --git a/src/components/about/Team/Joel.md b/src/pages/about/Team/Joel.md similarity index 100% rename from src/components/about/Team/Joel.md rename to src/pages/about/Team/Joel.md diff --git a/src/components/about/Team/Johan.md b/src/pages/about/Team/Johan.md similarity index 100% rename from src/components/about/Team/Johan.md rename to src/pages/about/Team/Johan.md diff --git a/src/components/about/Team/Julien.md b/src/pages/about/Team/Julien.md similarity index 100% rename from src/components/about/Team/Julien.md rename to src/pages/about/Team/Julien.md diff --git a/src/components/about/Team/Marion.md b/src/pages/about/Team/Marion.md similarity index 100% rename from src/components/about/Team/Marion.md rename to src/pages/about/Team/Marion.md diff --git a/src/components/about/Team/Martin.md b/src/pages/about/Team/Martin.md similarity index 100% rename from src/components/about/Team/Martin.md rename to src/pages/about/Team/Martin.md diff --git a/src/components/about/Team/Matthias.md b/src/pages/about/Team/Matthias.md similarity index 100% rename from src/components/about/Team/Matthias.md rename to src/pages/about/Team/Matthias.md diff --git a/src/components/about/Team/Meriem.md b/src/pages/about/Team/Meriem.md similarity index 100% rename from src/components/about/Team/Meriem.md rename to src/pages/about/Team/Meriem.md diff --git a/src/components/about/Team/Nicolas.md b/src/pages/about/Team/Nicolas.md similarity index 100% rename from src/components/about/Team/Nicolas.md rename to src/pages/about/Team/Nicolas.md diff --git a/src/components/about/Team/Olivier.md b/src/pages/about/Team/Olivier.md similarity index 100% rename from src/components/about/Team/Olivier.md rename to src/pages/about/Team/Olivier.md diff --git a/src/components/about/Team/Raul.md b/src/pages/about/Team/Raul.md similarity index 100% rename from src/components/about/Team/Raul.md rename to src/pages/about/Team/Raul.md diff --git a/src/components/about/Team/Romain.md b/src/pages/about/Team/Romain.md similarity index 100% rename from src/components/about/Team/Romain.md rename to src/pages/about/Team/Romain.md diff --git a/src/components/about/Team/Sandrine.md b/src/pages/about/Team/Sandrine.md similarity index 100% rename from src/components/about/Team/Sandrine.md rename to src/pages/about/Team/Sandrine.md diff --git a/src/components/about/Team/Serge.md b/src/pages/about/Team/Serge.md similarity index 100% rename from src/components/about/Team/Serge.md rename to src/pages/about/Team/Serge.md diff --git a/src/components/about/Team/Sylvain.md b/src/pages/about/Team/Sylvain.md similarity index 100% rename from src/components/about/Team/Sylvain.md rename to src/pages/about/Team/Sylvain.md diff --git a/src/components/about/Team/Thorsten.md b/src/pages/about/Team/Thorsten.md similarity index 100% rename from src/components/about/Team/Thorsten.md rename to src/pages/about/Team/Thorsten.md diff --git a/src/components/about/Team/Trung.md b/src/pages/about/Team/Trung.md similarity index 100% rename from src/components/about/Team/Trung.md rename to src/pages/about/Team/Trung.md diff --git a/src/components/about/Team/Yahia.md b/src/pages/about/Team/Yahia.md similarity index 100% rename from src/components/about/Team/Yahia.md rename to src/pages/about/Team/Yahia.md diff --git a/src/components/about/Team/team.ts b/src/pages/about/Team/_team.ts similarity index 89% rename from src/components/about/Team/team.ts rename to src/pages/about/Team/_team.ts index 692ca21a9..df6ce3b7b 100644 --- a/src/components/about/Team/team.ts +++ b/src/pages/about/Team/_team.ts @@ -1,70 +1,70 @@ -import AlexisMD from "@site/src/components/about/Team/Alexis.md"; +import AlexisMD from "@site/src/pages/about/Team/Alexis.md"; import AlexisAvatarUrl from "@site/static/img/avatars/Alexis.png"; -import AnastasiiaMD from "@site/src/components/about/Team/Anastasiia.md"; +import AnastasiiaMD from "@site/src/pages/about/Team/Anastasiia.md"; import AnastasiiaAvatarUrl from "@site/static/img/avatars/Anastasiia.png"; -import AndreasMD from "@site/src/components/about/Team/Andreas.md"; +import AndreasMD from "@site/src/pages/about/Team/Andreas.md"; import AndreasAvatarUrl from "@site/static/img/avatars/Andreas.png"; -import AntoineMD from "@site/src/components/about/Team/Antoine.md"; +import AntoineMD from "@site/src/pages/about/Team/Antoine.md"; import AntoineAvatarUrl from "@site/static/img/avatars/Antoine2.png"; -import AntoinePrvMD from "@site/src/components/about/Team/AntoinePrv.md"; +import AntoinePrvMD from "@site/src/pages/about/Team/AntoinePrv.md"; import AntoinePrvAvatarUrl from "@site/static/img/avatars/AntoinePrv.png"; -import AnutoshMD from "@site/src/components/about/Team/Anutosh.md"; +import AnutoshMD from "@site/src/pages/about/Team/Anutosh.md"; import AnutoshAvatarUrl from "@site/static/img/avatars/Anutosh.png"; -import ArjunMD from "@site/src/components/about/Team/Arjun.md"; +import ArjunMD from "@site/src/pages/about/Team/Arjun.md"; import ArjunAvatarUrl from "@site/static/img/avatars/Arjun.png"; -import DavidMD from "@site/src/components/about/Team/David.md"; +import DavidMD from "@site/src/pages/about/Team/David.md"; import DavidAvatarUrl from "@site/static/img/avatars/David.png"; -import DarianMD from "@site/src/components/about/Team/Darian.md"; +import DarianMD from "@site/src/pages/about/Team/Darian.md"; import DarianAvatarUrl from "@site/static/img/avatars/Darian.png"; -import DenisaMD from "@site/src/components/about/Team/Denisa.md"; +import DenisaMD from "@site/src/pages/about/Team/Denisa.md"; import DenisaAvatarUrl from "@site/static/img/avatars/Denisa.png"; -import FlorenceMD from "@site/src/components/about/Team/Florence.md"; +import FlorenceMD from "@site/src/pages/about/Team/Florence.md"; import FlorenceAvatarUrl from "@site/static/img/avatars/Florence.png"; -import GabrielaMD from "@site/src/components/about/Team/Gabriela.md"; +import GabrielaMD from "@site/src/pages/about/Team/Gabriela.md"; import GabrielaAvatarUrl from "@site/static/img/avatars/Gabriela.png"; -import GregMD from "@site/src/components/about/Team/Greg.md"; +import GregMD from "@site/src/pages/about/Team/Greg.md"; import GregAvatarUrl from "@site/static/img/avatars/Greg.png"; -import HindMD from "@site/src/components/about/Team/Hind.md"; +import HindMD from "@site/src/pages/about/Team/Hind.md"; import HindAvatarUrl from "@site/static/img/avatars/Hind.png"; -import IanMD from "@site/src/components/about/Team/Ian.md"; +import IanMD from "@site/src/pages/about/Team/Ian.md"; import IanAvatarUrl from "@site/static/img/avatars/Ian.png"; -import IsabelMD from "@site/src/components/about/Team/Isabel.md"; +import IsabelMD from "@site/src/pages/about/Team/Isabel.md"; import IsabelAvatarUrl from "@site/static/img/avatars/Isabel.png"; -import JeremyMD from "@site/src/components/about/Team/Jeremy.md"; +import JeremyMD from "@site/src/pages/about/Team/Jeremy.md"; import JeremyAvatarUrl from "@site/static/img/avatars/Jeremy.png"; -import JoelMD from "@site/src/components/about/Team/Joel.md"; +import JoelMD from "@site/src/pages/about/Team/Joel.md"; import JoelAvatarUrl from "@site/static/img/avatars/Joel.png"; -import JohanMD from "@site/src/components/about/Team/Johan.md"; +import JohanMD from "@site/src/pages/about/Team/Johan.md"; import JohanAvatarUrl from "@site/static/img/avatars/Johan.png"; -import JulienMD from "@site/src/components/about/Team/Julien.md"; +import JulienMD from "@site/src/pages/about/Team/Julien.md"; import JulienAvatarUrl from "@site/static/img/avatars/Julien.png"; -import MarionMD from "@site/src/components/about/Team/Marion.md"; +import MarionMD from "@site/src/pages/about/Team/Marion.md"; import MarionAvatarUrl from "@site/static/img/avatars/Marion.png"; -import MartinMD from "@site/src/components/about/Team/Martin.md"; +import MartinMD from "@site/src/pages/about/Team/Martin.md"; import MartinAvatarUrl from "@site/static/img/avatars/Martin.png"; -import MatthiasMD from "@site/src/components/about/Team/Matthias.md"; +import MatthiasMD from "@site/src/pages/about/Team/Matthias.md"; import MatthiasAvatarUrl from "@site/static/img/avatars/Matthias.png"; -import MeriemMD from "@site/src/components/about/Team/Meriem.md"; +import MeriemMD from "@site/src/pages/about/Team/Meriem.md"; import MeriemAvatarUrl from "@site/static/img/avatars/Meriem.png"; -import NicolasMD from "@site/src/components/about/Team/Nicolas.md"; +import NicolasMD from "@site/src/pages/about/Team/Nicolas.md"; import NicolasAvatarUrl from "@site/static/img/avatars/Nicolas.png"; -import OlivierMD from "@site/src/components/about/Team/Olivier.md"; +import OlivierMD from "@site/src/pages/about/Team/Olivier.md"; import OlivierAvatarUrl from "@site/static/img/avatars/Olivier.png"; -import RaulMD from "@site/src/components/about/Team/Raul.md"; +import RaulMD from "@site/src/pages/about/Team/Raul.md"; import RaulAvatarUrl from "@site/static/img/avatars/Raul.png"; -import RomainMD from "@site/src/components/about/Team/Romain.md"; +import RomainMD from "@site/src/pages/about/Team/Romain.md"; import RomainAvatarUrl from "@site/static/img/avatars/Romain.png"; -import SandrineMD from "@site/src/components/about/Team/Sandrine.md"; +import SandrineMD from "@site/src/pages/about/Team/Sandrine.md"; import SandrineAvatarUrl from "@site/static/img/avatars/Sandrine.png"; -import SergeMD from "@site/src/components/about/Team/Serge.md"; +import SergeMD from "@site/src/pages/about/Team/Serge.md"; import SergeAvatarUrl from "@site/static/img/avatars/Serge.png"; -import SylvainMD from "@site/src/components/about/Team/Sylvain.md"; +import SylvainMD from "@site/src/pages/about/Team/Sylvain.md"; import SylvainAvatarUrl from "@site/static/img/avatars/Sylvain.png"; -import ThorstenMD from "@site/src/components/about/Team/Thorsten.md"; +import ThorstenMD from "@site/src/pages/about/Team/Thorsten.md"; import ThorstenAvatarUrl from "@site/static/img/avatars/Thorsten.png"; -import TrungMD from "@site/src/components/about/Team/Trung.md"; +import TrungMD from "@site/src/pages/about/Team/Trung.md"; import TrungAvatarUrl from "@site/static/img/avatars/Trung.png"; -import YahiaMD from "@site/src/components/about/Team/Yahia.md"; +import YahiaMD from "@site/src/pages/about/Team/Yahia.md"; import YahiaAvatarUrl from "@site/static/img/avatars/Yahia.png"; export const teams = { diff --git a/src/pages/about/index.tsx b/src/pages/about/index.tsx index 04b239c18..1f07bb557 100644 --- a/src/pages/about/index.tsx +++ b/src/pages/about/index.tsx @@ -1,15 +1,95 @@ import Layout from "@theme/Layout"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import {About} from "@site/src/components/about"; import BrowserOnly from "@docusaurus/BrowserOnly"; import Footer from "@site/src/components/footer/Footer"; +import styles from "@site/src/components/about/styles.module.css"; +import { teams } from "@site/src/pages/about/Team/_team"; +import { valuesDetails } from "@site/src/components/about/valuesDetails"; +import { SmallPortraitCard } from "@site/src/components/about/SmallPortraitCard"; +import Section from "@site/src/components/layout/Section"; +import Banner from "@site/src/components/layout/Banner"; +import CardGrid from "@site/src/components/layout/CardGrid"; +import Card from "@site/src/components/layout/Card"; +import LinkToContact from "@site/src/components/LinkToContact"; +import ScrollDownCTA from "@site/src/components/layout/ScrollDownCTA"; + +export function getTeamByPageName(name: string) { + for (const [, members] of Object.entries(teams)) { + const person = members.find((person) => person.pageName === name); + if (person) { + return members; + } + } + return null; +} + +export function AboutContent() { + return ( + <> +
      +

      About us

      +

      ~30 engineers and researchers building the infrastructure for modern data analysis and science.

      +

      Founded in Paris in 2016. JupyterLab, Mamba, JupyterLite, emscripten-forge — tools reaching millions daily. Our team received several awards for our open source work.

      +
      + + +
      +
      +
      +

      Our values

      + + {valuesDetails.map((value, index) => ( +
    • + +
      + +
      +
      {value.name}
      +
      + +
      +
      +
    • + ))} +
      +
      +
      +

      Meet the team

      +
      + Many of us have PhDs, deep engineering or open source maintenance backgrounds. We operate as a collective of contributors — everyone on the team ships code to the projects we maintain. No passengers. +
      + {[ + { label: "The leadership team", members: teams.leadershipTeam }, + { label: "The core team", members: teams.coreTeam }, + { label: "QuantStack collaborators", members: teams.QSCollaboratorsTeam }, + ].map(({ label, members }) => ( +
      +

      {label}

      + + {members.map((person) => ( +
    • + +
    • + ))} +
      +
      + ))} +
      + } + > + We're looking for researchers and engineers who want to work at the frontier of open-source data science and scientific computing — and ship code that millions of people depend on. + + + ); +} export default function AboutPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - {() => } -
      + {() => } +
      ); } diff --git a/src/components/blog/styles.module.css b/src/pages/blog.module.css similarity index 51% rename from src/components/blog/styles.module.css rename to src/pages/blog.module.css index 92bbe7adb..5cb341d57 100644 --- a/src/components/blog/styles.module.css +++ b/src/pages/blog.module.css @@ -1,81 +1,69 @@ .blogpost_image { filter: grayscale(1); + height: 180px; + display: flex; + align-items: center; + justify-content: center; + background: var(--ifm-bg-brand); + border-radius: 4px; } .blogpost_card { height: 556px; - width: 369px; - border-radius: 8px; - box-shadow: 4px 4px 18px -1px #dee0fc; padding: var(--ifm-spacing-xl); - background: var(--ifm-background-color-card); -} - -.blogpost_card:hover { - border: 1px solid #cbc7b1; -} - -div .blogpost_header { - color: var(--ifm-text-color); -} -div .blogpost_summary { - color: var(--ifm-text-color); -} - -div .blogpost_authors { - color: var(--ifm-text-color); -} - -div .blogpost_date { - color: var(--ifm-text-color); } .blogpost_summary { - font-family: var(--ifm-font-family-roboto); font-size: 14px; - font-style: normal; font-weight: 300; - line-height: 150%; /* 21px */ + line-height: 150%; letter-spacing: -0.154px; text-align: justify; margin-bottom: var(--ifm-spacing-sm); height: 124px; color: var(--ifm-text-color); + flex: 1; } .blogpost_header { - color: var(---ifm-text-color); - font-family: var(--ifm-font-family-roboto); font-size: 16px; - font-style: normal; font-weight: 600; - line-height: 150%; /* 27px */ + line-height: 150%; letter-spacing: -0.198px; height: 64px; margin: var(--ifm-spacing-xl) 0; color: var(--ifm-text-color); } +.blogpost_footer { + margin-top: auto; + padding-top: var(--ifm-spacing-sm); +} + .blogpost_date { - color: var(---ifm-text-color); - font-family: var(--ifm-font-family-roboto); font-size: 12px; - font-style: normal; font-weight: 800; line-height: 16px; letter-spacing: -0.132px; - text-align: left; - color: var(--ifm-text-color); + color: var(--ifm-color-accent-red); +} + +.blogpost_date_dot { + display: inline-block; + width: 7px; + height: 7px; + border-radius: 50%; + background-color: var(--ifm-color-accent-red); + margin-right: 6px; + vertical-align: middle; + margin-bottom: 2px; } .blogpost_authors { - font-family: var(--ifm-font-family-roboto); font-size: 12px; - font-style: normal; font-weight: 400; line-height: 16px; - text-align: left; - color: var(--ifm-text-color); + color: var(--ifm-color-secondary-s3); } .search_input { @@ -86,7 +74,6 @@ div .blogpost_date { background-repeat: no-repeat; background-position: 8px; border-radius: 8px; - padding: var(--ifm-spacing-xs) var(--ifm-spacing-lg) var(--ifm-spacing-xs) - var(--ifm-spacing-lg); + padding: var(--ifm-spacing-xs) var(--ifm-spacing-lg) var(--ifm-spacing-xs) var(--ifm-spacing-lg); margin: var(--ifm-spacing-lg) 0; } diff --git a/src/pages/blog.tsx b/src/pages/blog.tsx index 3a88e7fdb..4304e9cb6 100644 --- a/src/pages/blog.tsx +++ b/src/pages/blog.tsx @@ -1,16 +1,34 @@ -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import Layout from "@theme/Layout"; -import BlogsComponent from "../components/blog"; -import { blogpostsDetails } from "../components/blog/blogpostsDetails"; +import BrowserOnly from "@docusaurus/BrowserOnly"; import Footer from "../components/footer/Footer"; - +import Section from "../components/layout/Section"; +import SectionSeparator from "../components/layout/SectionSeparator"; +import AtomOrange from "/img/icons/RSSOrange.svg"; +import BlogGrid from "../components/Blog"; +import ScrollDownCTA from "../components/layout/ScrollDownCTA"; export default function BlogPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - -
      +
      +

      Featured posts by QuantStack contributors

      +

      From the maintainers, at the source.

      +

      + Technical deep-dives, release notes, and perspectives from the people who wrote the code. Read about the decisions, trade-offs, and discoveries that go into the tools powering modern data analysis and science. From Mamba's solver design to JupyterLab's real-time collaboration protocol — these posts come from the engineers who made the calls. +

      + +
      + +
      + {() => } +
      +
      ); } diff --git a/src/pages/blogs/Fanny.tsx b/src/pages/blogs/Fanny.tsx index ed976c5ad..19b85fcc7 100644 --- a/src/pages/blogs/Fanny.tsx +++ b/src/pages/blogs/Fanny.tsx @@ -1,4 +1,4 @@ -import Fanny from "@site/src/components/about/Team/Fanny.md"; +import Fanny from "@site/src/pages/about/Team/Fanny.md"; import styles from "@site/src/components/about/styles.module.css"; import FannyAvatarUrl from "@site/static/img/avatars/Fanny.png"; import Layout from "@theme/Layout"; diff --git a/src/components/blog/blogpostsDetails.js b/src/pages/blogs/_blogpostsDetails.js similarity index 100% rename from src/components/blog/blogpostsDetails.js rename to src/pages/blogs/_blogpostsDetails.js diff --git a/src/components/careers/styles.module.css b/src/pages/careers.module.css similarity index 88% rename from src/components/careers/styles.module.css rename to src/pages/careers.module.css index 70b0576ef..c6de3ca02 100644 --- a/src/components/careers/styles.module.css +++ b/src/pages/careers.module.css @@ -3,11 +3,6 @@ padding: 0; } -.interview_picture { - width: 100%; - height: auto; -} - .picture_container { position: relative; width: 100%; @@ -16,6 +11,11 @@ justify-content: center; } +.interview_picture { + width: 100%; + height: auto; +} + .play_interview { height: 60px; width: 60px; @@ -26,19 +26,12 @@ -ms-transform: translate(-50%, -50%); } -.link_to_WTJ { - background-color: var(--ifm-color-secondary-s2); - color: white; - width: 358px; - font-weight: 700; -} - .interview_card { width: 280px; height: 300px; - background-color: var(--ifm-background-color); + background-color: var(--ifm-bg-neutral); border-radius: 10px; - box-shadow: 0px 0px 8px 1px #c8c8c7; + box-shadow: var(--ifm-shadow-card); padding: var(--ifm-spacing-sm); text-align: center; margin-bottom: var(--ifm-spacing-xl); @@ -59,7 +52,7 @@ font-size: 22px; font-style: normal; font-weight: 400; - line-height: 128.571%; + line-height: 128.571%; margin-top: var(--ifm-spacing-lg); } @@ -74,14 +67,18 @@ letter-spacing: 0.5px; } +.link_to_WTJ { + background-color: var(--ifm-bg-emphasis); + color: white; + font-weight: 700; +} + @media only screen and (max-width: 996px) { - /*Mobile*/ .join_the_team_text { text-align: center; font-size: 18px; font-family: var(--ifm-font-family-roboto); color: var(--ifm-color-primary-p2); - text-align: center; font-style: normal; font-weight: 400; line-height: 36px; @@ -93,13 +90,11 @@ } @media only screen and (min-width: 996px) { - /*Desktop*/ .join_the_team_text { text-align: center; font-size: 28px; font-family: var(--ifm-font-family-roboto); color: var(--ifm-color-primary-p2); - text-align: center; font-style: normal; font-weight: 400; line-height: 36px; diff --git a/src/pages/careers.tsx b/src/pages/careers.tsx index 2075918ae..5c53b54b8 100644 --- a/src/pages/careers.tsx +++ b/src/pages/careers.tsx @@ -1,16 +1,114 @@ -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Layout from '@theme/Layout'; -import Careers from '../components/careers'; +import Layout from "@theme/Layout"; +import BrowserOnly from "@docusaurus/BrowserOnly"; import Footer from "../components/footer/Footer"; +import Section from "../components/layout/Section"; +import SectionSeparator from "../components/layout/SectionSeparator"; +import Banner from "../components/layout/Banner"; +import Link from "@docusaurus/Link"; +import styles from "./careers.module.css"; +import PlayCircle from "@site/static/img/icons/PlayCircle.svg"; +import ScrollDownCTA from "../components/layout/ScrollDownCTA"; +import LinkToContact from "../components/LinkToContact"; +import GroupPhotoUrl from "@site/static/img/group/group-photo.png"; +import SylvainPictureUrl from "@site/static/img/interviews/Sylvain_WTJ.png"; +import JohanPictureUrl from "@site/static/img/interviews/Johan_WTJ.png"; +import MartinPictureUrl from "@site/static/img/interviews/Martin_WTJ.png"; +import JeremyPictureUrl from "@site/static/img/interviews/Jeremy_WTJ.png"; +import DarianPictureUrl from "@site/static/img/interviews/Darian_WTJ.png"; +import DavidPictureUrl from "@site/static/img/interviews/David_WTJ.png"; +import GabrielaPictureUrl from "@site/static/img/interviews/Gabriela_WTJ.png"; +import TrungPictureUrl from "@site/static/img/interviews/Trung_WTJ.png"; +import MeriemPictureUrl from "@site/static/img/interviews/Meriem_WTJ.png"; +import MatthiasPictureUrl from "@site/static/img/interviews/Matthias_WTJ.png"; +import SandrinePictureUrl from "@site/static/img/interviews/Sandrine_WTJ.png"; + +const interviews = [ + { completeName: "Sylvain Corlay", firstName: "Sylvain", position: "CEO", pictureUrl: SylvainPictureUrl, url: "https://www.dailymotion.com/video/xa0qmac" }, + { completeName: "Johan Mabille", firstName: "Johan", position: "Technical Director", pictureUrl: JohanPictureUrl, url: "https://www.dailymotion.com/video/x9zl9ta" }, + { completeName: "Martin Renou", firstName: "Martin", position: "Technical Director", pictureUrl: MartinPictureUrl, url: "https://www.dailymotion.com/video/x9zl9t6" }, + { completeName: "Jeremy Tuloup", firstName: "Jeremy", position: "Technical Director", pictureUrl: JeremyPictureUrl, url: "https://www.dailymotion.com/video/x9zl9t8" }, + { completeName: "Afshin Darian", firstName: "Darian", position: "Technical Director", pictureUrl: DarianPictureUrl, url: "https://www.dailymotion.com/video/x9zl9t2" }, + { completeName: "David Brochart", firstName: "David", position: "Technical Director", pictureUrl: DavidPictureUrl, url: "https://www.dailymotion.com/video/x9zl9t4" }, + { completeName: "Gabriela Vives", firstName: "Gabriela", position: "UX Designer and Researcher", pictureUrl: GabrielaPictureUrl, url: "https://www.dailymotion.com/video/x9zl9sw" }, + { completeName: "Trung Le Duc", firstName: "Trung", position: "Scientific Software Developer", pictureUrl: TrungPictureUrl, url: "https://www.dailymotion.com/video/x9zl9t0" }, + { completeName: "Sandrine Pataut", firstName: "Sandrine", position: "Scientific Software Developer", pictureUrl: SandrinePictureUrl, url: "https://www.dailymotion.com/video/xa0qmai" }, + { completeName: "Matthias Meschede", firstName: "Matthias", position: "Chief Operating Officer", pictureUrl: MatthiasPictureUrl, url: "https://www.dailymotion.com/video/xa0qmae" }, + { completeName: "Meriem Ben Ismail", firstName: "Meriem", position: "Scientific Software Developer", pictureUrl: MeriemPictureUrl, url: "https://www.dailymotion.com/video/xa0qmag" }, +]; + +function InterviewCard({ person }) { + return ( + +
      +
      +
      + {`${person.completeName}, + +
      +
      +
      {person.firstName}
      +
      {person.position}
      +
      + + ); +} + +function CareersContent() { + return ( + <> +
      +

      Join the QuantStack team.

      +

      Your code will reach millions. Your contributions go upstream.

      +

      We are ~30 researchers and engineers building the infrastructure of scientific computing. This is not a support role — it's a principal contributor role from day one. Most of us have PhDs or deep research backgrounds, and every one of us ships code upstream.

      +
      + Get in touch + +
      +
      + + + +
      +
      + QuantStack team gathered at JupyterCon in Paris, May 2023. +
      +
      +
      + We're looking for researchers and engineers who want to work at the frontier of open-source scientific computing. If you have strong fundamentals, a taste for hard problems, and care deeply about the impact of your work — we'd like to meet you. +
      +
      +

      Working at QuantStack

      +
      +
        + {interviews.map((person) => ( +
      • +
        + +
        +
      • + ))} +
      +
      +
      +
      +
      + + } + > + Ready to work on tools that millions of people depend on? We'd like to meet you. + + + ); +} export default function CareersPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - -
      + {() => } +
      ); } - diff --git a/src/components/contact/styles.module.css b/src/pages/contact.module.css similarity index 55% rename from src/components/contact/styles.module.css rename to src/pages/contact.module.css index ef330c1fb..e29c28515 100644 --- a/src/components/contact/styles.module.css +++ b/src/pages/contact.module.css @@ -4,8 +4,6 @@ background: var(--ifm-color-blue-jupyter); } - - .contact_form { margin-top: var(--ifm-spacing-xl); } @@ -13,48 +11,45 @@ .form_label { font-size: 12px; color: var(--ifm-text-color); - background-color: var(--ifm-background-color); + background-color: var(--ifm-bg-neutral); } - - @media only screen and (max-width: 996px) { - /*Mobile*/ .small_input { width: 300px; height: 56px; border-radius: 4px; } - + .large_input { width: 300px; height: 220px; border-radius: 4px; } + .send_button_container { height: 59px; width: 300px; margin: var(--ifm-spacing-2xl) 0; } - +} + +@media only screen and (min-width: 996px) { + .small_input { + width: 508px; + height: 56px; + border-radius: 4px; } - @media only screen and (min-width: 996px) { - /*Desktop*/ - .small_input { - width: 508px; - height: 56px; - border-radius: 4px; - } - - .large_input { - width: 508px; - height: 220px; - border-radius: 4px; - } - .send_button_container { - height: 59px; - width: 508px; - margin: var(--ifm-spacing-2xl) 0; - } - } \ No newline at end of file + .large_input { + width: 508px; + height: 220px; + border-radius: 4px; + } + + .send_button_container { + height: 59px; + width: 508px; + margin: var(--ifm-spacing-2xl) 0; + } +} diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index 1fd3daf8d..5069f6e7f 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -1,15 +1,33 @@ -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import Layout from "@theme/Layout"; -import Contact from "@site/src/components/contact"; import BrowserOnly from "@docusaurus/BrowserOnly"; import Footer from "../components/footer/Footer"; +import SplitSection from "../components/layout/SplitSection"; +import ContactForm from "../components/ContactForm"; +import ContactIllustration from "/img/illustrations/contact.svg"; export default function ContactPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - {() => } -
      + + {() => ( + + } + > +

      Contact us

      + +
      + )} +
      +
      ); } diff --git a/src/pages/fundable.tsx b/src/pages/fundable.tsx deleted file mode 100644 index 8bb5a9295..000000000 --- a/src/pages/fundable.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Layout from '@theme/Layout'; -import FundableProjects from '../components/fundable'; -import Footer from "../components/footer/Footer"; - -export default function FundableProjectsPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); - return ( - - -
      - - ); -} \ No newline at end of file diff --git a/src/pages/home.tsx b/src/pages/home.tsx deleted file mode 100644 index 11a7a04c0..000000000 --- a/src/pages/home.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import Layout from "@theme/Layout"; -import Home from "../components/home/Home"; -import BrowserOnly from "@docusaurus/BrowserOnly"; -import Footer from "../components/footer/Footer"; - -export default function HomePage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); - return ( - -
      - {() => } -
      -
      -
      - ); -} diff --git a/src/pages/index.module.css b/src/pages/index.module.css new file mode 100644 index 000000000..453850d0e --- /dev/null +++ b/src/pages/index.module.css @@ -0,0 +1,204 @@ +/* ── Hero ─────────────────────────────────────────────────────────────────── */ + +.hero_container { + background-color: var(--ifm-bg-brand); + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + padding-top: calc(var(--ifm-navbar-height) + var(--ifm-spacing-2xl)); + padding-bottom: var(--ifm-spacing-2xl); + margin-top: calc(-1 * var(--ifm-navbar-height)); + box-sizing: border-box; + position: relative; + overflow: hidden; +} + +.hero_body { + position: relative; + display: flex; + align-items: center; + gap: var(--ifm-spacing-2xl); +} + +.hero_text { + flex: 3; + min-width: 0; + position: relative; + z-index: 1; +} + +.hero_image { + flex: 2; + display: flex; + align-items: center; + justify-content: center; + position: relative; + z-index: 1; +} + +.hero_title { + font-size: 8rem; + line-height: 1; + white-space: nowrap; +} + +.sub_header { + text-align: left; +} + +.tech_tagline { + color: var(--ifm-color-blue-jupyter); + font-size: var(--ifm-font-size-secondary-title); + font-weight: 700; +} + +.accent { + color: var(--ifm-color-accent-red); +} + +@media (max-width: 996px) { + .hero_title { + font-size: 4rem; + } + + .hero_body { + flex-direction: column; + padding: var(--ifm-spacing-xl) 0; + } + + .hero_image { + display: none; + } + + .tech_tagline { + font-size: 20px; + line-height: 150%; + text-align: center; + } +} + +@media (max-width: 996px) and (min-width: 600px) { + .hero_title { + font-size: 6rem; + } + + .tech_tagline { + font-size: 26px; + } +} + +/* ── Services (How we work with you) ─────────────────────────────────────── */ + +.topics_header { + font-family: var(--ifm-font-family-roboto); + font-size: var(--ifm-font-size-secondary-title); + font-weight: 700; + line-height: 28px; + min-height: 56px; + display: flex; + align-items: flex-start; + justify-content: flex-start; + text-align: left; + margin-bottom: var(--ifm-spacing-xl); + color: var(--ifm-color-neutral-n2); +} + +.topics_card { + padding: var(--ifm-spacing-2xl) var(--ifm-spacing-lg); +} + +.projects_link { + display: none; +} + +@media (max-width: 996px) { + .projects_link { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--ifm-spacing-sm); + } +} + +/* ── Projects Overview ────────────────────────────────────────────────────── */ + +.projects_overview_container { + display: block; +} + +.tagline { + color: var(--ifm-color-blue-jupyter); +} + +@media (max-width: 996px) { + .projects_overview_container { + display: none; + } +} + +/* ── About Us ─────────────────────────────────────────────────────────────── */ + +.aboutQS_text { + font-size: 14px; + text-align: center; + margin-bottom: var(--ifm-spacing-xl); + max-width: 800px; + margin-left: auto; + margin-right: auto; +} + +.learn_more_button_container { + display: flex; + justify-content: center; + margin-top: var(--ifm-spacing-xl); +} + +.learn_more_button_container :global(.link-to-button) { + background: var(--ifm-color-accent-yellow); + color: var(--ifm-color-primary-p2); +} + +.learn_more_button_container :global(.link-to-button):hover { + color: var(--ifm-color-primary-p2); + box-shadow: 0 8px 28px rgba(245, 229, 59, 0.5); +} + +@media (min-width: 996px) { + .aboutQS_text { + font-size: 24px; + margin-bottom: var(--ifm-spacing-lg); + } +} + +/* ── News ─────────────────────────────────────────────────────────────────── */ + +@media (max-width: 996px) { + .news_wrapper { + display: none; + } +} + +/* ── Link buttons ─────────────────────────────────────────────────────────── */ + +@media only screen and (max-width: 996px) { + .link_to, + .link_to_services, + .link_to_about_us { + background-color: var(--ifm-color-primary-p1); + color: var(--ifm-text-color-on-primary-p1); + } + + .link_to:hover, + .link_to_services:hover, + .link_to_about_us:hover { + color: var(--ifm-text-color-on-primary-p1); + box-shadow: 0 8px 24px rgba(246, 241, 149, 0.5); + } +} + +@media only screen and (min-width: 996px) { + .link_to { background-color: var(--ifm-bg-emphasis); color: white; } + .link_to_services { background-color: var(--ifm-color-blue-jupyter); color: white; } + .link_to_about_us { background-color: var(--ifm-bg-emphasis); color: white; } +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 338a6dde5..8b0a7f9d6 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,16 +1,225 @@ -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import Layout from "@theme/Layout"; -import Home from "../components/home/Home"; import BrowserOnly from "@docusaurus/BrowserOnly"; +import Link from "@docusaurus/Link"; +import Layout from "@theme/Layout"; import Footer from "../components/footer/Footer"; +import Section from "../components/layout/Section"; +import SectionSeparator from "../components/layout/SectionSeparator"; +import SplitSection from "../components/layout/SplitSection"; +import Banner from "../components/layout/Banner"; +import Card from "../components/layout/Card"; +import CardGrid from "../components/layout/CardGrid"; +import LogoGrid from "../components/LogoGrid"; +import LinkToNotebookLink from "../components/LinkToNotebookLink"; +import BlogpostCard from "../components/BlogpostCard"; +import { blogpostsDetails } from "./blogs/_blogpostsDetails"; +import styles from "./index.module.css"; + +import Astronaut from "/img/quantstack/astronaut.svg"; +import GroupPhotoUrl from "@site/static/img/group/QuantStack-2000-58.png"; +import JupyterPictureUrl from "@site/static/img/projects/jupyterlab_examples.png"; +import MambaPictureUrl from "@site/static/img/projects/mamba_console.png"; +import SpecialProjectsPictureUrl from "@site/static/img/projects/special_projects.png"; +import RoboticsPictureUrl from "@site/static/img/projects/robotics.png"; +import XTensorXSIMDPicture from "@site/static/img/projects/xtensor_xsimd.svg"; +import ApacheArrowPicture from "@site/static/img/projects/apache_arrow.svg"; + +function HomeContent() { + const numberOfBlogs = blogpostsDetails.length; + + return ( + <> + {/* ── Hero ──────────────────────────────────────────────────────────── */} +
      +
      +
      +
      +

      QUANTSTACK

      +

      + OPEN TOOLS FOR DATA SCIENCE AND SCIENTIFIC COMPUTE +

      +

      + From Jupyter to Mamba to Apache Arrow, we maintain the stack millions of + researchers, engineers, and students depend on. Today we're also building + notebook.link to ship compute environments right in your browser. +

      +
      +
      + +
      +
      +
      +
      + + + + {/* ── Trusted By ────────────────────────────────────────────────────── */} +
      +

      Who we work with

      + +
      + + + + {/* ── How we work with you (services) ───────────────────────────────── */} +
      +

      How we work with you

      + +
    • + +
      Support Retainer
      +

      Direct access to the upstream maintainers of the tools your team depends on — not a helpdesk.

      +

      We triage issues, review pull requests, advise on architecture, and take ownership of problems your team cannot solve alone. Our clients include AWS, Bloomberg, Safran, and the European Space Agency.

      +
      +
    • +
    • + +
      Custom Engineering
      +

      We build tools and platforms at the frontier of open-source scientific computing.

      +

      Recent examples: JupyterGIS for a large public organisations, JupyterCAD for a big airospace engineering firm, notebook.link. What we build goes back upstream wherever possible.

      +
      +
    • +
    • + +
      Funded Development
      +

      Need a specific fix or feature in Mamba, JupyterLab, Arrow, or one of the many projects we maintain? We implement it upstream.

      +

      You get the feature. The community evolves and maintains it. No fork, no long-term maintenance burden on your team.

      +
      +
    • +
      +
      + DISCOVER ALL OF OUR PROJECTS + DISCOVER OUR SERVICES +
      +
      + + + + {/* ── What we work on (projects) ────────────────────────────────────── */} +
      +
      +

      What we work on

      +
      + + }> +

      Jupyter Ecosystem

      +

      Core contributors to JupyterLab, JupyterLite, Voilà, and the broader Jupyter ecosystem.

      +

      We co-founded JupyterLab and JupyterLite — the browser-native Jupyter that runs without a server. Our team drives real-time collaboration, AI integration, and the visual debugger across the Jupyter stack, and maintains Voilà, xeus, JupyterGIS, and JupyterCAD. JupyterLab reaches over 10 million users worldwide; JupyterLite serves hundreds of thousands of students on minimal infrastructure.

      +
      + + }> +

      Package Management

      +

      We created Mamba, the fast conda replacement serving 5 million downloads per month.

      +

      We created Mamba, the fast, reliable conda replacement now serving 5 million downloads per month. We co-maintain conda-forge, delivering over 1 billion package downloads per month, and built emscripten-forge — the package forge that brings the full multilingual scientific computing stack to WebAssembly.

      +
      + + }> +

      Bespoke Platforms

      +

      Platforms built on our open-source stack for clients and the community.

      +
        +
      • JupyterCAD — real-time collaborative 3D CAD editing, built for Safran Aircraft Engines.
      • +
      • JupyterGIS — collaborative geospatial platform for ESA and research institutions.
      • +
      +
      + + }> +

      Robotics

      +

      Creators of RoboStack, the first multi-platform ROS distribution, and maintainers of jupyter-ros.

      +

      We created RoboStack, the first multi-platform distribution of ROS as conda packages, enabling robotics development on Linux, macOS, and Windows without system dependencies. We maintain jupyter-ros, a JupyterLab-based development environment for the ROS ecosystem.

      +
      + + }> +

      Scientific Computing

      +

      Authors of xtensor and xsimd, adopted by Apache Arrow, Firefox, and Pythran.

      +

      We authored xtensor, a multi-dimensional array library for C++ with a NumPy-style API, and xsimd, a unified SIMD operations library adopted by Apache Arrow, Firefox, Krita, and Pythran.

      +
      + + }> +

      Data Infrastructure

      +

      Principal maintainers of Apache Arrow's C++ core.

      +

      We are principal maintainers of Apache Arrow's C++ core — the in-memory columnar format underpinning most of the modern data ecosystem. We also maintain Apache Parquet, the dominant columnar storage format for analytics workloads.

      +
      +
      + + {/* ── notebook.link ─────────────────────────────────────────────────── */} + } + > + A full Jupyter environment as a link. Instant setup, no server, no hassle. Sandboxed + compute runs in the browser, powered by WebAssembly and emscripten-forge. For{" "} + universities replacing JupyterHub, for{" "} + researchers sharing reproducible work, for{" "} + enterprise data teams, and for{" "} + public data portals serving millions of visitors + at near-zero infrastructure cost. + + + {/* ── About us ──────────────────────────────────────────────────────── */} +
      +

      About us

      +
      + QuantStack team photo +
      +

      + QuantStack was founded in 2016. Today we operate as a collective of about 30 engineers + contributing remotely or from our office in Paris to the global open-source stack and + to our clients' projects. Many of us have PhD-level research experience or deep + engineering backgrounds. Our team combines decades of senior experience with the fresh + creativity and energy from more recent contributors. +

      +
      + Learn more +
      +
      + + + + {/* ── Recent blog posts ─────────────────────────────────────────────── */} +
      +
      +

      Recent blog contributions

      + + {[0, 1, 2].map((i) => ( +
    • + +
    • + ))} +
      +
      + READ MORE POSTS +
      +
      +
      + + {/* ── End CTA ───────────────────────────────────────────────────────── */} + + SCHEDULE A MEETING +
      + } + > + Support retainer, custom feature, or a full engineering engagement — + you work directly with the upstream maintainers of the tools your team depends on. + + + ); +} export default function QSWebsite(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - {() => } -
      + {() => } +
      ); } - diff --git a/src/pages/notebooklink.module.css b/src/pages/notebooklink.module.css new file mode 100644 index 000000000..5ea5f7994 --- /dev/null +++ b/src/pages/notebooklink.module.css @@ -0,0 +1,29 @@ +.product_label { + color: var(--ifm-color-accent-yellow); + font-family: var(--ifm-font-family-roboto); + font-size: 13px; + font-weight: 700; + letter-spacing: 2.5px; + text-transform: uppercase; + margin-bottom: var(--ifm-spacing-xs); + padding: 0; +} + +.subtitle { + color: rgba(255, 255, 255, 0.85); + font-size: var(--ifm-font-size-medium); + padding: 0; +} + +.feature_icon { + font-size: 32px; + margin-bottom: var(--ifm-spacing-sm); + display: block; +} + +.feature_title { + font-family: var(--ifm-font-family-display); + font-weight: 800; + font-size: 22px; + margin-bottom: var(--ifm-spacing-xs); +} diff --git a/src/pages/notebooklink.tsx b/src/pages/notebooklink.tsx new file mode 100644 index 000000000..1f0acc03c --- /dev/null +++ b/src/pages/notebooklink.tsx @@ -0,0 +1,132 @@ +import Layout from "@theme/Layout"; +import BrowserOnly from "@docusaurus/BrowserOnly"; +import Footer from "../components/footer/Footer"; +import SplitSection from "../components/layout/SplitSection"; +import Section from "../components/layout/Section"; +import SectionSeparator from "../components/layout/SectionSeparator"; +import CardGrid from "../components/layout/CardGrid"; +import Card from "../components/layout/Card"; +import Banner from "../components/layout/Banner"; +import Rocket from "/img/notebooklink/rocket.svg"; +import LinkToNotebookLink from "../components/LinkToNotebookLink"; +import styles from "./notebooklink.module.css"; + +function NotebookLinkContent() { + return ( + <> + + } + > +

      Our product: Notebook.link

      +

      Browser-native scientific computing. Large-scale deployments, no server, no setup, no limits.

      + +
      + +
      +

      A complete compute environment in a link.

      +

      + Notebook.link delivers a full Jupyter environment running entirely in the browser — + powered by WebAssembly. No installation, no server spin-up, no IT ticket. + Click the link, start computing. +

      +

      + Built on JupyterLite and emscripten-forge, our open-source stack that brings + the complete scientific ecosystem — NumPy, SciPy, Pandas, Matplotlib, + and hundreds more including in C, R, Fortran and other languages — to any modern browser. The compute runs on your users' devices, + not our servers. That means it scales to any number of users for the cost of file storage. +

      +
      + +
      +

      Proven at scale.

      +

      + The technology has been tested to deploy notebooks to tens of thousands of concurrent users + — just from standard static web servers. Zero compute infrastructure cost per user. +

      + +
    • + +
      hundres of thousands of students
      +

      JupyterLite — the same engine powering notebook.link — has been tested with hundreds of thousands of users.

      +
      +
    • +
    • + +
      orders of magnitude cheaper
      +

      Compared to JupyterHub, or other commercial platforms. Because users bring their own compute, we only add the comfort layer, your cost remains low.

      +
      +
    • +
    • + +
      Order-0 scaling
      +

      More users don't mean more servers. Browser-based execution means your platform scales without your costs scaling with it.

      +
      +
    • +
      +
      + +
      +

      Built for every use case.

      + +
    • + +
      Education
      +

      Replace JupyterHub for your institution. No containers per student, no DevOps burden, no IT tickets. LMS integration via LTI. Gradable notebooks with encrypted solutions.

      +
      +
    • +
    • + +
      Research
      +

      Share reproducible work as a link. Byte-identical WASM environments mean your results are reproducible — not just in theory, but in practice. Computational irreproducibility costs billions annually.

      +
      +
    • +
    • + +
      Enterprise data platforms
      +

      Give internal analysts a Jupyter environment without the security overhead of local installs or the cost of per-user cloud kernels. SSO, RBAC, and audit logging on the roadmap. Backend kernels still available on demand.

      +
      +
    • +
    • + +
      Public data portals
      +

      Let millions of visitors interact with your data — including geospatial datasets via JupyterGIS or other advanced IDEs — without provisioning a single compute server. Data stays in the browser, GDPR-compliant by architecture.

      +
      +
    • +
    • + +
      Agentic AI
      +

      Let AI agents access compute environments and run real calculations right in the browser, like claude code but sandboxed, safe and available on the fly.

      +
      +
    • +
      +
      + + } + > + Free tier includes unlimited WebAssembly compute, link sharing, and basic storage. + Enterprise plans for universities and organizations with advanced storage and user management, on-demand backend kernels, grading + Moodle integration available. + + + ); +} + +export default function NotebookLinkPage(): JSX.Element { + return ( + + {() => } +
      + + ); +} diff --git a/src/pages/projects.module.css b/src/pages/projects.module.css new file mode 100644 index 000000000..377dbc9db --- /dev/null +++ b/src/pages/projects.module.css @@ -0,0 +1,69 @@ +.project_title { + margin-bottom: var(--ifm-spacing-sm); + margin-top: var(--ifm-spacing-md); + font-family: var(--ifm-font-family-roboto); + font-size: var(--ifm-font-size-secondary-title); + font-weight: bolder; + line-height: 150%; + text-align: start; + color: var(--ifm-color-primary-p2); +} + +.project_description { + text-align: left; + color: var(--ifm-color-primary-p2); +} + +.project_logo { + max-width: 160px; + max-height: 160px; + width: auto; + height: auto; + object-fit: contain; + display: block; +} + +.project_picture { + border-radius: 10px; + padding: var(--ifm-spacing-lg); + display: flex; + align-items: center; + justify-content: center; +} + +.project_picture_jupyter { border: solid 1px var(--ifm-color-orange-jupyter); } +.project_picture_mamba { border: solid 1px #4cae4c; } +.project_picture_condaforge { border: solid 1px var(--ifm-color-grey-condaforge); } +.project_picture_arrow { border: solid 1px black; } +.project_picture_xtensor { border: solid 1px var(--ifm-color-green-xtensor); } +.project_picture_robotics { border: solid 1px rgb(146, 95, 218); } + +@media only screen and (max-width: 996px) { + .project_picture_jupyter, + .project_picture_mamba, + .project_picture_condaforge, + .project_picture_arrow, + .project_picture_xtensor, + .project_picture_robotics { + border: none; + padding: var(--ifm-spacing-md); + } +} + +@media only screen and (min-width: 996px) { + .header_text { + font-size: 22px; + font-weight: 400; + line-height: 28px; + margin-bottom: var(--ifm-spacing-xl); + } +} + +@media only screen and (max-width: 996px) { + .header_text { + font-size: 14px; + font-weight: 400; + line-height: 20px; + margin-bottom: var(--ifm-spacing-lg); + } +} diff --git a/src/pages/projects.tsx b/src/pages/projects.tsx index b2e625c9d..ababc7571 100644 --- a/src/pages/projects.tsx +++ b/src/pages/projects.tsx @@ -1,14 +1,168 @@ -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import Layout from "@theme/Layout"; -import Projects from "@site/src/components/projects"; import BrowserOnly from "@docusaurus/BrowserOnly"; import Footer from "../components/footer/Footer"; +import Section from "../components/layout/Section"; +import SectionSeparator from "../components/layout/SectionSeparator"; +import SplitSection from "../components/layout/SplitSection"; +import Banner from "../components/layout/Banner"; +import LinkToContact from "../components/LinkToContact"; +import ScrollDownCTA from "../components/layout/ScrollDownCTA"; +import styles from "./projects.module.css"; + +import JupyterLogoUrl from "@site/static/img/projects/Jupyter.png"; +import MambaLogoUrl from "@site/static/img/projects/Mamba.png"; +import CondaForgeLogoUrl from "@site/static/img/projects/conda_forge.png"; +import ApacheArrowLogoUrl from "@site/static/img/projects/apache_arrow.png"; +import XtensorLogoUrl from "@site/static/img/projects/xtensor.png"; +import RobostackLogoUrl from "@site/static/img/projects/robostack.png"; + +function ProjectsContent() { + return ( + <> + {/* ── Header ────────────────────────────────────────────────────────── */} +
      +

      Working in the open

      +

      Tools reaching millions of researchers, engineers, and students worldwide.

      +

      + From interactive environments to package managers to data formats, we build in the open so that anyone can build on what we create. + Our tools are the foundation powering research pipelines, commercial data stacks, and classroom notebooks at scale. + What we make are digital commons, community-governed, and maintained for the long term. +

      +
      + + +
      +
      + + + + {/* ── Project list ──────────────────────────────────────────────────── */} +
      +

      What we build and maintain

      +
      + + {/* ── Jupyter ───────────────────────────────────────────────────────── */} + + Jupyter logo +
      + } + > +
      Jupyter
      +
      +

      QuantStack is one of the main organizations behind the Jupyter project. We co-created JupyterLab and JupyterLite — the browser-native Jupyter that runs without a server — and drive major features including real-time collaboration, the visual debugger, and AI integration.

      +

      We also maintain Voilà, xeus, JupyterGIS, and JupyterCAD. JupyterLab reaches over 10 million users worldwide; JupyterLite serves hundreds of thousands of students on minimal infrastructure.

      +
      + + + {/* ── Mamba ─────────────────────────────────────────────────────────── */} + + Mamba logo +
    + } + > +
    Mamba
    +
    +

    We created Mamba, the fast, reliable drop-in replacement for the conda package manager. Mamba delivers dramatically faster dependency solving, better error messages, and full compatibility with the conda ecosystem.

    +

    Mamba now serves 5 million downloads per month and is the package manager of choice for a large part of the scientific Python community.

    +
    + + + {/* ── Conda-forge ───────────────────────────────────────────────────── */} + + conda-forge logo + + } + > +
    Conda-forge & emscripten-forge
    +
    +

    We are one of the key organizations supporting conda-forge, the community-led collection of recipes and build infrastructure for the conda/mamba package manager. Conda-forge delivers over 1 billion package downloads per month and is the reference source for the scientific computing ecosystem.

    +

    We also built emscripten-forge, the package forge that brings the full multilingual scientific computing stack to WebAssembly — the backbone of JupyterLite and notebook.link.

    +
    +
    + + {/* ── Apache Arrow & Parquet ────────────────────────────────────────── */} + + Apache Arrow logo + + } + > +
    Apache Arrow & Parquet
    +
    +

    QuantStack is home to principal maintainers of Apache Arrow's C++ core — the in-memory columnar format that underpins most of the modern data ecosystem, from pandas to Spark to DuckDB.

    +

    We also co-maintain Apache Parquet, the dominant columnar storage format for analytics workloads, and provide commercial support and custom development across the Arrow ecosystem.

    +
    +
    + + {/* ── Xtensor & Xsimd ──────────────────────────────────────────────── */} + + xtensor logo + + } + > +
    xtensor & xsimd
    +
    +

    We authored xtensor, a multi-dimensional array library for C++ with a NumPy-style API supporting lazy broadcasting, universal functions, and language bindings for Python, R, and Julia.

    +

    We also created xsimd, a unified API for SIMD operations that has seen wide adoption: Apache Arrow, Firefox, Krita, and Pythran all depend on it for high-performance computing.

    +
    +
    + + {/* ── Robotics ──────────────────────────────────────────────────────── */} + + RoboStack logo + + } + > +
    Robotics
    +
    +

    We created RoboStack, the first multi-platform distribution of ROS as conda packages, enabling robotics development on Linux, macOS, and Windows without system dependencies.

    +

    We maintain jupyter-ros, a JupyterLab-based development environment integrating ROS with the Jupyter ecosystem.

    +
    +
    + + {/* ── CTA ───────────────────────────────────────────────────────────── */} + } + > + Support retainer, funded development, or a custom engineering engagement — + you work directly with the upstream maintainers of the tools your stack depends on. + + + ); +} export default function ProjectsPage(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); return ( - {() => } + {() => }