Add a generated manifest, icon set, offline page and service worker that never caches authenticated HTML, plus install and update UI. Turn the rail into a drawer below md with container-query internals, dvh and safe-area handling, and reconnect the socket after visibility/network changes. Add Web Push subscriptions, presence-aware delivery, notification settings and tests.
352 lines
8.5 KiB
CSS
Executable File
352 lines
8.5 KiB
CSS
Executable File
@import "@moduletrace/twui/base.css";
|
|
|
|
/* Cobble design tokens (handoff `tokens/tokens.css`). Light on `:root`, dark
|
|
on `.dark` (twui's dark variant). Exposed to Tailwind in `@theme inline`. */
|
|
:root {
|
|
--c-paper: #fbfaf7;
|
|
--c-surface: #ffffff;
|
|
--c-sunken: #f0ede6;
|
|
--c-ink: #0e1116;
|
|
--c-ink-secondary: #5b6470;
|
|
--c-ink-disabled: #a8afb8;
|
|
--c-border: #e8e4dc;
|
|
--c-border-strong: #948e83;
|
|
--c-on-ink: #fbfaf7;
|
|
|
|
--e-1: 0 1px 2px rgba(14, 17, 22, 0.06), 0 8px 24px rgba(14, 17, 22, 0.1);
|
|
|
|
--m-fast: 120ms;
|
|
--m-base: 180ms;
|
|
--m-slow: 240ms;
|
|
}
|
|
|
|
.dark {
|
|
--c-paper: #12151a;
|
|
--c-surface: #191d24;
|
|
--c-sunken: #20252d;
|
|
--c-ink: #f4f2ec;
|
|
--c-ink-secondary: #9ca5b0;
|
|
--c-ink-disabled: #6b7280;
|
|
--c-border: #2b3138;
|
|
--c-border-strong: #616c79;
|
|
--c-on-ink: #12151a;
|
|
|
|
--e-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
:root {
|
|
--m-fast: 0ms;
|
|
--m-base: 0ms;
|
|
--m-slow: 0ms;
|
|
}
|
|
}
|
|
|
|
@theme inline {
|
|
/* Typography */
|
|
--font-sans:
|
|
"Lato", "Liberation Sans", system-ui, -apple-system, sans-serif;
|
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
|
|
/* Cobble neutrals - switch with the color scheme */
|
|
--color-paper: var(--c-paper);
|
|
--color-surface: var(--c-surface);
|
|
--color-sunken: var(--c-sunken);
|
|
--color-ink: var(--c-ink);
|
|
--color-ink-secondary: var(--c-ink-secondary);
|
|
--color-ink-disabled: var(--c-ink-disabled);
|
|
--color-hairline: var(--c-border);
|
|
--color-hairline-strong: var(--c-border-strong);
|
|
--color-on-ink: var(--c-on-ink);
|
|
|
|
/* Bot identity hues - permanent, never status */
|
|
--color-hue-ember: #e4572e;
|
|
--color-hue-amber: #e9a23b;
|
|
--color-hue-moss: #7fae3c;
|
|
--color-hue-teal: #16a394;
|
|
--color-hue-cobalt: #3b7dd8;
|
|
--color-hue-violet: #7c5cd6;
|
|
--color-hue-rose: #d6538c;
|
|
|
|
--shadow-popover: var(--e-1);
|
|
|
|
/* Cool neutral scale - remaps `slate-*` so every existing border/text
|
|
utility across the app inherits the canvas + ink palette */
|
|
--color-slate-50: #f9fafb;
|
|
--color-slate-100: #f2f4f7;
|
|
--color-slate-200: #e4e7ec;
|
|
--color-slate-300: #d0d5dd;
|
|
--color-slate-400: #98a2b3;
|
|
--color-slate-500: #667085;
|
|
--color-slate-600: #475467;
|
|
--color-slate-700: #344054;
|
|
--color-slate-800: #1d2939;
|
|
--color-slate-900: #101828;
|
|
--color-slate-950: #0c111d;
|
|
|
|
--color-background-light: #ffffff;
|
|
--color-foreground-light: #0e1116;
|
|
--color-background-dark: #12151a;
|
|
--color-foreground-dark: #f4f2ec;
|
|
|
|
/* Ink - primary actions */
|
|
--color-primary: #0e1116;
|
|
--color-primary-hover: #252a32;
|
|
--color-primary-outline: #0e1116;
|
|
--color-primary-text: #0e1116;
|
|
--color-primary-dark: #f4f2ec;
|
|
--color-primary-dark-hover: #dedad0;
|
|
--color-primary-dark-outline: #f4f2ec;
|
|
--color-primary-dark-text: #12151a;
|
|
|
|
/* Graphite - links, secondary actions */
|
|
--color-secondary: #344054;
|
|
--color-secondary-hover: #1d2939;
|
|
--color-secondary-outline: #475467;
|
|
--color-secondary-text: #344054;
|
|
--color-secondary-dark: #d0d5dd;
|
|
--color-secondary-dark-hover: #eaecf0;
|
|
--color-secondary-dark-outline: #98a2b3;
|
|
--color-secondary-dark-text: #101828;
|
|
|
|
/* Secondary ink - Cobble has no accent hue; hues belong to bots */
|
|
--color-accent: #5b6470;
|
|
--color-accent-hover: #474f5a;
|
|
--color-accent-outline: #474f5a;
|
|
--color-accent-text: #5b6470;
|
|
--color-accent-dark: #9ca5b0;
|
|
--color-accent-dark-hover: #b8bfc8;
|
|
--color-accent-dark-outline: #9ca5b0;
|
|
--color-accent-dark-text: #ffffff;
|
|
|
|
--color-dark: #0e1116;
|
|
--color-dark-hover: #191d24;
|
|
--color-dark-outline: #0e1116;
|
|
--color-dark-text: #0e1116;
|
|
--color-dark-dark: #0e1116;
|
|
--color-dark-dark-hover: #191d24;
|
|
--color-dark-dark-outline: #0e1116;
|
|
--color-dark-dark-text: #0e1116;
|
|
|
|
/* Paper - page background */
|
|
--color-light: #fbfaf7;
|
|
--color-light-hover: #f0ede6;
|
|
--color-light-outline: #e8e4dc;
|
|
--color-light-text: #fbfaf7;
|
|
--color-light-dark: #fbfaf7;
|
|
--color-light-dark-hover: #f0ede6;
|
|
--color-light-dark-outline: #e8e4dc;
|
|
--color-light-dark-text: #fbfaf7;
|
|
|
|
--color-gray: #eaecf0;
|
|
--color-gray-hover: #e4e7ec;
|
|
--color-gray-dark: #1d2939;
|
|
--color-gray-dark-hover: #344054;
|
|
|
|
--color-link: #0e1116;
|
|
--color-link-dark: #f4f2ec;
|
|
|
|
--radius-default: 8px;
|
|
--radius-default-sm: 6px;
|
|
--radius-default-xs: 4px;
|
|
--radius-default-lg: 10px;
|
|
--radius-default-xl: 14px;
|
|
|
|
--container-container: 870px;
|
|
/* The rail's full (named) width: below it the rail shows icons only.
|
|
A container query, so the mobile drawer opens full too. */
|
|
--container-rail: 220px;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-sans);
|
|
@apply bg-light dark:bg-background-dark antialiased;
|
|
}
|
|
|
|
::selection {
|
|
@apply bg-accent/20 text-dark dark:text-white;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6,
|
|
.heading {
|
|
font-family: var(--font-sans);
|
|
@apply m-0! font-semibold leading-[1.15em] tracking-tight;
|
|
}
|
|
|
|
/* Display headings: tight, heavy geometric sans */
|
|
h1,
|
|
h2 {
|
|
@apply font-semibold tracking-[-0.045em] leading-[1.02em] text-balance;
|
|
}
|
|
|
|
h1 {
|
|
@apply text-[44px]! md:text-6xl! xl:text-[76px]!;
|
|
}
|
|
|
|
h2 {
|
|
@apply text-[34px]! xl:text-5xl! tracking-[-0.04em];
|
|
}
|
|
|
|
h3 {
|
|
@apply text-lg! leading-snug;
|
|
}
|
|
|
|
h4 {
|
|
@apply text-base! leading-snug;
|
|
}
|
|
|
|
h5 {
|
|
@apply text-sm! font-semibold;
|
|
}
|
|
|
|
h6 {
|
|
@apply text-xs! font-semibold;
|
|
}
|
|
|
|
.twui-button-general {
|
|
@apply font-medium tracking-tight transition-colors;
|
|
}
|
|
|
|
.twui-button-primary {
|
|
@apply dark:text-primary-dark-text;
|
|
}
|
|
|
|
/* `primary-dark-text` is ink for the filled light button; outlined sits on the dark page */
|
|
.twui-button-primary-outlined {
|
|
@apply dark:text-primary-dark;
|
|
}
|
|
|
|
.twui-row {
|
|
@apply gap-4;
|
|
}
|
|
|
|
a {
|
|
@apply outline-none border-none text-primary dark:text-primary-dark;
|
|
}
|
|
|
|
.twui-section {
|
|
@apply py-24 xl:py-32;
|
|
}
|
|
|
|
/* Eyebrow label with an accent dot */
|
|
.htag {
|
|
@apply inline-flex items-center gap-2.5 text-sm font-medium text-slate-500 dark:text-slate-400;
|
|
@apply before:size-1.5 before:rounded-full before:bg-accent before:content-[''];
|
|
}
|
|
|
|
.twui-paper,
|
|
.twui-card {
|
|
@apply border-slate-200 shadow-xs shadow-slate-900/3;
|
|
@apply dark:border-white/10 dark:shadow-none;
|
|
}
|
|
|
|
.twui-input-wrapper {
|
|
@apply bg-white dark:bg-background-dark transition-[outline-color];
|
|
}
|
|
|
|
.twui-input-label {
|
|
@apply text-slate-500 dark:text-slate-400;
|
|
}
|
|
|
|
.twui-breadcrumb-link {
|
|
@apply text-xs!;
|
|
}
|
|
|
|
header .twui-header-link {
|
|
@apply text-slate-600 hover:text-slate-900;
|
|
}
|
|
|
|
.dark header .twui-header-link {
|
|
@apply text-white/70 hover:text-white;
|
|
}
|
|
|
|
header .twui-header-link > * > * {
|
|
@apply transition-colors;
|
|
}
|
|
|
|
footer a {
|
|
@apply text-slate-500 hover:text-slate-900 hover:opacity-100 transition-colors;
|
|
@apply dark:text-slate-400 dark:hover:text-white;
|
|
}
|
|
|
|
.header-user-dropdown * {
|
|
@apply text-dark dark:text-foreground-dark;
|
|
}
|
|
|
|
.header-user-dropdown a {
|
|
@apply text-sm;
|
|
}
|
|
|
|
.twui-anchor {
|
|
@apply text-secondary dark:text-secondary-dark;
|
|
}
|
|
|
|
footer .twui-anchor {
|
|
@apply text-slate-500 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white;
|
|
}
|
|
|
|
footer .twui-anchor.active {
|
|
@apply text-slate-900! dark:text-white! font-normal;
|
|
}
|
|
|
|
.twui-anchor.active {
|
|
@apply font-semibold opacity-100! text-dark dark:text-white;
|
|
}
|
|
|
|
/* Admin sidebar navigation */
|
|
[data-admin-nav] .twui-anchor {
|
|
@apply flex w-full items-center rounded-default px-3 py-2 text-sm text-slate-600 border-0;
|
|
@apply hover:bg-slate-900/5 hover:text-slate-900 transition-colors;
|
|
@apply dark:text-slate-400 dark:hover:bg-white/5 dark:hover:text-white;
|
|
}
|
|
|
|
[data-admin-nav] .twui-anchor svg {
|
|
@apply text-slate-400 transition-colors dark:text-slate-500;
|
|
}
|
|
|
|
[data-admin-nav] .twui-anchor.active {
|
|
@apply bg-white font-medium text-slate-900 shadow-sm shadow-slate-900/5 ring-1 ring-slate-900/5;
|
|
@apply dark:bg-white/10 dark:text-white dark:shadow-none dark:ring-white/10;
|
|
}
|
|
|
|
[data-admin-nav] .twui-anchor.active svg {
|
|
@apply text-accent;
|
|
}
|
|
|
|
#admin-main {
|
|
@apply w-full max-w-[1200px] mx-auto;
|
|
}
|
|
|
|
#admin-main section {
|
|
@apply px-5 py-8 xl:px-10 flex flex-col items-start gap-10;
|
|
}
|
|
|
|
#admin-main h1 {
|
|
@apply text-3xl! xl:text-4xl! tracking-[-0.035em];
|
|
}
|
|
|
|
#admin-main h2 {
|
|
@apply text-2xl! tracking-[-0.03em];
|
|
}
|
|
|
|
#admin-main h3 {
|
|
@apply text-lg!;
|
|
}
|
|
|
|
#admin-main h4 {
|
|
@apply text-base!;
|
|
}
|
|
|
|
#admin-main h5 {
|
|
@apply text-sm!;
|
|
}
|
|
|
|
#admin-main h6 {
|
|
@apply text-xs!;
|
|
}
|