Compare commits

...

28 Commits

Author SHA1 Message Date
Colum Ferry cd97ff7a13 fix(vite): handle sophisticated vite plugins (#34242)
## Current Behavior
With Vite now providing additional options (environments etc) for
framework authors, vite.config files can be much more simple for the
user.
However, this often assumes that the `root` property will be set and
provided during `Vite CLI` invocation.

When we run `resolveConfig` to determine inputs and outputs, we do not
set this `root` and expect the user to have it in their vite config
file.
For some plugins/frameworks such as Tanstack Start - this causes the
plugin to error.

The `isBuildable` conditions is also not inclusive enough and can skip
projects that should be marked as buildable.

## Expected Behavior
Ensure that sophisticated vite plugins are supported with Nx

## Related Issue(s)

CLOSES NXC-3637

(cherry picked from commit 3d62c8b5c1)
2026-01-29 12:23:18 -05:00
Jack Hsu 075b6542b8 feat(core): add Nx Cloud connect URL to template README (#34249)
## Current Behavior
Template-generated workspaces use a generic link in the README instead
of a per-workspace short link for Nx Cloud setup.

## Expected Behavior
When users opt into Nx Cloud (or are auto-connected via variant 2), the
template README is updated with a personalized connect URL section that
helps them finish setting up their workspace.

---
BEFORE:

<img width="762" height="460" alt="image"
src="https://github.com/user-attachments/assets/58900071-1727-49d1-aa19-279c488b5037"
/>

AFTER:

<img width="1032" height="599" alt="image"
src="https://github.com/user-attachments/assets/a6e3a122-5807-4ba2-90dd-441e41a3280e"
/>

---

## Related Issue(s)
Closes NXC-3783

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 9c3a9d7e13)
2026-01-29 12:23:17 -05:00
Drew Teachout afc27c8ff6 fix(core): do not throw error if worker.stdout is not instanceof socket (#34224)
deno worker.stdout is a Readable/Writeable. To provide better deno
support an error should not be thrown

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->
If `worker.stdout` or `worker.stderr` are not instanceof Socket then nx
throws an error. This is problematic in Deno where `stdout` and `stderr`
are Readable/Writable and not Socket.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
`startupPluginWorker` function should work in Deno runtime

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

- https://github.com/denoland/deno/issues/31961
- https://github.com/oven-sh/bun/issues/26505

---------

Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
(cherry picked from commit e189dcc101)
2026-01-29 12:23:16 -05:00
Craigory Coppola 089db8762a fix(core): improve plugin worker error messages and lifecycle timeouts (#34251)
## Current Behavior
Plugin workers occasionally fall over during the start up steps.

## Expected Behavior
Improves some issues with the error handling when loading plugin workers
and adds some more logs to help understand what's went wrong here.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
(cherry picked from commit 4f4b9dc048)
2026-01-29 12:23:15 -05:00
Jason Jean cba9c88d9b chore(repo): update nx to 22.5.0-beta.1 (#34234)
Updating Nx from 22.5.0-beta.0 to 22.5.0-beta.1

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
(cherry picked from commit 8d5b316fdd)
2026-01-29 12:23:04 -05:00
Jack Hsu 52088dd13a docs(misc): add 1% scroll depth tracking to docs and non-docs pages (#34246)
This PR adds scroll depth event at the 10% level so we can filter out
users who actually engages with the page versus those who maybe land on
homepage just to get to docs.

<img width="2672" height="1527" alt="Screenshot 2026-01-28 at 4 00
54 PM"
src="https://github.com/user-attachments/assets/ad9be5ae-442c-48eb-9c1e-70f0b872563b"
/>

Also fix the scroll tracker for astro-docs.

<img width="2672" height="1527" alt="Screenshot 2026-01-28 at 4 00
54 PM"
src="https://github.com/user-attachments/assets/e4a24ef2-b6aa-4f5a-b10b-972b73385fee"
/>

<img width="2672" height="1527" alt="Screenshot 2026-01-28 at 2 39
09 PM"
src="https://github.com/user-attachments/assets/833c71f1-7a96-4637-bb6e-3b21227053f0"
/>

## Related Issue(s)
Closes CLOUD-4211

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit b53fd7c7f5)
2026-01-29 12:22:37 -05:00
Louie Weng cf42933bea fix(gradle): use tooling api compatible flags (#34247)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

--rerun is not tooling api compatible and therefore will break usage of
the batch executor. Replaced the flag with --rerun-tasks.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 5a424fa8df)
2026-01-29 12:22:26 -05:00
Jack Hsu 8ad00a791e docs(misc): content negotiation for LLM-friendly docs access (#34239)
## Current Behavior
LLMs and CLI tools must explicitly request the `.md` URL suffix to get
raw markdown content from documentation pages.

## Expected Behavior
When a client requests a docs page with `Accept: text/markdown` header,
the edge function rewrites to serve the `.md` version directly (no
redirect). This enables LLM tools to get markdown content by requesting
the standard URL.

Behavior:
- `Accept: text/markdown` → serves .md content (via rewrite, no
redirect)
- Default (browsers) → serves HTML with Link headers (unchanged)

Examples:
```
curl -H 'Accept: text/markdown' https://deploy-preview-34239--nx-docs.netlify.app/docs/getting-started/intro
curl -H 'Accept: text/markdown' https://deploy-preview-34239--nx-docs.netlify.app/docs/getting-started/tutorials/angular-monorepo-tutorial
```

Uses Netlify Edge Function rewrite (returns URL object) instead of
redirect for single-request response that works with all HTTP clients.

## Related Issue(s)
Closes DOC-389

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 7276e4cff7)
2026-01-29 12:22:26 -05:00
Caleb Ukle dfa878ec14 fix(nx-dev): update dead links across nx-dev UI libraries (#34238)
## Current Behavior

broken links

## Expected Behavior

links aren't broken any more and are updated to expected pages from docs
page.

## Related Issue(s)

Fixes DOC-391

(cherry picked from commit f9258c9d82)
2026-01-29 12:22:17 -05:00
Jack Hsu 5f8458469e feat(nx-dev): add llms-full.txt and HTTP Link headers for LLM discovery (#34232)
This PR adds:
1. `llms-full.txt` that is a full copy of our docs in markdown.
2. HTTP `Link` headers to our docs HTML pages so that they point to the
`.md` (markdown) version, and also to `llms.txt` and `llms-full.txt`.

The `llms-full.txt` is currently at 2.7 MB, which is much less than
other sites that are up to 5MB or more.

<img width="569" height="35" alt="Screenshot 2026-01-27 at 12 11 10 PM"
src="https://github.com/user-attachments/assets/61be02b4-2813-4c39-951c-d831af83e823"
/>

First 100 lines of `llms-full.txt`:

````
# Nx Documentation

> Complete Nx documentation compiled into a single file for LLM consumption.

Nx is a powerful, open source, technology-agnostic build platform designed to efficiently manage codebases of any scale. From small single projects to large enterprise monorepos, Nx provides intelligent task execution, caching, and CI optimization.

This file was generated from 503 documentation pages.
Individual pages are available at: https://nx.dev/docs/{slug}.md

# Quickstart

---
<!-- source: https://nx.dev/docs/quickstart.md -->
## Quickstart with Nx

Get up and running with Nx in just a few minutes by following these simple steps.

{% steps %}

1. Install the Nx CLI

   Installing Nx globally is **optional** - you can use `npx` to run Nx commands without installing it globally, especially if you're working with Node.js projects.

   {% tabs syncKey="install-method" %}
   {% tabitem label="npm" %}

   ```shell
   npm add --global nx
   ```

   **Note:** You can also use Yarn, pnpm, or Bun

   {% /tabitem %}
   {% tabitem label="Homebrew (macOS, Linux)" %}

   ```shell
   brew install nx
   ```

   {% /tabitem %}
   {% tabitem label="Chocolatey (Windows)" %}

   ```shell
   choco install nx
   ```

   {% /tabitem %}
   {% tabitem label="apt (Ubuntu)" %}

   ```shell
   sudo add-apt-repository ppa:nrwl/nx
   sudo apt update
   sudo apt install nx
   ```

   {% /tabitem %}
   {% /tabs %}

2. Start fresh or add to existing project

   For JavaScript-based projects you can **start with a new workspace** using the following command:

   ```shell
   npx create-nx-workspace@latest
   ```

   **Add to an existing project: (recommended also for non-JS projects)**

   ```shell
   npx nx@latest init
   ```

   **Get the complete experience:**
   For a fully integrated development workflow with AI-powered CI features, [start directly from Nx Cloud](https://cloud.nx.app/get-started).

   Learn more: [Start New Project](/docs/getting-started/start-new-project) • [Add to Existing](/docs/getting-started/start-with-existing-project) • [Complete Nx Experience](https://cloud.nx.app/get-started)

3. Run Your First Commands

   Nx provides powerful task execution with built-in caching. Here are some essential commands:

   **Run a task for a single project:**

   ```shell
   nx build my-app
   nx test my-lib
   ```

   **Run tasks for multiple projects:**

   ```shell
   nx run-many -t build test lint
   ```

   Learn more: [Run Tasks](/docs/features/run-tasks) • [Cache Task Results](/docs/features/cache-task-results)

4. What's next?

   Now that you've experienced the Nx basics, choose how you want to continue:

````

## Related Issue(s)
Closes DOC-236

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
(cherry picked from commit 8b245f1b0a)
2026-01-29 12:22:16 -05:00
Benjamin Cabanes 55fe0419e9 docs(nx-dev): migrate color variants to contrast design (#34077)
This design refresh emphasizes the contrast variant aesthetic across all
hero sections, pricing cards, and primary call-to-actions.

- Change 47 instances of variant="primary" to variant="contrast"
- Update ui-courses to use variant="secondary" for GitHub link
- Prefer high-contrast inverted style for primary CTAs
- Maintain proper visual hierarchy with secondary actions
- Replace all slate-* classes with zinc-* equivalents (1,158 instances)
- Replace all sky-* classes with blue-* equivalents (210 instances)
- Update opacity variants, gradients, rings, and borders
- Maintain full dark mode compatibility

(cherry picked from commit a092ed06c4)
2026-01-29 12:22:15 -05:00
MaxKless 86fbeac4ef fix(core): hide already-installed nx packages from suggestion list during nx import (#34227)
## Current Behavior
If something is in `package.json#dependencies`, we still suggest it to
be `nx add`-ed during `nx import`

## Expected Behavior
If a plugin is already installed, we don't suggest it anymore

(cherry picked from commit f89ccb091f)
2026-01-29 12:22:07 -05:00
Jason Jean a40d06ed23 chore(repo): update nx to 22.5.0-beta.0 (#34209)
Updating Nx from 22.4.0-beta.5 to 22.5.0-beta.0

(cherry picked from commit f9ab939c74)
2026-01-29 12:21:31 -05:00
Colum Ferry 758cc7b7c8 fix(web): ensure vitest config file is created (#34216)
`@nx/web:app` generator is incorrectly calling `createOrEditViteConfig`
when bundler != vite and unitTestRunner = vitest.

Ensure it is using the correct file

(cherry picked from commit 7a446e4979)
2026-01-29 12:21:29 -05:00
Jack Hsu b6cb5ccaca feat(core): add variant 2 to CNW cloud prompts with promo message (#34223)
This PR uses three variants for CNW for prompting for Cloud/platform
connection.

- Variant 0: Shows "Try the full Nx platform?" prompt → platform-setup
completion
- Variant 1: Shows "Would you like remote caching..." prompt →
cache-setup completion
- Variant 2: No prompt → platform-promo completion with "Want faster
builds?"

Both template and custom flows use the same messages and prompts.


### Skip (all) -- No changes


<img width="1392" height="994" alt="cnw_all_skip_completion"
src="https://github.com/user-attachments/assets/1579df01-fc36-4324-bc74-19efc18f78af"
/>

### Variant 0 (full platform)

Template prompt:

<img width="1392" height="994" alt="cnw_template_variant_0_prompt"
src="https://github.com/user-attachments/assets/d02e9ddc-fd25-4f6f-ac61-6f6d518fe338"
/>

Template completion:

<img width="1392" height="994" alt="cnw_template_variant_0_completion"
src="https://github.com/user-attachments/assets/12e459a0-962c-4724-82fa-a4f5a3b6fbd8"
/>

Custom prompt:

<img width="1392" height="994" alt="cnw_custom_variant_0_prompt"
src="https://github.com/user-attachments/assets/8143832a-a85e-43b4-81eb-15074c223476"
/>

Custom completion:

<img width="1392" height="994" alt="cnw_custom_variant_0_completion"
src="https://github.com/user-attachments/assets/036ef6f9-4977-459a-bbd2-502670a12d01"
/>

### Variant 1 (remote cache)

Template prompt:

<img width="1392" height="994" alt="cnw_template_variant_1_prompt"
src="https://github.com/user-attachments/assets/f69b540f-7e48-46ae-99e5-f53657176424"
/>

Template completion:

<img width="1392" height="994" alt="cnw_template_variant_1_completion"
src="https://github.com/user-attachments/assets/04c17847-b0f2-4e37-b7d2-5556aa14f510"
/>

Custom prompt:

<img width="1392" height="994" alt="cnw_custom_variant_1_prompt"
src="https://github.com/user-attachments/assets/abdb38b2-611e-458b-85c0-7b89cd1b827e"
/>


Custom completion:

<img width="1348" height="950" alt="cnw_custom_variant_1_completion"
src="https://github.com/user-attachments/assets/e7d35ddb-e8ac-4ad1-889e-9fff89538900"
/>

## Variant 2 (no prompt)

Template completion:

<img width="1392" height="994" alt="cnw_template_variant_2_completion"
src="https://github.com/user-attachments/assets/07050989-a56c-46eb-a0c3-8730916856ff"
/>

Custom completion:

<img width="1392" height="994" alt="cnw_custom_variant_2_completion"
src="https://github.com/user-attachments/assets/94000828-37b2-4059-a13b-0d36972cfd3e"
/>

## Related Issue(s)

Closes CLOUD-4189

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:31:20 -05:00
Jack Hsu 1dad304994 Revert "Revert "feat(core): add A/B testing variant 1 to skip cloud p…rompt in CNW (#34106)" (#34191) (#34204)
This reverts commit f016664557.

(cherry picked from commit e108dac1bb)
2026-01-26 16:01:21 -05:00
Colum Ferry eb239f3a91 fix(react): remove file-loader dependency and update svgr migration (#34218)
## Current Behavior
The migration for svgr requires using file-loader which is unmaintained.

## Expected Behavior
Use asset/resource instead of file-loader

## Related Issue(s)

CLOSES NXC-3667

(cherry picked from commit 3fcd2008ef)
2026-01-26 16:01:20 -05:00
Jason Jean c1c1a64daa fix(core): fall back to node_modules when tmp has noexec (#34207)
## Summary

- When `/tmp` is mounted with `noexec`, loading native modules from the
cache fails silently and causes Nx to hang indefinitely
- This adds a fallback to load from `node_modules` when permission
errors occur

## Problem

Users with `/tmp` mounted with `noexec` (a common security hardening
practice) experience Nx hanging forever, even for simple commands like
`nx --version`.

The root cause:
1. Nx copies native `.node` files to `/tmp` to avoid Windows file
locking issues
2. On `noexec` mounts, execution fails with `EACCES`/`EPERM`
3. The error wasn't caught, leading to broken native bindings and
infinite loops

## Solution

Catch permission errors when loading from the cache and fall back to the
original `node_modules` location. This:
- Works automatically without user config
- Preserves Windows file locking fix (only falls back when needed)
- No error messages for users

Closes #33991

(cherry picked from commit 75f36edb8f)
2026-01-26 09:58:23 -05:00
Miguel ca38b53eb4 fix(devkit): allow null values in JSON schema validation (#34167)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

Schema validation (done, for instance, when calling an executor) fails
when an option has value "null" and schema accepts null values. I had it
in a custom executor for `nx-release-publish`, that understands that
`nxReleaseVersionData` is implicitly passed, so I define its schema:
```json
"newVersion": {
  "type": ["string", "null"],
  "description": "The new version of the project, null if no changes detected"
}
```

My code calls `getReleaseClient().releaseVersion(options)`, which gets
me a `projectsVersionData` object with version info. It contains `null`
values (allowed). I then pass it, and ends up in:
```typescript
 // nx/src/tasks-runner/task-orchestrator.ts:531-539
  const combinedOptions = combineOptionsForExecutor(
      task.overrides,  // ← Contains nxReleaseVersionData with null values
      task.target.configuration,
      targetConfiguration,
      schema,           // ← Schema from executor
      task.target.project,
      relativeCwd,
      isVerbose
  );
```

which fails inside:
```typescript
 // nx/src/utils/params.js:126-201
  function validateObject(opts, schema, definitions) {
      // Line 191-200: Iterate through all properties
      Object.keys(opts).forEach((p) => {
          validateProperty(
              p,                              // "nxReleaseVersionData"
              opts[p],                        // { foo: { newVersion: null, ... }}
              (schema.properties ?? {})[p],   // schema for nxReleaseVersionData
              definitions
          );
      });
  }
  ```

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR -->

`null` values should be considered, as they are valid in JSON schemas. It was probably not considered, because we never think that `typeof null === "object"`, but it's unfortunately the case.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is merged. -->

I will create one

Fixes https://github.com/nrwl/nx/issues/34169

(cherry picked from commit 3672e1a3ea)
2026-01-26 09:58:22 -05:00
Leosvel Pérez Espinosa 30abc3fcc6 feat(core): display batch tasks in the tui (#33695)
Adds support for Batch tasks and displays them in the TUI.

---------

Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
(cherry picked from commit a15881db1a)
2026-01-26 09:58:21 -05:00
Jack Hsu f872ebdad7 docs(misc): collect usage data on .md and .txt files (#34203)
Right now GA only collects page views. This PR allow us to see which
`.md` files are being used. There are mostly useful for AI agents to
fetch without using too many tokens. We want to track usage so we can
see what techniques to guide agents actually work.

## Related Issue(s)
Closes DOC-386

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 1dd4262336)
2026-01-26 09:58:20 -05:00
Jack Hsu 0e37963f67 fix(core): cloud commands are noop when not connected rather than errors (#34193)
This PR makes it so Cloud commands like `npx nx record` and `npx nx
fix-ci` still work without `nxCloudId`. We'll log a warning so that
`ci.yml` using these commands will still work. The warning let's users
know that these do not work without being connected.

Closes #NXC-3753

(cherry picked from commit 687357c82e)
2026-01-26 09:58:19 -05:00
Mark Lindsey a475a43ac0 chore(repo): commit lint mention that commits should be lowercase (#34199)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
Commit linting does not mention requirement for commit message to be
lowercase.
<!-- This is the behavior we have today -->

## Expected Behavior
Hook message should instruct user to use all lowercase for commit
message.
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 3d1e544812)
2026-01-26 09:58:18 -05:00
Jack Hsu dc2e9d7087 fix(core): consolidate GitHub URL messaging when gh push fails (#34196)
When `gh repo create` fails, users see two redundant messages. This
consolidates them into a single message with the helpful `?name=...`
parameter in the GitHub URL.

BEFORE: (We show `Could not push. Push repo to complete setup.` and then
`Push your repo (https://github.com/new)...` again at the end)

<img width="1209" height="560" alt="image"
src="https://github.com/user-attachments/assets/e22c012c-8e0f-4ff9-a6c2-de8267b69b5d"
/>

AFTER: (Only show `Could not push` as an info log, and then complete
setup is shown only once at the end)

<img width="1250" height="591" alt="image"
src="https://github.com/user-attachments/assets/3dc075c7-4418-4373-a07a-1b95f71b3b87"
/>

Closes NXC-3754

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 9bb69383b8)
2026-01-26 09:58:17 -05:00
Jonathan Cammisuli 71039e8ffd docs(nx-dev): update docs to include SELF_HEALING.md information (#34200)
(cherry picked from commit 1831ace87e)
2026-01-26 09:58:16 -05:00
Mark Lindsey 126710a3ed docs(nx-dev): add bitbucket to self healing docs (#34198)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
Self-healing docs only reference being supported for GitHub, Azure, and
GitLab.
<!-- This is the behavior we have today -->

## Expected Behavior
We should show instructions for all currently supported vcs providers,
including Bitbucket.
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 478afc7046)
2026-01-26 09:58:15 -05:00
JamesHenry acb1b8e55c chore(repo): remove --auto-apply-fixes, it is set in Nx Cloud UI
(cherry picked from commit 1299d044eb)
2026-01-26 09:58:14 -05:00
Craigory Coppola 9b8a9b31f0 fix(core): handle resizing a bit better for inline_tui (#34006)
## Current Behavior
Resizing the TUI while in inline view kinda breaks things. Its
unfortunate, I'm not sure there's a ton to be done, but this PR explores
some solutions

## Expected Behavior
The TUI is less sensitive to resize events with inline mode

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 273a474047)
2026-01-26 09:58:12 -05:00
392 changed files with 10037 additions and 4094 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
main-branch-name: 'master'
- name: Start CI Run
run: npx nx-cloud@next start-ci-run --auto-apply-fixes="*format:check*,*sync:check*,*conformance:check*,*format-native*,*lint-native*,*lint*,*astro-docs:validate-links*" --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e"
run: npx nx-cloud@next start-ci-run --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e"
- name: Install dependencies
run: |
Generated
+90 -75
View File
@@ -86,6 +86,15 @@ dependencies = [
"libc",
]
[[package]]
name = "ansi-escape-sequences"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6afb74bb006f83a46d689f70e46ce3a9830db762134b3b585986fa9eab21f75d"
dependencies = [
"regex",
]
[[package]]
name = "anstyle"
version = "1.0.6"
@@ -295,7 +304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
dependencies = [
"memchr",
"regex-automata 0.4.6",
"regex-automata 0.4.13",
"serde",
]
@@ -790,6 +799,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
[[package]]
name = "east-asian-width"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8c47de0fcde8bd09c98fc22e4ea10ed14b9c05bf02c309e1e743aee7d0d9f6"
[[package]]
name = "either"
version = "1.10.0"
@@ -1382,8 +1397,8 @@ dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.6",
"regex-syntax 0.8.2",
"regex-automata 0.4.13",
"regex-syntax 0.8.8",
]
[[package]]
@@ -1587,7 +1602,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
"windows-core 0.57.0",
"windows-core",
]
[[package]]
@@ -1625,7 +1640,7 @@ dependencies = [
"globset",
"log",
"memchr",
"regex-automata 0.4.6",
"regex-automata 0.4.13",
"same-file",
"walkdir",
"winapi-util",
@@ -1892,7 +1907,7 @@ dependencies = [
"rustc-hash 2.1.1",
"serde",
"serde_json",
"thiserror 2.0.12",
"thiserror 2.0.18",
"tokio",
"tokio-stream",
"tower",
@@ -1916,7 +1931,7 @@ dependencies = [
"rustls-platform-verifier",
"serde",
"serde_json",
"thiserror 2.0.12",
"thiserror 2.0.18",
"tokio",
"tower",
"url",
@@ -1944,7 +1959,7 @@ dependencies = [
"http",
"serde",
"serde_json",
"thiserror 2.0.12",
"thiserror 2.0.18",
]
[[package]]
@@ -2072,9 +2087,9 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.7.1"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "memmap2"
@@ -2456,6 +2471,7 @@ dependencies = [
"watchexec-filterer-ignore",
"watchexec-signals",
"winapi",
"wrap-ansi",
"xxhash-rust",
]
@@ -3040,14 +3056,14 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.3"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.6",
"regex-syntax 0.8.2",
"regex-automata 0.4.13",
"regex-syntax 0.8.8",
]
[[package]]
@@ -3061,13 +3077,13 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.6"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.2",
"regex-syntax 0.8.8",
]
[[package]]
@@ -3078,9 +3094,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.2"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "rend"
@@ -3616,6 +3632,18 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "string-width"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f00d94d660cfa7bf3669352ebe9e06cc0351e0c9e696a31d051a54fa4bbb2b5"
dependencies = [
"east-asian-width",
"regex",
"strip-ansi-escapes",
"unicode-segmentation",
]
[[package]]
name = "string_cache"
version = "0.8.7"
@@ -3654,6 +3682,15 @@ dependencies = [
"syn 2.0.100",
]
[[package]]
name = "strip-ansi-escapes"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025"
dependencies = [
"vte 0.14.1",
]
[[package]]
name = "strsim"
version = "0.11.1"
@@ -3962,11 +3999,11 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.12"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl 2.0.12",
"thiserror-impl 2.0.18",
]
[[package]]
@@ -3982,9 +4019,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
version = "2.0.12"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
@@ -4459,7 +4496,7 @@ dependencies = [
"ratatui",
"tui-term 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.2.0",
"vte",
"vte 0.13.1",
]
[[package]]
@@ -4473,6 +4510,15 @@ dependencies = [
"vte_generate_state_changes",
]
[[package]]
name = "vte"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077"
dependencies = [
"memchr",
]
[[package]]
name = "vte_generate_state_changes"
version = "0.1.2"
@@ -4827,7 +4873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
dependencies = [
"windows-collections",
"windows-core 0.61.2",
"windows-core",
"windows-future",
"windows-link",
"windows-numerics",
@@ -4839,19 +4885,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
dependencies = [
"windows-core 0.61.2",
]
[[package]]
name = "windows-core"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [
"windows-implement 0.57.0",
"windows-interface 0.57.0",
"windows-result 0.1.2",
"windows-targets 0.52.6",
"windows-core",
]
[[package]]
@@ -4860,10 +4894,10 @@ version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement 0.60.2",
"windows-interface 0.59.3",
"windows-implement",
"windows-interface",
"windows-link",
"windows-result 0.3.4",
"windows-result",
"windows-strings",
]
@@ -4873,22 +4907,11 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core 0.61.2",
"windows-core",
"windows-link",
"windows-threading",
]
[[package]]
name = "windows-implement"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
@@ -4900,17 +4923,6 @@ dependencies = [
"syn 2.0.100",
]
[[package]]
name = "windows-interface"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
@@ -4934,19 +4946,10 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core 0.61.2",
"windows-core",
"windows-link",
]
[[package]]
name = "windows-result"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.3.4"
@@ -5253,6 +5256,18 @@ dependencies = [
"wayland-protocols-wlr",
]
[[package]]
name = "wrap-ansi"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "848bc403c11fc8f4d6597f2bad2ce43111fbf6757c7dd7d62590199e8dade5fd"
dependencies = [
"ansi-escape-sequences",
"regex",
"string-width",
"thiserror 2.0.18",
]
[[package]]
name = "wyz"
version = "0.5.1"
+22
View File
@@ -4,6 +4,28 @@
NX_GRADLE_DISABLE = "true"
NX_MAVEN_DISABLE = "true"
# Edge Functions for tracking LLM/AI tool requests to GA4
[[edge_functions]]
function = "track-asset-requests"
path = "/*.txt"
[[edge_functions]]
function = "track-asset-requests"
path = "/**/*.txt"
[[edge_functions]]
function = "track-asset-requests"
path = "/*.md"
[[edge_functions]]
function = "track-asset-requests"
path = "/**/*.md"
# Edge Function to add HTTP Link headers for LLM resource discovery
[[edge_functions]]
function = "add-link-headers"
path = "/docs/*"
# Permanent redirects (301 by default)
# Storybook docs consolidation
@@ -0,0 +1,62 @@
import type { Context } from 'https://edge.netlify.com';
/**
* Content negotiation for LLM-friendly docs access.
* See: https://llmstxt.org/
*/
export default async function handler(
request: Request,
context: Context
): Promise<Response | URL> {
const url = new URL(request.url);
const pathname = url.pathname;
// Skip non-page paths (assets, API endpoints, etc.)
if (
pathname.endsWith('.md') ||
pathname.endsWith('.txt') ||
pathname.includes('/og/') ||
pathname.includes('/_') ||
pathname.includes('/assets/')
) {
return context.next();
}
const acceptHeader = request.headers.get('accept') || '';
// Serve markdown for LLM tools that explicitly request it
// Or if there are no accept headers passed (e.g. Cursor)
if (!acceptHeader || acceptHeader.includes('text/markdown')) {
const mdPath = pathname.replace(/\/?$/, '.md');
return new URL(mdPath, request.url);
}
const response = await context.next();
const contentType = response.headers.get('content-type') || '';
if (!contentType.includes('text/html')) {
return response;
}
const mdPath = pathname.replace(/\/?$/, '.md');
const linkHeader = [
`<${mdPath}>; rel="alternate"; type="text/markdown"`,
`</docs/llms.txt>; rel="alternate"; type="text/markdown"; title="LLM Index"`,
`</docs/llms-full.txt>; rel="alternate"; type="text/markdown"; title="Full Documentation"`,
].join(', ');
// Netlify responses are immutable
const newHeaders = new Headers(response.headers);
newHeaders.set('Link', linkHeader);
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
});
}
export const config = {
path: ['/docs/*'],
};
@@ -0,0 +1,103 @@
import type { Context } from 'https://edge.netlify.com';
// Configuration - set these in Netlify environment variables
const GA_MEASUREMENT_ID =
Netlify.env.get('GA_MEASUREMENT_ID') || 'G-XXXXXXXXXX';
const GA_API_SECRET = Netlify.env.get('GA_API_SECRET') || '';
function getClientId(request: Request): string {
// Try to extract existing GA client ID from cookie
const cookies = request.headers.get('cookie') || '';
const gaMatch = cookies.match(/_ga=GA\d+\.\d+\.(\d+\.\d+)/);
if (gaMatch) {
return gaMatch[1];
}
// Generate a new client ID for this request
// For non-browser clients (AI tools), this creates a session-based ID
const timestamp = Date.now();
const random = Math.floor(Math.random() * 1000000000);
return `${random}.${timestamp}`;
}
async function sendToGA4(
request: Request,
context: Context,
pathname: string
): Promise<void> {
if (!GA_API_SECRET) {
console.warn('GA_API_SECRET not configured, skipping analytics');
return;
}
const clientId = getClientId(request);
const userAgent = request.headers.get('user-agent') || 'unknown';
// Detect AI tools from user agent
const isAITool =
/bot|crawler|spider|gpt|claude|anthropic|openai|perplexity|cohere/i.test(
userAgent
);
const payload = {
client_id: clientId,
events: [
{
name: 'page_view',
params: {
page_location: request.url,
page_title: pathname,
page_path: pathname,
// Custom parameters for filtering
file_extension: pathname.substring(pathname.lastIndexOf('.')),
user_agent: userAgent,
is_ai_tool: isAITool ? 'true' : 'false',
country: context.geo?.country?.code || 'unknown',
},
},
],
};
console.log(`Tracked asset path: ${pathname}`);
const endpoint = `https://www.google-analytics.com/mp/collect?measurement_id=${GA_MEASUREMENT_ID}&api_secret=${GA_API_SECRET}`;
try {
await fetch(endpoint, {
method: 'POST',
body: JSON.stringify(payload),
});
} catch (error) {
// Log but don't fail the request
console.error('Failed to send to GA4:', error);
}
}
export default async function handler(
request: Request,
context: Context
): Promise<Response> {
const url = new URL(request.url);
const pathname = url.pathname;
// Send analytics in background (non-blocking)
context.waitUntil(sendToGA4(request, context, pathname));
// Continue to serve the actual file
const response = await context.next();
// Netlify Edge Function responses are immutable, so create a new Response
const newHeaders = new Headers(response.headers);
newHeaders.set('x-nx-edge-function', 'track-asset-requests');
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
});
}
export const config = {
// Track all .txt and .md requests for AI/LLM usage analytics
path: ['/*.txt', '/**/*.txt', '/*.md', '/**/*.md'],
};
+75 -1
View File
@@ -144,6 +144,78 @@
window.twq('config', 'obtp4');
};
// Scroll depth tracking
const SCROLL_THRESHOLDS = [10, 25, 50, 75, 90];
let firedThresholds = new Set();
let scrollTrackingEnabled = false;
let scrollRafId = null;
function getScrollPercentage() {
const scrollTop = window.scrollY || document.documentElement.scrollTop;
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = window.innerHeight;
return (scrollTop + clientHeight) / scrollHeight;
}
function handleScrollTracking() {
if (!scrollTrackingEnabled) return;
const scrollPercentage = getScrollPercentage() * 100;
// Fire events for all thresholds we've passed but haven't fired yet
for (const threshold of SCROLL_THRESHOLDS) {
if (scrollPercentage >= threshold && !firedThresholds.has(threshold)) {
firedThresholds.add(threshold);
sendSearchEvent(`scroll_${threshold}`, {
event_category: 'scroll',
event_label: window.location.pathname,
});
}
}
}
function throttledScrollHandler() {
if (scrollRafId !== null) return;
scrollRafId = requestAnimationFrame(() => {
handleScrollTracking();
scrollRafId = null;
});
}
function attachScrollListener() {
window.addEventListener('scroll', throttledScrollHandler, {
passive: true,
});
}
function setupScrollTracking() {
// Reset scroll depth on navigation (for SPA-like behavior via View Transitions)
firedThresholds = new Set();
scrollTrackingEnabled = false;
// Delay tracking start to avoid false triggers during navigation
setTimeout(() => {
scrollTrackingEnabled = true;
// Immediately check current scroll position to capture thresholds
// that may have been passed during the delay
handleScrollTracking();
}, 500);
attachScrollListener();
// Handle Astro View Transitions - reset on navigation
document.addEventListener('astro:after-swap', () => {
firedThresholds = new Set();
scrollTrackingEnabled = false;
setTimeout(() => {
scrollTrackingEnabled = true;
// Immediately check current scroll position after navigation
handleScrollTracking();
}, 500);
});
}
const SEARCH_DEBOUNCE_MS = 1000;
let searchDebounceTimer;
let lastSearchQuery = '';
@@ -209,12 +281,14 @@
loadGTM();
loadHubSpot();
setupSearchTracking();
setupScrollTracking();
} else if (window.Cookiebot && window.Cookiebot.consent) {
// Statistics cookies (Google Analytics, GTM, Search Tracking)
// Statistics cookies (Google Analytics, GTM, Search, Scroll Tracking)
if (window.Cookiebot.consent.statistics) {
loadGoogleAnalytics();
loadGTM();
setupSearchTracking();
setupScrollTracking();
}
// Marketing cookies (HubSpot, Apollo, Hotjar, Twitter)
@@ -122,6 +122,33 @@ steps:
{% /tabitem %}
{% tabitem label="Bitbucket Pipelines" %}
```yaml
# bitbucket-pipelines.yml
image: node:22
pipelines:
pull-requests:
'**':
- step:
name: CI
script:
# Your existing steps which start-ci-run, install
# dependencies, etc.
# These are just illustrative examples...
- npx nx-cloud start-ci-run
- npm ci
- npx nx affected -t lint test build
after-script:
# NEW: Add this section at the end of your step
# IMPORTANT: after-script runs regardless of step success/failure
# so it's like if: always() on GitHub
- npx nx fix-ci
```
{% /tabitem %}
{% /tabs %}
> NOTE: If all tasks succeed then the `fix-ci` command becomes a no-op automatically, so that is why "always" is recommended.
@@ -182,31 +209,62 @@ Tasks matching these patterns will also have high-confidence, verified code chan
Tasks matching these patterns will **never** have code changes auto-applied, even if they match the include patterns or presets specified above. For example: `*e2e*`.
## Customization with CLAUDE.md
## Configuration with SELF_HEALING.md
Create a `CLAUDE.md` file in your repository root to provide additional context to the AI agent:
Create a `.nx/SELF_HEALING.md` file in your repository to provide project-specific instructions to the Self-Healing CI agent. This file contains freeform markdown that the AI agent reads and interprets naturally.
### Failure Classification Rules
{% aside title="Why a dedicated file?" type="note" %}
Using `.nx/SELF_HEALING.md` instead of `AGENTS.md` (or equivalent) separates CI-specific instructions from local development context. The file lives in the `.nx` directory alongside other Nx Cloud configuration.
{% /aside %}
Override how the AI categorizes failures:
### Example SELF_HEALING.md
```markdown
## Failure Classification
# Self-Healing Configuration
- Failures in `**/migrations/**` should be classified as `environment_state`
- Test timeouts in e2e tests are usually `flaky_task`
## Confidence Rules
- Fixes involving "test" targets should require high confidence
- Formatting fixes can be applied with medium confidence
## Off-Limits Areas
- `/src/generated/` - auto-generated, do not modify
- `/legacy/` - requires manual review
## Fix Preferences
- Prefer updating ESLint rules over adding disable comments
- For type errors, prefer explicit types over `any`
## Context
See ARCHITECTURE.md for module boundaries.
```
### Predefined Fixes
### What to Include
Specify deterministic solutions for common failures:
| Section | Purpose | Example |
| -------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
| **Confidence Rules** | Override how the AI categorizes failure severity | "Failures in `**/migrations/**` should be classified as `environment_state`" |
| **Off-Limits Areas** | Directories or files the agent should never modify | "`/src/generated/` - auto-generated code" |
| **Fix Preferences** | Guide the agent's approach to common issues | "Prefer updating ESLint rules over adding disable comments" |
| **Predefined Fixes** | Specify deterministic solutions for known failures | "For lint failures, always try running `nx lint --fix` first" |
| **Context** | Reference other documentation the agent should read | "See ARCHITECTURE.md for module boundaries" |
```markdown
## Predefined Fixes
### Using CLAUDE.md
- For lint failures, always try running `nx lint --fix` first
- Format failures should use `nx format:write`
```
If your repository already has a `CLAUDE.md` file at the root, the Self-Healing CI agent will read it for additional context. When both files exist:
- **SELF_HEALING.md takes precedence** for any conflicting instructions
- Both files are read, so general context in `CLAUDE.md` is still available
- CI-specific instructions should go in `SELF_HEALING.md`
This allows teams to maintain `CLAUDE.md` for local development workflows while using `SELF_HEALING.md` for CI-specific behavior.
### Viewing Configuration Status
After a CI run, navigate to the pipeline execution in Nx Cloud and check the **Configurations** tab to see whether `SELF_HEALING.md` was detected and applied.
## Receiving Fix Notifications
+183
View File
@@ -0,0 +1,183 @@
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';
import { readFileSync, existsSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const contentDocsDir = join(__dirname, '../content/docs');
interface DocEntry {
slug: string;
title: string;
content: string;
section: string;
}
/**
* Strips YAML frontmatter from markdown content.
* Frontmatter is delimited by --- at the start of the file.
*/
function stripFrontmatter(content: string): string {
// Match frontmatter: starts with ---, ends with ---
const frontmatterRegex = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/;
return content.replace(frontmatterRegex, '');
}
/**
* Generates llms-full.txt - a concatenated file of all Nx documentation.
* This file contains the full content of all docs for LLM consumption.
* See: https://llmstxt.org/
*/
export const GET: APIRoute = async ({ site }) => {
const siteUrl = site?.origin ?? 'https://nx.dev';
const entries: DocEntry[] = [];
// Preferred section order (same as llms.txt)
const sectionOrder = [
'quickstart',
'getting-started',
'concepts',
'features',
'guides',
'extending-nx',
'technologies',
'reference',
'enterprise',
'troubleshooting',
];
// Section display names
const sectionNames: Record<string, string> = {
'getting-started': 'Getting Started',
concepts: 'Core Concepts',
features: 'Features',
guides: 'Guides',
'extending-nx': 'Extending Nx',
technologies: 'Technologies',
reference: 'Reference',
enterprise: 'Enterprise',
troubleshooting: 'Troubleshooting',
quickstart: 'Quickstart',
};
// Get all docs from the content collection (static .mdoc/.mdx files)
const docs = await getCollection('docs');
for (const doc of docs) {
const slug = doc.id;
const title = doc.data.title || slug.split('/').pop() || slug;
const section = slug.split('/')[0] || 'other';
// Try to get file path from doc.filePath, or try common extensions
let filePath = doc.filePath;
if (!filePath) {
const extensions = ['.mdoc', '.mdx', '.md'];
for (const ext of extensions) {
const testPath = join(contentDocsDir, doc.id + ext);
if (existsSync(testPath)) {
filePath = testPath;
break;
}
}
}
// Skip if no file path found or not readable
if (!filePath || !existsSync(filePath)) {
continue;
}
try {
const rawContent = readFileSync(filePath, 'utf-8');
const content = stripFrontmatter(rawContent);
entries.push({ slug, title, content, section });
} catch {
// Skip files that can't be read
continue;
}
}
// Get plugin docs (executors, generators for each plugin)
try {
const pluginDocs = await getCollection('plugin-docs');
for (const doc of pluginDocs) {
if (doc.data.slug && doc.body) {
const slug = doc.data.slug;
const section = slug.split('/')[0] || 'technologies';
entries.push({
slug,
title: doc.data.title || slug,
content: stripFrontmatter(doc.body),
section,
});
}
}
} catch {
// plugin-docs collection might not exist
}
// Note: Excluding nx-reference-packages (devkit API docs) for now
// to keep the file size under 2MB. These are highly technical
// and can be accessed individually via .md endpoints.
// Sort entries by section order, then by slug within section
entries.sort((a, b) => {
const sectionIndexA = sectionOrder.indexOf(a.section);
const sectionIndexB = sectionOrder.indexOf(b.section);
const orderA = sectionIndexA === -1 ? 999 : sectionIndexA;
const orderB = sectionIndexB === -1 ? 999 : sectionIndexB;
if (orderA !== orderB) {
return orderA - orderB;
}
return a.slug.localeCompare(b.slug);
});
// Generate the llms-full.txt content
const lines: string[] = [
'# Nx Documentation',
'',
'> Complete Nx documentation compiled into a single file for LLM consumption.',
'',
'Nx is a powerful, open source, technology-agnostic build platform designed to efficiently manage codebases of any scale. From small single projects to large enterprise monorepos, Nx provides intelligent task execution, caching, and CI optimization.',
'',
`This file was generated from ${entries.length} documentation pages.`,
`Individual pages are available at: ${siteUrl}/docs/{slug}.md`,
'',
];
// Track current section for headers
let currentSection = '';
for (const entry of entries) {
// Add section header when section changes
if (entry.section !== currentSection) {
currentSection = entry.section;
const sectionName = sectionNames[currentSection] || currentSection;
lines.push('');
lines.push(`# ${sectionName}`);
lines.push('');
}
// URL encode spaces in the slug
const encodedSlug = entry.slug.replace(/ /g, '%20');
const sourceUrl = `${siteUrl}/docs/${encodedSlug}.md`;
lines.push('---');
lines.push(`<!-- source: ${sourceUrl} -->`);
lines.push(`## ${entry.title}`);
lines.push('');
lines.push(entry.content.trim());
lines.push('');
}
const content = lines.join('\n');
return new Response(content, {
status: 200,
headers: {
'Content-Type': 'text/markdown; charset=utf-8',
'Cache-Control': 'public, max-age=3600',
},
});
};
+15 -3
View File
@@ -237,7 +237,11 @@ describe('nx release - independent projects', () => {
const versionWithGitActionsCLIOutput = runCLI(
`release version 999.9.9-version-git-operations-test.2 -p ${pkg1} --git-commit --git-tag --verbose` // add verbose so we get richer output
);
expect(versionWithGitActionsCLIOutput).toMatchInlineSnapshot(`
const filteredOutput = versionWithGitActionsCLIOutput.replace(
/\[plugin-(pool|worker)\].*\n/g,
''
);
expect(filteredOutput).toMatchInlineSnapshot(`
NX Your filter "{project-name}" matched the following projects:
@@ -320,7 +324,11 @@ describe('nx release - independent projects', () => {
const versionWithGitActionsConfigOutput = runCLI(
`release version 999.9.9-version-git-operations-test.3 --verbose --gitTag` // add verbose so we get richer output
);
expect(versionWithGitActionsConfigOutput).toMatchInlineSnapshot(`
const filteredConfigOutput = versionWithGitActionsConfigOutput.replace(
/\[plugin-(pool|worker)\].*\n/g,
''
);
expect(filteredConfigOutput).toMatchInlineSnapshot(`
NX Running release version for project: {project-name}
@@ -516,7 +524,11 @@ describe('nx release - independent projects', () => {
const versionWithGitActionsCLIOutput = runCLI(
`release changelog 999.9.9-changelog-git-operations-test.1 -p ${pkg1} --verbose`
);
expect(versionWithGitActionsCLIOutput).toMatchInlineSnapshot(`
const filteredChangelogOutput = versionWithGitActionsCLIOutput.replace(
/\[plugin-(pool|worker)\].*\n/g,
''
);
expect(filteredChangelogOutput).toMatchInlineSnapshot(`
NX Your filter "{project-name}" matched the following projects:
@@ -54,6 +54,8 @@ expect.addSnapshotSerializer({
.replaceAll('pnpm install --lockfile-only', '{lock-file-command}')
.replaceAll(getSelectedPackageManager(), '{package-manager}')
.replaceAll(e2eRegistryUrl, '{registryUrl}')
// Filter out plugin worker verbose logs
.replaceAll(/\[plugin-(pool|worker)\].*\n/g, '')
// We trim each line to reduce the chances of snapshot flakiness
.split('\n')
.map((r) => r.trim())
@@ -47,6 +47,8 @@ expect.addSnapshotSerializer({
/Integrity:\s*.*/g,
'Integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
)
// Filter out plugin worker verbose logs
.replaceAll(/\[plugin-(pool|worker)\].*\n/g, '')
.split('\n')
.map((r) => r.trim())
@@ -32,6 +32,8 @@ expect.addSnapshotSerializer({
.replaceAll(/Test @[\w\d]+/g, 'Test @{COMMIT_AUTHOR}')
// Normalize the version title date.
.replaceAll(/\(\d{4}-\d{2}-\d{2}\)/g, '(YYYY-MM-DD)')
// Filter out plugin worker verbose logs
.replaceAll(/\[plugin-(pool|worker)\].*\n/g, '')
// We trim each line to reduce the chances of snapshot flakiness
.split('\n')
.map((r) => r.trim())
@@ -29,6 +29,8 @@ expect.addSnapshotSerializer({
.replaceAll(/Test @[\w\d]+/g, 'Test @{COMMIT_AUTHOR}')
// Normalize the version title date.
.replaceAll(/\(\d{4}-\d{2}-\d{2}\)/g, '(YYYY-MM-DD)')
// Filter out plugin worker verbose logs
.replaceAll(/\[plugin-(pool|worker)\].*\n/g, '')
// We trim each line to reduce the chances of snapshot flakiness
.split('\n')
.map((r) => r.trim())
+1 -1
View File
@@ -136,7 +136,7 @@ export function FeedContainer(): JSX.Element {
<div
className={cx(
'left0 fixed bottom-0 right-0 w-full px-4 py-4 lg:px-0 lg:py-6',
'bg-gradient-to-t from-white via-white/75 dark:from-slate-900 dark:via-slate-900/75'
'bg-gradient-to-t from-white via-white/75 dark:from-zinc-900 dark:via-zinc-900/75'
)}
>
<Prompt
+8 -11
View File
@@ -51,7 +51,7 @@ export function FeedAnswer({
return (
<>
<div className="grid h-12 w-12 items-center justify-center rounded-full bg-white text-slate-900 ring-1 ring-slate-200 dark:bg-slate-900 dark:text-white dark:ring-slate-700">
<div className="grid h-12 w-12 items-center justify-center rounded-full bg-white text-zinc-900 ring-1 ring-zinc-200 dark:bg-zinc-900 dark:text-white dark:ring-zinc-700">
<svg
role="img"
viewBox="0 0 24 24"
@@ -65,23 +65,20 @@ export function FeedAnswer({
</div>
<div className="min-w-0 flex-1">
<div>
<div className="flex items-center gap-2 text-lg text-slate-900 dark:text-slate-100">
<div className="flex items-center gap-2 text-lg text-zinc-900 dark:text-zinc-100">
Nx Assistant
</div>
<p className="mt-0.5 flex items-center gap-x-1 text-sm text-slate-500">
<ChatGptLogo
className="h-4 w-4 text-slate-400"
aria-hidden="true"
/>{' '}
<p className="mt-0.5 flex items-center gap-x-1 text-sm text-zinc-500">
<ChatGptLogo className="h-4 w-4 text-zinc-400" aria-hidden="true" />{' '}
AI powered
</p>
</div>
<div className="prose prose-slate dark:prose-invert mt-2 w-full max-w-none 2xl:max-w-4xl">
<div className="prose prose-zinc dark:prose-invert mt-2 w-full max-w-none 2xl:max-w-4xl">
{!isFirst && callout}
{renderMarkdown(normalizedContent, { filePath: '' }).node}
</div>
{!isFirst && (
<div className="text-md group flex-1 gap-4 text-slate-400 transition hover:text-slate-500 md:flex md:items-center md:justify-end">
<div className="text-md group flex-1 gap-4 text-zinc-400 transition hover:text-zinc-500 md:flex md:items-center md:justify-end">
{feedbackStatement ? (
<p className="italic group-hover:flex">
{feedbackStatement === 'good'
@@ -96,7 +93,7 @@ export function FeedAnswer({
<div className="flex gap-4">
<button
className={cx(
'p-1 transition-all hover:rotate-12 hover:text-blue-500 disabled:cursor-not-allowed dark:hover:text-sky-500',
'p-1 transition-all hover:rotate-12 hover:text-blue-500 disabled:cursor-not-allowed dark:hover:text-blue-500',
{ 'text-blue-500': feedbackStatement === 'bad' }
)}
disabled={!!feedbackStatement}
@@ -108,7 +105,7 @@ export function FeedAnswer({
</button>
<button
className={cx(
'p-1 transition-all hover:rotate-12 hover:text-blue-500 disabled:cursor-not-allowed dark:hover:text-sky-500',
'p-1 transition-all hover:rotate-12 hover:text-blue-500 disabled:cursor-not-allowed dark:hover:text-blue-500',
{ 'text-blue-500': feedbackStatement === 'good' }
)}
disabled={!!feedbackStatement}
@@ -1,7 +1,7 @@
export function FeedQuestion({ content }: { content: string }) {
return (
<div className="flex w-full justify-end">
<p className="whitespace-pre-wrap break-words rounded-lg bg-blue-500 px-4 py-2 text-base text-white selection:bg-sky-900 dark:bg-sky-500">
<p className="whitespace-pre-wrap break-words rounded-lg bg-blue-500 px-4 py-2 text-base text-white selection:bg-blue-900 dark:bg-blue-500">
{content}
</p>
</div>
+1 -1
View File
@@ -1,6 +1,6 @@
export function LoadingState(): JSX.Element {
return (
<div className="flex w-full items-center justify-center gap-4 px-4 py-2 text-blue-500 transition duration-150 ease-in-out dark:text-sky-500">
<div className="flex w-full items-center justify-center gap-4 px-4 py-2 text-blue-500 transition duration-150 ease-in-out dark:text-blue-500">
<svg
className="h-5 w-5 animate-spin"
xmlns="http://www.w3.org/2000/svg"
+6 -6
View File
@@ -62,7 +62,7 @@ export function Prompt({
<form
ref={formRef}
onSubmit={handleSubmit}
className="relative mx-auto flex max-w-3xl gap-2 rounded-md border border-slate-300 bg-white px-2 py-2 shadow-lg dark:border-slate-900 dark:bg-slate-700"
className="relative mx-auto flex max-w-3xl gap-2 rounded-md border border-zinc-300 bg-white px-2 py-2 shadow-lg dark:border-zinc-900 dark:bg-zinc-700"
>
<div
className={cx(
@@ -74,7 +74,7 @@ export function Prompt({
<Button
variant="secondary"
size="small"
className={cx('bg-white dark:bg-slate-900')}
className={cx('bg-white dark:bg-zinc-900')}
onClick={handleStopGenerating}
>
<StopIcon aria-hidden="true" className="h-5 w-5" />
@@ -85,7 +85,7 @@ export function Prompt({
<Button
variant="secondary"
size="small"
className={cx('bg-white dark:bg-slate-900')}
className={cx('bg-white dark:bg-zinc-900')}
onClick={handleNewChat}
>
<XMarkIcon aria-hidden="true" className="h-5 w-5" />
@@ -96,7 +96,7 @@ export function Prompt({
<Button
variant="secondary"
size="small"
className={cx('bg-white dark:bg-slate-900')}
className={cx('bg-white dark:bg-zinc-900')}
onClick={onRegenerate}
>
<ArrowPathIcon aria-hidden="true" className="h-5 w-5" />
@@ -123,14 +123,14 @@ export function Prompt({
name="query"
maxLength={500}
disabled={isGenerating}
className="block w-full resize-none border-none bg-transparent p-0 py-3 pl-2 text-sm placeholder-slate-500 focus-within:outline-none focus:placeholder-slate-400 focus:outline-none focus:ring-0 disabled:cursor-not-allowed dark:text-white dark:focus:placeholder-slate-300"
className="block w-full resize-none border-none bg-transparent p-0 py-3 pl-2 text-sm placeholder-zinc-500 focus-within:outline-none focus:placeholder-zinc-400 focus:outline-none focus:ring-0 disabled:cursor-not-allowed dark:text-white dark:focus:placeholder-zinc-300"
placeholder="How does caching work?"
rows={1}
/>
</div>
<div className="flex">
<Button
variant="primary"
variant="contrast"
size="small"
type="submit"
disabled={isGenerating}
@@ -2,16 +2,16 @@ import { InformationCircleIcon } from '@heroicons/react/24/outline';
export function ActivityLimitReached(): JSX.Element {
return (
<div className="rounded-md bg-slate-50 p-4 shadow-sm ring-1 ring-slate-100 dark:bg-slate-800/40 dark:ring-slate-700">
<div className="rounded-md bg-zinc-50 p-4 shadow-sm ring-1 ring-zinc-100 dark:bg-zinc-800/40 dark:ring-zinc-700">
<div className="flex">
<div className="flex-shrink-0">
<InformationCircleIcon
className="h-5 w-5 text-slate-500 dark:text-slate-300"
className="h-5 w-5 text-zinc-500 dark:text-zinc-300"
aria-hidden="true"
/>
</div>
<div className="ml-3 flex-1 md:flex md:justify-between">
<p className="text-sm text-slate-700 dark:text-slate-400">
<p className="text-sm text-zinc-700 dark:text-zinc-400">
You've reached the maximum message history limit. Previous messages
will be removed.
</p>
@@ -3,7 +3,7 @@ import { ReactNode } from 'react';
export function SidebarContainer({ children }: { children: ReactNode[] }) {
return (
<div id="sidebar" data-testid="sidebar">
<div className="hidden h-full w-72 flex-col border-r border-slate-200 md:flex dark:border-slate-700 dark:bg-slate-900">
<div className="hidden h-full w-72 flex-col border-r border-zinc-200 md:flex dark:border-zinc-700 dark:bg-zinc-900">
<div className="relative flex flex-col gap-4 overflow-y-scroll p-4">
{...children}
</div>
@@ -4,17 +4,11 @@ import { useEffect, useRef, useCallback } from 'react';
import { usePathname } from 'next/navigation';
import { sendCustomEvent } from './google-analytics';
function getScrollDepth(pct: number): 0 | 25 | 50 | 75 | 90 {
if (pct >= 0.9) return 90;
if (pct < 0.25) return 0;
if (pct < 0.5) return 25;
if (pct < 0.75) return 50;
return 75;
}
const SCROLL_THRESHOLDS = [10, 25, 50, 75, 90] as const;
export function useWindowScrollDepth(): void {
const pathname = usePathname();
const scrollDepth = useRef(0);
const firedThresholds = useRef<Set<number>>(new Set());
const shouldTrackScroll = useRef(true);
const rafId = useRef<number | null>(null);
@@ -23,13 +17,19 @@ export function useWindowScrollDepth(): void {
if (typeof window === 'undefined') return;
const scrollPercentage =
(window.scrollY + window.innerHeight) /
document.documentElement.scrollHeight;
const depth = getScrollDepth(scrollPercentage);
((window.scrollY + window.innerHeight) /
document.documentElement.scrollHeight) *
100;
if (depth > scrollDepth.current) {
scrollDepth.current = depth;
sendCustomEvent(`scroll_${depth}`, 'scroll', pathname || '/');
// Fire events for all thresholds we've passed but haven't fired yet
for (const threshold of SCROLL_THRESHOLDS) {
if (
scrollPercentage >= threshold &&
!firedThresholds.current.has(threshold)
) {
firedThresholds.current.add(threshold);
sendCustomEvent(`scroll_${threshold}`, 'scroll', pathname || '/');
}
}
}, [pathname]);
@@ -46,12 +46,15 @@ export function useWindowScrollDepth(): void {
shouldTrackScroll.current = false;
const timeout = setTimeout(() => {
scrollDepth.current = 0;
firedThresholds.current = new Set();
shouldTrackScroll.current = true;
// Immediately check current scroll position to capture thresholds
// that may have been passed during the delay
handleScroll();
}, 500);
return () => clearTimeout(timeout);
}, [pathname]);
}, [pathname, handleScroll]);
useEffect(() => {
if (typeof window === 'undefined') return;
@@ -135,7 +135,7 @@ export function DocViewer({
ref={ref}
data-document="main"
className={cx(
'prose prose-slate dark:prose-invert w-full max-w-none 2xl:max-w-4xl',
'prose prose-zinc dark:prose-invert w-full max-w-none 2xl:max-w-4xl',
{ 'xl:max-w-2xl': !hideTableOfContent }
)}
>
@@ -146,7 +146,7 @@ export function DocViewer({
<div>
<div
className={cx(
'sticky top-2 z-20 ml-[max(2rem,calc(50%-8rem))] hidden w-60 space-y-6 overflow-y-auto bg-white text-sm xl:block dark:bg-slate-900'
'sticky top-2 z-20 ml-[max(2rem,calc(50%-8rem))] hidden w-60 space-y-6 overflow-y-auto bg-white text-sm xl:block dark:bg-zinc-900'
)}
>
{widgetData.githubStarsCount > 0 && (
@@ -163,18 +163,18 @@ export function DocViewer({
document={document}
>
<>
<div className="my-4 flex items-center justify-center space-x-2 rounded-md border border-slate-200 pl-2 pr-2 hover:border-slate-400 dark:border-slate-700 print:hidden">
<div className="my-4 flex items-center justify-center space-x-2 rounded-md border border-zinc-200 pl-2 pr-2 hover:border-zinc-400 dark:border-zinc-700 print:hidden">
<button
type="button"
aria-label="Give feedback on this page"
title="Give feedback of this page"
className="whitespace-nowrap border-transparent px-4 py-2 font-bold hover:text-slate-900 dark:hover:text-sky-400"
className="whitespace-nowrap border-transparent px-4 py-2 font-bold hover:text-zinc-900 dark:hover:text-blue-400"
onClick={() => setShowFeedback(true)}
>
Feedback
</button>
</div>
<div className="my-4 flex items-center justify-center space-x-2 rounded-md border border-slate-200 pl-2 pr-2 hover:border-slate-400 dark:border-slate-700 print:hidden">
<div className="my-4 flex items-center justify-center space-x-2 rounded-md border border-zinc-200 pl-2 pr-2 hover:border-zinc-400 dark:border-zinc-700 print:hidden">
{document.filePath ? (
<a
aria-hidden="true"
@@ -190,7 +190,7 @@ export function DocViewer({
target="_blank"
rel="noreferrer"
title="Edit this page on GitHub"
className="whitespace-nowrap border-transparent px-4 py-2 font-bold hover:text-slate-900 dark:hover:text-sky-400"
className="whitespace-nowrap border-transparent px-4 py-2 font-bold hover:text-zinc-900 dark:hover:text-blue-400"
>
Edit this page
</a>
@@ -207,7 +207,7 @@ export function DocViewer({
<div
data-document="related"
className={cx(
'prose prose-slate dark:prose-invert w-full max-w-none pt-8 2xl:max-w-4xl',
'prose prose-zinc dark:prose-invert w-full max-w-none pt-8 2xl:max-w-4xl',
{ 'xl:max-w-2xl': !hideTableOfContent }
)}
>
@@ -221,7 +221,7 @@ export function DocViewer({
hideTableOfContent ? '' : 'xl:hidden'
}`}
>
<div className="ml-4 flex h-0.5 w-full flex-grow rounded bg-slate-50 dark:bg-slate-800/60" />
<div className="ml-4 flex h-0.5 w-full flex-grow rounded bg-zinc-50 dark:bg-zinc-800/60" />
<div className="relative z-0 inline-flex flex-shrink-0 rounded-md shadow-sm">
<button
type="button"
@@ -230,7 +230,7 @@ export function DocViewer({
className={`relative inline-flex items-center rounded-l-md ${
// If there is no file path for this page then don't show edit button.
document.filePath ? '' : 'rounded-r-md'
}border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 focus-within:ring-blue-500 hover:bg-slate-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800`}
}border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 focus-within:ring-blue-500 hover:bg-zinc-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800`}
onClick={() => setShowFeedback(true)}
>
Feedback
@@ -247,7 +247,7 @@ export function DocViewer({
target="_blank"
rel="noreferrer"
title="Edit this page on GitHub"
className="relative -ml-px inline-flex items-center rounded-r-md border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 focus-within:ring-blue-500 hover:bg-slate-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800"
className="relative -ml-px inline-flex items-center rounded-r-md border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 focus-within:ring-blue-500 hover:bg-zinc-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800"
>
Edit this page
</a>
@@ -40,12 +40,12 @@ const iconMap: { [key: string]: JSX.Element } = {
function CategoryBox({ category }: { category: RelatedDocumentsCategory }) {
return (
<div className="rounded-lg border border-slate-200 bg-white/60 p-5 dark:border-slate-800/40 dark:bg-slate-800/60">
<div className="rounded-lg border border-zinc-200 bg-white/60 p-5 dark:border-zinc-800/40 dark:bg-zinc-800/60">
<h4 className="mt-0 flex items-center pb-2 text-xl font-bold">
{iconMap[category.id] ?? iconMap.default}
{category.name}
</h4>
<ul className="list-none divide-y divide-slate-300 pl-0 dark:divide-slate-700">
<ul className="list-none divide-y divide-zinc-300 pl-0 dark:divide-zinc-700">
{category.relatedDocuments.map((d) => (
<li
key={d.id}
@@ -53,11 +53,11 @@ function CategoryBox({ category }: { category: RelatedDocumentsCategory }) {
>
<Link
href={d.path}
className="flex flex-grow items-center justify-between no-underline transition-colors ease-out hover:text-blue-700 hover:underline dark:text-sky-500 dark:hover:text-sky-400"
className="flex flex-grow items-center justify-between no-underline transition-colors ease-out hover:text-blue-700 hover:underline dark:text-blue-500 dark:hover:text-blue-400"
prefetch={false}
>
<span>{d.name}</span>
<ArrowRightIcon className="h-4 w-4 text-slate-500 dark:text-slate-400" />
<ArrowRightIcon className="h-4 w-4 text-zinc-500 dark:text-zinc-400" />
</Link>
</li>
))}
@@ -86,9 +86,9 @@ export function TableOfContents({
<Link
href={href}
className={cx(
'block w-full border-l-4 border-slate-200 py-1 pl-3 transition hover:border-slate-500 dark:border-slate-700/40 dark:hover:border-slate-700',
'block w-full border-l-4 border-zinc-200 py-1 pl-3 transition hover:border-zinc-500 dark:border-zinc-700/40 dark:hover:border-zinc-700',
{
'border-slate-500 bg-slate-50 dark:border-slate-700 dark:bg-slate-800/60':
'border-zinc-500 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800/60':
activeId === item.id && !item.highlightColor,
// region Highlight Color
'border-blue-200 bg-blue-50 hover:border-blue-500 dark:border-blue-700/40 dark:bg-blue-800/40 dark:hover:border-blue-700':
@@ -93,10 +93,10 @@ function FeedbackDialog({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<DialogPanel className="relative w-full max-w-2xl transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all dark:bg-slate-900">
<DialogPanel className="relative w-full max-w-2xl transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all dark:bg-zinc-900">
<DialogTitle
as="h3"
className="bg-white p-4 text-center text-lg font-medium leading-6 text-slate-700 dark:bg-slate-900 dark:text-slate-400"
className="bg-white p-4 text-center text-lg font-medium leading-6 text-zinc-700 dark:bg-zinc-900 dark:text-zinc-400"
>
What is on your mind?
<button className={styles.closebutton} onClick={closeDialog}>
@@ -154,7 +154,7 @@ function FeedbackDialog({
htmlFor="idea"
tabIndex={0}
onKeyDown={(e) => keydownHandler(e)}
className="inline-flex w-full cursor-pointer items-center justify-between rounded-lg border border-gray-200 bg-white p-5 text-gray-500 hover:bg-slate-50 focus:outline-none focus:ring-1 peer-checked:border-sky-500 peer-checked:text-sky-500 dark:border-gray-700 dark:bg-gray-800 dark:text-slate-400 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800 dark:hover:text-gray-300 dark:peer-checked:text-sky-500"
className="inline-flex w-full cursor-pointer items-center justify-between rounded-lg border border-gray-200 bg-white p-5 text-gray-500 hover:bg-zinc-50 focus:outline-none focus:ring-1 peer-checked:border-blue-500 peer-checked:text-blue-500 dark:border-gray-700 dark:bg-gray-800 dark:text-zinc-400 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800 dark:hover:text-gray-300 dark:peer-checked:text-blue-500"
>
<div className="block">
<div className="w-full text-lg font-semibold">Idea</div>
@@ -242,10 +242,10 @@ function FeedbackDialog({
onClick={submitFeedback}
disabled={formDisabled}
className={cx(
'rounded-md border border-slate-200 bg-white px-4 py-2 text-base font-medium text-slate-600 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400',
'rounded-md border border-zinc-200 bg-white px-4 py-2 text-base font-medium text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400',
{ 'cursor-not-allowed': formDisabled },
{
'focus-within:ring-blue-500 hover:bg-slate-50 focus:z-10 focus:outline-none focus:ring-1 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800':
'focus-within:ring-blue-500 hover:bg-zinc-50 focus:z-10 focus:outline-none focus:ring-1 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800':
!formDisabled,
}
)}
@@ -129,7 +129,7 @@ export function Content({
<div
aria-hidden="true"
data-tooltip="Schema type"
className="relative inline-flex rounded-md border border-slate-200 bg-slate-50 px-4 py-2 text-xs font-medium uppercase dark:border-slate-700 dark:bg-slate-800/60"
className="relative inline-flex rounded-md border border-zinc-200 bg-zinc-50 px-4 py-2 text-xs font-medium uppercase dark:border-zinc-700 dark:bg-zinc-800/60"
>
{schemaViewModel.type}
</div>
@@ -157,7 +157,7 @@ export function Content({
href={schemaViewModel.packageUrl}
title="See package information"
className={cx(
'relative inline-flex items-center rounded-l-md border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 focus-within:ring-blue-500 hover:bg-slate-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800',
'relative inline-flex items-center rounded-l-md border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 focus-within:ring-blue-500 hover:bg-zinc-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800',
schemaViewModel.packageName.startsWith('@nx/powerpack')
? 'rounded-md'
: 'rounded-l-md'
@@ -173,7 +173,7 @@ export function Content({
target="_blank"
rel="noreferrer"
title="See this schema on GitHub"
className="relative -ml-px inline-flex items-center rounded-r-md border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 focus-within:ring-blue-500 hover:bg-slate-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800"
className="relative -ml-px inline-flex items-center rounded-r-md border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 focus-within:ring-blue-500 hover:bg-zinc-50 focus:z-10 focus:outline-none focus:ring-1 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800"
>
<svg
className="mr-2 h-4 w-4"
@@ -237,7 +237,7 @@ export function Content({
{/* We remove the top description on sub property lookup */}
{!schemaViewModel.subReference && (
<>
<div className="prose prose-slate dark:prose-invert max-w-none">
<div className="prose prose-zinc dark:prose-invert max-w-none">
{vm.markdown.header}
{vm.markdown.customContent}
{vm.markdown.usageAndExamples}
@@ -269,7 +269,7 @@ export function Content({
setPresets(p.keys);
}}
type="button"
className="relative inline-flex items-center rounded-md border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:hover:bg-slate-800"
className="relative inline-flex items-center rounded-md border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:hover:bg-zinc-800"
>
{p.name}
</button>
@@ -278,7 +278,7 @@ export function Content({
<button
onClick={() => setPresets([])}
type="button"
className="relative inline-flex items-center rounded-md border border-slate-200 bg-white px-4 py-2 text-xs font-medium text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-400 dark:hover:bg-slate-800"
className="relative inline-flex items-center rounded-md border border-zinc-200 bg-white px-4 py-2 text-xs font-medium text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-400 dark:hover:bg-zinc-800"
>
Reset <XCircleIcon className="ml-1.5 h-4 w-4" />
</button>
@@ -286,7 +286,7 @@ export function Content({
</div>
</>
)}
<div className="rounded-md border border-slate-200 p-0.5 dark:border-slate-700">
<div className="rounded-md border border-zinc-200 p-0.5 dark:border-zinc-700">
<SchemaEditor
packageName={schemaViewModel.packageName}
schemaName={schemaViewModel.schemaMetadata.name}
@@ -21,7 +21,7 @@ export function MigrationViewer({
<summary className="cursor-pointer">
<Heading3 title={schema.name}></Heading3>
</summary>
<div className="prose prose-slate dark:prose-invert mb-6 ml-5">
<div className="prose prose-zinc dark:prose-invert mb-6 ml-5">
<p>{schema.description}</p>
<div className="my-1">
<strong>Version</strong>: {schema.version}
@@ -125,7 +125,7 @@ export function PackageSchemaList({
<div className="h-12">{/* SPACER */}</div>
<Heading2 title={'Migrations'} />
<ul className="divide-y divide-slate-100 dark:divide-slate-800">
<ul className="divide-y divide-zinc-100 dark:divide-zinc-800">
{!!filesAndLabels.length
? filesAndLabels.map((schema) =>
typeof schema === 'string' ? (
@@ -116,7 +116,7 @@ export function PackageSchemaSubList({
) : null}
{vm.type === 'migration' ? (
<ul className="divide-y divide-slate-100 dark:divide-slate-800">
<ul className="divide-y divide-zinc-100 dark:divide-zinc-800">
{filesAndLabels.map((schema) =>
typeof schema === 'string' ? (
<VersionLabelListItem
@@ -142,7 +142,7 @@ export function PackageSchemaSubList({
export const VersionLabelListItem = ({ label }: { label: string }) => {
return label ? (
<li className="relative flex px-1 pt-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-50 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800/60">
<li className="relative flex px-1 pt-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-zinc-50 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800/60">
<div className="pt-2">
<span className="text-sm font-bold">
<Heading2 title={label} />
@@ -24,13 +24,13 @@ export const ParameterView = (props: {
{props.alias && (
<span
data-tooltip="Property alias"
className="relative -top-0.5 inline-flex rounded-md px-2 text-xs font-semibold leading-5 dark:bg-slate-700"
className="relative -top-0.5 inline-flex rounded-md px-2 text-xs font-semibold leading-5 dark:bg-zinc-700"
>
{props.alias}
</span>
)}
{props.required && (
<span className="relative -top-0.5 inline-flex rounded-md bg-slate-100 px-2 text-xs font-semibold uppercase leading-5 dark:bg-slate-700">
<span className="relative -top-0.5 inline-flex rounded-md bg-zinc-100 px-2 text-xs font-semibold uppercase leading-5 dark:bg-zinc-700">
Required
</span>
)}
@@ -68,7 +68,7 @@ export const ParameterView = (props: {
)}
</div>
<div className="prose prose-slate dark:prose-invert -mt-4 max-w-none">
<div className="prose prose-zinc dark:prose-invert -mt-4 max-w-none">
{
renderMarkdown(props.description, {
filePath: '',
@@ -78,7 +78,7 @@ export const ParameterView = (props: {
{props.deprecated &&
typeof (props.schema as any)['x-deprecated'] === 'string' ? (
<div className="prose prose-slate dark:prose-invert mt-2 rounded-md bg-red-100 px-4 text-red-800 dark:bg-red-800 dark:text-red-100">
<div className="prose prose-zinc dark:prose-invert mt-2 rounded-md bg-red-100 px-4 text-red-800 dark:bg-red-800 dark:text-red-100">
{
renderMarkdown(String((props.schema as any)['x-deprecated']), {
filePath: '',
@@ -5,7 +5,7 @@ import Link from 'next/link';
export const Heading1 = ({ title }: { title: string }) => (
<h1
id={slugify(title)}
className="group mb-5 text-4xl font-extrabold tracking-tight text-slate-900 dark:text-slate-100"
className="group mb-5 text-4xl font-extrabold tracking-tight text-zinc-900 dark:text-zinc-100"
>
<span>{title}</span>
<Link aria-hidden="true" tabIndex={-1} href={'#' + slugify(title)}>
@@ -20,7 +20,7 @@ export const Heading1 = ({ title }: { title: string }) => (
export const Heading2 = ({ title }: { title: string }) => (
<h2
id={slugify(title)}
className="group mb-5 text-2xl font-bold tracking-tight text-slate-800 dark:text-slate-200"
className="group mb-5 text-2xl font-bold tracking-tight text-zinc-800 dark:text-zinc-200"
>
<span>{title}</span>
<Link aria-hidden="true" tabIndex={-1} href={'#' + slugify(title)}>
@@ -35,7 +35,7 @@ export const Heading2 = ({ title }: { title: string }) => (
export const Heading3 = ({ title }: { title: string }) => (
<h3
id={slugify(title)}
className="group text-xl font-semibold tracking-tight text-slate-700 dark:text-slate-300"
className="group text-xl font-semibold tracking-tight text-zinc-700 dark:text-zinc-300"
>
<span>{title}</span>
<Link aria-hidden="true" tabIndex={-1} href={'#' + slugify(title)}>
@@ -16,7 +16,7 @@ export function DocumentList({
documents: DocumentMetadata[];
}): JSX.Element {
return (
<ul className="divide-y divide-slate-100 dark:divide-slate-800">
<ul className="divide-y divide-zinc-100 dark:divide-zinc-800">
{!!documents.length ? (
documents.map((guide) => (
<DocumentListItem key={guide.id} document={guide} />
@@ -36,9 +36,9 @@ function DocumentListItem({
return (
<li
key={document.name}
className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-50 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800/60"
className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-zinc-50 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800/60"
>
<div className="flex-shrink-0 self-start rounded-lg border-slate-200 bg-slate-100 p-2 dark:border-slate-600 dark:bg-slate-700">
<div className="flex-shrink-0 self-start rounded-lg border-zinc-200 bg-zinc-100 p-2 dark:border-zinc-600 dark:bg-zinc-700">
<DocumentIcon className="h-5 w-5" role="img" />
</div>
<div className="ml-3 py-2">
@@ -61,7 +61,7 @@ export function SchemaList({
type: 'executor' | 'generator';
}): JSX.Element {
return (
<ul className="divide-y divide-slate-100 dark:divide-slate-800">
<ul className="divide-y divide-zinc-100 dark:divide-zinc-800">
{!!files.length ? (
files.map((schema) => (
<SchemaListItem key={schema.name} file={schema} />
@@ -77,9 +77,9 @@ function SchemaListItem({ file }: { file: FileMetadata }): JSX.Element {
return (
<li
key={file.name}
className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-50 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800/60"
className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-zinc-50 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800/60"
>
<div className="flex-shrink-0 self-start rounded-lg border-slate-200 bg-slate-100 p-2 dark:border-slate-600 dark:bg-slate-700">
<div className="flex-shrink-0 self-start rounded-lg border-zinc-200 bg-zinc-100 p-2 dark:border-zinc-600 dark:bg-zinc-700">
{file.type === 'executor' ? (
<CpuChipIcon className="h-5 w-5" role="img" />
) : (
@@ -99,7 +99,7 @@ function SchemaListItem({ file }: { file: FileMetadata }): JSX.Element {
</span>
)}
</p>
<div className="prose prose-slate dark:prose-invert prose-sm">
<div className="prose prose-zinc dark:prose-invert prose-sm">
{
renderMarkdown(file.description, {
filePath: '',
@@ -117,10 +117,10 @@ function EmptyList({
type: 'executor' | 'generator' | 'document';
}): JSX.Element {
return (
<li className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-50 dark:focus-within:ring-sky-500 dark:hover:bg-slate-800/60">
<div className="flex-shrink-0 self-start rounded-lg border-slate-200 bg-slate-100 p-2 dark:border-slate-600 dark:bg-slate-700">
<li className="relative flex px-2 py-2 transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-zinc-50 dark:focus-within:ring-blue-500 dark:hover:bg-zinc-800/60">
<div className="flex-shrink-0 self-start rounded-lg border-zinc-200 bg-zinc-100 p-2 dark:border-zinc-600 dark:bg-zinc-700">
<InformationCircleIcon
className="h-5 w-5 flex-shrink-0 rounded-md border-slate-200 bg-slate-50 dark:bg-slate-700 dark:bg-slate-800"
className="h-5 w-5 flex-shrink-0 rounded-md border-zinc-200 bg-zinc-50 dark:bg-zinc-700 dark:bg-zinc-800"
role="img"
/>
</div>
@@ -136,7 +136,7 @@ function EmptyList({
{type} available for this package yet!
</Link>
</p>
<div className="prose prose-slate dark:prose-invert prose-sm">
<div className="prose prose-zinc dark:prose-invert prose-sm">
<a
href="https://github.com/nrwl/nx/discussions"
target="_blank"
@@ -11,7 +11,7 @@ export function TopSchemaLayout({
<div className="mb-8 flex w-full items-center space-x-2">
<div className="w-full flex-grow">
<div
className="relative inline-flex rounded-md border border-slate-200 bg-slate-50 px-4 py-2 text-xs font-medium uppercase dark:border-slate-700 dark:bg-slate-800/60"
className="relative inline-flex rounded-md border border-zinc-200 bg-zinc-50 px-4 py-2 text-xs font-medium uppercase dark:border-zinc-700 dark:bg-zinc-800/60"
aria-hidden="true"
data-tooltip="Installable Package"
>
@@ -26,7 +26,7 @@ export function TopSchemaLayout({
rel="noreferrer"
aria-hidden="true"
title="See package on GitHub"
className="relative inline-flex items-center rounded-md border border-slate-200 bg-slate-50 px-4 py-2 text-xs font-medium dark:border-slate-700 dark:bg-slate-800/60"
className="relative inline-flex items-center rounded-md border border-zinc-200 bg-zinc-50 px-4 py-2 text-xs font-medium dark:border-zinc-700 dark:bg-zinc-800/60"
>
<svg
className="mr-2 h-4 w-4"
@@ -92,15 +92,15 @@ export function AlgoliaSearch({
type="button"
ref={searchButtonRef}
onClick={handleOpen}
className="flex w-full items-center rounded-md bg-white px-2 py-1.5 text-sm leading-4 ring-1 ring-slate-300 transition dark:bg-slate-700 dark:ring-slate-900"
className="flex w-full items-center rounded-md bg-white px-2 py-1.5 text-sm leading-4 ring-1 ring-zinc-300 transition dark:bg-zinc-700 dark:ring-zinc-900"
>
<MagnifyingGlassIcon className="h-4 w-4 flex-none" />
<span className="mx-3 inline-flex text-xs text-slate-300 md:text-sm dark:text-slate-400">
<span className="mx-3 inline-flex text-xs text-zinc-300 md:text-sm dark:text-zinc-400">
Search
</span>
<span
style={{ opacity: browserDetected ? '1' : '0' }}
className="ml-auto hidden flex-none rounded-md border border-slate-200 bg-slate-50 px-1 py-0.5 text-xs font-semibold text-slate-500 md:block dark:border-slate-700 dark:bg-slate-800/60"
className="ml-auto hidden flex-none rounded-md border border-zinc-200 bg-zinc-50 px-1 py-0.5 text-xs font-semibold text-zinc-500 md:block dark:border-zinc-700 dark:bg-zinc-800/60"
>
<span className="sr-only">Press </span>
<kbd className="font-sans">
@@ -122,7 +122,7 @@ export function AlgoliaSearch({
>
<span
style={{ opacity: browserDetected ? '1' : '0' }}
className="ml-auto block flex-none rounded-md border border-slate-200 bg-slate-50/60 px-1 py-0.5 text-xs font-semibold text-slate-400 transition hover:text-slate-500 dark:border-slate-700 dark:bg-slate-800/60 dark:text-slate-500 dark:hover:text-slate-400"
className="ml-auto block flex-none rounded-md border border-zinc-200 bg-zinc-50/60 px-1 py-0.5 text-xs font-semibold text-zinc-400 transition hover:text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-500 dark:hover:text-zinc-400"
>
<span className="sr-only">Press </span>
<kbd className="font-sans">
+1 -1
View File
@@ -119,7 +119,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
}}
/>
</head>
<body className="h-full bg-white text-slate-700 antialiased selection:bg-blue-500 selection:text-white dark:bg-slate-900 dark:text-slate-400 dark:selection:bg-sky-500">
<body className="h-full bg-white text-zinc-700 antialiased selection:bg-blue-500 selection:text-white dark:bg-zinc-900 dark:text-zinc-400 dark:selection:bg-blue-500">
<GlobalSearchHandler />
{children}
{bannerCollection.map((bannerConfig) => {
+7 -7
View File
@@ -15,7 +15,7 @@ interface ResourceCardProps {
function Hero(): JSX.Element {
return (
<section className="relative overflow-hidden py-16 dark:from-slate-900 dark:to-slate-950">
<section className="relative overflow-hidden py-16 dark:from-zinc-900 dark:to-zinc-950">
<div className="mx-auto max-w-3xl text-center">
<SectionHeading
as="h1"
@@ -27,7 +27,7 @@ function Hero(): JSX.Element {
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl text-xl text-slate-600 dark:text-slate-400"
className="mx-auto mt-6 max-w-3xl text-xl text-zinc-600 dark:text-zinc-400"
>
Learning Events Company
</SectionHeading>
@@ -41,8 +41,8 @@ function ResourceCard({ item }: ResourceCardProps) {
<a href={item.href} className="block h-full transform-gpu">
<div
className={cx(
'group relative h-full w-full overflow-hidden rounded-2xl border border-slate-200 bg-white p-8',
'dark:border-slate-800 dark:bg-slate-900 dark:hover:border-blue-900 dark:hover:shadow-blue-900/20',
'group relative h-full w-full overflow-hidden rounded-2xl border border-zinc-200 bg-white p-8',
'dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-blue-900 dark:hover:shadow-blue-900/20',
'before:absolute before:inset-0 before:z-0 before:bg-gradient-to-br before:from-blue-50 before:to-transparent before:opacity-0 before:transition-opacity',
'transition-all duration-300 ease-out',
'hover:-translate-y-2 hover:border-blue-200 hover:shadow-xl hover:shadow-blue-100/50',
@@ -51,15 +51,15 @@ function ResourceCard({ item }: ResourceCardProps) {
>
<div className="relative z-10">
{item.icon && (
<div className="mb-6 flex h-14 w-14 items-center justify-center rounded-xl bg-blue-50 group-hover:bg-blue-100 dark:bg-slate-800 dark:group-hover:bg-blue-900">
<div className="mb-6 flex h-14 w-14 items-center justify-center rounded-xl bg-blue-50 group-hover:bg-blue-100 dark:bg-zinc-800 dark:group-hover:bg-blue-900">
<item.icon className="h-8 w-8 text-blue-600 transition-transform duration-300 group-hover:scale-110 dark:text-blue-400" />
</div>
)}
<p className="text-xl font-medium text-slate-900 transition-colors duration-200 dark:text-slate-100">
<p className="text-xl font-medium text-zinc-900 transition-colors duration-200 dark:text-zinc-100">
{item.name}
</p>
{item.description && (
<p className="mt-3 text-slate-600 transition-colors duration-200 dark:text-slate-400">
<p className="mt-3 text-zinc-600 transition-colors duration-200 dark:text-zinc-400">
{item.description}
</p>
)}
+6 -1
View File
@@ -25,7 +25,8 @@ module.exports = withNx({
},
async rewrites() {
// Only configure rewrites if NEXT_PUBLIC_ASTRO_URL is set
const astroDocsUrl = process.env.NEXT_PUBLIC_ASTRO_URL;
// Remove trailing slash to prevent double slashes in rewrite destinations
const astroDocsUrl = process.env.NEXT_PUBLIC_ASTRO_URL?.replace(/\/$/, '');
if (!astroDocsUrl) {
// Skip rewrites if env var is not set
@@ -49,6 +50,10 @@ module.exports = withNx({
source: '/llms.txt',
destination: `${astroDocsUrl}/docs/llms.txt`,
},
{
source: '/llms-full.txt',
destination: `${astroDocsUrl}/docs/llms-full.txt`,
},
];
// For Vite assets only in development mode
+1 -1
View File
@@ -45,7 +45,7 @@ export function FourOhFour(): JSX.Element {
src={illustrationUrl}
className="drop-shadow"
/>
<h1 className="mt-4 text-4xl font-extrabold tracking-tight text-slate-900 sm:text-6xl lg:ml-8 dark:text-slate-100">
<h1 className="mt-4 text-4xl font-extrabold tracking-tight text-zinc-900 sm:text-6xl lg:ml-8 dark:text-zinc-100">
<span className="sr-only">404 - </span>Page not found!
</h1>
</div>
+1 -1
View File
@@ -22,7 +22,7 @@ export default function FiveOhOh(): JSX.Element {
src="/images/illustrations/500.svg"
className="drop-shadow"
/>
<h1 className="mt-4 text-4xl font-extrabold tracking-tight text-slate-900 sm:text-6xl lg:ml-8 dark:text-slate-100">
<h1 className="mt-4 text-4xl font-extrabold tracking-tight text-zinc-900 sm:text-6xl lg:ml-8 dark:text-zinc-100">
<div className="sr-only">500 - </div>Internal Server Error!
</h1>
</div>
+1 -1
View File
@@ -43,7 +43,7 @@ export default function Document(): ReactElement {
}}
/>
</Head>
<body className="h-full bg-white text-slate-700 antialiased selection:bg-blue-500 selection:text-white dark:bg-slate-900 dark:text-slate-400 dark:selection:bg-sky-500">
<body className="h-full bg-white text-zinc-700 antialiased selection:bg-blue-500 selection:text-white dark:bg-zinc-900 dark:text-zinc-400 dark:selection:bg-blue-500">
<Main />
<NextScript />
</body>
+7 -7
View File
@@ -225,7 +225,7 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
<Breadcrumbs path={router.asPath} />
</div>
<header className="mt-0">
<h1 className="text-3xl font-semibold tracking-tight text-slate-900 sm:text-5xl dark:text-slate-100">
<h1 className="text-3xl font-semibold tracking-tight text-zinc-900 sm:text-5xl dark:text-zinc-100">
Nx Changelog
</h1>
<p className="mt-4">
@@ -249,10 +249,10 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
'absolute left-0 top-0 hidden w-6 justify-center sm:flex'
)}
>
<div className="w-px bg-slate-200 dark:bg-slate-700" />
<div className="w-px bg-zinc-200 dark:bg-zinc-700" />
</div>
<div className="relative mt-1 hidden h-6 w-6 flex-none items-center justify-center sm:flex">
<div className="h-2 w-2 rounded-full bg-slate-100 ring-1 ring-slate-300 dark:bg-slate-600 dark:ring-slate-500" />
<div className="h-2 w-2 rounded-full bg-zinc-100 ring-1 ring-zinc-300 dark:bg-zinc-600 dark:ring-zinc-500" />
</div>
<div
id={changelog.version}
@@ -264,7 +264,7 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
href={`https://github.com/nrwl/nx/releases/tag/${changelog.version}`}
target="_blank"
rel="noreferrer"
className="text-xl font-medium leading-5 text-slate-900 hover:underline dark:text-slate-100"
className="text-xl font-medium leading-5 text-zinc-900 hover:underline dark:text-zinc-100"
>
<TagIcon
className="inline-flex h-4 w-4"
@@ -276,7 +276,7 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
<LinkIcon className="mb-1 ml-2 inline h-5 w-5 opacity-0 group-hover:opacity-100" />
</Link>
</p>
<p className="py-0.5 text-xs leading-5 text-slate-400 dark:text-slate-500">
<p className="py-0.5 text-xs leading-5 text-zinc-400 dark:text-zinc-500">
<time
dateTime={convertToDate(
changelog.date
@@ -288,7 +288,7 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
</div>
{/* CONTAINER */}
<div className="flex flex-grow flex-col gap-8 md:ml-12">
<div className="prose prose-slate dark:prose-invert max-w-none">
<div className="prose prose-zinc dark:prose-invert max-w-none">
{changelog.content}
</div>
{changelog.patches.length > 0 && (
@@ -299,7 +299,7 @@ export default function Changelog(props: ChangeLogProps): JSX.Element {
href={`https://github.com/nrwl/nx/releases/tag/${version}`}
target="_blank"
rel="noreferrer"
className="inline-flex items-center rounded-md bg-slate-50 px-2 py-1 text-xs font-medium text-slate-600 ring-1 ring-inset ring-slate-500/10 hover:underline dark:bg-slate-600/30 dark:text-slate-500 dark:ring-slate-700"
className="inline-flex items-center rounded-md bg-zinc-50 px-2 py-1 text-xs font-medium text-zinc-600 ring-1 ring-inset ring-zinc-500/10 hover:underline dark:bg-zinc-600/30 dark:text-zinc-500 dark:ring-zinc-700"
>
{version}
</a>
+2 -2
View File
@@ -60,7 +60,7 @@ export default function Community(): JSX.Element {
<div className="w-full">
<div
id="connect-with-us"
className="py-18 bg-slate-50 dark:bg-slate-800/40"
className="py-18 bg-zinc-50 dark:bg-zinc-800/40"
>
<ConnectWithUs />
</div>
@@ -81,7 +81,7 @@ export default function Community(): JSX.Element {
</SectionHeading>
</header>
<div className="mt-8 flex gap-16 font-normal">
<p className="max-w-xl text-lg text-slate-700 dark:text-slate-400">
<p className="max-w-xl text-lg text-zinc-700 dark:text-zinc-400">
These friendly people promote Nx in the community by
publishing content and sharing their expertise. They also
gather feedback from the community to help improve Nx.
+1 -1
View File
@@ -38,7 +38,7 @@ export function Company(): JSX.Element {
as="h2"
variant="subtitle"
id="trusted"
className="scroll-mt-24 font-medium tracking-tight text-slate-950 sm:text-3xl dark:text-white"
className="scroll-mt-24 font-medium tracking-tight text-zinc-950 sm:text-3xl dark:text-white"
>
Trusted by leading OSS projects and Fortune 500 companies.
</SectionHeading>
+1 -1
View File
@@ -18,7 +18,7 @@ export function Customers(): JSX.Element {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/contact/sales',
variant: 'primary',
variant: 'contrast',
size: 'small',
target: '_blank',
title: 'Book a demo',
+1 -1
View File
@@ -36,7 +36,7 @@ export function Enterprise(): ReactElement {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/enterprise/trial',
variant: 'primary',
variant: 'contrast',
size: 'small',
title: 'Request a free trial',
children: 'Request a free trial',
+1 -1
View File
@@ -43,7 +43,7 @@ export default function Index(): JSX.Element {
<div className="mt-32 lg:mt-56">
<Problem />
</div>
<div className="bg-white/50 bg-[url(/images/home/wave.svg)] bg-cover bg-center py-32 bg-blend-soft-light lg:py-56 dark:bg-slate-900/50 dark:bg-[url(/images/home/wave-dark.svg)] dark:bg-blend-darken">
<div className="bg-white/50 bg-[url(/images/home/wave.svg)] bg-cover bg-center py-32 bg-blend-soft-light lg:py-56 dark:bg-zinc-900/50 dark:bg-[url(/images/home/wave-dark.svg)] dark:bg-blend-darken">
<Solution />
</div>
@@ -21,7 +21,7 @@ export function EnterpriseSolutionsEngineering(): ReactElement {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/contact/sales',
variant: 'primary',
variant: 'contrast',
size: 'small',
title: 'Talk to our team',
children: 'Talk to our team',
+1 -1
View File
@@ -22,7 +22,7 @@ export function EnterpriseSolutionsLeadership(): ReactElement {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/contact/sales',
variant: 'primary',
variant: 'contrast',
size: 'small',
title: 'Talk to our team',
children: 'Talk to our team',
+1 -1
View File
@@ -22,7 +22,7 @@ export function EnterpriseSolutionsManagement(): ReactElement {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/contact/sales',
variant: 'primary',
variant: 'contrast',
size: 'small',
title: 'Talk to our team',
children: 'Talk to our team',
+1 -1
View File
@@ -22,7 +22,7 @@ export function EnterpriseSolutionsPlatform(): ReactElement {
const scrollCTAConfig: ButtonLinkProps[] = [
{
href: '/contact/sales',
variant: 'primary',
variant: 'contrast',
size: 'small',
title: 'Talk to our team',
children: 'Talk to our team',
+4 -4
View File
@@ -104,7 +104,7 @@ export function WhitePaperFastCI(): ReactElement {
</ButtonLink>
</div>
<figure className="mt-16 rounded-lg bg-slate-100 p-4 pl-8 dark:bg-slate-800">
<figure className="mt-16 rounded-lg bg-zinc-100 p-4 pl-8 dark:bg-zinc-800">
<blockquote className="text-base/7">
<p>
The decision to jump to Nx Cloud was really something
@@ -124,13 +124,13 @@ export function WhitePaperFastCI(): ReactElement {
<div className="font-semibold">
Justin Schwartzenberger
</div>
<div className="text-slate-500">
<div className="text-zinc-500">
Principal Software Engineer, SiriusXM
</div>
</div>
<SiriusxmAlternateIcon
aria-hidden="true"
className="ml-auto size-10 rounded text-[#0000EB] dark:bg-slate-200"
className="ml-auto size-10 rounded text-[#0000EB] dark:bg-zinc-200"
/>
</figcaption>
</figure>
@@ -156,7 +156,7 @@ export function WhitePaperFastCI(): ReactElement {
/>
</div>
</section>
<section className="flex-1 rounded-xl border border-slate-200 bg-white p-8 md:self-start dark:border-slate-800/40">
<section className="flex-1 rounded-xl border border-zinc-200 bg-white p-8 md:self-start dark:border-zinc-800/40">
<HubspotForm
region="na1"
portalId="2757427"
@@ -26,7 +26,7 @@ export function CallToAction(): ReactElement {
<svg
x="50%"
y={0}
className="overflow-visible fill-slate-200/20 dark:fill-slate-800/20"
className="overflow-visible fill-zinc-200/20 dark:fill-zinc-800/20"
>
<path
d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z"
@@ -57,7 +57,7 @@ export function CallToAction(): ReactElement {
{/* Content */}
<div className="mx-auto max-w-3xl text-center">
<h2 className="text-3xl font-medium tracking-tight text-slate-950 sm:text-5xl dark:text-white">
<h2 className="text-3xl font-medium tracking-tight text-zinc-950 sm:text-5xl dark:text-white">
Transform your AI assistant in minutes
</h2>
<div className="mt-10 flex items-center justify-center gap-x-6">
@@ -65,7 +65,7 @@ export function CallToAction(): ReactElement {
href={'/docs/features/enhance-ai#setting-up-nx-mcp'}
title="Get started with Nx AI integration"
prefetch={false}
className="rounded-md bg-slate-950 px-3.5 py-2.5 text-sm font-semibold text-slate-100 shadow-sm hover:bg-slate-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-slate-900 dark:hover:bg-slate-100"
className="rounded-md bg-zinc-950 px-3.5 py-2.5 text-sm font-semibold text-zinc-100 shadow-sm hover:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100"
>
Start here{' '}
<span
@@ -12,7 +12,7 @@ export function Features(): ReactElement {
Make your AI assistant workspace-aware
</SectionHeading>
<p className="mt-4 text-lg text-slate-500 dark:text-slate-400">
<p className="mt-4 text-lg text-zinc-500 dark:text-zinc-400">
Transform your LLM from context-blind to architecture-aware with
complete workspace intelligence.
</p>
@@ -276,8 +276,8 @@ function FeatureCard({
<a href={href} className="block h-full transform-gpu">
<div
className={cx(
'group relative h-full w-full overflow-hidden rounded-lg border border-slate-200 bg-white p-6',
'dark:border-slate-800 dark:bg-slate-900 dark:hover:border-blue-900 dark:hover:shadow-blue-900/20',
'group relative h-full w-full overflow-hidden rounded-lg border border-zinc-200 bg-white p-6',
'dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-blue-900 dark:hover:shadow-blue-900/20',
'before:absolute before:inset-0 before:z-0 before:bg-gradient-to-br before:from-blue-50 before:to-transparent before:opacity-0 before:transition-opacity',
'transition-all duration-300 ease-out',
'hover:-translate-y-2 hover:border-blue-200 hover:shadow-xl hover:shadow-blue-100/50',
@@ -285,11 +285,11 @@ function FeatureCard({
)}
>
<div className="relative z-10">
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-blue-50 text-blue-600 transition-transform duration-300 group-hover:scale-110 dark:bg-slate-800 dark:text-blue-400 dark:group-hover:bg-blue-900">
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-blue-50 text-blue-600 transition-transform duration-300 group-hover:scale-110 dark:bg-zinc-800 dark:text-blue-400 dark:group-hover:bg-blue-900">
{icon}
</div>
<h3 className="mb-2 text-lg font-medium">{title}</h3>
<p className="text-slate-500 dark:text-slate-400">{description}</p>
<p className="text-zinc-500 dark:text-zinc-400">{description}</p>
</div>
</div>
</a>
+5 -6
View File
@@ -197,7 +197,7 @@ export function Hero(): JSX.Element {
<div className="relative">
<div className="absolute bottom-0 start-0 -z-10 -translate-x-14 translate-y-10">
<svg
className="h-auto max-w-40 text-slate-200 dark:text-slate-800"
className="h-auto max-w-40 text-zinc-200 dark:text-zinc-800"
width="696"
height="653"
viewBox="0 0 696 653"
@@ -370,8 +370,7 @@ export function Hero(): JSX.Element {
{
'bg-blue-50 ring-2 ring-blue-500 dark:bg-blue-950/50 dark:ring-blue-400':
isSelected,
'hover:bg-slate-100 dark:hover:bg-slate-800':
!isSelected,
'hover:bg-zinc-100 dark:hover:bg-zinc-800': !isSelected,
}
)}
>
@@ -398,7 +397,7 @@ export function Hero(): JSX.Element {
'relative text-base font-medium leading-6 transition-colors',
isSelected
? 'text-blue-900 dark:text-blue-100'
: 'text-slate-900 group-hover:text-blue-600 dark:text-slate-100 dark:group-hover:text-blue-400'
: 'text-zinc-900 group-hover:text-blue-600 dark:text-zinc-100 dark:group-hover:text-blue-400'
)}
>
{feature.title}
@@ -420,7 +419,7 @@ export function Hero(): JSX.Element {
'mt-2 text-sm leading-6 transition-colors',
isSelected
? 'text-blue-700 dark:text-blue-200'
: 'text-slate-600 dark:text-slate-400'
: 'text-zinc-600 dark:text-zinc-400'
)}
>
{feature.description}
@@ -439,7 +438,7 @@ export function Hero(): JSX.Element {
>
<ButtonLink
href={'/docs/features/enhance-ai#setting-up-nx-mcp'}
variant="primary"
variant="contrast"
size="default"
title="Enhance your AI assistant"
onClick={() =>
@@ -27,7 +27,7 @@ export function AiHero(): ReactElement {
<ButtonLink
href={'/docs/getting-started/ai-setup'}
title="Nx AI Integration"
variant="primary"
variant="contrast"
size="small"
>
Integrate Nx with your Coding Assistant
@@ -36,7 +36,7 @@ export function AiHero(): ReactElement {
<div className="mt-8 flex flex-wrap items-center gap-4">
<a
href="#while-coding"
className="inline-flex items-center gap-1.5 rounded-full bg-slate-100 px-2 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"
className="inline-flex items-center gap-1.5 rounded-full bg-zinc-100 px-2 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700"
aria-label="Jump to While Coding section"
>
<CodeBracketIcon aria-hidden="true" className="size-4 shrink-0" />
@@ -44,7 +44,7 @@ export function AiHero(): ReactElement {
</a>
<a
href="#while-running-ci"
className="inline-flex items-center gap-1.5 rounded-full bg-slate-100 px-2 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"
className="inline-flex items-center gap-1.5 rounded-full bg-zinc-100 px-2 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700"
aria-label="Jump to While Running CI section"
>
<ServerStackIcon aria-hidden="true" className="size-4 shrink-0" />
@@ -52,7 +52,7 @@ export function AiHero(): ReactElement {
</a>
<a
href="#while-scaling-your-organization"
className="inline-flex items-center gap-1.5 rounded-full bg-slate-100 px-2 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"
className="inline-flex items-center gap-1.5 rounded-full bg-zinc-100 px-2 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-200 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700"
aria-label="Jump to Scaling Your Organization section"
>
<UserGroupIcon aria-hidden="true" className="size-4 shrink-0" />
@@ -50,7 +50,7 @@ export function FeatureCard({
return (
<div key={id} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="relative mb-6 aspect-video max-h-52 w-full overflow-hidden rounded-xl bg-slate-200 dark:bg-slate-700/60">
<div className="relative mb-6 aspect-video max-h-52 w-full overflow-hidden rounded-xl bg-zinc-200 dark:bg-zinc-700/60">
<Image
src={imageUrl}
alt={`Thumbnail for ${title}`}
@@ -32,7 +32,7 @@ export function NxPowerAi({
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
@@ -48,7 +48,7 @@ export function NxPowerAi({
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="invisible aspect-square" />
@@ -57,7 +57,7 @@ export function NxPowerAi({
<li className="flex aspect-square translate-x-1/2 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="relative isolate flex aspect-square h-20 translate-x-1/2 items-center justify-center">
@@ -83,7 +83,7 @@ export function NxPowerAi({
<li className="flex aspect-square translate-x-1/2 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="invisible"></li>
@@ -93,7 +93,7 @@ export function NxPowerAi({
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
@@ -109,7 +109,7 @@ export function NxPowerAi({
<li className="relative isolate flex aspect-square h-20 items-center justify-center">
<HexagonShape
aria-hidden="true"
className="absolute inset-0 z-0 text-slate-50/90 drop-shadow-sm dark:text-white/5"
className="absolute inset-0 z-0 text-zinc-50/90 drop-shadow-sm dark:text-white/5"
/>
</li>
<li className="invisible" />
@@ -119,20 +119,20 @@ export function NxPowerAi({
{/* Steps List */}
<div className="relative mt-12 space-y-2">
{/* Active Step */}
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 shadow-sm backdrop-blur-sm dark:border-slate-800/40 dark:bg-slate-800/60">
<div className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 shadow-sm backdrop-blur-sm dark:border-zinc-800/40 dark:bg-zinc-800/60">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-slate-200 to-slate-300 dark:border-slate-900 dark:from-slate-700 dark:to-slate-800">
<div className="size-2 rounded-full bg-white dark:bg-slate-900" />
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-zinc-200 to-zinc-300 dark:border-zinc-900 dark:from-zinc-700 dark:to-zinc-800">
<div className="size-2 rounded-full bg-white dark:bg-zinc-900" />
</div>
<div className="flex-1">
<p className="font-mono text-xs leading-tight text-slate-900 dark:text-slate-100">
<p className="font-mono text-xs leading-tight text-zinc-900 dark:text-zinc-100">
Generating a fix for test "ui-profile:test:save-preferences"
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<span className="text-xs text-slate-600 dark:text-slate-400">
<span className="text-xs text-zinc-600 dark:text-zinc-400">
Working...
</span>
<span className="relative flex size-1.5">
@@ -144,20 +144,20 @@ export function NxPowerAi({
</div>
{/* Completed Step */}
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 opacity-50 shadow-sm backdrop-blur-sm dark:border-slate-800/40 dark:bg-slate-800/60">
<div className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 opacity-50 shadow-sm backdrop-blur-sm dark:border-zinc-800/40 dark:bg-zinc-800/60">
<div className="flex items-center justify-between gap-4">
<div className="flex grow items-center space-x-3">
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-slate-200 to-slate-300 dark:border-slate-900 dark:from-slate-700 dark:to-slate-800">
<div className="size-2 rounded-full bg-white dark:bg-slate-900" />
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-zinc-200 to-zinc-300 dark:border-zinc-900 dark:from-zinc-700 dark:to-zinc-800">
<div className="size-2 rounded-full bg-white dark:bg-zinc-900" />
</div>
<div className="w-full grow space-y-1">
<div className="h-1 w-8 rounded-sm bg-slate-800/15 dark:bg-slate-200/35" />
<div className="h-1 w-1/2 rounded-sm bg-slate-500/10 dark:bg-slate-400/35" />
<div className="h-1 w-8 rounded-sm bg-zinc-800/15 dark:bg-zinc-200/35" />
<div className="h-1 w-1/2 rounded-sm bg-zinc-500/10 dark:bg-zinc-400/35" />
</div>
</div>
<div className="flex items-center space-x-2">
<span className="text-xs text-slate-600 dark:text-slate-300">
<span className="text-xs text-zinc-600 dark:text-zinc-300">
Done
</span>
<div className="size-1.5 rounded-full bg-green-500 shadow-sm" />
@@ -166,13 +166,13 @@ export function NxPowerAi({
</div>
{/* Pending Step */}
<div className="rounded-xl border border-slate-200 bg-slate-50 p-4 opacity-40 shadow-sm backdrop-blur-sm dark:border-slate-800/40 dark:bg-slate-800/60">
<div className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 opacity-40 shadow-sm backdrop-blur-sm dark:border-zinc-800/40 dark:bg-zinc-800/60">
<div className="flex items-center space-x-3">
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-slate-200 to-slate-300 dark:border-slate-900 dark:from-slate-700 dark:to-slate-800">
<div className="size-2 rounded-full bg-white dark:bg-slate-900" />
<div className="flex size-5 items-center justify-center rounded-full border border-white/25 bg-gradient-to-br from-zinc-200 to-zinc-300 dark:border-zinc-900 dark:from-zinc-700 dark:to-zinc-800">
<div className="size-2 rounded-full bg-white dark:bg-zinc-900" />
</div>
<div className="flex-1">
<div className="h-1 w-16 rounded-sm bg-slate-400/20" />
<div className="h-1 w-16 rounded-sm bg-zinc-400/20" />
</div>
</div>
</div>
@@ -57,7 +57,7 @@ export function PlayButton({
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-zinc-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
@@ -100,7 +100,7 @@ export function WhileCoding(): ReactElement {
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="max-w-2xl">
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-sky-500" />
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-blue-500" />
<SectionHeading as="h2" variant="title" id="while-coding-title">
While Coding
</SectionHeading>
@@ -65,7 +65,7 @@ export function WhileRunningCi(): ReactElement {
const [openVideoUrl, setOpenVideoUrl] = useState<string | null>(null);
return (
<div className="relative bg-slate-50 py-32 dark:bg-slate-800">
<div className="relative bg-zinc-50 py-32 dark:bg-zinc-800">
<div
id="while-running-ci"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
@@ -15,7 +15,7 @@ export function ProblemStatement({
Your AI assistant is blind to your workspace architecture
</SectionHeading>
<p className="mt-4 text-lg text-slate-500 dark:text-slate-400">
<p className="mt-4 text-lg text-zinc-500 dark:text-zinc-400">
As monorepos scale, AI tools become progressively less effective
without true workspace understanding.
</p>
@@ -24,7 +24,7 @@ export function ProblemStatement({
<div className="grid grid-cols-1 gap-x-8 gap-y-4 md:grid-cols-2">
{/* Left Column - Problems */}
<div>
<h3 className="mb-3 text-lg font-bold text-slate-900 dark:text-white">
<h3 className="mb-3 text-lg font-bold text-zinc-900 dark:text-white">
The challenges
</h3>
@@ -50,10 +50,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Limited context
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
LLMs only see individual files, missing the architectural
relationships in large monorepos.
</p>
@@ -77,10 +77,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Inconsistent output
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
AI generates code that doesn't follow team standards or may
break components it can't see.
</p>
@@ -106,10 +106,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
No workspace awareness
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
AI can't understand project dependencies, ownership, or
cross-project integration points.
</p>
@@ -136,10 +136,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Manual context burden
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
Developers must repeatedly provide the same contextual
information about project structure.
</p>
@@ -150,7 +150,7 @@ export function ProblemStatement({
{/* Right Column - Solutions */}
<div>
<h3 className="mb-3 text-lg font-bold text-slate-900 dark:text-white">
<h3 className="mb-3 text-lg font-bold text-zinc-900 dark:text-white">
How Nx helps
</h3>
@@ -176,10 +176,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Architectural awareness
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
Move from file-level to workspace-level understanding with
rich project relationship metadata.
</p>
@@ -203,10 +203,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Predictable + intelligent
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
Combine consistent generators with AI customization that
follows team standards.
</p>
@@ -241,10 +241,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Integrated workflows
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
Connect editor, terminal, CI, and AI for truly context-aware
assistance across your entire workspace.
</p>
@@ -290,10 +290,10 @@ export function ProblemStatement({
</svg>
</div>
<div>
<h4 className="mb-1 text-sm font-medium leading-tight text-slate-900 dark:text-slate-100">
<h4 className="mb-1 text-sm font-medium leading-tight text-zinc-900 dark:text-zinc-100">
Up-to-Date Documentation
</h4>
<p className="text-sm text-slate-600 dark:text-slate-300">
<p className="text-sm text-zinc-600 dark:text-zinc-300">
Access current docs and best practices for accurate,
workspace-specific guidance.
</p>
@@ -13,7 +13,7 @@ export function TechnicalImplementation({
}: TechnicalImplementationProps): JSX.Element {
return (
<section
className={`bg-gradient-to-b from-white to-slate-50 py-12 dark:from-slate-900 dark:to-slate-800 ${
className={`bg-gradient-to-b from-white to-zinc-50 py-12 dark:from-zinc-900 dark:to-zinc-800 ${
className || ''
}`}
>
@@ -21,7 +21,7 @@ export function TechnicalImplementation({
<div className="mb-12 grid grid-cols-1 gap-8 md:grid-cols-2 lg:gap-12">
{/* Left Side - Title and How It Works */}
<div className="flex flex-col justify-center">
<h2 className="mb-8 text-left text-3xl font-bold text-slate-900 md:text-4xl dark:text-white">
<h2 className="mb-8 text-left text-3xl font-bold text-zinc-900 md:text-4xl dark:text-white">
Powered by Nx workspace intelligence
</h2>
@@ -31,7 +31,7 @@ export function TechnicalImplementation({
<span className="text-lg font-semibold">1</span>
</div>
<div className="flex-1 pt-1">
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
Nx daemon runs in the background, maintaining up-to-date
workspace metadata
</p>
@@ -43,7 +43,7 @@ export function TechnicalImplementation({
<span className="text-lg font-semibold">2</span>
</div>
<div className="flex-1 pt-1">
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
This rich contextual data is processed and optimized for AI
consumption
</p>
@@ -55,7 +55,7 @@ export function TechnicalImplementation({
<span className="text-lg font-semibold">3</span>
</div>
<div className="flex-1 pt-1">
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
Nx Console exposes the data to your AI assistant via an MCP
</p>
</div>
@@ -82,16 +82,16 @@ export function TechnicalImplementation({
{/* Flow diagram with connected boxes */}
<div className="grid grid-cols-1 gap-6 md:grid-cols-3 lg:gap-8">
{/* Nx Console Box */}
<div className="relative rounded-xl border border-slate-200 bg-slate-50 p-6 shadow-md dark:border-slate-700 dark:bg-slate-800/50">
<div className="relative rounded-xl border border-zinc-200 bg-zinc-50 p-6 shadow-md dark:border-zinc-700 dark:bg-zinc-800/50">
<div className="mb-4 flex items-center">
<div className="mr-4 flex h-16 w-16 flex-shrink-0 items-center justify-center rounded-full bg-blue-500 text-white">
<NxConsoleSmallIcon className="h-24 w-24" />
</div>
<h4 className="text-xl font-bold text-slate-900 dark:text-white">
<h4 className="text-xl font-bold text-zinc-900 dark:text-white">
Start with Nx Console
</h4>
</div>
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
Install the Nx Console Extension, available for VSCode, Cursor,
and IntelliJ.
</p>
@@ -132,16 +132,16 @@ export function TechnicalImplementation({
</div>
{/* MCP Box */}
<div className="relative rounded-xl border border-slate-200 bg-slate-50 p-6 shadow-md dark:border-slate-700 dark:bg-slate-800/50">
<div className="relative rounded-xl border border-zinc-200 bg-zinc-50 p-6 shadow-md dark:border-zinc-700 dark:bg-zinc-800/50">
<div className="mb-4 flex items-center">
<div className="mr-4 flex h-16 w-16 flex-shrink-0 items-center justify-center rounded-full bg-indigo-500 text-white">
<ModelContextProtocolIcon className="h-8 w-8" />
</div>
<h4 className="text-xl font-bold text-slate-900 dark:text-white">
<h4 className="text-xl font-bold text-zinc-900 dark:text-white">
Nx MCP
</h4>
</div>
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
Nx Console automatically registers its MCP server or you can
configure it in any MCP compatible client.
</p>
@@ -182,7 +182,7 @@ export function TechnicalImplementation({
</div>
{/* Enhanced LLM Workflow Box */}
<div className="rounded-xl border border-slate-200 bg-slate-50 p-6 shadow-md dark:border-slate-700 dark:bg-slate-800/50">
<div className="rounded-xl border border-zinc-200 bg-zinc-50 p-6 shadow-md dark:border-zinc-700 dark:bg-zinc-800/50">
<div className="mb-4 flex items-center">
<div className="mr-4 flex h-16 w-16 flex-shrink-0 items-center justify-center rounded-full bg-blue-600 text-white">
<svg
@@ -200,11 +200,11 @@ export function TechnicalImplementation({
/>
</svg>
</div>
<h4 className="text-xl font-bold text-slate-900 dark:text-white">
<h4 className="text-xl font-bold text-zinc-900 dark:text-white">
Enhanced LLM workflow
</h4>
</div>
<p className="text-slate-600 dark:text-slate-300">
<p className="text-zinc-600 dark:text-zinc-300">
Your existing AI tools understand your workspace architecture
without changing your development habits.
</p>
+2 -2
View File
@@ -8,7 +8,7 @@ interface AuthorDetailProps {
export default function AuthorDetail({ author }: AuthorDetailProps) {
return (
<div className="space-between invisible absolute left-[65%] right-0 z-30 mt-2 flex w-60 translate-x-[-50%] items-center gap-4 rounded bg-slate-50 p-4 text-sm text-slate-700 opacity-0 shadow-lg ring-1 ring-slate-200 transition-all delay-75 duration-300 ease-in-out md:group-hover:visible md:group-hover:opacity-100 dark:bg-slate-900 dark:text-slate-400 dark:ring-slate-800">
<div className="space-between invisible absolute left-[65%] right-0 z-30 mt-2 flex w-60 translate-x-[-50%] items-center gap-4 rounded bg-zinc-50 p-4 text-sm text-zinc-700 opacity-0 shadow-lg ring-1 ring-zinc-200 transition-all delay-75 duration-300 ease-in-out md:group-hover:visible md:group-hover:opacity-100 dark:bg-zinc-900 dark:text-zinc-400 dark:ring-zinc-800">
<span>
<Image
alt={author.name}
@@ -18,7 +18,7 @@ export default function AuthorDetail({ author }: AuthorDetailProps) {
height="40"
decoding="async"
src={`/documentation/blog/images/authors/${author.name}.jpeg`}
className="rounded-full ring-1 ring-white grayscale dark:ring-slate-900"
className="rounded-full ring-1 ring-white grayscale dark:ring-zinc-900"
/>
</span>
<span className="text-balance">{author.name}</span>
+1 -1
View File
@@ -21,7 +21,7 @@ export function BlogAuthors({
height="48"
decoding="async"
src={`/documentation/blog/images/authors/${author.name}.jpeg`}
className="relative inline-block h-6 w-6 rounded-full ring-1 ring-white grayscale dark:ring-slate-900"
className="relative inline-block h-6 w-6 rounded-full ring-1 ring-white grayscale dark:ring-zinc-900"
/>
{showAuthorDetails && <AuthorDetail author={author} />}
</div>
+4 -4
View File
@@ -77,7 +77,7 @@ export function BlogContainer({ blogPosts, tags }: BlogContainerProps) {
<header className="mb-8 mt-20">
<h1
id="blog-title"
className="text-xl font-semibold tracking-tight text-slate-900 md:text-2xl dark:text-slate-100"
className="text-xl font-semibold tracking-tight text-zinc-900 md:text-2xl dark:text-zinc-100"
>
{selectedFilterHeading}
</h1>
@@ -100,7 +100,7 @@ export function BlogContainer({ blogPosts, tags }: BlogContainerProps) {
<FeaturedBlogs blogs={firstFiveBlogs} />
{!!remainingBlogs.length && (
<>
<div className="mx-auto mb-8 mt-20 flex items-center justify-between border-b-2 border-slate-300 pb-3 text-sm dark:border-slate-700">
<div className="mx-auto mb-8 mt-20 flex items-center justify-between border-b-2 border-zinc-300 pb-3 text-sm dark:border-zinc-700">
<h2 className="font-semibold">All blogs</h2>
<div className="flex gap-2">
<Link
@@ -108,14 +108,14 @@ export function BlogContainer({ blogPosts, tags }: BlogContainerProps) {
aria-label="RSS feed"
prefetch={false}
>
<RssIcon className="h-5 w-5 text-slate-600 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" />
<RssIcon className="h-5 w-5 text-zinc-600 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200" />
</Link>
<Link
href="/blog/atom.xml"
aria-label="Atom feed"
prefetch={false}
>
<AtSymbolIcon className="h-5 w-5 text-slate-600 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" />
<AtSymbolIcon className="h-5 w-5 text-zinc-600 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200" />
</Link>
</div>
</div>
+6 -6
View File
@@ -48,7 +48,7 @@ export function BlogDetails({ post, allPosts }: BlogDetailsProps) {
<div className="mx-auto flex justify-between px-4">
<Link
href="/blog"
className="flex w-20 shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
className="flex w-20 shrink-0 items-center gap-2 text-zinc-400 hover:text-zinc-800 dark:text-zinc-600 dark:hover:text-zinc-200"
prefetch={false}
>
<ChevronLeftIcon className="h-3 w-3" />
@@ -56,7 +56,7 @@ export function BlogDetails({ post, allPosts }: BlogDetailsProps) {
</Link>
<div className="flex max-w-sm flex-1 grow items-center justify-end gap-2">
<BlogAuthors authors={post.authors} />
<span className="text-sm text-slate-400 dark:text-slate-600">
<span className="text-sm text-zinc-400 dark:text-zinc-600">
{formattedDate}
</span>
</div>
@@ -64,7 +64,7 @@ export function BlogDetails({ post, allPosts }: BlogDetailsProps) {
{/* Title */}
<header className="mx-auto mb-16 mt-8 px-4">
<h1 className="text-center text-4xl font-semibold text-slate-900 dark:text-white">
<h1 className="text-center text-4xl font-semibold text-zinc-900 dark:text-white">
{post.title}
</h1>
</header>
@@ -120,7 +120,7 @@ export function BlogDetails({ post, allPosts }: BlogDetailsProps) {
)}
<div
data-document="main"
className="prose prose-lg prose-slate dark:prose-invert w-full max-w-none"
className="prose prose-lg prose-zinc dark:prose-invert w-full max-w-none"
>
{node}
</div>
@@ -137,10 +137,10 @@ export function BlogDetails({ post, allPosts }: BlogDetailsProps) {
{/* Related Posts Section */}
{post.tags.length > 0 && relatedPosts.length > 0 && (
<section className="mt-24 border-b border-t border-slate-200 bg-slate-50 py-24 sm:py-32 dark:border-slate-800 dark:bg-slate-900">
<section className="mt-24 border-b border-t border-zinc-200 bg-zinc-50 py-24 sm:py-32 dark:border-zinc-800 dark:bg-zinc-900">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-none">
<h2 className="mb-8 flex items-center gap-3 text-2xl font-semibold text-slate-900 dark:text-white">
<h2 className="mb-8 flex items-center gap-3 text-2xl font-semibold text-zinc-900 dark:text-white">
{primaryTopic ? (
<>
<primaryTopic.icon className="h-7 w-7" />
+2 -2
View File
@@ -10,7 +10,7 @@ export interface BlogEntryProps {
export function BlogEntry({ post, overrideLink }: BlogEntryProps) {
return (
<div className="relative flex h-full transform-gpu flex-col overflow-hidden rounded-2xl border border-slate-200 shadow transition-all duration-300 ease-in-out hover:scale-[1.02] hover:shadow-lg dark:border-slate-800">
<div className="relative flex h-full transform-gpu flex-col overflow-hidden rounded-2xl border border-zinc-200 shadow transition-all duration-300 ease-in-out hover:scale-[1.02] hover:shadow-lg dark:border-zinc-800">
{post.cover_image && (
<div className="aspect-[1.7] w-full">
<Image
@@ -28,7 +28,7 @@ export function BlogEntry({ post, overrideLink }: BlogEntryProps) {
<Link
href={overrideLink ? overrideLink : `/blog/${post.slug}`}
title={post.title}
className="text-balance text-lg font-semibold text-slate-900 dark:text-white"
className="text-balance text-lg font-semibold text-zinc-900 dark:text-white"
prefetch={false}
>
<span className="absolute inset-0" aria-hidden="true" />
+3 -3
View File
@@ -65,13 +65,13 @@ export function EpisodePlayer({
</div>
<div className="flex basis-1/2 flex-wrap justify-end gap-6 sm:gap-4">
<button
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
className="flex shrink-0 items-center gap-2 text-zinc-400 hover:text-zinc-800 dark:text-zinc-600 dark:hover:text-zinc-200"
onClick={() => setViewType(getOpposite(viewType))}
>
Switch to {getOpposite(viewType) === 'audio' ? 'Audio' : 'Video'}
</button>
<Link
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
className="flex shrink-0 items-center gap-2 text-zinc-400 hover:text-zinc-800 dark:text-zinc-600 dark:hover:text-zinc-200"
href="/podcast"
>
More Podcasts
@@ -124,7 +124,7 @@ export function PlatformLinks({
return (
<li
key={platform.name}
className="inline-block cursor-pointer place-items-center rounded-2xl border border-slate-100 bg-white p-4 text-slate-600 transition-all hover:scale-[1.02] hover:text-slate-950 dark:border-slate-800/60 dark:bg-slate-950 dark:text-slate-400 dark:hover:text-white"
className="inline-block cursor-pointer place-items-center rounded-2xl border border-zinc-100 bg-white p-4 text-zinc-600 transition-all hover:scale-[1.02] hover:text-zinc-950 dark:border-zinc-800/60 dark:bg-zinc-950 dark:text-zinc-400 dark:hover:text-white"
>
<a
href={platform.url}
+3 -3
View File
@@ -85,7 +85,7 @@ export function Filters({
aria-label={`Filter by ${filter.label}`}
scroll={false}
prefetch={false}
className="flex items-center justify-center gap-2 rounded-full border border-slate-400 bg-white px-2.5 py-1.5 font-medium text-slate-700 shadow-sm transition hover:bg-slate-50 hover:text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-700"
className="flex items-center justify-center gap-2 rounded-full border border-zinc-400 bg-white px-2.5 py-1.5 font-medium text-zinc-700 shadow-sm transition hover:bg-zinc-50 hover:text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
onClick={() => setSelectedFilterHeading(filter.heading)}
>
{filter.icon && (
@@ -101,7 +101,7 @@ export function Filters({
<div className="relative lg:hidden">
<Menu as="div" className="inline-block text-left">
<MenuButton
className="inline-flex w-full justify-center rounded-md border border-slate-400 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 shadow-sm transition hover:bg-slate-50 hover:text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-700"
className="inline-flex w-full justify-center rounded-md border border-zinc-400 bg-white px-3 py-1.5 text-sm font-medium text-zinc-700 shadow-sm transition hover:bg-zinc-50 hover:text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
aria-label="Select filter topic"
>
Topics
@@ -121,7 +121,7 @@ export function Filters({
>
<MenuItems
as="ul"
className="absolute right-0 z-[31] mt-2 flex w-56 origin-top-right flex-col gap-4 rounded-md bg-white p-4 shadow-lg ring-1 ring-black/5 focus:outline-none dark:bg-slate-800 dark:text-white"
className="absolute right-0 z-[31] mt-2 flex w-56 origin-top-right flex-col gap-4 rounded-md bg-white p-4 shadow-lg ring-1 ring-black/5 focus:outline-none dark:bg-zinc-800 dark:text-white"
aria-label="Filter topics"
>
{filters
+2 -2
View File
@@ -24,10 +24,10 @@ export function MoreBlogs({ blogs }: MoreBlogsProps) {
<Link
href={`/blog/${post.slug}`}
key={post.slug}
className="relative flex items-center gap-6 border-b border-slate-200 py-5 text-sm before:absolute before:inset-x-[-16px] before:inset-y-[-2px] before:z-[-1] before:rounded-xl before:bg-slate-200 before:opacity-0 last:border-0 before:hover:opacity-100 dark:border-slate-800 dark:before:bg-slate-800/50"
className="relative flex items-center gap-6 border-b border-zinc-200 py-5 text-sm before:absolute before:inset-x-[-16px] before:inset-y-[-2px] before:z-[-1] before:rounded-xl before:bg-zinc-200 before:opacity-0 last:border-0 before:hover:opacity-100 dark:border-zinc-800 dark:before:bg-zinc-800/50"
prefetch={false}
>
<span className="w-1/2 flex-none text-balance font-medium text-slate-500 sm:w-5/12 dark:text-white">
<span className="w-1/2 flex-none text-balance font-medium text-zinc-500 sm:w-5/12 dark:text-white">
{post.title}
</span>
<span className="w-1/2 flex-none sm:w-3/12">
+6 -6
View File
@@ -26,13 +26,13 @@ export function LernaBrand() {
in a way that confuses Nrwl with another brand.
</SectionDescription>
</header>
<h4 className="mt-4 text-lg leading-8 text-slate-700 sm:text-xl dark:text-slate-300">
<h4 className="mt-4 text-lg leading-8 text-zinc-700 sm:text-xl dark:text-zinc-300">
Spelling
</h4>
<p className="mt-2 text-base text-slate-700 dark:text-slate-400">
<p className="mt-2 text-base text-zinc-700 dark:text-zinc-400">
The preferred written format is Lerna. <br /> For social media
usage,
<span className="mx-1 inline-flex items-center rounded-full bg-slate-100 px-3 py-0.5 text-sm font-medium text-slate-800 dark:bg-slate-700 dark:text-slate-300">
<span className="mx-1 inline-flex items-center rounded-full bg-zinc-100 px-3 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-700 dark:text-zinc-300">
#Lerna
</span>{' '}
is an accepted format.
@@ -53,9 +53,9 @@ export function LernaBrand() {
</ButtonLink>
</div>
<div aria-hidden="true">
<div className="w-full rounded-md border border-slate-100 bg-slate-50/20 p-4 dark:border-slate-800 dark:bg-slate-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-slate-50 dark:bg-slate-800/80 dark:ring-slate-800">
<LernaIcon className="m-16 h-36 w-36 text-slate-900 dark:text-slate-100" />
<div className="w-full rounded-md border border-zinc-100 bg-zinc-50/20 p-4 dark:border-zinc-800 dark:bg-zinc-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-zinc-50 dark:bg-zinc-800/80 dark:ring-zinc-800">
<LernaIcon className="m-16 h-36 w-36 text-zinc-900 dark:text-zinc-100" />
</div>
</div>
</div>
+6 -6
View File
@@ -26,12 +26,12 @@ export function NxBrand() {
a way that confuses Nx with another brand.
</SectionDescription>
</header>
<h4 className="mt-4 text-lg leading-8 text-slate-700 sm:text-xl dark:text-slate-300">
<h4 className="mt-4 text-lg leading-8 text-zinc-700 sm:text-xl dark:text-zinc-300">
Spelling
</h4>
<p className="mt-2 text-base text-slate-700 dark:text-slate-400">
<p className="mt-2 text-base text-zinc-700 dark:text-zinc-400">
The preferred written format is Nx. <br /> For social media usage,
<span className="mx-1 inline-flex items-center rounded-full bg-slate-100 px-3 py-0.5 text-sm font-medium text-slate-800 dark:bg-slate-700 dark:text-slate-300">
<span className="mx-1 inline-flex items-center rounded-full bg-zinc-100 px-3 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-700 dark:text-zinc-300">
#NxDevTools
</span>{' '}
is an accepted format.
@@ -51,9 +51,9 @@ export function NxBrand() {
</ButtonLink>
</div>
<div aria-hidden="true">
<div className="w-full rounded-md border border-slate-100 bg-slate-50/20 p-4 dark:border-slate-800 dark:bg-slate-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-slate-50 dark:bg-slate-800/80 dark:ring-slate-800">
<NxIcon className="m-20 h-28 w-28 text-slate-900 dark:text-slate-100" />
<div className="w-full rounded-md border border-zinc-100 bg-zinc-50/20 p-4 dark:border-zinc-800 dark:bg-zinc-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-zinc-50 dark:bg-zinc-800/80 dark:ring-zinc-800">
<NxIcon className="m-20 h-28 w-28 text-zinc-900 dark:text-zinc-100" />
</div>
</div>
</div>
+6 -6
View File
@@ -26,13 +26,13 @@ export function NxCloudBrand() {
a way that confuses Nx with another brand.
</SectionDescription>
</header>
<h4 className="mt-4 text-lg leading-8 text-slate-700 sm:text-xl dark:text-slate-300">
<h4 className="mt-4 text-lg leading-8 text-zinc-700 sm:text-xl dark:text-zinc-300">
Spelling
</h4>
<p className="mt-2 text-base text-slate-700 dark:text-slate-400">
<p className="mt-2 text-base text-zinc-700 dark:text-zinc-400">
The preferred written format is Nx Cloud. <br /> For social media
usage,
<span className="mx-1 inline-flex items-center rounded-full bg-slate-100 px-3 py-0.5 text-sm font-medium text-slate-800 dark:bg-slate-700 dark:text-slate-300">
<span className="mx-1 inline-flex items-center rounded-full bg-zinc-100 px-3 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-700 dark:text-zinc-300">
#NxCloud
</span>{' '}
is an accepted format.
@@ -53,9 +53,9 @@ export function NxCloudBrand() {
</ButtonLink>
</div>
<div aria-hidden="true">
<div className="w-full rounded-md border border-slate-100 bg-slate-50/20 p-4 dark:border-slate-800 dark:bg-slate-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-slate-50 dark:bg-slate-800/80 dark:ring-slate-800">
<NxCloudIcon className="m-20 h-28 w-28 text-slate-900 dark:text-slate-100" />
<div className="w-full rounded-md border border-zinc-100 bg-zinc-50/20 p-4 dark:border-zinc-800 dark:bg-zinc-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-zinc-50 dark:bg-zinc-800/80 dark:ring-zinc-800">
<NxCloudIcon className="m-20 h-28 w-28 text-zinc-900 dark:text-zinc-100" />
</div>
</div>
</div>
@@ -26,13 +26,13 @@ export function NxConsoleBrand() {
Nx, or in a way that confuses Nx with another brand.
</SectionDescription>
</header>
<h4 className="mt-4 text-lg leading-8 text-slate-700 sm:text-xl dark:text-slate-300">
<h4 className="mt-4 text-lg leading-8 text-zinc-700 sm:text-xl dark:text-zinc-300">
Spelling
</h4>
<p className="mt-2 text-base text-slate-700 dark:text-slate-400">
<p className="mt-2 text-base text-zinc-700 dark:text-zinc-400">
The preferred written format is Nx Console. <br /> For social media
usage,
<span className="mx-1 inline-flex items-center rounded-full bg-slate-100 px-3 py-0.5 text-sm font-medium text-slate-800 dark:bg-slate-700 dark:text-slate-300">
<span className="mx-1 inline-flex items-center rounded-full bg-zinc-100 px-3 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-700 dark:text-zinc-300">
#NxConsole
</span>{' '}
is an accepted format.
@@ -53,9 +53,9 @@ export function NxConsoleBrand() {
</ButtonLink>
</div>
<div aria-hidden="true">
<div className="w-full rounded-md border border-slate-100 bg-slate-50/20 p-4 dark:border-slate-800 dark:bg-slate-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-slate-50 dark:bg-slate-800/80 dark:ring-slate-800">
<NxConsoleIcon className="m-16 h-40 w-40 text-slate-900 dark:text-slate-100" />
<div className="w-full rounded-md border border-zinc-100 bg-zinc-50/20 p-4 dark:border-zinc-800 dark:bg-zinc-800/60">
<div className="grid grid-cols-1 items-center justify-items-center rounded-sm bg-white p-2 ring-1 ring-zinc-50 dark:bg-zinc-800/80 dark:ring-zinc-800">
<NxConsoleIcon className="m-16 h-40 w-40 text-zinc-900 dark:text-zinc-100" />
</div>
</div>
</div>
@@ -9,10 +9,10 @@ export async function CurrentOpenings({ jobs }: CurrentOpeningsProps) {
return (
<section
id="current-openings"
className="border-b border-t border-slate-100 bg-slate-50/40 dark:border-slate-800 dark:bg-slate-800/60"
className="border-b border-t border-zinc-100 bg-zinc-50/40 dark:border-zinc-800 dark:bg-zinc-800/60"
>
<div className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8 lg:py-24">
<div className="relative mx-auto max-w-lg divide-y divide-slate-100 lg:max-w-7xl dark:divide-slate-700">
<div className="relative mx-auto max-w-lg divide-y divide-zinc-100 lg:max-w-7xl dark:divide-zinc-700">
<header className="max-w-prose">
<SectionHeading as="h2" variant="title" className="mt-4">
Current Openings
@@ -23,9 +23,9 @@ export async function CurrentOpenings({ jobs }: CurrentOpeningsProps) {
{jobs.map((post) => (
<div
key={post.title}
className="relative mt-2 block rounded-lg border border-transparent p-4 transition hover:border-slate-100 hover:shadow-sm dark:hover:border-slate-700"
className="relative mt-2 block rounded-lg border border-transparent p-4 transition hover:border-zinc-100 hover:shadow-sm dark:hover:border-zinc-700"
>
<p className="text-lg font-semibold leading-8 tracking-tight text-slate-800 dark:text-slate-200">
<p className="text-lg font-semibold leading-8 tracking-tight text-zinc-800 dark:text-zinc-200">
{post.title}
</p>
<p className="mt-3 text-base">
@@ -44,7 +44,7 @@ export async function CurrentOpenings({ jobs }: CurrentOpeningsProps) {
))}
{!jobs.length ? (
<div className="mt-2 block">
<p className="text-lg font-semibold leading-8 tracking-tight text-slate-800 dark:text-slate-200">
<p className="text-lg font-semibold leading-8 tracking-tight text-zinc-800 dark:text-zinc-200">
There are no job openings at this time.
</p>
</div>
+2 -2
View File
@@ -57,10 +57,10 @@ export function WhatWeOffer(): JSX.Element {
<div key={feature.name} className="relative">
<dt>
<CheckIcon
className="absolute mt-1 h-6 w-6 text-blue-500 dark:text-sky-500"
className="absolute mt-1 h-6 w-6 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<p className="ml-10 text-lg font-semibold leading-8 tracking-tight text-slate-800 dark:text-slate-200">
<p className="ml-10 text-lg font-semibold leading-8 tracking-tight text-zinc-800 dark:text-zinc-200">
{feature.name}
</p>
</dt>
+3 -3
View File
@@ -46,14 +46,14 @@ export function WhyJoinNx(): JSX.Element {
<div key={feature.name}>
<dt>
<feature.icon
className="h-8 w-8 text-blue-500 dark:text-sky-500"
className="h-8 w-8 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<p className="mt-4 text-lg font-semibold leading-8 tracking-tight text-slate-800 dark:text-slate-200">
<p className="mt-4 text-lg font-semibold leading-8 tracking-tight text-zinc-800 dark:text-zinc-200">
{feature.name}
</p>
</dt>
<dd className="mt-2 text-slate-500 dark:text-slate-400">
<dd className="mt-2 text-zinc-500 dark:text-zinc-400">
<p className="text-base leading-7">{feature.description}</p>
</dd>
</div>
+3 -3
View File
@@ -24,7 +24,7 @@ export function CallToAction(): ReactElement {
<svg
x="50%"
y={0}
className="overflow-visible fill-slate-200/20 dark:fill-slate-800/20"
className="overflow-visible fill-zinc-200/20 dark:fill-zinc-800/20"
>
<path
d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z"
@@ -55,7 +55,7 @@ export function CallToAction(): ReactElement {
{/* Content */}
<div className="mx-auto max-w-4xl text-center">
<h2 className="text-3xl font-medium tracking-tight text-slate-950 sm:text-5xl dark:text-white">
<h2 className="text-3xl font-medium tracking-tight text-zinc-950 sm:text-5xl dark:text-white">
Don't Let Your CI Slow You Down
</h2>
<p className="mt-12 text-xl">
@@ -66,7 +66,7 @@ export function CallToAction(): ReactElement {
href="https://cloud.nx.app/get-started"
title="Get started now"
prefetch={false}
className="rounded-md bg-slate-950 px-3.5 py-2.5 text-sm font-semibold text-slate-100 shadow-sm hover:bg-slate-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-slate-900 dark:hover:bg-slate-100"
className="rounded-md bg-zinc-950 px-3.5 py-2.5 text-sm font-semibold text-zinc-100 shadow-sm hover:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100"
>
Start here{' '}
<span
@@ -23,7 +23,7 @@ const Card = forwardRef<
<div
ref={ref}
className={cx(
'rounded-lg border border-slate-200 bg-slate-50 p-4 shadow-sm backdrop-blur-sm dark:border-slate-800/40 dark:bg-slate-800/60',
'rounded-lg border border-zinc-200 bg-zinc-50 p-4 shadow-sm backdrop-blur-sm dark:border-zinc-800/40 dark:bg-zinc-800/60',
className
)}
onMouseEnter={onMouseEnter}
@@ -57,7 +57,7 @@ export function CiBottleneckAnimation(): ReactElement {
className="border-green-400/60 bg-green-400/40 dark:border-green-800/60 dark:bg-green-800/40"
>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 text-slate-900 dark:text-slate-100">
<div className="flex items-center space-x-3 text-zinc-900 dark:text-zinc-100">
<ServerStackIcon
aria-hidden="true"
className="size-5 shrink-0"
@@ -75,7 +75,7 @@ export function CiBottleneckAnimation(): ReactElement {
className="border-green-400/60 bg-green-400/40 dark:border-green-800/60 dark:bg-green-800/40"
>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 text-slate-900 dark:text-slate-100">
<div className="flex items-center space-x-3 text-zinc-900 dark:text-zinc-100">
<UserPlusIcon
aria-hidden="true"
className="size-5 shrink-0"
@@ -95,7 +95,7 @@ export function CiBottleneckAnimation(): ReactElement {
className="border-green-400/60 bg-green-400/40 dark:border-green-800/60 dark:bg-green-800/40"
>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 text-slate-900 dark:text-slate-100">
<div className="flex items-center space-x-3 text-zinc-900 dark:text-zinc-100">
<WrenchScrewdriverIcon
aria-hidden="true"
className="size-5 shrink-0"
@@ -114,9 +114,9 @@ export function CiBottleneckAnimation(): ReactElement {
<div className="flex flex-col items-center">
<Card
ref={ciBottleneck}
className="relative bg-white dark:border-slate-800/60 dark:bg-slate-950"
className="relative bg-white dark:border-zinc-800/60 dark:bg-zinc-950"
>
<span className="absolute -bottom-8 right-0 hidden items-center gap-x-1.5 rounded-md bg-white px-2 py-1 text-xs font-medium text-slate-400 ring-1 ring-inset ring-slate-200 sm:inline-flex dark:bg-slate-950 dark:ring-slate-800/60">
<span className="absolute -bottom-8 right-0 hidden items-center gap-x-1.5 rounded-md bg-white px-2 py-1 text-xs font-medium text-zinc-400 ring-1 ring-inset ring-zinc-200 sm:inline-flex dark:bg-zinc-950 dark:ring-zinc-800/60">
<span className="relative flex size-1.5">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-orange-400/80 opacity-75" />
<span className="relative inline-flex size-1.5 rounded-full bg-orange-500/80" />
@@ -124,7 +124,7 @@ export function CiBottleneckAnimation(): ReactElement {
Queue increasing
</span>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 text-slate-900 dark:text-slate-100">
<div className="flex items-center space-x-3 text-zinc-900 dark:text-zinc-100">
<FunnelIcon aria-hidden="true" className="size-5 shrink-0" />
<div className="flex-1">
<p className="font-mono text-xs leading-tight">
@@ -143,7 +143,7 @@ export function CiBottleneckAnimation(): ReactElement {
className="border-red-400/60 bg-red-400/40 dark:border-red-800/60 dark:bg-red-800/40"
>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 text-slate-900 dark:text-slate-100">
<div className="flex items-center space-x-3 text-zinc-900 dark:text-zinc-100">
<ClockIcon aria-hidden="true" className="size-5 shrink-0" />
<div className="flex-1">
<p className="font-mono text-xs leading-tight">
+2 -2
View File
@@ -13,7 +13,7 @@ export function CiBottleneck(): ReactElement {
return (
<section
id="ci-bottleneck"
className="scroll-mt-24 border-b border-t border-slate-200 bg-slate-50 py-24 sm:py-32 dark:border-slate-800 dark:bg-slate-900"
className="scroll-mt-24 border-b border-t border-zinc-200 bg-zinc-50 py-24 sm:py-32 dark:border-zinc-800 dark:bg-zinc-900"
>
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-3xl text-center">
@@ -45,7 +45,7 @@ export function CiBottleneck(): ReactElement {
key={stat.id}
className="flex flex-col bg-white p-8 dark:bg-white/5"
>
<dt className="text-sm/6 font-semibold text-slate-700 dark:text-slate-300">
<dt className="text-sm/6 font-semibold text-zinc-700 dark:text-zinc-300">
{stat.name}
</dt>
<dd className="order-first text-3xl font-semibold tracking-tight text-black dark:text-white">
+9 -9
View File
@@ -32,13 +32,13 @@ export function CustomerMetrics(): ReactElement {
}}
className="group relative block rounded-2xl"
>
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-2xl bg-white/60 opacity-0 backdrop-blur-sm transition duration-300 group-hover:opacity-100 dark:bg-slate-950/60">
<div className="flex items-center gap-2 text-lg font-semibold text-slate-950 drop-shadow dark:text-white">
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-2xl bg-white/60 opacity-0 backdrop-blur-sm transition duration-300 group-hover:opacity-100 dark:bg-zinc-950/60">
<div className="flex items-center gap-2 text-lg font-semibold text-zinc-950 drop-shadow dark:text-white">
<PlayIcon className="size-8" />
Watch the interview
</div>
</div>
<figure className="relative rounded-2xl bg-white shadow-lg ring-1 ring-slate-900/5 dark:bg-slate-800">
<figure className="relative rounded-2xl bg-white shadow-lg ring-1 ring-zinc-900/5 dark:bg-zinc-800">
<blockquote className="p-6 text-lg font-semibold tracking-tight text-black dark:text-white">
<p>
The number of hours we spent trying to manage CI before,
@@ -50,15 +50,15 @@ export function CustomerMetrics(): ReactElement {
it fast."
</p>
</blockquote>
<figcaption className="flex flex-wrap items-center gap-x-4 gap-y-4 border-t border-slate-900/10 px-6 py-4 sm:flex-nowrap dark:border-slate-100/10">
<figcaption className="flex flex-wrap items-center gap-x-4 gap-y-4 border-t border-zinc-900/10 px-6 py-4 sm:flex-nowrap dark:border-zinc-100/10">
<img
alt="Nicolas Beaussart image"
src="https://avatars.githubusercontent.com/u/7281023?v=4"
className="size-10 rounded-full bg-slate-50"
className="size-10 rounded-full bg-zinc-50"
/>
<div className="flex-auto">
<div className="font-semibold">Nicolas Beaussart</div>
<div className="text-slate-600 dark:text-slate-500">
<div className="text-zinc-600 dark:text-zinc-500">
Staff Platform Engineer, Payfit
</div>
</div>
@@ -86,19 +86,19 @@ export function CustomerMetrics(): ReactElement {
</div>
<div className="lg:flex lg:flex-auto lg:justify-center">
<dl className="flex flex-col justify-center gap-8 sm:flex-row lg:flex-col xl:w-80">
<div className="flex flex-col-reverse gap-y-1 border-slate-200 pl-4 text-center sm:border-l sm:text-left dark:border-slate-800">
<div className="flex flex-col-reverse gap-y-1 border-zinc-200 pl-4 text-center sm:border-l sm:text-left dark:border-zinc-800">
<dt className="text-base/7">faster CI</dt>
<dd className="[text-shadow:1px 1px 0 white;] te text-5xl font-semibold tracking-tight text-black dark:text-white">
70%
</dd>
</div>
<div className="flex flex-col-reverse gap-y-1 border-slate-200 pl-4 text-center sm:border-l sm:text-left dark:border-slate-800">
<div className="flex flex-col-reverse gap-y-1 border-zinc-200 pl-4 text-center sm:border-l sm:text-left dark:border-zinc-800">
<dt className="text-base/7">less compute used</dt>
<dd className="text-5xl font-semibold tracking-tight text-black dark:text-white">
60%
</dd>
</div>
<div className="flex flex-col-reverse gap-y-1 border-slate-200 pl-4 text-center sm:border-l sm:text-left dark:border-slate-800">
<div className="flex flex-col-reverse gap-y-1 border-zinc-200 pl-4 text-center sm:border-l sm:text-left dark:border-zinc-800">
<dt className="text-base/7">reduction in infra costs</dt>
<dd className="text-5xl font-semibold tracking-tight text-black dark:text-white">
75%
+5 -5
View File
@@ -161,7 +161,7 @@ export function Faq(): ReactElement {
Check out our most commonly asked questions.
</SectionHeading>
<p className="text-md mt-4 text-slate-400 dark:text-slate-600">
<p className="text-md mt-4 text-zinc-400 dark:text-zinc-600">
<Link
href="/contact"
title="Reach out to the team"
@@ -186,14 +186,14 @@ export function Faq(): ReactElement {
}))}
/>
<div className="mt-12 lg:col-span-2 lg:mt-0">
<dl className="mt-6 space-y-6 divide-y divide-slate-100 dark:divide-slate-800">
<dl className="mt-6 space-y-6 divide-y divide-zinc-100 dark:divide-zinc-800">
{faqs.map((faq) => (
<Disclosure as="div" key={faq.question} className="pt-6">
{({ open }) => (
<>
<dt className="text-lg">
<DisclosureButton className="flex w-full items-start justify-between text-left text-slate-400">
<span className="font-medium text-slate-800 dark:text-slate-300">
<DisclosureButton className="flex w-full items-start justify-between text-left text-zinc-400">
<span className="font-medium text-zinc-800 dark:text-zinc-300">
{faq.question}
</span>
<span className="ml-6 flex h-7 items-center">
@@ -217,7 +217,7 @@ export function Faq(): ReactElement {
>
<DisclosurePanel
as="dd"
className="mt-2 pr-12 text-base text-slate-500 dark:text-slate-400"
className="mt-2 pr-12 text-base text-zinc-500 dark:text-zinc-400"
>
{faq.answerUi}
</DisclosurePanel>
+15 -15
View File
@@ -5,7 +5,7 @@ export function Features(): ReactElement {
return (
<section
id="features"
className="scroll-mt-24 border-b border-t border-slate-200 bg-slate-50 py-24 sm:py-32 dark:border-slate-800 dark:bg-slate-900"
className="scroll-mt-24 border-b border-t border-zinc-200 bg-zinc-50 py-24 sm:py-32 dark:border-zinc-800 dark:bg-zinc-900"
>
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-3xl text-center">
@@ -19,14 +19,14 @@ export function Features(): ReactElement {
</div>
<div className="mx-auto mt-12 grid max-w-5xl grid-cols-1 gap-4 sm:mt-16 md:grid-cols-2">
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-tl-[calc(2rem+1px)] dark:bg-slate-950 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-tl-[calc(2rem+1px)] dark:bg-zinc-950 dark:ring-white/10">
<img
alt="Nx Replay: remote caching"
src="/images/enterprise/nx-replay.avif"
className="h-80 object-cover object-center"
/>
<div className="relative p-10 pt-4">
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
Secure Remote Cache
</h3>
<p className="mt-2 max-w-lg text-sm/6">
@@ -38,14 +38,14 @@ export function Features(): ReactElement {
</div>
</div>
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-tr-[calc(2rem+1px)] dark:bg-slate-950 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-tr-[calc(2rem+1px)] dark:bg-zinc-950 dark:ring-white/10">
<img
alt="Nx flaky task detection & rerun"
src="/images/enterprise/nx-flaky-tasks-detection.avif"
className="h-80 object-cover"
/>
<div className="relative p-10 pt-4">
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
Self-Healing CI
</h3>
<p className="mt-2 max-w-lg text-sm/6">
@@ -57,14 +57,14 @@ export function Features(): ReactElement {
</div>
</div>
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 dark:bg-slate-950 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 dark:bg-zinc-950 dark:ring-white/10">
<img
alt="Nx Atomizer: split large tasks & E2E in chunks"
src="/images/enterprise/nx-atomizer.avif"
className="h-80 object-cover object-center"
/>
<div className="relative p-10 pt-4">
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
E2E Test Splitting
</h3>
<p className="mt-2 max-w-lg text-sm/6">
@@ -76,14 +76,14 @@ export function Features(): ReactElement {
</div>
</div>
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 dark:bg-slate-950 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 dark:bg-zinc-950 dark:ring-white/10">
<img
alt="Nx Agents: simple & fast task distribution"
src="/images/enterprise/nx-agents.avif"
className="h-80 object-cover object-center"
/>
<div className="relative p-10 pt-4">
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
Distributed Task Execution
</h3>
<p className="mt-2 max-w-lg text-sm/6">
@@ -95,7 +95,7 @@ export function Features(): ReactElement {
</div>
</div>
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-bl-[calc(2rem+1px)] dark:bg-slate-800 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-bl-[calc(2rem+1px)] dark:bg-zinc-800 dark:ring-white/10">
<img
alt="Nx Agents: simple & fast task distribution"
src="/images/enterprise/visibility.avif"
@@ -103,11 +103,11 @@ export function Features(): ReactElement {
/>
<div className="relative p-10 pt-4">
<div className="absolute -top-10 left-10">
<span className="inline-flex items-center rounded-md bg-slate-400/10 px-2 py-1 text-xs font-medium text-slate-400 ring-1 ring-inset ring-slate-400/20">
<span className="inline-flex items-center rounded-md bg-zinc-400/10 px-2 py-1 text-xs font-medium text-zinc-400 ring-1 ring-inset ring-zinc-400/20">
Enterprise
</span>
</div>
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
See Dependencies Across Teams & Repositories
</h3>
<p className="mt-2 max-w-lg text-sm/6">
@@ -121,7 +121,7 @@ export function Features(): ReactElement {
</div>
</div>
<div className="relative">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-br-[calc(2rem+1px)] dark:bg-slate-800 dark:ring-white/10">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] bg-white shadow ring-1 ring-black/5 lg:rounded-br-[calc(2rem+1px)] dark:bg-zinc-800 dark:ring-white/10">
<img
alt="Nx Atomizer: split large tasks & E2E in chunks"
src="/images/enterprise/conformance.avif"
@@ -129,11 +129,11 @@ export function Features(): ReactElement {
/>
<div className="relative p-10 pt-4">
<div className="absolute -top-10 left-10">
<span className="inline-flex items-center rounded-md bg-slate-400/10 px-2 py-1 text-xs font-medium text-slate-400 ring-1 ring-inset ring-slate-400/20">
<span className="inline-flex items-center rounded-md bg-zinc-400/10 px-2 py-1 text-xs font-medium text-zinc-400 ring-1 ring-inset ring-zinc-400/20">
Enterprise
</span>
</div>
<h3 className="text-lg font-medium tracking-tight text-slate-950 dark:text-white">
<h3 className="text-lg font-medium tracking-tight text-zinc-950 dark:text-white">
Streamline Onboarding & Governance
</h3>
<p className="mt-2 max-w-lg text-sm/6">
+2 -2
View File
@@ -12,14 +12,14 @@ export function GetStarted(): ReactElement {
as="h2"
variant="title"
id="get-started-title"
className="text-white dark:text-slate-950"
className="text-white dark:text-zinc-950"
>
Get Started
</SectionHeading>
<SectionHeading
as="p"
variant="subtitle"
className="mt-8 text-white dark:text-slate-950"
className="mt-8 text-white dark:text-zinc-950"
>
In 5 minutes, you'll see the difference.
</SectionHeading>
@@ -18,7 +18,7 @@ export function NxCloudHeroVideo(): ReactElement {
<div className="h-20 w-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--pink-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<picture className="relative flex h-full w-full items-center justify-center overflow-hidden rounded-xl border border-slate-100 bg-slate-50 antialiased backdrop-blur-xl dark:border-slate-900 dark:bg-slate-900/[0.8]">
<picture className="relative flex h-full w-full items-center justify-center overflow-hidden rounded-xl border border-zinc-100 bg-zinc-50 antialiased backdrop-blur-xl dark:border-zinc-900 dark:bg-zinc-900/[0.8]">
<Image
src="/images/cloud/nrwl-ocean.avif"
alt="App screenshot: overview"
+2 -2
View File
@@ -51,14 +51,14 @@ export function PlayButton({
>
<div className="absolute inset-0">
<MovingBorder duration={5000} rx="5%" ry="5%">
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--sky-500)_40%,transparent_60%)]" />
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<motion.div
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-slate-950 antialiased backdrop-blur-xl"
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-zinc-100 bg-white/10 p-6 text-zinc-950 antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
+1 -1
View File
@@ -139,7 +139,7 @@ export function NxCloudHero(): ReactElement {
<ButtonLink
href="https://cloud.nx.app/get-started"
title="Nx AI Integration"
variant="primary"
variant="contrast"
size="default"
onClick={() =>
sendCustomEvent(
+34 -34
View File
@@ -10,7 +10,7 @@ export function Pricing(): ReactElement {
return (
<section
id="plans"
className="scroll-mt-24 border-b border-t border-slate-200 bg-slate-50 py-24 sm:py-32 dark:border-slate-800 dark:bg-slate-900"
className="scroll-mt-24 border-b border-t border-zinc-200 bg-zinc-50 py-24 sm:py-32 dark:border-zinc-800 dark:bg-zinc-900"
>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<header className="mx-auto max-w-4xl text-center">
@@ -39,9 +39,9 @@ export function Pricing(): ReactElement {
<div className="isolate -mt-16 grid max-w-full grid-cols-1 gap-6 sm:mx-auto lg:mt-0 lg:grid-cols-3 xl:-mx-4 xl:gap-8">
{/*HOBBY*/}
<div>
<div className="rounded-lg border-2 border-blue-500 bg-white p-6 dark:border-sky-500 dark:bg-slate-950">
<div className="rounded-lg border-2 border-blue-500 bg-white p-6 dark:border-blue-500 dark:bg-zinc-950">
<div className="flex items-center gap-x-2">
<h4 className="text-xl font-semibold leading-8 text-slate-950 dark:text-white">
<h4 className="text-xl font-semibold leading-8 text-zinc-950 dark:text-white">
Hobby
</h4>
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10 dark:bg-blue-400/10 dark:text-blue-400 dark:ring-blue-400/30">
@@ -53,7 +53,7 @@ export function Pricing(): ReactElement {
product. No credit card required.
</p>
<p className="mt-4 pb-5 leading-5">
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
<span className="text-3xl font-semibold text-zinc-950 dark:text-white">
$0
</span>
</p>
@@ -63,7 +63,7 @@ export function Pricing(): ReactElement {
aria-describedby="hobby-plan"
title="Start now"
size="default"
variant="primary"
variant="contrast"
onClick={() =>
sendCustomEvent(
'start-hobby-plan-click',
@@ -76,21 +76,21 @@ export function Pricing(): ReactElement {
Start now
</ButtonLink>
</div>
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
<ul className="mt-4 divide-y divide-zinc-200 text-sm dark:divide-zinc-800">
<li className="py-2.5">
<span className="font-medium">Included for free</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>50,000 monthly credits</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<Link
href="/ai"
@@ -111,7 +111,7 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>
Remote caching with{' '}
@@ -135,7 +135,7 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>
Distributed task execution with{' '}
@@ -163,9 +163,9 @@ export function Pricing(): ReactElement {
</div>
{/*TEAM*/}
<div className="rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-950">
<div className="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-800 dark:bg-zinc-950">
<div className="flex items-center gap-x-2">
<h4 className="text-xl font-semibold leading-8 text-slate-950 dark:text-white">
<h4 className="text-xl font-semibold leading-8 text-zinc-950 dark:text-white">
Team
</h4>
</div>
@@ -173,7 +173,7 @@ export function Pricing(): ReactElement {
Start free, pay as you grow. Billed on the first of each month.
</p>
<p className="mt-4 leading-5">
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
<span className="text-3xl font-semibold text-zinc-950 dark:text-white">
$19
</span>
<span className="text-lg"> per Active Contributor¹</span>{' '}
@@ -203,35 +203,35 @@ export function Pricing(): ReactElement {
Free to start
</ButtonLink>
</div>
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
<ul className="mt-4 divide-y divide-zinc-200 text-sm dark:divide-zinc-800">
<li className="py-2.5">
<span className="font-medium">Included for free</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>5 active contributors¹</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>50,000 monthly credits</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>10 concurrent CI connections</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<Link
href="/ai"
@@ -252,7 +252,7 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>Email support</span>
</li>
@@ -262,35 +262,35 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<PlusIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>$19 per active contributor¹ / month</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<PlusIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>$5.50 per 10,000 credits</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<PlusIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>$2.25 per concurrent CI connection</span>
</li>
</ul>
<p className="mt-4 text-xs text-slate-500">
<p className="mt-4 text-xs text-zinc-500">
¹Any person or actor that has triggered a CI Pipeline Execution
within the current billing cycle. Up to 50 active contributors.
</p>
</div>
{/* ENTERPRISE */}
<div className="rounded-lg border border-slate-200 bg-slate-50/60 p-6 dark:border-slate-800 dark:bg-slate-900">
<div className="rounded-lg border border-zinc-200 bg-zinc-50/60 p-6 dark:border-zinc-800 dark:bg-zinc-900">
<div className="flex items-center gap-x-2">
<h4 className="text-xl font-semibold leading-8 text-slate-950 dark:text-white">
<h4 className="text-xl font-semibold leading-8 text-zinc-950 dark:text-white">
Enterprise
</h4>
</div>
@@ -299,7 +299,7 @@ export function Pricing(): ReactElement {
& payment options available.
</p>
<p className="mt-4 pb-5 leading-5">
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
<span className="text-3xl font-semibold text-zinc-950 dark:text-white">
Custom
</span>
</p>
@@ -322,28 +322,28 @@ export function Pricing(): ReactElement {
Request a trial
</ButtonLink>
</div>
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
<ul className="mt-4 divide-y divide-zinc-200 text-sm dark:divide-zinc-800">
<li className="py-2.5">
<span className="font-medium">Includes</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>Volume discounts on credits available</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>White glove onboarding</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>
<Link
@@ -367,7 +367,7 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>
Work hand-in-hand with the Nx team for continual improvement
@@ -376,7 +376,7 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>
Run on the Nx Cloud servers in any region or run fully
@@ -386,14 +386,14 @@ export function Pricing(): ReactElement {
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>SSO / SAML Login</span>
</li>
<li className="flex items-center justify-start gap-x-2 py-2.5">
<CheckCircleIcon
aria-hidden="true"
className="h-6 w-5 flex-none text-blue-600 dark:text-sky-500"
className="h-6 w-5 flex-none text-blue-600 dark:text-blue-500"
/>
<span>Premium Support and SLAs available</span>
</li>
+1 -1
View File
@@ -41,7 +41,7 @@ export function Security(): ReactElement {
and other regulated industries. Don't compromise.
</SectionHeading>
<div className="mt-8 flex flex-wrap items-center gap-4 md:gap-8">
<div className="flex w-52 shrink-0 items-center gap-2 rounded-xl px-2 py-1 text-xs text-slate-950 ring-1 ring-slate-200 dark:text-slate-50 dark:ring-slate-700">
<div className="flex w-52 shrink-0 items-center gap-2 rounded-xl px-2 py-1 text-xs text-zinc-950 ring-1 ring-zinc-200 dark:text-zinc-50 dark:ring-zinc-700">
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
+2 -2
View File
@@ -25,7 +25,7 @@ export function TimeToGreen(): ReactElement {
<h3 className="text-xl font-semibold">Average Time To Green</h3>
<div className="mt-2">
<div className="relative grid grid-cols-1 rounded-lg bg-slate-50 text-xs font-medium text-slate-900 ring-1 ring-slate-200 sm:h-12 sm:grid-cols-12 dark:bg-slate-900 dark:text-slate-100 dark:ring-white/10">
<div className="relative grid grid-cols-1 rounded-lg bg-zinc-50 text-xs font-medium text-zinc-900 ring-1 ring-zinc-200 sm:h-12 sm:grid-cols-12 dark:bg-zinc-900 dark:text-zinc-100 dark:ring-white/10">
<div className="flex h-12 items-center justify-center rounded-t-lg bg-blue-400/40 sm:col-span-2 sm:h-auto sm:rounded-l-lg sm:rounded-r-none dark:bg-blue-600/40">
<span className="px-2">Write Code</span>
</div>
@@ -50,7 +50,7 @@ export function TimeToGreen(): ReactElement {
<h3 className="text-xl font-semibold">Time To Green with Nx Cloud</h3>
<div className="mt-2 grid grid-cols-1 sm:h-12 sm:grid-cols-12">
<div className="col-span-4 grid grid-cols-1 sm:grid-cols-6">
<div className="grid grid-cols-1 rounded-lg bg-slate-50 text-xs font-medium text-slate-900 ring-1 ring-slate-200 sm:col-span-5 sm:grid-cols-10 dark:bg-slate-900 dark:text-slate-100 dark:ring-white/10">
<div className="grid grid-cols-1 rounded-lg bg-zinc-50 text-xs font-medium text-zinc-900 ring-1 ring-zinc-200 sm:col-span-5 sm:grid-cols-10 dark:bg-zinc-900 dark:text-zinc-100 dark:ring-white/10">
<div className="flex h-12 items-center justify-center rounded-t-lg bg-blue-400/40 sm:col-span-6 sm:h-auto sm:rounded-l-lg sm:rounded-r-none dark:bg-blue-600/40">
<span className="px-2">Write Code</span>
</div>
@@ -39,13 +39,10 @@ export function InlineCommand({
>
<button
type="button"
className="font-input-mono duration-180 flex w-full flex-none items-center justify-center space-x-2 rounded-md border border-slate-300 bg-white py-1 text-sm leading-6 text-slate-400 transition-colors hover:text-slate-800 focus:outline-none focus:ring-2 focus:ring-slate-300 focus:ring-offset-2 focus:ring-offset-white sm:max-w-full sm:space-x-4 sm:px-3"
className="font-input-mono duration-180 flex w-full flex-none items-center justify-center space-x-2 rounded-md border border-zinc-300 bg-white py-1 text-sm leading-6 text-zinc-400 transition-colors hover:text-zinc-800 focus:outline-none focus:ring-2 focus:ring-zinc-300 focus:ring-offset-2 focus:ring-offset-white sm:max-w-full sm:space-x-4 sm:px-3"
>
<span className="flex items-center overflow-auto text-slate-800">
<span
className="hidden text-slate-500 sm:inline"
aria-hidden="true"
>
<span className="flex items-center overflow-auto text-zinc-800">
<span className="hidden text-zinc-500 sm:inline" aria-hidden="true">
$
</span>
<SyntaxHighlighter
@@ -2,7 +2,7 @@ import Link from 'next/link';
export function AnnouncementBanner(): JSX.Element {
return (
<div className="group relative border border-y border-slate-200 bg-slate-50/40 transition hover:bg-slate-50 dark:border-slate-800/40 dark:bg-slate-800/60 dark:hover:bg-slate-800">
<div className="group relative border border-y border-zinc-200 bg-zinc-50/40 transition hover:bg-zinc-50 dark:border-zinc-800/40 dark:bg-zinc-800/60 dark:hover:bg-zinc-800">
<div className="mx-auto max-w-7xl px-3 py-3 sm:px-6 lg:px-8">
<div className="text-center">
<p className="text-sm font-medium">
@@ -22,7 +22,7 @@ export function AnnouncementBanner(): JSX.Element {
<span className="ml-2 inline-block">
<Link
href="https://monorepo.world?utm_source=nx.dev"
className="font-semibold text-blue-500 underline dark:text-sky-500"
className="font-semibold text-blue-500 underline dark:text-blue-500"
>
<span className="absolute inset-0" aria-hidden="true" />
Join us!
+3 -3
View File
@@ -82,15 +82,15 @@ export function Breadcrumbs({
<div className="flex items-center">
{!!index && (
<ChevronRightIcon
className="h-5 w-5 flex-shrink-0 text-slate-500"
className="h-5 w-5 flex-shrink-0 text-zinc-500"
aria-hidden="true"
/>
)}
<a
href={crumb.href}
className={classNames(
'text-sm font-medium hover:text-slate-600',
crumb.current ? 'text-slate-600' : 'text-slate-400',
'text-sm font-medium hover:text-zinc-600',
crumb.current ? 'text-zinc-600' : 'text-zinc-400',
!!index ? 'ml-4' : ''
)}
aria-current={crumb.current ? 'page' : undefined}
+6 -6
View File
@@ -25,11 +25,11 @@ export type ButtonLinkProps = ButtonProps & {
const variantStyles: Record<AllowedVariants, string> = {
primary:
'bg-blue-500 dark:bg-sky-500 text-white group-hover:bg-blue-600 dark:group-hover:bg-sky-600 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-sky-500 focus:group-ring-offset-2',
'bg-blue-500 dark:bg-blue-500 text-white group-hover:bg-blue-600 dark:group-hover:bg-blue-600 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-blue-500 focus:group-ring-offset-2',
secondary:
'border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 group-hover:bg-slate-50 dark:group-hover:bg-slate-700 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-sky-500 focus:ring-offset-2',
'border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-700 dark:text-zinc-200 group-hover:bg-zinc-50 dark:group-hover:bg-zinc-700 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-blue-500 focus:ring-offset-2',
contrast:
'bg-slate-950 dark:bg-white text-slate-100 dark:text-slate-950 group-hover:bg-slate-800 dark:group-hover:bg-slate-100 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-sky-500 focus:ring-offset-2',
'bg-zinc-950 dark:bg-white text-zinc-100 dark:text-zinc-950 group-hover:bg-zinc-800 dark:group-hover:bg-zinc-100 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-blue-500 focus:ring-offset-2',
};
const sizes: Record<AllowedSizes, string> = {
large: 'space-x-4 px-4 py-2 text-lg',
@@ -52,7 +52,7 @@ function getLayoutClassName(className = ''): string {
*/
function ButtonInner({
children,
variant = 'primary',
variant = 'contrast',
size = 'default',
rounded = 'default',
}: ButtonProps): JSX.Element {
@@ -79,7 +79,7 @@ function ButtonInner({
export function Button({
children,
className = '',
variant = 'primary',
variant = 'contrast',
size = 'large',
rounded = 'default',
...props
@@ -102,7 +102,7 @@ export const ButtonLink = forwardRef(function (
className = '',
href,
size = 'default',
variant = 'primary',
variant = 'contrast',
title = '',
...props
}: ButtonLinkProps,
+4 -4
View File
@@ -34,7 +34,7 @@ export function CallToAction({
<svg
x="50%"
y={0}
className="overflow-visible fill-slate-200/20 dark:fill-slate-800/20"
className="overflow-visible fill-zinc-200/20 dark:fill-zinc-800/20"
>
<path
d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z"
@@ -63,7 +63,7 @@ export function CallToAction({
<div className="mx-auto max-w-2xl text-center">
<h2
id="cta"
className="text-3xl font-medium tracking-tight text-slate-950 sm:text-5xl dark:text-white"
className="text-3xl font-medium tracking-tight text-zinc-950 sm:text-5xl dark:text-white"
>
Ready to
<br />
@@ -74,7 +74,7 @@ export function CallToAction({
href={mainActionLink}
title={mainActionTitle}
prefetch={false}
className="rounded-md bg-slate-950 px-3.5 py-2.5 text-sm font-semibold text-slate-100 shadow-sm hover:bg-slate-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-slate-900 dark:hover:bg-slate-100"
className="rounded-md bg-zinc-950 px-3.5 py-2.5 text-sm font-semibold text-zinc-100 shadow-sm hover:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100"
>
{mainActionLinkText}
</Link>
@@ -82,7 +82,7 @@ export function CallToAction({
href="/contact"
title="Get in touch"
prefetch={false}
className="group text-sm font-semibold leading-6 text-slate-950 dark:text-white"
className="group text-sm font-semibold leading-6 text-zinc-950 dark:text-white"
onClick={() => sendCustomEvent('contact-click', 'footer-cta', '')}
>
Contact us{' '}
+5 -5
View File
@@ -15,28 +15,28 @@ export interface Champion {
export function ChampionCard({ data }: { data: Champion }): JSX.Element {
return (
<figure className="relative flex flex-col justify-between rounded-lg border border-slate-200 bg-white/40 p-4 text-sm shadow-sm transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-white dark:border-slate-800/40 dark:bg-slate-800/60 dark:hover:bg-slate-800">
<figure className="relative flex flex-col justify-between rounded-lg border border-zinc-200 bg-white/40 p-4 text-sm shadow-sm transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-white dark:border-zinc-800/40 dark:bg-zinc-800/60 dark:hover:bg-zinc-800">
<figcaption className="flex items-center space-x-4">
<img
src={data.imageUrl}
alt={data.name}
className="h-12 w-12 flex-none rounded-full border border-slate-200 bg-slate-800/40 object-cover dark:border-slate-800/40 dark:bg-slate-200"
className="h-12 w-12 flex-none rounded-full border border-zinc-200 bg-zinc-800/40 object-cover dark:border-zinc-800/40 dark:bg-zinc-200"
loading="lazy"
/>
<div className="flex-auto">
<div className="font-semibold text-slate-500 dark:text-slate-300">
<div className="font-semibold text-zinc-500 dark:text-zinc-300">
<a target="_blank" rel="noreferrer" href={data.contact[0].link}>
<span className="absolute inset-0"></span>
{data.name}
</a>
</div>
<div className="mt-0.5 text-xs text-slate-400 dark:text-slate-500">
<div className="mt-0.5 text-xs text-zinc-400 dark:text-zinc-500">
<MapIcon className="inline h-4 w-4" /> {data.location}
</div>
</div>
</figcaption>
<p className="mt-4">{data.expertise}</p>
<div className="ml mt-4 inline text-xs text-slate-400 dark:text-slate-500">
<div className="ml mt-4 inline text-xs text-zinc-400 dark:text-zinc-500">
<ChatBubbleLeftIcon className="inline h-4 w-4" />{' '}
{data.contact[0].label}
</div>
+19 -19
View File
@@ -28,7 +28,7 @@ export function ChampionPerks(): JSX.Element {
return (
<article
id="making-of-champion"
className="relative bg-slate-50 py-28 dark:bg-slate-800/40"
className="relative bg-zinc-50 py-28 dark:bg-zinc-800/40"
>
<div className="mx-auto max-w-7xl px-4 sm:grid sm:grid-cols-2 sm:gap-8 sm:px-6 lg:px-8">
<div>
@@ -46,7 +46,7 @@ export function ChampionPerks(): JSX.Element {
</SectionHeading>
</header>
<div className="mt-8 flex gap-16 font-normal">
<p className="max-w-xl text-lg text-slate-700 dark:text-slate-400">
<p className="max-w-xl text-lg text-zinc-700 dark:text-zinc-400">
If you love Nx and want other people to love Nx too, you may have
the makings of an Nx Champion.
</p>
@@ -59,7 +59,7 @@ export function ChampionPerks(): JSX.Element {
<dt>
<div className="relative flex h-12 w-12">
<CheckBadgeIcon
className="h-8 w-8 text-blue-500 dark:text-sky-500"
className="h-8 w-8 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<HeartIcon
@@ -71,12 +71,12 @@ export function ChampionPerks(): JSX.Element {
aria-hidden="true"
/>
</div>
<p className="relative mt-4 text-base font-medium leading-6 text-slate-900 dark:text-slate-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-sky-500"></span>
<p className="relative mt-4 text-base font-medium leading-6 text-zinc-900 dark:text-zinc-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-blue-500"></span>
Recognition as a Leader
</p>
</dt>
<dd className="mt-2 text-base text-slate-500 dark:text-slate-400">
<dd className="mt-2 text-base text-zinc-500 dark:text-zinc-400">
You'll be listed in the Nx Champion directory above, receive
branded swag for yourself and Nx stickers to give away.
</dd>
@@ -85,7 +85,7 @@ export function ChampionPerks(): JSX.Element {
<dt>
<div className="relative flex h-12 w-12">
<NewspaperIcon
className="h-8 w-8 text-blue-500 dark:text-sky-500"
className="h-8 w-8 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<VideoCameraIcon
@@ -97,12 +97,12 @@ export function ChampionPerks(): JSX.Element {
aria-hidden="true"
/>
</div>
<p className="relative mt-4 text-base font-medium leading-6 text-slate-900 dark:text-slate-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-sky-500"></span>
<p className="relative mt-4 text-base font-medium leading-6 text-zinc-900 dark:text-zinc-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-blue-500"></span>
Content Promotion
</p>
</dt>
<dd className="mt-2 text-base text-slate-500 dark:text-slate-400">
<dd className="mt-2 text-base text-zinc-500 dark:text-zinc-400">
You can collaborate with other Nx Champions to improve your blog
posts and videos. Nx will promote your content on our social media
channels.
@@ -112,7 +112,7 @@ export function ChampionPerks(): JSX.Element {
<dt>
<div className="relative flex h-12 w-12">
<KeyIcon
className="h-8 w-8 text-blue-500 dark:text-sky-500"
className="h-8 w-8 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<LightBulbIcon
@@ -124,12 +124,12 @@ export function ChampionPerks(): JSX.Element {
aria-hidden="true"
/>
</div>
<p className="relative mt-4 text-base font-medium leading-6 text-slate-900 dark:text-slate-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-sky-500"></span>
<p className="relative mt-4 text-base font-medium leading-6 text-zinc-900 dark:text-zinc-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-blue-500"></span>
Special Access
</p>
</dt>
<dd className="mt-2 text-base text-slate-500 dark:text-slate-400">
<dd className="mt-2 text-base text-zinc-500 dark:text-zinc-400">
You'll have a dedicated Discord channel with the Nx team and
monthly video calls with Nx team members to share feedback and
brainstorm content ideas.
@@ -139,7 +139,7 @@ export function ChampionPerks(): JSX.Element {
<dt>
<div className="relative flex h-12 w-12">
<UserGroupIcon
className="h-8 w-8 text-blue-500 dark:text-sky-500"
className="h-8 w-8 text-blue-500 dark:text-blue-500"
aria-hidden="true"
/>
<UsersIcon
@@ -151,15 +151,15 @@ export function ChampionPerks(): JSX.Element {
aria-hidden="true"
/>
</div>
<p className="relative mt-4 text-base font-medium leading-6 text-slate-900 dark:text-slate-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-sky-500"></span>
<p className="relative mt-4 text-base font-medium leading-6 text-zinc-900 dark:text-zinc-100">
<span className="absolute -left-4 h-full w-0.5 bg-blue-500 dark:bg-blue-500"></span>
Join the Program
</p>
</dt>
<dd className="mt-2 text-base text-slate-500 dark:text-slate-400">
<dd className="mt-2 text-base text-zinc-500 dark:text-zinc-400">
When you're ready to join, fill out the{' '}
<a
className="text-slate-900 underline dark:text-slate-100"
className="text-zinc-900 underline dark:text-zinc-100"
href="https://forms.gle/wYd9mC3ka64ki96G7"
>
application form
+3 -3
View File
@@ -17,7 +17,7 @@ export function CourseVideo({
}: CourseVideoProps): JSX.Element {
return (
<div className="not-prose mx-auto max-w-4xl pt-4">
<div className="overflow-hidden rounded-xl bg-slate-50 shadow-sm ring-1 ring-slate-900/5 dark:bg-slate-800/50 dark:ring-slate-700/50">
<div className="overflow-hidden rounded-xl bg-zinc-50 shadow-sm ring-1 ring-zinc-900/5 dark:bg-zinc-800/50 dark:ring-zinc-700/50">
<div className="aspect-video w-full">
<YouTube
src={videoUrl}
@@ -28,12 +28,12 @@ export function CourseVideo({
</div>
<div className="px-6 py-4">
<div className="flex flex-col items-center gap-3 sm:flex-row sm:items-center sm:justify-between">
<h3 className="text-center text-xl font-medium text-slate-900 sm:text-left dark:text-white">
<h3 className="text-center text-xl font-medium text-zinc-900 sm:text-left dark:text-white">
{courseTitle}
</h3>
<ButtonLink
href={courseUrl}
variant="primary"
variant="contrast"
size="small"
title={`Watch the full "${courseTitle}" course`}
className="whitespace-nowrap"
+1 -1
View File
@@ -25,7 +25,7 @@ export function DefaultLayout({
useWindowScrollDepth();
return (
<div className="w-full dark:bg-slate-950">
<div className="w-full dark:bg-zinc-950">
{!hideHeader && (
<Header
ctaButtons={headerCTAConfig}
+6 -6
View File
@@ -45,15 +45,15 @@ export function FlipCard({
>
<div
className={cx(
'preserve-3d relative h-full w-full content-center rounded-lg border-2 bg-white/60 shadow-sm transition duration-200 focus-within:ring-offset-2 dark:bg-slate-800/90',
'preserve-3d relative h-full w-full content-center rounded-lg border-2 bg-white/60 shadow-sm transition duration-200 focus-within:ring-offset-2 dark:bg-zinc-800/90',
isFlippable && isFlipped
? 'my-rotate-y-180 bg-white dark:bg-slate-800'
? 'my-rotate-y-180 bg-white dark:bg-zinc-800'
: '',
isFlippable
? isFlipped
? 'border-blue-400 dark:border-slate-800'
: 'border-blue-400 hover:[transform:rotateY(10deg)] dark:border-slate-800'
: 'border-1 border-slate-300 dark:border-slate-800'
? 'border-blue-400 dark:border-zinc-800'
: 'border-blue-400 hover:[transform:rotateY(10deg)] dark:border-zinc-800'
: 'border-1 border-zinc-300 dark:border-zinc-800'
)}
>
<FlipCardFront>{fullDate}</FlipCardFront>
@@ -76,7 +76,7 @@ export function FlipCardBack({ children }: { children: ReactNode }) {
return (
<FlipCardContext.Consumer>
{() => (
<div className="my-rotate-y-180 backface-hidden h-full w-full overflow-hidden rounded-md bg-white text-3xl text-slate-900 dark:bg-slate-800 dark:text-slate-100">
<div className="my-rotate-y-180 backface-hidden h-full w-full overflow-hidden rounded-md bg-white text-3xl text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100">
<div className="p-4 text-sm sm:text-sm md:text-sm lg:text-lg">
{children}
</div>

Some files were not shown because too many files have changed in this diff Show More