Move base.css rules into cascade layers so utility classes win
Unlayered CSS beats Tailwind's @layer utilities regardless of specificity, so base.css (and consumer stylesheets) overrode classes passed to components. Element defaults now live in @layer base and twui-* rules in @layer components. Third-party TinyMCE/Ace overrides stay unlayered. README documents wrapping consumer overrides in layers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -44,11 +44,31 @@ Import `base.css` once in your main stylesheet. It includes `@import "tailwindcs
|
|||||||
/* ...see base.css for the full list of tokens */
|
/* ...see base.css for the full list of tokens */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Element defaults */
|
||||||
|
@layer base {
|
||||||
|
h1 {
|
||||||
|
@apply text-5xl font-bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Templates for twui components */
|
||||||
|
@layer components {
|
||||||
.twui-button-general {
|
.twui-button-general {
|
||||||
@apply rounded-full;
|
@apply rounded-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.twui-section {
|
||||||
|
@apply py-20;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Overriding with utility classes
|
||||||
|
|
||||||
|
Put your own rules inside `@layer base` (element selectors like `h1`, `ul`) or `@layer components` (classes like `.twui-*`). Tailwind's utilities come in the later `utilities` layer, so a class passed to a component (`<Section className="py-4">`) overrides your stylesheet without `!important`.
|
||||||
|
|
||||||
|
CSS outside any `@layer` beats every layered rule regardless of specificity. A bare `.twui-section { @apply py-44; }` would therefore override `className="py-4"` on every `Section`, which is why these rules belong in a layer.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Import from the root entry:
|
Import from the root entry:
|
||||||
|
|||||||
+80
-61
@@ -86,26 +86,37 @@
|
|||||||
|
|
||||||
@custom-variant dark (&:where(.dark, .dark *));
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cascade layers: Tailwind v4 puts its utilities in `@layer utilities`, and
|
||||||
|
* any CSS outside a layer beats every layered rule regardless of specificity.
|
||||||
|
* Everything here that styles our own markup lives in `base` or `components`,
|
||||||
|
* so utility classes passed to (or written in) a component always win over
|
||||||
|
* it without `!important`. Consumers should do the same in their own
|
||||||
|
* stylesheet: wrap `.twui-*` overrides in `@layer components { ... }`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@layer base {
|
||||||
body {
|
body {
|
||||||
@apply bg-background-light dark:bg-background-dark;
|
@apply bg-background-light dark:bg-background-dark;
|
||||||
@apply text-foreground-light dark:text-foreground-dark;
|
@apply text-foreground-light dark:text-foreground-dark;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tox-tinymce {
|
|
||||||
@apply w-full !rounded-default !border-slate-300 dark:!border-white/20;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* .moving-object {
|
|
||||||
@apply !bg-green-500;
|
|
||||||
} */
|
|
||||||
|
|
||||||
option {
|
option {
|
||||||
@apply dark:bg-background-dark;
|
@apply dark:bg-background-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-paper-hidden {
|
ol {
|
||||||
@apply max-md:p-0 max-md:border-none max-md:bg-transparent;
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-left: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
@@ -136,61 +147,17 @@ option {
|
|||||||
scrollbar-color: theme("colors.gray.500") theme("colors.gray.800");
|
scrollbar-color: theme("colors.gray.500") theme("colors.gray.800");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_editor {
|
|
||||||
@apply dark:bg-background-dark;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tox-editor-header,
|
@layer components {
|
||||||
.tox-toolbar-overlord,
|
.mobile-paper-hidden {
|
||||||
.tox .tox-toolbar,
|
@apply max-md:p-0 max-md:border-none max-md:bg-transparent;
|
||||||
.tox .tox-toolbar__overflow,
|
|
||||||
.tox .tox-toolbar__primary,
|
|
||||||
.tox .tox-tbtn,
|
|
||||||
.tox .tox-sidebar,
|
|
||||||
.tox .tox-statusbar,
|
|
||||||
.tox .tox-view-wrap,
|
|
||||||
.tox .tox-view-wrap__slot-container,
|
|
||||||
.tox .tox-editor-container,
|
|
||||||
.tox .tox-edit-area__iframe,
|
|
||||||
.twui-tinymce {
|
|
||||||
@apply dark:!bg-background-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twui-tinymce *:focus {
|
|
||||||
@apply !outline-white/10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tox .tox-tbtn:hover {
|
|
||||||
@apply dark:!bg-white/10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_gutter {
|
|
||||||
@apply dark:!bg-background-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_active-line,
|
|
||||||
.ace_gutter-active-line {
|
|
||||||
@apply dark:!bg-white/5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.normal-text {
|
.normal-text {
|
||||||
@apply text-foreground-light dark:text-foreground-dark;
|
@apply text-foreground-light dark:text-foreground-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol {
|
|
||||||
list-style: decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style: disc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul,
|
|
||||||
ol {
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assistant replies in `elements/ai/AIChat`. Scoped, since Tailwind's
|
/* Assistant replies in `elements/ai/AIChat`. Scoped, since Tailwind's
|
||||||
preflight strips the default styles of the elements markdown produces */
|
preflight strips the default styles of the elements markdown produces */
|
||||||
.twui-ai-chat-markdown {
|
.twui-ai-chat-markdown {
|
||||||
@@ -243,10 +210,6 @@ ol {
|
|||||||
@apply bg-slate-100 dark:bg-white/10;
|
@apply bg-slate-100 dark:bg-white/10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.twui-ai-chat-markdown .twui-code-block-pre {
|
|
||||||
@apply text-sm text-white whitespace-pre px-3 pt-2 pb-3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twui-ai-chat-markdown-table {
|
.twui-ai-chat-markdown-table {
|
||||||
@apply w-full overflow-x-auto;
|
@apply w-full overflow-x-auto;
|
||||||
}
|
}
|
||||||
@@ -263,3 +226,59 @@ ol {
|
|||||||
.twui-ai-chat-markdown th {
|
.twui-ai-chat-markdown th {
|
||||||
@apply font-semibold bg-slate-50 dark:bg-white/5;
|
@apply font-semibold bg-slate-50 dark:bg-white/5;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
/* Deliberately overrides CodeBlock's own utilities on its `<pre>` (e.g.
|
||||||
|
`whitespace-pre-wrap`) inside chat replies. It sits in the utilities
|
||||||
|
layer so its higher specificity beats those single-class utilities */
|
||||||
|
.twui-ai-chat-markdown .twui-code-block-pre {
|
||||||
|
@apply text-sm text-white whitespace-pre px-3 pt-2 pb-3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overrides for third-party widgets (TinyMCE, Ace). These stay unlayered on
|
||||||
|
* purpose: they have to beat the widgets' own unlayered stylesheets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.tox-tinymce {
|
||||||
|
@apply w-full !rounded-default !border-slate-300 dark:!border-white/20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_editor {
|
||||||
|
@apply dark:bg-background-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tox-editor-header,
|
||||||
|
.tox-toolbar-overlord,
|
||||||
|
.tox .tox-toolbar,
|
||||||
|
.tox .tox-toolbar__overflow,
|
||||||
|
.tox .tox-toolbar__primary,
|
||||||
|
.tox .tox-tbtn,
|
||||||
|
.tox .tox-sidebar,
|
||||||
|
.tox .tox-statusbar,
|
||||||
|
.tox .tox-view-wrap,
|
||||||
|
.tox .tox-view-wrap__slot-container,
|
||||||
|
.tox .tox-editor-container,
|
||||||
|
.tox .tox-edit-area__iframe,
|
||||||
|
.twui-tinymce {
|
||||||
|
@apply dark:!bg-background-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.twui-tinymce *:focus {
|
||||||
|
@apply !outline-white/10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tox .tox-tbtn:hover {
|
||||||
|
@apply dark:!bg-white/10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_gutter {
|
||||||
|
@apply dark:!bg-background-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_active-line,
|
||||||
|
.ace_gutter-active-line {
|
||||||
|
@apply dark:!bg-white/5;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user