Website last fixes (#19895)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -1,3 +1,9 @@
|
||||
<p align="center">
|
||||
<a href="https://www.producthunt.com/products/twenty-crm?launch=twenty-2-0">
|
||||
<img src="./packages/twenty-website/public/images/readme/product-hunt-banner.png" alt="We're live on Product Hunt — Support us" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.twenty.com">
|
||||
<img src="./packages/twenty-website/public/images/core/logo.svg" width="100px" alt="Twenty logo" />
|
||||
@@ -6,121 +12,159 @@
|
||||
|
||||
<h2 align="center" >The #1 Open-Source CRM</h2>
|
||||
|
||||
<p align="center"><a href="https://twenty.com">🌐 Website</a> · <a href="https://docs.twenty.com">📚 Documentation</a> · <a href="https://github.com/orgs/twentyhq/projects/1"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="12" height="12"/> Roadmap </a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a></p>
|
||||
<br />
|
||||
|
||||
<p align="center"><a href="https://twenty.com"><img src="./packages/twenty-website/public/images/readme/globe-icon.svg" width="12" height="12"/> Website</a> · <a href="https://docs.twenty.com"><img src="./packages/twenty-website/public/images/readme/book-icon.svg" width="12" height="12"/> Documentation</a> · <a href="https://github.com/orgs/twentyhq/projects/1"><img src="./packages/twenty-website/public/images/readme/map-icon.svg" width="12" height="12"/> Roadmap </a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.twenty.com">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/github-cover-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/github-cover-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/github-cover-light.png" alt="Cover" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/github-cover-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/github-cover-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/github-cover-light.png" alt="Twenty banner" />
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
# Installation
|
||||
|
||||
See:
|
||||
🚀 [Self-hosting](https://docs.twenty.com/developers/self-host/capabilities/docker-compose)
|
||||
🖥️ [Local Setup](https://docs.twenty.com/developers/contribute/capabilities/local-setup)
|
||||
|
||||
# Why Twenty
|
||||
|
||||
We built Twenty for three reasons:
|
||||
Twenty gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves. Twenty is the CRM you build, ship, and version like the rest of your stack.
|
||||
|
||||
**CRMs are too expensive, and users are trapped.** Companies use locked-in customer data to hike prices. It shouldn't be that way.
|
||||
|
||||
**A fresh start is required to build a better experience.** We can learn from past mistakes and craft a cohesive experience inspired by new UX patterns from tools like Notion, Airtable or Linear.
|
||||
|
||||
**We believe in open-source and community.** Hundreds of developers are already building Twenty together. Once we have plugin capabilities, a whole ecosystem will grow around it.
|
||||
<a href="https://twenty.com/why-twenty"><img src="./packages/twenty-website/public/images/readme/star-icon.svg" width="14" height="14"/> Learn more about why we built Twenty</a>
|
||||
|
||||
<br />
|
||||
|
||||
# What You Can Do With Twenty
|
||||
# Installation
|
||||
|
||||
Please feel free to flag any specific needs you have by creating an issue.
|
||||
### <img src="./packages/twenty-website/public/images/readme/globe-icon.svg" width="14" height="14"/> Cloud
|
||||
|
||||
Below are a few features we have implemented to date:
|
||||
The fastest way to get started. Sign up at [twenty.com](https://twenty.com) and spin up a workspace in under a minute, with no infrastructure to manage and always up to date.
|
||||
|
||||
+ [Personalize layouts with filters, sort, group by, kanban and table views](#personalize-layouts-with-filters-sort-group-by-kanban-and-table-views)
|
||||
+ [Customize your objects and fields](#customize-your-objects-and-fields)
|
||||
+ [Create and manage permissions with custom roles](#create-and-manage-permissions-with-custom-roles)
|
||||
+ [Automate workflow with triggers and actions](#automate-workflow-with-triggers-and-actions)
|
||||
+ [Emails, calendar events, files, and more](#emails-calendar-events-files-and-more)
|
||||
### <img src="./packages/twenty-website/public/images/readme/book-icon.svg" width="14" height="14"/> Build an app
|
||||
|
||||
Scaffold a new app with the Twenty CLI:
|
||||
|
||||
## Personalize layouts with filters, sort, group by, kanban and table views
|
||||
```bash
|
||||
npx create-twenty-app my-app
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
Define objects, fields, and views as code:
|
||||
|
||||
```ts
|
||||
import { defineObject, FieldType } from 'twenty-sdk/define';
|
||||
|
||||
export default defineObject({
|
||||
nameSingular: 'deal',
|
||||
namePlural: 'deals',
|
||||
labelSingular: 'Deal',
|
||||
labelPlural: 'Deals',
|
||||
fields: [
|
||||
{ name: 'name', label: 'Name', type: FieldType.TEXT },
|
||||
{ name: 'amount', label: 'Amount', type: FieldType.CURRENCY },
|
||||
{ name: 'closeDate', label: 'Close Date', type: FieldType.DATE_TIME },
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
Then ship it to your workspace:
|
||||
|
||||
```bash
|
||||
npx twenty deploy
|
||||
```
|
||||
|
||||
See the [app development guide](https://docs.twenty.com/developers/extend/apps/getting-started) for objects, views, agents, and logic functions.
|
||||
|
||||
### <img src="./packages/twenty-website/public/images/readme/rocket-icon.svg" width="14" height="14"/> Self-hosting
|
||||
|
||||
Run Twenty on your own infrastructure with [Docker Compose](https://docs.twenty.com/developers/self-host/capabilities/docker-compose), or contribute locally via the [local setup guide](https://docs.twenty.com/developers/contribute/capabilities/local-setup).
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
# Everything you need
|
||||
|
||||
Twenty gives you the building blocks of a modern CRM (objects, views, workflows, and agents) and lets you extend them as code. Here's a tour of what's in the box.
|
||||
|
||||
Want to go deeper? Read the <a href="https://docs.twenty.com/user-guide/introduction"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="14" height="14"/> User Guide</a> for product walkthroughs, or the <a href="https://docs.twenty.com"><img src="./packages/twenty-website/public/images/readme/book-icon.svg" width="14" height="14"/> Documentation</a> for developer reference.
|
||||
|
||||
<table align="center">
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/views-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/views-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/views-light.png" alt="Companies Kanban Views" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-build-apps-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-build-apps-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-build-apps-light.png" alt="Create your apps" />
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
## Customize your objects and fields
|
||||
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://docs.twenty.com/developers/extend/apps/getting-started"><img src="./packages/twenty-website/public/images/readme/code-icon.svg" width="16" height="16"/> Learn more about apps in doc</a></p>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/data-model-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/data-model-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/data-model-light.png" alt="Setting Custom Objects" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-version-control-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-version-control-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-version-control-light.png" alt="Stay on top with version control" />
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
## Create and manage permissions with custom roles
|
||||
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://docs.twenty.com/developers/extend/apps/publishing"><img src="./packages/twenty-website/public/images/readme/monitor-icon.svg" width="16" height="16"/> Learn more about version control in doc</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/permissions-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/permissions-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/permissions-light.png" alt="Permissions" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-all-tools-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-all-tools-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-all-tools-light.png" alt="All the tools you need to build anything" />
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
## Automate workflow with triggers and actions
|
||||
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://docs.twenty.com/developers/extend/apps/building"><img src="./packages/twenty-website/public/images/readme/rocket-icon.svg" width="16" height="16"/> Learn more about primitives in doc</a></p>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/workflows-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/workflows-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/workflows-light.png" alt="Workflows" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-tools-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-tools-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-tools-light.png" alt="Customize your layouts" />
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
## Emails, calendar events, files, and more
|
||||
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://docs.twenty.com/user-guide/views-pipelines/overview"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="16" height="16"/> Learn more about layouts in doc</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/plus-other-features-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/plus-other-features-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/plus-other-features-light.png" alt="Other Features" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-ai-agents-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-ai-agents-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-ai-agents-light.png" alt="AI agents and chats" />
|
||||
</picture>
|
||||
</p>
|
||||
<p align="center"><a href="https://docs.twenty.com/user-guide/ai/overview"><img src="./packages/twenty-website/public/images/readme/message-icon.svg" width="16" height="16"/> Learn more about AI in doc</a></p>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./packages/twenty-website/public/images/readme/v2-crm-tools-dark.png" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="./packages/twenty-website/public/images/readme/v2-crm-tools-light.png" />
|
||||
<img src="./packages/twenty-website/public/images/readme/v2-crm-tools-light.png" alt="Plus all the tools of a good CRM" />
|
||||
</picture>
|
||||
<p align="center"><a href="https://docs.twenty.com/user-guide/introduction"><img src="./packages/twenty-website/public/images/readme/star-icon.svg" width="16" height="16"/> Learn more about CRM features in doc</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
# Stack
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- [Nx](https://nx.dev/)
|
||||
- [NestJS](https://nestjs.com/), with [BullMQ](https://bullmq.io/), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/)
|
||||
- [React](https://reactjs.org/), with [Jotai](https://jotai.org/), [Linaria](https://linaria.dev/) and [Lingui](https://lingui.dev/)
|
||||
|
||||
- <a href="https://www.typescriptlang.org/"><img src="./packages/twenty-website/public/images/readme/stack-typescript.svg" width="14" height="14"/> TypeScript</a>
|
||||
- <a href="https://nx.dev/"><img src="./packages/twenty-website/public/images/readme/stack-nx.svg" width="14" height="14"/> Nx</a>
|
||||
- <a href="https://nestjs.com/"><img src="./packages/twenty-website/public/images/readme/stack-nestjs.svg" width="14" height="14"/> NestJS</a>, with <a href="https://bullmq.io/">BullMQ</a>, <a href="https://www.postgresql.org/"><img src="./packages/twenty-website/public/images/readme/stack-postgresql.svg" width="14" height="14"/> PostgreSQL</a>, <a href="https://redis.io/"><img src="./packages/twenty-website/public/images/readme/stack-redis.svg" width="14" height="14"/> Redis</a>
|
||||
- <a href="https://reactjs.org/"><img src="./packages/twenty-website/public/images/readme/stack-react.svg" width="14" height="14"/> React</a>, with <a href="https://jotai.org/">Jotai</a>, <a href="https://linaria.dev/">Linaria</a> and <a href="https://lingui.dev/">Lingui</a>
|
||||
|
||||
|
||||
|
||||
# Thanks
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.chromatic.com/"><img src="./packages/twenty-website/public/images/readme/chromatic.png" height="30" alt="Chromatic" /></a>
|
||||
<a href="https://greptile.com"><img src="./packages/twenty-website/public/images/readme/greptile.png" height="30" alt="Greptile" /></a>
|
||||
<a href="https://sentry.io/"><img src="./packages/twenty-website/public/images/readme/sentry.png" height="30" alt="Sentry" /></a>
|
||||
<a href="https://crowdin.com/"><img src="./packages/twenty-website/public/images/readme/crowdin.png" height="30" alt="Crowdin" /></a>
|
||||
<a href="https://e2b.dev/"><img src="./packages/twenty-website/public/images/readme/e2b.svg" height="30" alt="E2B" /></a>
|
||||
<a href="https://www.chromatic.com/"><img src="./packages/twenty-website/public/images/readme/chromatic.png" height="28" alt="Chromatic" /></a>
|
||||
|
||||
<a href="https://greptile.com"><img src="./packages/twenty-website/public/images/readme/greptile.png" height="28" alt="Greptile" /></a>
|
||||
|
||||
<a href="https://sentry.io/"><img src="./packages/twenty-website/public/images/readme/sentry.png" height="28" alt="Sentry" /></a>
|
||||
|
||||
<a href="https://crowdin.com/"><img src="./packages/twenty-website/public/images/readme/crowdin.png" height="28" alt="Crowdin" /></a>
|
||||
</p>
|
||||
|
||||
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
|
||||
@@ -128,9 +172,4 @@ Below are a few features we have implemented to date:
|
||||
|
||||
# Join the Community
|
||||
|
||||
- Star the repo
|
||||
- Subscribe to releases (watch -> custom -> releases)
|
||||
- Follow us on [Twitter](https://twitter.com/twentycrm) or [LinkedIn](https://www.linkedin.com/company/twenty/)
|
||||
- Join our [Discord](https://discord.gg/cx5n4Jzs57)
|
||||
- Improve translations on [Crowdin](https://twenty.crowdin.com/twenty)
|
||||
- [Contributions](https://github.com/twentyhq/twenty/contribute) are, of course, most welcome!
|
||||
<p><a href="https://github.com/twentyhq/twenty"><img src="./packages/twenty-website/public/images/readme/star-icon.svg" width="12" height="12"/> Star the repo</a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://github.com/twentyhq/twenty/discussions"><img src="./packages/twenty-website/public/images/readme/message-icon.svg" width="12" height="12"/> Feature requests</a> · <a href="https://github.com/orgs/twentyhq/projects/1/views/35"><img src="./packages/twenty-website/public/images/readme/rocket-icon.svg" width="12" height="12"/> Releases</a> · <a href="https://twitter.com/twentycrm"><img src="./packages/twenty-website/public/images/readme/x-icon.svg" width="12" height="12"/> X</a> · <a href="https://www.linkedin.com/company/twenty/"><img src="./packages/twenty-website/public/images/readme/linkedin-icon.svg" width="12" height="12"/> LinkedIn</a> · <a href="https://twenty.crowdin.com/twenty"><img src="./packages/twenty-website/public/images/readme/language-icon.svg" width="12" height="12"/> Crowdin</a> · <a href="https://github.com/twentyhq/twenty/contribute"><img src="./packages/twenty-website/public/images/readme/code-icon.svg" width="12" height="12"/> Contribute</a></p>
|
||||
|
||||
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 394 KiB |
|
After Width: | Height: | Size: 39 KiB |
@@ -11,6 +11,7 @@ import { TalkToUsButton } from '@/app/components/ContactCalModal';
|
||||
import { FAQ_DATA, MENU_DATA, TRUSTED_BY_DATA } from '@/app/_constants';
|
||||
import { Body, Eyebrow, Heading, LinkButton } from '@/design-system/components';
|
||||
import { Pages } from '@/enums/pages';
|
||||
import { ArrowRightUpIcon } from '@/icons';
|
||||
import { fetchCommunityStats } from '@/lib/community/fetch-community-stats';
|
||||
import { mergeSocialLinkLabels } from '@/lib/community/merge-social-link-labels';
|
||||
import { Faq } from '@/sections/Faq/components';
|
||||
@@ -28,11 +29,15 @@ import { styled } from '@linaria/react';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Twenty | Open Source CRM',
|
||||
description: 'Modular, scalable open source CRM for modern teams.',
|
||||
title: 'Twenty | #1 open source CRM',
|
||||
description:
|
||||
'The #1 open source CRM for modern teams. Modular, scalable, and built to fit your business.',
|
||||
};
|
||||
|
||||
const HOME_TOP_BACKGROUND_COLOR = '#F4F4F4';
|
||||
const PRODUCT_HUNT_LAUNCH_URL =
|
||||
'https://www.producthunt.com/products/twenty-crm?launch=twenty-2-0';
|
||||
const PRODUCT_HUNT_BRAND_COLOR = '#DA552F';
|
||||
|
||||
const HeroHeadingGroup = styled.div`
|
||||
align-items: center;
|
||||
@@ -41,11 +46,63 @@ const HeroHeadingGroup = styled.div`
|
||||
gap: ${theme.spacing(3)};
|
||||
width: 100%;
|
||||
|
||||
> *:nth-child(2) {
|
||||
> *:last-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroLaunchChip = styled.a`
|
||||
align-items: center;
|
||||
background: ${theme.colors.primary.background[100]};
|
||||
border: 1px solid ${theme.colors.primary.border[10]};
|
||||
border-radius: 999px;
|
||||
color: ${theme.colors.primary.text[100]};
|
||||
display: inline-flex;
|
||||
font-family: ${theme.font.family.mono};
|
||||
font-size: ${theme.font.size(2.5)};
|
||||
font-weight: ${theme.font.weight.medium};
|
||||
gap: ${theme.spacing(2)};
|
||||
line-height: ${theme.lineHeight(3)};
|
||||
padding: ${theme.spacing(2)} ${theme.spacing(3)};
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
transition:
|
||||
border-color 180ms ease,
|
||||
color 180ms ease,
|
||||
transform 180ms ease;
|
||||
white-space: nowrap;
|
||||
|
||||
&:is(:hover, :focus-visible) {
|
||||
border-color: ${PRODUCT_HUNT_BRAND_COLOR};
|
||||
color: ${PRODUCT_HUNT_BRAND_COLOR};
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px solid ${theme.colors.highlight[100]};
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroLaunchChipDot = styled.span`
|
||||
background: ${PRODUCT_HUNT_BRAND_COLOR};
|
||||
border-radius: 999px;
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
height: ${theme.spacing(2)};
|
||||
width: ${theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const HeroLaunchChipLabel = styled.span`
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
gap: ${theme.spacing(1.5)};
|
||||
`;
|
||||
|
||||
const HeroIntroGroup = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
@@ -109,6 +166,17 @@ export default async function HomePage() {
|
||||
<Hero.Root backgroundColor={HOME_TOP_BACKGROUND_COLOR} showHomeBackground>
|
||||
<HeroIntroGroup data-halftone-exclude>
|
||||
<HeroHeadingGroup>
|
||||
<HeroLaunchChip
|
||||
href={PRODUCT_HUNT_LAUNCH_URL}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<HeroLaunchChipDot />
|
||||
<HeroLaunchChipLabel>
|
||||
Live on Product Hunt
|
||||
<ArrowRightUpIcon size={8} strokeColor="currentColor" />
|
||||
</HeroLaunchChipLabel>
|
||||
</HeroLaunchChip>
|
||||
<Hero.Heading page={Pages.Home} segments={HERO_DATA.heading} />
|
||||
<Hero.Body page={Pages.Home} body={HERO_DATA.body} size="sm" />
|
||||
</HeroHeadingGroup>
|
||||
|
||||
@@ -25,7 +25,7 @@ export const FAQ_DATA: FaqDataType = {
|
||||
fontFamily: 'sans',
|
||||
},
|
||||
answer: {
|
||||
text: "Yes. Twenty is the #1 open-source CRM on GitHub. Most teams run it on our managed cloud for zero-ops setup; self-hosting is always available if you'd rather own the infrastructure.",
|
||||
text: "Yes. Twenty is the #1 open source CRM on GitHub. Most teams run it on our managed cloud for zero-ops setup; self-hosting is always available if you'd rather own the infrastructure.",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ export const MENU_DATA: MenuDataType = {
|
||||
image: '/images/shared/menu/developers-preview.png',
|
||||
imageAlt: 'Blue developer illustration with branching arrows',
|
||||
imagePosition: 'center',
|
||||
imageScale: 1.4,
|
||||
imageScale: 1.6,
|
||||
title: 'Build on an open platform',
|
||||
description:
|
||||
'APIs, SDKs and webhooks to extend Twenty and ship apps on top of your CRM data.',
|
||||
|
||||
@@ -120,7 +120,7 @@ export const CASE_STUDY_CATALOG_ENTRIES: CaseStudyCatalogEntry[] = [
|
||||
'NetZero uses Twenty as a modular CRM across product lines and countries, with a roadmap into AI-assisted workflows.',
|
||||
date: '2025',
|
||||
coverImageSrc:
|
||||
'https://images.unsplash.com/photo-1510524474345-1c4bac68d1d0?w=1600&q=80',
|
||||
'https://images.unsplash.com/photo-1744830343976-ce690ba2a67c?w=1600&q=80',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ import { theme } from '@/theme';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
const PLACEHOLDER_HERO =
|
||||
'https://images.unsplash.com/photo-1510524474345-1c4bac68d1d0?w=1600&q=80';
|
||||
'https://images.unsplash.com/photo-1744830343976-ce690ba2a67c?w=1600&q=80';
|
||||
|
||||
const CASE_STUDY: CaseStudyData = {
|
||||
meta: {
|
||||
|
||||
@@ -66,8 +66,9 @@ const StyledMain = styled.main`
|
||||
`;
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Twenty | Open Source CRM',
|
||||
description: 'Modular, scalable open source CRM for modern teams.',
|
||||
title: 'Twenty | #1 open source CRM',
|
||||
description:
|
||||
'The #1 open source CRM for modern teams. Modular, scalable, and built to fit your business.',
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
@@ -6,6 +6,6 @@ export const HERO_DATA = {
|
||||
{ text: 'our partner', fontFamily: 'sans', newLine: true },
|
||||
],
|
||||
body: {
|
||||
text: "We're building the #1 open-source CRM, but we can't do it alone. Join our partner ecosystem and grow with us.",
|
||||
text: "We're building the #1 open source CRM, but we can't do it alone. Join our partner ecosystem and grow with us.",
|
||||
},
|
||||
} satisfies HeroBaseDataType;
|
||||
|
||||
@@ -34,7 +34,7 @@ export const THREE_CARDS_ILLUSTRATION_DATA: ThreeCardsIllustrationDataType = {
|
||||
{
|
||||
heading: { text: 'Content & Community Partners', fontFamily: 'sans' },
|
||||
body: {
|
||||
text: "Share Twenty with your audience and help shape the future of open-source CRM. We're looking for creators, educators, and community builders who want to showcase great software.",
|
||||
text: "Share Twenty with your audience and help shape the future of the #1 open source CRM. We're looking for creators, educators, and community builders who want to showcase great software.",
|
||||
},
|
||||
benefits: [
|
||||
{ text: 'Revenue share for referred customers', icon: 'tag' },
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ThreeCards } from '@/sections/ThreeCards/components';
|
||||
import { TrustedBy } from '@/sections/TrustedBy/components';
|
||||
import type { ThreeCardsScrollLayoutOptions } from '@/sections/ThreeCards/utils/three-cards-scroll-layout';
|
||||
import { theme } from '@/theme';
|
||||
import { styled } from '@linaria/react';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
const PARTNER_ILLUSTRATION_CARDS_SCROLL_LAYOUT_OPTIONS: ThreeCardsScrollLayoutOptions =
|
||||
@@ -37,10 +38,18 @@ const PARTNER_ILLUSTRATION_CARDS_SCROLL_LAYOUT_OPTIONS: ThreeCardsScrollLayoutOp
|
||||
stagger: 0.16,
|
||||
};
|
||||
|
||||
const PromoSpacing = styled.div`
|
||||
margin-bottom: ${theme.spacing(8)};
|
||||
|
||||
@media (min-width: ${theme.breakpoints.md}px) {
|
||||
margin-bottom: ${theme.spacing(12)};
|
||||
}
|
||||
`;
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Partners | Twenty',
|
||||
description:
|
||||
'Join our partner ecosystem and grow with us as we build the #1 open-source CRM.',
|
||||
'Join our partner ecosystem and grow with us as we build the #1 open source CRM.',
|
||||
};
|
||||
|
||||
export default async function PartnerPage() {
|
||||
@@ -72,13 +81,16 @@ export default async function PartnerPage() {
|
||||
|
||||
<TrustedBy.Root
|
||||
backgroundColor={theme.colors.primary.background[100]}
|
||||
compactBottom
|
||||
>
|
||||
<TrustedBy.Separator separator={TRUSTED_BY_DATA.separator} />
|
||||
<TrustedBy.Logos logos={TRUSTED_BY_DATA.logos} />
|
||||
<TrustedBy.ClientCount label={TRUSTED_BY_DATA.clientCountLabel.text} />
|
||||
</TrustedBy.Root>
|
||||
|
||||
<CaseStudyCatalog.Promo entries={CASE_STUDY_CATALOG_ENTRIES} />
|
||||
<PromoSpacing>
|
||||
<CaseStudyCatalog.Promo compactTop entries={CASE_STUDY_CATALOG_ENTRIES} />
|
||||
</PromoSpacing>
|
||||
|
||||
<ThreeCards.Root backgroundColor={theme.colors.secondary.background[5]}>
|
||||
<ThreeCards.Intro page={Pages.Partners} align="left">
|
||||
|
||||
@@ -37,7 +37,7 @@ const PricingBannerContainer = styled.div`
|
||||
export const metadata: Metadata = {
|
||||
title: 'Pricing | Twenty',
|
||||
description:
|
||||
'Plans that scale with your team. Compare tiers of the #1 open-source CRM.',
|
||||
'Plans that scale with your team. Compare tiers of the #1 open source CRM.',
|
||||
};
|
||||
|
||||
export default async function PricingPage() {
|
||||
|
||||
@@ -7,5 +7,5 @@ export const RELEASE_NOTES_HERO_HEADING: HeadingType[] = [
|
||||
];
|
||||
|
||||
export const RELEASE_NOTES_HERO_BODY: BodyType = {
|
||||
text: 'Discover the newest features and improvements in Twenty,\nthe #1 open-source CRM.',
|
||||
text: 'Discover the newest features and improvements in Twenty,\nthe #1 open source CRM.',
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Fragment } from 'react';
|
||||
export const metadata: Metadata = {
|
||||
title: 'Releases | Twenty',
|
||||
description:
|
||||
'Discover the newest features and improvements in Twenty, the open-source CRM.',
|
||||
'Discover the newest features and improvements in Twenty, the #1 open source CRM.',
|
||||
};
|
||||
|
||||
export default async function ReleasesPage() {
|
||||
|
||||
@@ -11,7 +11,6 @@ import { LinkButton } from '@/design-system/components';
|
||||
import { Pages } from '@/enums/pages';
|
||||
import { fetchCommunityStats } from '@/lib/community/fetch-community-stats';
|
||||
import { mergeSocialLinkLabels } from '@/lib/community/merge-social-link-labels';
|
||||
import { OverflowProbe } from '@/lib/debug/overflow-probe';
|
||||
import { Editorial } from '@/sections/Editorial/components';
|
||||
import { Hero } from '@/sections/Hero/components';
|
||||
import { Marquee } from '@/sections/Marquee/components';
|
||||
@@ -72,7 +71,6 @@ export default async function WhyTwentyPage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<OverflowProbe />
|
||||
<Menu.Root
|
||||
backgroundColor={theme.colors.secondary.background[100]}
|
||||
scheme="secondary"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const PLUS_PATH = "M.5 7.25H14M7.25 14V.5";
|
||||
const PLUS_PATH = 'M1.5 7.5H13.5M7.5 13.5V1.5';
|
||||
|
||||
interface PlusIconProps {
|
||||
size: number;
|
||||
@@ -13,10 +13,13 @@ export function PlusIcon({ size, strokeColor }: PlusIconProps) {
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
overflow="visible"
|
||||
style={{ display: 'block' }}
|
||||
>
|
||||
<path
|
||||
d={PLUS_PATH}
|
||||
stroke={strokeColor}
|
||||
strokeWidth={1.25}
|
||||
strokeMiterlimit={10}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
|
||||
@@ -32,7 +32,8 @@ const StyledContainer = styled(Container)<{ compactTop: boolean }>`
|
||||
}
|
||||
`;
|
||||
|
||||
const CORNER_OFFSET = '-6px';
|
||||
const CORNER_SIZE = 14;
|
||||
const CORNER_OFFSET = '-7px';
|
||||
|
||||
const FramedGrid = styled.div`
|
||||
position: relative;
|
||||
@@ -89,11 +90,12 @@ const FrameRailBottom = styled.span`
|
||||
const FrameCorner = styled.span`
|
||||
align-items: center;
|
||||
display: none;
|
||||
height: 12px;
|
||||
height: ${CORNER_SIZE}px;
|
||||
justify-content: center;
|
||||
line-height: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
width: ${CORNER_SIZE}px;
|
||||
|
||||
@media (min-width: ${theme.breakpoints.md}px) {
|
||||
display: flex;
|
||||
@@ -157,18 +159,30 @@ export function Grid({
|
||||
{!compactTop && (
|
||||
<>
|
||||
<FrameCornerTopLeft aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerTopLeft>
|
||||
<FrameCornerTopRight aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerTopRight>
|
||||
</>
|
||||
)}
|
||||
<FrameCornerBottomLeft aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerBottomLeft>
|
||||
<FrameCornerBottomRight aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerBottomRight>
|
||||
<CardGrid>
|
||||
{entries.map((entry, index) => {
|
||||
|
||||
@@ -11,7 +11,9 @@ import { PromoMic } from '@/illustrations/CaseStudyCatalog/PromoMic';
|
||||
import { theme } from '@/theme';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const CORNER_OFFSET = '-6px';
|
||||
const CORNER_SIZE = 14;
|
||||
const CORNER_OFFSET = '-7px';
|
||||
const CONNECTED_TOP_OFFSET = '6px';
|
||||
const LINE_INSET = '20px';
|
||||
const TRUSTED_BY_BOTTOM_PADDING = 12;
|
||||
const TRUSTED_BY_BOTTOM_PADDING_DESKTOP = 16;
|
||||
@@ -59,12 +61,13 @@ const FrameBoard = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const Frame = styled.div`
|
||||
const Frame = styled.div<{ compactTop: boolean }>`
|
||||
bottom: ${theme.spacing(12)};
|
||||
left: ${theme.spacing(10)};
|
||||
position: absolute;
|
||||
right: ${theme.spacing(10)};
|
||||
top: ${theme.spacing(12)};
|
||||
top: ${({ compactTop }) =>
|
||||
compactTop ? CONNECTED_TOP_OFFSET : theme.spacing(12)};
|
||||
`;
|
||||
|
||||
const FrameLine = styled.span`
|
||||
@@ -86,28 +89,29 @@ const FrameLineBottom = styled(FrameLine)`
|
||||
right: ${LINE_INSET};
|
||||
`;
|
||||
|
||||
const FrameLineLeft = styled(FrameLine)`
|
||||
const FrameLineLeft = styled(FrameLine)<{ compactTop: boolean }>`
|
||||
bottom: ${LINE_INSET};
|
||||
left: 0;
|
||||
top: ${LINE_INSET};
|
||||
top: ${({ compactTop }) => (compactTop ? '0' : LINE_INSET)};
|
||||
width: 1px;
|
||||
`;
|
||||
|
||||
const FrameLineRight = styled(FrameLine)`
|
||||
const FrameLineRight = styled(FrameLine)<{ compactTop: boolean }>`
|
||||
bottom: ${LINE_INSET};
|
||||
right: 0;
|
||||
top: ${LINE_INSET};
|
||||
top: ${({ compactTop }) => (compactTop ? '0' : LINE_INSET)};
|
||||
width: 1px;
|
||||
`;
|
||||
|
||||
const FrameCorner = styled.span`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 12px;
|
||||
height: ${CORNER_SIZE}px;
|
||||
justify-content: center;
|
||||
line-height: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
width: ${CORNER_SIZE}px;
|
||||
`;
|
||||
|
||||
const FrameCornerTopLeft = styled(FrameCorner)`
|
||||
@@ -130,16 +134,20 @@ const FrameCornerBottomRight = styled(FrameCorner)`
|
||||
right: ${CORNER_OFFSET};
|
||||
`;
|
||||
|
||||
const StyledContainer = styled(Container)`
|
||||
const StyledContainer = styled(Container)<{ compactTop: boolean }>`
|
||||
align-items: center;
|
||||
display: grid;
|
||||
gap: ${theme.spacing(10)};
|
||||
grid-template-columns: 1fr;
|
||||
min-height: 520px;
|
||||
padding-bottom: ${theme.spacing(24 + TRUSTED_BY_BOTTOM_PADDING)};
|
||||
padding-bottom: ${({ compactTop }) =>
|
||||
compactTop
|
||||
? theme.spacing(16)
|
||||
: theme.spacing(24 + TRUSTED_BY_BOTTOM_PADDING)};
|
||||
padding-left: ${theme.spacing(4)};
|
||||
padding-right: ${theme.spacing(4)};
|
||||
padding-top: ${theme.spacing(20)};
|
||||
padding-top: ${({ compactTop }) =>
|
||||
compactTop ? theme.spacing(16) : theme.spacing(20)};
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
@@ -147,12 +155,14 @@ const StyledContainer = styled(Container)`
|
||||
column-gap: ${theme.spacing(16)};
|
||||
grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
|
||||
min-height: 500px;
|
||||
padding-bottom: ${theme.spacing(
|
||||
40 + TRUSTED_BY_BOTTOM_PADDING_DESKTOP,
|
||||
)};
|
||||
padding-bottom: ${({ compactTop }) =>
|
||||
compactTop
|
||||
? `calc(${theme.spacing(24)} + ${theme.spacing(12)} - ${CONNECTED_TOP_OFFSET})`
|
||||
: theme.spacing(40 + TRUSTED_BY_BOTTOM_PADDING_DESKTOP)};
|
||||
padding-left: ${theme.spacing(10)};
|
||||
padding-right: ${theme.spacing(10)};
|
||||
padding-top: ${theme.spacing(32)};
|
||||
padding-top: ${({ compactTop }) =>
|
||||
compactTop ? theme.spacing(24) : theme.spacing(32)};
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -250,41 +260,57 @@ type PromoProps = {
|
||||
entries: readonly CaseStudyCatalogEntry[];
|
||||
ctaHref?: string;
|
||||
ctaLabel?: string;
|
||||
compactTop?: boolean;
|
||||
};
|
||||
|
||||
export function Promo({
|
||||
entries,
|
||||
ctaHref = '/customers',
|
||||
ctaLabel = 'Explore customer stories',
|
||||
compactTop = false,
|
||||
}: PromoProps) {
|
||||
const featured = entries[0];
|
||||
|
||||
return (
|
||||
<Section aria-label="Customer stories preview">
|
||||
<BackgroundLayer aria-hidden>
|
||||
<FrameBoard>
|
||||
<Frame>
|
||||
<FrameLineTop />
|
||||
<Frame compactTop={compactTop}>
|
||||
{!compactTop && <FrameLineTop />}
|
||||
<FrameLineBottom />
|
||||
<FrameLineLeft />
|
||||
<FrameLineRight />
|
||||
<FrameLineLeft compactTop={compactTop} />
|
||||
<FrameLineRight compactTop={compactTop} />
|
||||
{!compactTop && (
|
||||
<>
|
||||
<FrameCornerTopLeft>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerTopLeft>
|
||||
<FrameCornerTopRight>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerTopRight>
|
||||
</>
|
||||
)}
|
||||
<FrameCornerBottomLeft>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerBottomLeft>
|
||||
<FrameCornerBottomRight>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</FrameCornerBottomRight>
|
||||
</Frame>
|
||||
</FrameBoard>
|
||||
</BackgroundLayer>
|
||||
|
||||
<StyledContainer>
|
||||
<StyledContainer compactTop={compactTop}>
|
||||
<VisualColumn>
|
||||
<VisualStage>
|
||||
<MicFrame aria-hidden>
|
||||
|
||||
@@ -8,10 +8,7 @@ import {
|
||||
} from '@/icons';
|
||||
import type { FaqQuestionType } from '@/sections/Faq/types/FaqQuestion';
|
||||
import { theme } from '@/theme';
|
||||
import {
|
||||
Accordion as BaseAccordion,
|
||||
type AccordionTriggerState,
|
||||
} from '@base-ui/react/accordion';
|
||||
import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const QuestionText = styled.span`
|
||||
@@ -55,12 +52,29 @@ const ToggleVisual = styled.span`
|
||||
display: inline-flex;
|
||||
height: 36px;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
width: 36px;
|
||||
`;
|
||||
|
||||
const ToggleIconLayer = styled.span`
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
inset: 0;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
transition:
|
||||
opacity 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
|
||||
&[data-icon='minus'] {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
`;
|
||||
|
||||
const RowTrigger = styled.button`
|
||||
background: transparent;
|
||||
border: none;
|
||||
@@ -123,6 +137,16 @@ export const ItemRow = styled.div`
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&[data-open] ${ToggleIconLayer}[data-icon='plus'] {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
&[data-open] ${ToggleIconLayer}[data-icon='minus'] {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
@media (min-width: ${theme.breakpoints.md}px) {
|
||||
grid-template-columns: 14px 60px 1fr 80px 36px;
|
||||
row-gap: ${theme.spacing(4)};
|
||||
@@ -186,13 +210,7 @@ export function Item({ question, value }: ItemProps) {
|
||||
return (
|
||||
<BaseAccordion.Item key={value} value={value} render={<ItemRow />}>
|
||||
<BaseAccordion.Header render={<Header />}>
|
||||
<BaseAccordion.Trigger
|
||||
render={(props, state: AccordionTriggerState) => {
|
||||
const isOpen = state.open;
|
||||
const ToggleIcon = isOpen ? MinusIcon : PlusIcon;
|
||||
return (
|
||||
// oxlint-disable-next-line react/jsx-props-no-spreading -- Accordion.Trigger host props
|
||||
<RowTrigger {...props} type="button">
|
||||
<BaseAccordion.Trigger render={<RowTrigger type="button" />}>
|
||||
<QuestionIconContainer aria-hidden>
|
||||
<QuestionIconLayer data-layer="outline">
|
||||
<RectangleOutlineIcon
|
||||
@@ -212,16 +230,21 @@ export function Item({ question, value }: ItemProps) {
|
||||
|
||||
<ToggleContainer>
|
||||
<ToggleVisual aria-hidden>
|
||||
<ToggleIcon
|
||||
<ToggleIconLayer data-icon="plus">
|
||||
<PlusIcon
|
||||
size={12}
|
||||
strokeColor={theme.colors.secondary.border[80]}
|
||||
/>
|
||||
</ToggleIconLayer>
|
||||
<ToggleIconLayer data-icon="minus">
|
||||
<MinusIcon
|
||||
size={12}
|
||||
strokeColor={theme.colors.secondary.border[80]}
|
||||
/>
|
||||
</ToggleIconLayer>
|
||||
</ToggleVisual>
|
||||
</ToggleContainer>
|
||||
</RowTrigger>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</BaseAccordion.Trigger>
|
||||
</BaseAccordion.Header>
|
||||
|
||||
<BaseAccordion.Panel render={<AnswerWrapper />} keepMounted>
|
||||
|
||||
@@ -4,7 +4,8 @@ import { theme } from '@/theme';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Children, type ReactNode } from 'react';
|
||||
|
||||
const CORNER_OFFSET = '-6px';
|
||||
const CORNER_SIZE = 14;
|
||||
const CORNER_OFFSET = '-7px';
|
||||
|
||||
const StyledSection = styled.section<{
|
||||
compactTop: boolean;
|
||||
@@ -18,6 +19,7 @@ const StyledSection = styled.section<{
|
||||
compactTop ? theme.spacing(4) : theme.spacing(12)};
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: ${({ compactBottom }) => (compactBottom ? 2 : 'auto')};
|
||||
|
||||
@media (min-width: ${theme.breakpoints.md}px) {
|
||||
padding-bottom: ${({ compactBottom }) =>
|
||||
@@ -97,11 +99,12 @@ const StyledCountCell = styled(StyledCell)`
|
||||
const CornerMarker = styled.span`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 12px;
|
||||
height: ${CORNER_SIZE}px;
|
||||
justify-content: center;
|
||||
line-height: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
width: ${CORNER_SIZE}px;
|
||||
`;
|
||||
|
||||
const CornerTopLeft = styled(CornerMarker)`
|
||||
@@ -150,16 +153,28 @@ export function Root({
|
||||
<StyledContainer>
|
||||
<StyledCard backgroundColor={cardBackgroundColor}>
|
||||
<CornerTopLeft aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</CornerTopLeft>
|
||||
<CornerTopRight aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</CornerTopRight>
|
||||
<CornerBottomLeft aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</CornerBottomLeft>
|
||||
<CornerBottomRight aria-hidden>
|
||||
<PlusIcon size={12} strokeColor={theme.colors.highlight[100]} />
|
||||
<PlusIcon
|
||||
size={CORNER_SIZE}
|
||||
strokeColor={theme.colors.highlight[100]}
|
||||
/>
|
||||
</CornerBottomRight>
|
||||
<StyledLabelCell>{label}</StyledLabelCell>
|
||||
<StyledLogosCell>{logos}</StyledLogosCell>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0"/>
|
||||
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0"/>
|
||||
<path d="M3 6v13"/>
|
||||
<path d="M12 6v13"/>
|
||||
<path d="M21 6v13"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 368 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M7 8l-4 4l4 4"/>
|
||||
<path d="M17 8l4 4l-4 4"/>
|
||||
<path d="M14 4l-4 16"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 288 B |
|
Before Width: | Height: | Size: 827 KiB After Width: | Height: | Size: 341 KiB |
|
Before Width: | Height: | Size: 699 KiB After Width: | Height: | Size: 302 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<path d="M3.6 9h16.8"/>
|
||||
<path d="M3.6 15h16.8"/>
|
||||
<path d="M11.5 3a17 17 0 0 0 0 18"/>
|
||||
<path d="M12.5 3a17 17 0 0 1 0 18"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 370 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 5h7"/>
|
||||
<path d="M9 3v2c0 4.418 -2.239 8 -5 8"/>
|
||||
<path d="M5 9c0 2.144 2.952 3.908 6.7 4"/>
|
||||
<path d="M12 20l4 -9l4 9"/>
|
||||
<path d="M19.1 18h-6.2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 372 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z"/>
|
||||
<path d="M8 11l0 5"/>
|
||||
<path d="M8 8l0 .01"/>
|
||||
<path d="M12 16l0 -5"/>
|
||||
<path d="M16 16v-3a2 2 0 0 0 -4 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 413 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M3 7l6 -3l6 3l6 -3v13l-6 3l-6 -3l-6 3v-13"/>
|
||||
<path d="M9 4v13"/>
|
||||
<path d="M15 7v13"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 306 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M3 20l1.3 -3.9a9 8 0 1 1 3.4 2.9l-4.7 1"/>
|
||||
<path d="M12 12l0 .01"/>
|
||||
<path d="M8 12l0 .01"/>
|
||||
<path d="M16 12l0 .01"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 339 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<rect x="3" y="4" width="18" height="12" rx="1"/>
|
||||
<path d="M7 20h10"/>
|
||||
<path d="M9 16v4"/>
|
||||
<path d="M15 16v4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 325 B |
@@ -1,55 +1,5 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg version="1.1" id="_x36_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 512 512" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#504F4F;" d="M512,28.891v308.708c0,0.986-0.071,1.973-0.141,2.959c-0.07,0.916-0.212,1.832-0.423,2.678
|
||||
c-2.819,13.177-14.939,23.112-29.454,23.112H30.018c-1.762,0-3.523-0.141-5.214-0.423c-12.754-2.184-22.76-12.049-24.522-24.522
|
||||
c-0.071-0.493-0.141-1.057-0.141-1.55C0,339.078,0,338.374,0,337.599V28.891c0-1.903,0.212-3.805,0.564-5.638
|
||||
C3.312,10.006,15.502,0,30.018,0h451.964c1.057,0,2.184,0.071,3.241,0.141c1.057,0.141,2.044,0.282,3.1,0.493
|
||||
c11.838,2.466,21.069,11.697,23.183,23.183c0.141,0.704,0.282,1.409,0.352,2.114C511.929,26.918,512,27.904,512,28.891z"/>
|
||||
<path style="fill:#C2C1C1;" d="M80.119,0v366.419H28.82c-1.268,0-2.537-0.071-3.805-0.282
|
||||
c-12.895-1.691-23.042-11.909-24.733-24.733c-0.071-0.493-0.141-1.057-0.141-1.55C0,339.078,0,338.374,0,337.599V28.891
|
||||
c0-1.903,0.212-3.805,0.564-5.638C3.171,10.006,14.798,0,28.82,0H80.119z"/>
|
||||
<path style="fill:#C2C1C1;" d="M512,28.891v308.708c0,0.986-0.071,1.973-0.141,2.959c-1.48,14.445-13.741,25.861-28.679,25.861
|
||||
h-51.298V0h51.298c1.691,0,3.382,0.141,4.933,0.423c11.979,2.114,21.351,11.556,23.465,23.465
|
||||
c0.141,0.705,0.211,1.339,0.282,2.043C511.929,26.918,512,27.904,512,28.891z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M246.925,28.905v313.198H62.734c-5.9,0-11.303-2.148-15.463-5.674
|
||||
c-5.176-4.385-8.477-10.941-8.477-18.265V52.844c0-13.224,10.715-23.939,23.94-23.939H246.925z"/>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M254.348,28.905v313.198h184.191c5.9,0,11.303-2.148,15.462-5.674
|
||||
c5.176-4.385,8.477-10.941,8.477-18.265V52.844c0-13.224-10.715-23.939-23.94-23.939H254.348z"/>
|
||||
</g>
|
||||
</g>
|
||||
<polygon style="fill:#E14D4B;" points="406.02,0 406.02,91.182 373.818,73.707 341.545,91.182 341.545,0 "/>
|
||||
<path style="fill:#FFFFFF;" d="M387.656,36.571h-11.063v-0.07l-3.03-9.372l-0.423-1.409h-0.141l-0.423,1.409l-3.1,9.442h-11.063
|
||||
v0.141l8.949,6.624l-1.127,3.523l-2.396,7.328l0.141,0.071l9.09-6.765l9.02,6.765l0.141-0.071l-3.523-10.851l8.949-6.624V36.571z"
|
||||
/>
|
||||
<rect x="73.178" y="75.654" style="fill:#D8D8D8;" width="145.522" height="72.479"/>
|
||||
<rect x="282.812" y="102.763" style="fill:#D8D8D8;" width="42.42" height="41.549"/>
|
||||
<rect x="335.706" y="102.763" style="fill:#D8D8D8;" width="42.42" height="41.549"/>
|
||||
<rect x="388.6" y="103.253" style="fill:#D8D8D8;" width="42.42" height="41.549"/>
|
||||
<rect x="73.178" y="170.951" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="73.178" y="207.12" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="73.178" y="250.071" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="73.178" y="283.98" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<g>
|
||||
<rect x="283.411" y="170.951" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="283.411" y="207.12" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="283.411" y="250.071" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
<rect x="283.411" y="283.98" style="fill:#D8D8D8;" width="145.522" height="6.782"/>
|
||||
</g>
|
||||
</g>
|
||||
<path style="opacity:0.03;fill:#040000;" d="M507.842,28.82v308.708c0,0.423-0.141,0.704-0.141,1.127
|
||||
c-0.563,14.868-12.402,26.988-27.199,27.693c-0.493,0.071-0.987,0.071-1.48,0.071h-51.369v-0.071H49.255l30.864-30.864
|
||||
l44.746-44.745l6.764-6.765l27.129-27.129l6.764-6.765l36.149-36.149l6.835-6.835l45.873-45.873l30.934-30.934l27.552-27.552
|
||||
l54.117-54.117l10.358-10.288v-0.071l9.372-9.372L406.02,9.583L415.603,0h63.419c3.805,0,7.399,0.775,10.781,2.114
|
||||
c7.117,2.889,12.825,8.597,15.714,15.714c1.268,3.03,2.044,6.342,2.184,9.794C507.701,28.045,507.842,28.468,507.842,28.82z"/>
|
||||
</g>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z"/>
|
||||
<path d="M4 12h16"/>
|
||||
<path d="M12 4v8"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 344 B |
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"/>
|
||||
<path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"/>
|
||||
<circle cx="15" cy="9" r="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 398 B |
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="#143055" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Nx</title><path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="#61DAFB" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>React</title><path d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="#FF4438" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Redis</title><path d="M22.71 13.145c-1.66 2.092-3.452 4.483-7.038 4.483-3.203 0-4.397-2.825-4.48-5.12.701 1.484 2.073 2.685 4.214 2.63 4.117-.133 6.94-3.852 6.94-7.239 0-4.05-3.022-6.972-8.268-6.972-3.752 0-8.4 1.428-11.455 3.685C2.59 6.937 3.885 9.958 4.35 9.626c2.648-1.904 4.748-3.13 6.784-3.744C8.12 9.244.886 17.05 0 18.425c.1 1.261 1.66 4.648 2.424 4.648.232 0 .431-.133.664-.365a100.49 100.49 0 0 0 5.54-6.765c.222 3.104 1.748 6.898 6.014 6.898 3.819 0 7.604-2.756 9.33-8.965.2-.764-.73-1.361-1.261-.73zm-4.349-5.013c0 1.959-1.926 2.922-3.685 2.922-.941 0-1.664-.247-2.235-.568 1.051-1.592 2.092-3.225 3.21-4.973 1.972.334 2.71 1.43 2.71 2.619z"/></svg>
|
||||
|
After Width: | Height: | Size: 776 B |
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="#3178C6" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>TypeScript</title><path d="M1.125 0C.502 0 0 .502 0 1.125v21.75C0 23.498.502 24 1.125 24h21.75c.623 0 1.125-.502 1.125-1.125V1.125C24 .502 23.498 0 22.875 0zm17.363 9.75c.612 0 1.154.037 1.627.111a6.38 6.38 0 0 1 1.306.34v2.458a3.95 3.95 0 0 0-.643-.361 5.093 5.093 0 0 0-.717-.26 5.453 5.453 0 0 0-1.426-.2c-.3 0-.573.028-.819.086a2.1 2.1 0 0 0-.623.242c-.17.104-.3.229-.393.374a.888.888 0 0 0-.14.49c0 .196.053.373.156.529.104.156.252.304.443.444s.423.276.696.41c.273.135.582.274.926.416.47.197.892.407 1.266.628.374.222.695.473.963.753.268.279.472.598.614.957.142.359.214.776.214 1.253 0 .657-.125 1.21-.373 1.656a3.033 3.033 0 0 1-1.012 1.085 4.38 4.38 0 0 1-1.487.596c-.566.12-1.163.18-1.79.18a9.916 9.916 0 0 1-1.84-.164 5.544 5.544 0 0 1-1.512-.493v-2.63a5.033 5.033 0 0 0 3.237 1.2c.333 0 .624-.03.872-.09.249-.06.456-.144.623-.25.166-.108.29-.234.373-.38a1.023 1.023 0 0 0-.074-1.089 2.12 2.12 0 0 0-.537-.5 5.597 5.597 0 0 0-.807-.444 27.72 27.72 0 0 0-1.007-.436c-.918-.383-1.602-.852-2.053-1.405-.45-.553-.676-1.222-.676-2.005 0-.614.123-1.141.369-1.582.246-.441.58-.804 1.004-1.089a4.494 4.494 0 0 1 1.47-.629 7.536 7.536 0 0 1 1.77-.201zm-15.113.188h9.563v2.166H9.506v9.646H6.789v-9.646H3.375z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1.002l3.086 -6.253l3.086 6.253l6.9 1.002l-5 4.867l1.179 6.873z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 333 B |
|
After Width: | Height: | Size: 377 KiB |
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 465 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 438 KiB |
|
After Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 363 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 402 KiB |
|
After Width: | Height: | Size: 345 KiB |
|
After Width: | Height: | Size: 465 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 285 KiB |
|
After Width: | Height: | Size: 285 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4A38F5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 4l11.733 16h4.267l-11.733 -16z"/>
|
||||
<path d="M4 20l6.768 -6.768m2.46 -2.46l6.772 -6.772"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 310 B |