diff --git a/images/logo-white.png b/images/logo-white.png new file mode 100644 index 0000000000..180ad25c8a Binary files /dev/null and b/images/logo-white.png differ diff --git a/packages/cursorless-org/mdx-components.tsx b/packages/cursorless-org/mdx-components.tsx new file mode 100644 index 0000000000..4687d27db0 --- /dev/null +++ b/packages/cursorless-org/mdx-components.tsx @@ -0,0 +1,15 @@ +import type { MDXComponents } from "mdx/types"; + +// This file allows you to provide custom React components +// to be used in MDX files. You can import and use any +// React component you want, including components from +// other libraries. + +// This file is required to use MDX in `app` directory. +export function useMDXComponents(components: MDXComponents): MDXComponents { + return { + // Allows customizing built-in components, e.g. to add styling. + // h1: ({ children }) =>

{children}

, + ...components, + }; +} diff --git a/packages/cursorless-org/next.config.js b/packages/cursorless-org/next.config.js index c8eb6fc1e7..247188d5a2 100644 --- a/packages/cursorless-org/next.config.js +++ b/packages/cursorless-org/next.config.js @@ -1,3 +1,9 @@ +const withMDX = require("@next/mdx")({ + options: { + providerImportSource: "@mdx-js/react", + }, +}); + /** @type {import('next').NextConfig} */ const nextConfig = { webpack(config) { @@ -9,7 +15,10 @@ const nextConfig = { return config; }, + experimental: { + mdxRs: true, + }, reactStrictMode: true, }; -module.exports = nextConfig; +module.exports = withMDX(nextConfig); diff --git a/packages/cursorless-org/package.json b/packages/cursorless-org/package.json index 839bd17178..b169a328ff 100644 --- a/packages/cursorless-org/package.json +++ b/packages/cursorless-org/package.json @@ -14,6 +14,9 @@ }, "dependencies": { "@cursorless/cheatsheet": "workspace:*", + "@mdx-js/loader": "2.3.0", + "@mdx-js/react": "2.3.0", + "@next/mdx": "13.4.10", "eslint": "^8.38.0", "eslint-config-next": "13.5.4", "next": "13.5.4", @@ -24,6 +27,8 @@ }, "devDependencies": { "@svgr/webpack": "6.5.1", + "@types/mdx": "2.0.5", + "@types/mdx-js__react": "1.5.5", "@types/node": "^16.11.3", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", diff --git a/packages/cursorless-org/public/andrew-dant.jpeg b/packages/cursorless-org/public/andrew-dant.jpeg new file mode 100644 index 0000000000..b97798f53b Binary files /dev/null and b/packages/cursorless-org/public/andrew-dant.jpeg differ diff --git a/packages/cursorless-org/public/big-hats.png b/packages/cursorless-org/public/big-hats.png new file mode 100644 index 0000000000..446085f52f Binary files /dev/null and b/packages/cursorless-org/public/big-hats.png differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-Bold.ttf b/packages/cursorless-org/public/fonts/Inconsolata-Bold.ttf new file mode 100644 index 0000000000..c83ecca68d Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-Bold.ttf differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-ExtraLight.ttf b/packages/cursorless-org/public/fonts/Inconsolata-ExtraLight.ttf new file mode 100644 index 0000000000..37320d6a45 Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-ExtraLight.ttf differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-Light.ttf b/packages/cursorless-org/public/fonts/Inconsolata-Light.ttf new file mode 100644 index 0000000000..36b47d6d6d Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-Light.ttf differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-Medium.ttf b/packages/cursorless-org/public/fonts/Inconsolata-Medium.ttf new file mode 100644 index 0000000000..86ba05ae86 Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-Medium.ttf differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-Regular.ttf b/packages/cursorless-org/public/fonts/Inconsolata-Regular.ttf new file mode 100644 index 0000000000..d1241516bc Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-Regular.ttf differ diff --git a/packages/cursorless-org/public/fonts/Inconsolata-SemiBold.ttf b/packages/cursorless-org/public/fonts/Inconsolata-SemiBold.ttf new file mode 100644 index 0000000000..90e7dc54dd Binary files /dev/null and b/packages/cursorless-org/public/fonts/Inconsolata-SemiBold.ttf differ diff --git a/packages/cursorless-org/public/james-stout.jpeg b/packages/cursorless-org/public/james-stout.jpeg new file mode 100644 index 0000000000..9155024311 Binary files /dev/null and b/packages/cursorless-org/public/james-stout.jpeg differ diff --git a/packages/cursorless-org/public/max-foxley-marrable.jpeg b/packages/cursorless-org/public/max-foxley-marrable.jpeg new file mode 100644 index 0000000000..e1f8c550c0 Binary files /dev/null and b/packages/cursorless-org/public/max-foxley-marrable.jpeg differ diff --git a/packages/cursorless-org/public/nathan-heffley.jpeg b/packages/cursorless-org/public/nathan-heffley.jpeg new file mode 100644 index 0000000000..3094f53024 Binary files /dev/null and b/packages/cursorless-org/public/nathan-heffley.jpeg differ diff --git a/packages/cursorless-org/public/sohee-yang.jpeg b/packages/cursorless-org/public/sohee-yang.jpeg new file mode 100644 index 0000000000..844a612275 Binary files /dev/null and b/packages/cursorless-org/public/sohee-yang.jpeg differ diff --git a/packages/cursorless-org/public/video-share-thumbnail.jpg b/packages/cursorless-org/public/video-share-thumbnail.jpg index 0e7cf74fb4..920760b986 100644 Binary files a/packages/cursorless-org/public/video-share-thumbnail.jpg and b/packages/cursorless-org/public/video-share-thumbnail.jpg differ diff --git a/packages/cursorless-org/src/components/Social.tsx b/packages/cursorless-org/src/components/BaseSocial.tsx similarity index 61% rename from packages/cursorless-org/src/components/Social.tsx rename to packages/cursorless-org/src/components/BaseSocial.tsx index 0ea09354b4..ec3775b3d4 100644 --- a/packages/cursorless-org/src/components/Social.tsx +++ b/packages/cursorless-org/src/components/BaseSocial.tsx @@ -1,17 +1,34 @@ import { - DESCRIPTION, BASE_URL, + VIDEO_SHARE_THUMBNAIL_HEIGHT, VIDEO_SHARE_THUMBNAIL_URL, - YOUTUBE_SLUG, - TITLE, VIDEO_SHARE_THUMBNAIL_WIDTH, - VIDEO_SHARE_THUMBNAIL_HEIGHT, } from "./constants"; -export default function Social() { +export interface Props { + title: string; + description: string; + relativeUrl: string; + youtubeSlug?: string; + thumbnailUrl?: string; + thumbnailWidth?: string; + thumbnailHeight?: string; +} + +export default function BaseSocial({ + title, + description, + relativeUrl, + youtubeSlug, + thumbnailUrl = VIDEO_SHARE_THUMBNAIL_URL, + thumbnailWidth = VIDEO_SHARE_THUMBNAIL_WIDTH, + thumbnailHeight = VIDEO_SHARE_THUMBNAIL_HEIGHT, +}: Props) { + const url = `${BASE_URL}/${relativeUrl}`; + return ( <> - + - - - - - + + + + + + {youtubeSlug != null ? ( + + ) : ( + + )} + + + + + + + + + + + + + + + + ); +} + +interface VideoProps { + youtubeSlug: string; +} + +function VideoSocial({ youtubeSlug }: VideoProps) { + return ( + <> @@ -67,28 +117,12 @@ export default function Social() { - - - - - - - - - - - - - ); } diff --git a/packages/cursorless-org/src/components/IndexSocial.tsx b/packages/cursorless-org/src/components/IndexSocial.tsx new file mode 100644 index 0000000000..076e7e088f --- /dev/null +++ b/packages/cursorless-org/src/components/IndexSocial.tsx @@ -0,0 +1,13 @@ +import BaseSocial from "./BaseSocial"; +import { DESCRIPTION, TITLE, VIDEO_SHARE_THUMBNAIL_URL } from "./constants"; + +export default function IndexSocial() { + return ( + + ); +} diff --git a/packages/cursorless-org/src/components/Layout.tsx b/packages/cursorless-org/src/components/Layout.tsx new file mode 100644 index 0000000000..071b6d8bfd --- /dev/null +++ b/packages/cursorless-org/src/components/Layout.tsx @@ -0,0 +1,143 @@ +import { MDXProvider } from "@mdx-js/react"; +import type { MDXComponents } from "mdx/types.js"; +import Head from "next/head"; +import Logo from "../pages/logo.svg"; +import BaseSocial from "./BaseSocial"; +import { SpamProofEmailLink } from "./SpamProofEmailLink"; +import Link from "next/link"; + +const components: MDXComponents = { + h1: ({ children }) => ( +

+ {children} +

+ ), + h2: ({ children }) => ( +

+ {children} +

+ ), + h3: ({ children }) => ( +

+ {children} +

+ ), + h4: ({ children }) => ( +

+ {children} +

+ ), + hr: () =>
, + ul: ({ children }) => , + ol: ({ children }) =>
    {children}
, + li: ({ children }) =>
  • {children}
  • , + img: ({ src, alt }) => ( + // FIXME: Figure out how to use next/image with MDX + // eslint-disable-next-line @next/next/no-img-element + {alt} + ), + CursorlessScreenshot: ({ src, alt }) => ( + // FIXME: Figure out how to use next/image with MDX + // eslint-disable-next-line @next/next/no-img-element + {alt} + ), + CalloutParent: ({ children }) => ( +
    + {children} +
    + ), + CalloutBox: ({ title, children }) => ( +
    +

    + {title} +

    + {children} +
    + ), + Testimonials: ({ children }) => ( +
    {children}
    + ), + Testimonial: ({ children, src, name, title, company }) => ( +
    +
    + {children} +
    +
    + {/* eslint-disable-next-line @next/next/no-img-element */} + {name} +
    +
    + {name} +
    +
    {title}
    +
    {company}
    +
    +
    +
    + ), + Tiers: ({ children }) => ( +
    + {children} +
    + ), + Tier: ({ emoji, type, price, address, subject, body }) => ( +
    + {emoji} + {type} + {"-"} + + {price} / year + +
    + ), +}; + +export const bodyClasses = "bg-salmon-100 dark:bg-salmon-900"; + +export interface Props extends React.PropsWithChildren { + title: string; + description: string; + relativeUrl: string; +} + +export function Layout({ title, description, relativeUrl, children }: Props) { + return ( + <> + + {title} + + + +
    +
    + + + + {children} +
    +
    +
    + + ); +} diff --git a/packages/cursorless-org/src/components/SpamProofEmailLink.tsx b/packages/cursorless-org/src/components/SpamProofEmailLink.tsx new file mode 100644 index 0000000000..a8cdafb3e3 --- /dev/null +++ b/packages/cursorless-org/src/components/SpamProofEmailLink.tsx @@ -0,0 +1,69 @@ +import { EmailAddress } from "../parseEmailAddress"; + +interface Props extends React.PropsWithChildren { + address: EmailAddress; + subject?: string; + body?: string; +} + +/** + * Encodes a string for use in a URL, but unlike encodeURIComponent, it encodes + * every character, including regular ASCII characters [a-zA-Z] etc. For example: + * + * encodeURIComponent("user@example.com") === "%75%73%65%72%40%65%78%61%6D%70%6C%65%2E%63%6F%6D" + * + * @param str The string to encode + * @returns A URL-encoded version of the string, where every character is encoded + */ +function strictEncodeURIComponent(str: string) { + const components: string[] = []; + for (let i = 0; i < str.length; i++) { + components.push("%" + str.charCodeAt(i).toString(16).toUpperCase()); + } + return components.join(""); +} + +/** + * A link to an email address, attempting to prevent spam bots from finding it. + * Encodes the URI for the href using very aggressive uri encoding, and for the + * displayed email text, injects dummy text in a hidden span so that bots will + * see it but humans won't. + * + * Tricks taken from https://spencermortensen.com/articles/email-obfuscation/ + * + * @param param0 The email address to use + * @returns A link to the email address, attempting to prevent spam bots from + * finding it + */ +export function SpamProofEmailLink({ + address: { username, domain }, + subject, + body, + children, +}: Props) { + // URL encode every character of the email address, including the mailto: prefix + const rawEmailHref = `${username}@${domain}`; + let href = `mailto:${strictEncodeURIComponent(rawEmailHref)}`; + + if (subject != null) { + const subjectEncoded = encodeURIComponent(subject).replace(/\+/g, "%20"); + href += `?subject=${subjectEncoded}`; + } + + if (body != null) { + const bodyEncoded = encodeURIComponent(body).replace(/\+/g, "%20"); + href += (href.includes("?") ? "&" : "?") + `body=${bodyEncoded}`; + } + + return ( + + {children ?? ( + <> + {`${username}@`} + Die spam! + {domain} + + )} + + ); +} diff --git a/packages/cursorless-org/src/content/enablement-group.mdx b/packages/cursorless-org/src/content/enablement-group.mdx new file mode 100644 index 0000000000..bec5f4289f --- /dev/null +++ b/packages/cursorless-org/src/content/enablement-group.mdx @@ -0,0 +1,210 @@ +export const meta = { + title: "Cursorless Enablement Group", + description: + "Help enable the adoption of Cursorless by accelerating its development.", +}; + +import { SpamProofEmailLink } from "../components/SpamProofEmailLink"; +export const emailSubject = "Cursorless Enablement Group"; +export const emailBody = `Hi Pokey, + +I'm interested in joining the Cursorless Enablement Group. Please send me more information. + +Thanks, + +`; + +# {meta.title} + +--- + +## {meta.description} + +Cursorless, an open-source spoken language for editing code, enables users to write software entirely by voice faster than with a keyboard and mouse. Software engineers can code using high-level semantic manipulations (increased productivity), and all computer users can reduce strain on their wrists to prevent injury (preventative healthcare). + + + +## Cursorless development is user-led + +Your support will help Cursorless founder, Pokey Rule, and his team develop the following feature requests as quickly as possible: + +- Reduce the learning curve with interactive tutorials, videos, and documentation to increase the rate of adoption. +- Launch Cursorless in other IDEs, such as JetBrains, emacs, etc, as well as in a web browser, and even work globally using OCR / accessibility APIs to operate anywhere on the screen. +- Further improvements to the Cursorless execution engine to advance the state of the art in voice coding. + +### 🫶 Developers love Cursorless + + + + "Phenomenal extension. This is the state of the art for coding by voice. + Nothing else comes close. Awesome to see this from the open source community!" + + + + "This extension is a genuine game-changer. As someone who suffers with chronic + RSI, I was seriously concerned I would be unfit to continue my career + long-term. Discovering Talon and Cursorless has given me hope again and has + additionally given me the means to write code and interface with my computer + in ways I never thought possible. It's also made coding way more fun than + before! I often feel like a code-slinging wizard!" + + + + +"For developers turning to Talon due to typing limitations, Cursorless isn’t just beneficial—it’s indispensable. When I lost my ability to type due to RSI, I was consumed with the fear of significantly reduced productivity and potentially not being able to work anymore. However, when I discovered Cursorless, it gave me hope and confidence that I could regain my prior efficiency once I mastered the tool." + + + + + +"This is fantastic extension that is not only saving my career but is even speeding up my workflow within VS Code more than when I was typing anyway. The best part is you really feel like a hacker when you rattle off a long command and the code does exactly what you wanted!" + + + + + +### 🎯 Goals + +Cursorless needs a dedicated, full-time software engineer on staff. This will cost $5,000 USD per month. The Enablement Group guides development and the participation fees contribute to this crucial funding. Cursorless will always be open source. + +## 🙌 Join the Cursorless Enablement Group + +The Enablement Group consists of stakeholders whose talents, lived experiences, and career experiences bring vital perspectives to the development of Cursorless. Support and input help increase the speed at which new features can be delivered. + +**To join, send an email to Cursorless founder Pokey Rule** + + + + + + + By joining the Enablement Group, you solidify your position as a dedicated + advocate for accessible technology and inclusion. Your active involvement + showcases your commitment to driving positive change and making technology + more accessible for everyone. + + + + As a valued member of the Enablement Group, you gain increased visibility + within both the open source and accessible technology communities. Your + participation will be recognized on all web properties including GitHub Repo, + cursorless.org, social media, via any other acknowledgments in project + updates, newsletters, and events to cement your role as a key player in + advancing Cursorless. + + + + Your commitment to the Enablement Group supports the long-term vision of + creating a full-time staff engineer dedicated to developing Cursorless. As the + group grows, the possibility of achieving this goal becomes more tangible, + contributing to a sustainable and impactful initiative for accessible + technology. + + + + Joining the Enablement Group provides an opportunity to collaborate with + like-minded individuals and industry leaders who share your passion for + accessible technology. This network allows you to exchange insights, share + best practices, and collectively drive the advancement of inclusive digital + solutions. + + + + While the development of Cursorless is guided by its community of users, your + annual fee directly contributes to the development of these feature requests! + Use your expertise and experience to help prioritize and comment on effective + solutions around feature requests. You're ensuring that development directly + aligns with the needs of users who value inclusive and accessible technology + and rely on it to succeed in their lives. + + + + +### All participants also enjoy the following benefits + +Members of the Cursorless Enablement Group enjoy several privileges. The access and public visibility participants receive make for a dynamic combination of benefits. The value that individuals and companies gain from their involvement in the group is tangible. + +#### 🤓 Technical + +- Be the first to access Cursorless feature updates and new versions. +- Lead the adoption of Cursorless by understanding its implementation and having superior knowledge of its use. +- Have some influence over the direction of the technology through your expertise. +- Gain an advanced and deeper knowledge of any outputs of the group (recommended practices, engineering guidelines) + +#### 🥽 Visibility + +- Ability to promote your organization as a champion for accessible technology and in particular Cursorless. +- Ability to promote your organization as a leader in the area of accessible technology. +- Opportunity to connect with other influencers in software and accessibility. +- Networking and ability to cultivate deep relationships and potential partnerships with leaders, founders, and influencers. + +#### 🪖 Strategic + +- Support an initiative targeted at facilitating an increased and more rapid shift of adoption of Cursorless as a faster way to code and a healthier way to code. +- Support of open standards approach. Standards are critical to interoperability and openness is consistent with a positive image in the industry. + +## 🚀 Join the Cursorless Enablement Group + +Your participation will help Cursorless maintain its growth trajectory and uphold its cutting-edge quality and esteemed 5-star reputation in coding by voice. And you'll make a lasting impact on the direction of accessible technology. + + + + + + + +To join, send an email to Cursorless founder Pokey Rule + + diff --git a/packages/cursorless-org/src/content/enablement-group.mdx.d.ts b/packages/cursorless-org/src/content/enablement-group.mdx.d.ts new file mode 100644 index 0000000000..0da46b532b --- /dev/null +++ b/packages/cursorless-org/src/content/enablement-group.mdx.d.ts @@ -0,0 +1,6 @@ +export { default } from "*.mdx"; + +export const meta: { + title: string; + description: string; +}; diff --git a/packages/cursorless-org/src/pages/enablement-group.tsx b/packages/cursorless-org/src/pages/enablement-group.tsx new file mode 100644 index 0000000000..76f6db51c3 --- /dev/null +++ b/packages/cursorless-org/src/pages/enablement-group.tsx @@ -0,0 +1,41 @@ +import { + default as EnablementGroup, + meta, +} from "../content/enablement-group.mdx"; +import { Layout, bodyClasses } from "../components/Layout"; +import { env } from "process"; +import { parseEmailAddress, EmailAddress } from "../parseEmailAddress"; + +const RELATIVE_URL = "cursorless-enablement"; + +export async function getStaticProps() { + return { + props: { + // See https://github.com/vercel/next.js/discussions/12325#discussioncomment-1116108 + bodyClasses, + + //! IMPORTANT: Don't return the email address unparsed, because it will + //! be serialized as JSON and exposed to the client, so spam bots might + //! find it. Instead, parse it and return the parsed object. + emailAddress: parseEmailAddress( + env["ENABLEMENT_GROUP_EMAIL"] ?? "user@example.com", + ), + }, + }; +} + +interface Props extends React.PropsWithChildren { + emailAddress: EmailAddress; +} + +export default function Page({ emailAddress }: Props) { + return ( + + + + ); +} diff --git a/packages/cursorless-org/src/pages/index.tsx b/packages/cursorless-org/src/pages/index.tsx index 1abf9a8a56..6e0ed190c1 100644 --- a/packages/cursorless-org/src/pages/index.tsx +++ b/packages/cursorless-org/src/pages/index.tsx @@ -2,7 +2,7 @@ import { EmbeddedVideo } from "../components/embedded-video"; import Head from "next/head"; import Button from "../components/Button"; import { TITLE, YOUTUBE_SLUG } from "../components/constants"; -import Social from "../components/Social"; +import IndexSocial from "../components/IndexSocial"; import Logo from "./logo.svg"; // See https://github.com/vercel/next.js/discussions/12325#discussioncomment-1116108 @@ -19,9 +19,9 @@ export default function LandingPage() { <> {TITLE} - + -
    +
    {/* Note that the font scale gets applied to this element so that all nested elements can use `em` units and will automatically be scaled. diff --git a/packages/cursorless-org/src/pages/logo.svg b/packages/cursorless-org/src/pages/logo.svg index b1e2ec41ca..784726d12f 100644 --- a/packages/cursorless-org/src/pages/logo.svg +++ b/packages/cursorless-org/src/pages/logo.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/packages/cursorless-org/src/parseEmailAddress.ts b/packages/cursorless-org/src/parseEmailAddress.ts new file mode 100644 index 0000000000..912f5ec99c --- /dev/null +++ b/packages/cursorless-org/src/parseEmailAddress.ts @@ -0,0 +1,8 @@ +export interface EmailAddress { + username: string; + domain: string; +} +export function parseEmailAddress(email: string): EmailAddress { + const [username, domain] = email.split("@"); + return { username, domain }; +} diff --git a/packages/cursorless-org/src/styles/globals.css b/packages/cursorless-org/src/styles/globals.css index 99c212068e..f839c576cc 100644 --- a/packages/cursorless-org/src/styles/globals.css +++ b/packages/cursorless-org/src/styles/globals.css @@ -74,3 +74,67 @@ /* Modern Browsers */ url("/fonts/Inconsolata_SemiExpanded-ExtraBold.ttf") format("truetype"); } + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 200; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-ExtraLight.ttf") + format("truetype"); +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 300; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-Light.ttf") format("truetype"); +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 400; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-Regular.ttf") + format("truetype"); +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 500; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-Medium.ttf") + format("truetype"); +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 600; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-SemiBold.ttf") + format("truetype"); +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 700; + font-stretch: 1% 500%; /* Required by Chrome */ + src: + local(""), + /* Modern Browsers */ url("/fonts/Inconsolata-Bold.ttf") format("truetype"); +} diff --git a/packages/cursorless-org/tailwind.config.js b/packages/cursorless-org/tailwind.config.js index d96f4f226a..e63bf88925 100644 --- a/packages/cursorless-org/tailwind.config.js +++ b/packages/cursorless-org/tailwind.config.js @@ -58,7 +58,8 @@ module.exports = { stretched: { raw: "(min-aspect-ratio: 2/1), (max-aspect-ratio: 1/1)" }, }, fontFamily: { - mono: ["Inconsolata-SemiExpanded", ...defaultTheme.fontFamily.mono], + mono: ["Inconsolata", ...defaultTheme.fontFamily.mono], + monoWide: ["Inconsolata-SemiExpanded", ...defaultTheme.fontFamily.mono], }, width: { smBase: smallWidth, @@ -74,15 +75,26 @@ module.exports = { xs: "1.2em", lg: "1.8em", "2xl": "2.4em", + "3xl": "3.6em", }, colors: { salmon: { 100: "#FFFAF8", 300: "#F8C9BA", 400: "#FF9273", + 700: "#372e2a", 800: "#161110", 900: "#0A0707", }, + teal: { + 100: "#F9FFFE", + 200: "#CDFFF9", + 300: "#99FFF3", + 400: "#00907F", + 700: "#005349", + 800: "#00443C", + 900: "#00110F", + }, }, }, }, diff --git a/packages/cursorless-org/tsconfig.json b/packages/cursorless-org/tsconfig.json index 833ac65504..6086e6a074 100644 --- a/packages/cursorless-org/tsconfig.json +++ b/packages/cursorless-org/tsconfig.json @@ -8,7 +8,7 @@ "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "nodenext", + "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4642c94d68..4dea2da84c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -275,6 +275,15 @@ importers: '@cursorless/cheatsheet': specifier: workspace:* version: link:../cheatsheet + '@mdx-js/loader': + specifier: 2.3.0 + version: 2.3.0(webpack@5.88.2) + '@mdx-js/react': + specifier: 2.3.0 + version: 2.3.0(react@18.2.0) + '@next/mdx': + specifier: 13.4.10 + version: 13.4.10(@mdx-js/loader@2.3.0)(@mdx-js/react@2.3.0) eslint: specifier: ^8.38.0 version: 8.38.0 @@ -300,6 +309,12 @@ importers: '@svgr/webpack': specifier: 6.5.1 version: 6.5.1 + '@types/mdx': + specifier: 2.0.5 + version: 2.0.5 + '@types/mdx-js__react': + specifier: 1.5.5 + version: 1.5.5 '@types/node': specifier: ^16.11.3 version: 16.18.13 @@ -3309,6 +3324,18 @@ packages: /@leichtgewicht/ip-codec@2.0.4: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} + /@mdx-js/loader@2.3.0(webpack@5.88.2): + resolution: {integrity: sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg==} + peerDependencies: + webpack: '>=4' + dependencies: + '@mdx-js/mdx': 2.3.0 + source-map: 0.7.4 + webpack: 5.88.2(webpack-cli@5.1.4) + transitivePeerDependencies: + - supports-color + dev: false + /@mdx-js/mdx@2.3.0: resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} dependencies: @@ -3358,6 +3385,22 @@ packages: glob: 7.1.7 dev: false + /@next/mdx@13.4.10(@mdx-js/loader@2.3.0)(@mdx-js/react@2.3.0): + resolution: {integrity: sha512-0ZbUIr3yuFFfkaYth2kNFAT0fbyylJTMqZy5zTdb7YGqvYjKFD8n75L3UYAX0g5mibGp3iETJ0I7730sW13PKQ==} + peerDependencies: + '@mdx-js/loader': '>=0.15.0' + '@mdx-js/react': '>=0.15.0' + peerDependenciesMeta: + '@mdx-js/loader': + optional: true + '@mdx-js/react': + optional: true + dependencies: + '@mdx-js/loader': 2.3.0(webpack@5.88.2) + '@mdx-js/react': 2.3.0(react@18.2.0) + source-map: 0.7.4 + dev: false + /@next/swc-darwin-arm64@13.5.4: resolution: {integrity: sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==} engines: {node: '>= 10'} @@ -4758,9 +4801,14 @@ packages: '@types/unist': 2.0.6 dev: false + /@types/mdx-js__react@1.5.5: + resolution: {integrity: sha512-k8pnaP6JXVlQh18HgL5X6sYFNC/qZnzO7R2+HsmwrwUd+JnnsU0d9lyyT0RQrHg1anxDU36S98TI/fsGtmYqqg==} + dependencies: + '@types/react': 18.0.28 + dev: true + /@types/mdx@2.0.5: resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==} - dev: false /@types/mime@3.0.1: resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}