UNPKG

tldraw

Version:

A tiny little drawing editor.

1,963 lines (1,655 loc) 37.8 kB
/* @tldraw/ui */ .tl-container { --layer-above: 1; --layer-focused-input: 10; --layer-menu-click-capture: 250; --layer-panels: 300; --layer-menus: 400; --layer-toasts: 650; --layer-cursor: 700; --layer-header-footer: 999; --layer-following-indicator: 1000; } /* -------------------------------------------------- */ /* UI Refresh */ /* -------------------------------------------------- */ /* Button */ .tlui-button { position: relative; height: 40px; min-width: 40px; padding: 0px 12px; display: flex; align-items: center; justify-content: center; background-color: transparent; border: transparent; color: currentColor; cursor: pointer; pointer-events: all; font-weight: inherit; font-family: inherit; line-height: inherit; text-rendering: optimizeLegibility; font-size: 12px; gap: 0px; color: var(--color-text-1); z-index: 0; } .tlui-button:disabled { color: var(--color-text-3); text-shadow: none; cursor: default; } .tlui-button:disabled .tlui-kbd { color: var(--color-text-3); } .tlui-button > * { position: relative; z-index: var(--layer-above); } .tlui-button__label { font-size: 12px; flex-grow: 2; text-align: left; } /* * We only want to show the focus ring if: * - the container is focused * - we're not using the mouse to interact (which is the .tl-container__no-focus-ring) */ .tl-container__focused:not(.tl-container__no-focus-ring) .tlui-button:focus-visible { border-radius: 10px; outline: 2px solid var(--color-focus); outline-offset: -5px; } .tl-container__focused:not(.tl-container__no-focus-ring) .tlui-button__tool:focus-visible { border-radius: 12px; } .tlui-slider__container:has(.tlui-slider__thumb:focus-visible) { border-radius: 10px; outline: 2px solid var(--color-focus); outline-offset: -5px; } .tlui-button::after { display: block; content: ''; position: absolute; inset: 4px; border-radius: var(--radius-2); background: var(--color-muted-2); opacity: 0; } .tlui-button__menu[data-highlighted]::after { opacity: 1; } .tlui-button[data-isactive='true']::after, .tlui-button[data-isactive='true']:not(:disabled, :focus-visible):active:after { background: var(--color-hint); opacity: 1; } .tlui-button[aria-expanded='true'][data-direction='left']:not(:hover)::after { background: linear-gradient(270deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); opacity: 1; } @media (hover: hover) { .tlui-button:not(:disabled):hover { z-index: 1; } .tlui-button:not(:disabled):hover::after { opacity: 1; } } .tlui-button__icon + .tlui-button__label { margin-left: var(--space-2); } /* Low button */ .tlui-button__low { border-radius: var(--radius-3); background-color: var(--color-low); } .tlui-button__low::after { background-color: var(--color-muted-2); opacity: 0; } @media (hover: hover) { .tlui-button__low:hover::after { opacity: 1; } } /* Primary / danger buttons */ .tlui-button__primary { color: var(--color-primary); } .tlui-button__danger { color: var(--color-warn); text-shadow: none; } @media (hover: hover) { .tlui-button__primary:not(:disabled, :focus-visible):hover { color: var(--color-primary); } .tlui-button__danger:not(:disabled, :focus-visible):hover { color: var(--color-warn); text-shadow: none; } } /* Panel button */ .tlui-button__panel { position: relative; } /* Menu button */ .tlui-button__menu { height: 40px; min-height: 40px; width: 100%; gap: 8px; margin: -4px 0px; } .tlui-button__menu::after { inset: 4px; border-radius: var(--radius-2); } .tlui-button__menu > .tlui-icon + .tlui-button__label { margin-left: 0px; } .tlui-button__menu:nth-child(1) { margin-top: 0px; } .tlui-button__menu:nth-last-child(1) { margin-bottom: 0px; } /* Menu checkbox button */ .tlui-button__checkbox { padding-left: 8px; } .tlui-button__checkbox__indicator { width: 15px; height: 15px; } /* Tool lock button */ .tlui-toolbar__lock-button { position: absolute; top: 4px; right: 0px; pointer-events: all; height: 40px; width: 40px; min-width: 0px; border-radius: var(--radius-2); } .tlui-toolbar__lock-button::after { top: 4px; left: 8px; inset: 4px; } /* Tool button */ .tlui-button__tool { position: relative; height: 48px; width: 48px; margin-left: -2px; margin-right: -2px; } .tlui-button__tool:nth-of-type(1) { margin-left: 0px; } .tlui-button__tool:nth-last-of-type(1) { margin-right: 0px; } .tlui-button__tool::after { inset: 4px; border-radius: 8px; } .tlui-button__tool[aria-pressed='true'] { color: var(--color-selected-contrast); } .tlui-button__tool[aria-pressed='true']:not(:disabled, :focus-visible):active { color: var(--color-selected-contrast); } .tlui-button__tool[aria-pressed='true']:not(:disabled)::after { background: var(--color-selected); opacity: 1; } .tlui-layout__mobile .tlui-button__tool { height: 48px; width: 43px; } .tlui-layout__mobile .tlui-button__tool > .tlui-icon { height: 16px; width: 16px; } /* Help */ .tlui-button__help { height: 32px; width: 32px; padding: 0px; min-width: 32px; border-radius: 100%; background-color: var(--color-low); border: 1px solid var(--color-low-border); } @media (hover: hover) { .tlui-button__help::after { background-color: var(--color-muted-2); border-radius: 100%; inset: 4px; } } /* Button Row */ .tlui-buttons__horizontal { display: flex; flex-direction: row; } .tlui-buttons__horizontal > * { margin-left: -2px; margin-right: -2px; } .tlui-buttons__horizontal > *:nth-child(1) { margin-left: 0px; } .tlui-buttons__horizontal > *:nth-last-child(1) { margin-right: 0px; } /* Button Grid */ .tlui-buttons__grid { display: grid; grid-template-columns: repeat(4, auto); grid-auto-flow: row; overflow: hidden; } .tlui-buttons__grid > .tlui-button { margin: -2px; } .tlui-buttons__grid > .tlui-button:nth-of-type(4n), .tlui-buttons__vertical-align > .tlui-button:nth-of-type(3n) { margin-right: 0px; } .tlui-buttons__grid > .tlui-button:nth-of-type(4n - 3) { margin-left: 0px; } .tlui-buttons__grid > .tlui-button:nth-of-type(-n + 4) { margin-top: 0px; } .tlui-buttons__grid > .tlui-button:nth-last-of-type(-n + 4) { margin-bottom: 0px; } /* Zoom button */ .tlui-zoom-menu__button { width: 60px; min-width: 60px; text-align: center; } .tlui-zoom-menu__button__pct { width: 60px; min-width: 60px; text-align: center; } /* --------------------- Layout --------------------- */ .tlui-layout { position: relative; display: grid; grid-template-columns: 1fr; grid-template-rows: minmax(0px, 1fr) auto; grid-auto-rows: auto; height: 100%; max-height: 100%; overflow: clip; pointer-events: none; user-select: none; contain: strict; z-index: var(--layer-panels); transform: translate3d(0, 0, 0); --sab: env(safe-area-inset-bottom); font-weight: 500; line-height: 1.6; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-smooth: antialiased; text-rendering: optimizeLegibility; } .tlui-layout__top { grid-column: 1; grid-row: 1; display: flex; min-width: 0px; justify-content: space-between; } .tlui-layout__top__left { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; width: 100%; height: 100%; flex: 0 1 0; } .tlui-layout__top__right { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-start; height: 100%; flex: 0 0 auto; min-width: 0px; } .scrollable, .scrollable * { pointer-events: all; touch-action: auto; overscroll-behavior: none; } /* ----------------- Helper Buttons ---------------- */ .tlui-helper-buttons { position: relative; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; width: min-content; gap: var(--space-3); margin: var(--space-2) var(--space-3); white-space: nowrap; pointer-events: none; z-index: var(--layer-panels); } /* ---------------------- Icon ---------------------- */ .tlui-icon { flex-shrink: 0; width: 18px; height: 18px; background-color: currentColor; } .tlui-icon__placeholder { flex-shrink: 0; width: 18px; height: 18px; background-color: transparent; } .tlui-icon__small { width: 15px; height: 15px; } /* --------------------- Slider --------------------- */ .tlui-slider__container { width: 100%; padding: 0px var(--space-4); } .tlui-slider { position: relative; display: flex; align-items: center; user-select: none; touch-action: none; width: 100%; } .tlui-slider__track { position: relative; flex-grow: 1; height: 44px; cursor: pointer; } .tlui-slider__track::after { display: block; position: absolute; top: calc(50% - 2px); content: ''; height: 3px; width: 100%; background-color: var(--color-muted-1); border-radius: 14px; } .tlui-slider__range { position: absolute; top: calc(50% - 2px); left: 0px; height: 3px; background-color: var(--color-selected); border-radius: 14px; } .tlui-slider__thumb { all: unset; cursor: grab; display: block; width: 18px; height: 18px; position: relative; top: -1px; background-color: var(--color-panel); border-radius: 999px; box-shadow: inset 0px 0px 0px 2px var(--color-text-1); } .tlui-slider__thumb:active { cursor: grabbing; box-shadow: inset 0px 0px 0px 2px var(--color-text-1), var(--shadow-1); } /* ----------------------- Kbd ---------------------- */ .tlui-kbd { font-family: inherit; font-size: 11px; line-height: 11px; display: grid; justify-items: center; grid-auto-flow: column; grid-template-columns: auto; grid-auto-columns: minmax(1em, auto); align-self: bottom; color: currentColor; margin-left: var(--space-4); } .tlui-kbd > span { width: 100%; text-align: center; display: inline; margin: 0px; padding: 2px; border-radius: 2px; } .tlui-kbd > span:last-child { padding-right: 0; } .tlui-kbd:not(:last-child) { margin-right: var(--space-2); } /* Focus Mode Button */ .tlui-focus-button { z-index: var(--layer-panels); pointer-events: all; } /* --------------------- Popover -------------------- */ .tlui-popover { position: relative; display: flex; align-content: stretch; } .tlui-popover__content { position: relative; max-height: calc(var(--radix-popover-content-available-height) - 8px); margin: 0px; border: none; border-radius: var(--radius-3); background-color: var(--color-panel); box-shadow: var(--shadow-3); z-index: var(--layer-menus); overflow: hidden; overflow-y: auto; touch-action: auto; overscroll-behavior: none; scrollbar-width: none; -ms-overflow-style: none; } /* -------------------------------------------------- */ /* Zones */ /* -------------------------------------------------- */ /* ------------------- Status Bar ------------------- */ .tlui-debug-panel { background-color: var(--color-low); width: 100%; display: grid; align-items: center; grid-template-columns: 1fr auto auto auto; justify-content: space-between; padding-left: var(--space-4); border-top: 1px solid var(--color-background); font-size: 12px; color: var(--color-text-1); z-index: var(--layer-panels); pointer-events: all; } .tlui-debug-panel__current-state { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .tlui-debug-panel__fps { margin-right: 8px; } .tlui-debug-panel__fps__slow { font-weight: bold; color: var(--color-warn); } .tlui-a11y-audit { border-collapse: collapse; } .tlui-a11y-audit th, .tlui-a11y-audit td { padding: 8px; border: 1px solid var(--color-low-border); } /* -------------------- Menu Zone ------------------- */ .tlui-menu-zone { position: relative; z-index: var(--layer-panels); width: fit-content; border-right: 2px solid var(--color-background); border-bottom: 2px solid var(--color-background); border-bottom-right-radius: var(--radius-4); background-color: var(--color-low); } .tlui-menu-zone *[data-state='open']:not(:hover)::after { background: linear-gradient(180deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); opacity: 1; } /* ------------------- Style Panel ------------------ */ .tlui-style-panel__wrapper { box-shadow: var(--shadow-2); border-radius: var(--radius-3); pointer-events: all; background-color: var(--color-panel); height: fit-content; max-height: 100%; margin: 8px; margin-top: 4px; touch-action: auto; overscroll-behavior: none; overflow-y: auto; overflow-x: hidden; color: var(--color-text); } /* if the style panel is the only child (ie no share menu), increase the margin */ .tlui-style-panel__wrapper:only-child { margin-top: 8px; } .tlui-style-panel { position: relative; z-index: var(--layer-panels); pointer-events: all; width: 148px; max-width: 148px; } .tlui-style-panel::-webkit-scrollbar { display: none; } .tlui-style-panel .tlui-button.select { width: 100%; } .tlui-style-panel__section { display: flex; position: relative; flex-direction: column; } .tlui-style-panel__section:nth-of-type(n + 2):not(:last-child) { border-bottom: 1px solid var(--color-divider); } .tlui-style-panel__section:empty { display: none; } .tlui-style-panel__section__common:not(:only-child) { margin-bottom: 7px; border-bottom: 1px solid var(--color-divider); } .tlui-style-panel__row { display: flex; } /* Only really used for the alignment picker */ .tlui-style-panel__row__extra-button { margin-left: -2px; } .tlui-style-panel__double-select-picker { display: flex; grid-template-columns: 1fr auto; align-items: center; padding-left: var(--space-4); color: var(--color-text-1); font-size: 12px; } .tlui-style-panel__double-select-picker-label { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; flex-grow: 2; max-width: 100%; } .tlui-style-panel .tlui-button[data-state='open']:not(:hover)::after { opacity: 1; background: linear-gradient(270deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); } /* ---------------------- Input --------------------- */ .tlui-input { background: none; margin: 0px; position: relative; z-index: var(--layer-above); height: 40px; max-height: 40px; display: flex; align-items: center; justify-content: center; font-family: inherit; font-size: 12px; font-weight: inherit; color: var(--color-text-1); padding: var(--space-4); padding-left: 0px; border: none; outline: none; text-overflow: ellipsis; width: 100%; user-select: all; text-rendering: optimizeLegibility; -webkit-user-select: auto !important; } .tlui-input__wrapper { width: 100%; height: 44px; display: flex; align-items: center; gap: var(--space-4); color: var(--color-text); } .tlui-input__wrapper > .tlui-icon { flex-shrink: 0; } /* If mobile use 16px as font size */ /* On iOS, font size under 16px in an input will make the page zoom into the input 🤦‍♂️ */ /* https://css-tricks.com/16px-or-larger-text-prevents-ios-form-zoom/ */ @media (max-width: 600px) { @supports (-webkit-touch-callout: none) { /* CSS specific to iOS devices */ .tlui-input { font-size: 16px; } } } /* ---------------- Dialog ---------------- */ .tlui-dialog__overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: var(--layer-canvas-overlays); background-color: var(--color-overlay); pointer-events: all; animation: fadeIn 0.12s ease-out; display: grid; place-items: center; overflow-y: auto; padding: 0px var(--space-3); } .tlui-dialog__content { display: flex; flex-direction: column; position: relative; cursor: default; background-color: var(--color-panel); box-shadow: var(--shadow-3); border-radius: var(--radius-3); font-size: 12px; overflow: hidden; min-width: 300px; max-width: 100%; max-height: 80%; } .tlui-dialog__header { position: relative; display: flex; align-items: center; flex: 0; z-index: var(--layer-header-footer); padding-left: var(--space-4); color: var(--color-text); height: 40px; } .tlui-dialog__header__title { flex: 1; font-weight: inherit; font-size: 12px; margin: 0px; color: var(--color-text-1); } .tlui-dialog__header__close { justify-self: flex-end; } .tlui-dialog__body { padding: var(--space-4) var(--space-4); flex: 0 1; overflow-y: auto; overflow-x: hidden; color: var(--color-text-1); user-select: all; -webkit-user-select: text; } .tlui-dialog__body a { color: var(--color-selected); } .tlui-dialog__body ul, .tlui-dialog__body ol { padding-left: 16px; display: flex; flex-direction: column; gap: var(--space-4); } .tlui-dialog__footer { position: relative; min-height: 12px; z-index: var(--layer-header-footer); } .tlui-dialog__footer__actions { display: flex; align-items: center; justify-content: flex-end; } .tlui-dialog__footer__actions > .tlui-button:nth-last-child(n + 2) { margin-right: -4px; } /* --------------------- Toolbar -------------------- */ /* Wide container */ .tlui-toolbar { grid-column: 1 / span 3; grid-row: 1; display: flex; align-items: center; justify-content: center; flex-grow: 2; padding-bottom: calc(var(--space-3) + var(--sab)); } /* Centered Content */ .tlui-toolbar__inner { position: relative; width: fit-content; display: flex; gap: var(--space-3); align-items: flex-end; } .tlui-toolbar__left { width: fit-content; } /* Row of controls + lock button */ .tlui-toolbar__extras { position: relative; z-index: var(--layer-above); width: 100%; pointer-events: none; top: 6px; height: 48px; } .tlui-toolbar__extras:empty { display: none; } .tlui-toolbar__extras__controls { display: flex; position: relative; flex-direction: row; z-index: var(--layer-above); background-color: var(--color-low); border-top-left-radius: var(--radius-4); border-top-right-radius: var(--radius-4); border: 2px solid var(--color-background); margin-left: 8px; margin-right: 0px; pointer-events: all; width: fit-content; } .tlui-toolbar__tools { display: flex; flex-direction: row; align-items: center; border-radius: var(--radius-4); z-index: var(--layer-panels); pointer-events: all; position: relative; background: var(--color-panel); box-shadow: var(--shadow-2); } .tlui-toolbar__tools__list { display: flex; flex-direction: row; align-items: center; } .tlui-toolbar__overflow { width: 40px; } .tlui-layout__mobile .tlui-toolbar__overflow { width: 32px; padding: 0px; } .tlui-toolbar *[data-state='open']:not(:hover)::after { background: linear-gradient(0deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); } .tlui-layout__mobile .tlui-toolbar { transition: transform 0.15s ease-out 0.05s; } /* -------------------- Help Zone ------------------- */ .tlui-help-menu { pointer-events: all; position: absolute; bottom: var(--space-2); right: var(--space-2); z-index: var(--layer-panels); border: 2px solid var(--color-background); border-radius: 100%; } /* ------------------ Context Menu ------------------ */ .tlui-context-menu__move-to-page__name { max-width: calc(min(300px, 35vw)); overflow: hidden; text-overflow: ellipsis; } .tlui-context-menu__move-to-page__name[data-disabled] { color: var(--color-text-3); pointer-events: none; } /* ---------------------- Menu ---------------------- */ .tlui-menu:empty { display: none; } .tlui-menu { z-index: var(--layer-menus); height: fit-content; width: fit-content; border-radius: var(--radius-3); pointer-events: all; touch-action: auto; overflow-y: auto; overscroll-behavior: none; background-color: var(--color-panel); box-shadow: var(--shadow-3); } .tlui-menu::-webkit-scrollbar { display: none; } .tlui-menu__arrow { position: relative; top: -1px; fill: var(--color-panel); stroke: var(--color-panel-contrast); stroke-width: 1px; } .tlui-menu__group { width: 100%; } .tlui-menu__group:empty { display: none; } .tlui-menu__group { border-bottom: 1px solid var(--color-divider); } .tlui-menu__group:nth-last-of-type(1) { border-bottom: none; } .tlui-menu__submenu__trigger[data-state='open']:not(:hover)::after { opacity: 1; background: linear-gradient(90deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); } .tlui-menu__submenu__trigger[data-direction='left'][data-state='open']:not(:hover)::after { opacity: 1; background: linear-gradient(270deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); } /* Menu Sizes */ .tlui-menu[data-size='large'] > .tlui-menu__group { min-width: initial; } .tlui-menu[data-size='medium'] > .tlui-menu__group { min-width: 144px; } .tlui-menu[data-size='small'] > .tlui-menu__group { min-width: 96px; } .tlui-menu[data-size='tiny'] > .tlui-menu__group { min-width: 0px; } /* ------------------ Language menu ----------------- */ .tlui-language-menu { max-height: 500px; } .tlui-language-menu::after { content: ''; display: block; position: absolute; bottom: 0px; left: 0px; right: 0px; height: 24px; background: linear-gradient( to bottom, var(--color-panel-transparent) 0%, var(--color-panel) 90%, var(--color-panel) 100% ); border-bottom-left-radius: var(--radius-3); border-bottom-right-radius: var(--radius-3); pointer-events: none; } /* ------------------ Actions Menu ------------------ */ .tlui-actions-menu { max-height: calc(100vh - 150px); } /* --------------------- Toasts --------------------- */ .tlui-toast__viewport { position: absolute; inset: 0px; margin: 0px; display: flex; align-items: flex-end; justify-content: flex-end; flex-direction: column; gap: var(--space-3); pointer-events: none; padding: 0px var(--space-3) 64px 0px; z-index: var(--layer-toasts); } .tlui-toast__viewport > * { pointer-events: all; } .tlui-toast__icon { padding-top: 11px; padding-left: var(--space-4); color: var(--color-text-1); } .tlui-toast__container { min-width: 200px; display: flex; flex-direction: row; background-color: var(--color-panel); box-shadow: var(--shadow-2); border-radius: var(--radius-3); font-size: 12px; } .tlui-toast__container[data-severity='success'] .tlui-icon { color: var(--color-success); } .tlui-toast__container[data-severity='info'] .tlui-icon { color: var(--color-info); } .tlui-toast__container[data-severity='warning'] .tlui-icon { color: var(--color-warning); } .tlui-toast__container[data-severity='error'] .tlui-icon { color: var(--color-error); } .tlui-toast__main { flex-grow: 2; max-width: 280px; } .tlui-toast__content { padding: var(--space-4); display: flex; line-height: 1.4; flex-direction: column; gap: var(--space-3); } .tlui-toast__main[data-actions='true'] .tlui-toast__content { padding-bottom: var(--space-2); } .tlui-toast__title { font-weight: bold; color: var(--color-text-1); /* this makes the default toast look better */ line-height: 16px; } .tlui-toast__description { color: var(--color-text-1); padding: var(--space-3); margin: 0px; padding: 0px; } .tlui-toast__icon + .tlui-toast__main > .tlui-toast__actions { padding-left: 0px; } .tlui-toast__actions { display: flex; flex-direction: row; justify-content: flex-start; margin-left: 0; } .tlui-toast__close { align-self: flex-end; flex-shrink: 0; } @media (prefers-reduced-motion: no-preference) { .tlui-toast__container[data-state='open'] { animation: slide-in 200ms cubic-bezier(0.785, 0.135, 0.15, 0.86); } .tlui-toast__container[data-state='closed'] { animation: hide 100ms ease-in; } .tlui-toast__container[data-swipe='move'] { transform: translateX(var(--radix-toast-swipe-move-x)); } .tlui-toast__container[data-swipe='cancel'] { transform: translateX(0); transition: transform 200ms ease-out; } .tlui-toast__container[data-swipe='end'] { animation: swipe-out 100ms ease-out; } } /* --------------------- Bottom --------------------- */ .tlui-layout__bottom { grid-row: 2; } .tlui-layout__bottom__main { width: 100%; position: relative; display: flex; align-items: flex-end; justify-content: center; } /* ------------------- Navigation ------------------- */ .tlui-navigation-panel { display: flex; width: min-content; flex-direction: column; z-index: var(--layer-panels); pointer-events: all; position: absolute; left: 0px; bottom: 0px; } .tlui-navigation-panel::before { content: ''; display: block; position: absolute; z-index: -1; inset: -2px -2px 0px 0px; border-radius: 0; border-top: 2px solid var(--color-background); border-right: 2px solid var(--color-background); border-top-right-radius: var(--radius-4); background-color: var(--color-low); } .tlui-navigation-panel__toggle .tlui-icon { opacity: 0.24; } .tlui-navigation-panel__toggle:active .tlui-icon { opacity: 1; } @media (hover: hover) { .tlui-navigation-panel__toggle:hover .tlui-icon { opacity: 1; } } .tlui-minimap { width: 100%; height: 96px; min-height: 96px; overflow: hidden; padding: var(--space-3); padding-top: 0px; } .tlui-minimap__canvas { position: relative; width: 100%; height: 100%; } /* ----------------------- ... ---------------------- */ @keyframes hide { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes slide-in { from { transform: translateX(calc(100% + var(--space-3))); } to { transform: translateX(0px); } } @keyframes swipe-out { from { transform: translateX(var(--radix-toast-swipe-end-x)); } to { transform: translateX(calc(100% + var(--space-3))); } } /* ------------------- Page Select ------------------ */ .tlui-page-menu__wrapper { position: relative; display: flex; flex-direction: column; width: 260px; height: fit-content; max-height: 50vh; } .tlui-page-menu__trigger { width: 128px; } .tlui-page-menu__header { display: flex; flex-direction: row; align-items: center; width: 100%; height: 40px; padding-left: var(--space-4); border-bottom: 1px solid var(--color-divider); } .tlui-page-menu__header > .tlui-button:nth-of-type(1) { margin-right: -4px; } .tlui-page-menu__header__title { color: var(--color-text); font-size: 12px; flex-grow: 2; } .tlui-page-menu__name { flex-grow: 2; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tlui-page-menu__list { position: relative; touch-action: auto; flex-direction: column; max-height: 100%; overflow-x: hidden; overflow-y: auto; touch-action: auto; } .tlui-page-menu__item { position: relative; } .tlui-page_menu__item__submenu[data-isediting='true'] > .tlui-button[data-state='open'] { opacity: 1; } @media (hover: hover) { .tlui-page-menu__item:hover > .tlui-page_menu__item__submenu > .tlui-button { opacity: 1; } } .tlui-page-menu__item:nth-of-type(n + 2) { margin-top: -4px; } .tlui-page-menu__item__button { width: 100%; } .tlui-page-menu__item__button:not(:only-child) { flex-grow: 2; margin-right: -2px; } .tlui-page-menu__item__button > span { display: block; flex-grow: 2; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tlui-page-menu__item__button__checkbox { padding-left: 35px; } .tlui-page-menu__item__button__check { position: absolute; left: 0px; width: 24px; padding-left: 10px; display: inline-flex; align-items: center; justify-content: center; color: var(--color-text); } .tlui-page_menu__item__sortable { position: absolute; top: 0px; left: 0px; width: 100%; height: fit-content; display: flex; flex-direction: row; align-items: center; overflow: hidden; z-index: var(--layer-above); } .tlui-page_menu__item__sortable__title { flex: 1; } .tlui-page_menu__item__sortable__title > .tlui-input__wrapper { height: 100%; } .tlui-page_menu__item__sortable:focus-visible { z-index: var(--layer-focused-input); } .tlui-page_menu__item__sortable__handle { touch-action: none; width: 32px; min-width: 0px; height: 40px; cursor: grab; color: var(--color-text-3); flex-shrink: 0; margin-right: -9px; } .tlui-page_menu__item__sortable__handle:active { cursor: grabbing; } .tlui-page-menu__item__input { margin-left: 12px; height: 100%; } /* The more menu has complex CSS here: */ /* If the user can hover, then visible but opacity zero until hover */ /* If the user cannot hover, then not displayed unless editing, and then opacity 1 */ .tlui-page_menu__item__submenu { pointer-events: all; position: absolute; right: 0px; top: 0px; height: 100%; cursor: pointer; margin: 0px; margin-left: -2px; z-index: 10; } .tlui-page_menu__item__submenu > .tlui-button { opacity: 0; } .tlui-page_menu__item__sortable:focus-visible > .tlui-page_menu__item__submenu > .tlui-button, .tlui-page_menu__item__submenu[data-isediting='true'], .tlui-page_menu__item__submenu > .tlui-button[data-state='open'], .tlui-page_menu__item__submenu > .tlui-button:focus-visible { opacity: 1; } .tlui-page_menu__item__submenu > .tlui-button[data-state='open']:not(:hover)::after { background: linear-gradient(90deg, rgba(144, 144, 144, 0) 0%, var(--color-muted-2) 100%); } @media (any-pointer: coarse) { .tlui-page_menu__item__submenu > .tlui-button { opacity: 1; } } .tlui-button__icon { padding: 0px; } .tlui-page-menu__item__button .tlui-button__icon { margin-right: 4px; } @media (hover: hover) { .tlui-page_menu__item__submenu[data-isediting='true'] > .tlui-button { opacity: 0; } .tlui-page_menu__item__submenu:hover > .tlui-button { opacity: 1; } } /* --------------------- Dialogs -------------------- */ /* Edit Link Dialog */ .tlui-edit-link-dialog { display: flex; flex-direction: column; gap: var(--space-4); color: var(--color-text); } .tlui-edit-link-dialog__input { background-color: var(--color-muted-2); flex-grow: 2; border-radius: var(--radius-2); padding: 0px var(--space-4); } /* Embed Dialog */ .tlui-embed__spacer { flex-grow: 2; min-height: 0px; margin-left: calc(-1 * var(--space-4)); margin-top: calc(-1 * var(--space-4)); pointer-events: none; } .tlui-embed-dialog__list { display: flex; flex-direction: column; padding-bottom: var(--space-5); } .tlui-embed-dialog__item__image { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; background-size: contain; background-repeat: no-repeat; background-position: center center; } .tlui-embed-dialog__enter { display: flex; flex-direction: column; gap: var(--space-4); color: var(--color-text-1); } .tlui-embed-dialog__input { background-color: var(--color-muted-2); flex-grow: 2; border-radius: var(--radius-2); padding: 0px var(--space-4); } .tlui-embed-dialog__warning { color: var(--color-warn); text-shadow: none; } .tlui-embed-dialog__instruction__link { display: flex; gap: var(--space-1); margin-top: var(--space-4); } .tlui-embed-dialog__enter a { color: var(--color-text-1); } .tlui-following-indicator { display: block; position: absolute; inset: 0px; border-width: 2px; border-style: solid; z-index: var(--layer-following-indicator); pointer-events: none; } /* ---------------- Offline Indicator --------------- */ .tlui-offline-indicator { display: flex; flex-direction: row; gap: var(--space-3); color: var(--color-text); background-color: var(--color-low); border: 3px solid var(--color-background); padding: 0px var(--space-5); height: 42px; align-items: center; justify-content: center; border-radius: 99px; opacity: 0; animation: fade-in; animation-duration: 0.12s; animation-delay: 2s; animation-fill-mode: forwards; } /* --------------- Keyboard shortcuts --------------- */ .tlui-shortcuts-dialog__header { border-bottom: 1px solid var(--color-divider); } .tlui-shortcuts-dialog__body { position: relative; columns: 3; column-gap: var(--space-9); pointer-events: all; touch-action: auto; /* Terrible fix to allow firefox users to scroll the dialog */ overflow-x: auto; } .tlui-shortcuts-dialog__body__tablet { columns: 2; } .tlui-shortcuts-dialog__body__mobile { columns: 1; } .tlui-shortcuts-dialog__group { break-inside: avoid-column; padding-bottom: var(--space-6); } .tlui-shortcuts-dialog__group__title { font-size: inherit; font-weight: inherit; margin: 0px; color: var(--color-text-3); height: 32px; display: flex; align-items: center; } .tlui-shortcuts-dialog__group__content { display: flex; flex-direction: column; color: var(--color-text-1); } .tlui-shortcuts-dialog__key-pair { display: flex; gap: var(--space-4); align-items: center; justify-content: space-between; height: 32px; } .tlui-shortcuts-dialog__key-pair__key { flex: 1; font-size: 12px; } /* ------------------- Da share zone ------------------ */ .tlui-share-zone { padding: 0px 0px 0px 0px; display: flex; flex-direction: row; justify-content: flex-end; z-index: var(--layer-panels); align-items: center; padding-top: 2px; padding-right: 4px; } /* ------------------- People Menu ------------------- */ .tlui-people-menu__avatars-button { display: flex; align-items: center; justify-content: flex-end; background: none; border: none; cursor: pointer; pointer-events: all; border-radius: var(--radius-1); padding-right: 1px; height: 100%; } .tlui-people-menu__avatars { display: flex; flex-direction: row; } .tlui-people-menu__avatar { height: 24px; width: 24px; border: 2px solid var(--color-background); background-color: var(--color-low); border-radius: 100%; display: flex; align-items: center; justify-content: center; position: relative; font-size: 10px; font-weight: bold; color: var(--color-selected-contrast); z-index: 2; } .tlui-people-menu__avatar:nth-of-type(n + 2) { margin-left: -12px; } .tlui-people-menu__avatars-button[data-state='open'] { opacity: 1; } @media (hover: hover) { .tlui-people-menu__avatars-button:hover .tlui-people-menu__avatar { border-color: var(--color-low); } } .tlui-people-menu__more { position: absolute; top: 0px; right: 0px; min-width: 0px; font-size: 11px; font-weight: 600; color: var(--color-text-1); font-family: inherit; padding: 0px 4px; letter-spacing: 1.5; } .tlui-people-menu__more::after { border-radius: var(--radius-2); inset: 0px; } .tlui-people-menu__wrapper { position: relative; display: flex; flex-direction: column; width: 220px; height: fit-content; max-height: 50vh; } .tlui-people-menu__section { position: relative; touch-action: auto; flex-direction: column; max-height: 100%; overflow-x: hidden; overflow-y: auto; touch-action: auto; } .tlui-people-menu__section:first-child, .tlui-people-menu__section:last-child { flex-shrink: 0; } .tlui-people-menu__section:not(:last-child) { border-bottom: 1px solid var(--color-divider); } .tlui-people-menu__user { display: flex; justify-content: flex-start; align-items: center; } .tlui-people-menu__user__color { flex-shrink: 0; } .tlui-people-menu__user__name { text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--color-text-1); max-width: 100%; flex-grow: 1; flex-shrink: 100; } .tlui-people-menu__user__label { text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--color-text-3); flex-grow: 100; flex-shrink: 0; margin-left: 4px; } .tlui-people-menu__user__input { flex-grow: 2; height: 100%; padding: 0px; margin: 0px; } .tlui-people-menu__user > .tlui-input__wrapper { width: auto; display: flex; align-items: auto; flex-grow: 2; gap: 8px; height: 100%; padding: 0px; } .tlui-people-menu__item { position: relative; } .tlui-people-menu__item:last-of-type .tlui-button__menu { margin-bottom: 0; } .tlui-people-menu__item__button { padding: 0 11px; overflow: hidden; } .tlui-people-menu__item > .tlui-button__menu { width: auto; display: flex; align-items: auto; justify-content: flex-start; flex-grow: 2; gap: 11px; } .tlui-people-menu__name { text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tlui-people-menu__item__follow { position: absolute; top: 0px; right: 0px; max-width: 40px; flex-shrink: 0; } .tlui-people-menu__item[data-follow='true'], .tlui-people-menu__item:has(.tlui-button:focus-visible) { padding-right: 36px; } .tlui-people-menu__item[data-follow='true'] .tlui-people-menu__item__follow, .tlui-people-menu__item:has(.tlui-button:focus-visible) .tlui-people-menu__item__follow { opacity: 1; } @media (hover: hover) { .tlui-people-menu__item__follow { opacity: 0; } .tlui-people-menu__item:hover { padding-right: 36px; } .tlui-people-menu__item:hover .tlui-people-menu__item__follow { opacity: 1; } } .tlui-menu-click-capture { position: fixed; inset: 0; z-index: var(--layer-menu-click-capture); } /* --------------- Contextual Toolbar --------------- */ .tlui-contextual-toolbar { position: absolute; } /** * N.B. We hide the toolbar while mousing down, so no need to turn these off. */ .tlui-contextual-toolbar, .tlui-contextual-toolbar * { pointer-events: all; } .tlui-contextual-toolbar [data-isactive='true']::after { background-color: var(--color-muted-2); opacity: 1; } .tlui-rich-text__toolbar { opacity: 0; transition: opacity 0.08s ease-in-out; } .tlui-rich-text__toolbar, .tlui-rich-text__toolbar * { pointer-events: none; } .tlui-rich-text__toolbar[data-visible='true'] { opacity: 1; } .tlui-rich-text__toolbar[data-interactive='true'], .tlui-rich-text__toolbar[data-interactive='true'] * { pointer-events: all; } .tlui-rich-text__toolbar-link-input { margin-left: 12px; /* * Nice touch tweak: keep the link editor toolbar the same as the default toolbar. * This is so the toolbar size stays stable going in and out of the link editor. */ width: 148px; } .tlui-rich-text__toolbar .tlui-input__wrapper { height: 40px; } /* ------------------- Accessibilty ------------------- */ .tl-skip-to-main-content { position: fixed; top: 48px; left: -9999px; padding: 8px 16px; z-index: var(--layer-toasts); } .tl-skip-to-main-content:focus { left: 8px; }