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:
+144
-125
@@ -86,57 +86,166 @@
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
body {
|
||||
@apply bg-background-light dark:bg-background-dark;
|
||||
@apply text-foreground-light dark:text-foreground-dark;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
/*
|
||||
* 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 { ... }`.
|
||||
*/
|
||||
|
||||
.tox-tinymce {
|
||||
@apply w-full !rounded-default !border-slate-300 dark:!border-white/20;
|
||||
}
|
||||
@layer base {
|
||||
body {
|
||||
@apply bg-background-light dark:bg-background-dark;
|
||||
@apply text-foreground-light dark:text-foreground-dark;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* .moving-object {
|
||||
@apply !bg-green-500;
|
||||
} */
|
||||
option {
|
||||
@apply dark:bg-background-dark;
|
||||
}
|
||||
|
||||
option {
|
||||
@apply dark:bg-background-dark;
|
||||
}
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.mobile-paper-hidden {
|
||||
@apply max-md:p-0 max-md:border-none max-md:bg-transparent;
|
||||
}
|
||||
ul {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
@apply w-2;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
@apply bg-gray rounded-full dark:bg-gray;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
@apply w-2;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
@apply bg-foreground-light/40 rounded-full hover:bg-foreground-light/60;
|
||||
@apply dark:bg-foreground-dark/40 rounded-full hover:bg-foreground-dark/60;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
@apply bg-gray rounded-full dark:bg-gray;
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: theme("colors.gray.400") theme("colors.gray.100");
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
@apply bg-foreground-light/40 rounded-full hover:bg-foreground-light/60;
|
||||
@apply dark:bg-foreground-dark/40 rounded-full hover:bg-foreground-dark/60;
|
||||
}
|
||||
|
||||
@supports (selector(:where(*))) {
|
||||
:where(*) {
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: theme("colors.gray.400") theme("colors.gray.100");
|
||||
}
|
||||
|
||||
.dark :where(*) {
|
||||
scrollbar-color: theme("colors.gray.500") theme("colors.gray.800");
|
||||
@supports (selector(:where(*))) {
|
||||
:where(*) {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: theme("colors.gray.400") theme("colors.gray.100");
|
||||
}
|
||||
|
||||
.dark :where(*) {
|
||||
scrollbar-color: theme("colors.gray.500") theme("colors.gray.800");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.mobile-paper-hidden {
|
||||
@apply max-md:p-0 max-md:border-none max-md:bg-transparent;
|
||||
}
|
||||
|
||||
.normal-text {
|
||||
@apply text-foreground-light dark:text-foreground-dark;
|
||||
}
|
||||
|
||||
/* Assistant replies in `elements/ai/AIChat`. Scoped, since Tailwind's
|
||||
preflight strips the default styles of the elements markdown produces */
|
||||
.twui-ai-chat-markdown {
|
||||
@apply flex flex-col gap-3 leading-7 break-words min-w-0;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown > * {
|
||||
@apply m-0;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h1 {
|
||||
@apply text-2xl font-bold mt-2;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h2 {
|
||||
@apply text-xl font-bold mt-2;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h3,
|
||||
.twui-ai-chat-markdown h4,
|
||||
.twui-ai-chat-markdown h5,
|
||||
.twui-ai-chat-markdown h6 {
|
||||
@apply text-base font-semibold mt-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown ul,
|
||||
.twui-ai-chat-markdown ol {
|
||||
@apply ml-5 flex flex-col gap-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown li > ul,
|
||||
.twui-ai-chat-markdown li > ol {
|
||||
@apply mt-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown a {
|
||||
@apply text-link dark:text-link-dark underline;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown blockquote {
|
||||
@apply border-l-4 border-solid border-slate-300 dark:border-white/20 pl-4 opacity-80;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown hr {
|
||||
@apply border-slate-200 dark:border-white/10;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown :not(pre) > code {
|
||||
@apply px-1.5 py-0.5 rounded-default-sm text-[0.875em];
|
||||
@apply bg-slate-100 dark:bg-white/10;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown-table {
|
||||
@apply w-full overflow-x-auto;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown table {
|
||||
@apply w-full border-collapse text-sm;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown th,
|
||||
.twui-ai-chat-markdown td {
|
||||
@apply border border-solid border-slate-200 dark:border-white/10 px-3 py-1.5 text-left;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown th {
|
||||
@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;
|
||||
}
|
||||
@@ -173,93 +282,3 @@ option {
|
||||
.ace_gutter-active-line {
|
||||
@apply dark:!bg-white/5;
|
||||
}
|
||||
|
||||
.normal-text {
|
||||
@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
|
||||
preflight strips the default styles of the elements markdown produces */
|
||||
.twui-ai-chat-markdown {
|
||||
@apply flex flex-col gap-3 leading-7 break-words min-w-0;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown > * {
|
||||
@apply m-0;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h1 {
|
||||
@apply text-2xl font-bold mt-2;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h2 {
|
||||
@apply text-xl font-bold mt-2;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown h3,
|
||||
.twui-ai-chat-markdown h4,
|
||||
.twui-ai-chat-markdown h5,
|
||||
.twui-ai-chat-markdown h6 {
|
||||
@apply text-base font-semibold mt-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown ul,
|
||||
.twui-ai-chat-markdown ol {
|
||||
@apply ml-5 flex flex-col gap-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown li > ul,
|
||||
.twui-ai-chat-markdown li > ol {
|
||||
@apply mt-1;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown a {
|
||||
@apply text-link dark:text-link-dark underline;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown blockquote {
|
||||
@apply border-l-4 border-solid border-slate-300 dark:border-white/20 pl-4 opacity-80;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown hr {
|
||||
@apply border-slate-200 dark:border-white/10;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown :not(pre) > code {
|
||||
@apply px-1.5 py-0.5 rounded-default-sm text-[0.875em];
|
||||
@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 {
|
||||
@apply w-full overflow-x-auto;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown table {
|
||||
@apply w-full border-collapse text-sm;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown th,
|
||||
.twui-ai-chat-markdown td {
|
||||
@apply border border-solid border-slate-200 dark:border-white/10 px-3 py-1.5 text-left;
|
||||
}
|
||||
|
||||
.twui-ai-chat-markdown th {
|
||||
@apply font-semibold bg-slate-50 dark:bg-white/5;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user