forked from coracle/flotilla
642 lines
12 KiB
CSS
642 lines
12 KiB
CSS
@import "tailwindcss";
|
|
|
|
@config "../tailwind.config.js";
|
|
|
|
@theme {
|
|
--font-sans: "Lato", ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: "Baloo 2", "Lato", ui-rounded, system-ui, sans-serif;
|
|
}
|
|
|
|
/* root */
|
|
|
|
:root {
|
|
font-family: var(--font-sans);
|
|
--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));
|
|
}
|
|
|
|
@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 {
|
|
@apply pl-sai pr-sai;
|
|
}
|
|
|
|
@utility py-sai {
|
|
@apply pt-sai pb-sai;
|
|
}
|
|
|
|
@utility p-sai {
|
|
@apply py-sai px-sai;
|
|
}
|
|
|
|
@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 {
|
|
@apply ml-sai mr-sai;
|
|
}
|
|
|
|
@utility my-sai {
|
|
@apply mt-sai mb-sai;
|
|
}
|
|
|
|
@utility m-sai {
|
|
@apply my-sai mx-sai;
|
|
}
|
|
|
|
@utility top-sai {
|
|
top: var(--sait);
|
|
}
|
|
|
|
@utility right-sai {
|
|
right: var(--sair);
|
|
}
|
|
|
|
@utility bottom-sai {
|
|
bottom: var(--saib);
|
|
}
|
|
|
|
@utility left-sai {
|
|
left: var(--sail);
|
|
}
|
|
|
|
@utility card2 {
|
|
@apply rounded-box text-base-content p-4 sm:p-6;
|
|
}
|
|
|
|
@utility column {
|
|
@apply flex flex-col;
|
|
}
|
|
|
|
@utility center {
|
|
@apply flex items-center justify-center;
|
|
}
|
|
|
|
@utility row-2 {
|
|
@apply flex items-center gap-2;
|
|
}
|
|
|
|
@utility row-3 {
|
|
@apply flex items-center gap-3;
|
|
}
|
|
|
|
@utility row-4 {
|
|
@apply flex items-center gap-4;
|
|
}
|
|
|
|
@utility col-2 {
|
|
@apply flex flex-col gap-2;
|
|
}
|
|
|
|
@utility col-3 {
|
|
@apply flex flex-col gap-3;
|
|
}
|
|
|
|
@utility col-4 {
|
|
@apply flex flex-col gap-4;
|
|
}
|
|
|
|
@utility col-8 {
|
|
@apply flex flex-col gap-8;
|
|
}
|
|
|
|
@utility ellipsize {
|
|
@apply overflow-hidden text-ellipsis;
|
|
}
|
|
|
|
@utility content-padding-x {
|
|
@apply px-4 sm:px-8 md:px-12;
|
|
}
|
|
|
|
@utility content-padding-t {
|
|
@apply pt-4 sm:pt-8 md:pt-12;
|
|
}
|
|
|
|
@utility content-padding-b {
|
|
@apply pb-4 sm:pb-8 md:pb-12;
|
|
}
|
|
|
|
@utility content-padding-y {
|
|
@apply pt-4 pb-4 sm:pt-8 sm:pb-8 md:pt-12 md:pb-12;
|
|
}
|
|
|
|
@utility content-sizing {
|
|
@apply m-auto w-full max-w-3xl;
|
|
}
|
|
|
|
@utility content {
|
|
@apply m-auto w-full max-w-3xl px-4 pt-4 pb-4 sm:px-8 sm:pt-8 sm:pb-8 md:px-12 md:pt-12 md:pb-12;
|
|
}
|
|
|
|
@utility heading {
|
|
@apply font-display text-center text-2xl font-bold tracking-tight;
|
|
}
|
|
|
|
@utility brand {
|
|
@apply font-display text-primary font-bold tracking-tight;
|
|
}
|
|
|
|
@utility label {
|
|
@apply font-display text-sm font-semibold tracking-wider uppercase opacity-70;
|
|
}
|
|
|
|
@utility link {
|
|
@apply text-primary cursor-pointer underline;
|
|
}
|
|
|
|
/* content visibility */
|
|
|
|
@utility cv {
|
|
content-visibility: auto;
|
|
}
|
|
|
|
/*
|
|
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
|
so we've added these compatibility styles to make sure everything still
|
|
looks the same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add an explicit border
|
|
color utility to any element that depends on these defaults.
|
|
*/
|
|
@layer base {
|
|
*,
|
|
::after,
|
|
::before,
|
|
::backdrop,
|
|
::file-selector-button {
|
|
border-color: var(--color-gray-200, currentcolor);
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
/* Fonts */
|
|
|
|
@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: normal;
|
|
font-weight: 300;
|
|
src:
|
|
local(""),
|
|
url("/fonts/Lato-Light.ttf") format("truetype");
|
|
}
|
|
|
|
/* Lato ships Regular + Bold only; map 600 (semibold) and 700 (bold) to the
|
|
Bold file so the browser never synthesizes a faux-bold. */
|
|
@font-face {
|
|
font-family: "Lato";
|
|
font-style: normal;
|
|
font-weight: 600 700;
|
|
src:
|
|
local(""),
|
|
url("/fonts/Lato-Bold.ttf") format("truetype");
|
|
}
|
|
|
|
@font-face {
|
|
font-family: "Lato";
|
|
font-style: italic;
|
|
font-weight: 400;
|
|
src:
|
|
local(""),
|
|
url("/fonts/Lato-Italic.ttf") format("truetype");
|
|
}
|
|
|
|
/* Baloo 2 — rounded, friendly display face (self-hosted, Latin subset). */
|
|
@font-face {
|
|
font-family: "Baloo 2";
|
|
font-style: normal;
|
|
font-weight: 500;
|
|
font-display: swap;
|
|
src: url("/fonts/Baloo2-Medium.woff2") format("woff2");
|
|
}
|
|
|
|
@font-face {
|
|
font-family: "Baloo 2";
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
font-display: swap;
|
|
src: url("/fonts/Baloo2-SemiBold.woff2") format("woff2");
|
|
}
|
|
|
|
@font-face {
|
|
font-family: "Baloo 2";
|
|
font-style: normal;
|
|
font-weight: 700;
|
|
font-display: swap;
|
|
src: url("/fonts/Baloo2-Bold.woff2") format("woff2");
|
|
}
|
|
|
|
/* root */
|
|
|
|
:root {
|
|
font-family: var(--font-sans);
|
|
text-size-adjust: 100%;
|
|
--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));
|
|
}
|
|
|
|
[data-theme] {
|
|
@apply bg-base-300;
|
|
}
|
|
|
|
.mobile [data-tip]::before {
|
|
display: none !important;
|
|
}
|
|
|
|
/* safe area insets */
|
|
}
|
|
|
|
/* utilities */
|
|
|
|
.bg-alt,
|
|
.bg-alt .bg-alt .bg-alt,
|
|
.hover\:bg-alt:hover,
|
|
.bg-alt .bg-alt .hover\:bg-alt:hover,
|
|
.bg-alt .bg-alt.hover\:bg-alt:hover {
|
|
@apply bg-base-100 text-base-content transition-colors;
|
|
}
|
|
|
|
.bg-alt .bg-alt,
|
|
.bg-alt .bg-alt .bg-alt .bg-alt,
|
|
.bg-alt .hover\:bg-alt:hover,
|
|
.bg-alt .bg-alt .bg-alt .hover\:bg-alt:hover,
|
|
.bg-alt.hover\:bg-alt:hover,
|
|
.bg-alt .bg-alt .bg-alt.hover\:bg-alt:hover {
|
|
@apply bg-base-300 text-base-content transition-colors;
|
|
}
|
|
|
|
.card2.card2-sm {
|
|
@apply text-base-content p-2 sm:p-4;
|
|
}
|
|
|
|
[data-tip]::before {
|
|
@apply overflow-hidden text-ellipsis;
|
|
}
|
|
|
|
.input input::placeholder {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
/* editors */
|
|
|
|
.input-editor,
|
|
.chat-editor,
|
|
.note-editor {
|
|
@apply -m-1 p-1;
|
|
}
|
|
|
|
.tiptap {
|
|
--tiptap-object-bg: var(--color-neutral);
|
|
--tiptap-object-fg: var(--color-neutral-content);
|
|
--tiptap-active-bg: var(--color-primary);
|
|
--tiptap-active-fg: var(--color-primary-content);
|
|
}
|
|
|
|
.tiptap-suggestions {
|
|
--tiptap-object-bg: var(--color-base-100);
|
|
--tiptap-object-fg: var(--color-base-content);
|
|
--tiptap-active-bg: var(--color-base-300);
|
|
--tiptap-active-fg: var(--color-base-content);
|
|
}
|
|
|
|
.tiptap-suggestions__item {
|
|
@apply border-base-100 border-l-2 border-solid;
|
|
}
|
|
|
|
.tiptap-suggestions__selected {
|
|
@apply border-primary;
|
|
}
|
|
|
|
.tiptap {
|
|
@apply max-h-[350px] min-h-10 overflow-y-auto p-2 px-4;
|
|
}
|
|
|
|
.tiptap p.is-editor-empty:first-child::before {
|
|
opacity: 40%;
|
|
}
|
|
|
|
.chat-editor .tiptap {
|
|
@apply bg-base-300 rounded-[1.5rem] pr-12 transition-shadow;
|
|
}
|
|
|
|
.chat-editor:focus-within .tiptap {
|
|
box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-primary), transparent 55%);
|
|
}
|
|
|
|
.note-editor .tiptap {
|
|
--tiptap-object-bg: var(--color-base-200);
|
|
@apply input rounded-box block h-auto min-h-32 w-full p-[.65rem] pb-6;
|
|
}
|
|
|
|
.input-editor .tiptap {
|
|
--tiptap-object-bg: var(--color-base-200);
|
|
@apply input block h-auto p-[.65rem];
|
|
}
|
|
|
|
/* link-content, based on tiptap */
|
|
|
|
.link-content {
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
border-radius: 3px;
|
|
padding: 0 0.25rem;
|
|
background-color: var(--color-base-100);
|
|
color: var(--color-base-content);
|
|
}
|
|
|
|
/* content rendered by welshman/content */
|
|
|
|
.welshman-content a {
|
|
@apply link;
|
|
}
|
|
|
|
.welshman-content-error a {
|
|
@apply underline;
|
|
}
|
|
|
|
/* date input */
|
|
|
|
.picker {
|
|
--date-picker-foreground: var(--color-base-content);
|
|
--date-picker-background: var(--color-base-300);
|
|
--date-picker-highlight-border: var(--color-primary);
|
|
--date-picker-selected-color: var(--color-primary-content);
|
|
--date-picker-selected-background: var(--color-primary);
|
|
}
|
|
|
|
.date-time-field {
|
|
@apply input rounded-lg px-0;
|
|
}
|
|
|
|
.date-time-field input {
|
|
@apply h-full! w-full! rounded-lg! border-none! bg-inherit! px-4! text-inherit!;
|
|
}
|
|
|
|
/* tippy popover */
|
|
|
|
.tippy-target {
|
|
@apply z-tooltip pointer-events-none fixed inset-0;
|
|
}
|
|
|
|
.tippy-target > * {
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.tippy-box {
|
|
@apply rounded-box shadow-xl;
|
|
}
|
|
|
|
/* emoji picker */
|
|
|
|
emoji-picker {
|
|
--background: var(--color-base-100);
|
|
--border-color: var(--color-base-100);
|
|
--border-radius: var(--rounded-box);
|
|
--button-active-background: var(--color-base-content);
|
|
--button-hover-background: var(--color-base-content);
|
|
--indicator-color: var(--color-base-content);
|
|
--input-border-color: var(--color-base-100);
|
|
--input-font-color: var(--color-base-content);
|
|
--outline-color: var(--color-base-100);
|
|
}
|
|
|
|
/* progress */
|
|
|
|
progress[value]::-webkit-progress-value {
|
|
transition: width 0.5s;
|
|
}
|
|
|
|
/* content width for fixed elements */
|
|
|
|
.left-content {
|
|
@apply md:left-[calc(18.5rem+var(--sail))];
|
|
}
|
|
|
|
.left-content-full {
|
|
@apply md:left-[calc(3.5rem+var(--sail))];
|
|
}
|
|
|
|
/* Keyboard open state adjustments */
|
|
|
|
body.keyboard-open {
|
|
--saib: 0px;
|
|
}
|
|
|
|
body.keyboard-open .hide-on-keyboard {
|
|
display: none;
|
|
}
|
|
|
|
body.keyboard-open .chat__compose {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* chat view */
|
|
|
|
.chat__compose {
|
|
@apply z-compose relative mb-14 shrink-0 md:mb-0;
|
|
}
|
|
|
|
.chat__compose .chat__compose-inner {
|
|
@apply min-w-0;
|
|
}
|
|
|
|
.chat__scroll-down {
|
|
@apply pb-sai z-feature fixed right-4 bottom-28 md:bottom-16;
|
|
}
|
|
|
|
/* shape, depth & motion */
|
|
|
|
/* Accessibility: neutralize all motion when the user asks for it. Decorative
|
|
motion is otherwise opt-in via `motion-safe:` and the guards below. */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|
|
|
|
/* Soft, diffuse elevation — replaces ad-hoc hard `shadow-md` uses. */
|
|
@utility shadow-soft {
|
|
box-shadow:
|
|
0 4px 16px -4px oklch(0% 0 0 / 0.18),
|
|
0 1px 3px oklch(0% 0 0 / 0.08);
|
|
}
|
|
|
|
/* Organic "hand-drawn" avatar masks. The image (or gradient fallback) fills
|
|
the blob; three variants are chosen deterministically by pubkey hash so a
|
|
person's shape stays stable across the app. */
|
|
@utility avatar-blob {
|
|
border-radius: 42% 58% 54% 46% / 58% 46% 54% 42%;
|
|
}
|
|
@utility avatar-blob-2 {
|
|
border-radius: 60% 40% 46% 54% / 43% 57% 43% 57%;
|
|
}
|
|
@utility avatar-blob-3 {
|
|
border-radius: 47% 53% 62% 38% / 50% 62% 38% 50%;
|
|
}
|
|
|
|
/* Friendly rounded-square for space / relay / room tiles. */
|
|
@utility squircle {
|
|
border-radius: 30%;
|
|
}
|
|
|
|
/* Every DaisyUI button speaks in the rounded display voice and presses in. */
|
|
.btn {
|
|
font-family: var(--font-display);
|
|
font-weight: 600;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.btn {
|
|
transition:
|
|
transform 150ms ease,
|
|
box-shadow 150ms ease,
|
|
background-color 150ms ease,
|
|
border-color 150ms ease;
|
|
}
|
|
.btn:active {
|
|
transform: scale(0.96);
|
|
}
|
|
}
|
|
|
|
/* ---- Motion vocabulary ---- */
|
|
@keyframes nav-button-pop {
|
|
0% {
|
|
transform: scale(0.9);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
@keyframes button-pop {
|
|
0% {
|
|
transform: scale(0.97);
|
|
}
|
|
40% {
|
|
transform: scale(1.02);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
@keyframes pop {
|
|
0% {
|
|
transform: scale(0);
|
|
}
|
|
70% {
|
|
transform: scale(1.1);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
@keyframes reaction-pop {
|
|
0% {
|
|
transform: scale(0.6);
|
|
}
|
|
60% {
|
|
transform: scale(1.15);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
@keyframes float {
|
|
0%,
|
|
100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-6px);
|
|
}
|
|
}
|
|
@keyframes wiggle {
|
|
0%,
|
|
100% {
|
|
transform: rotate(0deg);
|
|
}
|
|
25% {
|
|
transform: rotate(-4deg);
|
|
}
|
|
75% {
|
|
transform: rotate(4deg);
|
|
}
|
|
}
|
|
@keyframes shimmer {
|
|
0% {
|
|
background-position: -200% 0;
|
|
}
|
|
100% {
|
|
background-position: 200% 0;
|
|
}
|
|
}
|
|
|
|
@utility animate-pop {
|
|
animation: pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
}
|
|
@utility animate-reaction-pop {
|
|
animation: reaction-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
}
|
|
@utility animate-float {
|
|
animation: float 6s ease-in-out infinite;
|
|
}
|
|
@utility animate-wiggle {
|
|
animation: wiggle 0.4s ease-in-out;
|
|
}
|