2026-06-24 20:56:53 +00:00
|
|
|
/* ============================================================================
|
|
|
|
|
base.css — Tailwind token registration (theme-independent)
|
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
|
The @theme block below registers our semantic tokens with Tailwind so it
|
|
|
|
|
emits themed utilities (bg-surface, text-content, text-content-muted,
|
|
|
|
|
border-line-more, bg-primary-bold, shadow-lg, …).
|
|
|
|
|
============================================================================ */
|
|
|
|
|
|
|
|
|
|
@theme inline {
|
|
|
|
|
--color-primary: var(--primary);
|
|
|
|
|
--color-primary-soft: var(--primary-soft);
|
|
|
|
|
--color-primary-bold: var(--primary-bold);
|
|
|
|
|
--color-primary-content: var(--primary-content);
|
|
|
|
|
|
|
|
|
|
--color-secondary: var(--secondary);
|
|
|
|
|
--color-secondary-soft: var(--secondary-soft);
|
|
|
|
|
--color-secondary-bold: var(--secondary-bold);
|
|
|
|
|
--color-secondary-content: var(--secondary-content);
|
|
|
|
|
|
|
|
|
|
--color-success: var(--success);
|
|
|
|
|
--color-success-content: var(--success-content);
|
|
|
|
|
--color-warning: var(--warning);
|
|
|
|
|
--color-warning-content: var(--warning-content);
|
|
|
|
|
--color-error: var(--error);
|
|
|
|
|
--color-error-content: var(--error-content);
|
|
|
|
|
|
|
|
|
|
--color-backdrop: var(--backdrop);
|
|
|
|
|
--color-surface: var(--surface);
|
|
|
|
|
--color-surface-more: var(--surface-more);
|
|
|
|
|
--color-surface-less: var(--surface-less);
|
|
|
|
|
|
|
|
|
|
--color-content: var(--content);
|
|
|
|
|
--color-content-muted: var(--content-muted);
|
|
|
|
|
--color-content-subtle: var(--content-subtle);
|
|
|
|
|
|
|
|
|
|
--color-line: var(--line);
|
|
|
|
|
--color-line-more: var(--line-more);
|
|
|
|
|
--color-line-less: var(--line-less);
|
|
|
|
|
|
|
|
|
|
--shadow: 6px 6px 0 color-mix(in srgb, var(--primary) 12%, transparent);
|
|
|
|
|
--shadow-sm: 4px 4px 0 color-mix(in srgb, var(--primary) 10%, transparent);
|
|
|
|
|
--shadow-lg: 8px 8px 0 color-mix(in srgb, var(--primary) 15%, transparent);
|
|
|
|
|
--shadow-inset: inset 0 -4px 0 rgba(0, 0, 0, 0.05);
|
|
|
|
|
--shadow-inset-strong: inset 0 -3px 0 rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
|
|
--border-thin: 1px;
|
|
|
|
|
--border-thick: 1px;
|
|
|
|
|
|
|
|
|
|
--font-body: "Lato", sans-serif;
|
|
|
|
|
--font-heading: "Lato", sans-serif;
|
|
|
|
|
--font-fancy: "Lato", sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:root {
|
|
|
|
|
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
|
|
|
|
|
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
|
|
|
|
|
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
|
|
|
|
|
--sair: var(--safe-area-inset-right, env(safe-area-inset-right));
|
|
|
|
|
|
|
|
|
|
text-size-adjust: 100%;
|
2026-07-01 18:20:49 +00:00
|
|
|
font-size: 110%;
|
2026-06-24 20:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@layer base {
|
|
|
|
|
body {
|
|
|
|
|
@apply text-content font-body bg-surface-less;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1,
|
|
|
|
|
h2,
|
|
|
|
|
h3,
|
|
|
|
|
h4 {
|
|
|
|
|
@apply font-heading font-bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button {
|
|
|
|
|
@apply cursor-pointer text-left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input:focus,
|
|
|
|
|
textarea:focus,
|
|
|
|
|
select:focus,
|
|
|
|
|
[contenteditable]:focus {
|
|
|
|
|
@apply outline-none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
Layout helpers
|
|
|
|
|
---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
@utility heading {
|
|
|
|
|
@apply font-heading text-center text-2xl font-bold;
|
|
|
|
|
}
|
|
|
|
|
@utility subheading {
|
|
|
|
|
@apply font-heading text-center text-xl font-bold;
|
|
|
|
|
}
|
|
|
|
|
@utility superheading {
|
|
|
|
|
@apply font-heading text-center text-4xl font-extrabold;
|
|
|
|
|
}
|
|
|
|
|
@utility cv {
|
|
|
|
|
content-visibility: auto;
|
|
|
|
|
}
|
|
|
|
|
@utility pt-sai {
|
|
|
|
|
padding-top: var(--sait);
|
|
|
|
|
}
|
|
|
|
|
@utility pr-sai {
|
|
|
|
|
padding-right: var(--sair);
|
|
|
|
|
}
|
|
|
|
|
@utility pb-sai {
|
|
|
|
|
padding-bottom: var(--saib);
|
|
|
|
|
}
|
|
|
|
|
@utility pl-sai {
|
|
|
|
|
padding-left: var(--sail);
|
|
|
|
|
}
|
|
|
|
|
@utility px-sai {
|
|
|
|
|
padding-left: var(--sail);
|
|
|
|
|
padding-right: var(--sair);
|
|
|
|
|
}
|
|
|
|
|
@utility py-sai {
|
|
|
|
|
padding-top: var(--sait);
|
|
|
|
|
padding-bottom: var(--saib);
|
|
|
|
|
}
|
|
|
|
|
@utility p-sai {
|
|
|
|
|
padding: var(--sait) var(--sair) var(--saib) var(--sail);
|
|
|
|
|
}
|
|
|
|
|
@utility mt-sai {
|
|
|
|
|
margin-top: var(--sait);
|
|
|
|
|
}
|
|
|
|
|
@utility mr-sai {
|
|
|
|
|
margin-right: var(--sair);
|
|
|
|
|
}
|
|
|
|
|
@utility mb-sai {
|
|
|
|
|
margin-bottom: var(--saib);
|
|
|
|
|
}
|
|
|
|
|
@utility ml-sai {
|
|
|
|
|
margin-left: var(--sail);
|
|
|
|
|
}
|
|
|
|
|
@utility mx-sai {
|
|
|
|
|
margin-left: var(--sail);
|
|
|
|
|
margin-right: var(--sair);
|
|
|
|
|
}
|
|
|
|
|
@utility my-sai {
|
|
|
|
|
margin-top: var(--sait);
|
|
|
|
|
margin-bottom: var(--saib);
|
|
|
|
|
}
|
|
|
|
|
@utility m-sai {
|
|
|
|
|
margin: var(--sait) var(--sair) var(--saib) var(--sail);
|
|
|
|
|
}
|
|
|
|
|
@utility top-sai {
|
|
|
|
|
top: var(--sait);
|
|
|
|
|
}
|
|
|
|
|
@utility right-sai {
|
|
|
|
|
right: var(--sair);
|
|
|
|
|
}
|
|
|
|
|
@utility bottom-sai {
|
|
|
|
|
bottom: var(--saib);
|
|
|
|
|
}
|
|
|
|
|
@utility left-sai {
|
|
|
|
|
left: var(--sail);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
Keyboard-open adjustments
|
|
|
|
|
---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
body.keyboard-open {
|
|
|
|
|
--saib: 0px;
|
|
|
|
|
}
|
|
|
|
|
body.keyboard-open .hide-on-keyboard {
|
|
|
|
|
@apply hidden;
|
|
|
|
|
}
|
|
|
|
|
body.keyboard-open .room__compose {
|
|
|
|
|
@apply mb-0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
Fonts shared/default across all themes
|
|
|
|
|
---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
@font-face {
|
|
|
|
|
font-family: "Satoshis";
|
|
|
|
|
font-style: normal;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
src:
|
|
|
|
|
local(""),
|
|
|
|
|
url("/fonts/Satoshi Symbol.ttf") format("truetype");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@font-face {
|
|
|
|
|
font-family: "Lato";
|
|
|
|
|
font-style: normal;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
src:
|
|
|
|
|
local(""),
|
|
|
|
|
url("/fonts/Lato-Regular.ttf") format("truetype");
|
|
|
|
|
}
|
|
|
|
|
@font-face {
|
|
|
|
|
font-family: "Lato";
|
|
|
|
|
font-style: bold;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
src:
|
|
|
|
|
local(""),
|
|
|
|
|
url("/fonts/Lato-Bold.ttf") format("truetype");
|
|
|
|
|
}
|
|
|
|
|
@font-face {
|
|
|
|
|
font-family: "Lato";
|
|
|
|
|
font-style: italic;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
src:
|
|
|
|
|
local(""),
|
|
|
|
|
url("/fonts/Italic.ttf") format("truetype");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
Integrations — rewired onto the shared tokens (unlayered so they win over
|
|
|
|
|
third-party defaults)
|
|
|
|
|
---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* tiptap editor */
|
|
|
|
|
.input-editor,
|
|
|
|
|
.chat-editor,
|
|
|
|
|
.note-editor {
|
|
|
|
|
@apply -m-1 p-1;
|
|
|
|
|
}
|
|
|
|
|
.tiptap {
|
|
|
|
|
--tiptap-object-bg: var(--surface);
|
|
|
|
|
--tiptap-object-fg: var(--content);
|
|
|
|
|
--tiptap-active-bg: var(--primary);
|
|
|
|
|
--tiptap-active-fg: var(--primary-content);
|
|
|
|
|
@apply min-h-10 overflow-y-auto px-4 py-2;
|
|
|
|
|
max-height: 350px;
|
|
|
|
|
}
|
|
|
|
|
.tiptap-suggestions {
|
|
|
|
|
--tiptap-object-bg: var(--surface);
|
|
|
|
|
--tiptap-object-fg: var(--content);
|
|
|
|
|
--tiptap-active-bg: var(--surface-more);
|
|
|
|
|
--tiptap-active-fg: var(--content);
|
|
|
|
|
}
|
|
|
|
|
.tiptap-suggestions__item {
|
|
|
|
|
border-left: 2px solid var(--surface);
|
|
|
|
|
}
|
|
|
|
|
.tiptap-suggestions__selected {
|
|
|
|
|
border-left-color: var(--primary);
|
|
|
|
|
}
|
|
|
|
|
.tiptap p.is-editor-empty:first-child::before {
|
|
|
|
|
@apply opacity-40;
|
|
|
|
|
}
|
|
|
|
|
.chat-editor .tiptap {
|
|
|
|
|
/* standard input border, kept at 1px so the :focus border swap doesn't reflow */
|
2026-06-18 10:52:04 +00:00
|
|
|
@apply bg-surface border-line rounded-3xl border border-solid;
|
2026-06-24 20:56:53 +00:00
|
|
|
}
|
|
|
|
|
.note-editor .tiptap {
|
|
|
|
|
--tiptap-object-bg: var(--surface);
|
|
|
|
|
@apply bg-surface block h-auto min-h-32 w-full rounded-2xl;
|
|
|
|
|
border: var(--border-thin) solid var(--line);
|
|
|
|
|
padding: 0.65rem;
|
|
|
|
|
padding-bottom: 1.5rem;
|
|
|
|
|
}
|
|
|
|
|
.input-editor .tiptap {
|
|
|
|
|
--tiptap-object-bg: var(--surface);
|
|
|
|
|
@apply bg-surface block h-auto rounded-2xl;
|
|
|
|
|
border: var(--border-thin) solid var(--line);
|
|
|
|
|
padding: 0.65rem;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 21:43:00 +00:00
|
|
|
/* @svelte-plugins/datepicker — the library declares its variables on :root,
|
|
|
|
|
where chained var() references resolve immediately, and our theme tokens
|
|
|
|
|
only exist under .fl; so each color is overridden individually here. The
|
|
|
|
|
tripled selector out-specifies the component's scoped .datepicker rule. */
|
|
|
|
|
.datepicker.datepicker.datepicker {
|
|
|
|
|
--datepicker-font-family: var(--font-body);
|
|
|
|
|
--datepicker-color: var(--content);
|
|
|
|
|
--datepicker-border-color: var(--line);
|
|
|
|
|
--datepicker-state-active: var(--primary);
|
|
|
|
|
--datepicker-state-hover: var(--surface-more);
|
|
|
|
|
|
|
|
|
|
--datepicker-container-background: var(--surface);
|
|
|
|
|
--datepicker-container-border: var(--border-thin) solid var(--line);
|
|
|
|
|
|
|
|
|
|
--datepicker-calendar-header-color: var(--content);
|
|
|
|
|
--datepicker-calendar-header-text-color: var(--content);
|
|
|
|
|
--datepicker-calendar-header-month-nav-color: var(--content);
|
|
|
|
|
--datepicker-calendar-header-month-nav-background-hover: var(--surface-more);
|
|
|
|
|
--datepicker-calendar-header-year-nav-color: var(--content);
|
|
|
|
|
|
|
|
|
|
--datepicker-calendar-dow-color: var(--content-muted);
|
|
|
|
|
--datepicker-calendar-day-color: var(--content);
|
|
|
|
|
--datepicker-calendar-day-color-hover: var(--content);
|
|
|
|
|
--datepicker-calendar-day-background-hover: var(--surface-more);
|
|
|
|
|
--datepicker-calendar-day-color-disabled: var(--content-subtle);
|
|
|
|
|
--datepicker-calendar-day-other-color: var(--content-subtle);
|
|
|
|
|
--datepicker-calendar-today-border: var(--border-thin) solid var(--line-more);
|
|
|
|
|
|
|
|
|
|
/* pale wash for in-range days and the square connectors that join the
|
|
|
|
|
endpoint circles; endpoints themselves get full primary + primary-content */
|
|
|
|
|
--fl-dp-wash: color-mix(in srgb, var(--primary) 14%, var(--surface));
|
|
|
|
|
|
|
|
|
|
--datepicker-calendar-range-color: var(--content);
|
|
|
|
|
--datepicker-calendar-range-background: var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-background-disabled: var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-start-box-shadow: inset -20px 0 0 var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-end-box-shadow: inset 20px 0 0 var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-start-box-shadow-selected: inset -20px 0 0 var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-end-box-shadow-selected: inset 20px 0 0 var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-start-end-background: var(--primary);
|
|
|
|
|
--datepicker-calendar-range-start-end-color: var(--primary-content);
|
|
|
|
|
--datepicker-calendar-range-selected-background: var(--primary);
|
|
|
|
|
--datepicker-calendar-range-selected-color: var(--primary-content);
|
|
|
|
|
--datepicker-calendar-range-included-background: var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-included-box-shadow: inset 20px 0 0 var(--fl-dp-wash);
|
|
|
|
|
--datepicker-calendar-range-included-color: var(--content);
|
|
|
|
|
|
|
|
|
|
--datepicker-timepicker-input-border: var(--border-thin) solid var(--line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* While only the start of a range is picked, the cell doesn't yet have the
|
|
|
|
|
.range class, so the library's generic day-hover rule (square, gray) paints
|
|
|
|
|
over the selected circle. Keep the selected look on hover instead. The :not()
|
|
|
|
|
chain exists to out-specify that hover rule, which carries five of its own. */
|
|
|
|
|
.datepicker.datepicker.datepicker
|
|
|
|
|
.calendar
|
|
|
|
|
.date.start:not(.range):not(.other):not(.past):not(.future):not(.disabled)
|
|
|
|
|
span:hover,
|
|
|
|
|
.datepicker.datepicker.datepicker
|
|
|
|
|
.calendar
|
|
|
|
|
.date.end:not(.range):not(.other):not(.past):not(.future):not(.disabled)
|
|
|
|
|
span:hover {
|
|
|
|
|
background-color: var(--primary);
|
|
|
|
|
color: var(--primary-content);
|
|
|
|
|
border-radius: var(--datepicker-calendar-range-selected-border-radius);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hovering the picked start makes the cell both ends of a zero-width preview
|
|
|
|
|
range; the library's !important sibling rules still paint a square connector
|
|
|
|
|
shadow behind the circle, so remove it (their !important, out-specified) */
|
|
|
|
|
.datepicker.datepicker.datepicker .calendars-container .calendar .date.rangehover.start.end {
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* A freshly picked start with no end and no hover preview carries the same
|
|
|
|
|
classes as the start of a real range, so the library paints its half-cell
|
|
|
|
|
connector shadow toward a range that doesn't exist yet. The only reliable
|
|
|
|
|
distinguisher is whether the next day is in-range. */
|
|
|
|
|
.datepicker.datepicker.datepicker
|
|
|
|
|
.calendars-container
|
|
|
|
|
.calendar
|
|
|
|
|
.date.range.start:not(:has(+ .range, + .rangehover)) {
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-24 20:56:53 +00:00
|
|
|
/* link-content (tiptap pill) */
|
|
|
|
|
.link-content {
|
2026-07-06 19:55:03 +00:00
|
|
|
@apply bg-surface-more text-content max-w-full overflow-hidden px-1 text-ellipsis whitespace-nowrap;
|
2026-06-24 20:56:53 +00:00
|
|
|
border-radius: 3px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* welshman/content */
|
|
|
|
|
.welshman-content a {
|
|
|
|
|
@apply text-primary cursor-pointer underline underline-offset-2;
|
|
|
|
|
}
|
|
|
|
|
.welshman-content-error a {
|
|
|
|
|
@apply underline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* tippy popover */
|
|
|
|
|
.tippy-target {
|
|
|
|
|
@apply z-tooltip pointer-events-none fixed inset-0;
|
|
|
|
|
}
|
|
|
|
|
.tippy-target > * {
|
|
|
|
|
@apply pointer-events-auto;
|
|
|
|
|
}
|
|
|
|
|
.tippy-box {
|
|
|
|
|
@apply rounded-3xl;
|
|
|
|
|
box-shadow: var(--shadow-lg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* emoji picker */
|
|
|
|
|
emoji-picker {
|
|
|
|
|
--background: var(--surface);
|
|
|
|
|
--border-color: var(--surface-more);
|
|
|
|
|
--border-radius: var(--radius-2xl);
|
|
|
|
|
--button-active-background: var(--surface-more);
|
|
|
|
|
--button-hover-background: var(--surface);
|
|
|
|
|
--indicator-color: var(--primary);
|
|
|
|
|
--input-border-color: var(--line);
|
|
|
|
|
--input-font-color: var(--content);
|
|
|
|
|
--outline-color: var(--primary);
|
2026-07-15 21:23:43 +00:00
|
|
|
width: min(352px, calc(100vw - 2rem));
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tippy-root]:has(emoji-picker) {
|
|
|
|
|
max-width: min(352px, calc(100vw - 2rem));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tippy-box:has(emoji-picker) {
|
|
|
|
|
overflow: visible;
|
|
|
|
|
max-width: none;
|
2026-06-24 20:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* content width for fixed elements (sidebar offsets) */
|
|
|
|
|
.left-content {
|
|
|
|
|
left: var(--sail);
|
|
|
|
|
}
|
|
|
|
|
@media (min-width: 768px) {
|
|
|
|
|
.left-content {
|
|
|
|
|
left: calc(18.5rem + var(--sail));
|
|
|
|
|
}
|
|
|
|
|
}
|