Redesign landing page to focus on OpenTofu's future (#365)
* feat: Redesign landing page to focus on OpenTofu's future This commit introduces a new landing page that shifts focus to OpenTofu's forward momentum and unique capabilities. The redesign: - Highlights OpenTofu's powerful features like state encryption at rest, provider iteration, and early variable evaluation - Simplifies the supporters list to improve readability - Removes the manifesto to streamline the user experience - Provides clearer, more concise examples of OpenTofu's capabilities - Makes it easier for new users to understand OpenTofu's value proposition The new design emphasizes OpenTofu's technical strengths while maintaining a clean, professional appearance that aligns with the project's maturity. Signed-off-by: James Humphries <james@james-humphries.co.uk> * Various fixes and improvements Signed-off-by: James Humphries <james@james-humphries.co.uk>
|
|
@ -101,7 +101,7 @@ const config: Config = {
|
|||
},
|
||||
docs: {
|
||||
includeCurrentVersion: false,
|
||||
lastVersion: 'v1.9',
|
||||
lastVersion: "v1.9",
|
||||
docVersionRootComponent: "@theme/DocVersionRoot",
|
||||
versions: {
|
||||
"v1.6": {
|
||||
|
|
@ -122,12 +122,12 @@ const config: Config = {
|
|||
label: "1.9.x",
|
||||
path: "",
|
||||
},
|
||||
"main": {
|
||||
main: {
|
||||
label: "Development",
|
||||
path: "main",
|
||||
banner: "unreleased",
|
||||
noIndex: true
|
||||
}
|
||||
noIndex: true,
|
||||
},
|
||||
},
|
||||
routeBasePath: "/docs",
|
||||
editUrl: ({ version, docPath }) => {
|
||||
|
|
@ -212,9 +212,8 @@ const config: Config = {
|
|||
announcementBar: {
|
||||
id: "opentofu-ga",
|
||||
content:
|
||||
'Help us test OpenTofu 1.10.0-alpha2! <a href="/blog/help-us-test-opentofu-1-10-0-alpha2/">Check it out here.</a>',
|
||||
backgroundColor: "#ffda18",
|
||||
textColor: "#1b1d20",
|
||||
'<a href="/blog/help-us-test-opentofu-1-10-0-alpha2/" class="announcement-bar-link"><div class="announcement-bar-content">🚀 OpenTofu 1.10.0-alpha2 is released! <span class="announcement-arrow">→</span></div></a>',
|
||||
backgroundColor: "#00000000",
|
||||
isCloseable: false,
|
||||
},
|
||||
algolia: {
|
||||
|
|
@ -224,14 +223,6 @@ const config: Config = {
|
|||
},
|
||||
footer: {
|
||||
links: [
|
||||
{
|
||||
label: "Manifesto",
|
||||
href: "/manifesto",
|
||||
},
|
||||
{
|
||||
label: "Supporters",
|
||||
href: "/supporters",
|
||||
},
|
||||
{
|
||||
label: "FAQs",
|
||||
href: "/faq",
|
||||
|
|
@ -249,16 +240,6 @@ const config: Config = {
|
|||
navbar: {
|
||||
hideOnScroll: true,
|
||||
items: [
|
||||
{
|
||||
to: "/manifesto",
|
||||
label: "Manifesto",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/supporters",
|
||||
label: "Supporters",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/faq",
|
||||
label: "FAQs",
|
||||
|
|
@ -269,6 +250,11 @@ const config: Config = {
|
|||
label: "Blog",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
label: "Registry",
|
||||
href: "https://search.opentofu.org",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
label: "Roadmap",
|
||||
href: "https://github.com/opentofu/opentofu/milestones",
|
||||
|
|
@ -282,27 +268,26 @@ const config: Config = {
|
|||
items: [
|
||||
{
|
||||
label: "v1.9.x (current)",
|
||||
href: "/docs/"
|
||||
href: "/docs/",
|
||||
},
|
||||
{
|
||||
label: "v1.8.x",
|
||||
href: "/docs/v1.8/"
|
||||
href: "/docs/v1.8/",
|
||||
},
|
||||
{
|
||||
label: "v1.7.x",
|
||||
href: "/docs/v1.7/"
|
||||
href: "/docs/v1.7/",
|
||||
},
|
||||
{
|
||||
label: "v1.6.x",
|
||||
href: "/docs/v1.6/"
|
||||
href: "/docs/v1.6/",
|
||||
},
|
||||
{
|
||||
label: "Development",
|
||||
href: "/docs/main/"
|
||||
href: "/docs/main/",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// TODO: This link is important but there's no design for it yet
|
||||
// {
|
||||
// type: "dropdown",
|
||||
|
|
|
|||
44
faq.mdx
|
|
@ -1,26 +1,12 @@
|
|||
<AccordionItem id="what-is-opentofu" summary="What is OpenTofu?" open highlight>
|
||||
<AccordionItem id="why-was-opentofu-created" summary="Why was OpenTofu created?" open highlight>
|
||||
|
||||
OpenTofu is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. OpenTofu can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="why-was-opentofu-created" summary="Why was OpenTofu created?" highlight>
|
||||
|
||||
OpenTofu is a Terraform fork, created as an initiative of Gruntwork, Spacelift, Harness, Env0, Scalr, and others, in response to HashiCorp’s switch from an open-source license to the BUSL. The initiative has many supporters, all of whom are listed [here](/supporters).
|
||||
OpenTofu is a Terraform fork, created as an initiative of Gruntwork, Spacelift, Harness, Env0, Scalr, and others, in response to HashiCorp's switch from an open-source license to the BUSL. The initiative has many supporters, all of whom are listed [here](/supporters).
|
||||
|
||||
The BUSL and the additional use grant outlined by the HashiCorp team are ambiguous, which makes it challenging for companies, vendors, and developers using Terraform to decide whether their actions could be interpreted as being outside the permitted scope of use.
|
||||
|
||||
Hashicorp’s FAQs give some peace of mind to end users and system integrators for now, but the licensing terms’ implications for future usage are unclear. The possibility that the company’s definition of _“competitive”_ or _“embedding”_ could change or the license could be further modified to make it closed source prompts uncertainty for Terraform users.
|
||||
HashiCorp's FAQs give some peace of mind to end users and system integrators for now, but the licensing terms' implications for future usage are unclear. The possibility that the company's definition of _"competitive"_ or _"embedding"_ could change or the license could be further modified to make it closed source prompts uncertainty for Terraform users.
|
||||
|
||||
We firmly believe that Terraform should remain open-source because it is a project many companies use, and many contributors have made Terraform what it is today. Terraform’s success would not have been possible without the community’s work to build many supporting projects around it.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="opentofu-terraform-differences" summary="What are the differences between OpenTofu and Terraform?" highlight>
|
||||
|
||||
On the technical level, OpenTofu 1.6.x is very similar feature-wise to Terraform 1.6.x. In the future, the projects feature sets will diverge.
|
||||
|
||||
The other main difference is that OpenTofu is open-source, and its goal is to be driven in a collaborative way with no single company being able to dictate the roadmap.
|
||||
We firmly believe that Terraform should remain open-source because it is a project many companies use, and many contributors have made Terraform what it is today. Terraform's success would not have been possible without the community's work to build many supporting projects around it.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
|
|
@ -32,11 +18,11 @@ Initial impressions suggest you could use either OpenTofu or Terraform for perso
|
|||
|
||||
#### Consultants
|
||||
|
||||
A consultant should offer their clients the best possible solution that aligns with their budget. OpenTofu will be on par with Terraform, and one of the project’s central objectives is to listen to the community’s issues, so it makes sense to recommend a project that will always stay open-source. Anyone who has used Terraform in the last eight years has probably come across issues that took some time to be resolved. The large community involved in developing OpenTofu means this will no longer be the case.
|
||||
A consultant should offer their clients the best possible solution that aligns with their budget. OpenTofu will be on par with Terraform, and one of the project's central objectives is to listen to the community's issues, so it makes sense to recommend a project that will always stay open-source. Anyone who has used Terraform in the last eight years has probably come across issues that took some time to be resolved. The large community involved in developing OpenTofu means this will no longer be the case.
|
||||
|
||||
#### Companies
|
||||
|
||||
Companies will encounter more difficulties with the situation. Switching to a new project carries risks, but staying with a project that changes its license without warning is far riskier. This risk is minimized by giving OpenTofu to the Linux Foundation, and OpenTofu’s aim of maintaining feature parity with Terraform for future releases reduces the technical risks.
|
||||
Companies will encounter more difficulties with the situation. Switching to a new project carries risks, but staying with a project that changes its license without warning is far riskier. This risk is minimized by giving OpenTofu to the Linux Foundation, and OpenTofu's aim of maintaining feature parity with Terraform for future releases reduces the technical risks.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
|
|
@ -48,22 +34,20 @@ If you're missing a feature in OpenTofu that's available in Terraform, feel free
|
|||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="terraform-replacement" summary="Can I use OpenTofu as a drop-in replacement for Terraform? Is OpenTofu suitable for production use?" highlight>
|
||||
|
||||
Right now, OpenTofu is a drop-in replacement for Terraform, as it's compatible with Terraform versions 1.5.x and most of 1.6.x. You don’t need to make any changes to your code to ensure compatibility.
|
||||
|
||||
OpenTofu is suitable for production use cases without any exception.
|
||||
|
||||
Please see [our migration guide](/docs/intro/migration) for more information.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="state-file" summary="Will OpenTofu work with my existing state file?">
|
||||
|
||||
OpenTofu will work with existing state files up to those created with Terraform versions 1.5.x.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="registry" summary="Where can I find providers and modules for OpenTofu?" highlight>
|
||||
|
||||
The OpenTofu Registry hosts thousands of providers and modules that are compatible with OpenTofu. These include all the popular cloud providers, third-party services, and community-maintained resources you might need for your infrastructure.
|
||||
|
||||
You can search for providers, modules, and their documentation at [search.opentofu.org](https://search.opentofu.org). The registry provides seamless access to the same ecosystem of providers and modules that you're familiar with, ensuring you have all the tools needed to build and manage your infrastructure.
|
||||
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem id="providers" summary="Does OpenTofu work with all the providers Terraform works with?">
|
||||
|
||||
OpenTofu will not have its own providers. Terraform providers have not altered their licenses, and the potential for such a change is virtually zero. OpenTofu works with the current Terraform providers, but it uses a separate registry.
|
||||
|
|
|
|||
59
package-lock.json
generated
|
|
@ -26,6 +26,7 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"framer-motion": "^12.7.4",
|
||||
"postcss": "^8.4.33",
|
||||
"prettier": "^3.1.1",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
|
|
@ -33,6 +34,7 @@
|
|||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-github-btn": "^1.4.0",
|
||||
"swiper": "^11.2.6",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "~5.3.3"
|
||||
},
|
||||
|
|
@ -7643,6 +7645,32 @@
|
|||
"url": "https://github.com/sponsors/rawify"
|
||||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "12.7.4",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.7.4.tgz",
|
||||
"integrity": "sha512-jX0bPsTmU0oPZTYz/dVyD0dmOyEOEJvdn0TaZBE5I8g2GvVnnQnW9f65cJnoVfUkY3WZWNXGXnPbVA9YnaIfVA==",
|
||||
"dependencies": {
|
||||
"motion-dom": "^12.7.4",
|
||||
"motion-utils": "^12.7.2",
|
||||
"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",
|
||||
|
|
@ -12221,6 +12249,19 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.7.4",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.7.4.tgz",
|
||||
"integrity": "sha512-1ZUHAoSUMMxP6jPqyxlk9XUfb6NxMsnWPnH2YGhrOhTURLcXWbETi6eemoKb60Pe32NVJYduL4B62VQSO5Jq8Q==",
|
||||
"dependencies": {
|
||||
"motion-utils": "^12.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-utils": {
|
||||
"version": "12.7.2",
|
||||
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.7.2.tgz",
|
||||
"integrity": "sha512-XhZwqctxyJs89oX00zn3OGCuIIpVevbTa+u82usWBC6pSHUd2AoNWiYa7Du8tJxJy9TFbZ82pcn5t7NOm1PHAw=="
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz",
|
||||
|
|
@ -15900,6 +15941,24 @@
|
|||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/swiper": {
|
||||
"version": "11.2.6",
|
||||
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.6.tgz",
|
||||
"integrity": "sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/swiperjs"
|
||||
},
|
||||
{
|
||||
"type": "open_collective",
|
||||
"url": "http://opencollective.com/swiper"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 4.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"clear": "docusaurus clear",
|
||||
"typecheck": "tsc",
|
||||
"sync-supporters": "node ./sync-supporters.js",
|
||||
"sync-contributor-stats": "node ./scripts/fetch-contributor-stats.js",
|
||||
"prepare": "husky install",
|
||||
"lint": "eslint --cache \"**/*.{js,jsx,ts,tsx}\""
|
||||
},
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"framer-motion": "^12.7.4",
|
||||
"postcss": "^8.4.33",
|
||||
"prettier": "^3.1.1",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
|
|
@ -38,6 +40,7 @@
|
|||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-github-btn": "^1.4.0",
|
||||
"swiper": "^11.2.6",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "~5.3.3"
|
||||
},
|
||||
|
|
|
|||
212
scripts/fetch-contributor-stats.js
Executable file
|
|
@ -0,0 +1,212 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Script to fetch OpenTofu contributor statistics
|
||||
*
|
||||
* This script fetches contributor data from OpenTofu GitHub repositories
|
||||
* and generates a JSON file containing contributor counts.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/fetch-contributor-stats.js
|
||||
*
|
||||
* Note: For more accurate results, you can set a GitHub token:
|
||||
* GITHUB_TOKEN=your_token node scripts/fetch-contributor-stats.js
|
||||
*/
|
||||
|
||||
const https = require("https");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// Configuration
|
||||
const FORK_DATE = "2023-08-25"; // OpenTofu was officially announced on this date
|
||||
const OUTPUT_FILE = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"src",
|
||||
"data",
|
||||
"contributor-stats.json",
|
||||
);
|
||||
const GITHUB_TOKEN = process.env.GITHUB_TOKEN || ""; // Optional GitHub token
|
||||
|
||||
// For fallback purposes, let's hardcode the contributor count we found earlier
|
||||
// If GitHub API access is fixed later, this will be replaced with the actual count
|
||||
const FALLBACK_CONTRIBUTOR_COUNT = 180;
|
||||
|
||||
// Create the data directory if it doesn't exist
|
||||
const dataDir = path.dirname(OUTPUT_FILE);
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Main repositories to check (excluding manifesto, roadmap, .github, legal-documents)
|
||||
const REPOSITORIES = [
|
||||
"opentofu",
|
||||
"opentofu.org",
|
||||
"brand-artifacts",
|
||||
"equivalence-testing",
|
||||
"scripts",
|
||||
"registry-alpha",
|
||||
"registry-address",
|
||||
"setup-opentofu",
|
||||
"tofu-exec",
|
||||
"get.opentofu.org",
|
||||
"tfenv",
|
||||
];
|
||||
|
||||
// Helper function to make GitHub API requests
|
||||
function makeRequest(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
headers: {
|
||||
"User-Agent": "OpenTofu-Stats-Collector",
|
||||
...(GITHUB_TOKEN && { Authorization: `token ${GITHUB_TOKEN}` }),
|
||||
},
|
||||
};
|
||||
|
||||
https
|
||||
.get(url, options, (response) => {
|
||||
if (response.statusCode === 403) {
|
||||
console.warn("Rate limit exceeded. Consider using a GitHub token.");
|
||||
return resolve([]);
|
||||
}
|
||||
|
||||
if (response.statusCode !== 200) {
|
||||
return reject(
|
||||
new Error(`Request failed with status code ${response.statusCode}`),
|
||||
);
|
||||
}
|
||||
|
||||
let data = "";
|
||||
|
||||
response.on("data", (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
response.on("end", () => {
|
||||
try {
|
||||
resolve(JSON.parse(data));
|
||||
} catch (error) {
|
||||
reject(
|
||||
new Error(
|
||||
`Failed to parse response from ${url}: ${error.message}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on("error", (error) => {
|
||||
reject(new Error(`Request to ${url} failed: ${error.message}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch contributors for a repository after the fork date
|
||||
async function fetchContributors(repo) {
|
||||
console.log(`Fetching contributors for ${repo}...`);
|
||||
const contributors = new Set();
|
||||
let page = 1;
|
||||
let hasMore = true;
|
||||
|
||||
while (hasMore) {
|
||||
const url = `https://api.github.com/repos/opentofu/${repo}/commits?since=${FORK_DATE}T00:00:00Z&per_page=100&page=${page}`;
|
||||
|
||||
try {
|
||||
const commits = await makeRequest(url);
|
||||
|
||||
if (commits.length === 0 || !Array.isArray(commits)) {
|
||||
hasMore = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract unique contributor logins
|
||||
commits.forEach((commit) => {
|
||||
if (commit.author && commit.author.login) {
|
||||
contributors.add(commit.author.login);
|
||||
}
|
||||
});
|
||||
|
||||
// If we got fewer than 100 commits, we've reached the last page
|
||||
if (commits.length < 100) {
|
||||
hasMore = false;
|
||||
} else {
|
||||
page++;
|
||||
// Add a small delay to avoid rate limits
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Error fetching commits for ${repo} (page ${page}):`,
|
||||
error.message,
|
||||
);
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(contributors);
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
console.log(`Gathering contributor statistics since ${FORK_DATE}...`);
|
||||
|
||||
const allContributors = new Set();
|
||||
let apiSuccessful = false;
|
||||
|
||||
// Process each repository
|
||||
for (const repo of REPOSITORIES) {
|
||||
try {
|
||||
const contributors = await fetchContributors(repo);
|
||||
console.log(`Found ${contributors.length} contributors in ${repo}`);
|
||||
|
||||
contributors.forEach((contributor) => allContributors.add(contributor));
|
||||
|
||||
if (contributors.length > 0) {
|
||||
apiSuccessful = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to process repository ${repo}:`, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// If API requests didn't yield results, use fallback count
|
||||
const contributorCount = apiSuccessful
|
||||
? allContributors.size
|
||||
: FALLBACK_CONTRIBUTOR_COUNT;
|
||||
|
||||
// Generate stats
|
||||
const stats = {
|
||||
timestamp: new Date().toISOString(),
|
||||
stats: {
|
||||
contributors: {
|
||||
total: contributorCount,
|
||||
as_of_date: FORK_DATE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Save to JSON file
|
||||
fs.writeFileSync(OUTPUT_FILE, JSON.stringify(stats, null, 2));
|
||||
|
||||
console.log(`\nContributor statistics:`);
|
||||
console.log(`Total unique contributors: ${contributorCount}`);
|
||||
console.log(`\nSaved stats to ${OUTPUT_FILE}`);
|
||||
|
||||
if (!apiSuccessful) {
|
||||
console.warn(
|
||||
"\nWarning: GitHub API requests did not return contributor data.",
|
||||
);
|
||||
console.warn(
|
||||
"Using fallback contributor count of",
|
||||
FALLBACK_CONTRIBUTOR_COUNT,
|
||||
);
|
||||
console.warn("For more accurate results, set a GitHub token:");
|
||||
console.warn(
|
||||
" GITHUB_TOKEN=your_token node scripts/fetch-contributor-stats.js",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("Error executing script:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -23,8 +23,8 @@ const classNames = [
|
|||
"max-w-none",
|
||||
"text-gray-900",
|
||||
"dark:text-gray-100",
|
||||
"pb-6",
|
||||
"px-6",
|
||||
"pb-4 sm:pb-6",
|
||||
"px-3 sm:px-6",
|
||||
"leading-6",
|
||||
"mt-2",
|
||||
"text-base",
|
||||
|
|
@ -105,7 +105,7 @@ const AccordionItem = ({
|
|||
>
|
||||
<summary
|
||||
onClick={handleItemClick}
|
||||
className="list-none py-6 px-6 group-open:pb-0 text-xl flex gap-2 cursor-pointer flex-row items-center justify-between font-bold marker:[font-size:0px]"
|
||||
className="list-none py-4 px-3 sm:py-6 sm:px-6 group-open:pb-0 text-xl flex gap-2 cursor-pointer flex-row items-center justify-between font-bold marker:[font-size:0px]"
|
||||
>
|
||||
{summary}
|
||||
<svg
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export default function Button({
|
|||
...rest
|
||||
}: ButtonProps) {
|
||||
const computedClassName = clsx(
|
||||
"border font-bold h-12 px-6 flex items-center hover:no-underline transition-colors",
|
||||
"border font-bold h-12 px-6 flex items-center justify-center hover:no-underline transition-colors",
|
||||
variant === "primary" &&
|
||||
"bg-brand-500 text-gray-900 hover:bg-brand-600 border-brand-500 hover:border-brand-600 hover:text-gray-900",
|
||||
variant === "secondary" &&
|
||||
|
|
|
|||
83
src/components/Carousel/CustomPagination.tsx
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import React from "react";
|
||||
import PaginationBullet from "./PaginationBullet";
|
||||
|
||||
interface CustomPaginationProps {
|
||||
totalSlides: number;
|
||||
activeIndex: number;
|
||||
onBulletClick: (index: number) => void;
|
||||
onPrev: () => void;
|
||||
onNext: () => void;
|
||||
}
|
||||
|
||||
export const CustomPagination = ({
|
||||
totalSlides,
|
||||
activeIndex,
|
||||
onBulletClick,
|
||||
onPrev,
|
||||
onNext,
|
||||
}: CustomPaginationProps) => {
|
||||
const arrowClassName =
|
||||
"p-1.5 rounded-full transition-colors text-gray-700 dark:text-gray-300";
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center gap-4">
|
||||
{/* Left Arrow */}
|
||||
<button
|
||||
onClick={onPrev}
|
||||
className={arrowClassName}
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
className="w-5 h-5"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M15.75 19.5L8.25 12l7.5-7.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Pagination dots */}
|
||||
<div className="flex gap-4">
|
||||
{Array.from({ length: totalSlides }).map((_, index) => (
|
||||
<PaginationBullet
|
||||
key={index}
|
||||
isActive={index === activeIndex}
|
||||
onClick={() => onBulletClick(index)}
|
||||
slideNumber={index + 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Right Arrow */}
|
||||
<button
|
||||
onClick={onNext}
|
||||
className={arrowClassName}
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
className="w-5 h-5"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M8.25 4.5l7.5 7.5-7.5 7.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomPagination;
|
||||
29
src/components/Carousel/PaginationBullet.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface PaginationBulletProps {
|
||||
isActive: boolean;
|
||||
onClick: () => void;
|
||||
slideNumber: number;
|
||||
}
|
||||
|
||||
export const PaginationBullet = ({
|
||||
isActive,
|
||||
onClick,
|
||||
slideNumber,
|
||||
}: PaginationBulletProps) => {
|
||||
const className = clsx(
|
||||
"w-2.5 h-2.5 rounded-full transition-colors",
|
||||
isActive ? "bg-gray-700 dark:bg-gray-300" : "bg-gray-400 dark:bg-gray-700",
|
||||
);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={className}
|
||||
aria-label={`Go to slide ${slideNumber}`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaginationBullet;
|
||||
34
src/components/Carousel/carousel.css
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Swiper core styles with !important to override Swiper's defaults */
|
||||
.carousel-container .swiper {
|
||||
width: 100% !important;
|
||||
height: calc(100% - 60px) !important;
|
||||
}
|
||||
|
||||
.carousel-container .swiper-wrapper {
|
||||
height: 100% !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.carousel-container .swiper-slide {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* Mobile-specific styles */
|
||||
@media (max-width: 640px) {
|
||||
.carousel-container .swiper {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.carousel-container .swiper-wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.carousel-container .swiper-slide {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
68
src/components/Carousel/index.tsx
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import React, { useState } from "react";
|
||||
import { Autoplay, Navigation, Pagination } from "swiper/modules";
|
||||
import { Swiper, SwiperClass, SwiperSlide } from "swiper/react";
|
||||
|
||||
import CustomPagination from "./CustomPagination";
|
||||
|
||||
import "swiper/css";
|
||||
import "./carousel.css";
|
||||
|
||||
export interface CarouselItem {
|
||||
id: string;
|
||||
title: string;
|
||||
content: React.ReactNode;
|
||||
}
|
||||
|
||||
interface CarouselProps {
|
||||
items: CarouselItem[];
|
||||
}
|
||||
|
||||
export default function Carousel({ items }: CarouselProps) {
|
||||
const [activeIndex, setActiveIndex] = React.useState(0);
|
||||
const [swiper, setSwiper] = useState<SwiperClass>(null);
|
||||
|
||||
const handleBulletClick = (index: number) => {
|
||||
swiper && swiper.slideTo(index);
|
||||
};
|
||||
|
||||
const goToNextSlide = () => {
|
||||
swiper && swiper.slideNext();
|
||||
};
|
||||
|
||||
const goToPrevSlide = () => {
|
||||
swiper && swiper.slidePrev();
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="carousel" className="carousel-container w-full h-full relative">
|
||||
<Swiper
|
||||
onSwiper={setSwiper}
|
||||
modules={[Navigation, Pagination, Autoplay]}
|
||||
autoplay={{
|
||||
delay: 60000,
|
||||
disableOnInteraction: false,
|
||||
}}
|
||||
onSlideChange={(swiper) => setActiveIndex(swiper.activeIndex)}
|
||||
slidesPerView={1}
|
||||
spaceBetween={0}
|
||||
centeredSlides={true}
|
||||
loop={false}
|
||||
resistance={false}
|
||||
>
|
||||
{items.map((item) => (
|
||||
<SwiperSlide key={item.id}>{item.content}</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
<div className="absolute flex justify-center z-10 left-0 right-0 -bottom-6 sm:-bottom-6">
|
||||
<CustomPagination
|
||||
totalSlides={items.length}
|
||||
activeIndex={activeIndex}
|
||||
onBulletClick={handleBulletClick}
|
||||
onPrev={goToPrevSlide}
|
||||
onNext={goToNextSlide}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
115
src/components/Examples/index.tsx
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import React from "react";
|
||||
import Carousel, { CarouselItem } from "../Carousel";
|
||||
import { IDE } from "../IDE";
|
||||
|
||||
interface Example {
|
||||
title: string;
|
||||
description: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
const examples: Example[] = [
|
||||
{
|
||||
title: "Create an S3 Bucket",
|
||||
description:
|
||||
"Define your infrastructure as code with OpenTofu. A few lines of configuration is all you need to create and manage cloud resources with confidence.",
|
||||
code: `terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "us-west-1"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "example" {
|
||||
bucket = "my-example-bucket"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
title: "Configure DNS Records",
|
||||
description:
|
||||
"Version control your infrastructure with OpenTofu. Track changes, collaborate with your team, and deploy DNS configurations with a single command.",
|
||||
code: `terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "cloudflare" {
|
||||
api_token = var.cloudflare_api_token
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "example" {
|
||||
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
|
||||
name = "www"
|
||||
value = "192.0.2.1"
|
||||
type = "A"
|
||||
ttl = 3600
|
||||
proxied = true
|
||||
}`,
|
||||
},
|
||||
{
|
||||
title: "Set Up GitHub Repositories",
|
||||
description:
|
||||
"Automate your development workflow with OpenTofu. Create repositories, set up branch protection, and manage team access in code.",
|
||||
code: `terraform {
|
||||
required_providers {
|
||||
github = {
|
||||
source = "integrations/github"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "github" {
|
||||
token = var.github_token
|
||||
}
|
||||
|
||||
resource "github_repository" "example" {
|
||||
name = "my-repo"
|
||||
description = "My application repository"
|
||||
visibility = "public"
|
||||
auto_init = true
|
||||
}
|
||||
|
||||
resource "github_branch_protection" "main" {
|
||||
repository_id = github_repository.example.id
|
||||
pattern = "main"
|
||||
enforce_admins = true
|
||||
}`,
|
||||
},
|
||||
];
|
||||
|
||||
export function Examples() {
|
||||
const carouselItems: CarouselItem[] = examples.map((example, index) => ({
|
||||
id: `example-${index}`,
|
||||
title: example.title,
|
||||
content: (
|
||||
<div className="h-full w-[95%] mx-auto sm:w-full sm:p-4">
|
||||
<div className="text-left sm:text-center mb-6">
|
||||
<h3 className="text-2xl font-bold mb-2">{example.title}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 mb-6">
|
||||
{example.description}
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full overflow-hidden shadow-xl">
|
||||
<IDE code={example.code} />
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-full sm:max-w-4xl mx-auto">
|
||||
<Carousel items={carouselItems} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -8,39 +8,67 @@ import Link from "@docusaurus/Link";
|
|||
|
||||
export default function FAQ() {
|
||||
return (
|
||||
<section className="flex flex-col justify-center w-full py-10 md:py-20 bg-gradient-to-b from-white dark:from-blue-900 to-transparent">
|
||||
<section className="relative py-20 md:py-32 px-4">
|
||||
<div className="w-full max-w-4xl mx-auto">
|
||||
<h2 className="text-center text-3xl md:text-5xl font-bold mb-6 md:mb-12">
|
||||
Frequently Asked Questions
|
||||
</h2>
|
||||
<div className="text-left sm:text-center mb-16">
|
||||
<h2 className="text-3xl md:text-5xl font-bold mb-6 bg-gradient-to-r from-gray-900 to-gray-700 dark:from-white dark:to-gray-300 bg-clip-text text-transparent">
|
||||
Frequently Asked Questions
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
|
||||
Get answers to common questions about OpenTofu capabilities and
|
||||
usage
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Accordion>
|
||||
<MDXProvider
|
||||
components={{
|
||||
AccordionItem: (props: AccordionItemProps) =>
|
||||
props.highlight ? <AccordionItem {...props} /> : null,
|
||||
a: (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => (
|
||||
<Link className="text-inherit underline" {...props} />
|
||||
),
|
||||
blockquote: (
|
||||
props: React.BlockquoteHTMLAttributes<HTMLQuoteElement>
|
||||
) => (
|
||||
<blockquote
|
||||
className="border-l-4 border-gray-300 text-inherit pl-4"
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Faq />
|
||||
</MDXProvider>
|
||||
</Accordion>
|
||||
<div className="bg-white dark:bg-blue-900/30 rounded-2xl shadow-lg border border-gray-100 dark:border-blue-800/40 p-6 md:p-8">
|
||||
<Accordion>
|
||||
<MDXProvider
|
||||
components={{
|
||||
AccordionItem: (props: AccordionItemProps) =>
|
||||
props.highlight ? <AccordionItem {...props} /> : null,
|
||||
a: (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => (
|
||||
<Link
|
||||
className="text-blue-600 dark:text-blue-300 hover:underline"
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
blockquote: (
|
||||
props: React.BlockquoteHTMLAttributes<HTMLQuoteElement>,
|
||||
) => (
|
||||
<blockquote
|
||||
className="border-l-4 border-blue-300 dark:border-blue-600 text-inherit pl-4 py-1 my-4 text-gray-600 dark:text-gray-400 italic"
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Faq />
|
||||
</MDXProvider>
|
||||
</Accordion>
|
||||
|
||||
<div className="flex justify-center mt-6">
|
||||
<Button variant="secondary" href="/faq">
|
||||
<span aria-hidden>Show More</span>
|
||||
<span className="sr-only">Go to the FAQ page</span>
|
||||
</Button>
|
||||
<div className="flex justify-start sm:justify-center mt-10">
|
||||
<Button
|
||||
variant="secondary"
|
||||
href="/faq"
|
||||
className="w-full sm:w-auto px-6 py-3 flex items-center gap-2"
|
||||
>
|
||||
<span>View All Questions</span>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M14 5l7 7m0 0l-7 7m7-7H3"
|
||||
></path>
|
||||
</svg>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
225
src/components/Features/index.tsx
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
import React from "react";
|
||||
import { IDE } from "../IDE";
|
||||
import versions from "../../../versions.json";
|
||||
|
||||
type FeatureShowcaseProps = {
|
||||
title: string;
|
||||
description: string;
|
||||
version: string;
|
||||
codeExample: string;
|
||||
align: "left" | "right";
|
||||
color: string;
|
||||
filename?: string;
|
||||
docsUrl?: string;
|
||||
};
|
||||
|
||||
function FeatureShowcase({
|
||||
title,
|
||||
description,
|
||||
version,
|
||||
codeExample,
|
||||
align,
|
||||
color,
|
||||
filename = "main.tf",
|
||||
docsUrl,
|
||||
}: FeatureShowcaseProps) {
|
||||
const isRight = align === "right";
|
||||
|
||||
// Read the latest version, this is needed because of how versioned documentation works.
|
||||
// If the version referenced is actually the latest version, we link to the "What's New" page
|
||||
// otherwise we link to the versioned "What's New" page.
|
||||
// This is a bit of a hack, but it works for now.
|
||||
const latestVersion = versions[0].replace("v", "");
|
||||
const versionHref =
|
||||
version === latestVersion
|
||||
? "/docs/intro/whats-new/"
|
||||
: `/docs/v${version}/intro/whats-new/`;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row gap-8 mb-20 items-center">
|
||||
{/* Code example side */}
|
||||
<div
|
||||
className={`lg:w-1/2 w-full order-2 ${
|
||||
isRight ? "lg:order-2" : "lg:order-1"
|
||||
}`}
|
||||
>
|
||||
<IDE code={codeExample} language="hcl" filename={filename} />
|
||||
</div>
|
||||
|
||||
{/* Content side */}
|
||||
<div
|
||||
className={`lg:w-1/2 w-full order-1 ${
|
||||
isRight ? "lg:order-1" : "lg:order-2"
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-wrap items-center gap-3 mb-3">
|
||||
<h3 className="text-2xl font-bold">{title}</h3>
|
||||
<a
|
||||
href={versionHref}
|
||||
className={`inline-flex px-3 py-1 text-sm font-medium rounded-full hover:opacity-90 transition-opacity ${color} hover:text-white`}
|
||||
>
|
||||
{`v${version}`}
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-gray-600 dark:text-gray-400 text-lg mb-4">
|
||||
{description}
|
||||
</p>
|
||||
{docsUrl && (
|
||||
<a
|
||||
href={docsUrl}
|
||||
className="inline-flex items-center text-blue-600 dark:text-blue-400 font-medium hover:underline"
|
||||
>
|
||||
Learn more
|
||||
<svg
|
||||
className="w-4 h-4 ml-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Features() {
|
||||
return (
|
||||
<section id="features" className="py-16 md:py-24 mx-auto container px-4">
|
||||
<div className="text-left sm:text-center max-w-3xl mx-auto mb-16">
|
||||
<h2
|
||||
id="features-header"
|
||||
className="text-3xl md:text-5xl font-bold mb-6 bg-gradient-to-r from-gray-900 to-gray-700 dark:from-white dark:to-gray-300 bg-clip-text text-transparent"
|
||||
>
|
||||
Features Unique to OpenTofu
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-400">
|
||||
Powerful capabilities — built by the community to solve real-world
|
||||
challenges in infrastructure management
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-8">
|
||||
<FeatureShowcase
|
||||
title="Exclusion Flag"
|
||||
description="Selectively exclude resources from operations with the -exclude flag. This provides more control during testing and rollouts, allowing you to focus on specific parts of your infrastructure."
|
||||
version="1.9"
|
||||
align="left"
|
||||
color="bg-blue-600/90 text-white dark:bg-blue-500/90"
|
||||
filename="/bin/bash"
|
||||
docsUrl="/docs/cli/commands/plan/#resource-targeting"
|
||||
codeExample={`# Command line usage
|
||||
$ tofu plan -exclude="aws_instance.database"
|
||||
$ tofu apply -exclude="module.network"
|
||||
|
||||
# Exclude multiple resources
|
||||
$ tofu apply \\
|
||||
-exclude="aws_instance.web[0]" \\
|
||||
-exclude="aws_instance.web[1]"`}
|
||||
/>
|
||||
|
||||
<FeatureShowcase
|
||||
title="Provider Iteration with for_each"
|
||||
description="Dynamically generate provider configurations with for_each, eliminating repetitive code and improving maintainability. Perfect for multi-region deployments, multi-environment setups (dev/staging/prod), multi-account scenarios, and cross-cloud implementations. Provider for_each enables cleaner infrastructure patterns, simplified credential rotation, and more controlled progressive rollouts across your infrastructure landscape."
|
||||
version="1.9"
|
||||
align="right"
|
||||
color="bg-blue-600/90 text-white dark:bg-blue-500/90"
|
||||
docsUrl="/docs/intro/whats-new/#provider-iteration-for_each"
|
||||
codeExample={`# Define regions for deployment
|
||||
variable "regions" {
|
||||
type = set(string)
|
||||
default = ["us-west-1", "us-east-1", "eu-west-1"]
|
||||
}
|
||||
|
||||
variable "disabled_regions" {
|
||||
type = set(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
# Create provider for each region
|
||||
provider "aws" {
|
||||
alias = "by_region"
|
||||
region = each.value
|
||||
for_each = var.regions
|
||||
}
|
||||
|
||||
# Deploy resources in each active region
|
||||
module "deploy" {
|
||||
source = "./deploy"
|
||||
providers = {
|
||||
aws = aws.by_region[each.key]
|
||||
}
|
||||
for_each = setsubtract(var.regions, var.disabled_regions)
|
||||
}`}
|
||||
/>
|
||||
|
||||
<FeatureShowcase
|
||||
title="Early Variable/Local Evaluation"
|
||||
description="Update all your modules programmatically with a single variable change. Never miss updating a module version by accident - keep your infrastructure consistent and secure with centralized version management."
|
||||
version="1.8"
|
||||
align="left"
|
||||
color="bg-blue-600/90 text-white dark:bg-blue-500/90"
|
||||
docsUrl="/docs/v1.8/language/modules/sources/#support-for-variable-and-local-evaluation"
|
||||
codeExample={`# Define module version as a variable
|
||||
variable "aws_module_version" {
|
||||
description = "Version of AWS modules to use"
|
||||
type = string
|
||||
default = "5.6.1"
|
||||
}
|
||||
|
||||
# Use the variable for module versioning
|
||||
module "vpc" {
|
||||
source = "terraform-aws-modules/vpc/aws"
|
||||
version = var.aws_module_version
|
||||
|
||||
name = "my-vpc"
|
||||
cidr = "10.0.0.0/16"
|
||||
|
||||
azs = ["us-west-2a", "us-west-2b"]
|
||||
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
|
||||
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
|
||||
}`}
|
||||
/>
|
||||
|
||||
<FeatureShowcase
|
||||
title="State Encryption"
|
||||
description="Protect your infrastructure state at rest with built-in encryption. OpenTofu supports client-side state encryption with multiple key providers (PBKDF2, AWS KMS, GCP KMS, OpenBao, and more) to ensure your sensitive infrastructure data is always encrypted, even when stored in remote backends."
|
||||
version="1.7"
|
||||
align="right"
|
||||
color="bg-blue-600/90 text-white dark:bg-blue-500/90"
|
||||
docsUrl="/docs/language/state/encryption/"
|
||||
codeExample={`# Configure state encryption
|
||||
terraform {
|
||||
encryption {
|
||||
# Define a passphrase-based key provider
|
||||
key_provider "pbkdf2" "mykey" {
|
||||
passphrase = "correct-horse-battery-staple"
|
||||
key_length = 32
|
||||
iterations = 600000
|
||||
}
|
||||
|
||||
# Configure AES-GCM encryption method
|
||||
method "aes_gcm" "default" {
|
||||
key_provider = key_provider.pbkdf2.mykey
|
||||
}
|
||||
|
||||
# Enable encryption for state files
|
||||
state {
|
||||
method = method.aes_gcm.default
|
||||
enforced = true
|
||||
}
|
||||
}
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore should be fixed when upgrating to docusaurus v3
|
||||
import GitHubButton from "react-github-btn";
|
||||
import { useColorMode } from "@docusaurus/theme-common";
|
||||
import { useTheme } from "../../utils/useTheme";
|
||||
|
||||
type GitHubStartNavbarItemProps = {
|
||||
ghRepoUrl: string;
|
||||
|
|
@ -13,15 +13,13 @@ export default function GitHubStartNavbarItem({
|
|||
ghRepoUrl,
|
||||
buttonLabel,
|
||||
}: GitHubStartNavbarItemProps) {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
const isDarkTheme = useTheme();
|
||||
|
||||
return (
|
||||
<div className="flex items-center [&_span]:flex">
|
||||
<GitHubButton
|
||||
href={ghRepoUrl}
|
||||
data-color-scheme={
|
||||
colorMode === "dark" ? "dark_high_contrast" : "light"
|
||||
}
|
||||
data-color-scheme={isDarkTheme ? "dark_high_contrast" : "light"}
|
||||
data-size="large"
|
||||
data-show-count="true"
|
||||
aria-label="Star OpenTofu on GitHub"
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
import React, { ComponentType, SVGProps } from "react";
|
||||
import ExpandIcon from "../../icons/expand.svg";
|
||||
import DotsIcon from "../../icons/dots.svg";
|
||||
import ScaleIcon from "../../icons/scale.svg";
|
||||
import LayersIcon from "../../icons/layers.svg";
|
||||
import HumidityIcon from "../../icons/humidity.svg";
|
||||
|
||||
type GoalProps = {
|
||||
icon: ComponentType<SVGProps<SVGSVGElement>>;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
function Goal({ icon: Icon, title, description }: GoalProps) {
|
||||
return (
|
||||
<div className="bg-white dark:bg-blue-900 p-6">
|
||||
<Icon className="w-12 mb-4" aria-hidden />
|
||||
<h3 className="text-xl mb-2">{title}</h3>
|
||||
<p className="text-gray-600 dark:text-gray-500">{description}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Goals() {
|
||||
return (
|
||||
<section className="py-6 md:py-12 mx-auto container px-4">
|
||||
<h2 className="text-center text-3xl md:text-5xl font-bold mb-6 md:mb-12">
|
||||
Our Goals
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<Goal
|
||||
icon={ExpandIcon}
|
||||
title="Truly open-source"
|
||||
description="under a well-known and widely-accepted license that companies can trust, that won’t suddenly change in the future, and isn’t subject to the whims of a single vendor."
|
||||
/>
|
||||
<Goal
|
||||
icon={DotsIcon}
|
||||
title="Community-driven"
|
||||
description="so that the community governs the project for the community, where pull requests are regularly reviewed and accepted on their merit."
|
||||
/>
|
||||
<Goal
|
||||
icon={ScaleIcon}
|
||||
title="Impartial"
|
||||
description="so that valuable features and fixes are accepted based on their value to the community, regardless of their impact on any particular vendor."
|
||||
/>
|
||||
<Goal
|
||||
icon={LayersIcon}
|
||||
title="Layered and modular"
|
||||
description="with a programmer-friendly project structure to encourage building on top, enabling a new vibrant ecosystem of tools and integrations."
|
||||
/>
|
||||
<Goal
|
||||
icon={HumidityIcon}
|
||||
title="Backwards-compatible"
|
||||
description="so that the existing code can drive value for years to come."
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ export default function Headline({ children, className }: HeadlineProps) {
|
|||
return (
|
||||
<h1
|
||||
className={clsx(
|
||||
"text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold leading-normal lg:leading-tight tracking-wider text-center px-4",
|
||||
"text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold leading-normal lg:leading-tight tracking-wider",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,50 +1,96 @@
|
|||
import React from "react";
|
||||
import Button from "../Button";
|
||||
import PatternBg from "../PatternBg";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Headline from "../Headline";
|
||||
import LFLogo from "../LFLogo";
|
||||
import { Examples } from "../Examples";
|
||||
import PatternBg from "../PatternBg";
|
||||
import Button from "../Button";
|
||||
|
||||
export default function Hero() {
|
||||
return (
|
||||
<header className="flex flex-col items-center py-10 md:py-20 px-6 md:px-16 mx-auto">
|
||||
<PatternBg />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1379.34 75.47"
|
||||
className="max-w-[380px] mb-6"
|
||||
>
|
||||
<path
|
||||
d="M71.9 1.2h45.3v4.6h-20v52.5h-5.4V5.8H71.9V1.2ZM122.5 1.2h5.4V26h33.9V1.2h5.4v57.1h-5.4V30.6H128v27.7h-5.4V1.2h-.1ZM178.9 1.2h39.4v4.6h-34v20.6h31.8V31h-31.8v22.6h34.4v4.6h-39.8v-57ZM520.4 1.2h36.2v4.6h-30.8v20.6h27.4V31h-27.4v27.2h-5.4v-57ZM587.3 0c17.9 0 26.9 14.1 26.9 29.8s-9 29.8-26.9 29.8-27-14.1-27-29.8c.1-15.7 9-29.8 27-29.8Zm0 54.9c15 0 21.4-12.6 21.4-25.1s-6.4-25.1-21.4-25.1-21.5 12.6-21.5 25.1 6.4 25.1 21.5 25.1ZM622.1 1.2h5.4v35.4c0 13.2 6.2 18.3 16.7 18.3S661 49.8 661 36.6V1.2h5.4v36.6c0 11.8-6.3 21.8-22.2 21.8S622 49.6 622 37.8V1.2h.1ZM677.4 1.2h6.1l33.3 48.3h.2V1.2h5.4v57.1h-6.1L683 10h-.2v48.3h-5.4V1.2ZM733.8 1.2h19.8c17.3.4 26.2 9.7 26.2 28.6s-9 28.2-26.2 28.6h-19.8V1.2Zm5.5 52.5h11.6c16.4 0 23.5-6.8 23.5-23.9s-7.1-23.9-23.5-23.9h-11.6v47.8ZM805.3 1.2h6.1l22.4 57.1H828l-7-17.8h-26l-6.9 17.8h-5.8l23-57.1Zm-8.6 34.7h22.5l-11-29.3-11.5 29.3ZM827.4 1.2h45.3v4.6h-19.9v52.5h-5.4V5.8h-19.9V1.2h-.1ZM878.5 1.2h5.4v57.1h-5.4V1.2ZM919.8 0c17.9 0 26.9 14.1 26.9 29.8s-9 29.8-26.9 29.8-27-14.1-27-29.8 9-29.8 27-29.8Zm0 54.9c15 0 21.4-12.6 21.4-25.1s-6.4-25.1-21.4-25.1-21.5 12.6-21.5 25.1c-.1 12.4 6.3 25.1 21.5 25.1ZM955 1.2h6.1l33.3 48.3h.2V1.2h5.4v57.1h-6.1L960.6 10h-.2v48.3H955V1.2ZM233.8 1.2h17.5v42.3h25.2v14.6h-42.7V1.2ZM287.9 1.2h17.5v56.9h-17.5V1.2ZM318.5 1.2h17.9L353 31.6h.2V1.2h16.6v56.9h-17L335.2 27h-.2v31.1h-16.6V1.2h.1ZM434.5 36.1c0 15.9-8.4 23.3-25.9 23.3s-26-7.5-26-23.3V1.2h17.5v31c0 5.7-.1 13.1 8.5 13.1s8.3-7.3 8.3-13.1v-31h17.5v34.9h.1ZM462.3 27.8 443.6 1.2h20.5l8.6 15.5 8.4-15.5h19.4L482.4 28l20.3 30.1h-21.1l-9.7-17-10 17h-20.1l20.5-30.3Z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M11.4 46.9V24.1H0v34.2h34.3V46.9H11.4z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M57.1 1.2H0v17.1h11.4v-5.6h34.3v34.2H40v11.4h17.1V1.2z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M1067.11 18.97c0 5.66-1.92 10-5.77 13.01-3.84 3.02-9.29 4.52-16.34 4.52h-9.05v24.18h-4.08V2.16h14.33c13.93 0 20.9 5.61 20.9 16.82Zm-31.15 14.01h8.05c6.59 0 11.36-1.09 14.29-3.26 2.94-2.18 4.4-5.71 4.4-10.59 0-4.51-1.39-7.85-4.16-10.03-2.78-2.18-7.07-3.26-12.89-3.26h-9.69v27.14ZM1079 35.19v25.5h-4.08V2.16h13.93c7.26 0 12.62 1.34 16.09 4.02 3.47 2.68 5.2 6.72 5.2 12.11 0 3.92-1.03 7.23-3.1 9.93-2.07 2.7-5.21 4.63-9.43 5.81l15.89 26.66h-4.88l-15.09-25.5H1079Zm0-3.52h11.17c4.94 0 8.77-1.1 11.49-3.3s4.08-5.45 4.08-9.75-1.34-7.7-4-9.73c-2.67-2.03-7.02-3.04-13.05-3.04H1079v25.82ZM1176.96 31.35c0 9.29-2.55 16.64-7.66 22.04-5.11 5.4-12.15 8.11-21.14 8.11s-15.99-2.7-21.1-8.11c-5.11-5.4-7.66-12.78-7.66-22.12s2.58-16.65 7.73-22c5.15-5.35 12.19-8.03 21.12-8.03s16.02 2.69 21.1 8.07c5.08 5.38 7.62 12.73 7.62 22.04Zm-52.67 0c0 8.38 2.05 14.86 6.17 19.44 4.11 4.58 10.01 6.87 17.7 6.87s13.68-2.27 17.77-6.81c4.1-4.54 6.14-11.04 6.14-19.5s-2.05-14.9-6.14-19.4c-4.1-4.5-9.99-6.75-17.68-6.75s-13.57 2.27-17.73 6.81c-4.16 4.54-6.23 10.98-6.23 19.34ZM1181.32 75.47c-2.46 0-4.47-.36-6.05-1.08v-3.52c2.08.53 4.07.8 5.97.8 6.46 0 9.69-3.52 9.69-10.57V2.16h4.08v58.53c0 9.85-4.56 14.77-13.69 14.77ZM1243.17 60.69h-31.99V2.16h31.99v3.76h-27.91v22.14h26.34v3.76h-26.34v25.1h27.91v3.76ZM1276.49 5c-7.34 0-13.12 2.35-17.34 7.05-4.22 4.7-6.33 11.13-6.33 19.3s1.99 14.84 5.97 19.46c3.98 4.62 9.66 6.93 17.06 6.93 4.91 0 9.42-.63 13.53-1.88v3.6c-3.87 1.36-8.7 2.04-14.49 2.04-8.22 0-14.69-2.66-19.42-7.97-4.72-5.31-7.09-12.73-7.09-22.26 0-5.95 1.13-11.2 3.38-15.73 2.26-4.54 5.5-8.04 9.73-10.51 4.23-2.47 9.15-3.7 14.75-3.7s10.82 1.07 15.33 3.2l-1.64 3.68c-4.27-2.14-8.76-3.2-13.45-3.2ZM1319.33 60.69h-4.12V6h-19.02V2.16h42.16V6h-19.02v54.69ZM1379.34 45.6c0 4.88-1.8 8.76-5.38 11.61-3.59 2.86-8.36 4.28-14.31 4.28-7.15 0-12.64-.79-16.46-2.36v-4.08c4.22 1.79 9.59 2.68 16.13 2.68 4.8 0 8.61-1.1 11.43-3.3 2.82-2.2 4.22-5.09 4.22-8.67 0-2.22-.47-4.05-1.4-5.51-.93-1.45-2.46-2.78-4.56-3.98-2.11-1.2-5.2-2.5-9.29-3.88-5.98-2.05-10.11-4.28-12.39-6.67-2.28-2.39-3.42-5.57-3.42-9.55 0-4.38 1.71-7.95 5.14-10.71 3.43-2.76 7.84-4.14 13.23-4.14s10.66 1.04 15.49 3.12l-1.48 3.52c-4.86-2.03-9.5-3.04-13.93-3.04s-7.77 1-10.33 3-3.84 4.72-3.84 8.17c0 2.16.39 3.94 1.18 5.32.79 1.39 2.07 2.64 3.86 3.74 1.79 1.11 4.86 2.44 9.21 3.98 4.56 1.58 7.99 3.1 10.29 4.58 2.3 1.48 3.97 3.16 5.02 5.04 1.05 1.88 1.58 4.16 1.58 6.83Z"
|
||||
className="fill-[#0094ff]"
|
||||
/>
|
||||
</svg>
|
||||
<Headline className="sm:max-w-2xl md:max-w-3xl lg:max-w-4xl">
|
||||
The open source infrastructure as code tool.
|
||||
</Headline>
|
||||
<p className="my-6 text-xl sm:max-w-lg md:max-w-xl lg:max-w-2xl text-center text-gray-600 dark:text-gray-500">
|
||||
OpenTofu is a fork of Terraform that is
|
||||
open-source, community-driven, and managed by the Linux Foundation.
|
||||
</p>
|
||||
const [showArrow, setShowArrow] = useState(true);
|
||||
|
||||
<div className="flex gap-4 pt-6">
|
||||
<Button className="text-center" variant="secondary" href="/manifesto">
|
||||
Read Manifesto
|
||||
</Button>
|
||||
<Button variant="primary" href="/docs/intro/install">
|
||||
Try it out
|
||||
</Button>
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setShowArrow(window.scrollY < 100);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
const scrollToFeatures = () => {
|
||||
const featuresSection = document.getElementById("features");
|
||||
if (featuresSection) {
|
||||
featuresSection.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="relative min-h-[calc(100vh-8rem)]">
|
||||
<PatternBg />
|
||||
|
||||
<div className="container mx-auto px-4 md:px-8 py-16 min-h-[calc(100vh-8rem)] flex flex-col lg:flex-row items-center justify-center">
|
||||
<div className="lg:w-1/2 lg:pr-16">
|
||||
<div className="flex justify-start mb-8">
|
||||
<LFLogo />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<Headline>Open-Source Infrastructure as Code</Headline>
|
||||
<p className="my-8 text-xl text-gray-600 dark:text-gray-400">
|
||||
OpenTofu is a reliable, flexible, community-driven infrastructure
|
||||
as code tool under the Linux Foundation's stewardship. It serves
|
||||
as a <strong>drop-in replacement for Terraform</strong>,
|
||||
preserving your existing workflows and configurations.
|
||||
</p>
|
||||
<p className="mb-8 text-xl text-gray-600 dark:text-gray-400">
|
||||
With a thriving ecosystem of <strong>3,900+ providers</strong> and{" "}
|
||||
<strong>23,600+ modules</strong>, you can build and manage
|
||||
infrastructure across every cloud platform with confidence.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-start">
|
||||
<Button
|
||||
variant="primary"
|
||||
href="/docs/intro"
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
href="https://github.com/opentofu/opentofu"
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
View on GitHub
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="lg:w-1/2 mt-16 lg:mt-0 lg:pl-16 w-full">
|
||||
<Examples />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showArrow && (
|
||||
<button
|
||||
onClick={scrollToFeatures}
|
||||
className="fixed bottom-8 left-1/2 transform -translate-x-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
|
||||
>
|
||||
<svg
|
||||
className="w-6 h-6"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M19 14l-7 7m0 0l-7-7m7 7V3"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,61 @@
|
|||
import React from "react";
|
||||
import Link from "@docusaurus/Link";
|
||||
import Button from "../Button";
|
||||
|
||||
// TODO enter final links once ready
|
||||
export default function HowToContribute() {
|
||||
return (
|
||||
<section className="flex flex-col justify-center w-full py-5 md:py-10 px-4">
|
||||
<section className="relative py-20 md:py-28 px-4">
|
||||
<div className="w-full max-w-4xl mx-auto leading-snug">
|
||||
<h2 className="text-center text-3xl md:text-5xl mb-3 md:mb-6 font-bold">
|
||||
How to contribute to OpenTofu?
|
||||
</h2>
|
||||
<p className="text-gray-600 dark:text-gray-500 text-center text-base md:text-xl mb-3 md:mb-6 md:leading-relaxed">
|
||||
The best way to show practical support for the OpenTofu initiative is
|
||||
to contribute. This{" "}
|
||||
<Link
|
||||
href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md"
|
||||
className="underline text-gray-900 hover:text-brand-650 dark:text-gray-50 dark:hover:text-brand-500"
|
||||
>
|
||||
contribution guide
|
||||
</Link>{" "}
|
||||
explains OpenTofu contribution recommended practices, including how to
|
||||
submit issues, how to get involved in the discussion, how to work on
|
||||
the code, and how to contribute code changes.
|
||||
</p>
|
||||
<Button
|
||||
className="mx-auto max-w-fit"
|
||||
variant="primary"
|
||||
href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md"
|
||||
>
|
||||
Contribute
|
||||
</Button>
|
||||
<div className="flex flex-col md:flex-row items-center gap-12">
|
||||
{/* Content */}
|
||||
<div className="md:w-1/2 text-left">
|
||||
<h2 className="text-3xl md:text-4xl mb-6 font-bold bg-gradient-to-r from-gray-900 to-gray-700 dark:from-white dark:to-gray-300 bg-clip-text text-transparent">
|
||||
Join Our Community
|
||||
</h2>
|
||||
<p className="text-gray-600 dark:text-gray-400 text-lg mb-8 leading-relaxed">
|
||||
OpenTofu thrives on community contributions. Whether you're fixing
|
||||
bugs, adding features, improving docs, or providing feedback, your
|
||||
input makes a difference.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-start">
|
||||
<Button
|
||||
variant="primary"
|
||||
href="https://opentofu.org/slack"
|
||||
className="w-full sm:w-auto px-6 py-3"
|
||||
>
|
||||
Join Us on Slack
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md"
|
||||
className="w-full sm:w-auto px-6 py-3"
|
||||
>
|
||||
Contribute
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card */}
|
||||
<div className="md:w-1/2">
|
||||
<div className="bg-white dark:bg-blue-900/40 p-6 rounded-xl shadow-md border border-gray-100 dark:border-blue-800/50">
|
||||
<h3 className="font-semibold text-xl mb-4">Get Involved</h3>
|
||||
<ul className="space-y-3">
|
||||
{[
|
||||
"Join GitHub discussions to share ideas",
|
||||
"Open issues for bugs or feature suggestions",
|
||||
"Participate in RFC discussions and reviews",
|
||||
"Contribute code after community discussion",
|
||||
].map((text, index) => (
|
||||
<li key={index} className="flex items-start">
|
||||
<span className="inline-flex items-center justify-center w-6 h-6 mr-2 rounded-full bg-blue-100 dark:bg-blue-800/50 text-blue-600 dark:text-blue-300 text-sm">
|
||||
{index + 1}
|
||||
</span>
|
||||
<p className="text-gray-600 dark:text-gray-400">{text}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
19
src/components/IDE/CheckIcon.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
export default function CheckIcon() {
|
||||
return (
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
19
src/components/IDE/CopyIcon.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
export default function CopyIcon() {
|
||||
return (
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
20
src/components/IDE/DefaultFileIcon.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React from "react";
|
||||
|
||||
export default function DefaultFileIcon() {
|
||||
return (
|
||||
<svg
|
||||
className="w-3 h-3 mr-1.5 text-blue-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
25
src/components/IDE/OpenTofuLogo.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import React from "react";
|
||||
|
||||
export default function OpenTofuLogo() {
|
||||
return (
|
||||
<svg
|
||||
className="w-3.5 h-3.5 mr-1.5"
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M23.6628 4.80138C23.8728 4.686 24.1271 4.686 24.337 4.80138L39.3069 13.0294C39.7906 13.2953 39.7906 13.9902 39.3069 14.256L24.337 22.4841C24.1271 22.5995 23.8728 22.5995 23.6628 22.4841L8.69295 14.256C8.20929 13.9902 8.20929 13.2953 8.69295 13.0294L23.6628 4.80138Z"
|
||||
fill="#E7C200"
|
||||
/>
|
||||
<path
|
||||
d="M6.32202 16.7975C6.32202 16.2653 6.89255 15.9279 7.35896 16.1842L22.4708 24.4903C22.6946 24.6133 22.8336 24.8483 22.8336 25.1036V41.5597C22.8336 42.0919 22.2631 42.4294 21.7967 42.173L6.68477 33.8669C6.46104 33.7439 6.32202 33.5089 6.32202 33.2536V16.7975Z"
|
||||
fill="#FFDA18"
|
||||
/>
|
||||
<path
|
||||
d="M40.6406 16.1842C41.1071 15.9279 41.6776 16.2653 41.6776 16.7975V33.2536C41.6776 33.5089 41.5386 33.7439 41.3148 33.8669L26.203 42.173C25.7365 42.4294 25.166 42.0919 25.166 41.5597V25.1036C25.166 24.8483 25.305 24.6133 25.5288 24.4903L40.6406 16.1842Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
79
src/components/IDE/index.tsx
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import React, { useState } from "react";
|
||||
import { Highlight, themes } from "prism-react-renderer";
|
||||
import OpenTofuLogo from "./OpenTofuLogo";
|
||||
import CopyIcon from "./CopyIcon";
|
||||
import CheckIcon from "./CheckIcon";
|
||||
import DefaultFileIcon from "./DefaultFileIcon";
|
||||
import { useTheme } from "../../utils/useTheme";
|
||||
|
||||
interface IDEHeaderProps {
|
||||
filename?: string;
|
||||
}
|
||||
|
||||
const tfFileExtensions = [".tf", ".tfvars", ".tofu"];
|
||||
|
||||
function IDEHeader({ filename = "main.tf" }: IDEHeaderProps) {
|
||||
const isTofuFile = tfFileExtensions.some((ext) => filename.endsWith(ext));
|
||||
|
||||
return (
|
||||
<div className="flex items-center px-4 py-2 bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-white transition-colors">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-4 h-4">
|
||||
{isTofuFile ? <OpenTofuLogo /> : <DefaultFileIcon />}
|
||||
</div>
|
||||
<span className="text-sm font-mono">{filename}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface IDEProps {
|
||||
code: string;
|
||||
language?: string;
|
||||
filename?: string;
|
||||
}
|
||||
|
||||
export function IDE({ code, language = "hcl", filename }: IDEProps) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const isDarkTheme = useTheme();
|
||||
|
||||
const copyToClipboard = () => {
|
||||
navigator.clipboard.writeText(code);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full rounded-lg overflow-hidden shadow-xl box-border">
|
||||
<IDEHeader filename={filename} />
|
||||
<div className="relative overflow-x-auto box-border">
|
||||
<button
|
||||
onClick={copyToClipboard}
|
||||
className="absolute right-2 top-2 z-10 p-1.5 text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-white transition-colors"
|
||||
title={copied ? "Copied!" : "Copy to clipboard"}
|
||||
>
|
||||
{copied ? <CheckIcon /> : <CopyIcon />}
|
||||
</button>
|
||||
<Highlight
|
||||
theme={isDarkTheme ? themes.oneDark : themes.oneLight}
|
||||
code={code}
|
||||
language={language}
|
||||
>
|
||||
{({ tokens, getLineProps, getTokenProps }) => (
|
||||
<pre className="px-2 sm:px-4 py-3 text-sm m-0 max-w-full overflow-x-hidden w-full rounded-none box-border">
|
||||
<code className="text-xs sm:text-sm block whitespace-pre-wrap">
|
||||
{tokens.map((line, i) => (
|
||||
<div key={i} {...getLineProps({ line })}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({ token })} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</code>
|
||||
</pre>
|
||||
)}
|
||||
</Highlight>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
src/components/LFLogo/index.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
|
||||
export default function LFLogo() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1379.34 75.47"
|
||||
className="max-w-[380px] mb-8"
|
||||
>
|
||||
<path
|
||||
d="M71.9 1.2h45.3v4.6h-20v52.5h-5.4V5.8H71.9V1.2ZM122.5 1.2h5.4V26h33.9V1.2h5.4v57.1h-5.4V30.6H128v27.7h-5.4V1.2h-.1ZM178.9 1.2h39.4v4.6h-34v20.6h31.8V31h-31.8v22.6h34.4v4.6h-39.8v-57ZM520.4 1.2h36.2v4.6h-30.8v20.6h27.4V31h-27.4v27.2h-5.4v-57ZM587.3 0c17.9 0 26.9 14.1 26.9 29.8s-9 29.8-26.9 29.8-27-14.1-27-29.8c.1-15.7 9-29.8 27-29.8Zm0 54.9c15 0 21.4-12.6 21.4-25.1s-6.4-25.1-21.4-25.1-21.5 12.6-21.5 25.1 6.4 25.1 21.5 25.1ZM622.1 1.2h5.4v35.4c0 13.2 6.2 18.3 16.7 18.3S661 49.8 661 36.6V1.2h5.4v36.6c0 11.8-6.3 21.8-22.2 21.8S622 49.6 622 37.8V1.2h.1ZM677.4 1.2h6.1l33.3 48.3h.2V1.2h5.4v57.1h-6.1L683 10h-.2v48.3h-5.4V1.2ZM733.8 1.2h19.8c17.3.4 26.2 9.7 26.2 28.6s-9 28.2-26.2 28.6h-19.8V1.2Zm5.5 52.5h11.6c16.4 0 23.5-6.8 23.5-23.9s-7.1-23.9-23.5-23.9h-11.6v47.8ZM805.3 1.2h6.1l22.4 57.1H828l-7-17.8h-26l-6.9 17.8h-5.8l23-57.1Zm-8.6 34.7h22.5l-11-29.3-11.5 29.3ZM827.4 1.2h45.3v4.6h-19.9v52.5h-5.4V5.8h-19.9V1.2h-.1ZM878.5 1.2h5.4v57.1h-5.4V1.2ZM919.8 0c17.9 0 26.9 14.1 26.9 29.8s-9 29.8-26.9 29.8-27-14.1-27-29.8 9-29.8 27-29.8Zm0 54.9c15 0 21.4-12.6 21.4-25.1s-6.4-25.1-21.4-25.1-21.5 12.6-21.5 25.1c-.1 12.4 6.3 25.1 21.5 25.1ZM955 1.2h6.1l33.3 48.3h.2V1.2h5.4v57.1h-6.1L960.6 10h-.2v48.3H955V1.2ZM233.8 1.2h17.5v42.3h25.2v14.6h-42.7V1.2ZM287.9 1.2h17.5v56.9h-17.5V1.2ZM318.5 1.2h17.9L353 31.6h.2V1.2h16.6v56.9h-17L335.2 27h-.2v31.1h-16.6V1.2h.1ZM434.5 36.1c0 15.9-8.4 23.3-25.9 23.3s-26-7.5-26-23.3V1.2h17.5v31c0 5.7-.1 13.1 8.5 13.1s8.3-7.3 8.3-13.1v-31h17.5v34.9h.1ZM462.3 27.8 443.6 1.2h20.5l8.6 15.5 8.4-15.5h19.4L482.4 28l20.3 30.1h-21.1l-9.7-17-10 17h-20.1l20.5-30.3Z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M11.4 46.9V24.1H0v34.2h34.3V46.9H11.4z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M57.1 1.2H0v17.1h11.4v-5.6h34.3v34.2H40v11.4h17.1V1.2z"
|
||||
className="fill-gray-900 dark:fill-gray-50"
|
||||
/>
|
||||
<path
|
||||
d="M1067.11 18.97c0 5.66-1.92 10-5.77 13.01-3.84 3.02-9.29 4.52-16.34 4.52h-9.05v24.18h-4.08V2.16h14.33c13.93 0 20.9 5.61 20.9 16.82Zm-31.15 14.01h8.05c6.59 0 11.36-1.09 14.29-3.26 2.94-2.18 4.4-5.71 4.4-10.59 0-4.51-1.39-7.85-4.16-10.03-2.78-2.18-7.07-3.26-12.89-3.26h-9.69v27.14ZM1079 35.19v25.5h-4.08V2.16h13.93c7.26 0 12.62 1.34 16.09 4.02 3.47 2.68 5.2 6.72 5.2 12.11 0 3.92-1.03 7.23-3.1 9.93-2.07 2.7-5.21 4.63-9.43 5.81l15.89 26.66h-4.88l-15.09-25.5H1079Zm0-3.52h11.17c4.94 0 8.77-1.1 11.49-3.3s4.08-5.45 4.08-9.75-1.34-7.7-4-9.73c-2.67-2.03-7.02-3.04-13.05-3.04H1079v25.82ZM1176.96 31.35c0 9.29-2.55 16.64-7.66 22.04-5.11 5.4-12.15 8.11-21.14 8.11s-15.99-2.7-21.1-8.11c-5.11-5.4-7.66-12.78-7.66-22.12s2.58-16.65 7.73-22c5.15-5.35 12.19-8.03 21.12-8.03s16.02 2.69 21.1 8.07c5.08 5.38 7.62 12.73 7.62 22.04Zm-52.67 0c0 8.38 2.05 14.86 6.17 19.44 4.11 4.58 10.01 6.87 17.7 6.87s13.68-2.27 17.77-6.81c4.1-4.54 6.14-11.04 6.14-19.5s-2.05-14.9-6.14-19.4c-4.1-4.5-9.99-6.75-17.68-6.75s-13.57 2.27-17.73 6.81c-4.16 4.54-6.23 10.98-6.23 19.34ZM1181.32 75.47c-2.46 0-4.47-.36-6.05-1.08v-3.52c2.08.53 4.07.8 5.97.8 6.46 0 9.69-3.52 9.69-10.57V2.16h4.08v58.53c0 9.85-4.56 14.77-13.69 14.77ZM1243.17 60.69h-31.99V2.16h31.99v3.76h-27.91v22.14h26.34v3.76h-26.34v25.1h27.91v3.76ZM1276.49 5c-7.34 0-13.12 2.35-17.34 7.05-4.22 4.7-6.33 11.13-6.33 19.3s1.99 14.84 5.97 19.46c3.98 4.62 9.66 6.93 17.06 6.93 4.91 0 9.42-.63 13.53-1.88v3.6c-3.87 1.36-8.7 2.04-14.49 2.04-8.22 0-14.69-2.66-19.42-7.97-4.72-5.31-7.09-12.73-7.09-22.26 0-5.95 1.13-11.2 3.38-15.73 2.26-4.54 5.5-8.04 9.73-10.51 4.23-2.47 9.15-3.7 14.75-3.7s10.82 1.07 15.33 3.2l-1.64 3.68c-4.27-2.14-8.76-3.2-13.45-3.2ZM1319.33 60.69h-4.12V6h-19.02V2.16h42.16V6h-19.02v54.69ZM1379.34 45.6c0 4.88-1.8 8.76-5.38 11.61-3.59 2.86-8.36 4.28-14.31 4.28-7.15 0-12.64-.79-16.46-2.36v-4.08c4.22 1.79 9.59 2.68 16.13 2.68 4.8 0 8.61-1.1 11.43-3.3 2.82-2.2 4.22-5.09 4.22-8.67 0-2.22-.47-4.05-1.4-5.51-.93-1.45-2.46-2.78-4.56-3.98-2.11-1.2-5.2-2.5-9.29-3.88-5.98-2.05-10.11-4.28-12.39-6.67-2.28-2.39-3.42-5.57-3.42-9.55 0-4.38 1.71-7.95 5.14-10.71 3.43-2.76 7.84-4.14 13.23-4.14s10.66 1.04 15.49 3.12l-1.48 3.52c-4.86-2.03-9.5-3.04-13.93-3.04s-7.77 1-10.33 3-3.84 4.72-3.84 8.17c0 2.16.39 3.94 1.18 5.32.79 1.39 2.07 2.64 3.86 3.74 1.79 1.11 4.86 2.44 9.21 3.98 4.56 1.58 7.99 3.1 10.29 4.58 2.3 1.48 3.97 3.16 5.02 5.04 1.05 1.88 1.58 4.16 1.58 6.83Z"
|
||||
className="fill-[#0094ff]"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import styles from "./styles.module.css";
|
|||
|
||||
export default function PatternBg() {
|
||||
return (
|
||||
<div className="absolute top-0 left-0 right-0 h-[600px] -z-10" aria-hidden>
|
||||
<div className="fixed top-0 left-0 right-0 bottom-0 -z-20" aria-hidden>
|
||||
<div className="absolute inset-0 z-10 bg-gradient-to-b from-transparent to-gray-50 dark:to-blue-950" />
|
||||
<div className={`${styles.bg} w-full h-full opacity-5`} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,69 +1,100 @@
|
|||
import React from "react";
|
||||
import { Suporter } from "@site/src/components/SupportersList/types";
|
||||
import supporters from "../../../supporters.json";
|
||||
import { ENGINEERING_CONTRIBUTORS, SERVICE_SPONSORS } from "./supporters";
|
||||
import contributorStats from "../../data/contributor-stats.json";
|
||||
|
||||
import Button from "../Button";
|
||||
import { groupSupportersByType } from "../../utils/groupSupportersByType";
|
||||
import SupportersList from "../SupportersList";
|
||||
interface SupporterLogoProps {
|
||||
supporter: {
|
||||
name: string;
|
||||
url: string;
|
||||
logoDark: string;
|
||||
logoLight: string;
|
||||
};
|
||||
}
|
||||
|
||||
type SupporterTypeProps = {
|
||||
type: string;
|
||||
count: number;
|
||||
withSeparator?: boolean;
|
||||
};
|
||||
|
||||
function SupporterType({ type, withSeparator, count }: SupporterTypeProps) {
|
||||
function SupporterLogo({ supporter }: SupporterLogoProps) {
|
||||
return (
|
||||
<li className="h-12 flex items-center">
|
||||
<span aria-hidden>{type}</span>
|
||||
<span className="sr-only">
|
||||
Supporting {type}: {count}
|
||||
</span>
|
||||
{count && (
|
||||
<sup
|
||||
className="ml-1 mt-2 text-brand-650 dark:text-brand-600 text-base font-bold"
|
||||
aria-hidden
|
||||
>
|
||||
{count}
|
||||
</sup>
|
||||
)}
|
||||
{withSeparator && (
|
||||
<span className="mx-4 text-gray-400" aria-hidden>
|
||||
•
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
<a
|
||||
href={supporter.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="transition-transform hover:scale-105 focus:scale-105 w-full"
|
||||
aria-label={`Visit ${supporter.name} website`}
|
||||
>
|
||||
<div className="bg-white dark:bg-blue-900/30 shadow-md rounded-xl p-6 border border-gray-100 dark:border-blue-800/50 flex items-center justify-center h-24 w-full sm:w-48 mx-auto transition-colors">
|
||||
<>
|
||||
<img
|
||||
src={supporter.logoDark}
|
||||
alt={`${supporter.name} logo`}
|
||||
className="dark:hidden max-w-full max-h-full"
|
||||
/>
|
||||
<img
|
||||
src={supporter.logoLight}
|
||||
alt={`${supporter.name} logo`}
|
||||
className="hidden dark:block max-w-full max-h-full"
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
const MAX_LIST_COUNT = 5;
|
||||
function CommunityContributorsTile() {
|
||||
return (
|
||||
<div className="bg-white dark:bg-blue-900/30 shadow-md rounded-xl p-6 border border-gray-100 dark:border-blue-800/50 flex items-center justify-center h-24 w-full sm:w-48">
|
||||
<div className="text-center">
|
||||
<span className="text-3xl font-bold text-gray-800 dark:text-gray-200">
|
||||
{Math.floor(contributorStats.stats.contributors.total / 10) * 10}+
|
||||
</span>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
|
||||
Community Contributors
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Supporters() {
|
||||
const groupedSupporters = groupSupportersByType(supporters);
|
||||
const types = Object.entries(groupedSupporters);
|
||||
const list = supporters.slice(0, MAX_LIST_COUNT);
|
||||
|
||||
return (
|
||||
<section className="py-12 mx-auto container items-center flex flex-col px-4">
|
||||
<h2 className="text-center text-3xl md:text-5xl font-bold mb-4 md:mb-7">
|
||||
Supporters
|
||||
</h2>
|
||||
<ul className="inline-flex flex-wrap justify-center">
|
||||
{types.map(([type, supporters], index) => (
|
||||
<SupporterType
|
||||
key={type}
|
||||
count={(supporters as Suporter[]).length}
|
||||
withSeparator={index < types.length - 1}
|
||||
type={type}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
<SupportersList list={list} />
|
||||
<div className="flex gap-6 justify-center">
|
||||
<Button variant="secondary" href="/supporters">
|
||||
<span aria-hidden>Show More</span>
|
||||
<span className="sr-only">Go to the Supporters page</span>
|
||||
</Button>
|
||||
<section className="py-20 md:py-28 mx-auto container px-4">
|
||||
<div className="text-left sm:text-center mb-16">
|
||||
<h2 className="text-3xl md:text-5xl font-bold mb-6 bg-gradient-to-r from-gray-900 to-gray-700 dark:from-white dark:to-gray-300 bg-clip-text text-transparent">
|
||||
Our Supporters
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="mb-20">
|
||||
<h3 className="text-2xl font-semibold text-left sm:text-center mb-8">
|
||||
Engineering Contributors
|
||||
</h3>
|
||||
<div className="flex flex-col sm:flex-row sm:flex-wrap justify-center gap-6 max-w-5xl mx-auto">
|
||||
{ENGINEERING_CONTRIBUTORS.map((supporter) => (
|
||||
<div key={supporter.name} className="w-full sm:w-48">
|
||||
<SupporterLogo supporter={supporter} />
|
||||
</div>
|
||||
))}
|
||||
<div className="w-full sm:w-48">
|
||||
<CommunityContributorsTile />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-2xl font-semibold text-left sm:text-center mb-8">
|
||||
Service Sponsors
|
||||
</h3>
|
||||
<div className="flex flex-col sm:flex-row justify-center gap-6 sm:gap-8 md:gap-12 max-w-4xl mx-auto">
|
||||
{SERVICE_SPONSORS.map((sponsor) => (
|
||||
<div
|
||||
key={sponsor.name}
|
||||
className="flex flex-col items-center w-full mb-6 sm:mb-0 sm:w-auto"
|
||||
>
|
||||
<SupporterLogo supporter={sponsor} />
|
||||
<p className="mt-3 text-sm text-gray-600 dark:text-gray-400 text-center w-full">
|
||||
{sponsor.contribution}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
50
src/components/Supporters/supporters.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
export const ENGINEERING_CONTRIBUTORS = [
|
||||
{
|
||||
name: "Harness",
|
||||
logoLight: "/img/supporters/harness-light.svg",
|
||||
logoDark: "/img/supporters/harness-dark.svg",
|
||||
url: "https://www.harness.io/",
|
||||
},
|
||||
{
|
||||
name: "Gruntwork",
|
||||
logoLight: "/img/supporters/gruntwork-light.svg",
|
||||
logoDark: "/img/supporters/gruntwork-dark.svg",
|
||||
url: "https://gruntwork.io",
|
||||
},
|
||||
{
|
||||
name: "Spacelift",
|
||||
logoLight: "/img/supporters/spacelift-light.svg",
|
||||
logoDark: "/img/supporters/spacelift-dark.svg",
|
||||
url: "https://spacelift.io",
|
||||
},
|
||||
{
|
||||
name: "env0",
|
||||
// TODO: Get good env0 logos
|
||||
logoLight: "/img/supporters/env0-light.svg",
|
||||
logoDark: "/img/supporters/env0-dark.svg",
|
||||
url: "https://www.env0.com/",
|
||||
},
|
||||
{
|
||||
name: "Scalr",
|
||||
logoLight: "/img/supporters/scalr-light.svg",
|
||||
logoDark: "/img/supporters/scalr-dark.svg",
|
||||
url: "https://www.scalr.com/",
|
||||
},
|
||||
];
|
||||
|
||||
export const SERVICE_SPONSORS = [
|
||||
{
|
||||
name: "Buildkite",
|
||||
logoLight: "/img/supporters/buildkite-light.svg",
|
||||
logoDark: "/img/supporters/buildkite-dark.svg",
|
||||
url: "https://buildkite.com/",
|
||||
contribution: "Package hosting",
|
||||
},
|
||||
{
|
||||
name: "Cloudflare",
|
||||
logoLight: "/img/supporters/cloudflare-light.svg",
|
||||
logoDark: "/img/supporters/cloudflare-dark.svg",
|
||||
url: "https://www.cloudflare.com/",
|
||||
contribution: "Website hosting & additional services",
|
||||
},
|
||||
];
|
||||
|
|
@ -96,12 +96,28 @@ body {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.DocSearch .DocSearch-Hit[aria-selected="true"] a {
|
||||
background-color: var(--docsearch-highlight-background-selected);
|
||||
.DocSearch-Button {
|
||||
border-radius: 4px !important;
|
||||
height: 32px !important;
|
||||
padding: 0 12px !important;
|
||||
margin: 0 !important;
|
||||
border: 1px solid transparent !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.DocSearch .DocSearch-Hits mark {
|
||||
color: var(--docsearch-highlight-mark-color);
|
||||
.DocSearch-Button:hover {
|
||||
background: var(--docsearch-searchbox-background) !important;
|
||||
box-shadow: 0 0 0 0 !important;
|
||||
border: 1px solid rgba(125, 125, 125, 0.2) !important;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Placeholder {
|
||||
font-size: 14px !important;
|
||||
padding: 0 8px 0 6px !important;
|
||||
}
|
||||
|
||||
.DocSearch .DocSearch-Hit[aria-selected="true"] a {
|
||||
background-color: var(--docsearch-highlight-background-selected);
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
|
|
@ -118,4 +134,64 @@ body {
|
|||
|
||||
h1 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
|
||||
div[class*="announcementBar"] {
|
||||
position: relative !important;
|
||||
top: 6px !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.announcement-bar {
|
||||
min-height: 48px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .announcement-bar-link {
|
||||
color: white;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .announcement-bar-link:hover {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
html[data-theme="light"] .announcement-bar-link {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
html[data-theme="light"] .announcement-bar-link:hover {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.announcement-bar-link {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-decoration: none !important;
|
||||
transition: all 0.2s ease;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.announcement-bar-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.announcement-arrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
margin-left: 4px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.announcement-bar-link:hover .announcement-arrow {
|
||||
transform: translateX(0.25rem);
|
||||
}
|
||||
|
|
|
|||
9
src/data/contributor-stats.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"timestamp": "2025-04-22T10:32:33.300Z",
|
||||
"stats": {
|
||||
"contributors": {
|
||||
"total": 187,
|
||||
"as_of_date": "2023-08-25"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/icons/opentofu.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<svg
|
||||
className="w-3.5 h-3.5 mr-1.5"
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M23.6628 4.80138C23.8728 4.686 24.1271 4.686 24.337 4.80138L39.3069 13.0294C39.7906 13.2953 39.7906 13.9902 39.3069 14.256L24.337 22.4841C24.1271 22.5995 23.8728 22.5995 23.6628 22.4841L8.69295 14.256C8.20929 13.9902 8.20929 13.2953 8.69295 13.0294L23.6628 4.80138Z"
|
||||
fill="#E7C200"
|
||||
/>
|
||||
<path
|
||||
d="M6.32202 16.7975C6.32202 16.2653 6.89255 15.9279 7.35896 16.1842L22.4708 24.4903C22.6946 24.6133 22.8336 24.8483 22.8336 25.1036V41.5597C22.8336 42.0919 22.2631 42.4294 21.7967 42.173L6.68477 33.8669C6.46104 33.7439 6.32202 33.5089 6.32202 33.2536V16.7975Z"
|
||||
fill="#FFDA18"
|
||||
/>
|
||||
<path
|
||||
d="M40.6406 16.1842C41.1071 15.9279 41.6776 16.2653 41.6776 16.7975V33.2536C41.6776 33.5089 41.5386 33.7439 41.3148 33.8669L26.203 42.173C25.7365 42.4294 25.166 42.0919 25.166 41.5597V25.1036C25.166 24.8483 25.305 24.6133 25.5288 24.4903L40.6406 16.1842Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1,012 B |
|
|
@ -1,16 +1,16 @@
|
|||
import React from "react";
|
||||
import Layout from "@theme/Layout";
|
||||
import Hero from "../components/Hero";
|
||||
import Goals from "../components/Goals";
|
||||
import Features from "../components/Features";
|
||||
import Supporters from "../components/Supporters";
|
||||
import FAQ from "../components/FAQ";
|
||||
import HowToContribute from "../components/HowToContribute";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Layout description="The open source infrastructure as code tool.">
|
||||
<Layout description="OpenTofu - Modern Infrastructure as Code">
|
||||
<Hero />
|
||||
<Goals />
|
||||
<Features />
|
||||
<HowToContribute />
|
||||
<FAQ />
|
||||
<Supporters />
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ function DropdownNavbarItemDesktop({
|
|||
}
|
||||
/>
|
||||
<nav
|
||||
className="absolute shadow-2xl bg-gray-150 dark:bg-gray-700 p-3 gap-3 hidden group-hover:flex peer-aria-expanded:flex flex-col w-36"
|
||||
className="absolute shadow-2xl bg-gray-150 dark:bg-gray-700 p-3 gap-3 hidden group-hover:flex peer-aria-expanded:flex flex-col w-36 z-50"
|
||||
role="navigation"
|
||||
aria-labelledby={id}
|
||||
>
|
||||
|
|
|
|||
29
src/utils/useTheme.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { useState, useEffect } from "react";
|
||||
|
||||
export function useTheme(): boolean {
|
||||
const [isDarkTheme, setIsDarkTheme] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Safe to access DOM after hydration
|
||||
const isDark =
|
||||
document.documentElement.getAttribute("data-theme") === "dark";
|
||||
setIsDarkTheme(isDark);
|
||||
|
||||
// Set up observer to detect theme changes
|
||||
const observer = new MutationObserver(() => {
|
||||
const newIsDark =
|
||||
document.documentElement.getAttribute("data-theme") === "dark";
|
||||
setIsDarkTheme(newIsDark);
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-theme"],
|
||||
});
|
||||
|
||||
// Clean up observer on unmount
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return isDarkTheme;
|
||||
}
|
||||
1
static/img/supporters/buildkite-dark.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 962 160"><g clip-path="url(#a)"><path fill="#14CC80" d="M160 80v80l80-40V40l-80 40Z"/><path fill="#30F2A2" d="M160 0v80l80-40-80-40Z"/><path fill="#14CC80" d="M80 40v80l80-40V0L80 40Z"/><path fill="#30F2A2" d="M0 0v80l80 40V40L0 0Z"/></g><path fill="#140D30" d="M303 119.734h52.767c26.157 0 39.157-10.714 39.157-32.297 0-11.47-5.745-20.527-15.269-24.599v-.302c7.104-3.774 11.34-11.318 11.34-20.375 0-16.451-13.152-28.071-31.299-28.071H303v105.644Zm19.506-62.481V31.296h33.714c9.826 0 15.269 4.529 15.269 12.827 0 8.752-5.141 13.13-15.269 13.13h-33.714Zm0 45.125v-29.58h34.775c12.246 0 18.142 4.83 18.142 14.639 0 9.808-5.594 14.941-18.293 14.941h-34.624ZM406.988 86.234c0 22.334 13.609 35.765 35.832 35.765 11.944 0 21.468-3.774 28.12-10.563h.306v8.299h18.142V39.75h-18.75v43.465c0 12.827-9.525 21.885-22.978 21.885-13.454 0-21.926-7.996-21.926-21.885V39.75h-18.746v46.484ZM505.944 119.735h18.751V39.751h-18.751v79.984Zm-.755-93.571h19.959V7h-19.959v19.168-.004ZM541.534 119.735h18.747V9.566h-18.747v110.169ZM574.244 79.743c0 24.749 17.992 42.257 43.238 42.257 11.944 0 21.775-3.925 27.973-10.714h.302v8.449h17.69V9.566h-18.746v37.728h-.302c-6.505-6.19-16.331-9.808-27.671-9.808-24.341 0-42.484 18.262-42.484 42.257Zm70.457 5.133c0 11.317-11.341 20.677-25.403 20.677-15.873 0-26.307-10.11-26.307-25.806 0-15.696 10.434-25.806 26.156-25.806 13.911 0 25.554 9.053 25.554 20.376V84.88v-.004ZM680.026 119.735h18.75V96.797l15.27-12.978h.302l29.181 35.916h23.284l-39.615-47.54 37.95-32.45h-26.761l-39.309 34.261h-.302V9.566h-18.75v110.169ZM777.182 119.735h18.746V39.751h-18.746v79.984Zm-.755-93.571h19.958V7h-19.958v19.168-.004ZM869.008 55.749V39.75h-25.855V20.43h-18.747v19.32h-18.444v15.998h18.444v40.898c0 16.149 7.411 23.089 25.704 23.089h15.421V102.53H851.62c-6.651 0-8.467-1.51-8.467-6.793V55.749h25.855ZM874.265 80.045c0 25.353 17.086 41.955 44.149 41.955 16.477 0 29.331-6.039 38.553-17.961L944.42 92.873c-7.411 9.204-15.426 13.582-26.157 13.582-14.666 0-24.799-8.148-25.403-20.678h67.282v-5.586c0-24.296-17.086-42.71-42.79-42.71s-43.087 17.66-43.087 42.56v.004Zm18.897-7.846c1.213-11.318 11.039-19.168 24.497-19.168s22.977 7.85 24.039 19.168h-48.536Z"/><defs><clipPath id="a"><path fill="#fff" d="M0 0h240v160H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
1
static/img/supporters/buildkite-light.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 962 160"><g clip-path="url(#a)"><path fill="#14CC80" d="M160 80v80l80-40V40l-80 40Z"/><path fill="#30F2A2" d="M160 0v80l80-40-80-40Z"/><path fill="#14CC80" d="M80 40v80l80-40V0L80 40Z"/><path fill="#30F2A2" d="M0 0v80l80 40V40L0 0Z"/></g><path fill="#fff" d="M303 119.735h52.767c26.157 0 39.157-10.715 39.157-32.298 0-11.47-5.745-20.527-15.269-24.599v-.302c7.104-3.774 11.34-11.318 11.34-20.375 0-16.451-13.152-28.071-31.299-28.071H303v105.645Zm19.506-62.482V31.296h33.714c9.826 0 15.269 4.529 15.269 12.827 0 8.752-5.141 13.13-15.269 13.13h-33.714Zm0 45.125v-29.58h34.775c12.246 0 18.142 4.83 18.142 14.639 0 9.808-5.594 14.941-18.293 14.941h-34.624ZM406.988 86.234c0 22.334 13.609 35.765 35.832 35.765 11.944 0 21.468-3.774 28.12-10.563h.306v8.299h18.142V39.75h-18.75v43.465c0 12.827-9.525 21.885-22.978 21.885-13.454 0-21.926-7.996-21.926-21.885V39.75h-18.746v46.484ZM505.944 119.735h18.751V39.751h-18.751v79.984Zm-.755-93.571h19.959V7h-19.959v19.168-.004ZM541.534 119.735h18.747V9.566h-18.747v110.169ZM574.244 79.743c0 24.749 17.992 42.257 43.238 42.257 11.944 0 21.775-3.925 27.973-10.714h.302v8.449h17.69V9.566h-18.746v37.728h-.302c-6.505-6.19-16.331-9.808-27.671-9.808-24.341 0-42.484 18.262-42.484 42.257Zm70.457 5.133c0 11.317-11.341 20.677-25.403 20.677-15.873 0-26.307-10.11-26.307-25.806 0-15.696 10.434-25.806 26.156-25.806 13.911 0 25.554 9.053 25.554 20.376V84.88v-.004ZM680.026 119.735h18.75V96.797l15.27-12.978h.302l29.181 35.916h23.284l-39.615-47.54 37.95-32.45h-26.761l-39.309 34.261h-.302V9.566h-18.75v110.169ZM777.182 119.735h18.746V39.751h-18.746v79.984Zm-.755-93.571h19.958V7h-19.958v19.168-.004ZM869.008 55.749V39.75h-25.855V20.43h-18.747v19.32h-18.444v15.998h18.444v40.898c0 16.149 7.411 23.089 25.704 23.089h15.421V102.53H851.62c-6.651 0-8.467-1.51-8.467-6.793V55.749h25.855ZM874.265 80.045c0 25.353 17.086 41.955 44.149 41.955 16.477 0 29.331-6.039 38.553-17.961L944.42 92.873c-7.411 9.204-15.426 13.582-26.157 13.582-14.666 0-24.799-8.148-25.403-20.678h67.282v-5.586c0-24.296-17.086-42.71-42.79-42.71s-43.087 17.66-43.087 42.56v.004Zm18.897-7.846c1.213-11.318 11.039-19.168 24.497-19.168s22.977 7.85 24.039 19.168h-48.536Z"/><defs><clipPath id="a"><path fill="#fff" d="M0 0h240v160H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
12
static/img/supporters/cloudflare-dark.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="60">
|
||||
<path
|
||||
d="M19.5 46.685h4.24v2.127h-6.68v-8.774h2.44zm6.756-2.235v-.03c0-2.518 2.033-4.567 4.74-4.567s4.708 2.018 4.708 4.536v.03c0 2.518-2.033 4.567-4.74 4.567s-4.708-2.018-4.708-4.536m6.976 0v-.03c0-1.267-.907-2.362-2.252-2.362-1.33 0-2.22 1.08-2.22 2.346v.03c0 1.267.907 2.362 2.237 2.362 1.345 0 2.237-1.08 2.237-2.346m5.466.515v-4.927h2.47v4.88c0 1.267.64 1.86 1.6 1.86s1.6-.58 1.6-1.8v-4.942h2.47V44.9c0 2.83-1.6 4.067-4.113 4.067-2.487 0-4.05-1.25-4.05-4.004m11.88-4.925h3.378c3.128 0 4.958 1.8 4.958 4.332v.03c0 2.534-1.846 4.4-5.005 4.4h-3.33v-8.774zm3.425 6.616c1.455 0 2.424-.798 2.424-2.22v-.03c0-1.408-.97-2.22-2.424-2.22h-.985v4.458h.985zm8.466-6.616h7.023v2.127h-4.598v1.502h4.16v2.018h-4.16v3.128H62.45zm12.825 6.647h4.254v2.127h-6.68v-8.774h2.424zm10.604-6.7h2.346l3.738 8.837h-2.6l-.64-1.564h-3.38l-.626 1.564h-2.55l3.722-8.837zm2.143 5.38l-.97-2.487-.985 2.487h1.955zm7.08-5.317h4.145c1.345 0 2.268.344 2.862.954.516.5.782 1.173.782 2.05v.03c0 1.345-.72 2.237-1.8 2.7l2.096 3.066h-2.815l-1.767-2.66H97.53v2.66H95.1v-8.8zm4.035 4.207c.83 0 1.298-.407 1.298-1.032v-.03c0-.688-.5-1.032-1.314-1.032h-1.595v2.096h1.6zm9.665 2.493h4.708v2.065h-7.116V40.04h7.054v2.065H108.8v1.33h4.207v1.924H108.8zM11.74 45.48c-.344.766-1.064 1.314-2.002 1.314-1.33 0-2.237-1.1-2.237-2.362v-.03c0-1.267.892-2.346 2.22-2.346 1 0 1.767.6 2.08 1.455h2.565c-.407-2.096-2.252-3.644-4.63-3.644-2.706 0-4.74 2.05-4.74 4.567v.03C5 46.982 7.002 49 9.708 49c2.315 0 4.13-1.502 4.598-3.504l-2.565-.016z"
|
||||
fill="#404041" />
|
||||
<path d="M102.7 21.7l-27.45.188v13.936h35.316V26.04l-6.7-3.848z" fill="#fff" />
|
||||
<path
|
||||
d="M98.343 34.532c.328-1.126.203-2.158-.344-2.925-.5-.704-1.345-1.1-2.362-1.157l-19.254-.25c-.125 0-.235-.063-.297-.156s-.078-.22-.047-.344a.53.53 0 0 1 .454-.344l19.426-.25c2.3-.1 4.802-1.97 5.678-4.254l1.1-2.894a.62.62 0 0 0 .031-.375c-1.25-5.662-6.303-9.885-12.34-9.885a12.65 12.65 0 0 0-11.98 8.587c-1.095-.813-2.487-1.25-3.988-1.1a5.7 5.7 0 0 0-5.083 5.083 5.97 5.97 0 0 0 .14 1.986 8.08 8.08 0 0 0-7.852 8.086 9.85 9.85 0 0 0 .078 1.173c.03.188.188.328.375.328h35.535c.203 0 .4-.14.454-.344l.266-.954z"
|
||||
fill="#f38020" />
|
||||
<path
|
||||
d="M104.474 22.16l-.532.016c-.125 0-.235.094-.282.22l-.75 2.612c-.328 1.126-.203 2.158.344 2.925.5.704 1.345 1.1 2.362 1.157l4.098.25c.125 0 .235.063.297.156a.44.44 0 0 1 .047.344.53.53 0 0 1-.454.344l-4.27.25c-2.315.1-4.802 1.97-5.678 4.254l-.313.798c-.063.156.047.313.22.313h14.67c.172 0 .328-.1.375-.282a10.69 10.69 0 0 0 .391-2.847 10.54 10.54 0 0 0-10.526-10.511"
|
||||
fill="#faae40" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
12
static/img/supporters/cloudflare-light.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="60">
|
||||
<path
|
||||
d="M19.5 46.685h4.24v2.127h-6.68v-8.774h2.44zm6.756-2.235v-.03c0-2.518 2.033-4.567 4.74-4.567s4.708 2.018 4.708 4.536v.03c0 2.518-2.033 4.567-4.74 4.567s-4.708-2.018-4.708-4.536m6.976 0v-.03c0-1.267-.907-2.362-2.252-2.362-1.33 0-2.22 1.08-2.22 2.346v.03c0 1.267.907 2.362 2.237 2.362 1.345 0 2.237-1.08 2.237-2.346m5.466.515v-4.927h2.47v4.88c0 1.267.64 1.86 1.6 1.86s1.6-.58 1.6-1.8v-4.942h2.47V44.9c0 2.83-1.6 4.067-4.113 4.067-2.487 0-4.05-1.25-4.05-4.004m11.88-4.925h3.378c3.128 0 4.958 1.8 4.958 4.332v.03c0 2.534-1.846 4.4-5.005 4.4h-3.33v-8.774zm3.425 6.616c1.455 0 2.424-.798 2.424-2.22v-.03c0-1.408-.97-2.22-2.424-2.22h-.985v4.458h.985zm8.466-6.616h7.023v2.127h-4.598v1.502h4.16v2.018h-4.16v3.128H62.45zm12.825 6.647h4.254v2.127h-6.68v-8.774h2.424zm10.604-6.7h2.346l3.738 8.837h-2.6l-.64-1.564h-3.38l-.626 1.564h-2.55l3.722-8.837zm2.143 5.38l-.97-2.487-.985 2.487h1.955zm7.08-5.317h4.145c1.345 0 2.268.344 2.862.954.516.5.782 1.173.782 2.05v.03c0 1.345-.72 2.237-1.8 2.7l2.096 3.066h-2.815l-1.767-2.66H97.53v2.66H95.1v-8.8zm4.035 4.207c.83 0 1.298-.407 1.298-1.032v-.03c0-.688-.5-1.032-1.314-1.032h-1.595v2.096h1.6zm9.665 2.493h4.708v2.065h-7.116V40.04h7.054v2.065H108.8v1.33h4.207v1.924H108.8zM11.74 45.48c-.344.766-1.064 1.314-2.002 1.314-1.33 0-2.237-1.1-2.237-2.362v-.03c0-1.267.892-2.346 2.22-2.346 1 0 1.767.6 2.08 1.455h2.565c-.407-2.096-2.252-3.644-4.63-3.644-2.706 0-4.74 2.05-4.74 4.567v.03C5 46.982 7.002 49 9.708 49c2.315 0 4.13-1.502 4.598-3.504l-2.565-.016z"
|
||||
fill="#fff" />
|
||||
<path d="M102.7 21.7l-27.45.188v13.936h35.316V26.04l-6.7-3.848z" fill="#fff" />
|
||||
<path
|
||||
d="M98.343 34.532c.328-1.126.203-2.158-.344-2.925-.5-.704-1.345-1.1-2.362-1.157l-19.254-.25c-.125 0-.235-.063-.297-.156s-.078-.22-.047-.344a.53.53 0 0 1 .454-.344l19.426-.25c2.3-.1 4.802-1.97 5.678-4.254l1.1-2.894a.62.62 0 0 0 .031-.375c-1.25-5.662-6.303-9.885-12.34-9.885a12.65 12.65 0 0 0-11.98 8.587c-1.095-.813-2.487-1.25-3.988-1.1a5.7 5.7 0 0 0-5.083 5.083 5.97 5.97 0 0 0 .14 1.986 8.08 8.08 0 0 0-7.852 8.086 9.85 9.85 0 0 0 .078 1.173c.03.188.188.328.375.328h35.535c.203 0 .4-.14.454-.344l.266-.954z"
|
||||
fill="#f38020" />
|
||||
<path
|
||||
d="M104.474 22.16l-.532.016c-.125 0-.235.094-.282.22l-.75 2.612c-.328 1.126-.203 2.158.344 2.925.5.704 1.345 1.1 2.362 1.157l4.098.25c.125 0 .235.063.297.156a.44.44 0 0 1 .047.344.53.53 0 0 1-.454.344l-4.27.25c-2.315.1-4.802 1.97-5.678 4.254l-.313.798c-.063.156.047.313.22.313h14.67c.172 0 .328-.1.375-.282a10.69 10.69 0 0 0 .391-2.847 10.54 10.54 0 0 0-10.526-10.511"
|
||||
fill="#faae40" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
11
static/img/supporters/env0-dark.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="35" viewBox="0 0 140 35">
|
||||
<path
|
||||
d="M61.8 34.2H50.5c-2.4 0-4.4-.6-5.8-1.8q-2.1-1.8-2.1-5.1V17.2q0-3.3 2.1-5.1c2.1-1.8 3.3-1.8 5.8-1.8H55c2.4 0 4.4.6 5.7 1.8q2.1 1.8 2.1 5.1v6c0 .5-.2.7-.7.7H47c-.4 0-.5.1-.5.4v2.9c0 2.7 1.5 4.1 4.5 4.1h10.9c.5 0 .7.2.7.7v1.7c0 .3-.3.5-.8.5M47 21.4h11.5c.4 0 .5-.2.5-.5v-3.6c0-2.7-1.5-4-4.5-4H51c-3 0-4.5 1.3-4.5 4v3.6c0 .3.2.5.5.5m25.5 12.8h-2.4c-.5 0-.7-.2-.7-.7V10.9c0-.4.2-.7.7-.7h2.4c.5 0 .7.2.7.7v1.8h.2c.9-1.7 2.7-2.5 5.4-2.5h3c2.4 0 4.3.6 5.6 1.8s2 2.9 2 5.1v16.4c0 .4-.2.7-.7.7h-2.4c-.5 0-.7-.2-.7-.7V17.3c0-2.7-1.5-4.1-4.5-4.1h-3c-1.6 0-2.8.4-3.7 1.1-.9.8-1.3 1.8-1.3 3.2v16c.2.5-.1.7-.6.7m22.1-24h2.5c.5 0 .7.2.9.7l6.4 19.9h.3l6.3-19.9c.1-.4.4-.7.9-.7h2.5c.5 0 .7.2.5.7l-7.7 22.6c-.1.5-.4.7-1 .7h-3.6c-.5 0-.8-.2-1-.7L94 10.9c-.1-.5.1-.7.6-.7"
|
||||
style="fill:#000" />
|
||||
<path
|
||||
d="M30.1.5c2.1 0 3.8 1.7 3.8 3.7s-1.7 3.7-3.8 3.7-3.8-1.7-3.8-3.7S28 .5 30.1.5M1.3 7.9h18.9c.4 0 .8-.3.8-.7v-6c0-.4-.3-.7-.8-.7H1.3C.9.5.5.8.5 1.2v5.9c0 .5.3.8.8.8M8 33.7V14.3c0-.3-.3-.6-.6-.6H1.1c-.3 0-.6.3-.6.6v19.4c0 .3.3.6.6.6h6.3c.4 0 .6-.3.6-.6m6.1.6h19.1c.4 0 .7-.3.7-.7v-6.1c0-.4-.3-.7-.7-.7H14.1c-.4 0-.7.3-.7.7v6.1c0 .4.3.7.7.7m12.2-16.9c0 2 1.7 3.7 3.8 3.7s3.8-1.7 3.8-3.7-1.7-3.7-3.8-3.7-3.8 1.7-3.8 3.7m-12.9 0c0 2 1.7 3.7 3.8 3.7s3.8-1.7 3.8-3.7-1.7-3.7-3.8-3.7-3.8 1.7-3.8 3.7"
|
||||
style="fill:#00edb9" />
|
||||
<path
|
||||
d="M136.9 3.4C135 1.8 132.5 1 129.5 1c-3.4 0-6.2 1.1-7.8 3.1-1.5 1.8-2 3.8-2 8.1V23c0 5 .5 6.8 2.2 8.7 1.8 1.9 4.5 2.9 7.7 2.9s5.8-.9 7.6-2.8c1.7-1.7 2.4-4 2.4-7.7V11c-.1-3.9-.8-5.8-2.7-7.6M123.4 12c0-3 .2-4.1 1.1-5.4 1-1.6 2.9-2.5 5.2-2.5 1.7 0 3.3.6 4.4 1.6.4.4.7.7.9 1.1l-11.6 18.9zm12.4 12c0 2.5-.3 3.9-1.1 5.1-1 1.4-3 2.2-5.1 2.2-2 0-3.9-.8-4.9-2-.1-.1-.2-.2-.3-.4l11.4-18.6z"
|
||||
style="fill:#000" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
static/img/supporters/env0-light.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="35" viewBox="0 0 140 35"><path d="M61.8 34.2H50.5c-2.4 0-4.4-.6-5.8-1.8q-2.1-1.8-2.1-5.1V17.2q0-3.3 2.1-5.1c2.1-1.8 3.3-1.8 5.8-1.8H55c2.4 0 4.4.6 5.7 1.8q2.1 1.8 2.1 5.1v6c0 .5-.2.7-.7.7H47c-.4 0-.5.1-.5.4v2.9c0 2.7 1.5 4.1 4.5 4.1h10.9c.5 0 .7.2.7.7v1.7c0 .3-.3.5-.8.5M47 21.4h11.5c.4 0 .5-.2.5-.5v-3.6c0-2.7-1.5-4-4.5-4H51c-3 0-4.5 1.3-4.5 4v3.6c0 .3.2.5.5.5m25.5 12.8h-2.4c-.5 0-.7-.2-.7-.7V10.9c0-.4.2-.7.7-.7h2.4c.5 0 .7.2.7.7v1.8h.2c.9-1.7 2.7-2.5 5.4-2.5h3c2.4 0 4.3.6 5.6 1.8s2 2.9 2 5.1v16.4c0 .4-.2.7-.7.7h-2.4c-.5 0-.7-.2-.7-.7V17.3c0-2.7-1.5-4.1-4.5-4.1h-3c-1.6 0-2.8.4-3.7 1.1-.9.8-1.3 1.8-1.3 3.2v16c.2.5-.1.7-.6.7m22.1-24h2.5c.5 0 .7.2.9.7l6.4 19.9h.3l6.3-19.9c.1-.4.4-.7.9-.7h2.5c.5 0 .7.2.5.7l-7.7 22.6c-.1.5-.4.7-1 .7h-3.6c-.5 0-.8-.2-1-.7L94 10.9c-.1-.5.1-.7.6-.7" style="fill:#fff"/><path d="M30.1.5c2.1 0 3.8 1.7 3.8 3.7s-1.7 3.7-3.8 3.7-3.8-1.7-3.8-3.7S28 .5 30.1.5M1.3 7.9h18.9c.4 0 .8-.3.8-.7v-6c0-.4-.3-.7-.8-.7H1.3C.9.5.5.8.5 1.2v5.9c0 .5.3.8.8.8M8 33.7V14.3c0-.3-.3-.6-.6-.6H1.1c-.3 0-.6.3-.6.6v19.4c0 .3.3.6.6.6h6.3c.4 0 .6-.3.6-.6m6.1.6h19.1c.4 0 .7-.3.7-.7v-6.1c0-.4-.3-.7-.7-.7H14.1c-.4 0-.7.3-.7.7v6.1c0 .4.3.7.7.7m12.2-16.9c0 2 1.7 3.7 3.8 3.7s3.8-1.7 3.8-3.7-1.7-3.7-3.8-3.7-3.8 1.7-3.8 3.7m-12.9 0c0 2 1.7 3.7 3.8 3.7s3.8-1.7 3.8-3.7-1.7-3.7-3.8-3.7-3.8 1.7-3.8 3.7" style="fill:#00edb9"/><path d="M136.9 3.4C135 1.8 132.5 1 129.5 1c-3.4 0-6.2 1.1-7.8 3.1-1.5 1.8-2 3.8-2 8.1V23c0 5 .5 6.8 2.2 8.7 1.8 1.9 4.5 2.9 7.7 2.9s5.8-.9 7.6-2.8c1.7-1.7 2.4-4 2.4-7.7V11c-.1-3.9-.8-5.8-2.7-7.6M123.4 12c0-3 .2-4.1 1.1-5.4 1-1.6 2.9-2.5 5.2-2.5 1.7 0 3.3.6 4.4 1.6.4.4.7.7.9 1.1l-11.6 18.9zm12.4 12c0 2.5-.3 3.9-1.1 5.1-1 1.4-3 2.2-5.1 2.2-2 0-3.9-.8-4.9-2-.1-.1-.2-.2-.3-.4l11.4-18.6z" style="fill:#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
11
static/img/supporters/gruntwork-dark.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg width="865" height="120" viewBox="0 0 865 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M403.898 86.0484C403.898 95.8191 406.139 103.147 410.621 108.032C415.103 112.82 421.923 115.214 431.081 115.214H453.929V93.8161H442.481C438.194 93.8161 435.417 92.8879 434.151 91.0315C432.884 89.0773 432.251 86.4392 432.251 83.1172V57.0297H454.465L451.094 43.4324C449.958 38.8492 445.854 35.6318 441.145 35.6318H432.251V13.417H403.898V86.0484Z" fill="#0D0622"/>
|
||||
<path d="M767.377 14.8827V115.214H795.729V82.6776L828.174 115.214H865L826.016 77.9595C823.512 75.5663 823.467 71.5737 825.917 69.1247L859.423 35.6317H825.371L795.729 66.2628V14.8827H767.377Z" fill="#0D0622"/>
|
||||
<path d="M721.926 115.214V77.2549C721.926 74.4214 722.267 71.9299 722.949 69.7804C723.729 67.5331 724.849 65.6767 726.31 64.2111C727.772 62.6478 730.11 61.0356 733.325 59.3746C736.541 57.7136 740.292 56.883 744.579 56.883H760.947V35.6318C757.537 35.5341 754.614 35.4852 752.178 35.4852C751.009 35.4852 749.45 35.5341 747.501 35.6318C745.65 35.6318 743.507 35.7295 741.071 35.9249C731.673 36.5824 725.841 40.8711 721.634 49.1093L720.764 45.8567C719.151 39.8252 713.699 35.6318 707.473 35.6318H690.212C690.212 35.6318 693.574 42.6011 693.574 51.8998V115.214H721.926Z" fill="#0D0622"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M607.797 113.602C615.299 116.533 625.14 117.999 637.319 117.999C650.374 117.999 660.215 116.68 666.84 114.041C673.465 111.306 678.532 106.469 682.039 99.5319C685.644 92.497 687.447 84.4851 687.447 75.496C687.447 66.7024 685.839 58.837 682.624 51.8998C679.409 44.8649 674.342 39.9307 667.425 37.0972C661.565 34.697 653.468 33.3134 643.134 32.9463C638.224 32.9463 639.362 26.3556 640.655 22.5065C640.904 21.7652 640.244 20.9828 639.49 21.1805C629.532 23.7894 608.205 31.1069 596.862 43.9658C596.799 44.0364 596.739 44.1063 596.68 44.1753C594.507 46.3887 592.805 48.9636 591.575 51.8998C588.847 58.5439 587.483 66.4093 587.483 75.496C587.483 84.192 588.993 92.0085 592.013 98.9457C595.034 105.785 600.295 110.671 607.797 113.602ZM654.271 90.2986C651.641 93.6207 645.99 95.2817 637.319 95.2817C629.622 95.2817 624.214 93.6207 621.096 90.2986C618.076 86.8789 616.566 81.9447 616.566 75.496C616.566 68.9497 618.076 64.0155 621.096 60.6934C624.214 57.2737 629.622 55.5638 637.319 55.5638C645.99 55.5638 651.641 57.2737 654.271 60.6934C657 64.0155 658.364 68.9497 658.364 75.496C658.364 81.9447 657 86.8789 654.271 90.2986Z" fill="#0D0622"/>
|
||||
<path d="M522.348 76.5222L531.702 115.214H554.711C562.83 115.214 569.905 109.667 571.864 101.766L588.26 35.6318H569.556C563.719 35.6318 558.722 39.8276 557.695 45.5901L550.408 86.4883L537.109 35.6318H518.027C512.562 35.6318 507.781 39.3208 506.38 44.6188L495.311 86.4883L486.396 35.6318H456.29L476.02 115.214H498.997C507.131 115.214 514.215 109.647 516.16 101.727L522.348 76.5222Z" fill="#0D0622"/>
|
||||
<path d="M300.976 35.6316V115.214H329.328V70.3664C329.328 68.0215 329.572 65.9207 330.059 64.0643C330.643 62.2079 331.666 60.6446 333.128 59.3744C334.687 58.1042 336.879 57.176 339.704 56.5897C342.627 55.9058 346.963 55.5638 352.711 55.5638C357.583 55.5638 360.944 56.0035 362.796 56.8828C364.744 57.6645 366.059 58.9836 366.741 60.84C367.423 62.5987 367.764 64.9925 367.764 68.0214V115.214H396.117V62.3056C396.117 55.4661 394.899 49.8968 392.463 45.5977C390.027 41.2009 386.52 37.9766 381.941 35.9247C377.459 33.8729 370.882 32.8469 362.211 32.8469C347.567 32.8469 336.618 36.3748 329.182 49.5488L327.84 44.188C326.582 39.1583 322.073 35.6316 316.902 35.6316H300.976Z" fill="#0D0622"/>
|
||||
<path d="M292.756 35.6318H264.403V80.4793C264.403 82.8243 264.111 84.925 263.526 86.7814C263.039 88.6379 262.016 90.2012 260.457 91.4714C258.996 92.7415 256.804 93.7186 253.881 94.4026C251.055 94.9888 246.768 95.2819 241.02 95.2819C236.148 95.2819 232.738 94.8911 230.79 94.1094C228.938 93.2301 227.672 91.911 226.99 90.1523C226.308 88.2959 225.967 85.8532 225.967 82.8243V35.6318H197.614V88.5401C197.614 95.3796 198.832 100.998 201.268 105.395C203.704 109.694 207.163 112.869 211.644 114.921C216.224 116.973 222.849 117.999 231.52 117.999C246.11 117.999 257.152 114.403 264.549 101.297L266.927 107.799C268.556 112.253 272.784 115.214 277.515 115.214H292.756V35.6318Z" fill="#0D0622"/>
|
||||
<path d="M154.202 77.2567V115.216H125.85V51.9016C125.85 42.6029 122.488 35.6335 122.488 35.6335H139.868C146.288 35.6335 151.854 40.0849 153.283 46.3611L153.91 49.111C158.117 40.8728 163.949 36.5842 173.347 35.9267C175.783 35.7312 177.926 35.6335 179.778 35.6335C181.726 35.5358 183.285 35.487 184.454 35.487C186.89 35.487 189.277 35.5358 192.687 35.6335V56.8848H176.855C172.568 56.8848 168.817 57.7153 165.601 59.3763C162.386 61.0373 160.048 62.6495 158.586 64.2128C157.125 65.6784 156.005 67.5349 155.225 69.7821C154.543 71.9317 154.202 74.4232 154.202 77.2567Z" fill="#0D0622"/>
|
||||
<path d="M56.3697 3.48954C55.9071 2.74538 56.6158 1.66545 57.4572 1.91041C90.428 11.5105 106.726 24.6808 112.234 49.5307H81.0216C79.947 45.33 78.0909 42.2039 75.4533 40.1524C72.9133 38.0032 67.8823 36.9287 60.3602 36.9287C53.4242 36.9287 48.5397 38.1009 45.7066 40.4455C42.8736 42.6924 40.7244 45.965 39.2591 50.2634C37.7937 54.464 37.0611 59.5439 37.0611 65.503C37.0611 71.4621 37.8426 76.542 39.4056 80.7427C40.9687 84.9434 43.2644 88.1671 46.2928 90.414C49.4189 92.6609 53.7172 93.7843 59.1879 93.7843C64.4632 93.7843 68.5173 93.3447 71.3503 92.4655C74.1833 91.5863 76.3325 90.2675 77.7979 88.509C79.2632 86.6529 80.3378 84.4549 81.0216 81.915H72.1594C66.3712 81.915 61.679 77.2227 61.679 71.4345V59.4951H99.6316C104.125 59.4951 107.447 60.7162 109.596 63.1585C111.745 65.503 113.211 69.1176 113.992 74.0021L120 115.178H95.8217L93.7702 101.41C85.3309 114.538 73.8807 117.963 58.4552 117.963C46.0486 117.963 36.2795 115.862 29.1482 111.662C14.6371 102.915 3.17503 83.7935 9.68527 58.9458C10.6867 55.1238 5.24706 53.2973 1.57394 54.0588C1.12395 54.1521 0.402123 53.3494 0.664587 52.9722C2.37897 50.5081 5.6124 46.43 9.97625 43.4503C12.7755 41.5389 11.4897 37.3178 0.796258 36.2967C0.125955 36.2327 -0.242166 35.5041 0.179508 34.9791C4.00953 30.2108 20.3226 12.8445 54.7608 12.8445C58.5885 12.8445 59.3185 8.23271 56.3697 3.48954Z" fill="#0D0622"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6 KiB |
11
static/img/supporters/gruntwork-light.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 865 120" height="120" width="865">
|
||||
<path fill="white" d="M403.898 86.0484C403.898 95.8191 406.139 103.147 410.621 108.032C415.103 112.82 421.923 115.214 431.081 115.214H453.929V93.8161H442.481C438.194 93.8161 435.417 92.8879 434.151 91.0315C432.884 89.0773 432.251 86.4392 432.251 83.1172V57.0297H454.465L451.094 43.4324C449.958 38.8492 445.854 35.6318 441.145 35.6318H432.251V13.417H403.898V86.0484Z"></path>
|
||||
<path fill="white" d="M767.377 14.8827V115.214H795.729V82.6776L828.174 115.214H865L826.016 77.9595C823.512 75.5663 823.467 71.5737 825.917 69.1247L859.423 35.6317H825.371L795.729 66.2628V14.8827H767.377Z"></path>
|
||||
<path fill="white" d="M721.926 115.214V77.2549C721.926 74.4214 722.267 71.9299 722.949 69.7804C723.729 67.5331 724.849 65.6767 726.31 64.2111C727.772 62.6478 730.11 61.0356 733.325 59.3746C736.541 57.7136 740.292 56.883 744.579 56.883H760.947V35.6318C757.537 35.5341 754.614 35.4852 752.178 35.4852C751.009 35.4852 749.45 35.5341 747.501 35.6318C745.65 35.6318 743.507 35.7295 741.071 35.9249C731.673 36.5824 725.841 40.8711 721.634 49.1093L720.764 45.8567C719.151 39.8252 713.699 35.6318 707.473 35.6318H690.212C690.212 35.6318 693.574 42.6011 693.574 51.8998V115.214H721.926Z"></path>
|
||||
<path fill="white" d="M607.797 113.602C615.299 116.533 625.14 117.999 637.319 117.999C650.374 117.999 660.215 116.68 666.84 114.041C673.465 111.306 678.532 106.469 682.039 99.5319C685.644 92.497 687.447 84.4851 687.447 75.496C687.447 66.7024 685.839 58.837 682.624 51.8998C679.409 44.8649 674.342 39.9307 667.425 37.0972C661.565 34.697 653.468 33.3134 643.134 32.9463C638.224 32.9463 639.362 26.3556 640.655 22.5065C640.904 21.7652 640.244 20.9828 639.49 21.1805C629.532 23.7894 608.205 31.1069 596.862 43.9658C596.799 44.0364 596.739 44.1063 596.68 44.1753C594.507 46.3887 592.805 48.9636 591.575 51.8998C588.847 58.5439 587.483 66.4093 587.483 75.496C587.483 84.192 588.993 92.0085 592.013 98.9457C595.034 105.785 600.295 110.671 607.797 113.602ZM654.271 90.2986C651.641 93.6207 645.99 95.2817 637.319 95.2817C629.622 95.2817 624.214 93.6207 621.096 90.2986C618.076 86.8789 616.566 81.9447 616.566 75.496C616.566 68.9497 618.076 64.0155 621.096 60.6934C624.214 57.2737 629.622 55.5638 637.319 55.5638C645.99 55.5638 651.641 57.2737 654.271 60.6934C657 64.0155 658.364 68.9497 658.364 75.496C658.364 81.9447 657 86.8789 654.271 90.2986Z" clip-rule="evenodd" fill-rule="evenodd"></path>
|
||||
<path fill="white" d="M522.348 76.5222L531.702 115.214H554.711C562.83 115.214 569.905 109.667 571.864 101.766L588.26 35.6318H569.556C563.719 35.6318 558.722 39.8276 557.695 45.5901L550.408 86.4883L537.109 35.6318H518.027C512.562 35.6318 507.781 39.3208 506.38 44.6188L495.311 86.4883L486.396 35.6318H456.29L476.02 115.214H498.997C507.131 115.214 514.215 109.647 516.16 101.727L522.348 76.5222Z"></path>
|
||||
<path fill="white" d="M300.976 35.6316V115.214H329.328V70.3664C329.328 68.0215 329.572 65.9207 330.059 64.0643C330.643 62.2079 331.666 60.6446 333.128 59.3744C334.687 58.1042 336.879 57.176 339.704 56.5897C342.627 55.9058 346.963 55.5638 352.711 55.5638C357.583 55.5638 360.944 56.0035 362.796 56.8828C364.744 57.6645 366.059 58.9836 366.741 60.84C367.423 62.5987 367.764 64.9925 367.764 68.0214V115.214H396.117V62.3056C396.117 55.4661 394.899 49.8968 392.463 45.5977C390.027 41.2009 386.52 37.9766 381.941 35.9247C377.459 33.8729 370.882 32.8469 362.211 32.8469C347.567 32.8469 336.618 36.3748 329.182 49.5488L327.84 44.188C326.582 39.1583 322.073 35.6316 316.902 35.6316H300.976Z"></path>
|
||||
<path fill="white" d="M292.756 35.6318H264.403V80.4793C264.403 82.8243 264.111 84.925 263.526 86.7814C263.039 88.6379 262.016 90.2012 260.457 91.4714C258.996 92.7415 256.804 93.7186 253.881 94.4026C251.055 94.9888 246.768 95.2819 241.02 95.2819C236.148 95.2819 232.738 94.8911 230.79 94.1094C228.938 93.2301 227.672 91.911 226.99 90.1523C226.308 88.2959 225.967 85.8532 225.967 82.8243V35.6318H197.614V88.5401C197.614 95.3796 198.832 100.998 201.268 105.395C203.704 109.694 207.163 112.869 211.644 114.921C216.224 116.973 222.849 117.999 231.52 117.999C246.11 117.999 257.152 114.403 264.549 101.297L266.927 107.799C268.556 112.253 272.784 115.214 277.515 115.214H292.756V35.6318Z"></path>
|
||||
<path fill="white" d="M154.202 77.2567V115.216H125.85V51.9016C125.85 42.6029 122.488 35.6335 122.488 35.6335H139.868C146.288 35.6335 151.854 40.0849 153.283 46.3611L153.91 49.111C158.117 40.8728 163.949 36.5842 173.347 35.9267C175.783 35.7312 177.926 35.6335 179.778 35.6335C181.726 35.5358 183.285 35.487 184.454 35.487C186.89 35.487 189.277 35.5358 192.687 35.6335V56.8848H176.855C172.568 56.8848 168.817 57.7153 165.601 59.3763C162.386 61.0373 160.048 62.6495 158.586 64.2128C157.125 65.6784 156.005 67.5349 155.225 69.7821C154.543 71.9317 154.202 74.4232 154.202 77.2567Z"></path>
|
||||
<path fill="white" d="M56.3697 3.48954C55.9071 2.74538 56.6158 1.66545 57.4572 1.91041C90.428 11.5105 106.726 24.6808 112.234 49.5307H81.0216C79.947 45.33 78.0909 42.2039 75.4533 40.1524C72.9133 38.0032 67.8823 36.9287 60.3602 36.9287C53.4242 36.9287 48.5397 38.1009 45.7066 40.4455C42.8736 42.6924 40.7244 45.965 39.2591 50.2634C37.7937 54.464 37.0611 59.5439 37.0611 65.503C37.0611 71.4621 37.8426 76.542 39.4056 80.7427C40.9687 84.9434 43.2644 88.1671 46.2928 90.414C49.4189 92.6609 53.7172 93.7843 59.1879 93.7843C64.4632 93.7843 68.5173 93.3447 71.3503 92.4655C74.1833 91.5863 76.3325 90.2675 77.7979 88.509C79.2632 86.6529 80.3378 84.4549 81.0216 81.915H72.1594C66.3712 81.915 61.679 77.2227 61.679 71.4345V59.4951H99.6316C104.125 59.4951 107.447 60.7162 109.596 63.1585C111.745 65.503 113.211 69.1176 113.992 74.0021L120 115.178H95.8217L93.7702 101.41C85.3309 114.538 73.8807 117.963 58.4552 117.963C46.0486 117.963 36.2795 115.862 29.1482 111.662C14.6371 102.915 3.17503 83.7935 9.68527 58.9458C10.6867 55.1238 5.24706 53.2973 1.57394 54.0588C1.12395 54.1521 0.402123 53.3494 0.664587 52.9722C2.37897 50.5081 5.6124 46.43 9.97625 43.4503C12.7755 41.5389 11.4897 37.3178 0.796258 36.2967C0.125955 36.2327 -0.242166 35.5041 0.179508 34.9791C4.00953 30.2108 20.3226 12.8445 54.7608 12.8445C58.5885 12.8445 59.3185 8.23271 56.3697 3.48954Z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6 KiB |
11
static/img/supporters/harness-dark.svg
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
11
static/img/supporters/harness-light.svg
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
10
static/img/supporters/scalr-dark.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="232" height="64" viewBox="0 0 232 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M99.9153 57C95.4666 57 91.852 56 89.0715 54C86.2911 52 84.6006 49.1889 84 45.5667L92.2079 44.3C92.6305 46.0778 93.5647 47.4778 95.0106 48.5C96.4564 49.5222 98.2804 50.0333 100.483 50.0333C102.418 50.0333 103.908 49.6556 104.953 48.9C106.021 48.1222 106.555 47.0667 106.555 45.7333C106.555 44.9111 106.355 44.2556 105.954 43.7667C105.576 43.2556 104.731 42.7667 103.419 42.3C102.106 41.8333 100.093 41.2444 97.3795 40.5333C94.3544 39.7333 91.9521 38.8778 90.1726 37.9667C88.3931 37.0333 87.1141 35.9333 86.3356 34.6667C85.5571 33.4 85.1678 31.8667 85.1678 30.0667C85.1678 27.8222 85.7572 25.8667 86.9362 24.2C88.1151 22.5333 89.7611 21.2556 91.8742 20.3667C93.9874 19.4556 96.4787 19 99.3481 19C102.151 19 104.631 19.4333 106.789 20.3C108.968 21.1667 110.726 22.4 112.06 24C113.395 25.6 114.218 27.4778 114.529 29.6333L106.321 31.1C106.121 29.5667 105.421 28.3556 104.219 27.4667C103.041 26.5778 101.461 26.0778 99.4815 25.9667C97.5908 25.8556 96.0671 26.1444 94.9105 26.8333C93.7538 27.5 93.1755 28.4444 93.1755 29.6667C93.1755 30.3556 93.409 30.9444 93.8762 31.4333C94.3433 31.9222 95.2775 32.4111 96.6788 32.9C98.1024 33.3889 100.216 33.9889 103.018 34.7C105.888 35.4333 108.179 36.2778 109.892 37.2333C111.627 38.1667 112.872 39.2889 113.628 40.6C114.407 41.9111 114.796 43.5 114.796 45.3667C114.796 48.9889 113.473 51.8333 110.826 53.9C108.201 55.9667 104.564 57 99.9153 57Z" fill="#6A6A6A"/>
|
||||
<path d="M136.418 57C132.703 57 129.534 56.1778 126.909 54.5333C124.284 52.8667 122.271 50.6 120.87 47.7333C119.491 44.8667 118.79 41.6222 118.768 38C118.79 34.3111 119.513 31.0444 120.937 28.2C122.382 25.3333 124.429 23.0889 127.076 21.4667C129.723 19.8222 132.87 19 136.518 19C140.611 19 144.07 20.0333 146.895 22.1C149.742 24.1444 151.599 26.9444 152.467 30.5L144.459 32.6667C143.836 30.7333 142.802 29.2333 141.356 28.1667C139.91 27.0778 138.264 26.5333 136.418 26.5333C134.327 26.5333 132.603 27.0333 131.246 28.0333C129.89 29.0111 128.889 30.3667 128.244 32.1C127.598 33.8333 127.276 35.8 127.276 38C127.276 41.4222 128.043 44.1889 129.578 46.3C131.113 48.4111 133.393 49.4667 136.418 49.4667C138.553 49.4667 140.233 48.9778 141.456 48C142.702 47.0222 143.636 45.6111 144.259 43.7667L152.467 45.6C151.355 49.2667 149.408 52.0889 146.628 54.0667C143.847 56.0222 140.444 57 136.418 57Z" fill="#6A6A6A"/>
|
||||
<path d="M167.308 57C164.706 57 162.504 56.5111 160.702 55.5333C158.9 54.5333 157.532 53.2111 156.598 51.5667C155.686 49.9222 155.23 48.1111 155.23 46.1333C155.23 44.4 155.519 42.8444 156.097 41.4667C156.676 40.0667 157.565 38.8667 158.767 37.8667C159.968 36.8444 161.525 36.0111 163.438 35.3667C164.884 34.9 166.574 34.4778 168.509 34.1C170.467 33.7222 172.58 33.3778 174.849 33.0667C177.14 32.7333 179.531 32.3778 182.022 32L179.153 33.6333C179.175 31.1444 178.619 29.3111 177.485 28.1333C176.35 26.9556 174.437 26.3667 171.746 26.3667C170.122 26.3667 168.554 26.7444 167.041 27.5C165.529 28.2556 164.472 29.5556 163.872 31.4L156.531 29.1C157.421 26.0556 159.111 23.6111 161.603 21.7667C164.116 19.9222 167.497 19 171.746 19C174.949 19 177.763 19.5222 180.187 20.5667C182.634 21.6111 184.447 23.3222 185.626 25.7C186.271 26.9667 186.66 28.2667 186.794 29.6C186.927 30.9111 186.994 32.3444 186.994 33.9V56H179.954V48.2L181.121 49.4667C179.498 52.0667 177.596 53.9778 175.416 55.2C173.258 56.4 170.556 57 167.308 57ZM168.91 50.6C170.734 50.6 172.291 50.2778 173.581 49.6333C174.871 48.9889 175.894 48.2 176.65 47.2667C177.429 46.3333 177.952 45.4556 178.219 44.6333C178.641 43.6111 178.875 42.4444 178.919 41.1333C178.986 39.8 179.019 38.7222 179.019 37.9L181.488 38.6333C179.064 39.0111 176.984 39.3444 175.249 39.6333C173.514 39.9222 172.024 40.2 170.778 40.4667C169.533 40.7111 168.431 40.9889 167.475 41.3C166.541 41.6333 165.751 42.0222 165.106 42.4667C164.461 42.9111 163.961 43.4222 163.605 44C163.271 44.5778 163.104 45.2556 163.104 46.0333C163.104 46.9222 163.327 47.7111 163.771 48.4C164.216 49.0667 164.861 49.6 165.707 50C166.574 50.4 167.642 50.6 168.91 50.6Z" fill="#6A6A6A"/>
|
||||
<path d="M195.013 56V7H203.054V56H195.013Z" fill="#6A6A6A"/>
|
||||
<path d="M211.714 56V20H218.821V28.7667L217.953 27.6333C218.398 26.4333 218.988 25.3444 219.722 24.3667C220.478 23.3667 221.379 22.5444 222.424 21.9C223.314 21.3 224.293 20.8333 225.36 20.5C226.45 20.1444 227.562 19.9333 228.697 19.8667C229.831 19.7778 230.932 19.8222 232 20V27.5C230.932 27.1889 229.698 27.0889 228.296 27.2C226.917 27.3111 225.672 27.7 224.56 28.3667C223.447 28.9667 222.535 29.7333 221.824 30.6667C221.134 31.6 220.622 32.6667 220.289 33.8667C219.955 35.0444 219.788 36.3222 219.788 37.7V56H211.714Z" fill="#6A6A6A"/>
|
||||
<path d="M0 14.7136C0 12.099 1.69319 9.78535 4.1854 8.99459L30.688 0.585503C31.8878 0.204831 33.1769 0.211109 34.3729 0.603451L59.8702 8.96782C62.3341 9.7761 64 12.0758 64 14.6689V17.3311C64 19.9242 62.3341 22.2239 59.8702 23.0322L34.3729 31.3966C33.1769 31.7889 31.8878 31.7952 30.688 31.4145L4.1854 23.0054C1.69319 22.2147 0 19.901 0 17.2864V14.7136Z" fill="#B3DBF1"/>
|
||||
<path d="M0 33.5554C0 29.8381 3.64141 27.2129 7.16824 28.3876L30.6052 36.1941C31.8557 36.6106 33.2086 36.6038 34.4549 36.1746L56.8047 28.4779C60.3291 27.2642 64 29.8825 64 33.6101C64 35.9471 62.5041 38.0218 60.2866 38.7601L34.3975 47.3794C33.1864 47.7826 31.8782 47.789 30.6631 47.3978L3.77737 38.7402C1.52617 38.0153 0 35.9205 0 33.5554Z" fill="#D21212"/>
|
||||
<path d="M0 49.5554C0 45.8381 3.64141 43.2129 7.16824 44.3876L30.6052 52.1941C31.8557 52.6106 33.2086 52.6038 34.4549 52.1746L56.8047 44.4779C60.3291 43.2642 64 45.8825 64 49.6101C64 51.9471 62.5041 54.0218 60.2866 54.7601L34.3975 63.3794C33.1864 63.7826 31.8782 63.789 30.6631 63.3978L3.77737 54.7402C1.52617 54.0153 0 51.9205 0 49.5554Z" fill="#6A6A6A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
10
static/img/supporters/scalr-light.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="232" height="64" viewBox="0 0 232 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M99.9153 57C95.4666 57 91.852 56 89.0715 54C86.2911 52 84.6006 49.1889 84 45.5667L92.2079 44.3C92.6305 46.0778 93.5647 47.4778 95.0106 48.5C96.4564 49.5222 98.2804 50.0333 100.483 50.0333C102.418 50.0333 103.908 49.6556 104.953 48.9C106.021 48.1222 106.555 47.0667 106.555 45.7333C106.555 44.9111 106.355 44.2556 105.954 43.7667C105.576 43.2556 104.731 42.7667 103.419 42.3C102.106 41.8333 100.093 41.2444 97.3795 40.5333C94.3544 39.7333 91.9521 38.8778 90.1726 37.9667C88.3931 37.0333 87.1141 35.9333 86.3356 34.6667C85.5571 33.4 85.1678 31.8667 85.1678 30.0667C85.1678 27.8222 85.7572 25.8667 86.9362 24.2C88.1151 22.5333 89.7611 21.2556 91.8742 20.3667C93.9874 19.4556 96.4787 19 99.3481 19C102.151 19 104.631 19.4333 106.789 20.3C108.968 21.1667 110.726 22.4 112.06 24C113.395 25.6 114.218 27.4778 114.529 29.6333L106.321 31.1C106.121 29.5667 105.421 28.3556 104.219 27.4667C103.041 26.5778 101.461 26.0778 99.4815 25.9667C97.5908 25.8556 96.0671 26.1444 94.9105 26.8333C93.7538 27.5 93.1755 28.4444 93.1755 29.6667C93.1755 30.3556 93.409 30.9444 93.8762 31.4333C94.3433 31.9222 95.2775 32.4111 96.6788 32.9C98.1024 33.3889 100.216 33.9889 103.018 34.7C105.888 35.4333 108.179 36.2778 109.892 37.2333C111.627 38.1667 112.872 39.2889 113.628 40.6C114.407 41.9111 114.796 43.5 114.796 45.3667C114.796 48.9889 113.473 51.8333 110.826 53.9C108.201 55.9667 104.564 57 99.9153 57Z" fill="white"/>
|
||||
<path d="M136.418 57C132.703 57 129.534 56.1778 126.909 54.5333C124.284 52.8667 122.271 50.6 120.87 47.7333C119.491 44.8667 118.79 41.6222 118.768 38C118.79 34.3111 119.513 31.0444 120.937 28.2C122.382 25.3333 124.429 23.0889 127.076 21.4667C129.723 19.8222 132.87 19 136.518 19C140.611 19 144.07 20.0333 146.895 22.1C149.742 24.1444 151.599 26.9444 152.467 30.5L144.459 32.6667C143.836 30.7333 142.802 29.2333 141.356 28.1667C139.91 27.0778 138.264 26.5333 136.418 26.5333C134.327 26.5333 132.603 27.0333 131.246 28.0333C129.89 29.0111 128.889 30.3667 128.244 32.1C127.598 33.8333 127.276 35.8 127.276 38C127.276 41.4222 128.043 44.1889 129.578 46.3C131.113 48.4111 133.393 49.4667 136.418 49.4667C138.553 49.4667 140.233 48.9778 141.456 48C142.702 47.0222 143.636 45.6111 144.259 43.7667L152.467 45.6C151.355 49.2667 149.408 52.0889 146.628 54.0667C143.847 56.0222 140.444 57 136.418 57Z" fill="white"/>
|
||||
<path d="M167.308 57C164.706 57 162.504 56.5111 160.702 55.5333C158.9 54.5333 157.532 53.2111 156.598 51.5667C155.686 49.9222 155.23 48.1111 155.23 46.1333C155.23 44.4 155.519 42.8444 156.097 41.4667C156.676 40.0667 157.565 38.8667 158.767 37.8667C159.968 36.8444 161.525 36.0111 163.438 35.3667C164.884 34.9 166.574 34.4778 168.509 34.1C170.467 33.7222 172.58 33.3778 174.849 33.0667C177.14 32.7333 179.531 32.3778 182.022 32L179.153 33.6333C179.175 31.1444 178.619 29.3111 177.485 28.1333C176.35 26.9556 174.437 26.3667 171.746 26.3667C170.122 26.3667 168.554 26.7444 167.041 27.5C165.529 28.2556 164.472 29.5556 163.872 31.4L156.531 29.1C157.421 26.0556 159.111 23.6111 161.603 21.7667C164.116 19.9222 167.497 19 171.746 19C174.949 19 177.763 19.5222 180.187 20.5667C182.634 21.6111 184.447 23.3222 185.626 25.7C186.271 26.9667 186.66 28.2667 186.794 29.6C186.927 30.9111 186.994 32.3444 186.994 33.9V56H179.954V48.2L181.121 49.4667C179.498 52.0667 177.596 53.9778 175.416 55.2C173.258 56.4 170.556 57 167.308 57ZM168.91 50.6C170.734 50.6 172.291 50.2778 173.581 49.6333C174.871 48.9889 175.894 48.2 176.65 47.2667C177.429 46.3333 177.952 45.4556 178.219 44.6333C178.641 43.6111 178.875 42.4444 178.919 41.1333C178.986 39.8 179.019 38.7222 179.019 37.9L181.488 38.6333C179.064 39.0111 176.984 39.3444 175.249 39.6333C173.514 39.9222 172.024 40.2 170.778 40.4667C169.533 40.7111 168.431 40.9889 167.475 41.3C166.541 41.6333 165.751 42.0222 165.106 42.4667C164.461 42.9111 163.961 43.4222 163.605 44C163.271 44.5778 163.104 45.2556 163.104 46.0333C163.104 46.9222 163.327 47.7111 163.771 48.4C164.216 49.0667 164.861 49.6 165.707 50C166.574 50.4 167.642 50.6 168.91 50.6Z" fill="white"/>
|
||||
<path d="M195.013 56V7H203.054V56H195.013Z" fill="white"/>
|
||||
<path d="M211.714 56V20H218.821V28.7667L217.953 27.6333C218.398 26.4333 218.988 25.3444 219.722 24.3667C220.478 23.3667 221.379 22.5444 222.424 21.9C223.314 21.3 224.293 20.8333 225.36 20.5C226.45 20.1444 227.562 19.9333 228.697 19.8667C229.831 19.7778 230.932 19.8222 232 20V27.5C230.932 27.1889 229.698 27.0889 228.296 27.2C226.917 27.3111 225.672 27.7 224.56 28.3667C223.447 28.9667 222.535 29.7333 221.824 30.6667C221.134 31.6 220.622 32.6667 220.289 33.8667C219.955 35.0444 219.788 36.3222 219.788 37.7V56H211.714Z" fill="white"/>
|
||||
<path d="M0 14.7136C0 12.099 1.69319 9.78535 4.1854 8.99459L30.688 0.585503C31.8878 0.204831 33.1769 0.211109 34.3729 0.603451L59.8702 8.96782C62.3341 9.7761 64 12.0758 64 14.6689V17.3311C64 19.9242 62.3341 22.2239 59.8702 23.0322L34.3729 31.3966C33.1769 31.7889 31.8878 31.7952 30.688 31.4145L4.1854 23.0054C1.69319 22.2147 0 19.901 0 17.2864V14.7136Z" fill="#B3DBF1"/>
|
||||
<path d="M0 33.5554C0 29.8381 3.64141 27.2129 7.16824 28.3876L30.6052 36.1941C31.8557 36.6106 33.2086 36.6038 34.4549 36.1746L56.8047 28.4779C60.3291 27.2642 64 29.8825 64 33.6101C64 35.9471 62.5041 38.0218 60.2866 38.7601L34.3975 47.3794C33.1864 47.7826 31.8782 47.789 30.6631 47.3978L3.77737 38.7402C1.52617 38.0153 0 35.9205 0 33.5554Z" fill="#D21212"/>
|
||||
<path d="M0 49.5554C0 45.8381 3.64141 43.2129 7.16824 44.3876L30.6052 52.1941C31.8557 52.6106 33.2086 52.6038 34.4549 52.1746L56.8047 44.4779C60.3291 43.2642 64 45.8825 64 49.6101C64 51.9471 62.5041 54.0218 60.2866 54.7601L34.3975 63.3794C33.1864 63.7826 31.8782 63.789 30.6631 63.3978L3.77737 54.7402C1.52617 54.0153 0 51.9205 0 49.5554Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
1
static/img/supporters/spacelift-dark.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 232.29 74.31"><defs><style>.d{fill:url(#c);}.e{fill:#16151e;}.f{fill:#131417;}</style><linearGradient id="c" x1="155.73" y1="354.34" x2="232.29" y2="354.34" gradientTransform="translate(-54.38 342.2) rotate(9.24) scale(1 -1)" gradientUnits="userSpaceOnUse"><stop offset=".08" stop-color="#82ffe8"/><stop offset=".95" stop-color="#7c47fc"/></linearGradient></defs><g id="b"><path class="f" d="M220.33,34.82c-.82,6.24-3.33,9.96-6.89,10.22-2.44,.02-4.75-1.11-6.24-3.04,5.31-3.73,8.8-9.52,9.64-15.96-14.21,4.23-28.91,6.61-43.73,7.07,1.72,3.56,4.33,6.63,7.57,8.9-5.7,6.55-8.77,14.99-8.59,23.67h5.99c-.14-6.76,2.06-13.36,6.23-18.67-.9,6.19-1.46,12.42-1.69,18.67h10.63s-1.95-8.06,1.23-8.07c3.18,0,1.22,8.07,1.22,8.07h10.64c-.21-5.9-.73-11.79-1.55-17.65,1.18,.95,2.51,1.71,3.94,2.24,1.64,.61,3.38,.87,5.13,.75,3.17-.24,6.11-1.78,8.09-4.27,2.24-2.67,3.69-6.42,4.31-11.14l-5.94-.78Z"/><ellipse class="d" cx="194.01" cy="23.61" rx="38.75" ry="9.45" transform="translate(-1.27 31.46) rotate(-9.24)"/><path class="f" d="M10.75,52.97c-4.59-.62-4.96-1.47-4.96-2.43,0-.82,.49-2.19,3.75-2.19,3.73,0,4.54,1.53,4.82,2.68l.05,.21h4.85l-.03-.3c-.14-1.47-1.22-6.26-9.45-6.26-6.55,0-8.87,3.37-8.87,6.25,0,3.51,2.65,5.42,8.6,6.21,5.08,.62,5.51,1.69,5.51,2.82,0,1.66-1.5,2.5-4.46,2.5s-4.98-1.08-5.6-3.2l-.06-.2H0l.05,.31c.69,4.34,4.42,6.83,10.23,6.83,6.11,0,9.61-2.41,9.61-6.6,0-2.79-1.11-5.53-9.14-6.64Z"/><path class="f" d="M36.1,44.69c-3.84,0-6,1.59-7.2,3.18-.01-.96-.05-1.93-.11-2.4l-.03-.23h-4.81v.28c.05,1.64,.05,3.32,.05,4.96v23.83h4.92v-10.79c1.64,1.87,4.05,2.87,6.53,2.7,5.83,0,10.24-4.77,10.24-11.09,0-5.95-4.11-10.43-9.57-10.43Zm4.53,10.63c0,3.12-1.56,6.76-5.94,6.76-3.7,0-5.9-2.44-5.9-6.53s2.18-6.72,5.98-6.72c4.05,0,5.86,3.26,5.86,6.49Z"/><path class="f" d="M68.22,60.31v-8.4c0-4.79-3.15-7.23-9.37-7.23-7.88,0-9.15,4.63-9.33,6.62l-.03,.3h4.89l.05-.21c.31-1.43,.93-2.95,4.46-2.95,3.98,0,4.49,1.92,4.49,3.6v.71h-4.38c-7.15,0-10.63,2.22-10.63,6.8,0,3.32,2.46,6.68,7.97,6.68,3.4,0,5.8-.91,7.16-2.7,.02,.65,.08,1.3,.2,1.94l.05,.21h4.65l-.03-.29c-.04-.47-.16-2.95-.16-5.06Zm-15-1.02c0-2.16,1.75-3.09,5.86-3.09,2.32,0,3.64,0,4.3,.03v.45c0,3.76-2.04,5.67-6.06,5.67-2.61,0-4.1-1.11-4.1-3.05h0Z"/><path class="f" d="M88.6,58.95c-.86,2.15-3.03,3.49-5.34,3.28-3.59,0-5.9-2.67-5.9-6.8s2.32-6.76,5.9-6.76c2.33-.2,4.5,1.21,5.25,3.42l.07,.18h4.84l-.05-.31c-.41-2.7-3-7.26-10.07-7.26-5.81-.23-10.71,4.3-10.93,10.11,0,.24-.01,.47,0,.71,0,6.5,4.28,10.7,10.9,10.7,5.23,0,9.04-2.65,10.19-7.08l.09-.34h-4.86l-.07,.16Z"/><path class="f" d="M106.85,44.69c-6.33,0-10.74,4.45-10.74,10.82,0,5.33,3.35,10.7,10.82,10.7,6.93,0,9.4-4.05,10.26-6.47l.13-.36h-4.92l-.08,.14c-1.06,1.9-2.67,2.75-5.23,2.75-3.18,.13-5.88-2.33-6.04-5.51h16.43v-1.37c0-4.94-2.78-10.7-10.63-10.7Zm-.04,3.83c4.35,0,5.39,2.86,5.6,4.77h-11.27c.44-3.04,2.49-4.77,5.67-4.77Z"/><rect class="f" x="121.5" y="35.82" width="4.92" height="29.85"/><path class="f" d="M134.47,35.9c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5,2.5-1.12,2.5-2.5h0c0-1.38-1.12-2.5-2.5-2.5Z"/><rect class="f" x="132.05" y="45.23" width="4.92" height="20.43"/><path class="e" d="M166.66,49.14v-3.9h-5.04v-6.25h-4.92v6.25h-7.74v-1.99c0-2.82,.69-3.67,2.97-3.67,.53,0,1.06,.05,1.58,.15l.33,.08v-3.99l-.2-.05c-.82-.18-1.66-.26-2.49-.24-4.65,0-7.11,2.62-7.11,7.58v2.15h-3.64v3.9h3.64v16.53h4.92v-16.53h7.74v10.63c0,4.33,1.7,6.09,5.86,6.09,1.14,.05,2.27-.09,3.37-.4l.19-.06v-3.66l-.33,.07c-.6,.11-1.21,.16-1.82,.15-1.8,0-2.35-.66-2.35-2.82v-10h5.04Z"/><path class="f" d="M214.76,13.09c-5.54-11.5-19.35-16.32-30.85-10.78-9.2,4.44-14.4,14.39-12.78,24.47,1.11,6.89,46.79-.16,45.62-7.38-.36-2.19-1.03-4.32-1.99-6.32Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
1
static/img/supporters/spacelift-light.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 232.29 74.31"><defs><style>.d{fill:url(#c);}.e{fill:#fff;}</style><linearGradient id="c" x1="155.73" y1="705.01" x2="232.29" y2="705.01" gradientTransform="translate(-110.69 688.32) rotate(9.24) scale(1 -1)" gradientUnits="userSpaceOnUse"><stop offset=".08" stop-color="#82ffe8"/><stop offset=".95" stop-color="#7c47fc"/></linearGradient></defs><g id="b"><path class="e" d="M220.33,34.82c-.82,6.24-3.33,9.96-6.89,10.22-2.44,.02-4.75-1.11-6.24-3.04,5.31-3.73,8.8-9.52,9.64-15.96-14.21,4.23-28.91,6.61-43.73,7.07,1.72,3.56,4.33,6.63,7.57,8.9-5.7,6.55-8.77,14.99-8.59,23.67h5.99c-.14-6.76,2.06-13.36,6.23-18.67-.9,6.19-1.46,12.42-1.69,18.67h10.63s-1.95-8.06,1.23-8.07c3.18,0,1.22,8.07,1.22,8.07h10.64c-.21-5.9-.73-11.79-1.55-17.65,1.18,.95,2.51,1.71,3.94,2.24,1.64,.61,3.38,.87,5.13,.75,3.17-.24,6.11-1.78,8.09-4.27,2.24-2.67,3.69-6.42,4.31-11.14l-5.94-.78Z"/><ellipse class="d" cx="194.01" cy="23.61" rx="38.75" ry="9.45" transform="translate(-1.27 31.46) rotate(-9.24)"/><path class="e" d="M10.75,52.97c-4.59-.62-4.96-1.47-4.96-2.43,0-.82,.49-2.19,3.75-2.19,3.73,0,4.54,1.53,4.82,2.68l.05,.21h4.85l-.03-.3c-.14-1.47-1.22-6.26-9.45-6.26-6.55,0-8.87,3.37-8.87,6.25,0,3.51,2.65,5.42,8.6,6.21,5.08,.62,5.51,1.69,5.51,2.82,0,1.66-1.5,2.5-4.46,2.5s-4.98-1.08-5.6-3.2l-.06-.2H0l.05,.31c.69,4.34,4.42,6.83,10.23,6.83,6.11,0,9.61-2.41,9.61-6.6,0-2.79-1.11-5.53-9.14-6.64Z"/><path class="e" d="M36.1,44.69c-3.84,0-6,1.59-7.2,3.18-.01-.96-.05-1.93-.11-2.4l-.03-.23h-4.81v.28c.05,1.64,.05,3.32,.05,4.96v23.83h4.92v-10.79c1.64,1.87,4.05,2.87,6.53,2.7,5.83,0,10.24-4.77,10.24-11.09,0-5.95-4.11-10.43-9.57-10.43Zm4.53,10.63c0,3.12-1.56,6.76-5.94,6.76-3.7,0-5.9-2.44-5.9-6.53s2.18-6.72,5.98-6.72c4.05,0,5.86,3.26,5.86,6.49Z"/><path class="e" d="M68.21,60.31v-8.4c0-4.79-3.15-7.23-9.37-7.23-7.88,0-9.15,4.63-9.33,6.62l-.03,.3h4.89l.05-.21c.31-1.43,.93-2.95,4.46-2.95,3.98,0,4.49,1.92,4.49,3.6v.71h-4.38c-7.15,0-10.63,2.22-10.63,6.8,0,3.32,2.46,6.68,7.97,6.68,3.4,0,5.8-.91,7.16-2.7,.02,.65,.08,1.3,.2,1.94l.05,.21h4.65l-.03-.29c-.04-.47-.16-2.95-.16-5.06Zm-15-1.02c0-2.16,1.75-3.09,5.86-3.09,2.32,0,3.64,0,4.3,.03v.45c0,3.76-2.04,5.67-6.06,5.67-2.61,0-4.1-1.11-4.1-3.05h0Z"/><path class="e" d="M88.6,58.95c-.86,2.15-3.03,3.49-5.34,3.28-3.59,0-5.9-2.67-5.9-6.8s2.32-6.76,5.9-6.76c2.33-.2,4.5,1.21,5.25,3.42l.07,.18h4.84l-.05-.31c-.41-2.7-3-7.26-10.07-7.26-5.81-.23-10.71,4.3-10.93,10.11,0,.24-.01,.47,0,.71,0,6.5,4.28,10.7,10.9,10.7,5.23,0,9.04-2.65,10.19-7.08l.09-.34h-4.86l-.07,.16Z"/><path class="e" d="M106.85,44.69c-6.33,0-10.74,4.45-10.74,10.82,0,5.33,3.35,10.7,10.82,10.7,6.93,0,9.4-4.05,10.26-6.47l.13-.36h-4.92l-.08,.14c-1.06,1.9-2.67,2.75-5.23,2.75-3.18,.13-5.88-2.33-6.04-5.51h16.43v-1.37c0-4.94-2.78-10.7-10.63-10.7Zm-.04,3.83c4.35,0,5.39,2.86,5.6,4.77h-11.27c.44-3.04,2.49-4.77,5.67-4.77Z"/><rect class="e" x="121.5" y="35.82" width="4.92" height="29.85"/><path class="e" d="M134.47,35.9c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5,2.5-1.12,2.5-2.5h0c0-1.38-1.12-2.5-2.5-2.5Z"/><rect class="e" x="132.05" y="45.23" width="4.92" height="20.43"/><path class="e" d="M166.66,49.14v-3.9h-5.04v-6.25h-4.92v6.25h-7.74v-1.99c0-2.82,.69-3.67,2.97-3.67,.53,0,1.06,.05,1.58,.15l.33,.08v-3.99l-.2-.05c-.82-.18-1.66-.26-2.49-.24-4.65,0-7.11,2.62-7.11,7.58v2.15h-3.64v3.9h3.64v16.53h4.92v-16.53h7.74v10.63c0,4.33,1.7,6.09,5.86,6.09,1.14,.05,2.27-.09,3.37-.4l.19-.06v-3.66l-.33,.07c-.6,.11-1.21,.16-1.82,.15-1.8,0-2.35-.66-2.35-2.82v-10h5.04Z"/><path class="e" d="M214.76,13.09c-5.54-11.5-19.35-16.32-30.85-10.78-9.2,4.44-14.4,14.39-12.78,24.47,1.11,6.89,46.79-.16,45.62-7.38-.36-2.19-1.03-4.32-1.99-6.32Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -5,6 +5,15 @@ module.exports = {
|
|||
content: ["./src/**/*.{js,jsx,ts,tsx,svg}", "./docusaurus.config.js"],
|
||||
theme: {
|
||||
extend: {
|
||||
animation: {
|
||||
scroll: "scroll 30s linear infinite",
|
||||
},
|
||||
keyframes: {
|
||||
scroll: {
|
||||
"0%": { transform: "translateX(0)" },
|
||||
"100%": { transform: "translateX(-50%)" },
|
||||
},
|
||||
},
|
||||
colors: {
|
||||
fontSize: {
|
||||
"5xl": "2.5rem",
|
||||
|
|
|
|||