diff --git a/docs/website/docusaurus.config.js b/docs/website/docusaurus.config.js index e0a63bf113b..a160d5ba863 100644 --- a/docs/website/docusaurus.config.js +++ b/docs/website/docusaurus.config.js @@ -15,7 +15,7 @@ const config = { baseUrl: "/doc/", onBrokenLinks: "throw", onBrokenMarkdownLinks: "warn", - favicon: "img/logo.svg", + favicon: "img/mithril-logo.svg", organizationName: "Input Output Global", projectName: "Mithril", @@ -88,6 +88,17 @@ const config = { ], plugins: [ + async function myPlugin(context, options) { + return { + name: "docusaurus-tailwindcss", + configurePostCss(postcssOptions) { + // Appends TailwindCSS and AutoPrefixer. + postcssOptions.plugins.push(require("tailwindcss")); + postcssOptions.plugins.push(require("autoprefixer")); + return postcssOptions; + }, + }; + }, [ "@docusaurus/plugin-content-blog", { @@ -200,15 +211,20 @@ const config = { id: "announcement", content: 'Participate in Mithril Protocol’s Mainnet Beta! Follow our SPO on-boarding guide here!', - backgroundColor: "#2e8555", + backgroundColor: "#2A598E", textColor: "#f1f1f1", isCloseable: true, }, + colorMode: { + defaultMode: "light", + disableSwitch: true, + respectPrefersColorScheme: false, + }, navbar: { - title: "Mithril", logo: { alt: "Mithril. A complete guide.", - src: "img/logo.svg", + + src: "img/mithril-logo-text.svg", }, items: [ { @@ -238,23 +254,21 @@ const config = { label: "Glossary", position: "right", }, - { to: "/dev-blog", label: "Dev blog", position: "right" }, + { to: "/dev-blog", label: "Blog", position: "right" }, { to: "/adr", label: "ADRs", position: "right" }, - { - className: "header-github-link", - href: "https://github.com/input-output-hk/mithril/", - position: "right", - }, ], }, footer: { - style: "dark", + logo: { + alt: "Mithril. A complete guide.", + src: "img/mithril-logo-dark.svg", + }, links: [ { title: "Contributing", items: [ { - label: "Contributing Guidelines", + label: "Contributing guidelines", href: "https://github.com/input-output-hk/mithril/blob/main/CONTRIBUTING.md", }, { @@ -271,7 +285,7 @@ const config = { href: "https://discord.gg/5kaErDKDRq", }, { - label: "GitHub Discussions", + label: "GitHub discussions", href: "https://github.com/input-output-hk/mithril/discussions", }, { @@ -284,11 +298,11 @@ const config = { title: "More", items: [ { - label: "Mithril Networks Status", + label: "Mithril networks status", href: "https://mithril.cronitorstatus.com/", }, { - label: "Mithril Protocol Insights", + label: "Mithril protocol insights", href: "https://lookerstudio.google.com/s/mbL23-8gibI", }, { @@ -301,8 +315,21 @@ const config = { }, ], }, + { + title: "Legal", + items: [ + { + label: "Privacy policy", + href: "https://static.iohk.io/terms/iog-privacy-policy.pdf", + }, + { + label: "Terms and conditions", + href: "https://static.iohk.io/terms/iog-terms-and-conditions.pdf", + }, + ], + }, ], - copyright: `Copyright © ${new Date().getFullYear()} Input Output Global
Privacy Policy | Terms & Conditions
Built with Docusaurus`, + copyright: `Copyright © ${new Date().getFullYear()} IOG, Inc.`, }, prism: { theme: lightCodeTheme, diff --git a/docs/website/helpers/media-queries.ts b/docs/website/helpers/media-queries.ts new file mode 100644 index 00000000000..6d602709527 --- /dev/null +++ b/docs/website/helpers/media-queries.ts @@ -0,0 +1,11 @@ +export const not = (query: string) => "not screen and " + query; + +export const forPhablet = "(min-width: 640px)"; + +export const forTablet = "(min-width: 768px)"; + +export const forLaptop = "(min-width: 1024px)"; + +export const forDesktop = "(min-width: 1280px)"; + +export const forTabletOnly = `${forTablet} and (max-width: 1024px)`; diff --git a/docs/website/homepage-content/features.tsx b/docs/website/homepage-content/features.tsx new file mode 100644 index 00000000000..de6b5d9bbb8 --- /dev/null +++ b/docs/website/homepage-content/features.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { translate } from "@docusaurus/Translate"; +import Security from "../src/components/icons/Security"; +import Speed from "../src/components/icons/Speed"; +import Verification from "../src/components/icons/Verification"; +import Scalability from "../src/components/icons/Scalability"; + +export const FeatureList = [ + { + title: translate({ + id: "homepage.featureList.security.title", + message: "Secure data exchange", + }), + icon: , + description: translate({ + id: "homepage.featureList.security.description", + message: + "Fast and secure data synchronization with layer 2 solutions – including bridges, sidechains, and rollups – as well as applications like light wallets.", + }), + }, + { + title: translate({ + id: "homepage.featureList.speed.title", + message: "Faster node bootstrapping", + }), + icon: , + description: translate({ + id: "homepage.featureList.speed.description", + message: + "Mithril's certified snapshots allow nodes to bootstrap quickly while maintaining the same level of security.", + }), + }, + { + title: translate({ + id: "homepage.featureList.verification.title", + message: "Trustless state verification", + }), + icon: , + description: translate({ + id: "homepage.featureList.verification.description", + message: + "Blockchain data is validated and certified by a minimum share of the stake, enabling secure data exchange between decentralized applications.", + }), + }, + { + title: translate({ + id: "homepage.featureList.scalability.title", + message: "Scalability", + }), + icon: , + description: translate({ + id: "homepage.featureList.scalability.description", + message: + "Stake-based threshold multi-signatures efficiently aggregate individual signatures, ensuring scalability even as the number of participants grows.", + }), + }, +]; diff --git a/docs/website/homepage-content/hero.ts b/docs/website/homepage-content/hero.ts new file mode 100644 index 00000000000..9ba206a1168 --- /dev/null +++ b/docs/website/homepage-content/hero.ts @@ -0,0 +1,12 @@ +import { translate } from "@docusaurus/Translate"; + +export const hero = { + title: translate({ + id: "homepage.hero.title", + message: "Mithril documentation", + }), + standfirst: translate({ + id: "homepage.hero.standfirst", + message: `Mithril is a protocol and network designed for proof-of-stake blockchains. It aims to provide lightweight access to blockchain data with a high degree of security and decentralization.`, + }), +}; diff --git a/docs/website/homepage-content/use-cases.ts b/docs/website/homepage-content/use-cases.ts new file mode 100644 index 00000000000..3b500371737 --- /dev/null +++ b/docs/website/homepage-content/use-cases.ts @@ -0,0 +1,21 @@ +import { translate } from "@docusaurus/Translate"; + +export const useCases = { + nonScrollingText: translate({ + id: "homepage.useCases.nonScrollingText", + message: "Use cases include:", + }), + scrollingText: { + id: "homepage.useCases.scrollingText", + items: [ + "Full node clients", + "Light clients", + "Light wallets", + "Mobile applications", + "Sidechains", + "Bridges", + "Rollups", + "State channels", + ], + }, +}; diff --git a/docs/website/homepage-content/why-mithril.tsx b/docs/website/homepage-content/why-mithril.tsx new file mode 100644 index 00000000000..04c476a50f6 --- /dev/null +++ b/docs/website/homepage-content/why-mithril.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { translate } from "@docusaurus/Translate"; + +export const WhyMithrilContents = { + title: translate({ + id: "homepage.whyMithril.title", + message: "WHY MITHRIL?", + }), + descriptionParagraph: { + id: "homepage.whyMithril.paragraphs", + message: ( +
+

+ The Cardano blockchain offers robust security, but starting up a new + node, syncing it with the network, or exchanging data can be slow and + resource intensive (24GB of RAM, 150GB (and growing) of storage, and + over 24 hours for initial synchronization.) +

+

+ Mithril was developed for Cardano as part of the Basho development + phase to support optimization, scalability, and interoperability. +

+
+ ), + }, + timeline: ["Byron", "Shelley", "Goguen", "Basho", "Voltaire"], +}; diff --git a/docs/website/package-lock.json b/docs/website/package-lock.json index 5907dbb1329..8d72ba61554 100644 --- a/docs/website/package-lock.json +++ b/docs/website/package-lock.json @@ -1,12 +1,12 @@ { "name": "mithril-doc", - "version": "0.1.55", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mithril-doc", - "version": "0.1.55", + "version": "0.2.0", "dependencies": { "@docusaurus/core": "^3.8.0", "@docusaurus/plugin-client-redirects": "^3.8.0", @@ -14,6 +14,8 @@ "@docusaurus/preset-classic": "^3.8.0", "@docusaurus/theme-mermaid": "^3.8.0", "clsx": "^2.1.1", + "cva": "^1.0.0-beta.4", + "framer-motion": "^11.3.19", "react": "^18.3.1", "react-dom": "^18.3.1", "redocusaurus": "^2.5.0", @@ -21,7 +23,9 @@ "remark-math": "^6.0.0" }, "devDependencies": { - "prettier": "3.3.2" + "autoprefixer": "^10.4.19", + "prettier": "3.3.2", + "tailwindcss": "^3.4.7" } }, "node_modules/@algolia/autocomplete-core": { @@ -237,6 +241,18 @@ "node": ">= 14.0.0" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -3785,6 +3801,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -3953,6 +4013,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "license": "MIT", @@ -5273,6 +5343,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.3", "license": "ISC", @@ -5708,6 +5784,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/camelize": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", @@ -6839,6 +6924,25 @@ "version": "3.1.3", "license": "MIT" }, + "node_modules/cva": { + "version": "1.0.0-beta.4", + "resolved": "https://registry.npmjs.org/cva/-/cva-1.0.0-beta.4.tgz", + "integrity": "sha512-F/JS9hScapq4DBVQXcK85l9U91M6ePeXoBMSp7vypzShoefUBxjQTo3g3935PUHgQd+IW77DjbPRIxugy4/GCQ==", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + }, + "peerDependencies": { + "typescript": ">= 4.5.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/cytoscape": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz", @@ -7499,6 +7603,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -7510,6 +7620,12 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "node_modules/dns-packet": { "version": "5.6.1", "license": "MIT", @@ -8433,6 +8549,34 @@ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==" }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data-encoder": { "version": "2.1.4", "license": "MIT", @@ -8467,6 +8611,32 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "11.18.2", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz", + "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==", + "dependencies": { + "motion-dom": "^11.18.1", + "motion-utils": "^11.18.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -9738,6 +9908,21 @@ "node": ">=0.10.0" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -12448,6 +12633,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mlly": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", @@ -12531,6 +12725,19 @@ } } }, + "node_modules/motion-dom": { + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", + "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==", + "dependencies": { + "motion-utils": "^11.18.1" + } + }, + "node_modules/motion-utils": { + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz", + "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==" + }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -12555,6 +12762,17 @@ "multicast-dns": "cli.js" } }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -12831,6 +13049,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -13054,6 +13281,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "node_modules/package-manager-detector": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", @@ -13201,6 +13434,28 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/path-to-regexp": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", @@ -13242,6 +13497,24 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/pkg-dir": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", @@ -13841,6 +14114,42 @@ "postcss": "^8.4" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, "node_modules/postcss-lab-function": { "version": "7.0.10", "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.10.tgz", @@ -13869,6 +14178,53 @@ "postcss": "^8.4" } }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/postcss-loader": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", @@ -14100,6 +14456,31 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, "node_modules/postcss-nesting": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", @@ -15068,6 +15449,15 @@ "react": "^18.0.0 || ^19.0.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "license": "MIT", @@ -16445,6 +16835,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "license": "MIT", @@ -16504,6 +16915,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", @@ -16636,6 +17060,81 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==" }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "7.2.0", "license": "MIT", @@ -16720,6 +17219,55 @@ "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "license": "MIT", @@ -16845,6 +17393,27 @@ "version": "2.20.3", "license": "MIT" }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/thunky": { "version": "1.1.0", "license": "MIT" @@ -16927,6 +17496,12 @@ "node": ">=6.10" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, "node_modules/tslib": { "version": "2.6.2", "license": "0BSD" @@ -17973,6 +18548,44 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "license": "MIT", diff --git a/docs/website/package.json b/docs/website/package.json index 015700826fa..3b1a800cb03 100644 --- a/docs/website/package.json +++ b/docs/website/package.json @@ -1,6 +1,6 @@ { "name": "mithril-doc", - "version": "0.1.55", + "version": "0.2.0", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -26,7 +26,9 @@ "react-dom": "^18.3.1", "redocusaurus": "^2.5.0", "rehype-katex": "^7.0.1", - "remark-math": "^6.0.0" + "remark-math": "^6.0.0", + "framer-motion": "^11.3.19", + "cva": "^1.0.0-beta.4" }, "browserslist": { "production": [ @@ -41,6 +43,8 @@ ] }, "devDependencies": { - "prettier": "3.3.2" + "prettier": "3.3.2", + "tailwindcss": "^3.4.7", + "autoprefixer": "^10.4.19" } } diff --git a/docs/website/src/components/AnimatedText.tsx b/docs/website/src/components/AnimatedText.tsx new file mode 100644 index 00000000000..6a268bc1a3d --- /dev/null +++ b/docs/website/src/components/AnimatedText.tsx @@ -0,0 +1,74 @@ +import React, { FC } from "react"; +import { motion } from "framer-motion"; + +const processText = (children: React.ReactNode): React.ReactNode => + React.Children.map(children, (child) => { + if (typeof child === "string") { + return child.split(" ").map((word, index) => ( + + {word.split("").map((char, charIndex) => ( + + {char} + {charIndex === word.length - 1 && ( +   + )} + + ))} + + )); + } + + if (React.isValidElement(child)) { + //@ts-ignore + const processedText = processText(child.props.children); + //@ts-ignore + return React.cloneElement(child, child.props, processedText); + } + }); + +const AnimatedText: FC = () => { + return ( +
+ + {processText( +

+ Choosing Mithril means opting for a scalable, secure, and versatile + enhancement to the Cardano blockchain +

, + )} +
+
+ ); +}; + +export default AnimatedText; diff --git a/docs/website/src/components/Features.tsx b/docs/website/src/components/Features.tsx new file mode 100644 index 00000000000..1573dbaaea5 --- /dev/null +++ b/docs/website/src/components/Features.tsx @@ -0,0 +1,67 @@ +import React, { FC } from "react"; +import { motion } from "framer-motion"; +import { FeatureList } from "../../homepage-content/features"; +import useMediaQuery from "../hooks/useMediaQuery"; +import { forTablet } from "../../helpers/media-queries"; + +type Props = { + icon: React.JSX.Element; + title: string; + description: string; + index: number; +}; + +const Feature: FC = ({ icon, title, description, index }) => { + const isTabletUp = useMediaQuery(forTablet); + + return ( + +
+ {icon} +

+ {title} +

+
+

{description}

+
+ ); +}; + +const Features: FC = () => { + return ( +
+
+ + FEATURES + + + {FeatureList.map((props, idx) => ( + + ))} + +
+
+ ); +}; + +export default Features; diff --git a/docs/website/src/components/HomepageFeatures/index.js b/docs/website/src/components/HomepageFeatures/index.js deleted file mode 100644 index a8f3b681e74..00000000000 --- a/docs/website/src/components/HomepageFeatures/index.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; -import clsx from "clsx"; -import styles from "./styles.module.css"; - -const FeatureList = [ - { - title: "User manual", - Svg: require("@site/static/img/card-get-started.svg").default, - description: ( - <> - Read about how to get started and explore guides, installation instructions, and developer - docs. - - ), - link: "/doc/manual/welcome", - }, - { - title: "The Mithril protocol", - Svg: require("@site/static/img/card-native-tokens.svg").default, - description: ( - <>Discover how the Mithril protocol works and find more about the Mithril multi signature. - ), - link: "/doc/mithril/mithril-protocol/protocol", - }, - { - title: "The Mithril network", - Svg: require("@site/static/img/card-operate-a-stake-pool.svg").default, - description: ( - <>Learn about the Mithril network and find more about its nodes and architecture. - ), - link: "/doc/mithril/mithril-network/architecture", - }, -]; - -function Feature({ Svg, title, description, link }) { - return ( -
-
- - - -
-
-

- {title} -

-

{description}

-
-
- ); -} - -export default function HomepageFeatures() { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/docs/website/src/components/HomepageFeatures/styles.module.css b/docs/website/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2e5de..00000000000 --- a/docs/website/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/docs/website/src/components/HomepageHero.tsx b/docs/website/src/components/HomepageHero.tsx new file mode 100644 index 00000000000..b0d751f8be4 --- /dev/null +++ b/docs/website/src/components/HomepageHero.tsx @@ -0,0 +1,73 @@ +import React, { FC } from "react"; +import Link from "@docusaurus/Link"; +import { forTablet } from "../../helpers/media-queries"; +import { motion } from "framer-motion"; +import { hero } from "../../homepage-content/hero"; + +const HomepageHero: FC = () => { + return ( +
+ +
+
+
+ + {hero.title} + + + {hero.standfirst} + +
+ + + Learn more + + +
+
+
+ ); +}; + +export default HomepageHero; diff --git a/docs/website/src/components/UseCases.tsx b/docs/website/src/components/UseCases.tsx new file mode 100644 index 00000000000..2aba2dbc4e2 --- /dev/null +++ b/docs/website/src/components/UseCases.tsx @@ -0,0 +1,80 @@ +import React, { FC, useEffect, useState } from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import Link from "@docusaurus/Link"; +import { useCases } from "../../homepage-content/use-cases"; + +const processItems = (items: string[]): React.ReactNode => { + const [index, setIndex] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setIndex((prev) => (prev + 1) % items.length); + }, 2500); + + return () => clearInterval(interval); + }, []); + return ( + + + {items[index]} + + + ); +}; +const UseCases: FC = () => { + return ( +
+ +

+ {useCases.nonScrollingText} + {processItems(useCases.scrollingText.items)} +

+ + Learn more + +
+
+ ); +}; + +export default UseCases; diff --git a/docs/website/src/components/WhyMithril.tsx b/docs/website/src/components/WhyMithril.tsx new file mode 100644 index 00000000000..32289bca881 --- /dev/null +++ b/docs/website/src/components/WhyMithril.tsx @@ -0,0 +1,131 @@ +import React, { FC, useRef } from "react"; +import { + motion, + useScroll, + useTransform, + useSpring, + useMotionTemplate, +} from "framer-motion"; +import { WhyMithrilContents } from "../../homepage-content/why-mithril"; +import { cx } from "cva"; +import Link from "@docusaurus/Link"; + +const WhyMithril: FC = () => { + const containerRef = useRef(null); + + const { scrollYProgress } = useScroll({ + target: containerRef, + offset: ["start end", "end start"], + }); + + return ( +
+
+ + {WhyMithrilContents.title} + + +
+
+ {WhyMithrilContents.timeline.map((item, index) => { + const start = 0.07 + index * 0.07; + const end = start + 0.3; + + const z = useTransform( + scrollYProgress, + [start, (start + end) / 2, end], + [-200, 0, 200], + ); + const opacity = useTransform( + scrollYProgress, + [start, (start + end) / 2, end], + [0, 1, 0], + ); + const blur = useTransform( + scrollYProgress, + [start, (start + end) / 1.8, end], + [5, 0, 100], + ); + + const springZ = useSpring(z, { stiffness: 100, damping: 30 }); + const springOpacity = useSpring(opacity, { + stiffness: 100, + damping: 30, + }); + const springBlur = useSpring(blur, { + stiffness: 100, + damping: 30, + }); + + const transform = useMotionTemplate`translateZ(${springZ}px)`; + const filter = useMotionTemplate`blur(${springBlur}px)`; + + const alignments = [ + "flex-start", + "flex-end", + "flex-start", + "center", + "flex-end", + ]; + + return ( + + {item} + + ); + })} +
+ + + {WhyMithrilContents.descriptionParagraph.message} + + Learn more + + +
+
+
+ ); +}; + +export default WhyMithril; diff --git a/docs/website/src/components/icons/Discord.tsx b/docs/website/src/components/icons/Discord.tsx new file mode 100644 index 00000000000..9a34d431cee --- /dev/null +++ b/docs/website/src/components/icons/Discord.tsx @@ -0,0 +1,18 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Discord = (props: SVGProps) => ( + + + +); + +export default Discord; diff --git a/docs/website/src/components/icons/Github.tsx b/docs/website/src/components/icons/Github.tsx new file mode 100644 index 00000000000..252be9b0f95 --- /dev/null +++ b/docs/website/src/components/icons/Github.tsx @@ -0,0 +1,20 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Github = (props: SVGProps) => ( + + + +); + +export default Github; diff --git a/docs/website/src/components/icons/Scalability.tsx b/docs/website/src/components/icons/Scalability.tsx new file mode 100644 index 00000000000..843a8b6602a --- /dev/null +++ b/docs/website/src/components/icons/Scalability.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Scalability = (props: SVGProps) => ( + + + + + + + + + + + + + + +); + +export default Scalability; diff --git a/docs/website/src/components/icons/Security.tsx b/docs/website/src/components/icons/Security.tsx new file mode 100644 index 00000000000..1ec8ab95298 --- /dev/null +++ b/docs/website/src/components/icons/Security.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Security = (props: SVGProps) => ( + + + + + + + + + +); + +export default Security; diff --git a/docs/website/src/components/icons/Speed.tsx b/docs/website/src/components/icons/Speed.tsx new file mode 100644 index 00000000000..cb47318f1b8 --- /dev/null +++ b/docs/website/src/components/icons/Speed.tsx @@ -0,0 +1,40 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Speed = (props: SVGProps) => ( + + + + + + + + + +); + +export default Speed; diff --git a/docs/website/src/components/icons/Verification.tsx b/docs/website/src/components/icons/Verification.tsx new file mode 100644 index 00000000000..107c6885424 --- /dev/null +++ b/docs/website/src/components/icons/Verification.tsx @@ -0,0 +1,40 @@ +import * as React from "react"; +import { SVGProps } from "react"; +const Verification = (props: SVGProps) => ( + + + + + + + + + +); + +export default Verification; diff --git a/docs/website/src/context/PageContext.ts b/docs/website/src/context/PageContext.ts new file mode 100644 index 00000000000..ea895ba158f --- /dev/null +++ b/docs/website/src/context/PageContext.ts @@ -0,0 +1,10 @@ +import { createContext } from "react"; + +export enum PageType { + Landing = "Landing", + Default = "Default", +} + +export const PageContext = createContext({ + page: PageType.Default, +}); diff --git a/docs/website/src/css/custom.css b/docs/website/src/css/custom.css index 243344cd8b3..608a6deb3d3 100644 --- a/docs/website/src/css/custom.css +++ b/docs/website/src/css/custom.css @@ -11,19 +11,76 @@ * https://docusaurus.io/docs/styling-layout#styling-your-site-with-infima */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@font-face { + font-family: "Lexend"; + font-weight: 400; + src: url("/fonts/Lexend-VariableFont.ttf"); + font-display: swap; +} + +@font-face { + font-family: "Lexend"; + font-weight: 500; + src: url("/fonts/Lexend-VariableFont.ttf"); + font-display: swap; +} + +@font-face { + font-family: "Lexend"; + font-weight: 600; + src: url("/fonts/Lexend-VariableFont.ttf"); + font-display: swap; +} + +@font-face { + font-family: "Inter"; + font-weight: 400; + src: url("/fonts/Inter-VariableFont.ttf"); + font-display: swap; +} + +@font-face { + font-family: "Inter"; + font-weight: 400; + font-style: italic; + src: url("/fonts/Inter-Italic-VariableFont.ttf"); + font-display: swap; +} + +@font-face { + font-family: "Inter"; + font-weight: 700; + src: url("/fonts/Inter-VariableFont.ttf"); + font-display: swap; +} + :root { - --ifm-color-primary: #0969da; - --ifm-color-primary-dark: #085ec4; - --ifm-color-primary-darker: #0859b9; - --ifm-color-primary-darkest: #064999; - --ifm-color-primary-light: #0a73f0; - --ifm-color-primary-lighter: #1079f5; - --ifm-color-primary-lightest: #318cf6; + --ifm-color-primary: #397589; + --ifm-color-primary-dark: #397589; + --ifm-color-primary-darker: #397589; + --ifm-color-primary-darkest: #397589; + --ifm-color-primary-light: #65cfe1; + --ifm-color-primary-lighter: #65cfe1; + --ifm-color-primary-lightest: #65cfe1; --ifm-code-font-size: 95%; + + --ifm-navbar-height: 60px; + + font-family: "Inter"; +} + +@media (min-width: 768px) { + :root { + --ifm-navbar-height: 96px; + } } /* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme="dark"] { +/* [data-theme="dark"] { --ifm-color-primary: #669fe1; --ifm-color-primary-dark: #4b8edc; --ifm-color-primary-darker: #3d85d9; @@ -31,6 +88,79 @@ --ifm-color-primary-light: #81b0e6; --ifm-color-primary-lighter: #8fb9e9; --ifm-color-primary-lightest: #b8d2f1; +} */ + +h1, +h2, +h3, +h4 { + font-family: "Lexend"; +} + +h5, +h6 { + font-family: "Inter"; +} + +h1 { + font-size: 2.5rem; + font-weight: 500; +} + +h2 { + font-size: 2rem; +} + +h3 { + font-size: 1.5rem; +} + +.pageContainer { + max-width: 1280px; + width: 100%; + margin-left: auto; + margin-right: auto; + padding-left: 24px; + padding-right: 24px; +} + +@media (min-width: 768px) { + .pageContainer { + padding-left: 48px; + padding-right: 48px; + } +} + +.component { + padding-top: 72px; + padding-bottom: 72px; +} + +.teal-gradient { + background: linear-gradient(to right, #397589, #65cfe1); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + color: transparent; +} + +.use-case-text { + background: #01193c; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + color: transparent; +} + +.navbar__item { + font-weight: 600; + font-size: 1rem; + line-height: 2rem; +} + +.navbar__items { + display: flex !important; + font-family: "Lexend"; } .docusaurus-highlight-code-line { @@ -44,19 +174,6 @@ background-color: rgba(0, 0, 0, 0.3); } -.header-github-link:before { - background: url("/static/img/GitHub-Mark-32px.png") no-repeat; - background-size: cover; - display: flex; - content: ""; - height: 24px; - width: 24px; -} - -[data-theme="dark"] .header-github-link { - filter: invert(1); -} - @media screen and (max-width: 996px) { .footer { text-align: center; @@ -75,3 +192,113 @@ div[role="banner"] { div[role="banner"] div { font-size: 90%; } + +.announcementBarClose_gvF7 { + color: var(--ifm-color-white); +} + +.announcementBarClose_gvF7 > svg { + width: 12px; +} + +.announcementBarClose_gvF7 > svg > g { + stroke-width: 2; +} + +.announcementBar_mb4j { + border-bottom: 0px !important; +} + +@media (min-width: 768px) { + .theme-doc-version-badge { + margin-bottom: 16px !important; + } +} + +.col--7 .markdown { + padding: 0 !important; +} + +.breadcrumbHomeIcon_src-theme-DocBreadcrumbs-Items-Home-styles-module { + height: 100% !important; + width: 100% !important; +} + +.breadcrumbs__link { + margin-bottom: -8px !important; +} + +.menu__link--active { + font-weight: 700; +} + +a.menu__link { + text-decoration: none !important; + -webkit-text-decoration: none !important; +} + +.markdown ul, +.markdown ol { + padding-left: 2rem; + margin: 1rem 0; +} + +.markdown ul { + list-style-type: disc; +} + +.markdown ol { + list-style-type: decimal; +} + +.markdown li { + margin: 0.25rem 0; +} + +.markdown p { + margin-bottom: 1.5rem; +} + +.markdown a { + text-decoration: underline; + text-underline-offset: 2px; +} + +.markdown h1, +.markdown h2, +.markdown h3, +.markdown h4 { + margin-bottom: 1rem; + font-weight: 700; +} + +.title_f1Hy { + font-weight: 700; +} + +.markdown h3 { + font-size: 1.5rem !important; +} + +.admonitionHeading_Gvgb { + display: flex; + align-items: center; +} + +.card { + text-decoration: none !important; +} + +.markdown table a { + text-decoration: none !important; +} + +.theme-edit-this-page { + display: flex; + align-items: center; +} + +.stuck-grid { + perspective: 500px; + transform-style: preserve-3d; +} diff --git a/docs/website/src/hooks/useIsLandingPage.ts b/docs/website/src/hooks/useIsLandingPage.ts new file mode 100644 index 00000000000..9235d597aa6 --- /dev/null +++ b/docs/website/src/hooks/useIsLandingPage.ts @@ -0,0 +1,8 @@ +import { useContext } from "react"; +import { PageContext, PageType } from "../context/PageContext"; + +export function useIsLandingPage() { + const context = useContext(PageContext); + + return context && context.page === PageType.Landing; +} diff --git a/docs/website/src/hooks/useMediaQuery.ts b/docs/website/src/hooks/useMediaQuery.ts new file mode 100644 index 00000000000..b0c47c5dcd9 --- /dev/null +++ b/docs/website/src/hooks/useMediaQuery.ts @@ -0,0 +1,19 @@ +import { useEffect, useState } from "react"; + +export default function useMediaQuery(query: string) { + const [match, setMatch] = useState(false); + + useEffect(() => { + const matchMedia = window.matchMedia(query); + const listener = (e: MediaQueryListEvent) => { + if (process.env.NODE_ENV !== "production") { + console.info(`Media query change: ${query}`, e.matches); + } + setMatch(e.matches); + }; + matchMedia.addEventListener("change", listener); + setMatch(matchMedia.matches); + return () => matchMedia.removeEventListener("change", listener); + }, [query]); + return match; +} diff --git a/docs/website/src/pages/index.js b/docs/website/src/pages/index.js deleted file mode 100644 index 20efa4c6be1..00000000000 --- a/docs/website/src/pages/index.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from "react"; -import clsx from "clsx"; -import Layout from "@theme/Layout"; -import Link from "@docusaurus/Link"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import styles from "./index.module.css"; -import HomepageFeatures from "@site/src/components/HomepageFeatures"; - -function HomepageHeader() { - const { siteConfig } = useDocusaurusContext(); - return ( -
-
-

{siteConfig.title}

-

{siteConfig.tagline}

-
- - Getting Started - 5min ⏱️ - -
-
-
- ); -} - -export default function Home() { - const { siteConfig } = useDocusaurusContext(); - return ( - - -
- -
-
- ); -} diff --git a/docs/website/src/pages/index.tsx b/docs/website/src/pages/index.tsx new file mode 100644 index 00000000000..2f886200810 --- /dev/null +++ b/docs/website/src/pages/index.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import Layout from "@theme/Layout"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import { PageContext, PageType } from "../context/PageContext"; +import HomepageHero from "../components/HomepageHero"; +import Features from "../components/Features"; +import WhyMithril from "../components/WhyMithril"; +import AnimatedText from "../components/AnimatedText"; +import UseCases from "../components/UseCases"; + +export default function Home() { + const { siteConfig } = useDocusaurusContext(); + return ( + +
+ + +
+ + + + +
+
+
+
+ ); +} diff --git a/docs/website/src/theme/Footer/Copyright/index.tsx b/docs/website/src/theme/Footer/Copyright/index.tsx new file mode 100644 index 00000000000..508da70acb0 --- /dev/null +++ b/docs/website/src/theme/Footer/Copyright/index.tsx @@ -0,0 +1,13 @@ +import React, { type ReactNode } from "react"; +import type { Props } from "@theme/Footer/Copyright"; + +export default function FooterCopyright({ copyright }: Props): ReactNode { + return ( +
+ ); +} diff --git a/docs/website/src/theme/Footer/Layout/index.tsx b/docs/website/src/theme/Footer/Layout/index.tsx new file mode 100644 index 00000000000..dbf8df940e8 --- /dev/null +++ b/docs/website/src/theme/Footer/Layout/index.tsx @@ -0,0 +1,23 @@ +import React, { type ReactNode } from "react"; +import type { Props } from "@theme/Footer/Layout"; +import clsx from "clsx"; + +export default function FooterLayout({ + links, + logo, + copyright, +}: Props): ReactNode { + return ( +
+
+ {links} + {(logo || copyright) && ( +
+ {logo &&
{logo}
} + {copyright} +
+ )} +
+
+ ); +} diff --git a/docs/website/src/theme/Footer/LinkItem/index.tsx b/docs/website/src/theme/Footer/LinkItem/index.tsx new file mode 100644 index 00000000000..5aedc324ba6 --- /dev/null +++ b/docs/website/src/theme/Footer/LinkItem/index.tsx @@ -0,0 +1,28 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; + +import type { Props } from "@theme/Footer/LinkItem"; + +export default function FooterLinkItem({ item }: Props): ReactNode { + const { to, href, label, prependBaseUrlToHref, className, ...props } = item; + const toUrl = useBaseUrl(to); + const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true }); + + return ( + + {label} + + ); +} diff --git a/docs/website/src/theme/Footer/Links/MultiColumn/index.tsx b/docs/website/src/theme/Footer/Links/MultiColumn/index.tsx new file mode 100644 index 00000000000..dec1797ad7e --- /dev/null +++ b/docs/website/src/theme/Footer/Links/MultiColumn/index.tsx @@ -0,0 +1,45 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import LinkItem from "@theme/Footer/LinkItem"; +import type { Props } from "@theme/Footer/Links/MultiColumn"; + +type ColumnType = Props["columns"][number]; +type ColumnItemType = ColumnType["items"][number]; + +function ColumnLinkItem({ item }: { item: ColumnItemType }) { + return item.html ? ( +
  • + ) : ( +
  • + +
  • + ); +} + +function Column({ column }: { column: ColumnType }) { + return ( +
    +
    {column.title}
    +
      + {column.items.map((item, i) => ( + + ))} +
    +
    + ); +} + +export default function FooterLinksMultiColumn({ columns }: Props): ReactNode { + return ( +
    + {columns.map((column, i) => ( + + ))} +
    + ); +} diff --git a/docs/website/src/theme/Footer/Links/Simple/index.tsx b/docs/website/src/theme/Footer/Links/Simple/index.tsx new file mode 100644 index 00000000000..fc4f2ec25be --- /dev/null +++ b/docs/website/src/theme/Footer/Links/Simple/index.tsx @@ -0,0 +1,36 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import LinkItem from "@theme/Footer/LinkItem"; +import type { Props } from "@theme/Footer/Links/Simple"; + +function Separator() { + return ·; +} + +function SimpleLinkItem({ item }: { item: Props["links"][number] }) { + return item.html ? ( + + ) : ( + + ); +} + +export default function FooterLinksSimple({ links }: Props): ReactNode { + return ( +
    +
    + {links.map((item, i) => ( + + + {links.length !== i + 1 && } + + ))} +
    +
    + ); +} diff --git a/docs/website/src/theme/Footer/Links/index.tsx b/docs/website/src/theme/Footer/Links/index.tsx new file mode 100644 index 00000000000..76bd9f47bfd --- /dev/null +++ b/docs/website/src/theme/Footer/Links/index.tsx @@ -0,0 +1,14 @@ +import React, { type ReactNode } from "react"; + +import { isMultiColumnFooterLinks } from "@docusaurus/theme-common"; +import FooterLinksMultiColumn from "@theme/Footer/Links/MultiColumn"; +import FooterLinksSimple from "@theme/Footer/Links/Simple"; +import type { Props } from "@theme/Footer/Links"; + +export default function FooterLinks({ links }: Props): ReactNode { + return isMultiColumnFooterLinks(links) ? ( + + ) : ( + + ); +} diff --git a/docs/website/src/theme/Footer/Logo/index.tsx b/docs/website/src/theme/Footer/Logo/index.tsx new file mode 100644 index 00000000000..e7427e7320d --- /dev/null +++ b/docs/website/src/theme/Footer/Logo/index.tsx @@ -0,0 +1,43 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import Link from "@docusaurus/Link"; +import { useBaseUrlUtils } from "@docusaurus/useBaseUrl"; +import ThemedImage from "@theme/ThemedImage"; +import type { Props } from "@theme/Footer/Logo"; + +import styles from "./styles.module.css"; + +function LogoImage({ logo }: Props) { + const { withBaseUrl } = useBaseUrlUtils(); + const sources = { + light: withBaseUrl(logo.src), + dark: withBaseUrl(logo.srcDark ?? logo.src), + }; + return ( + + ); +} + +export default function FooterLogo({ logo }: Props): ReactNode { + return logo.href ? ( + + + + ) : ( +
    + +

    Mithril

    +
    + ); +} diff --git a/docs/website/src/theme/Footer/Logo/styles.module.css b/docs/website/src/theme/Footer/Logo/styles.module.css new file mode 100644 index 00000000000..faf0e60f3e1 --- /dev/null +++ b/docs/website/src/theme/Footer/Logo/styles.module.css @@ -0,0 +1,9 @@ +.footerLogoLink { + opacity: 0.5; + transition: opacity var(--ifm-transition-fast) + var(--ifm-transition-timing-default); +} + +.footerLogoLink:hover { + opacity: 1; +} diff --git a/docs/website/src/theme/Footer/index.tsx b/docs/website/src/theme/Footer/index.tsx new file mode 100644 index 00000000000..a7862df9410 --- /dev/null +++ b/docs/website/src/theme/Footer/index.tsx @@ -0,0 +1,26 @@ +import React, { type ReactNode } from "react"; + +import { useThemeConfig } from "@docusaurus/theme-common"; +import FooterLinks from "@theme/Footer/Links"; +import FooterLogo from "@theme/Footer/Logo"; +import FooterCopyright from "@theme/Footer/Copyright"; +import FooterLayout from "@theme/Footer/Layout"; + +function Footer(): ReactNode { + const { footer } = useThemeConfig(); + if (!footer) { + return null; + } + const { copyright, links, logo, style } = footer; + + return ( + 0 && } + logo={logo && } + copyright={copyright && } + /> + ); +} + +export default React.memo(Footer); diff --git a/docs/website/src/theme/Navbar/Content/index.tsx b/docs/website/src/theme/Navbar/Content/index.tsx new file mode 100644 index 00000000000..2c98c10ac46 --- /dev/null +++ b/docs/website/src/theme/Navbar/Content/index.tsx @@ -0,0 +1,93 @@ +import React from "react"; +import { useThemeConfig, ErrorCauseBoundary } from "@docusaurus/theme-common"; +import { + splitNavbarItems, + useNavbarMobileSidebar, +} from "@docusaurus/theme-common/internal"; +import NavbarItem from "@theme/NavbarItem"; +import NavbarColorModeToggle from "@theme/Navbar/ColorModeToggle"; +import SearchBar from "@theme/SearchBar"; +import NavbarMobileSidebarToggle from "@theme/Navbar/MobileSidebar/Toggle"; +import NavbarLogo from "@theme/Navbar/Logo"; +import NavbarSearch from "@theme/Navbar/Search"; +import styles from "./styles.module.css"; +import Discord from "../../../components/icons/Discord"; +import Github from "../../../components/icons/Github"; + +function useNavbarItems() { + // TODO temporary casting until ThemeConfig type is improved + return useThemeConfig().navbar.items; +} +function NavbarItems({ items }) { + return ( + <> + {items.map((item, i) => ( + + new Error( + `A theme navbar item failed to render. +Please double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config: +${JSON.stringify(item, null, 2)}`, + { cause: error }, + ) + } + > + + + ))} + + ); +} +function NavbarContentLayout({ left, right }) { + return ( +
    +
    {left}
    +
    {right}
    +
    + ); +} +export default function NavbarContent() { + const mobileSidebar = useNavbarMobileSidebar(); + const items = useNavbarItems(); + const [leftItems, rightItems] = splitNavbarItems(items); + const searchBarItem = items.find((item) => item.type === "search"); + return ( + + + + + } + right={ + <> + + + {!searchBarItem && ( + + + + )} + + + + + + + {!mobileSidebar.disabled && } + + } + /> + ); +} diff --git a/docs/website/src/theme/Navbar/Content/styles.module.css b/docs/website/src/theme/Navbar/Content/styles.module.css new file mode 100644 index 00000000000..4c9471e1098 --- /dev/null +++ b/docs/website/src/theme/Navbar/Content/styles.module.css @@ -0,0 +1,8 @@ +/* +Hide color mode toggle in small viewports + */ +@media (max-width: 996px) { + .colorModeToggle { + display: none; + } +} diff --git a/docs/website/src/theme/Navbar/Layout/index.tsx b/docs/website/src/theme/Navbar/Layout/index.tsx new file mode 100644 index 00000000000..7072c3c07d8 --- /dev/null +++ b/docs/website/src/theme/Navbar/Layout/index.tsx @@ -0,0 +1,77 @@ +import React from "react"; +import clsx from "clsx"; +import { useThemeConfig } from "@docusaurus/theme-common"; +import { + useHideableNavbar, + useNavbarMobileSidebar, +} from "@docusaurus/theme-common/internal"; +import { translate } from "@docusaurus/Translate"; +import NavbarMobileSidebar from "@theme/Navbar/MobileSidebar"; +import styles from "./styles.module.css"; + +import { useScroll, motion, useTransform } from "framer-motion"; +import { useIsLandingPage } from "../../../hooks/useIsLandingPage"; + +function NavbarBackdrop(props) { + return ( +
    + ); +} +export default function NavbarLayout({ children }) { + const { scrollY } = useScroll(); + const y = useTransform( + scrollY, + [0, 70], + ["rgba(255, 255, 255, 0)", "rgba(255, 255, 255, 0.96)"], + ); + const isLandingPage = useIsLandingPage(); + const { + navbar: { hideOnScroll }, + } = useThemeConfig(); + const mobileSidebar = useNavbarMobileSidebar(); + const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll); + return ( + +
    + {children} +
    + + +
    + ); +} diff --git a/docs/website/src/theme/Navbar/Layout/styles.module.css b/docs/website/src/theme/Navbar/Layout/styles.module.css new file mode 100644 index 00000000000..e72891a44ff --- /dev/null +++ b/docs/website/src/theme/Navbar/Layout/styles.module.css @@ -0,0 +1,7 @@ +.navbarHideable { + transition: transform var(--ifm-transition-fast) ease; +} + +.navbarHidden { + transform: translate3d(0, calc(-100% - 2px), 0); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/Header/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/Header/index.tsx new file mode 100644 index 00000000000..b2af39a48a7 --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/Header/index.tsx @@ -0,0 +1,34 @@ +import React, { type ReactNode } from "react"; +import { useNavbarMobileSidebar } from "@docusaurus/theme-common/internal"; +import { translate } from "@docusaurus/Translate"; +import NavbarColorModeToggle from "@theme/Navbar/ColorModeToggle"; +import IconClose from "@theme/Icon/Close"; +import NavbarLogo from "@theme/Navbar/Logo"; + +function CloseButton() { + const mobileSidebar = useNavbarMobileSidebar(); + return ( + + ); +} + +export default function NavbarMobileSidebarHeader(): ReactNode { + return ( +
    + + + +
    + ); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/Layout/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/Layout/index.tsx new file mode 100644 index 00000000000..18659aa1846 --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/Layout/index.tsx @@ -0,0 +1,25 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import { useNavbarSecondaryMenu } from "@docusaurus/theme-common/internal"; +import type { Props } from "@theme/Navbar/MobileSidebar/Layout"; + +export default function NavbarMobileSidebarLayout({ + header, + primaryMenu, + secondaryMenu, +}: Props): ReactNode { + const { shown: secondaryMenuShown } = useNavbarSecondaryMenu(); + return ( +
    + {header} +
    +
    {primaryMenu}
    +
    {secondaryMenu}
    +
    +
    + ); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx new file mode 100644 index 00000000000..4e8f3d918c6 --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx @@ -0,0 +1,40 @@ +import React, { type ReactNode } from "react"; +import { useThemeConfig } from "@docusaurus/theme-common"; +import { useNavbarMobileSidebar } from "@docusaurus/theme-common/internal"; +import NavbarItem, { type Props as NavbarItemConfig } from "@theme/NavbarItem"; +import Discord from "../../../../components/icons/Discord"; + +function useNavbarItems() { + // TODO temporary casting until ThemeConfig type is improved + return useThemeConfig().navbar.items as NavbarItemConfig[]; +} + +// The primary menu displays the navbar items +export default function NavbarMobilePrimaryMenu(): ReactNode { + const mobileSidebar = useNavbarMobileSidebar(); + + // TODO how can the order be defined for mobile? + // Should we allow providing a different list of items? + const items = useNavbarItems(); + + return ( +
      + {items.map((item, i) => ( + mobileSidebar.toggle()} + key={i} + /> + ))} + + + +
    + ); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx new file mode 100644 index 00000000000..cc9aa9eea34 --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx @@ -0,0 +1,33 @@ +import React, { type ComponentProps, type ReactNode } from "react"; +import { useThemeConfig } from "@docusaurus/theme-common"; +import { useNavbarSecondaryMenu } from "@docusaurus/theme-common/internal"; +import Translate from "@docusaurus/Translate"; + +function SecondaryMenuBackButton(props: ComponentProps<"button">) { + return ( + + ); +} + +// The secondary menu slides from the right and shows contextual information +// such as the docs sidebar +export default function NavbarMobileSidebarSecondaryMenu(): ReactNode { + const isPrimaryMenuEmpty = useThemeConfig().navbar.items.length === 0; + const secondaryMenu = useNavbarSecondaryMenu(); + return ( + <> + {/* edge-case: prevent returning to the primaryMenu when it's empty */} + {!isPrimaryMenuEmpty && ( + secondaryMenu.hide()} /> + )} + {secondaryMenu.content} + + ); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/Toggle/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/Toggle/index.tsx new file mode 100644 index 00000000000..89237cf77ef --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/Toggle/index.tsx @@ -0,0 +1,24 @@ +import React, { type ReactNode } from "react"; +import { useNavbarMobileSidebar } from "@docusaurus/theme-common/internal"; +import { translate } from "@docusaurus/Translate"; +import IconMenu from "@theme/Icon/Menu"; + +export default function MobileSidebarToggle(): ReactNode { + const { toggle, shown } = useNavbarMobileSidebar(); + return ( + + ); +} diff --git a/docs/website/src/theme/Navbar/MobileSidebar/index.tsx b/docs/website/src/theme/Navbar/MobileSidebar/index.tsx new file mode 100644 index 00000000000..50bf4c629fd --- /dev/null +++ b/docs/website/src/theme/Navbar/MobileSidebar/index.tsx @@ -0,0 +1,26 @@ +import React, { type ReactNode } from "react"; +import { + useLockBodyScroll, + useNavbarMobileSidebar, +} from "@docusaurus/theme-common/internal"; +import NavbarMobileSidebarLayout from "@theme/Navbar/MobileSidebar/Layout"; +import NavbarMobileSidebarHeader from "@theme/Navbar/MobileSidebar/Header"; +import NavbarMobileSidebarPrimaryMenu from "@theme/Navbar/MobileSidebar/PrimaryMenu"; +import NavbarMobileSidebarSecondaryMenu from "@theme/Navbar/MobileSidebar/SecondaryMenu"; + +export default function NavbarMobileSidebar(): ReactNode { + const mobileSidebar = useNavbarMobileSidebar(); + useLockBodyScroll(mobileSidebar.shown); + + if (!mobileSidebar.shouldRender) { + return null; + } + + return ( + } + primaryMenu={} + secondaryMenu={} + /> + ); +} diff --git a/docs/website/src/theme/Navbar/Search/index.tsx b/docs/website/src/theme/Navbar/Search/index.tsx new file mode 100644 index 00000000000..ea6d3d7d325 --- /dev/null +++ b/docs/website/src/theme/Navbar/Search/index.tsx @@ -0,0 +1,16 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import type { Props } from "@theme/Navbar/Search"; + +import styles from "./styles.module.css"; + +export default function NavbarSearch({ + children, + className, +}: Props): ReactNode { + return ( +
    + {children} +
    + ); +} diff --git a/docs/website/src/theme/Navbar/Search/styles.module.css b/docs/website/src/theme/Navbar/Search/styles.module.css new file mode 100644 index 00000000000..9eeb2934d46 --- /dev/null +++ b/docs/website/src/theme/Navbar/Search/styles.module.css @@ -0,0 +1,21 @@ +/* +Workaround to avoid rendering empty search container +See https://github.com/facebook/docusaurus/pull/9385 +*/ +.navbarSearchContainer:empty { + display: none; +} + +@media (max-width: 996px) { + .navbarSearchContainer { + position: absolute; + right: var(--ifm-navbar-padding-horizontal); + } +} + +@media (min-width: 997px) { + .navbarSearchContainer { + padding: var(--ifm-navbar-item-padding-vertical) + var(--ifm-navbar-item-padding-horizontal); + } +} diff --git a/docs/website/src/theme/Navbar/index.tsx b/docs/website/src/theme/Navbar/index.tsx new file mode 100644 index 00000000000..ecae8f8d1c0 --- /dev/null +++ b/docs/website/src/theme/Navbar/index.tsx @@ -0,0 +1,11 @@ +import React, { type ReactNode } from "react"; +import NavbarLayout from "@theme/Navbar/Layout"; +import NavbarContent from "@theme/Navbar/Content"; + +export default function Navbar(): ReactNode { + return ( + + + + ); +} diff --git a/docs/website/static/desktop-mithril-hero-original.mp4 b/docs/website/static/desktop-mithril-hero-original.mp4 new file mode 100644 index 00000000000..d472a162724 Binary files /dev/null and b/docs/website/static/desktop-mithril-hero-original.mp4 differ diff --git a/docs/website/static/desktop-mithril-hero-thumbnail.jpg b/docs/website/static/desktop-mithril-hero-thumbnail.jpg new file mode 100644 index 00000000000..087d1dbe140 Binary files /dev/null and b/docs/website/static/desktop-mithril-hero-thumbnail.jpg differ diff --git a/docs/website/static/fonts/Inter-Italic-VariableFont.ttf b/docs/website/static/fonts/Inter-Italic-VariableFont.ttf new file mode 100644 index 00000000000..43ed4f5ee6c Binary files /dev/null and b/docs/website/static/fonts/Inter-Italic-VariableFont.ttf differ diff --git a/docs/website/static/fonts/Inter-VariableFont.ttf b/docs/website/static/fonts/Inter-VariableFont.ttf new file mode 100644 index 00000000000..e31b51e3e93 Binary files /dev/null and b/docs/website/static/fonts/Inter-VariableFont.ttf differ diff --git a/docs/website/static/fonts/Lexend-VariableFont.ttf b/docs/website/static/fonts/Lexend-VariableFont.ttf new file mode 100644 index 00000000000..b294dc840ff Binary files /dev/null and b/docs/website/static/fonts/Lexend-VariableFont.ttf differ diff --git a/docs/website/static/img/mithril-logo-dark.svg b/docs/website/static/img/mithril-logo-dark.svg new file mode 100644 index 00000000000..3dcbb30b3b9 --- /dev/null +++ b/docs/website/static/img/mithril-logo-dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/website/static/img/mithril-logo-text.svg b/docs/website/static/img/mithril-logo-text.svg new file mode 100644 index 00000000000..576b049936e --- /dev/null +++ b/docs/website/static/img/mithril-logo-text.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/website/static/img/logo.svg b/docs/website/static/img/mithril-logo.svg similarity index 100% rename from docs/website/static/img/logo.svg rename to docs/website/static/img/mithril-logo.svg diff --git a/docs/website/static/mobile-mithril-hero-original.mp4 b/docs/website/static/mobile-mithril-hero-original.mp4 new file mode 100644 index 00000000000..f079e42cd69 Binary files /dev/null and b/docs/website/static/mobile-mithril-hero-original.mp4 differ diff --git a/docs/website/static/mobile-mithril-hero-thumbnail.jpg b/docs/website/static/mobile-mithril-hero-thumbnail.jpg new file mode 100644 index 00000000000..12fd64c1385 Binary files /dev/null and b/docs/website/static/mobile-mithril-hero-thumbnail.jpg differ diff --git a/docs/website/tailwind.config.ts b/docs/website/tailwind.config.ts new file mode 100644 index 00000000000..8e9ba679955 --- /dev/null +++ b/docs/website/tailwind.config.ts @@ -0,0 +1,68 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + content: ["./src/**/*.{js,jsx,ts,tsx}"], + theme: { + backgroundImage: {}, + screens: { + phablet: "640px", + // => @media (min-width: 640px) { ... } + + tablet: "768px", + // => @media (min-width: 768px) { ... } + + laptop: "996px", + // => @media (min-width: 996px) { ... } + + desktop: "1280px", + // => @media (min-width: 1280px) { ... } + }, + fontFamily: { + display: [ + "Bw Gradual", + "ui-sans-serif", + "system-ui", + "sans-serif", + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + body: [ + "var(--font-lexend)", + "ui-sans-serif", + "system-ui", + "sans-serif", + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + }, + colors: { + transparent: "transparent", + current: "currentColor", + blue: { + DEFAULT: "#01193C", + light: "#ECF9FD", + highlight: "#2634AD", + }, + secondary: "#3c9ec8", + black: "#000000", + gray: { + DEFAULT: "#7C8080", + dark: "#99a3b1", + light: "#808C9D", + "extra-light": "#F3F4F4", + border: "#B3BAC5", + }, + white: "#FFFFFF", + cyan: { + DEFAULT: "#65CFE1", + dark: "#397589", + }, + }, + }, + plugins: [], +}; +export default config;