Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ out
/.cache
/pages/api
/pages/loaders
/pages/plugins
/pages/plugins
/generated
4 changes: 4 additions & 0 deletions .lintstagedrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
"**/*.{js,mjs,ts,tsx,md,mdx,json.yml}": [
"eslint --fix",
"prettier --check --write"
],
"**/*.css": [
"stylelint --allow-empty-input --fix",
"prettier --check --write"
]
}
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ out
*.generated.*
/.cache
/pages/api
versions.json
versions.json
/generated
7 changes: 7 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
out
*.generated.*
/.cache
/pages/api
versions.json
/generated
55 changes: 55 additions & 0 deletions .stylelintrc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Ref: https://github.com/nodejs/nodejs.org/blob/main/apps/site/.stylelintrc.mjs

// These are all the custom `@` (at) rules that we use within our custom PostCSS plugins
const CUSTOM_AT_RULES = [
// Tailwind-specific at-rules
'apply',
'layer',
'responsive',
'reference',
'utility',
'theme',
'custom-variant',
'screen',
'source',
'tailwind',
'variants',
];

// Enforces certain selectors to be only in camelCase notation
// We use these for id selectors and classname selectors
const ONLY_ALLOW_CAMEL_CASE_SELECTORS = [
/^(?:[a-z]+(?:[A-Z][a-z]*)*)$/,
{ message: s => `Expected '${s}' to be in camelCase` },
];

export default {
extends: ['stylelint-config-standard'],
plugins: [
'stylelint-order',
'./node_modules/@node-core/ui-components/dist/stylelint/one-utility-class-per-line.mjs',
],
rules: {
// Enforces Element Class Names to be camelCase
'selector-class-pattern': ONLY_ALLOW_CAMEL_CASE_SELECTORS,
// Enforces Element IDs to be camelCase
'selector-id-pattern': ONLY_ALLOW_CAMEL_CASE_SELECTORS,
// Allow Tailwind-based CSS Rules
'at-rule-no-unknown': [true, { ignoreAtRules: CUSTOM_AT_RULES }],
// Allow the Global CSS Selector
'selector-pseudo-class-no-unknown': [
true,
{ ignorePseudoClasses: ['global'] },
],
// Enforces the order of the CSS properties to be in alphabetical order
'order/properties-alphabetical-order': true,
'no-descending-specificity': null,
// Disables the Level-4 Media Queries; Since they're more exotic and less known
'media-feature-range-notation': 'prefix',
// Adopts the import notation from `postcss-import`
'import-notation': 'string',
// Allow the `@apply` at rule as its part of Tailwind
'at-rule-no-deprecated': [true, { ignoreAtRules: CUSTOM_AT_RULES }],
'nodejs/one-utility-class-per-line': true,
},
};
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ The pipeline is split into three stages: `prepare` fetches each webpack tag into

## Scripts

| Script | Description |
| ---------------------- | ----------------------------------------------------------------- |
| `npm run prep` | Fetch every webpack tag in `versions.json` into `.cache/webpack/` |
| `npm run build:md` | Generate Markdown for every prepared webpack source |
| `npm run build:html` | Convert Markdown to HTML |
| `npm run build` | Full pipeline: prepare → Markdown → HTML |
| `npm run lint` | Run ESLint |
| `npm run format:check` | Check Prettier formatting |
| Script | Description |
| ----------------------- | ----------------------------------------------------------------- |
| `npm run build:prepare` | Fetch every webpack tag in `versions.json` into `.cache/webpack/` |
| `npm run build:md` | Generate Markdown for every prepared webpack source |
| `npm run build:html` | Convert Markdown to HTML |
| `npm run build` | Full pipeline: prepare → Markdown → HTML |
| `npm run lint` | Run ESLint |
| `npm run format:check` | Check Prettier formatting |

To generate Markdown for a single webpack source, invoke the processor directly:

Expand Down
91 changes: 76 additions & 15 deletions components/Footer/index.module.css
Original file line number Diff line number Diff line change
@@ -1,61 +1,122 @@
@reference "../../styles/index.css";

.footer {
@apply border-t border-neutral-900 bg-neutral-950 text-neutral-500;
@apply border-t
border-neutral-900
bg-neutral-950
text-neutral-500;
}

.inner {
@apply max-w-7xl mx-auto px-6 pt-12 pb-6;
@apply max-w-7xl
mx-auto
px-6
pt-12
pb-6;
}

.top {
@apply grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-[1.5fr_repeat(4,1fr)] lg:gap-8;
@apply grid
grid-cols-1
gap-10
sm:grid-cols-2
lg:grid-cols-[1.5fr_repeat(4,1fr)]
lg:gap-8;
}

.brand {
@apply flex flex-col gap-4 max-w-72;
@apply flex
flex-col
gap-4
max-w-72;
}

.logo {
@apply inline-flex items-center gap-2 no-underline;
@apply inline-flex
items-center
gap-2
no-underline;
}

.wordmark {
@apply text-lg font-semibold text-neutral-50;
@apply text-lg
font-semibold
text-neutral-50;
}

.tagline {
@apply m-0 text-sm leading-relaxed text-neutral-600;
@apply m-0
text-sm
leading-relaxed
text-neutral-600;
}

.section {
@apply flex flex-col gap-3.5;
@apply flex
flex-col
gap-3.5;
}

.heading {
@apply m-0 text-xs font-semibold tracking-[0.08em] uppercase text-blue-300;
@apply m-0
text-xs
font-semibold
tracking-[0.08em]
uppercase
text-blue-300;
}

.list {
@apply flex flex-col gap-2.5 m-0 p-0 list-none;
@apply flex
flex-col
gap-2.5
m-0
p-0
list-none;
}

.link {
@apply text-[0.9375rem] text-neutral-300 no-underline transition-colors duration-150 ease-in-out hover:text-blue-300;
@apply text-[0.9375rem]
text-neutral-300
no-underline
transition-colors
duration-150
ease-in-out
hover:text-blue-300;
}

.bottom {
@apply flex flex-col gap-4 items-center mt-10 pt-6 border-t border-neutral-900 sm:flex-row sm:justify-between;
@apply flex
flex-col
gap-4
items-center
mt-10
pt-6
border-t
border-neutral-900
sm:flex-row
sm:justify-between;
}

.legal {
@apply m-0 text-sm text-neutral-600;
@apply m-0
text-sm
text-neutral-600;
}

.social {
@apply flex items-center gap-4 m-0 p-0 list-none;
@apply flex
items-center
gap-4
m-0
p-0
list-none;
}

.socialLink {
@apply inline-flex text-neutral-500 transition-colors duration-150 hover:text-neutral-50;
@apply inline-flex
text-neutral-500
transition-colors
duration-150
hover:text-neutral-50;
}
28 changes: 28 additions & 0 deletions components/Icons/Diamond.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Small diamond/gem glyph used to mark a sponsorship tier.
*
* @param {import('react').SVGProps<SVGSVGElement>} props
*/
export default props => (
<svg
viewBox="0 0 24 24"
width="1em"
height="1em"
fill="none"
aria-hidden="true"
{...props}
>
<path
d="M5.5 3h13l3 5.2L12 21 2.5 8.2 5.5 3Z"
fill="currentColor"
opacity="0.18"
/>
<path
d="M5.5 3h13l3 5.2L12 21 2.5 8.2 5.5 3Zm0 0 6.5 5.2L18.5 3M2.5 8.2h19M12 21V8.2"
stroke="currentColor"
strokeWidth="1.3"
strokeLinejoin="round"
strokeLinecap="round"
/>
</svg>
);
File renamed without changes.
2 changes: 2 additions & 0 deletions components/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import DefaultLayout from '@node-core/doc-kit/src/generators/web/ui/components/Layout/index.jsx';
import HomeLayout from '../layouts/Home/index.jsx';
import SponsorsLayout from '../layouts/Sponsors/index.jsx';
import '../styles/index.css';

const LAYOUTS = {
home: HomeLayout,
sponsors: SponsorsLayout,
};

export default function Layout(props) {
Expand Down
20 changes: 20 additions & 0 deletions components/SectionHeader/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import classNames from 'classnames';

import styles from './index.module.css';

/**
* Centered section heading: an uppercase eyebrow, a title and an optional description.
*
* @param {import('react').ComponentProps<'header'> & {
* eyebrow?: import('react').ReactNode,
* title: import('react').ReactNode,
* description?: import('react').ReactNode,
* }} props
*/
export default ({ eyebrow, title, description, className, ...props }) => (
<header {...props} className={classNames(styles.header, className)}>
{eyebrow && <p className={styles.eyebrow}>{eyebrow}</p>}
<h2 className={styles.title}>{title}</h2>
{description && <p className={styles.description}>{description}</p>}
</header>
);
39 changes: 39 additions & 0 deletions components/SectionHeader/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@reference "../../styles/index.css";

.header {
@apply mx-auto
flex
max-w-2xl
flex-col
items-center
gap-3
text-center;
}

.eyebrow {
@apply m-0
text-xs
font-semibold
tracking-[0.12em]
uppercase
text-blue-600
dark:text-blue-400;
}

.title {
@apply m-0
text-3xl
font-bold
tracking-tight
text-neutral-900
sm:text-4xl
dark:text-white;
}

.description {
@apply m-0
text-base
leading-relaxed
text-neutral-600
dark:text-neutral-300;
}
Loading