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
7 changes: 3 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,12 @@ Ghost Admin uses **TailwindCSS v4** via the `@tailwindcss/vite` plugin. CSS proc
@import "./preflight.css";
@import "tailwindcss/utilities.css";
@import "tw-animate-css";

@config "./tailwind.config.cjs";
@import "./tailwind.theme.css";
```

**Why unlayered:** Ember's legacy CSS (`.flex`, `.hidden`, etc.) is unlayered. If Tailwind utilities were in a `@layer`, they would lose to Ember's unlayered CSS in the cascade. Keeping both unlayered means source order determines specificity.

The `@config` bridge loads `tailwind.config.cjs` for the custom theme (colors, spacing, shadows, etc.). `tw-animate-css` is the v4 replacement for `tailwindcss-animate`.
Theme tokens/variants/animations are defined in CSS (`apps/shade/tailwind.theme.css` + runtime vars in `styles.css`), so there is no JS `@config` bridge in the Admin runtime lane. `tw-animate-css` is the v4 replacement for `tailwindcss-animate`.

### Critical Rule: Embedded Apps Must NOT Import Shade Independently

Expand All @@ -202,7 +201,7 @@ Public-facing apps (`comments-ui`, `signup-form`, `sodo-search`, `portal`, `anno

### Legacy Apps

`admin-x-design-system` and `admin-x-settings` keep TW v3 dependencies for their own Storybook builds. Their source files are consumed via `@source` in admin's v4 pipeline for production.
`admin-x-design-system` and `admin-x-settings` are consumed via `@source` in admin's centralized v4 pipeline for production, and both packages build with CSS-first Tailwind v4 setup.

## Code Guidelines

Expand Down
15 changes: 9 additions & 6 deletions apps/activitypub/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-env node */
const tailwindConfig = `${__dirname}/tailwind.config.cjs`;
const tailwindCssConfig = `${__dirname}/../admin/src/index.css`;

module.exports = {
root: true,
Expand All @@ -16,6 +16,9 @@ module.exports = {
settings: {
react: {
version: 'detect'
},
tailwindcss: {
config: tailwindCssConfig
}
},
rules: {
Expand Down Expand Up @@ -53,12 +56,12 @@ module.exports = {
'react/no-array-index-key': 'error',
'react/jsx-key': 'off',

'tailwindcss/classnames-order': ['error', {config: tailwindConfig}],
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: tailwindConfig}],
'tailwindcss/enforces-shorthand': ['warn', {config: tailwindConfig}],
'tailwindcss/migration-from-tailwind-2': ['warn', {config: tailwindConfig}],
'tailwindcss/classnames-order': 'off',
'tailwindcss/enforces-negative-arbitrary-values': 'warn',
'tailwindcss/enforces-shorthand': 'warn',
'tailwindcss/migration-from-tailwind-2': 'warn',
'tailwindcss/no-arbitrary-value': 'off',
'tailwindcss/no-custom-classname': 'off',
'tailwindcss/no-contradicting-classname': ['error', {config: tailwindConfig}]
'tailwindcss/no-contradicting-classname': 'error'
}
};
54 changes: 0 additions & 54 deletions apps/activitypub/tailwind.config.cjs

This file was deleted.

15 changes: 9 additions & 6 deletions apps/admin-x-design-system/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const tailwindConfig = `${__dirname}/tailwind.config.cjs`;
const tailwindCssConfig = `${__dirname}/../admin/src/index.css`;

module.exports = {
extends: [
Expand All @@ -14,6 +14,9 @@ module.exports = {
settings: {
react: {
version: 'detect'
},
tailwindcss: {
config: tailwindCssConfig
}
},
rules: {
Expand All @@ -35,12 +38,12 @@ module.exports = {
// Enforce kebab-case (lowercase with hyphens) for all filenames
'ghost/filenames/match-regex': ['error', '^[a-z0-9.-]+$', false],

'tailwindcss/classnames-order': ['error', {config: tailwindConfig}],
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: tailwindConfig}],
'tailwindcss/enforces-shorthand': ['warn', {config: tailwindConfig}],
'tailwindcss/migration-from-tailwind-2': ['warn', {config: tailwindConfig}],
'tailwindcss/classnames-order': 'off',
'tailwindcss/enforces-negative-arbitrary-values': 'warn',
'tailwindcss/enforces-shorthand': 'warn',
'tailwindcss/migration-from-tailwind-2': 'warn',
'tailwindcss/no-arbitrary-value': 'off',
'tailwindcss/no-custom-classname': 'off',
'tailwindcss/no-contradicting-classname': ['error', {config: tailwindConfig}]
'tailwindcss/no-contradicting-classname': 'error'
}
};
11 changes: 4 additions & 7 deletions apps/admin-x-design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
},
"files": [
"es",
"types",
"tailwind.cjs",
"tailwind.config.cjs"
"types"
],
"devDependencies": {
"@codemirror/lang-html": "6.4.11",
Expand All @@ -38,8 +36,7 @@
"@storybook/react": "8.6.14",
"@storybook/react-vite": "8.6.14",
"@storybook/testing-library": "0.2.2",
"@tailwindcss/forms": "0.5.10",
"@tailwindcss/line-clamp": "0.4.4",
"@tailwindcss/postcss": "^4",
"@testing-library/react": "14.3.1",
"@testing-library/react-hooks": "8.0.1",
"@types/lodash-es": "4.17.12",
Expand All @@ -49,7 +46,7 @@
"chai": "4.5.0",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-react-refresh": "0.4.24",
"eslint-plugin-tailwindcss": "3.18.2",
"eslint-plugin-tailwindcss": "4.0.0-beta.0",
"jsdom": "28.1.0",
"lodash-es": "4.17.21",
"postcss": "8.5.6",
Expand All @@ -59,7 +56,7 @@
"rollup-plugin-node-builtins": "2.1.2",
"sinon": "18.0.1",
"storybook": "8.6.14",
"tailwindcss": "3.4.18",
"tailwindcss": "^4",
"typescript": "5.8.3",
"validator": "13.12.0",
"vite": "5.4.20",
Expand Down
3 changes: 1 addition & 2 deletions apps/admin-x-design-system/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
'@tailwindcss/postcss': {},
autoprefixer: {}
}
};
122 changes: 122 additions & 0 deletions apps/admin-x-design-system/styles.base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
@import './preflight.css';

@import 'tailwindcss/theme.css';
@import '@tryghost/shade/tailwind.theme.css';

@import url(https://fonts.bunny.net/css?family=cardo:400,700);
@import url(https://fonts.bunny.net/css?family=manrope:300,500,700);
@import url(https://fonts.bunny.net/css?family=merriweather:300,700);
@import url(https://fonts.bunny.net/css?family=nunito:400,600,700);
@import url(https://fonts.bunny.net/css?family=old-standard-tt:400,700);
@import url(https://fonts.bunny.net/css?family=prata:400);
@import url(https://fonts.bunny.net/css?family=roboto:400,500,700);
@import url(https://fonts.bunny.net/css?family=rufina:400,500,700);
@import url(https://fonts.bunny.net/css?family=tenor-sans:400);
@import url(https://fonts.bunny.net/css?family=space-grotesk:700);
@import url(https://fonts.bunny.net/css?family=chakra-petch:400);
@import url(https://fonts.bunny.net/css?family=noto-sans:400,700);
@import url(https://fonts.bunny.net/css?family=poppins:400,700);
@import url(https://fonts.bunny.net/css?family=fira-sans:400,700);
@import url(https://fonts.bunny.net/css?family=inter:400,700);
@import url(https://fonts.bunny.net/css?family=noto-serif:400,700);
@import url(https://fonts.bunny.net/css?family=lora:400,700);
@import url(https://fonts.bunny.net/css?family=ibm-plex-serif:400,700);
@import url(https://fonts.bunny.net/css?family=space-mono:400,700);
@import url(https://fonts.bunny.net/css?family=fira-mono:400,700);
@import url(https://fonts.bunny.net/css?family=jetbrains-mono:400,700);

/* Defaults */
@layer base {
/* This just serves as a placeholder; we actually load Inter from a font file in Ember admin */
@font-face {
font-family: "Inter";
src: local("Inter") format("truetype-variations");
font-weight: 100 900;
}

.admin-x-base {
& {
@apply font-sans text-black text-base leading-normal;
}

h1, h2, h3, h4, h5 {
@apply font-bold tracking-tight leading-tighter;
}

h1 {
@apply text-4xl leading-supertight;
}

h2 {
@apply text-2xl;
}

h3 {
@apply text-xl;
}

h4 {
@apply text-lg;
}

h5 {
@apply text-md leading-supertight;
}

h6 {
@apply text-md leading-normal;
}
}
}

.admin-x-base {
line-height: 1.5;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;

text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
letter-spacing: unset;

height: 100vh;
width: 100%;
overflow-x: hidden;
overflow-y: auto;
}


/*
Used to be for fixed bottom mobile menu bar
@media (max-width: 800px) {
.admin-x-base {
height: calc(100vh - 55px);
}
} */

.dark .admin-x-base {
color: #FAFAFB;
}

.dark .admin-x-base .gh-loading-orb-container {
background-color: #000000;
}

.dark .admin-x-base .gh-loading-orb {
filter: invert(100%);
}

.admin-x-base .no-scrollbar::-webkit-scrollbar {
display: none; /* Chrome */
}

.admin-x-base .no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}

/* Prose classes are for formatting arbitrary HTML that comes from the API */
.gh-prose-links a {
color: #30CF43;
}
6 changes: 3 additions & 3 deletions apps/admin-x-design-system/styles.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@import './preflight.css';

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
@import 'tailwindcss/theme.css';
@import '@tryghost/shade/tailwind.theme.css';
@import 'tailwindcss/utilities.css';

@import url(https://fonts.bunny.net/css?family=cardo:400,700);
@import url(https://fonts.bunny.net/css?family=manrope:300,500,700);
Expand Down
7 changes: 0 additions & 7 deletions apps/admin-x-design-system/tailwind.cjs

This file was deleted.

Loading
Loading